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.mdand 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.
1. Executive summary
Section titled “1. Executive summary”Three findings reshape the 0.7 plan materially:
-
cocoindexis 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. -
pullmdsolves 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_idbecomes the stablesource_documents.storage_pathsentinel. HYBRID re-use: pullmd as URL shape adapter inside cocoindex flow. -
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:
-
skill-seekersships 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 integratepdf_scraper(v2 PDF upgrade),openapi_scraper(NEW shape —api_specification),MarkdownCleanercleanup helpers. -
skill-checkcatches at least one prior-bug class (the YAML-frontmatter trap fromfeedback_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:
-
graphifyadoption 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. -
open-multi-agentis a net regression if adopted wholesale. KH’s existingAgent({ isolation: "worktree" })+ Spec-Code-Verify workflow is more disciplined. Borrow primitives only —onTraceevent taxonomy as a structured-log schema (~2-3 days, no dependency).
Three findings from the Q&A trace investigation reshape Phase F:
-
Actual prod Q&A count is 395, not 440 (0.7-synthesis was wrong; never DB-verified).
-
TWO Python ingest scripts produced 380 of the 395 rows —
import_bid_library.py(P3 docx, 221 rows) ANDingest_stage2_markdown.py(159 rows). The second was MISSED by every prior audit. The 10-path inventory is incomplete — there are 11. -
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:
| Path | Total effort | Code retained |
|---|---|---|
| Build canonical pipeline (Phase 0.7 Stream 2 as planned) | 9-12 weeks | All of lib/extraction/, scripts/kb_pipeline/, much of lib/ingest/ |
| Adopt cocoindex Option A | 6-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 dispatch | Layer 2 input-shape router |
| Unified scraper merge layer | Layer 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_idIS 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.
3. Tool verdict matrix
Section titled “3. Tool verdict matrix”| Tool | Lens | Verdict | Confidence | Adoption sequencing | Effort |
|---|---|---|---|---|---|
| cocoindex | Platform | Re-use Option A (canonical pipeline substrate) — conditional on schema-coupling spike | 80% | Spike (3-5 days) → decide → 6-8 weeks if go | Replaces Stream 2 9-12 weeks |
| pullmd | Platform | HYBRID re-use as URL shape adapter for P4 + P9 Tier 2-3 | 84% | Within Phase A foundation (~3-3.5 weeks) | Drop ~1k LOC of KH URL extraction |
| skill-seekers | Platform | Adopt-as-pattern + selective module import (3 strong / 3 conditional / 5 don’t) | 88% | Phase A patterns reference; v2 PDF upgrade; new api_specification shape | Mixed |
| mempalace | Platform + dev | Adopt Shape A + B pre-launch; Shape C deferred | 84% | A: with re-ingest (Q1 captured_date alignment); B: Stream 1 (~1.5 days) | Schema migration + new MCP mode |
| graphify | Dev workflow | Installed + integrated (this branch). 5 baselines committed. Post-launch concept-map deferred under cocoindex Neo4j target | 88% | Already done | n/a |
| skill-check | Dev workflow | Adopt as CI step alongside knip | 88% | Stream 1 (~30-60 min) | Catches YAML-frontmatter regressions |
| open-multi-agent | Dev workflow | Borrow onTrace schema only; no wholesale adoption | 86% | 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:
| Dimension | Build canonical core (Phase 0.7 Stream 2) | Adopt cocoindex (Option A) |
|---|---|---|
| Effort | 9-12 weeks | 6-8 weeks (post-spike) |
| Code retained | 7,400+ LOC ingestion + orchestration | ~500-800 LOC declarative flow + dependency |
| Re-ingest cycle | Manual, weeks 3-4 of Stream 1 | Engine-native incremental Δ |
| Re-upload UPDATE | Custom build | Engine-native |
| Long-term maintenance | KH owns 7,400+ LOC | KH 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)
doclingvs KH’sunpdf+mammoth+turndownchain (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.
4.2 pullmd — URL shape adapter
Section titled “4.2 pullmd — URL shape adapter”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_idtyped 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+jsdomdependencies@mendable/firecrawl-js(if Playwright path covers Cloudflare + Google News)FIRECRAWL_API_KEYenv 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.
| Module | Adopt verdict | Effort | Sequencing |
|---|---|---|---|
SkillConverter base class + CONVERTER_REGISTRY | PATTERN INSPIRATION for canonical pipeline Layer 3 | n/a | Phase 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 week | Post-launch |
pdf_scraper.py + pdf_extractor_poc.py | STRONG INTEGRATE for v2 — replaces unpdf with chapter detection + OCR + image extraction | ~2 weeks | v2 (post-launch) — pdfplumber + Pillow + Tesseract footprint shift |
word_scraper.py | PARTIAL ADOPT — same toolchain (mammoth + python-docx); add metadata extraction pattern | ~3-4h | Stream 1 |
MarkdownCleaner | ADOPT cleanup helpers (remove_html_tags, extract_first_section) | ~1-2h | Stream 1 |
RAGChunker | DON’T REPLACE (KH heading-based is correct for Q&A-dominant corpus). Optionally add token-budget mode for headingless corpora | ~150 LOC | Post-launch |
embedding_pipeline.py (cache + cost tracking) | CONSIDER cost-tracking + disk-cache patterns | ~1 day | Post-launch |
code_analyzer.py + dependency_analyzer.py | NICHE ADOPT as 3rd build-not-wired-detector alongside Knip + Graphify | ~1-2 days | Optional |
openapi_scraper.py | STRONG ADOPT — adds api_specification content type | ~1 week | New shape, can ship anytime post-Phase A |
Notable non-adoptions:
- Skill-Seekers’s
categoriesconfig 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 forinternal-it / production-infrastructure / application-layertaxonomy. - 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:
-
mempalace’s schema IS what KH’s
entity_relationshipsshould 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. Addvalid_from,valid_to,confidence,source_content_item_id,adapter_namecolumns toentity_relationships. Implementkg_invalidate(subject, predicate, object, ended)andkg_timeline(entity, as_of)as RPCs. -
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 tosearch_knowledge_baseMCP 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).
| Shape | What it adds | Effort | Sequencing |
|---|---|---|---|
A — Temporal-KG columns on entity_relationships | valid_from / valid_to / confidence / source_content_item_id / adapter_name + kg_invalidate/kg_timeline RPCs | ~3-5 days | With re-ingest (populate valid_from from content_items.captured_date per Q1) |
| B — Strict-extraction MCP mode | mode='strict_extract' parameter on search_knowledge_base; returns verbatim chunk + cite-or-refuse | ~1.5 days | Stream 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.
4.5 graphify — already adopted
Section titled “4.5 graphify — already adopted”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):
| Metric | Value |
|---|---|
| Files | 2,461 |
| Words | 4,738,799 |
| Nodes | 30,520 |
| Edges | 44,935 |
| Communities | 2,051 |
| Isolated nodes | 20,615 |
| Wall clock | 9.5 s |
| Cost | 0 (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):
safeErrorMessage()— 361 edgesauthFailureResponse()— 348 edgescn()— 339 edgesgetAuthorisedClient()— 299 edgesparseBody()— 196 edgesButton()— 187 edgescreateMockSupabaseClient()— 168 edgeslogger— 125 edgescreateTestRequest()— 117 edgescheckRateLimit()— 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
--fixonce 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:
- Adopt OMA’s
onTraceevent taxonomy as KH’s structured-log schema for agent dispatches — ~2-3 days, no OMA dependency, aligns with deferredai_call_logwork. Highest ROI from this evaluation. - Production-checklist audit of
lib/ai/draft.ts+ queue handlers against OMA’s 6 controls — surfaced real gaps: nomaxTokenBudgetenforcement anywhere (runaway risk), no structured trace correlation, retry policies live at queue layer not AI layer. - 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 shape | v1 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.
6. Client feedback resolution
Section titled “6. Client feedback resolution”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):
-
FUNC-XXX content NOT in
q_a_paircontent_type. Graphify’s god-nodes confirm bid-library hubs are structurally connected to FUNC-XXX entries but probably classified asfeature_specificationor similar at ingest. Fix: classifier prompt update to recognise FUNC-XXX as Q&A-shaped content; canonical pipeline’s classifier becomes single chokepoint. -
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.
-
Default limit 5 too low. Trivial fix. ~10 min change. Stream 1 candidate.
-
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:
- New typed column
content_items.scope_tag(or ARRAY column for multi-scope content). Migration in Stream 1. - Anti-tags via
content_items.anti_scope_tags ARRAY— explicit “does not apply to” set. Migration in Stream 1. - Skill-seekers
categoriesconfig pattern as keyword-rule tier in classifier — runs BEFORE AI classification, sets default scope. Adoption: ~3 days. - Mempalace Shape B
strict_extractMCP mode — verbatim-only retrieval with mandatory citation. ~1.5 days. - MCP tool
search_knowledge_baseextended withscope_tagandanti_scope_tagfilter 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):
| # | Item | Effort | Status |
|---|---|---|---|
| 1 | D1 markdown_batch ingest_source value | ~30 min | Approved |
| 3 | 5 P0 missing FKs on content_items | ~1h | Approved |
| 5 | P0-2 fix feed_prompts fire-and-forget | ~1h | Approved |
| 6 | Drop migrations notes/source_bid (verify parent_id still correct given 0.7.4 findings) | ~1h | Approved |
| 7 | Reader rewrites for source_document text + drop migration | ~3h | Approved |
| 11 | 4 knip TRUE-POSITIVE-FIX-NOW items | ~1h | Approved |
Total approved Stream 1: ~7-8 hours.
Items moved to “absorbed by cocoindex Option A” (if adopted):
| # | Item | Cocoindex absorption mechanism |
|---|---|---|
| 2 | D2 EP2 source_documents parity | Source-key model dissolves the question |
| 4 | P0-1 Path 7 silent-fail | Engine’s failure-isolation replaces try/catch handling |
| 8 | OVERSIGHT helpers (source_domain, platform, content_owner_id, pipeline_runs) | Folded into cocoindex flow stages |
| 9 | RSS chunks regen wiring | Chunks regenerate automatically when chunking logic changes |
| 10 | Batch chunks regen wiring | Same |
| 12 | TS-side ingestion_quality_log helper (~3 days) | Replaced by custom emitter @coco.fn (~half day) |
| 13 | Path 7 swallow-catch user surfacing spec | Still needed (UX, not pipeline); pipeline failure-isolation is engine-native |
Items added to Stream 1 from 0.8.x recommendations:
| # | New Item | Source | Effort |
|---|---|---|---|
| 14 | skill-check installation + CI integration | 0.8.3 | ~30-60 min |
| 15 | mempalace Shape B (strict-extraction MCP mode) | 0.8.7 | ~1.5 days |
| 16 | Scope-tag taxonomy schema migration (scope_tag + anti_scope_tags) | Client Item 3 | ~1 day |
| 17 | search_knowledge_base MCP tool — scope_tag filter parameters | Client Item 3 | ~1 day |
| 18 | Skill-seekers categories keyword-rule tier in classifier | 0.8.5 | ~3 days |
| 19 | open-multi-agent onTrace schema as KH structured-log schema | 0.8.6 | ~2-3 days |
| 20 | mempalace Shape A (entity_relationships temporal-KG columns) | 0.8.7 | ~3-5 days |
| 21 | Default 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_scraperv2 PDF upgrade) — ~2 weeks; pdfplumber + Pillow + Tesseract footprint - OPS-SS-2 (
openapi_scraperforapi_specificationcontent 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:
8.1 Actual prod count is 395, not 440
Section titled “8.1 Actual prod count is 395, not 440”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.
8.4 The remaining 15 of 395 rows
Section titled “8.4 The remaining 15 of 395 rows”- 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.
8.6 lib/bid-library-ingest/ is mis-named
Section titled “8.6 lib/bid-library-ingest/ is mis-named”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.
8.7 Phase F revisions
Section titled “8.7 Phase F revisions”- F.2 — port
ingest_stage2_markdown.pyto 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:
-
source_documentstable has 0 rows in prod. Confirms 0.7.4 P0-1 silent-fail finding. The 395 Q&A rows have NULLsource_document_id. Under cocoindex: source-key model dissolves the gap. Under no-cocoindex: D2 implementation must backfill from existingsource_filetext. -
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 addrecordPipelineRun()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_importrows: ratify? (~30 min migration; should ship Stream 1 for analytical correctness.) - D16 —
section_namesemantic 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.
9. Graphify baseline summary
Section titled “9. Graphify baseline summary”5 of 6 baselines committed; 6th (code-and-docs-with-llm) running.
| Run | Files | Words | Nodes | Edges | Communities | Isolated | Time | Cost |
|---|---|---|---|---|---|---|---|---|
| code-and-docs-no-llm | 2,461 | 4,738,799 | 30,520 | 44,935 | 2,051 | 20,615 | 9.5s | $0 |
| code-only-no-llm | 2,067 | 1,859,648 | 16,654 | 31,436 | 993 | 10,283 | 6.9s | $0 |
| client-docs-no-llm | 30 | 111,320 | 764 | 736 | 45 | 613 | 0.4s | $0 |
| code-only-with-llm | 2,067 | 1,859,648 | 16,762 | 31,555 | 1,005 | 10,343 | 145.7s | ~$0.45 |
| client-docs-with-llm | 30 | 111,320 | 832 | 933 | 53 | 616 | 130.8s | ~$0.55 |
| code-and-docs-with-llm | 2,461 | 4,738,799 | 34,258 | 50,292 | 2,295 | 22,155 | 4,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_id— user 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|docxexport 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
categorieskeyword-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
onTraceschema for KH structured logs? Recommendation: YES (~2-3 days; aligns with deferredai_call_logwork). - 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_scraperfor newapi_specificationcontent type? Recommendation: post-launch backlog (OPS-SS-2). - D10 — Defer skill-seekers
pdf_scraperv2 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)”- D13 —
ingest_stage2_markdown.pyas 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_importrows (S207 backfill artefact)? Recommendation: YES — Stream 1 (~30 min migration; analytical correctness regardless of canonical-pipeline decision). - D16 —
section_namesemantic 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 BOTHimport_bid_library.pyANDingest_stage2_markdown.pyin 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 intolib/qa-edit-helpers/(production-USED) + delete BNW extractors after Phase F. Stream 1 or Phase F.
11. Confidence assessment
Section titled “11. Confidence assessment”| Section | Confidence | Drag |
|---|---|---|
| Tool verdicts (cocoindex, pullmd, skill-seekers, mempalace, skill-check, open-multi-agent) | 84-88% per tool | Schema-coupling unverified (cocoindex); AGPL details (pullmd); v4-alpha (mempalace) |
| Stream 1 collapse logic | 85% | Conditional on cocoindex adoption decision |
| Stream 2 sequencing under Option A | 78% | 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 findings | 92% | 6th run (code+docs+LLM) pending; 20,615 isolated requires classification |
| Q&A pipeline status | n/a | [PLACEHOLDER] — pending agent return |
| Open questions list | 90% | Comprehensive; per-item confidence attached |
Overall synthesis confidence: 84%.
Below 90% specifically because:
- cocoindex schema-coupling unverified. Single dimension changes recommendation materially.
- Q&A pipeline trace pending. Decisions on P3.B (B1 above) await the trace.
- Big graphify run pending. Doesn’t change the verdicts but enriches the 20,615 isolated-node analysis.
- Effort estimates ±25% under “we haven’t done this before” framing.
12. Files written / updated
Section titled “12. Files written / updated”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
Phase 0.8 synthesis (this document)
Section titled “Phase 0.8 synthesis (this document)”docs/plans/phase-0-investigation/0.8-synthesis.md(this file)
Branch infrastructure
Section titled “Branch infrastructure”.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.