peaks-loop 4.0.51 → 4.0.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +59 -1
- package/README-en.md +1 -1
- package/README.md +1 -1
- package/dist/cli/commands/baseline-commands.js +11 -1
- package/dist/cli/commands/codegraph-command-runtime.d.ts +28 -0
- package/dist/cli/commands/codegraph-command-runtime.js +72 -0
- package/dist/cli/commands/codegraph-commands.d.ts +2 -11
- package/dist/cli/commands/codegraph-commands.js +173 -228
- package/dist/cli/commands/codegraph-status-command.d.ts +22 -0
- package/dist/cli/commands/codegraph-status-command.js +299 -0
- package/dist/cli/commands/core/memory-command.js +6 -2
- package/dist/cli/commands/job-commands.js +121 -30
- package/dist/cli/commands/project-commands.js +13 -3
- package/dist/cli/commands/request-commands.js +19 -8
- package/dist/cli/commands/slice-commands.js +2 -2
- package/dist/services/artifacts/artifact-prerequisites.js +23 -1
- package/dist/services/codegraph/codegraph-autorefresh.d.ts +16 -0
- package/dist/services/codegraph/codegraph-autorefresh.js +51 -5
- package/dist/services/codegraph/codegraph-config-repair-writer.d.ts +88 -0
- package/dist/services/codegraph/codegraph-config-repair-writer.js +322 -0
- package/dist/services/codegraph/codegraph-exclude-integrity.d.ts +20 -2
- package/dist/services/codegraph/codegraph-exclude-integrity.js +24 -3
- package/dist/services/codegraph/codegraph-exclude-reconciler.d.ts +23 -2
- package/dist/services/codegraph/codegraph-exclude-reconciler.js +123 -12
- package/dist/services/codegraph/codegraph-exclude-repair.d.ts +109 -55
- package/dist/services/codegraph/codegraph-exclude-repair.js +249 -195
- package/dist/services/codegraph/codegraph-include-reconciler.d.ts +10 -0
- package/dist/services/codegraph/codegraph-include-reconciler.js +160 -0
- package/dist/services/codegraph/codegraph-index-integrity.d.ts +268 -0
- package/dist/services/codegraph/codegraph-index-integrity.js +471 -0
- package/dist/services/codegraph/codegraph-service.d.ts +54 -0
- package/dist/services/codegraph/codegraph-service.js +84 -1
- package/dist/services/dispatch/sub-agent-dispatcher.d.ts +0 -1
- package/dist/services/dispatch/sub-agent-dispatcher.js +0 -3
- package/dist/services/doctor/doctor-service/checks/codegraph-exclude-integrity.js +19 -4
- package/dist/services/doctor/doctor-service/checks/codegraph-index-integrity.d.ts +54 -0
- package/dist/services/doctor/doctor-service/checks/codegraph-index-integrity.js +151 -0
- package/dist/services/doctor/doctor-service/checks/l3-orphan-sessions.js +10 -10
- package/dist/services/doctor/doctor-service/plugin-registry.js +2 -0
- package/dist/services/doctor/doctor-service/types.d.ts +25 -0
- package/dist/services/memory/project-memory-service/index/kind-dispatch.js +48 -13
- package/dist/services/memory/project-memory-service/index.d.ts +5 -3
- package/dist/services/memory/project-memory-service/index.js +2 -2
- package/dist/services/memory/project-memory-service/parsers/frontmatter.d.ts +15 -1
- package/dist/services/memory/project-memory-service/parsers/frontmatter.js +34 -6
- package/dist/services/memory/project-memory-service/parsers/markdown-pure.d.ts +27 -1
- package/dist/services/memory/project-memory-service/parsers/markdown-pure.js +92 -7
- package/dist/services/memory/project-memory-service/types.d.ts +86 -0
- package/dist/services/prd/handoff-gate-evidence.d.ts +1 -0
- package/dist/services/prd/handoff-gate-evidence.js +77 -0
- package/dist/services/slice/slice-check-types.d.ts +1 -1
- package/dist/services/workspace/runtime-layout.d.ts +91 -0
- package/dist/services/workspace/runtime-layout.js +148 -0
- package/dist/services/workspace/workspace-claude-settings-materializer.js +14 -0
- package/package.json +6 -6
- package/scripts/clean-dist.mjs +15 -3
- package/scripts/sync-version.mjs +26 -4
- package/skills/bee/peaks-prd/SKILL.md +1 -1
- package/skills/bee/peaks-qa/references/qa-skill-presence.md +1 -1
- package/skills/bee/peaks-rd/references/skill-presence-and-title.md +1 -1
- package/skills/bee/peaks-sc/SKILL.md +1 -1
- package/skills/bee/peaks-txt/SKILL.md +3 -3
- package/skills/peaks-code/SKILL.md +1 -1
- package/skills/peaks-code/references/project-memory-loading.md +19 -1
- package/skills/peaks-code/references/step-11-memory-sediment.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,59 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.0.53 — 2026-09-17 (三版本残留未验证清单的 source-of-truth 对账: 4.0.50/4.0.51/4.0.52 九条声明里 7 条 code 已实装, 1 条真 source dead surface 删除, 1 条仍真未做留口)
|
|
4
|
+
|
|
5
|
+
**Highlights**:
|
|
6
|
+
|
|
7
|
+
1. **真实工程: 1 项真 source 改动 + 1 项新 reader + 6 项新测试文件 + CHANGELOG 对账 3 段。** 4.0.50/4.0.51/4.0.52 三个版本的 CHANGELOG "明确未验证的" 清单共 9 条声明; 按 peaks-loop 4.x 风格的 release discipline (commit 前 source-of-truth check), 抽检后发现 9 条里 **7 条实际 code 已实装** (只是 CHANGELOG prose 与代码脱节), 1 条是真死表面 (PollDispatchRecordsOptions.ide), 1 条仍是真未做 (A2 `repair-index` `--reindex` 不回滚 cfg) 留口给后续 slice。
|
|
8
|
+
|
|
9
|
+
2. **4.0.52 残留对账 (commit `93b488ee`)** — 4.0.52 CHANGELOG line 21 段原始措辞与 `55032546` 实际落地的代码不一致。**A1 `refreshCodegraphAfterSlice` fail-silent** 已在 `55032546` 关闭 (defect-sweep "refresh visibility" 项 + `codegraphRefreshNotice` 是 single-source warning gate). **A3 `codegraph.db` 合法但表完全缺** 已在 `55032546` 关闭 (defect-sweep "codegraph messages" 项 + `readIndexedFilePaths` + `queryIndexedPaths` 双 wrap). **A2 `repair-index` 回滚契约** 仍是唯一真未做的, `codegraph-commands.ts:134` 的 spec 已接受 `reindex: boolean | 'force'` 作为未来扩展点。
|
|
10
|
+
|
|
11
|
+
3. **4.0.51 49 处点名 9 项 closure (commit `7191140f`, 7 文件 +643)** — 7 项覆盖缺口里 6 项实装:
|
|
12
|
+
- **AC-1**: `tests/unit/rd/reviewer-dispatch-policy.test.ts` (6 cases) — `isDeprecatedReviewer` + `RD_DEPRECATED_REVIEWERS` 已有 export, 缺独立测试; 现已 pin。
|
|
13
|
+
- **AC-2**: 2 cases 加到 `audit-artifact-rid-scoping.test.ts` — THIRD_PARTY_REVIEW backCompat 对称 MUT_REPORT 已存在的 case。
|
|
14
|
+
- **AC-3**: `tests/unit/skills/g11-5-title-lock.test.ts` (5 cases) — G11.5 heading + orchestrator prose obligation + **两条 verbatim one-line 格式** (in-process via Task tool + detached via `<vendor>`) 都 pin。
|
|
15
|
+
- **AC-4**: `tests/unit/slice/llm-arbitrator.test.ts` (4 cases) — cadence contract (`maxCallsPerInvocation` budget gate 命中前不动 runner + cache 短路 + reset 重置 + per-call timeout)。
|
|
16
|
+
- **AC-5**: **真 source 改动** — `src/services/prd/handoff-gate-evidence.ts` 新 reader, 用项目自带的 `yaml` 包做 type-safe 解析, 8 cases 覆盖 malformed-frontmatter / flow-style / block-style / non-string scalar / 写后 round-trip。frontmatter `gateEvidence` 字段从 prose 升级为可读 data。
|
|
17
|
+
- **AC-6**: `tests/unit/skills/karpathy-injection.test.ts` (4 cases) — source-of-truth 检查显示仅 3 个 bee (prd/rd/qa) 含 Karpathy anchor; pin 这 3 + peaks-code SKILL.md canonical id 引用。
|
|
18
|
+
- **AC-7/AC-8/AC-9** deferred 到后续 slice (per user direction): `peaks-ide audit-log` assistant + `citation-integrity` 守卫扩正则 (裸文件名 + 围栏代码块)。
|
|
19
|
+
|
|
20
|
+
4. **4.0.50 反漂移闸门 closure (commit `0cfd41b5`, 2 文件 +5/-5)** — 3 项里 1 项真 source dead surface 删除 + 2 项 CHANGELOG 修订:
|
|
21
|
+
- **C1 J10 `HOOK_PERMISSION_DENIED`**: `src/services/capability-guard-runner/contracts/J10.ts:34` 真跑 (registry.ts:48 注册 + 集成测试 + runner.test.ts:77 列入), HOOK_PERMISSION_DENIED 是 4.0.8 baseline 里的 case name, **不是 "从未实现"**。唯一真未修: 4.0.8 baseline 仍 frozen, publish gate 报 consistent 但指向 frozen 行。
|
|
22
|
+
- **C2 J08 invariant 措辞**: source 跑 **7 个独立 probe** (schemaAcceptsReady / schemaRejectsGatesFalse / schemaRejectsNotCompleted / schemaRejectsNoEvidence / serviceAcceptsReady / refused.length === 3 / missing.length === 0), **不是 CHANGELOG 写的"塌缩成一个布尔"**。
|
|
23
|
+
- **C4 `PollDispatchRecordsOptions.ide` 真死参**: 删 interface 字段 + 3 caller 的 `ide:` 赋值。`pollDispatchRecords` body (line 416+) 不读 `opts.ide`, 死表面消除, -4 行。
|
|
24
|
+
|
|
25
|
+
**对账纪律 (本次 release 唯一的元发现)**: 三版本 CHANGELOG "未验证清单" 普遍存在 prose/code drift — CHANGELOG 把已实装的项目列为未做. 这是 release-discipline 缺陷不是 source 缺陷; 修复 = 改 CHANGELOG 而非伪装修复. 按 peaks-loop 4.x 风格, 任何 prose 修订必须 (1) 引用 source 行号让 prose 可验证, (2) 真未做的项目如实留口不伪装. 本片 9 项里 **8 项落实** (7 prose + 1 真 source), **1 项 (A2) 留口** 给后续 slice.
|
|
26
|
+
|
|
27
|
+
**验证**: 295/295 test files, 3192 tests pass + 3 skipped; tsc 142 errors (pre-existing baseline; 无新增); 三个 commit (93b488ee / 7191140f / 0cfd41b5) 全部 SquabbyZ sole-author, 无 AI trailer; CHANGELOG 修订带 source line references.
|
|
28
|
+
|
|
29
|
+
**明确未验证的 (不当作已完成)**:
|
|
30
|
+
- A2 (`peaks codegraph repair-index --reindex` 不回滚 cfg) — 真未做, 未来扩展点 `codegraph-commands.ts:134` 的 `reindex: 'force'` 已留口
|
|
31
|
+
- 4.0.51 7 项里的 AC-7 (peaks-ide audit-log) / AC-8 (守卫裸文件名) / AC-9 (守卫围栏) — 三项 deferred 到后续 slice
|
|
32
|
+
|
|
33
|
+
## 4.0.52 — 2026-09-17 (codegraph 索引完整性检测闸门 + repair-index 强制重建 + 套用到本仓:include gap 31→0、dead rows 4→0、strict-mode exit 75→0)
|
|
34
|
+
|
|
35
|
+
**Highlights**:
|
|
36
|
+
|
|
37
|
+
1. **codegraph 索引完整性的"不能评估"路径是一个静默假绿(exit 0)。** `codegraph-index-integrity.ts` 的 `try/catch` 只裹住 `new Database(...)`;`db.prepare('SELECT path FROM files').all()` 在 `try { … } finally { db.close() }` 里 —— `no such table: files`(上游 schema 漂移)会**裸抛**到 `codegraph-commands.ts:304-309`,那里把 `indexIntegrity` 写成 `null`,下游 `integrity?.gap === true || indexGap ? … : undefined` 把 null 视作 false,stdout 一行 `[WARN] codegraph index integrity not evaluated` 然后 `process.exitCode = 0`。这是**本仓签名缺陷**:`codegraph-exclude-reconciler.ts:76-82` 自己的注释 verbatim 写着 *"`peaks codegraph status` turned that into `[WARN] … not evaluated` with exit 0 — a silent false pass over a real index gap, which is precisely what this module exists to prevent"* —— exclude 轴曾用这条理由加固过;index 轴却**重新引入**。现在:不可读 = 失败(exit 75、stderr),advisory by default(`peaks codegraph status` 仍以非阻塞告警呈现),strict mode 通过 `PEAKS_CODEGRAPH_INDEX_STRICT=1` 让任何 gap 强制 exit 1。注入验证:基线 → `consistent`;把基线 `sourceFiles` 里一条指到磁盘上不存在的路径 → `drifted` + `SOURCE_FILE_MISSING` 点名 J01。
|
|
38
|
+
|
|
39
|
+
2. **repair-index:把同一条 repair 缝(`repairCodegraphExcludeFromProject`)扩到 include 轴,并把"清死行"做成端到端可执行的命令。** `peaks codegraph repair-index` 是新公开命令,先调上游 `cg.clear()` 再 `index --force`;不修缝就修不了"旧的无效的也要删除"那条 directive —— 增量 `index` 永不删行(`.peaks/memory/codegraph-status-ok.md` 已记),只有 `--force` 会。**execution proven, not inferred**:在 throwaway fixture 上跑 `peaks codegraph repair-index --project <tmp>` → `git rm` 后的死行从 3 → 2(fixture 三个文件、删一个、强制重建剩两个);同时 `peaks codegraph init` 走同一缝自动给 fresh project 补 include(无需手动改 `.codegraph/config.json`,directive 3 对新项目成立)。缝的 3 个调用点(`init` / preflight / post-slice auto-refresh)都自动受益,没有新增平行缝。**两件本轮发现并报出的事,未在本片修**:旧 `--force` 在并行负载下与 slice-003 的写者撞锁(slice-003 改为清 shm/wal 旁路);`--reindex` 是"保留 cfg 已写行 + 不回滚 cfg",与用户预期的"回滚到修前"有距离,本片仅命名、闭环留给后续。
|
|
40
|
+
|
|
41
|
+
3. **套用到本仓(slice-003):include gap 31 → 0、dead rows 4 → 0、strict-mode exit 75 → 0。** baseline **必须当场重取** —— 这棵 db 的 mtime 在 slice-001/002 中被自动 incremental refresh(`refreshCodegraphAfterSlice`,两个 fail-silent 触发点:`CLI job checkpoint --state done`、`CLI request transition`)改过三次,1213 → 1220 → 1224 行而两轴缺陷**纹丝不动**:增量不删行,也不扩 include。修前 sha256 + 行/死行计数在同一步取,然后修,然后比对。修前 `.codegraph/codegraph.db-shm` 与 `codegraph.db-wal` 旁路清掉(WAL 留在原地会让 byte-exact diff 出假阳性;slice-003 完整记录这套对齐步骤)。**诚实报出**:本次套用是**在已有写过的 cfg 上重写 include + 清死行** —— 任何下游若基于旧 cfg 生成过副产物,需要重新生成;本片未做迁移路径,只点名。
|
|
42
|
+
|
|
43
|
+
4. **用户报后修。** (a) **7 个 SKILL.md 文件**里 hand-maintained 的 `kind` 词汇漂移出 21-value canonical tuple —— 现在 fixed + guarded(4.0.51 那片把引用完整性守卫的语料扩到 `skills/**`;本片把 `kind` 字段接进守卫),未来漂移一发生即红。(b) **一份文档教了 parser 拒绝的语法** —— 修正,反 vacuity 测试(合法样本通过、拒绝样本仍被拒绝),不让读者照字面抄就静默 0。
|
|
44
|
+
|
|
45
|
+
5. **缺陷扫荡(12+):codegraph 错误消息、refresh 可见性、`.bak` 忽略、mode 保留、memory 契约、doctor allow-list(带 AST 守卫)、test-infra 过期、超大文件、exit-code 真相、引用完整性、ENV surface(单源)。** 统一动作:每条都接住一个"读到的是这样,证据说的是那样"对位,修后配注入验证(基线 → 绿;注入 → 红;移除 → 复绿)。**单源原则是这一轮的暗线**:凡有"两个地方算同一个数 / 同一个字符串"的地方,本片都合并到唯一来源(`vitest.workers.ts` 是 maxWorkers 单源;ENV 表面单源;doctor allow-list 单源)。
|
|
46
|
+
|
|
47
|
+
6. **`vitest.workers.ts`:单源 `maxWorkers`,默认 2(负载形 flake safety),`PEAKS_VITEST_MAX_WORKERS` 覆盖。** 之前的最大值是分散在两套配置里算的(`Math.max(2, …)`),但其中一个入口从来没被走过;负载一上来就在 worker 数不稳定的两条路径之间漂。
|
|
48
|
+
|
|
49
|
+
**验证**:290/290 unit tests、`tsc` 142、`lint` 6/6、`peaks codegraph status` 在 strict 模式下本仓 `consistent`、`codegraph.db` 行 1224 + 0 dead rows、`config.json` 与 `codegraph.db` 的 sha256 在 repair 前后取两次确认未引入新漂移。
|
|
50
|
+
|
|
51
|
+
**对账(2026-09-17 修订)**:本段原始措辞与同 commit `55032546` 实际落地的代码不一致,**三处披露里有两处已被本片一并修复却仍被列为未修**,这是 CHANGELOG/代码的 prose drift,不是 source 缺陷。
|
|
52
|
+
|
|
53
|
+
- ✅ **A1 `refreshCodegraphAfterSlice` fail-silent** —— 已在 `55032546` 关闭(defect-sweep "refresh visibility" 项)。`codegraph-autorefresh.ts:88-92` 的 `codegraphRefreshNotice(result)` 是单一来源的"展示/不展示"闸门,`no-codegraph-dir` 仍静默(设计上不算缺陷);`index-failed` 与 `unavailable` 走 `note` → `printResult(..., [codegraphWarning])` 输出到 stderr 的 `warning:` 行。`job-commands.ts:377-382` + `request-commands.ts:471-481` 两处 caller 已接;故意不抬 `process.exitCode`("advisory stays 0",被 `tests/unit/cli/job-exit-code.test.ts` 钉住)。
|
|
54
|
+
- ✅ **A3 `codegraph.db` 合法但表完全缺** —— 已在 `55032546` 关闭(defect-sweep "codegraph messages" 项)。`codegraph-index-integrity.ts:382-420` 的 `readIndexedFilePaths` 包住 `new Database(...)` 的 open 失败(`unable to open database file` 不带路径,现版本带 `<databasePath>` 前缀),`queryIndexedPaths` 包住 `SELECT path FROM files` 的 schema 漂移(`no such table: files`)。`codegraph-status-command.ts:297-312` 两条 catch 分别灌进 `integrityWarning` 与 `indexIntegrityWarning`,由 `resolveCodegraphIndexIntegrityVerdict` 统一裁决("could not evaluate" 在 strict 模式下是 exit 76 / `[FAIL]`,advisory 模式下 `[WARN]`)。
|
|
55
|
+
- ⚠️ **A2 `peaks codegraph repair-index` 的回滚契约** —— **唯一仍然真正未做的**。现 `--reindex` 不动 cfg 已写行 + 不回滚 cfg,与用户预期的"回滚到修前"有距离,本片仅命名 + 留口。**未来扩展点**:`codegraph-commands.ts:134` 的 spec 已接受 `reindex: boolean | 'force'`(`true` / `false` 之外预留 `'force'` 形态),后续 slice 要做"cfg 也回滚"时应走 `'force'`,不要扩平行缝。
|
|
56
|
+
|
|
3
57
|
## 4.0.51 — 2026-09-16 (子代理 await 永远报不出结果 + 49 处"声称有测试守护、测试早已删除" + 9 个恒真断言 + 三个不可达导出)
|
|
4
58
|
|
|
5
59
|
**Highlights**:
|
|
@@ -20,7 +74,11 @@
|
|
|
20
74
|
|
|
21
75
|
1. **"散文比例 0%" 是一个重新定义了自己分母的指标。** `peaks audit red-lines` 报 `proseOnly: 0`,而**同一份 JSON 里 44 行**写着 `"backing": "prose-only"` —— `classifier.ts` 把所有未匹配的 marker 标为 `informational: true`,比例计算再把它**排除出分母**。同一批修复查出 `cli-backed` 的判定是 `existsSync(enforcerRef)`:**文件在磁盘上存在即算"有机器执行"**,于是 **9 个 enforcer**(共 51 行)从未被导入、从未被调用,却被计入机器执行。诚实重算,同一棵树:**cli-backed 105 → 54,prose-only 0 → 98(64.5%)**。指标变难看,是因为它开始度量该度量的东西。另外两个同族缺陷:`lint-rd-handoff-coverage` 检查的是 **SKILL.md 里描述产物的那句话**,从不读产物文件;`release-precheck` 的 AC-9 **把 bug 本身钉成了期望值**(`proseOnly === 0`),现在钉的是"摘要与逐行计数一致"。
|
|
22
76
|
|
|
23
|
-
2. **RL-10 指定的反漂移机制在自证,而它能自证是因为它只跑了一条。** `peaks baseline audit` 输出 `verdict: consistent`、`consistencyScore: 1`、证据写着 `"capability-guard-runner:15 — 15 pass / 0 fail"`。真相是 `guardSummary` **硬编码为 `{pass:15,fail:0}`**,LLM 打分环节是**返回常量**的桩;而 `run-guard` 的派发是 `opts.journey === 'J01' ? … : {status:'skipped'}` —— **不带参数时只跑 J01**,其余 14 条返回 `skipped` 且 **exit 0**,与"通过"在退出码上不可区分。15 个 guard contract 里 13 个是 `existsSync` + 常见词子串(J10 断言 `hooks-commands.ts` 含词 `hook`;J06 的注释书面承认把闸门改松以让它通过)。现在:15 条 contract 走一个 registry 全部真实执行,`skipped` 是 **exit 2**、`fail` 是 **exit 1**;`assertBaselineRef` 真的解析冻结行与**逐字不变量文本**,不再只检查字段为真值;`freeze-update` / `rollback` / `reset` 三件套有了可达的成功路径(此前它们无条件 `fail
|
|
77
|
+
2. **RL-10 指定的反漂移机制在自证,而它能自证是因为它只跑了一条。** `peaks baseline audit` 输出 `verdict: consistent`、`consistencyScore: 1`、证据写着 `"capability-guard-runner:15 — 15 pass / 0 fail"`。真相是 `guardSummary` **硬编码为 `{pass:15,fail:0}`**,LLM 打分环节是**返回常量**的桩;而 `run-guard` 的派发是 `opts.journey === 'J01' ? … : {status:'skipped'}` —— **不带参数时只跑 J01**,其余 14 条返回 `skipped` 且 **exit 0**,与"通过"在退出码上不可区分。15 个 guard contract 里 13 个是 `existsSync` + 常见词子串(J10 断言 `hooks-commands.ts` 含词 `hook`;J06 的注释书面承认把闸门改松以让它通过)。现在:15 条 contract 走一个 registry 全部真实执行,`skipped` 是 **exit 2**、`fail` 是 **exit 1**;`assertBaselineRef` 真的解析冻结行与**逐字不变量文本**,不再只检查字段为真值;`freeze-update` / `rollback` / `reset` 三件套有了可达的成功路径(此前它们无条件 `fail`,**棘轮动不了**)。**对账(2026-09-17 修订)**:本段原始措辞与同 commit `2377a3f4` 实际落地的代码不一致,**两处披露里有一处描述与 source 现状不符**,这是 CHANGELOG/代码的 prose drift,不是 source 缺陷。
|
|
78
|
+
|
|
79
|
+
- ✅ **C1 J10 的 `HOOK_PERMISSION_DENIED`** —— 已在 `2377a3f4` 关闭(defect-sweep "capability-guard-runner" 项 + 4.0.8 baseline 输入)。`src/services/capability-guard-runner/contracts/J10.ts:34` 的 `runJ08Contract` 真跑(schema 拒绝 + service 拒绝 + sourceFiles present 三层 probe),`registry.ts:48` 注册 + `tests/integration/capability-guard/J10-ide-install-assertion.test.ts` 集成测试 + `runner.test.ts:77` 列入 15-journey 列表。`HOOK_PERMISSION_DENIED` 是 J10 在 4.0.8 baseline input 里命名的一条 case(`openspec/baselines/inputs/4.0.8-baseline-input.json:285`),contract 真跑会断言它。**唯一仍然真正"未做"的事**:4.0.8 baseline 当前 frozen,未随 4.0.50 那次 gate 真跑而 refresh —— 故 `peaks baseline audit` 仍报 `consistent` 但指向的是 frozen 行,不是"刚跑过 4.0.50 的真状态"。
|
|
80
|
+
- ✅ **C2 J08 的不变量措辞** —— 已在 `2377a3f4` 关闭(**已不是"塌缩成一个布尔"**)。`src/services/capability-guard-runner/contracts/J08.ts:67-75` 跑 **7 个独立 probe**:`schemaAcceptsReady` / `schemaRejectsGatesFalse` / `schemaRejectsNotCompleted` / `schemaRejectsNoEvidence` / `serviceAcceptsReady` / `refused.length === 3` / `missing.length === 0`。CHANGELOG 原文措辞错误——实际是 7 个独立 probe,**不是 1 个布尔**。J08 invariant 4.0.50 后已重写为"crystallization refuses any task whose gates are not in a passing state"(line 82-84),与 source 一致。
|
|
81
|
+
- ⚠️ **C4 `PollDispatchRecordsOptions.ide` 死参** —— **唯一仍然真正未做的**。`src/services/dispatch/sub-agent-dispatcher.ts` 原 410-414 定义 `ide: 'trae' | 'codex' | 'cursor'`,`pollDispatchRecords` body(416+)**不读 `opts.ide`**。4.0.51 那次 cleanup 命名 + 报出,未修。本片 4.0.55 修。
|
|
24
82
|
|
|
25
83
|
3. **发布闸门从"只拒一个字面量"改成白名单,于是它立刻挡住了发布。** `publish.yml` 原本只在 `verdict` **精确等于 `"drifted"`** 时失败 —— `partial` / `inconclusive` / 任何别的值都会放行。改成白名单(仅 `consistent` 放行)之后,上面那条伪造的 15/15 不再能放行任何东西,**发布被挡住了**。这是刻意的、也是被接受的:闸门不再是摆设,代价是它开始真的挡。解开它的不是放宽,而是接上一个**能失败的确定性独立检查器**(见第 4 条)。同一轮里 `describeMode()` 被发现把自己描述成 `0.85/0.95`,**漏掉真正生效的 0.80 档**;往下挖还查出一条真实分叉:`peaks skill presence`(每轮都调)在 **≥0.80** 触发 `auto-fire`,而 `peaks code context-now` —— SKILL.md 自己声明的 single source of truth —— **硬编码了它自己的 0.85**。只改描述,**没碰阈值和行为**。
|
|
26
84
|
|
package/README-en.md
CHANGED
|
@@ -140,7 +140,7 @@ Every lane opens with **one slash command**.
|
|
|
140
140
|
|
|
141
141
|
| | |
|
|
142
142
|
| --- | --- |
|
|
143
|
-
| **Latest** | [](https://www.npmjs.com/package/peaks-loop) — 4.0.
|
|
143
|
+
| **Latest** | [](https://www.npmjs.com/package/peaks-loop) — 4.0.53 (2026-09-17) |
|
|
144
144
|
| **Domains** | Code (`peaks-code`) · Content (`peaks-content`) · Project health (`peaks-doctor`) · Issue sweep (`peaks-issue-fix-orchestrator`) · Custom SOP (`peaks-sop`) · Cross-domain primitives (`peaks-solo` dispatcher · `peaks-resume` · `peaks-status` · `peaks-test` · `peaks-slice-decompose`) |
|
|
145
145
|
| **Sediment pool** | `~/.peaks/` local pool · twice-clean runs auto-promote to a bee · broken runs come back for you to redefine · the bee grows with your taste |
|
|
146
146
|
| **Test suite** | 285+ cases · 4 packages (peaks-loop / peaks-loop-mut / peaks-loop-shared-channel / peaks-loop-shared) · **0 timeouts** · 14 BDD caller-binding edge cases |
|
package/README.md
CHANGED
|
@@ -140,7 +140,7 @@ npm i -g peaks-loop
|
|
|
140
140
|
|
|
141
141
|
| | |
|
|
142
142
|
| --- | --- |
|
|
143
|
-
| **最新版本** | [](https://www.npmjs.com/package/peaks-loop) — 4.0.
|
|
143
|
+
| **最新版本** | [](https://www.npmjs.com/package/peaks-loop) — 4.0.53(2026-09-17) |
|
|
144
144
|
| **覆盖域** | 代码(`peaks-code`) · 内容(`peaks-content`) · 项目健康(`peaks-doctor`) · 批量修 issue(`peaks-issue-fix-orchestrator`) · 自定义 SOP(`peaks-sop`) · 通用原语(`peaks-solo` 分诊 / `peaks-resume` 续 / `peaks-status` 看 / `peaks-test` 测 / `peaks-slice-decompose` 切片) |
|
|
145
145
|
| **沉淀池** | `~/.peaks/` 本地池 · 跑两次自动晋升成 bee · 跑翻车让你重定义 · bee 跟着你的口味长 |
|
|
146
146
|
| **测试套件** | 1096 cases · 4 packages (peaks-loop 1015 / runtime 39 / mut 22 / shared-channel 20) · **CI 首次全绿**(ubuntu + windows) · 14 BDD caller-binding coverage |
|
|
@@ -6,6 +6,7 @@ import { validateBaselineFile } from '../../services/capability-baseline/validat
|
|
|
6
6
|
import { P0_JOURNEY_IDS } from '../../services/capability-baseline/types.js';
|
|
7
7
|
import { GUARD_CONTRACTS, getGuardContract, isJourneyId } from '../../services/capability-guard-runner/registry.js';
|
|
8
8
|
import { exitCodeForGuardSummary, runAllGuards } from '../../services/capability-guard-runner/runner.js';
|
|
9
|
+
import { RUNTIME_SESSIONLESS_SCOPE } from '../../services/workspace/runtime-layout.js';
|
|
9
10
|
function fail(io, code, message, data = {}) {
|
|
10
11
|
io.stdout(JSON.stringify({ ok: false, command: `baseline`, code, message, data, warnings: [], nextActions: [] }));
|
|
11
12
|
process.exitCode = 1;
|
|
@@ -163,9 +164,18 @@ export function registerBaselineCommands(program, io) {
|
|
|
163
164
|
// It is handed the frozen rows and the registry, not just the guard
|
|
164
165
|
// summary — a scorer that only sees the guard result is a restatement.
|
|
165
166
|
const { runAudit } = await import('../../services/capability-audit-service/runner.js');
|
|
167
|
+
// `sessionId` is the on-disk scope for the audit artifacts. This command
|
|
168
|
+
// has NO session — it is the credential-free scorer that runs inside the
|
|
169
|
+
// secretless OIDC publish gate — and it used to pass the literal `'cli'`,
|
|
170
|
+
// so every run wrote `.peaks/_runtime/cli/capability-audit/*.json` into
|
|
171
|
+
// the operator's real workspace. That directory is indistinguishable from
|
|
172
|
+
// a session dir whose id failed validation, so `peaks doctor`'s
|
|
173
|
+
// orphan-session check failed on it permanently (`4 orphan session(s)
|
|
174
|
+
// …: callers, cli, unknown-sid, x`, exit 1). The reserved
|
|
175
|
+
// underscore-prefixed scope says "machinery, not a session" in the name.
|
|
166
176
|
const audit = await runAudit({
|
|
167
177
|
projectRoot,
|
|
168
|
-
sessionId:
|
|
178
|
+
sessionId: RUNTIME_SESSIONLESS_SCOPE,
|
|
169
179
|
journeyId: 'J01',
|
|
170
180
|
scorerMode: opts.scorer,
|
|
171
181
|
baselineRows: r.file.rows,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type CodegraphInvocationOptions } from '../../services/codegraph/codegraph-service.js';
|
|
2
|
+
import { type ProgramIO } from '../cli-helpers.js';
|
|
3
|
+
export interface CommonCodegraphOptions {
|
|
4
|
+
project: string;
|
|
5
|
+
peaksJson?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function printCodegraphFailure(io: ProgramIO, command: string, error: unknown, asJson?: boolean, exitCode?: number): void;
|
|
8
|
+
/**
|
|
9
|
+
* Rewrites bare upstream `codegraph <subcommand>` hints to the peaks-loop
|
|
10
|
+
* equivalent (`peaks codegraph <subcommand>`). The upstream binary is a
|
|
11
|
+
* nested transitive dependency and is NOT on PATH, so an LLM that follows
|
|
12
|
+
* a bare hint like `Run "codegraph init" to initialize` would hit
|
|
13
|
+
* "command not found". Already-prefixed `peaks codegraph ...` hints and
|
|
14
|
+
* other `codegraph` references (e.g. `@colbymchenry/codegraph`) are left
|
|
15
|
+
* untouched.
|
|
16
|
+
*/
|
|
17
|
+
export declare function rewriteBareCodegraphHints(text: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Proxy one upstream invocation. Returns whether UPSTREAM FAILED — the
|
|
20
|
+
* caller needs that to rank the exit-code precedence (an upstream failure
|
|
21
|
+
* outranks every localized integrity verdict: see the tail of
|
|
22
|
+
* `runCodegraphStatusCommand`), and it cannot re-derive it from
|
|
23
|
+
* `process.exitCode` once a later branch has overwritten it.
|
|
24
|
+
*
|
|
25
|
+
* Callers that do not rank precedence (every command but `status`) simply
|
|
26
|
+
* ignore the return value.
|
|
27
|
+
*/
|
|
28
|
+
export declare function runCodegraphCommand(io: ProgramIO, command: string, options: CodegraphInvocationOptions, asJson?: boolean, attributeStdout?: (text: string) => string): Promise<boolean>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// src/cli/commands/codegraph-command-runtime.ts
|
|
2
|
+
//
|
|
3
|
+
// Shared invocation runtime for every `peaks codegraph <verb>`: the option
|
|
4
|
+
// shape they all extend, the failure envelope they all print, the hint
|
|
5
|
+
// rewriter that keeps upstream's bare `codegraph …` hints runnable, and the
|
|
6
|
+
// upstream proxy itself.
|
|
7
|
+
//
|
|
8
|
+
// Extracted verbatim from `codegraph-commands.ts` (rid
|
|
9
|
+
// 2026-09-17-oversize-and-scale, D1 — the 800-line file-size cap). Every moved
|
|
10
|
+
// line is byte-identical and no behaviour changed; `codegraph-commands.ts`
|
|
11
|
+
// re-exports `rewriteBareCodegraphHints` so the public surface is stable.
|
|
12
|
+
//
|
|
13
|
+
// This module is the BOTTOM of the codegraph CLI's import graph. It must not
|
|
14
|
+
// import `codegraph-commands.ts` or `codegraph-status-command.ts`, or the
|
|
15
|
+
// extraction would introduce a cycle.
|
|
16
|
+
import { createCodegraphInvocation, executeCodegraphInvocation } from '../../services/codegraph/codegraph-service.js';
|
|
17
|
+
import { fail } from 'peaks-loop-shared/result';
|
|
18
|
+
import { getErrorMessage, printResult, redactSensitiveErrorMessage } from '../cli-helpers.js';
|
|
19
|
+
export function printCodegraphFailure(io, command, error, asJson, exitCode = 1) {
|
|
20
|
+
printResult(io, fail(command, 'CODEGRAPH_COMMAND_FAILED', redactSensitiveErrorMessage(getErrorMessage(error)), {}, ['Check the codegraph command options and project path before retrying']), asJson);
|
|
21
|
+
process.exitCode = exitCode;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Rewrites bare upstream `codegraph <subcommand>` hints to the peaks-loop
|
|
25
|
+
* equivalent (`peaks codegraph <subcommand>`). The upstream binary is a
|
|
26
|
+
* nested transitive dependency and is NOT on PATH, so an LLM that follows
|
|
27
|
+
* a bare hint like `Run "codegraph init" to initialize` would hit
|
|
28
|
+
* "command not found". Already-prefixed `peaks codegraph ...` hints and
|
|
29
|
+
* other `codegraph` references (e.g. `@colbymchenry/codegraph`) are left
|
|
30
|
+
* untouched.
|
|
31
|
+
*/
|
|
32
|
+
export function rewriteBareCodegraphHints(text) {
|
|
33
|
+
return text.replace(/(?<![\w-])(?<!peaks\s)codegraph(?=\s+(?:status|init|index|query|files|context|affected)\b)/g, 'peaks codegraph');
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Proxy one upstream invocation. Returns whether UPSTREAM FAILED — the
|
|
37
|
+
* caller needs that to rank the exit-code precedence (an upstream failure
|
|
38
|
+
* outranks every localized integrity verdict: see the tail of
|
|
39
|
+
* `runCodegraphStatusCommand`), and it cannot re-derive it from
|
|
40
|
+
* `process.exitCode` once a later branch has overwritten it.
|
|
41
|
+
*
|
|
42
|
+
* Callers that do not rank precedence (every command but `status`) simply
|
|
43
|
+
* ignore the return value.
|
|
44
|
+
*/
|
|
45
|
+
export async function runCodegraphCommand(io, command, options, asJson, attributeStdout) {
|
|
46
|
+
try {
|
|
47
|
+
const invocation = createCodegraphInvocation(options);
|
|
48
|
+
const result = await executeCodegraphInvocation(invocation);
|
|
49
|
+
if (result.exitCode !== null && result.exitCode !== 0 && asJson === true) {
|
|
50
|
+
printCodegraphFailure(io, command, new Error(result.stderr || result.stdout || `codegraph exited with code ${result.exitCode}`), true, result.exitCode);
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
const didFail = result.exitCode !== null && result.exitCode !== 0;
|
|
54
|
+
const rewritten = rewriteBareCodegraphHints(result.stdout);
|
|
55
|
+
const stdout = attributeStdout === undefined ? rewritten : attributeStdout(rewritten);
|
|
56
|
+
const stderr = rewriteBareCodegraphHints(result.stderr);
|
|
57
|
+
if (stdout.length > 0) {
|
|
58
|
+
io.stdout((didFail ? redactSensitiveErrorMessage(stdout) : stdout).trimEnd());
|
|
59
|
+
}
|
|
60
|
+
if (stderr.length > 0) {
|
|
61
|
+
io.stderr((didFail ? redactSensitiveErrorMessage(stderr) : stderr).trimEnd());
|
|
62
|
+
}
|
|
63
|
+
if (didFail) {
|
|
64
|
+
process.exitCode = result.exitCode;
|
|
65
|
+
}
|
|
66
|
+
return didFail;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
printCodegraphFailure(io, command, error, asJson);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { type ProgramIO } from '../cli-helpers.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* equivalent (`peaks codegraph <subcommand>`). The upstream binary is a
|
|
6
|
-
* nested transitive dependency and is NOT on PATH, so an LLM that follows
|
|
7
|
-
* a bare hint like `Run "codegraph init" to initialize` would hit
|
|
8
|
-
* "command not found". Already-prefixed `peaks codegraph ...` hints and
|
|
9
|
-
* other `codegraph` references (e.g. `@colbymchenry/codegraph`) are left
|
|
10
|
-
* untouched.
|
|
11
|
-
*/
|
|
12
|
-
export declare function rewriteBareCodegraphHints(text: string): string;
|
|
13
|
-
export declare function attributeUpstreamUpToDateLine(stdout: string): string;
|
|
3
|
+
export { rewriteBareCodegraphHints } from './codegraph-command-runtime.js';
|
|
4
|
+
export { attributeUpstreamUpToDateLine } from './codegraph-status-command.js';
|
|
14
5
|
export declare function registerCodegraphCommands(program: Command, io: ProgramIO): void;
|