# Knowledge domain — schema The knowledge domain is the durable, authoritative current-state documentation of the homelab: narrative for every node and cross-cutting system, synthesized from live state and evidence. It answers "what exists and how does it work right now." It follows the [LLM Wiki layer model](../../shared/llm-wiki.md) and the [writing-style](../../shared/writing-style.md) and [page-templates](../../shared/page-templates.md) rules. ## Source of truth — the database Per ADR 0003, the Postgres database is the single source of truth for all structured data **and** narrative knowledge. The narrative/substrate split of the Python era is gone: the DB holds both the structured graph (entities, relationships, status, metrics) and the narrative layer (documents, investigations, runbooks) in the `knowledge_entities` table. | Concern | Where it lives | How it gets there | |---------|----------------|-------------------| | Knowledge content — documents, investigations, runbooks | `knowledge_entities` table (rows linked to `entities` via `documents` / `about` edges) | Seeded from `seeds/knowledge.yaml` at deploy; mutated at runtime via the API | | Seed manifest (bootstrap + DR) | `seeds/knowledge.yaml` | Hand-edited or regenerated; ingested idempotently (content-hashed via `seed_versions`) | | Structured graph — hosts, services, entity types, relationships | `entities`, `relationships`, `entity_types` tables | Seeded from `seeds/{ontology,inventory}.yaml`; mutated via API/MCP | | Archived narrative wiki (read-only history) | `archive/knowledge/` | Frozen 2026-07-07 when the DB became source of truth | ### Seed ingest `seeds/knowledge.yaml` has three top-level lists — `documents`, `investigations`, `runbooks` — each entry carrying `slug`, `title`, `content` (markdown), and tags. `internal/knowledge/seed.go` ingests each entry by: 1. `getOrCreateEntity` — ensures the slug exists in `entities` (type `document` / `investigation` / `runbook`). 2. `upsertKnowledgeEntity` — writes the markdown body into `knowledge_entities`, keyed by `content_hash` so re-ingest is a no-op when nothing changed. 3. `createEdge` — links the knowledge entity to its subject(s) via `documents` (for `document`) or `about` (for `investigation`) edges. Runbooks bind to an `entity_type` via `applies_to_type` rather than to a single entity. ### Runtime mutation Agents register or update knowledge through the API, not by editing the seed: - `POST /api/v1/knowledge/{entity_slug}` — upsert a document/investigation on an entity (`upsert_knowledge` MCP tool). - `update_entity_attributes` — merge a discovered fact (IP, version, port) into an entity. - `create_relationship` — record a discovered edge (`depends-on`, `hosts`, `routes-to`). > **Export gap.** `oikos export` regenerates `seeds/{ontology,inventory,policy}.yaml` from the DB > for version control, but **not** `seeds/knowledge.yaml`. Knowledge added via the API today lives > only in the DB until someone hand-edits the seed. Tracked as a follow-up. ## Knowledge kinds - **Documents** (`document` entities, linked via `documents` edges) — node and cross-cutting narrative pages. Carry `at_glance` (structured attributes) and a parsed `changelog`. Follow the container / cross-cutting templates in [page-templates.md](../../shared/page-templates.md). - **Investigations** (`investigation` entities, linked via `about` edges) — incident evidence, written once at incident time. Sections: `## Summary`, `## Timeline`, `## Root cause`, `## Mitigations applied`, `## Open questions`. - **Runbooks** (`runbook` entities, bound by `applies_to_type`) — repeatable procedures. Carry `risk_class` and a JSON-schema-validated `procedure`. **Runbooks also live as `SKILL.md` files under `.agents/skills//`** — the DB row is the policy/lifecycle framing, the SKILL.md is the executable procedure the agent loads. See [the operations schema](../operations/schema.md). ## The two logs - The per-document **`## Changelog`** records infrastructure changes to that node. Keep the `### YYYY-MM-DD — title` shape so the parsed `changelog` field stays structured. - **`archive/knowledge/log.md`** is the append-only record of *documentation-maintenance* operations on the legacy wiki (restructures, source ingests, lint sweeps): `## [YYYY-MM-DD] | `. It is frozen with the rest of `archive/knowledge/`; new doc-maintenance operations are recorded in the DB audit trail instead. ## Querying knowledge Use MCP, not grep: - `search_knowledge(query)` — ILIKE search over documents, investigations, and runbooks in `knowledge_entities`. - `get_entity_knowledge(entity_slug)` — every document, investigation, and runbook linked to one entity, in one call. - `get_entity(slug)` / `get_relations(entity)` — the structured graph around an entity. Grep the clone only when MCP is unreachable, and prefer `archive/knowledge/` for historical narrative (it is not updated when the DB changes). ## Same-session update rule A change to a node updates the DB in the same session — the entity's attributes, the relationships that reference it, and any document whose `at_glance` or changelog should reflect the new state. See [page-templates.md](../../shared/page-templates.md#same-session-update-rule) for the legacy wiki equivalent (now scoped to `archive/knowledge/` history).