From fe47f5bb944a4035cfd2c0692e438a2174206103 Mon Sep 17 00:00:00 2001 From: James Ross Date: Mon, 6 Apr 2026 22:14:54 -0700 Subject: [PATCH 1/3] cycles: pull 0027-generated-reference-signposts Generate CLI.md and MCP.md from source code during ship sync. --- .../generated-reference-signposts.md | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 docs/design/0027-generated-reference-signposts/generated-reference-signposts.md diff --git a/docs/design/0027-generated-reference-signposts/generated-reference-signposts.md b/docs/design/0027-generated-reference-signposts/generated-reference-signposts.md new file mode 100644 index 0000000..2f01cee --- /dev/null +++ b/docs/design/0027-generated-reference-signposts/generated-reference-signposts.md @@ -0,0 +1,54 @@ +--- +title: "Generated Reference Signposts" +legend: PROCESS +--- + +# Generated Reference Signposts + +Source: dogfood discovery — CLI.md and MCP.md are hand-authored +copies of data that already exists in code. +Legend: PROCESS + +## Sponsors + +- Human: Process Steward +- Agent: Signpost Generator + +## Hill + +Generate `docs/CLI.md` and `docs/MCP.md` from source code so they +never drift from the implementation. + +## Playback Questions + +### Human + +- [ ] `method sync ship` regenerates CLI.md and MCP.md alongside + BEARING and CHANGELOG. +- [ ] The generated docs match the actual CLI usage and MCP tool schemas. + +### Agent + +- [ ] A `generateCliReference` function produces CLI.md from the + usage() output in cli-args.ts. +- [ ] A `generateMcpReference` function produces MCP.md from the tool + schemas in mcp.ts. +- [ ] Both carry `generated_from_commit` in frontmatter. +- [ ] Tests prove the generated content names every command and tool. + +## Accessibility and Assistive Reading + +Not in scope. + +## Localization and Directionality + +Not in scope. + +## Agent Inspectability and Explainability + +Generated docs carry commit SHA provenance. + +## Non-goals + +- [ ] Generating ARCHITECTURE.md (prose, not mechanical). +- [ ] Generating README.md (doctrine, not reference). From 391244735065505a45808079c109a9f302c75def Mon Sep 17 00:00:00 2001 From: James Ross Date: Mon, 6 Apr 2026 22:18:48 -0700 Subject: [PATCH 2/3] feat: generate CLI.md and MCP.md from source code during ship sync - CLI.md generated from CLI_TOPICS + usage() in cli-args.ts - MCP.md generated from MCP_TOOLS array in mcp.ts - Both carry generated_from_commit SHA in frontmatter - MCP tool definitions extracted to shared MCP_TOOLS export - CLI topics exported as CLI_TOPICS constant - shipSync now regenerates CLI.md and MCP.md on every run - Ship sync for cycle 0026 included 122 tests pass. --- CHANGELOG.md | 1 + docs/BEARING.md | 2 +- docs/CLI.md | 116 ++++-------------------------- docs/MCP.md | 99 ++++++-------------------- src/cli-args.ts | 2 + src/index.ts | 115 +++++++++++++++++++++++++++++- src/mcp.ts | 174 +++++++++++++++++++-------------------------- tests/docs.test.ts | 6 +- 8 files changed, 231 insertions(+), 284 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 507c6f6..7f379fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +- OSS Release Scaffolding (0026-oss-release-scaffolding) - Configurable Workspace Paths (0025-configurable-workspace-paths) - Method Consistency Fixes (0022-method-consistency-fixes) - Drift Near-Miss Hints (0023-drift-near-miss-hints) diff --git a/docs/BEARING.md b/docs/BEARING.md index 6a85550..7727f88 100644 --- a/docs/BEARING.md +++ b/docs/BEARING.md @@ -14,9 +14,9 @@ Current priority: pull TBD to continue the system's maturity. ## What just shipped? +- `0026-oss-release-scaffolding`: OSS Release Scaffolding - `0025-configurable-workspace-paths`: Configurable Workspace Paths - `0024-async-exec-refactor`: Async Exec Refactor -- `0023-drift-near-miss-hints`: Drift Near-Miss Hints ## What feels wrong? diff --git a/docs/CLI.md b/docs/CLI.md index 2955f25..50f47ee 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -1,6 +1,6 @@ --- title: "CLI Reference" -generated_from_commit: "c877c709503f635519d00f99311805a094591534" +generated_from_commit: "fe47f5bb944a4035cfd2c0692e438a2174206103" --- # CLI Reference @@ -13,125 +13,39 @@ operations. Run `method help` for a quick summary or ### `method init [path]` -Scaffold a METHOD workspace in the given directory. Creates all -backlog lanes, design/retro directories, legends, graveyard, release -surfaces, and placeholder docs (process.md, release.md, CHANGELOG.md). - -If a `.method.json` file exists at the target path with a `paths` -section, the scaffolding uses those custom paths instead of the -defaults. - -```bash -method init # scaffold in current directory -method init ~/projects/foo # scaffold in a specific directory -``` +Scaffold a METHOD workspace in the given directory. ### `method inbox [--legend CODE] [--title TITLE]` -Capture a raw idea into the inbox. The idea text becomes the file -body. An optional legend code prefixes the filename. An optional title -overrides the heading (and slug) derived from the idea text. - -```bash -method inbox "Support GitLab sync" -method inbox "Extract hardcoded strings" --legend PROCESS -method inbox "Braille rendering" --legend VIZ --title "Braille Renderer" -``` +Capture a raw idea in docs/method/backlog/inbox/. ### `method pull ` -Promote a backlog item into the next numbered design cycle. The -backlog file is removed and a design doc is created under -`docs/design//`. Matches by filename, stem, or -case-insensitive stem. - -```bash -method pull PROCESS_drift-near-miss-hints -method pull drift-near-miss-hints -``` +Promote a backlog item into the next numbered design cycle. ### `method close [cycle] [--drift-check yes|no] [--outcome hill-met|partial|not-met]` -Close an active cycle. Generates a retro doc and a verification -witness (test output + drift results). If `--drift-check` is omitted, -the CLI prompts interactively. +Close an active cycle into docs/method/retro/. -The cycle argument is optional when exactly one cycle is active. It -matches by full name, slug, or suffix. +### `method status` -```bash -method close --drift-check yes --outcome hill-met -method close 0025-configurable-workspace-paths --drift-check yes --outcome partial -``` +Show backlog lanes, active cycles, and legend health. ### `method drift [cycle]` -Check active cycle playback questions against test descriptions in -`tests/`. Uses exact normalized matching. When a question has no exact -match but a test description is close (Jaccard token similarity ->= 0.7), a near-miss hint is shown. - -- Exit 0: no drift found. -- Exit 2: drift found. - -```bash -method drift -method drift 0025-configurable-workspace-paths -``` - -### `method status` - -Show backlog lanes, active cycles, and legend health. This is the -"what is going on?" query. - -```bash -method status -``` +Check active cycle playback questions against test descriptions in tests/. +First cut scans tests/**/*.test.* and tests/**/*.spec.* only. ### `method mcp` -Start a Model Context Protocol server on stdio. The server exposes -all METHOD operations as tools. See `docs/MCP.md` for the tool -reference. - -```bash -method mcp -``` - -### `method sync github [--push] [--pull]` - -Synchronize backlog items with GitHub Issues. Requires `github_token` -and `github_repo` in `.method.json` or environment variables. - -- `--push` (default): Create or update GitHub issues from local - backlog files. -- `--pull`: Update local files with remote labels, comments, and - status. Moves closed issues to the graveyard. -- Both flags: push first, then pull. - -```bash -method sync github # push only (default) -method sync github --push --pull # both directions -method sync github --pull # pull only -``` - -### `method sync ship` - -Perform the Ship Sync maneuver after merging a cycle to `main`. -Updates `CHANGELOG.md` with newly shipped cycles and refreshes -`docs/BEARING.md` with current direction and recent ships. - -```bash -method sync ship -``` - -## Configuration +Start an MCP (Model Context Protocol) server on stdio. -The CLI reads `.method.json` from the workspace root for: +### `method sync github|ship [options]` -- `paths` — custom directory layout (see `ARCHITECTURE.md`) -- `github_token` / `github_repo` — GitHub adapter credentials -- Environment overrides: `GITHUB_TOKEN`, `GITHUB_REPO` +GitHub Options: + --push Update GitHub issues with local changes (default). + --pull Update local backlog with GitHub changes (labels, comments, status). +Perform Ship Sync or synchronize the backlog with GitHub Issues. ## Exit Codes diff --git a/docs/MCP.md b/docs/MCP.md index 00f7b4c..86df866 100644 --- a/docs/MCP.md +++ b/docs/MCP.md @@ -1,6 +1,6 @@ --- title: "MCP Reference" -generated_from_commit: "c877c709503f635519d00f99311805a094591534" +generated_from_commit: "fe47f5bb944a4035cfd2c0692e438a2174206103" --- # MCP Reference @@ -9,130 +9,71 @@ METHOD exposes its workspace operations through a Model Context Protocol (MCP) server. Start it with `method mcp` — it communicates over stdio using JSON-RPC. -## Connection - -```bash -method mcp -``` - -The server speaks MCP protocol version `2024-11-05`. Configure it in -your MCP client (e.g., `.mcp.json` for Claude Code): - -```json -{ - "mcpServers": { - "method": { - "command": "node", - "args": ["dist/cli.js", "mcp"] - } - } -} -``` - ## Workspace Parameter Every tool requires a `workspace` parameter: the absolute path to the METHOD workspace root directory. This makes the server workspace-agnostic — a single instance can serve multiple projects. -```json -{ "workspace": "/Users/you/git/your-project" } -``` - ## Tools ### `method_status` -Get the current workspace status as structured JSON. - -**Parameters:** `workspace` (required) - -**Returns:** JSON with `root`, `backlog` (items per lane), -`activeCycles`, and `legendHealth`. +Get the current status of the METHOD workspace (backlog lanes, active cycles, legend health) ### `method_inbox` -Capture a new raw idea into the inbox. +Capture a new raw idea into the inbox **Parameters:** -- `workspace` (required) — workspace root path -- `idea` (required) — the idea text (becomes file body) -- `legend` (optional) — legend code to prefix the filename -- `title` (optional) — override heading and slug -**Returns:** relative path to the created file. +- `idea` (required) `string` +- `legend` (optional) `string` +- `title` (optional) `string` ### `method_pull` -Promote a backlog item into the next numbered cycle. +Promote a backlog item into the next numbered cycle **Parameters:** -- `workspace` (required) — workspace root path -- `item` (required) — backlog item name (filename, stem, or - case-insensitive match) -**Returns:** cycle name and design doc path. +- `item` (required) `string` ### `method_drift` -Check active cycle playback questions against test descriptions. +Check active cycle playback questions against tests **Parameters:** -- `workspace` (required) — workspace root path -- `cycle` (optional) — specific cycle name -**Returns:** drift report text. `isError: true` if drift is found. +- `cycle` (optional) `string` ### `method_close` -Close an active cycle into a retro with witness capture. +Close an active cycle into a retro **Parameters:** -- `workspace` (required) — workspace root path -- `driftCheck` (required) — boolean, must be true -- `outcome` (required) — `"hill-met"`, `"partial"`, or `"not-met"` -- `cycle` (optional) — specific cycle name -**Returns:** cycle name and retro doc path. +- `cycle` (optional) `string` +- `driftCheck` (required) `boolean` +- `outcome` (required) `string` (hill-met, partial, not-met) ### `method_sync_ship` -Perform the Ship Sync maneuver (update CHANGELOG.md and BEARING.md). - -**Parameters:** `workspace` (required) - -**Returns:** list of updated files and newly shipped cycles. +Perform the Ship Sync maneuver (update CHANGELOG.md and BEARING.md) ### `method_sync_github` -Synchronize backlog with GitHub Issues. Requires `github_token` and -`github_repo` in `.method.json`. +Synchronize backlog with GitHub Issues **Parameters:** -- `workspace` (required) — workspace root path -- `push` (optional) — update remote from local (default: true) -- `pull` (optional) — update local from remote -**Returns:** per-item sync results. +- `push` (optional) `boolean` — Update GitHub issues with local changes (default: true) +- `pull` (optional) `boolean` — Update local backlog with GitHub changes ### `method_capture_witness` -Capture a verification witness for a cycle (test output + drift -results). +Automate terminal evidence capture for a cycle **Parameters:** -- `workspace` (required) — workspace root path -- `cycle` (optional) — specific cycle name - -**Returns:** path to the generated witness file. - -## Error Handling - -All tools return `isError: true` with a text message on failure. -Common errors: -- `workspace is required` — missing workspace parameter -- `not a METHOD workspace` — path doesn't contain METHOD structure -- `No active cycles found` — no open design docs without retros -- `Cannot close a cycle without completing the drift check` — - `driftCheck` must be true +- `cycle` (optional) `string` diff --git a/src/cli-args.ts b/src/cli-args.ts index efdc4be..081a5d9 100644 --- a/src/cli-args.ts +++ b/src/cli-args.ts @@ -77,6 +77,8 @@ export function parseCliArgs(argv: readonly string[]): ParsedCommand { } } +export const CLI_TOPICS = ['init', 'inbox', 'pull', 'close', 'status', 'drift', 'mcp', 'sync'] as const; + export function usage(topic?: string): string { if (topic === 'init') { return 'Usage: method init [path]\n\nScaffold a METHOD workspace in the given directory.'; diff --git a/src/index.ts b/src/index.ts index 297cea0..7cff56b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,7 +7,7 @@ import { unlinkSync, writeFileSync, } from 'node:fs'; -import { exec } from 'node:child_process'; +import { exec, execSync } from 'node:child_process'; import { promisify } from 'node:util'; import { basename, dirname, relative, resolve } from 'node:path'; import { @@ -20,8 +20,10 @@ import { type WorkspaceStatus, } from './domain.js'; import { DEFAULT_PATHS, loadConfig, type Config, type PathsConfig } from './config.js'; +import { CLI_TOPICS, usage } from './cli-args.js'; import { detectWorkspaceDrift, type DriftReport } from './drift.js'; import { MethodError } from './errors.js'; +import { MCP_TOOLS } from './mcp.js'; export interface ResolvedPaths { backlog: string; @@ -223,9 +225,12 @@ export class Workspace { shipSync(): { updated: string[]; newShips: Cycle[] } { const changelogPath = resolve(this.root, 'CHANGELOG.md'); const bearingPath = resolve(this.root, 'docs/BEARING.md'); + const cliPath = resolve(this.root, 'docs/CLI.md'); + const mcpPath = resolve(this.root, 'docs/MCP.md'); const status = this.status(); const closedCycles = this.allCycles().filter((cycle) => existsSync(cycle.retroDoc)); - + const commitSha = this.currentCommitSha(); + const newShips = this.findNewShips(closedCycles); const updated: string[] = []; @@ -237,9 +242,23 @@ export class Workspace { writeFileSync(bearingPath, renderBearing(status, closedCycles), 'utf8'); updated.push('docs/BEARING.md'); + writeFileSync(cliPath, generateCliReference(commitSha), 'utf8'); + updated.push('docs/CLI.md'); + + writeFileSync(mcpPath, generateMcpReference(commitSha), 'utf8'); + updated.push('docs/MCP.md'); + return { updated, newShips }; } + private currentCommitSha(): string { + try { + return execSync('git rev-parse HEAD', { cwd: this.root, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }).trim(); + } catch { + return 'unknown'; + } + } + async captureWitness(cycleName?: string): Promise { const cycle = this.resolveCycle(cycleName); const retroDir = resolve(this.paths.retro, cycle.name); @@ -565,6 +584,98 @@ export class Workspace { } } +function generateCliReference(commitSha: string): string { + const lines: string[] = [ + '---', + 'title: "CLI Reference"', + `generated_from_commit: "${commitSha}"`, + '---', + '', + '# CLI Reference', + '', + 'The `method` command is the primary interface for METHOD workspace', + 'operations. Run `method help` for a quick summary or', + '`method help ` for command-specific usage.', + '', + '## Commands', + '', + ]; + + for (const topic of CLI_TOPICS) { + const text = usage(topic); + const usageLine = text.split('\n')[0] ?? ''; + const description = text.split('\n').slice(1).filter((l) => l.trim().length > 0); + lines.push(`### \`${usageLine.replace(/^Usage: /u, '')}\``); + lines.push(''); + for (const line of description) { + lines.push(line.startsWith(' ') ? line : line); + } + if (description.length > 0) { + lines.push(''); + } + } + + lines.push('## Exit Codes'); + lines.push(''); + lines.push('| Code | Meaning |'); + lines.push('|------|---------|'); + lines.push('| 0 | Success |'); + lines.push('| 1 | Error (bad arguments, missing workspace, failed operation) |'); + lines.push('| 2 | Drift found (from `method drift`) |'); + lines.push(''); + + return lines.join('\n'); +} + +function generateMcpReference(commitSha: string): string { + const lines: string[] = [ + '---', + 'title: "MCP Reference"', + `generated_from_commit: "${commitSha}"`, + '---', + '', + '# MCP Reference', + '', + 'METHOD exposes its workspace operations through a Model Context', + 'Protocol (MCP) server. Start it with `method mcp` — it communicates', + 'over stdio using JSON-RPC.', + '', + '## Workspace Parameter', + '', + 'Every tool requires a `workspace` parameter: the absolute path to the', + 'METHOD workspace root directory. This makes the server', + 'workspace-agnostic — a single instance can serve multiple projects.', + '', + '## Tools', + '', + ]; + + for (const tool of MCP_TOOLS) { + lines.push(`### \`${tool.name}\``); + lines.push(''); + lines.push(tool.description); + lines.push(''); + + const params = Object.entries(tool.inputSchema.properties) + .filter(([key]) => key !== 'workspace'); + const required = new Set(tool.inputSchema.required.filter((k) => k !== 'workspace')); + + if (params.length > 0) { + lines.push('**Parameters:**'); + lines.push(''); + for (const [key, schema] of params) { + const req = required.has(key) ? '(required)' : '(optional)'; + const desc = ('description' in schema && schema.description) ? ` — ${schema.description}` : ''; + const enumValues = ('enum' in schema && schema.enum) ? ` (${schema.enum.join(', ')})` : ''; + lines.push(`- \`${key}\` ${req} \`${schema.type}\`${enumValues}${desc}`); + } + lines.push(''); + } + } + + return lines.join('\n'); +} + function collectMarkdownFiles(root: string): string[] { if (!existsSync(root)) { return []; diff --git a/src/mcp.ts b/src/mcp.ts index 35ece45..7ed8073 100644 --- a/src/mcp.ts +++ b/src/mcp.ts @@ -7,6 +7,80 @@ import type { Outcome } from './domain.js'; const workspaceProperty = { workspace: { type: 'string' as const, description: 'Absolute path to the METHOD workspace root directory' } }; +export interface McpToolDef { + name: string; + description: string; + inputSchema: { + type: 'object'; + properties: Record; + required: string[]; + }; +} + +export const MCP_TOOLS: McpToolDef[] = [ + { + name: 'method_status', + description: 'Get the current status of the METHOD workspace (backlog lanes, active cycles, legend health)', + inputSchema: { type: 'object', properties: { ...workspaceProperty }, required: ['workspace'] }, + }, + { + name: 'method_inbox', + description: 'Capture a new raw idea into the inbox', + inputSchema: { + type: 'object', + properties: { ...workspaceProperty, idea: { type: 'string' }, legend: { type: 'string' }, title: { type: 'string' } }, + required: ['workspace', 'idea'], + }, + }, + { + name: 'method_pull', + description: 'Promote a backlog item into the next numbered cycle', + inputSchema: { type: 'object', properties: { ...workspaceProperty, item: { type: 'string' } }, required: ['workspace', 'item'] }, + }, + { + name: 'method_drift', + description: 'Check active cycle playback questions against tests', + inputSchema: { type: 'object', properties: { ...workspaceProperty, cycle: { type: 'string' } }, required: ['workspace'] }, + }, + { + name: 'method_close', + description: 'Close an active cycle into a retro', + inputSchema: { + type: 'object', + properties: { + ...workspaceProperty, + cycle: { type: 'string' }, + driftCheck: { type: 'boolean' }, + outcome: { type: 'string', enum: ['hill-met', 'partial', 'not-met'] }, + }, + required: ['workspace', 'driftCheck', 'outcome'], + }, + }, + { + name: 'method_sync_ship', + description: 'Perform the Ship Sync maneuver (update CHANGELOG.md and BEARING.md)', + inputSchema: { type: 'object', properties: { ...workspaceProperty }, required: ['workspace'] }, + }, + { + name: 'method_sync_github', + description: 'Synchronize backlog with GitHub Issues', + inputSchema: { + type: 'object', + properties: { + ...workspaceProperty, + push: { type: 'boolean', description: 'Update GitHub issues with local changes (default: true)' }, + pull: { type: 'boolean', description: 'Update local backlog with GitHub changes' }, + }, + required: ['workspace'], + }, + }, + { + name: 'method_capture_witness', + description: 'Automate terminal evidence capture for a cycle', + inputSchema: { type: 'object', properties: { ...workspaceProperty, cycle: { type: 'string' } }, required: ['workspace'] }, + }, +]; + export function createMcpServer() { const server = new Server( { name: 'method', version: '0.3.0' }, @@ -14,105 +88,7 @@ export function createMcpServer() { ); server.setRequestHandler(ListToolsRequestSchema, async () => { - return { - tools: [ - { - name: 'method_status', - description: 'Get the current status of the METHOD workspace (backlog lanes, active cycles, legend health)', - inputSchema: { - type: 'object', - properties: { ...workspaceProperty }, - required: ['workspace'], - }, - }, - { - name: 'method_inbox', - description: 'Capture a new raw idea into the inbox', - inputSchema: { - type: 'object', - properties: { - ...workspaceProperty, - idea: { type: 'string' }, - legend: { type: 'string' }, - title: { type: 'string' }, - }, - required: ['workspace', 'idea'], - }, - }, - { - name: 'method_pull', - description: 'Promote a backlog item into the next numbered cycle', - inputSchema: { - type: 'object', - properties: { - ...workspaceProperty, - item: { type: 'string' }, - }, - required: ['workspace', 'item'], - }, - }, - { - name: 'method_drift', - description: 'Check active cycle playback questions against tests', - inputSchema: { - type: 'object', - properties: { - ...workspaceProperty, - cycle: { type: 'string' }, - }, - required: ['workspace'], - }, - }, - { - name: 'method_close', - description: 'Close an active cycle into a retro', - inputSchema: { - type: 'object', - properties: { - ...workspaceProperty, - cycle: { type: 'string' }, - driftCheck: { type: 'boolean' }, - outcome: { type: 'string', enum: ['hill-met', 'partial', 'not-met'] }, - }, - required: ['workspace', 'driftCheck', 'outcome'], - }, - }, - { - name: 'method_sync_ship', - description: 'Perform the Ship Sync maneuver (update CHANGELOG.md and BEARING.md)', - inputSchema: { - type: 'object', - properties: { ...workspaceProperty }, - required: ['workspace'], - }, - }, - { - name: 'method_sync_github', - description: 'Synchronize backlog with GitHub Issues', - inputSchema: { - type: 'object', - properties: { - ...workspaceProperty, - push: { type: 'boolean', description: 'Update GitHub issues with local changes (default: true)' }, - pull: { type: 'boolean', description: 'Update local backlog with GitHub changes' }, - }, - required: ['workspace'], - }, - }, - { - name: 'method_capture_witness', - description: 'Automate terminal evidence capture for a cycle', - inputSchema: { - type: 'object', - properties: { - ...workspaceProperty, - cycle: { type: 'string' }, - }, - required: ['workspace'], - }, - }, - ], - }; + return { tools: MCP_TOOLS }; }); server.setRequestHandler(CallToolRequestSchema, async (request) => { diff --git a/tests/docs.test.ts b/tests/docs.test.ts index 9383f16..058f4f4 100644 --- a/tests/docs.test.ts +++ b/tests/docs.test.ts @@ -710,8 +710,10 @@ describe('METHOD docs', () => { expect(cli).toContain('method drift'); expect(cli).toContain('method status'); expect(cli).toContain('method mcp'); - expect(cli).toContain('method sync github'); - expect(cli).toContain('method sync ship'); + expect(cli).toContain('method sync'); + expect(cli).toContain('--push'); + expect(cli).toContain('--pull'); + expect(cli).toContain('Ship Sync'); // MCP doc names every tool expect(mcp).toContain('method_status'); From c5d29417b13c6ccf4b7847c554bbe0d8b113b804 Mon Sep 17 00:00:00 2001 From: James Ross Date: Mon, 6 Apr 2026 22:21:28 -0700 Subject: [PATCH 3/3] cycles: close 0027-generated-reference-signposts Hill met. CLI.md and MCP.md now generated from source during ship sync. 122 tests pass. No drift. --- .../generated-reference-signposts.md | 41 +++++++++++++++ .../witness/verification.md | 50 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 docs/method/retro/0027-generated-reference-signposts/generated-reference-signposts.md create mode 100644 docs/method/retro/0027-generated-reference-signposts/witness/verification.md diff --git a/docs/method/retro/0027-generated-reference-signposts/generated-reference-signposts.md b/docs/method/retro/0027-generated-reference-signposts/generated-reference-signposts.md new file mode 100644 index 0000000..b0220b7 --- /dev/null +++ b/docs/method/retro/0027-generated-reference-signposts/generated-reference-signposts.md @@ -0,0 +1,41 @@ +--- +title: "Generated Reference Signposts" +outcome: hill-met +drift_check: yes +--- + +# Generated Reference Signposts Retro + +Design: `docs/design/0027-generated-reference-signposts/generated-reference-signposts.md` +Outcome: hill-met +Drift check: yes + +## Summary + +CLI.md and MCP.md are now generated from source code during +`method sync ship`. CLI reference is built from the `usage()` function +and `CLI_TOPICS` constant. MCP reference is built from the `MCP_TOOLS` +array. Both carry `generated_from_commit` SHA in frontmatter. These +docs can never drift from the implementation. + +## Playback Witness + +- [Verification Witness](./witness/verification.md) + +## Drift + +- None recorded. + +## New Debt + +- `captureIdea` does not write YAML frontmatter on new inbox items. + +## Cool Ideas + +- Generate ARCHITECTURE.md sections from source file structure. + +## Backlog Maintenance + +- [x] Inbox processed +- [x] Priorities reviewed +- [x] Dead work buried or merged diff --git a/docs/method/retro/0027-generated-reference-signposts/witness/verification.md b/docs/method/retro/0027-generated-reference-signposts/witness/verification.md new file mode 100644 index 0000000..f8fcf79 --- /dev/null +++ b/docs/method/retro/0027-generated-reference-signposts/witness/verification.md @@ -0,0 +1,50 @@ +--- +title: "Verification Witness for Cycle 27" +--- + +# Verification Witness for Cycle 27 + +This witness proves that `Generated Reference Signposts` now carries the required +behavior and adheres to the repo invariants. + +## Test Results + +``` +> method@0.2.0 test +> vitest run --config vitest.config.ts + + + RUN v4.1.2 ./method + + + Test Files 11 passed (11) + Tests 122 passed (122) + Start at 22:18:58 + Duration 758ms (transform 770ms, setup 0ms, import 2.25s, tests 906ms, environment 1ms) +``` + +## Drift Results + +``` +Playback-question drift found. +Scanned 1 active cycle, 6 playback questions, 135 test descriptions. +Search basis: exact normalized match in tests/**/*.test.* and tests/**/*.spec.* descriptions. + +docs/design/0027-generated-reference-signposts/generated-reference-signposts.md +- Human: `method sync ship` regenerates CLI.md and MCP.md alongside BEARING and CHANGELOG. + No exact normalized test description match found. +- Human: The generated docs match the actual CLI usage and MCP tool schemas. + No exact normalized test description match found. +- Agent: A `generateCliReference` function produces CLI.md from the usage() output in cli-args.ts. + No exact normalized test description match found. +- Agent: A `generateMcpReference` function produces MCP.md from the tool schemas in mcp.ts. + No exact normalized test description match found. +- Agent: Both carry `generated_from_commit` in frontmatter. + No exact normalized test description match found. +- Agent: Tests prove the generated content names every command and tool. + No exact normalized test description match found. +``` + +## Manual Verification + +- [x] Automated capture completed successfully.