Skip to content

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 in plan-subtasks.json (this directory) — the ledger intent the Orchestrator applies on MAIN via bun scripts/ledger-cli.ts add-subtasks 135 --file <path>. Every record carries load-bearing details, a ≤300-char testStrategy, 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).

Two net-new, read-only, authenticated UI surfaces over the OKF L-records model:

  • Surface A (/search) — corpus search/browse/filter over q_a_pairs + source_documents
    • reference_items, a parallel copy-and-generalisation of the shipped id-111 reference stack ({135.5}–{135.10}).
  • Surface B (/documents/[id]) — source_document detail/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 CorpusSearchResult discriminated union is the stable internal contract. Surface A is built against it now, with a mapping layer in useCorpusSearch reconciling {131.11} AC4’s actual /api/search emit 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.ts edits 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.ts publicRoutes; omission is what enforces the /login redirect (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:

IDSliceTECH proposed change(s)EffortDeps (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, §5M{135.5}
{135.7}CorpusResultCard (polymorphic per-kind)§3 BI-12/13/14, §4M{135.5}
{135.8}Corpus controls (search box / filters / kind-narrow)§3 BI-9/15/16, §4M{135.5}
{135.9}Surface A page shell + CorpusSearchContent + states§3 BI-1/7/8/17/18/19/20, §4, §2M{135.6},{135.7},{135.8}
{135.10}Surface A nav entry (id-118-coupled)§3 BI-21, §4XS{135.9}
{135.11}BND-1 Path α — re-point [id] route → derived_pairs§3 BI-29, §6 BND-1, §4S
{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, §4M{135.5},{135.11},{135.12}
{135.14}SourceDocumentProvenance panel§3 BI-24 (+BI-3), §4S
{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, §4XS{135.13}
{135.18}Surface B detail page + SourceDocumentDetailClient shell§3 BI-1/22/23/24/30/31, §4, §2, BND-2M{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-dependencies intent, never encoded as a Subtask cross-Task dep. {135.13}/{135.17} consume derived_pairs regardless 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.)

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 /library mode). 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_item hits 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_search over EMB-STORE — {135.6}/{135.9}.
  • AAT-2 (OQ-3): typed polymorphic /api/search shape — {135.6} mapping layer.
  • AAT-3 (OQ-4): application_type ranking-profile threading — {135.6} (BI-11).
  • AAT-4 (OQ-6): CITE-EXT cited_target_kind contract — {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.tsx into 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_item as 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.

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.