ID-135 {135.4} PLAN — OKF human search/browse + source_document provenance UI
ID-135 {135.4} PLAN — OKF human search/browse + source_document provenance UI
Section titled “ID-135 {135.4} PLAN — OKF human search/browse + source_document provenance UI”Status: PLAN artefact — not self-ratified. Authored 28/06/2026 by a fresh Planner instance (Q-PLANNER-2 — NOT the {135.1}/{135.2}/{135.3} authors). British English throughout; dates DD/MM/YYYY.
Predecessors (read in full):
{135.3}TECH.md (gated PASS_WITH_NOTES) — the §3 BI→ proposed-change mapping and §4 concrete-artefact inventory are this decomposition’s source;{135.2}PRODUCT.md (gated PASS_WITH_NOTES) — the 32 invariants BI-1 … BI-32 the Subtasks satisfy;{135.1}RESEARCH.md §2 reuse-or-rebuild verdict matrix for grounding.Decomposition output: 14 implementation Subtasks
{135.5}…{135.18}, recorded as a JSON array inplan-subtasks.json(this directory) — the ledger intent the Orchestrator applies on MAIN viabun scripts/ledger-cli.ts add-subtasks 135 --file <path>. Every record carries load-bearingdetails, a ≤300-chartestStrategy, and sibling-only dependencies. No Subtask carries a cross-Task dependency (the two cross-Task couplings — {131.11}/{131.19} and BND-1 Path β — are carried as Task-level sequencing, below).
1. Overview
Section titled “1. Overview”Two net-new, read-only, authenticated UI surfaces over the OKF L-records model:
- Surface A (
/search) — corpus search/browse/filter overq_a_pairs+source_documentsreference_items, a parallel copy-and-generalisation of the shipped id-111 reference stack ({135.5}–{135.10}).
- Surface B (
/documents/[id]) —source_documentdetail/provenance viewer composing the id-111 detail-shell pattern + the id-117 diff/version leg + the id-111 B-28 provenance field set ({135.11}–{135.18}).
The decomposition slices vertically per surface, foundation-first, with each Subtask mapping
to one or more TECH §3 proposed changes (cited in every details field). No DDL (TECH §8).
2. Architecture decisions (inherited from TECH, load-bearing for sequencing)
Section titled “2. Architecture decisions (inherited from TECH, load-bearing for sequencing)”- The TECH §5
CorpusSearchResultdiscriminated union is the stable internal contract. Surface A is built against it now, with a mapping layer inuseCorpusSearchreconciling {131.11} AC4’s actual/api/searchemit at the read boundary (AAT-2). This decouples Surface A implementation from the in-flight {131.11} integration — Subtasks build and unit-test against the target shape with mocked emit; live reconciliation is the Task-level gate (§5). - All
lib/query/query-keys.tsedits for both surfaces are centralised in {135.5} (the foundation Subtask) so no two parallel Subtasks edit that file — eliminating the only shared-file cherry-pick hazard between Surface A and Surface B. - The diff/version engine is reused, never rebuilt (HARD RULE): {135.15} links out to the
shipped
/documents/[id]/diff(UnifiedDiffContainer+sourceDocumentRevisionToUnified). - Both surfaces are authenticated, not public — neither route is added to
proxy.tspublicRoutes; omission is what enforces the/loginredirect (BI-1).
3. Subtask slice plan + dependency graph (sibling-only)
Section titled “3. Subtask slice plan + dependency graph (sibling-only)”Full records (title / description / details / testStrategy / dependencies) are in
plan-subtasks.json. Summary:
| ID | Slice | TECH proposed change(s) | Effort | Deps (sibling) |
|---|---|---|---|---|
| {135.5} | Foundation — types/corpus-search.ts + query-key namespaces | §5 union, §4 query-keys (BI-3/BI-14) | S | — |
| {135.6} | useCorpusSearch hook (URL-driven, infinite, mapping layer) | §3 BI-9/10/11/17/20, §4, §5 | M | {135.5} |
| {135.7} | CorpusResultCard (polymorphic per-kind) | §3 BI-12/13/14, §4 | M | {135.5} |
| {135.8} | Corpus controls (search box / filters / kind-narrow) | §3 BI-9/15/16, §4 | M | {135.5} |
| {135.9} | Surface A page shell + CorpusSearchContent + states | §3 BI-1/7/8/17/18/19/20, §4, §2 | M | {135.6},{135.7},{135.8} |
| {135.10} | Surface A nav entry (id-118-coupled) | §3 BI-21, §4 | XS | {135.9} |
| {135.11} | BND-1 Path α — re-point [id] route → derived_pairs | §3 BI-29, §6 BND-1, §4 | S | — |
| {135.12} | Citations read route | §3 BI-27, §4 (AAT-4) | S | — |
| {135.13} | Surface B detail hooks (versions/citations/derived) | §3 BI-25/27/28/30, §4 | M | {135.5},{135.11},{135.12} |
| {135.14} | SourceDocumentProvenance panel | §3 BI-24 (+BI-3), §4 | S | — |
| {135.15} | DocumentVersionList + diff link-out | §3 BI-25/26, §4 (RD-4) | S | {135.13} |
| {135.16} | DocumentCitationsPanel | §3 BI-27, §4 (AAT-4) | S | {135.13} |
| {135.17} | DerivedPairsList | §3 BI-28, §4 | XS | {135.13} |
| {135.18} | Surface B detail page + SourceDocumentDetailClient shell | §3 BI-1/22/23/24/30/31, §4, §2, BND-2 | M | {135.14},{135.15},{135.16},{135.17} |
Dependency graph (arrows = “depends on”):
Surface A: {135.5} ──┬─→ {135.6} ─┐ ├─→ {135.7} ─┼─→ {135.9} ─→ {135.10} └─→ {135.8} ─┘
Surface B: {135.11} ─┐ {135.12} ─┼─→ {135.13} ─┬─→ {135.15} ─┐ {135.5} ──┘ ├─→ {135.16} ─┼─→ {135.18} └─→ {135.17} ─┘ {135.14} ───────────────────────────────┘All 14 Subtasks live within id-135; every dependency edge is {135.x}→{135.y}. No cross-Task
Subtask dependency exists (verified). 14 Subtasks is well under the 25-Subtask soft ceiling.
4. Parallel-vs-serial waves (disjoint file sets parallel; shared files serial)
Section titled “4. Parallel-vs-serial waves (disjoint file sets parallel; shared files serial)”Cherry-pick (not merge) parallel branches per the worktree discipline; the only shared-file
serialisation point (lib/query/query-keys.ts) is removed by centralising it in {135.5}.
- Wave 1 (foundation + Surface B independents): {135.5} ‖ {135.11} ‖ {135.12} ‖ {135.14}.
Disjoint files (
types/corpus-search.ts+query-keys.ts;[id]/route.ts;citations/route.ts;source-document-provenance.tsx). Risk: {135.5} is the bottleneck for all of Surface A — schedule first. {135.11} carries the BND-1 branch decision (§5). - Wave 2: {135.6} ‖ {135.7} ‖ {135.8} (Surface A, all dep {135.5}, disjoint files) ‖ {135.13} (Surface B hooks, dep {135.5}/{135.11}/{135.12}, own file). All disjoint — fully parallel.
- Wave 3: {135.9} (Surface A page, dep {135.6}/{135.7}/{135.8}) ‖ {135.15} ‖ {135.16} ‖ {135.17} (Surface B panels, dep {135.13}, disjoint files). Parallel.
- Wave 4: {135.10} (nav, edits
site-header.tsx) ‖ {135.18} (Surface B page+client). Disjoint files — parallel.
Highest-risk-first note: {135.6} (the mapping layer / infinite-query hook against the in-flight contract) and {135.11} (BND-1 route re-point) are the two riskiest slices; both land early (Waves 1–2) so contract drift fails fast.
5. Cross-Task couplings — carried at TASK level (NOT as Subtask deps)
Section titled “5. Cross-Task couplings — carried at TASK level (NOT as Subtask deps)”5.1 BND-1 (OQ-5) — WHO re-points app/api/source-documents/[id]/route.ts
Section titled “5.1 BND-1 (OQ-5) — WHO re-points app/api/source-documents/[id]/route.ts”The decomposition defaults to Path α: {135.11} is a self-contained Surface-B Subtask that
re-points the route (drop the eliminated content_items join; read published q_a_pairs by
source_document_id; return derived_pairs). This keeps every Subtask dependency sibling-only.
- Path α (DEFAULT — id-135 owns it): {135.11} ships the re-point. No cross-Task dependency.
- Path β (parent may rule at ratification): id-131’s
content_items-elimination sweep ships the re-point. Then {135.11} is DROPPED, and id-131 becomes a Task-level upstream sequencing dependency the PARENT manages — recorded as an id-135 → id-131 Task-dependenciesintent, never encoded as a Subtask cross-Task dep. {135.13}/{135.17} consumederived_pairsregardless of who lands it.
Parent action: rule α vs β before the Surface-B wave (Wave 1). If β, drop {135.11} from the
add-subtasks array and add the id-135→id-131 Task dependency.
5.2 In-flight {131.11}/{131.19} — the §9 search/citations contracts
Section titled “5.2 In-flight {131.11}/{131.19} — the §9 search/citations contracts”Surface A’s live behaviour and Surface B’s citations panel depend on id-131 deliverables still in
flight: the polymorphic hybrid_search / EMB-STORE, the typed /api/search shape ({131.11} AC4),
the application_type ranking-profile threading, and the CITE-EXT citations contract. These are
Task-level gates, recorded as an id-135 → id-131 Task-dependencies intent for the parent
— NOT Subtask deps. The Surface-A Subtasks build against the TECH §5 CorpusSearchResult union as
the stable internal contract (with a mapping layer reconciling {131.11} AC4’s actual emit), so
they are implementable + unit-testable now against the target with mocked data; the
live-integration reconciliation pass (AAT-1/2/3) and the citations-contract reconciliation
(AAT-4) are the Task-level sequencing the parent owns before id-135 ships to users.
Parent action: record the id-135 → id-131 Task-level dependency; sequence the Surface-A live-integration verification (and Surface-B citations verification) after {131.11}/{131.19} land.
(No Subtask cannot be expressed with sibling-only deps — no Task-split/merge escalation is required. Both cross-Task couplings resolve cleanly at the Task level.)
6. Ratification gate handoff
Section titled “6. Ratification gate handoff”The human ratification gate at the parent should confirm the following before the implementation waves dispatch. All are inherited from PRODUCT §“Ratification decisions” and TECH §6 — listed here so the gate is a single checklist.
Ratification decisions (RD):
- RD-1 (OQ-1): Surface A is a distinct corpus-search surface that links INTO
/library(not a/librarymode). Baked into {135.9} (BI-7). - RD-2 (OQ-4): Surface A exposes a kind-narrow control (narrows only). Baked into {135.8} (BI-15).
- RD-3 (OQ-8): Surface A renders
reference_itemhits inline as a third result kind →/reference/[id]. Baked into {135.7} (BI-12/13). See advisory note (a). - RD-4 (OQ-9): Surface B renders an inline version list + links out to the diff (does not embed a full diff by default). Baked into {135.15} (BI-25/26).
Assumptions-against-target (AAT) — gated on id-131 (§5.2):
- AAT-1 (OQ-2): §9 polymorphic
hybrid_searchover EMB-STORE — {135.6}/{135.9}. - AAT-2 (OQ-3): typed polymorphic
/api/searchshape — {135.6} mapping layer. - AAT-3 (OQ-4):
application_typeranking-profile threading — {135.6} (BI-11). - AAT-4 (OQ-6): CITE-EXT
cited_target_kindcontract — {135.12}/{135.16} (BI-27).
Boundary decisions (BND):
- BND-1 (OQ-5): route-re-point ownership — Path α default ({135.11}); parent rules α/β (§5.1).
- BND-2 (OQ-10): id-135 adds the sibling
app/documents/[id]/page.tsxinto id-117’s existing/documents/[id]tree — confirm the shared-route-tree seam (no behavioural coupling). {135.18}.
Out of scope (OOS):
- OOS-1 (OQ-7): no related-records affordance, no keyword pre-filter facet in either surface v1 (BI-32) — recorded as the §9-dropped co-design backlog seam. No Subtask proposed.
PRODUCT advisory notes for the gate:
- (a)
reference_itemas a third grain is §9-MANDATED, not merely recommended. Although RD-3 is tabled as a “recommended” decision, the §9 search-ALL default requires reference hits to appear; excluding them would contradict BI-10. The gate should treat RD-3 as load-bearing, not optional. - (b) id-118 nav grouping is UNRATIFIED. {135.10} (BI-21) places the Surface-A nav entry under the id-118-ratified corpus grouping, which is pending. {135.10}‘s Executor must ship consistently with whatever id-118 ratifies (never a divergent slot) and escalate to the Orchestrator if the grouping is still unratified at dispatch. The parent should sequence the id-118 grouping decision before Wave 4.
7. Acceptance for this artefact
Section titled “7. Acceptance for this artefact”PLAN.md exists; the 14 implementation Subtasks have load-bearing details + ≤300-char
testStrategy + sibling-only dependencies; each maps to a TECH proposed change (cited in
details); no cross-Task Subtask dependency exists (the two cross-Task couplings are carried at
Task level per §5). Quality bars (semantic Warm Meridian tokens, UK English/DD/MM/YYYY,
auth.success+authFailureResponse, sb()/tryQuery(), no barrels, TanStack-only, bun run test, proxy.ts non-addition, diff engine reused never rebuilt) are baked into every relevant
Subtask’s details so Executors inherit them automatically.
End of {135.4} PLAN. 14 Subtasks {135.5}…{135.18} in plan-subtasks.json; vertical-slice,
foundation-first, sibling-only DAG; BND-1 α/β branch + the {131.11}/{131.19} coupling carried at
Task level (no Subtask cross-Task dep, no Task-split/merge escalation required); ratification-gate
handoff consolidated. No code, no DDL, no ledger writes, no commits.