Tasks: Implement-Loop Coord-Authority Completion

Mission: implement-loop-coord-authority-completion-01KW2E7A Branch: design/coord-authority-remediation-2160 | Spec: spec.md | Plan: plan.md

Routes the implement/review-loop PRIMARY-kind reads (tasks/, WP*.md, lanes.json, WP-frontmatter) onto the kind-aware seam resolve_planning_read_dir(kind=...) for coordination-topology missions; hardens the dir-read ratchet (inline-shape + whole-src + self-test); closes #2140 and folds #2183.

Ownership / lane note: WP02 owns tests/architectural/test_gate_read_literal_ban.py (the dir-read ratchet + _DIR_READ_KNOWN_RESIDUALS). The routing WPs (WP03–WP06) each remove their own pins from that file in the same commit they route (FR-009) — a rationale-backed out-of-map edit — so they form a sequential chain (one lane) to avoid a shared-file race. WP01 (fixture), WP08 (#2140), WP09 (dead-symbol) are parallel. C-009: never edit merge/, lanes/, or core/worktree_topology — those are #2185.

Subtask Index

IDDescriptionWPParallel
T001Build shared un-stubbed coord-topology fixture (status-only husk + primary tasks/+lanes.json)WP01[P]
T002Fixture helpers: assert-reads-primary / assert-status-from-coord dual-leg assertersWP01[D]
T003Fixture smoke test (flat + coord topologies materialize correctly)WP01[D]
T004Add inline-call-shape detection arm to the dir-read AST scannerWP02
T005Widen scan scope to all of src/specify_cli/WP02
T006Mandatory self-test: synthetic inline pre-fix snippet flagged; routed snippet not flaggedWP02
T007Pin the full surfaced residual set; cite #2185 / #2186 / #2167 on out-of-scope pinsWP02
T008Recount + record the dir-read baseline census after wideningWP02
T009Route tasks status tasks/ read to seam (mixed-read per-leg split)WP03
T010Route list_tasks (inline-shape) + _map_requirements_feature_dir reads to seamWP03
T011Route finalize_tasks dir-read leg to seam (keep bootstrap STATUS coord)WP03
T012Route build_dependency_graph IN-LOOP caller in tasks.py (do NOT change its signature)WP03
T013Remove the tasks.py _DIR_READ_KNOWN_RESIDUALS pins (same commit)WP03
T014RED-first per-site tests for the tasks.py sites (both legs) on the coord fixtureWP03
T015Split discovery.py::preview_claimable_wp signature → planning_dir + status_dirWP04
T016Route _preview_claimable_wp_for_mission to pass the split dirsWP04
T017Route _resolve_review_context (lanes.json + tasks/) + _find_first_for_review_wp (inline)WP04
T018Route the review tasks/ leg; KEEP review-cycle sub-artifacts coord (C-008); avoid :539-617 legacy blockWP04
T019Remove the workflow.py/discovery.py pins (same commit)WP04
T020RED-first per-site tests (both legs; selection_reason unchanged on flat)WP04
T021Route build_normalized_wp_index:666 + resolve_workspace_for_wp/resolve_feature_worktree (lanes.json)WP05
T022Split the resolve_active_wp_for_branch:470 mixed read per-legWP05
T023Route context/resolver.py:163 (primary-anchor pattern) + task_utils/support.py:309WP05
T024Remove the workspace/context pins (same commit)WP05
T025RED-first per-site tests (both legs) on the coord fixtureWP05
T026Route tasks_dependency_graph.py:118 IN-LOOP caller (no signature change)WP06
T027Route tasks_parsing_validation.py:935 research-artifact readWP06
T028Split the validate_tasks.py:113 mixed read per-legWP06
T029Remove the dep-graph cluster pins (same commit)WP06
T030RED-first per-site tests (both legs)WP06
T031Teach is_def_use_canonical the _canonicalize_bare_modern_handle fold seamWP07
T032Auto-route the 4 hand-sanctioned entries; shrink permanent allowlist 7→3WP07
T033Recompute ROUTED_CANONICALIZER_FLOOR strictly below post-fix live censusWP07
T034Gate self-mutation test covering the new discriminator branchWP07
T035Refresh is_committed docstring to the primary-surface readWP08[D]
T036Add negative-assertion caller-contract regression pin (False on husk path)WP08[D]
T037Remove dead symbol FEATURE_CONTEXT_UNRESOLVED_CODE (prove zero importers)WP09[D]

Work Packages

WP01 — Shared coord-topology test fixture [P]

husk with no tasks//lanes.json + tasks/WP*.md and lanes.json on primary) plus dual-leg asserters, so every routing WP proves tasks-from-PRIMARY AND status-from-COORD.

smoke test materializes both topologies; reproduces the husk divergence without patching.

anti-pattern); must synthesize the post-#2106 shape (latent on existing repo missions).

  • Goal: One un-stubbed fixture (real meta.json coord topology + status-only -coord
  • Priority: P0 (foundational — WP03–WP06 depend on it). Independent test: fixture
  • Requirements: FR-014, NFR-003.
  • Subtasks: T001, T002, T003.
  • Risks: must NOT patch the topology-resolution stack (the test_done_bookkeeping_seam.py:353
  • Dependencies: none.

WP02 — Dir-read ratchet hardening + residual pinning

add the mandatory self-test, and pin the full surfaced residual set (out-of-scope sites cite #2185 / #2186 / #2167). Establishes the ratchet the routing WPs then drain.

green post-widening with the full pin set; self-test flags the synthetic inline snippet.

(NFR-005); pin every surfaced site (no silent skip).

  • Goal: Teach the scanner the inline-call shape, widen scope to all src/specify_cli/,
  • Priority: P0 (foundational; starts the ratchet chain). Independent test: gate
  • Requirements: FR-007, FR-008, FR-015 (pin citations), NFR-001.
  • Subtasks: T004, T005, T006, T007, T008.
  • Risks: gate-unmask-cannot-self-validate — the widening only bites post-merge
  • Dependencies: none. Owns tests/architectural/test_gate_read_literal_ban.py.

WP03 — Route tasks.py loop reads

_map_requirements_feature_dir, and the in-loop build_dependency_graph caller; split mixed reads per-leg; remove the tasks.py pins.

read tasks/ from primary; status events still from coord.

(T012 routes at the caller only).

  • Goal: Route the tasks/ reads in tasks status, list_tasks, finalize_tasks,
  • Priority: P1. Independent test: tasks status/tasks list on the coord fixture
  • Requirements: FR-001, FR-003, FR-006, FR-009.
  • Subtasks: T009, T010, T011, T012, T013, T014.
  • Risks: mixed-read per-leg (C-001); do NOT change build_dependency_graph's signature
  • Dependencies: WP01, WP02.

WP04 — Route workflow.py + discovery.py (signature split)

(the WP09-trap fix), route _preview_claimable_wp_for_mission, _resolve_review_context, _find_first_for_review_wp, and the review tasks/ leg; keep review-cycle sub-artifacts coord (C-008); remove the workflow/discovery pins.

fixture resolve primary; selection_reason unchanged on flat; review-cycle reads coord.

swap; avoid the workflow.py:539-617 legacy-fallback block and the feedback:// paths.

  • Goal: Split discovery.py::preview_claimable_wp into planning_dir + status_dir
  • Priority: P1. Independent test: claimable preview + review auto-find on the coord
  • Requirements: FR-002, FR-006, FR-009.
  • Subtasks: T015, T016, T017, T018, T019, T020.
  • Risks: the single-arg MIXED read is the exact WP09 trap — SPLIT the signature, don't
  • Dependencies: WP01, WP03 (ratchet chain).

WP05 — Route workspace/context + context/resolver + task_utils

resolve_feature_worktree (lanes.json), the resolve_active_wp_for_branch mixed read, context/resolver.py:163, and task_utils/support.py:309; remove the pins.

fixture read primary; status legs coord.

the :714 not-found message path must still resolve; context/resolver.py should adopt the implement.py:1018 primary-anchor pattern, not a bare swap.

  • Goal: Route build_normalized_wp_index, resolve_workspace_for_wp/
  • Priority: P1. Independent test: workspace WP index + lane resolution on the coord
  • Requirements: FR-005, FR-006, FR-009.
  • Subtasks: T021, T022, T023, T024, T025.
  • Risks: do NOT consolidate the coord-aware twin resolve_feature_dir_for_slug (C-007);
  • Dependencies: WP01, WP04 (ratchet chain).

WP06 — Route dependency-graph / WP-frontmatter readers

tasks_dependency_graph.py, the tasks_parsing_validation.py:935 research-artifact read, and the validate_tasks.py:113 mixed read; remove the pins.

the coord fixture read primary.

— protects out-of-loop callers merge/ordering:95, policy/merge_gates:238).

  • Goal: Route the in-loop build_dependency_graph caller in
  • Priority: P1. Independent test: dependency-graph + ready-for-review validation on
  • Requirements: FR-004, FR-006, FR-009.
  • Subtasks: T026, T027, T028, T029, T030.
  • Risks: route build_dependency_graph at the in-loop caller only (no signature change
  • Dependencies: WP01, WP05 (ratchet chain).

WP07 — Resolution gate: #2183 fold + floor recompute

the 4 hand-sanctioned entries auto-route; shrink the permanent allowlist 7→3; recompute ROUTED_CANONICALIZER_FLOOR strictly below the post-fix live census; cover the new branch.

floor < live; shrink-only twin-guard passes.

floor must be computed AFTER routing (depends on WP06).

resolution_gate_allowlist.yaml.

  • Goal: Teach is_def_use_canonical the _canonicalize_bare_modern_handle fold seam so
  • Priority: P2. Independent test: resolution-authority gate green; allowlist=3;
  • Requirements: FR-011, FR-012, NFR-001, C-005.
  • Subtasks: T031, T032, T033, T034.
  • Risks: the other 3 permanent sanctions are raw-param (not self-fold) — keep them;
  • Dependencies: WP06 (final routed census). Owns test_resolution_authority_gates.py,

WP08 — #2140 close (is_committed) [P]

caller-contract regression pin (False on a husk spec path lacking spec.md); close #2140.

coord-resolved reversion, GREEN now.

  • Goal: Refresh the stale coord-worktree docstring; add a negative-assertion
  • Priority: P2. Independent test: the regression test is RED against a hypothetical
  • Requirements: FR-010, C-004.
  • Subtasks: T035, T036.
  • Risks: pin must assert the negative, not a tautology; no multi-leg OR.
  • Dependencies: WP01 (fixture).

WP09 — Dead-symbol removal [P]

behavior-preservingly (prove zero importers; the bare string error code is untouched).

suite green.

  • Goal: Remove FEATURE_CONTEXT_UNRESOLVED_CODE from _read_path_resolver.py
  • Priority: P3. Independent test: grep proves no import FEATURE_CONTEXT_UNRESOLVED_CODE;
  • Requirements: FR-013, C-005.
  • Subtasks: T037.
  • Dependencies: none.

Close-out obligations (mission-level, not a WP)

branch, run the two architectural gates -v and paste the verbatim output into the PR body (the scan widening + floor raises only self-validate post-merge).

in separate lanes (a/c/d/e/f), not one lane. They edit the same _DIR_READ_KNOWN_RESIDUALS literal as cross-lane out-of-map pin removals. Before merging the chain, run spec-kitty merge --dry-run and inspect the conflict forecast on tests/architectural/test_gate_read_literal_ban.py (removed pin blocks are disjoint so it should be clean; #1684 dep-tip propagation carries each prior lane's removals). If it conflicts, resolve in pin-removal order WP03→WP04→WP05→WP06.

terminology guard locally before PR.

  • NFR-005 — after spec-kitty merge (local), BEFORE gh pr create, on the merged
  • Lane-chain merge forecast (post-tasks squad, alphonso)lanes.json placed WP03–WP06
  • NFR-004 — run tests/architectural/, tests/integration/, tests/git/ + the
  • FR-015 — confirm the #2185 / #2186 pins cite their issues; #2167 cites the scripts/tasks pins.
  • Issue-matrix terminal verdicts for #2115 / #2140 / #2183.

Dependencies (summary)

WP01 ─┬─> WP03 ─> WP04 ─> WP05 ─> WP06 ─> WP07
WP02 ─┘   (ratchet chain: each removes its own pins from WP02's file)
WP08 [P]   WP09 [P]