Implementation Plan: Owned issue-verdict authority
Branch: owned-issue-verdict-authority-01M55KGY | Date: 2026-10-17 | Spec: spec.md Input: Mission specification from kitty-specs/owned-issue-verdict-authority-01M55KGY/spec.md
Summary
Thread the validated OwnedCheckout fact through the agent mission issue-verdict command and the fail-closed write-target gate (coordination.surface_resolver.resolve_for_write → mission_runtime.write_target_degrade) so an owned-only mission can record issue-matrix verdicts via --owned-checkout (and via flagless adoption from inside the owned checkout). Also thread the owned fact through the coord-owned read + legacy-migration path (coord_read_dir_for / _resolve_read_dir / _migrate_if_needed) per the resolved scope decision. This is the twin of the merged #6023 acceptance-verdict fix; it reuses that fix's carrier pattern and owned test fixtures. The only net-new surface over #6023 is the shared write_target_degrade gate, which issue-verdict reaches (via resolve_for_write) and acceptance-verdict does not.
Technical Context
Language/Version: Python 3.11+ Primary Dependencies: typer (CLI), existing specify_cli / mission_runtime / coordination layers; no new deps Storage: issue-matrix.json per mission (unchanged format); event log / status files via existing writers Testing: pytest; red-first integration tests reusing #6023 owned R/P/S fixtures (tests/integration/test_owned_acceptance_authority_6023.py, test_p0_repro_6023_owned_acceptance_verdict.py); p0_repro-marked reproduction; mission_runtime unit tests for the gate functions Target Platform: Linux/macOS dev + CI Project Type: single project (CLI/control-plane) Performance Goals: N/A (no hot path changed) Constraints: additive owned=None keyword args only; import direction specify_cli → coordination → mission_runtime preserved; issue-matrix format and locked-writer semantics unchanged; three unrelated write_target_degrade callers stay byte-identical Scale/Scope: ~3–4 source files (issue_verdict.py, coordination/surface_resolver.py, mission_runtime/write_target_degrade.py, optionally mission_runtime/resolution.py::coord_read_dir_for) + tests + changelog/CLI-reference
Charter Check
GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.
- Brownfield onboarding / architectural alignment: PASS — change rides existing seams; mirrors the proven #6023 pattern; no new authority or placement seam (C-001).
- ATDD-first / red-first (DIRECTIVE test discipline): PASS — a failing owned repro lands before the fix (C-003);
p0_reproreproduction included. - Tiered rigour / fail-closed: PASS — fail-closed refusal preserved for an owned fact that does not resolve a real mission (NFR-001); no silent fallback to the repository root.
- Shared-helper backward-compat: PASS — the three unrelated callers of
write_target_degrade.assert_coord_write_materializedkeepowned=Nonedefaults and stay byte-identical (FR-005). - Test economy (DIRECTIVE_041): PASS — new tests guard real owned behavior through the existing entry points; ratchet rows carry same-fixture positive controls; no shape-pins or inert self-compares.
- Layer rules: PASS — no new reverse import edge;
mission_runtimegains only additive params.
No violations → Complexity Tracking empty.
Project Structure
Documentation (this mission)
kitty-specs/owned-issue-verdict-authority-01M55KGY/
├── plan.md # This file
├── spec.md
├── research.md # Phase 0 output
├── data-model.md # Phase 1 output
└── tasks.md # Phase 2 output (/spec-kitty.tasks)
(No contracts/ — this mission defines no new interfaces; meta.json records contracts: none with rationale.)
Source Code (repository root)
src/specify_cli/cli/commands/agent/issue_verdict.py # command surface: option + do_issue_verdict + _resolve_write_dir/_resolve_read_dir/_migrate_if_needed + locked writer passthrough + flagless adoption
src/specify_cli/coordination/surface_resolver.py # resolve_for_write: add owned passthrough
src/mission_runtime/write_target_degrade.py # resolve_write_target_or_degrade / _mission_meta_exists / assert_coord_write_materialized: owned-aware (additive None default)
src/mission_runtime/resolution.py # coord_read_dir_for: owned param for coord-owned read (scope decision)
tests/integration/ # red-first owned issue-verdict authority test + p0-repro (reuse #6023 fixtures)
tests/<mission_runtime path>/ # unit tests for the three gate functions' owned param + byte-identity of the 3 unrelated callers
docs/changelog/CHANGELOG.md # Fixed entry
docs/reference/cli (regenerated) # issue-verdict --owned-checkout option
Structure Decision: Single project. Changes ride three existing layers in strict specify_cli → coordination → mission_runtime direction; no new modules.
Complexity Tracking
No Charter Check violations — not applicable.
Implementation Concern Map
> Concerns, not work packages. /spec-kitty.tasks turns these into executable WPs. > A single_branch mission runs WPs sequentially; the dependency order below is load-bearing.
IC-01 — mission_runtime write-target gate owned-awareness
- Purpose: Make the fail-closed gate recognize an owned-only mission when handed the owned fact, so it stops refusing a genuinely-present owned mission — while leaving its three unrelated callers byte-identical.
- Relevant requirements: FR-002, FR-005, NFR-001, NFR-002
- Affected surfaces:
src/mission_runtime/write_target_degrade.py(resolve_write_target_or_degrade,_mission_meta_exists,assert_coord_write_materialized); downstreamresolve_placement_onlyalready owned-capable - Sequencing/depends-on: none (foundation)
- Risks: shared helper with 3 other callers (decision-log default target, bookkeeping-commit target, status-transition write target) — the new
ownedparam MUST defaultNoneand be proven byte-identical for them; theestablish_coord_write_location(..., owned=None)hard-code must become a passthrough
IC-02 — resolve_for_write owned passthrough
- Purpose: Carry the owned fact from the command across the coordination seam into the gate.
- Relevant requirements: FR-002
- Affected surfaces:
src/specify_cli/coordination/surface_resolver.py::resolve_for_write - Sequencing/depends-on: IC-01
- Risks: thin; keep the public signature additive (
owned=None)
IC-03 — issue-verdict command owned wiring + flagless adoption
- Purpose: Add
--owned-checkoutto the command, resolve ownership once (mirror #6023), and thread the fact through resolution, the write dir, the read/migration dir, and the locked re-read/splice/write. - Relevant requirements: FR-001, FR-004, FR-006
- Affected surfaces:
src/specify_cli/cli/commands/agent/issue_verdict.py(issue_verdict_command,do_issue_verdict,_resolve_write_dir,_resolve_read_dir,_migrate_if_needed,_locked_reread_splice_and_write); reuse_owned_checkout.OwnedCheckoutOption/resolve_owned_or_refuse,LIFECYCLE_OWNED_TOPOLOGIES - Sequencing/depends-on: IC-02
- Risks:
write_issue_matrixalready acceptsowned— must actually pass it; preserve fail-closed when the owned fact resolves no mission (NFR-001)
IC-04 — coord-owned read path threading
- Purpose: Thread the owned fact through the coord-owned read + legacy-matrix migration so an owned coord mission reads/migrates from the owned surface, not the repository root (resolved scope decision).
- Relevant requirements: FR-003
- Affected surfaces:
src/mission_runtime/resolution.py::coord_read_dir_for;issue_verdict._resolve_read_dir/_migrate_if_needed;tasks/issue_matrix_migration.pycall - Sequencing/depends-on: IC-03
- Risks:
coord_read_dir_forreturnsNonefor ownedsingle_branch(primary case), so the write-dir path (IC-03) already covers #6320's headline; this concern covers the coord-topology case and must not regress thesingle_branchfallback tofeature_dir
IC-05 — red-first proof, p0-repro, and deliverable hygiene
- Purpose: Land the failing owned repro before the fix, pin it as a p0-repro, add mission_runtime unit tests (including the byte-identity of the 3 unrelated callers), and update changelog + regenerated CLI reference.
- Relevant requirements: C-003, SC-001, SC-002
- Affected surfaces:
tests/integration/, mission_runtime unit tests,docs/changelog/CHANGELOG.md, regenerated CLI reference - Sequencing/depends-on: woven through IC-01..IC-04 (red-first per concern), hygiene at the end
- Risks: test economy — one focused positive test per behavior; reuse #6023 fixtures; ratchet tests pair with same-fixture positive controls