Mission Specification: single_branch implement/review loop + commit-message hygiene

Mission Branch: ccr-ba04d8aa-fx98ee Created: 2026-10-04 Status: Draft Input: Issues #5459, #5655, #5647, #5648

User Scenarios & Testing (mandatory)

User Story 1 - Agent claim on a single_branch mission is guarded (Priority: P1)

An agent runs spec-kitty agent action implement WP01 on a single_branch mission. The claim records a claim base, so move-task --to for_review passes after a real commit, without --force. A second claim into a busy or dirty write checkout is refused, as spec-kitty implement already refuses it.

Why this priority: Release blocker (#5459). Every agent-driven single_branch mission needs --force to reach review, and the one-writer refusals are bypassed with exit 0.

Independent Test: The #5459 reproducer exits 0.

Acceptance Scenarios:

1. Given a single_branch mission, When agent action implement WP01 runs, Then a claim-base ref exists for WP01. 2. Given WP01 in_progress in the write checkout, When agent action implement WP02 runs, Then it refuses with WRITE_CHECKOUT_OCCUPIED and WP02 stays planned. 3. Given uncommitted operator edits and no WP in progress, When agent action implement WP01 runs, Then it refuses with WRITE_CHECKOUT_DIRTY. 4. Given WP01 already in_progress with uncommitted work, When agent action implement WP01 runs again, Then it resumes (no refusal, claim base unchanged).

User Story 2 - Status mutations on single_branch commit themselves (Priority: P1)

mark-status and move-task on a single_branch mission commit the status files they write, so the write checkout is clean afterwards.

Why this priority: Release blocker (#5655). Left-over status files make a later move-task refuse, and the status surface drifts from HEAD.

Independent Test: After mark-status and after move-task --to for_review, git status --porcelain is empty.

Acceptance Scenarios:

1. Given a claimed single_branch WP, When mark-status T01 --status done runs, Then status.events.jsonl / status.json are committed. 2. Given a single_branch WP ready for review, When move-task --to for_review runs, Then no status file is left modified (including the implementer-identity annotation).

User Story 3 - Repeated -m builds a multi-paragraph message (Priority: P2)

spec-kitty safe-commit / spec-commit accept -m several times and join the values with blank lines, as git commit does (#5647).

Acceptance Scenarios:

1. Given -m "subject" -m "Co-Authored-By: X <x@y>", When safe-commit runs, Then the commit message is subject\n\nCo-Authored-By: X <x@y>.

User Story 4 - The gate-mechanics doc names the supported writer (Priority: P3)

docs/development/reference/ci-gate-mechanics.md points to spec-kitty agent acceptance-verdict (including negative-invariant mode) instead of hand-editing acceptance-matrix.json (#5648).

Edge Cases

  • Resume of the same WP in a dirty checkout stays allowed.
  • Lanes/coord missions keep their current claim path (the repo-root guard is single_branch-only).
  • Flat/legacy missions keep uncommitted annotations (unchanged).

Requirements (mandatory)

Functional Requirements

IDTitleUser StoryPriorityStatusDeliveryNo-op passable?
FR-001Action-implement records the claim baseAs an agent, I want agent action implement to record the claim base on single_branch so that for_review passes without --force.HighOpen[build]no — reproducer asserts the ref exists
FR-002Action-implement enforces write-checkout refusalsAs an operator, I want OCCUPIED/DIRTY/WRONG_BRANCH refusals on the agent path so that one checkout has one writer.HighOpen[build]no — paired with the resume positive control
FR-003Status annotations commit on single_branchAs an operator, I want mark-status and move-task annotations committed on single_branch so that the checkout stays clean.HighOpen[build]no — asserts clean porcelain
FR-004Repeated -m joins paragraphsAs an agent, I want repeated -m joined with blank lines so that subject+trailer commits keep the subject.MediumOpen[build]no — asserts the full message
FR-005Doc names acceptance-verdictAs an operator, I want the doc to name the supported writer so that I do not hand-edit the matrix.LowOpen[build]no — doc text check

Non-Functional Requirements

IDTitleRequirementCategoryPriorityStatus
NFR-001No regression on other topologiesExisting lanes/coord claim and status tests pass unchanged (0 new failures).ReliabilityHighOpen

Constraints

IDTitleConstraintCategoryPriorityStatus
C-001One guard authorityReuse _ensure_repo_root_checkout_available + record_claim_base; no second copy of the refusal order.TechnicalHighOpen

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: The #5459 reproducer exits 0 on this branch — [build] · no-op passable: no
  • SC-002: A single_branch mark-status + move-task cycle leaves git status --porcelain empty — [build] · no-op passable: no