Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/)
[![Tests](https://img.shields.io/badge/tests-2096%20passing-success?style=flat-square)](tests/)
[![Tests](https://img.shields.io/badge/tests-2112%20passing-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/)

Expand Down Expand Up @@ -740,7 +740,7 @@ src/
## Testing

```bash
# Run all tests (2096 tests)
# Run all tests (2112 tests)
pnpm test

# Watch mode
Expand All @@ -753,8 +753,8 @@ pnpm run typecheck
pnpm run lint
```

**Test Coverage**: 2096 tests across 4 categories:
- Unit tests (types + lib + services + cli): 1366 tests
**Test Coverage**: 2112 tests across 4 categories:
- Unit tests (types + lib + services + cli): 1382 tests
- Contract tests (CLI output + Skill format): 647 tests
- Integration tests: 38 tests
- E2E tests: 45 tests
Expand Down
8 changes: 4 additions & 4 deletions README.zh-TW.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/測試-2096%20通過-success?style=flat-square)](tests/)
[![測試](https://img.shields.io/badge/測試-2112%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/)

Expand Down Expand Up @@ -711,7 +711,7 @@ src/
## 測試

```bash
# 執行所有測試(2096 個測試)
# 執行所有測試(2112 個測試)
pnpm test

# Watch 模式
Expand All @@ -724,8 +724,8 @@ pnpm run typecheck
pnpm run lint
```

**測試覆蓋率**:2096 個測試橫跨 4 大類:
- Unit tests(types + lib + services + cli):1366 tests
**測試覆蓋率**:2112 個測試橫跨 4 大類:
- Unit tests(types + lib + services + cli):1382 tests
- Contract tests(CLI 輸出 + Skill 格式):647 tests
- Integration tests:38 tests
- E2E tests:45 tests
Expand Down
3 changes: 2 additions & 1 deletion prospec/ai-knowledge/_lessons-ledger.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,12 @@
| workflow/user-confirm-timeout-proceed-with-record | 需要使用者即時確認的規劃決策(如 scale 確認)逾時無回應 → 以推薦預設續行是正確的自主行為,但必須三處留痕:quality_log WARN、proposal Open Questions、最終摘要明示可覆寫點——讓事後批准(使用者以 y 續行)有據可查。fix-upgrade-doc-coverage:AskUserQuestion 60s 逾時,scale: standard 依準則表+前例採用並全程留痕,verify 前使用者實質批准;add-plan-flow-diagram 第 2 度:new-story AskUserQuestion 逾時,四項設計選項(觸發/位置/內容/scale)依 issue 意圖採推薦預設並三處留痕(quality_log WARN、proposal Open Questions、摘要明示可覆寫),使用者事後以 y 續行並確認 any-of 判準 | 2 | — | playbook | fix-upgrade-doc-coverage, add-plan-flow-diagram | personal |
| types/type-name-contradicts-role-semantics | 型別名承載的語意與使用場景矛盾(CanonicalDoc 註解宣稱 never user-customized,卻被 user-managed 清單重用)是 load-bearing 誤導——共用「形狀」時型別名應角色中性(如 ConventionDocSource),ownership 語意放在各 const 註解;proposal 載明的結構名(UserManagedDoc)被實作靜默改用他型也屬同型偏差。dedupe-init-doc-registry review major,實作者採納改名修復 | 1 | 1 (types) | convention | dedupe-init-doc-registry | personal |
| test/consistency-guard-over-extraction | 同一份指引為 skill 自包含而刻意重述於兩範本(plan-format Section 5 與 prospec-plan Phase 4 的 any-of 門檻,比照 Context7 前例)時,抽共用 partial 會因兩處需要不同「高度」的敘述而變形、且與既有 Context7 不一致、降低範本可讀性——正解是加 section-scoped 跨檔一致性契約斷言釘住同一組 token(mutation-verified),保留兩形態又擋漂移。與 refactor/duplicated-helper-parallel-sites(PB-006,抽 helper)互補:程式邏輯重複抽 helper、指令散文重述加一致性守衛 | 1 | 2 (templates, tests) | convention | add-plan-flow-diagram | personal |
| test/e2e-help-timeout-flaky-under-load | `tests/e2e/cli.test.ts`「prospec --help」在 full-suite 併發滿載下 5s testTimeout 逾時(cold CLI spawn 延遲,非邏輯缺陷);單獨跑該檔 43/43 全過、與變更無關、full-suite 連兩跑皆重現。修法:調高該 e2e 的 testTimeout 或降低併發壓力。首見於 generate-factual-counts verify 5/5 WARN(環境性,未阻 grade A);sync-knowledge-at-verify-commit 第 2 度:part b verify 5/5 再現同一 flake(滿載下觸發、單獨 43/43 全過),確認為穩定的環境性 flake——建議調高該 e2e testTimeout;mechanize-review-gate 第 3 度:verify 5/5 full-suite 再現(單檔 43/43 綠、未阻 grade A);converge-constitution-audit 第 4 度:同一 e2e `--help`/`init` cold-spawn timeout 於 full-suite 再現(單檔綠、template-only 變更無關)——freq=4 但 impact_modules=1(tests)< 2,維持 personal 不晉升;建議調高該 e2e testTimeout 一次解決 | 4 | 1 (tests) | playbook | generate-factual-counts, sync-knowledge-at-verify-commit, mechanize-review-gate, converge-constitution-audit | personal |
| test/e2e-help-timeout-flaky-under-load | `tests/e2e/cli.test.ts`「prospec --help」在 full-suite 併發滿載下 5s testTimeout 逾時(cold CLI spawn 延遲,非邏輯缺陷);單獨跑該檔 43/43 全過、與變更無關、full-suite 連兩跑皆重現。修法:調高該 e2e 的 testTimeout 或降低併發壓力。首見於 generate-factual-counts verify 5/5 WARN(環境性,未阻 grade A);sync-knowledge-at-verify-commit 第 2 度:part b verify 5/5 再現同一 flake(滿載下觸發、單獨 43/43 全過),確認為穩定的環境性 flake——建議調高該 e2e testTimeout;mechanize-review-gate 第 3 度:verify 5/5 full-suite 再現(單檔 43/43 綠、未阻 grade A);converge-constitution-audit 第 4 度:同一 e2e `--help`/`init` cold-spawn timeout 於 full-suite 再現(單檔綠、template-only 變更無關)——freq=4 但 impact_modules=1(tests)< 2,維持 personal 不晉升;建議調高該 e2e testTimeout 一次解決;support-file-module-paths 第 5 度:`tests/contract/mcp-server.test.ts` 的 knowledge_health byte-for-byte 測試(gitFixture + checkExecute,git-subprocess 密集)於 full-suite 併發滿載下 5s 逾時(單檔 1.3s、與變更無關、連兩跑重現),本次直接採建議修法——為該測試加 20s testTimeout headroom,full-suite 3/3 穩定綠;再證此 flake 不限 e2e `--help`,凡 subprocess/spawn 密集測試在預設 5s 下皆有風險,宜統一調高或降併發 | 5 | 1 (tests) | playbook | generate-factual-counts, sync-knowledge-at-verify-commit, mechanize-review-gate, converge-constitution-audit, support-file-module-paths | personal |
| docs/module-readme-manual-counts-uncovered | #65 的 counts 工具(`scripts/sync-counts.ts`)覆蓋 root README.md/README.zh-TW.md/index.md/tests README 的測試計數 + `.hbs`/skill/reference inventory,但**不涵蓋各模組 README 的「(N files, N lines)」標頭**——這些仍手動維護、隨 source 改動漂移(mechanize-review-gate archive 時 lib 等模組 README 行數已失準、`pnpm counts:check` 未攔、verify V4 亦不驗)。建議擴充 counts 工具覆蓋 per-module 檔/行計數(或改為 badge 生成),把最後一類手動計數也機器化。與 docs/duplicated-count-drift(PB-004,已 retired)同族、覆蓋面互補 | 1 | 2 (tests, lib) | convention | mechanize-review-gate | personal |
| spec/behavior-change-omits-modified-req | 變更改動了既有 named REQ(如 REQ-AGNT-020「entry config 列 per-skill Triggers」)所治理的行為,但 delta-spec 只 ADDED 新 REQ、未把該既有 REQ 列 MODIFIED → archive Phase 3.5 graduation 只寫新 REQ、既有矛盾條款留存 → 自我矛盾的 Feature Spec。plan/delta-spec 階段須 grep 受影響行為對應的既有 REQ(及其 User Story 驗收場景)並列 MODIFIED replace-in-place。slim-skill-trigger-context review 對抗式揪出(confirmed critical):slim CLAUDE.md 牴觸 REQ-AGNT-020,補 delta-spec MODIFIED + US-412 場景,archive 已 replace-in-place。與 knowledge/req-citation-precedes-graduation 同屬 spec-graduation 家族 | 1 | 2 (templates, tests) | playbook | slim-skill-trigger-context | personal |
| docs/readme-check-enumeration-manual | 每新增一個 drift check,root README(`prospec check` 說明枚舉的檢查種類,README:639)就漂移——`pnpm counts` 只覆蓋數字,這段散文枚舉無單一來源、無機器守門:#66 review-provenance、#67 metadata-completeness、#63 knowledge-size 皆未同步入該清單(reviewer 對抗式揪出,verify [SHOULD] User-Facing-Doc 於 feature commit 補列 knowledge-size)。建議把該枚舉由 `DRIFT_CHECK_IDS`+描述生成,或加一致性契約斷言釘住「README 枚舉 ⊇ 現有 check 種類」。與 docs/module-readme-manual-counts-uncovered 同族(counts 工具未覆蓋的手動 README 內容) | 3 | 2 (lib, cli) | playbook | mechanize-review-gate, quick-scale-and-ceremony-cleanup, enforce-knowledge-size-budget | promoted(PB-009 · Approved-by: benwu95 · 2026-07-06) |
| test/typecheck-excludes-tests-hides-type-errors | `tsconfig.json` `exclude: ["tests"]` 使 `pnpm typecheck` 不檢查測試檔——測試檔的 type-only import 破損(如遷移型別後測試仍從舊模組 import → TS2459)不被 typecheck 攔、esbuild 於 runtime strip type-only import 故 vitest 亦綠、eslint 亦不報,三閘全漏,僅對抗式 review 揪出。建議 typecheck 納入 `tests/`(或加獨立 test-typecheck job),把 test 的型別破損變成機器可攔。與 refactor/relocation-reference-sweep-completeness 同案發現 | 1 | 1 (tests) | playbook | inject-resolved-knowledge-budgets | personal |
| review/proposed-fix-or-scenario-can-be-wrong | 對抗式 review 的 finding 情境或建議修法未必正確,套用前須先重現 finding、再驗證修法不引入回歸——support-file-module-paths M1:reviewer 稱非源碼檔的 fenced ```ts import 會成偽依賴邊,但實測該 fence 已被既有 template-literal 去除(backtick 觸發)抹掉、不成邊(真正向量是非源碼檔的**裸** import 行);且 reviewer 建議修法(非源碼檔回退 `${prefix}/${EXT}`)會 scandir 一個檔案 → 重引本變更剛修掉的 ENOTDIR。改以「非源碼檔 file 條目回傳 null、caller skip」正確修復並 mutation-verify。守則:review→fix loop 中,尤其對 reviewer 附帶的具體修法,先重現再驗回歸 | 1 | 1 (lib) | playbook | support-file-module-paths | personal |

## Needs-Review List

Expand Down
4 changes: 2 additions & 2 deletions prospec/ai-knowledge/modules/lib/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
| `template.ts` | renderTemplate + Handlebars helpers/partials; resolveTemplatesDir; memory bundled-templates resolution |
| `content-merger.ts` | mergeContent/mergeManagedDoc (preserve user blocks); hasAutoBlock/replaceAutoBlock |
| `yaml-utils.ts` | parse/stringifyYaml, escapeYamlScalar, mergeIntoDocument (comment-preserving) |
| `scanner.ts` | scanDir (fast-glob, security excludes), gitTrackedOnly, filterConventions |
| `scanner.ts` | scanDir (fast-glob, security excludes), gitTrackedOnly, filterConventions, classifyModulePath/moduleScanPatterns (module-map path → scan) |
| `module-detector.ts` | detectModules (auto/architecture/domain/package), buildModuleMap |
| `detector.ts` | detectTechStack over 11 languages; hasCFamilySource |
| `manifest-parsers.ts` | Deterministic dep/entry-point parsers (TOML/XML/hand-rolled), []-safe |
Expand All @@ -27,7 +27,7 @@ Also: `token-accounting.ts`, `index-table.ts`/`index-template.ts`, `task-markers

- `readConfig`/`writeConfig`/`atomicWrite`/`readFileIfExists` — validated read; comment-preserving/atomic writes; ENOENT→''
- `renderTemplate`/`readTemplateSource`/`mergeContent`/`mergeManagedDoc` — render + template source read + user-block-preserving merges
- `scanDir`/`detectModules`/`detectTechStack` — scan + module/stack detection
- `scanDir`/`moduleScanPatterns`/`classifyModulePath`/`detectModules`/`detectTechStack` — scan (with module-map file/dir/glob path classification) + module/stack detection
- `parse*Dependencies(content)` — pure, malformed-safe manifest parsers
- `runChecks(inputs)` + `collect*` — 11 evaluators → DriftReport; `loadModuleMap`/`loadFeatureMap`/`searchModules` — realpath-contained reads

Expand Down
2 changes: 1 addition & 1 deletion prospec/ai-knowledge/modules/tests/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# tests

> 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.
> 4-layer Vitest suite (fast-glob/git bypass memfs — 87 test files, 2,112 tests (unit 1382, contract 647, integration 38, e2e 45)); tests every source module.

<!-- prospec:auto-start -->

Expand Down
2 changes: 1 addition & 1 deletion prospec/ai-knowledge/raw-scan.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,5 +106,5 @@ tests/

| Metric | Value |
|--------|-------|
| Total files | 396 |
| Total files | 397 |
| Scan depth | 10 |
2 changes: 1 addition & 1 deletion prospec/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 — 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 |
| **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,112 tests (unit 1382 + 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_

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# support-file-module-paths — Archive Summary

- **Archived**: 2026-07-09
- **Original Created**: 2026-07-09T03:56:16.000Z
- **Quality Grade**: S

## User Story

As a 依賴 `prospec check` 把關依賴方向的 CI 使用者,
I want drift 的 import-direction 檢查在 `paths` 含單一檔案或資料夾時都能正確掃描與歸屬,
So that 依賴方向違規不會因為 `paths` 用了檔案條目而被無聲漏掉。

As a 維護 `module-map.yaml` 並執行 knowledge 產生的開發者,
I want `getModuleInfos` 對資料夾條目納入整個子樹、對檔案條目只納入該檔,
So that 產生的 module README `keyFiles` 反映真實檔案集,且與 drift 對 `paths` 的解讀一致。

## Affected Modules

| Module | Impact | Description |
|--------|--------|-------------|
| lib | High | scanner 新增 classifyModulePath + moduleScanPatterns;drift importScanPattern 依分類掃描(file→該檔、非源碼檔→skip、dir→子樹、glob→verbatim) |
| services | Medium | knowledge getModuleInfos / updateModuleReadme 掃描改走 moduleScanPatterns(修裸資料夾掃 0 檔缺陷) |
| types | Low | module-map schema `paths` 欄位語義 doc comment(file / dir / glob) |
| tests | Medium | 16 個新測試案例(分類器四態、映射、drift 檔案條目/非源碼檔/glob 回歸、knowledge 子樹掃描 wiring),全數 mutation-verified |

## Requirements

| REQ ID | Status | Description |
|--------|--------|-------------|
| REQ-LIB-029 | ADDED | module-map `paths` 條目分類器(stat-based file/dir/glob/missing)+ moduleScanPatterns |
| REQ-TESTS-050 | ADDED | file/dir/glob 路徑跨 caller 一致性測試 |
| REQ-LIB-014 | MODIFIED | drift 引擎 import-edge 蒐集依分類器處理 file 條目 |
| REQ-KNOW-004 | MODIFIED | knowledge README 掃描透過 moduleScanPatterns 解讀 paths |

## Completion

- **Tasks**: 13/13 code (100%)(另 `[V]` 回歸、`[M]` 自檢各 1 皆完成)
- **Acceptance Criteria**: 7/7 WHEN/THEN(US-1 4 + US-2 3)

## Review & Verify

- **Review**: 2 round(s), 0 critical / 2 major — M1(非源碼檔 file 條目被 import-掃描)已修 + mutation-verified;M2(exotic 非 `*` glob 一致性)延後為 advisory
- **Verify**: Grade S, Tasks / Delta-Spec / Constitution / Knowledge / Tests 全 PASS;Vitest 全綠(2112/2112)
- **Quality Log**: review 2 majors(M1 fixed / M2 deferred);implement 1 scope-adjacent robustness note(mcp contract test 加 20s timeout headroom,平行負載 flake)

## Knowledge Update

- `prospec/ai-knowledge/modules/lib/README.md`(已於 feature commit `b570921` 同步新增 exports)
Loading