Skip to main content

anchors

Requirements-driven development framework. Use when setting up product/engineering requirements documents, checking traceability between requirements and code, verifying document consistency, or working on code in a repo that contains ANCHORS.md files (load the skill to understand the requirements context before making changes).

Source facts

Repository
block/anchorsmd
Last source activity
April 6, 2026 at 18:34
Detected SKILL.md language
English
Stars
2
Forks
1

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
2 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
anchors
description
Requirements-driven development framework. Use when setting up product/engineering requirements documents, checking traceability between requirements and code, verifying document consistency, or working on code in a repo that contains ANCHORS.md files (load the skill to understand the requirements context before making changes).
# anchors A skill for managing ANCHORS requirements-driven development documents. ANCHORS keeps product requirements, engineering requirements, testing strategy, dependency constraints, and implementation in a consistent, traceable hierarchy. --- ## The ANCHORS Framework ### Documents A module's ANCHORS document set consists of up to four documents plus a marker file: | Document | Purpose | Requirement IDs | |----------|---------|-----------------| | **ANCHORS.md** | Module marker. YAML frontmatter with `prefix` field. | — | | **PRODUCT.md** | Product requirements — observable behavior, outcomes, and qualities. No implementation approach. Litmus test: could you verify this requirement without reading source code? Source of truth. | `P-*` | | **ENGINEERING.md** | Engineering architecture — rules, principles, and constraints that govern how the system is built. Organized by cross-cutting concern. Must not contradict PRODUCT.md. | `E-*` | | **TESTING.md** | Testing strategy — pyramid, coverage invariants, tooling. Defines how requirements are verified. | — | | **DEPENDENCIES.md** | External dependencies — what the environment must provide because the system cannot supply it. | `D-DEP-*` | All four documents are part of the framework. TESTING.md and DEPENDENCIES.md participate in the truth hierarchy and have defined disagreement rules. ### Modes ANCHORS operates in one of two modes: - **Embedded** (default): Docs live alongside the code they describe. Requirement IDs are tagged inline in source code and tests. Check searches the local codebase for traceability. This is the standard mode. - **Detached**: Docs live separately from the code they describe. The target codebase is never modified. Traceability uses `→` forward references in ENGINEERING.md pointing to code locations in the target codebase. Detached mode works whether the docs are in the same repo (in-repo detached) or in a completely separate repo (external detached). Mode is set explicitly: if `ANCHORS.md` frontmatter contains `mode: detached`, the module is detached. Otherwise it's embedded. **ANCHORS.md frontmatter** — embedded mode: ```yaml --- prefix: AUTH --- ``` **ANCHORS.md frontmatter** — detached mode (in-repo): ```yaml --- prefix: PENPAL mode: detached path: .. --- ``` **ANCHORS.md frontmatter** — detached mode (external repo): ```yaml --- prefix: AUTH mode: detached repo: github.com/org/auth-service ref: main path: src/auth --- ``` - `mode` — `detached` or omitted. When `detached`, the target code is never modified and ENGINEERING.md uses `→` forward references instead of inline code tags. - `repo` — target codebase (GitHub URL or local path). Only used in detached mode when the code is in a different repo. Omit for in-repo detached. - `ref` — branch, tag, or SHA to track (defaults to `main`). Only meaningful with `repo`. - `path` — subdirectory to scope research and traceability. **In-repo detached** (no `repo`): relative to the ANCHORS.md file, like embedded mode. **External detached** (with `repo`): relative to the target repo root. Defaults to `.` (in-repo) or `/` (external). ### Truth Hierarchy ``` PRODUCT.md (what to build — authoritative on behavior) ENGINEERING.md (how to build it — authoritative on architecture, must not contradict PRD) ↓ constrains DEPENDENCIES.md (external prerequisites — what the environment must provide) TESTING.md (testing strategy — covers both PRODUCT.md and ENGINEERING.md) ↓ executed as Tests (executable specification — truthier than implementation) ↓ validated against Implementation (must satisfy all of the above) ``` ### Disagreement Rules - Implementation vs tests → implementation is probably wrong - Tests vs PRD/Engineering → tests are wrong (fix the tests, or update the documents first if the requirement changed) - TESTING.md vs PRD/Engineering → TESTING.md is wrong (update the testing strategy to match the requirements) - ENGINEERING.md vs PRD → ENGINEERING.md is wrong (PRD is authoritative) - DEPENDENCIES.md vs ENGINEERING.md → check which is correct (ENGINEERING.md may include requirements for the system to manage something that DEPENDENCIES.md lists as external — resolve which is current) ### Rules 1. **PRODUCT.md is authoritative.** If there is a conflict between documents, PRODUCT.md wins. 2. **ENGINEERING.md must fully satisfy PRODUCT.md.** Every product requirement should have corresponding engineering requirements that cover it. 3. **All implementation must meet both PRD and Engineering requirements.** Do not implement against only one document. 4. **Keep documents consistent.** When changing a requirement, update PRODUCT.md first, then ENGINEERING.md to reflect it (and link back). 5. **Do not add requirements to ENGINEERING.md that contradict or extend PRODUCT.md without updating PRODUCT.md first.** The PRD drives ENGINEERING.md, not the other way around. 6. **Tests are truthier than implementation, but documents are truthier than tests.** If the implementation diverges from the tests, the implementation is assumed buggy. If the tests diverge from the PRD or ENGINEERING.md, the tests are wrong. Fix the code to match the tests; fix the tests to match the documents; update the documents first if the requirement has genuinely changed. 7. **Every P-\* and E-\* requirement must have test coverage.** See TESTING.md for coverage invariants. A requirement without a corresponding test is a coverage gap that must be addressed. ### Content Guidelines The litmus test: a product manager should read PRODUCT.md without needing to Google anything, and a staff engineer should read ENGINEERING.md and find architectural rules that constrain real decisions — not a rephrasing of the product requirements or a step-by-step implementation spec. **PRODUCT.md — describe what users see and do:** - Name the experience, not the mechanism. "Updates in real-time" not "updates via SSE." "Interactive diagrams" not "interactive SVGs." - Every requirement needs a visible verb — what a human sees or does. "The UI shows X", "Users can Y", "A modal appears with Z." If you can't describe an observable behavior, it belongs in ENGINEERING.md or is underspecified. - Specify concrete details when they ARE the product requirement. "Cmd+T opens a new tab, Cmd+W closes the current tab" — not "keyboard shortcuts for tab management." - Don't reference undefined terms. If a concept isn't self-evident from the user's perspective, define it or point to where it's defined. **ENGINEERING.md — define architectural rules and principles:** - Each entry states a cross-cutting rule, explains WHY it exists, and links to all product requirements it governs. - Organize by architectural concern (data integrity, trust boundaries, performance invariants, extensibility), not by feature area. - Rules should be durable — they survive refactors. Implementation details that change with each sprint belong in code comments, not here. - A good engineering rule constrains many decisions. A bad one describes one function. - Add WHY, don't restate WHAT. If an entry reads like a rephrasing of the P-* it links to, it's not adding value. ### Document Structure Each document follows a canonical structure. Setup generates documents matching this structure. Check validates documents against it — unrecognized sections are flagged as structural drift. This is the self-cleaning mechanism: when the skill spec changes (e.g., a section is removed or renamed), upgrading the skill updates the canonical structure, the next check flags the now-unrecognized section, and the next setup overwrite regenerates the document to match. **All documents** share: - YAML frontmatter with `scope` and `see-also` fields - A title heading: `# {ModuleName}: {Document Type}` **PRODUCT.md** — flexible structure: - `## Overview` *(optional)* — brief product context - `## {Functional Area}` — one per area, containing P-\* requirements - `## Open Questions` / `## Resolved Questions` *(optional)* Check validates content patterns (proper P-\* IDs, anchor format) rather than specific section names, since sections are project-specific. **ENGINEERING.md** — flexible structure: - `## {Architectural Concern}` — sections organized by cross-cutting concern, containing E-\* requirements with `←` backlinks - `## Open Questions` / `## Resolved Questions` *(optional)* Check validates content patterns (proper E-\* IDs, backlinks) rather than specific section names. **TESTING.md** — prescribed structure (H2 sections, in order): 1. `## Source of Truth Hierarchy` *(optional)* — testable components and their truth relationships 2. `## How We Test` — overview of the testing approach and what can/cannot be tested automatically 3. `## Coverage Invariants` — project-specific instantiation of the 6 universal coverage invariants 4. `## Pyramid Shape` — test pyramid visualization showing layer distribution 5. `## Layer {N}: {Name}` — one section per test layer, detailing what each layer covers 6. `## Test Infrastructure` — test runner, assertion helpers, fixtures, directory layout 7. `## Tooling` — tools table (tool → purpose) 8. `## Coverage Targets` — targets table (layer → target → rationale) 9. `## What We Deliberately Don't Test` — explicit exclusions with rationale Any H2 section not in this list is structural drift and should be flagged by check. **DEPENDENCIES.md** — prescribed structure: - `### D-DEP-{ID}: {Name}` — one entry per dependency, with `Used by`, `Where it runs`, `Why external` fields ### Requirement ID Conventions **PRODUCT.md** — `P-` prefix with section-scoped slugs: ```markdown - <a id="P-AUTH-LOGIN"></a>**P-AUTH-LOGIN**: Users can log in with email and password. ``` **ENGINEERING.md** — `E-` prefix with backlink to the product requirements it governs: ```markdown - <a id="E-AUTH-SESSION"></a>**E-AUTH-SESSION**: Sessions use signed JWTs with 24-hour expiry. ← [P-AUTH-LOGIN](PRODUCT.md#P-AUTH-LOGIN) ``` Every `E-*` requirement must have a `←` backlink. This is how the check tracks coverage. **ENGINEERING.md (detached mode)** — `E-` prefix with backlink and `→` forward references to code locations in the target repo: ```markdown - <a id="E-AUTH-SESSION"></a>**E-AUTH-SESSION**: Sessions use signed JWTs with 24-hour expiry. ← [P-AUTH-LOGIN](PRODUCT.md#P-AUTH-LOGIN) → `src/auth/session.go:NewSession`, `src/auth/middleware.go:ValidateToken` ``` The `→` line lists `file:symbol` pairs wrapped in backticks, comma-separated. File paths are relative to the resolved target directory (the `path` directory, however it was resolved — see Modes section). Forward references replace inline code tags — in detached mode, the target code is never modified. **DEPENDENCIES.md** — `D-DEP-` prefix: ```markdown ### D-DEP-POSTGRES: PostgreSQL - **Used by:** API server - **Where it runs:** All environments - **Why external:** Stateful service, cannot be bundled ``` ### Coverage Invariants TESTING.md defines the project-specific test strategy. These invariants apply universally: 1. **Every requirement has a test.** Every P-* and E-* must be covered by at least one test. 2. **Contract boundaries are tested from both sides.** Parsers (reading) and builders (writing) are both tested. 3. **Trust boundaries are tested end-to-end.** Human-approval vs. automatic actions each need an E2E test. 4. **Every public API surface has a test.** Happy path and error path. 5. **Recovery paths are tested.** At integration layer or above. 6. **Every interface has its production implementation verified.** Test doubles don't mask missing real implementations. ### Code Traceability Tag functions and tests with requirement IDs. Augment comments, never replace them. ```go // BuildStartCommand builds the argument list for starting the process. // E-CLI-START: construct CLI start invocation with config flags. func BuildStartCommand(req StartRequest) []string { ``` ```go // TestSessionExpiry verifies that expired sessions are rejected. // E-AUTH-SESSION: sessions expire after the configured TTL. func TestSessionExpiry(t *testing.T) { ``` Rules: - One tag per function, not per line - Keep existing descriptive comments — the tag is an addition - Natural prose is fine: `// Per E-AUTH-SESSION, tokens expire after 24 hours` - Skip self-explanatory code, boilerplate, and standard library calls - **Tag test functions too** — every test file that verifies a requirement must carry the relevant E-*/P-* ID ### Monorepo Support ANCHORS supports arbitrary module nesting. A directory is an ANCHORS module if it contains an `ANCHORS.md` file with a `prefix` frontmatter field: ```yaml --- prefix: PAY-CHECKOUT --- ``` Prefixes must be unique across the repo. Within a module, PRODUCT.md/ENGINEERING.md links are relative (backlinks in ENGINEERING.md point to PRODUCT.md). Cross-module references use relative paths: ```markdown ← [P-PAY-CHECKOUT-CART](../checkout/PRODUCT.md#P-PAY-CHECKOUT-CART) ``` Not every module needs all four documents. Pure infrastructure modules might have only ENGINEERING.md tracing to another module's PRODUCT.md. TESTING.md can be per-module or shared. --- ## Routing This skill is invoked as `/anchors` with optional arguments. **Parse the args to determine the mode:** | User types | Mode | |------------|------| | `/anchors` (no args) | **Interactive** — use `AskUserQuestion` to ask "Setup or check?" (see below) | | `/anchors setup` | **Setup** — determine target path (see below) | | `/anchors setup path/to/dir` | **Setup** — use the given path | | `/anchors check` | **Check** | | `/anchors embed` | **Embed** — convert detached module to embedded (see below) | | `/anchors embed path/to/dir` | **Embed** — convert the detached module at the given path | Any other args → tell the user the available modes (setup, check, embed). **Interactive mode prompt:** When invoked with no args, first check whether any `ANCHORS.md` files exist in the repo (glob for `**/ANCHORS.md` excluding `node_modules`, `vendor`, `.git`, build output). Then use `AskUserQuestion`: - Question: "What would you like to do?" - Header: "Mode" - If ANCHORS modules already exist, present **Check** first (recommended): - **Check** — "Check traceability and consistency across modules (Recommended)" - **Setup** — "Scaffold ANCHORS documents in a new directory" - **Embed** — "Convert a detached module to embedded mode" (only show if any module has `mode: detached`) - If no ANCHORS modules exist, present **Setup** first (recommended): - **Setup** — "Scaffold ANCHORS documents in a directory (Recommended)" - **Check** — "Check traceability and consistency across modules" --- ## Setup Mode Set up a complete ANCHORS document set for a project or module. Setup produces fully populated documents — real requirements, real engineering specs, a real testing strategy — not empty templates. A full setup (not "Skip existing") should produce a document set that passes an immediate check. The `anchors` CLI handles distribution (`install`, `upgrade`) and CI (`check` in pipelines). The skill handles all interactive work directly — no CLI dependency at runtime. ### Determine the target path 1. If a path was given as an argument, use it. 2. If no path was given, check whether the current working directory already has an `ANCHORS.md`. - **No** → use the current working directory. - **Yes** → use `AskUserQuestion` to ask for a path: - Question: "This directory already has ANCHORS.md. Where should the new module be set up?" - Header: "Path" - Options: suggest 2-3 likely subdirectories based on the repo structure (e.g., `src/`, `services/`, `packages/`). The user can always pick "Other" to type a custom path. ### Steps 1. Check if any ANCHORS documents already exist in the target directory (`ANCHORS.md`, `PRODUCT.md`, `ENGINEERING.md`, `TESTING.md`, `DEPENDENCIES.md`; also check for legacy `ERD.md`). If any exist, use `AskUserQuestion` to confirm: - Question: "These ANCHORS documents already exist: [list]. Overwrite them?" - Header: "Overwrite" - Options: **Skip existing** ("Only create missing documents"), **Overwrite all** ("Replace all documents with fresh content") 2. Use `AskUserQuestion` to ask the user for project details (both in a single call): - Question 1: "What is the project/module name?" — Header: "Name" — Options: offer the target directory name as the recommended default, plus 1-2 alternatives derived from parent directories or repo name. - Question 2: "What requirement ID prefix should be used?" — Header: "Prefix" — Options: offer an uppercase abbreviation of the name as the recommended default, plus 1-2 alternatives (e.g., shorter/longer forms). 3. **Determine the mode.** Check whether the target directory contains code (source files, not just docs). If it does, this is an **embedded** setup — skip to step 4. If the target directory has no code (it's a standalone docs repo or empty directory), use `AskUserQuestion`: - Question: "Does this describe an existing codebase?" - Header: "Mode" - Options: - **In-repo detached** ("Yes — code is elsewhere in this repo") - **External detached** ("Yes — code is in another repo")
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub