homelab-codex-ws/.claude/skills/kb-authoring/SKILL.md
oskar ba94be1599 feat(kb): skill i skrypt do pisania dokumentow kb/ (OKF authoring)
kb-authoring: sciagawka frontmattera OKF v0.1, taksonomia typow z
rozstrzygnieciami decision/incident/runbook/audit wyciagnietymi z historii
migracji (SPLIT commity), domyslne visibility: private, przypomnienie o
check_okf.py po kazdej zmianie. Odrebne od kb-publish (to dotyczy pisania
zrodel, nie wystawki public).

new-doc.sh: scaffolduje kb/<type>s/<slug>.md z poprawnym frontmatterem,
waliduje type, odmawia nadpisania, dokłada as_of dla type: audit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UXe8RXn1YDY2HAnX3RVwVS
2026-08-26 16:59:43 +02:00

7.9 KiB

name description
kb-authoring Conventions for writing/editing source knowledge-base documents under kb/**/*.md (frontmatter schema, type taxonomy, visibility default, validation). Trigger whenever creating or editing a file under kb/ — this is about authoring the sources, not publishing kb-site (see kb-publish for that).

Scope

This skill governs writing kb/**/*.md documents themselves — the OKF-format knowledge base sources. It is not about publishing them: for "should I run the publish script", see the kb-publish skill, referenced again at the bottom here.

docs/sessions/*.md files use type: session-log frontmatter and are validated by the same script, but they are not kb/ documents — they are a running diary of work sessions. Never convert a session log into a kb/ doc and never move/copy a kb/ doc's content into docs/sessions/. If material in a session log deserves a permanent home (a decision, an incident writeup, a runbook), write a new file under kb/ that captures it properly — don't relocate the diary entry.

Frontmatter schema (OKF v0.1)

Every kb/ document opens with a YAML frontmatter block (--- ... ---) as the first thing in the file. Validated by scripts/kb/check_okf.py — read that file if you need the exact rules; summary:

Field Required Values Notes
okf yes "0.1" Pinned. Always this literal string, quoted.
type yes one of the taxonomy below Determines which kb/<type>s/ directory the file lives in.
visibility yes private | public Default is private. See below — never default to public.
status yes active | deprecated | planned planned = decisions not yet made / work not yet started. deprecated requires superseded_by.
updated yes YYYY-MM-DD Bump every time you edit the file's content.
links yes (may be []) list of paths Relative to this file's own directory, e.g. ../phases/backlog.md or sibling-doc.md. Every entry must resolve to an existing file — check_okf verifies this.
as_of only for type: audit YYYY-MM-DD Required exactly when type: audit, forbidden otherwise. See "audit" below for why this is a separate field from updated.
superseded_by only when status: deprecated free text or path Required exactly when status: deprecated, forbidden otherwise. Points to whatever replaced this doc (a doc path, or prose describing the replacement if there's no single successor file).
contradicts optional list Free-text notes about known conflicts with other sources (e.g. "CLAUDE.md says X, but the directory doesn't exist"). Entries that look like a .md path (contain / and end in .md) are checked for existence like links; plain-text entries are not.
stub optional bool Marks a doc as a placeholder/incomplete. Must be a real YAML bool (true/false), not a string.

Type taxonomy — kb/s/

type Directory What goes here
node kb/nodes/ One doc per physical/virtual host — role, configured services, runtime data paths. Mirrors hosts/<node>/.
service kb/services/ One doc per deployed service — what it is, how it's used/configured. Mirrors services/<svc>/.
subsystem kb/subsystems/ Cross-cutting architecture/design docs describing how something works in general (access model, agent system, deployment conventions) — not tied to a single node or service. Kept in sync with current reality (unlike audit, see below).
decision kb/decisions/ A choice that was made (or is still open, status: planned) plus its rationale — forward-looking, governs future behavior. Gets edited in place and re-dated as the decision evolves; it is not a historical log of what happened.
incident kb/incidents/ A factual account of something that broke: symptom, root cause, fix/status, at a point in time. Slug conventionally date-prefixed (YYYY-MM-DD-short-description.md) since incidents are anchored to when they happened. Content generally stays close to the as-happened account rather than being rewritten into "current state" prose.
runbook kb/runbooks/ Step-by-step operational procedure — deploy, install, recover, troubleshoot. Imperative, command-heavy, meant to be followed live.
phase kb/phases/ A project/milestone plan broken into steps, tracking progress (including backlog/roll-up index docs).
audit kb/audits/ A point-in-time snapshot of actual/verified state (ground truth recon), never an ongoing description. Requires as_of — the date the finding was true — kept distinct from updated (the date the doc text was last edited) precisely because an audit's findings can go stale even when nobody touches the file. Slug conventionally date-suffixed (topic-YYYY-MM-DD.md).

session-log also exists as a type value (for docs/sessions/) but is out of scope for kb/ — see Scope above.

Decision vs incident vs runbook vs audit — how ambiguous cases got resolved

This came up repeatedly during the kb/ migration (docs that mixed genres got split, not force-fit into one type):

  • decision vs incident: a doc that both narrates "here's what broke" and states "here's the guardrail we adopted because of it" is two documents. Split the incident account into kb/incidents/, keep (or extract) the resulting decision/guardrail into kb/decisions/. Example: home-assistant/DESIGN.mdkb/decisions/ha-configs-as-code.md + kb/incidents/2026-07-22-ha-dwie-instancje.md.
  • decision vs runbook: if a decision doc contains a reusable operational recipe (install steps, recovery procedure), that section is a runbook, not part of the decision's rationale. Split it out. Example: deploy-runnerkb/services/job-deploy-runner.md (how it works) + kb/decisions/deploy-runner-uzasadnienie.md (why) + kb/runbooks/deploy-runner-install.md (how to install/operate it).
  • subsystem vs audit: a subsystem doc is the maintained description of how something is designed/intended to work — you keep it in sync. An audit is a frozen investigation result ("I checked X on this date and found Y") — you don't rewrite it as things change, you write a new audit or a decision/incident instead. This is why audit got its own as_of field distinct from updated.
  • When in doubt, prefer splitting a doc across two types over stretching one type's frontmatter to cover mixed content — that's the pattern the migration itself followed (see git log feat(kb): SPLIT ... commits for worked examples).

Visibility default: private

visibility defaults to private. Every new document must be written private unless the operator has explicitly and consciously decided it should be public — never infer or default to public on your own, even if the content looks harmless. visibility: public documents are the only ones scripts/kb/gen_pages.py will ever emit to the public kb-site (fail-closed: missing/unparseable/unrecognized visibility is treated as private).

After every change to kb/**/*.md

Run the validator and fix anything it flags before considering the edit done:

python3 scripts/kb/check_okf.py

It checks frontmatter parses, okf is pinned, type/visibility/status are from their closed lists, dates are well-formed, as_of/superseded_by are present exactly when required, and every links/path-like contradicts entry resolves to a real file. A red run means something is broken — fix it, don't skip it.

Creating a new document

Use scripts/kb/new-doc.sh <type> <slug> [--public] to scaffold a correctly-placed file with valid frontmatter, then fill in the content.

If you just made a public change

If a file you created or edited carries visibility: public, don't forget the KB site itself doesn't update on its own — see the kb-publish skill for the one-line reminder to run scripts/kb/publish.sh.