diff --git a/.agents/skills/prospec-knowledge-generate/SKILL.md b/.agents/skills/prospec-knowledge-generate/SKILL.md index 15561c0..1fb833e 100644 --- a/.agents/skills/prospec-knowledge-generate/SKILL.md +++ b/.agents/skills/prospec-knowledge-generate/SKILL.md @@ -128,11 +128,16 @@ If a module's README would exceed the ≤100 line / ≤1000 token budget even af > Description, and Depends On (via `relationships.depends_on`) — are curated in > `prospec/ai-knowledge/module-map.yaml`; `prospec/index.md`'s `prospec:auto` block is > **generated** from it. Curate these fields in `module-map.yaml`, not by hand-editing the index -> table — `/prospec-knowledge-update` regenerates the auto block from `module-map.yaml` (blanking any -> index-only curated cell). Fill the table below only for a first-pass bootstrap; the values belong in -> `module-map.yaml`. +> table. -Fill module table within `prospec:auto-start/end` markers using new format: +The `prospec:auto` block contains two auto-generated sections. Populate them within `prospec:auto-start/end` markers: + +1. **Conventions**: + - Scan the `prospec/ai-knowledge/` directory for `.md` files (excluding `_index.md`). + - List them under **Core Conventions (L1)** if they are built-in core files (e.g. `_conventions.md`) or defined in `.prospec.yaml`'s `additional_core_conventions`. + - List the rest under **Load-on-Demand Conventions (L2)**. + +2. **Modules**: Fill the module table using the new format: ``` | Module | Keywords | Aliases | Status | Description | Rationale | Depends On | diff --git a/.agents/skills/prospec-knowledge-update/SKILL.md b/.agents/skills/prospec-knowledge-update/SKILL.md index e7f7cdf..129c51b 100644 --- a/.agents/skills/prospec-knowledge-update/SKILL.md +++ b/.agents/skills/prospec-knowledge-update/SKILL.md @@ -147,10 +147,15 @@ NOT by hand-editing the index table (it gets regenerated). - Preserve each existing module's `category` (do NOT re-guess it); for an ADDED module, derive an ordered `category: [primary, …]` consistent with existing grouping and write it - Skip if module-map.yaml doesn't exist -#### 3d: prospec/index.md (generated from module-map) +#### 3d: prospec/index.md (generated from module-map and conventions) -The `prospec:auto` block is regenerated from `module-map.yaml` by `updateIndex` using the canonical -column format — you do not hand-fill curated cells: +The `prospec:auto` block contains two auto-generated sections: +1. **Conventions**: Core Conventions (L1) and Load-on-Demand Conventions (L2) lists. +2. **Modules**: The module table regenerated from `module-map.yaml` using the canonical column format. + +When updating the auto block manually, **you must preserve and update both sections**. +- **Conventions**: Scan the `prospec/ai-knowledge/` directory for `.md` files (excluding `_index.md`). List them under Core Conventions if they are built-in core files (e.g. `_conventions.md`) or defined in `.prospec.yaml`'s `additional_core_conventions`. Otherwise, list them under Load-on-Demand Conventions. +- **Modules**: Regenerate the table from `module-map.yaml` using the canonical columns. You do not hand-fill curated cells: ``` | Module | Keywords | Aliases | Status | Description | Rationale | Depends On | diff --git a/.agents/skills/prospec-upgrade/SKILL.md b/.agents/skills/prospec-upgrade/SKILL.md index 10f7dcd..96ddbe0 100644 --- a/.agents/skills/prospec-upgrade/SKILL.md +++ b/.agents/skills/prospec-upgrade/SKILL.md @@ -59,28 +59,30 @@ user to run `prospec init` first. touches an EXISTING one — updating a present doc's format, or enriching a freshly-created doc beyond its baseline, requires consent. Do that here: -1. **Locate the latest templates** shipped with the installed prospec version. **Source-repo +1. **Retrieve the latest templates** shipped with the installed prospec version. **Source-repo short-circuit first**: if the project's own `package.json` `name` equals the prospec package name - (`@benwu95/prospec`), the working directory IS the package root — use `.` and skip the resolution - below. This is the dogfooding case; `require.resolve('@benwu95/prospec/package.json')` fails here - because the package is absent from its own `node_modules` and the package has no `exports` field - to enable Node self-referencing. Otherwise resolve the package root (e.g. - `node -e "console.log(require.resolve('@benwu95/prospec/package.json'))"`, or check - `node_modules/@benwu95/prospec`, or a global install via `npm root -g`). If `require.resolve` - fails — a `pnpm link`/globally-linked install keeps the package outside the project's - `node_modules` — derive the root from the running CLI instead: follow `$(which prospec)` (a - shim/symlink to `/dist/cli/index.js`) back up to ``. All doc - templates are language-neutral `.hbs` files under `src/templates/` (the package ships and - loads them from `src/templates/`, not a root-level `templates/` — `tsc` does not copy `.hbs` into - `dist/`). If the templates cannot be located, say so and SKIP this step (do not guess the latest - format). + (`@benwu95/prospec`), the working directory IS the package root — read the templates directly from + `src/templates/` and skip the CLI call below (dogfooding case). Otherwise, retrieve the template + content directly by running the CLI command: + `prospec print-template ` (Bash). + For example, to get the template for `init/constitution.md.hbs`, run `prospec print-template init/constitution.md.hbs`. + If the template cannot be retrieved, say so and SKIP this step (do not guess the latest format). 2. **Take the scan scope from Step 1's `Docs inventory:` section** — every line names an init-created doc, its present/MISSING status, and its source template path. That list is the ONLY scan scope: do not keep, reconstruct, or fall back to a file list written into this skill. If the report has no `Docs inventory:` section, the installed CLI predates it (CLI/skill version mismatch) — STOP this step and tell the user to re-run `prospec upgrade` (which re-syncs this skill to match the CLI), then re-run `/prospec-upgrade`. -3. **Index enrichment / migration**: `prospec upgrade` back-fills `prospec/index.md` as a BASELINE — its module table is empty. Offer to populate that table from the current modules, and if `prospec/ai-knowledge/_index.md` exists (a project from before the hierarchical-index move), migrate its curated content into that baseline: preserve any user notes in the `` block, and **copy the curated `Modules` table rows verbatim** into the `prospec:auto` block — the Keywords / Aliases / Rationale / Depends On columns are human-curated and exist nowhere else. Do NOT run `prospec knowledge update` to rebuild the table: it fills only Module / Status / Description from `module-map.yaml` and blanks every curated column to `—`. Delete the old `prospec/ai-knowledge/_index.md` after a successful migration. +3. **Index enrichment / migration**: `prospec upgrade` back-fills `prospec/index.md` as a + BASELINE — its module table is empty. Offer to populate that table from the current modules, + and if `prospec/ai-knowledge/_index.md` exists (a project from before the hierarchical-index + move), migrate its curated content into that baseline: preserve any user notes in the + `` block, and **copy both the Core/Demand Conventions lists and the + curated `Modules` table rows verbatim** into the `prospec:auto` block — the Keywords / Aliases / + Rationale / Depends On columns are human-curated and exist nowhere else. Do NOT run + `prospec knowledge update` to rebuild the table: it fills only Module / Status / Description from + `module-map.yaml` and blanks every curated column to `—`. Delete the old + `prospec/ai-knowledge/_index.md` after a successful migration. 4. **Back-fill safety net** — `prospec upgrade` already created every doc it could (the report's `created …` line), so the inventory should show them present. For any doc the inventory **still marks MISSING** (its back-fill failed), offer to create it by rendering its listed template. @@ -164,7 +166,7 @@ Emit one line: `Met N/M | Unmet: | Overall: PASS|WARN|FAIL | Next: Description, and Depends On (via `relationships.depends_on`) — are curated in > `prospec/ai-knowledge/module-map.yaml`; `prospec/index.md`'s `prospec:auto` block is > **generated** from it. Curate these fields in `module-map.yaml`, not by hand-editing the index -> table — `/prospec-knowledge-update` regenerates the auto block from `module-map.yaml` (blanking any -> index-only curated cell). Fill the table below only for a first-pass bootstrap; the values belong in -> `module-map.yaml`. +> table. -Fill module table within `prospec:auto-start/end` markers using new format: +The `prospec:auto` block contains two auto-generated sections. Populate them within `prospec:auto-start/end` markers: + +1. **Conventions**: + - Scan the `prospec/ai-knowledge/` directory for `.md` files (excluding `_index.md`). + - List them under **Core Conventions (L1)** if they are built-in core files (e.g. `_conventions.md`) or defined in `.prospec.yaml`'s `additional_core_conventions`. + - List the rest under **Load-on-Demand Conventions (L2)**. + +2. **Modules**: Fill the module table using the new format: ``` | Module | Keywords | Aliases | Status | Description | Rationale | Depends On | diff --git a/.claude/skills/prospec-knowledge-update/SKILL.md b/.claude/skills/prospec-knowledge-update/SKILL.md index e7f7cdf..129c51b 100644 --- a/.claude/skills/prospec-knowledge-update/SKILL.md +++ b/.claude/skills/prospec-knowledge-update/SKILL.md @@ -147,10 +147,15 @@ NOT by hand-editing the index table (it gets regenerated). - Preserve each existing module's `category` (do NOT re-guess it); for an ADDED module, derive an ordered `category: [primary, …]` consistent with existing grouping and write it - Skip if module-map.yaml doesn't exist -#### 3d: prospec/index.md (generated from module-map) +#### 3d: prospec/index.md (generated from module-map and conventions) -The `prospec:auto` block is regenerated from `module-map.yaml` by `updateIndex` using the canonical -column format — you do not hand-fill curated cells: +The `prospec:auto` block contains two auto-generated sections: +1. **Conventions**: Core Conventions (L1) and Load-on-Demand Conventions (L2) lists. +2. **Modules**: The module table regenerated from `module-map.yaml` using the canonical column format. + +When updating the auto block manually, **you must preserve and update both sections**. +- **Conventions**: Scan the `prospec/ai-knowledge/` directory for `.md` files (excluding `_index.md`). List them under Core Conventions if they are built-in core files (e.g. `_conventions.md`) or defined in `.prospec.yaml`'s `additional_core_conventions`. Otherwise, list them under Load-on-Demand Conventions. +- **Modules**: Regenerate the table from `module-map.yaml` using the canonical columns. You do not hand-fill curated cells: ``` | Module | Keywords | Aliases | Status | Description | Rationale | Depends On | diff --git a/.claude/skills/prospec-upgrade/SKILL.md b/.claude/skills/prospec-upgrade/SKILL.md index 10f7dcd..96ddbe0 100644 --- a/.claude/skills/prospec-upgrade/SKILL.md +++ b/.claude/skills/prospec-upgrade/SKILL.md @@ -59,28 +59,30 @@ user to run `prospec init` first. touches an EXISTING one — updating a present doc's format, or enriching a freshly-created doc beyond its baseline, requires consent. Do that here: -1. **Locate the latest templates** shipped with the installed prospec version. **Source-repo +1. **Retrieve the latest templates** shipped with the installed prospec version. **Source-repo short-circuit first**: if the project's own `package.json` `name` equals the prospec package name - (`@benwu95/prospec`), the working directory IS the package root — use `.` and skip the resolution - below. This is the dogfooding case; `require.resolve('@benwu95/prospec/package.json')` fails here - because the package is absent from its own `node_modules` and the package has no `exports` field - to enable Node self-referencing. Otherwise resolve the package root (e.g. - `node -e "console.log(require.resolve('@benwu95/prospec/package.json'))"`, or check - `node_modules/@benwu95/prospec`, or a global install via `npm root -g`). If `require.resolve` - fails — a `pnpm link`/globally-linked install keeps the package outside the project's - `node_modules` — derive the root from the running CLI instead: follow `$(which prospec)` (a - shim/symlink to `/dist/cli/index.js`) back up to ``. All doc - templates are language-neutral `.hbs` files under `src/templates/` (the package ships and - loads them from `src/templates/`, not a root-level `templates/` — `tsc` does not copy `.hbs` into - `dist/`). If the templates cannot be located, say so and SKIP this step (do not guess the latest - format). + (`@benwu95/prospec`), the working directory IS the package root — read the templates directly from + `src/templates/` and skip the CLI call below (dogfooding case). Otherwise, retrieve the template + content directly by running the CLI command: + `prospec print-template ` (Bash). + For example, to get the template for `init/constitution.md.hbs`, run `prospec print-template init/constitution.md.hbs`. + If the template cannot be retrieved, say so and SKIP this step (do not guess the latest format). 2. **Take the scan scope from Step 1's `Docs inventory:` section** — every line names an init-created doc, its present/MISSING status, and its source template path. That list is the ONLY scan scope: do not keep, reconstruct, or fall back to a file list written into this skill. If the report has no `Docs inventory:` section, the installed CLI predates it (CLI/skill version mismatch) — STOP this step and tell the user to re-run `prospec upgrade` (which re-syncs this skill to match the CLI), then re-run `/prospec-upgrade`. -3. **Index enrichment / migration**: `prospec upgrade` back-fills `prospec/index.md` as a BASELINE — its module table is empty. Offer to populate that table from the current modules, and if `prospec/ai-knowledge/_index.md` exists (a project from before the hierarchical-index move), migrate its curated content into that baseline: preserve any user notes in the `` block, and **copy the curated `Modules` table rows verbatim** into the `prospec:auto` block — the Keywords / Aliases / Rationale / Depends On columns are human-curated and exist nowhere else. Do NOT run `prospec knowledge update` to rebuild the table: it fills only Module / Status / Description from `module-map.yaml` and blanks every curated column to `—`. Delete the old `prospec/ai-knowledge/_index.md` after a successful migration. +3. **Index enrichment / migration**: `prospec upgrade` back-fills `prospec/index.md` as a + BASELINE — its module table is empty. Offer to populate that table from the current modules, + and if `prospec/ai-knowledge/_index.md` exists (a project from before the hierarchical-index + move), migrate its curated content into that baseline: preserve any user notes in the + `` block, and **copy both the Core/Demand Conventions lists and the + curated `Modules` table rows verbatim** into the `prospec:auto` block — the Keywords / Aliases / + Rationale / Depends On columns are human-curated and exist nowhere else. Do NOT run + `prospec knowledge update` to rebuild the table: it fills only Module / Status / Description from + `module-map.yaml` and blanks every curated column to `—`. Delete the old + `prospec/ai-knowledge/_index.md` after a successful migration. 4. **Back-fill safety net** — `prospec upgrade` already created every doc it could (the report's `created …` line), so the inventory should show them present. For any doc the inventory **still marks MISSING** (its back-fill failed), offer to create it by rendering its listed template. @@ -164,7 +166,7 @@ Emit one line: `Met N/M | Unmet: | Overall: PASS|WARN|FAIL | Next: ] [--dry-run] [--raw-scan-only]` | Scan project → generate raw-scan.md + curated skeletons (module-map.yaml / prospec/index.md / _conventions.md, only if absent). `--raw-scan-only` regenerates **only** raw-scan.md (deterministic, no LLM), leaving curated files untouched — run after code changes or before `/prospec-knowledge-generate` to refresh the structure snapshot | | `prospec agent sync [--cli ]` | Sync AI agent configs + generate Skills (reads `skill_triggers` from .prospec.yaml for native-language trigger words) | +| `prospec print-template ` | Print the raw content of a bundled template (Offline, Node.js-free template retrieval) | > **Agent config layout** — `agent sync` writes each detected agent's entry config + Skills: > - **Claude Code** → `CLAUDE.md` + `.claude/skills/` @@ -739,7 +740,7 @@ src/ ## Testing ```bash -# Run all tests (2092 tests) +# Run all tests (2096 tests) pnpm test # Watch mode @@ -752,11 +753,11 @@ pnpm run typecheck pnpm run lint ``` -**Test Coverage**: 2092 tests across 4 categories: -- Unit tests (types + lib + services + cli): 1364 tests +**Test Coverage**: 2096 tests across 4 categories: +- Unit tests (types + lib + services + cli): 1366 tests - Contract tests (CLI output + Skill format): 647 tests - Integration tests: 38 tests -- E2E tests: 43 tests +- E2E tests: 45 tests The suite includes a real `init` + `agent sync` generation contract (`tests/integration/skill-contract.test.ts`) asserting agent-specific reference paths, no dangling references, canonical convention docs, `base_dir`-relative spec paths, and `.agents` convergence. diff --git a/README.zh-TW.md b/README.zh-TW.md index 9a898a2..7d5160b 100644 --- a/README.zh-TW.md +++ b/README.zh-TW.md @@ -4,7 +4,7 @@ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](LICENSE) [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue?style=flat-square&logo=typescript)](https://www.typescriptlang.org/) -[![測試](https://img.shields.io/badge/測試-2092%20通過-success?style=flat-square)](tests/) +[![測試](https://img.shields.io/badge/測試-2096%20通過-success?style=flat-square)](tests/) [![Node](https://img.shields.io/badge/node-%3E%3D22.13-brightgreen?style=flat-square&logo=node.js)](https://nodejs.org/) [![pnpm](https://img.shields.io/badge/pnpm-%3E%3D11-orange?style=flat-square&logo=pnpm)](https://pnpm.io/) @@ -467,6 +467,7 @@ Prospec 生成 17 個 Skills —— 15 個涵蓋完整 SDD 生命週期,外加 | `prospec init [options]` | 初始化 Prospec 專案結構(`--language` 設定 AI 產出文件語言,預設英文) | | `prospec knowledge init [--depth ] [--dry-run] [--raw-scan-only]` | 掃描專案 → 生成 raw-scan.md + 精選骨架(module-map.yaml / prospec/index.md / _conventions.md,僅在缺檔時)。`--raw-scan-only` **僅**重新產生 raw-scan.md(deterministic、不使用 LLM),不碰 curated 檔 — 程式碼變動後或 `/prospec-knowledge-generate` 前執行以刷新結構快照 | | `prospec agent sync [--cli ]` | 同步 AI Agent 配置 + 生成 Skills(讀取 .prospec.yaml 的 `skill_triggers` 注入母語觸發詞) | +| `prospec print-template ` | 輸出內置樣板的原始內容(離線、免 Node.js 讀取樣板) | > **Agent 配置佈局** — `agent sync` 為每個偵測到的 agent 生成 entry 配置 + Skills: > - **Claude Code** → `CLAUDE.md` + `.claude/skills/` @@ -710,7 +711,7 @@ src/ ## 測試 ```bash -# 執行所有測試(2092 個測試) +# 執行所有測試(2096 個測試) pnpm test # Watch 模式 @@ -723,11 +724,11 @@ pnpm run typecheck pnpm run lint ``` -**測試覆蓋率**:2092 個測試橫跨 4 大類: -- Unit tests(types + lib + services + cli):1364 tests +**測試覆蓋率**:2096 個測試橫跨 4 大類: +- Unit tests(types + lib + services + cli):1366 tests - Contract tests(CLI 輸出 + Skill 格式):647 tests - Integration tests:38 tests -- E2E tests:43 tests +- E2E tests:45 tests 測試套件內含真實 `init` + `agent sync` 生成契約(`tests/integration/skill-contract.test.ts`):檢查 agent 專屬的 reference 路徑、無 dangling reference、canonical convention 文件、`base_dir` 相對的 spec 路徑,以及 antigravity/codex/copilot 收斂至 `.agents/skills` + `AGENTS.md`。 diff --git a/prospec/ai-knowledge/feature-map.yaml b/prospec/ai-knowledge/feature-map.yaml index ad549ae..5b229f2 100644 --- a/prospec/ai-knowledge/feature-map.yaml +++ b/prospec/ai-knowledge/feature-map.yaml @@ -79,12 +79,14 @@ features: - cli - lib - services + - templates - types req_prefixes: - CLI - LIB - TYPES - DOCS + - TEMPLATES status: active - feature: token-measurement modules: diff --git a/prospec/ai-knowledge/modules/cli/README.md b/prospec/ai-knowledge/modules/cli/README.md index 8401c8b..84b4273 100644 --- a/prospec/ai-knowledge/modules/cli/README.md +++ b/prospec/ai-knowledge/modules/cli/README.md @@ -8,9 +8,9 @@ | File | Purpose | |------|---------| -| `index.ts` | `createProgram()` registers all 12 commands + `preAction` config gate (resolves `.prospec.yaml` against `mcp serve --cwd`, else cwd); `main()` entry; `setup-color.js` first import; `.version()` from `types/version` | -| `commands/` | 12 `registerXxxCommand(program)` files, one per command (init, quickstart, upgrade, knowledge[+init], agent, change story/plan/tasks, measure, check, mcp): parse flags → call service → format | -| `formatters/` | 14 `formatXxxOutput(result, logLevel)` modules — stdout success, stderr errors; `error-output.ts` also has `handleError()` | +| `index.ts` | `createProgram()` registers all 13 commands + `preAction` config gate (resolves `.prospec.yaml` against `mcp serve --cwd`, else cwd); `main()` entry; `setup-color.js` first import; `.version()` from `types/version` | +| `commands/` | 13 `registerXxxCommand(program)` files, one per command (init, quickstart, upgrade, print-template, knowledge[+init], agent, change story/plan/tasks, measure, check, mcp): parse flags → call service → format | +| `formatters/` | 15 `formatXxxOutput(result, logLevel)` modules — stdout success, stderr errors; `error-output.ts` also has `handleError()` | | `formatters/sanitize.ts` | Shared `sanitizeTerminal()` — strips C0/C1/DEL; single source for check/measure/error output | | `log-level.ts` | `resolveLogLevel(opts)` — root-flag → LogLevel; imported by every command | | `parse-options.ts` | `parseDepth(value)` — shared `--depth` validator (positive int or throws) | @@ -18,8 +18,8 @@ ## Public API -- `createProgram()` — Commander program, all 12 commands; `main()` runs on load (NOT exported) -- `registerXxxCommand(program)` — 12 registrars; `formatXxxOutput(result, logLevel)` — 14 formatters; `handleError(err, verbose)` → stderr +- `createProgram()` — Commander program, all 13 commands; `main()` runs on load (NOT exported) +- `registerXxxCommand(program)` — 13 registrars; `formatXxxOutput(result, logLevel)` — 15 formatters; `handleError(err, verbose)` → stderr - `resolveLogLevel(opts)` / `parseDepth(value)` — shared cli helpers - `sanitizeTerminal(s)` — in `formatters/sanitize.ts`, re-exported by `check-output.ts` - `GlobalOptions` (type) — `{ verbose?, quiet? }` diff --git a/prospec/ai-knowledge/modules/lib/README.md b/prospec/ai-knowledge/modules/lib/README.md index 14ddd3d..da01b77 100644 --- a/prospec/ai-knowledge/modules/lib/README.md +++ b/prospec/ai-knowledge/modules/lib/README.md @@ -26,7 +26,7 @@ Also: `token-accounting.ts`, `index-table.ts`/`index-template.ts`, `task-markers ## Public API - `readConfig`/`writeConfig`/`atomicWrite`/`readFileIfExists` — validated read; comment-preserving/atomic writes; ENOENT→'' -- `renderTemplate`/`mergeContent`/`mergeManagedDoc` — render + user-block-preserving merges +- `renderTemplate`/`readTemplateSource`/`mergeContent`/`mergeManagedDoc` — render + template source read + user-block-preserving merges - `scanDir`/`detectModules`/`detectTechStack` — scan + module/stack detection - `parse*Dependencies(content)` — pure, malformed-safe manifest parsers - `runChecks(inputs)` + `collect*` — 11 evaluators → DriftReport; `loadModuleMap`/`loadFeatureMap`/`searchModules` — realpath-contained reads diff --git a/prospec/ai-knowledge/modules/services/README.md b/prospec/ai-knowledge/modules/services/README.md index 3e90a39..e478552 100644 --- a/prospec/ai-knowledge/modules/services/README.md +++ b/prospec/ai-knowledge/modules/services/README.md @@ -1,6 +1,6 @@ # services -> Business logic — one `execute(options) → Promise` service per command, plus shared helpers (16 files) +> Business logic — one `execute(options) → Promise` service per command, plus shared helpers (17 files) @@ -11,6 +11,7 @@ | `init.service.ts` | Scaffold config + Constitution + AI Knowledge; per-file skip-if-exists; writes `.prospec.yaml` last | | `quickstart.service.ts` | Orchestrate init + agentSync (no LLM work) | | `upgrade.service.ts` | Record `version`, re-sync, back-fill missing init docs (never overwrite), build migration report | +| `print-template.service.ts` | Retrieve raw Handlebars template contents from lib | | `agent-sync.service.ts` | Sync skills + references + entry configs; synthesize triggers; sweep orphan skill dirs; merge user blocks | | `knowledge.service.ts` | Generate module READMEs + root `index.md` (Recipe-First, ContentMerger) | | `knowledge-init.service.ts` | Initial scan → raw-scan.md + module-map.yaml + skeletons | @@ -25,22 +26,22 @@ ## Public API -- `execute(options)` per service (`init`/`quickstart`/`upgrade`/`agentSync`/`knowledge`/`knowledgeUpdate`/`archive`/`check`/`measure`/`mcp`/`change-*`) → typed `Result` +- `execute(options)` per service (`init`/`quickstart`/`upgrade`/`print-template`/`agentSync`/`knowledge`/`knowledgeUpdate`/`archive`/`check`/`measure`/`mcp`/`change-*`) → typed `Result` - `resolveChange(cwd, explicit, quiet, msg)` — shared change selector (zero/ambiguous → `PrerequisiteError`) - `generateRawScan(options)` — deterministic raw-scan core (shared by knowledge-init + upgrade) - `buildMcpServer(ctx)` — assemble the MCP server transport-free ## Dependencies -**Depends on:** `lib` (config, scanner, template, fs-utils, content-merger, yaml-utils, detector), `types` (schemas, errors) +**Depends on:** `lib` (config, scanner, template, fs-utils, content-merger, yaml-utils), `types` (schemas, errors) **Used by:** `cli` (each command calls one service), `tests` ## Modification Guide -1. **Add a service** — create `{name}.service.ts` exporting `execute()`; add matching CLI command + formatter + unit test. -2. **Change a Result type** — update the interface → its CLI formatter → unit-test assertions. -3. **Change knowledge output** — edit `knowledge.service.ts`; context keys must match `module-readme.hbs` variables. -4. **Change archive/spec-sync** — edit `archive.service.ts`; affects Feature Specs, product.md, `feature-map.yaml`. +1. **Add a service** — create `{name}.service.ts` exporting `execute()`; add command + formatter + unit test. +2. **Change a Result type** — update interface → CLI formatter → unit-test assertions. +3. **Change knowledge output** — edit `knowledge.service.ts` (keys must match `module-readme.hbs` variables). +4. **Change archive/spec-sync** — edit `archive.service.ts` (affects Feature Specs, product.md, `feature-map.yaml`). ## Ripple Effects diff --git a/prospec/ai-knowledge/modules/templates/README.md b/prospec/ai-knowledge/modules/templates/README.md index bd104ed..a1fabc8 100644 --- a/prospec/ai-knowledge/modules/templates/README.md +++ b/prospec/ai-knowledge/modules/templates/README.md @@ -18,6 +18,7 @@ ## Public API +- `prospec print-template ` — CLI command to print the raw content of any bundled template. - No code API — pure `.hbs` resources, consumed via `renderTemplate(name, ctx)` / `registerPartial()` from `lib/template.ts`. ## Dependencies @@ -27,11 +28,11 @@ ## Modification Guide -1. **Add a skill** — create `skills/prospec-{name}.hbs`, register in `SKILL_DEFINITIONS` (`types/skill.ts`), run `prospec agent sync`; needs a `## Output Contract` before `## NEVER` (`skill-format.test.ts`). -2. **Add a reference** — create `skills/references/{name}.hbs`, map templateName→outputName in `agent-sync.service.ts`, cite it from the owning skill. -3. **Edit a template** — modify the `.hbs`; variables are `{{snake_case}}` matching the service's context keys. -4. **Change index/README rendering** — edit `knowledge/module-readme.hbs` or `index.md.hbs` / `_index-auto-block.hbs`; sync context keys with `knowledge.service.ts` and update the knowledge-generate/update skills. -5. **Change a Startup Loading item** — classify `[STABLE]`/`[DYNAMIC]` (all STABLE first), then regenerate `tests/fixtures/startup-loading-baseline.json`. +1. **Add a skill** — create `skills/prospec-{name}.hbs`, register in `SKILL_DEFINITIONS` (`types/skill.ts`), run `prospec agent sync` (needs `## Output Contract` before `## NEVER`). +2. **Add a reference** — create `skills/references/{name}.hbs`, map in `agent-sync.service.ts`, cite it in skill. +3. **Edit a template** — modify the `.hbs`; variables are `{{snake_case}}` matching context keys. +4. **Change index/README rendering** — edit `knowledge/module-readme.hbs` or `index.md.hbs`; sync context with `knowledge.service.ts` and update skills. +5. **Change a Startup Loading item** — classify `[STABLE]`/`[DYNAMIC]` (STABLE first), then run tests to update baseline. ## Ripple Effects diff --git a/prospec/ai-knowledge/modules/tests/README.md b/prospec/ai-knowledge/modules/tests/README.md index 0609246..4d31c83 100644 --- a/prospec/ai-knowledge/modules/tests/README.md +++ b/prospec/ai-knowledge/modules/tests/README.md @@ -1,6 +1,6 @@ # tests -> 4-layer Vitest suite (fast-glob/git bypass memfs — 86 test files, 2,092 tests (unit 1364, contract 647, integration 38, e2e 43)); tests every source module. +> 4-layer Vitest suite (fast-glob/git bypass memfs — 87 test files, 2,096 tests (unit 1366, contract 647, integration 38, e2e 45)); tests every source module. diff --git a/prospec/ai-knowledge/raw-scan.md b/prospec/ai-knowledge/raw-scan.md index dcea04c..1da8c7d 100644 --- a/prospec/ai-knowledge/raw-scan.md +++ b/prospec/ai-knowledge/raw-scan.md @@ -106,5 +106,5 @@ tests/ | Metric | Value | |--------|-------| -| Total files | 388 | +| Total files | 395 | | Scan depth | 10 | diff --git a/prospec/index.md b/prospec/index.md index e760988..9e2a895 100644 --- a/prospec/index.md +++ b/prospec/index.md @@ -28,7 +28,7 @@ Load these specific convention files only when their topics are relevant to the | **services** | init, knowledge, change, archive, agent-sync, spec-sync, product, feature-map, triggers, language, measure, check, mcp, serve | 服務, 業務邏輯, business logic, execute pattern, use case, 量測報告, 漂移檢查, 真相層 | Active | Business logic — one `execute()` service per command — init / quickstart / upgrade, knowledge generate + update, change story / plan / tasks, archive + spec-sync, agent-sync, measure, drift check, and the read-only MCP server. | Isolates business logic from I/O layer, enables testability | types, lib | | **cli** | commands, formatters, commander, output, preaction, measure, check, strict, mcp, stdio | 指令, 命令列, command line, 終端, entry point | Active | Thin CLI entry — Commander commands + formatters that parse → call one service → format output. No business logic (delegates everything to services). | Thin I/O layer: no business logic, delegates to services | types, lib, services | | **templates** | handlebars, hbs, skills, agent-configs, recipe-first, loading-rules, references, change, stable-prefix, entry-gate, scale, kind, ci-workflow, flywheel, lessons-ledger, feature-map, category, grouping | 模板, 範本, handlebars, template engine, resources, 穩定前綴, 知識同步閘門, 複雜度適配, CI 閘門 | Active | Handlebars template library — 17 skills + 5 shared partials, 19 references, 1 agent-config, 4 change, 15 init/knowledge (61 `.hbs` templates). Pure resources consumed by lib/template — the source of every generated skill, README, and index. | Pure resources — no logic, consumed by lib/template.ts | — | -| **tests** | vitest, memfs, unit, integration, contract, e2e, knowledge-format, skill-format, token-corpus, drift, lessons-harvest, mcp-server, in-memory-transport | 測試, 單元測試, test suite, 驗證, vitest | Active | 4-layer test suite — 86 files, 2,092 tests (unit 1364 + contract 647 + integration 38 + e2e 43) across unit / contract / integration / e2e. Validates every module — format contracts, the drift engine, token corpus, and the MCP protocol over in-memory transport. | Quality gate — validates all layers with pyramid coverage | types, lib, services, cli, templates | +| **tests** | vitest, memfs, unit, integration, contract, e2e, knowledge-format, skill-format, token-corpus, drift, lessons-harvest, mcp-server, in-memory-transport | 測試, 單元測試, test suite, 驗證, vitest | Active | 4-layer test suite — 87 files, 2,096 tests (unit 1366 + contract 647 + integration 38 + e2e 45) across unit / contract / integration / e2e. Validates every module — format contracts, the drift engine, token corpus, and the MCP protocol over in-memory transport. | Quality gate — validates all layers with pyramid coverage | types, lib, services, cli, templates | _Table format: Module | Keywords | Aliases | Status | Description | Rationale | Depends On_ diff --git a/prospec/specs/_archived-history/2026-07-08-cli-print-template.md b/prospec/specs/_archived-history/2026-07-08-cli-print-template.md new file mode 100644 index 0000000..fb1cf15 --- /dev/null +++ b/prospec/specs/_archived-history/2026-07-08-cli-print-template.md @@ -0,0 +1,46 @@ +# cli-print-template — Archive Summary + +- **Archived**: 2026-07-08 +- **Original Created**: 2026-07-08 +- **Quality Grade**: S + +## User Story + +作為一位 AI 程式碼代理(AI Coding Agent), +我想要 Prospec 技能都不再需要呼叫 Node.js 指令,而能直接透過 `prospec` CLI 原生取得所需要的樣板內容, +以便於在沒有安裝 Node.js 或只安裝 `prospec` 獨立執行檔的環境中也能順利執行升級與維護。 + +## Affected Modules + +| Module | Impact | Description | +|--------|--------|-------------| +| templates | High | 修改 prospec-upgrade.hbs 技能樣板,移除 node 執行指令 | +| lib | Medium | 調整 template.ts 導出 readTemplateSource | +| services | Low | 新增 print-template.service.ts 業務邏輯 | +| cli | Medium | 註冊 print-template 指令與對應的輸出格式化工具,並加入至 INIT_COMMANDS 免檢測列表 | +| tests | Medium | 新增單元測試與 E2E 測試 | + +## Requirements + +| REQ ID | Status | Description | +|--------|--------|-------------| +| REQ-CLI-020 | ADDED | 新增 print-template 子命令 | +| REQ-SERVICES-015 | ADDED | 實現 Print-Template 業務邏輯 | +| REQ-TEMPLATES-005 | MODIFIED | 更新 prospec-upgrade.hbs 中的樣板讀取邏輯 | +| REQ-LIB-008 | MODIFIED | 導出 readTemplateSource 函數 | + +## Completion + +- **Tasks**: 10/10 (100%) +- **Acceptance Criteria**: 5/5 + +## Review & Verify + +- **Review**: no review round (recorded directly via CLI) +- **Verify**: Grade S, Task Completion PASS, Delta Spec Compliance PASS, Constitution Full Audit PASS, Knowledge ↔ Implementation Consistency PASS, Test Verification PASS; Vitest E2E/unit suite 100% PASS (2096/2096) +- **Quality Log**: no WARN/FAIL + +## Knowledge Update + +The following module documentation may need updating: +- `prospec/ai-knowledge/modules/templates/README.md` diff --git a/prospec/specs/features/standalone-binary.md b/prospec/specs/features/standalone-binary.md index 48c903d..6215e81 100644 --- a/prospec/specs/features/standalone-binary.md +++ b/prospec/specs/features/standalone-binary.md @@ -1,9 +1,9 @@ --- feature: standalone-binary status: active -last_updated: 2026-07-07 +last_updated: 2026-07-08 story_count: 1 -req_count: 4 +req_count: 8 --- # Standalone Binary Compilation @@ -58,6 +58,32 @@ So that 我不需要在機器上另外安裝 Node.js 就能直接使用 prospec - WHEN 查看 README.md 與 README.zh-TW.md,THEN 新增一鍵安裝腳本、standalone binary 下載、以及 npx/devDependency 選項,且移除了 global npm install。 - WHEN 造訪 docs/ 網站,THEN 相關網頁的安裝說明同步調整為一鍵安裝腳本。 +#### REQ-CLI-020: 新增 print-template 子命令 +為 `prospec` CLI 新增 `print-template ` 子指令,以便直接輸出內置 Handlebars 樣板的源碼內容。 + +**Scenarios:** +- WHEN 執行 `prospec print-template ` 且樣板存在,THEN 無格式地直接輸出樣板原始字串至 `stdout`。 +- WHEN 傳入不存在的樣板路徑,THEN 拋出 `TemplateError` 且以退出碼 `1` 結束執行。 + +#### REQ-SERVICES-015: 實現 Print-Template 業務邏輯 +實作對應 `print-template` 的服務,從 `lib/template.ts` 中的 `readTemplateSource` 取得樣板內容。 + +**Scenarios:** +- WHEN 傳入參數 `templatePath` 並傳遞給 `readTemplateSource`,THEN 回傳對應的樣板源碼字串。 + +#### REQ-TEMPLATES-005: 更新 prospec-upgrade.hbs 中的樣板讀取邏輯 +修改 `prospec-upgrade` 技能的執行步驟,將原先使用 Node.js (`require.resolve`) 和尋找 package 的腳本完全移除,改為原生呼叫 `prospec print-template ` 指令。 + +**Scenarios:** +- WHEN 執行 `prospec-upgrade` 技能,THEN 不再呼叫任何 `node` 指令。 +- WHEN 尋找樣板時,THEN 一律優先呼叫 `prospec print-template` 取得樣板內容。 + +#### REQ-LIB-008: 導出 readTemplateSource 函數 +修改 `src/lib/template.ts` 以公開導出 `readTemplateSource`。 + +**Scenarios:** +- WHEN 其他模組需要讀取樣板源碼,THEN 可直接調用導出的 `readTemplateSource` 函數。 + ## Edge Cases - **範本找不到的錯誤**:在 Standalone Binary 中執行涉及檔案生成的指令(如 `prospec init`)時,Handlebars 範本讀取機制若預期存取外部 `src/templates` 目錄會崩潰。預期行為:範本內容在打包時需被內嵌於二進位檔中,確保不需外部實體範本檔案即可正常讀取。 @@ -85,3 +111,4 @@ _(None)_ | Date | Change | Impact | Stories/REQs | |------|--------|--------|-------------| | 2026-07-07 | compile-standalone-binary | Implement standalone binary compilation and publish pipeline | US-1, REQ-CLI-001, REQ-LIB-001, REQ-TYPES-001, REQ-DOCS-001 | +| 2026-07-08 | cli-print-template | Add print-template CLI subcommand and service to support Node.js-free template resolution in prospec-upgrade skill | US-1, REQ-CLI-020, REQ-SERVICES-015, REQ-TEMPLATES-005, REQ-LIB-008 | diff --git a/prospec/specs/product.md b/prospec/specs/product.md index 1587637..9416856 100644 --- a/prospec/specs/product.md +++ b/prospec/specs/product.md @@ -1,6 +1,6 @@ --- product: prospec -last_updated: 2026-07-07 +last_updated: 2026-07-08 --- # prospec diff --git a/src/cli/commands/print-template.ts b/src/cli/commands/print-template.ts new file mode 100644 index 0000000..b96e6a5 --- /dev/null +++ b/src/cli/commands/print-template.ts @@ -0,0 +1,29 @@ +import type { Command } from 'commander'; +import { execute } from '../../services/print-template.service.js'; +import { formatPrintTemplateOutput } from '../formatters/print-template-output.js'; +import { handleError } from '../formatters/error-output.js'; +import type { GlobalOptions } from '../index.js'; + +/** + * Register the `print-template` command onto the program. + * + * Usage: + * prospec print-template + * + * This command outputs the raw template content of a bundled template. + * It is registered in INIT_COMMANDS so it can be run on uninitialized projects. + */ +export function registerPrintTemplateCommand(program: Command): void { + program + .command('print-template ') + .description('Print the raw content of a bundled template by its relative path') + .action(async (templatePath: string) => { + const globalOpts = program.opts(); + try { + const result = await execute({ templatePath }); + formatPrintTemplateOutput(result); + } catch (err) { + handleError(err, globalOpts.verbose ?? false); + } + }); +} diff --git a/src/cli/formatters/print-template-output.ts b/src/cli/formatters/print-template-output.ts new file mode 100644 index 0000000..ee5ee69 --- /dev/null +++ b/src/cli/formatters/print-template-output.ts @@ -0,0 +1,11 @@ +import type { PrintTemplateResult } from '../../services/print-template.service.js'; + +/** + * Format the PrintTemplateResult for terminal output. + * Writes the raw template content directly to stdout. + * + * @param result - The print-template service result + */ +export function formatPrintTemplateOutput(result: PrintTemplateResult): void { + process.stdout.write(result.content); +} diff --git a/src/cli/index.ts b/src/cli/index.ts index d1cfecd..d146c3f 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -11,6 +11,7 @@ import { ConfigNotFound } from '../types/errors.js'; import { registerInitCommand } from './commands/init.js'; import { registerQuickstartCommand } from './commands/quickstart.js'; import { registerUpgradeCommand } from './commands/upgrade.js'; +import { registerPrintTemplateCommand } from './commands/print-template.js'; import { registerKnowledgeCommand } from './commands/knowledge-generate.js'; import { registerKnowledgeInitCommand } from './commands/knowledge-init.js'; import { registerAgentCommand } from './commands/agent-sync.js'; @@ -25,7 +26,7 @@ import { PROSPEC_VERSION } from '../types/version.js'; /** * Commands that do NOT require .prospec.yaml to exist. */ -const INIT_COMMANDS = new Set(['init', 'quickstart', 'help']); +const INIT_COMMANDS = new Set(['init', 'quickstart', 'help', 'print-template']); /** * Resolve verbose/quiet from global options into a log level. @@ -83,6 +84,7 @@ export function createProgram(): Command { registerInitCommand(program); registerQuickstartCommand(program); registerUpgradeCommand(program); + registerPrintTemplateCommand(program); const knowledge = registerKnowledgeCommand(program); registerKnowledgeInitCommand(knowledge, program); registerAgentCommand(program); diff --git a/src/lib/bundled-templates.ts b/src/lib/bundled-templates.ts index 38231b2..f8cd60a 100644 --- a/src/lib/bundled-templates.ts +++ b/src/lib/bundled-templates.ts @@ -40,7 +40,7 @@ export const BUNDLED_TEMPLATES: Record = { "skills/prospec-quickstart.hbs": "---\nname: prospec-quickstart\ndescription: \"{{skill_description}} Triggers: {{trigger_words}}\"\n---\n{{> generated-notice}}\n\n# Prospec Quickstart Skill\n\n## Activation\n\nWhen triggered, briefly describe:\n- That `prospec quickstart` has scaffolded the project and you'll finish onboarding\n- You'll localize skill triggers to the configured language (when non-English), re-sync agent config, prepare the knowledge scan, then hand off to knowledge generation\n- This is a one-time onboarding flow — it is re-runnable and self-terminating\n\n## Startup Loading\n\n1. [DYNAMIC] Read `.prospec.yaml` — `artifact_language` and `skill_triggers` decide whether native-language trigger localization runs\n\n## Core Workflow\n\n> This skill shells out to the `prospec` CLI (Bash), mirroring how `prospec-verify`\n> runs `prospec check --json`. When the CLI is unavailable, degrade gracefully —\n> never fail silently.\n\n### Step 0: Probe the CLI\n\nRun `prospec --version` (Bash). When it is unavailable (not built / installed / linked),\nSTOP and tell the user to **install prospec** — you are adopting prospec for this project and\nquickstart is entirely CLI-driven, so it must be available: `npm i -g prospec`. For a **Node.js\nproject**, also declare `prospec` in `devDependencies` so contributors share it without a global\ninstall (this is what later lets `/prospec-knowledge-generate` and `/prospec-archive` refresh\n`raw-scan.md` via `pnpm exec` / `npx` with no per-developer install). Non-Node projects: a global\ninstall is the path. Re-run quickstart after installing; never proceed silently.\n\n### Step 1: Localize Skill Triggers (non-English only, fill-missing)\n\nRead `.prospec.yaml`. When `artifact_language` is not English, localize the skills that have\n**no `skill_triggers` entry yet** (the exact gap `prospec agent sync` names in its hint). This covers\nboth a fresh project (all skills missing) and a project that just gained new skills (only the new ones\nmissing) — so you never delete `.prospec.yaml` to re-localize:\n\n1. **Capture the current `.prospec.yaml` content verbatim** as a snapshot to restore from if the write goes wrong\n2. For each skill missing a `skill_triggers` entry, translate its English trigger baseline into the `artifact_language` — leave skills that already have an entry untouched\n3. **Show the proposed translations to the user and wait for confirmation** before writing anything\n4. On confirmation, add the missing `skill_triggers` keys by a **minimal in-place edit** — insert only the new keys, leaving every existing key, its ordering, and all comments untouched (do not re-serialize the whole file)\n5. Read `.prospec.yaml` back and confirm it still parses as valid YAML; if it does not, restore the captured snapshot verbatim and report the malformed translation\n\nSkip this step entirely when the language is English or every skill already has a `skill_triggers`\nentry — never overwrite curated triggers.\n\n### Step 2: Re-sync Agent Config\n\nRun `prospec agent sync` (Bash) so the localized triggers render into each SKILL.md\nfrontmatter and the entry config. Skip only when Step 1 made no change.\n\n### Step 3: Prepare the Knowledge Scan\n\nRun `prospec knowledge init` (Bash) to (re)generate `raw-scan.md` and the knowledge\nscaffolding. It always overwrites `raw-scan.md`, so this is safe to re-run and keeps the\nscan fresh for the next step.\n\n### Step 4: Generate AI Knowledge\n\nChain directly into the `/prospec-knowledge-generate` workflow — read `raw-scan.md`,\ndecide module boundaries, and write the module READMEs and `{{base_dir}}/index.md`. Do NOT inline a\ncopy of that workflow here; hand off to it so large repositories get their own context\nbudget.\n\n## Output Contract\n\n{{> output-summary-note}}\n\n### Success Criteria\n- [ ] `.prospec.yaml` exists and parses as valid YAML\n- [ ] when non-English, `skill_triggers` is populated (or the user declined)\n- [ ] `raw-scan.md` exists after `prospec knowledge init`\n- [ ] the `/prospec-knowledge-generate` workflow was entered\n\n### Failure Conditions\n- wrote malformed `skill_triggers` to `.prospec.yaml`\n- proceeded silently when the `prospec` CLI was unavailable\n\n### Output Summary\nEmit one line: `Met N/M | Unmet: | Overall: PASS|WARN|FAIL | Next: `\n\n## NEVER\n\n- **NEVER** proceed silently when the `prospec` CLI is unavailable — stop and tell the user to install prospec (they are adopting it for this project), then re-run\n- **NEVER** overwrite an existing `skill_triggers` entry — localize only the skills missing an entry (fill-missing)\n- **NEVER** write `skill_triggers` without reading `.prospec.yaml` back to confirm it still parses\n- **NEVER** inline the `/prospec-knowledge-generate` workflow — chain to it so large repos get a fresh context budget\n- **NEVER** translate triggers without showing the user the proposed words first\n\n## Error Handling\n\n| Scenario | Action |\n|----------|--------|\n| `prospec` CLI unavailable | Stop; tell the user to install prospec (`npm i -g prospec`; Node.js projects can also add it to `devDependencies`), then re-run quickstart — do not proceed silently |\n| `prospec agent sync` reports no configured agent | Stop and instruct the user to re-run `prospec init` or add an agent to `.prospec.yaml` |\n| `.prospec.yaml` fails to parse after writing triggers | Restore the captured pre-write `.prospec.yaml` snapshot verbatim, then report the malformed translation |\n| `raw-scan.md` still missing after `knowledge init` | Report the failure; do not fabricate knowledge |\n", "skills/prospec-review.hbs": "---\nname: prospec-review\ndescription: \"{{skill_description}} Triggers: {{trigger_words}}\"\n---\n{{> generated-notice}}\n\n# Prospec Review Skill\n\n## Activation\n\nWhen triggered, briefly describe:\n- That an independent reviewer (fresh context) will audit the entire change diff between implement and verify\n- That only verifier-confirmed criticals are auto-fixed; majors are proposed and passed to verify as WARN\n- That the loop converges to zero unresolved critical or escalates to you at a hard cap — review never silently passes\n\n## Startup Loading\n\n1. [STABLE] Read `{{constitution_path}}` — principles and dependency/layering rule\n2. [STABLE] **MANDATORY** — Read [`references/review-format.md`](references/review-format.md) for the severity contract, review.md format, and reviewer lenses\n3. [DYNAMIC] Read `.prospec/changes/[name]/tasks.md`, `plan.md`, `delta-spec.md`, `proposal.md` — the contract this change must honour\n4. [DYNAMIC] Read `{{knowledge_base_path}}/_conventions.md` + each affected module `README.md` — patterns and ripple effects\n5. [DYNAMIC] Compute the change diff relative to the branch base (`git diff`), reviewing source + tests; exclude generated artifacts (`dist/`, lockfiles, deployed skills)\n\n## Entry Gate\n\n> Blocking precondition check before this skill runs. If any item FAILs, stop and tell the user what is missing — do not proceed.\n\n- Implementation is done: metadata status is `implemented` and tasks.md **code-task** checkboxes are complete (unchecked `[M]`/`[V]` tasks do not block; kind schema: tasks-format reference); if still `tasks`, FAIL and point to `/prospec-implement`.\n- Planning artifacts exist: proposal.md, plan.md, delta-spec.md, tasks.md. **Exception — `metadata.scale: quick`**: only proposal.md + tasks.md are required (a quick change legitimately has no plan/delta-spec); do not FAIL on their absence. **Exception — `metadata.scale: backfill`**: only proposal.md + delta-spec.md are required (a backfill change records existing code — no forward plan/tasks); do not FAIL on their absence.\n- Prior unresolved WARN: read `metadata.yaml` `quality_log` and surface any unresolved WARN from earlier stages.\n\n## Core Workflow\n\n### Reviewer Modes\n\n- **B — single reviewer, multi-lens (default)**: one fresh-context reviewer covers every must-run lens in a single pass. Token-friendly; independence from the implementer is already satisfied.\n- **A — parallel lenses (opt-in)**: N independent lens agents run concurrently. Use for large or high-risk diffs, or Scale=Full. Higher first-round cost buys maximum inter-lens independence.\n\n### Review Lenses\n\nMust-run every round:\n- **correctness & edge cases**\n- **security & data integrity**\n- **spec-architecture** — the prospec differentiator, always layered on regardless of reviewer engine: implementation vs `delta-spec` REQ intent, dependency direction `cli → services → lib → types`, module conventions, and unhandled ripple effects.\n - **Quick degradation** (`metadata.scale: quick`): the delta-spec REQ comparison is `not-applicable` (there is no delta-spec — never report it as PASS); dependency direction, module conventions, and ripple checks still run in full. Additionally, when the diff appears to touch behavior covered by existing `{{base_dir}}/specs/features/` REQs, raise an early warning — the `/prospec-archive` Entry Gate re-checks this, but catching it at review is cheaper.\n\nConditional: **security & data integrity** (untrusted input, auth, external integrations), efficiency/performance (hot-path or data-layer changes), maintainability/DRY (new abstractions), **docs-claims** (the change adds/edits README or doc claims about behavior — check claim ⊆ implementation, PB-003), **parallel-site completeness** (the change touches a shared resolver / invariant / data source — grep EVERY consumer, PB-007), and **test-quality** (the change adds/edits tests — section-scoped + structural + negative + mutation-verified, PB-001). When any conditional lens applies, load [`references/review-lenses-content.md`](references/review-lenses-content.md) **on demand** for its concrete, severity-pre-mapped criteria (OWASP/IDOR/SSRF/injection/secrets; N+1/CWV/blocking I/O; DRY/complexity/Rule-of-N; docs-claims/parallel-site/test-quality) — severity vocabulary stays defined in `review-format.md`, the lens-content reference only maps onto it. This reference is on-demand only — it is NOT a Startup Loading item. A pluggable language-specific engine may add further language lenses; the spec-architecture lens is always added by prospec and is never replaced by the vendored lens criteria.\n\n### Severity Routing\n\nApply `references/review-format.md`. In short: **critical** blocks the loop and is auto-fixed; **major** does not block (proposed, passed to verify as WARN, never counted in verify's grade); **nit** is dropped.\n\n### The Loop\n\n1. Spawn the reviewer (mode B or A) over the change diff. The reviewer reads whole functions/classes and greps ripple, not just diff hunks.\n2. For each reported **critical**, spawn an **independent verifier** to confirm the issue's **existence** — it Reads the code and cites Evidence, marking `[confirmed]` / `[not-found]`. Only confirmed criticals with a concrete, local, drop-in fix are auto-fixed; architectural, large-refactor, or ambiguous fixes are **escalated to the human**, not auto-applied.\n3. Apply each fix to the **working tree** (no commit), then **re-run `pnpm test`**; the suite must stay green — if a fix turns a test red, roll that fix back and re-decide, never proceed on red.\n4. Re-review (mode B narrow pass) to confirm criticals are resolved with no regression, until **0 unresolved critical** (review-clean).\n5. **Hard cap**: 3 rounds (maximum 5). **Early-stop** if a round resolves 0 new criticals or reverts a previously-applied fix.\n6. **Escalation**: at the cap or early-stop with unresolved criticals, stop and hand the list of unresolved criticals plus attempted fixes to the human for decision — never silently pass.\n\n### Harness Degradation\n\nIf the execution harness cannot spawn an independent sub-agent, **offer a choice** — use the harness's own reviewer command, or fall back to a single-pass fresh-context review — and say so explicitly. Never silently skip review.\n\n### Persistence\n\nWrite findings to `.prospec/changes/[name]/review.md`: a cumulative table (`location | severity | lens | status`), deduplicated by Location with severity taken as the maximum, carried forward across rounds as the anchor so resolved items are not re-raised and verdicts stay consistent. Confirmed cross-change recurring criticals may be flagged for promotion (feeds the feedback-promotion pipeline).\n\n### Review Provenance (machine gate)\n\nReview must leave a machine-queryable record so `/prospec-verify`'s Entry Gate can prove it ran and is still current:\n\n1. **Every round** — including a **review-clean** round (0 critical / 0 major) — append a `skill: prospec-review` entry to `metadata.yaml` `quality_log` (result `PASS` when clean, `WARN` when unresolved majors/FAIL carry forward). A clean review that records nothing is indistinguishable from a review that never ran. Carry the round's counts as structured fields so quality trends are machine-aggregatable (not buried in `review.md` prose): `criticals_found`, `criticals_fixed`, and `majors` (integers ≥ 0). These are additive — `result`/`warnings` are unchanged; a round that finds nothing records the counts as `0`.\n2. **At loop convergence** (review-clean or escalation), run `prospec check --record-review` — it code-computes the reviewed change's digest and writes `review_provenance` to `metadata.yaml`. This is the baseline the `review-provenance` drift check compares against. **Graceful**: if the CLI is unavailable, state so explicitly and record the review entry anyway — never silently skip.\n\nBecause the digest is code-computed, editing the change's code after this point flips `review-provenance` to stale — `/prospec-verify` will then require a fresh review round before it runs.\n\n## Output Contract\n\n{{> output-summary-note}}\n\n### Success Criteria\n- [ ] no unresolved critical (loop converged, or escalated to the human with the list)\n- [ ] every fix round left `pnpm test` green\n- [ ] `review.md` written with the findings table\n- [ ] a `prospec-review` `quality_log` entry recorded (every round, incl. review-clean) and the review baseline stamped via `prospec check --record-review`\n- [ ] every auto-fixed critical was verifier-confirmed before the fix (manual)\n\n### Failure Conditions\n- a critical auto-fixed without an existence-verification step\n- tests left red, or the loop exceeded the hard cap without escalating\n\n### Output Summary\nEmit one line: `Met N/M | Unmet: | Overall: PASS|WARN|FAIL | Next: `\n\n### Exit Gate (Constitution)\n\nVerify the output against this skill's **site-specific** Constitution rule (**dependency-direction/layering** — the spec-architecture lens's concern), not the full Constitution; the every-principle audit is `/prospec-verify` V3/5 only. When the rule carries RFC-2119 severity (BL-031), grade by weight — MUST→FAIL, SHOULD→WARN, MAY→informational (the grade vocabulary stays PASS/WARN/FAIL). A free-text Constitution falls back to judgment-based grading. **Always** record a `prospec-review` entry to `metadata.yaml` `quality_log` (`skill: prospec-review` / `date` / `result` / `warnings`) — **every round, including review-clean** (result `PASS` when clean, `WARN` when unresolved majors/FAIL carry forward) — so `/prospec-verify` can machine-verify review ran and surface any majors; majors are advisory and do not block. Then record the review baseline (`prospec check --record-review`, see Review Provenance) and suggest `/prospec-verify`.\n\n## NEVER\n\n- **NEVER** auto-fix a critical that was not independently confirmed to exist — acting on a hallucinated finding edits correct code and erodes trust\n- **NEVER** proceed to the next round with the test suite red — a fix that breaks a test must be rolled back; silent green→red regression defeats the loop\n- **NEVER** loop without a hard cap or silently pass unresolved criticals — unbounded retries waste tokens; unresolved criticals must escalate to the human\n- **NEVER** auto-apply an architectural or large-refactor fix — only concrete, local, drop-in fixes are safe to apply unattended; the rest are proposed\n- **NEVER** count major findings in verify's grade — review and verify are separate axes; majors pass as advisory WARN, not as a grade penalty\n- **NEVER** silently skip review when sub-agents are unavailable — offer a degraded path so the developer decides knowingly\n- **NEVER** commit during review — the commit boundary is after `/prospec-verify` reaches S/A; review only edits the working tree\n\n## Error Handling\n\n| Scenario | Action |\n|----------|--------|\n| metadata status not `implemented` | Stop; point to `/prospec-implement` to finish tasks first |\n| No change diff vs branch base | Report nothing to review; suggest proceeding to `/prospec-verify` |\n| Sub-agent spawn unavailable | Offer the harness reviewer or single-pass fallback; do not skip |\n| Fix repeatedly turns tests red | Roll back, mark the critical unresolved, escalate to the human |\n| Reviewer and verify disagree on layering | Keep both — review catches it first, verify re-checks independently; no mutual exemption |\n\n{{> next-step-handoff}}\n", "skills/prospec-tasks.hbs": "---\nname: prospec-tasks\ndescription: \"{{skill_description}} Triggers: {{trigger_words}}\"\n---\n{{> generated-notice}}\n\n# Prospec Tasks Skill\n\n## Activation\n\nWhen triggered, briefly describe:\n- That you'll read plan.md and delta-spec.md to understand the implementation scope\n- Tasks will be organized by architecture layer (Types → Lib → Services → CLI → Tests)\n- Non-code tasks carry a `[M]`/`[V]` kind marker; complexity estimates and `[P]` markers are optional\n\n{{> language-policy}}\n\n## Startup Loading\n\n1. [STABLE] Read `{{constitution_path}}` — prepare test coverage check\n2. [STABLE] **MANDATORY** — Read [`references/tasks-format.md`](references/tasks-format.md) for tasks.md format\n3. [DYNAMIC] Read `.prospec/changes/[name]/plan.md` — parse implementation steps\n4. [DYNAMIC] Read `.prospec/changes/[name]/delta-spec.md` — parse file changes and specifications\n5. [DYNAMIC] Read `.prospec/changes/[name]/design-spec.md` (if exists) — identify UI components for task decomposition\n6. [DYNAMIC] Read related module `README.md` from `{{knowledge_base_path}}/modules/` (and any `{sub-module}.md` it links) — confirm architecture layers and dependency directions for task ordering\n\n## Entry Gate\n\n> Blocking precondition check before this skill runs. If any item FAILs, stop and tell the user what is missing — do not proceed.\n\n- plan.md and delta-spec.md exist. **Exception — `metadata.scale: quick`**: only proposal.md is required (a quick change legitimately has no plan/delta-spec); decompose directly from proposal.md and advance status `story → tasks` (the legal quick transition — see `{{knowledge_base_path}}/_status-lifecycle.md`).\n- Prior unresolved WARN: read `metadata.yaml` `quality_log` and surface any unresolved WARN from earlier stages.\n\n## Core Workflow\n\n### Phase 1: Parse Planning Documents\n\nAuto-identify current change, read plan.md and delta-spec.md, summarize implementation phases, file changes, and spec count.\n\n> **Phase 1 Gate** — proceed when:\n> - [ ] current change name resolved and plan.md + delta-spec.md (or proposal.md for `scale: quick`) read\n> - [ ] implementation phases, file changes, and spec/REQ count summarized\n\n### Phase 2: Create Scaffolding\n\n| Scenario | Action |\n|----------|--------|\n| tasks.md doesn't exist | Create empty `tasks.md`, update `metadata.yaml` status → `tasks` |\n| Already exists | Read and populate |\n\n> **Phase 2 Gate** — proceed when:\n> - [ ] `tasks.md` exists (created or read)\n> - [ ] `metadata.yaml` status updated to `tasks`\n\n### Phase 3: Decompose by Architecture Layer\n\nOrganize tasks following the layer order defined in `references/tasks-format.md`:\n\n```\nTypes → Lib → Services → CLI → Tests\n```\n\nTask format: `- [ ] [description]`. A `~{lines} lines` estimate and a `[P]` parallelization marker are **optional** — no skill or service *gates* on them (nothing reads `~lines`; `/prospec-implement` treats `[P]` only as a best-effort \"could parallelize\" reminder that degrades cleanly when absent). Add them only when they aid the reader; never gate on their presence.\n\n**Task kind tagging:** mark each non-code task with its kind — `[M]` (manual) or `[V]` (verification); leave code tasks unmarked. The kind schema is frozen in `references/tasks-format.md` (Task Kind Markers) — cite it, do not restate. This is the one **required** marker class: downstream, verify counts only code tasks in the completion rate and archive warns on unchecked tasks by kind.\n\n**Decomposition principles:**\n- Single responsibility: one task does one thing\n- Verifiable: clear completion criteria\n- Right-sized: ideal 15-25 tasks, each 20-100 lines\n- Dependency direction: follow `cli → services → lib → types` order from `_conventions.md` — implement lower layers first\n\n**UI task decomposition** (when design-spec.md exists):\n- Reference specific component names from design-spec.md in each UI task description\n- Annotate each UI task with: \"Read precise design values from design tool via adapter MCP before implementing\"\n- This ensures the implement phase knows which components to look up and which MCP tools to use\n\n> **Phase 3 Gate** — proceed when:\n> - [ ] tasks written to `tasks.md`, grouped by architecture layer (Types → Lib → Services → CLI → Tests)\n> - [ ] non-code tasks carry `[M]`/`[V]` kind markers (the one required marker class; `~lines`/`[P]` are optional)\n\n### Phase 4 (Optional): Mark Parallelization Opportunities\n\nOptionally mark dependency-free tasks with `[P]` when it helps a human split the work. No skill or service consumes `[P]` (implement executes sequentially), so this is a reader aid, not a requirement — skip it freely.\n\n> **Phase 4 Gate** — proceed when:\n> - [ ] (if any `[P]` markers were added) none sits on a task that depends on a lower layer\n\n### Phase 5: Generate Summary\n\nAdd a Total Tasks count at end of file; Parallelizable Tasks / Total Estimated Lines are optional (include only if `[P]`/`~lines` were used).\n\n> **Phase 5 Gate** — proceed when:\n> - [ ] a Total Tasks count is appended at end of `tasks.md`\n> - [ ] Total Tasks count reconciles with the checkboxes in the file\n\n### Phase 6: Constitution Test Check (site-specific: TDD)\n\nCheck only this station's **site-specific** Constitution rule — **TDD / test coverage** — NOT a generic multi-principle scan (the full every-principle audit is `/prospec-verify` V3/5 only). Ensure each new/modified module has corresponding test tasks. If coverage is insufficient, add test tasks or raise a warning.\n\n> **Phase 6 Gate** — proceed when:\n> - [ ] every new/modified module has a corresponding test task in `tasks.md`\n> - [ ] any test-coverage gap is resolved by added test tasks or a recorded warning\n\n### Phase 7: Knowledge Quality Gate\n\nConfirm the decomposition against Knowledge in **one line**: layer order matches the module dependency graph, task file paths exist or are clearly new, and every new/modified module has a test task. Any gap → WARN with a clarification note on the affected task (non-blocking); record to `metadata.yaml` `quality_log`. (The full per-station Quality-Gate table lives only in `/prospec-verify` — the SDD stations no longer each restate it.)\n\n> **Phase 7 Gate** — proceed when:\n> - [ ] the one-line Knowledge check is recorded PASS or WARN (with a clarification note per WARN)\n\n### Phase 8: Summary + Next Steps\n\nSuggest: `/prospec-implement` or manual review.\n\n## Output Contract\n\n{{> output-summary-note}}\n\n### Success Criteria\n- [ ] tasks cover every delta-spec REQ (quick: every proposal acceptance scenario — no delta-spec by contract)\n- [ ] tasks grouped by architecture layer\n- [ ] non-code tasks carry a `[M]`/`[V]` kind marker\n- [ ] every new/modified module has a test task\n\n### Failure Conditions\n- no plan.md present (does not apply to `scale: quick`)\n- > 30 tasks, or a modified module has no test task\n\n### Output Summary\nEmit one line: `Met N/M | Unmet: | Overall: PASS|WARN|FAIL | Next: `\n\n### Exit Gate (Constitution)\n\nVerify the output against this skill's **site-specific** Constitution rule (**TDD / test coverage**) — not the full Constitution; the every-principle audit is `/prospec-verify` V3/5 only. When the rule carries RFC-2119 severity (BL-031), grade by weight — MUST→FAIL, SHOULD→WARN, MAY→informational (the grade vocabulary stays PASS/WARN/FAIL). A free-text Constitution falls back to judgment-based grading. Record each WARN/FAIL to `metadata.yaml` `quality_log` (`skill` / `date` / `result` / `warnings`). Advisory — surface issues, do not hard-block.\n\n## NEVER\n\n- **NEVER** produce more than 30 tasks — indicates Story scope creep; large task lists overwhelm AI context and lose coherence\n- **NEVER** create overly fine-grained tasks (<10 lines) — micro-tasks inflate task count and add checkbox overhead without meaningful progress tracking\n- **NEVER** create overly coarse tasks (>200 lines) — unverifiable; if a 200-line task fails, the entire block must be debugged and reworked\n- **NEVER** forget to update metadata.yaml status to `tasks` — downstream Skills check status to determine workflow stage (full lifecycle: `{{knowledge_base_path}}/_status-lifecycle.md`)\n- **NEVER** start decomposition without plan.md — tasks without architecture context produce random file edits instead of layered implementation (`scale: quick` is the exception: decompose from proposal.md, there is no plan by contract)\n- **NEVER** skip test tasks — Constitution requires test coverage; untested modules are deployment blockers in Verify phase\n- **NEVER** gate on `[P]` or `~lines` — both are optional reader aids that no skill gates on (nothing reads `~lines`; implement's `[P]` reminder is best-effort and executes sequentially anyway); if you do add an estimate, use `~{lines} lines`, not S/M/L\n- **NEVER** omit a non-code task's `[M]`/`[V]` kind marker — verify's completion rate and archive's unchecked-task warnings depend on it (this is the one required marker)\n\n## Error Handling\n\n| Scenario | Action |\n|----------|--------|\n| plan.md not found | `scale: quick`: expected — decompose from proposal.md. Otherwise guide user to run `/prospec-plan` first |\n| Task count exceeds 30 | Suggest splitting the Story or merging fine-grained tasks |\n| Insufficient test coverage | Offer options: add test tasks / document test debt |\n\n{{> next-step-handoff}}\n", - "skills/prospec-upgrade.hbs": "---\nname: prospec-upgrade\ndescription: \"{{skill_description}} Triggers: {{trigger_words}}\"\n---\n{{> generated-notice}}\n\n# Prospec Upgrade Skill\n\n## Activation\n\nWhen triggered, briefly describe:\n- That `prospec upgrade` has recorded the new prospec version in `.prospec.yaml` and re-synced agents, and you'll finish the judgment steps it cannot do deterministically\n- You'll work through the report's docs inventory (every file `prospec init` creates): `prospec upgrade` has already back-filled any that were missing, so you offer to update any whose format has drifted from the latest templates and to enrich the docs it just created that need more than a baseline (e.g. the index's real module table) — asking before each change — plus, as a safety net, create any still marked missing; offer to set an artifact language if the project never chose one (a project from a pre-feature CLI); and localize triggers for skills that have none\n- This is a periodic upgrade flow — re-runnable and self-terminating\n\n## Language Policy\n\nWrite generated documents in the language defined by the Constitution's Language Policy rule. Keep code, identifiers, technical terms, and git commit messages in English.\n\n## Startup Loading\n\n1. [DYNAMIC] Read `.prospec.yaml` — `version`, `artifact_language`, and `skill_triggers` drive the steps below\n\n## Core Workflow\n\n> This skill shells out to the `prospec` CLI (Bash), mirroring `prospec-quickstart`.\n> When the CLI is unavailable, degrade gracefully — never fail silently.\n\n### Step 0: Probe the CLI\n\nRun `prospec --version` (Bash). When it is unavailable (not built / installed / linked),\nSTOP and tell the user to install or rebuild prospec, then re-run — never proceed silently.\n\n### Step 1: Run the deterministic upgrade\n\nRun `prospec upgrade --no-interactive` (Bash) and read its stdout. The `--no-interactive` flag is\nrequired: without it `prospec upgrade` prompts to fill nudges on a terminal, which would block this\nBash call — you drive those choices in-conversation (Steps 3–4) instead. It has already (a) recorded\nthe running prospec version in `.prospec.yaml` `version` (comment-preserving in-place merge), and\n(b) re-run `agent sync`. Parse the **Upgrade report**:\n- `version ` — the prospec version delta\n- `no artifact_language set …` — the project predates the artifact-language feature and never chose a\n language (Step 3). Mutually exclusive with the line below: an unset language resolves to English, so\n no triggers are reported missing.\n- `skills missing triggers: …` — newly-added skills with no localized triggers (Step 4)\n- `Docs inventory:` — one line per init-created doc, `✓ (template: )` when present or\n `✗ — MISSING (template: )` when absent, reported AFTER `prospec upgrade` back-filled the\n missing ones (so most read present), then a `created N missing doc(s): …` line naming what it just\n wrote. This section is Step 2's authoritative scan scope: it is derived from the same registry\n `prospec init` creates from, so it can never miss a file init would create. A line still marked\n MISSING means its back-fill failed — Step 2's safety net.\n\nIf `prospec upgrade` fails with `ConfigNotFound`, the project is not initialized — STOP and tell the\nuser to run `prospec init` first.\n\n### Step 2: Refresh init-created docs (inventory → enrich/diff → consent)\n\n`prospec upgrade` now BACK-FILLS any missing init doc (deterministic render, skip-if-exists) but never\ntouches an EXISTING one — updating a present doc's format, or enriching a freshly-created doc beyond its\nbaseline, requires consent. Do that here:\n\n1. **Locate the latest templates** shipped with the installed prospec version. **Source-repo\n short-circuit first**: if the project's own `package.json` `name` equals the prospec package name\n (`@benwu95/prospec`), the working directory IS the package root — use `.` and skip the resolution\n below. This is the dogfooding case; `require.resolve('@benwu95/prospec/package.json')` fails here\n because the package is absent from its own `node_modules` and the package has no `exports` field\n to enable Node self-referencing. Otherwise resolve the package root (e.g.\n `node -e \"console.log(require.resolve('@benwu95/prospec/package.json'))\"`, or check\n `node_modules/@benwu95/prospec`, or a global install via `npm root -g`). If `require.resolve`\n fails — a `pnpm link`/globally-linked install keeps the package outside the project's\n `node_modules` — derive the root from the running CLI instead: follow `$(which prospec)` (a\n shim/symlink to `/dist/cli/index.js`) back up to ``. All doc\n templates are language-neutral `.hbs` files under `src/templates/` (the package ships and\n loads them from `src/templates/`, not a root-level `templates/` — `tsc` does not copy `.hbs` into\n `dist/`). If the templates cannot be located, say so and SKIP this step (do not guess the latest\n format).\n2. **Take the scan scope from Step 1's `Docs inventory:` section** — every line names an init-created\n doc, its present/MISSING status, and its source template path. That list is the ONLY scan scope:\n do not keep, reconstruct, or fall back to a file list written into this skill. If the report has\n no `Docs inventory:` section, the installed CLI predates it (CLI/skill version mismatch) — STOP\n this step and tell the user to re-run `prospec upgrade` (which re-syncs this skill to match the\n CLI), then re-run `/prospec-upgrade`.\n3. **Index enrichment / migration**: `prospec upgrade` back-fills `{{base_dir}}/index.md` as a\n BASELINE — its module table is empty. Offer to populate that table from the current modules,\n and if `{{knowledge_base_path}}/_index.md` exists (a project from before the hierarchical-index\n move), migrate its curated content into that baseline: preserve any user notes in the\n `` block, and **copy both the Core/Demand Conventions lists and the\n curated `Modules` table rows verbatim** into the `prospec:auto` block — the Keywords / Aliases /\n Rationale / Depends On columns are human-curated and exist nowhere else. Do NOT run\n `prospec knowledge update` to rebuild the table: it fills only Module / Status / Description from\n `module-map.yaml` and blanks every curated column to `—`. Delete the old\n `{{knowledge_base_path}}/_index.md` after a successful migration.\n4. **Back-fill safety net** — `prospec upgrade` already created every doc it could (the report's\n `created …` line), so the inventory should show them present. For any doc the inventory **still\n marks MISSING** (its back-fill failed), offer to create it by rendering its listed template.\n Creating a file risks no authored content, but still **ask before each creation** and show what\n will be written; leave declined files uncreated.\n5. **For each doc the inventory marks present**, compare it to its listed template — compare the\n **format/structure** (severity tags, section markers), never the user's authored wording. For\n each file whose format has drifted, **show a diff and ask the user whether to update it** —\n migrate the FORMAT only, preserving authored content. Apply only the files the user approves;\n leave the rest unchanged.\n\n### Step 3: Offer to set an artifact language (only when unset)\n\nRun this step ONLY when Step 1's report shows `no artifact_language set` (a project scaffolded by a\npre-feature CLI — `prospec init` always writes the field). Skip it entirely otherwise; never re-ask a\nproject that already chose a language, including an explicit `English`.\n\n1. Tell the user their project has no `artifact_language`, so AI-generated documents currently default\n to **English**, and ask which language they want for AI-generated documents (default: English).\n2. **If they choose a non-English language**: capture `.prospec.yaml` verbatim as a snapshot, add the\n `artifact_language` key by a **minimal in-place edit** (insert the single key; never re-serialize or\n reorder), then read the file back to confirm it still parses — restore the snapshot if not. Every\n skill is now unlocalized, so Step 4 will localize them all.\n3. **If they keep English**: add `artifact_language: English` by the same minimal in-place edit (so this\n prompt is self-terminating on the next upgrade), then skip Step 4 — English uses the baseline\n triggers and needs no `skill_triggers`.\n\n### Step 4: Localize triggers for skills missing them (fill-missing) + re-sync\n\nRe-read `.prospec.yaml` (Step 3 may have just set the language). When `artifact_language` is non-English,\nlocalize every skill that still has **no `skill_triggers` entry** — that is Step 1's \"skills missing\ntriggers\" list, plus, when Step 3 just set the language, all skills. Skip entirely when the language is\nEnglish or every skill already has an entry.\n\n1. **Capture the current `.prospec.yaml` content verbatim** as a snapshot to restore from\n2. Translate ONLY those skills' English trigger baselines into `artifact_language`\n3. **Show the proposed translations and wait for confirmation** before writing anything\n4. On confirmation, add the new `skill_triggers` keys by a **minimal in-place edit** — insert only the\n missing keys; never re-serialize the file or touch existing keys, their order, or comments\n5. Read `.prospec.yaml` back and confirm it still parses as valid YAML; if not, restore the snapshot\n6. If anything changed in Step 2, Step 3, or Step 4, run `prospec agent sync` (Bash) so the language,\n localized triggers, and refreshed docs land in each SKILL.md frontmatter and the entry config\n\n## Output Contract\n\n{{> output-summary-note}}\n\n### Success Criteria\n- [ ] `prospec upgrade` ran and `.prospec.yaml` `version` equals the installed prospec version\n- [ ] every doc in the report's `Docs inventory:` was handled — present docs diffed against their listed template and updated only on consent, the docs `prospec upgrade` back-filled were enriched where needed (index module table / legacy `_index.md` migration) on consent, and any still-MISSING doc was offered for creation as a safety net (or templates were unavailable / the inventory section was absent, and the step was skipped with a note)\n- [ ] when the report flagged `no artifact_language set`, the user was asked which language to use and `artifact_language` was written to their choice (or they declined)\n- [ ] every skill in the report's \"missing triggers\" list (and all skills, when Step 3 just set a non-English language) is localized (or the user declined)\n- [ ] `prospec agent sync` ran when Step 2, Step 3, or Step 4 changed anything\n\n### Failure Conditions\n- updated an init-created file without showing a diff and getting confirmation\n- created a doc the inventory marked MISSING without asking first\n- scanned from a file list hardcoded in this skill instead of the report's `Docs inventory:`\n- set `artifact_language` (or wrote `skill_triggers`) without user confirmation\n- wrote malformed `artifact_language` or `skill_triggers` to `.prospec.yaml`\n- proceeded silently when the `prospec` CLI or its templates were unavailable\n\n### Output Summary\nEmit one line: `Met N/M | Unmet: | Overall: PASS|WARN|FAIL | Next: `\n\n## NEVER\n\n- **NEVER** update an init-created file without a diff preview AND explicit user confirmation — `prospec upgrade` never touches these, and the skill does so only with consent\n- **NEVER** create a doc the inventory marks MISSING without showing what will be written AND asking first\n- **NEVER** scan from a file list maintained inside this skill — the report's `Docs inventory:` (derived from init's own registry) is the only scan scope; a parallel list here drifts and re-opens the coverage gap\n- **NEVER** rewrite a doc's authored content/intent — migrate only its format/structure to the latest template\n- **NEVER** set or change `artifact_language` for a project that already has one — Step 3 runs only when the report flags it unset\n- **NEVER** set `artifact_language` without first asking the user which language they want\n- **NEVER** re-translate or overwrite an existing `skill_triggers` entry — localize only the skills with no entry yet\n- **NEVER** write `artifact_language` or `skill_triggers` without reading `.prospec.yaml` back to confirm it still parses\n- **NEVER** proceed silently when the `prospec` CLI or its templates are unavailable — stop or skip with a note, then let the user decide\n\n## Error Handling\n\n| Scenario | Action |\n|----------|--------|\n| `prospec` CLI unavailable | Stop; tell the user to install/rebuild prospec, then re-run — do not proceed silently |\n| `prospec upgrade` reports `ConfigNotFound` | Project not initialized — stop and instruct the user to run `prospec init` first |\n| prospec templates cannot be located | Skip Step 2 with a note; still do Step 3 (artifact language) and Step 4 (trigger localization) |\n| report has no `Docs inventory:` section | CLI/skill version mismatch — skip Step 2 with a note telling the user to re-run `prospec upgrade` (it re-syncs this skill), then re-run `/prospec-upgrade` |\n| User declines creating a still-MISSING doc | Leave it uncreated; the next `prospec upgrade` will attempt to back-fill it again |\n| `prospec agent sync` reports no configured agent | Stop and instruct the user to re-run `prospec init` or add an agent to `.prospec.yaml` |\n| `.prospec.yaml` fails to parse after writing `artifact_language` or triggers | Restore the captured pre-write snapshot verbatim, then report the malformed write |\n| User declines setting an artifact language | Leave `.prospec.yaml` unchanged and skip Step 4; the next upgrade will offer again |\n| User declines a doc-format update | Leave the file unchanged; record it as declined in the Output Summary |\n", + "skills/prospec-upgrade.hbs": "---\nname: prospec-upgrade\ndescription: \"{{skill_description}} Triggers: {{trigger_words}}\"\n---\n{{> generated-notice}}\n\n# Prospec Upgrade Skill\n\n## Activation\n\nWhen triggered, briefly describe:\n- That `prospec upgrade` has recorded the new prospec version in `.prospec.yaml` and re-synced agents, and you'll finish the judgment steps it cannot do deterministically\n- You'll work through the report's docs inventory (every file `prospec init` creates): `prospec upgrade` has already back-filled any that were missing, so you offer to update any whose format has drifted from the latest templates and to enrich the docs it just created that need more than a baseline (e.g. the index's real module table) — asking before each change — plus, as a safety net, create any still marked missing; offer to set an artifact language if the project never chose one (a project from a pre-feature CLI); and localize triggers for skills that have none\n- This is a periodic upgrade flow — re-runnable and self-terminating\n\n## Language Policy\n\nWrite generated documents in the language defined by the Constitution's Language Policy rule. Keep code, identifiers, technical terms, and git commit messages in English.\n\n## Startup Loading\n\n1. [DYNAMIC] Read `.prospec.yaml` — `version`, `artifact_language`, and `skill_triggers` drive the steps below\n\n## Core Workflow\n\n> This skill shells out to the `prospec` CLI (Bash), mirroring `prospec-quickstart`.\n> When the CLI is unavailable, degrade gracefully — never fail silently.\n\n### Step 0: Probe the CLI\n\nRun `prospec --version` (Bash). When it is unavailable (not built / installed / linked),\nSTOP and tell the user to install or rebuild prospec, then re-run — never proceed silently.\n\n### Step 1: Run the deterministic upgrade\n\nRun `prospec upgrade --no-interactive` (Bash) and read its stdout. The `--no-interactive` flag is\nrequired: without it `prospec upgrade` prompts to fill nudges on a terminal, which would block this\nBash call — you drive those choices in-conversation (Steps 3–4) instead. It has already (a) recorded\nthe running prospec version in `.prospec.yaml` `version` (comment-preserving in-place merge), and\n(b) re-run `agent sync`. Parse the **Upgrade report**:\n- `version ` — the prospec version delta\n- `no artifact_language set …` — the project predates the artifact-language feature and never chose a\n language (Step 3). Mutually exclusive with the line below: an unset language resolves to English, so\n no triggers are reported missing.\n- `skills missing triggers: …` — newly-added skills with no localized triggers (Step 4)\n- `Docs inventory:` — one line per init-created doc, `✓ (template: )` when present or\n `✗ — MISSING (template: )` when absent, reported AFTER `prospec upgrade` back-filled the\n missing ones (so most read present), then a `created N missing doc(s): …` line naming what it just\n wrote. This section is Step 2's authoritative scan scope: it is derived from the same registry\n `prospec init` creates from, so it can never miss a file init would create. A line still marked\n MISSING means its back-fill failed — Step 2's safety net.\n\nIf `prospec upgrade` fails with `ConfigNotFound`, the project is not initialized — STOP and tell the\nuser to run `prospec init` first.\n\n### Step 2: Refresh init-created docs (inventory → enrich/diff → consent)\n\n`prospec upgrade` now BACK-FILLS any missing init doc (deterministic render, skip-if-exists) but never\ntouches an EXISTING one — updating a present doc's format, or enriching a freshly-created doc beyond its\nbaseline, requires consent. Do that here:\n\n1. **Retrieve the latest templates** shipped with the installed prospec version. **Source-repo\n short-circuit first**: if the project's own `package.json` `name` equals the prospec package name\n (`@benwu95/prospec`), the working directory IS the package root — read the templates directly from\n `src/templates/` and skip the CLI call below (dogfooding case). Otherwise, retrieve the template\n content directly by running the CLI command:\n `prospec print-template ` (Bash).\n For example, to get the template for `init/constitution.md.hbs`, run `prospec print-template init/constitution.md.hbs`.\n If the template cannot be retrieved, say so and SKIP this step (do not guess the latest format).\n2. **Take the scan scope from Step 1's `Docs inventory:` section** — every line names an init-created\n doc, its present/MISSING status, and its source template path. That list is the ONLY scan scope:\n do not keep, reconstruct, or fall back to a file list written into this skill. If the report has\n no `Docs inventory:` section, the installed CLI predates it (CLI/skill version mismatch) — STOP\n this step and tell the user to re-run `prospec upgrade` (which re-syncs this skill to match the\n CLI), then re-run `/prospec-upgrade`.\n3. **Index enrichment / migration**: `prospec upgrade` back-fills `{{base_dir}}/index.md` as a\n BASELINE — its module table is empty. Offer to populate that table from the current modules,\n and if `{{knowledge_base_path}}/_index.md` exists (a project from before the hierarchical-index\n move), migrate its curated content into that baseline: preserve any user notes in the\n `` block, and **copy both the Core/Demand Conventions lists and the\n curated `Modules` table rows verbatim** into the `prospec:auto` block — the Keywords / Aliases /\n Rationale / Depends On columns are human-curated and exist nowhere else. Do NOT run\n `prospec knowledge update` to rebuild the table: it fills only Module / Status / Description from\n `module-map.yaml` and blanks every curated column to `—`. Delete the old\n `{{knowledge_base_path}}/_index.md` after a successful migration.\n4. **Back-fill safety net** — `prospec upgrade` already created every doc it could (the report's\n `created …` line), so the inventory should show them present. For any doc the inventory **still\n marks MISSING** (its back-fill failed), offer to create it by rendering its listed template.\n Creating a file risks no authored content, but still **ask before each creation** and show what\n will be written; leave declined files uncreated.\n5. **For each doc the inventory marks present**, compare it to its listed template — compare the\n **format/structure** (severity tags, section markers), never the user's authored wording. For\n each file whose format has drifted, **show a diff and ask the user whether to update it** —\n migrate the FORMAT only, preserving authored content. Apply only the files the user approves;\n leave the rest unchanged.\n\n### Step 3: Offer to set an artifact language (only when unset)\n\nRun this step ONLY when Step 1's report shows `no artifact_language set` (a project scaffolded by a\npre-feature CLI — `prospec init` always writes the field). Skip it entirely otherwise; never re-ask a\nproject that already chose a language, including an explicit `English`.\n\n1. Tell the user their project has no `artifact_language`, so AI-generated documents currently default\n to **English**, and ask which language they want for AI-generated documents (default: English).\n2. **If they choose a non-English language**: capture `.prospec.yaml` verbatim as a snapshot, add the\n `artifact_language` key by a **minimal in-place edit** (insert the single key; never re-serialize or\n reorder), then read the file back to confirm it still parses — restore the snapshot if not. Every\n skill is now unlocalized, so Step 4 will localize them all.\n3. **If they keep English**: add `artifact_language: English` by the same minimal in-place edit (so this\n prompt is self-terminating on the next upgrade), then skip Step 4 — English uses the baseline\n triggers and needs no `skill_triggers`.\n\n### Step 4: Localize triggers for skills missing them (fill-missing) + re-sync\n\nRe-read `.prospec.yaml` (Step 3 may have just set the language). When `artifact_language` is non-English,\nlocalize every skill that still has **no `skill_triggers` entry** — that is Step 1's \"skills missing\ntriggers\" list, plus, when Step 3 just set the language, all skills. Skip entirely when the language is\nEnglish or every skill already has an entry.\n\n1. **Capture the current `.prospec.yaml` content verbatim** as a snapshot to restore from\n2. Translate ONLY those skills' English trigger baselines into `artifact_language`\n3. **Show the proposed translations and wait for confirmation** before writing anything\n4. On confirmation, add the new `skill_triggers` keys by a **minimal in-place edit** — insert only the\n missing keys; never re-serialize the file or touch existing keys, their order, or comments\n5. Read `.prospec.yaml` back and confirm it still parses as valid YAML; if not, restore the snapshot\n6. If anything changed in Step 2, Step 3, or Step 4, run `prospec agent sync` (Bash) so the language,\n localized triggers, and refreshed docs land in each SKILL.md frontmatter and the entry config\n\n## Output Contract\n\n{{> output-summary-note}}\n\n### Success Criteria\n- [ ] `prospec upgrade` ran and `.prospec.yaml` `version` equals the installed prospec version\n- [ ] every doc in the report's `Docs inventory:` was handled — present docs diffed against their listed template and updated only on consent, the docs `prospec upgrade` back-filled were enriched where needed (index module table / legacy `_index.md` migration) on consent, and any still-MISSING doc was offered for creation as a safety net (or templates were unavailable / the inventory section was absent, and the step was skipped with a note)\n- [ ] when the report flagged `no artifact_language set`, the user was asked which language to use and `artifact_language` was written to their choice (or they declined)\n- [ ] every skill in the report's \"missing triggers\" list (and all skills, when Step 3 just set a non-English language) is localized (or the user declined)\n- [ ] `prospec agent sync` ran when Step 2, Step 3, or Step 4 changed anything\n\n### Failure Conditions\n- updated an init-created file without showing a diff and getting confirmation\n- created a doc the inventory marked MISSING without asking first\n- scanned from a file list hardcoded in this skill instead of the report's `Docs inventory:`\n- set `artifact_language` (or wrote `skill_triggers`) without user confirmation\n- wrote malformed `artifact_language` or `skill_triggers` to `.prospec.yaml`\n- proceeded silently when the `prospec` CLI or its templates were unavailable\n\n### Output Summary\nEmit one line: `Met N/M | Unmet: | Overall: PASS|WARN|FAIL | Next: `\n\n## NEVER\n\n- **NEVER** update an init-created file without a diff preview AND explicit user confirmation — `prospec upgrade` never touches these, and the skill does so only with consent\n- **NEVER** create a doc the inventory marks MISSING without showing what will be written AND asking first\n- **NEVER** scan from a file list maintained inside this skill — the report's `Docs inventory:` (derived from init's own registry) is the only scan scope; a parallel list here drifts and re-opens the coverage gap\n- **NEVER** rewrite a doc's authored content/intent — migrate only its format/structure to the latest template\n- **NEVER** set or change `artifact_language` for a project that already has one — Step 3 runs only when the report flags it unset\n- **NEVER** set `artifact_language` without first asking the user which language they want\n- **NEVER** re-translate or overwrite an existing `skill_triggers` entry — localize only the skills with no entry yet\n- **NEVER** write `artifact_language` or `skill_triggers` without reading `.prospec.yaml` back to confirm it still parses\n- **NEVER** proceed silently when the `prospec` CLI or its templates are unavailable — stop or skip with a note, then let the user decide\n\n## Error Handling\n\n| Scenario | Action |\n|----------|--------|\n| `prospec` CLI unavailable | Stop; tell the user to install/rebuild prospec, then re-run — do not proceed silently |\n| `prospec upgrade` reports `ConfigNotFound` | Project not initialized — stop and instruct the user to run `prospec init` first |\n| `prospec print-template` fails to retrieve a template | Skip Step 2 with a note; still do Step 3 (artifact language) and Step 4 (trigger localization) |\n| report has no `Docs inventory:` section | CLI/skill version mismatch — skip Step 2 with a note telling the user to re-run `prospec upgrade` (it re-syncs this skill), then re-run `/prospec-upgrade` |\n| User declines creating a still-MISSING doc | Leave it uncreated; the next `prospec upgrade` will attempt to back-fill it again |\n| `prospec agent sync` reports no configured agent | Stop and instruct the user to re-run `prospec init` or add an agent to `.prospec.yaml` |\n| `.prospec.yaml` fails to parse after writing `artifact_language` or triggers | Restore the captured pre-write snapshot verbatim, then report the malformed write |\n| User declines setting an artifact language | Leave `.prospec.yaml` unchanged and skip Step 4; the next upgrade will offer again |\n| User declines a doc-format update | Leave the file unchanged; record it as declined in the Output Summary |\n", "skills/prospec-verify.hbs": "---\nname: prospec-verify\ndescription: \"{{skill_description}} Triggers: {{trigger_words}}\"\n---\n{{> generated-notice}}\n\n# Prospec Verify Skill\n\n## Activation\n\nWhen triggered, briefly describe:\n- That you'll perform a comprehensive audit of the implementation\n- All 5+1 verification dimensions will be checked (task completion, spec compliance, Constitution full audit, Knowledge ↔ implementation consistency, tests, and design consistency if UI scope applies)\n- A quality grade (S/A/B/C/D) with deployment recommendation will be provided\n\n## Startup Loading\n\n1. [STABLE] Read `{{constitution_path}}` — for full audit\n2. [DYNAMIC] Read `.prospec/changes/[name]/tasks.md` — task completion status\n3. [DYNAMIC] Read `.prospec/changes/[name]/plan.md` — design intent (**skip for `scale: quick`/`backfill`** — no plan by contract)\n4. [DYNAMIC] Read `.prospec/changes/[name]/delta-spec.md` — file specifications (**skip for `scale: quick`** — no delta-spec by contract; 2/5 is `not-applicable`)\n5. [DYNAMIC] Read `.prospec/changes/[name]/proposal.md` — acceptance scenarios\n6. [DYNAMIC] Read `.prospec/changes/[name]/metadata.yaml` — current status (updated on pass; see Status Update)\n7. [DYNAMIC] Read `{{base_dir}}/specs/features/` — load relevant Feature Specs for consistency check (**skip for `scale: quick`** — no delta-spec REQs to compare)\n8. [DYNAMIC] Read `{{base_dir}}/specs/product.md` — understand product-level overview\n9. [DYNAMIC] Run `prospec check --json` (Bash) and read `prospec-report.json` — deterministic structural facts for Verification 1/5 and 4/5 (the same engine the CI gate runs). If the command is unavailable (not built/installed), state **\"drift engine unavailable — falling back to manual checks\"** and continue with the documented fallbacks; never fall back silently\n\n> **Scale-aware execution (`metadata.scale: quick`)** — a quick change is genuinely lighter here, not just relabeled: skip Startup Loading items 3, 4, and 7 (plan/delta-spec/Feature-Spec-comparison — absent or moot by contract), run dimension 2/5 as `not-applicable` (spec impact is re-checked against the actual diff at the `/prospec-archive` Entry Gate), and emit the **condensed report** below (omit the `not-applicable` dimension's detail block). The dimensions that genuinely apply to a quick change (1/5 tasks, 3/5 Constitution, 4/5 Knowledge, 5/5 tests) still run in full — this trims ceremony, never a dimension that applies. `standard`/`full` run every item above.\n\n{{> knowledge-loading-rules}}\n\n**Principles (Verify-specific):**\n- **L2** loads more modules than other skills (all affected modules, not just the current task's module), specifically **during Verification 2/5 and 4/5** to perform a comprehensive cross-module check and compare spec against knowledge.\n- **L3** is loaded **during Verification 2/5** to verify implementation matches spec and find evidence for PASS/FAIL judgments.\n\n## Key Difference from Other Skills\n\nVerify is the **sole** station that performs a Constitution **full audit** (every principle checked). Every other **SDD-pipeline** skill (new-story → plan → tasks → implement → review → archive, plus periodic learn) checks only its **site-specific** rule — new-story→INVEST, plan→dependency/layering, tasks→TDD coverage, implement→TDD/commit, review→dependency/layering, learn→promotion-approval — never a generic multi-principle scan. (The pre-SDD `/prospec-explore` thinking-partner keeps its own advisory multi-principle Constitution Checkpoint — it is a decision aid, not a verification gate.) Converging the every-principle audit to this one station is why verify's Constitution audit is the one that gates.\n\n## Entry Gate\n\n> Blocking precondition check before this skill runs. If any item FAILs, stop and tell the user what is missing — do not proceed.\n\n- All planning artifacts exist: proposal.md, plan.md, delta-spec.md, tasks.md. **Exception — `metadata.scale: quick`**: only proposal.md + tasks.md are required (a quick change legitimately has no plan/delta-spec). **Exception — `metadata.scale: backfill`**: only proposal.md + delta-spec.md are required (a backfill change records existing code — there is no forward plan and no task list; do not FAIL on their absence).\n- Implementation is done: metadata status is `implemented` and tasks.md **code-task** checkboxes are complete (unchecked `[M]`/`[V]` tasks do not block; kind schema: tasks-format reference); if still `tasks`, FAIL and point to `/prospec-implement`. **`metadata.scale: backfill`** has no tasks.md — `status: implemented` (set by `/prospec-promote-backfill`) satisfies this item; the brownfield code already exists.\n- Prior unresolved WARN: read `metadata.yaml` `quality_log` and surface any unresolved WARN from earlier stages (including `/prospec-review` majors).\n- **`metadata.scale: backfill` provenance** (gates the backfill quality relaxations in 3/5 and 5/5): `scale` is plain, hand-editable metadata, so the marker alone does not prove the code is pre-existing. The backfill downgrades apply **only** when `.prospec/changes/[name]/backfill-draft.md` exists — proof the change came through `/prospec-promote-backfill`, which records *existing* brownfield behavior. If the draft is **absent**, grade 3/5 and 5/5 under the **standard** contract (a code-quality `[MUST]` violation → FAIL, missing tests → graded normally) and record a WARN: \"`scale: backfill` claimed but no `backfill-draft.md` — graded as standard\". This keeps `scale: backfill` from becoming a quality-gate bypass for new code.\n\n- **Review provenance (blocking, non-backfill)**: run `prospec check --json` and read the `review-provenance` check for this change. If it is **FAIL** — no review recorded, or the recorded review is **stale** (code changed since the review) — **stop and do not proceed**; point the user to `/prospec-review` to review the current code. This makes review non-skippable before verify: verify grades contract compliance, not adversarial correctness, so an unreviewed change must not reach an S/A grade. **Drift engine unavailable** (CLI not installed/built): state so, then fall back to the CLI-free signal — read `metadata.yaml` `quality_log` directly and **still block when there is no `prospec-review` entry** (absence needs no engine to detect); staleness cannot be machine-verified without the engine, so surface it as a WARN that relies on whether code changed since that entry — never silently pass.\n- **`scale: backfill` review exemption (non-blocking)**: the backfill path has no review station, so `review-provenance` skips it — verify does NOT block on a missing review for `scale: backfill`. Running `/prospec-review` first stays recommended but optional.\n\n## Core Workflow\n\n### Verification 1/5: Task Completion\n\n**Data source — drift engine first**: when the `prospec check --json` report is available, take\nthe code-task completion facts from its `task-completion` check (findings carry file + line per\nunchecked code task) — do not recount by hand; cite the report. Only when the engine is\nunavailable, fall back to parsing tasks.md manually and say so. A report check with status\n`skipped` provides no facts — it is never treated as complete or PASS.\n\n**`metadata.scale: backfill`**: this dimension is `not-applicable` — a backfill change has no\ntasks.md (it records existing code, there is nothing to schedule). Report it as `not-applicable`\n(NEVER as PASS — an unchecked dimension must not look checked); it does not enter the grade.\n\nThe completion denominator counts **code tasks only** (unmarked tasks; kind schema frozen in the\ntasks-format reference): `[M]` manual and `[V]` verification tasks are listed separately and\nnever counted in the rate.\n- 100% of code tasks → PASS\n- < 100% → WARN (list uncompleted code tasks)\n- Unchecked `[M]`/`[V]` tasks → listed as reminders, not graded\n\n### Verification 2/5: Delta Spec Compliance\n\n**`metadata.scale: quick`**: this dimension is `not-applicable` — there is no delta-spec to\ncompare against. Report it as `not-applicable` (NEVER as PASS — an unchecked dimension must not\nlook checked); it does not enter the grade. Spec impact is re-checked against the actual diff\nat the `/prospec-archive` Entry Gate.\n\n**`metadata.scale: backfill`**: this dimension is the **primary graded dimension** — a backfill\nchange documents *existing* code, so the grade turns on **spec-fidelity**, not new-code quality.\nVerify every delta-spec REQ's Acceptance Criteria against the cited evidence: the AC resolves to\nreal code at its `file:line` → PASS; the cited code does not exist or contradicts the AC → FAIL;\nan AC with **no `file:line` evidence** to check → WARN/FAIL — **NEVER an empty PASS** (unverifiable\nfidelity is not fidelity). Grade S/A here means \"the spec faithfully reflects the code\".\n\nOtherwise, compare each file specification in delta-spec.md:\n- New files exist\n- Modified files contain expected changes\n- API endpoints match specifications\n- Type definitions are complete\n\nMark each item PASS / WARN / FAIL.\n\n### Verification 3/5: Constitution Full Audit\n\nCheck **every principle** in the Constitution:\n- Find **evidence** from implementation code and planning documents\n- Mark PASS / WARN / FAIL with score (1-5)\n- **Severity-graded**: when a principle carries an RFC-2119 tag (`[MUST]` / `[SHOULD]` / `[MAY]`), map a violation by weight — **MUST → FAIL**, **SHOULD → WARN**; a **MAY** is advisory, so a violation is an informational note that does NOT affect the grade (grade vocabulary stays PASS/WARN/FAIL). When the Constitution is free-text without severity tags, fall back to judgment-based PASS/WARN/FAIL (backward-compatible). A rule's `Verify` hint guides the check (mechanically-checkable rules use it directly; others are interpretive).\n- **`metadata.scale: backfill`** (only when the Entry Gate's backfill provenance check passed — `backfill-draft.md` present): a `[MUST]` **code-quality** violation the backfill did not introduce — the existing brownfield code lacks tests, falls below coverage, or pre-dates a layering rule — is recorded as an **informational tech-debt note**, explicitly \"pre-existing, not introduced by this backfill\", and **does NOT lower the grade**. Backfill documents existing behavior; it is not a new-code quality gate. A `[MUST]` the backfill artifact itself can satisfy (document language, no fabricated intent, INVEST of the reverse-extracted story) still applies normally.\n- FAIL items must include specific remediation steps\n- **Call Chain ↔ layering**: if `plan.md` declares a Call Chain, confirm the implementation matches it and introduces no layering violation against the Constitution's dependency/layering rule (a layer reaching past its neighbor, business logic in the entry/transport layer, a skipped data-access layer, or a side effect emitted before commit). Plan-declared clean layering but dirty implementation → FAIL.\n\n### Verification 4/5: Knowledge ↔ Implementation Consistency\n\nThis dimension **grades only pre-existing Knowledge drift** — NOT whether Knowledge or the permanent Feature Spec already reflects this (still-unarchived) change. Feature Specs graduate at `/prospec-archive` Phase 3.5; module-README Knowledge is synced at the `/prospec-verify` S/A commit prompt (the archive Entry Gate re-confirms it as a **backstop**). Lag behind this change during grading is normal — it is synced at the S/A commit prompt that follows — **not drift**, and must NOT lower the grade.\n\n**Structural freshness facts come from the drift engine**: when the `prospec check --json`\nreport is available, its `knowledge_health` section (git-timestamp staleness per module +\nREADME coverage) is the factual base for this dimension — cite it instead of re-deriving\nfreshness by hand. The semantic judgments below (does the README describe behavior the code\ndoes not have?) remain LLM work layered on those facts. Engine unavailable → state the\nfallback explicitly. A `skipped` knowledge-health check is never presented as PASS.\n\n**Graded — pre-existing Knowledge vs current code** (`{{knowledge_base_path}}/modules/`):\n- **PASS**: each affected module's README.md accurately describes the code this change did not touch (no stale APIs, no wrong descriptions)\n- **WARN**: README exists but is vague or outdated vs code outside this change's scope\n- **FAIL**: README describes behavior the codebase does not have, beyond this change's lag — or a module that existed before this change has no README at all (remediate: `/prospec-knowledge-update`, or `/prospec-knowledge-generate` for the missing README)\n\n**This change's Knowledge lag — informational only (does NOT affect the grade):**\n- A delta-spec ADDED/MODIFIED REQ not yet described — or a REMOVED REQ's behavior still described — in the affected module's README → informational note listing the affected modules; synced at the S/A commit prompt below (run `/prospec-knowledge-update`, folded into the feature commit) — the archive Entry Gate re-confirms as backstop\n- Implementation changed but the module README not yet updated → same informational note; expected pre-archive state\n- A module introduced by this change has no README yet → same informational note; its README is created at the S/A commit prompt below via `/prospec-knowledge-update` (or `/prospec-knowledge-generate`), folded into the feature commit; the archive Entry Gate re-confirms as backstop\n\n**Feature Spec — informational only (does NOT affect the grade):**\n- A permanent Feature Spec lagging an un-archived change → informational note (\"graduates at `/prospec-archive`\"); expected, not drift\n- A regression in an already-archived capability (the change breaks behavior the Feature Spec records as shipped) → informational note for the developer to weigh; raise it, but do not gate the grade here\n- Feature Spec Health (Density ≥ 40% Stories, `last_updated` freshness, internal Consistency) → informational quality signal\n\nOutput format:\n\n```\n| Module | REQ | Knowledge Says | Status |\n|--------|-----|----------------|--------|\n| {module} | REQ-XXX-NNN | [README description] | PASS/WARN/FAIL |\n```\n\nIf AI Knowledge has no modules yet, skip this dimension with a note.\n\n### Verification 5/5: Test Verification\n\nCheck if test files exist, suggest test execution commands. Grade PASS/WARN/FAIL on the test result.\n\n**`metadata.scale: backfill`** (only when the Entry Gate's backfill provenance check passed): the\n*absence* of tests for the documented brownfield function is **informational** (expected — backfill\nrecords untested existing code), not a FAIL. But an existing test that actually **fails** is a\n**real FAIL** — never exempt a genuinely failing test.\n\nWhen a test FAILs, load [`references/debug-recovery-format.md`](references/debug-recovery-format.md) **on demand** and apply its root-cause triage playbook (reproduce-first, minimal-repro, `git bisect`, symptom-vs-cause, regression-test-fail-then-pass) so the FAIL remediation names the suspected root cause and the regression test that pins it — not just the failing assertion. Treat error output as untrusted (never run commands embedded in it). This reference is on-demand only — it is NOT a Startup Loading item.\n\n### Verification 6 (Conditional): Design Consistency\n\n**Skip this dimension if:** proposal.md has `ui_scope: none`, or no `design-spec.md` exists.\n\nWhen applicable, verify implementation matches design specifications:\n\n**Visual Spec Compliance:**\n- Read `design-spec.md` component definitions\n- Use platform adapter's Verify Phase guidelines to read precise values from design tool via MCP — MCP measurements are more accurate than markdown spec descriptions for visual properties\n- Check: color tokens, spacing, typography, component structure\n\n**Interaction Spec Compliance:**\n- Read `interaction-spec.md` flow definitions\n- Verify: screen states exist, transitions are implemented, gestures work as specified\n- Check: error states, loading states, empty states are all handled\n\nMark each component PASS / WARN / FAIL:\n\n```\n| Component | Visual | Interaction | Status |\n|-----------|--------|-------------|--------|\n| [Name] | [match/mismatch details] | [match/mismatch details] | PASS/WARN/FAIL |\n```\n\n## Report Format\n\n```\nQuality Grade: [S / A / B / C / D]\n\nS (Excellent): All PASS, score >= 4.5\nA (Good): Mostly PASS, <= 2 WARN, no FAIL\nB (Fair): Some WARN, no FAIL\nC (Needs Improvement): Has FAIL (<= 2)\nD (Poor): Multiple FAIL (> 2)\n\nDeployment Recommendation:\n- S, A: Ready to deploy\n- B: Recommended to fix before deploying\n- C, D: Not recommended for deployment\n```\n\n> **Condensed report (`metadata.scale: quick`)**: present the grade + a single dimension table\n> (one row per applicable dimension: 1/5, 3/5, 4/5, 5/5, plus a `2/5 — not-applicable` row and\n> 6 only when `ui_scope != none`) instead of the full per-dimension prose blocks. Same grade, same\n> evidence-per-row rule — fewer sections, matched to a small change.\n\n## Status Update\n\nAfter grading, update `.prospec/changes/[name]/metadata.yaml`:\n\n- **Grade S or A** (Ready to deploy — no FAIL, ≤ 2 WARN) → set `status: verified`. This is the gate `/prospec-archive` looks for.\n- **Grade B / C / D** → **leave `status` unchanged**; state in the report that the change is NOT verified, list the WARN/FAIL items to resolve, then re-run `/prospec-verify` after fixing.\n\n`verified` means S/A only — WARN-heavy (B) or FAIL (C/D) changes do not graduate. Full lifecycle (`implemented → verified`): `{{knowledge_base_path}}/_status-lifecycle.md`.\n\n**Record the verify result to `quality_log` (structured).** Append one `skill: prospec-verify` entry to `metadata.yaml` `quality_log` carrying:\n- `grade` — the S/A/B/C/D quality grade (structured, machine-aggregatable);\n- `dimensions` — one `{ name, result }` per graded 5+1 dimension (each `PASS`/`WARN`/`FAIL`; omit a `not-applicable` dimension);\n- `result` — the gate three-state (`PASS` at grade S/A, else `WARN`/`FAIL`); **never overwrite `result` with the grade** — the grade lives in `grade`;\n- `warnings` — any WARN/FAIL detail strings.\n\nThe `metadata-completeness` drift check reads only `grade` (`hasVerifyGrade` accepts `grade` ∈ {S,A}); `dimensions` and the review counts are not read by any check — together with `grade` they make quality trends aggregatable across archives.\n\n> **`metadata.scale: backfill`**: grade S/A means the spec is **faithful to the code** (fidelity),\n> reached on the spec-fidelity contract in 2/5 — pre-existing code-quality debt (3/5) and missing\n> brownfield tests (5/5) are informational, not grade inputs. The `verified` gate is unchanged; the\n> commit-prompt Knowledge-sync step below applies but **defers module derivation to the archive\n> Entry Gate** (see its `scale: backfill` exception — feature-slug REQ ids are not module names).\n\n**Commit prompt (S/A only)**: reaching S/A is the commit boundary — the last gate that can require code changes. Because no further code changes follow, this is the point to fold derived-artifact sync **into the feature commit** rather than deferring it to archive:\n\n1. **Sync affected-module Knowledge** — run `/prospec-knowledge-update` for the modules this change touched so each module README reflects the final code. Update descriptions only; do **not** cite this change's not-yet-graduated REQ ids (they graduate at `/prospec-archive` Phase 3.5 — citing them now trips `prospec check` `req-references`). **`scale: backfill` exception**: do **not** run REQ-prefix-driven `/prospec-knowledge-update` here — its feature-slug REQ ids (`REQ-{FEATURE-SLUG}-NNN`) are not module names and would mint phantom modules; sync only the READMEs named by `metadata.related_modules` (by description), leaving module derivation to the archive Entry Gate (`related_modules`/`**Feature:**`→feature-map).\n2. **Re-derive factual counts** — if the project has a factual-count generator (a script/command that regenerates the counts its docs declare), run it; otherwise re-derive those counts from source. (This repo's generator is named in its contributor docs.)\n3. **Prompt the user to commit** the change as a single atomic-by-feature commit that folds the implement, review, and verify fixes **plus the sync from steps 1–2** together. **Do not commit automatically** — prospec only prompts; the user runs the commit. This S/A boundary is the change's **single commit point** — implement never commits (see `/prospec-implement`), so the whole change lands as one commit here.\n\nBecause the sync lands in the same commit and no code changes follow S/A, the feature commit already carries synced Knowledge — a source-only commit no longer flips `knowledge-health` stale. The `/prospec-archive` Entry Gate re-confirms this as a **backstop**.\n\n> The **grade** still does not gate on Feature Spec freshness or this change's Knowledge lag — 4/5 stays informational; grading and the commit-prep sync above are separate axes. Feature Specs still graduate only at `/prospec-archive` Phase 3.5 (verify never writes them — deadlock avoidance); module-README Knowledge is synced at the commit prompt above, with the archive Entry Gate as backstop. Verify gates on code↔delta-spec (2/5), Constitution (3/5), and pre-existing Knowledge↔code drift (4/5).\n\n## Knowledge Quality Gate\n\nFinal Knowledge consistency summary:\n\n| Check Item | PASS | WARN |\n|------------|------|------|\n| No pre-existing Knowledge drift | Module READMEs accurate for code outside this change's scope | Drift identified in Verification 4/5 — suggest `/prospec-knowledge-update` |\n| No undocumented features | Knowledge entries trace to a delta-spec REQ or shipped behavior | Features in Knowledge without any requirement |\n| This change's Knowledge sync | Informational — synced at the verify S/A commit prompt (archive Entry Gate re-confirms as backstop); not gated here | — |\n| Feature Spec graduation | Informational — Feature Specs update at `/prospec-archive`; not gated here | — |\n\nWARN items are deployment risks — recommend resolving before `/prospec-archive`.\n\n## Output Contract\n\n{{> output-summary-note}}\n\n### Success Criteria\n- [ ] all applicable dimensions executed (6 dimension sections for standard/full; `scale: quick` uses the condensed table — one row per applicable dimension, 2/5 shown as `not-applicable`, 6 only when `ui_scope != none`)\n- [ ] each dimension graded PASS/WARN/FAIL with evidence (manual)\n- [ ] status updated per grade (S/A -> verified)\n- [ ] FAIL items include remediation steps\n\n### Failure Conditions\n- a dimension skipped, or a PASS without an evidence reference (manual)\n- status: verified set for grade B/C/D\n\n### Output Summary\nEmit one line: `Met N/M | Unmet: | Overall: PASS|WARN|FAIL | Next: `\n\n### Exit Gate (Constitution)\n\nVerify the output against the Constitution. When rules carry RFC-2119 severity (BL-031), grade by weight — MUST→FAIL, SHOULD→WARN, MAY→informational (the grade vocabulary stays PASS/WARN/FAIL). A free-text Constitution falls back to judgment-based grading. Fold each WARN/FAIL into the same `prospec-verify` `quality_log` entry written in Status Update (`skill` / `date` / `result` / `warnings`, plus the structured `grade` / `dimensions`) — one entry per verify run, not a second one. Advisory — surface issues, do not hard-block.\n\n## NEVER\n\n- **NEVER** only spot-check the Constitution — Verify's core distinction from other Skills is full audit; spot-checking defeats the purpose of a dedicated verification phase\n- **NEVER** give PASS without supporting evidence — unsubstantiated PASS creates false confidence; evidence ensures the assessment is reproducible\n- **NEVER** give FAIL without remediation steps — a FAIL without fix guidance blocks the user; they need actionable next steps to resolve\n- **NEVER** skip any verification dimension — each dimension catches different defect classes; skipping one leaves a blind spot in quality assurance\n- **NEVER** proceed on a non-backfill change whose `review-provenance` check FAILs (review absent or stale) — the review gate keeps an S/A grade from resting on unreviewed code; send the user to `/prospec-review` instead of grading\n- **NEVER** continue verification when planning documents are missing — verifying against incomplete specs produces meaningless results and wastes tokens (`scale: quick` legitimately omits plan/delta-spec and 2/5 reports `not-applicable`; `scale: backfill` legitimately omits plan/tasks and 1/5 reports `not-applicable` — these are the only exceptions)\n- **NEVER** report a `not-applicable` dimension as PASS — quick's missing delta-spec dimension stays visibly unchecked\n- **NEVER** treat a drift-report `skipped` check as PASS — skipped means unchecked; present the skip reason instead\n- **NEVER** fall back from the drift engine silently — engine unavailable must be stated in the report before manual checks proceed\n- **NEVER** make subjective assessments — subjective grades vary between sessions; evidence-based scoring ensures consistency across verifications\n- **NEVER** ignore FAIL items and give \"ready to deploy\" — FAIL items represent unmet specifications that will surface as production bugs\n- **NEVER** set `status: verified` for grade B / C / D — only S/A (Ready to deploy) graduate; a lower gate lets unmet WARN/FAIL items reach `/prospec-archive`\n- **NEVER** let a pre-existing code-quality violation the backfill did not introduce (missing tests, low coverage, legacy layering) lower a `scale: backfill` grade — record it as informational tech debt; backfill documents existing behavior, it is **not a new-code quality gate**\n- **NEVER** exempt a `scale: backfill` delta-spec REQ whose cited `file:line` does not resolve, nor an existing test that actually fails — under backfill, **fidelity and real test failures stay hard** signals\n- **NEVER** apply the `scale: backfill` quality relaxations without the Entry Gate's provenance check (`backfill-draft.md` present) — the `scale` marker is self-attested, hand-editable metadata; an unproven backfill is graded as **standard** so it cannot bypass the tested-functions gate for new code\n\n## Error Handling\n\n| Scenario | Action |\n|----------|--------|\n| Planning documents missing | Confirm change has gone through Story → Plan → Tasks → Implement workflow |\n| `prospec check` unavailable or fails | State \"drift engine unavailable — falling back to manual checks\" in the report, then run the manual fallbacks for 1/5 and 4/5 |\n| Constitution file read fails | Skip Constitution audit, but clearly mark in report |\n| Implementation severely mismatches spec | Pause verification, suggest updating spec or fixing implementation |\n\n{{> next-step-handoff}}\n", "skills/references/adapter-figma.hbs": "# Platform Adapter: Figma\n\nDesign tool adapter for Figma, using html-to-figma MCP for design creation and Figma MCP for reading.\n\n**Requires:** `html-to-figma` MCP server and/or `figma` MCP server configured in `.mcp.json`\n\n---\n\n## Design Phase\n\nCreate designs in Figma by generating HTML prototypes and pushing them via MCP.\n\n### Workflow\n\n```\n1. Generate HTML + CSS prototype from design-spec.md\n - Use semantic HTML elements\n - Apply design tokens as CSS custom properties\n - Include all component states as separate sections\n\n2. Push to Figma using html-to-figma MCP:\n - import-html: Push HTML string directly\n - import-url: Push from a served URL\n\n3. Refine in Figma manually if needed\n```\n\n### Tips\n\n- Structure HTML with clear component boundaries (one `
` per component)\n- Use CSS Grid/Flexbox matching the design-spec layout descriptions\n- Include visual state variations as adjacent elements for Figma review\n\n---\n\n## Implement Phase\n\nRead design details from Figma for precise implementation.\n\n### Reading Design Data\n\nUse Figma MCP tools to read node properties:\n\n1. Navigate Figma file structure to find target components\n2. Read node properties: fills (colors), strokes, effects (shadows), text styles\n3. Extract auto-layout properties (padding, spacing, alignment)\n4. Read component variants for state-based designs\n\n### Workflow\n\n```\n1. Read design-spec.md to identify component names\n2. Use Figma MCP to find matching components/frames\n3. Read exact property values (hex colors, px spacing, font details)\n4. Implement using Figma-read values, not markdown approximations\n```\n\n**Important:** Figma MCP values are authoritative. Prefer them over design-spec.md descriptions.\n\n---\n\n## Verify Phase\n\nCompare implementation against Figma design.\n\n### Verification Workflow\n\n1. Use Figma MCP to read design node details\n2. Compare against implementation:\n - Color values (hex/rgba match)\n - Spacing and padding (px match)\n - Typography (font, size, weight, line-height)\n - Layout direction and alignment\n3. Flag discrepancies with specific property differences\n\n### Verification Checklist\n\n- [ ] Color palette matches Figma fills and strokes\n- [ ] Spacing matches Figma auto-layout padding and item spacing\n- [ ] Typography matches Figma text style properties\n- [ ] Component structure follows Figma layer hierarchy\n", "skills/references/adapter-html.hbs": "# Platform Adapter: HTML\n\nZero-dependency design adapter that produces HTML + CSS prototypes directly.\n\n**Requires:** No external MCP server — works with standard file system only.\n\n---\n\n## Design Phase\n\nGenerate HTML + CSS prototype files from design-spec.md.\n\n### Workflow\n\n```\n1. Create output directory: design.output_dir (default: .prospec/changes/[name]/prototype/)\n2. Generate index.html with semantic HTML structure\n3. Generate styles.css with:\n - CSS custom properties for all design tokens\n - Component styles matching design-spec.md\n - Responsive media queries matching breakpoints\n4. Generate component files if needed (one HTML file per screen)\n```\n\n### File Structure\n\n```\nprototype/\n index.html — Main entry with navigation\n styles.css — Design tokens + component styles\n [screen-name].html — Individual screen prototypes\n```\n\n### Tips\n\n- Use CSS custom properties (`--color-primary`, `--space-md`) for all design tokens\n- Use `