Files
oikos/plans/done/2026-07-06-adopt-wiki-hq-doc-architecture.md

165 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 2026-07-06 — Adopt the wiki-hq documentation architecture
## Goal
Reorganize the Homelab-Docs **narrative layer** into the `wiki-hq`
(`/Users/dtoro/Downloads/wiki-hq-main`) documentation model — `sources / wiki / index / log`
plus an `.agents/` separation and a single lint-checkable writing-style standard — **without
breaking** the Oikos machine-readable substrate that reads fixed paths. Keep the existing Mermaid
topology generator (no LikeC4).
## Context
Homelab-Docs is already a mature operational-docs system: `inventory.yaml` as source of truth,
generated `hosts/*.yaml`, an MCP server, a `homelab` CLI, and the Oikos OODA kernel (scheduler,
drift, decide, ledger, approvals). Its weakness is on the *narrative* side — the prose layer grew
organically and lacks the discipline wiki-hq shows:
- No enforceable **writing-style** standard (CONTRIBUTING.md has a one-line "voice" note; CAVEMAN.md governs agent *chat*, not docs).
- **Index/README files are inconsistent** — some pure listings, some prose+tables, some with stale counts.
- **No append-only operations log** for doc maintenance — doc changes are visible only in git.
- **Agent instructions and human content are interleaved** at the repo root (AGENTS.md, OIKOS.md, CAVEMAN.md, CONTRIBUTING.md, GLOSSARY.md alongside `containers/`, `infrastructure/`, …).
Decision (confirmed with operator): **full structural adoption**, **keep Mermaid**, adopt all four
borrows — writing-style guide, section-index/README pattern, append-only per-area logs, and
agent-instruction separation.
## Hard constraint: protect the operational substrate
These paths are read programmatically and **must not move** (see `mcp/server.py`, `bin/homelab`, `oikos/`):
- `inventory.yaml` (root) — MCP (`mcp/server.py:36`), CLI (`bin/homelab:36`), scheduler, drift, relations, gen-topology.
- `hosts/*.yaml` (root, generated) — `HOSTS_DIR` (`mcp/server.py:37`); written by `mcp/build_host_files.py`; read/written by `bin/homelab`.
- `oikos/` — kernel code, `oikos/cards/` (`explain` tool, `mcp/server.py:38`), `oikos/state.json`.
- `secrets/`, `secrets-issuance/`, `ssh/`, `scripts/`, `tools/`, `vps/`, `bin/`, `bootstrap.sh`.
Two MCP tools are path-agnostic and survive any narrative reorg: `search_docs` (ripgreps all
`*.md`) and `get_page(path)` (agent supplies a repo-relative path). The **`## Changelog` convention
must stay** on node pages — `get_changelog` (`mcp/server.py:214`) and the ledger parse it. New
`log.md` files are **additive**, not a replacement for per-page changelogs.
## Current → target structure
Restructure the **narrative layer only**; leave the substrate in place.
```
Homelab-Docs/
README.md # human landing page (kept; refreshed to new nav)
AGENTS.md # kept at root (conventional discovery path)
.agents/ # NEW — agent-facing instruction, separated from content
shared/
writing-style.md # NEW — adapted from wiki-hq (homelab voice)
llm-wiki.md # NEW — the sources/wiki/index/log contract for THIS repo
caveman.md # moved from CAVEMAN.md (agent chat mode)
page-templates.md # moved from CONTRIBUTING.md (page templates)
domains/
knowledge/schema.md # contract for the current-state wiki
operations/schema.md # contract for runbooks / investigations / plans
skills/ # runbooks reshaped as SKILL.md (Phase 4)
lifecycle-provision-node/SKILL.md
service-health-check/SKILL.md
...
OIKOS.md # operating-model doc (moved; agent-facing)
knowledge/ # durable current-state wiki (Feedback/authoritative layer)
index.md # pure listing → section indexes only
log.md # append-only doc-maintenance operations log
GLOSSARY.md # moved from root
sources/
index.md # flat catalog table
references/ # external docs (from infrastructure/references/)
wiki/
hosts/ README.md + hubris.md + strong.md
containers/ README.md (= today's index.md) + <id>-<name>.md
vms/ README.md + <id>-<name>.md
infrastructure/ README.md + grouped: network/ identity/ storage/ ingress/ operations/
operations/ # operator runbook narrative index
index.md commands.md agent-enrollment.md hermes-agent.md
investigations/ # incident evidence (Observe sources)
README.md + log.md + YYYY-MM-DD-*.md + archive/
plans/ # projects / design docs (Act)
README.md + YYYY-MM-DD-*.md + done/
# substrate — UNCHANGED (see Hard constraint)
inventory.yaml hosts/*.yaml oikos/ mcp/ secrets/ secrets-issuance/
ssh/ scripts/ tools/ vps/ bin/ bootstrap.sh
```
**hosts/ split:** generated `hosts/*.yaml` stay at root (substrate); only the two *narrative* pages
`hosts/hubris.md` and `hosts/strong.md` move to `knowledge/wiki/hosts/`. This is the one directory
where machine and narrative content currently mix.
## Consumers to update when narrative paths move
Same phase as the move:
- **`inventory.yaml` `doc_page` fields** — per-host pointer; consumed by `bin/homelab` (`die("no doc_page recorded…")` near `bin/homelab:1288`). Repoint to `knowledge/wiki/...`.
- **`oikos/gen-topology.py` / `oikos/gen_topology_lib.py`** — write `infrastructure/topology.md` and link `oikos/cards/` to doc pages. Move `topology.md` under `knowledge/wiki/infrastructure/` and update the output-path constant (`oikos/gen-topology.py:3`, `:49`, `:195`).
- **`oikos/cards/` templates** and `oikos/drift.py` docstring at `oikos/drift.py:218` (`containers/121-caddy.md`) — cosmetic, update for accuracy.
- **Internal cross-links** — repo-wide relative-link rewrite + link-check pass.
- **Same-session update rule** (`CONTRIBUTING.md:125`) — rewrite its path checklist to the new layout.
`search_docs`, `get_page`, `get_changelog` need **no** code change.
## Writing-style standard (adapted, not copied)
Create `.agents/shared/writing-style.md` from
`/Users/dtoro/Downloads/wiki-hq-main/.agents/shared/writing-style/writing-style.md`:
- **Keep:** banned-vocabulary list (puffers, "leverage/utilize/delve", poetic nouns, promotional adjectives), information-density rule, bold-leading-phrase pattern, tables-over-bullets, `>` blockquotes for caveats, one-sided cross-references, "cross-references are content not catalog".
- **Adjust voice:** wiki-hq mandates strict third-person "no you". Homelab docs are operator runbooks that already use imperative recipes. Allow **imperative/second-person in runbooks, recipes, and skills**; third-person reference voice for node/infrastructure descriptions. State this exception explicitly.
- **Clarify vs CAVEMAN.md:** Caveman governs agent *chat responses*; writing-style governs *committed docs*. No conflict.
- **Make it lint-checkable:** the Oikos lint surface (or a new `.agents/skills/docs-lint`) greps banned words + structural violations.
## Reconciling "append-only per-area logs" with the Oikos ledger
- The **Oikos change ledger** (`oikos/ledger.py`) stays authoritative for *infrastructure changes* (who/what/risk/approval/verification). Do not duplicate it.
- **Per-page `## Changelog`** stays (parsed by `get_changelog`).
- New **per-area `log.md`** (`knowledge/log.md`, `investigations/log.md`, `plans/log.md`) records *doc-maintenance operations only* — restructures, source ingests, lint sweeps — in wiki-hq's single-line format `## [YYYY-MM-DD] <op> | <summary>`.
## Convention: plans always live in `plans/`
The restructure must codify — in `.agents/domains/operations/schema.md`, `AGENTS.md`, and
`.agents/shared/page-templates.md` — that **any plan or design doc for the Homelab is always
written into the repo `plans/` folder** (`plans/YYYY-MM-DD-slug.md`), never into a scratch/agent
plan path, an ad-hoc location, or a chat message. Agents drafting a plan create the file under
`plans/`, list it in `plans/index.md`, and move it to `plans/done/` on completion. This rule is
stated once in the operations schema and cross-referenced from `AGENTS.md` so every agent sees it
at orientation.
## Section-index / README pattern
Every folder gets a `README.md`: 13 sentence prose intro, then a single two-column nav table
`| Document | What it covers |`, nothing else — no stale counts, no duplicated prose. Pure-listing
`index.md` files (e.g. `containers/index.md`) become the folder `README.md`. Root `README.md` stays
the human landing page (may exceed the strict pattern).
## Phased rollout
Each phase independently valuable, independently verifiable, committed separately.
1. **Conventions first (no moves).** Add `.agents/shared/writing-style.md`, `llm-wiki.md`; move CAVEMAN.md → `.agents/shared/caveman.md`, CONTRIBUTING.md → `.agents/shared/page-templates.md` (leave thin root stubs pointing to the new locations). Verify: links resolve; MCP untouched.
2. **Agent-instruction separation.** Move OIKOS.md → `.agents/OIKOS.md`; author `.agents/domains/{knowledge,operations}/schema.md`. Keep AGENTS.md at root, pointing at `.agents/`. Verify: AGENTS.md still the discovery entry; `tools/setup-hermes-soul.sh:51` references resolve or are updated.
3. **Narrative move into `knowledge/wiki/`.** Move `containers/`, `vms/`, `infrastructure/`, host narratives; add `knowledge/index.md`, `knowledge/log.md`, `knowledge/sources/`. Same commit: update `inventory.yaml` `doc_page` fields, `oikos/gen-topology.py` output path, all internal links. Verify: link-check clean; CLI `doc_page` lookups work; `gen-topology.py` writes to the new path; MCP `get_page`/`search_docs` return moved pages.
4. **Runbooks → skills.** Reshape `runbooks/*.md` into `.agents/skills/<name>/SKILL.md` (they already carry `risk_class`, `inputs`, `verification` frontmatter — near-compatible). Update runbook-path references. Verify: frontmatter parses; lifecycle transitions still map to `oikos/ontology.yaml`.
5. **Style + README pass.** Apply the writing-style standard and README pattern across narrative pages; add `log.md` entries recording the restructure. Verify: docs-lint clean.
## Verification (end to end)
- **Link integrity:** markdown link checker (or `rg` over `](` targets) after each move phase; zero broken relative links.
- **MCP resolves docs:** `HOMELAB_CONTEXT_DIR=<repo>``get_page("knowledge/wiki/containers/104-gitea.md")` returns content; `search_docs("gitea")` hits new paths; `get_changelog(<moved page>)` parses.
- **CLI doc_page lookups:** exercise `bin/homelab`'s `doc_page` read against a moved page — no "no doc_page recorded" error.
- **Topology generation:** run `oikos/gen-topology.py` — writes the new `topology.md` path; `oikos/cards/` links point at moved pages.
- **Substrate untouched:** `mcp/build_host_files.py` regenerates `hosts/*.yaml` identically; `git diff` shows no substrate churn.
- **Style lint:** banned-vocabulary grep over `knowledge/` returns no hits; every folder `README.md` matches the intro-plus-nav-table shape.
## Post-migration
Update `plans/index.md` to list this plan; on completion move it to `plans/done/`. Record the
restructure in the new `knowledge/log.md`. Update `README.md` and `AGENTS.md` navigation to the new
layout.
```