diff --git a/.agents/.keep b/.agents/.keep new file mode 100644 index 0000000..e69de29 diff --git a/.agents/skills/docs-review/SKILL.md b/.agents/skills/docs-review/SKILL.md new file mode 100644 index 0000000..30e3b46 --- /dev/null +++ b/.agents/skills/docs-review/SKILL.md @@ -0,0 +1,49 @@ +--- +name: docs-review +description: Checks a module's README.md and docs/ folder against the convention in /docs/README.md. Use whenever those files are added or edited, anywhere in the repo. +user-invocable: true +effort: low +--- + +You review documentation against the convention defined in `/docs/README.md` at +the repo root. That file is the single source of truth for what each of its +document types must look like — every rule, template, and relationship it +defines. + +Do not rely on your own memory of what that convention says, and do not keep a +paraphrased checklist of it here in your own instructions — `/docs/README.md` +changes, and a copy here would drift out of sync exactly the way the actual docs +you're reviewing do. Every time you run, re-read `/docs/README.md` in full and +derive your checklist from it directly. + +## What to do + +1. Read `/docs/README.md` in full. +2. Read the feature/module you were asked to review: its `README.md` and its + `docs/` folder (or the illustrative set under `/docs` if none is given). +3. Check every file against every rule and every layout/template + `/docs/README.md` defines for its type — don't skip a section of that file + because it seems minor. +4. Follow every relative link you find and confirm the target actually exists at + that path and, where a link points at an identifier, that the identifier's + anchor actually exists in the target file. +5. If `/docs/README.md` disagrees with itself (e.g. prose text and its own + layout/template describing the same thing differently), report that as its + own finding — don't silently pick a side and validate against it. + +## What NOT to do + +- Don't flag the location of files under a root `/docs` folder if that location + is the illustrative `## Example` set referenced by `/docs/README.md` itself — + that's a documented, intentional exception. +- Don't propose changes to `/docs/README.md`'s own conventions. Your job is to + check conformance, not redesign the convention. If you think the convention + itself has a gap, say so as an observation, separate from conformance + findings. +- Don't touch files — this is a review, not an edit pass. + +## Output + +A short list of findings, each with: file path, line (if applicable), what's +wrong, and what `/docs/README.md` says it should be instead. If everything +checks out, say so plainly — don't invent findings to seem thorough. diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 9995114..f63ae35 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -2,6 +2,8 @@ name: Pull Request on: pull_request: + paths-ignore: + - **/*.md permissions: contents: read diff --git a/.gitignore b/.gitignore index efd1012..6506664 100644 --- a/.gitignore +++ b/.gitignore @@ -78,3 +78,7 @@ !/AGENTS.md !/BUILDING.md !/LICENSE + +!/.agents +!/.agents/** +!/.agents/**/* \ No newline at end of file diff --git a/BUILDING.md b/BUILDING.md index 98d3b3b..73263c8 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -67,14 +67,15 @@ which Docker can't build for. ## Markdown front-matter Every `.md` file requires frontmatter with `title`, `summary`, and `tags` — -makes docs easy to index for agents. Exception: `README.md`, which doesn't need -frontmatter. +makes docs easy to index for agents. Exception: the root `README.md`, which +doesn't need frontmatter. Module `README.md` files do need it — see +[Module README](./docs/README.md#readme-readmemd). ## Agents Don't commit AI agent config that's exclusive to a single agent (Claude-only, -Codex-only, etc.). Config meant to work across agents still doesn't belong in -the repo — it lives in the dev's own environment. +Codex-only, etc.) — it lives in the dev's own environment. Config meant to +work across agents may be committed. ## Code standards diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..835e109 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,279 @@ +--- +title: Specifications +summary: Conventions for documenting feature intent, requirements, and acceptance scenarios. +tags: [specification, requirements, acceptance, ears, documentation] +--- + +## Purpose + +This document defines how this repo records feature intent, behavioral +requirements, and acceptance scenarios. + +It defines the documentation protocol, not the behavior of a specific feature. + +### Example + +A minimal, illustrative application of this convention: + +- [Example intent](./example-intent.md) +- [Example area specification](./example/example.spec.md) +- [Example area acceptance](./example/example.acceptance.md) + +## Docs layout + +Documentation lives with the feature it describes. Never in root /docs + +```text +/ +└── docs/ + ├── -intent.md + └── / + ├── .spec.md + └── .acceptance.md +``` + +Documentation does not need to map one-to-one to source files, platform files, +or tests. Create a document when a domain behavior needs a durable contract. + +## Docs Identifiers + +Identifiers use an uppercase feature area, followed by a type and a four-digit +sequence number. + +```text +_-REQ-0001 +_-ACC-0001 +``` + +For example: + +- Feature: ENV-VAR +- Area: Declarations + +```text +ENV-VAR_DECLARATIONS-REQ-0001 +ENV-VAR_DECLARATIONS-ACC-0001 +``` + +## Docs graph + +Every document links to the documents adjacent to it, so the full set forms a +navigable graph instead of files nobody points into. This lets graph-based +retrieval (graph RAG) walk from any document to related context without a +full-text search. + +- A **Readme** links forward to its **Intent** and to each **Specification**. +- An **Intent** links back to its **Readme** and forward to every + **Specification** it introduces. +- A **Specification** links back to its **Intent** and forward to its matching + **Acceptance** scenarios. +- An **Acceptance** document links back to the **Specification** requirement it + verifies. + +No document is reachable only by knowing its file path. + +## Docs types + +### Readme (*/README.md) + +Every module/feature folder has a `README.md` that orients a reader before they +open its `docs/`. Unlike the root `README.md`, a module `README.md` requires +[markdown front-matter](../BUILDING.md#markdown-front-matter) + +**Layout**: + +```md +--- +title: +summary: +tags: [, , ...] +--- + + + +> **Note:** this document describes 's model, including concepts and +> sources planned for its evolution. It does not imply that all of these +> capabilities are already implemented. + +## Documentation + +- [Intent](./docs/-intent.md): purpose, boundaries, and evolution of + this module. +- [](./docs//.spec.md): requirements and acceptance + scenarios. +``` + +### Intent (*.intent.md) + +An intent explains why a feature exists, the problem it addresses, its +boundaries, and its non-goals. It is not normative. + +**Layout**: + +```md +--- +title: intent +summary: +tags: [, , ...] +--- + +## Problem + + + +## Intent + + + +## Boundaries + + + +## Documentation + +- [Readme](../README.md): module overview. +- [](.//.spec.md): Specification. +``` + +### Specification (*.spec.md) + +A specification defines normative, traceable behavioral requirements. Each +requirement has a stable identifier, a name, statuses, and links to its +acceptance scenarios. + +**Status:** + +Each requirement declares two independent statuses: + +- **Doc status:** `Draft`, `Accepted`, or `Superseded`. +- **Implementation status:** `Not implemented`, `Partially implemented`, + `Implemented` or `Unknown` + +**Language:** + +Specifications use EARS notation and the normative terms defined by RFC 2119 and +RFC 8174. + +- **SHALL** and **SHALL NOT** define mandatory behavior. +- **SHOULD** and **SHOULD NOT** define expected behavior that requires an + explicit justification to deviate from. +- **MAY** defines optional behavior. + +Use the EARS pattern that matches the behavior: + +```text +The software SHALL . + +WHEN , +THE SOFTWARE SHALL . + +IF , +THEN THE SOFTWARE SHALL . +``` + +**Layout:** + +```md +--- +title: - SPEC +summary: +tags: [, , specification, spec] +--- + +> [!IMPORTANT] +> Requirements in this specification use EARS notation. **SHALL** and **SHALL +> NOT** define mandatory behavior; **SHOULD** and **SHOULD NOT** define expected +> behavior that requires an explicit justification to deviate from; **MAY** +> defines optional behavior. +> +> These terms follow RFC 2119 and RFC 8174. + +## Requirements + +### _-REQ-0001 + +Name: + +**Links:** + +- [_-ACC-0001](./.acceptance.md#_-acc-0001) +- [Intent](../-intent.md) + +**Status**: + +- Doc status: Draft +- Implementation status: Not implemented + +**WHEN:** , + +**THE SOFTWARE SHALL:** . +``` + +### Acceptance (*.acceptance.md) + +An acceptance document defines observable scenarios derived from requirements. +Scenarios use embedded Gherkin and link back to the requirement they verify. + +Each acceptance scenario declares its own acceptance and verification status. +Implementation status belongs to the requirement, not to each scenario. + +A requirement may have multiple acceptance scenarios. An acceptance scenario +belongs to one primary requirement. + +**Status:** + +Each acceptance declares two independent statuses: + +- **Doc status:** `Draft`, `Accepted`, or `Superseded`. +- **Verification status:** `Not Meets`, `Partially Meets`, `Meets` or `Unknown` + +**Language:** + +Acceptance scenarios use Gherkin. A `Feature` groups scenarios for one area, a +`Rule` scopes scenarios to the requirement they verify, and a `Scenario` states +one observable behavior as `Given`/`When`/`Then` steps. + +```gherkin +Feature: + + Rule: + + Scenario: + Given + When + Then +``` + +**Layout:** + +````md +--- +title: - Acceptance +summary: +tags: [, , acceptance, gherkin] +--- + +## _-ACC-0001 + +Name: + +**Links:** + +- [_-REQ-0001](./.spec.md#_-req-0001) + +**Status**: + +- Doc status: Draft +- Verification status: Unknown + +```gherkin +Feature: _-FEAT-0001 — + + Rule: _-REQ-0001 — + + Scenario: _-ACC-0001 — + Given + When + Then +``` +```` diff --git a/docs/example-intent.md b/docs/example-intent.md new file mode 100644 index 0000000..68d8a26 --- /dev/null +++ b/docs/example-intent.md @@ -0,0 +1,26 @@ +--- +title: Example intent +summary: Illustrative intent statement used to demonstrate the specification format. +tags: [specification, example, intent] +--- + +## Problem + +Configuration read directly from process state is difficult to review, +reproduce, or audit. + +## Intent + +The feature must make process configuration explicit rather than inheriting +undeclared host state. + +## Boundaries + +This example does not define how configuration is stored, transmitted, or +loaded — only that unknown keys are rejected. + +## Documentation + +- [Readme](./README.md): module overview. +- [Example area specification](./example/example.spec.md): example area + requirements and acceptance scenarios. diff --git a/docs/example/example.acceptance.md b/docs/example/example.acceptance.md new file mode 100644 index 0000000..25ceac7 --- /dev/null +++ b/docs/example/example.acceptance.md @@ -0,0 +1,29 @@ +--- +title: Example area - Acceptance +summary: Illustrative acceptance scenario used to demonstrate the acceptance format. +tags: [example, acceptance, gherkin] +--- + +## EXAMPLE_AREA-ACC-0001 + +Name: Unknown configuration key is rejected + +**Links:** + +- [EXAMPLE_AREA-REQ-0001](./example.spec.md#example_area-req-0001) + +**Status**: + +- Doc status: Draft +- Verification status: Unknown + +```gherkin +Feature: EXAMPLE_AREA-FEAT-0001 — Explicit configuration + + Rule: EXAMPLE_AREA-REQ-0001 — Explicit configuration + + Scenario: EXAMPLE_AREA-ACC-0001 — Unknown configuration key is rejected + Given no declaration exists for "EXAMPLE_KEY" + When configuration provides a value for "EXAMPLE_KEY" + Then the software rejects the configuration +``` diff --git a/docs/example/example.spec.md b/docs/example/example.spec.md new file mode 100644 index 0000000..d343bfd --- /dev/null +++ b/docs/example/example.spec.md @@ -0,0 +1,33 @@ +--- +title: Example area - SPEC +summary: Illustrative specification used to demonstrate the requirement format. +tags: [example, specification, spec] +--- + +> [!IMPORTANT] +> Requirements in this specification use EARS notation. **SHALL** and **SHALL +> NOT** define mandatory behavior; **SHOULD** and **SHOULD NOT** define expected +> behavior that requires an explicit justification to deviate from; **MAY** +> defines optional behavior. +> +> These terms follow RFC 2119 and RFC 8174. + +## Requirements + +### EXAMPLE_AREA-REQ-0001 + +Name: Explicit configuration + +**Links:** + +- [EXAMPLE_AREA-ACC-0001](./example.acceptance.md#example_area-acc-0001) +- [Intent](../example-intent.md) + +**Status**: + +- Doc status: Draft +- Implementation status: Not implemented + +**WHEN:** Configuration provides an unknown key, + +**THE SOFTWARE SHALL:** reject the configuration.