Expand description
kranz exec -f <mission.md> — fully headless missions for CI (roadmap M5).
Plan file in, exit code out. There is no human on the other end: the
mission.md is a ticket-shaped markdown that must be self-sufficient, and
approval is automatic. The one place a headless run can’t proceed is when
the orchestrator answers request_plan with clarifying questions instead
of a plan — that means the plan file was underspecified, so exec fails with
a distinct exit code (3) and prints the questions to stderr for the CI log.
Flow (mirrors cmd_draft’s non-interactive seed→plan path, but then runs
the mission instead of parking it):
parse file → Ticket::mission_goal() → build backend →
MissionEngine::create → one planning_turn seeding the whole ticket →
request_plan() → auto-approve (or exit 3) → run() to a terminal state.
Events stream to stderr live (the same tail::tail_events feed kranz run uses) so CI logs show progress; the only thing on stdout is the final
one-line machine-readable summary:
kranz exec <id> <STATUS> cost=$X.XX branch=<b>
stdin is never read and no TUI is ever opened.
Structs§
- Exec
Options - Non-file inputs to one headless exec invocation.
- External
Enqueue Source
Constants§
- EXIT_
PUSH_ FAILED - Exit code when the mission COMPLETE’d but
--pushfailed. Distinct from mission failure (1) and underspecified (3) so CI can tell delivery apart from the run itself. Stdout still reportspushed=false. - EXIT_
UNDERSPECIFIED - Exit code exec fails with when the plan file is underspecified: the
orchestrator wanted clarification it cannot get headlessly (
NotReady).
Functions§
- cmd_
exec kranz exec -f <mission.md> [--repo <path>] [--yes] [--max-cycles N] [--enqueue] [--allow-unvalidated].- exit_
code_ for - Map a terminal mission status to the process exit code exec returns.
- parse_
mission_ markdown - Parse a ticket-shaped plan file into a
Ticket. The slug is derived from the file stem (likeTicket::load), so the foldedTicket::mission_goalcarries the goal, scoping answers, acceptance hints, and context verbatim. - scrutiny_
gate - The unattended scrutiny floor:
execruns with no human present, so a mission whose config disables the scrutiny validator (skipScrutiny) has no adversarial reader at all and can satisfy its own acceptance tautologically (docs/gascity.md lesson 3 records exactly this incident). Interactiverun/planare not gated — a human is present there. Passing--allow-unvalidated(or settingKRANZ_ALLOW_UNVALIDATED=1) is an explicit, auditable acknowledgment that overrides the floor.