KH Ontology — Markdown Register
KH Ontology — Markdown Register
Section titled “KH Ontology — Markdown Register”Status: Editor wave (S236 WP6 C2) — frontmatter provenance + Relationships + Consumers + cross-link tables added on top of C1 (B1 findings + INV-1/2/3 + Liam direct rulings + UK English).
Scope (DR-027): This directory is the human-readable Layer-1 CV register / development mirror — the contract layer for the platform’s controlled vocabularies. It is NOT the source of truth for the OKF concept/entity/relationship vocabulary: per DR-027, those base system CVs live in the canonical repo (producer/validator.py, lib/ontology/*), versioned with the linter that enforces them; canonical’s parity tests guard this mirror against drift. See initiatives/core-product/knowledge-base-foundations/okf-platform/ontology-sync.md.
This register implements Layer 1 (Controlled Vocabulary) of the Talisman Ontology Pipeline retrospectively for KH. Source: docs/plans/phase-0-investigation/phase-b-prerequisite-1-onthology-pipeline.md §2.1 + §6.
Purpose
Section titled “Purpose”KH currently has 33 controlled vocabularies scattered across 5 different homes (DB enums, DB tables, TS const tuples, TS type unions, Zod schemas). There is no single artefact that:
- Lists every term across the platform
- Defines each term and its synonyms / acronyms
- Records lifecycle (active / planned / needed)
- Captures provenance (
core/client/hybrid) and editability (database_migration/admin_ui/seed_data) - Cross-references where the vocabulary is consumed
This register fills that gap. It is the Talisman Layer-1 starting artefact KH never built, authored retrospectively to unblock Phase 2-6 ontology work.
Multi-agent update workflow
Section titled “Multi-agent update workflow”Per Liam (S235 Wave 1 ratification), updates to this register follow a sequential multi-agent workflow for quality:
- Drafter agent — Writes initial Markdown files from source (
phase-b-prerequisite-1-onthology-pipeline.md§2.1). Output: 29 .md files + this README. Current wave (S236 WP6 A1). - Verifier agent — Adversarially diffs every value list against live DB CHECK constraints,
lib/validation/schemas.ts, andtypes/*.ts. Reports drift items (no edits — drift report only). - Editor agent — Applies verifier findings, improves prose, ensures UK English, completes provenance and cross-references.
- Ratifier agent — Confirms WP-ONTO-R1 §6.3 frontmatter compliance, writes
lib/ontology/schemas.tsZod schema validating every file, writes__tests__/lib/ontology/markdown-parity.test.tsVitest harness, wires the first downstream consumer (asserts thesource_documents.content_typeenum matches the markdown-declared values in04-content-type.md; historicallycontent_items.content_type, pre-ID-131). - Implementer / ratifiers (Liam) — Final ratification of any open questions before merging.
Do NOT collapse these stages into a single pass. Each stage exists to catch a different failure mode.
Frontmatter shape (Zod-validated)
Section titled “Frontmatter shape (Zod-validated)”Every CV file MUST carry frontmatter matching phase-b-prerequisite-1-onthology-pipeline-feedback-investigation.md §6.3 verbatim:
---cv_name: <name>layer: <1-6 per Talisman>provenance_model: core | client | hybridclient_extensible: true | falseeditable_via: database_migration | admin_ui | seed_datacore_seed_path: <path or null>related_layers: [<list of layer ints>]status: active | planned | neededbaseline_values: - key: <key> label: <label> provenance: core | client | recommended - ...---Per-file body sections: Definition, Synonyms / Acronyms, Baseline values, Relationships, Consumers, Notes.
Provenance model — at a glance
Section titled “Provenance model — at a glance”Three classifications per §6.2 of the WP-ONTO-R1 doc:
- CORE — Ships with the platform, can’t be deleted by clients. Closed enums (e.g.
content_type,change_type,lifecycle_type). - CLIENT — Empty by default; clients add via admin UI (e.g.
scope_tag). - HYBRID — Ships with baseline values that clients can override or extend (e.g.
taxonomy_domains,application_type,requirement_type).
Each individual term within a hybrid CV carries its own provenance — core, client, or recommended. This pattern mirrors the existing taxonomy_domains.provenance precedent.
Where does new data live?
Section titled “Where does new data live?”The decision procedure for ANY new artefact class a future activity introduces. Source: docs/research/s314-ontology-boundary.md §6, as amended by ID-75 BI-22 (the Q1a/Q1b split + the adoption promotion edge). Check this rule FIRST when a spec proposes a new table, a new content_type value, or a new storage home.
The three storage layers these boxes occupy — L-raw (client raw sources), L-records (the Canonical DB), and L-concepts (the client OKF bundle) — are defined in 36-three-layer-model.md; that OKF storage-layer axis is ORTHOGONAL to the 03-layer-vocabulary audience axis. L-concepts are client-owned, NOT a DB table.
Q1 — Is it a unit of usable knowledge (text a consumer should retrieve, cite, or ground AI answers on)? Q1 splits in two:
-
Q1a — client-canonical / client-adopted knowledge → split by record type (ID-131 retires the
content_itemsgod-table; ID-133 re-aligns the register to the three-layer model):- a canonical answer (a question paired with a vetted answer) →
q_a_pairs(32-q-a-pair.md); - a provenance-bearing document body (a classified, chunked source body, retrieved and cited) →
source_documents+content_chunks(the retrieval grain); - a distilled concept that is NOT a record (a synthesised, reusable idea) → an L-concept in the client OKF bundle (
36-three-layer-model.md) — client-owned, NOT a DB table.
All three are embedded + classified + chunked (ID-56 C-1..C-30), with provenance via
source_document_id/source_url/ingest_source. Workspace scoping is query-timescope_tagoverlap, not an M2M association — thecontent_item_workspacesjunction is dropped (ID-131). If the artefact is meaningless without an owning workspace — an operational instrument, not a unit of knowledge — it is not a canonical record; go to Q3. Examples: an uploaded policy doc →source_documents; a vetted question/answer →q_a_pairs; a distilled methodology write-up → an L-concept. - a canonical answer (a question paired with a vetted answer) →
-
Q1b — external evidence admitted by a curation gate → the reference layer (
reference_items,33-reference-item.md): global, workspace-less, embedded, cited as external evidence. The relevance gate admits evidence, not knowledge (ID-75 DP-5). Examples: gate-passed feed articles, manually imported URLs.
Q2 — Is it the raw original (binary/URL identity, custody, extraction lineage) of something in Q1? → source_documents (one row per original; FK from the Q1 row). Never workspace-scope it on the canonical path. Examples: the uploaded DOCX, the fetched URL.
Q3 — Is it an operational instrument or workflow artefact with its own lifecycle, schema, and (usually) workspace ownership? → First-class Layer-5 table(s) + Layer-1 CVs for its discriminators — the forms pattern: instance table(s), discriminator CVs, optional global catalogue. Register it: a Layer-5 entity file in this directory (the 32-q-a-pair.md shape). Examples: blank forms, bids/responses.
Q4 — Is it a discovery/triage/audit record about candidate or rejected inputs? → Sidecar table with a nullable promotion FK — the feed_articles pattern: workspace-scoped, dedup-keyed on external identity, carries the gate fields, retained for audit even when never promoted. Q4 sidecars promote into Q1b, not Q1a: feed_articles.reference_item_id is the promotion FK (ID-75 BI-10).
The Q1b→Q1a edge is the adoption act (ID-75 BI-13): external evidence becomes canonical knowledge only by an explicit, cited adoption or derivation — never automatically. It mirrors the extraction→pair promotion edge of the Q&A model.
Two corollaries: (1) Never solve Q3/Q4 — or Q1a/Q1b placement — with a new content_type value: the enum is closed and describes editorial shape within a source_documents classification, not storage routing (the q_a_pair migration-out and the reference layer’s no-content-type rule are the precedents). (2) The same real-world activity usually produces artefacts in several boxes at once (a feed item: Q4 staging row + Q2 provenance row + Q1b evidence row) — route each artefact, not the activity.
Docs-site auto-update (Astro + Starlight)
Section titled “Docs-site auto-update (Astro + Starlight)”The pattern is “MD source-of-truth → mirror to docs site”. This directory is the source; the Astro + Starlight site is its mirror. Since ID-68 the docs corpus and its automation live in this private docs-site repo (relocated under {68.26}/{68.27}); the earlier framing of a public-repo docs-site/ sub-directory and a deferred production-readiness build is retired.
Stack ratified S237: Astro + Starlight (NOT GitBook). Liam ratified Astro+Starlight as the framework; the GitBook framing in earlier drafts is retired.
Build trigger pattern (docubot lane — live in this repo; see RELOCATION-STATUS.md §Docubot lane):
- A merged PR to
mainin the publicknowledge-hubrepo fires a thindocs-dispatch.ymlrepository_dispatch(kh-public-pr-merged,client_payload.pr_number) into this repo. .github/workflows/docubot.ymlconsumes the event, mints a GitHub App token covering BOTH repos (APP_ID/APP_PRIVATE_KEYsecrets), and runs the composite action.github/actions/docubot/(rendersprompt.txt, checks the public repo out atKH_PUBLIC_REPO_DIRfor source context, invokes the Claude Agent SDK driver atharness/scripts/docubot/run-agent.ts).- The agent reads the changed source in the merge, regenerates the corresponding pages under
src/content/docs/, and opens a docs-only follow-up PR in this repo, commenting once on the public source PR.
Authentication: the cross-repo GitHub App (APP_ID / APP_PRIVATE_KEY repo secrets) — a plain GITHUB_TOKEN is insufficient now the docs-site is a separate repo.
Conversion rules: the keep-docs-in-sync skill (.claude/skills/keep-docs-in-sync/SKILL.md, loaded by the agent) encodes the conversion between this directory’s frontmatter shape (per §“Frontmatter shape (Zod-validated)” above) and Starlight’s content-collection schema. The root AGENTS.md is the docs-corpus style guide the drivers fail-loud-require.
Validation harness: every CV frontmatter is contracted by the Zod schema lib/ontology/schemas.ts (OntologyCVSchema) and bound to the runtime artefacts by the parity guards — see “Decision-A authority chain” below. The earlier cocoindex scripts/ontology-sync/parse-flow.py sync stub and the lib/ontology/loader.ts register reader are retired (ID-133 Decision A): the register markdown is the human contract, never read at runtime.
Cross-references:
src/content/docs/themes/workflow-orchestration/kh-workflow-orchestration-assessment.md§8 (original docubot replication plan)src/content/docs/specs/wp6-ontology-harness/TECH.md§8 (cocoindex parse → validation flow plan)- WP-ONTO-R1 §6.3 (frontmatter shape — input contract to the docs-sync agent)
RELOCATION-STATUS.md§Docubot lane (current wiring)
Decision-A authority chain (single source of truth + lockstep)
Section titled “Decision-A authority chain (single source of truth + lockstep)”The private docs-site register is THE single human source of truth; every other artefact is a DERIVED mirror kept in lockstep by parity guards (ID-133 Decision A; specs/id-133-ontology-three-layer-pass/TECH.md §“Decision A”). The dead lib/ontology/loader.ts is retired rather than repointed at the private register — repointing would add a reader without removing drift.
| Role | Artefact | Kept in lockstep by |
|---|---|---|
| Human source of truth | ${KH_PRIVATE_DOCS_DIR}/…/ontology/*.md | authored by hand; docubot lane |
| Public mirror (CI-visible) | __tests__/fixtures/ontology/ontology-cv-baselines.json (EXPANDED: + entity_type, + relationship) | docs-site “parity-guard twin” (ID-68.27 follow-up) |
| DB-derived runtime list | scripts/tests/fixtures/taxonomy_snapshot.json | bun run sync:taxonomy |
| Build-time client tuple | lib/ontology/content-type-values.generated.ts | generate:content-type-values (predev/prebuild) |
| Code Literals (KG CVs) | extraction.py Literals + schemas.ts/classify.ts consts | the parity guards |
The register markdown is never read at runtime — it is the human contract; the machine reads the snapshot / fixture / Literals. Drift in any derived artefact fails a parity guard at build/CI. The __tests__/lib/ontology/markdown-parity.test.ts harness asserts the public fixture, the generated tuple, and taxonomy_snapshot.json agree (post-BI-3, against the trimmed source_documents.content_type set — no longer “15 values”).
Source documents
Section titled “Source documents”docs/plans/phase-0-investigation/phase-b-prerequisite-1-onthology-pipeline.md§2.1 (29 CV inventory) + §6 (Phase 1 build order).docs/plans/phase-0-investigation/phase-b-prerequisite-1-onthology-pipeline-feedback-investigation.md§6.2 (core/client/hybrid classification table) + §6.3 (frontmatter shape).docs/plans/phase-0-investigation/0.9-decision-graph.md§11 (S234 + S235 ratifications consolidated).
File index
Section titled “File index”B3 ruling executed (id-417, S535; DR-130 wave): CVs
05,07,11,14,15,19,30,31are DELETED from the register (the “workspace ≠ tenant” clarification from15is re-homed inreference/entity-glossary.md);13-ingest-sourceis rewritten connectors-first;27-form-format’s incorrect reference is corrected;17-diff-modeis retained. CVs01/02are retired historic records — their tables drop under DR-130.
The register spans Talisman Layers 1–6: most CVs sit at Layer 1 (Controlled Vocabulary), while the KG-entity CVs 32/33/34 and the L-concept discriminator 37-concept-type sit at Layer 5 (Ontology), and 35-relationship at Layer 6 (Knowledge Graph). The provenance_model column is the WP-ONTO-R1 §6.2 classification. The editable_via column tells you the canonical change-path. The “Where to look first” column points at the primary code surface a future engineer or agent should consult when working with that CV.
| # | File | CV | Status | Provenance | Editable via | Where to look first |
|---|---|---|---|---|---|---|
| 01 | 01-taxonomy-domains.md | taxonomy_domains | retired (DR-130) | — | — | historic record; table dropped, id-417 DR-130 wave |
| 02 | 02-taxonomy-subtopics.md | taxonomy_subtopics | retired (DR-130) | — | — | historic record; table dropped, id-417 DR-130 wave |
| 03 | 03-layer-vocabulary.md | layer_vocabulary | active | hybrid | admin_ui | contexts/layer-vocabulary-context.tsx |
| 04 | 04-content-type.md | content_type | active | core | database_migration | lib/validation/schemas.ts:41-57 |
| 06 | 06-lifecycle-type.md | lifecycle_type | active | core | database_migration | lib/freshness.ts:22-128 |
| 08 | 08-freshness.md | freshness | active | core | database_migration | lib/freshness.ts |
| 09 | 09-governance-review-status.md | governance_review_status | active | core | database_migration | app/api/governance/review/route.ts |
| 10 | 10-publication-status.md | publication_status | active | core | database_migration | lib/governance/publication-transitions.ts:31 |
| 12 | 12-requirement-type.md | requirement_type | active | hybrid | admin_ui | lib/templates/template-coverage.ts |
| 13 | 13-ingest-source.md | ingest_source | active | core | database_migration | lib/validation/schemas.ts:300-302 |
| 16 | 16-extraction-method.md | extraction_method | active | core | database_migration | lib/intelligence/pipeline.ts |
| 17 | 17-diff-mode.md | diff_mode | active | core | database_migration | lib/source-documents/document-diff.ts |
| 18 | 18-entity-aliases.md | entity_aliases | active | client | admin_ui | lib/entities/entity-aliases.ts |
| 20 | 20-chunk-kind.md | chunk_kind | planned | core | database_migration | (planned column on content_chunks) |
| 21 | 21-scope-tag.md | scope_tag | planned | client | admin_ui | (planned source_documents.scope_tag[]) |
| 22 | 22-origin-kind.md | origin_kind | planned | core | database_migration | (planned q_a_pairs.origin_kind) |
| 23 | 23-extractor-kind.md | extractor_kind | planned | core | database_migration | (planned q_a_extractions.extractor_kind) |
| 24 | 24-citation-kind.md | citation_kind | planned | core | database_migration | (planned citations.citation_kind; cf. existing content_citations.citation_type) |
| 25 | 25-application-type.md | application_type | needed | hybrid | admin_ui | (planned application_types table) |
| 26 | 26-form-type.md | form_type | needed | hybrid | admin_ui | (planned form_types table; cf. existing template_requirements.template_type) |
| 27 | 27-form-format.md | form_format | needed | core | database_migration | form_instances.mime_type (corrected reference, id-417 B3) |
| 28 | 28-change-report-category.md | change_report_category | planned | core | database_migration | lib/mcp/tools/change-report.ts (P1-35; refactors when column lands) |
| 29 | 29-cocoindex-source-kind.md | cocoindex_source_kind | active | core | database_migration | supabase/migrations/20260703160050_id138_sd_source_binding_cols.sql (source_documents.origin_type) |
| 32 | 32-q-a-pair.md | q_a_pair (entity) | APPLIED-S249 | hybrid | database_migration | supabase/migrations/20260520225456_t6_q_a_pairs_full_schema.sql + WP2 20260520231524_t6_q_a_search_rpcs.sql |
| 33 | 33-reference-item.md | reference_item (entity) | APPLIED-S318 | core | database_migration | supabase/migrations/20260606121451_id75_reference_items_layer.sql |
| 34 | 34-entity-type.md | entity_type (Layer 5) | active | hybrid | database_migration | scripts/cocoindex_pipeline/extraction.py:378-391 (Literal) |
| 35 | 35-relationship.md | relationship (Layer 6) | active | hybrid | database_migration | scripts/cocoindex_pipeline/extraction.py:423-434 (Literal) |
| 36 | 36-three-layer-model.md | three_layer_model (Layer 1) | active | core | database_migration | this register — README “Where does new data live?“ |
| 37 | 37-concept-type.md | concept_type (Layer 5) | active | hybrid | database_migration | lib/ontology/concept-schema.ts |
Higher Talisman layers (2 Metadata Standards, 3 Taxonomy, 4 Thesaurus, 5 Ontology, 6 Knowledge Graph) are addressed in phase-b-prerequisite-1-onthology-pipeline.md §6 Phase 2-6 — separate doc artefacts to be authored in later phases.
Per-application matrix
Section titled “Per-application matrix”Which CVs are most relevant to which application surface. (Indicative — every CV has cross-cutting consumers; this picks the strongest signal.)
| CV | Procurement / Bid | Sector Intelligence | Sales Proposal | Knowledge Base (cross-cutting) |
|---|---|---|---|---|
taxonomy_domains (01) | yes | |||
taxonomy_subtopics (02) | yes | |||
layer_vocabulary (03) | yes | yes | yes | yes |
content_type (04) | yes | |||
platform (05) | yes | |||
lifecycle_type (06) | yes | |||
dedup_status (07) | yes | |||
freshness (08) | yes | |||
governance_review_status (09) | yes | |||
publication_status (10) | yes | |||
change_type (11) | yes | |||
requirement_type (12) | yes | yes | ||
ingest_source (13) | yes | |||
BID_STATES (14) | yes | |||
workspaces_type (15) | yes | yes | yes | yes (transitional — replaced by CV 25) |
extraction_method (16) | yes | |||
diff_mode (17) | yes | |||
entity_aliases (18) | yes | |||
engineering_types (19) | yes (engineering-only) | |||
chunk_kind (20) | yes | |||
scope_tag (21) | yes | yes | yes | yes |
origin_kind (22) | yes | |||
extractor_kind (23) | yes | |||
citation_kind (24) | yes | yes | ||
application_type (25) | yes | yes | yes | yes |
form_type (26) | yes | yes | ||
form_format (27) | yes | yes | ||
change_report_category (28) | yes | |||
cocoindex_source_kind (29) | yes | |||
procurement_vehicle (30) | yes | |||
procurement_vehicle_instance (31) | yes | |||
q_a_pair (32) | yes | yes | yes | yes |
reference_item (33) | yes | yes | ||
entity_type (34) | yes | |||
relationship (35) | yes | |||
three_layer_model (36) | yes | |||
concept_type (37) | yes |
Provenance rollup
Section titled “Provenance rollup”| Provenance model | Count | CVs |
|---|---|---|
core (closed enum or platform-internal) | 23 | 04, 05, 06, 07, 08, 09, 10, 11, 13, 14, 15, 16, 17, 19, 20, 22, 23, 24, 27, 28, 29, 33, 36 |
hybrid (baseline + client extension) | 12 | 01, 02, 03, 12, 25, 26, 30, 31, 32, 34, 35, 37 |
client (no platform baseline; client-defined) | 2 | 18, 21 |
Editable-via rollup
Section titled “Editable-via rollup”| Editable via | Count | CVs |
|---|---|---|
database_migration (CHECK / ENUM / migration-driven) | 27 | 04, 05, 06, 07, 08, 09, 10, 11, 13, 14, 15, 16, 17, 19, 20, 22, 23, 24, 27, 28, 29, 32, 33, 34, 35, 36, 37 |
admin_ui (DB table; admin CRUD) | 10 | 01, 02, 03, 12, 18, 21, 25, 26, 30, 31 |
seed_data (planned baseline + admin override) | 0 | (none currently — could be used by future CVs) |