Contracts

next-routing.md

Contract: Finalized Task Routing for spec-kitty next

Scope

This contract covers #961.

Rule

When a mission has finalized tasks and WP files, canonical task board and WP lane state are authoritative for implement-review routing. Stale runtime or mission phase state must not route the agent back to discovery.

Inputs

  • Mission handle from --mission.
  • Mission directory under kitty-specs/<mission>/.
  • tasks.md.
  • tasks/WP*.md.
  • Canonical status.events.jsonl reduced lane state.
  • Existing runtime state, if present.

Outputs

spec-kitty next --mission <mission> --agent <agent> --json returns one of:

  • Implement step for the next implementable WP.
  • Review step for the next reviewable WP.
  • Merge/completion step when all WPs are approved or done.
  • Terminal state for completed missions.
  • Blocked decision with guard failures when finalized state is inconsistent.

Prohibited Output

  • discovery or another early planning phase solely because stale runtime/phase state says so after finalized tasks and WP lane state exist.

Regression Fixture Requirements

Create a fixture mission with:

  • spec.md, plan.md, tasks.md.
  • At least one tasks/WP*.md.
  • Canonical status events showing finalized WP state.
  • Stale runtime/phase state set to discovery or equivalent early phase.

Assertions:

  • Planned/in-progress WPs route to implement.
  • for_review or in_review WPs route to review or active review handling.
  • Approved/done WPs route toward merge/completion.
  • Blocked WPs produce blocked output rather than discovery.

retrospective-cli.md

Contract: Completed-Mission Retrospective Missing-Record Path

Scope

This contract covers #965.

Command Surface

Existing:

  • spec-kitty agent retrospect synthesize --mission <mission> --json

Allowed addition:

  • spec-kitty agent retrospect capture --mission <mission> --json
  • or spec-kitty agent retrospect init --mission <mission> --json

Required JSON Outcomes

Every JSON response for missing-record handling must be parseable and include:

  • command.
  • mission_id or resolvable mission identity when available.
  • mission_slug when available.
  • status.
  • outcome.
  • next_action when operator action is required.

Outcome values:

  • retrospective_record_created.
  • retrospective_synthesized.
  • insufficient_mission_artifacts.
  • mission_not_found.

Behavior

Missing Mission

Return a structured JSON outcome with outcome="mission_not_found" and no Python traceback.

Completed Mission With Missing Record and Sufficient Artifacts

Either:

  • synthesize initializes the record and continues, returning retrospective_record_created and/or retrospective_synthesized; or
  • capture/init creates the record and synthesize reports the command to run.

Completed Mission With Missing Record and Insufficient Artifacts

Return outcome="insufficient_mission_artifacts" with the missing artifact list and a human-actionable next_action.

Existing Record

Preserve existing synthesize behavior and proposal application semantics.

Regression Coverage

  • Missing retrospective.yaml no longer emits only record_not_found.
  • JSON output parses for all required outcomes.
  • Missing mission is distinct from missing retrospective record.
  • Created records go through retrospective.writer.write_record.

review-cycle-domain.md

Contract: Review-Cycle Domain Boundary

Scope

This contract covers #960, #962, #963, and fix-mode rejection context loading. It defines the shared invariant boundary used before status/state pointers change.

Proposed Module

src/specify_cli/review/cycle.py

Required Capabilities

Create Rejected Review Cycle

Input:

  • Repository root path.
  • Mission slug.
  • WP id.
  • Feedback source file path.
  • Reviewer or actor identity.
  • Optional affected files.

Output:

  • Written review-cycle artifact path.
  • Canonical review-cycle://... pointer.
  • ReviewResult for a rejected outbound in_review transition.

Failure behavior:

  • Missing feedback file fails before artifact write.
  • Empty feedback fails before artifact write.
  • Invalid artifact frontmatter fails before pointer/result return.
  • Pointer resolution failure fails before status transition.

Validate Review Artifact

Input:

  • review-cycle-N.md path.

Output:

  • Parsed artifact metadata.

Required validation:

  • YAML frontmatter exists.
  • Required fields are present and non-empty.
  • Cycle number is positive.
  • Verdict is valid for the caller's requested path.
  • Mission and WP identity match the requested context.

Generate Canonical Pointer

Input:

  • Mission slug.
  • WP task-file slug.
  • Review cycle artifact filename.

Output:

  • review-cycle://<mission>/<wp-task-file-slug>/review-cycle-N.md

Rules:

  • New rejected review state must persist this pointer form.
  • Path traversal or malformed pointer segments are invalid.

Resolve Pointer

Input:

  • Repository root path.
  • Pointer string.

Output:

  • Resolved file path, warning list, and pointer kind.

Rules:

  • review-cycle:// resolves under kitty-specs/<mission>/tasks/<wp-slug>/.
  • feedback:// resolves legacy git-common-dir feedback paths and reports a deprecation warning.
  • Operational sentinels resolve to no artifact and no warning.
  • Unknown or missing pointers fail safely for mutation paths and warn for prompt-rendering paths.

Adapter Requirements

  • src/specify_cli/cli/commands/agent/tasks.py uses the boundary for --to planned --review-feedback-file.
  • src/specify_cli/cli/commands/agent/workflow.py uses the boundary for fix-mode pointer resolution.
  • src/specify_cli/review/artifacts.py remains the artifact dataclass/parser unless implementation discovers a small validation helper belongs there.
  • src/specify_cli/status/emit.py remains the only status event persistence gateway.

Regression Coverage

  • #960: Reject from in_review with feedback file succeeds without manual review_result.
  • #960: Invalid feedback fails before state mutation.
  • #962: New persisted pointer is canonical review-cycle://....
  • #962: Legacy feedback:// pointer resolves with deprecation warning.
  • #963: Missing required frontmatter is rejected before pointer persistence.
  • Fix-mode: focused rejection context loads from canonical pointer and ignores action-review-claim sentinel.