Skip to main content

Module ticket

Module ticket 

Source
Expand description

Mission tickets — .kranz/tickets/<slug>.md (design: docs/backlog-and-slack.md).

A ticket is a mission-in-waiting authored by a human as markdown: a small --- frontmatter block (parsed here without a YAML dependency) plus body sections (## Goal, ## Context, ## Scoping answers, ## Acceptance hints). The .md stays human-authored; mutable pipeline status lives in a sibling <slug>.status JSON file so the ticket text is never rewritten by the engine (except the explicit “needs context” append the orchestrator makes, and the committed lifecycle state below).

§Committed lifecycle state (design: ticket-state-frontmatter)

The .status sidecar is gitignored runtime: on a fresh clone it vanishes, and with it any operator verdict like done/superseded — a closed ticket would silently re-enter the ready path. The durable home for that verdict is the ticket .md itself: an optional additive state: frontmatter key (TicketLifecycle; open default, plus terminal done, superseded, wontfix) with an optional free-text state-note:. It is the SINGLE SOURCE OF TRUTH: reads resolve with frontmatter precedence (a diverging sidecar cache is logged, never silently followed), and the one lifecycle write path — Ticket::write_lifecycle — writes BOTH, demoting the sidecar to a write-through cache so existing readers keep working. A ticket with NO state: key reads its sidecar exactly as before this schema existed (backcompat).

Ticket::mission_goal folds the whole ticket into one readable markdown blob so the non-interactive draft driver can seed the orchestrator with the entire ticket in a single message.

Structs§

ResolvedTicketState
The outcome of resolving a ticket’s effective state under frontmatter precedence (see Ticket::resolve_state).
StateDivergence
One observed frontmatter/sidecar disagreement: the committed frontmatter state: won over the .status sidecar cache. Surfaced (and tracing::warn!-logged by Ticket::read_state) rather than silently resolved — design rule 2 is “never a silent divergence”.
Ticket
A parsed ticket: frontmatter fields plus body sections.

Enums§

Schedule
How often a ticket re-instantiates. Recurring schedules are re-drafted by the scheduler; Once is the default one-shot ticket.
TicketLifecycle
The committed, operator-declared lifecycle state of a ticket — the optional state: frontmatter key (design: ticket-state-frontmatter). Unlike the pipeline TicketState (which the engine flips as a ticket moves draft → review → queue → run), this is the human’s terminal verdict, and it lives IN the committed .md so it survives a fresh clone. Terminal values (done/superseded/wontfix) exclude the ticket from ready/queue evaluation exactly like terminal pipeline states.
TicketState
Pipeline status of a ticket, stored in <slug>.status (never time-based — determinism matters for the event-sourced engine).

Constants§

MAX_TICKET_BUDGET_USD
Ceiling on the per-ticket max-budget-usd override (audit M10). Ticket bytes are unauthenticated tree data — a worker commit or a PR-comment webhook can write them — and the value raises the orchestrator’s own spend cap, so a ticket may lower or moderately raise the default ($20, crate::types::MissionConfig::default) but never name an unbounded one.

Functions§

is_known_frontmatter_key
Whether key is a frontmatter key this parser recognizes. Public so the allowlist is testable as the list it is, rather than only through the match arms that consume it.
parse_task_class_from_goal
Recover the task class Ticket::mission_goal folded in, from a mission goal string. crate::orchestrator::MissionEngine::create calls this to route the executor tier for a mission seeded from a ticket, since by the time create runs it only has the folded goal, not the Ticket.