# 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`: 1–3 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.
```
