Skip to content

Phase B Prerequisite 2 — Verification (cocoindex deep-dive vs feedback-findings-review)

Phase B Prerequisite 2 — Verification (cocoindex deep-dive vs feedback-findings-review)

Section titled “Phase B Prerequisite 2 — Verification (cocoindex deep-dive vs feedback-findings-review)”

Date: 13/05/2026 (S234 end-of-session adversarial cross-check) Audit purpose: Confirm dispositions are mutually consistent before propagation into 0.9-decision-graph.md / 0.9-collapse-candidates.md / 00-synthesis-v2.md. Auditor: Claude (Opus 4.7, 1M-context) — adversarial verification pass; mandate was to surface contradictions, not validate them. Source docs verified:

  • docs/plans/phase-0-investigation/phase-b-prerequisite-2-cocoindex-deep-dive.md (315 lines, with §7 Docling spike resolution appended end-of-session)
  • docs/plans/phase-0-investigation/feedback-findings-review.md (578 lines, with §5 post-prereq rollup + §5.5 Docling spike resolution appended end-of-session)
  • Tertiary: phase-b-prerequisite-2d-docling-bakeoff.md (387 lines, ground truth on spike facts); phase-b-prerequisite-2c-cocoindex-doc-handling.md (370 lines, doc-handling capability source); phase-b-prerequisite-2a-cocoindex-examples.md (556 lines, ExtractByLlm primary source); 10-feedback-investigation-findings/06-cx33-source-doc-explorer.md (Finding 06 source).

Side-by-side per-decision dispositions. ”✓” = agreement; “Δ” = disposition state-label differs but resolves to same outcome; ”✗” = contradiction.

ItemCocoindex deep-dive (location)feedback-findings-review §5 (location)Agree?
Theme A (form-type generalisation)Not framed as a theme; closure is form_templates table family + question_matches discriminator implied via §2 lines 60/85/86/95RESOLVED — §5.1 line 378: form_type + form_format CVs; templatesform_templates; generalised question_matches with question_kind discriminator
Theme B (form extraction 6-step)§2 line 83 = RESOLVED-DIRECTIONAL; §7.1 lines 267-270 + closing line 315 = RESOLVED post-Docling-spike§5.1 line 379 = RESOLVED-DIRECTIONAL; §5.5 line 570 = upgraded to RESOLVEDΔ — see §2 C1 (internal cocoindex-doc inconsistency between §2 and §7)
Theme C (edit / re-classification state-machine)§1.2 line 47 + §1.1 line 36: cocoindex re-extracts naturally; gates on edit_intent ∈ {data, structural}§5.1 line 380: RESOLVED-DIRECTIONAL — edit_intent Layer-1 CV (cosmetic/data/structural); cocoindex re-extract gated KH-side
Theme D (cocoindex ‘freshness’)§1.2 line 48: separate substrates kept (cocoindex ingest-latency vs KH governance content_items.freshness)§5.1 line 381: RESOLVED — same wording
Theme E (applications layer)Not directly addressed (out-of-scope for cocoindex prereq)§5.1 line 382: RESOLVED — application_types Layer-1 CV; Shape B holds; per-application_type satellites✓ (gap not contradiction — application-layer is ontology-only)
Theme F (Mempalace MCP)Not addressed§5.1 line 383: STILL-OPEN (out-of-prereq operational decision)
Theme G (doc skills)§2 line 94: RESOLVED — Anthropic skills step 1, cocoindex step 3+4, markitdown fallback§5.1 line 384: RESOLVED — same wording

1.2 — B1/B2/I1/I2/I3 (00-synthesis blocking + important decisions)

Section titled “1.2 — B1/B2/I1/I2/I3 (00-synthesis blocking + important decisions)”
ItemCocoindex deep-divefeedback-findings-reviewAgree?
B1 (Pattern A/B parser fate)§1.2 line 57: DISSOLVED via ExtractByLlm. Recurring adapter ownership = cocoindex ExtractByLlm + KH-side q_a_extractions cache. Pattern A/B retire as one-shot Phew migration helpers.§5.2.4 line 435: OQ-Q11-A RESOLVED via cocoindex ExtractByLlm. Pattern A/B retire confirmed (post Phew migration) per §6 line 251.
B2 (Option α/β for source_documents)§1.2 line 58: Option α (slim-and-keep) confirmed§5.2.1 line 394: RESOLVED-DIRECTIONAL: Option α (slim-and-keep). §5.3.1 line 464: same.
I1 (bid_workspaces shape)Not addressed (ontology-only)§5.2.5 line 441: Option B (satellite) per Shape B precedent
I2 (template_requirements rename inventory)Not addressed (ontology-only)§5.2.4 line 431: RESOLVED — 3-table inventory (form_templates + form_template_fields + form_template_requirements)
I3 (S9 spike status)§1.3 + §3.6 line 159: STILL-OPEN (empirical spike pending)§5.2.2 line 410 + §5.4 line 514: STILL-OPEN — defer to dedicated sub-session

1.3 — Cocoindex affordances + per-finding closures (cocoindex doc §2 vs feedback-findings §5.2)

Section titled “1.3 — Cocoindex affordances + per-finding closures (cocoindex doc §2 vs feedback-findings §5.2)”
ItemCocoindex deep-dive § / linefeedback-findings-review § / lineAgree?
OQ-Q24-A (pipeline_runs retain)§1.2 line 46: RETAIN as KH-side rollup§5.2.1 line 398: RESOLVED — RETAIN
OQ-CX33-A (cocoindex re-extract on edit-back)§1.2 line 47: natural; gates on KH-side edit_intent§5.2.6 line 451: RESOLVED — natural; KH-side gate via edit_intent per Theme C
pipeline_failures table§1.2 line 49: DO NOT BUILD(not explicitly in §5; implied by Theme D closure)Gap (see §3.2)
Q4.12 cost-tracking§1.2 line 50: RETIRE(not explicitly in §5)Gap (see §3.2)
source_documents.{version, parent_id, original_filename, source_document_diffs} retire§1.2 line 51: RETIRE§5.2.1 line 395: diff UI retires under Option α — source_document_diffs absorbed by cocoindex ops-DB ledger
OQ-Q19-B (downstream of source-documents API)§2 line 79: RESOLVED — localfs covers UC10; upload-route stays for HITL§5.2.1 line 396: same
OQ-Q19-C (upload-route binary-shape adapter)§2 line 79: RESOLVED (under Option α)§5.2.1 line 396: same
OQ-Q19-D (upload-route silent-fail)§2 line 79: KH-side fix in N5§5.2.1 line 397: RESOLVED — fix proceeds under Option α
OQ-Q29-A / I3 (S9 spike)§2 line 81 + §3.6: STILL-OPEN§5.2.2 line 410: STILL-OPEN
OQ-Q112-A (per-method scoring)§2 line 82: STILL-OPEN — cocoindex doesn’t prescribe§5.2.2 line 413: STILL-OPEN — separate columns recommendation stays
OQ-Q112-B (single hybrid vs separate cols)(not directly addressed; folded into OQ-Q112-A)§5.2.2 line 414: STILL-OPEN — same as OQ-Q112-A✓ (deep-dive less specific)
OQ-Q32-A (predetermined-markdown shape)§2 row 84 (“PDF→Markdown”) doesn’t address; ontology issue§5.2.2 line 411: RESOLVED — does NOT vary (single canonical YAML-frontmatter shape)✓ (ontology-routed, cocoindex didn’t touch)
OQ-Q35-B (cataloguer skill output shape)§2 line 95: RESOLVED — generated scripts/catalogue-<slug>.ts§5.2.4 line 433: RESOLVED — same
N2 cataloguer skill build-trigger§2 line 96: STILL-OPEN pending Docling spike. Closing line 315: “N2 cataloguer (deferred)“§5.5 line 572: RESOLVED — defer (post-spike)Δ — internal inconsistency in cocoindex doc; see §2 C2
Theme B step 3 (markdown convert)§1.2 line 59 (RESOLVED-DIRECTIONAL); §7.1 lines 267-270 (per-format RESOLVED with Docling)§5.1 line 379 (RESOLVED-DIRECTIONAL); §5.5 lines 533-538 (per-format RESOLVED with Docling)✓ on facts; Δ on state-label in pre-§7 sections (see §2 C1)
Theme B step 4 (classify-form-data)§1.2 line 60: cocoindex Structured Extraction (paper_metadata-style, Claude + instructor)§5.1 line 379: cocoindex ExtractByLlm with typed Python output_type✓ (same primitive — ExtractByLlm IS the paper_metadata-pattern op)
Finding 06 viewer rewrite§2 line 98: STILL-OPEN pending Docling spike. §7.1-§7.3: post-spike RESOLVED. Closing line 315: “Finding 06 viewer architecture RESOLVED post-Docling-spike — sidecar v1 confirmed; zero new deps obsolete”§5.2.6 lines 447-451: RESOLVED-DIRECTIONAL (PDF/DOCX/XLSX). §5.5 line 571: upgraded to RESOLVED — sidecar-v1 (markdown → Tiptap ContentEditor)Δ on state-label labels but ✓ on end-state — see §2 C1
Finding 06 “zero new deps for v1” claim§2 line 99 + §7.3 lines 281-284: REOPENED → OBSOLETE post-Docling-spike§5.2.6 line 452 + §5.5 line 550 + line 571: REOPENED → OBSOLETE post-Docling-spike

1.4 — Citations + ontology items (covered by Prereq 1 but echoed in both docs)

Section titled “1.4 — Citations + ontology items (covered by Prereq 1 but echoed in both docs)”
ItemCocoindex deep-divefeedback-findings-reviewAgree?
Q1.11 citations rename + extend in placeNot framed (Prereq 1 territory)§5.2.2 line 408: RESOLVED — polymorphic citing_entity (bid_response / sales_proposal_response / competitor_research_finding / training_unit / mcp_search_response per Prereq 1 §5)✓ (gap not contradiction)
Q1.12 bid_question_matchesquestion_matchesNot framed (Prereq 1 territory)§5.2.2 line 409: RESOLVED — generalised question_matches with question_kind discriminator
OQ-Q111-A future citersNot framed§5.2.2 line 412: RESOLVED — citing_entity enum extended
OQ-Q113-A per-type satellite registry patternNot framed§5.2.3 line 423: RESOLVED — satellite per application_type vocabulary entry
OQ-Q35-C form requirement_type=checklistNot framed§5.2.4 line 434: RESOLVED — NO, fold into existing
OQ-Q311-A form_templates pre-buildNot framed§5.2.3 line 424: RESOLVED — build as part of Theme A
ItemCocoindex deep-divefeedback-findings-reviewAgree?
OQ-Q24-B audit_log RLS§1.3 N7-adjacent: KH-side, not cocoindex§5.2.1 line 399: STILL-OPEN — RLS pattern doc pending
OQ-Q24-C op_id propagation§1.3 N7 + §2 line 82: STILL-OPEN, not cocoindex§5.2.1 line 400: STILL-OPEN — Liam ruling
Mempalace MCP wrapping (Theme F)Not addressed§5.2.3 line 422: STILL-OPEN — operational
OQ-Q55-A combined-PR renameNot addressed(DECIDED in §2.3 — out of §5 by design)
OQ-Q45-A mempalace wing-filter bugNot addressed(DECIDED in §2.3 — out of §5 by design)
CocoInsight on-prem§3.4 line 145 + §5 line 231: STILL-OPEN§5.4 line 521: STILL-OPEN
TS-facing per-flow-run ledger§3.4 line 145: STILL-OPEN§5.4 line 520: STILL-OPEN
Anthropic prompt-cache passthrough§5 line 233: STILL-OPEN§5.4 line 522: STILL-OPEN
Discriminated-union Pydantic with ExtractByLlm§5 line 234: STILL-OPEN (Q-EX2)§5.4 line 523: STILL-OPEN (Q-EX2)
Knowledge Map graph substrate (S7)§5 line 236: DEFERRED§5.4 line 519: DEFERRED
XLSX structure-preserving conversion (Q-XL1)§5 line 235: STILL-OPEN (Docling may flatten tables)§5.4 line 524: STILL-OPEN

Matrix-level verdict: Of ~40 cross-checked items, 0 hard contradictions on end-state direction. 2 Δ items are internal inconsistencies within the cocoindex deep-dive (§2 = directional / spike-pending state vs §7 + closing paragraph = upgraded-to-RESOLVED state). The feedback-findings-review §5.5 explicitly upgrades the matching state labels (e.g. “Theme B RESOLVED (was RESOLVED-DIRECTIONAL pending spike)”) whereas the cocoindex deep-dive does not back-port the §7 result into its §2 disposition table.


#ItemCocoindex deep-dive claimFindings-review claimSeverityRecommended resolution
C1Theme B / Finding 06 state-label§2 line 83 (Theme B = RESOLVED-DIRECTIONAL), §2 line 98 (Finding 06 = STILL-OPEN pending Docling), but §7 (lines 263-315) post-spike says RESOLVED. The §2 disposition table is NOT updated to reflect §7’s spike resolution.§5.5 line 570 explicitly upgrades: “Theme B (form extraction pipeline): RESOLVED (was RESOLVED-DIRECTIONAL pending spike)”. §5.5 line 571: “Finding 06 DOCX/PDF/XLSX viewer rewrite: RESOLVED”.LOW — both docs reach the same end-state; cocoindex doc’s §2 is just stale relative to its own §7Add a one-line note at top of cocoindex deep-dive §2 (or §1.2 row 59) saying “Theme B step 3 + Finding 06 dispositions upgraded by §7 — see §7.1 + §7.5 for current state”. Optional: rewrite §2 line 83 + line 98 inline.
C2N2 cataloguer skill state-label§2 line 96: “STILL-OPEN pending Docling fidelity spike. If Docling fails: build… If Docling succeeds: cataloguer skill becomes optional.” Closing paragraph line 315: “N2 cataloguer (deferred)”. §7 does not directly resolve N2.§5.5 line 572: “RESOLVED — defer. Docling fidelity is high enough that a cataloguer skill isn’t needed pre-launch. Build-now flagged only if Docling fails on broader XLSX corpus verification.”LOW — same end-state (“defer”); state-label differs (STILL-OPEN→implicit defer in deep-dive; explicit RESOLVED→defer in findings-review).Add a §7 row for N2 in cocoindex doc mirroring findings-review §5.5 wording (“RESOLVED — defer; build-now flagged only if broader XLSX corpus verification fails”).
C3Pattern A/B retire trigger framing§1.2 line 57: Pattern A/B parsers retire “as one-shot Phew migration helpers” (i.e. used for one-shot Phew migration, then retired). Closing line 315 + §6 line 251 say “Pattern A/B retire confirmed (post Phew migration)” — same wording.§5.2.4 line 432: doesn’t explicitly mention Pattern A/B in §5 retire-seed; §5 leans on cocoindex ExtractByLlm subsumption (§5.2.2 line 411, §5.2.4 line 435).LOW — both docs converge on “Pattern A/B retire post-Phew-migration”; findings-review just doesn’t restate the wording.No fix required; this is a cocoindex-doc-only statement of the Phew-migration timing — findings-review preserves the substantive direction. Optional: add row in findings-review §5.2.4 echoing “Pattern A/B parser: RESOLVED — retire post-Phew-migration; recurring adapter is ExtractByLlm”.
C4N2 cataloguer wording in §5.4 vs §5.5 within feedback-findings-reviewn/a (cocoindex doc not implicated)§5.4 line 514 (Docling fidelity spike) says “This session if sub-agent completes”. §5.4 doesn’t list N2 explicitly. §5.5 line 572 says N2 RESOLVED—defer. §5.4 lists “Docling fidelity spike STILL-OPEN — IN-FLIGHT S234”; §5.5 says spike completed.LOW — these are sequenced (§5.4 was written pre-spike, §5.5 post-spike); internal-to-findings-review only.Optional: collapse §5.4 + §5.5 in a final pass, or add a header on §5.4 (“superseded by §5.5 for Docling-spike-gated items”).
C5Cocoindex deep-dive §5 still-open list (lines 226-237) lists “Docling fidelity spike” as STILL-OPEN HIGH. §7.5 then updates: “RESOLVED (was HIGH)”. §5 is not actually rewritten — §7.5 says “Updated still-open list (replaces §5)“.n/a (cocoindex-internal)Findings-review §5.4 (line 511) flags it “IN-FLIGHT S234”; §5.5 confirms resolution.LOW — same pattern as C1; §7.5 explicitly states “replaces §5” but the §5 text is left intact.Reader navigates §5 → §7.5; explicit “REPLACED BY §7.5” header at top of §5 would prevent confusion when someone greps for “STILL-OPEN” and lands on §5 line 228.
C6CocoInsight vs audit_log§3.3 lines 137-143: distinct surfaces; both kept. CocoInsight is operational/engineering; audit_log is product/compliance.(Findings-review §5 does not directly state this distinction but §5.2.1 line 399 routes audit_log RLS to a “RLS pattern doc” — implies audit_log retained as a separate concern from CocoInsight)NONE — agreement implicitNo fix required.
C7Theme B step 1 (evaluate-form) ownership§1.2 line 60 (step 4 only mentioned at this row); cross-ref to Prereq 2c via line 60 + §6 line 251 explicitly say “step 1: Anthropic doc skills”. §7.1 doesn’t re-state.§5.1 line 379: Step 1: Anthropic doc skills (docx/xlsx/pdf).✓ — agreement (no contradiction).No fix required.

Severity legend used:

  • HIGH — would cause incorrect downstream decision in WP4 / decision-graph propagation
  • MEDIUM — would require a re-touch within the next 1-2 sessions
  • LOW — cosmetic / state-label only, end-state agrees
  • NONE — no contradiction, listed for completeness

Net contradiction count: 0 HIGH, 0 MEDIUM, 5 LOW (C1, C2, C3, C4, C5). None block propagation; all are state-label drift, not direction drift.


3.1 — Items in feedback-findings-review §5 not addressed in the cocoindex doc

Section titled “3.1 — Items in feedback-findings-review §5 not addressed in the cocoindex doc”

These are correctly out-of-scope for cocoindex prereq (route to ontology prereq, operational decisions, or out-of-prereq) but listed here for completeness so Phase 3 propagation knows the cocoindex doc cannot be the source:

ItemFindings-review locationRoutes toCocoindex-doc gap?
Theme A (form-type generalisation) end-state schema§5.1 line 378Ontology (Prereq 1)No — correctly out of scope
Theme E (applications layer)§5.1 line 382OntologyNo — correctly out of scope
Theme F (Mempalace)§5.1 line 383OperationalNo — correctly out of scope
Q1.11 citations polymorphic shape§5.2.2 line 408OntologyNo — correctly out of scope
Q1.12 question_matches discriminator§5.2.2 line 409OntologyNo — correctly out of scope
Q3.11 templates rename to form_templates§5.2.3 line 421OntologyNo — correctly out of scope
Q1.13 Shape B + application_type§5.2.3 line 420OntologyNo — correctly out of scope
OQ-Q113-A per-type satellite registry§5.2.3 line 423OntologyNo — correctly out of scope
OQ-Q35-C form requirement_type=checklist§5.2.4 line 434OntologyNo — correctly out of scope
Finding 05 (all decisions)§5.2.5 line 441OntologyNo — correctly out of scope
OQ-Q19-E backfill for 387 q_a_pair rows§2.1 (DECIDED — no backfill)DECIDEDNo — pre-DECIDED, properly omitted from §5
OQ-Q310-A/B/C, OQ-Q113-B/C, OQ-Q45-A, OQ-Q55-A§2.3/§2.4 (DECIDED items)DECIDEDNo — properly omitted

Verdict: no missed routing. Cocoindex deep-dive correctly stays within its lane (cocoindex affordances + Theme B/C/D/G + Findings 01/02/04/06 substrate decisions). All items not addressed in cocoindex doc are either ontology-routed (Prereq 1) or out-of-prereq operational.

3.2 — Items in cocoindex deep-dive not present in feedback-findings-review §5

Section titled “3.2 — Items in cocoindex deep-dive not present in feedback-findings-review §5”

These ARE present in cocoindex deep-dive but not echoed in feedback-findings §5 — minor propagation gap that should be back-filled if findings-review §5 is intended to be canonical:

ItemCocoindex deep-dive locationFindings-review statusAction
pipeline_failures table fate (DO NOT BUILD)§1.2 line 49 + §4 line 198Not explicitly in §5 (implicit via Theme D + Finding 01 closures)Add row to §5.2.1 (Finding 01) or §5.3.2: “pipeline_failures table: DO NOT BUILD (cocoindex retry/DLQ subsumes)”.
Q4.12 skill-seekers cost-tracking pattern (RETIRE)§1.2 line 50 + §4 line 199Not in §5Add row to §5.2.1 or §5.3.2: “Q4.12 cost-tracking pattern: RETIRE (cocoindex memoisation + per-stage metrics supersede)”.
Entity Resolution scope (selective adoption)§1.1 line 31 + §3.2 lines 127-135 + Rec 3 lines 188-192Findings-review §5.3.2 line 487 has 1-line entry “Entity Resolution capability: RESOLVED — selective adoption” but doesn’t restate scoping rules.OK as 1-liner; deeper scoping (named-entity vs Q&A-pair-dedup vs content_items dedup) lives only in cocoindex doc — propagate the 3-scope split to §5.2 or §5.3 only if WP4 needs explicit reference.
Meeting Notes Graph Neo4j (person-dedup pattern)§1.1 line 29 + §2 line 89§5.3.2 line 490: “RESOLVED-DIRECTIONAL — person-dedup adopted; substrate defers to S7” — present.✓ — no gap.
Cocoindex memoisation @coco.fn(memo=True) retiring Q4.12 cost-tracking§1.1 line 32 + §1.2 line 50Implied via Theme D closure but not explicitOptional row addition to §5.3.2.
Cocoindex pipeline catalog + version tracking§1.1 line 33§5.3.2 line 492: “Persistent Pipeline: RESOLVED — inherit; pipeline_failures DO NOT BUILD” — covers it.✓ — no gap.
Crash recovery§1.1 line 35Not in §5 (subsumed under Persistent Pipeline)OK; no specific row needed.
Recommendation 5 — Prereq 1 ontology mapping to cocoindex flows§4 lines 210-218Not in §5 (cross-prereq architectural binding)Optional — could land as a 1-line note in §5.3.2 or be deferred to WP4 02-data-flow.md.

Verdict: two genuine gaps (pipeline_failures DO-NOT-BUILD + Q4.12 RETIRE) that should be back-filled into feedback-findings-review §5 for completeness. Both are LOW severity — the dispositions are correct, just not echoed.

3.3 — Items mentioned in both but with subtly different framing

Section titled “3.3 — Items mentioned in both but with subtly different framing”
ItemCocoindex deep-dive framingFindings-review framingReconciliation
Theme B step 4 primitive name”Cocoindex Structured Extraction (paper_metadata-style)” — pattern reference”Cocoindex ExtractByLlm” — primitive nameBoth correct: ExtractByLlm IS the named cocoindex op that implements the paper_metadata pattern. Verified in Prereq 2a line 198 (cocoindex.functions.ExtractByLlm).
DOCX step 3 library choice§1.2 line 59: “mammoth+Turndown OR Docling (DOCX)”; §7.1 line 268: “Docling — narrow win, conditional. Consolidate IFF PDF is Docling. mammoth+Turndown stays as fallback for tracked-changes DOCX edge cases.”§5.5 line 535: “Docling (conditional)” + line 554: “Docling conditional (alternative: mammoth+Turndown stays as fallback for tracked-changes DOCX edge case).”✓ — same direction, both name mammoth+Turndown as tracked-changes fallback.

Cross-checking spike facts (phase-b-prerequisite-2d-docling-bakeoff.md as source of truth) against both target docs’ Docling-related sections.

Docling spike claim (2d source)feedback-findings-review §5.5cocoindex deep-dive §7Both accurate?
PDF: Docling decisive win (75 headings + 299 GFM table rows vs markitdown 0+0)Line 534: “75 headings + 299 GFM table rows vs markitdown’s 0 + 0. Q-number↔question-text association intact (critical for SSQ extraction).”Line 267: “Docling — decisive win (75 headings + 299 GFM table rows vs markitdown’s 0+0). Q-number↔question-text association intact.”✓ Both quote the 75 + 299 figures verbatim. Source 2d §2.1 line 65-68 verifies.
PDF wall-clock 44.75sNot quoted explicitly (just “model load on first call”)§7.3 line 286: “Docling model load on first call = 506 MB download; subsequent calls amortise” + general statement✓ — neither doc requotes the 44.75s figure but neither contradicts it. (Source 2d §2.1 line 72.)
DOCX: Docling narrow win, conditionalLine 535: “Narrow win on heading-level fidelity (H1-H4 vs H1-H3); table fidelity tied with markitdown + KH’s existing mammoth+Turndown. Consolidate IFF PDF goes Docling.”Line 268: “Docling — narrow win, conditional. Consolidate IFF PDF is Docling. mammoth+Turndown stays as fallback for tracked-changes DOCX edge cases.”✓ Findings-review provides heading-level detail (H1-H4 vs H1-H3); cocoindex doc more terse. Both name mammoth+Turndown as tracked-changes fallback. Source 2d §2.3 line 113-132 verifies the conditional framing.
XLSX: Docling wins with NCSC URL drop caveatLine 536: “Clean GFM output without NaN/Unnamed: placeholder pollution; merged-cell headers handled correctly. Caveat: appears to drop NCSC URLs from some single-content cells — needs verification on a broader XLSX corpus”Line 269 + §7.4 line 292: “Docling — wins with caveat (NCSC URL drops on some single-content cells — broader corpus verification scheduled)”✓ — both name NCSC URL drop, both flag broader-corpus verification. Source 2d §2.2 line 93 + §6 line 239 verifies.
HTML: keep pullmd, no consolidationLine 537: “Docling matches pullmd’s static-HTML tier but cannot replace pullmd’s Playwright sidecar (JS-pages), Cloudflare short-circuit, Reddit comment-trees, or share-id stable identity contract. Consolidation costs JS-page coverage.”Line 270: “KEEP pullmd — no consolidation. Docling matches static-HTML tier but cannot replace pullmd’s Playwright/Cloudflare/Reddit/share-id stack.”✓ Both list the four pullmd-exclusive features (Playwright/Cloudflare/Reddit/share-id). Source 2d §2.4 + §5 verifies.
License: Docling MITLine 540: “Docling = MIT”Line 274: “Docling = MIT (verified via PyPI + pyproject.toml). KH-compatible.”✓ — cocoindex doc adds “verified via PyPI + pyproject.toml” provenance. Source 2d §3.1 verifies.
License: markitdown MITLine 540: “markitdown = MIT”Line 275: “markitdown = MIT. KH-compatible.”✓ Source 2d §3.1 verifies.
License: pullmd AGPL v3 (pre-existing)Line 540: “pullmd = AGPL v3 (already tracked PM-Q2 per 0.8.4-pullmd-evaluation.md; this spike did not reopen)“Line 276: “pullmd = AGPL v3 (already tracked per 0.8.4 PM-Q2; not reopened)”✓ Source 2d §3.1 + §6 verifies.
Footprint: 1.8 GB on diskLine 546: “Docling | ~1.8 GB (1.3 GB site-packages: torch 443 MB + transformers 101 MB + scipy 98 MB + pandas 71 MB; plus 506 MB HF model cache for layout-heron + docling-models)“Line 277 + line 281: “~1.8 GB on disk (1.3 GB site-packages + 506 MB HF model cache for layout-heron + docling-models). CPU-only viable.”✓ — findings-review has more granular breakdown (per-package MB); cocoindex doc accurate at the aggregate level. Source 2d §3.1 line 178 verifies.
506 MB model cache (HF cache for layout-heron + docling-models)Line 546: “506 MB HF model cache for layout-heron + docling-models”Line 277 + line 286: “506 MB HF model cache”✓ Source 2d §3.1 line 178 verifies.
Cloud Run sidecar required (Vercel 250 MB limit)Line 550: “Docling’s 1.8 GB footprint cannot land in Vercel functions. The form-extraction pipeline must run as a Cloud Run sidecar (KH already runs Cloud Run for the Python pipeline per CLAUDE.md kh-prod-494815 / kh-staging-494815).”Line 281: “Docling’s 1.8 GB footprint cannot land in Vercel functions (250 MB limit). The form-extraction pipeline must run as a Cloud Run sidecar. KH already runs Cloud Run for the Python pipeline (kh-prod-494815 / kh-staging-494815 per CLAUDE.md) — extend the deployment to host the Docling-backed cocoindex flow.”✓ — both name kh-prod-494815 / kh-staging-494815 per CLAUDE.md. Source 2d §3.2 line 183 verifies.
Finding 06 “zero new deps” OBSOLETELine 550: “Finding 06’s ‘zero new dependencies for v1’ claim is OBSOLETE if Docling adopted.” Line 571: “‘Zero new deps for v1’ claim OBSOLETE — Docling 1.8 GB. Cloud Run sidecar required.”Line 284: “Finding 06’s ‘zero new dependencies for v1’ claim is OBSOLETE. Update phase-b-prerequisite-2c-cocoindex-doc-handling.md §1.1 + Finding 06 source-doc explorer doc.”✓ — both flag OBSOLETE; cocoindex doc additionally names the downstream doc updates required. Source 2d §6 line 242 verifies.
Partial failure: XLSX NCSC URL dropLine 562: “Docling XLSX drops NCSC URLs from some Principle rows where URL was sole cell content | MEDIUM | Verify on broader XLSX corpus before commit.”Line 292: “Docling XLSX drops NCSC URLs from cells where URL is sole content | MEDIUM | Verify on broader XLSX corpus before WP4 land.”✓ — minor wording variance (“before commit” vs “before WP4 land”) but same MEDIUM severity + same recommendation. Source 2d §2.2 line 93 + §6 line 239 verifies.
Partial failure: markitdown 0.0.2 vs 0.1.5Line 563: “markitdown 0.0.2 resolved on Python 3.14 (PyPI head is 0.1.5) | LOW | Re-run bake-off on KH’s target Python version (3.x — verify) before commit.”Line 293: “markitdown 0.0.2 resolved on Python 3.14 (head = 0.1.5) | LOW | Re-run bake-off on KH target Python version. Architectural verdict unchanged.”✓ Source 2d §1.1 line 21 + §6 line 240 verifies.
Partial failure: tracked-changes DOCX not testedLine 564: “Tracked-changes DOCX NOT tested | MEDIUM | Add tracked-changes DOCX to Theme B regression suite.”Line 294: “Tracked-changes DOCX not tested | MEDIUM | Add tracked-changes DOCX to Theme B regression suite. May surface the python-docx Gotcha (Document(path) direct calls).”✓ — both name MEDIUM + Theme B regression suite. Cocoindex doc additionally references CLAUDE.md python-docx Gotcha. Source 2d §1.4 line 53 + §6 line 243 verifies.
Confidence: 88%Line 528: “387-line empirical report, 88% confidence”Line 261: “387-line empirical report, 88% confidence”✓ Source 2d §7 closing line 387 verifies.

Docling propagation verdict: PASS — both docs accurately quote the spike’s per-format winners, license verdict, dependency footprint, Cloud Run architectural requirement, Finding 06 obsolescence finding, and all three partial-failure surfaces. Minor wording variance only; no factual drift. The 88% confidence figure is consistent across all three documents (2d source + 5.5 + §7).


§5 — Finding 06 + Theme B specific audit

Section titled “§5 — Finding 06 + Theme B specific audit”

5.1 — Finding 06 viewer architecture + Theme B step 3 consistency

Section titled “5.1 — Finding 06 viewer architecture + Theme B step 3 consistency”
Cocoindex doc saysFindings-review saysConsistent?
§1.2 line 59 (Theme B step 3): “Reusable cocoindex pipeline converter with format-specific @coco.fn per MIME. Library choices: pandas (XLSX), mammoth+Turndown OR Docling (DOCX), Docling (PDF), pullmd (HTML).”§5.1 line 379 (Theme B): “Reusable cocoindex pipeline converter with format-specific @coco.fn per MIME — gates on Docling fidelity spike for Docling vs alternatives library choice.”✓ — both align on per-MIME @coco.fn architecture.
§6 line 253 (Finding 06): “Markdown sidecar v1 = Tiptap ContentEditor unchanged. PDF flow: cocoindex pdf_to_markdown OR existing PdfReaderView (gates on Docling spike). XLSX flow: cocoindex converter + structured form UI (Theme B). DOCX flow: cocoindex converter or mammoth+Turndown (gates on Docling fidelity).”§5.2.6 line 447-450 (Finding 06): “sidecar-v1 architecture (markdown → Tiptap ContentEditor). PDF flow + DOCX flow gates on Docling spike. … DOCX flow rewrite RESOLVED-DIRECTIONAL — Markdown → Tiptap (existing ContentEditor); conversion library gates on Docling fidelity spike (mammoth+Turndown alternative if Docling fails on track-changes). PDF flow rewrite RESOLVED-DIRECTIONAL — cocoindex pdf_to_markdown (Docling-backed) for sidecar conversion; existing PdfReaderView for read-only view.”✓ — both align on PDF read-only fallback via PdfReaderView; both align on cocoindex converter + Tiptap edit for editable surface; both align on mammoth+Turndown as DOCX tracked-changes fallback.
§7.1 line 267-270 (post-spike) + §7.5 line 571: “RESOLVED — sidecar-v1 (markdown → Tiptap ContentEditor) with Docling-backed cocoindex pipeline producing the sidecar markdown.”§5.5 line 571: “Finding 06 DOCX/PDF/XLSX viewer rewrite: RESOLVED — sidecar-v1 (markdown → Tiptap ContentEditor) with Docling-backed cocoindex pipeline producing the sidecar markdown.”✓ — identical wording (word-for-word match), consistent with original Finding 06 §4.1 primary recommendation.

Both docs commit to sidecar v1 architecture: binary (localfs) → cocoindex converter → markdown sidecar → Tiptap. Originally proposed in Finding 06 §4.1 + §6, ratified per Liam’s notes in feedback-findings §4.6 lines 344-350 (“binary (localfs) -> convert all file types to markdown (localfs sidecar) -> any edits made via UI update the localfs markdown sidecar”). Both prereq docs preserve this commitment in their post-spike sections.

5.3 — Cloud Run sidecar architectural requirement

Section titled “5.3 — Cloud Run sidecar architectural requirement”
Cocoindex docFindings-reviewConsistent?
§7.3 lines 280-286: full paragraph mandating Cloud Run sidecar deployment for cocoindex + Docling, naming kh-prod-494815 / kh-staging-494815, calling out Vercel hosts Next.js app + UI; Cloud Run hosts ingest + extraction.§5.5 line 550: “Docling’s 1.8 GB footprint cannot land in Vercel functions. The form-extraction pipeline must run as a Cloud Run sidecar (KH already runs Cloud Run for the Python pipeline per CLAUDE.md kh-prod-494815 / kh-staging-494815). Finding 06’s ‘zero new dependencies for v1’ claim is OBSOLETE if Docling adopted.”✓ — both name the same Cloud Run projects; both flag Finding 06 obsolescence; both attribute to CLAUDE.md as the deployment-pattern source.

Finding 06 + Theme B verdict: PASS — fully consistent on viewer architecture (per-MIME, sidecar v1, Tiptap ContentEditor as edit surface), conversion library choices (Docling primary, mammoth+Turndown fallback for tracked-changes DOCX, pullmd for HTML), Cloud Run sidecar deployment requirement, and zero-new-deps claim obsolescence.


Consistency verdict: PASS-WITH-NOTES

Confidence: 92%.

The 8% drag is:

  • C1 + C5 internal inconsistency within cocoindex deep-dive (§2 disposition table stale relative to §7 spike resolution). Reader navigating only §2 would land on STILL-OPEN states that §7 has resolved.
  • C2 N2 cataloguer state-label mismatch (deep-dive STILL-OPEN→implicit defer in closing line; findings-review explicit RESOLVED→defer). Same end-state but cocoindex doc less crisp.
  • Two minor gaps in findings-review §5 (pipeline_failures DO-NOT-BUILD + Q4.12 RETIRE) not back-propagated from cocoindex doc §1.2. End-state agreement but findings-review §5 incomplete relative to cocoindex doc.

No HIGH or MEDIUM contradictions surfaced. All 5 LOW-severity contradictions are state-label drift within a single document, not direction drift between documents. End-state directions agree on all ~40 cross-checked items.

Top-3 fixes required before propagation to Phase 3 docs

Section titled “Top-3 fixes required before propagation to Phase 3 docs”
  1. Resolve C1: Reconcile cocoindex deep-dive §2 disposition table with §7 spike resolution. Add a [UPGRADED BY §7 — see §7.1 + §7.5] annotation to §2 rows where state-label is stale (line 83 Theme B; line 96 N2; line 98 Finding 06; lines 98-99 Finding 06 zero-new-deps). This prevents a Phase 3 reader of decision-graph/collapse-candidates from grepping §2 and missing the spike resolution. OR rewrite the §2 cells inline to RESOLVED with cross-ref to §7. Either approach acceptable; second is cleaner.
  2. Add the pipeline_failures DO-NOT-BUILD and Q4.12 RETIRE rows to feedback-findings-review §5.2.1 (or §5.3.2). These two dispositions are in cocoindex doc §1.2 lines 49-50 but missing from §5. Without them, propagating §5 into 0.9-decision-graph.md would miss the retire-seed direction from cocoindex deep-dive. ONE-line additions each.
  3. Update cocoindex deep-dive §5 still-open list header to “REPLACED BY §7.5” (C5). §7.5 says “Updated still-open list (replaces §5)” but §5 text remains intact 226-237, so a reader greping for STILL-OPEN finds stale entries. Either delete §5 still-open table or prepend a [SUPERSEDED BY §7.5] warning header.

Top-3 fixes that can defer to next session

Section titled “Top-3 fixes that can defer to next session”
  1. C2 N2 cataloguer wording crispness in cocoindex deep-dive §7. Add an explicit §7.x row for N2: “N2 cataloguer skill build-trigger: RESOLVED — defer; build-now flagged only if broader XLSX corpus verification fails.” Matches findings-review §5.5 wording.
  2. Theme E (applications layer) cross-reference in cocoindex doc. Cocoindex doc doesn’t currently reference Theme E (correctly out-of-scope) but a one-line note “Applications layer per Theme E (ontology-routed) — orthogonal to cocoindex; see findings-review §5.1” would help WP4 readers triangulating across both prereqs.
  3. Findings-review §5.4 + §5.5 consolidation pass (C4). §5.4 has pre-spike “IN-FLIGHT” entries that §5.5 supersedes. Either annotate §5.4 or fold §5.5 entries back into §5.4. End-state is correct; readability could be tightened.

  1. Read both docs end-to-end (cocoindex deep-dive 315 lines; findings-review 578 lines).
  2. Read tertiary sources as ground truth:
    • phase-b-prerequisite-2d-docling-bakeoff.md (387 lines, Docling spike empirical source)
    • phase-b-prerequisite-2c-cocoindex-doc-handling.md (370 lines, doc-handling capability source)
    • phase-b-prerequisite-2a-cocoindex-examples.md (556 lines, ExtractByLlm primary source)
    • 10-feedback-investigation-findings/00-synthesis.md (306 lines, S233 directional baseline)
    • 10-feedback-investigation-findings/06-cx33-source-doc-explorer.md (Finding 06 source)
  3. Built canonical disposition matrix (§1) — cross-referenced ~40 items (Themes A-G, B1/B2/I1/I2/I3, cocoindex affordances, per-finding closures, OQs).
  4. Grepped both docs for key terms: Docling, markitdown, sidecar, Cloud Run, 1.8 GB, 506 MB, NCSC, tracked.changes, ExtractByLlm, paper_metadata, instructor, Option α, Option β, slim-and-keep, source_document, form_template_requirements, question_matches, edit_intent, polymorphic, citing_entity, peer.class, content_history, content_items, cataloguer, N2, diff UI, source_document_diffs, Q-XL1, Q-EX2, Pattern A, Phew, migration.
  5. Cross-checked Docling spike facts against both target docs at numeric/string-literal level (75 headings, 299 table rows, 1.8 GB, 506 MB, 88% confidence, kh-prod-494815 / kh-staging-494815, NCSC URL drop, markitdown 0.0.2 vs 0.1.5, tracked-changes DOCX).
  6. Audited Finding 06 + Theme B specifically (§5) for cross-doc viewer architecture consistency.

~40 disposition rows verified; ~13 Docling spike-fact rows verified; 7 themes verified; 5 BLOCKING/IMPORTANT decisions verified; 17 OQs verified; 6 finding-doc closures verified. Total ≈ 90 verification points.

  • State-label drift vs direction drift: I distinguish between “the cocoindex doc says RESOLVED-DIRECTIONAL and findings-review says RESOLVED” (state-label drift — both same end-state direction) vs “the cocoindex doc says α and findings-review says β” (direction drift — different end-state). All 5 contradictions found are state-label drift; 0 direction drift.
  • Adversarial bias acknowledged: I was instructed to find contradictions, not validations. The output skews toward calling out drift; the verdict is PASS-WITH-NOTES because all drift is recoverable in-session, not because the docs are flawless.
  • No empirical re-verification of Docling spike claims — I trusted phase-b-prerequisite-2d-docling-bakeoff.md as ground truth. Spike was empirical (file outputs at /tmp/claude-501/docling-bakeoff/outputs/); if Phase 3 propagation goes badly, re-verifying the spike numbers against the actual output files is the right escalation.
  • pipeline_failures + Q4.12 gap detection assumes findings-review §5 is intended to be the canonical Phase 3 propagation source. If both docs are intended to feed Phase 3 in parallel, the gap is moot.

End of Phase B Prerequisite 2 verification. Verdict: PASS-WITH-NOTES, 92% confidence. Top-3 in-session fixes: (1) reconcile cocoindex deep-dive §2 with §7 (C1 + C5), (2) back-fill pipeline_failures + Q4.12 rows into findings-review §5, (3) explicit “REPLACED BY §7.5” header on cocoindex doc §5 still-open list. Propagation to 0.9-decision-graph.md / 0.9-collapse-candidates.md / 00-synthesis-v2.md is safe after the three in-session fixes; deferring them risks Phase 3 grepping stale STILL-OPEN entries in cocoindex doc §2/§5.