Files
oikos/.agents/domains/knowledge/schema.md
dtoro a2410cf9c2 docs(R5): rewrite knowledge schema + llm-wiki for DB-native model; deprecate root inventory.yaml
Rewrote .agents/domains/knowledge/schema.md and .agents/shared/llm-wiki.md
which described the deleted Python substrate (bin/homelab, oikos/cards/,
oikos/ledger.py, root inventory.yaml, knowledge/sources/, get_page/
search_docs MCP tools). Now reflect ADR 0003: Postgres DB is the single
source of truth for structured data and narrative knowledge; seeds/*.yaml
are bootstrap+DR manifests (content-hashed via seed_versions); archive/
knowledge/ is the frozen legacy wiki; MCP search_knowledge/get_entity_
knowledge replace get_page/search_docs.

Swept substrate refs in .agents/shared/{writing-style,page-templates}.md
and .agents/domains/operations/schema.md: bare inventory.yaml ->
seeds/inventory.yaml; knowledge/sources/ -> archive/knowledge/sources/
(historical); get_changelog/oikos/ledger.py -> DB audit trail / structured
document changelog field; HERMES -> Nomos.

Root inventory.yaml (618-line Python-era file superseded 2026-07-07 by
seeds/inventory.yaml) replaced with a deprecation stub pointing to the seed
and DB. Kept as a stub rather than deleted because AGENTS.md §1/§2 still
point clients at /opt/homelab-context/inventory.yaml; full on-client path
reconciliation deferred to R13.

Flagged export gap: oikos export regenerates seeds/{ontology,inventory,
policy}.yaml but NOT seeds/knowledge.yaml — API-added knowledge lives only
in the DB until hand-edited into the seed.

VERSION 0.7.7 -> 0.7.8. Plan R5 marked done.
2026-07-17 22:36:41 +02:00

5.3 KiB

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 and the writing-style and page-templates 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.
  • 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/<name>/ — the DB row is the policy/lifecycle framing, the SKILL.md is the executable procedure the agent loads. See the operations schema.

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] <op> | <summary>. 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 for the legacy wiki equivalent (now scoped to archive/knowledge/ history).