okf-record-model-v3 — CRITIC NOTES (read before driving any Task)
okf-record-model-v3 — CRITIC NOTES (read before driving any Task)
Section titled “okf-record-model-v3 — CRITIC NOTES (read before driving any Task)”Critic verdict: SOUND_WITH_CAVEATS. One blocker (resolvable, needs owner confirmation), caveats to fold into Task scoping, confirmations independently verified. These supersede the named v3 sections.
BLOCKER — q_a_pairs reproducibility vs bundle citation — RESOLVED (owner ratified 2026-06-28: “Anchors only”)
Section titled “BLOCKER — q_a_pairs reproducibility vs bundle citation — RESOLVED (owner ratified 2026-06-28: “Anchors only”)”RATIFIED RESOLUTION: the OKF bundle (L-concepts) cites ONLY deterministic anchors
{source_document, reference_item, concept}; q_a_pair citation is DB-INTERNAL ONLY. q_a_pairs keep the
opaque gen_random_uuid() master PK. This is now a SEED-CONTRACT clause (Task B). Detail retained below.
- v3 §2.2 keeps the
q_a_pairsmaster PK opaquegen_random_uuid()(non-deterministic across full-replace rebuilds) and says “nothing external depends on a stable master uuid.” TRUE for source_documents/reference_items/q_a_extractions (deterministic uuid5 seeds) — FALSE for q_a_pairs. - BUT CITE-EXT (§3.4) activates
q_a_pairas a citation target, and §1/§7.2 have L-concepts cite records viacanonical://<table>/<uuid>. If a CONCEPT in the client-owned bundle cites aq_a_pair, every full-replace re-ingest re-mints that uuid → orphaned citation, even pre-launch. The SEED-CONTRACT (freeze seed STRINGS) cannot fix it — the master tier has no seed string.
RESOLUTION (recommended) — the bundle cites deterministic anchors only
Section titled “RESOLUTION (recommended) — the bundle cites deterministic anchors only”The OKF bundle (L-concepts) cites ONLY deterministic anchors: source_document (rel_path seed),
reference_item (source_url seed), and concept-path. It does NOT cite q_a_pairs.
- Why: provenance flows
source_document → concept → q_a_pair. A bid Q&A answer DERIVES from the concept/source; a concept citing a Q&A answer is backwards (the answer is downstream USE, not evidence FOR the concept). - The
citationstable’sq_a_pairtarget kind stays valid for DB-internal citations (draft reuse, forms completion, win-rate) — these are rebuilt on full-replace and need no cross-rebuild stability, so opaque PK is fine there. - A metric/dataset concept (e.g. “Cyber-Essentials bid win-rate”) points at q_a_pairs as a table /
query via
resource:, not per-row uuids — so no per-row q_a_pair pin is ever needed in the bundle. - SEED-CONTRACT addition: “Bundle citation target set = {source_document, reference_item, concept}; q_a_pair citation is DB-internal only.” Keeps q_a_pairs opaque-DB-native AND closes the hole.
ALTERNATIVE (only if the owner wants bundle→q_a_pair per-row citations)
Section titled “ALTERNATIVE (only if the owner wants bundle→q_a_pair per-row citations)”Give q_a_pairs a deterministic master seed (feasible via the built merge-anchor) — but adds merge/edit re-mint complexity and contradicts “opacity is a feature.” Not recommended.
CAVEATS (fold into Task scoping — do not change the conclusions)
Section titled “CAVEATS (fold into Task scoping — do not change the conclusions)”- “8 of 22 columns”: hybrid_search returns 21, not 22 (the 8-mapped figure is correct; denominator off by one).
- content_items footprint is larger than the section-by-section enumeration: 184
.from('content_items')sites across 142 files (65 app/api, 15 lib/mcp); governance is 66 files (not ~60). Task B is correctly the largest Task. “Cheaper than it appears” = the VALUE-PATH output contract is small (8 mapped cols), NOT the whole Task. quality_issues_pendingis a VIEW over content_items (0 rows) — uncounted consumer; rewrite/drop with the table.q_a_extractions.source_content_item_idis a 3rd bare-uuid ref (handled by QA-REPARENT).declare_fileorphan-delete + fingerprint-overwrite semantics mean a machine-regenerated, client-OWNED bundle dir will OVERWRITE human hand-edits. Task A must define the human-edit-vs-regeneration reconciliation, not just git-sync.- Path drift: forms-matching is
lib/domains/procurement/form-templating/template-coverage.ts(v3 sayslib/procurement/...); substance + line 519 correct.
CONFIRMATIONS (independently verified against the live DB / current head)
Section titled “CONFIRMATIONS (independently verified against the live DB / current head)”- Record-identity thesis holds: sd/qa/ri uuid5 seeds at the cited flow.py lines; namespace constant
fbfaf1ff-1ee4-583c-9757-1674465b2ec1(flow.py:1640); source_documents has ONLY a PK (no UNIQUE on storage_path/content_hash) so the seed string IS the idempotency; q_a_pairs.id DEFAULT gen_random_uuid() DB-assigned; two-tier merge anchor built (promoted_to_pair_id + source_document_id + superseded_by); reference_items UNIQUE(source_url). The “SD keeps rel_path / Q&A master already DB-only opaque / nothing to switch” correction is accurate. - content_items decomposition: exactly 10 enforced FKs + 2 unenforced bare-uuid cols; source_documents is a lean 21-col provenance table with NO classification/freshness/governance/title/created_by → “~25-30 net-new cols” is right; v2’s “mostly already on SD” is FALSE. cite_content still writes cited_kind=‘content_item’; get_content_win_rate has 2 live callers (NOT dead).
- WINRATE-FIX dual-outcome-source bug is REAL (get_content_win_rate via form_outcome_types vs hybrid_search.win_stats via workspaces.domain_metadata).
- Governance-as-facet well-grounded: q_a_pairs carries only the hot subset; reference_items zero governance (BI-16 enforceable as CHECK); governance footprint 66 TS files; the 3 freshness/review DB fns exist.
- Producer net-new (zero okf/producer/reference_agent/declare_file hits in the pipeline); declare_file is a native incremental file target (cocoindex v1.0.7); 6 scattered vector cols (5 vector + company_profiles.company_embedding as TEXT).
- {127.4} gap real: 33 content_items, 0 content_chunks, 496 pipeline_runs on prod (partial pipeline never completed an end-to-end content write).
- Zero-prod-data-lock-in verified: governance_config=0, q_a_pairs=0, q_a_extractions=0, content_chunks=0, content_templates=0; content_items=33 (E2E debris); form_template_requirements=96; reference_items=3.