ct-documentor
/ct-documentor
Documentation coordinator with CLEO style guide compliance. Routes every canonical-doc write (spec, adr, research, handoff, note, llm-readme) through the docs SSoT via `cleo docs add` / `cleo docs publish` / `cleo docs fetch` — never raw filesystem writes. Carries the CLEO writing and review guides as references and coordinates ct-spec-writer and ct-adr-recorder. Use when creating or updating documentation files, consolidating scattered documentation, or validating documentation against style standards. Triggers on documentation tasks, doc update requests, or style guide compliance checks.
- Author
- kryptobaseddev ↗
- Repository
- cleo ↗
- Licence
- MIT
- Last repository change
- 27.10.2026
Assessment and security
- Files in this package
- 15
- Scripts
- 2
- HTML comments
- 0
- URLs in SKILL.md
- 0
No signals detected. Repository changed on 27.10.2026, without references to retired models or APIs.
MIT, open: use and modify while retaining author attribution.
- 2 scripts in this package. Review them before installing, as Claude may execute them.
Scripts: __tests__/reviewing-reference.test.ts, __tests__/writing-reference.test.ts
What it does and when to use it
Documentation coordinator with CLEO style guide compliance. Routes every canonical-doc write (spec, adr, research, handoff, note, llm-readme) through the docs SSoT via `cleo docs add` / `cleo docs publish` / `cleo docs fetch` — never raw filesystem writes. Carries the CLEO writing and review guides as references and coordinates ct-spec-writer and ct-adr-recorder. Use when creating or updating documentation files, consolidating scattered documentation, or validating documentation against style standards. Triggers on documentation tasks, doc update requests, or style guide compliance checks.
Original author description
Documentation coordinator with CLEO style guide compliance. Routes every canonical-doc write (spec, adr, research, handoff, note, llm-readme) through the docs SSoT via `cleo docs add` / `cleo docs publish` / `cleo docs fetch` — never raw filesystem writes. Carries the CLEO writing and review guides as references and coordinates ct-spec-writer and ct-adr-recorder. Use when creating or updating documentation files, consolidating scattered documentation, or validating documentation against style standards. Triggers on documentation tasks, doc update requests, or style guide compliance checks.
How it works
- Canonical Docs Command Path (T10516 — T11048)
- Verify document storage and optional projections separately
- Purpose
- Skill Coordination
- Coordinator Pattern: SSoT-First Routing
- Decision: update vs supersede vs create (T10168 · Saga T9855 / E12)
- Through SDK (preferred)
- Deprecated: Direct filesystem
- Worktree-Aware Routing (T10389 / ADR-068 amendment §3.1)
- Core Principle: MAINTAIN, DON'T DUPLICATE
SKILL.md preview
---
name: ct-documentor
description: Documentation coordinator with CLEO style guide compliance. Routes every canonical-doc write (spec, adr, research, handoff, note, llm-readme) through the docs SSoT via `cleo docs add` / `cleo docs publish` / `cleo docs fetch` — never raw filesystem writes. Carries the CLEO writing and review guides as references and coordinates ct-spec-writer and ct-adr-recorder. Use when creating or updating documentation files, consolidating scattered documentation, or validating documentation against style standards. Triggers on documentation tasks, doc update requests, or style guide compliance checks.
version: 3.26.0
protocol: null
dependencies:
- ct-spec-writer
- ct-adr-recorder
sharedResources:
- subagent-protocol-base
- task-system-integration
compatibility:
- claude-code
- cursor
- windsurf
- gemini-cli
license: MIT
metadata:
version: 3.26.0
tier: core
install: harness
covers:
- packages/cleo/src/cli/commands/docs.ts
- packages/contracts/src/docs-taxonomy.ts
lastReviewed: 2026-10-23
stability: stable
---
# Documentation Specialist Context Injection
**Protocol**: @src/protocols/implementation.md
**Type**: Context Injection (cleo-subagent)
**Version**: 3.0.0
---
## Canonical Docs Command Path (T10516 — T11048)
The agent-facing docs surface is simplified to six canonical verbs. Use these as the
primary workflow. Legacy verbs remain available but are **advanced or migration
surfaces** — do not present them as the default path to agents.
| Canonical Verb | Purpose | When to Use |
|---------------|---------|-------------|
| `add` | Create a new doc attached to a task/session | First write of any canonical doc |
| `update` | Patch/replace an existing doc's content | Fixes, extensions, refreshes |
| `fetch` | Retrieve a doc by slug | Reading, reviewing, verifying |
| `list` | Browse docs by owner, type, or project | Discovery, checking what exists |
| `remove` | Detach a doc from an owner | Cleanup, de-duplication |
| `publish` | Mirror an SSoT blob to a git-tracked path | When a doc must live on disk |
**Advanced verbs** (beyond the canonical six):
`supersede`, `query --similar`, `graph`, `versions`, `sync`, `merge`,
`schema`, `list-types`, `serve`/`open`/`stop`/`viewer-status`, `status`,
`publish-pr`, `doctor`.
T13361 retired the legacy verbs `search`, `find`, `rank` (use `query`),
`generate`, `export` (use `llm-output`), `gap-check` (use `check`), and
`import`; `sync` stays until the T9645 reingest workflow migrates, and
`status` stays agent-facing per `cleodocs-rearch-design` §6.
`cleo docs stats` (T13363) is a read-only adoption-metrics probe: add:update
ratio from the docs audit log, loose-markdown count (gitignore-aware scan),
`docs_wikilinks` edge count, and live `decision_adr_links` count. Use it for
pilot baseline comparisons — it never writes.
`cleo docs doctor` (T13447) audits the docs store — dangling `local-file`
pointers, docVersion skew vs the audit log, empty topics/related_tasks,
`docs_wikilinks` drift, legacy store surfaces, stale drafts — and with
`--apply` repairs them after creating a backup automatically. Use it for
store hygiene checks; it never edits doc content.
`cleo docs migrate` (T13360) imports legacy docs + history into the re-keyed
conduit store inside the migration safety harness (pre-step backup, verified
rollback, COMMIT only on full verification). It is additive and idempotent:
every imported history row is labeled `origin: migrated`, authors come from
the legacy audit log (or the honest `system:migration` attribution — never
invented), docs whose content pointers dangle are content-captured or
recorded dangling in `conduit_doc_migration_ledger`, and a re-run is a
verified no-op. Legacy slugs that already exist natively are counted as
native-conflict skips, never clobbered. Run it once per project before the
T13361/T13362 retirement lands; it needs no `--force`.
For discovery (`find`, `search`, `schema`, `list-types`), prefer `cleo docs list`
first — it returns slug + owner + type without forcing a filesystem walk. Use
legacy discovery verbs only when `list` is insufficient.
---
## Verify document storage and optional projections separately
After `cleo docs add`, retain the canonical attachment ID and SHA-256, then use
`cleo docs fetch <slug>` to verify the accepted bytes. For exact-byte checks,
hash the UTF-8 bytes of `data.content` from the JSON response (text docs, T13352;
binary docs carry `data.bytesBase64` to decode instead) and compare its digest
with `data.metadata.sha256`; rendered content can add a trailing newline.
The add result's `projection` reports captured project identity/root, coverage,
diagnostics, the original deadline, and any durable `jobId` or verified receipt.
A successful document write can coexist with failed or pending graph/observation
work. Preserve those diagnostics and references in the handoff. Missing identity
means missing projection coverage; it does not authorize guessing a project.
Optional projection work shares a two-second foreground budget across identity
capture, preparation, locking, execution, and verification. Deadline expiry ends
foreground observation; synchronous database work is not preempted by a timer.
If the outcome is unresolved, inspect the retained job and accepted attachment
before explicitly resuming. Do not repeat the add to simulate a retry or assume
that a lost worker reply means no write committed. A projection receipt verifies
its domain results; it is not an atomic receipt for all document side effects.
## Purpose
Context injection for documentation tasks spawned via cleo-subagent. Orchestrates documentation workflows by coordinating specialized skills for lookup, writing, and review.
## Skill Coordination
| Skill | Purpose | Invoke When |
|-------|---------|-------------|
| `cleo docs query` / `list` / `fetch` (and the Context7 MCP for library APIs) | Query existing docs and current external docs | Discovery phase, checking what exists |
| `references/writing.md` (was ct-docs-write) | Create/edit docs via `cleo docs add` with CLEO style | Writing or updating content |
| `references/reviewing.md` (was ct-docs-review) | Check compliance with style guide, read through `cleo docs fetch`; PR mode | Quality validation before completion |
| `ct-spec-writer` | Author specs (REQ-XXX requirements) via `cleo docs add --type spec` | Formal specification work |
| `ct-adr-recorder` | Author ADRs via `cleo docs add --type adr --slug adr-NNN-...` | Architecture decisions promoted from consensus |
The coordinator never writes content itself — it routes the work to the
specialist skill that owns the doc type, and every specialist routes its
filesystem write through the docs SSoT (see "Coordinator Pattern" below).
---
## Coordinator Pattern: SSoT-First Routing
ct-documentor is a router. It dispatches each doc-type to its owning skill,
and every owner writes through `cleo docs add` — not raw filesystem writes.
Argument order (T13726): OWNER-ID is the first positional and the file the second —
`cleo docs add T123 ./doc.md`, never `cleo docs add ./doc.md`. A path in the owner slot,
reversed positionals, a missing source or a missing file each fail with the corrected command
in `error.fix`.
| Doc Type | Owner Skill | SSoT Command |
|----------|-------------|--------------|
| `spec` (REQ-XXX requirements) | `ct-spec-writer` | `cleo docs add <ownerId> <path> --type spec --slug spec-<feature>` |
| `adr` (architecture decisions) | `ct-adr-recorder` | `cleo docs add <ownerId> <path> --type adr --slug adr-<NNN>-<rest>` (TODO T10360 · E3.2 pending: `--title` + auto-`adr-NNN` allocation) |
| `research` (multi-source investigation) | `ct-research-agent` | `cleo docs add <ownerId> <path> --type research --slug research-<topic>` |
| `handoff` (session/agent transition) | `ct-documentor` (this skill) | `cleo docs add <ownerId> <path> --type handoff --slug handoff-<context>` |
| `note` (conversational prose) | `ct-documentor` (`references/writing.md`) | `cleo docs add <ownerId> <path> --type note --slug <kebab-topic>` |
| `llm-readme` (agent-facing) | `ct-documentor` (`references/writing.md`) | `cleo docs add <ownerId> <path> --type llm-readme --slug <kebab-topic>` |
Hard rule: EVERY canonical-type write goes through the SSoT. The coordinator
rejects any subagent return that wrote raw markdown into `.cleo/adrs/`,
`.cleo/research/`, `.cleo/agent-outputs/`, or `docs/` without first
materializing through `cleo docs add` + (optionally) `cleo docs publish`.
---
## Decision: update vs supersede vs create (T10168 · Saga T9855 / E12)
Before adding a new doc, ALWAYS ask: is this **a new doc**, **a change to an existing doc**, or **a replacement for an existing doc**? Prefer the canonical six-verb path (`add` / `update` / `fetch` / `list` / `remove` / `publish`). Legacy verbs annotated below.
```
┌─────────────────────────────────────────────────────────────────────┐
│ Question │ Verb │
├─────────────────────────────────────────────────────────────────────┤
│ Same idea, fixing/extending content? │ cleo docs update <slug> │
│ → typo in ADR-076 │ (canonical — T10161) │
│ → adding a clarifying paragraph │ │
│ → refreshing a stale section │ │
│ │
│ Replacing the whole canonical model? │ cleo docs supersede │
│ → "saga model v2" replaces v1 │ <old> <new> │
│ → ADR-080 replaces ADR-073 │ (ADVANCED — T10162) │
│ → new architecture supplants old │ │
│ │
│ Genuinely new idea? │ cleo docs list FIRST │
│ → drafting a new spec │ (canonical discovery) │
│ → fresh ADR for a new concern │ → if no hit, docs add │
│ → recording a new investigation │ → if hit, docs update │
│ │
│ Tracing the lineage graph? │ cleo docs graph │
│ → "what does this doc replace?" │ --root <slug> │
│ → "what tasks reference this ADR?" │ (ADVANCED — T10164) │
│ Triaging a backlog of stale drafts? │ cleo docs triage │
│ → 2,152 drafts with empty metadata │ [--limit N] [--record] │
│ → verdicts are proposals only │ (T13446 — no mutation) │
└─────────────────────────────────────────────────────────────────────┘
```
**Canonical discovery path**: `cleo docs list` (browse by owner/type) → `cleo docs fetch <slug>` (read). Reserve `cleo docs query --similar <slug>` (ADVANCED — T10163) for near-duplicate collision checks and `cleo docs query "<text>"` for semantic queries.
### Examples
- **"Fix a typo in ADR-076 saga-first-class"** - `cleo docs update adr-076-saga-first-class --file /tmp/fixed.md --message "fix typo in §2"` (canonical - T10161). NOT a new doc. NOT a supersession. Just patch in place; T10161 squashes patches within a 5-minute window so consecutive typo fixes don't bloat the audit log.
- **"Accept a spec that review signed off"** - `cleo docs update <slug> --status accepted` (T12654). `--status` alone changes only the lifecycle status (draft, proposed, accepted, superseded, archived, deprecated); the stored bytes are kept, so there is no need to re-supply `--file` or `--content`. Any content edit without `--status` resets the doc to `draft`.
- **"Replace a doc's body from a pipe"** - `cat new.md | cleo docs update <slug> --content -` (T13564). As in `docs add`, `-` reads stdin; an empty or bare `-` body is refused, never stored.
- **"Editing a doc another agent may touch"** - `cleo docs fetch <slug>` first, note `metadata.headVersionUid`, then `cleo docs update <slug> --file new.md --base-version-uid <headVersionUid>` (T13674). A stale base merges append edits into the head (`staleBaseMerged: true`) or records `sectionConflicts` — a concurrent writer's edit is never silently dropped; a base that no longer resolves is refused with `E_DOC_BASE_UNKNOWN`. `--file` must be UTF-8 text when a base is given (`E_DOC_BASE_UNSUPPORTED` otherwise). The update result's `headVersionUid` is the base for your next edit, so chained edits need no re-fetch.
- **"`docs fetch --content` says content not retrievable"** - the doc row exists but its bytes are not in the blob store. A doc synced from another device gets its bytes on the next `cleo cloud sync` (T13721): they travel encrypted on the stream, and the sync's `W_SYNC_DOC_BYTES_UNAVAILABLE` / `W_SYNC_DOC_BYTES_REFUSED` warnings say why when they cannot. Otherwise run `cleo docs doctor --repair`.
- **"Trace an ADR to the decisions it ratifies"** - `cleo docs link-decision <adr-slug> D####` (T13598): the slug must be an existing doc and the decision a stored one, since a link is permanent. `cleo docs fetch <adr-slug>` then lists them as `linkedDecisions`. `cleo docs unlink-decision <adr-slug> D####` cannot be undone: the revoke is a permanent tombstone, and that pair can never be re-linked.
- **"Replace the entire saga-orchestration model with v2" (ADVANCED)** - `cleo docs add T9999 v2.md --type adr --slug adr-080-saga-orchestration-v2` followed by `cleo docs supersede adr-073-above-epic-naming adr-080-saga-orchestration-v2 --reason "v2 canonicalizes the SG- prefix + 4-tier hierarchy"`. Both rows survive in the attachments table; readers see `lifecycle_status=superseded` on v1 and `supersedes=adr-073` on v2.
- **"Drafting a new spec for the BRAIN recovery pipeline"** - FIRST run `cleo docs list --type spec` to browse existing specs (canonical discovery). If a matching spec exists, use `cleo docs update`. If no match, proceed with `cleo docs add T#### draft.md --type spec --slug spec-brain-recovery-pipeline`. The `cleo docs query --similar brain-recovery` path is the ADVANCED collision-detection surface - use only when `list` is insufficient.
- **"Auditing the supersession chain for ADR-039" (ADVANCED)** - `cleo docs graph --root adr-039-lafs-envelope-unification --depth 3`. Returns a DocProvenanceGraph envelope (T10166 contract) with nodes + edges, optionally `--format dot` for graphviz visualization.
### Anti-patterns (INSTANT REJECTION)
- ❌ Calling `cleo docs add` with a slug that's only a typo-distance away from an existing doc — the auto-warn (T10167) fires `W_SLUG_SIMILAR`; respect it and route to `cleo docs update` instead of bypassing with `--allow-similar`.
- ❌ Editing a `.cleo/adrs/*.md` file directly with `Write` — bypasses the SSoT writer; T10366 `WriterRegistry` is the chokepoint and the docs SSoT will reconcile auto-emit drift.
- ❌ Creating a new doc when an existing one needs updating — bloats the attachments table and breaks lineage. The decision tree above resolves this — when in doubt, run `cleo docs list` first, or `cleo docs query --similar <proposed-slug>` (ADVANCED) as a last resort.
## Through SDK (preferred)
Documentation work flows through the docs SSoT using the canonical six-verb path:
**add, update, fetch, list, remove, publish**. Use the slug-based contract so downstream consumers
can retrieve docs without grepping the filesystem.
### Add a doc attached to a task
```bash
cleo docs add T1234 docs/drafts/feature-x.md \
--type note \
--slug feature-x-overview \
--desc "Conversational overview — pre-review"
```
- `--type` MUST be one of `spec | adr | research | handoff | note | llm-readme`.
Pick the type by the document's purpose, not its filename.
- `--slug` is the human-friendly retrieval handle (kebab-case). If taken the
CLI returns `E_SLUG_RESERVED` (legacy alias `E_SLUG_TAKEN`) with 3
alternatives — pick one, do not overwrite.
- The owner ID (`T1234` above) auto-classifies the attachment by prefix:
`T###` → task, `ses_*` → session, `O-*` → observation.
### Strict flag validation (T10359 · closes T10238)
`cleo docs add` rejects unknown flags with `E_UNKNOWN_FLAG` + Levenshtein
"did you mean" suggestions and exits with code `6` (`VALIDATION_ERROR`).
This closes the silent-absorption footgun where citty's underlying
`parseArgs({ strict: false })` accepted typo'd flags (e.g. `--titel`,
`--title`) as positional values.
```bash
# Typo → E_UNKNOWN_FLAG with suggestion
$ cleo docs add T123 file.md --titel "X" # cleo-cmd: negative-example
{
"success": false,
"error": {
"code": 6,
"codeName": "E_UNKNOWN_FLAG",
"message": "E_UNKNOWN_FLAG: unknown flag '--titel' for 'docs add'. Did you mean: --type, --slug?",
"fix": "Try one of: --type, --slug. Run `cleo docs add --help` for the full flag list.",
"alternatives": [{ "action": "--type", "command": "--type" }, { "action": "--slug", "command": "--slug" }],
"details": { "flag": "--titel", "knownFlags": [...] }
},
"meta": { ... }
}
```
The accepted positional + named surface is enumerated in
`cleo docs add --help` — agents MUST consult `--help` rather than guessing
flag names. Use the `--flag=value` form (`--type=spec`) or
`--flag value` (`--type spec`) — both are recognised.
#### Slug allocation goes through ONE chokepoint (T10392 · Saga T10288)
Every code path that writes an attachment with a slug — `cleo docs add`,
`cleo changeset add`, and any future writer — MUST first call the central
allocator at `packages/core/src/docs/slug-allocator.ts:reserveSlug` BEFORE
invoking `attachmentStore.put({ slug })`. The allocator:
1. Normalises the slug to canonical kebab-case (lowercase, trim, single
hyphens).
2. Acquires a per-slug in-process Mutex so concurrent reservations
serialise.
3. Returns `{ ok: false, code: 'E_SLUG_RESERVED', suggestions }` when the
slug is taken — uniform shape across both writers.
The `attachmentStore.put` chokepoint enforces this via a runtime assert
(`SlugNotReservedByAllocatorError`) when `CLEO_STRICT_SLUG_ALLOCATOR=1`
is set. Strict mode becomes default in the next release after both
writers are wired. **BOTH writers are LIVE on the allocator as of T10388**:
`cleo docs add` (T10386 — `packages/cleo/src/dispatch/domains/docs.ts:add`)
and `cleo changeset add` (T10388 — `packages/core/src/changesets/writer.ts:writeChangesetEntry`)
both call `reserveSlug(kind, slug)` BEFORE any filesystem or DB mutation.
Collisions surface the uniform envelope:
```json
{
"success": false,
"error": {
"code": "E_SLUG_RESERVED",
"message": "slug 'foo' is already in use in this project",
"details": {
"suggestions": ["foo-2", "foo-3", "foo-4"],
"aliases": ["E_SLUG_TAKEN"]
}
}
}
```
`details.aliases` retains the legacy `E_SLUG_TAKEN` (docs-add path) /
`E_SSOT_WRITE_FAILED` (changeset-add path) codes for ONE release of
back-compat — downstream consumers grepping for the old codes can still match
via the alias array. Removed after E2 (T10290 — DocKind writer dedup) lands.
Slugs share a GLOBAL namespace across all DocKinds — `reserveSlug('changeset',
'foo')` followed by `reserveSlug('research', 'foo')` collides. The decision
is recorded in **ADR-076 §6 amendment AMD-001** (slug
`adr-076-canonical-docs-ssot`, T10390 / E1.5). Three-point evidence (human-memorable
global lookup, DocKind-distinct prefix conventions, backward-compat cost) and
the full counterfactual analysis live in that amendment. Matches the
`uniq_attachments_slug` partial UNIQUE INDEX in migration `20260519000001`.
When choosing a slug, follow the DocKind prefix conventions in the routing
matrix above (`adr-NNN-*`, `spec-*`, `research-*`, `t<id>-*` for changesets,
etc.) — this is what makes cross-kind collisions structurally near-impossible.
#### One writer per DocKind — WriterRegistry SSoT (T10366 · Saga T10288 / Epic T10290)
`packages/core/src/docs/writer-registry.ts:WriterRegistry` is the SSoT for
"which CLI verb writes which DocKind". Every `BuiltinDocKind` maps to EXACTLY
ONE writer descriptor — multi-writer regressions trip the registry at build
time (the slug-collision class root-cause from T10294).
**Decision tree — pick the verb without guessing:**
```text
if kind === 'changeset' → cleo changeset add
elif kind === 'llm-readme' → tooling-composed (system-managed)
elif kind === 'release-note' → cleo release reconcile (system-managed)
else → cleo docs add --type <kind>
```
In code:
```ts
import { WriterRegistry } from '@cleocode/core/internal';
const desc = WriterRegistry.for('changeset');
// → { kind: 'changeset', verb: 'changeset add', dispatchOp: 'changeset.add',
// coreFn: 'writeChangesetEntry', mode: 'ssot-first',
// sourcePath: 'packages/core/src/changesets/writer.ts' }
// Resolve the verb programmatically — no string-matching in caller code.
const verb = WriterRegistry.for(kind).verb; // 'docs add' | 'changeset add' | 'system-managed'
```
Descriptor modes mirror `.cleo/canon.yml`'s `canonicalHome`:
- `'ssot'` — bytes live in the blob store; published copy is a mirror.
- `'ssot-first'` — dual-write via a dedicated verb (`changeset` today).
- `'system-managed'` — tooling-composed (e.g. `llm-readme`, `release-note`).
Test parity: every `ssot-first` descriptor MUST match a kind whose
`canonicalHome: 'ssot-first'` in `.cleo/canon.yml`, and vice versa.
**Legitimate bypass — `WriterRegistry.systemManaged` (T10368):** writers
for `system-managed` kinds (e.g. `generateDocsLlmsTxt`, `composeReleaseNotes`)
do not go through `cleo docs add` because the bytes are tooling-composed
rather than human-authored. The registry still names the producer via
`coreFn`, so drift tooling can follow the breadcrumb from kind →
core function without an exception list. Do NOT invent NEW `system-managed`
entries to dodge the docs-add path — every kind authored by a human MUST
flow through `cleo docs add` or `cleo changeset add`.
**Cross-link to the allocator contract:** the registry calls
{@link reserveSlug} BEFORE the writer delegates. A taken slug returns
`{ ok: false, code: 'E_SLUG_RESERVED', details: { suggestions } }`
with the SAME shape both `cleo docs add` and `cleo changeset add` surface
to callers (closing the T10294 envelope-drift bug). See the
"Slug allocation goes through ONE chokepoint" section above for the
allocator contract and the legacy `E_SLUG_TAKEN` alias.
T10366 establishes the registry contract; T10367 (docs add) and T10368
(changeset add) wire the actual writer delegation. Until those land,
`WriterRegistry.write()` returns `E_NOT_IMPLEMENTED` after consulting the
allocator — callers should continue invoking the existing writers
(`cleo docs add` dispatch handler, `writeChangesetEntry`) directly.
**T10367 LIVE — `cleo docs add --type changeset` delegates to
`writeChangesetEntry`.** The dispatch handler in
`packages/cleo/src/dispatch/domains/docs.ts` now branches on
`payload.type === 'changeset'` and routes the call through the
canonical dual-write transaction. This eliminates the second writer
for the `changeset` DocKind (the SG-DOCS-INTEGRITY invariant) — the
bytes that land on `.changeset/<slug>.md` AND the SSoT blob are
byte-identical regardless of which verb the operator invoked. The
`cleo changeset add` CLI remains the friendlier authoring surface
(it prompts for every required frontmatter field) while
`cleo docs add --type changeset --file <path>` works for agents that
already have a fully-formed changeset markdown blob in hand.
Contract for the docs-add path:
- The input file MUST carry valid changeset frontmatter
(`id`, `tasks`, `kind`, `summary`). Missing → `E_REQUIRES_CHANGESET_VERB`
with a fix hint pointing at `cleo changeset add` for guided authoring.
- When `--slug` is also passed it MUST match the frontmatter `id`
(the frontmatter is canonical) — divergence → `E_SLUG_MISMATCH`.
- The LAFS envelope on success carries `data.type === 'changeset'`,
`data.slug`, `data.attachmentId`, and `data.sha256` — round-trip
identical to what `cleo changeset add` emits.
#### CI gate — DocKind Writer Uniqueness (T10369)
`scripts/lint-dockind-writer-uniqueness.mjs` (CI job:
`DocKind Writer Uniqueness (T10369)`) enforces the
WriterRegistry invariants at PR-time. It refuses to merge a PR that:
1. Adds a new entry to `BUILTIN_DOC_KINDS` (in
`packages/contracts/src/docs-taxonomy.ts`) without a matching
descriptor in `writer-registry.ts` (`dockind-coverage-missing`).
2. Declares more than one descriptor for the same DocKind
(`dockind-coverage-collision` — the registry itself throws at module
load too, this gate surfaces it earlier in CI).
3. Has a `mode: 'ssot-first'` descriptor that does NOT match
`.cleo/canon.yml`'s `canonicalHome` for the same kind, or vice versa
(`canon-yml-ssot-first-drift`).
4. Adds a NEW raw `writeFileSync(path.md, …)` / `writeFile(path.md, …)`
call inside `packages/core/src/**` that is not in
`.lint-dockind-writer-baseline.json` (`unregistered-md-write`).
Schema-parity rules (#1-#3) are ALWAYS strict — there is no baseline.
The unregistered-md-write rule runs in baseline mode by default; count
decreases always pass, count increases fail. The two legitimate
non-DocKind `.md` writers (`packages/core/src/sessions/handoff-markdown.ts`
for session snapshots and `packages/core/src/changesets/writer.ts` for
the canonical `changeset` DocKind) are allowlisted in the script.
Per-line opt-out (use sparingly): append
`// dockind-writer-allowed: <reason>` on the writeFile line.
#### Audit complement — manual-write sweep (T10372)
`scripts/sweep-manual-doc-writes.mjs` (CI job:
`Manual Write Sweep (T10372)`) is the read-only audit counterpart to
the writer-uniqueness lint. Where T10369 prevents *new* raw `.md`
writers from landing in `packages/core/src/**`, this sweep walks every
`*.md` file *already* added under `.cleo/canon.yml`'s `rawMdPaths`
directories since the T9791 docs-import cutoff — the commit that
imported the legacy corpus and committed its manifests under
`.cleo/audit/imports/`, which is how the sweep locates it — and
classifies each one against the docs SSoT:
| Remediation | Meaning | Fix |
|---|---|---|
| `in-sync` | File SHA matches a blob already in the SSoT — bytes are tracked. | None. |
| `drift` | Slug exists in SSoT but the on-disk content has changed. | Re-publish via `cleo docs publish` or re-add as a new version. |
| `orphan` | Neither SHA nor slug resolves — the file is a raw fs write that bypassed `cleo docs add`. | Migrate via `cleo docs add <ownerId> <file> --type <kind> --slug <slug>`. |
| `deleted` | File was added since the cutoff but no longer exists on disk. | Informational only — does not count toward `unresolved`. |
Each run writes a timestamped report to
`audit/manual-write-sweep-<date>.json` and prints the summary block to
stdout. The CI job uploads the report as a workflow artefact on every
run and is wired with `continue-on-error: true` initially so the
existing orphan corpus does not break PRs. Saga T10288 / Epic T10293
E5.3 closes the orphan migration; the gate flips strict after that
lands.
```bash
# Local invocation — uses the globally-installed `cleo` on PATH.
node scripts/sweep-manual-doc-writes.mjs
# CI / monorepo build — point at the just-built local CLI bundle.
node scripts/sweep-manual-doc-writes.mjs \
--cleo-bin "node packages/cleo/dist/cli/index.js" \
--allow-unresolved
```
Exit codes: `0` (clean OR `--allow-unresolved`), `1` (at least one
`orphan` or `drift` entry), `2` (canon.yml parse failure, git not
available, SSoT query failed).
### T10179 + T10203 manual-write migration (T10371)
Saga T10176's two known raw-write workarounds are normalised:
| Original file | SSoT slug | Type | Notes |
|---|---|---|---|
| `docs/research/t10179-executor-probe-result.md` | `t10179-executor-probe` | research | in-sync via earlier T9791 import — verified by SHA. |
| `.changeset/t10179-executor-probe.md` (consumed v5.108) | `t10179-changeset-archive` | note | bytes preserved verbatim from git `cc48ca10e`; archived because the pnpm/changesets `"@cleocode/cleo": patch` frontmatter does not satisfy the `changeset` DocKind schema. |
| `.changeset/t10203-napi-step-exports.md` (consumed v5.108) | `t10203-napi-step-exports` | changeset | in-sync via the `cleo changeset add` dual-write at PR-time. |
Round-trip parity is regression-locked by
`packages/core/src/docs/__tests__/manual-write-migration.test.ts`. The
test embeds the canonical bytes inline and asserts that
`createAttachmentStore().put(...) → findBySlug(...)` returns the same
SHA-256 it started with. Any future migration that silently rewrites or
recompresses these blobs fails the test.
### Sweep-driven remediation loop (T10373)
T10371 only covers the *known* manual-write set declared in the original
Saga T10176 disposition. The T10372 sweep surfaces *every* orphan
remaining under `rawMdPaths` at the moment it runs. T10373 closes the
loop by consuming the sweep report and migrating each orphan into the
SSoT using the same `cleo docs add --slug` pattern T10371 established.
The recurring pattern (use this any time the sweep flags fresh
orphans):
1. Run the sweep: `node scripts/sweep-manual-doc-writes.mjs`. The
report lands at `audit/manual-write-sweep-<date>.json`.
2. For each `orphan` entry, derive the migration tuple:
- `--type` from the file's parent directory (`.cleo/adrs/` → `adr`,
`.cleo/research/` → `research`, `.cleo/agent-outputs/` →
`handoff` or `note` based on content, `.cleo/rcasd/` → `rcasd`).
- `--slug` from the filename — lowercase, kebab-case, no
extension (e.g. `ADR-085-cross-db-invariants.md` →
`adr-085-cross-db-invariants`).
- `<owner-id>` from the file's frontmatter `task:` field if
present, otherwise from `cleo find "<filename-keyword>"`.
3. Run `cleo docs add <ownerId> <file> --type <kind> --slug <slug>
--desc "<sweep-remediation context>"`. The `--desc` should
reference the originating task ID so future operators can trace
the migration.
4. Verify via `cleo docs fetch <slug>` and re-run the sweep — the
`orphan` count MUST drop by the number of files migrated.
5. Add the new (slug, sha256, type, ownerId) row to a
round-trip parity test alongside the T10371 set. The canonical
example lives at
`packages/core/src/docs/__tests__/sweep-remediation.test.ts`.
T10373 migrated five orphans this way: `ADR-083`, `ADR-085`,
`T10268-saga-closeout`, `t10292-e4-cli-verb-matrix`, and
`t10292-e4-sdk-import-edges`. The last two were direct fallout from
the pre-T10389 worktree-unreachable bug — T10353 and T10354 workers
fell back to raw filesystem writes because `cleo docs add` rejected
inside their spawned worktrees. Re-publishing the bytes via the SSoT
proves the round-trip and closes the loop the bug opened.
If a sweep run surfaces a file that should genuinely stay as raw
markdown (e.g. an audit log not meant for SSoT propagation), add an
entry to `audit/sweep-exemptions.yml` rather than migrating it. The
sweep script honours exemptions and does not flag them as orphans.
### Stuck-saga closure via `cleo saga reconcile` (T10374 · Saga T10288 / Epic T10293)
When a Saga's docs-related closeout was completed under the saga's
member Epics — every Epic flipped to `status='done'` — but the parent
Saga row itself is still `pending`, the recovery verb is
`cleo saga reconcile <sagaId>`. This is the cron-safe T10121 path
that the ADR-076 / T10113 auto-close path delivers; sagas that pre-date
the auto-close path (T9625 is the canonical example) need an explicit
nudge.
The recipe — use this any time a docs-canon Saga is observably stuck
even though its members have all shipped via `cleo docs add` /
`cleo docs publish`:
1. Verify member-Epic terminality:
`for E in <memberIds>; do cleo show $E | jq '.data.task.status'; done`.
Every member must be `done`, `cancelled`, or `archived` before
reconcile will close the parent. If any member is genuinely stuck,
close THAT one first (evidence-based per ADR-051) — do NOT cancel
a member just to satisfy the gate.
2. Verify the SSoT fetch-gate the Saga's acceptance gates on (typically
a research plan or closure note):
`cleo docs fetch <slug>` — must return `success: true` with the
expected bytes.
3. Reconcile: `cleo saga reconcile <sagaId>`. The verb is idempotent
(re-runs return `action: 'no-op'`) and never modifies member rows.
4. Confirm: `cleo show <sagaId>` — `status` must be `done` and
`completedAt` populated. The action is appended to
`.cleo/audit/saga-reconcile.jsonl` for audit.
5. Write a closure-evidence handoff via
`cleo docs add <taskId> <file> --type handoff --slug <saga>-closure-evidence`
capturing: member statuses (table), reconcile envelope output,
sibling-saga sanity check (no cross-saga side effects), and
ADR-076 + T10113 path validation. The slug `t9625-closure-evidence`
is the canonical reference.
Regression coverage for this path lives at
`packages/core/src/sagas/__tests__/t9625-closure.test.ts` and locks
three invariants: stuck-saga closure (AC1), sibling-saga isolation
(AC2), and idempotency (AC3). Add a new case there whenever you close
another stuck docs-canon Saga so the recovery pattern stays under
test.
### Docs->BRAIN link (T13985 · owner decision D11180)
Every successful `cleo docs add` links the document to its owner in the BRAIN
graph as `llmtxt:<sha256> --documents--> <ownerType>:<ownerId>` (for example
`task:T1234`). The `llmtxt:<sha256>` node carries the slug (or file name) as
its label. The link is canonical, so it is written even when
`brain.autoCapture` is off; the owner's `embeds` edge is automatic capture and
follows that setting. The write runs in the docs projection after the
attachment is stored, so a BRAIN failure never fails `docs add`.
There is no "Doc attached" observation any more (T9976's auto-emit was retired
by D11180): find a document through `cleo docs` (`list`, `find`, `fetch`), not
`cleo memory find`. Legacy "Doc attached" rows still in a store are kept out
of recall, and `cleo memory verify <observationId>` still round-trips one
against the docs store.
The internal `memory.backfill-docs` operation writes the missing `documents`
edges for attachments that predate the link (idempotent). Regression coverage:
`packages/cleo/src/dispatch/domains/__tests__/docs-memory-observation.test.ts`
and `docs-memory-observation-retroactive.test.ts` (slug shapes from the
T10371 + T10373 sweep).
**Anti-pattern**: do NOT write a `cleo memory observe` after a
`cleo docs add` to "register" the document: the documents edge already links
it, and an observation only adds noise to recall.
#### System-managed exemptions (T10368)
Not every `.md` write inside `packages/core/src/**` is a DocKind authoring
path. Release composers, RCASD migration tooling, nexus wiki generators, and
the publish-mirror copier all emit Markdown bytes from inside `core/` but
SHOULD NOT route through `WriterRegistry.write` — they are deterministic
derived artifacts, not user-authored canonical documents.
These legitimate bypasses live in `SYSTEM_MANAGED_ENTRIES` inside
`writer-registry.ts`. Every entry cites an ADR pointer:
```ts
WriterRegistry.listSystemManaged();
// → [
// { id: 'release.plan-json', adrRef: 'ADR-028 ...' },
// { id: 'release.changelog', adrRef: 'ADR-028 §2.5 ...' },
// { id: 'lifecycle.rcasd-migration', adrRef: 'ADR-076 ...' },
// { id: 'lifecycle.stage-artifact', adrRef: 'ADR-076 ...' },
// { id: 'sessions.handoff-markdown', adrRef: 'ADR-076 ...' },
// { id: 'nexus.wiki-overview', adrRef: 'ADR-076 ...' },
// { id: 'docs.publish-mirror', adrRef: 'ADR-076 ...' },
// ]
// Path-based exemption lookup — used by the writer-audit test + T10369 lint:
const hit = WriterRegistry.isSystemManaged('.cleo/release/v2026.5.103.plan.json');
// → { id: 'release.plan-json', kind: null, adrRef: 'ADR-028 ...', ... }
```
When adding a NEW `.md` writer inside `packages/core/src/**`, you MUST
either:
1. Route through `WriterRegistry.write({kind, slug, payload})` (the
canonical path for DocKind authoring), OR
2. Append a new entry to `SYSTEM_MANAGED_ENTRIES` with an ADR pointer
ratifying the bypass.
The `writer-audit.test.ts` regression test fails when a new `.md` writer
appears without either path. T10369 (next in the epic) promotes this from a
unit test to a full CI lint gate.
### Slug similarity warn (T10361 · closes T10167)
`cleo docs add` runs a fuzzy-match check against existing slugs for the
SAME DocKind at write-time. If the proposed `--slug` is close to an
existing one (default threshold: normalised Levenshtein score ≥ `0.85`,
< `1.0`), the CLI surfaces "did you mean: `cleo docs update <slug>`?"
so an agent does not fork a near-duplicate when an update is the
intent. Exact (`1.0`) matches fall through to the slug-collision path
(`E_SLUG_TAKEN`) — they are NOT covered by this check.
```bash
# Near-duplicate slug — warn mode is the project default.
$ cleo docs add T123 file.md --slug cant-spec --type spec
INFO Similar to 'cantspec' (score 0.89) — did you mean: cleo docs update cantspec? Pass --allow-similar to bypass.
# (write proceeds because mode=warn)
# Same input under `mode: block` (configured in .cleo/canon.yml) — exits 6.
$ cleo docs add T123 file.md --slug cant-spec --type spec
{
"success": false,
"error": {
"code": 6,
"codeName": "E_SLUG_SIMILARITY",
"message": "Similar to 'cantspec' (score 0.89) — did you mean: cleo docs update cantspec? Pass --allow-similar to bypass.",
"fix": "Use `cleo docs update cantspec` if updating, or pass --allow-similar to add as a new doc.",
"alternatives": [
{ "action": "update 'cantspec' instead", "command": "cleo docs update cantspec" },
{ "action": "bypass the similarity check", "command": "cleo docs add T123 file.md --slug cant-spec --type spec --allow-similar" }
]
}
}
# Intentional add (true near-twin, not an update) — bypass + audit-log.
$ cleo docs add T123 file.md --slug cant-spec --type spec --allow-similar
# appends one JSONL line to .cleo/audit/similar-bypass.jsonl
```
Project-level overrides live in `.cleo/canon.yml`:
```yaml
similarity:
warnThreshold: 0.85 # 0..1 — score above this triggers the hint
mode: warn # 'warn' (default) | 'block'
```
`mode: block` is recommended for CI agents — it surfaces the intent
mismatch as an exit code rather than a silently-printed warning that
non-TTY callers ignore. The `--allow-similar` flag is ALWAYS the
escape hatch and ALWAYS logged.
### Publish to a git-tracked path (when the doc must live on disk)
```bash
cleo docs publish --for T1234 --to docs/feature-x.md
```
Atomic tmp-then-rename. The published file ships in the next commit; the
SSoT blob remains canonical and continues to track future versions.
### Fetch the doc back by slug
```bash
cleo docs fetch feature-x-overview # latest version
cleo docs versions --for T1234 # list every SHA version
```
Slug-based fetch is the contract used by reviewers, downstream skills, and
the docs graph — never grep the filesystem for the file you just wrote.
### List + sync / versions
```bash
cleo docs list --type spec --project # canonical: every spec in this project
cleo docs list --task T1234 # canonical: everything attached to a task
cleo docs versions --for T1234 # ADVANCED: list every SHA version
cleo docs versions --for my-doc-slug # ADVANCED: same, resolved from a doc slug
cleo docs sync --from docs/legacy.md --for T1234 # ADVANCED: back-fill on-disk file into SSoT (no --type/--slug; classify with docs add)
```
`docs versions --for` resolves owner id first, then slug. An owner id
(`T###`, `ses_*`, `O-*`) is listed as-is, even when empty. Any other arg is
looked up as a doc slug and lists its owning task's blobs, sibling docs
included (add `--name <blob>` to narrow). An arg that is neither fails with
`E_NOT_FOUND`.
---
## Deprecated: Direct filesystem
The legacy "write straight to `.cleo/adrs/`, `.cleo/research/`,
`.cleo/agent-outputs/`, or `docs/` and commit" pattern is deprecated.
The drift between the working file and the docs SSoT is real: published
files go stale, types are inferred ad-hoc from path, and slug-based
retrieval becomes impossible. Migrate every doc-type write to
`cleo docs add --type X --slug Y`.
---
## Worktree-Aware Routing (T10389 / ADR-068 amendment §3.1)
When running from an agent-spawned worktree (e.g. under
`~/.local/share/cleo/worktrees/<hash>/<task>/`), `cleo docs add` and
`cleo changeset add` automatically route the SSoT write back to the
canonical project root. The bytes land in the MAIN repo's SSoT — never
inside the worktree.
You can pass file paths relative to the worktree cwd as usual:
```bash
cd ~/.local/share/cleo/worktrees/<hash>/<task>/
cleo docs add T10389 docs/note.md --slug t10389-investigation --type note
# stderr: [T10389] routing SSoT write from worktree cwd <...> → canonical project root <...>
```
The verbs detect a stray `.cleo/tasks.db` inside the worktree
(pre-T9803 leak or rogue write) and emit `E_STRAY_WORKTREE_DB` BEFORE
invoking the DB chokepoint, so the user gets actionable remediation
(`rm -rf <worktree>/.cleo`) instead of the deeper
`E_WT_DB_ISOLATION_VIOLATION` exception.
Suppress the routing log line with `CLEO_QUIET=1` if you need clean
stderr in automation. The fix-pack closes T10353 + T10354 + T10294's
3-guard collision class (`E_PATH_TRAVERSAL` + `E_FILE_ERROR` +
`E_WT_DB_ISOLATION_VIOLATION`).
---
## Core Principle: MAINTAIN, DON'T DUPLICATE
```
BEFORE creating ANY new file, you MUST:
1. Search for existing documentation on the topic
2. Identify the canonical location for this information
3. UPDATE the existing file instead of creating a new one
4. Only create new files when NO suitable location exists
```
---
## Workflow Phases
### Phase 1: Discovery (MANDATORY)
Before writing anything, discover what exists. Prefer the SSoT over `Glob`/`Grep`
when scanning canonical docs — `cleo docs list` returns slug + owner + type
without forcing a filesystem walk.
```bash
# SSoT-first discovery (preferred — canonical six-verb path)
cleo docs list --project # all docs for this project
cleo docs list --type {TYPE} --project # docs filtered by canonical type
cleo docs fetch {SUSPECTED_SLUG} # check if a slug exists
# Filesystem fallback (only for un-migrated content)
Glob: pattern="docs/**/*.md"
Grep: pattern="{TOPIC_KEYWORDS}" path="docs/"
Grep: pattern="{RELATED_TERMS}" path="docs/" output_mode="files_with_matches"
```
**Use the Context7 MCP** (`resolve-library-id` → `query-docs`) for current library and framework docs.
### Phase 2: Assess
| Question | Action |
|----------|--------|
| Does a doc file for this topic exist? | UPDATE that file |
| Is the info scattered across files? | CONSOLIDATE into canonical location |
| Is there a related doc that should include this? | ADD section to that file |
| Is this truly new with no home? | CREATE minimal new file |
### Phase 3: Write/Update
**Load `references/writing.md`** for content creation.
**For EXISTING files:**
1. Read the current content
2. Identify the correct section for new info
3. Add/update content IN PLACE
4. Preserve existing structure
5. Update any version numbers or dates
**For CONSOLIDATION:**
1. Identify all files with related content
2. Choose the canonical location
3. Move content to canonical file
4. Add deprecation notices to old locations
5. Update cross-references
**For NEW files (last resort):**
1. Confirm no existing location is suitable
2. Follow project's doc structure conventions
3. Add to appropriate docs/ subdirectory
4. Update any index or TOC files
5. Keep minimal - single topic focus
### Phase 4: Review
**Load `references/reviewing.md`** for quality validation.
Checklist:
- [ ] No formal language ("utilize", "offerings", "cannot")
- [ ] "People/companies" not "users"
- [ ] No excessive exclamation points
- [ ] Important information leads, not buried
- [ ] No verbose text without value
- [ ] Headings state the point
- [ ] Descriptive link text (never "here")
- [ ] No "easy" or "simple"
- [ ] Code examples actually work
---
## Anti-Duplication Checklist
Before completing, verify:
- [ ] Searched for existing docs on this topic via `cleo docs list` first
- [ ] Did NOT create a file that duplicates existing content
- [ ] Updated existing file if one existed
- [ ] Added deprecation notice if consolidating
- [ ] Cross-references are updated
- [ ] No orphaned documentation created
- [ ] Every canonical-type write went through `cleo docs add --type X --slug Y`
- [ ] Slug retrieval verified via `cleo docs fetch <slug>` before declaring done
---
## Task System Integration
@skills/_shared/task-system-integration.md
### Task Workflow
```bash
# 1. Read task details
cleo show {TASK_ID}
# 2. Start task. If it fails with E_SESSION_UNBOUND (spawned workers and
# subagents are already bound), run
# 'cleo session start --scope global --name "<what you are doing>"'
# or 'cleo session resume <id>' first, then retry.
cleo start {TASK_ID}
# 3. Execute documentation workflow (phases 1-4)
# 4. Complete task when done
cleo complete {TASK_ID}
# 5. Link research if applicable
cleo research link {TASK_ID} {RESEARCH_ID}
```
---
## Subagent Protocol
@skills/_shared/subagent-protocol-base.md
### Output Requirements
1. MUST record documentation output with `cleo docs add {{TASK_ID}} --content - --type <kind> --slug {{TOPIC_SLUG}}` (never a raw file under `.cleo/agent-outputs/`)
2. MUST record ONE manifest entry: `cleo manifest append --entry '<entry JSON>'` (the flat manifest file is retired, ADR-027)
3. MUST return ONLY: "Documentation complete. Manifest appended to pipeline_manifest."
4. MUST NOT return documentation content in response
### Output File Format
Record it with `cleo docs add {{TASK_ID}} --content - --type <kind> --slug {{TOPIC_SLUG}}`, using this body:
```markdown
# Documentation Update: {TITLE}
**Date**: {DATE} | **Agent**: ct-documentor | **Status**: complete
---
## Summary
{What was updated and why}
## Changes Made
### File: {path/to/file.md}
- {Change 1}
- {Change 2}
## Files NOT Created (Avoided Duplication)
- {Considered creating X but updated Y instead}
- {Found existing coverage in Z}
## Verification
- [ ] Changes don't duplicate existing content
- [ ] Cross-references updated
- [ ] Examples tested
- [ ] Style guide compliance verified via `references/reviewing.md`
```
### Manifest Entry
Record it with `cleo manifest append --entry '<entry JSON>'` (the flat manifest file is retired, ADR-027):
```json
{"id":"docs-{TOPIC}-{DATE}","file":"{DATE}_docs-{TOPIC}.md","title":"Documentation Update: {TITLE}","date":"{DATE}","status":"complete","agent_type":"documentation","topics":["documentation","{topic}"],"key_findings":["Updated {file} with {change}","Consolidated {topic} docs into {canonical-location}","Avoided duplication by updating existing {file}"],"actionable":false,"needs_followup":[],"linked_tasks":["{TASK_ID}"]}
```
---
## Completion Requirements
- [ ] Discovery phase completed (searched existing docs via `cleo docs list`)
- [ ] Core principle followed (maintain, don't duplicate)
- [ ] Coordinator pattern followed: every doc-type routed to its owning skill
- [ ] Every canonical-type write went through `cleo docs add --type X --slug Y`
- [ ] `references/writing.md` followed for `note`/`llm-readme` content
- [ ] `/ct-spec-writer` invoked when writing specs (REQ-XXX requirements)
- [ ] `/ct-adr-recorder` invoked when promoting consensus → ADR
- [ ] `references/reviewing.md` applied for quality validation
- [ ] Anti-duplication checklist verified
- [ ] Output file written with "Files NOT Created" section
- [ ] Manifest entry appended
- [ ] Task completed via `cleo complete`
---
## See references/
Progressive disclosure — load on demand only:
- `references/chain-orchestration.md` — when to invoke lookup/write/review, input shapes, review loop budget
- `references/doc-types-and-templates.md` — Diátaxis grid plus CLEO-native (ADR, agent-output, skill) templates
- `references/style-coordination.md` — tone pillars, forbidden phrases, link/code/table discipline
- `references/anti-patterns.md` — twelve documentation coordination failure modes
Files in this package (15)
- SKILL.md 48 KB
- __tests__/reviewing-reference.test.ts 2 KB
- __tests__/writing-reference.test.ts 2 KB
- references/anti-patterns.md 7 KB
- references/audience-targeting.md 8 KB
- references/chain-orchestration.md 6 KB
- references/cleo-style-guide.md 8 KB
- references/doc-types-and-templates.md 6 KB
- references/inline-comment-patterns.md 7 KB
- references/markdown-patterns.md 8 KB
- references/pr-review-mode.md 7 KB
- references/reviewing.md 11 KB
- references/style-coordination.md 6 KB
- references/style-violations.md 9 KB
- references/writing.md 11 KB
Versions
The database has no other skills named ct-documentor.
Database snapshot: 13.11.2026 · package version 7effc348fd4b (SHA-256 digest of the entire package)
Downloads in the last 30 days: 0 · ranking
Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.
Similar skills
- 100ct-cleo
CLEO task management protocol - session, task, and workflow guidance. Use when managing tasks, sessions, or multi-agent workflows with the CLEO CLI protocol. - 100docs-review
Review documentation for Sentry style and voice. Use when reviewing or writing user-facing documentation to ensure it follows the Sentry documentation style guide. - 85write-the-docs
Write or edit project documentation. Use when writing a README, design doc, or module doc. - 100compliance-mcp-tools
Use when calling Cleo Legal API, Cleo Insight, or Bastion MCP tools, planning a multi-tool compliance workflow, troubleshooting MCP tool errors, or choosing which tool to use for a product compliance task - 100technical-documentation
Audit, write, and improve developer documentation using Google''s Developer Documentation Style Guide and Technical Writing courses. Use this skill for any documentation work, even when the user names no style guide: "audit our docs", "review this README", "write a README",… - 90tc-docs-write
Use when writing or updating the TcKit documentation site or the README — anything under docs/content/ or README.md. Triggers on requests like "update the docs", "document this in the docs", "write a docs page for X", "the README needs Y", "add a capability page", "fix the home…