# Write Document

> Use whenever a delivery run needs a Knowledge Object created from its template or an existing one updated to reflect changed behavior: filing a business rule, requirement, ADR, user story, or any other graph-node fact into the knowledge graph, or writing/updating a non-graph prose document (an ExecPlan, a query/roadmap/test-strategy document) under the run workspace. This is the promote_to_product_knowledge action of the planning stretch, the documentation_update action of the implementation stretch, and the ADR-drafting half of technical_design's stop condition — one Agent-tool dispatch each, parameterized by doctype and mode, distinct from the later review-evidence documentation_evidence_review pass that judges this work, not produces it.

- Skill: `bhangeef16/write-document` (Agent Skill)
- Install (CLI): `npx skillmds@latest add bhangeef16/write-document`
- Raw SKILL.md: https://api.skillmd.com/api/skills/bhangeef16/write-document/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Product & Planning
- Author: BhangeeF16 (https://skillmd.com/u/bhangeef16)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/bhangeef16/write-document

---


# Write Document

Produce or update exactly one properly-shaped Knowledge Object. Every `doctype` is either graph-mapped (one of the fifteen node types in [Graph Node Schema](../../templates/graph-schema.md)) or non-graph (stays a plain prose file). Which one it is decides how this skill writes it — see below — but both apply the same formatting law from `documentation-standards` for whichever fields/sections remain.

## Dispatch

One synchronous `Agent`-tool call. `subagent_type` is whatever role the dispatching action entry names (`business-analyst` for `promote_to_product_knowledge`, `documentation-steward` for `documentation_update`, `solution-architect` for the ADR half of `technical_design`) — this skill defines the contract, not the persona.

## Graph-mapped doctypes: route through `kaizen graph new`/`update`

For these `doctype` values, never hand-write the file or its front matter directly — call the CLI, which allocates the id, serializes front matter, and writes the file:

| `doctype` | node type | CLI verb |
| --- | --- | --- |
| `business-rule` | `BR` | `kaizen graph new business-rule` |
| `requirement` | `FR` | `kaizen graph new requirement` |
| `nfr` | `NFR` | `kaizen graph new nfr` |
| `adr` | `ADR` | `kaizen graph new adr` |
| `user-story` | `US` | `kaizen graph new user-story` |
| `question` | `QST` | `kaizen graph new question` |
| `acceptance-criteria` | `AC` | `kaizen graph new acceptance-criteria` |
| `user-flow` | `FLOW` | `kaizen graph new user-flow` |
| `api` | `API` | `kaizen graph new api` |
| `event` | `EVT` | `kaizen graph new event` |
| `command` | `CMD` | `kaizen graph new command` |
| `entity` | `ENT` | `kaizen graph new entity` |
| `ui-component` | `COMP` | `kaizen graph new ui-component` |
| `ui-page` | `PAGE` | `kaizen graph new ui-page` |
| `integration` | `INT` | `kaizen graph new integration` |

- `mode: create` — resolve the target `knowledge-graph` path from `.kaizen/workspace.map.yaml` (per `init-workspace`), then run `python3 "${CLAUDE_PLUGIN_ROOT}/bin/kaizen.py" graph new <doctype> --title "..." --domain <domain> --field statement="..." [--related ID...]` (field names per that node type's own template in `templates/`). The CLI returns the allocated id and file path — do not invent either yourself.
- `mode: update` — run `kaizen.py graph update <id> --field k=v...` (or `--status S`) against the existing node id; never edit a node file's front matter by hand.
- Resolve the destination node's own body content from the matching template in `templates/` (e.g. `business-rule-template.md` for `business-rule`) for what fields/sections that type expects — the CLI writes the skeleton, this skill fills the field values it's given.
- `kaizen.py graph new`/`update`/`link` already reject any value that looks like a run reference (per the one-way reference guard in `kaizen_graph.py`) — if a call is rejected for that reason, that is a signal the input was wrong, not a tooling failure to route around.
- After a successful `create` or `update`, if this dispatch is running inside a run (not a standalone skill invocation), call `kaizen.py run link-nodes <run-id> --created ID...` or `--updated ID...` so the run's own `discovery/manifest.yaml` records which node ids it touched.

## Non-graph doctypes: plain file write under the run workspace

These `doctype` values are not graph nodes and keep the older Purpose / Scope / Canonical Content / Relationships / Validation shell, written as a normal file directly (no CLI involved):

- `implementation-plan` (`PLAN`) — an ExecPlan or implementation plan; write it under the current run's own `planning/` folder (e.g. `.kaizen/runs/<run-id>/planning/execplan.md`), per `exec-plans-standard`.
- `query` (`QRY`) — a query/reporting document; write it under the run's relevant stage folder (typically `discovery/` or `design/`).
- `roadmap` (`RMAP`) — a hand-authored roadmap document. Note to the caller that most roadmap-shaped questions ("every open FR in domain X") are better served by `kaizen graph query --type FR --status Requirements` than a hand-maintained file that goes stale — only write one if genuinely asked for a durable roadmap artifact.
- `test-strategy` (`TEST`) — a test plan tied to this run's own implementation; write it under the run's `verification/` folder, never into the graph (acceptance criteria the plan validates against, if durable, are separate `AC` graph nodes it should link to by id, not restate).

`capability` and `feature` doctypes are retired — do not accept either. A `capability`-shaped grouping need is a plain `domain:` field on any graph node, not a document; a `feature`-shaped need is either a `user-story` node or a decomposition into the atomic `BR`/`FR`/`NFR` nodes it's made of.

## Required inputs

- Graph-mapped `mode: create` — the structured field values to pass as `--field k=v` (a resolved requirement-register row's content, or the decision content for an ADR) and, for an ADR specifically, whether the request reached this point via the `migrate` verb (adds a mandatory rollback plan to its body).
- Graph-mapped `mode: update` — the node id and the changed field values.
- Non-graph `mode: create`/`update` — the content to write, and the existing run workspace path it belongs under.

## Required outputs (all mandatory)

- Graph-mapped `mode: create` — the new node's id and file path (as returned by `kaizen.py graph new`), status `Requirements` for an ordinary promoted fact, or `Design` for a freshly drafted ADR — never `Approved`/`Accepted` straight out of this dispatch; for a promoted requirement-register row, the row marked promoted with a link to the new node id; a `run link-nodes` call recording the new id against the current run, when running inside a run.
- Graph-mapped `mode: update` — confirmation of the field(s) changed on the existing node id; a `run link-nodes --updated` call when running inside a run.
- Non-graph `mode: create`/`update` — the file written or updated at its run-workspace path, with real front matter (`id`, `title`, `type`, `status`, `owner`, `priority`, `tags`, `depends_on`, `related`, `last_updated`) per the older Documentation Standard field set.

## Rules

- If a fact's canonical destination (which graph node type, or which non-graph run-workspace folder) cannot be determined, stop and ask — never invent a new owner or duplicate the fact across two places.
- `mode: update` on a non-graph document: when the change moved or deleted a path, every active reference to it is repaired — not just noted — before this action reports pass.
- `mode: create` for an ADR: this dispatch produces only the working draft (`Design` status, body `## Status: Proposed`). Flipping it to `Approved`/`Accepted` happens only after the evidence-verification checkpoint pass that follows this dispatch approves it — never inside this same dispatch, and always via `kaizen.py graph update <id> --status Approved`, never a hand edit.
- Never invent a lifecycle status outside `documentation-standards`' Approved Lifecycle Statuses list (also the list `kaizen_graph.py` itself accepts for graph nodes).
- Never write a graph node's front matter or file content by hand — every graph-mapped write goes through the CLI, so id allocation, the index cache, and the one-way reference guard all stay correct.

## Result

Report each required output produced (with its id and/or location), the result (pass / pass_with_risks / blocked / failure), and blocking questions as an explicit list (empty list stated explicitly).

