Contracts

cli-surface.md

Contract: CLI surface

SurfaceAddition
spec-kitty consolidate`--origin-check [enforce\
spec-kitty accept`--origin-check [enforce\
orchestrator-api accept-mission--origin-check; refusal MISSION_NOT_READY, data.preflight_error_code, data.origin_freshness
orchestrator-api consolidate-mission--origin-check; refusal PREFLIGHT_FAILED, data.preflight_error_code(s), data.origin_freshness
envelopeCONTRACT_VERSION 1.10.0 → 1.11.0
agent action reviewno flag; prints Updated <lane> from <remote>/<lane> (<n> commits) or Created review workspace from <remote>/<lane>; refuses ORIGIN_LANE_DIVERGED; warns on unreachable
spec-kitty init (already initialized)installs merge-driver config; still exit 0 "Already initialized"
spec-kitty upgradeinstalls merge-driver config, reported in its outcome
environment`SPEC_KITTY_ORIGIN_CHECK=enforce\

kernel-git-remote.md

Contract: kernel.git.remote

Foundation layer; knows refs and remotes, never Missions, lanes or status. Every function is bounded and non-prompting (GIT_TERMINAL_PROMPT=0, SSH BatchMode=yes, caller's GIT_SSH_COMMAND preserved).

  • no_prompt_env(base: Mapping[str,str] | None = None) -> dict[str,str]
  • resolve_remote(cwd: Path, branch: str) -> str | None — FR-017 rule; local config reads only.
  • tracking_ref(remote: str, branch: str) -> str — refs/remotes/<remote>/<branch>.
  • remote_heads(cwd, remote, branches: Sequence[str], *, timeout=LS_REMOTE_TIMEOUT) -> dict[str, str] — branch → sha for the listed ones; raises RemoteUnreachable on any failure/timeout.
  • fetch_branches(cwd, remote, branches, *, timeout=FETCH_TIMEOUT) -> None — fetch --no-tags with explicit +refs/heads/b:refs/remotes/r/b refspecs; never writes refs/heads; raises RemoteUnreachable.
  • divergence(cwd, local: str, remote_ref: str, *, paths=()) -> Divergence(ahead, behind) — one rev-list --left-right --count local...remote_ref [-- paths]; ahead meaningful only unscoped. Also serves push_preflight.inspect_target_branch_sync.
  • describe_remote_head(cwd, remote, *, timeout) -> str | None — the remote show default-branch probe used by protection_policy.
  • clone_repository(...) / fetch_tags(...) — thin bounded wrappers for doctrine.sources.git_source (census closure, not freshness reuse).
  • No separate runner: every function calls kernel.git.runner.run_git(..., env=no_prompt_env(), timeout=...).
  • Errors: RemoteUnreachable(GitCommandError) carries remote, argv and stderr summary.
  • Timeouts: LS_REMOTE_TIMEOUT = 5.0, FETCH_TIMEOUT = 15.0 (NFR-001).

origin-freshness.md

Contract: specify_cli.git.origin_freshness and specify_cli.git.origin_gate (as shipped)

origin_freshness (verdicts and policy; data-only):

  • ORIGIN_CHECK_ENV = "SPEC_KITTY_ORIGIN_CHECK"; resolve_origin_check_mode(flag: str | None) -> OriginCheckSetting(mode, source, warning), source in default | flag | environment | read-only; READ_ONLY_ORIGIN_CHECK for accept --no-commit / --diagnose.
  • check_mission_branches(repo_root, mission_slug, *, lane_branches, owned=None) -> MissionFreshness(evidence, lanes) — ONE ls-remote + ONE fetch per resolved remote for the evidence branch and the lanes together; evidence branch = placement_seam(...).write_target(STATUS_STATE).ref; evidence behind scoped to every mission_dir_aliases alias + /status.events.jsonl (ADR 2026-10-05-1).
  • approved_lane_branches(repo_root, mission_slug, lanes_manifest, *, completed_wps=frozenset(), owned=None) -> list[str] — code lanes not fully canceled; over-selects when status is unreadable.
  • enforce_merge_gate(*, evidence, lanes, setting, merge_record_exists, evidence_checkout) -> list[str] — returns warnings (warn mode) or raises OriginFreshnessRefused(.error_code, .error_codes, .verdicts).
  • plan_review_lane(repo_root, lane_branch) -> ReviewLaneAction(kind, verdict, remote_sha, remote_ref, code, message).
  • FreshnessVerdict(branch, remote, state, behind, ahead, scope, detail, remote_sha); states up_to_date | behind | ahead | diverged | local_missing | remote_missing | unreachable | no_remote.
  • Refusal text: first line <CODE>: <branch> is <state> (<n> behind / <m> ahead of <remote>/<branch>), then remedy lines (git -C <checkout> pull <remote> <branch> when a checkout holds the branch, else git fetch <remote> <branch>:<branch>; consolidate --abort first when a merge record exists), then Opt out (not recommended): --origin-check warn, or SPEC_KITTY_ORIGIN_CHECK=warn.

origin_gate (the single shared gate authority):

  • run_origin_gate(repo_root, slug, *, setting, lane_branches, owned, merge_record_exists) — combined contact, coordination local_missing pass-through via routes_through_coordination(resolve_topology(...)), enforce_merge_gate; used by accept, orchestrator-api accept-mission / consolidate-mission and (through consolidation.origin_gate) consolidate.