Skip to content

ID-135 {135.1} RESEARCH — OKF human search/browse + source_document provenance UI (reuse-or-rebuild reconciliation)

ID-135 {135.1} RESEARCH — OKF human search/browse + source_document provenance UI

Section titled “ID-135 {135.1} RESEARCH — OKF human search/browse + source_document provenance UI”

Status: RESEARCH artefact — not self-ratified. Authored 28/06/2026, fresh Planner dispatch (Q-PLANNER-2). British English throughout; dates DD/MM/YYYY.

Task: ID-135 — two net-new human-facing UI surfaces over the OKF L-records model. Surface A (was bl-386): human search/browse/filter over q_a_pairs + source_documents, filling the gap left by the deleted IMS browse/item UI. Surface B (was bl-387): source_document detail/provenance viewer — version chain, citations, and which q_a_pairs derive from each document.

The load-bearing job of {135.1} (owner note, S429): bl-386/387 were authored possibly unaware of id-117 and the id-110/111/118 reference-item UI/UX work. This RESEARCH gives an explicit reuse-or-rebuild verdict per surface against each of id-110/111/117/118, with the concrete component/route/hook each verdict maps to. HARD RULE honoured: no net-new component is proposed without first checking the reference-item / diff-surface equivalent and stating why it cannot be reused/extended.


1.1 Code-intelligence orientation (cited verbatim, not paraphrased)

Section titled “1.1 Code-intelligence orientation (cited verbatim, not paraphrased)”

Tools run against the indexed main repo /Users/liamj/Documents/development/canonical (the repo: 'canonical' name was ambiguous — two registered repos match; the absolute path disambiguates). On-disk existence re-verified in the id-135 worktree at HEAD 3a222eac feat(id-131 {131.9}): G-SD-COLS M3 classification cols.

  • gitnexus_query({query: 'reference item browse detail search list page'}) → top processes proc_155_referencedetailpage (ReferenceDetailPage → Cn) and proc_160_browsecontent (BrowseContent → UseBrowseFilters). Definitions surfaced the shipped id-111 reference stack: Function:app/reference/reference-content.tsx:ReferenceContent (44–165), Function:app/reference/reference-content.tsx:ReferenceSearchBox (173–225), Function:hooks/reference/use-reference-data.ts:useReferenceData (146–369), Interface:hooks/reference/use-reference-data.ts:ReferenceListPage (62–66), Function:app/reference/[id]/reference-detail-client.tsx:ReferenceDetailError (205–221), plus the query-key factories Function:lib/query/query-keys.ts:browse (20–21) / library (23–24) / list (41–42). The IMS browse stack (app/browse/browse-content.tsx:BrowseContent 58–672, hooks/browse/use-browse-data.ts BrowsePage/UseBrowseDataReturn) also surfaced — present but slated for BI-12 deletion (§1.3).
  • gitnexus_query({query: 'source document provenance version chain revision diff viewer'}) → surfaced the shipped id-117 diff stack: Interface:lib/diff/unified-revision.ts:UnifiedRevision (99–147) / :UnifiedDiff (162–167), Function:lib/diff/adapters/source-document-revision.ts:sourceDocumentRevisionToUnified (53–83), Function:components/diff/binary-diff-pane.tsx:BinarySide (112–231), Function:app/documents/[id]/diff/page.tsx:DocumentDiffPage (83–208), Function:components/item-detail/version-history.tsx:VersionHistory (166–473), Function:components/qa/qa-revision-history.tsx:QARevisionHistory (62–140), Function:lib/source-documents/source-document-impact.ts:analyseDocumentImpact (46–146), and the q_a_pair history route Function:app/api/q-a-pairs/[id]/history/route.ts:GET (31–92).
  • gitnexus_query({query: 'hybrid search api route web search hook results'}) → top processes are the homepage SearchBar (components/browse/search-bar.tsx:SearchBar 39–568) and the MCP lib/mcp/tools/search.ts:registerSearchTools (76–819) / findSimilarItemsImpl (267–383). The human web search surface is the loosely-coupled SearchBar/api/searchhooks/use-search.ts pass-through (§2.3), distinct from the AI MCP find.
  • gitnexus_context({name: 'useReferenceData'})hooks/reference/use-reference-data.ts 146–369; incoming.calls: exactly ONEReferenceContent (app/reference/reference-content.tsx); outgoing accesses isLoading/error; processes: []. The Surface-A reuse base is a single-caller list+search hook.
  • gitnexus_context({name: 'UnifiedDiffContainer'})components/diff/unified-diff-container.tsx 74–105; incoming.calls: exactly ONEDocumentDiffPage (app/documents/[id]/diff/page.tsx); outgoing.calls: BinaryDiffPane, toRevisionBlob, RevisionDiffView (components/item-detail/revision-diff-view.tsx), deriveRenderMode (lib/diff/unified-revision.ts); processes: []. The Surface-B version/diff reuse base is a single-caller composition over the landed engine.
  • ccc search fallback: attempted for both greenfield claims (ccc search "source document detail provenance viewer page ..." and ccc search "q_a_pair human search browse filter list page"). The cocoindex-code daemon errored in this environment (DaemonStartError traceback — same failure id-111’s TECH recorded). The greenfield claims below therefore rest on the definitive gitnexus + on-disk ls/find evidence, which is conclusive for the two specific gaps.

1.2 The greenfield gaps (verified absent on disk)

Section titled “1.2 The greenfield gaps (verified absent on disk)”
  • No human q_a_pair search/browse page. find app -path '*q-a-pairs*' -name page.tsx returns only admin surfaces (app/admin/q-a-pairs/dedup-proposals/...); the rest of app/api/q-a-pairs/* is API/promotion/dedup. There is no reader-facing q_a_pair browse/search/list page. Surface A is genuinely net-new as a page.
  • No source_document detail/provenance page. app/documents/[id]/ contains only diff/ (page.tsx + error.tsx + loading.tsx) — id-117 shipped the version-compare route but no app/documents/[id]/page.tsx detail landing. Surface B is net-new as a page, but composes shipped id-117 pieces (§4).

1.3 The L-records read schema these surfaces read (id-131 PRODUCT/TECH)

Section titled “1.3 The L-records read schema these surfaces read (id-131 PRODUCT/TECH)”
  • q_a_pairs — the answer grain. Carries the hot lifecycle subset inline (publication_status, superseded_by, valid_from, valid_to — BI-20; q_a_search filters publication_status on every query), answer_standard/answer_advanced, scope_tag[], source_document_id (nullable provenance — BI-15/BI-33), opaque gen_random_uuid() PK (BI-5), origin_kind (incl. new 'manually_authored', BI-33). Question-embedded in EMB-STORE. Primary match grain for Surface A.
  • source_documents — the provenance/citation anchor. NO embedding (BI-29) — never a direct vector-match target. {131.9} (shipped on this HEAD) added the classification family (primary_domain, primary_subtopic, secondary_domain, secondary_subtopic, ai_keywords, summary, classification_confidence, classification_reasoning, classified_at, … — BI-11) plus a M3 domain-sync trigger, so SD now carries the metadata both surfaces render. Identity seed sd:{rel_path} (BI-3); content_hash audit; version/parent_id version chain (id-117); storage_path/mime_type for the binary leg.
  • reference_items — external evidence; flat, workspace-less, write-once, UNIQUE(source_url) (BI-6); no version chain / history (id-117 OQ-117-6 confirmed out). Owned by id-111/id-118; explicitly out of Surface A/B scope as a primary grain (§9 of the design routes reference surfaces elsewhere), but reference results DO appear in the §9 search-ALL default (Surface A renders them as one of three result kinds).
  • record_lifecycle facet (BI-18/BI-20/BI-22) — cold governance/freshness, polymorphic (owner_kind, owner_id); freshness axis = {source_document} only, review axis = {source_document, q_a_pair}. Surface B may surface SD freshness/review state from here.
  • EMB-STORE (BI-17) — polymorphic (owner_kind, owner_id, model) vector store; the substrate Surface A’s search reads through. In flight (§3).

    S438 {135.19} reconcile: “EMB-STORE” was the design codename; the shipped store is record_embeddings. Per {131.11} (G-SEARCH, implemented-to-commit on cmux-worker-subo-search-13111), hybrid_search is a 4-arm polymorphic UNION over record_embeddings (source_document text-only, content_chunk→SD collapse+dedup, q_a_pair ×1.1 profile, reference_item) — see §1.4.

  • Citations (BI-23 CITE-EXT) — cited_target_kind extended to {content_item→removed, q_a_pair, reference_item, source_document, concept}; Surface B’s “citations” panel reads these. In flight (§3).

1.4 The {131.20} §9 ratified search/sourcing contract (target Surface A designs against)

Section titled “1.4 The {131.20} §9 ratified search/sourcing contract (target Surface A designs against)”

The owner-ratified ({131.20} §9, S428) search redesign that {131.11} G-SEARCH implements — the target contract Surface A’s behaviour must assume (not the legacy content_items path):

  • Default scope = ALL owner_kinds (q_a_pair + content_chunksource_document + reference_item), retrieved per-grain, normalised, then merged — NOT a flat 4-way cosine UNION, and NOT scope-narrowed to q_a_pairs.
  • Answer-first is a bounded boost (~×1.1), applied after per-grain normalisation, living in a named ranking PROFILE selected by application_type (derived from workspace_id). One profile ships now (answer-first default; procurement is q_a_pair-primary — sales-proposals/sector-intelligence profiles are later config).
  • content_chunk hits collapse up to their source_document for result identity + citation (one underlying fact → one hit; de-dup by provenance). SD is reached via chunks, never embedded directly.
  • Result content_type field now carries owner_kind/record-kind (BI-27 semantic change, owner-approved §7.3) so the two-step preview→fetch resolves a polymorphic id.
  • type/scope param NARROWS only (type=q_a_pair = prior-answer match + forms path).
  • find_related_items + filter_by_keywords are DROPPED (§9 §7.4/§7.5). Related-records and a keyword facet are future backlog, co-designed with these surfaces — so a “related records” affordance and a keyword pre-filter are explicitly NOT Surface A v1 features (they are flagged here as the co-design seam).

1.5 Reuse-prohibited: the IMS browse/item stack (id-131 BI-12)

Section titled “1.5 Reuse-prohibited: the IMS browse/item stack (id-131 BI-12)”

On this HEAD ({131.9}) the legacy IMS stack is still present (components/content/*: content-card.tsx, content-grid.tsx, content-list.tsx, …; app/browse/, app/item/, app/library/) because id-131 sequences drops last and {131.11}+ are in flight. id-131 BI-12 / design §6 delete this stack (it binds dropped IMS columns). Therefore it is reuse-PROHIBITED for Surfaces A/B — Surface A exists precisely to replace the eliminated IMS /browse. The reuse base is the id-111 reference stack + the id-117 diff stack, never the IMS content stack. (/library is the one exception — BI-33 repoints it to q_a_pairs inside id-131; its relationship to Surface A is the single biggest reuse question — §6, OQ-1.)

S438 {135.19} reconcile (D7): the BI-33 /libraryq_a_pairs repoint was DEFERRED out of id-131 (at the {131.2} ratification) to the id-71 AI-tooling family ({71.16}/ID-59/ID-69); /library still reads content_items today. Surface A’s /library link target is therefore not an id-131 guarantee — it is an open owner decision (NO-1); see OQ-1 and the §6 handoff.


2. Per-surface reuse-or-rebuild verdict matrix

Section titled “2. Per-surface reuse-or-rebuild verdict matrix”

Each cell: {reuse as-is | extend | rebuild | n/a} + mapped artefact + one-line justification. “n/a” = the effort is not a UI analogue for that surface (orthogonal), recorded so the HARD RULE check is explicit, not skipped.

S438 {135.19} reconcile (DR-013): the “EXTEND / HARD RULE” reuse framing below is superseded. Per DR-013 the id-135 surfaces are net-new-by-design: Surface A reuses the id-111 stack only at the leaf/pattern level (its single-grain, non-paginated useReferenceData forces the polymorphic abstraction), and Surface B reuses id-117’s version-chain data leg only (RPC + /versions route + diff link-out) — NOT UnifiedDiffContainer. Read the verdict cells below as reuse evidence, not as an extend-in-place mandate.

Surface A — human search/browse/filter over q_a_pairs + source_documents

Section titled “Surface A — human search/browse/filter over q_a_pairs + source_documents”
vsVerdictMaps toJustification
id-110 (url_import→reference_items, backend re-point)n/a (no UI reuse)— (backend write-path; IngestionSuccessCard only)id-110 is a backend re-point + a success-card link; it ships no browse/search UI. Only carry is the evidence-vs-knowledge framing, irrelevant to a read surface.
id-111 (reference browse/detail UI)EXTENDapp/reference/reference-content.tsx (ReferenceContent, ReferenceSearchBox), hooks/reference/use-reference-data.ts (useReferenceData, ReferenceListPage), lib/query/query-keys.ts (list/browse factories)Closest analogue. Page shell, search box, list/card, empty/loading/error states, reduced-filter UX (domain/subtopic/date), URL-driven search state, infinite-list pattern are directly reusable. But grain differs: id-111 is single-RPC reference-scoped (reference_list/reference_search, one ReferenceListItem shape); Surface A is polymorphic multi-grain over the §9 search-ALL contract (per-grain normalise + merge + answer-first profile, result card rendered per owner_kind). So copy-and-generalise the shell/hook/card to a polymorphic result type — EXTEND, not reuse-as-is.
id-117 (diff/version surface)n/a (orthogonal)Search/browse has no diff/version need. id-117 reuse is Surface B’s.
id-118 (reference nav + corpus IA)EXTENDcomponents/shell/site-header.tsx NAV_LINKS, components/shell/command-palette.tsx; id-118’s option-B “Knowledge Base” corpus groupingSurface A is a new corpus-layer surface replacing the eliminated IMS /browse. Its nav slot must be co-decided under the same corpus-vs-application IA decision id-118 frames (don’t ship a divergent nav). Reuse id-118’s placement/role-uniform/active-state machinery.

Surface B — source_document detail/provenance viewer (version chain + citations + derived q_a_pairs)

Section titled “Surface B — source_document detail/provenance viewer (version chain + citations + derived q_a_pairs)”
vsVerdictMaps toJustification
id-110 (url_import provenance pair)reuse as-is (field set, no component)id-111 detail-page B-28 SD-join (tryQuery over source_documents.select('original_filename, filename, mime_type, extraction_method, source_url, created_at'), plain-language extraction_method)id-110 lands the sd+ri provenance pair; the SD provenance field set + plain-language rendering id-111 already built (B-28) is the direct template for Surface B’s provenance panel. Reuse the field set + rendering verbatim; no new component.
id-111 (reference detail page)EXTENDapp/reference/[id]/reference-detail-client.tsx + app/reference/[id]/page.tsx (read-only detail shell: notFound(), loading/error, markdown body, metadata badges, provenance affordance)The reference detail page shape is the template for the SD detail page shell. But SD is richer: it is the provenance anchor itself, with a version chain (id-117), citations (BI-23), and derived q_a_pairs — features a flat reference lacks. So EXTEND the id-111 detail shell with the version/citation/derived-pairs sections.
id-117 (unified diff/version surface)REUSE-AS-IS (version/diff leg) + EXTEND (add detail page)components/diff/unified-diff-container.tsx (UnifiedDiffContainer), lib/diff/adapters/source-document-revision.ts (sourceDocumentRevisionToUnified), app/api/source-documents/[id]/versions/route.ts (get_document_version_chain RPC), app/documents/[id]/diff/page.tsx, app/api/source-documents/[id]/send-to-review/route.tsMaterial overlap — the load-bearing reuse. The SD version chain + diff Surface B needs is already shipped by id-117 (version-chain RPC + route + UnifiedDiffContainer + SD adapter + re-ingest review). REUSE-AS-IS: the SD detail page links to / embeds the existing /documents/[id]/diff and renders the version list from get_document_version_chain. EXTEND: id-117 deliberately built no app/documents/[id]/page.tsx detail landing — Surface B ADDS that missing sibling page in the same route tree. HARD RULE: do NOT build a net-new version-diff component — UnifiedDiffContainer is reused.
id-118 (corpus IA)EXTENDapp/documents/[id] route tree; site-header (no own nav slot)id-118 frames /documents as a homeless corpus route. Surface B (/documents/[id]) is a detail destination reachable from Surface A’s SD search results, not a top-nav entry. Fold its IA into id-118’s corpus grouping; no standalone nav link.

HARD-RULE audit (net-new components proposed): Surface A’s polymorphic result card + generalised list/search hook is the only genuinely net-new component — and it is an EXTEND of useReferenceData + ReferenceContent’s ReferenceListItem card, justified by the single-RPC→multi-grain grain change (§9). Surface B’s SD detail page is net-new as a page but composes id-111’s detail shell + id-117’s UnifiedDiffContainer/version chain + id-111’s B-28 provenance field set — no net-new version/diff/detail-shell component.


3. Read-contract dependency list (shipped vs in-flight → OQ)

Section titled “3. Read-contract dependency list (shipped vs in-flight → OQ)”

The id-131 search/API waves ({131.11} G-SEARCH / {131.19}) are still in flight. Surface A must design against the §9 target contract; anything {131.11}+ has not shipped is an OQ, never assumed present.

Read-contractStateNote
§9 polymorphic hybrid_search (per-grain normalise + merge, content_chunk→SD collapse, owner_kind in result)IN FLIGHT ({131.11}) → OQ-2The whole Surface-A result model depends on this; design against §9 target, do not assume shipped.
Typed polymorphic /api/search web result shape (replacing SearchResult extends ContentListItem, types/content.ts:135)IN FLIGHT ({131.11} AC4) → OQ-3Today hooks/use-search.ts POSTs /api/search{results, count} typed as content_items SearchResult. {131.11} must hand the web path a typed polymorphic shape; Surface A consumes that, not the legacy one.
Per-application_type ranking profile (one shipped; answer-first default)IN FLIGHT (§9) → OQ-4workspace_idapplication_type threading into /api/search (§9 AC4). Surface A renders results under the one shipped profile.
EMB-STORE (BI-17)IN FLIGHT ({131.11}) → OQ-2The retrieval substrate; gated before any RPC rewrite (id-131 AC11).
q_a_pairs.publication_status (hot, inline)SHIPPED (BI-20)Surface A filters published pairs.
source_documents classification cols (primary_domain, summary, …)SHIPPED on this HEAD ({131.9})SD result cards + the SD detail page can render these now.
record_lifecycle facet (SD freshness/review)IN FLIGHT (id-131 F-cluster)Optional for Surface A v1 (search need not show governance).
Read-contractStateNote
get_document_version_chain RPC + app/api/source-documents/[id]/versions routeSHIPPED (id-117)Version chain reuse is ready.
UnifiedDiffContainer / source-document-revision adapter / /documents/[id]/diffSHIPPED (id-117)Diff leg reuse ready.
app/api/source-documents/[id] GET (SD row + linked records)SHIPPED but BREAKSOQ-5The route currently joins content_items (select('id,title,content_type,...').eq('source_document_id', id)). id-131 BI-9 eliminates content_items — this read must re-point to q_a_pairs (the “derived pairs” the SD detail page renders). This is a dependency + a defect-in-waiting, not an assumption.
Citations contract (BI-23 CITE-EXT: cited_target_kind incl. source_document, q_a_pair)IN FLIGHT (id-131 G-cluster, atomic w/ WINRATE-FIX) → OQ-6Surface B’s “citations” panel reads these; citations is 0 rows today, so design against the extended contract, not the dormant one.
”Which q_a_pairs derive from this SD” = q_a_pairs.source_document_idSHIPPED (schema)Filterable now; the route exposing it is OQ-5’s re-point.

4. IA / nav placement findings (id-118 precedent)

Section titled “4. IA / nav placement findings (id-118 precedent)”
  • Current NAV_LINKS (components/shell/site-header.tsx): /browse, /library, /coverage, /workspaces, /change-reports, /intelligence, /review, /settings. No /reference entry — confirming id-118 (surface reference nav) is spec_needed / unbuilt (bun scripts/ledger-cli.ts show task 118: status: "spec_needed", dep [111]).
  • id-118 settled context (from its ledger record): standalone corpus surfaces are the ratified design (ID-75 BI-16 two-surface principle); References = corpus layer, peer to Browse + Q&A Library, not inside any application. Open decision (Liam): (A) top-level corpus nav entry now [recommended] → (B) “Knowledge Base” group collapsing Browse+Library+References [best long-term] → (C) contextual-only.
  • Consequence for id-135: post-id-131 the corpus-nav set is reshaped — /browse (IMS content_items) is eliminated (BI-12), /library is repointed to q_a_pairs (BI-33), /reference is the id-111 surface (id-118 to surface). Surface A is the replacement for the eliminated /browse (cross-grain search/browse) and Surface B (/documents/[id]) is a detail destination, reachable from Surface A’s SD results, with no own nav slot. Recommendation: id-135’s nav placement must be co-decided with id-118, not shipped divergently — Surface A becomes the corpus search/browse entry (under id-118’s option-B “Knowledge Base” grouping), Surface B inherits the corpus IA without a top-nav link. (id-118’s own scope already flags /documents as a homeless corpus route.)

  1. Surface A vs the BI-33 /library q_a_pair viewer (the biggest reuse question). After id-131 BI-33, /library (app/library/library-content.tsx — a TanStack-virtualised list with search/filter/tag) becomes the q_a_pair viewer/editor. Surface A is a cross-grain search/browse. Are these one surface or two? Is Surface A a mode of the repointed /library, or a distinct corpus-search surface that links into /library for single-pair read/edit? This materially shapes the whole of Surface A and overlaps two Tasks. PRODUCT must decide; may need Orchestrator Task-boundary input.

    S438 {135.19} reconcile (D7): the /libraryq_a_pairs repoint this OQ assumes lands “inside id-131” was DEFERRED out of id-131 to the id-71 family ({71.16}/ID-59/ID-69) at {131.2}; /library still reads content_items. Surface A’s answer-result deep-link target is an open owner decision (NO-1) — not an id-131 deliverable.

  2. Polymorphic hybrid_search / EMB-STORE result contract (§9) is in flight ({131.11}). Surface A cannot finalise its result model until the typed polymorphic result shape + owner_kind field + per-grain merge are shipped. Design against §9 target; flag the dependency on {131.11}/{131.19}.
  3. Typed polymorphic /api/search web shape. The SearchResult extends ContentListItem coupling (types/content.ts:135, consumed by hooks/use-search.ts) breaks under id-131. Surface A depends on {131.11} AC4 delivering the replacement typed shape — confirm its fields before Surface A’s card/hook are specified.
  4. Ranking profile exposure. Does Surface A surface any profile/scope control to the user (e.g. a “documents only” / “answers only” type narrow), or is the one shipped answer-first profile entirely implicit (AI-invisible-infrastructure)? §9 says type narrows only; the UX affordance is undecided.
  5. SD detail route’s content_items join breaks (OQ-5 above). app/api/source-documents/[id]/route.ts joins content_items; id-131 eliminates that table. Surface B’s “derived records” panel must read q_a_pairs via source_document_id. Is re-pointing this route an id-135 deliverable, or does it belong to id-131’s content_items-elimination sweep? Boundary question for the Orchestrator.
  6. Citations panel contract. BI-23 CITE-EXT (extended cited_target_kind) lands as one atomic slice in id-131 and citations is 0 rows today. Confirm the shipped contract shape before Surface B’s citations panel is specified; until then it is design-against-target.
  7. Related-records + keyword facet are §9-DROPPED / future backlog. §9 §7.4/§7.5 drop find_related_items and filter_by_keywords and route related-records (ontology-grounded)
    • a keyword facet param to future backlog co-designed with these surfaces. Confirm both are out of Surface A/B v1 (recommended) — they are the named co-design seam, not v1 features.
  8. Reference grain in Surface A’s results. §9 default scope includes reference_item results, but reference surfaces are owned by id-111/id-118. Does Surface A render reference hits inline (as one of three result kinds, linking out to /reference/[id]), or exclude them? Recommended: render inline + link out (the §9 search-ALL intent), reusing id-111’s reference card.
  9. Provenance depth on Surface B. id-111 B-28 surfaces SD original_filename / extraction_method / landed date. Surface B is the SD itself — does it additionally surface record_lifecycle freshness/review state, content_hash audit, and the full version chain inline, or link out to /documents/[id]/diff for the chain? Recommended: inline version list + link-out to the diff route for pairwise compare.
  10. /documents/[id]/diff ownership boundary. id-117 owns the diff route; Surface B adds the sibling /documents/[id] detail page and links to it. Confirm id-135 may add to the id-117 route tree (it should — same surface family) vs. coordinating a shared seam.

6. What PRODUCT ({135.2}) must decide — handoff list

Section titled “6. What PRODUCT ({135.2}) must decide — handoff list”
  1. Resolve OQ-1 first — Surface A vs the BI-33 /library viewer: one surface or two. Everything else in Surface A’s scope follows from this. (May need an Orchestrator Task-boundary call before {135.2} proceeds.)

    S438 {135.19} reconcile (D7): the BI-33 /library q_a_pair viewer repoint is deferred out of id-131 (to the id-71 family); do not treat the /library answer-link destination as an id-131 guarantee — it needs an owner decision (NO-1).

  2. Fix the spec tier per surface. Surface A is behaviourally ambiguous (search ranking, filters, polymorphic results, in-flight dependencies) → full PRODUCT + likely TECH. Surface B is largely a composition of shipped id-111/id-117 pieces + one new page → PRODUCT
    • a thin TECH for the OQ-5 route re-point and the version/citation embedding.
  3. Lock the reuse verdicts (§2) as the implementation spine: Surface A EXTENDs the id-111 reference stack (shell + useReferenceData + card → polymorphic); Surface B EXTENDs the id-111 detail shell + REUSEs id-117’s UnifiedDiffContainer/version chain + reuses id-111’s B-28 provenance field set. No net-new browse/detail/diff component.
  4. State every in-flight dependency as an explicit assumption-against-target (OQ-2/3/4/6), not a present fact — Surface A’s behaviour invariants must reference the §9 contract, and the Checker must be able to see which reads are gated on {131.11}/{131.19}.
  5. Decide the §9-dropped affordances out (OQ-7): no related-records, no keyword pre-filter in v1; record them as the co-design backlog seam.
  6. Co-decide nav/IA with id-118 (§4): Surface A as the corpus search/browse entry under the “Knowledge Base” grouping; Surface B as a detail destination with no own nav slot.
  7. Carry the quality bars into every invariant: semantic Warm Meridian tokens only, UK English, DD/MM/YYYY, getAuthorisedClient() + authFailureResponse(auth), sb()/tryQuery(), TanStack Query only, no barrel re-exports, bun run test, behaviour-first tests. Both surfaces are read-only, authenticated, role-uniform (inherit id-111 B-21) and AI-invisible-infrastructure (no “AI search” chrome, no raw scores).

7. Empirical verification (OQ-3 / Q-EX2 scope)

Section titled “7. Empirical verification (OQ-3 / Q-EX2 scope)”

This RESEARCH cites no external-library symbols. Every symbol referenced is internal Canonical (useReferenceData, ReferenceContent, ReferenceSearchBox, UnifiedDiffContainer, sourceDocumentRevisionToUnified, the reference/version-chain RPCs, hybrid_search), Postgres/Supabase RPC surface (get_document_version_chain, .from().select(), .rpc()), or Next.js/TanStack framework (notFound, useQuery, useInfiniteQuery) — all out of the import-and-call verification scope (external-library symbols only, per shared-discipline §Empirical verification). No verification block required. The one runtime contract that will drift is the §9 polymorphic search shape and the OQ-5 content_items route join — both carried as explicit OQs gated on {131.11}, not as unverified assumptions.


End of {135.1} RESEARCH. Reuse-or-rebuild verdict given per surface against id-110/111/117/118 with mapped artefacts; read-contract dependencies split shipped/in-flight; IA folded into id-118; 10 OQs + a PRODUCT handoff list. No implementation, no DDL, no ledger writes, no commits.