ID-71 {71.4} PLAN — AI tooling surface rationalisation (decomposition)
ID-71 {71.4} PLAN — AI tooling surface rationalisation
Section titled “ID-71 {71.4} PLAN — AI tooling surface rationalisation”Status:
{71.4}PLAN. Authored by a FRESH Planner instance (Q-PLANNER-2 / B4) against the ratified pair —{71.2}PRODUCT.md (B-INV-1..43) +{71.3}TECH.md (M-changes + §M 1:1 mapping) — and the now-ratified hard-upstream{104.3}TECH.md (the canonicalAgentEvalContractinlib/eval/contract.ts, S356). Decomposes ID-71 implementation into ordered Subtasks{71.6+}({71.1/2/3} = spec chain, {71.5} = Phase-0 done). British English throughout. DD/MM/YYYY.Decomposition is sized for QUALITY, NOT a count budget — there is NO 25-subtask ceiling (TECH §PLAN-readiness, inherited verbatim). Standalone slices are carved wherever they raise quality: the eval layer is split OUT (ID-104-owned, consumed-not-built), and M-CREATE is a standalone ID-59-coupled slice.
Overview
Section titled “Overview”ID-71 rationalises KH’s AI-consumption surface into ONE outcome-grouped MCP server (Option A) with a headless-agent fleet (Option C) layered additively, shipped with a testable headless-completeness guarantee. This PLAN decomposes the ratified PRODUCT+TECH pair into vertical, outcome-shaped slices, ordered along the settled chain:
ID-104 eval-engine (HARD UPSTREAM — spec-done, ratified S356) │ provides lib/eval/contract.ts (AgentEvalContract), eval_touchpoints registry, │ severity model, recordAiCall(), graduation metric — ID-71 CONSUMES, does not build ▼Wave 0 — carried PI-items (PI-13/14 fold prep, PI-15 retire record) ▼Wave 1 — outcome-grouped surface consolidation + bid→forms rename cutover (ONE atomic break) │ (find / where-are-we-exposed / whats_in_my_queue / get·dedup·assign / layer-placement) ├── Wave 1b — M-DOCS client-doc refresh (lands IN the rename cutover wave) └── M-CREATE — create-into-store leg (STANDALONE slice, coupled to ID-59, NOT onboarding) ▼Wave 2 — grounding shapes + eval-guard rollout (GATED on ID-104 contract existing) ▼Wave 3 — headless-completeness + fleet substrate + MVP pilot (GATED on ID-104; pilot-gated) ▼Wave 3b — deferred-with-anchor (B-INV-43 / M-DEFER-O8 — NO launch slice; anchor only)Architecture decisions inherited (do NOT re-litigate)
Section titled “Architecture decisions inherited (do NOT re-litigate)”- Eval layer is ID-104-owned, consumed not built (OQ-2 / §X#2). No ID-71 Subtask implements
eval-runner/ the severity model /recordAiCall()/ the touchpoint registry / theAgentEvalContractdefinition. ID-71 slices IMPORTAgentEvalContractfrom@/lib/eval/contract(direct file import, no barrel) and the M38 guard reads the registry. The born-evaluable Waves 2/3 are HARD-GATED on ID-104’slib/eval/contract.tsexisting — this is the eval-layer split the §PLAN-readiness directive mandates. - M-CREATE is a standalone slice coupled to ID-59 (OQ-1, cutover SATISFIED).
reference_ingestis LIVE on prod (verified 15/06/2026); the create-leg mints thesource_document/reference FIRST then materialises thecontent_itemfile-first on ID-59’s substrate, satisfying the{59.10}source-less guard (bl-266). It is NOT a direct-DB.insert(todaycontent.ts:525), NOT the edit-pathwriteBackFileFirst, and NOT onboarding-routed (OQ-1 fallback RETIRED). - Corrected ontology RULE (OQ-4, BLOCKER fix).
application_type(CV 25, umbrella) andform_type(CV 26, sibling axis) are DISTINCT.procurementis the application umbrella;bidis aform_typevalue WITHIN procurement.list_active_procurement/get_procurement_detailare application-umbrella reads (they queryapplication_types.key='procurement',procurement.ts:53/156) and are KEPT, NOT renamed. The inverted “procurement is a form-type” framing is a RATIFIED-REJECTED anti-pattern and is NOT inherited. What retires is the genericbidform vocab (get_bid_question→get_form_question,bid_*resources/prompts/apps). - Single human-facing server; fleet additive; Option B deferred (B-INV-25/26).
outputSchemaforward-standard for NEW entries only (B-INV-37); never retrofitted.
Code-intelligence orientation (PLAN-pass, knowledge-hub, 15/06/2026)
Section titled “Code-intelligence orientation (PLAN-pass, knowledge-hub, 15/06/2026)”Independently re-confirmed by this Planner (gitnexus + grep + filesystem; gitnexus is partially stale on the MCP string-literal surface, so grep/filesystem are the conclusive tool — stated per finding). Grounds each slice’s file-ownership boundary:
findconsolidation surface (gitnexus querydefinitions+ grep). Registry barrelregisterTools(lib/mcp/tools/index.ts); search trio +findSimilarItemsImplinlib/mcp/tools/search.ts; formatterslib/mcp/formatters/search.ts. The L4 substraterunSearchToolChecks(scripts/mcp-eval/functional-correctness.ts:260-618) is the verifier.findSimilarItemsImpldid NOT resolve bygitnexus_contextname lookup (index drift) — grep is conclusive.- bid→forms rename surface (grep, conclusive — string literals, not graph symbols). Confirmed
bare-
bidsites:lib/mcp/tools/procurement.ts:334(get_bid_question);lib/mcp/resources.ts148-149 (bid_workspace,kb://bids/{id}), 662/670/680 (ui://bid-dashboard/app.html), 835 (bid_briefing), 1029 (bid_pipeline_review);lib/mcp/tools/apps.ts:435(procurementDashboardUri = 'ui://bid-dashboard/app.html');scripts/mcp-eval/fixtures.ts95-97/170/242/247/255/267/550;lib/queue/envelope.ts61 ('bid_draft_all'), 182 (the dedup-key shape);mcp-apps/bid-dashboardsingle-file build (callsget_bid_question,get_procurement_detail,search_knowledge_base). KEEP confirmed:list_active_procurement(procurement.ts:53),get_procurement_detail(procurement.ts:156) — application-umbrella reads, already correctly named. create_content_itemdirect insert (grep, conclusive).lib/mcp/tools/content.ts:251registration;:525.insert(insertData)— the direct-DB write M-CREATE replaces.writeBackFileFirst(lib/edit-intent/write-back.ts:131-282) callers arerunSweep/rollbackSweep/patchHandler(gitnexus_context) — confirms it is the EDIT-back path only, NOT a create verb, validating the M-CREATE carve. Source-less guard atwrite-back.ts:116(if (!row.source_document_id || !row.storage_path) return null;).- One-queue substrate (grep, conclusive).
lib/attention.ts:AttentionItem(:24,typediscriminator lists'source_document_change':38 — no producer/count, scoped OUT of v1),AttentionSourceData(:80),SEVERITY_ORDER(:107),produceGovernanceReviewItems(:122),produceQualityFlagItems(:194),produceCoverageGapItems(:382). Fragmented MCP queue reads to consolidate live inlib/mcp/tools/governance.ts,lib/mcp/tools/dashboard.ts,lib/mcp/tools/review.ts+ formatterslib/mcp/formatters/governance.ts/lib/mcp/formatters/review.ts. The/review(app/review,app/api/review) +/api/governance/review(app/api/governance/review) ROUTE layer is UNCHANGED (OQ-5 — only the MCP read surface collapses). - Inline AI touchpoints (Wave 2 —
ls lib/ai/).classify.ts,draft.ts,quality-check.ts,extract-questions.ts,summarise.ts,extract-content.ts,match.ts,vision.ts,change-reports.ts— the M35/M36 grounding-shape + no-silent-fallback surface. - Guard pattern (M38 extends — filesystem).
scripts/lib/mcp-parser.ts(parser),__tests__/mcp/mcp-fixture-sync.test.ts,__tests__/scripts/mcp-inventory-parser.test.ts. ID-104 shipsrecordAiCall(grep-guard (__tests__/eval/record-ai-call-guard.test.ts, T16) that M38 extends — consumed, not rebuilt. - Remote MCP transport (B-INV-10 — no code change).
app/api/mcp/[transport]/route.tsEXISTS; guarded byproxy.tspublicRoutes. Auth seamcreateMcpClient/checkMcpRole(lib/mcp/auth.ts).
Line anchors are indicative; resolve by symbol + file path, not line.
Wave/chain ordering and parallelisation guidance
Section titled “Wave/chain ordering and parallelisation guidance”| Wave | Slices | Gate | Parallelisable within wave? |
|---|---|---|---|
| 0 | {71.6} | none (prep record) | n/a (single slice) |
| 1 | {71.7}–{71.11} surface + {71.12}–{71.14} rename | after {71.6} | {71.7}/{71.8}/{71.9}/{71.10} parallel (distinct tool files); {71.12}–{71.14} rename lockstep is ONE PR (serial, atomic) |
| 1b | {71.15} M-DOCS | with rename ({71.12}–{71.14}) | lands in cutover wave; coordinated with docs-site lane |
| M-CREATE | {71.16} | ID-59 substrate (cross-Task) | standalone; parallel to Wave 1 surface slices |
| 2 | {71.17}–{71.21} | HARD-GATED on ID-104 lib/eval/contract.ts + Wave 1 done | {71.17}/{71.18} parallel (distinct touchpoints); {71.19}/{71.20} after contract import lands |
| 3 | {71.22}–{71.28} | HARD-GATED on ID-104 + Wave 2 grounding done | {71.22}/{71.23}/{71.24} reads parallel; {71.25}–{71.28} fleet/pilot serial (pilot proves the chain) |
| 3b | none | n/a | anchor-only; NO slice (B-INV-43) |
Serial spine (must respect): ID-104 contract → Wave 1 surface (the consolidated entries the headless set drives) → Wave 1 rename atomic break → Wave 2 grounding/guard (needs the contract + the consolidated entries) → Wave 3 headless-complete L4 enumeration (needs all consolidated entries + grounding) → MVP pilot (proves the whole chain end-to-end). M-CREATE sequences with ID-59 in parallel to Wave 1.
Per-wave Subtask groupings
Section titled “Per-wave Subtask groupings”Wave 0 — Carried PI-items ({71.6})
Section titled “Wave 0 — Carried PI-items ({71.6})”- {71.6} records PI-15 RETIRED (B-INV-42, M42) with the one-line no-live-consumer confirmation +
kb://taxonomynamed replacement, and stages the PI-13/14 branding/connector inventory (B-INV-41, M41) that the rename lockstep ({71.12}–{71.14}) folds in. Surface-design record slice; no live code path re-enabled. PI-13/14 actual rename happens in the rename lockstep, not here.
Wave 1 — Outcome-grouped surface consolidation ({71.7}–{71.11}) + bid→forms rename ({71.12}–{71.14})
Section titled “Wave 1 — Outcome-grouped surface consolidation ({71.7}–{71.11}) + bid→forms rename ({71.12}–{71.14})”Surface consolidation (Option A; each a vertical outcome slice, parallelisable across distinct tool files):
- {71.7} ONE
findtool (M27/M33, B-INV-27/33) — collapses the search trio +find_similar_items;type/scope/granularityparams preserve q&a + chunk semantics; two-step list/preview→verbatim preserved; declaresoutputSchema(M37, new entry). - {71.8}
where-are-we-exposedfive-layer (M29/M4, B-INV-4/29) — consolidates exposure / freshness / coverage / quality / certification reads into data→quality→use-today→gaps→opportunities withsuggest_content_creationresolution affordance attached. - {71.9}
whats_in_my_queuefaceted queue (M30/OQ-5, B-INV-30) — NEW MCP read overlib/attention.ts;facet?: content_quality|governance|all;source_document_changescoped OUT of v1. Route layer (/review,/api/governance/review) unchanged. - {71.10}
get/dedup/assign one-or-many consolidation (M32, B-INV-32) — three single+batch pairs → three parameterised entries. - {71.11} ontology-grounding affordance + layer placement (M28/M34/M22-26, B-INV-28/34/22/23/24/25/26)
—
get_entity_relationships+kb://entitiespromoted to afindanswering affordance; prompts//kb:*commands become thin orchestrators; 4 MCP Apps stay visual-density layer; surface-design verdict record anchors every keep/refine/retire to an O/W number (no orphaned outcome); single-server + Option-B deferral trigger recorded.
bid→forms rename cutover (ONE atomic PR — B-INV-31, M31; serial, six-lane lockstep):
- {71.12} rename lane 1+2 — code symbols (
gitnexus_rename:useBidActions→useFormActions,useBidTransitions→useFormTransitions,BidsPage→FormsPage) + MCP string literals (get_bid_question→get_form_question;bid_workspace/kb://bids/{id}→kb://forms/{id};ui://bid-dashboard→ui://forms-dashboard;bid_briefing→form_briefing;bid_pipeline_review→form_pipeline_review). KEEPlist_active_procurement/get_procurement_detail. - {71.13} rename lane 3+4 — plugin bundle (
bid-pipeline-review.md→form-pipeline-review.md,bid-status.md→form-status.md, skillbid-writing→completing-forms;bun run build:pluginregenerates the committed bundle) + queue/API ('bid_draft_all'→'form_draft_all',bid_id→form_id,app/api/bids/[id]→app/api/forms/[id]withproxy.ts publicRoutesre-check; thes224job_type CHECK-widen migration — the ONE DDL touch). - {71.14} rename lane 5+6 — fixtures + evals (
scripts/mcp-eval/fixtures.ts, L4 checks infunctional-correctness.ts, Pythonscripts/tests/test_cocoindex_server.pyvia grep) + inventory (mcp-parser.ts/mcp-inventory-parser.test.tscount assertions). The drift-guard forces these in lockstep with {71.12}/{71.13}.
Wave 1b — Client-doc refresh ({71.15})
Section titled “Wave 1b — Client-doc refresh ({71.15})”- {71.15} M-DOCS (B-INV-41) — refresh Platform Overview + Claude Integration Guide to the rationalised outcome-grouped surface + forms vocabulary. Lands IN the cutover wave; coordinated with the docs-site docubot lane (§X#5). Docs-site repo PR, not KH code.
M-CREATE — create-into-store leg ({71.16}; standalone, ID-59-coupled)
Section titled “M-CREATE — create-into-store leg ({71.16}; standalone, ID-59-coupled)”- {71.16} M-CREATE (B-INV-6/12) —
create_content_itemgains a write-to-canonical-store create-leg on ID-59’s substrate: mintsource_document/reference FIRST (viareference_ingest, LIVE on prod), THEN materialise thecontent_itemfile-first so the{59.10}source-less guard passes. Replaces the direct.insert(content.ts:525). Adjacent to ID-59’spromoteCorpusExtractionscreate-into-store pattern. Cross-Task-coupled to ID-59 (§X#1).
Wave 2 — Grounding shapes + eval-guard rollout ({71.17}–{71.21}; HARD-GATED on ID-104)
Section titled “Wave 2 — Grounding shapes + eval-guard rollout ({71.17}–{71.21}; HARD-GATED on ID-104)”- {71.17} grounding shapes (M35, B-INV-35) — each
lib/ai/touchpoint declares + uses exactly one ofoutput_config.format| forced-toolstrict:true+additionalProperties:false| citations oversearch_result; citations never combined with structured output;draft.ts3-pass split stays forced. - {71.18} no silent fallback (M36, B-INV-36) —
stop_reason:"refusal"/"max_tokens"handled explicitly (log + surface); replacedraft.tsPass-1 bare try/catch; no assistant prefills. - {71.19} born-evaluable guard (M38/M13/M40, B-INV-38/13/40) — extend
__tests__/mcp/mcp-fixture-sync.test.ts/mcp-inventory-parser.test.ts+ the ID-104recordAiCall(grep-guard so any tool/prompt/skill/inline change FAILS without acreate-skill/update-skillcall AND an eval/fixture update AND a boundAgentEvalContract(imported from@/lib/eval/contract). CONSUMES ID-104; builds nothing inlib/eval/. - {71.20} born-evaluable contracts + KH-owned evals (M14/M15/M40, B-INV-14/15/40) — author the
per-touchpoint
AgentEvalContractrows for new/refined ID-71 touchpoints (register via ID-104’s registry); evals authored locally (Raindrop Workshop) committed into KH’s harness; in-house WS-5 graduation metric with a zero-Raindrop-egress network assertion. - {71.21} AI-invisibility +
outputSchemaforward-standard (M39/M37, B-INV-39/37) — consumption surfaces present enrichments as native (admin Provenance carve-out aside); new entries carryoutputSchema, retiring tools NOT retrofitted.
Wave 3 — Headless-completeness + fleet substrate ({71.22}–{71.28}; HARD-GATED on ID-104; pilot-gated)
Section titled “Wave 3 — Headless-completeness + fleet substrate ({71.22}–{71.28}; HARD-GATED on ID-104; pilot-gated)”- {71.22} headless-complete read set + L4 enumeration (M1-M5, B-INV-1/2/3/4/5) — the L4 suite enumerates EXACTLY {O1 find/answer, O4 reorientation/briefing (widened beyond KH state), O6 exposure five-layer, W5.6 re-syndication}; each driven MCP-only to a terminal result, zero human-in-UI step.
- {71.23} propose-writes + auto-apply-off (M6/M7, B-INV-6/7) — agents create propose-rows/drafts/ resolutions into the queue ({71.9}) with no publication gate; publishing routes to the human gate; per-workflow auto-apply switch exists and is verifiably OFF at launch.
- {71.24} dual runtime + connectivity (M8/M9/M10/M11/M12, B-INV-8/9/10/11/12) — headless set reachable
identically from Claude runtimes AND goose via the SAME remote-MCP surface (no runtime-privileged entry,
inventories equal); one trigger-driven push channel (RSS/webhook/email); write-back scoped to the three
sanctioned destinations (
writeBackFileFirstedit-back + {71.16} M-CREATE create-into-store + push), net-new source-system write-back refused at the surface. - {71.25} scope-boundary enforcement (M16/M17/M20, B-INV-16/17/20) — W9.3 absent from enumeration, present as onboarding cross-reference; launch scope = {O1/O4/O6 + W5.6} + one piloted recipe; no net-new capability built; WS-10/WS-12 carry-forward recorded to O5/O2 own-Tasks (§X#4).
- {71.26} goose runtime substrate (M-prep for MVP; OQ-3) — Coolify service on the existing IONOS box
(co-located, RATIFIED): YAML Recipes + built-in cron + remote-MCP +
goose run(NOTgoosed); pinned image tag, pin-and-soak policy; self-signed-TLS health-probe (#7685) configured on Coolify healthcheck; container sized conservatively (burn-guard headroom). - {71.27} MVP pilot recipe (M18/M21, B-INV-18/21) — ONE goose recipe: cron → remote-MCP → Claude → one O4 briefing → deliver to one outbound channel + write one propose-row into the queue. Exercises HC-1/HC-2/HC-4 + the §7 must-be-true assumptions; goose committed as launch substrate ONLY on pilot success.
- {71.28} fleet-graduation framing record (M19, B-INV-19) — fleet grows additively, per-Task, metric-gated; surface-design record states the graduation mechanism (no big-bang fleet; auto-apply is the per-workflow reward of clearing the ID-104 threshold). Record slice; no fleet agents built.
Wave 3b — Deferred-with-anchor (NO slice)
Section titled “Wave 3b — Deferred-with-anchor (NO slice)”- B-INV-43 / M-DEFER-O8: O8 W8.4 argument-quality checking is recorded DEFERRED-WITH-ANCHOR (covered by the {71.11} surface-design verdict record’s deferred-anchor list). No launch Subtask is created — the numbered anchor carries it forward to a later O8 group / own-Task, born-evaluable when it lands.
B-INV → Subtask coverage table (orphan-check)
Section titled “B-INV → Subtask coverage table (orphan-check)”Every B-INV ID-71 OWNS maps to ≥1 Subtask. Eval-infrastructure B-INV are marked ID-104-owned (consumed not built); five “no code change — satisfied by X” B-INV per TECH §M carry no slice.
| B-INV | Owner / Subtask | Note |
|---|---|---|
| B-INV-1/2/3/4/5 | {71.22} (B-INV-4 also {71.8}) | headless-complete read set + L4 enumeration |
| B-INV-6 | {71.23} + {71.16} (create-into-store) | propose-rows; create via M-CREATE |
| B-INV-7 | {71.23} | auto-apply off at launch |
| B-INV-8/9 | {71.24} | dual runtime; inventories equal |
| B-INV-10 | {71.24} | no code change — remote MCP exists; evaluated as a connection |
| B-INV-11/12 | {71.24} (B-INV-12 also {71.16}) | push channel; sanctioned write-back destinations |
| B-INV-13 | {71.19} | ID-104-owned contract CONSUMED by the M38 guard |
| B-INV-14/15 | {71.20} | evals KH-owned; metric on ID-104 infra (consumed); egress assertion |
| B-INV-16 | {71.25} | no code change — W9.3 cross-reference only |
| B-INV-17 | {71.25} | scope enumeration matches |
| B-INV-18/21 | {71.27} | MVP pilot proves HC-1/2/4; pilot-gated |
| B-INV-19 | {71.28} | fleet additive, Task+metric-gated (record) |
| B-INV-20 | {71.25} | no code change — net-new not built; WS-10/WS-12 carry-forward |
| B-INV-22/23/24 | {71.11} | verdicts anchored to O/W; no orphaned outcome |
| B-INV-25 | {71.11} | one human-facing server; fleet additive |
| B-INV-26 | {71.11} | no code change — Option-B deferral trigger recorded |
| B-INV-27/33 | {71.7} | one find; two-step retrieval preserved |
| B-INV-28 | {71.11} | ontology-grounding affordance |
| B-INV-29 (+4) | {71.8} | one where-are-we-exposed five-layer |
| B-INV-30 | {71.9} | one queue + facet over lib/attention.ts |
| B-INV-31 | {71.12}+{71.13}+{71.14} | completing-forms + bid→forms rename (one atomic break) |
| B-INV-32 | {71.10} | get/dedup/assign one-or-many |
| B-INV-34 | {71.11} | layer placement holds |
| B-INV-35 | {71.17} | one grounding shape per touchpoint |
| B-INV-36 | {71.18} | no silent fallback |
| B-INV-37 | {71.21} | outputSchema forward-standard |
| B-INV-38 | {71.19} | forcing-function guard (consumes ID-104 registry) |
| B-INV-39 | {71.21} | AI-invisibility |
| B-INV-40 | {71.19}+{71.20} | eval is the gate (consumes ID-104) |
| B-INV-41 | {71.6}+{71.12}/{71.13}+{71.15} | PI-13/14 fold into rename; M-DOCS refresh |
| B-INV-42 | {71.6} | PI-15 retired; kb://taxonomy replacement |
| B-INV-43 | no slice (anchored in {71.11} record) | deferred-with-anchor; O8 W8.4; own-Task/later-group |
Coverage: all 43 invariants accounted for. No orphan B-INV. Eval-infrastructure invariants
(B-INV-13/14/15/40) are satisfied by CONSUMING ID-104’s lib/eval/contract.ts + registry +
recordAiCall() guard — no ID-71 Subtask builds eval infrastructure. Five “no code change”
records (B-INV-10/16/20/26 + B-INV-43 deferred-anchor) carry no implementation slice by design.
Risks and mitigations (decomposition-level)
Section titled “Risks and mitigations (decomposition-level)”| Risk | Impact | Mitigation |
|---|---|---|
| ID-104 hard-upstream slip blocks Wave 2/3 | High | Waves 2/3 HARD-GATED on lib/eval/contract.ts existing; the lib/eval/types.ts placeholder is a last-resort schedule fallback only (OQ-2 — NOT intent). ID-104 is spec-done + ratified (S356). |
| Rename half-break shows clients a mixed surface | High | {71.12}/{71.13}/{71.14} are ONE atomic PR; mcp-fixture-sync.test.ts drift-guard forces fixtures in lockstep; proxy.ts publicRoutes re-check for the new API path. |
| M-CREATE trips the {59.10} source-less guard | Med | {71.16} mints source binding BEFORE the file leg; coupled to ID-59 which owns the substrate. |
| goose burn-guard headroom on the co-located box | Med | {71.26} sizes the container conservatively; watch burn guard during soak; pilot-gated. |
| Inverted ontology re-introduced in rename | High | Corrected RULE stated in every rename slice’s details; list_active_procurement/get_procurement_detail explicitly KEPT. |
Cross-Task dependencies surfaced (sibling-only constraint HONOURED — not bent)
Section titled “Cross-Task dependencies surfaced (sibling-only constraint HONOURED — not bent)”Subtask dependencies are sibling-only ({71.x}). The two genuine cross-Task couplings stay at
Task level as coordination intents (TECH §X), NOT bent into Subtask deps:
- ID-59 → {71.16} M-CREATE (file-first write-back substrate,
in_progress). The create-leg builds on ID-59’s substrate. Sequence {71.16} with ID-59. Recommendation to Orchestrator: a Task-level coordination note (ID-71 ←couples→ ID-59), NOT a Subtask dep. No Task-split/merge needed — {71.16} is self-contained ID-71 work that consumes an ID-59 substrate. - ID-104 → Waves 2/3 (eval engine, spec-done/ratified S356) — HARD UPSTREAM. ID-71 CONSUMES
lib/eval/contract.ts+ registry +recordAiCall(). Recommendation to Orchestrator: a Task-level hard-dependency note (ID-71 Wave 2/3 ←depends→ ID-104 implementation), NOT a Subtask dep. No Task-split/merge needed.
No sibling-only violation surfaced — no ID-71 Subtask wanted a dep on a non-{71.x} sibling, so no Task-split/merge escalation is required. Both cross-Task couplings are legitimately Task-level.
Open questions
Section titled “Open questions”None blocking. ID-104 (spec-done) and ID-59 (in-progress) sequencing is the Orchestrator’s wave-merge concern; this PLAN states the coupling explicitly and gates the dependent waves accordingly.
End of {71.4} PLAN. 23 implementation Subtasks ({71.6}–{71.28}) across Wave 0 / Wave 1 (+1b) /
M-CREATE / Wave 2 / Wave 3 (+3b anchor-only). Eval layer SPLIT OUT (ID-104-owned, consumed not built);
M-CREATE carved standalone, coupled to ID-59; bid→forms rename is ONE atomic three-slice break with the
corrected ontology RULE; B-INV-43 deferred-with-anchor (no slice). All 43 B-INV accounted for. Records in
plan-subtasks.json for add-subtasks --file.