Skip to content

0.9 Canonical Pipeline — TECH

Status: RATIFIED-S238 reconciliation — companion to PRODUCT.md. Per-invariant technical notes grounded in current code (file:line refs) reflect the S234-S237 ratification state; spike requirements + ratification gates noted inline. Items NOT yet implementable carry explicit STILL-OPEN — gates on X notes.

This file carries implementation references for each P-N invariant in PRODUCT.md. Each P-N entry contains:

  • Current state: code file:line that today implements (or partially implements) the invariant, or “greenfield” if no code exists.
  • Target state: what the canonical pipeline must do after migration.
  • Spike requirement: which of the 8 spikes in 0.9-spike-plan.md must resolve before this invariant can be implemented.
  • Validation: how we verify (unit / integration / MCP eval / manual).

Authoring conventions adopted from warp write-tech-spec skill (/Users/liamj/Documents/development/warp/.agents/skills/write-tech-spec/).

  • PRODUCT.md (numbered invariants): ./PRODUCT.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
  • Architecture split readiness (10-item supersession backbone): docs/specs/core-docs-pathway-assessment/INV-architecture-split-readiness.md
  • Intended architecture (OUTDATED per S237 — preserved as audit-trail): docs/plans/phase-0-investigation/0.9-intended-architecture.md
  • Spike plan: docs/plans/phase-0-investigation/0.9-spike-plan.md
  • Synthesis impact (test/code blast radius): docs/audits/kh-production-readiness-phase-1/0-9-synthesis-impact.md

P-1 external-folder polling [RATIFIED-S234]

Section titled “P-1 external-folder polling [RATIFIED-S234]”
  • Current state: greenfield. lib/intelligence/feed-poller.ts handles RSS/web sources today but no LocalFS / SharePoint / Notion adapter. scripts/ingest_markdown.py is a one-shot CLI, not a watcher.
  • Target state: cocoindex flow with external-folder source binding + configurable poll cadence per workspace. pullmd as URL adapter inside the flow (HTML — Docling does not displace pullmd per 00-synthesis-v2.md §3.3). Cloud Run sidecar hosts Docling per §3.1 / §3.2 (Docling 1.8 GB

    Vercel 250 MB).

  • Spike requirement: Spike #1 — cocoindex schema-coupling Scenario A vs B (PENDING-SPIKE per 00-synthesis-v2.md §2.2 I3 row — sidecar v1 promotion UNBLOCKED-CONDITIONAL on layered fn-shape).
  • Validation: integration test — write a file to a test folder, poll fires, content_item row appears within cadence; MCP query returns row.

P-2 markdown ingest end-to-end [RATIFIED-S234]

Section titled “P-2 markdown ingest end-to-end [RATIFIED-S234]”
  • Current state: scripts/ingest_markdown.py (CLI) + app/api/items/route.ts (web form) + lib/mcp/tools/content.ts (MCP create_content_item). Chunking via lib/content/chunking.ts:chunkByHeadings() (S167 ship). Embeddings via lib/ai/embed.ts. Classification via lib/ai/classify.ts (S168 hardening).
  • Target state: unified through cocoindex ExtractByLlm flow. CLI + web form + MCP all hit the same flow rather than parallel code paths. Pattern A/B retires post-Phew-migration per 00-synthesis-v2.md §2.1 B1
    • Prereq 2 Rec 1. Cocoindex memo scoping is per-component-path, not global content-hash dedup (per S9 spike RESOLVED-PARTIAL).
  • Spike requirement: Spike #1 + Spike #2 (cocoindex orchestration pattern). Spike S9 RESOLVED-PARTIAL (95% confidence) — substrate works subject to layered fn-shape (inner-tier extraction fns must consume content_text: str, not FileLike).
  • Validation: MCP eval Layer 4 — create_content_item over MCP results in queryable content within same call; existing functional-correctness suite (37 checks) extended.

P-10 stable external-source pointer [RATIFIED-S234]

Section titled “P-10 stable external-source pointer [RATIFIED-S234]”
  • Current state: content_items.source_url stores URL for web ingest; source_path not present. Markdown ingest stores nothing about origin location.
  • Target state: content_items.external_source_uri (NEW column) + external_source_kind (folder | sharepoint | notion | web | …). MCP + UI surface always returns these. source_documents adopts Option α (slim-and-keep) + nullable source_documents.workspace_id for admin-shared binaries (Q-OQR1-09; 00-synthesis-v2.md §3.15). Retires source_documents.{version, parent_id, original_filename} + source_document_diffs entirely (B2 + INV-architecture-split-readiness.md §2 row 6).
  • Spike requirement: Spike #1 (informs adapter schema).
  • Validation: schema constraint + unit test on adapter ingest path.

P-11 per-UC write-back set [RATIFIED-S235]

Section titled “P-11 per-UC write-back set [RATIFIED-S235]”
  • Current state: all edits are KH-internal — Tiptap editor + app/api/items/[id]/route.ts PATCH. No write-back to external folder.
  • Target state: seven UCs with explicit Candidate A/B/C assignments per 0.9-edit-flow-investigation.md §6 (Liam S229 + S235 confirmation):
    • UC1 (typo fix) — Candidate A: in-platform Tiptap + Yjs editor + KH server writes DB row (content_items.content + content_history via auto-version trigger) + filesystem write at source_documents.original_path (markdown) or sidecar .md (binary source). Cocoindex source binding observes file change on next scan; S9 spike confirmed idempotency conditional on layered fn-shape.
    • UC2 (date / version bump) — collapses to UC1 per S228 §3.2 de-scope. Expiry dates handled by Q1.8 extractDates flow.
    • UC3 (sweeping rename) — two-variant split:
      • Candidate A find-replace: KH server iterates affected files; writes each under a shared sweep ID; per-record provenance entry references sweep ID; rollback affordance per §6.0.6.
      • Candidate B smart-agent: KH server invokes Anthropic API with text-editor-tool; user reviews + approves per-match before commit.
    • UC4 (paragraph rewrite, cited content) — Candidate A: in-platform Tiptap + Yjs; edit-intent gate at save time; source classification surfaced inline (approved Q&A / draft Q&A / MCP-derived / generated); citation re-anchor per §6.0.2 hybrid policy.
    • UC5 (bid response → Q&A promotion) — KH-DB-only operation (no candidate; no folder write-back). Creates new q_a_pair draft with lineage to source bid response + bid question.
    • UC6 (Q&A pair revision) — split:
      • User-direct: KH-DB-only via existing Tiptap + Yjs editor; mempalace Shape A temporal columns record version transition.
      • AI-suggest: Candidate B — KH server detects source-doc change via cocoindex; invokes Anthropic API to propose draft revision; user reviews + edits + commits via user-direct flow.
    • UC7 + UC10 (external folder change detected) — cocoindex source binding native (no candidate). Conflict-resolution UI for transactional-window collisions = git-style merge prompt.
    • UC8 (AI-suggested dedup merge) — v1 Candidate A + LLM-reasoning; v1.1 upgrade to Candidate C: KH server orchestrates merge directly; Claude API used only for per-pair similarity reasoning. Substrate (cross-record detection) GATES ON S10 spike result.
    • UC9 (scope-tag taxonomy update) — KH-native typed-column work-package (no candidate). Per OPS-X-SCOPE-TAGS WP, ~1-2 weeks.
  • Spike requirement:
    • S9 RESOLVED-PARTIAL (95% confidence) for UC1/UC4/UC6 filesystem write-back idempotency. Layered fn-shape required.
    • S10 GATES UC8 substrate (cocoindex post-target-write @coco.fn / mempalace KG entity-resolution / hybrid).
    • Spike #3 (write-back adapter contract) — UC1/UC4/UC6 sidecar pattern.
  • Validation:
    • UC1/UC4: integration — edit content in UI, verify file delta in test folder + verify KH stays in sync.
    • UC3: integration — sweep variant A; smart-agent variant B with Anthropic API mock.
    • UC6 AI-suggest: integration — source-doc change triggers AI-suggest; user-direct flow commits via mempalace Shape A.
    • UC7+UC10: integration — external folder change detected within cadence; conflict-resolution merge UI rendered for collisions.
    • UC8 v1: integration — Candidate A merge; rollback per §6.0.6.

P-20 q_a_pairs corpus-level + scope_tag-driven [RATIFIED-S235]

Section titled “P-20 q_a_pairs corpus-level + scope_tag-driven [RATIFIED-S235]”
  • Current state: Q&A pairs stored as content_items rows with content_type='q_a_pair'. References in code:
    • lib/claude-prompts.ts:155 (MCP prompt listing valid types)
    • lib/format.ts:138 (display label)
    • lib/layer-inference.ts:16, 95, 164 (layer-inference branching by type)
    • lib/extraction/qa-pair-extractor.ts (mining)
  • Target state: new q_a_pairs table — corpus-level, with cols id, question, answer, source_content_item_id, source_offset_start, source_offset_end, effective_from, effective_to, scope_tags[], anti_scope_tag[], source_workspace_id (nullable — provenance audit only, NO direct workspace FK), plus standard created_at / updated_at / metadata. content_items.content_type='q_a_pair' retired (soft-archive existing rows per P-70). Workspace relevance computed via scope_tag overlap query, not FK join. Supersedes both 0.9-intended-architecture.md §4.3 N:1 framing AND prior onto-doc §4.4 M:N junction recommendation. (Cite 00-synthesis-v2.md §3.6 + 0.9-decision-graph.md §11.1 ONT.5
    • Q-OQR1-06 + Q-OQR1-07.)
  • Spike requirement: none — schema design ratified; migration scriptable.
  • Validation: integration — extract Q&A from sample corpus, assert q_a_pairs row matches source content offset; MCP tool list_q_a_pairs returns shape; scope_tag overlap query returns workspace-relevant pairs.

P-21 scope + validity + per-method scoring [RATIFIED-S234/S236]

Section titled “P-21 scope + validity + per-method scoring [RATIFIED-S234/S236]”
  • Current state: no validity window today; Q&A pairs effectively permanent. bid_question_matches carries a single hybrid score.
  • Target state:
    • Bid composer (components/bid/ — renaming to components/procurement/ per P-42) + sales-proposal composer surface only pairs where effective_to IS NULL OR effective_to > now() AND scope_tags @> ARRAY[<context-scope>].
    • bid_question_matches (renaming to question_matches per 0.9-collapse-candidates.md §12.5 row 4) carries separate embedding_score + fulltext_score columns (RATIFIED-S236 per 00-synthesis-v2.md §5.1; operational verification deferred to feature spec time). question_kind discriminator added.
  • Validation: unit — composer filter SQL asserts; integration — expire pair, verify it disappears from composer surface; verify separate score columns surface in match results.

P-22 citations polymorphic enum [RATIFIED-S234]

Section titled “P-22 citations polymorphic enum [RATIFIED-S234]”
  • Current state: citations.bid_response_id NOT NULL (single-citer assumption).
  • Target state: citations.citing_entity enum: bid_response, sales_proposal_response, competitor_research_finding, training_unit, mcp_search_response. (Cite 00-synthesis-v2.md §2.3 N8 row.)
  • Spike requirement: none — schema design ratified.
  • Validation: integration — write citation for each citing_entity kind; assert query selects per-kind.

P-30 temporal + provenance entity_mentions [RATIFIED-S234]

Section titled “P-30 temporal + provenance entity_mentions [RATIFIED-S234]”
  • Current state: entity_mentions table exists with content_item_id
    • entity_id + offsets. No temporal validity window. No provenance chain beyond source content_item_id.
  • Target state: add asserted_at, verified_at, stale_at cols + provenance_chain JSONB (extraction agent, timestamps, parent mentions for re-extractions). Mempalace Shape A (temporal KG) + Shape B (provenance-tagged) adopted.
  • Spike requirement: Spike #4 (mempalace integration pattern).
  • Validation: integration — re-extract same content, verify new mention row chains back to previous + temporal window updates.

P-31 workspace-scoped KG queries [RATIFIED-S234]

Section titled “P-31 workspace-scoped KG queries [RATIFIED-S234]”
  • Current state: lib/mcp/tools/kg.ts (if present) — TBC. Current workspace scoping pattern: RLS via get_user_role() per CLAUDE.md.
  • Target state: all mempalace_kg_* MCP tool wrappers default to caller’s workspace_id; cross-workspace requires --scope=global + admin role check. Supabase auto-RLS event trigger (rls_auto_enable() on ddl_command_end for CREATE TABLE / CREATE TABLE AS / SELECT INTO in public schema) closes OQ-Q24-B + OQ-Q113-B together (00-synthesis-v2.md §3.16).
  • Validation: MCP eval Layer 4 — viewer/editor get scoped result; admin with --scope=global gets cross-workspace.

P-40 combined pre-launch PR (Q-OQR1-16) [RATIFIED-S235]

Section titled “P-40 combined pre-launch PR (Q-OQR1-16) [RATIFIED-S235]”
  • Current state: mixed. workspace_id used in 27 lib files (lib/mcp/tools/, lib/dashboard.ts, lib/reorient.ts, etc.). project_id still appears in 5+ lib files (lib/mcp/resources.ts, lib/mcp/tools/apps.ts, lib/mcp/tools/bids.ts, …). 2 DB columns (bid_questions, templates) still use project_id.
  • Target state: zero project_id references in code; all replaced with workspace_id. Schema migration for the 2 DB columns. Lands as part of the combined pre-launch PR with the other nine items per 0.9-decision-graph.md §11.3 — see PRODUCT.md §5 P-40 for the 10-item enumeration.
  • Note (S238): prior “~5d HIGH cost” budget framing retired — budget/day-count terminology banned platform-wide since S231 per INV-architecture-split-readiness.md §2 row 7. Pre-launch is the cheapest time to land naming cleanup + ontology rework together.
  • Spike requirement: none. Mechanical rename via script (ts-morph + ast-grep sweep across 44 code files).
  • Validation: grep -rn "project_id" lib/ scripts/ app/ components/ returns zero hits; CI test added to prevent regression.

P-41 change_reports rename [RATIFIED-S235]

Section titled “P-41 change_reports rename [RATIFIED-S235]”
  • Current state: code uses digests throughout (lib/ai/digest.ts, lib/query/query-keys.ts, lib/query/fetchers.ts, lib/validation/schemas.ts). UI labels already say “Change Reports”.
  • Target state: schema table digestschange_reports; all code references flipped; UI labels unchanged. Lands in combined PR (Q-OQR1-16 item 7).
  • Spike requirement: none. Mechanical rename + migration.
  • Validation: grep -rn "digest" lib/ scripts/ app/ components/ returns only intentional historical refs; CI test prevents regression.
  • Current state: application_type='bid' framing pervasive — BID_STATES in types/bid.ts:3-14, state machine in lib/bid/bid-state-machine.ts:48-59, satellite table bid_workspaces.
  • Target state:
    • application_type='bid''procurement' (umbrella; form_type ∈ {bid, rfp, pqq, itt, framework, dps, gcloud} discriminator within).
    • bid_workspacesprocurement_workspaces (satellite table; Shape B typed-columns retained per I1 + Q-OQR1-04 KISS single discriminator).
    • BID_STATESPROCUREMENT_WORKFLOW_STATES.
    • lib/bid/bid-state-machine.tslib/procurement/procurement-workflow.ts.
    • lib/bid/ subtree → lib/procurement/.
    • components/bid/ subtree → components/procurement/.
    • CHECK constraint name projects_status_check updated to procurement_status_check (drop legacy projects prefix).
  • Spike requirement: none. Mechanical rename via script.
  • Validation: grep -rn "BID_STATES\|bid_workspaces\|lib/bid" lib/ scripts/ app/ components/ returns zero hits post-rename; CI test added to prevent regression.

P-43 application_types instance table [RATIFIED-S235]

Section titled “P-43 application_types instance table [RATIFIED-S235]”
  • Current state: workspaces.type text column with CHECK constraint type ∈ ('bid', 'kb_section', 'intelligence'). Per-type config in code-level registry lib/workspace-types.ts:WORKSPACE_TYPE_REGISTRY.
  • Target state: new application_types instance table (Option (c) hybrid per Q-OQR1-01) with cols id, key (text unique), label, description, provenance enum (core vs client), default_color, default_icon, route, state_machine_name, satellite_table_name, plus standard audit cols. Seed 6 core-provenance rows: procurement, intelligence, sales_proposal, product_guide, competitor_research, training_onboarding (Q-OQR1-03). workspaces.application_type_id FK replaces workspaces.type text column. Backfill from existing 4 prod rows (all intelligence). lib/workspace-types.ts becomes a seed data source for application_types, not the source of truth.
  • Spike requirement: none — schema design ratified.
  • Validation: integration — seed migration creates 6 core-provenance rows; existing 4 prod workspaces backfill cleanly; admin UI surfaces v1.1 (DEFERRED — see PRODUCT.md §14).

P-50 Claude as primary edit surface [RATIFIED-S234]

Section titled “P-50 Claude as primary edit surface [RATIFIED-S234]”
  • Current state: KH has Tiptap markdown editor + WYSIWYG components (components/content/editor/, components/bid/ — renaming to components/procurement/ per P-42). Content edits flow through KH UI.
  • Target state: Claude (Word / Excel / PowerPoint / Desktop / claude.ai / headless) as primary edit surface via MCP. KH UI editor retained as fallback / admin tool. Note: P-50 covers production-content authoring; the per-UC Candidate A flows in P-11 (UC1/UC4/UC6) still use KH’s Tiptap editor for atomic in-platform edits — coexist by design.
  • Spike requirement: Spike #5 (MCP tooling surface — list_source_documents, get_source_document_content, upload_source_document, check_content_duplicates).
  • Validation: MCP eval Layer 4 — Claude in Word edits a document, KH receives via MCP, content_item updated; manual walkthrough.

P-51 KH UI as admin / governance / visualisation tier [RATIFIED-S234]

Section titled “P-51 KH UI as admin / governance / visualisation tier [RATIFIED-S234]”
  • Current state: UI today is full content-editing surface. 13 CARRIES
    • 4 LOAD-BEARING features identified in 0.9 DW audit; 8 COLLAPSES-CLEANLY features move to MCP; 3 COLLAPSES-WITH-FRICTION need re-evaluation.
  • Target state: UI surface trimmed to admin/governance/visualisation. Editor components retained for admin / fallback only.
  • Spike requirement: Spike #5 (MCP tooling completeness).
  • Validation: UI smoke walkthrough — admin can do governance review, gap analysis, visualisation; editor surface still functional but visually de-emphasised.

§7 — Onboarding & client experience (CX)

Section titled “§7 — Onboarding & client experience (CX)”

P-60 folder-required onboarding [STILL-OPEN — gates on CX.28 ratification]

Section titled “P-60 folder-required onboarding [STILL-OPEN — gates on CX.28 ratification]”
  • Current state: onboarding flow at app/onboarding/ (if exists) — TBC. Folder connection not a current step.
  • Target state (provisional): external-folder connection is a hard-required step. No client proceeds past step N without it. Not addressed in Q-OQR1-01..17 ratifications; remains operational per 00-synthesis-v2.md §5.2.
  • Spike requirement: Spike #6 (onboarding adapter integration). Cannot start until CX.28 ratified.
  • Validation: integration — onboarding flow blocks at folder step without connection; allows past with connection.

P-61 SMB data-fix v1 scope [STILL-OPEN — gates on CX.29 ratification]

Section titled “P-61 SMB data-fix v1 scope [STILL-OPEN — gates on CX.29 ratification]”
  • Current state: no SMB data-fix tool today. (SMB = small/medium business clients.)
  • Target state (provisional): v1 ships scoped to single workspace. Not addressed in Q-OQR1-01..17 ratifications; single-Phew-tenant v1 framing per 00-synthesis-v2.md §3.14 supports user-scoped subset.
  • Spike requirement: Spike #7 (data-fix tool — separate workstream).
  • Validation: unit — data-fix CLI scoped to single workspace_id argument; integration — cross-workspace invocation errors.

§8 — Migration (current → canonical pipeline)

Section titled “§8 — Migration (current → canonical pipeline)”

P-70 q_a_pair content_items migration [RATIFIED-S234]

Section titled “P-70 q_a_pair content_items migration [RATIFIED-S234]”
  • Current state: 395 prod Q&A items (per 00-synthesis-v2.md §3.6 empirical check). All as content_items.content_type='q_a_pair'. Empirically 0/395 assigned to workspaces today — supports corpus-level shape per P-20.
  • Target state: all migrated to q_a_pairs table. Source content_items rows soft-archived (content_type='q_a_pair_archived' or similar — to be ratified) for rollback safety.
  • Spike requirement: Spike #8 (migration runbook). Migration script + dry-run + rollback path. Note: separate sequenced migration from the combined-PR (Q-OQR1-16); the combined PR sets the shape, the q_a_pairs migration moves the data.
  • Validation: integration — pre/post counts match (395 in, 395 out); rollback restores original state.

P-71 Stream 1 backlog re-derivation [RATIFIED-S234]

Section titled “P-71 Stream 1 backlog re-derivation [RATIFIED-S234]”
  • Current state: 6-item Stream 1 backlog in product-backlog.json (verify exact items at ratification time).
  • Target state: items 1, 5, 11 carry as-is; items 3, 6, 7 re-derive against new schema. Backlog updated post-migration.
  • Spike requirement: none. Re-derivation is a doc-update task.
  • Validation: product-backlog.json post-migration shows re-derived item shapes.

Per 0.9-spike-plan.md (8 spikes, ~785 lines). Order suggested by synthesis impact + S235 spike outputs:

  1. Spike #1 — cocoindex schema-coupling Scenario A vs B (blocks P-1, P-2, P-10). PENDING-SPIKE.
  2. Spike #2 — cocoindex orchestration pattern (blocks P-2).
  3. Spike #4 — mempalace Shape A integration (blocks P-30).
  4. Spike #5 — MCP tooling surface completeness (blocks P-50, P-51).
  5. Spike #3 — write-back adapter contract (UC1/UC4/UC6 sidecar pattern; supports P-11 per-UC set).
  6. Spike #6 — onboarding adapter integration (gated by CX.28; then blocks P-60).
  7. Spike #7 — SMB data-fix tool (gated by CX.29; then blocks P-61).
  8. Spike #8 — migration runbook (last; needs all schema spikes resolved; blocks P-70).
  9. Spike #9 — cocoindex equal-hash idempotency (RESOLVED-PARTIAL-S235; 95% confidence per 0.9-spike-S9-cocoindex-idempotency.md). Layered fn-shape required (content_text: str consumption).
  10. Spike #10 — cross-record dedup substrate (UC8 v1 substrate decision; cocoindex post-target-write @coco.fn vs mempalace KG entity-resolution vs hybrid).

Per PRODUCT.md §11 — see PRODUCT.md for the full DEFERRED-v1.1 register.

Headline items:

  • mempalace Shape D PG backend (v4-alpha unstable; defer until upstream stable).
  • Skill-seekers multi-source dedupe (v1+1).
  • Cross-workspace KG without admin + scope flag (v2).
  • Workspace-private q_a_pairs (Q-OQR1-08).
  • Admin UI for client-managed vocabularies (Q-OQR1-13).
  • Markdown sidecar materialisation for approved Q&A pairs.
  • Yjs y-supabase persistence.
  • Candidate C (Managed Agent) upgrade for UC8.
  • p0-layer-nesting-spec.md (CV 03 UI nesting).

As of S238, these need resolution before TECH spec is fully ratified:

  • Schema rename strategy [RATIFIED-S235: combined PR per Q-OQR1-16] — atomic migration as part of the 10-item combined PR (P-40, P-41, P-42, P-43, P-70 share migration sequencing). Per 0.9-decision-graph.md §11.3.
  • Cocoindex deployment shape [RATIFIED-S234: Cloud Run sidecar] — Docling 1.8 GB > Vercel 250 MB function-bundle limit. KH already runs Cloud Run for the Python pipeline (kh-prod-494815 / kh-staging-494815). Cite 00-synthesis-v2.md §3.1.
  • Q&A migration rollback window [STILL-OPEN] — how long do we keep soft-archived rows before hard-delete? Tied to compliance retention requirements. Pre-launch documentation pending.
  • RLS-PATTERN.md destination [STILL-OPEN — Liam discretion] — separate doc vs section within architecture/04-workspace-types. Cite 00-synthesis-v2.md §3.16. Working recommendation per INV-architecture-split-readiness.md §7.4: standalone docs/specs/rls-pattern/PRODUCT.md + TECH.md.
  • Theme F (MCP-action review pass) [STILL-OPEN — Liam pre-decision] — Mempalace direct vs wrapped in KH MCP. Per 00-synthesis-v2.md §5.2 row 1. Blocks WP4 06-mcp-tooling.md.
  • Discriminated-union Pydantic with ExtractByLlm (Q-EX2) — STILL-OPEN, pre-launch schema design.
  • Anthropic prompt-cache passthrough verification — STILL-OPEN, pre-launch cost projection.
  • TS-facing API for cocoindex per-flow-run ledger — STILL-OPEN, pre-launch documentation.

§12 — Supabase platform compliance (S236)

Section titled “§12 — Supabase platform compliance (S236)”

Two platform deadlines added in S236 per 00-synthesis-v2.md §3.17 + §3.18.

§12.1 Public-schema grants compliance (May 30 platform deadline)

Section titled “§12.1 Public-schema grants compliance (May 30 platform deadline)”

[NEW-S236] From 30/05/2026, new tables in public will not be exposed to the Data API by default. Every future CREATE TABLE public.* migration must include explicit GRANT per role (anon / authenticated / service_role) before supabase-js, PostgREST, or GraphQL can access it. Pair with §12.2 in the same combined migration so RLS enable + grants land together (RLS-first, then grants).

  • Lands in: Combined migration enable_rls_auto_event_trigger_and_grants_pattern.sql (or split into two sequential migrations) + CLAUDE.md Supabase Gotcha addition + migration template / generator update so future tables include the grants block by default.

§12.2 OAuth token endpoint (May 26 platform deadline)

Section titled “§12.2 OAuth token endpoint (May 26 platform deadline)”

[NEW-S236] /v1/oauth/token will return HTTP 200 (not 201) from 26/05/2026 per OAuth 2.1 §3.2.3. Verify KH OAuth client surfaces in app/api/oauth/ (decision / grants / revoke) and any MCP-side token consumers do NOT branch on HTTP 201 specifically.

  • Lands in: Targeted check at app/api/oauth/* + MCP plugin OAuth client + a Vitest assertion that 200 is treated as success in any OAuth-token-handling code path.

§12.3 Auto-RLS event trigger (S236 — replaces audit_log RLS pattern)

Section titled “§12.3 Auto-RLS event trigger (S236 — replaces audit_log RLS pattern)”

[RATIFIED-S236] Adopt Supabase platform-recommended rls_auto_enable() event trigger (ddl_command_end on CREATE TABLE / CREATE TABLE AS / SELECT INTO, public schema only) platform-wide. Closes OQ-Q24-B + OQ-Q113-B together. Removes the recurring audit_log and per-tenant RLS-omission risk for any new public table. Cite 00-synthesis-v2.md §3.16.

  • Lands in: Dedicated RLS pattern doc + new migration enable_rls_auto_event_trigger.sql (combined with §12.1 grants helper).
  • Note: CLAUDE.md Gotcha already flags the orthogonal anon-EXECUTE issue for PL/pgSQL functions — keep that REVOKE-EXECUTE step in every function migration; the auto-RLS trigger covers tables only.
  • 2026-05-10 (kh-prod-readiness-S42 W4-warp-adoption): scaffold authored. Code refs grounded in HEAD 9446a98f. All P-N entries provisional; spike requirements + ratification gates noted inline.
  • 2026-05-14 (S238 in-place reconciliation): every [PROVISIONAL] flipped to [RATIFIED-S2XX] with source citation or [STILL-OPEN — gates on X] with explicit gating item. P-11 reframed from “hybrid write-back” to the seven-UC Candidate A/B/C set per 0.9-edit-flow-investigation.md §6. P-20 reframed from N:1 FK to corpus-level + scope_tag-driven per Q-OQR1-06. P-22 added (citations polymorphic enum, N8). P-40 reframed from “~5d HIGH cost” budget framing to combined-PR scope per Q-OQR1-16 (10 items). P-42 + P-43 added (procurement rename + application_types instance table). §10 Out-of-scope refreshed to point at PRODUCT.md §11 + §14 register. §11 Open implementation questions refreshed with RATIFIED markers on the items that are now closed. §12 Supabase platform compliance section added (S236 NEW items). Source-of-truth pointers updated to cite 00-synthesis-v2.md and INV-architecture-split-readiness.md. Note on 0.9-intended-architecture.md outdated-ness added per S237 Liam ruling.