Skip to content

Canonical Pipeline Implementation Plan

Date: 18/05/2026 (S241) Status: [DRAFT — pending Liam review] Source specs: docs/specs/id-31-0.9-canonical-pipeline/{PRODUCT,TECH}.md (canonical substrate); landed Wave 2 architecture sub-docs (docs/plans/phase-0-investigation/architecture/02-data-flow.md, 04-workspace-types.md, 05-qa-flow.md, 06-mcp-tooling.md, 08-new-features.md); docs/specs/id-38-rls-pattern/{PRODUCT,TECH}.md; docs/specs/reserved-workspace-seats/{PRODUCT,TECH}.md. Purpose: Decompose the canonical-pipeline spec pair into top-level implementation tasks with subtasks, dependencies, and per-task spec requirements. Becomes the authoritative implementation plan for canonical-pipeline v1 (Phase 1 of the overall project plan, S242+).


This plan applies planning-and-task-breakdown skill discipline against the canonical-pipeline spec pair plus the four post-S238 architecture sub-docs (02 / 04 / 05 / 06 / 08), the RLS-pattern spec pair, the reserved-workspace-seats spec pair, and the S240 audits (drift + readiness).

Task-size discipline (per skill §“Task Sizing Guidelines”):

  • 1 task unit ≈ 1-1.5h foreground OR 2h sub-agent. Top-level tasks aim for 1-3 units; if a task exceeds 3 units it is decomposed into subtasks.
  • Acceptance criteria are verifiable — every subtask has a concrete observable (test passes, grep returns 0, migration applies cleanly, etc.).
  • No fabrication — every claim cites a source per construction-guide §5.

Parallel-safety criteria (per skill §“Parallelization Opportunities”):

  • Safe to parallelize: Independent feature slices (no file overlap), pre-launch spec drafts, doc-only edits in different directories.
  • Must be sequential: Database migrations (single combined PR per Q-OQR1-16); schema cascades that depend on table creation; rename sweeps that touch shared files.
  • Coordination contract: Specs that gate implementation tasks land BEFORE their dependent task starts (§3 dependency graph + §8 ordering).

Gating logic (per skill §“Step 5 Order and Checkpoint”):

  • Spec gates implementation. Where a new spec is required (Q-EX2 contract, cocoindex ledger API, procurement-workspaces, etc.), the spec drafting task gates the implementation task.
  • Migration gates downstream. The Q-OQR1-16 combined PR is the central gate — many tasks [LOCKSTEP-WITH-MIGRATION] and cannot land before it.
  • Spike gates substrate decisions. PENDING-SPIKE items (S1, S3, S5, S8, S10) gate the corresponding P-N implementation tasks.

UK English throughout (colour, organisation, DD/MM/YYYY). Per CLAUDE.md.


13 top-level tasks decomposed from canonical-pipeline P-N invariants + drift-audit + STILL-OPEN register. Task IDs are stable references used across §3 dependency graph and §4 per-task detail.

#Top-level taskFamilyEffort (units)
T1Gating spec drafting — Q-EX2 + cocoindex ledger + Q1.3-Q1.N invariantsSpec drafting2.5
T2Q-OQR1-16 combined PR migration drafting (10-item canonical scope + 5 reserved seats)Database migration3
T3RLS-pattern combined migration apply + observability validationDatabase migration1.5
T4Procurement umbrella rename (44-file sweep + lib/bid → lib/procurement + state machine)Code refactor2
T5digestschange_reports renameCode refactor1
T6Q&A two-tier model: q_a_pairs + q_a_extractions + q_a_pair_history migration + RPCsDatabase + RPC2.5
T7Phew Q&A first-ingest via cocoindex (markdown source files → q_a_extractions → promote to q_a_pairs)Pipeline re-ingest2
T8Cocoindex flow scaffolding — source-binding + extraction + Cloud Run sidecar deployPipeline implementation3
T9Per-UC write-back implementation (UC1/UC4/UC6 user-direct + UC3 + UC5 + UC8) + Diff-UI sidecar re-pointFeature implementation3
T10question_matches table + retrieval substrate + scoring columnsDatabase + retrieval1.5
T11Citations polymorphic enum + version-on-citeDatabase + integration1
T12Mempalace KG integration — Shape A temporal + Shape B provenanceKG integration2
T13Pre-launch operational pre-decisions + observability gates (Theme F follow-through, prompt-cache spike, tracked-changes DOCX regression)Operational1.5
T14Cocoindex absorption cleanup — delete retired pipeline code + dependencies post-T8 stableCode retirement1

Total foreground equivalent: ~27 task units. Implementation kickoff is S242+ per S241 continuation prompt. (S243 interim ratifications: T7 reframed data migrationcocoindex re-ingest; T14 NEW; Diff-UI retained — folded into T9; ledger-API DEFERRED-v1.1; intelligence_workspaces / sales_proposal_workspaces / product_guide_workspaces specs added to §5; concurrent-edit-intent-arbitration spec lifted from CONDITIONAL to MUST; form_type taxonomy 3-tier split per Item 19.)

Procurement-workspaces feature spec (T9 sub-dependency) is out of scope for this PLAN — owned by the procurement feature spec per docs/specs/reserved-workspace-seats/PRODUCT.md line 93 (referenced as a sibling future-spec). See §5 NEW specs row “procurement-workspaces” for the placeholder.


ASCII flow (top blocks gate bottom blocks; || = parallel-safe within block):

WAVE 0 — Spec gates (T1)
Q-EX2 contract spec || Q1.3-Q1.N invariants extension
intelligence-workspaces spec || sales-proposal-workspaces spec || product-guide-workspaces spec
concurrent-edit-intent-arbitration TECH spec (MUST)
|
v
WAVE 1 — RLS infra (T3 DONE-S239; verified S243)
|
v
WAVE 2 — Combined PR migration (T2)
application_types + workspaces.application_type_id FK
kb_section retire
procurement satellite rename
project_id → workspace_id (2 DB cols)
form_templates rename + form_type 3-tier split (form_type / procurement_vehicle / vehicle_instance)
digests → change_reports
provenance enum + entity_aliases.category rename
source_documents.workspace_id NULLABLE
q_a_pairs schema sketch
+5 reserved satellite seats (per S-1)
intelligence_workspaces JSONB → typed (company_profile_id, guide_id, relevance_threshold) Shape B promotion
|
v
WAVE 3 — Parallel feature slices (T4 || T5 || T6 || T11)
T4 procurement code rename + state machine
T5 digest → change_reports code sweep
T6 q_a_pairs table + extractions cache + history
T11 citations polymorphic enum + version-on-cite
|
v
WAVE 4 — Pipeline scaffolding + retrieval (T8 || T10)
T8 cocoindex flow scaffolding + Cloud Run sidecar
T10 question_matches table + retrieval scoring
|
v
WAVE 5 — Phew first-ingest + features + KG (T7 || T9 || T12)
T7 Phew Q&A markdown source files → cocoindex first-ingest (depends on T8)
T9 per-UC write-back (UC1/UC3/UC4/UC5/UC6/UC8) + Diff-UI sidecar re-point
T12 mempalace KG Shape A + Shape B integration
|
v
WAVE 6 — Operational gates (T13)
Prompt-cache verification spike
Tracked-changes DOCX regression test
Theme F MCP-action follow-through + per-tool audit
|
v
WAVE 7 — Cleanup (T14)
Delete scripts/kb_pipeline/ + lib/extraction/ + retired deps post-T8 stable

Critical-path tasks (one-fail-blocks-everything): T1 → T2 → T6 → T8 → T7. T7 now depends on T8 (cocoindex flow must exist before Phew Q&A can ingest via cocoindex). Without the gating specs (T1), the migration (T2), the schema (T6), the cocoindex flow (T8), or the first-ingest (T7), the rest of the pipeline cannot be exercised end-to-end.

Maximally-parallel band: Wave 3 (T4 || T5 || T6 || T11) and Wave 4 (T8 || T10) and Wave 5 (T7 || T9 || T12). Each Wave keeps 3-4 sub-agents in flight subject to CLAUDE.md isolation: "worktree" + sequential merge pattern.


§4.1 T1 — Gating spec drafting (Q-EX2 + cocoindex ledger + Q1.3-Q1.N)

Section titled “§4.1 T1 — Gating spec drafting (Q-EX2 + cocoindex ledger + Q1.3-Q1.N)”
  • Scope (in): Three independent specs drafted ahead of any pipeline implementation. (i) docs/specs/id-36-cocoindex-extraction-contract/{PRODUCT,TECH}.md for Q-EX2 Pydantic discriminated union with ExtractByLlm. (ii) docs/specs/id-36-cocoindex-ledger-api/TECH.md for the TS-facing API over cocoindex per-flow-run ledger. (iii) Extension to docs/specs/id-31-0.9-canonical-pipeline/PRODUCT.md §1 covering Q1.3-Q1.N content-model invariants (or a sibling docs/specs/id-56-content-model-invariants/PRODUCT.md if scope justifies — judgement at draft time).
  • Scope (out): Implementation of the contract or the ledger API — purely spec work. Implementation tasks (T8 cocoindex flow + T10 question_matches) consume these specs.
  • Acceptance criteria:
    • Q-EX2 contract spec lands with discriminated-union schema (extracted Q&A vs entity mention vs classification output), Pydantic class shapes, ExtractByLlm typed output_type integration pattern, and validation rules.
    • Cocoindex ledger TECH spec lands with the TS API surface (per pipeline_runs rollup vs internal LMDB exposure boundary), file:line refs to landing points, and the partial-resolve framing from 02-data-flow.md §7.2.
    • Q1.3-Q1.N invariants spec lands with content-model invariants beyond P-1 + P-2 (what a content_items row looks like after ingest, chunking-boundary invariants per lib/content/chunking.ts, field population rules) — applies construction-guide §5.3 gap-flag format if any sub-invariant is STILL-OPEN.
    • All three specs cite source ratifications and use construction-guide / write-product-spec discipline as appropriate.
  • Subtasks:
    1. Draft cocoindex-extraction-contract/PRODUCT.md (S-N invariants for typed extraction).
    2. Draft cocoindex-extraction-contract/TECH.md (Python class shapes + ExtractByLlm integration).
    3. Draft cocoindex-ledger-api/TECH.md (partial-resolution framing per 02-data-flow.md §7.2).
    4. Draft Q1.3-Q1.N content-model extension (location TBD per skill judgement — extend PRODUCT.md §1 or new spec).
  • Dependencies: None — this is the entry gate.
  • Spec requirement: 3 NEW specs (drafting IS this task). All three use /write-product-spec + /write-tech-spec skills (feature-spec pattern per S241 critical-rule 5 — not construction-guide pattern, since these are pipeline-feature specs).
  • Effort estimate: 2.5 task units (3 × ~1 unit each, with some overlap).
  • Risk: Q-EX2 discriminated-union design may surface ambiguity in ExtractByLlm output_type capability — a short spike could be needed before the spec lands. Cocoindex internal LMDB exposure boundary may force re-scoping of the ledger API spec.

§4.2 T2 — Q-OQR1-16 combined PR migration

Section titled “§4.2 T2 — Q-OQR1-16 combined PR migration”
  • Scope (in): Single migration file landing all 10 items from 0.9-decision-graph.md §11.3 PLUS the 5 reserved satellite seats per docs/specs/reserved-workspace-seats/TECH.md T-1.

  • Scope (out): Code-side renames (T4, T5); data migration of existing q_a_pair rows (T7); per-app columns on reserved seats (deferred to feature specs per S-7).

  • Acceptance criteria:

    • Migration applies to staging (turayklvaunphgbgscat) cleanly; supabase db push succeeds with no errors.
    • All 10 Q-OQR1-16 items present: application_types instance table + 6 seed rows; workspaces.application_type_id FK + drop type text col; kb_section retire; procurement rename (bid_workspacesprocurement_workspaces); project_idworkspace_id (2 DB cols); form templates rename (3 tables); digestschange_reports; provenance enum + entity_aliases.categoryprovenance; source_documents.workspace_id NULLABLE; q_a_pairs schema sketch.
    • 5 reserved seats created upfront (PK + FK + RLS only per S-1..S-8); auto-RLS event trigger fires per RLS-PATTERN P-1; grants helper called per S-6.
    • Migration file passes migration-revoke-guard.yml + schema-parity.yml workflows.
    • supabase gen types regenerated; database.types.ts reflects all new tables.
  • Subtasks: 0. WP2a (pre-T2 helper + code sweep) — DONE-S245 (commits f6a13f4e + c8cf4e8f). lib/intelligence/workspace-context.ts ships getIntelligenceWorkspaceContext() + extractContextFromDomainMetadata() reading JSONB (behaviour-preserving). 23 read sites migrated; IntelligenceWorkspace interface migrated to typed top-level (company_profile_id / guide_id / relevance_thresholddomain_metadata reduced to loose Json | null); 5 API routes (app/api/intelligence/*) project typed top-level via extractContextFromDomainMetadata; page + workspace-settings.tsx UI + lib/intelligence/pipeline.ts loadWorkspaceContext consume helper; Zod schema comment updated; 6 test fixtures aligned (4 modified, 2 unchanged DB-row mocks); scripts/batch-rescore-articles.ts:157-158 deferred with TODO(T2-followup) per spec. CI green; verifier sub-agent PASS; UI smoke validated end-to-end against staging. Per S244 Wave 0.5 helper-first hybrid ratification.

    1. Draft migration SQL — DDL for application_types + seeds; FK swap on workspaces; kb_section retire (no data rows); procurement rename per 04-workspace-types.md §7.2. DONE-S246 (commit 38242fef).
    2. Draft form templates rename (templatesform_templates, template_fieldsform_template_fields, template_requirementsform_template_requirements). DONE-S246 (commit 38242fef).
    3. Draft digestschange_reports rename (data lands here; code rename is T5). DONE-S246 (commit 38242fef).
    4. Draft provenance enum cascade + entity_aliases.categoryprovenance. DONE-S246 (commit 38242fef).
    5. Draft source_documents.workspace_id NULLABLE. DONE-S246 (commit 38242fef — no-op DROP NOT NULL on prod since column was already nullable from initial schema).
    6. Draft q_a_pairs schema shape (table created here; full schema in T6 follow-up). NOTE: no data migration from existing 395 content_items.content_type='q_a_pair' rows — superseded by T7 cocoindex first-ingest per S243 ratification. DONE-S246 (commit 38242fef).
    7. Draft 5 reserved satellite seats (PK + FK + RLS only per RWS spec). DONE-S246 (commit 38242fef).
    8. Draft intelligence_workspaces Shape B promotion: add THREE typed columns per S243 audit + S244 Wave 0.5 amendment: (1) company_profile_id uuid NULL REFERENCES company_profiles(id) ON DELETE SET NULL (3/4 prod intel workspaces carry this in workspaces.domain_metadata JSONB); (2) guide_id uuid NULL REFERENCES guides(id) ON DELETE SET NULL (2/4 prod); (3) relevance_threshold real NULL CHECK (relevance_threshold IS NULL OR (relevance_threshold >= 0.1 AND relevance_threshold <= 1.0)) — admin-only SI-L5 pipeline setting (0/4 prod rows but live write path + UI per S244 Wave 0.5 audit). Backfill all 3 from JSONB during migration; then strip all 3 keys from workspaces.domain_metadata for application_type='intelligence' rows (post-migration JSONB = empty {}). Mirrors procurement Shape B pattern per 07-collapse-list.md §3.4. See docs/specs/intelligence-workspaces/TECH.md for canonical DDL. DONE-S246 (commit 38242fef).
    9. Draft form_type 3-tier split per S243 Item 19 ratification: (a) form_types CV trimmed to true form types (bid, rfp, pqq, itt, tender, checklist, questionnaire, sales_proposal_template); (b) NEW procurement_vehicles CV (framework, dps, dynamic_procurement); (c) NEW procurement_vehicle_instances table or CV (g_cloud + dos — G-Cloud + DOS are instances of framework). Procurement satellite gets FK to procurement_vehicle. Migrate live template_requirements.template_type 10-value CHECK to new structure (66 sqpqq + 30 rfprfp). See ontology updates: docs/ontology/26-form-type.md trimmed + NEW 30-procurement-vehicle.md + NEW 31-procurement-vehicle-instance.md. DONE-S246 (commit 38242fef).
    10. Apply migration to staging; verify with mcp__supabase__execute_sql queries. DONE-S246 (NOTICEs verified clean on staging: env-agnostic invariants 0/0/0/0 + 96/96 crosswalk + entity_aliases 24/24 + 6 application_types + 6 reserved seats + 8 form_types + 3 procurement_vehicles).
    11. Apply migration to production. DONE-S247 (commit 2f98c8cfsync_bid_status trigger drop pulled forward from T4 to 1.5b after first prod-apply failed with record "new" has no field "type" SQLSTATE 42703; staging-apply S246 had bypassed because greenfield 0 intel rows w/ JSONB keys; prod has 3 such rows. Audit confirmed no production path writes workspaces.status column for bid workspaces — trigger was dead-code w.r.t. live writers. Re-applied clean: env-agnostic invariants 4/3/2/0 + 96/96 + 24/24 + 6/6/8/3; staging trigger drop applied manually via MCP execute_sql for state parity; types regen’d from prod — schema parity confirmed with staging-generated types byte-identical).
  • Dependencies: T3 (RLS-pattern migration applied first so auto-trigger + grants helper exist).

  • Spec requirement: None new — combined-PR scope is RATIFIED-S235 per 0.9-decision-graph.md §11.3; per-seat schema per docs/specs/reserved-workspace-seats/. Procurement-workspaces 6-column scope is per OQ-Q38-E ratification in 04-workspace-types.md §4.2 — the procurement feature spec (NEW required, see §5) carries the per-column SQL for T4 stage 2.

  • Effort estimate: 3 task units (the 10+5 items together drive this above the 1-3 unit ceiling for a single sub-agent — best done as foreground main + verifier pattern).

  • Risk: Long-running migration risk — DDL on workspaces + entity_aliases + 3 form_templates tables in one transaction may hit lock contention. Mitigation: stage into ordered DDL blocks within one transaction; verify against staging first per CLAUDE.md “Supabase & Schema” gotcha. The application_type_id backfill from existing workspaces.type values must verify cleanly (4 intelligence prod rows per 04-workspace-types.md §2.2). Per CLAUDE.md gotcha — mcp__supabase__apply_migration auto-generates server-side timestamps that diverge from local file naming; rename file to match post-apply.

    Helper-swap risk (Wave 0.5 hybrid): the lib/intelligence/workspace-context.ts helper swap from JSONB read → typed-column JOIN read MUST land in the same PR as the T2 SQL drafting (WP2b) to avoid a window where the helper reads JSONB after the migration has stripped JSONB. WP2a (helper-first PR) keeps CI green because the helper still reads JSONB and behaviour is unchanged. Verify via post-migration bun run test full regression + manual smoke of intel feed UI before merge.

§4.3 T3 — RLS-pattern combined migration apply + observability validation

Section titled “§4.3 T3 — RLS-pattern combined migration apply + observability validation”
  • Scope (in): Apply supabase/migrations/20260514150238_enable_rls_auto_event_trigger_and_grants_pattern.sql (currently APPLY-GATED-ON-LIAM-REVIEW per RLS-PATTERN T-3) to staging then production. Validate per RLS-PATTERN P-1..P-5 invariants. Confirm P-5 observability via RAISE LOG shipping per S240 ratification (option (c)).
  • Scope (out): P-5 observability v1.1 upgrades (audit_log insertion or fan-out helper) — DEFERRED-v1.1.
  • Acceptance criteria:
    • Migration applies cleanly to staging; pg_event_trigger shows ensure_rls.
    • Test table CREATE TABLE public.test_rls_autoenable (id int) immediately has pg_class.relrowsecurity = true (verify per RLS-PATTERN T-1 Validation).
    • grant_standard_public_table_access(regclass) helper callable from staging psql.
    • SCHEMA-QUICK-REFERENCE.md §32 updated per T-3 post-apply checklist.
    • [skip-doc-freshness-guard] marker dropped per T-3 post-apply checklist.
    • Negative-case validation: CREATE table WITHOUT calling grants helper; PostgREST returns 42501 permission denied (per implementation-readiness audit P4 fix).
  • Subtasks:
    1. Liam ratification pass on migration draft (gate per RLS-PATTERN T-1).
    2. Apply to staging (supabase db push with dangerouslyDisableSandbox: true per CLAUDE.md Supabase gotcha).
    3. Run RLS-PATTERN T-1 + T-2 + T-3 validation tests.
    4. Apply negative-case test for P-3 (fail-loud Data API on missing grants).
    5. Update SCHEMA-QUICK-REFERENCE.md §32 + drop skip-doc-freshness marker.
    6. Apply to production (separate supabase db push --linked rovrymhhffssilaftdwd).
  • Dependencies: None (RLS-PATTERN spec pair is ratified S239 per docs/specs/rls-pattern/PRODUCT.md).
  • Spec requirement: None new — docs/specs/rls-pattern/{PRODUCT,TECH}.md is the authoritative spec.
  • Effort estimate: 1.5 task units.
  • Risk: Pre-existing public-schema tables created BEFORE this trigger applies do NOT retroactively get RLS — gap C2 per implementation-readiness audit P9. Audit existing tables before apply: SELECT relname FROM pg_class WHERE relkind='r' AND relnamespace='public'::regnamespace AND relrowsecurity=false. Decide per-table: enable or document as deliberately unprotected.

§4.4 T4 — Procurement umbrella rename (code + state machine)

Section titled “§4.4 T4 — Procurement umbrella rename (code + state machine)”
  • Scope (in): Code-side execution of P-42 procurement rename — lib/bid/lib/procurement/; BID_STATESPROCUREMENT_WORKFLOW_STATES; components/bid/components/procurement/; MCP tool name updates per 06-mcp-tooling.md §6.3 (list_active_bidslist_active_procurement etc.); 44-file sweep for project_idworkspace_id per Q5.5. Procurement workspaces 6-column population (buyer / deadline / submission_date / outcome / outcome_recorded_at / outcome_recorded_by) per OQ-Q38-E.
  • Scope (out): Net-new procurement features; non-procurement application_type wiring.
  • Acceptance criteria:
    • grep -rn "BID_STATES\|bid_workspaces\|lib/bid" lib/ scripts/ app/ components/ returns zero hits.
    • grep -rn "project_id" lib/ scripts/ app/ components/ returns zero hits.
    • State machine moved + tested (__tests__/lib/procurement/procurement-workflow.test.ts passes).
    • MCP tool rename lands [LOCKSTEP-WITH-MIGRATION] with T2.
    • CI test added preventing bid regressions in code (per TECH.md P-40 validation).
    • bun run knip shows no orphaned lib/bid/* files.
  • Subtasks:
    1. Pre-rename impact: gitnexus_impact({target: "BID_STATES", direction: "upstream"}) + gitnexus_impact({target: "bid_workspaces", direction: "upstream"}) to enumerate callers + blast radius before edit. Then gitnexus_rename per CLAUDE.md .gitnexus/CLAUDE.md discipline.
    2. Post-rename verify: ast-dataflow-rename-sweep skill (.claude/skills/ast-dataflow/ast-dataflow-rename-sweep/SKILL.md) — runs string-literal sites + import-path sweep + new-symbol references. Plus ts-morph + ast-grep sweep over 44 code files for project_idworkspace_id.
    3. Move lib/bid/lib/procurement/ (preserve git history via git mv).
    4. Move lib/bid/bid-state-machine.tslib/procurement/procurement-workflow.ts.
    5. Rename BID_STATESPROCUREMENT_WORKFLOW_STATES in types/bid.ts (move to types/procurement.ts).
    6. Move components/bid/components/procurement/.
    7. Update MCP tool names per 06-mcp-tooling.md §6.3.
    8. Procurement-workspaces 6-column population per procurement feature spec (T4.7 — NEW spec).
    9. Post-edit verify: gitnexus_detect_changes() to confirm scope; bun run test full regression; fix breakages.
    10. Run bun run knip; clean unused.
  • Dependencies: T2 (database rename) — [LOCKSTEP-WITH-MIGRATION]. T1 (procurement feature spec) for the per-column SQL on the procurement satellite.
  • Spec requirement: NEW spec requireddocs/specs/procurement-workspaces/{PRODUCT,TECH}.md per docs/specs/reserved-workspace-seats/PRODUCT.md line 93 reference to the procurement feature spec. The 6-column scope (per OQ-Q38-E) lives in this feature spec.
  • Effort estimate: 2 task units (sweep + tests + verification).
  • Risk: 44-file rename leaks into test files — sweep must cover __tests__/**. State machine ratification cascade — BID_STATES 10 values preserved verbatim per Q-OQR1-02 (procurement state set unchanged).

§4.5 T5 — digestschange_reports code rename

Section titled “§4.5 T5 — digests → change_reports code rename”

SHIPPED: S248 T5 (lib/digest/* → lib/change-reports/*, lib/ai/digest.ts → lib/ai/change-reports.ts, queryKeys, hook internals, scripts/export-user-data DB ref); S251 W1B closed the URL/column/enum residual (URL paths app/api/digest/* → app/api/change-reports/*, page app/digest/* → app/change-reports/*, type file types/digest.ts → types/change-reports.ts, component dir, hook file, e2e spec, ~14 test files, ~40 symbol renames, 49 URL literals, DB column digest_type → frequency, notifications enum digest_ready → change_report_ready + entity_type 'digest' → 'change_report', ThemeCluster + theme_clusters elimination as IMS-fork legacy, plugin marketplace /kb:digest → /kb:change-report). CLAUDE.md “Change Reports not Digest” gotcha + __tests__/validation/no-digest-import-regression.test.ts CI guard DELETED per Liam ratification (single-dev repo). Scope-discovery + apply log: docs/research/s251-w1b-digest-to-change-reports-scope-discovery.md.

  • Scope (in): Code-side execution of P-41 — lib/digest/lib/change-reports/; lib/ai/digest.tslib/ai/change-reports.ts; lib/query/query-keys.ts + lib/query/fetchers.ts updates; cron entry rename (digest-generatechange-reports-generate); CLAUDE.md gotcha update.
  • Scope (out): UI label change (UI already uses “Change Reports” per CLAUDE.md gotcha — no UI work needed).
  • Acceptance criteria:
    • grep -rn "digest" lib/ scripts/ app/ components/ returns only intentional historical refs (e.g. archived migration notes).
    • CI guard added to prevent digest regressions in new code (per TECH.md P-41 validation).
    • Cron entry renamed in vercel.json or equivalent scheduler config.
    • CLAUDE.md “‘Change Reports’ not ‘Digest’” gotcha updated to reflect the rename completion.
    • bun run test full regression passes.
  • Subtasks:
    1. Pre-rename impact: gitnexus_impact({target: "digest", direction: "upstream"}) (or lib/digest/index); confirm blast radius. Use gitnexus_rename for symbol-level renames per CLAUDE.md .gitnexus/CLAUDE.md.
    2. ts-morph sweep + ast-grep over digestchange_reports in code (especially string literals + import paths via ast-dataflow-rename-sweep skill post-symbol rename).
    3. git mv lib/digest/lib/change-reports/; lib/ai/digest.tslib/ai/change-reports.ts.
    4. Update lib/query/query-keys.ts + lib/query/fetchers.ts.
    5. Update CLAUDE.md gotcha.
    6. Cron entry update.
    7. Post-edit verify: gitnexus_detect_changes(); bun run test full regression.
  • Dependencies: T2 (DB rename) — [LOCKSTEP-WITH-MIGRATION].
  • Spec requirement: None new — RATIFIED-S235 per 04-workspace-types.md §8 item 7 + 08-new-features.md §4.
  • Effort estimate: 1 task unit.
  • Risk: Low — mechanical sweep. UI label parity already in place.

§4.6 T6 — Q&A two-tier model migration + RPCs

Section titled “§4.6 T6 — Q&A two-tier model migration + RPCs”
  • Scope (in): Create q_a_pairs table (corpus-level shape per P-20 + 05-qa-flow.md §2); create q_a_extractions derived cache (per 05-qa-flow.md §3); create q_a_pair_history trigger-driven version table (per 05-qa-flow.md §3.3); RPC signatures for q_a_search (two-step list/preview + get/verbatim per S16 §6.1).
  • Scope (out): Data migration of existing content_items q_a_pair rows (T7); MCP tool wiring (separate post-T6 task — lib/mcp/tools/qa.ts); sidecar materialisation (DEFERRED-v1.1).
  • Acceptance criteria:
    • q_a_pairs table with full column set per 05-qa-flow.md §2.1 (question_text + alternate_question_phrasings + answer_standard + answer_advanced + scope_tag + anti_scope_tag + source_workspace_id NULLABLE + origin_kind + question_embedding vector(1024) + publication_status + superseded_by + valid_from + valid_to).
    • q_a_extractions table per 05-qa-flow.md §3 (extractor_kind enum + promoted_to_pair_id + invalidated_at + cocoindex UPSERT target compatibility per postgres.mount_table_target(managed_by='user')).
    • q_a_pair_history trigger writes version transitions on every q_a_pairs UPDATE per §3.3.
    • GIN indexes idx_q_a_pairs_scope_tag + idx_q_a_pairs_anti_scope_tag per §2.2.
    • No idx_q_a_pairs_workspace (RATIFIED-DO-NOT-BUILD per §11 anti-patterns).
    • q_a_search RPC signature shipped with separate embedding_score + fulltext_score returns per N9 + §7.3.
    • All Supabase grants per RLS-PATTERN P-2.
  • Subtasks:
    1. Migration draft for q_a_pairs + q_a_extractions + q_a_pair_history. DONE-S249 (commit 2f3428c7 — WP1 migration 20260520225456_t6_q_a_pairs_full_schema.sql, 289 lines).
    2. Trigger function for q_a_pair_history auto-version on UPDATE. DONE-S249 (commit 2f3428c7q_a_pairs_history_trigger() SECURITY DEFINER + REVOKE EXECUTE FROM anon; trigger q_a_pairs_history_on_update AFTER UPDATE FOR EACH ROW).
    3. GIN indexes on scope_tag fields. DONE-S249 (commit 2f3428c7idx_q_a_pairs_scope_tag + idx_q_a_pairs_anti_scope_tag; idx_q_a_pairs_workspace RATIFIED-DO-NOT-BUILD per §11 anti-patterns confirmed excluded).
    4. q_a_search RPC implementation (Postgres function with hybrid embedding + fulltext rank). DONE-S249 (commit 6614d8c3 — WP2 migration 20260520231524_t6_q_a_search_rpcs.sql; q_a_search + q_a_get_verbatim both SECURITY DEFINER, REVOKE anon, GRANT authenticated/service_role; separate embedding_score + fulltext_score per N9 RESOLVED-S236).
    5. Apply migration to staging + prod. DONE-S249 staging (supabase db push S249; both WP1 + WP2 migrations applied clean to staging branch turayklvaunphgbgscat; smoke gates green per commit messages f7ce9754 + a20786f5). DONE-S250 prod (rovrymhhffssilaftdwd) — both WP1 + WP2 migrations recorded on prod at S250 session start; channel undetermined (likely MCP apply_migration during S249 — supabase_migrations.schema_migrations records byte-identical to staging including comment headers). S250 W1b follow-up 20260521095209_t6_followup_revoke_public_execute_anon_inherit_fix.sql applied to BOTH staging + prod via CLI db push — addresses anon EXECUTE leak via PUBLIC inheritance discovered during S250 W1 acceptance audit. Prod smoke green (insert → UPDATE → history trigger → q_a_get_verbatim → CASCADE cleanup). database.types.ts regen byte-identical post-W1b.
    6. Regenerate database.types.ts. DONE-S249 (commits f7ce9754 + a20786f5 — types regen post-WP1 + post-WP2 staging apply; q_a_extractions + q_a_pair_history new tables surfaced; q_a_search + q_a_get_verbatim Functions types surfaced; schema parity vs staging-generated types confirmed).
    7. Integration tests for two-step retrieval pattern. DONE-S249 (commit 275bc9e5 — WP3 __tests__/integration/q-a-pairs/two-step-retrieval.integration.test.ts, 4 tests covering q_a_search separate-score columns + q_a_get_verbatim embedding-exclusion + history-trigger version transitions + CASCADE; all pass against staging w/ KH_RUN_INTEGRATION=1).
  • Dependencies: T2 (the combined-PR sets the q_a_pairs shape per 04-workspace-types.md §8 item 10; this task adds the full schema + extractions + history).
  • Spec requirement: None new — schema design ratified per 0.9-spike-S16-qa-schema-design.md §6 + 05-qa-flow.md §2-§3.
  • Effort estimate: 2.5 task units.
  • Risk: q_a_pair_history trigger interaction with cocoindex UPSERT to q_a_extractions — verify trigger fires correctly when q_a_pairs is updated via promotion flow vs direct user edit. Layered fn-shape requirement (S9 spike per 05-qa-flow.md §5.2) — inner extraction functions must consume content_text: str, NOT FileLike. Embedding cost (1024-dim vector per row × 395 prod q_a_pair rows + new extractions) — verify cost projection (also gates on T13 prompt-cache verification).

§4.7 T7 — Phew full-corpus reingest via cocoindex (all content types)

Section titled “§4.7 T7 — Phew full-corpus reingest via cocoindex (all content types)”

RATIFIED-S243: Prior framing as data migration from content_items.content_type='q_a_pair' superseded. Liam clarified the original Phew Q&A source files (markdown) exist and should be ingested via cocoindex as first-time-for-first-client. This validates the canonical pipeline end-to-end against the real client corpus. No SQL data migration of the 395 legacy rows.

S262 CLARIFICATION: Scope updated to all Phew content types (not Q&A only) — see Task ID-45 in task-list.json, which supersedes the Q&A-only framing per Liam’s S262 directive. Full-corpus reingest is the intent: Q&A pairs, capability/methodology, sector intelligence, procurement content (markdown/PDF/DOCX/URL). The detailed decomposition and updated acceptance criteria are tracked in ID-45.

  • Scope (in): Stage Phew’s existing source files (all content types) into the cocoindex-tracked location (localfs source binding per 02-data-flow.md §2.1). Cocoindex’s normal flow (T8) ingests them → emits q_a_extractions rows via ExtractByLlm → manual promotion to q_a_pairs via UC5-adjacent review queue (or one-shot promote-all script for the legacy import). The 395 existing content_items.content_type='q_a_pair' rows soft-archive (not deleted) for audit trail; production reads exclusively from new q_a_pairs once promoted.
  • Scope (out): Net-new cocoindex flow scaffolding (T8); real-time future Q&A ingestion (cocoindex handles that natively once the source files land in tracked location).
  • Acceptance criteria:
    • Phew’s Q&A markdown source files staged into cocoindex-tracked location (path TBC at task start — likely docs/client-documentation-base/qa-library/ or equivalent per cocoindex source-binding config).
    • Cocoindex flow observes the files, emits q_a_extractions rows for each Q&A pair detected (using extractor_kind='markdown_heading_v1' or yaml_frontmatter_v1 per 05-qa-flow.md §3.2 depending on shape).
    • Extraction count matches expected Phew Q&A pair count (Liam confirms expected count at task start; cross-reference 395 baseline noting that count was a S234 point-in-time figure).
    • Promote-all script (scripts/qa-promote-legacy/) walks q_a_extractions where extractor_kind IN ('markdown_heading_v1', 'yaml_frontmatter_v1') AND promoted_to_pair_id IS NULL AND source = Phew first-ingest batch, emits q_a_pairs rows with origin_kind='imported_legacy' and links via promoted_to_pair_id.
    • Soft-archive original content_items rows: content_type = 'q_a_pair_archived' OR archived_at IS NOT NULL per existing P-70 target shape (preserved for 1-year audit per RATIFIED-S241 retention window).
    • End-to-end validation: a Phew Q&A pair retrievable from q_a_pairs via q_a_search RPC (T10) matches the content of the corresponding markdown source file + the legacy content_items row.
    • Re-ingestion idempotent: re-running cocoindex over the same files does not duplicate q_a_extractions rows (memo-hit per @coco.fn(memo=True) + content-hash idempotency).
  • Subtasks:
    1. Liam confirms expected Q&A pair count + source-file location.
    2. Stage Phew Q&A markdown files into cocoindex-tracked path (manual or scripted file copy from existing storage).
    3. Trigger cocoindex flow (T8 dependency) — observe ingestion + q_a_extractions emit.
    4. Spot-check 5-10 random extraction rows against source markdown for shape correctness.
    5. Promote-all script (scripts/qa-promote-legacy/) — walks new extractions + emits q_a_pairs with origin_kind='imported_legacy'.
    6. Soft-archive original content_items.content_type='q_a_pair' rows (script).
    7. End-to-end validation: q_a_search RPC returns Phew Q&A pairs; UI surfaces them correctly.
    8. Audit-trail documentation update (CLAUDE.md q_a_pair_archived framing if needed).
  • Dependencies: T8 (cocoindex flow scaffolding — must exist to ingest) + T6 (q_a_pairs + q_a_extractions schemas) + T1 (Q-EX2 contract spec to confirm extractor_kind enum compat). No retention-window or migration-script gates — RATIFIED-S243 redirects this from “data migration” to “cocoindex re-ingest of source files.”
  • Spec requirement: None new. Cocoindex extraction contract (T1.1+T1.2) provides shape guarantees.
  • Effort estimate: 2 task units.
  • Risk: Source-file shape variance — Phew’s historical Q&A may use 5 catalogued shapes per S16 §4. Each shape needs an extractor_kind per 05-qa-flow.md §3.2. If a shape lacks an extractor, T7 surfaces the gap and a corresponding extractor_kind row + extraction function is added under T8 scope. content_items.content_text_hash is GENERATED ALWAYS per CLAUDE.md gotcha — omit from any payload. Soft-archive path needs the 1-year retention window per RATIFIED-S241 for audit-trail. Per 05-qa-flow.md §1.2 + 04-workspace-types.md §5: q_a_pairs.source_workspace_id will be NULL for origin_kind='imported_legacy' rows (corpus-level model). Re-ingestion may surface previously-unsurfaced data-quality issues in source files — expected, treat as a feature of the canonical-pipeline validation.
  • Downstream backlog activation: Once Phew Q&A corpus is seeded via T7, backlog ID-25 (T6 WP3 integration test hardening — docs/reference/product-backlog.json) becomes actionable: rank-ordering assertions in __tests__/integration/q-a-pairs/two-step-retrieval.integration.test.ts can be tightened against real-corpus shape rather than synthetic fixtures. Also backlog ID-26 (ts_rank normalisation flag — corpus measurement) becomes actionable: A/B-test option 0/1/2 against the seeded corpus for ranking-quality discrimination.

§4.8 T8 — Cocoindex flow scaffolding + Cloud Run sidecar deploy

Section titled “§4.8 T8 — Cocoindex flow scaffolding + Cloud Run sidecar deploy”
  • Scope (in): Cocoindex pipeline implementation per 02-data-flow.md §3 (6-stage topology: source walk → binary conversion → LLM extraction → embedding → entity resolution → Postgres UPSERT). Cloud Run sidecar deploy per §4 (Docling 1.8 GB + pullmd + cocoindex engine). localfs.walk_dir(live=True) source binding per §2.1. @coco.fn(memo=True) + layered fn-shape per §3.2 + COCO.9. pipeline_runs rollup via recordPipelineRun() per 02-data-flow.md §7.2. op_id hybrid pattern per §5 + N7.
  • Scope (out): UC3 sweep tool (T9); UC8 dedup substrate (T12 + Spike #10).
  • Acceptance criteria:
    • Cocoindex flow scaffolding lands at scripts/cocoindex_pipeline/flow.py per 02-data-flow.md §3.
    • Cloud Run sidecar deploys via .github/workflows/cloud-run-deploy.yml (existing infra per CLAUDE.md).
    • LocalFS source binding observes file change → pipeline run → content_items row written within polling cadence (integration test).
    • Layered fn-shape: inner-tier functions consume content_text: str per COCO.10 (verify by source inspection).
    • Per-flow op_id propagated into content_items.op_id column (added in T2 if not present; canonical-pipeline TECH §5.3 says op_id column is part of Q-OQR1-16 combined-PR scope per 0.9-decision-graph.md §11.4.1 — verify present after T2).
    • audit_log row written for cocoindex-driven inserts/updates per trigger pattern.
    • MCP eval Layer 4 — create_content_item over MCP results in queryable content within same call.
    • Spike #1 (cocoindex schema-coupling) resolves cleanly OR per 02-data-flow.md §3.1 (Scenario A confirmed).
  • Subtasks:
    1. Spike #1 completion — cocoindex schema-coupling Scenario A confirmation per 0.9-spike-plan.md §1.
    2. Cloud Run sidecar config — Docling + pullmd + cocoindex engine.
    3. scripts/cocoindex_pipeline/flow.py scaffolding.
    4. Outer-tier @coco.fn source-binding adapter (process_sidecar_file(file: FileLike, …)).
    5. Inner-tier extraction functions (extract_q_a(content_text: str, …), extract_entities(content_text: str, …), etc.).
    6. ExtractByLlm integration per Q-EX2 contract (T1 dependency).
    7. LiteLLMEmbedder integration for vector(1024) embeddings.
    8. postgres.mount_table_target(managed_by='user') for content_items + q_a_extractions + source_documents.
    9. op_id propagation to target columns.
    10. Integration test — write file to test folder, poll fires, content_item row appears.
    11. CocoInsight on-prem deployment posture (per 02-data-flow.md §5.4) — note as DEFERRED unless KH self-hosts.
  • Dependencies: T1 (Q-EX2 contract + ledger API + Q1.3-Q1.N invariants) + T2 (schema in place) + T6 (q_a_extractions target table) + T3 (RLS pattern for new tables touched by ingestion). Spike #1 + Spike #2 PENDING per canonical-pipeline TECH §9.
  • Spec requirement: None new beyond T1’s three specs.
  • Effort estimate: 3 task units.
  • Risk: Cloud Run sidecar deployment cost projection (1.8 GB Docling + ~3.7 GB pullmd Playwright) — verify within budget. cocoindex 1.0.3 requires dangerouslyDisableSandbox: true per CLAUDE.md gotcha. localfs.walk_dir defaults recursive=False — explicit recursive=True needed per gotcha. Memoisation per-component-path scope (NOT global content-hash) per 05-qa-flow.md §5.3 — UC8 cross-record dedup must go through entity_resolution / mempalace, NOT cocoindex memo.

§4.9 T9 — Per-UC write-back implementation

Section titled “§4.9 T9 — Per-UC write-back implementation”
  • Scope (in): UC1 (typo fix Candidate A — Tiptap + Yjs + filesystem write to source_documents.original_path); UC3 (sweeping rename two-variant — find-replace + smart-agent); UC4 (paragraph rewrite Candidate A — Tiptap + Yjs + edit-intent gate); UC5 (bid response → Q&A promotion — KH-DB-only per 05-qa-flow.md §9); UC6 (Q&A pair revision — user-direct + AI-suggest Candidate B per 05-qa-flow.md §8); UC8 (cross-workspace dedup Candidate A — KH server orchestration + Claude API similarity reasoning); edit_intent CV trigger policy per 02-data-flow.md §8. Plus Diff-UI sidecar re-point per RATIFIED-S243 (Item 5) — Diff-UI retained for v1 (previously DEFERRED-v1.1), re-pointed from source_document_diffs substrate to markdown sidecar revision comparison. Plus content_items-without-source_documents audit + per-case ratification per RATIFIED-S243 (Item 10) — sweep prod for content_items with source_document_id IS NULL; classify each path (MCP create_content_item, legacy import, etc.); ratify edit-back behaviour per case (auto-create source_document with connector='mcp' storage path, OR fall back to KH-DB-only edit).
  • Scope (out): UC7 + UC10 (external folder change detected — handled natively by cocoindex source binding in T8); UC9 (scope-tag taxonomy update — owned by separate OPS-X-SCOPE-TAGS work-package per 08-new-features.md §5); UC2 (collapsed to UC1 per S228); Candidate C upgrade for UC8 (DEFERRED-v1.1).
  • Acceptance criteria:
    • UC1: edit content in UI → file delta in test folder + KH stays in sync (per TECH.md P-11 Validation).
    • UC3: sweep variant A — KH server iterates affected files; per-record provenance with shared sweep ID; rollback per §6.0.6.
    • UC3: smart-agent variant B — Anthropic API with text-editor-tool; user reviews + approves per-match before commit.
    • UC4: edit-intent gate at save time per 02-data-flow.md §8; closed per-UC vocabulary + free-text “other-with-note” escape.
    • UC5: bid response → q_a_pair draft with lineage to source bid response + bid question; review queue transition.
    • UC6 user-direct: KH-DB-only via Tiptap + Yjs; q_a_pair_history records version transition.
    • UC6 AI-suggest: source-doc change triggers AI-suggest; Anthropic API proposes; user reviews + commits.
    • UC8 v1: Candidate A + LLM-reasoning; rollback per §6.0.6.
    • edit_intent CV: cosmetic → skip cocoindex re-run; data / structural → trigger re-run (per 02-data-flow.md §8.2 mapping).
  • Subtasks:
    1. UC1 — Tiptap + Yjs editor wire to filesystem write (or sidecar .md for binary).
    2. UC3 Candidate A — sweep tool implementation.
    3. UC3 Candidate B — smart-agent with text-editor-tool.
    4. UC4 — edit-intent capture at save time + paragraph rewrite with citation re-anchor.
    5. UC5 — bid response → Q&A promotion (KH-DB-only).
    6. UC6 user-direct — Q&A pair revision via Tiptap.
    7. UC6 AI-suggest — Anthropic API with cocoindex source-binding trigger.
    8. UC8 v1 Candidate A — KH server orchestration + Claude similarity reasoning.
    9. edit_intent CV — controlled vocabulary lookup + cocoindex re-run trigger plumbing.
    10. Concurrent-edit handling per 02-data-flow.md §8.3 — codify v1 safe default (any concurrent edit containing data or structural intent treated as data intent).
  • Dependencies: T8 (cocoindex flow scaffolding) for UC1/UC4/UC6 sidecar write-back observe-on-next-scan. T6 (q_a_pairs schema) for UC5/UC6. T2 (procurement rename + form_templates rename) for UC5 (bid response context).
  • Spec requirement: NEW spec MUST — docs/specs/id-59-concurrent-edit-intent-arbitration/TECH.md per RATIFIED-S243 (Item 6 — lifted from CONDITIONAL to MUST). UC1/UC4/UC6 all write via Tiptap+Yjs with edit_intent gating cocoindex re-run; cross-user concurrent edits require explicit arbitration rules. Spec drafts in Wave 0 (T1-adjacent). Per 02-data-flow.md §8.3 v1 safe default: any concurrent edit including data or structural intent → treated as data. Spec codifies this + the CRDT-merge write-site enforcement contract.
  • Effort estimate: 3 task units (the 7 UCs each touch separate flow surfaces).
  • Risk: S9 spike RESOLVED-PARTIAL (95% confidence per COCO.10) — layered fn-shape required for sidecar idempotency. S10 spike PENDING for UC8 cross-record dedup substrate (cocoindex post-target-write @coco.fn vs mempalace KG vs hybrid) — UC8 v1 implementation cannot fully complete without S10 resolution. Spike #3 (write-back adapter contract) PENDING.

§4.10 T10 — question_matches table + retrieval substrate

Section titled “§4.10 T10 — question_matches table + retrieval substrate”
  • Scope (in): Create question_matches table per 05-qa-flow.md §7 — question_kind discriminator aligned with form_types vocabulary; separate embedding_score + fulltext_score NUMERIC(5,4) columns per N9 RESOLVED-S236. Two-step retrieval pattern per S16 §6.1 (list/preview → get/verbatim). MCP q_a_search tool wiring.
  • Scope (out): Per-method score weighting / blend function / UI presentation — DEFERRED to procurement feature spec per 05-qa-flow.md §7.3 gap flag (operational verification deferred).
  • Acceptance criteria:
    • question_matches table created (never built under old bid_question_matches name per 05-qa-flow.md §7.1 + drift item 3.2-a P1).
    • question_kind column populated per form_types vocabulary ('bid' / 'rfp' / 'pqq' / 'itt' / 'framework' / 'dps' / 'gcloud' for procurement workspaces).
    • Separate embedding_score + fulltext_score columns (NOT a blended match_score) per N9.
    • Composer (procurement) surface filters: q_a_pairs.scope_tag && workspaces.scope_tag AND NOT q_a_pairs.anti_scope_tag && workspaces.scope_tag AND effective_to IS NULL OR effective_to > now().
    • MCP q_a_search tool returns separate score columns per 06-mcp-tooling.md §6.1.
    • No idx_q_a_pairs_workspace (RATIFIED-DO-NOT-BUILD per §11 anti-patterns + drift item 3.2-a).
  • Subtasks:
    1. Migration draft for question_matches.
    2. Postgres function for retrieval with scope_tag overlap + separate scoring.
    3. MCP q_a_search tool implementation.
    4. Integration test: scope tag overlap returns workspace-relevant pairs.
    5. Procurement bid composer wiring (per 04-workspace-types.md §4.2 procurement_workspaces post-rename).
  • Dependencies: T2 (procurement rename — composer uses post-rename names) + T6 (q_a_pairs in place).
  • Spec requirement: None new (procurement feature spec already covers composer per OQ-Q38-E).
  • Effort estimate: 1.5 task units.
  • Risk: bid_question_matches was the planned name pre-Q-OQR1-02 — verify table is BUILT under question_matches from day one per drift item 3.2-a P1.

§4.11 T11 — Citations polymorphic enum + version-on-cite

Section titled “§4.11 T11 — Citations polymorphic enum + version-on-cite”
  • Scope (in): P-22 — citations table with citing_entity polymorphic enum per 05-qa-flow.md §6.1 (5 values: bid_response, sales_proposal_response, competitor_research_finding, training_unit, mcp_search_response); citing_entity_id UUID polymorphic FK; cited_q_a_pair_id UUID to q_a_pairs. Version-on-cite per §6.3 — citations bind to q_a_pair_history version snapshot at ship time.
  • Scope (out): Cross-application citation rendering surfaces (handled per-application feature spec).
  • Acceptance criteria:
    • citations.citing_entity enum with 5 ratified values.
    • Polymorphic FK pattern: citing_entity_id indexed per enum value (no single typed FK).
    • Bid response → Q&A pair citation writes the q_a_pair_history version ID at ship time.
    • Updating a published Q&A pair does NOT alter shipped citations (verify via history-table snapshot resolution).
    • Pre-S234 bid_response_id NOT NULL framing fully retired (RATIFIED-RETIRE per §11 anti-patterns).
  • Subtasks:
    1. Migration draft for citations table + enum + indexes.
    2. Version-on-cite logic at bid ship time.
    3. Citation resolution to q_a_pair_history version snapshot.
    4. Integration test for citation immutability under Q&A pair revision.
  • Dependencies: T6 (q_a_pairs + q_a_pair_history in place).
  • Spec requirement: None new — N8 RESOLVED-S234 per 05-qa-flow.md §6 + drift item 1.5-a (already handled by forward-ref to 05-qa-flow.md §6.2).
  • Effort estimate: 1 task unit.
  • Risk: Low — schema design well-ratified.
  • Scope (in): P-30 — Mempalace Shape A (temporal KG: asserted_at, verified_at, stale_at) + Shape B (provenance-tagged: provenance_chain JSONB) adopted. P-31 — workspace-scoped KG queries default; cross-workspace requires --scope=global + admin role. Per Q-OQR1-04 + Q4.5: wing wire-up convention (wing: <workspace_id>) per 06-mcp-tooling.md §5.2.
  • Scope (out): Mempalace wrapped pattern (DEFERRED-POST-LAUNCH per Theme F S240); audit_log integration of mempalace operations (accepted v1 limitation per 06-mcp-tooling.md §4.5).
  • Acceptance criteria:
    • entity_mentions table extended with asserted_at, verified_at, stale_at, provenance_chain JSONB per P-30 target state.
    • Re-extraction of same content chains new mention row back to previous via provenance_chain.
    • MCP eval Layer 4: viewer/editor get scoped result; admin with --scope=global gets cross-workspace.
    • Wing wire-up: every mempalace MCP call operating on workspace data passes wing: <workspace_id> per 06-mcp-tooling.md §4.3 (system-prompt enforcement; accepted v1 limitation).
    • Spike #4 (mempalace integration pattern) PENDING per canonical-pipeline TECH §9 — resolves before this task starts.
  • Subtasks:
    1. Spike #4 — mempalace integration pattern decision per 0.9-spike-plan.md §4.
    2. Schema migration for entity_mentions temporal + provenance columns.
    3. mempalace_kg_* MCP wrappers default-to-workspace-scoped.
    4. System-prompt instruction for wing: <workspace_id> enforcement (per Theme F direct pattern).
    5. Integration test for re-extraction chaining.
  • Dependencies: T2 (KG schema migration) + T8 (cocoindex pipeline emits entity-mention events).
  • Spec requirement: None new beyond the direct pattern ratified S240 per 06-mcp-tooling.md §4.
  • Effort estimate: 2 task units.
  • Risk: mempalace_search wing-filter bug per CLAUDE.md “Memory (Mempalace)” — accepted v1 workaround (search default, filter client-side). Cross-workspace KG queries DEFERRED-v2 per 0.9-canonical-pipeline/PRODUCT.md §11 — confirm scope-flag plumbing matches v1 + v2 trajectory.
  • Downstream backlog activation: UC8 merge-lineage audit cases (per T8 §4.8 scope (out) + Spike #10) require backlog ID-74 (q_a_pair_history snapshot completeness — docs/reference/product-backlog.json) to land first: q_a_pair_history needs superseded_by uuid + source_workspace_id uuid snapshot columns + trigger-fn body update before history rows can support merge-lineage reconstruction. Activate ID-74 when T12 + Spike #10 scope kick-off. (S299: renumbered ID-24 → ID-74 — the q_a_pair_history backlog item is bl-74; current ID-24 is unrelated.)

§4.13 T13 — Pre-launch operational pre-decisions + observability

Section titled “§4.13 T13 — Pre-launch operational pre-decisions + observability”
  • Scope (in): (a) Prompt-cache passthrough verification spike (per implementation-readiness audit P4.2-c) — verify ExtractByLlm calls include cache_control block; assert cache hit in Anthropic API response. (b) Tracked-changes DOCX regression test (per 00-synthesis-v2.md §5.2 row 8 + CLAUDE.md “python-docx and Track Changes” gotcha) — add to Theme B regression suite. (c) Per-tool MCP audit completion (per 06-mcp-tooling.md §6.11 + S241 prompt WP2). (d) bid/procurement MCP tool rename sequencing per 06-mcp-tooling.md §6.3.
  • Scope (out): CocoInsight on-prem deployment (contingent; per 00-synthesis-v2.md §5.2 row 6 — only relevant if KH self-hosts); RLS observability v1.1 upgrade (DEFERRED-v1.1 per S240).
  • Acceptance criteria:
    • Prompt-cache verification spike: write test ExtractByLlm call with cache_control block; confirm cache hit in Anthropic API response. Cost projection updated.
    • Tracked-changes DOCX regression test added to __tests__/scripts/ (uses open_document_safe() per CLAUDE.md).
    • docs/specs/mcp-tooling-audit/{PRODUCT,TECH}.md lands per S241 WP2.
    • docs/client-documentation/Knowledge Hub — Claude Integration Guide.md refreshed to current 58/12/7 inventory.
    • MCP tool rename PR for list_active_bidslist_active_procurement etc. ([LOCKSTEP-WITH-MIGRATION] with T2; gated on Liam decision per S241 prompt pre-req 2).
  • Subtasks:
    1. Prompt-cache spike (1-2h per implementation-readiness audit P4.2-c).
    2. Tracked-changes DOCX regression test authoring.
    3. Per-tool MCP audit (58 tools) per 06-mcp-tooling.md §6.11.
    4. Client integration guide refresh.
    5. MCP tool rename PR.
  • Dependencies: T2 (procurement rename) — sequences MCP tool rename. T8 (cocoindex flow) — provides the call site for prompt-cache verification.
  • Spec requirement: NEW specdocs/specs/mcp-tooling-audit/{PRODUCT,TECH}.md per S241 WP2. Uses /write-product-spec + /write-tech-spec (feature-spec pattern, NOT construction-guide pattern per S241 critical-rule 5).
  • Effort estimate: 1.5 task units.
  • Risk: Per-tool MCP audit is independently 2-3 units (per S241 WP2 effort estimate); this PLAN treats it as parallel-safe operational and breaks it off as a separate work-package once the implementation phases are underway.

§4.14 T14 — Cocoindex absorption cleanup (NEW per RATIFIED-S243 Item 17)

Section titled “§4.14 T14 — Cocoindex absorption cleanup (NEW per RATIFIED-S243 Item 17)”
  • Scope (in): Post-T8-stable retirement of code + dependencies absorbed by the cocoindex flow per 07-collapse-list.md §5. Specifically: delete scripts/kb_pipeline/ (~5,797 LOC), lib/extraction/ (~1,000 LOC), lib/extraction/html.ts, lib/intelligence/content-extractor.ts (Tier 2/2.5/3 extractor), lib/bid-library-ingest/extract-qa-pairs.ts (Pattern A/B parser — post-Phew T7 first-ingest), scripts/dedup.py::dedup_across_files_by_title, lib/dedup-normalise.ts + scripts/dedup_normalise.py, custom batch-reclassify scripts, URL-freshness cron (content_items.freshness_checked_at cron), regenerateChunks() (built-not-wired). Remove npm dependencies: @mozilla/readability, jsdom, unpdf, @mendable/firecrawl-js. Run bun run knip post-deletion; clean any orphaned imports.
  • Scope (out): Anything cocoindex hasn’t observably absorbed (live-path call sites remaining). Items where retirement direction is set but binding deferred to 02-data-flow.md (per 07-collapse-list.md §8) — those bind at the relevant feature task, not here.
  • Acceptance criteria:
    • All files in 07-collapse-list.md §5 (Pipeline ingestion retires + cocoindex absorption) deleted via git rm.
    • package.json dependencies removed: @mozilla/readability, jsdom, unpdf, @mendable/firecrawl-js.
    • bun install clean; bun lint clean; bun run knip no orphaned exports added by this task.
    • bun run test full regression passes (no callers remain for deleted modules).
    • bun run build clean.
    • CLAUDE.md “Gotchas” entries referencing deleted modules removed or updated.
  • Subtasks:
    1. Pre-flight: confirm T8 is observably stable in staging (no rollback within last 7d) and Phew T7 first-ingest complete.
    2. ts-morph sweep over each deleted-file candidate for live call sites; flag any unexpected callers for resolution.
    3. git rm deletion pass per 07-collapse-list.md §5 list.
    4. package.json dependency removal.
    5. bun install + bun lint + bun run knip + bun run test + bun run build.
    6. CLAUDE.md gotcha cleanup.
  • Dependencies: T8 stable (cocoindex flow ingesting in production) + T7 complete (Phew first-ingest validated).
  • Spec requirement: None new. 07-collapse-list.md §5 is the authoritative list.
  • Effort estimate: 1 task unit.
  • Risk: Hidden callers not surfaced by bun run knip (e.g. dynamic imports). Mitigation: ts-morph sweep pre-deletion + full test suite + build. Sub-agent task — worktree-isolated for clean diff.

All NEW spec drafts use the /write-product-spec + /write-tech-spec skill pattern (feature-spec / Summary+Behavior shape) UNLESS marked construction-guide (architecture-substrate pattern with numbered P-N / S-N invariants) per S241 critical-rule 5.

Spec pathTypeSkillDrafting task IDSource ratifications
docs/specs/id-36-cocoindex-extraction-contract/PRODUCT.md + TECH.mdboth/write-product-spec + /write-tech-specT1.1 + T1.2Q-EX2 (S241 Liam ratification per S241 prompt §“Critical rules”); phase-b-prerequisite-2-cocoindex-deep-dive.md §4 Recommendation 1
docs/specs/id-36-cocoindex-ledger-api/TECH.mdTECH only/write-tech-specT1.3DEFERRED-v1.1 per RATIFIED-S243 (Item 11). v1 ships only pipeline_runs rollup; per-stage detail surface (getFlowRunMetrics etc.) deferred. Existing docs/specs/id-36-cocoindex-ledger-api/TECH.md draft marked DEFERRED-v1.1 in its header.
Q1.3-Q1.N content-model invariants — extension or new specdepends on skill judgementconstruction-guide if extending PRODUCT.md; /write-product-spec if separateT1.4Per implementation-readiness audit P6; 00-synthesis-v2.md §3.1-§3.3; COCO.1-COCO.10
docs/specs/procurement-workspaces/PRODUCT.md + TECH.mdboth/write-product-spec + /write-tech-specT4.7OQ-Q38-E ratification (6-column procurement satellite per 04-workspace-types.md §4.2); referenced from docs/specs/reserved-workspace-seats/PRODUCT.md line 93
docs/specs/intelligence-workspaces/PRODUCT.md + TECH.mdboth/write-product-spec + /write-tech-specT2-adjacent (Wave 0)LANDED-S244 (commit 4abf7328) — RATIFIED-S243 + AMENDED-S244-Wave-0.5 (Item 15 + post-ratification audit). S243 audit found 2 JSONB fields (company_profile_id, guide_id); S244 Wave 0.5 audit extended to 3 typed columns by adding relevance_threshold real NULL (admin-only SI-L5 pipeline setting; live write path + UI; 0/4 prod rows). Spec ratifies the typed-column set + retrofit path for the 4 prod intel workspaces. See docs/specs/intelligence-workspaces/TECH.md for canonical 3-column shape.
docs/specs/sales-proposal-workspaces/PRODUCT.md + TECH.mdboth/write-product-spec + /write-tech-specWave 0 (gates Phase 3)LANDED-S244 (commits 3af858b1 + 8463d72f + 7ea4c77d) — RATIFIED-S243 (Item 15) — Phase 3 substrate; draft in Phase 1 so Phase 3 has substrate. Per-app columns landed via ALTER at Phase 3 build time.
docs/specs/product-guide-workspaces/PRODUCT.md + TECH.mdboth/write-product-spec + /write-tech-specWave 0LANDED-S244 (commits e257dbac + 0cec141a) — RATIFIED-S243 (Item 15) — Phase 1 spec; per-app columns landed via ALTER at feature-build time.
docs/specs/id-59-concurrent-edit-intent-arbitration/TECH.md (MUST per RATIFIED-S243)TECH only/write-tech-specWave 0 (T1-adjacent)LANDED-S244 (commit 12a20963) — RATIFIED-S243 (Item 6) — lifted from CONDITIONAL to MUST. 02-data-flow.md §8.3 gap flag; UC1/UC4/UC6 cross-user concurrent edits need arbitration rules. v1 safe default codified at CRDT-merge write site.
docs/specs/mcp-tooling-audit/PRODUCT.md + TECH.mdboth/write-product-spec + /write-tech-specT13.306-mcp-tooling.md §6.11; S241 WP2
docs/specs/qa-promotion-ui/PRODUCT.md (CONDITIONAL — if UC5 build scope warrants pre-build)PRODUCT only/write-product-specNEW UC5 build task (T9-derived)05-qa-flow.md §9.3 gap flag (3 UI-shape sub-decisions: quality checklist, scope-tag picker UX, duplicate-detection threshold UX)
docs/specs/procurement-question-matching/TECH.md (CONDITIONAL — operational verification at procurement build cycle)TECH only/write-tech-specT10 follow-up05-qa-flow.md §7.3 gap flag (per-method scoring tunability)
docs/specs/pipeline-observability/TECH.md (CONDITIONAL — if cocoindex per-stage metrics surface need exceeds pipeline_runs rollup)TECH only/write-tech-specT13-derived (post-launch)Implementation-readiness audit P4.2-d partial-resolve; 00-synthesis-v2.md §5.2 row 5

Specs to definitely land before S242+ implementation: cocoindex-extraction-contract (T1.1+T1.2) + Q1.3-Q1.N (T1.4) + procurement-workspaces + intelligence-workspaces + sales-proposal-workspaces + product-guide-workspaces + concurrent-edit-intent-arbitration. The mcp-tooling-audit can land in parallel with implementation (T13 — pre-launch operational).

Conditional specs: evaluate at the corresponding task start. qa-promotion-ui spec materialises at UC5 build kickoff; procurement-question-matching at procurement-feature build cycle; pipeline-observability if cocoindex per-stage metrics surface need exceeds pipeline_runs rollup.


The 19 drift items from canonical-pipeline-drift-audit-s240.md are mapped to PLAN.md sections or NEW spec files per Liam’s S241 direction. The canonical-pipeline PRODUCT/TECH is NOT modified inline — instead, every gap lands in PLAN.md or a task-specific spec file.

Drift item #Original P-tierLands in: PLAN.md §X OR new spec path OR no-action
1.2-aP3T2 acceptance criteria (column list illustrative; migration SQL authoritative) — §4.2
1.3-aP2T2 acceptance criteria (reserved-seats forward-ref to RWS spec) — §4.2 + §5 procurement-workspaces NEW spec
1.5-aP3T11 spec-requirement note (citations schema in 05-qa-flow.md §6.2) — §4.11
2.1-aP3T8 subtask 1 + acceptance criteria (cocoindex 6-stage topology forward-ref to 02-data-flow.md §3) — §4.8
2.2-aP2T8 risk + subtask 2 (Cloud Run sidecar forward-ref to 02-data-flow.md §4 — fixes dead §3.1/§3.2 ref) — §4.8
2.3-aP2T8 acceptance criteria + T2 subtask 9 (op_id hybrid pattern + content_items.op_id column in combined PR) — §4.2 + §4.8
2.5-aP3T8 acceptance criteria + §9 freshness-substrate gotcha — §4.8
2.6-aP2T9 acceptance criteria + subtask 9 (edit_intent CV mapping per 02-data-flow.md §8) — §4.9
3.1-aP3T6 risk note (sidecar layered fn-shape per 05-qa-flow.md §5.2) — §4.6
3.2-aP1T10 acceptance criteria + risk (question_matches never built under old name; drift fix lives in PLAN, NOT inline) — §4.10
3.3-aP2T10 acceptance criteria (question_kind aligned with form_types) — §4.10
3.4-aP2T8 subtask 8 + T6 risk (cocoindex UPSERTs to q_a_extractions derived cache; q_a_pairs is golden record) — §4.6 + §4.8
4.1-aP1NO-ACTION — 03-tech-stack.md §8.2 already fixed in S239 (commit 86f65214). Canonical-pipeline TECH §11 entry is stale per drift audit but Liam S241 direction means PLAN.md represents the authoritative current state — see §6.2 below for the resolved-S239 note.
4.2-aP1RESOLVED-S241 — Q&A migration rollback window RATIFIED at 1 year per S239-still-open-consolidation.md S241 addendum row 5. T7 subtask 2 no longer gating.
4.2-bP2§5 NEW spec cocoindex-extraction-contract/ — Q-EX2 Pydantic — drafted in T1 — §4.1
4.2-cP2T13 subtask 1 (prompt-cache verification spike) — §4.13
4.2-dP2DEFERRED-v1.1 per RATIFIED-S243 (Item 11). v1 ships only pipeline_runs rollup. Existing docs/specs/id-36-cocoindex-ledger-api/TECH.md draft retained as v1.1 substrate; per-stage detail surface (FlowRunMetrics etc.) not built v1.
5.1-aP2T2 acceptance criteria + §5 NEW spec procurement-workspaces (reserved-seats forward-ref) — §4.2 + §5
5.2-aP2T2 subtask 7 + procurement-workspaces NEW spec (satellite table DDL forward-ref) — §4.2 + §5
6.2-a + 6.4-aP3NO-ACTION inline; tier vocabulary already canonical per 04-workspace-types.md §11 + 05-qa-flow.md §11 — PLAN.md uses 6-tag vocabulary throughout

§6.1 Stale RLS-PATTERN destination — already resolved

Section titled “§6.1 Stale RLS-PATTERN destination — already resolved”

Drift item 4.1-a notes the stale [STILL-OPEN] for RLS-PATTERN destination in canonical-pipeline TECH §11 (lines 465-468). Resolution status: the destination decision was ratified at S239 Wave 2 dispatch.

§6.2 Per implementation-readiness audit findings

Section titled “§6.2 Per implementation-readiness audit findings”

Implementation-readiness audit (S240) surfaced 18 findings across 3 spec pairs. The canonical-pipeline-specific findings (D1, D2, B1, C1, C2, C3, A1, A2, A3) map into the per-task acceptance criteria + risk notes in §4. The reserved-workspace-seats T-5 USING-predicate gap (C1) and the rls-pattern T-2 edge-case examples (B1) are addressed in the RWS / RLS spec files themselves — NOT in this PLAN (those specs are external dependencies, not deliverables of canonical-pipeline implementation).


Items from S239-still-open-consolidation.md (post-S240/S241 closures) that are NOT part of v1 canonical-pipeline scope. Listed with disposition.

#ItemStatus as of S241Disposition
1Theme F MCP-action review passRATIFIED-S240 (direct pattern) per 06-mcp-tooling.md §4CLOSED; migration to wrapped DEFERRED-POST-LAUNCH per 06-mcp-tooling.md §7. Per-tool audit handled in T13.
2Diff-UI retire scopeRATIFIED-S243 — RETAINED for v1 (Item 5). Surface re-pointed from source_document_diffs substrate to markdown sidecar revision comparison.IN-SCOPE — T9 (Diff-UI sidecar re-point sub-task added)
3P7 file-upload route dispositionRESOLVED per N5 per 02-data-flow.md §2.3 (Option α slim-and-keep)CLOSED
4Roadmap §3/§3.7/§11 LIKELY-ABSORB per-item verificationRATIFIED-RETIRE per 02-data-flow.md §3.3 (Roadmap §3 + §3.7) + CONDITIONAL-RETIRE pending S7 spike (Roadmap §11)CLOSED for §3/§3.7; carried as KG-substrate STILL-OPEN below
5EP8 partial obsolescenceOQ7 OPEN-WITH-NOTEOUT-OF-SCOPE v1; carry forward — schedule OQ7 spike or docs/specs/ep8-qa-docx-import-ui-spec.md rewrite
6Q-OQR1-16 combined PR migration draftingRATIFIED-S235 in framing; migration STILL-OPENIN-SCOPE — T2 of this plan
7P-5 RLS auto-enable observability hookDEFERRED-v1.1 per S240 ratification (option (c) structured-logging)OUT-OF-SCOPE v1; v1.1 if operational signal surfaces
8Knowledge Map graph substrateSTILL-OPEN; future S7 spike per 08-new-features.md §2.2OUT-OF-SCOPE canonical-pipeline; tracked in 08-new-features.md — mention-only at this layer until S7 spike
9TS-facing API for cocoindex per-flow-run ledgerDEFERRED-v1.1 per RATIFIED-S243 (Item 11). v1 ships only pipeline_runs rollup. Per-stage detail (FlowRunMetrics + partial-completed UX) deferred.OUT-OF-SCOPE v1; existing TECH.md draft retained as v1.1 substrate
10CocoInsight on-prem deployment postureSTILL-OPEN; contingent (KH self-hosts)DEFERRED — re-evaluate if self-host scenario surfaces; out-of-scope v1
11Tracked-changes DOCX regression testSTILL-OPEN; pre-launchIN-SCOPE — T13.2
12Discriminated-union Pydantic (Q-EX2)RATIFIED-S241 (Liam direction); spec drafting requiredIN-SCOPE — T1.1 + T1.2 NEW spec drafts cocoindex-extraction-contract
13Anthropic prompt-cache passthrough verificationRATIFIED-S241 (Liam direction); spike requiredIN-SCOPE — T13.1
14 (CX.28)Onboarding folder-requiredPROVISIONAL: folder-required per P-60OUT-OF-SCOPE v1 canonical-pipeline (binds at onboarding feature spec). Gate: Liam ratification on CX.28.
15 (CX.29)SMB data-fix v1 scopePROVISIONAL: user-scoped per P-61OUT-OF-SCOPE v1 canonical-pipeline (data-fix is separate workstream — Spike #7). Gate: Liam ratification on CX.29.
16Admin UI v1.1 for client-managed vocabulariesDEFERRED-v1.1 per Q-OQR1-13 + 08-new-features.md §9OUT-OF-SCOPE v1; v1.1 PRODUCT spec needed
17Workspace-private q_a_pairsDEFERRED-v1.1 per Q-OQR1-08OUT-OF-SCOPE v1
18Markdown sidecar materialisation for approved Q&ADEFERRED-v1.1 per UC5 4.6.Q7OUT-OF-SCOPE v1; v1 keeps Q&A pairs KH-DB-only
19Yjs y-supabase persistenceDEFERRED-v1.1 per UC1 4.1.Q4OUT-OF-SCOPE v1
20UC8 Candidate C upgradeDEFERRED-v1.1OUT-OF-SCOPE v1; T9 ships UC8 Candidate A + LLM-reasoning
21UC8 auto-merge thresholdDEFERRED to post-v1.1OUT-OF-SCOPE v1
22CV 03 UI nesting spec (p0-layer-nesting-spec.md)DEFERRED-S238+OUT-OF-SCOPE v1
23Form_type-specific behaviour data-driven modelDEFERRED-v2 per Q-OQR1-14OUT-OF-SCOPE v1 + v1.1; v1 is code-driven
24Cross-workspace KG without admin + scope flagDEFERRED-v2OUT-OF-SCOPE v1 + v1.1
25UC9 cross-workspace operationsOPS-X-SCOPE-TAGS separate WP per 08-new-features.md §5OUT-OF-SCOPE canonical-pipeline; separate work-package

§8 Implementation ordering recommendation

Section titled “§8 Implementation ordering recommendation”

Recommended sequence with rationale. Sequential merge per CLAUDE.md “Worktree isolation rules”; parallel agent isolation via isolation: "worktree" where stated.

Wave 0 — Spec gates (foreground main + sub-agents)

Section titled “Wave 0 — Spec gates (foreground main + sub-agents)”
  1. T1 — Drafting Q-EX2 contract + cocoindex ledger TECH + Q1.3-Q1.N invariants. Foreground for the three drafts; verifier sub-agents in worktree for review. Gates: nothing. Effort: 2.5 units. Must complete before T8 (cocoindex flow scaffolding consumes the Q-EX2 contract).
  2. procurement-workspaces NEW spec (T4.7 spec) — drafted in parallel with T1 (different file scope). Foreground or sub-agent. Gates: nothing. Must complete before T4 (procurement code rename + state machine). 2a. intelligence-workspaces spec (RATIFIED-S243 Item 15, AMENDED-S244-Wave-0.5) — PRODUCT + TECH landed docs/specs/intelligence-workspaces/{PRODUCT,TECH}.md S243 + extended to full Shape B (3 typed cols) at S244 commit 4abf7328. Must complete before T2 sub-task 8 (Shape B promotion of company_profile_id + guide_id + relevance_threshold JSONB → typed columns). Helper-first hybrid migration approach ratified per Wave 0.5 — pre-T2 helper landing at lib/intelligence/workspace-context.ts + ~23-site code sweep (helper reads JSONB initially; behaviour-preserving); helper swaps to typed-column JOIN at T2 PR. Per Wave 0.5: T-5 read-path inventory expanded from 13 refs/6 files to ~23 refs/13 files (added scripts/batch-rescore-articles.ts:157-158 + 9 relevance_threshold sites + interface migration in hooks/intelligence/use-intelligence-workspaces.ts:13-18 + API response shape change). 2b. sales-proposal-workspaces spec (RATIFIED-S244) — PRODUCT + TECH landed docs/specs/sales-proposal-workspaces/{PRODUCT,TECH}.md S244 (commits 3af858b1 + 8463d72f substrate-cite + 7ea4c77d verifier fix). Reserved-seat only at Phase 1 (T-1..T-5); Phase 3 substrate carries 4 candidate arm files via T-8 gap-flag pending Liam-review + canonical-pipeline reconciliation passes before Phase 3 kickoff. Phase 1 NOT gated on the gap. 2c. product-guide-workspaces spec (RATIFIED-S244) — PRODUCT + TECH landed docs/specs/product-guide-workspaces/{PRODUCT,TECH}.md S244 (commits e257dbac + 0cec141a verifier fix). Reserved-seat only at Phase 1; 3 gap-flags GF-1/GF-2/GF-3 deferred to feature-build with §5.2 category tags (Ratification needed / Tech spec needed). Per-app ALTER lands at feature-build time. 2d. concurrent-edit-intent-arbitration spec (RATIFIED-S244) — TECH landed docs/specs/id-59-concurrent-edit-intent-arbitration/TECH.md S244 (commit 12a20963). v1 safe default codified at CRDT-merge write site (CV: cosmetic / data / structural per S234 ONT.14, NOT freeform). Must complete before T9 (already satisfied).
  1. T3 — RLS-pattern combined migration apply + observability validation. DONE-S239 (migration 20260514150238_enable_rls_auto_event_trigger_and_grants_pattern.sql applied at or before S239 close on both staging + prod; verified S243 18/05/2026 per docs/specs/phase-1-kickoff-scoping-s243.md §3 — functions live, event trigger enabled, RLS-PATTERN P-1..P-5 invariants satisfied). No further T3 work; T2 (Wave 2) is the next implementation task.

Wave 2 — Combined PR migration (foreground main + verifier)

Section titled “Wave 2 — Combined PR migration (foreground main + verifier)”
  1. T2 — Q-OQR1-16 combined PR + 5 reserved seats. Foreground for SQL drafting (per S241 critical-rule on combined-PR cohesion); verifier sub-agent for migration parity + grants helper test. Gates: T3 applied. Effort: 3 units. Must complete before all Wave 3+ tasks.

Wave 3 — Parallel feature slices (4 sub-agents in worktrees, sequential merge)

Section titled “Wave 3 — Parallel feature slices (4 sub-agents in worktrees, sequential merge)”
  1. T4 — Procurement rename + state machine. Worktree sub-agent. Gates: T2 + procurement-workspaces spec. Effort: 2 units. Cherry-pick to main per CLAUDE.md gotcha.
  2. T5digestschange_reports code sweep. Worktree sub-agent. Gates: T2. Effort: 1 unit. Parallel-safe with T4 (different lib dirs).
  3. T6 — q_a_pairs + q_a_extractions + q_a_pair_history migration + RPCs. Worktree sub-agent. Gates: T2. Effort: 2.5 units. Parallel-safe with T4 + T5 (separate schema).
  4. T11 — citations polymorphic enum + version-on-cite. Worktree sub-agent. Gates: T6 (q_a_pair_history exists). Effort: 1 unit. Sequential after T6 starts (can run partial-parallel during T6 if T11 awaits the q_a_pair_history trigger landing).

Wave 4 — Pipeline scaffolding + retrieval (2 sub-agents)

Section titled “Wave 4 — Pipeline scaffolding + retrieval (2 sub-agents)”
  1. T8 — Cocoindex flow scaffolding + Cloud Run sidecar. Worktree sub-agent + foreground for Spike #1/#2 closure. Gates: T1 + T2 + T6 + T3. Effort: 3 units. NOW gates T7 per RATIFIED-S243 Item 18 (T7 is cocoindex re-ingest of Phew Q&A markdown source files; cannot run until cocoindex flow exists).
  2. T10question_matches + retrieval. Worktree sub-agent. Gates: T2 + T6. Effort: 1.5 units. Parallel-safe with T8 (different surfaces).

Wave 5 — Phew first-ingest + features + KG (3 sub-agents)

Section titled “Wave 5 — Phew first-ingest + features + KG (3 sub-agents)”
  1. T7 — Phew Q&A markdown source files → cocoindex first-ingest (RATIFIED-S243 Item 18 reframe). Foreground for source-file staging + promote-all script. Gates: T8 stable + T6 (q_a_extractions schema) + T1 (Q-EX2 contract). Effort: 2 units.
  2. T9 — Per-UC write-back implementation + Diff-UI sidecar re-point. Multiple sub-agents — one per UC or UC pair in worktrees, sequential merge per CLAUDE.md. Gates: T8 (cocoindex source-binding) + T6 (q_a_pairs schema) + T2 (procurement rename) + concurrent-edit-intent-arbitration spec (Wave 0 spec gate). Effort: 3 units total but parallelisable per-UC.
  3. T12 — Mempalace KG integration. Worktree sub-agent + foreground for Spike #4. Gates: T2 (entity_mentions extended) + T8 (cocoindex emits entity events). Effort: 2 units. Parallel-safe with T7 + T9.

Wave 6 — Operational gates (foreground + sub-agents)

Section titled “Wave 6 — Operational gates (foreground + sub-agents)”
  1. T13 — Pre-launch operational. Foreground for Liam pre-decisions (MCP tool rename PR sequencing); sub-agents for prompt-cache spike + tracked-changes regression test + per-tool MCP audit. Gates: T2 (MCP tool rename [LOCKSTEP-WITH-MIGRATION]) + T8 (call site for prompt-cache verification). Effort: 1.5 units. Parallel with T7 + T9 + T12 for the audit work-package.

Wave 7 — Cocoindex absorption cleanup (1 sub-agent)

Section titled “Wave 7 — Cocoindex absorption cleanup (1 sub-agent)”
  1. T14 (NEW per RATIFIED-S243 Item 17) — Delete retired pipeline code + dependencies post-T8 stable. Worktree sub-agent. Gates: T8 observably stable in production (no rollback within last 7d) + T7 complete (Phew first-ingest validated). Effort: 1 unit. ~6,800 LOC removed + 4 npm deps.

Gating spec list (must land before dependent task starts):

Gating specDrafting taskDependent tasks
cocoindex-extraction-contract/{PRODUCT,TECH}.mdT1.1 + T1.2T8 (cocoindex extraction stage)
Q1.3-Q1.N invariants (location TBD)T1.4T8 + T9 (content-model expectations)
procurement-workspaces/{PRODUCT,TECH}.mdT4.7T2 (per-app columns SQL) + T4 (code-side rename + state machine)
intelligence-workspaces/{PRODUCT,TECH}.md (NEW-S243, AMENDED-S244-Wave-0.5)Wave 0T2 sub-task 8 (Shape B promotion company_profile_id + guide_id + relevance_threshold)
sales-proposal-workspaces/{PRODUCT,TECH}.md (NEW-S243)Wave 0Phase 3 (per-app ALTER)
product-guide-workspaces/{PRODUCT,TECH}.md (NEW-S243)Wave 0Feature-build time ALTER
concurrent-edit-intent-arbitration/TECH.md (NEW-S243 — MUST lifted from CONDITIONAL)Wave 0T9 (UC1/UC4/UC6 CRDT-merge write site)
mcp-tooling-audit/{PRODUCT,TECH}.mdT13.3T13 closure
cocoindex-ledger-api/TECH.mdT1.3DEFERRED-v1.1 per RATIFIED-S243 Item 11

Sequential merge discipline: Wave 3 + 4 + 5 sub-agents merge to main one-at-a-time per CLAUDE.md “Cherry-pick (not merge) parallel agent branches” gotcha — agents branch from main at launch and go stale when earlier agents merge first. Each agent’s first action MUST be git reset --hard main.


RiskSeverityMitigation
Combined-PR migration is non-trivial (10 items + 5 reserved seats in one transaction)HIGHT2 staged: foreground SQL drafting + verifier sub-agent. Apply to staging FIRST; verify all 15 items present; verify auto-RLS fired on all new tables; rollback path on staging before production apply.
Spike #10 (UC8 dedup substrate) PENDING per canonical-pipeline TECH §9MEDIUM (T9 UC8 gating)UC8 v1 implementation can scaffold Candidate A skeleton; substrate decision can land mid-T9 if spike runs in parallel.
q_a_pair_history trigger interaction with cocoindex UPSERT — risk that trigger fires unexpectedly during cocoindex writes to q_a_extractionsMEDIUMT6 integration tests must cover: (a) cocoindex UPSERT to q_a_extractions does NOT fire q_a_pair_history trigger; (b) promotion from extraction → pair fires the history trigger correctly. Separate q_a_extractions_history if needed.
Per-UC write-back coupling — UC1/UC4/UC6 all touch Tiptap + Yjs + sidecar pattern; race conditions across UCsMEDIUMT9 subtasks 1, 4, 6 sequenced; integration test covers concurrent UC1+UC6 on same source-doc-backed Q&A pair. v1 safe-default per 02-data-flow.md §8.3.
Q&A migration rollback window not yet ratifiedRESOLVED-S241RESOLVEDRATIFIED-S241 = 1 year retention. UK data-protection-aligned. T7 subtask 2 marked DONE-S241. Risk row preserved for audit-trail.
MCP tool rename [LOCKSTEP-WITH-MIGRATION] — Liam input on whether rename ships in Q-OQR1-16 combined PR or separate MCP-tooling PR per S241 prompt pre-req 2LOWT13.5 gates on Liam decision; default is co-ship with T2 to keep MCP tool names aligned with DB names at any code freeze.
Embedding cost projection — 1024-dim vector × 395 q_a_pairs × any re-extraction cyclesMEDIUMT13.1 prompt-cache verification spike: confirm cache_control block works; reduces re-extraction cost via cocoindex memo.

Source ratifications cited by this plan:

  • Canonical-pipeline PRODUCT/TECH (S238 reconciliation): docs/specs/id-31-0.9-canonical-pipeline/PRODUCT.md + TECH.md.
  • Phase 0.9 synthesis V2 (rolling ratification register): docs/plans/phase-0-investigation/10-feedback-investigation-findings/00-synthesis-v2.md.
  • Decision graph (187 decisions + §11 S234-S237 ratifications): docs/plans/phase-0-investigation/0.9-decision-graph.md.
  • WP-ONTO-R1 feedback investigation (Q-OQR1-01..17 ratifications 14/05/2026): docs/plans/phase-0-investigation/phase-b-prerequisite-1-onthology-pipeline-feedback-investigation.md.
  • Edit-flow investigation §6 (per-UC Candidate A/B/C ratifications): docs/plans/phase-0-investigation/0.9-edit-flow-investigation.md.
  • Spike plan (8 spikes + S9 + S10): docs/plans/phase-0-investigation/0.9-spike-plan.md.
  • Architecture sub-docs (S239-S240): docs/plans/phase-0-investigation/architecture/{02-data-flow,04-workspace-types,05-qa-flow,06-mcp-tooling,08-new-features}.md.
  • RLS pattern spec pair (NEW-S239): docs/specs/rls-pattern/{PRODUCT,TECH}.md.
  • Reserved workspace seats spec pair (NEW-S240): docs/specs/reserved-workspace-seats/{PRODUCT,TECH}.md.
  • Drift audit (S240): docs/specs/core-docs-pathway-assessment/canonical-pipeline-drift-audit-s240.md.
  • Implementation-readiness audit (S240): docs/specs/core-docs-pathway-assessment/implementation-readiness-audit-s240.md.
  • STILL-OPEN consolidation (S239): docs/specs/core-docs-pathway-assessment/S239-still-open-consolidation.md.
  • Architecture sub-doc construction guide: docs/specs/core-docs-pathway-assessment/architecture-sub-doc-construction-guide.md.
  • S241 continuation prompt: docs/continuation-prompts/continuation-prompt-kh-s241-main-architecture-family-close.md.

End of PLAN.md. S242+ implementation kickoff per S241 continuation prompt §“Anti-patterns to avoid” + S241 pre-req chain. Ratification of this plan gates Wave 0 dispatch.