Skip to content

Phase 0.8 — Synthesis: third-party-tooling re-framing of canonical pipeline plan

Phase 0.8 — Synthesis: third-party-tooling re-framing of canonical pipeline plan

Section titled “Phase 0.8 — Synthesis: third-party-tooling re-framing of canonical pipeline plan”

Audit date: 2026-05-08 Branch: content-items-investigation Predecessors: Phase 0.6 (synthesis #1) → 0.7.1-0.7.6 (architectural sub-investigations) → 0.7-synthesis (canonical pipeline plan) → user feedback (graphify, tRPC, kh-client, 0.7-synthesis) → 0.8.x parallel tool evaluations. Inputs: 7 evaluation outputs (skill-check, pullmd, cocoindex, skill-seekers, mempalace, open-multi-agent, Q&A trace) + 5 graphify baseline runs (no-LLM) + 2 graphify with-LLM runs (client-docs + code-only) + 1 graphify with-LLM run pending (code+docs full corpus).

Status: partial draft. Awaiting return of 0.8.8-qa-pipeline-trace.md and the full code+docs+LLM graphify run. Sections marked [PLACEHOLDER] will be updated once those land. The substantive findings + verdicts below do not depend on the outstanding work.


Three findings reshape the 0.7 plan materially:

  1. cocoindex is semantically the canonical pipeline core that 0.7 Stream 2 plans to build. A 6-8 week adoption (post-spike) replaces 9-12 weeks of bespoke construction, retires ~6,000-7,000 LOC of KH ingestion code, and architecturally enforces the A2-ratified re-upload-UPDATE behaviour for free. Single dominant unknown: schema-coupling (resolvable via 1-day spike). Recommendation: spike-and-decide.

  2. pullmd solves three open architectural questions simultaneously for URL inputs (P4 + P9 Tier 2-3): 0.7.4-Q7 (URLs → source_documents in v1), §3.1 (re-upload UPDATE via stable URL identity), and the URL portion of §3.2 (no bucket needed for URL inputs — pullmd IS the cache). share_id becomes the stable source_documents.storage_path sentinel. HYBRID re-use: pullmd as URL shape adapter inside cocoindex flow.

  3. mempalace’s design directly addresses two of the three client feedback items. The verbatim-first / strict-extraction design IS the answer to Item 3 (AI safety / scope tags / citation). The temporal-KG schema is the answer to “answer was right last quarter, may be wrong now”. Adopt Shape A (entity_relationships temporal columns) + Shape B (strict-extraction MCP mode) pre-launch.

Two findings extend the architectural lens:

  1. skill-seekers ships the exact 4-layer canonical pipeline architecture 0.7-synthesis §2 recommends KH adopt — battle-tested at 13.4k-star scale with 17 source adapters. Adopt-as-pattern (not module-import) for canonical pipeline Phase A; selectively integrate pdf_scraper (v2 PDF upgrade), openapi_scraper (NEW shape — api_specification), MarkdownCleaner cleanup helpers.

  2. skill-check catches at least one prior-bug class (the YAML-frontmatter trap from feedback_subagent_yaml_frontmatter.md) that no existing tool in the KH dev workflow surfaces. ~30-60 min integration cost, fills a real gap. Adopt as a CI step alongside knip.

Two findings constrain ambition:

  1. graphify adoption is well-validated for dev workflow (5 baselines committed) but not a candidate for canonical pipeline replacement. Distinct primitive from cocoindex (static analysis vs runtime data engine). Useful as pre/post re-ingest verifier; post-launch concept-map feature is deferred under cocoindex’s Neo4j target — they overlap.

  2. open-multi-agent is a net regression if adopted wholesale. KH’s existing Agent({ isolation: "worktree" }) + Spec-Code-Verify workflow is more disciplined. Borrow primitives onlyonTrace event taxonomy as a structured-log schema (~2-3 days, no dependency).

Three findings from the Q&A trace investigation reshape Phase F:

  1. Actual prod Q&A count is 395, not 440 (0.7-synthesis was wrong; never DB-verified).

  2. TWO Python ingest scripts produced 380 of the 395 rows — import_bid_library.py (P3 docx, 221 rows) AND ingest_stage2_markdown.py (159 rows). The second was MISSED by every prior audit. The 10-path inventory is incomplete — there are 11.

  3. The entire P6 (/api/items/batch) chain is TRUE-ORPHAN. Zero prod rows, zero pipeline_runs entries, no UI consumer. Phase F.4 shifts from “refactor P6 absorption” to “delete-not-refactor” — ~4,000-5,000 LOC removed wholesale.

Combined impact on Stream 1 effort:

Stream 1 collapses from 13 items to ~6 if cocoindex Option A is adopted. The “on hold” items (D2 source_documents parity, P7 silent-fail, OVERSIGHT helpers, RSS/batch chunks regen wiring, ingestion_quality_log helper, swallow-catch surfacing) are mostly absorbed by cocoindex’s engine semantics. Stream 1 becomes ~6 hours of work (items 1, 3, 5, 6, 7, 11 — schema-side fixes) regardless of cocoindex decision.

Updated Stream 2 effort:

PathTotal effortCode retained
Build canonical pipeline (Phase 0.7 Stream 2 as planned)9-12 weeksAll of lib/extraction/, scripts/kb_pipeline/, much of lib/ingest/
Adopt cocoindex Option A6-8 weeks (post 3-5 day spike)~500-800 LOC declarative flow + dependency

Overall confidence: 84% (drag from: cocoindex schema-coupling unverified hands-on; LiteLLM Anthropic prompt-cache passthrough unverified; 6th graphify run + Q&A trace pending; final ratification depends on Liam’s read of trade-offs).


2. Reframed framing — three correction loops

Section titled “2. Reframed framing — three correction loops”

2.1 “Same scarce hours” was a wrong framing

Section titled “2.1 “Same scarce hours” was a wrong framing”

The graphify and tRPC evaluations defaulted to “defer to post-launch” via a launch-readiness lens that the user explicitly invalidated in 07-synthesis-feedback.md:

“Be cautious using timelines (e.g., ‘~5-7 weeks; ~16-19h’) — if you consider that the current platform was built over the past 6-8 weeks, that should provide an indication of how different development timeframes are when building agentically in an AI-human paired-programming environment.”

“we are potentially scaling back considerable complexity/duplication in the platform” — not under time pressure.

Correction applied across all 0.8.x evaluations: the lens is “what should we be doing” not “lowest-disruption to current code”. Bias toward re-use of battle-tested infrastructure when it pays.

The 7 sub-agents were briefed with this correction explicitly. Their verdicts where pre-launch architectural changes are recommended (cocoindex, mempalace Shape A+B, skill-seekers patterns, pullmd URL shape adapter) are deliberate applications of the corrected lens — not premature adoption.

2.2 The 4-layer canonical pipeline plan validates externally

Section titled “2.2 The 4-layer canonical pipeline plan validates externally”

skill-seekers independently arrived at the same architecture KH planned in 0.7-synthesis §2:

Skill-Seekers layer (production at 13.4k-star scale)KH planned Layer 1-4 (per 0.7-synthesis §2)
Per-source adapter (SkillConverter subclass)Layer 3 shape adapter
CONVERTER_REGISTRY central dispatchLayer 2 input-shape router
Unified scraper merge layerLayer 4 canonical core
Output exporter (vector DB / file system)Side-channel writes

Three independently validated reference points (KH 0.7 plan, skill-seekers production code, cocoindex flow model) converge on the same architectural shape. The architecture is not speculative.

2.3 The “do we need binary storage” question dissolves

Section titled “2.3 The “do we need binary storage” question dissolves”

07-synthesis-feedback.md line 61:

“Do we need to store binaries? If all content is extracted to markdown anyway, and we have the file provenance (for audit purposes), could all content be saved as markdown in a DB column/table?”

Two tools answer this from different angles:

  • pullmd for URL inputs: share_id IS the stable identifier. No bucket needed for URL inputs ever. source_documents.storage_path = pullmd://${share_id} becomes the sentinel.
  • cocoindex for binary inputs: source-key + content-hash IS the engine’s incremental model. Bucket storage becomes a separate audit-trail concern (decoupled from the pipeline). Re-upload of same logical-doc-id with new content → engine re-runs flow → UPDATEs target row. Bucket storage becomes optional v2 work (“download original” UX symmetry) or even retired entirely (if SharePoint/Notion sync is the v2 answer).

Net answer to NEW5/NEW7: the bucket-vs-column question is the wrong question. The right question is “what’s the stable source-key at upload time?” — and both tools answer that without requiring binary persistence.


ToolLensVerdictConfidenceAdoption sequencingEffort
cocoindexPlatformRe-use Option A (canonical pipeline substrate) — conditional on schema-coupling spike80%Spike (3-5 days) → decide → 6-8 weeks if goReplaces Stream 2 9-12 weeks
pullmdPlatformHYBRID re-use as URL shape adapter for P4 + P9 Tier 2-384%Within Phase A foundation (~3-3.5 weeks)Drop ~1k LOC of KH URL extraction
skill-seekersPlatformAdopt-as-pattern + selective module import (3 strong / 3 conditional / 5 don’t)88%Phase A patterns reference; v2 PDF upgrade; new api_specification shapeMixed
mempalacePlatform + devAdopt Shape A + B pre-launch; Shape C deferred84%A: with re-ingest (Q1 captured_date alignment); B: Stream 1 (~1.5 days)Schema migration + new MCP mode
graphifyDev workflowInstalled + integrated (this branch). 5 baselines committed. Post-launch concept-map deferred under cocoindex Neo4j target88%Already donen/a
skill-checkDev workflowAdopt as CI step alongside knip88%Stream 1 (~30-60 min)Catches YAML-frontmatter regressions
open-multi-agentDev workflowBorrow onTrace schema only; no wholesale adoption86%Adopt as structured-log schema (~2-3 days)No new dependency

4. Per-tool deep dive (where verdict differs from initial framing)

Section titled “4. Per-tool deep dive (where verdict differs from initial framing)”

4.1 cocoindex — the canonical pipeline core

Section titled “4.1 cocoindex — the canonical pipeline core”

File: 0.8.2-cocoindex-evaluation.md (655 lines, 80% confidence)

Single biggest finding: the engine’s per-row content-hash + per-stage code-hash memoisation semantically IS the canonical pipeline core that Phase 0.7 Stream 2 was going to spend 2 weeks building from scratch. The Phase 0.7 plan’s whole point — collapse-to-one-canonical-core with chokepoint guarantees on source_domain, platform, content_owner_id, pipeline_runs, ingestion_quality_log, AI-telemetry — is exactly what cocoindex provides as battle-tested Apache 2.0 infrastructure.

Re-ingest cycle disappears. Today’s plan: explicit re-ingest of 617 prod rows in weeks 3-4 of Stream 1. Under cocoindex: the engine’s incremental Δ runs cocoindex update once on the empty staging DB; future runs only recompute changed rows. Re-ingest as a discrete concept retires.

Re-upload UPDATE behaviour (A2 ratified yes) becomes engine-native. When the source binding’s key is logical-doc-id (not filename), engine sees same key + new content-hash → UPDATEs existing target row → content_history v2 written via existing DB trigger. The biggest single UX unlock from Phase 0.7 §3.1 happens automatically rather than via custom build.

Stream 1 collapse. Items 2 (D2 source_documents parity), 4 (P7 silent-fail), 8 (OVERSIGHT helpers), 9-10 (chunks regen), 12 (ingestion_quality_log helper), 13 (swallow-catch surfacing) are absorbed by cocoindex’s flow + emitter pattern. Stream 1 collapses from 13 items to ~6 (items 1, 3, 5, 6, 7, 11 — schema-side fixes that need to happen regardless).

Effort comparison:

DimensionBuild canonical core (Phase 0.7 Stream 2)Adopt cocoindex (Option A)
Effort9-12 weeks6-8 weeks (post-spike)
Code retained7,400+ LOC ingestion + orchestration~500-800 LOC declarative flow + dependency
Re-ingest cycleManual, weeks 3-4 of Stream 1Engine-native incremental Δ
Re-upload UPDATECustom buildEngine-native
Long-term maintenanceKH owns 7,400+ LOCKH owns ~500-800 LOC

Single dominant unknown — schema-coupling (Scenario A vs B). Does postgres.mount_table_target(PG, "content_items") accept the existing 70-column schema with FKs and triggers (Scenario A — desired), or does it want schema ownership (Scenario B — fallback)? Resolvable via 1-day spike. If Scenario A: 6-8 weeks. If Scenario B: 12-16 weeks (significant fallback cost) and case weakens.

Other open questions (8 enumerated in 0.8.2 §7):

  • LiteLLM Anthropic prompt-cache passthrough (1-day prototype gates classification cost)
  • docling vs KH’s unpdf + mammoth + turndown chain (2-day comparison study)
  • Operations DB at scale (load test in spike)
  • Concurrency on Cloud Run (docs review + spike)
  • TypeScript subprocess wrapping for extract-qa-pairs.ts — code-hash semantics
  • RSS staging-table handoff design
  • Backout plan if cocoindex underperforms

Recommendation: Spike-and-decide. 3-5 day cocoindex schema-coupling validation, in parallel with user-approved Stream 1 items 1/3/5/6/7/11. Decision gate at end of week 1. If go: 6-8 weeks Option A. If no-go: 9-12 weeks Phase 0.7 Stream 2 as planned.

File: 0.8.4-pullmd-evaluation.md (639 lines, 84% confidence)

Single biggest finding: pullmd’s share_id becomes the source_documents identity for URL inputs. This directly resolves three open questions in 0.7-synthesis:

  • 0.7.4-Q7 (URLs → source_documents in v1): yes, via pullmd_share_id typed column. URLs become first-class source_documents with stable provenance.
  • §3.1 re-upload UPDATE behaviour for URLs: same URL → same share_id → engine sees stable key + new content-hash → UPDATEs existing content_items row.
  • §3.2 binary-bucket question (URL portion): no bucket needed for URL inputs — pullmd IS the cache. storage_path = pullmd://${share_id} sentinel.

Verdict: HYBRID re-use as URL shape adapter for P4 + P9 Tier 2-3. It does NOT replace P4 entirely — the EXTRACTION step swaps but auth/dedup/classify/embed/chunk all stay KH-side. PDFs (unpdf), binaries (mammoth), and markdown inputs are out of pullmd’s scope.

Drop candidates if pullmd ships:

  • lib/extraction/html.ts
  • @mozilla/readability + jsdom dependencies
  • @mendable/firecrawl-js (if Playwright path covers Cloudflare + Google News)
  • FIRECRAWL_API_KEY env var

Turndown stays for P9 Tier 1 (RSS content:encoded).

Two GO/NO-GO gates:

  • PM-Q1: 50-URL bake-off vs current extractor — extraction quality must match or exceed
  • PM-Q2: AGPL v3 acceptable for self-hosted use (KH would be running pullmd on its own infra; AGPL only triggers if pullmd’s code is modified — direct re-use is fine, but worth Liam sign-off)

Effort: ~3-3.5 weeks v1 for Phases A-D (foundation + P4 swap + P9 swap + cleanup). Lands BEFORE re-ingest, not after — pullmd’s share_id becomes the source-key cocoindex’s engine binds to.

Sequencing under cocoindex Option A: pullmd’s URL fetcher runs inside a @coco.fn URL shape adapter. The flow is cocoindex source (logical-doc-id) → pullmd HTTP fetch → markdown → cocoindex pipeline core → Postgres targets. Both tools layer cleanly.

4.3 skill-seekers — architectural mirror + targeted module import

Section titled “4.3 skill-seekers — architectural mirror + targeted module import”

File: 0.8.5-skill-seekers-evaluation.md (~770 lines, 88% confidence)

Single biggest finding: skill-seekers ships the exact 4-layer canonical pipeline architecture that 0.7-synthesis §2 recommends KH adopt — production code at 13.4k-star scale with 17 source adapters. Strong external validation that the architecture is right.

Verdict: HYBRID — adopt-as-pattern + selective module import.

ModuleAdopt verdictEffortSequencing
SkillConverter base class + CONVERTER_REGISTRYPATTERN INSPIRATION for canonical pipeline Layer 3n/aPhase A reference
doc_scraper.py (BeautifulSoup + llms.txt + sitemap)HYBRID — keep Readability for single-URL; add for bulk-docs-site ingest (NEW use case)~1 weekPost-launch
pdf_scraper.py + pdf_extractor_poc.pySTRONG INTEGRATE for v2 — replaces unpdf with chapter detection + OCR + image extraction~2 weeksv2 (post-launch) — pdfplumber + Pillow + Tesseract footprint shift
word_scraper.pyPARTIAL ADOPT — same toolchain (mammoth + python-docx); add metadata extraction pattern~3-4hStream 1
MarkdownCleanerADOPT cleanup helpers (remove_html_tags, extract_first_section)~1-2hStream 1
RAGChunkerDON’T REPLACE (KH heading-based is correct for Q&A-dominant corpus). Optionally add token-budget mode for headingless corpora~150 LOCPost-launch
embedding_pipeline.py (cache + cost tracking)CONSIDER cost-tracking + disk-cache patterns~1 dayPost-launch
code_analyzer.py + dependency_analyzer.pyNICHE ADOPT as 3rd build-not-wired-detector alongside Knip + Graphify~1-2 daysOptional
openapi_scraper.pySTRONG ADOPT — adds api_specification content type~1 weekNew shape, can ship anytime post-Phase A

Notable non-adoptions:

  • Skill-Seekers’s categories config field as a keyword-rule tier of scope inference that runs before AI classification → directly addresses client feedback Item 3 (scope tags). KH could adopt this pattern for internal-it / production-infrastructure / application-layer taxonomy.
  • Skill-Seekers’s “conflict detection” does NOT solve LBBD-CSP scope-tag problem (different problem class — see eval §2.4).

4.4 mempalace — temporal KG schema + strict-extraction

Section titled “4.4 mempalace — temporal KG schema + strict-extraction”

File: 0.8.7-mempalace-evaluation.md (537 lines, 84% confidence)

Two findings of critical importance:

  1. mempalace’s schema IS what KH’s entity_relationships should become. The temporal-KG triple shape (subject, predicate, object, valid_from, valid_to, confidence, source_drawer_id, adapter_name) solves the “answer was right last quarter, may be wrong now” problem KH currently has no answer for. Add valid_from, valid_to, confidence, source_content_item_id, adapter_name columns to entity_relationships. Implement kg_invalidate(subject, predicate, object, ended) and kg_timeline(entity, as_of) as RPCs.

  2. mempalace’s verbatim-first design IS the answer to client feedback Item 3. “AI safety needs the hub to enforce citation, not just answer” is exactly what mempalace’s mission doc and CLAUDE.md frame as their architectural answer to “AI confidently pulling correct content from the wrong domain”. Add mode='strict_extract' parameter to search_knowledge_base MCP tool that returns only verbatim chunk + source content_item_id + chunk_id, no LLM rephrasing.

Adopt: Shape A + Shape B PRE-LAUNCH (per the corrected lens — these aren’t speculative; client has already articulated the gap they fill).

ShapeWhat it addsEffortSequencing
A — Temporal-KG columns on entity_relationshipsvalid_from / valid_to / confidence / source_content_item_id / adapter_name + kg_invalidate/kg_timeline RPCs~3-5 daysWith re-ingest (populate valid_from from content_items.captured_date per Q1)
B — Strict-extraction MCP modemode='strict_extract' parameter on search_knowledge_base; returns verbatim chunk + cite-or-refuse~1.5 daysStream 1 (independent of canonical pipeline)

Shape C (per-user memory via mempalace MCP server) deferred. Stdio-only MCP transport doesn’t fit Claude.ai’s HTTP MCP architecture. Revisit if v4-alpha PostgreSQL backend stabilises (mempalace ROADMAP.md mentions PG backend in review).

Shapes D + E don’t pursue. D (fork mempalace + Supabase backend) is too much commit; E (wholesale embed) doesn’t fit KH’s existing Pass 1/Pass 2 classification semantics.

Direct response to client feedback Item 1 (list_user_workspaces schema mismatch): mempalace’s mempalace_search exposes wing= filter as the exact analog of KH’s workspace_id filter that was broken. This is independent infrastructure validation that the design pattern is correct.

File: 0.8-synthesis.md (this doc) §9 — graphify baseline runs

5 of 6 graphify baseline runs committed (code-and-docs-no-llm, code-only-no-llm, client-docs-no-llm, code-only-with-llm, client-docs-with-llm). 6th (code-and-docs-with-llm) running in background — synthesis will update when complete.

Headline numbers (no-LLM, full corpus):

MetricValue
Files2,461
Words4,738,799
Nodes30,520
Edges44,935
Communities2,051
Isolated nodes20,615
Wall clock9.5 s
Cost0 (deterministic AST + line-based markdown)

20,615 isolated nodes is the headline structural signal — substantially larger than Phase 0.2.5 surfaced manually. Detailed classification deferred to a build-not-wired follow-up audit (cheap to do; ~1-2 sessions). Many will be intentional (test fixtures, documentation excerpts) but a non-trivial subset is likely TRUE-POSITIVE-FIX-NOW.

God nodes top 10 (corroborate tRPC eval boilerplate findings):

  1. safeErrorMessage() — 361 edges
  2. authFailureResponse() — 348 edges
  3. cn() — 339 edges
  4. getAuthorisedClient() — 299 edges
  5. parseBody() — 196 edges
  6. Button() — 187 edges
  7. createMockSupabaseClient() — 168 edges
  8. logger — 125 edges
  9. createTestRequest() — 117 edges
  10. checkRateLimit() — 105 edges

The getAuthorisedClient() + parseBody() + checkRateLimit() cluster is exactly the per-route middleware the tRPC eval flagged as boilerplate that would collapse under a typed-route wrapper. Strong validation that the tRPC concern is real — but does NOT change the verdict (Option α — typed defineRoute() wrapper, post-launch per trpc-evaluation.md §6.3, with the corrected-lens caveat that the API surface will shrink under canonical-pipeline collapse — fewer routes to migrate).

Client docs no-LLM run: 30 files / 111K words / 764 nodes / 613 isolated. Top concepts:

  • Security & Information Governance (24 edges)
  • Website — Tender and Bid Library (Schema Format) (17)
  • LMS — Tender and Bid Library (Schema Format) — v2.2 (15)
  • Knowledge Hub — Platform Overview (15)
  • BID RESPONSE TOPIC INDEX (15)

These hubs corroborate client feedback Item 2 (search underperforming on FUNC-XXX entries that ARE in the source files). The graph confirms FUNC-XXX content is structurally connected to bid-library hubs but probably has the wrong content_type (not q_a_pair) at ingest time. Fixes via canonical pipeline + scope-tag taxonomy + classifier prompt.

Verdict: graphify install on this branch is complete and operational. Pre/post re-ingest comparison artefacts are in place. Post-launch concept-map feature (graphify Option A in original eval) is deferred — cocoindex’s Neo4j target gives the same primitive natively.

4.6 skill-check — narrow CI step, real gap

Section titled “4.6 skill-check — narrow CI step, real gap”

File: 0.8.3-skill-check-evaluation.md (331 lines, 88% confidence)

Verifiably catches the YAML-frontmatter trap from feedback_subagent_yaml_frontmatter.md (the silent un-registration bug class). Synthesised the exact failure shape (multi-line description + blank line + <example> tag); skill-check emits ERROR frontmatter.required with parser message at line 2 column 14. No existing tool in KH dev workflow catches this — knip + ESLint + vitest sweep + prettier + doc-freshness guard all run on different surfaces.

Grounded run on KH’s 13 skills: scored 94/100 in 15ms. 0 errors, 6 warnings (5× missing “Use when” phrasing; 1× false-positive broken local link in update-docs/SKILL.md:101).

Verdict: adopt as a CI step alongside knip.

  • SC1 install (bun add -d skill-check) — 90% confidence
  • SC2 scope to KH-owned skills only (.claude/skills/* + .claude/plugins/knowledge-hub/1.0.0/skills/*), NOT user-level ~/.claude/skills/ or marketplace caches — 92% confidence
  • SC3 run --fix once on existing skills — 88% confidence
  • SC6 ship before re-ingest work — 90% confidence

Effort: ~30-60 min total (config + CI wiring).

Out-of-scope: skill-check’s --security-scan mode delegates to mcp-scan (Python). For MCP-tool-injection scanning, invoke mcp-scan directly — separate tool decision.

4.7 open-multi-agent — borrow, don’t adopt

Section titled “4.7 open-multi-agent — borrow, don’t adopt”

File: 0.8.6-open-multi-agent-evaluation.md (551 lines, 86% confidence)

Verdict: net regression if adopted wholesale.

KH’s Agent({ isolation: "worktree" }) + Spec-Code-Verify workflow is filesystem-isolated, plan-persistent, verifier-gated, sequential-cherry-pick-merged. OMA’s coordinator is process-shared, plan-ephemeral, end-to-end-automated. The coordinator pattern does not solve KH’s actual failure modes (spec-assumption, build-not-wired, silent failures, worktree mechanics drift, test mock drift) and would remove the discipline that makes KH’s parallel work safe.

Selective primitive borrowing is the right shape:

  1. Adopt OMA’s onTrace event taxonomy as KH’s structured-log schema for agent dispatches — ~2-3 days, no OMA dependency, aligns with deferred ai_call_log work. Highest ROI from this evaluation.
  2. Production-checklist audit of lib/ai/draft.ts + queue handlers against OMA’s 6 controls — surfaced real gaps: no maxTokenBudget enforcement anywhere (runaway risk), no structured trace correlation, retry policies live at queue layer not AI layer.
  3. Defer Phase 2 sector-intelligence + Sales Proposals proposal-generation evaluation as backlog items OPS-OMA1 + OPS-OMA2.

Counter-pattern: the bespoke 4-pass shape in lib/ai/draft.ts is faster and lower-risk than re-shaping it as OMA runTasks() calls. KH should not “modernise” this code with multi-agent abstractions.


5. Re-framed answers to NEW5 / NEW7 — storage may collapse entirely

Section titled “5. Re-framed answers to NEW5 / NEW7 — storage may collapse entirely”

The 0.7-synthesis recommended for NEW5 (D2 markdown storage_path): “Nullable for v1 (or sentinel inline://${id}); add markdown bucket in v2.”

Re-framed: under cocoindex + pullmd adoption, the storage question dissolves for the main flow:

Input shapev1 storage answer (under cocoindex + pullmd)
URL (P4 + P9)pullmd_share_id typed column + sentinel pullmd://${share_id} storage_path. No bucket needed. pullmd IS the cache.
Document-binary (P7 PDFs, DOCXs)Source-key = logical-doc-id; cocoindex tracks content-hash in ops-DB. Bucket optional (audit-trail only — separate concern from pipeline).
Document-text (P8 markdown batch)Source-key = logical-doc-id; markdown IS the canonical text in content_items.content. storage_path = NULL or sentinel inline://${id}.
Q&A docx (P3)Same as binary. Bucket optional for audit.

For the audit-trail concern (legal/compliance — “show me the original PDF the user uploaded”), upload to a dedicated audit bucket (or v2 SharePoint integration per user’s note) — separate from cocoindex’s flow. cocoindex tracks WHAT was extracted; the bucket tracks WHAT WAS UPLOADED. They’re decoupled.

Recommendation: NO main-flow bucket in v1. Markdown lives in content_items.content. Binaries are extracted-and-discarded by cocoindex (or audit-bucket-archived for compliance). v2 evaluates SharePoint/Notion sync as the storage layer.

Re-upload detection (NEW7): under cocoindex, engine handles natively. New content-hash for same source-key → recompute → UPDATE existing target row → content_history v2 written via auto-version trigger. No detect_reupload RPC needed for the markdown path; the existing P7 RPC retires for the binary path too once cocoindex’s source-key model is in.


Item 1 — list_user_workspaces returns array, schema declares record

Section titled “Item 1 — list_user_workspaces returns array, schema declares record”

Status: small fix. May already be resolved — verify in Stream 1 worktree.

If not yet fixed: wrap response in { "workspaces": [...] } object, update output schema. ~30 min. Stream 1 candidate (could fold into items 1/3/5/6/7/11 worktree work).

Item 2 — Search underperforming (FUNC-XXX, semantic similarity, default limit 5, domain filter too restrictive)

Section titled “Item 2 — Search underperforming (FUNC-XXX, semantic similarity, default limit 5, domain filter too restrictive)”

Status: architecturally shaped by canonical pipeline + scope-tag introduction.

Diagnosis (cross-referenced with graphify client-docs run):

  1. FUNC-XXX content NOT in q_a_pair content_type. Graphify’s god-nodes confirm bid-library hubs are structurally connected to FUNC-XXX entries but probably classified as feature_specification or similar at ingest. Fix: classifier prompt update to recognise FUNC-XXX as Q&A-shaped content; canonical pipeline’s classifier becomes single chokepoint.

  2. Semantic similarity ranking weak when vocab differs (PCI-DSS ↔ “payment providers”). Two paths:

    • Cross-encoder reranker (post-vector-search) — proven pattern; ~1-2 weeks build
    • Query expansion at search time using LLM — cheaper to ship; lower quality ceiling
    • Recommend cross-encoder for Stream 2 / post-canonical-pipeline.
  3. Default limit 5 too low. Trivial fix. ~10 min change. Stream 1 candidate.

  4. Domain filter too restrictive. Architectural — solved by Item 3’s scope-tag taxonomy. Filter on scope (production-infrastructure) AND domain (security) becomes a 2-D filter that includes adjacent content rather than excluding it.

Item 3 — Hard scope tags + enforced citation + strict-extraction mode

Section titled “Item 3 — Hard scope tags + enforced citation + strict-extraction mode”

Status: directly addressed by mempalace Shape B (strict-extraction MCP mode) + skill-seekers categories pattern (keyword-rule scope tier) + canonical pipeline classifier.

Proposed scope-tag taxonomy (per client feedback): internal-it / production-infrastructure / application-layer / office-physical / data-centre-physical + anti-tags (“does not apply to: production infrastructure” on Bitdefender content).

Implementation:

  1. New typed column content_items.scope_tag (or ARRAY column for multi-scope content). Migration in Stream 1.
  2. Anti-tags via content_items.anti_scope_tags ARRAY — explicit “does not apply to” set. Migration in Stream 1.
  3. Skill-seekers categories config pattern as keyword-rule tier in classifier — runs BEFORE AI classification, sets default scope. Adoption: ~3 days.
  4. Mempalace Shape B strict_extract MCP mode — verbatim-only retrieval with mandatory citation. ~1.5 days.
  5. MCP tool search_knowledge_base extended with scope_tag and anti_scope_tag filter parameters. ~1 day.

Total: ~7-9 days for full resolution of Item 3. Lands in Stream 1 (mempalace Shape B + scope-tag schema migration) + Phase A (canonical pipeline classifier integration).


7. Updated Stream 1 / Stream 2 plan with cocoindex spike

Section titled “7. Updated Stream 1 / Stream 2 plan with cocoindex spike”

7.1 Updated Stream 1 (re-ingest readiness gates) — collapse from 13 items to ~6

Section titled “7.1 Updated Stream 1 (re-ingest readiness gates) — collapse from 13 items to ~6”

Approved by user (Stream 1 worktree, separate session):

#ItemEffortStatus
1D1 markdown_batch ingest_source value~30 minApproved
35 P0 missing FKs on content_items~1hApproved
5P0-2 fix feed_prompts fire-and-forget~1hApproved
6Drop migrations notes/source_bid (verify parent_id still correct given 0.7.4 findings)~1hApproved
7Reader rewrites for source_document text + drop migration~3hApproved
114 knip TRUE-POSITIVE-FIX-NOW items~1hApproved

Total approved Stream 1: ~7-8 hours.

Items moved to “absorbed by cocoindex Option A” (if adopted):

#ItemCocoindex absorption mechanism
2D2 EP2 source_documents paritySource-key model dissolves the question
4P0-1 Path 7 silent-failEngine’s failure-isolation replaces try/catch handling
8OVERSIGHT helpers (source_domain, platform, content_owner_id, pipeline_runs)Folded into cocoindex flow stages
9RSS chunks regen wiringChunks regenerate automatically when chunking logic changes
10Batch chunks regen wiringSame
12TS-side ingestion_quality_log helper (~3 days)Replaced by custom emitter @coco.fn (~half day)
13Path 7 swallow-catch user surfacing specStill needed (UX, not pipeline); pipeline failure-isolation is engine-native

Items added to Stream 1 from 0.8.x recommendations:

#New ItemSourceEffort
14skill-check installation + CI integration0.8.3~30-60 min
15mempalace Shape B (strict-extraction MCP mode)0.8.7~1.5 days
16Scope-tag taxonomy schema migration (scope_tag + anti_scope_tags)Client Item 3~1 day
17search_knowledge_base MCP tool — scope_tag filter parametersClient Item 3~1 day
18Skill-seekers categories keyword-rule tier in classifier0.8.5~3 days
19open-multi-agent onTrace schema as KH structured-log schema0.8.6~2-3 days
20mempalace Shape A (entity_relationships temporal-KG columns)0.8.7~3-5 days
21Default search limit raised from 5 to 10 (or configurable)Client Item 2~10 min

Total NEW Stream 1 items: ~10-13 days additional work (depending on which are scoped). All independent of A1 ratification (they don’t depend on cocoindex decision).

7.2 Updated Stream 2 sequencing under cocoindex Option A

Section titled “7.2 Updated Stream 2 sequencing under cocoindex Option A”
Week 1: cocoindex schema-coupling spike (3-5 days, parallel)
+ Stream 1 user-approved items (~7-8h, parallel)
+ Stream 1 new items 14-21 (~10-13 days, parallel)
Decision gate: end of week 1 — go/no-go on cocoindex Option A.
If GO (recommended):
Weeks 2-3: cocoindex foundation
- flow.py skeleton + Postgres targets bound + first shape (markdown text) end-to-end
- LiteLLM Anthropic prompt-cache validation
- Operations DB persistence design (GCS volume on Cloud Run)
Weeks 4-5: Shape adapters + pullmd integration
- URL adapter (pullmd inside @coco.fn)
- document-binary (docling-based)
- qa-docx subprocess-wrap (wraps existing TS extract-qa-pairs.ts)
Week 6: Custom emitters
- pipeline_runs + ingestion_quality_log + post-stage adapters
Week 7: RSS staging-table integration + migration off existing pipeline
Week 8: Cutover + re-ingest (engine's incremental Δ runs once on empty DB)
If NO-GO:
Weeks 2-13: Phase 0.7 Stream 2 as originally planned (9-12 weeks)

Re-ingest happens at the end of Stream 1 if GO; replaced by cocoindex’s incremental Δ. If NO-GO: re-ingest happens in week 3 (post Stream 1) per the 0.7-synthesis sequencing.

7.3 Backlog post-launch (per per-tool evaluations)

Section titled “7.3 Backlog post-launch (per per-tool evaluations)”

Aggregated from 0.8.2 / 0.8.3 / 0.8.4 / 0.8.5 / 0.8.6 / 0.8.7:

  • OPS-T1 (typed defineRoute() wrapper) — original tRPC §6.3 backlog. Defer until canonical-pipeline-collapse is complete (fewer routes to migrate)
  • OPS-PM-1 (pullmd Reddit content-modeling) — defer; product decision
  • OPS-SS-1 (skill-seekers pdf_scraper v2 PDF upgrade) — ~2 weeks; pdfplumber + Pillow + Tesseract footprint
  • OPS-SS-2 (openapi_scraper for api_specification content type) — ~1 week; new product capability
  • OPS-MP-1 (mempalace Shape D — fork + Supabase backend) — re-evaluate post-v4-alpha PG backend stable
  • OPS-OMA-1 (open-multi-agent for Phase 2 sector-intelligence dispatcher) — re-evaluate post-launch
  • OPS-OMA-2 (open-multi-agent for Sales Proposals 4-pass) — re-evaluate when Sales Proposals app is in design
  • OPS-G-1 (graphify Option A — workspace concept map) — deferred under cocoindex Neo4j target overlap; re-evaluate if cocoindex doesn’t ship

8. Q&A pipeline trace — substantial corrections to 0.7-synthesis

Section titled “8. Q&A pipeline trace — substantial corrections to 0.7-synthesis”

File: 0.8.8-qa-pipeline-trace.md (669 lines, 88% confidence)

The Q&A pipeline trace investigation surfaced eight corrections to prior audits. Several materially change the canonical-pipeline Phase F sequencing:

0.7-synthesis and 0.1-qa-docx-import quoted 440 without DB verification. The correct count is 395. Effort estimates that depended on row count (e.g. backfill scope) need ±10% adjustment.

8.2 TWO Python ingest scripts produced 380 of the 395 rows — not one

Section titled “8.2 TWO Python ingest scripts produced 380 of the 395 rows — not one”

Prior audits (0.1-qa-docx-import, 0.7-synthesis, 0.7.2) only identified scripts/import_bid_library.py (P3, the docx pipeline). A second script — scripts/ingest_stage2_markdown.py — produced 159 of the 395 prod rows from client-supplied stage2 markdown files (Advanced_Audits_v5, LMS_v2.2, Website_v4_2).

This script’s existence was missed by every prior audit including the 10-path enumeration. It’s a hidden 11th path. Implications:

  • The “10 paths” inventory in 0.7-synthesis is incomplete — there are 11.
  • Phase F (P3 Q&A retire via EP8) was scoped against only 221 docx rows. The 159 stage2-markdown rows need a separate retire path.
  • The ingestion-source-uniformity work (OVERSIGHT cluster) skipped this script’s contribution.

8.3 qa_import ingest_source bucket is a backfill artefact

Section titled “8.3 qa_import ingest_source bucket is a backfill artefact”

S207 (backfill_ingest_source.sql migration) collapsed both Python scripts onto the qa_import label via heuristic WHEN platform='extraction' THEN 'qa_import'. The current ingest_stage2_markdown.py writes python_markdown per its current code, but the 159 prod rows still say qa_import because they pre-date the script’s update.

Implication: the 159 mis-bucketed rows need a cleanup migration independent of canonical pipeline — they’re already mis-labelled in prod and will misclassify in any audit that filters by ingest_source.

  • 7 from MCP create_content_item (Doncaster batch by Matthew Burgess)
  • 8 from E2E test fixtures

Both are correct provenance, no action needed.

8.5 0.7.6’s detectQAPairs() claim was correct — and broader than stated

Section titled “8.5 0.7.6’s detectQAPairs() claim was correct — and broader than stated”

The entire P6 (/api/items/batch) chain is TRUE-ORPHAN — zero rows in prod from that route, zero pipeline_runs.pipeline_name='qa_autosplit' rows, the only UI consumer requires a prop that’s never passed. The “paste-from-spreadsheet UI” the synthesis described does not exist.

This shifts Phase F.4 from “refactor P6 absorption into P8” to “delete-not-refactor the entire P6 + qa-detection chain” — ~4,000-5,000 lines of code can be removed wholesale.

The directory’s DOCX/markdown extractor (extract-qa-pairs.ts, docx-to-markdown.ts) is BUILT-NOT-WIRED. Its extract-answer.ts and resolve-question.ts ARE production-USED, but only on the EDIT path (MCP create + PATCH), not for ingest.

Implication: the directory name suggests an ingestion role it does not have. Renaming or splitting (e.g. lib/qa-edit-helpers/ for the production-USED parts; deletion for the BNW parts) is a Stream 1 candidate.

  • F.2 — port ingest_stage2_markdown.py to canonical adapter: ~1.5-2 weeks (NEW work; this script wasn’t in the original Phase F scope)
  • F.4 — delete-not-refactor the entire P6 + qa-detection chain: ~0.5 week (~4,000-5,000 LOC removed)
  • Net Phase F effort: ~5.5-7.5 weeks (vs prior 5-7 weeks). Cleaner scope; the porting work is balanced by the deletion work.

Under cocoindex Option A: Phase F still applies (Q&A docx is a custom shape adapter; stage2 markdown is the markdown shape). Effort estimates are similar.

8.8 source_documents empty + zero Q&A pipeline_runs telemetry

Section titled “8.8 source_documents empty + zero Q&A pipeline_runs telemetry”

Two operational findings that confirm 0.7.4 + flag a separate issue:

  1. source_documents table has 0 rows in prod. Confirms 0.7.4 P0-1 silent-fail finding. The 395 Q&A rows have NULL source_document_id. Under cocoindex: source-key model dissolves the gap. Under no-cocoindex: D2 implementation must backfill from existing source_file text.

  2. Zero pipeline_runs entries from any Q&A ingest — P3 docx, P2-stage2, P10 MCP all telemetry-invisible. Both Python scripts skip recordPipelineRun() entirely. This is a regression risk for re-ingest (we have no historical telemetry to compare against). Stream 1 should add recordPipelineRun() to both Python scripts before re-ingest.

8.9 Implications for B1 (P3.B keyword vs AI classify)

Section titled “8.9 Implications for B1 (P3.B keyword vs AI classify)”

The trace surfaces that the question is per-source-shape, not per-path:

  • 221 docx rows (from import_bid_library.py) use keyword_classifier today
  • 159 stage2-markdown rows (from ingest_stage2_markdown.py) — verify classification mode in trace doc

Recommendation: refine B1 to ratify per-source-shape:

  • B1.A — Q&A docx shape (221 rows): AI classify with 50-row eval gate (per 0.7-synthesis recommendation)
  • B1.B — Q&A markdown shape (159 rows): AI classify with quality eval (currently using ?, awaiting trace doc detail)

8.10 Five new open questions (per 0.8.8 §6)

Section titled “8.10 Five new open questions (per 0.8.8 §6)”
  • D13 — stage2 ingest as permanent path or one-shot client-data-load? (May retire if EP8 + canonical-markdown UI ships.)
  • D14 — P3.B per-source-shape ratification (replace B1 with B1.A + B1.B per §8.9 above).
  • D15 — Cleanup migration for 159 mis-bucketed qa_import rows: ratify? (~30 min migration; should ship Stream 1 for analytical correctness.)
  • D16section_name semantic in Q&A schema — what’s its intended meaning post-canonical-pipeline?
  • D17 — Phase F.4 retirement scope — confirm “delete-not-refactor entire P6 + qa-detection chain”? ~4,000-5,000 LOC removal is the largest single deletion in the canonical-pipeline plan.

5 of 6 baselines committed; 6th (code-and-docs-with-llm) running.

RunFilesWordsNodesEdgesCommunitiesIsolatedTimeCost
code-and-docs-no-llm2,4614,738,79930,52044,9352,05120,6159.5s$0
code-only-no-llm2,0671,859,64816,65431,43699310,2836.9s$0
client-docs-no-llm30111,320764736456130.4s$0
code-only-with-llm2,0671,859,64816,76231,5551,00510,343145.7s~$0.45
client-docs-with-llm30111,32083293353616130.8s~$0.55
code-and-docs-with-llm2,4614,738,79934,25850,2922,29522,1554,396s (73 min)~$18

Total cost: ~$19. All 6 runs complete.

LLM delta (with-LLM vs no-LLM, full corpus): adds 3,974 semantic nodes + 5,399 semantic edges + 244 communities + 1,540 isolated nodes. Tokens: 1.86M input / 1.10M output. Confirms what the no-LLM run already surfaced — semantic extraction adds depth (cross-module concepts, INFERRED edges) but doesn’t change the architectural picture. The dominant signal (20,615+ isolated nodes) is structural and visible in the no-LLM run.

Caveats from with-LLM run: several chunks hit JSON-truncation issues at recursion depth 3 (graphify’s max retry depth). Some semantic extractions partial. Acceptable for baseline-comparison purposes — the structural backbone is intact; future iterations can re-run on subset to capture missed edges if needed.

Headline finding: 20,615 isolated nodes in code+docs no-LLM run. Substantially larger than Phase 0.2.5 build-not-wired audit surfaced manually. Many will be intentional (test fixtures, doc excerpts) but a non-trivial subset is likely TRUE-POSITIVE-FIX-NOW.

Recommendation: dedicated build-not-wired audit follow-up (~1-2 sessions) to classify the 20,615 isolated nodes against:

  • TRUE-POSITIVE-FIX-NOW (code change required)
  • TRUE-POSITIVE-DEFERRED (backlog ticket)
  • INTENTIONAL-FALSE-POSITIVE (test fixtures, doc excerpts; suppress)
  • LEGACY-SCAFFOLD (delete)
  • DRIFT (already obsolete)

This audit is independent of canonical-pipeline decision (the findings exist regardless) and can ship in Stream 1.


10. Updated open questions for parent session

Section titled “10. Updated open questions for parent session”

Aggregated + de-duplicated from 7 evaluation outputs and the 0.7-synthesis open-questions list:

Group A — canonical-pipeline architectural commitment (ratification needed)

Section titled “Group A — canonical-pipeline architectural commitment (ratification needed)”
  • A1 (refined) — Run cocoindex schema-coupling spike (3-5 days) before final commitment? Recommendation: YES (95% confidence; the spike is cheap and gates the rest).
  • A2 (refined) — If spike confirms Schema Scenario A: adopt cocoindex Option A as canonical pipeline substrate? Recommendation: YES, conditional (75% confidence; re-use of battle-tested infrastructure is exactly the corrected-lens answer).
  • A3 (refined) — If spike confirms Scenario B: fall back to Phase 0.7 Stream 2 as planned? Recommendation: YES (90% confidence; schema rework cost too high otherwise).

Group B — pre-canonical Stream 1 ratifications (carrying forward + new)

Section titled “Group B — pre-canonical Stream 1 ratifications (carrying forward + new)”
  • B1 — P3.B keyword_classifier vs AI classify for 440 prod Q&A rows. Recommendation: AI classify with quality-eval gate (per 0.7-synthesis ratification carries; awaiting Q&A trace findings to refine).
  • B2 — NEW1 expiry_date strategy. Recommendation: keep extractDates on P4+P7 only for v1; defer cross-path to §1.15 (per 0.7-synthesis; carries forward).
  • B3 — 0.7.4-Q1 identical-re-upload parent_iduser ratified: bug in 07-synthesis-feedback.
  • B4 — 0.7.4-Q4 Python Q&A 387-row backfill — user ratified: re-import via canonical in 07-synthesis-feedback.
  • B5?format=markdown|docx export route — user ratified: v1 in 07-synthesis-feedback.
  • B6 — Per-item Re-classify button on item-detail page — user ratified: v1 in 07-synthesis-feedback.

Group C — operational / cross-track (some now resolved)

Section titled “Group C — operational / cross-track (some now resolved)”
  • C1 — production-readiness Cloud Run scheduler timing — user ratified: COMPLETE; production-readiness track now waiting on main-track for next steps in 07-synthesis-feedback.
  • C2 — EP8 ship priority — still open; no change.
  • C3 — Knip baseline reduction — apply in Stream 1 (already approved as item 11).

Group D — new from Phase 0.8 evaluations

Section titled “Group D — new from Phase 0.8 evaluations”
  • D1 — Adopt mempalace Shape A (entity_relationships temporal-KG columns) in Stream 1? Recommendation: YES (~3-5 days; aligns with re-ingest captured_date stamping).
  • D2 — Adopt mempalace Shape B (strict-extraction MCP mode) in Stream 1? Recommendation: YES (~1.5 days; directly addresses client feedback Item 3).
  • D3 — Adopt skill-seekers categories keyword-rule scope tier? Recommendation: YES (~3 days; addresses client feedback Item 3 from a different angle).
  • D4 — Adopt skill-check as a CI step? Recommendation: YES (~30-60 min; catches regression class).
  • D5 — Adopt open-multi-agent onTrace schema for KH structured logs? Recommendation: YES (~2-3 days; aligns with deferred ai_call_log work).
  • D6 — Scope-tag taxonomy ratification: internal-it / production-infrastructure / application-layer / office-physical / data-centre-physical? Recommendation: ratify as proposed; iterate post-launch.
  • D7 — pullmd AGPL v3 acceptable for self-hosted use? Recommendation: yes for direct re-use; flag for legal review if forking.
  • D8 — pullmd 50-URL bake-off vs current extractor — gate before Phase A foundation. Recommendation: run as part of cocoindex spike week.
  • D9 — Adopt skill-seekers openapi_scraper for new api_specification content type? Recommendation: post-launch backlog (OPS-SS-2).
  • D10 — Defer skill-seekers pdf_scraper v2 PDF upgrade to post-launch? Recommendation: yes, OPS-SS-1.
  • D11 — Build-not-wired follow-up audit on graphify’s 20,615 isolated nodes — Stream 1 or post-launch? Recommendation: Stream 1 (~1-2 sessions; cheap; findings exist regardless).
  • D12 — Default search limit raised from 5 to 10 (or configurable per-call)? Recommendation: configurable with default 10.

Group D’ — Q&A trace findings (per 0.8.8)

Section titled “Group D’ — Q&A trace findings (per 0.8.8)”
  • D13ingest_stage2_markdown.py as permanent path or one-shot client-data-load? Recommendation: one-shot (retire post-EP8 + canonical-markdown UI ship).
  • D14 — P3.B per-source-shape ratification — replace original B1 with B1.A (Q&A docx, 221 rows: AI classify with 50-row eval gate) + B1.B (Q&A markdown, 159 rows: AI classify with quality eval — verify current mode in ingest_stage2_markdown.py). Recommendation: ratify as split.
  • D15 — Cleanup migration for 159 mis-bucketed qa_import rows (S207 backfill artefact)? Recommendation: YES — Stream 1 (~30 min migration; analytical correctness regardless of canonical-pipeline decision).
  • D16section_name semantic in Q&A schema — what’s its intended meaning post-canonical-pipeline? Recommendation: defer to Phase F design; iterate based on canonical adapter’s Pattern A/B output.
  • D17 — Phase F.4 retirement scope — confirm “delete-not-refactor entire P6 + qa-detection chain”? ~4,000-5,000 LOC removal. Recommendation: YES (largest single deletion; validates 0.7.6 zero-callers finding).
  • D18 — Add recordPipelineRun() to BOTH import_bid_library.py AND ingest_stage2_markdown.py in Stream 1 (zero historical telemetry today)? Recommendation: YES — re-ingest needs telemetry baseline. ~1h work.
  • D19 — Rename / split lib/bid-library-ingest/ to reflect actual usage (BNW vs production-USED EDIT helpers)? Recommendation: split into lib/qa-edit-helpers/ (production-USED) + delete BNW extractors after Phase F. Stream 1 or Phase F.

SectionConfidenceDrag
Tool verdicts (cocoindex, pullmd, skill-seekers, mempalace, skill-check, open-multi-agent)84-88% per toolSchema-coupling unverified (cocoindex); AGPL details (pullmd); v4-alpha (mempalace)
Stream 1 collapse logic85%Conditional on cocoindex adoption decision
Stream 2 sequencing under Option A78%Effort estimates ±25%; LiteLLM Anthropic prompt-cache passthrough unverified
Storage collapse (NEW5/NEW7)85%Audit-trail bucket question still requires Liam call
Client feedback resolution (Item 3)85%Scope-tag taxonomy is a proposal; iterate post-launch
Graphify baseline findings92%6th run (code+docs+LLM) pending; 20,615 isolated requires classification
Q&A pipeline statusn/a[PLACEHOLDER] — pending agent return
Open questions list90%Comprehensive; per-item confidence attached

Overall synthesis confidence: 84%.

Below 90% specifically because:

  1. cocoindex schema-coupling unverified. Single dimension changes recommendation materially.
  2. Q&A pipeline trace pending. Decisions on P3.B (B1 above) await the trace.
  3. Big graphify run pending. Doesn’t change the verdicts but enriches the 20,615 isolated-node analysis.
  4. Effort estimates ±25% under “we haven’t done this before” framing.

Phase 0.8 inputs (committed in this branch)

Section titled “Phase 0.8 inputs (committed in this branch)”
  • docs/plans/phase-0-investigation/0.8.2-cocoindex-evaluation.md (655 lines, 80%)
  • docs/plans/phase-0-investigation/0.8.3-skill-check-evaluation.md (331 lines, 88%)
  • docs/plans/phase-0-investigation/0.8.4-pullmd-evaluation.md (639 lines, 84%)
  • docs/plans/phase-0-investigation/0.8.5-skill-seekers-evaluation.md (~770 lines, 88%)
  • docs/plans/phase-0-investigation/0.8.6-open-multi-agent-evaluation.md (551 lines, 86%)
  • docs/plans/phase-0-investigation/0.8.7-mempalace-evaluation.md (537 lines, 84%)
  • docs/plans/phase-0-investigation/0.8.8-qa-pipeline-trace.md [PENDING]
  • .planning/codebase/graphify-baselines/{code-and-docs-no-llm,code-only-no-llm,client-docs-no-llm,code-only-with-llm,client-docs-with-llm}/ — 5 of 6 baseline runs
  • docs/plans/phase-0-investigation/0.8-synthesis.md (this file)
  • .graphifyignore (graphify dev workflow exclusions)
  • .planning/codebase/graphify-baselines/run_baseline.py (replicable baseline runner)

End of Phase 0.8 synthesis. 84% overall confidence. Two outstanding inputs (0.8.8-qa-pipeline-trace.md + 6th graphify run) will trigger updates. 12 new open questions (Group D) for parent ratification on top of carrying-forward 0.7-synthesis open questions.