---
name: oat-project-document
version: 1.6.1
description: Use when the user requests or confirms documenting an active OAT project — e.g. "document the project", "update the docs", "run oat-project-document", or confirms a previously offered documentation run. Do NOT auto-invoke when implementation completes. Analyzes project artifacts, presents a documentation delta plan, and applies approved changes.
argument-hint: '[project-path] [--auto]'
disable-model-invocation: false
user-invocable: true
allowed-tools: Read, Write, Edit, Bash(git:*), Glob, Grep, AskUserQuestion, Skill
---

# Project Documentation Sync

Read project artifacts and implementation code to identify documentation surfaces that need updating, present a delta plan for approval, and apply changes — all in a single invocation.

## Prerequisites

**Required:**

- Active OAT project (or explicit project path) with at least `plan.md` or `implementation.md`
- Project should have completed some implementation work (artifacts describe what was built)

## Mode Assertion

**OAT MODE: Project Document**

**Purpose:** Analyze what a project built, identify documentation gaps, and apply approved documentation updates.

When `OAT_AUTONOMOUS=1`, read `references/docs/autonomy-contract.md` and execute
the existing `--auto` path for this run. Keep `OAT_NON_INTERACTIVE=1`
session-scoped and never persist either environment signal. This branch is inert
when autonomy is inactive.

## Progress Indicators (User-Facing)

- Print a phase banner once at start:

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  OAT ▸ PROJECT DOCUMENT
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

- For each step, announce a compact header:
  - `OAT ▸ DOCUMENT — Step N: {step_name}`
- Before multi-step work:
  - `[1/N] {action}…`
- Keep it concise; don't print a line for every shell command.

**BLOCKED Activities:**

- No modifying implementation source code
- No modifying project phase state (except `oat_docs_updated` in state.md)
- No deleting or restructuring existing documentation without user approval
- No creating documentation content that contradicts source code

**ALLOWED Activities:**

- Reading all project artifacts (discovery.md, spec.md, design.md, plan.md, implementation.md)
- Reading source code referenced in artifacts
- Scanning all documentation and instruction surfaces
- Writing/editing documentation files (after approval or with --auto)
- Creating new documentation files and directories
- Editing docs tooling config (e.g., mkdocs.yml nav) for new files
- Updating `oat_docs_updated` in state.md

**Self-Correction Protocol:**
If you catch yourself:

- Modifying source code → STOP (this skill only writes documentation)
- Inventing documentation without evidence → STOP (every recommendation needs artifact/code evidence)
- Changing project phase or task state → STOP (only `oat_docs_updated` is allowed)

**Recovery:**

1. Acknowledge the deviation
2. Return to current step
3. Ask user for guidance

## Artifact Hygiene

Artifact hygiene contract: Before finishing or committing, format every file you created or edited. Use the concrete write/fix formatting command supplied by the governing plan, task, or brief. If none is usable, discover the repository's documented write/fix command from applicable `AGENTS.md`/`CLAUDE.md` instructions and relevant package manifests; do not infer or hardcode a formatter. Prefer a file-scoped invocation when supported, and avoid rewriting unrelated files. If no command is discoverable, warn once with `no format command discovered in repo instructions; skipping`, then continue.

After formatting, run only repository checks relevant to the files changed;
writing documentation does not imply unrelated full test suites.

## Argument Parsing

Parse `$ARGUMENTS` for:

1. **`--auto` flag:** If present, skip user approval and apply all recommendations directly.

   ```
   AUTO_MODE=false
   if echo "$ARGUMENTS" | grep -q '\-\-auto'; then
     AUTO_MODE=true
   fi
   ```

   If `OAT_AUTONOMOUS=1`, set `AUTO_MODE=true` after normal argument parsing
   even when `--auto` was not passed. Record gate `DOCUMENT-02` and the applied
   recommendation set in the documentation outcome. This is the existing
   `--auto` behavior, not a new approval mode.

2. **`project-path`:** Any non-flag argument is treated as an explicit project path.
   ```
   PROJECT_ARG=$(echo "$ARGUMENTS" | sed 's/--auto//g' | xargs)
   ```

## Process

### Step 0: Resolve Project Context

OAT stores active project context in `.oat/config.local.json` (`activeProject`, local-only).

```bash
PROJECT_PATH=$(oat config get activeProject 2>/dev/null || true)
PROJECTS_ROOT="${OAT_PROJECTS_ROOT:-$(oat config get projects.root 2>/dev/null || echo ".oat/projects/shared")}"
PROJECTS_ROOT="${PROJECTS_ROOT%/}"
```

**Resolution order:**

1. If `$PROJECT_ARG` is provided, use it as `$PROJECT_PATH`
2. Else if `activeProject` is set in config, use that
3. If neither available, use `AskUserQuestion` to ask: "No active project found. Please provide the path to the project directory (e.g., `.oat/projects/shared/my-project`)."

**Validation:**

- Verify `$PROJECT_PATH/state.md` exists
- Verify at least one of `plan.md` or `implementation.md` exists (need to know what was built)
- If validation fails, report the error and STOP

Derive `{project-name}` as the directory name: `basename "$PROJECT_PATH"`.

**Documentation config resolution:**

Read documentation config from `.oat/config.json`:

```bash
DOCS_ROOT=$(oat config get documentation.root 2>/dev/null || true)
DOCS_TOOLING=$(oat config get documentation.tooling 2>/dev/null || true)
DOCS_CONFIG=$(oat config get documentation.config 2>/dev/null || true)
```

If `$DOCS_ROOT` is empty, attempt auto-detection:

1. Look for `mkdocs.yml` — if found, set `DOCS_TOOLING=mkdocs` and infer `DOCS_ROOT` from the `docs_dir` field (or default to `docs/` relative to the mkdocs.yml location), set `DOCS_CONFIG` to the mkdocs.yml path
2. Look for `docusaurus.config.js` or `docusaurus.config.ts` — if found, set `DOCS_TOOLING=docusaurus`, infer `DOCS_ROOT` from config
3. Look for `conf.py` (Sphinx) — if found, set `DOCS_TOOLING=sphinx`
4. Look for a top-level `docs/` directory — if found, set `DOCS_ROOT=docs`
5. If nothing found, `DOCS_ROOT` remains empty (docs directory scanning will be skipped)

For auto-detection, use Glob to scan from repo root:

```
Glob: **/mkdocs.yml (exclude node_modules, .oat, dist)
Glob: **/docusaurus.config.{js,ts}
```

Store resolved values for use in later steps. Do not write auto-detected values to config.

### Step 1: Check for PJM Infrastructure

Check whether the project-management tool pack is installed by reading config:

```bash
PJM_INSTALLED=$(oat config get tools.project-management 2>/dev/null || echo "false")
```

**If `PJM_INSTALLED` is `true`:**

- Invoke `oat-pjm-update-repo-reference` automatically before proceeding.
- Do not ask whether to run the repo reference update during project-document.
- **If invocation succeeds:** Log that repo reference docs were refreshed and continue to Step 2. The reference surfaces will already be current when the documentation scan reads them in Step 4a.4.
- **If invocation fails:** Warn the user that the repo reference update failed, but continue with the documentation sync — a PJM failure should not block documentation updates.

**If `PJM_INSTALLED` is not `true`:** Skip silently and proceed to Step 2.

### Step 2: Read Project Artifacts

Read all available project artifacts to build an understanding of what was built.

**Read in order:**

1. `$PROJECT_PATH/discovery.md` — initial requirements, key decisions, constraints
2. `$PROJECT_PATH/spec.md` (if exists) — formal requirements, acceptance criteria
3. `$PROJECT_PATH/design.md` (if exists) — architecture, components, data models, integration points
4. `$PROJECT_PATH/plan.md` — phases, tasks, file lists, commit messages
5. `$PROJECT_PATH/implementation.md` — execution log, outcomes, files changed, decisions

**Synthesize a "what was built" model:**

From the artifacts, extract and organize:

- **Features and capabilities added** — what can users/developers now do that they couldn't before?
- **Architectural decisions** — new patterns, component boundaries, data flow changes
- **New frameworks, tooling, or libraries** — dependencies added, build tool changes, test frameworks
- **New CLI commands or config schema changes** — new user-facing commands, config keys, options
- **New directories or structural changes** — new packages, apps, or significant directory reorganization
- **API changes** — new endpoints, modified interfaces, changed contracts

**Note source file references:**

While reading artifacts, collect all source file paths mentioned in:

- Plan task `**Files:**` sections (Create/Modify entries)
- Implementation.md `**Files changed:**` entries
- Design component interfaces and data models

These will be verified against actual code in Step 3.

**Handle missing artifacts gracefully:**

- Quick-mode projects may lack spec.md and design.md — extract what's available
- If only plan.md exists (no implementation.md), the project may not have started implementation yet — still proceed, but note that documentation recommendations will be based on planned work rather than verified implementation

### Step 3: Verify Against Code and Build a Capability Inventory

Read source files referenced in artifacts to confirm what actually shipped, then do a targeted capability-discovery pass so the skill can catch newly introduced documentation surfaces rather than only updating already-documented ones.

**For each referenced source file:**

1. Check if the file exists (it may have been renamed or deleted since the plan was written)
2. Read the file to verify artifact claims:
   - Do described APIs/commands/config schemas actually exist?
   - Were architectural patterns from design.md followed?
   - Are there implementation details not captured in artifacts?

**Augment the model:**

- Add code-verified details that artifacts didn't capture
- Note any discrepancies between artifacts and code (informational — include in delta plan as context, not as blocking issues)
- Organize the verified implementation into **capability areas** (for example: new app surface, CI/CD pipeline, release automation flow, deployment target, integration surface, CLI/config workflow)

**Targeted capability discovery pass:**

After verifying artifact-referenced files, inspect the strongest adjacent signals for newly shipped capability surfaces even when the exact docs target does not already exist.

Prioritize evidence from:

- new apps/packages/directories called out by the artifacts
- workflow/config files tied to shipped behavior (`.github/workflows`, release configs, deploy configs, mobile build/release files, etc.)
- entrypoints, route registration files, service modules, and schemas that define user- or operator-facing behavior
- package manifests and scripts that expose new setup, release, or operational workflows

For each significant capability area, capture:

- capability name
- concrete repo evidence proving it shipped
- likely audience (`developer`, `operator`, `integrator`, `end user`)
- whether the capability represents a new docs surface versus an addition to an existing surface

**Scope control:**

- Start with files directly referenced in artifacts, then inspect only the highest-signal adjacent files needed to understand the shipped capability areas
- Do not scan the entire codebase blindly; stay anchored to the implementation areas surfaced by the project artifacts
- If artifacts reference many files (>20), prioritize: new files first, then modified files with the most changes, then only the adjacent files needed to confirm docs impact
- Read file contents, not just check existence — the skill needs to understand what the code does to make good documentation recommendations

### Step 4: Discover Documentation Surfaces

Scan the repository for all documentation and instruction surfaces.

**4a. Documentation surfaces (primary — thorough analysis):**

1. **Docs directory** (if `$DOCS_ROOT` is set):
   - Read the docs tooling config (e.g., `$DOCS_CONFIG`) to understand nav structure
   - List all files in `$DOCS_ROOT` recursively
   - Read existing docs files that could be affected by the project
   - Identify the parent section or directory where each uncovered capability area would naturally live
   - Note when no existing page or directory is a good fit — this is a strong signal for a `CREATE` recommendation, not a reason to force the content into an unrelated existing page

2. **Root README.md:**
   - Always check — read current content

3. **Subdirectory README.md files:**
   - Glob `**/README.md` (exclude `node_modules`, `.oat`, `dist`, `.worktrees`)
   - Read existing ones that are in directories affected by the project
   - Note directories for new apps/packages that lack a README

4. **Reference files:**
   - Check the active PJM layer under `.oat/repo/pjm/` and the durable layer under `.oat/repo/reference/`
   - Read (whichever exist): `pjm/current-state.md`, `pjm/roadmap.md`, `pjm/backlog/index.md`, `pjm/backlog/completed.md`, relevant `pjm/backlog/items/*.md` files, and `reference/decisions/index.md` plus relevant `reference/decisions/*.md` records
   - Legacy repos may still have `reference/current-state.md`, `reference/roadmap.md`, `reference/backlog/`, or a `reference/decision-record.md` monolith until they run `oat pjm migrate`; read those only as a fallback when the `pjm/` and `reference/decisions/` equivalents are absent

**4b. Instruction surfaces (secondary — strong signals only):**

1. **Root AGENTS.md / CLAUDE.md:**
   - Always check — read current content

2. **Subdirectory AGENTS.md files:**
   - Glob `**/AGENTS.md` (exclude `node_modules`, `.oat`, `dist`, `.worktrees`)
   - Read ones in directories affected by the project

3. **Provider rules files:**
   - Check `.oat/sync/config.json` for enabled providers
   - For each enabled provider, check its rules directory:
     - Claude: `.claude/rules/`
     - Cursor: `.cursor/rules/`
     - Copilot: `.github/copilot-instructions.md`
     - Gemini: `.gemini/rules/`
   - Read existing rules files that may need updating

**Store surface inventory** for use in Step 5. For each surface, record:

- File path (existing or potential)
- Surface type (docs | readme | reference | agents | provider-rules)
- Current content summary (for existing files)
- Whether it's in a directory affected by the project

### Step 5: Assess Documentation Delta

Compare "what was built" (from Steps 2-3) against "what's documented" (from Step 4) to produce recommendations.

**5a. Capability coverage assessment (required):**

Before recommending file-level edits, evaluate coverage for each significant capability area in the "what was built" model.

For each capability area, classify the documentation state as:

- **adequately covered** — existing docs already explain the shipped behavior accurately
- **thin coverage** — the area is mentioned, but important setup, workflow, or usage details are missing
- **no coverage** — no existing docs surface meaningfully covers the capability

For each capability with **thin coverage** or **no coverage**, determine the best docs home:

- **Expand an existing page** when a clear, discoverable page already owns the topic
- **Create a new page** when the topic is distinct enough to deserve its own entrypoint
- **Create a new docs directory** (with `index.md` entrypoint, where that is the local convention) when the shipped work introduces a new top-level capability area with multiple likely subtopics

Bias rules:

- If a docs app exists and the shipped work represents a new major capability area, do **not** default to stuffing the information into `README.md`, `roadmap.md`, or `current-state.md`
- Examples that often warrant `CREATE` recommendations: new mobile apps, CI/CD and release automation, new deployment targets, new integration surfaces, or new operator workflows
- If no existing docs section is a natural fit, prefer recommending a new page or directory rather than forcing an `UPDATE` on a loosely related page

Each coverage-gap finding should capture:

- capability area
- current docs state (`thin coverage` or `no coverage`)
- evidence proving the capability shipped
- likely audience
- suggested docs location (`existing page`, `new page`, or `new directory`)
- why that location is the right home

**5b. Documentation surface assessment:**

For each documentation surface relevant to the project, determine one of:

- **UPDATE:** Existing doc needs content changes. Specify:
  - What content to add/modify
  - Where in the file it should go
  - Why (evidence from artifacts/code)

- **CREATE:** No existing doc covers this area. Specify:
  - Proposed file path
  - Proposed content outline (section headings, key points)
  - Why this warrants a new file (evidence)
  - If inside a docs app, note any parent index/nav follow-on work that will be needed

- **SPLIT:** Existing doc would become too large with additions. Specify:
  - Current file path and approximate size
  - Proposed split structure (which content moves where)
  - Why splitting is recommended (file would exceed ~300 lines, or logical separation warrants it)

- **No change:** Surface is already accurate — skip from delta plan.

When deciding between `UPDATE` and `CREATE`, prefer `CREATE` if:

- the capability currently has **no coverage**
- the docs app has no discoverable home for that topic
- the proposed addition would otherwise bury a new major workflow inside an unrelated page

**5c. Instruction surface assessment (strong signals only):**

Only recommend instruction changes when there is a clear trigger:

| Signal                              | Example                             | Recommendation                             |
| ----------------------------------- | ----------------------------------- | ------------------------------------------ |
| New test framework                  | vitest added to devDependencies     | Create test rules for enabled providers    |
| New styling/component library       | tailwind, storybook added           | Create styling rules for enabled providers |
| New build tooling                   | different bundler, new build step   | Update AGENTS.md development commands      |
| New directory with complex patterns | new package with unique conventions | Create subdirectory AGENTS.md              |
| New dev commands                    | new CLI commands, scripts           | Update root AGENTS.md                      |

If no strong signal is present for an instruction surface, skip it.

**5d. Per recommendation, capture:**

```
- Target: {file path — existing or proposed}
- Action: {UPDATE | CREATE | SPLIT}
- Summary: {1-2 sentences on what changes and why}
- Evidence: {artifact/code reference — e.g., "spec.md §3", "plan.md p02-t03", "implementation.md p01-t01 outcome", "workflow file X proves release automation shipped"}
- Audience: {developer | operator | integrator | end user}
- Content guidance: {specific content to add or outline for new files}
- Coverage state: {adequately covered | thin coverage | no coverage}
- Parent docs impact: {parent index/nav updates needed, or "none"}
```

### Step 6: Present Delta Plan

Format and present the recommendations for user approval.

**6a. Format output:**

```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 OAT ▸ PROJECT DOCUMENT — Delta Plan
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

## Documentation Updates ({N} recommendations)

1. {ACTION}  {target file path}
   {Summary of what changes and why}
   Evidence: {artifact/code reference}

2. {ACTION}  {target file path}
   {Summary}
   Evidence: {reference}

## Instruction Updates ({N} recommendations)

3. {ACTION}  {target file path}
   {Summary}
   Evidence: {reference}
```

**6b. Handle edge cases:**

- If `$AUTO_MODE` is true: skip to Step 7 (apply all recommendations)
- If no recommendations found: report "No documentation updates identified for this project.", set `oat_docs_updated: complete` in state.md, and exit
- If only instruction recommendations (no docs): still present, but note the documentation-first priority

Under `OAT_AUTONOMOUS=1`, the auto path applies all non-destructive
recommendations without presenting Step 6c. A recommendation that deletes
documentation or broadly restructures existing documentation beyond the
approved project plan remains gate `DOCUMENT-03`: stop before applying it,
record the proposed change and evidence, and leave the project resumable.

**6c. Interactive approval:**

```
Approve recommendations?
  [Y]es — apply all
  [I]ndividual — approve/reject each one
  [S]kip — skip documentation updates
```

- **Yes:** mark all recommendations as approved
- **Individual:** present each recommendation one at a time with approve/reject
- **Skip:** set `oat_docs_updated: skipped` and `oat_project_state_updated: "{ISO 8601 UTC timestamp}"` in `$PROJECT_PATH/state.md` frontmatter, commit the state change, and exit without applying documentation changes

Track which recommendations were approved for Step 7.

### Step 7: Apply Approved Changes

Execute the approved documentation updates.

**For each approved recommendation:**

1. **UPDATE:**
   - Read the target file
   - Edit the file to add/modify content as specified in the recommendation
   - Preserve existing content structure — insert new sections or update existing ones

2. **CREATE:**
   - Create parent directories if needed (`mkdir -p`)
   - Write the new file with the content outlined in the recommendation
   - For docs directory files: follow the existing docs conventions for entrypoints and local navigation (for example, `index.md` entrypoints and `## Contents` sections where that is the local pattern)
   - If the recommendation created a new docs directory, add the required entrypoint file for that directory as part of the same change

3. **SPLIT:**
   - Create the new file with the content being moved
   - Edit the original file to remove the moved content
   - Add a cross-reference in the original file pointing to the new location
   - If the original had sections that logically separate, use section headings as split boundaries

**Nav structure updates:**

If `$DOCS_CONFIG` exists and new files were created in the docs directory:

- Read the tooling config (e.g., mkdocs.yml)
- Add new entries to the nav structure in the appropriate location
- Preserve existing nav order

**Error handling:**

- Track a `$ALL_SUCCEEDED` flag (default: true). If any file write fails, set `$ALL_SUCCEEDED` to false, log the error, and continue with remaining recommendations
- At the end, report any failures with the specific files that could not be written

### Step 8: Commit and Update State

**8a. Stage and commit documentation changes:**

```bash
git add {list of changed/created documentation files}
git diff --cached --quiet || git commit -m "docs({project-name}): update documentation from project artifacts"
```

Only stage files that were actually changed or created in Step 7. Do not use `git add -A`.

**8b. Update project state:**

Update `$PROJECT_PATH/state.md` frontmatter based on apply outcome:

- If `$ALL_SUCCEEDED` is true: set `oat_docs_updated: complete` and `oat_project_state_updated: "{ISO 8601 UTC timestamp}"`
- If `$ALL_SUCCEEDED` is false: do **not** set `oat_docs_updated: complete` — leave the field as `null` so the skill can be re-run. Still set `oat_project_state_updated: "{ISO 8601 UTC timestamp}"`. Surface the failures clearly in the summary report (Step 8d) so the user knows which updates failed and why.

```bash
git add "$PROJECT_PATH/state.md"
git diff --cached --quiet || git commit -m "chore({project-name}): mark docs updated"
```

**8c. Handle edge cases:**

- If user explicitly skipped (chose [S]kip in Step 6): `oat_docs_updated` was already set to `skipped` in Step 6. No further state update needed here.
- If no recommendations were found: set `oat_docs_updated: complete` (nothing to do is still "done").
- If `--auto` mode: apply all, commit, set state — no user interaction.

**8d. Report summary:**

If `$ALL_SUCCEEDED` is true:

```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 OAT ▸ PROJECT DOCUMENT — Complete
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Documentation sync complete for {project-name}.

  Updated: {N} files
  Created: {N} files
  Split:   {N} files

Commit: {sha}
State:  oat_docs_updated = complete

Next steps:
  - oat-project-complete → close out the project
  - Review changes before pushing
```

If `$ALL_SUCCEEDED` is false:

```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 OAT ▸ PROJECT DOCUMENT — Partial Failure
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Documentation sync partially failed for {project-name}.

  Succeeded: {N} files
  Failed:    {N} files
    - {path}: {error reason}

Commit: {sha} (successful changes only)
State:  oat_docs_updated NOT set (re-run to retry)

Next steps:
  - Investigate and fix the failed writes
  - Re-run oat-project-document to complete the sync
```

## Success Criteria

- All documentation surfaces relevant to the project are scanned
- Significant capability areas from the "what was built" model are classified as `adequately covered`, `thin coverage`, or `no coverage` before file-level recommendations are chosen
- Recommendations are evidence-based (every recommendation cites artifact/code sources)
- `CREATE` actions are recommended when no existing docs surface is a natural fit, including new docs pages or directories when the shipped work introduces a new capability area
- Interactive approval flow works correctly (all/individual/skip)
- `--auto` mode applies all changes without user interaction
- New files and splits are handled correctly
- Docs tooling nav is updated when applicable
- `oat_docs_updated` state is set correctly in all paths
- Skill works on both active and completed/archived projects
- Skill does not modify source code or project phase state (except `oat_docs_updated`)
