Skip to content
Back to skills

Docs

ASecurity

Documentation bootstrapper for mature-but-undocumented repos — the 'read then ask' lane. Reads the codebase FIRST (structure, manifests, routes/entrypoints/models/migrations, existing README, git-log themes) and drafts a 'what this system appears to do' map where every inference is marked ⚠ UNVERIFIED → interviews the owner in ONE batched question table (each question carries what the code suggests, what is ambiguous, and a proposed answer acceptable in one word) → writes the standard oracle ...

  • 6 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 2, 2026
developmentpythongobashgitdocumentation

Works with

  • cli

Security analysis

A100/100

Scanned September 2, 2026

npx -y skills add connorpham/vteam-harness --skill docs --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Docs?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Docs
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/connorpham-docs/badge)](https://www.skillsdirectory.com/skills/connorpham-docs)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: docs
description: "Documentation bootstrapper for mature-but-undocumented repos — the 'read then ask' lane. Reads the codebase FIRST (structure, manifests, routes/entrypoints/models/migrations, existing README, git-log themes) and drafts a 'what this system appears to do' map where every inference is marked ⚠ UNVERIFIED → interviews the owner in ONE batched question table (each question carries what the code suggests, what is ambiguous, and a proposed answer acceptable in one word) → writes the standard oracle the other lanes assume exists: specs INDEX + per-area shards (DRAFT-FROM-CODE vs OWNER-CONFIRMED), decisions.md seeds, knowledge-base.md seeds, known-issues.md → proposes a vteam.config.yaml patch (high_stakes_terms/paths, specs.sources, docs.task_context) for the owner to apply. Writes documentation only — never product code, never the config itself."
argument-hint: "[area]"
---

> **Model routing for this tool** (from `model-routing.data.yaml`, snapshot 2026-08-17):
> `frontier` → **fable** · `workhorse` → **opus** · `standard` → **sonnet** · `utility` → **haiku**
> Roles → tiers: ba-challenger: standard · ba-draft: standard · dev-r1: workhorse · dev-r2: standard (high-stakes: workhorse) · dev-r3: workhorse · explore: utility · qa-challenger: standard · sa-background: workhorse · sa-challenger: workhorse · sa-writer: workhorse
> Resolve at runtime: `python3 .vteam/scripts/model_route.py <role> --tool claude-code [--high-stakes]` — high-stakes diffs (review.high_stakes_*) bump dev-r2 to the workhorse tier.
> Spawning a subagent: pass the resolved name as the Agent tool's `model` parameter.


# /docs — create the documented truth the gates assume (docs lane, no code)

**Why this exists:** every other vteam lane reads an oracle. /ba shards a spec,
/dev cites `docs/specs/<feature>.md`, /qa derives expected values from it, and
the review gate escalates on `review.high_stakes_terms`. A mature repo that grew
without documentation has none of that — so the gates either idle or fire on
nothing. This workflow CREATES that oracle from the only two sources that
actually hold it: **the codebase** and **the owner's head**. It does not require
documentation to pre-exist; it manufactures it, then says out loud which parts
are still guesses.

**What this workflow is NOT:** it never writes or edits product code, never
touches `vteam.config.yaml` (it PROPOSES a patch, the owner applies it), never
files tickets, and never turns an inference into a fact by rewording it.

**Lane boundaries:** this lane needs CODE to read. A project with neither code
nor docs → `/plan` (the greenfield interview); a spec document already in hand
→ `/ba` shards it directly.

**Immutable principles:**
1. **Read before asking.** D0 runs to completion before the first question. A
   question the code already answers wastes the owner's only scarce resource, and
   an interview conducted blind produces documentation that describes an
   imaginary system.
2. **Inference is never presented as fact.** Every sentence derived from code
   carries `⚠ UNVERIFIED` (D0) or the `DRAFT-FROM-CODE` marker (D2); every
   sentence the owner confirmed carries `OWNER-CONFIRMED`. **Never mix inference
   and confirmed truth in one sentence without its marker** — a mixed sentence is
   a lie with a citation attached.
3. **ONE interview round.** All questions go to the owner in a single batched
   table (decision-queue discipline, `docs/pm/decisions.md`). Follow-ups born
   from the answers do NOT reopen the interview — they become rows in the
   decision queue with a proposal, and the docs ship marked DRAFT for those
   spots. Never invent an answer.
4. **Every question is answerable in one word.** Each row states what the code
   suggests, what is ambiguous, and a concrete PROPOSED ANSWER — the owner types
   "yes" / "no" / a correction. A bare question ("what is the domain model?")
   outsources the reading this lane was hired to do.
5. **The config is the owner's.** `high_stakes_terms`, `high_stakes_paths`,
   `specs.sources`, `docs.task_context` are DERIVED here and SHOWN as a patch.
   Auto-applying them would silently change which diffs get a third reviewer.
6. **Token discipline.** Cite paths and line ranges, never paste file contents
   into the transcript or into the docs. Read manifests and entrypoints in full;
   sample everything else.
7. **Visible, human-readable process.** One `▶ [D1/D3]` line per phase. The
   deliverable leads with plain language — the owner reads the map and the
   question table without opening a single source file.

Tempted to skip the read and just interview? That excuse is in `red-flags.md`,
next to the reason the resulting docs describe a system nobody shipped.

---

## D0 — READ THE REPO (before a single question)

Scope from the argument: `[area]` narrows to one subsystem; no argument = the
whole repo. Announce:

```
▶ DOCS: reading <repo|area> before asking anything
  manifests: <N> | entrypoints: <N> | existing docs: <N files> | commits scanned: <N>
```

**Build the code map first** — `python3 .vteam/scripts/code_map.py build` (needs
`git.code_paths`; on a repo where that is still empty, build it right after step 1
names where code lives): it is the cheap index for every read below —
`code_map.py query <term>` answers with paths + line ranges instead of a tree walk.

Read, in this order — each line is a source, not a suggestion:

1. **Structure** — the directory tree to a sensible depth, with the generated /
   vendored / build directories excluded. Note where product code actually lives
   (candidate for `git.code_paths`).
2. **Package manifests** — `package.json`, `pyproject.toml`, `go.mod`, `Gemfile`,
   `pom.xml`, `Cargo.toml`, whatever exists. Read these IN FULL: dependencies name
   the stack, the scripts section names the real build/test/lint commands (they
   feed the `/verify` gate later), and the dependency list is the fastest honest
   read of what the system integrates with.
3. **Entrypoints and routes** — `main`/`index`/`app` files, route files, HTTP
   handlers, CLI commands, scheduled jobs, queue consumers. Enumerate them; do
   not read them all.
4. **Data model** — schema files, ORM models, and **the migration directory in
   chronological order** — migrations are the repo's only honest changelog of
   what the domain used to be and what it became.
5. **Existing docs** — README, `docs/`, ADRs, wiki exports, comment blocks at the
   top of core modules, `CONTRIBUTING`. Whatever is already true here gets
   REUSED, not rewritten (and its path is a candidate for `specs.sources`).
6. **Git-log themes** — `git log --oneline` over a meaningful window plus the
   most-churned files. What the team has been changing for months IS the system's
   center of gravity, and the churn list is the best first draft of
   `high_stakes_paths`.
7. **Vocabulary harvest** — collect the domain nouns that recur in model names,
   table names, enum values, and route segments. This is the raw material for
   `high_stakes_terms`; at D0 it is only a word list, not a risk judgment.

**Deliverable — the appearance map** (`docs/specs/DRAFT-system-map.md`, and
summarized in the transcript, ≤1 page):

```markdown
# What this system appears to do — DRAFT FROM CODE, <date>
⚠ Every line below is an INFERENCE from reading code. Nothing here is confirmed.

## Purpose (⚠ UNVERIFIED)
<2–4 plain sentences: what the system seems to be for, who seems to use it>

## Areas (⚠ UNVERIFIED per row)
| Area | Evidence (paths) | What it appears to do | Confidence |
|---|---|---|---|

## Domain vocabulary observed
| Term | Where it appears | Guessed meaning (⚠ UNVERIFIED) |

## Flows that touch money / external systems / irreversible state (⚠ UNVERIFIED)
| Flow | Entrypoint path | Why it looks high-stakes |

## Stack facts (VERIFIED — read from manifests, not inferred)
<language/framework/db/test runner + the real script names>

## What I could NOT determine from code
<the list that becomes the D1 questions>
```

The "Stack facts" section is the only unmarked section in the file: a dependency
read out of a manifest is a fact. Everything else is marked.

## D1 — INTERVIEW THE OWNER (one batched table, one round)

The core of this lane: **read, then ask.** The code told us how the system is
built; only the owner knows what it is FOR, what is dangerous, and where the
bodies are buried.

Present ONE table. Every row is answerable with one word because the proposal is
already written:

```markdown
| # | Question | What the code suggests | What's ambiguous | PROPOSED ANSWER (say "ok" to accept) |
|---|---|---|---|---|
| Q1 | … | <path>: … | … | … |
```

Cover all six categories — a category with nothing to ask says
`Q(n): nothing to ask, the code was unambiguous here`:

| # | Category | What the answer is FOR | Feeds |
|---|---|---|---|
| 1 | **System purpose + users** — what it is for, who the real roles are, which are internal vs customer | The one paragraph every spec shard opens with | specs INDEX, shard headers |
| 2 | **Domain vocabulary** — for each harvested term: does it mean what it looks like, and does it mean *money or irreversibility* in this business? | Turning a word list into a risk list | `review.high_stakes_terms` |
| 3 | **Money / irreversible flows** — which flows move money, delete real data, notify customers, or hit a partner that cannot be un-called | Which diffs deserve a third reviewer | `review.high_stakes_paths` |
| 4 | **Source-of-truth documents elsewhere** — the spec in a drive folder, the Notion page, the contract PDF, the sheet the rules actually live in | Stopping this lane from re-deriving requirements the owner already wrote down | `specs.sources` |
| 5 | **What "done" means here** — what must be true before a change ships: tests? staging? a person clicking? a release window? | The DoD the /verify and /qa gates enforce | `/verify` profile, DoD sections |
| 6 | **Known debt + landmines** — "never touch X on a Friday", the module everyone fears, the flaky suite, the manual step nobody automated | Warning the /dev lane before it steps on it | `known-issues.md` |

Rules for this phase:
- **One round.** Ask everything at once. An answer that raises a new question →
  a row in `docs/pm/decisions.md` with a proposal and what it blocks, NOT a
  second interview.
- **Unanswered rows stay unanswered.** A question the owner skips leaves its
  documentation marked `DRAFT-FROM-CODE` + `⚠ OWNER QUESTION OPEN (Qn)`. Silence
  is never consent to the proposal here — that mechanism belongs to /pm's
  decision queue, and only for questions recorded there with a deadline.
- **Record the answers verbatim** into
  `docs/specs/DRAFT-system-map.md` under `## Owner answers <date>` before
  writing anything in D2 — the answers are the citation D2's OWNER-CONFIRMED
  markers point at.

## D2 — WRITE THE STANDARD DOCS (from D0 + D1, markers on every line)

Marker law, applied per sentence or per row — never per file:

| Marker | Means | Source |
|---|---|---|
| `OWNER-CONFIRMED` | The owner stated it in D1 | the answer log |
| `DRAFT-FROM-CODE` | Inferred from code, unconfirmed | cited path(s) |
| `⚠ OWNER QUESTION OPEN (Qn)` | Asked, not answered | the D1 table row |

Write:

1. **`docs/specs/INDEX.md`** — one row per area (area | file | scope | status
   `DRAFT-FROM-CODE`/`OWNER-CONFIRMED`/`MIXED`). This is the file /ba and /dev
   will look for; it exists after this phase or the lane failed.
2. **Per-area spec shards `docs/specs/<area>.md`** — for each area in the map:
   purpose (from Q1), the roles who use it, observed behavior as numbered
   `§x.y` sections so later lanes can cite them, the data it owns, and an
   explicit **`## NOT DOCUMENTED`** section listing what nobody could answer.
   Each `§` carries its marker and its evidence path. These shards are PROSE
   DESCRIPTION of observed behavior — they are **not** verbatim requirement rows
   copied from an upstream document, so they carry no coded requirement ids (see
   D3 on the verbatim gate).
3. **`docs/pm/decisions.md` seeds** — the architectural choices the code
   already made, recorded as decisions that were taken implicitly: the framework,
   the auth mechanism, the data store, the deploy target, the multi-tenancy
   model, whatever else the code committed to. One row each:
   `implicit decision · evidence path · when (first commit/migration) ·
   status: 🟢 IN FORCE (undocumented until now)`. Where a real trade-off is
   visible and load-bearing, note it as an **ADR candidate** for the SA lane —
   this lane does not write ADRs.
4. **`docs/qa/knowledge-base.md` seeds** — §0 + INDEX per the standard shape,
   seeded with the operational lessons the repo itself reveals: the real
   dev-server bring-up sequence, the env vars without which nothing runs, the
   seed/fixture path, the test command that actually passes. Tag each lesson so
   the /dev and /qa index-only preflights can match it.
5. **`docs/qa/known-issues.md`** — one heading per landmine from Q6, each with:
   what breaks, how to recognize it, the workaround, and whether it is a bug
   nobody filed (→ candidate for /ba) or accepted behavior.
6. **The proposed config patch — SHOWN, NEVER APPLIED.** Print it as a diff-ready
   block with a one-line justification per key, then state in plain language what
   each key will start doing once applied:

   ```yaml
   # PROPOSED — review, then paste into vteam.config.yaml yourself.
   # /docs does not write this file.
   specs:
     sources: [<the real source docs from Q4>]
   review:
     high_stakes_paths: [<paths from Q3 + the churn list>]
     high_stakes_terms: [<terms the owner confirmed mean money/irreversibility in Q2>]
   docs:
     task_context:
       always: [<what every ticket must read>]
       by_label:
         <label>: [<extra reading for that label/type>]
   ```

   `docs.task_context` is the payoff of this whole lane: it is how the /dev lane
   learns to read the right background for the right ticket without the owner
   repeating themselves (dev.md T1, "Task context"). A label with nothing worth
   reading is omitted, not filled with the README.

## D3 — VERIFY THE DOCS, READ BACK, HAND OVER

1. **Gate the generated docs against the gates that will now judge them:**
   - `python3 .vteam/scripts/verbatim_gate.py` — **must stay GREEN, and if
     `specs.sources` is still empty it has nothing to compare and says so.** State
     this explicitly to the owner: **the shards this lane writes are PROSE
     DESCRIPTIONS of observed behavior, not verbatim requirement rows, so they
     carry no coded ids for the gate to byte-compare.** The verbatim gate starts
     guarding real requirement text only when /ba later shards an actual source
     document listed in `specs.sources`. A shard from this lane that DID paste
     coded rows out of a source document is a /docs bug — move those rows to /ba.
   - `bash .vteam/scripts/preflight.sh` — confirms the paths this lane just
     created are where the config says they are.
   - Marker audit: every `§` in every shard carries exactly one marker; grep for
     unmarked sections and fix them. An unmarked sentence is the one failure mode
     this whole workflow exists to prevent.
2. **Read-back list — every file written, one line each** (path → what it
   contains → marker mix), plus the files deliberately NOT written and why:
   ```
   WROTE  docs/specs/INDEX.md            — 6 areas (2 OWNER-CONFIRMED, 4 DRAFT)
   WROTE  docs/specs/billing.md          — §1–§7, DRAFT-FROM-CODE, 2 open questions
   …
   NOT WRITTEN  docs/adr/               — ADR candidates listed, SA lane's call
   NOT WRITTEN  vteam.config.yaml       — patch proposed above, yours to apply
   ```
3. **Closing line — which gates now guard what.** Plain language, one line per
   gate, naming what became enforceable that was not enforceable an hour ago:
   ```
   ▶ DOCS done. From now on:
     · /dev cites docs/specs/<area>.md instead of guessing — dor_check will demand it
     · <N> tickets' worth of background is auto-read via docs.task_context (once you apply the patch)
     · reviews escalate to a 3rd reviewer on <terms> and <paths> (once applied)
     · /qa derives expected values from the shards; the NOT DOCUMENTED sections
       are where it will still say BLOCKED and send the question to /ba
     · verbatim_gate guards nothing yet — it starts the day /ba shards <source doc>
   ```
4. **State the debt honestly.** Count and name what is still `DRAFT-FROM-CODE`
   and every `⚠ OWNER QUESTION OPEN` — the docs are a starting oracle, not a
   finished one, and the next lane must know which sentences it may not lean on.
5. **Close the learning loop** — append a lesson (+1 INDEX line) to
   `docs/qa/knowledge-base.md` or state "no new lesson".

## Definition of Done
- [ ] D0 ran to completion BEFORE the first question; the appearance map exists
      with `⚠ UNVERIFIED` on every inferred line
- [ ] Stack facts read from real manifests (not inferred), including the real
      build/test/lint script names
- [ ] D1 was ONE batched table covering all six categories; every row carried
      what-the-code-suggests + what's-ambiguous + a one-word-acceptable proposal
- [ ] Owner answers recorded verbatim before any doc was written; follow-ups went
      to `docs/pm/decisions.md`, not to a second interview round
- [ ] `docs/specs/INDEX.md` + one shard per area exist; every `§` carries
      exactly one marker; no sentence mixes inference with confirmed truth
- [ ] `decisions.md` seeds recorded for the choices already made in code; ADR
      candidates listed, not written
- [ ] `knowledge-base.md` seeded (§0 + INDEX + tagged lessons);
      `known-issues.md` written from the landmines question (or "none reported")
- [ ] Config patch SHOWN with per-key justification; `vteam.config.yaml`
      UNTOUCHED by this lane
- [ ] `verbatim_gate.py` GREEN, and the prose-not-verbatim reason stated out loud
- [ ] Read-back list printed: every file written + every file deliberately not
      written
- [ ] Closing line delivered: which gate now guards what; remaining DRAFT and
      open-question count named
- [ ] No product code touched; no requirement invented; no config auto-applied
- [ ] ▶ narration per phase; lesson recorded/declared at D3

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…