---
name: apt:create-docs
description: "Generate persona-first product docs from PROJECT.md + personas.json + the features registry"
apt-skill-version: {{APT_VERSION}}
stage: setup
intent: x-document
when_to_use: "Run after PROJECT.md, personas.json, and the features registry are all present to generate or refresh persona-first product docs at docs/product/."
user_invocable: true
internal: false
spawns_agent: true
agent_name: apt-docs-author
task_context: create-new
default_execution_mode: auto
execution_modes:
  - auto
  - step
allowed-tools: "Read, Glob, Grep, Write, Bash"
argument-hint: "apt:create-docs [--persona <id> | --tier primary|secondary|tertiary | --area <area-id> | --output-dir <path> | --force]"
gates: []
---

<objective>
Generate a persona-first, tier-gated product-docs tree at `docs/product/`
from three deterministic inputs the framework already maintains:

1. **Strategic intent** — `.aperant/product-context.json` (derived from
   PROJECT.md via C47). Sets the product name + target-audience framing
   that anchors every generated page.
2. **Persona roster** — `.aperant/personas.json` (written by C48).
   Tier-gated inclusion: primary personas get a full variant-aware tree,
   secondary personas get shared non-variant docs, tertiary personas get
   skeleton-only references (D-02).
3. **Feature inventory** — `.aperant/features/*.json` + `REGISTRY.md`
   (maintained by /apt:scan). Wired features → full docs. Stubbed
   features → "Coming soon" stubs (primary-persona only). Unwired
   features → omitted entirely (D-03).

The **CLI side is deterministic**: `apt-tools create-docs` composes the
three inputs into a `StructurePlan` + rendered navigation index. No LLM.

The **LLM side is the apt-docs-author agent**: per-feature prose
synthesis, D-04 variant-vs-shared rubric decisions, D-05 section-level
diff-and-confirm, one commit per feature written. The agent mirrors
apt-executor's subtask pattern but with "features" as the atomicity unit
(D-09).

Locked rules:

- **Output location (D-01):** `docs/product/` at repo root by default;
  overridable via `--output-dir`. Never writes to an existing
  `docs/developer/` or `docs/api/` tree.
- **Markdown only (D-06):** v1 emits `.md` files. JSON/HTML/static-site
  publishing is deferred to a future `apt:publish-docs` skill. The
  white-label URL integration (D-08) is out of scope.
- **Dogfood measurement (D-10) is NOT implemented in v1.** Success
  criterion is "user rating ≥4 on ≥2 repos," captured manually in
  `.aperant/dogfood-c49-feedback.json`. No rating UI is shipped; the
  JSON file is human-editable for the measurement window only.
</objective>

<your_environment>
- **Working directory:** The project root
- **apt-tools path:** `node packages/framework/bin/apt-tools.mjs` or the locally installed `apt-tools` binary
- **Upstream context:**
  - `PROJECT.md` (C47) + `.aperant/product-context.json` (derived)
  - `.aperant/personas.json` (C48)
  - `.aperant/features/*.json` + `REGISTRY.md` (/apt:scan)
- **Output:** `docs/product/{persona-id}/{area-id}/{feature-id}.md`
  (primary + secondary variant pages), `docs/product/_shared/{area-id}/{feature-id}.md`
  (shared non-variant), `docs/product/{persona-id}/{area-id}/index.md`
  (tertiary skeletons), `docs/product/README.md` (D-07 nav index)
- **Intent:** `x-document` — second custom-intent dogfood (end-to-end
  validation of router-0.3.0's x-* extension path after apt:personas
  shipped `x-personas` in C48)
</your_environment>

<state_files>
## State Files

**Reads:**
- `PROJECT.md` + `.aperant/product-context.json` — product name /
  target audience / scope (for the H1 + opening copy on every page)
- `.aperant/personas.json` — tier roster drives persona-first structure
- `.aperant/features/*.json` + `REGISTRY.md` — feature inventory drives
  per-area tree contents (wired / stubbed → included, unwired → omitted)
- `docs/product/**/*.md` (if present) — existing tree for D-05 diff-and-
  confirm

**Writes (via the apt-docs-author agent):**
- `docs/product/{persona-id}/README.md` — per-persona landing page
- `docs/product/{persona-id}/{area-id}/{feature-id}.md` — variant page
  (primary personas; secondary when LLM rubric picks variant over shared)
- `docs/product/_shared/{area-id}/{feature-id}.md` — shared page
  (secondary personas default; primary when rubric picks shared)
- `docs/product/{persona-id}/{area-id}/index.md` — tertiary skeleton
- `docs/product/README.md` — D-07 navigation index (deterministic, via
  `apt-tools create-docs render-nav`)
</state_files>

<process>

## 0. Hard-Gate + Autonomy Check

No hard gates (`gates: []`). Autonomy inherited from
`.aperant/config.json`'s `autonomy.default`:

| Autonomy | Behavior |
|---|---|
| 0 supervised | Show the full StructurePlan; confirm each persona+area group before the agent writes |
| 1 guided | Show the plan summary (totals + parse errors); ask once to proceed; section-level diff-and-confirm per D-05 on existing files |
| 2 autonomous | Show summary; proceed; keep D-05 diff-and-confirm on existing files |
| 3 yolo | Proceed silently; overwrite existing files without diff-confirm (equivalent to `--force`) |

Parse flags from the invocation:

- `--persona <id>` — scope the run to a single persona tree (useful for
  re-running one tier after a persona-variant decision flips).
- `--tier primary|secondary|tertiary` — scope by tier (useful for a
  focused primary-persona refresh).
- `--area <area-id>` — scope by area. Combines with --persona / --tier.
- `--output-dir <path>` — override the default `docs/product/` location.
- `--force` — skip D-05 diff-and-confirm and overwrite existing files.

## 1. Pre-flight — Verify Upstream Inputs

Invoke the planner; if any input is missing, surface the next-step
suggestion and stop.

```bash
node packages/framework/bin/apt-tools.mjs create-docs run . \
  [--output-dir <path>]
```

Envelope shape:

```json
{
  "command": "create-docs-run",
  "status": "ok" | "needs-scan",
  "registry_status": "ok" | "missing" | "empty",
  "personas_count": N,
  "product_name": "Aperant" | null,
  "parse_errors": [],
  "plan": { ... StructurePlan ... },
  "existing_output": { "output_dir_exists": bool, "file_count": N },
  "next_steps": ["...", "..."]
}
```

If `status === "needs-scan"`: show `next_steps` (the envelope includes
the suggested remediation — run `/apt:scan` when the registry is empty,
`/apt:personas` when the roster is empty) and stop.

## 2. Show the Plan Summary

At autonomy ≤ 1, present the user the high-level plan:

- `{areas} feature areas` (from `envelope.totals.areas`)
- `{features_documented} wired features to document`
- `{stubs_included} "Coming soon" stubs (primary-persona only per D-03)`
- `{features_omitted_unwired} unwired features omitted`
- `{personas_count} personas (primary/secondary/tertiary breakdown)`

Include a warning for every entry in `envelope.parse_errors[]` — those
are features-registry JSONs that failed to load and won't be documented.

Ask the user to proceed, edit the persona/tier/area scope, or cancel.
At autonomy ≥ 2 this step just prints the summary and proceeds.

## 3. Spawn the apt-docs-author Agent

Hand off to the agent with the full envelope. The agent does the LLM
work:

1. For each wired feature in `plan.areas[].features[]`:
   - Make the D-04 variant-vs-shared decision using the rubric
     (primary+secondary candidates, interaction patterns differ →
     variant; identical → shared; minor differences → shared with
     callout).
   - Synthesize the feature page prose (sections: Overview / Who this
     is for / How it works / Current status). The status section cites
     the feature's wiring bucket (wired / stubbed — never "unwired"
     because unwired features are omitted per D-03).
   - For stubbed features, emit the "Coming soon" stub with a short
     rationale sourced from `product-context.json.scope` if available.
2. D-05 diff-and-confirm per feature when the target file already
   exists — the agent uses `apt-tools create-docs read` to enumerate
   existing files, then section-level diffs new content against old and
   asks the user per-section (unless `--force` is set or autonomy=3).
3. Write the file (Write tool; the agent's `allowed-tools` excludes
   Edit to preserve the "one-file-at-a-time atomic write" contract).
4. Commit per feature (D-09). Commit message:
   `docs(product): feature {area}/{feature-id} for {persona-id|shared} (C49)`.
5. Update an in-memory progress structure so the agent can report
   mid-run status. The agent does NOT write `.aperant/build-progress.json`
   — that file belongs to the executor's plan-based flow, not to the
   feature-by-feature docs flow.

## 4. Regenerate the Navigation Index

After the agent finishes, regenerate `docs/product/README.md`:

```bash
node packages/framework/bin/apt-tools.mjs create-docs render-nav . \
  [--output-dir <path>]
```

This command is deterministic (no LLM) — it re-reads the plan and
rewrites the README atomically. Runs once at the end of every invocation,
even when the agent wrote zero new files (the index may still need to
pick up deleted files or timestamp changes).

## 5. Report

Emit the summary the user sees at the end of the run:

```
Product docs generated at docs/product/

Coverage:
  {features_documented} wired features documented
  {stubs_included} "Coming soon" stubs (primary personas only)
  {features_omitted_unwired} unwired features omitted per D-03
  {parse_errors.length} areas failed to load (see below)

Personas:
  [primary]   Maya, Alex     → full variant-aware tree
  [secondary] Sam            → shared non-variant docs
  [tertiary]  Jordan         → skeleton-only references

Navigation:
  docs/product/README.md      (tier-grouped TOC + coverage summary)

Next:
  Review the generated docs and publish via your usual flow
  Re-run /apt:create-docs after /apt:scan to refresh feature-driven
    content incrementally (D-05 diff-and-confirm preserves hand edits)
  /apt:publish-docs (future milestone) — white-label URL + static site
```

</process>

## Re-invocation

This skill is safe to re-run. D-05 section-level diff-and-confirm is the
default — the agent asks per-section before overwriting, so manual edits
to generated docs are preserved unless the user explicitly accepts the
new draft.

Common triggers:

- `/apt:scan` surfaces new wired features → re-run `/apt:create-docs`
  to incorporate them.
- `/apt:personas` adds a persona → re-run to populate the new persona's
  tree (use `--persona <new-id>` to scope the run).
- Product pivot → PROJECT.md's Core Value shifted, the per-page H1 /
  opening copy needs to align.

The `--force` flag bypasses D-05 (overwrite without confirmation). Use it
when regenerating in CI or in a scripted context where interactive
prompts are not available.

## Deferred

- **Dogfood measurement system (D-10).** v1 does not ship a rating UI or
  measurement pipeline. The success criterion is captured manually in
  `.aperant/dogfood-c49-feedback.json` during the measurement window;
  the framework does not own the evaluation.
- **White-label URL publishing (D-08).** Out of scope for v1. Markdown
  output is the contract. A future `apt:publish-docs` skill layers
  publishing concerns on top without changing this skill.
- **JSON / HTML / static-site output (D-06).** Same deferral as D-08;
  markdown is the interchange format, downstream publishers convert.
- **Docs freshness indicator** — flag docs that reference features
  changed in the repo since they were last generated. Needs a history
  layer this skill does not own.

## Integration with Other Skills

| Skill | How it relates to /apt:create-docs |
|-------|-----------------------------------|
| `/apt:bootstrap` (C47) | Writes `.aperant/product-context.json` — the source of the H1 productName + target-audience framing on every generated page |
| `/apt:personas` (C48) | Writes `.aperant/personas.json` — the tier roster that drives the persona-first structure (D-02) |
| `/apt:scan` | Writes `.aperant/features/*.json` — the feature inventory that drives per-area tree contents (D-03) |
| `/apt:review` | Pass 6 (docs-coherence) flags hand-edited prose in `docs/product/` that drifts from the registry; users resolve via `/apt:docs` or a re-run of this skill |
| `/apt:docs` | Focuses on developer docs (README.md, AGENTS.md, CLAUDE.md). `/apt:create-docs` focuses on product docs (docs/product/). The two flows share the features registry but write different surfaces |
| Future `apt:publish-docs` | Consumes the markdown this skill writes and publishes to white-label URL / static site (D-08 deferral path) |
