Research — Placement-Port Residuals Closure
All open decisions were resolved before planning: two by operator design-fork answers, the rest by the post-spec adversarial squad (architect-alphonso, reviewer-renata, debugger-debbie, planner-priti; profile-loaded, evidence-grounded). This file records the decisions; no NEEDS CLARIFICATION remain.
D-01 — A3 remedy: read tasks/ from the PRIMARY leg (not a fail-closed abort)
- Decision: Move only the
tasks/frontmatter READ (_seed_phase/_verify_phase) to the PRIMARY leg; keep the seed-event WRITE on the COORD leg and thestatus_phaseflip on PRIMARY. - Rationale: Operator chose "heal, don't abort." Squad (architect + debbie) proved a naive
status_dir → feature_dirswap would pushstatus.events.jsonl(STATUS_STATE = COORD) onto PRIMARY — wrong partition. The fix must decouplebackfill_runtime_state's read-dir from its event write-dir. - Alternatives rejected: (a) fail-closed abort guard — operator declined; halts rather than heals. (b) naive leg swap — moves the split instead of closing it.
D-02 — B2 remedy: degrade _load_traces to []
- Decision: Wrap
read_dir(TRACER_FILE)inexcept (CoordinationBranchDeleted, StatusReadPathNotFound): return []. - Rationale: Operator chose to preserve the documented best-effort contract.
CoordinationBranchDeletedsubclassesStatusReadPathNotFound, so the except set is exact; do not widen to bareException(Edge Case: unexpected errors stay loud). - Alternatives rejected: make the raise explicit — contradicts the best-effort docstring; scoped narrow to one call site to avoid #2922 collision (C-003).
D-03 — C-001 corrected: FR-003 is A1-independent (BLOCKER fix)
- Decision: Remove the "A1-before-A2 hard sequence." Gate greenness depends on FR-008/FR-012 (the
executor.pycoord-seed call site), not on routing_flip_phase. - Rationale: Adjudicated from source — the write-side gate scans only
CommitTarget/safe_commit;_flip_phasewrites viawrite_meta(<dir>)(invisible), andgrepshows the entiremigration/subtree has zeroCommitTarget/safe_commitcalls, so dropping its prefix reds nothing. See [[reference-write-side-rederivation-gate-grammar]]. - Consequence: FR-001's PRIMARY-correctness is enforced by a runtime assert, not a static gate. C-007 keeps the FRs in one lane for file-ownership (not correctness) reasons.
D-04 — FR-008 + FR-012 resolution: allow-list, not seam-route / not STANDARD
- Decision: Extend both gate allow-lists (
BOUNDARY_SANCTIONED_MODULESfor write-side;_PROTECTED_FLOW_ALLOWLISTS["MERGE_BOOKKEEPING"]for guard-capability) to includemerge/executor.py's coord-seed call site with one dated rationale. - Rationale: The coord-seed commit writes
status.events.jsonl(STATUS_STATE → COORD) to the capturedpre_target_coord_reffrom the COORD worktree, on a best-effort merge path that must never abort. Seam-routing adds merge-window resolvability coupling (ActionContextError); STANDARD would refuse the protected coord destination. Allow-list is the partition-correct, non-destabilizing resolution. - Alternatives rejected: seam-route (couples best-effort path to resolvability); assert STANDARD (breaks the legitimate protected-destination write — the exact PR #1850 regression the guard test names, but inverted).
D-05 — FR-004 scope: migration/-subtree only; upgrade/migrations/ retained
- Decision: Narrow only
src/specify_cli/migration/; keepsrc/mission_runtime/andsrc/specify_cli/upgrade/migrations/as justified prefixes; scope the guarantee wording accordingly. - Rationale: The merged NFR-001 deferred BOTH
migration*subtrees. Narrowing only one and claiming an un-qualified "any module" guarantee would be a documented lie whileupgrade/migrations/remains a prefix.upgrade/migrations/holds sanctioned version-migration drivers.
D-06 — FR-005 helper home: src/mission_runtime/
- Decision: New
resolve_write_target_or_degrade(repo_root, mission_slug, kind, *, degrade_ref)lives inmission_runtime(ownsresolve_placement_only+candidate_feature_dir_for_mission); import-legal for all three call sites. - Rationale: Keeps the degrade policy beside the authority;
decision_log/gitare not coordination modules, somission_runtimebeatscoordination/. - Constraint: kind-parameterized — coord kinds degrade to the coord ref (C-004).
D-07 — Tracker shape
- Decision: Mint a parent epic; native-link #2923 + #2924 + #2926 (all orphaned,
parent: null); mint a Part-C issue for FR-009/010/011; one issue-matrix row per issue. - Rationale: A mission is not an issue; #2923's body covers A1/A2/A3 only, so the CLI/merge reds need their own tracked home for a clean 1:1 terminal matrix.
Live-evidence baseline (debbie)
All six Part C tests confirmed RED on the merge-base for the stated reasons (PWHEADLESS=1 pytest): write-side-rederivation @ executor.py:1056, guard-capability[MERGE_BOOKKEEPING] @ executor.py, raw-mission-spec-path @ mission_repair.py:65, golden-contract 9≠8, and the two status.events.jsonl merge tests. FR-011's tests encode the real FR-019/FR-020 durability invariant → fix the product. test_repair_command_registered_on_mission_app passed locally / failed CI → parked as verify-on-CI.