Documentation System Policy
Purpose: Define the canonical documentation taxonomy, naming rules, file headers, and navigation contract for all active docs. Read when: Creating, moving, splitting, or validating documentation files. Skip when: You only need to consume a playbook or domain doc without changing the docs system. Read next: docs-first-protocol.md, agent-workflow.md, task-lifecycle.md
Nav: Docs Index
SSOT Direction — Docs First, Code Follows
Docs are the source of truth; code is the implementation that must match. The full read-anchor-edit procedure lives in docs-first-protocol.md and is enforced by:
- Rule 0 (critical-rules.md#rule-0) —
enforce-doc-anchor.shBLOCKS code Write/Edit without a populated.doc-anchor. - Rule 19 (critical-rules.md#rule-19) —
enforce-doc-sync.shWARNs PostToolUse when code drift leaves docs stale. nudge-docs-first.sh— UserPromptSubmit nudge that recommendscos_doc_search/cos_doc_headerwhen a code-edit intent is detected and no anchor exists.
If you are about to edit code, stop here and read docs-first-protocol.md first.
Layer Model
index— navigation hub, parent/child routing onlyplaybook— task workflow with read selection guide and verificationspec— canonical product/content requirementspolicy— process or governance rulesreference— supporting factual reference, not primary truthadr— immutable decision recordtask— execution log for a specific work item
Naming Rules
- Root index:
docs/00-index.md(master navigation hub). - Sub-directory indexes:
00-index.mdin directories that have many files (architecture, playbooks, api-contracts). - Per-file
<file>.INDEX.mdsidecars are NOT canonical — only00-index.mdandsection-index.mdare recognized index forms. - Task SSOT:
docs/tasks/TASK-###-slug.md(one detail file per active or completed task). Live board view:cos board(DB-mirrored from these files). There is no flatdocs/tasks.mdindex. - Playbooks:
kebab-case.md - ADRs:
NNNN-slug.md(zero-padded sequence + kebab title) underdocs/architecture/adr/ - Tasks:
TASK-###-slug.md - Historical archive docs:
YYYY-MM-topic.mdundergovernance/archive/ - Other active docs:
kebab-case.md - No version suffixes in filenames (
*-V1.md,*-v2.md). Versioning lives in frontmatterupdated:only.
Header Contract
Every file inside docs/ starts with a one-line HTML-comment header:
<!-- domain:DOMAIN | layer:LAYER | ssot:true|ref|false | updated:YYYY-MM-DD -->
docs-lint.sh validates domain + layer against these canonical enums (warn by default; COS_DOCS_LINT_STRICT=1 makes unknown values gate). This block is the SSOT the linter mirrors — keep both in sync (TASK-074).
- domain —
ALLCOREMETAADAPTERSDOCSOPSINFRASECURITY(meta-repo) ·PRODUCTBACKENDFRONTENDAIMOBILEAPIARCH(consumer projects).XXX/STACK_DOMAINare template fill-in placeholders. - layer —
indexpolicyplaybookspecadrreferencerunbookpostmortemtaskengineeringarchitecturetemplateplancontractchecklist. - ssot —
true(canonical) ·ref(pointer/derived) ·false. - updated —
YYYY-MM-DD, the last substantive edit.
Opening Block Contract
Immediately after the H1, every active doc includes these four lines. Two equivalent forms are accepted; pick one per file.
Long form (default):
Purpose:Read when:Skip when:Read next:
Short form (token-tight, ~30% fewer header bytes — recommended for high-traffic routing files):
> P:> R:> S:> N:
docs-lint accepts either form. cos_doc_header (MCP) parses both into the same structured response (opening_block.purpose / read_when / skip_when / read_next). The md_links graph extractor emits read_next edges from either.
These lines must let an agent decide within the first screenful whether to keep reading.
Playbook Read-Pack Limit
Playbook read packs must not exceed 10 files. Most tasks need 3-6; complex multi-domain tasks may reach 10. If more are needed, split into a sub-playbook or a domain-specific routing hub.
Navigation Rules
docs/00-index.mdis the single master navigation hub.- Directories with many files (architecture, prd, api-contracts, pages-content-spec) keep their own
00-index.md. Smaller directories (engineering, design, governance, playbooks, ops) may not need an index. - Every file should include a
> Nav:breadcrumb on the line after the opening block.- Files inside a directory with a local index → Nav links to
./00-index.md. - Files inside a directory without an index → Nav links to the root
../00-index.md. - Index files → Nav links to parent index or root.
- Files inside a directory with a local index → Nav links to
- Use relative links only.
- Use
REF:*shortcodes fromdocs/_meta/foundation-map.mdin taskRead Firstsections where shorter references improve readability.
Task File Rules
Single SSOT (Scrumban):
docs/tasks/TASK-###-slug.md— canonical detail file. One per active or completed task. Holds frontmatter (swimlane / kind / epic / labels / status / priority / appetite / depends_on / blocked_by / references), Outcome, Read First, Acceptance, Work Log, Rollback. Authored fromdocs/governance/_templates/task-detail.md. Token cap: warn ≥1.5k, block ≥3k (Rule 14).cos board(orcos board --web) — live view rendered fromsrc/core/board_os/db.py. The DB is a derived mirror of the detail files (mtime-incremental sync); the file is SSOT, the DB is the index.- Status transitions go through
cos task-move/cos task-start/cos task-done(or the MCPcos_task_*family). These write the detail-file frontmatter and the DB atomically — never edit status by hand in only one place. - There is no flat
docs/tasks.mdindex. The legacy index file has been retired in favor ofcos board+ per-task detail files.
Lifecycle:
- A task is created via
cos task-create(writes both the detail file and the DB row). - Once a task is in_progress, completed, or blocked → the detail file under
docs/tasks/is REQUIRED. DB-only mode exists insrc/core/board_os/workflow.pybut is reserved for migrations and tests, never normal authoring. - Companion docs (checklists, research annexes that would break the 3k cap) use
layer:reference, link back to the parent task, and never carry canonical status. docs/governance/_templates/task-detail.mdis a template reference, not a live task record. Do not edit it as if it were a task.
Architecture Boundary
docs/architecture/contains evergreen architecture and ADRs only.- Temporary migration history and audit trails live under
docs/governance/archive/. - Open risks and blind spots live in
docs/governance/risk-register.md.
Changes Log Policy
changes.loglives at repo root and tracks completed task summaries.- Max 5 lines per task entry: title + reason + key changes + files.
- Detailed breakdowns belong in the task file, not changes.log.
- When changes.log exceeds 200 lines, archive entries older than 30 days to
docs/governance/archive/YYYY-MM-changes.md.
Extension Protocol
When adding a new domain to the project, follow this order:
- Architecture doc →
docs/architecture/NN-<domain>.md - Playbook →
docs/playbooks/<domain>.md - API contracts →
docs/api-contracts/<domain>-endpoints.md(if applicable) - Routing entry →
AGENTS.mdCore Loop § Execute - REF codes →
docs/_meta/foundation-map.md - Index updates →
docs/00-index.md - Run
make docs-lintto verify
Authoring a NEW Doc — Read This First
Before creating any new file under docs/, read _templates/doc-cheat-sheet.md. It contains:
- The decision tree (intent → layer → directory → token budget).
- Mandatory frontmatter + opening block contract.
- Required sections per layer (adr · playbook · runbook · post-mortem · spec · policy · reference · task).
- Anti-patterns (code dumps, version-suffix files, "future work" sections).
- Token-efficiency rules — the audience is the next agent that has to act on the doc.
Available templates under docs/governance/_templates/:
task-detail.md— task execution log.runbook-template.md— operational SOP for an alert / incident type.post-mortem-template.md— blameless retrospective for a specific incident.playbook-template.md— repeatable workflow.security-review-template.md— OWASP-aligned per-change checklist.doc-cheat-sheet.md— decision guide for new docs (read first).
Decision History
A doc's decision history lives in git: every edit is a commit, reverts are git revert commits, and git log --follow <path> reconstructs the full timeline. There is no separate trail table — git is the single forensic record.