Operating manual for documentation work in nexus-agents.
Use when updating docs, adding new docs, changing doc pipeline, or troubleshooting doc issues.
Triggers on "update docs", "add documentation", "doc pipeline".
Installs into .claude/skills of the current project.
Are you the author of Documentation Management?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/nexus-substrate-documentation-management)
---
name: documentation-management
description: |
Operating manual for documentation work in nexus-agents.
Use when updating docs, adding new docs, changing doc pipeline, or troubleshooting doc issues.
Triggers on "update docs", "add documentation", "doc pipeline".
allowed-tools: Read, Edit, Write, Bash, Grep, Glob, Task
---
# Documentation Management Skill
<!-- CANONICAL SOURCE: docs/ops/docops-spec.md -->
<!-- DOCOPS MANIFEST CHECKSUM: [auto-updated by CI] -->
**Full specification:** [docops-spec.md](../../docs/ops/docops-spec.md)
---
## Fast Path: Common Tasks
### Update Documentation Content
```bash
# 1. Edit canonical source
edit docs/architecture/MEMORY_SYSTEM.md # or relevant file
# 2. Verify docs are indexed
pnpm exec tsx scripts/check-docs-indexed.ts
```
### Add New Document
1. Create file in appropriate `docs/` directory
2. **REQUIRED:** Add YAML frontmatter (`title`, `description`, `tier`, `keywords`, `related_files`)
3. **REQUIRED:** Add entry to `docs/README.md`
4. Commit and push
### Change Doc Pipeline
1. Edit pipeline script/config
2. **REQUIRED:** Update `docs/ops/docops-spec.md`
3. **REQUIRED:** Update this skill (`.claude/skills/documentation-management.md`)
4. Run all checks (see Verification below)
5. Commit and push
### Verify Pipeline Health
```bash
pnpm exec tsx scripts/check-docs-indexed.ts
pnpm exec tsx scripts/generate-repo-index.ts --check
pnpm exec tsx scripts/inject-governance.ts check
```
---
## Core Concepts
### Canonical Sources
| Source | Purpose |
| ---------------- | --------------------------------------------- |
| `docs/README.md` | Human-readable index (SINGLE SOURCE OF TRUTH) |
| `docs/**/*.md` | Canonical documentation |
| Root `*.md` | Project entry points |
### Generated Outputs
| Output | Generated By | From |
| -------------------------------- | ---------------------------- | ------------------------------ |
| `docs/interfaces/agent.md` | `generate-docs-content.ts` | `core/types/agent.ts` |
| `docs/design/components.md` | `generate-docs-content.ts` | `src/` module scan |
| `docs/ops/docs-inventory.md` | `generate-docs-content.ts` | ADR + MCP tool scan |
| `docs/reference/capabilities.md` | `generate-repo-index.ts` | Source code |
| `docs/reference/tools/*.md` | `generate-tool-reference.ts` | TOOL_MANIFEST + `*InputSchema` |
| CLAUDE.md tool index | `inject-governance.ts` | MCP tool files |
### Tier System
- **Tier 1 (Essential):** README, CLAUDE.md, QUICK_START, TROUBLESHOOTING
- **Tier 2 (Reference):** Hub documents (architecture/README.md, etc.)
- **Tier 3 (Detail):** Deep-dive documents, ADRs, proposals
---
## Pipeline Scripts
### generate-docs-content.ts
Auto-generates documentation sections that are derivable from source code:
the `AgentRole` interface, a module inventory, and the ADR / MCP tool counts.
Prevents drift by reading directly from the source of truth.
```bash
pnpm exec tsx scripts/generate-docs-content.ts # Generate all
pnpm exec tsx scripts/generate-docs-content.ts --check # CI validation
```
### generate-repo-index.ts
Generates capability index from source code. MCP tools are discovered by parsing
the canonical `tools: [...]` return array in `mcp/tools/index.ts`.
```bash
pnpm exec tsx scripts/generate-repo-index.ts # Generate index
pnpm exec tsx scripts/generate-repo-index.ts --check # CI validation
```
### inject-governance.ts
Injects MCP tool table into CLAUDE.md. Tool descriptions are defined in the
`TOOL_DESCRIPTIONS` map — add an entry there when registering a new MCP tool.
```bash
pnpm exec tsx scripts/inject-governance.ts inject # Update CLAUDE.md
pnpm exec tsx scripts/inject-governance.ts check # CI validation
```
---
## CI Validation
### docs-check.yml jobs
<!-- Count + job list intentionally not hardcoded here. See #1837 for
the work to inject counts programmatically. Authoritative source:
`.github/workflows/docs-check.yml` — grep for `^ [a-z-]+:` under
`jobs:` for the current list. -->
The pipeline runs a family of jobs covering: TypeDoc freshness, `capabilities.md` regeneration, link validation, docs coverage, secrets scanning, DocOps skill sync, canonical-index enforcement, markdown lint, spell check, skills/index.yaml freshness, agents/index.yaml + gap-coverage check, and governance drift. Blocking-vs-warning status is declared per job in the workflow file.
---
## Enforcement Rules
### Rule 1: Canonical Index Required
All documentation MUST be indexed in `docs/README.md`.
### Rule 2: No Parallel Indexes
`docs/README.md` is the ONLY permitted documentation index.
### Rule 3: Generated Files Must Match Source
CI fails if generated files drift from canonical sources.
### Rule 4: DocOps Changes Require Skill Update
Changes to pipeline files require updating this skill and `docs/ops/docops-spec.md`.
**Pipeline files:**
- `scripts/generate-docs-content.ts`
- `scripts/generate-repo-index.ts`
- `scripts/inject-governance.ts`
- `.github/workflows/docs-check.yml`
---
## Troubleshooting
### "docs-content check failed"
```bash
pnpm exec tsx scripts/generate-docs-content.ts
git add docs/interfaces/agent.md docs/design/components.md docs/ops/docs-inventory.md
git commit -m "docs: regenerate source-derived docs"
```
### "Link check failed"
1. Run `npx lychee . --config lychee.toml` to identify broken links
2. Fix links in canonical source
### "CI keeps failing on docs"
```bash
# Run full validation suite locally
pnpm lint
pnpm typecheck
pnpm exec tsx scripts/generate-docs-content.ts --check
pnpm exec tsx scripts/generate-repo-index.ts --check
pnpm exec tsx scripts/inject-governance.ts check
```
---
## Quality Checklist
Before committing documentation changes:
- [ ] File indexed in `docs/README.md`
- [ ] `pnpm exec tsx scripts/generate-docs-content.ts --check` passes (if types/module structure changed)
- [ ] `pnpm exec tsx scripts/generate-repo-index.ts --check` passes (if MCP tools added/renamed)
- [ ] Links work: `npx lychee . --config lychee.toml`
- [ ] No secrets in content
---
## Periodic Drift Audit
Adapted from `paperclipai/paperclip` doc-maintenance skill. Triggers: weekly cadence, post-release, after a major merge, or on explicit request ("audit docs", "doc drift").
### Targets
User-facing docs that get stale fastest as the codebase moves:
- `README.md` — features table, quickstart, prerequisites
- `docs/README.md` — canonical doc index
- `docs/getting-started/INSTALLATION.md` — install commands, Node/pnpm versions
- `docs/getting-started/CONFIGURATION.md` — env var table, config schema
- `CLAUDE.md` — Canonical Paths table, MCP Tools table (auto-generated, but check the _non_-auto sections)
### Cursor Pattern (incremental review)
Store the last-reviewed commit SHA in `.doc-review-cursor` (gitignored — it's local audit state, not project state). On each audit run:
```bash
LAST_SHA=$(cat .doc-review-cursor 2>/dev/null || echo "HEAD~200")
git log "$LAST_SHA"..HEAD --oneline --no-merges > /tmp/audit-window.log
```
After committing the audit fixes:
```bash
git rev-parse HEAD > .doc-review-cursor
```
Without the cursor, every audit re-reads the whole history → audits get skipped. With it, audits stay incremental and cheap.
### Commit Classification
From the audit window, only these commit prefixes warrant a doc check:
| Prefix | Action |
| ------------------------------------------ | -------------------------------------------------------- |
| `feat:` / `feat(...)`: | Check feature tables, README highlights, capability docs |
| `fix:` containing `breaking` / API-removal | Check API reference, migration notes |
| New top-level `src/` directory | Check architecture overview, canonical paths |
| `chore(deps):` major bumps | Check prerequisites + compat tables |
Ignore: `refactor`, `test`, `chore(ci)`, `docs`, `style` — they don't shift user-facing surface.
### What to Look For
Run the audit through this lens:
| Drift class | Signal |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| **False negative** | Shipped capability missing from feature/MCP tool/expert tables. Resolved design questions still marked TBD. Removed adapters/skills still listed. |
| **False positive** | "Coming soon" / "planned" features that have shipped. Cancelled items still on roadmap. Capability claims that contradict current implementation. |
| **Quickstart breakage** | `npx`/`pnpm` commands that don't work. Prerequisites pinning unsupported versions. Clone URL drift. Required env vars unmentioned. |
| **Feature-table drift** | `## MCP Tools Reference` count mismatch. Adapter "Works with" table missing recently-added CLI. Skill index missing a new skill. |
For our auto-generated tables (CLAUDE.md MCP tools, `capabilities.md`, `docs/interfaces/agent.md`), drift is a generation-script bug, not a doc edit — file an issue against the script instead of editing the rendered output.
### Audit-PR Discipline
- Branch: `docs/audit-$(date +%Y%m%d)`
- Commit message lists fixes + the source PR/commit that triggered each
- **Factual fixes only** — do NOT bundle style refactors, link-checker autofixes, or formatting passes. Style/refactor PRs are separate; mixing them defeats the audit's signal-to-noise.
- If a doc needs _more_ than drift fixes (e.g., a section is structurally wrong), open a follow-up issue rather than expanding the audit PR
### Out of Scope
- Auto-generated tables (handled by `scripts/inject-governance.ts`, `scripts/generate-docs-content.ts`, `scripts/generate-repo-index.ts`, etc.) — see Pipeline section above
- Style/voice/markdown formatting — orthogonal, separate PRs
- Adding new docs — separate workflow; this audit only fixes drift in existing docs
---
## Architecture Decision Records (ADRs)
ADRs capture the _why_ behind significant technical decisions. Code shows _what_ was built; ADRs explain _why this way_ and _what alternatives were rejected_. They're the highest-leverage documentation in the repo for onboarding (humans and agents) and for evaluating future changes.
ADRs live in [`docs/adr/`](../../docs/adr/) with sequential numbering: `0001-foo.md`, `0002-bar.md`, …
### When to write an ADR
- Choosing a framework, library, or major dependency (consensus_vote candidate)
- Designing a data model or schema
- Selecting an authentication, voting, or routing strategy
- Deciding on a public-API shape (REST, MCP tool, CLI command)
- **Any decision expensive to reverse** — that's the threshold
### ADR template
```markdown
# ADR-NNNN: <decision in present tense>
## Status
Proposed | Accepted | Superseded by ADR-MMMM | Deprecated
## Date
YYYY-MM-DD
## Context
What problem are we solving? What constraints (technical, organizational, time-bound) apply?
Cite the issue, vote, or incident that prompted the decision.
## Decision
The chosen approach, in 1-3 sentences.
## Alternatives Considered
Each as its own subsection. Pros, cons, and **why rejected**. Don't skip — the rejected
alternatives are how future readers understand the trade-off space.
## Consequences
Positive AND negative outcomes. What new constraints does this create?
What follow-up work falls out of this decision?
```
### ADR lifecycle
```text
PROPOSED → ACCEPTED → (SUPERSEDED-BY-NNNN | DEPRECATED)
```
- **Don't delete old ADRs.** They're historical context. A superseded ADR + its replacement together tell the story of why the system evolved.
- **When a decision changes, write a new ADR** that references and supersedes the old one. Update the old one's `Status:` line to `Superseded by ADR-NNNN`.
- ADRs are **immutable after Accepted** in spirit — fix typos, but don't rewrite the substance. New thinking goes in a new ADR.
### When NOT to write an ADR
- Reversible decisions (small refactor choices, naming style nits)
- Mechanical changes (dependency bump, lockfile update)
- Decisions already captured in a higher-level doc (`CLAUDE.md`, `.rules/`) — reference, don't duplicate
## Anti-rationalization — Documentation
| Excuse | Counter |
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| "The code is self-documenting" | Code says **how**, not **why**. The why-this-not-that lives nowhere if not in an ADR or doc comment. |
| "I'll document it later" | Later never comes. The context decays within days; what felt obvious now will be a mystery to next-quarter-you. Document at decision time. |
| "We'll update the docs in the next release" | Drift compounds. By the next release, the doc says one thing, the code does another, and the audit gate fires (see #2225 audit). Update docs in the same PR as the code change. |
| "Comments lie, only code is truth" | Lies-in-comments is a culture problem, not a comments problem. Code can also lie (subtly broken implementations). Both need review. |
| "Nobody reads the docs anyway" | Future-you reads them. New contributors (human or agent) read them. The skill-tree of the project depends on them. |
| "It's just an internal API" | Internal APIs accumulate Hyrum's Law just like public ones (see `api-and-interface-design`). Internal docs prevent internal coupling. |
## Verification — Documentation changes
- [ ] Every public-API change has a documentation update in the same PR
- [ ] Significant architectural decisions have an ADR (or reference an existing one)
- [ ] Auto-generated docs regenerated via the pipeline scripts after source changes
- [ ] Doc additions follow the Tier system (Tier 1 essential / Tier 2 reference / Tier 3 detail)
- [ ] No drift from canonical sources — `pnpm exec tsx scripts/check-docs-indexed.ts` passes
- [ ] Markdown lint clean: `npx markdownlint 'docs/**/*.md' '*.md'`
## Related Documents
- **DocOps Spec:** [docs/ops/docops-spec.md](../../docs/ops/docops-spec.md)
- **Documentation Index:** [docs/README.md](../../docs/README.md)
- **Inventory:** [docs/ops/docs-inventory.md](../../docs/ops/docs-inventory.md)
- **ADR directory:** [docs/adr/](../../docs/adr/)
## Red flags
- Public-API change PR with no doc update in the same diff
- Architectural decision merged without an ADR
- Auto-generated doc table broken (`inject-governance.ts check` fails)
- Stale `@deprecated` references in `docs/` after a removal
- Doc PR with markdown lint errors (line wraps, table formatting)