signoff-cli 0.0.0-stage → 4.0.0
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/.pre-commit-hooks.yaml +27 -0
- package/CHANGELOG.md +336 -0
- package/LICENSE +21 -0
- package/README.md +540 -3
- package/action.yml +24 -0
- package/bin/signoff.js +218 -0
- package/docs/diagrams/README.md +41 -0
- package/docs/diagrams/signoff-1-capability-en.png +0 -0
- package/docs/diagrams/signoff-1-capability.png +0 -0
- package/docs/diagrams/signoff-2-market-en.png +0 -0
- package/docs/diagrams/signoff-2-market.png +0 -0
- package/docs/diagrams/signoff-3-user-en.png +0 -0
- package/docs/diagrams/signoff-3-user.png +0 -0
- package/docs/diagrams/signoff-4-flow-en.png +0 -0
- package/docs/diagrams/signoff-4-flow.png +0 -0
- package/docs/diagrams/signoff-5-competitors-en.png +0 -0
- package/docs/diagrams/signoff-5-competitors.png +0 -0
- package/docs/diagrams/src/signoff-1-capability-en.mmd +81 -0
- package/docs/diagrams/src/signoff-1-capability.mmd +84 -0
- package/docs/diagrams/src/signoff-2-market-en.mmd +72 -0
- package/docs/diagrams/src/signoff-2-market.mmd +72 -0
- package/docs/diagrams/src/signoff-3-user-en.mmd +94 -0
- package/docs/diagrams/src/signoff-3-user.mmd +92 -0
- package/docs/gates.en.md +105 -0
- package/docs/gates.md +88 -0
- package/docs/integrations.md +58 -0
- package/docs/promotion.md +71 -0
- package/docs/signoff.schema.json +108 -0
- package/docs/trust.md +72 -0
- package/gates/guard.py +474 -0
- package/gates/p1_verify.py +111 -0
- package/gates/p2_coverage.py +127 -0
- package/gates/p3_queue.py +186 -0
- package/gates/p4_ledger.py +249 -0
- package/gates/p5_slop.py +109 -0
- package/lib/audit.js +213 -0
- package/lib/bootstrap.js +361 -0
- package/lib/checkpoint.js +184 -0
- package/lib/ci.js +58 -0
- package/lib/core.js +120 -0
- package/lib/cov.js +253 -0
- package/lib/detect.js +169 -0
- package/lib/doctor.js +304 -0
- package/lib/editor.js +97 -0
- package/lib/explain.js +73 -0
- package/lib/guard.js +1229 -0
- package/lib/p1.js +469 -0
- package/lib/p2.js +323 -0
- package/lib/p3.js +633 -0
- package/lib/p4.js +733 -0
- package/lib/p5.js +438 -0
- package/lib/preset.js +66 -0
- package/lib/secrets.js +336 -0
- package/lib/sign.js +196 -0
- package/package.json +55 -6
- package/test/selftest.js +1226 -0
- package/test/selftest.py +190 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# pre-commit hooks: https://pre-commit.com
|
|
2
|
+
# - repo: https://github.com/ayuanxx-max/dsh-signoff (package @signoff/cli)
|
|
3
|
+
# rev: v3.15.0
|
|
4
|
+
# hooks: [{id: signoff-guard}]
|
|
5
|
+
- id: signoff-guard
|
|
6
|
+
name: signoff guard (five gates)
|
|
7
|
+
description: run the gates before the commit; a red gate stops it
|
|
8
|
+
entry: signoff guard
|
|
9
|
+
language: node
|
|
10
|
+
pass_filenames: false
|
|
11
|
+
stages: [pre-commit]
|
|
12
|
+
|
|
13
|
+
- id: signoff-p5
|
|
14
|
+
name: signoff text rules
|
|
15
|
+
description: block AI-slop words and unnumbered claims in documents
|
|
16
|
+
entry: signoff p5
|
|
17
|
+
language: node
|
|
18
|
+
pass_filenames: false
|
|
19
|
+
stages: [pre-commit]
|
|
20
|
+
|
|
21
|
+
- id: signoff-cov
|
|
22
|
+
name: signoff changed-line coverage
|
|
23
|
+
description: require coverage on the lines this change adds
|
|
24
|
+
entry: signoff cov --diff --allow-missing
|
|
25
|
+
language: node
|
|
26
|
+
pass_filenames: false
|
|
27
|
+
stages: [pre-push]
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
## 4.0.0
|
|
2
|
+
|
|
3
|
+
**改名:`dsh-signoff` → `signoff-cli`。命令 `signoff`、仓库地址、功能集都不变。**
|
|
4
|
+
|
|
5
|
+
- 新包名 `signoff-cli`。`@signoff/cli` 因 npm scope 归属不可用(发布返回 404),改用等价的 `signoff-cli`。
|
|
6
|
+
旧包 `dsh-signoff` 标记 deprecated,`npm i -g dsh-signoff`
|
|
7
|
+
仍能装到旧版本,但提示改投新包。
|
|
8
|
+
- 钩子与 CI 文件头改成 `# generated by signoff-cli`;**旧文件头仍被识别为自家产物**
|
|
9
|
+
(`markedByUs` 同时认两种),升级不会把老钩子当外来文件覆盖或丢弃。
|
|
10
|
+
- 生成的 CI workflow 改用 `npx --yes signoff-cli@latest`;`action.yml`、`smithery.yaml`、
|
|
11
|
+
`server.json`(MCP 注册表 identifier)同步改为 `signoff-cli`。
|
|
12
|
+
- 仓库内 `node_modules` 查找同时支持 `signoff-cli` 与 `dsh-signoff` 两种布局。
|
|
13
|
+
|
|
14
|
+
## 3.15.3
|
|
15
|
+
|
|
16
|
+
**中英文说明补齐:新特性、能力矩阵、匿名竞品、两张图各出中英两版。**
|
|
17
|
+
|
|
18
|
+
- README 新增「能力矩阵与匿名竞品」与英文对照段:8 项能力 × 落印 + 6 类匿名竞品(A 平台级、
|
|
19
|
+
B 钩子框架、C 密钥扫描、D 文本规则、E 供应链证明、F 覆盖率单点),并写明最后两行是短板。
|
|
20
|
+
- 新增两张框架图,各出中英文:`signoff-4-flow`(一次提交的完整路径与四层证据)、
|
|
21
|
+
`signoff-5-competitors`(覆盖广度 vs 生态采用度,匿名坐标)。
|
|
22
|
+
- 检查点段落补 3.15.2 的三件事:`p4 path`、guard 后自动续签、BOM 容忍。
|
|
23
|
+
|
|
24
|
+
## 3.15.2
|
|
25
|
+
|
|
26
|
+
**把两个分发清单真的装进 tarball。**(3.15.1 被 npm 暂存发布卡住,改用 3.15.2 落地)
|
|
27
|
+
|
|
28
|
+
- `files` 里补上 `.pre-commit-hooks.yaml` 与 `action.yml`:3.15.0 的 tarball 里没有它们,
|
|
29
|
+
审计当场抓到("package ships ..." 两条红)。仓库里有、包里没有,属于发布漏项,不是文档问题。
|
|
30
|
+
- 审计脚本里两条版本断言写死了旧版本号,一并修掉(自身 bug,会让"最新版"永远红)。
|
|
31
|
+
|
|
32
|
+
## 3.15.0
|
|
33
|
+
|
|
34
|
+
**加了"可核对外部"的那一层:签名检查点 + 锚点。**
|
|
35
|
+
|
|
36
|
+
- `signoff p4 checkpoint`:把账本第 N 条的 `head` 与 Merkle `root` 签成一个文件;
|
|
37
|
+
`signoff p4 anchor` 打出一行 `signoff1:<seq>:<head12>:<root16>` 供发布。
|
|
38
|
+
- `signoff p4 verify --checkpoint [--anchor LINE]`:账本被截断、被改写、签名不属于
|
|
39
|
+
`allowed_signers`、锚点对不上,各自给出不同的失败原因。
|
|
40
|
+
- `signoff p4 path`:打印账本与检查点的实际位置(脚本用)。
|
|
41
|
+
- guard 通过后自动续签检查点(同一份账本不重复签),所以"用起来"不需要多一条命令。
|
|
42
|
+
- 账本读取容忍 BOM(Windows 编辑器与 `Set-Content -Encoding utf8` 常见)。
|
|
43
|
+
- 分发面:`.pre-commit-hooks.yaml`(3 个 hook)、`action.yml`(复合 Action)、`docs/integrations.md`。
|
|
44
|
+
- 测试 290 条:新增 17 条检查点断言、5 条分发清单断言、4 条确定性 fuzz 断言。
|
|
45
|
+
|
|
46
|
+
## 3.14.1
|
|
47
|
+
|
|
48
|
+
**修:`tests/` 目录不再抢走 `package.json` 的 `test` 脚本。**
|
|
49
|
+
|
|
50
|
+
- 实测(全新全局安装 + 真仓库):一个 JS 仓库只要有 `tests/` 目录,P1 会去跑
|
|
51
|
+
`python -m pytest tests -q`,在没有 pytest 的机器上 30 ms 失败——而 npm 项目带 `tests/` 极其常见。
|
|
52
|
+
- 现在:`package.json` 的 `test` 脚本优先(明确的意图声明),`pytest-tests` 必须同时有 Python 证据
|
|
53
|
+
(`tests/*.py`、`pyproject.toml`、`setup.py`、`requirements.txt`、`tox.ini`、`pytest.ini`、`conftest.py`)。
|
|
54
|
+
只有 `tests/` 目录的项目不再被误判成任何 runner。
|
|
55
|
+
- 3 条回归测试覆盖三种输入(261 tests)。
|
|
56
|
+
|
|
57
|
+
## 3.14.0
|
|
58
|
+
|
|
59
|
+
**P2:规则包、场景预设、编辑器集成。**(258 tests)
|
|
60
|
+
|
|
61
|
+
- P5 规则包:`--pack zh|en|both`;中文词表仍是默认值,`en` 用 Unicode 词边界匹配,
|
|
62
|
+
`both` 两套同跑并按行去重。`--rules` 追加自定义词表,也可写进 `config.json#p5` 或 `signoff.json#p5`。
|
|
63
|
+
- 场景预设:`signoff init --preset node|python|go|java`,置预算/文档/覆盖率阈值/规则包,
|
|
64
|
+
`test_cmd` 继续自动探测(不锁死脚本)。
|
|
65
|
+
- 编辑器:`signoff init --editor vscode` 生成 `.vscode/tasks.json` 与 problem matcher,
|
|
66
|
+
已存在任务只合并不覆盖。
|
|
67
|
+
- `DEFAULT_CONFIG` 显式列出 `secrets/cache/docsFast/coverage/sign`,不再靠 `!== false` 推断。
|
|
68
|
+
|
|
69
|
+
## 3.13.0
|
|
70
|
+
|
|
71
|
+
**P1:签名判决、增量行覆盖率、CI 注解。**(235 tests)
|
|
72
|
+
|
|
73
|
+
- `signoff init --sign`:仓库本地 ed25519 密钥;`commit-msg` 追加 `Signoff-Key:` + `Signoff-Sig:`,
|
|
74
|
+
对完整 tree 签名,单行 base64 做 trailer。无密钥则保持未签名,不阻塞提交。
|
|
75
|
+
- `signoff audit --verify` / `--require-signed`:逐提交验签;身份锚点是提交进仓库的
|
|
76
|
+
`.signoff/allowed_signers`(或 `signoff.json` 的 `allowed_signers`)。不在名单只报 `self-signed`。
|
|
77
|
+
- `signoff cov --diff --min N`:只统计本次改动新增行的覆盖,读 lcov / istanbul / python coverage json,
|
|
78
|
+
没有覆盖率文件时报"未测"(退出 2)而不是通过;`--allow-missing` 可放行。
|
|
79
|
+
- `GITHUB_ACTIONS=true` 时输出 `::error file=…,line=…` 注解 + `$GITHUB_STEP_SUMMARY` 表格。
|
|
80
|
+
|
|
81
|
+
## 3.12.0
|
|
82
|
+
|
|
83
|
+
**P0:密钥扫描门 + 运行器探测扩展 + 结果缓存。**(210 tests)
|
|
84
|
+
|
|
85
|
+
- `signoff secrets`:16 条高信号规则扫暂存区,命中即退出 1;值在输出里打码(`AKIA…EF`)。
|
|
86
|
+
`--engine gitleaks` 可换用本机 gitleaks 的全套规则,不装也能跑。
|
|
87
|
+
- 守护顺序改成 **secrets → P5 → P1 → …**:密钥泄露不排在测试后面。
|
|
88
|
+
- 机器层守护在未 opt-in 的仓库也会先扫密钥(`--no-state`,不写任何状态)。
|
|
89
|
+
- P1 运行器探测从 2 种扩到 11 种:go / cargo / maven / gradle / dotnet / ruby / elixir / php / make。
|
|
90
|
+
- P1 结果缓存:同一暂存树 + 同一命令 + 同版本 → 0 ms 命中;纯文档提交直接跳过测试。
|
|
91
|
+
开关:`SIGNOFF_NO_CACHE=1`、`SIGNOFF_NO_FAST=1`。
|
|
92
|
+
|
|
93
|
+
## 3.11.2(2026-11-07)
|
|
94
|
+
|
|
95
|
+
- 测试修复:安装点补 sha 的用例在 CI 上失败,因为夹具仓库里那次提交触发的是 signoff 自己的钩子,
|
|
96
|
+
而 runner 上没有全局 `signoff` 可执行文件。改用 `git commit --no-verify`:那次提交只需要产生一个 `HEAD`。
|
|
97
|
+
(本地因为有全局 junction 而通过,是典型的"只在本机能过"的用例。)
|
|
98
|
+
|
|
99
|
+
## 3.11.1(2026-11-07)
|
|
100
|
+
|
|
101
|
+
- 修复:机器层的自动安装在**首次提交**时就跑起来了,那时 `HEAD` 还不存在,`installed.json` 记成了空 sha,
|
|
102
|
+
导致 `audit --since-install` 从此不可用(CI 的 smoke job 就是这样红的)。
|
|
103
|
+
现在提交之后再跑一次 `signoff init` 会把安装点补上,并说明「首次 bootstrap 早于这次提交」。
|
|
104
|
+
- `audit --since-install` 遇到空 sha 时给出可执行的提示,而不是笼统的「没有安装点」。
|
|
105
|
+
- `.github/workflows/mcp-registry.yml` 加三次重试:registry 偶尔拒绝云端出口连接,一次失败不该让版本靠人手补发。
|
|
106
|
+
- 测试:新增「首次提交前 init → 提交 → 再 init 补 sha → audit 可用」用例(`npm test` 188 passed)。
|
|
107
|
+
|
|
108
|
+
## 3.11.0(2026-11-07)
|
|
109
|
+
|
|
110
|
+
- **仓库声明 `signoff.json`**:`signoff init --share` 在仓库根写一份声明并提交它,`.signoff/` 仍是 gitignore 的;
|
|
111
|
+
任何人克隆后第一次 commit,机器层看到声明就自动把 hooks / config / CI 建好并跑全套 P1–P5,克隆方零操作。
|
|
112
|
+
声明只认 `gates`(文档用)、`test_cmd`、`budget`、`docs`、`pre_push` 五个字段,schema 见 `docs/signoff.schema.json`;
|
|
113
|
+
默认不锁测试运行器,避免克隆机器上没有那个 runner 时全线飘红。
|
|
114
|
+
- **MCP Registry 发布进 CI**:新增 `.github/workflows/mcp-registry.yml`,用 GitHub Actions OIDC
|
|
115
|
+
(`mcp-publisher login github-oidc`) 在 release 发布时自动推 `server.json`,不再依赖每 30 分钟失效的设备码。
|
|
116
|
+
- 测试:`npm test` 增加声明生效、声明红关拦截、`init --share` 三个用例。
|
|
117
|
+
|
|
118
|
+
## 3.10.1(2026-11-07)
|
|
119
|
+
|
|
120
|
+
- 兜底:npm 11 把 `postinstall` 放进脚本 allowlist 提示,可能不执行;现在**仓库里第一次跑任何一关**
|
|
121
|
+
(`signoff p1..p5`、`all`、`guard`)会自动把 hooks / config / CI / ledger 装好,第二次起静默。
|
|
122
|
+
- 只读命令(`doctor`、`status`、`explain`、`audit`)与钩子路径不做自动安装:前者不该改现场,
|
|
123
|
+
后者是机器层的轻量关,未 opt-in 的仓库只跑 P1。
|
|
124
|
+
- 文档:补 `--allow-scripts=dsh-signoff` 与首关兜底的说明(中英双语)。
|
|
125
|
+
- 测试:`npm test` 177 passed(夹具默认 `SIGNOFF_NO_BOOTSTRAP=1`,只有 ensure 用例显式打开)。
|
|
126
|
+
|
|
127
|
+
## 3.10.0(2026-11-07)
|
|
128
|
+
|
|
129
|
+
**零接触安装**:`npm i -g dsh-signoff` 之后不再需要 `signoff init`。
|
|
130
|
+
|
|
131
|
+
- 新增 `signoff ensure [--global] [--json] [--quiet]`:幂等安装,仓库层 + 机器层。
|
|
132
|
+
- 新增 `lib/bootstrap.js`:机器层用 `core.hooksPath` 指向 `~/.signoff/hooks`,本机所有仓库(含新克隆)
|
|
133
|
+
下一次 commit 就受约束;派发脚本先执行仓库自带的 `.git/hooks/<stage>`,判决仍归仓库。
|
|
134
|
+
- `package.json` 增加 `postinstall`:全局安装时自动装机器层,在仓库内安装时顺便把该仓库五关装好;
|
|
135
|
+
postinstall 永不失败(失败也 exit 0,不会弄坏别人的 npm install)。
|
|
136
|
+
- 未 opt-in 的仓库只跑 P1(测试),不写 `.signoff/config.json`、不写 marker、不带 trailer:
|
|
137
|
+
机器层不会把「没同意过 P2–P5 规矩」的仓库拦在门外。
|
|
138
|
+
- 两个逃生阀:`SIGNOFF_NO_BOOTSTRAP=1`、`SIGNOFF_NO_MACHINE=1`;撤销机器层用 `signoff uninstall --global`。
|
|
139
|
+
- 测试:新增 ensure / 机器层 / 轻量关 的用例(`npm test` 177 passed)。
|
|
140
|
+
|
|
141
|
+
## 3.9.8(2026-11-07)
|
|
142
|
+
|
|
143
|
+
- 文档:英文版两张图(能力图、用户路径图)从中文段落移到 `## English` 段内,英文读者按自己的语言路径阅读,
|
|
144
|
+
不再需要先翻过中文内容。
|
|
145
|
+
- 版本号同步:`package.json` / `server.json` 3.9.8。
|
|
146
|
+
|
|
147
|
+
## 3.9.7(2026-11-07)
|
|
148
|
+
|
|
149
|
+
- 图表:三张框架图补齐**英文版**(`signoff-1-capability-en` / `signoff-2-market-en` / `signoff-3-user-en`),
|
|
150
|
+
与中文版同结构、同配色、同源目录,`diagram.py` 一次渲染六张。
|
|
151
|
+
- 文档:README 增补 `### At a glance (English)`,英文读者不必先读中文;`docs/diagrams/README.md`
|
|
152
|
+
列出中英对照表。
|
|
153
|
+
- 一致性:中文图 1 标题版本号同步到 3.9.7。
|
|
154
|
+
|
|
155
|
+
## 3.9.6(2026-11-07)
|
|
156
|
+
|
|
157
|
+
- 与 3.9.5 内容相同:3.9.5 因 npm 侧 staged 占用未能公开,改以 3.9.6 发布。
|
|
158
|
+
|
|
159
|
+
## 3.9.5(2026-11-07)
|
|
160
|
+
|
|
161
|
+
- 文档:README 顶部新增「一张图看懂」,用 Mermaid 生成的能力全景图与用户路径图解释五关、边界与已知坑。
|
|
162
|
+
- 图表:三张图全部改为 Mermaid 源文件(`docs/diagrams/src/*.mmd`),可 diff、可重渲;旧的 HTML 拼版已移除。
|
|
163
|
+
- 一致性:图里的判定标准与 `docs/diagrams/README.md`、`signoff explain p1..p5` 的文案同源,避免图文漂移。
|
|
164
|
+
|
|
165
|
+
# Changelog
|
|
166
|
+
|
|
167
|
+
## 3.9.4 — 2026-11-06
|
|
168
|
+
|
|
169
|
+
- `package.json` 增加 `mcpName: io.github.ayuanxx-max/signoff`:官方 MCP Registry 会校验已发布包的
|
|
170
|
+
这个字段,缺失时拒绝发布(`NPM package 'dsh-signoff' is missing required 'mcpName' field`)。
|
|
171
|
+
- `server.json` 与包版本同步到 3.9.4。
|
|
172
|
+
- 自查 164 项、Python 对等 30 项全过。
|
|
173
|
+
|
|
174
|
+
## 3.9.3 — 2026-11-06
|
|
175
|
+
|
|
176
|
+
- 新增 `signoff mcp`:一条命令把五关挂到 stdio MCP 上,`npx -y dsh-signoff mcp` 即可被任何 MCP 客户端调用。
|
|
177
|
+
- 新增 `server.json`(官方 MCP Registry 清单)与 `smithery.yaml`(Smithery 配置),registry 名称 `io.github.ayuanxx-max/signoff`。
|
|
178
|
+
- `signoff explain` 与 MCP 工具描述同步指向同一套判定说明。
|
|
179
|
+
- 自查 164 项、Python 对等 30 项全过。
|
|
180
|
+
|
|
181
|
+
## 3.9.2 — 2026-11-06
|
|
182
|
+
|
|
183
|
+
- 新增 `signoff explain p1..p5`(`--json`):每关查什么、怎么判、怎么修,答案与代码放在一起。
|
|
184
|
+
- 新增 `integrations/skill/SKILL.md`:给 agent 的技能说明书,只写模型容易做错的三件事(退出码是判决、不许绕过红关、先 doctor 再 explain)。
|
|
185
|
+
- 新增 `integrations/mcp/server.js`:零依赖 stdio MCP 服务器,五个工具(run/status/doctor/audit/explain),`isError` 跟随退出码;`initialize` / `tools/list` / `tools/call` 已实测。
|
|
186
|
+
- 新增 `docs/integrations.md`(四种形态对比,含“为什么不做宿主插件”)与 `docs/promotion.md`(GitHub 可发现性、清单收录、度量)。
|
|
187
|
+
- README 增加接入方式(中英两版)。
|
|
188
|
+
- 自查 164 项、Python 对等 30 项全过。
|
|
189
|
+
|
|
190
|
+
## 3.9.1 — 2026-11-06
|
|
191
|
+
|
|
192
|
+
- 修 `audit --since-install` 会在安装点不是 HEAD 祖先时静默给出偏大范围:现在先 `git cat-file -e <sha>^{commit}` + `git merge-base --is-ancestor`,对不上退 2 并说明原因(rebase / 强推 / 换了克隆),提示改用 `signoff init --reset-install` 或 `--range`。审计结论不可信比审计报错更糟。
|
|
193
|
+
- 新增 `signoff init --reset-install`:把安装点重写为当前 HEAD(历史被改写后唯一的正确修法)。
|
|
194
|
+
- 新增 `signoff init --lock-test`:把识别到的测试命令写进 `test_cmd`,换机器不再从 vitest 漂到 pytest。
|
|
195
|
+
- 钩子锁从 `open(..., "wx")` 改为 `mkdir` + `owner.json`:`mkdir` 在 SMB/NFS 上仍是原子的,`O_EXCL` 不是;3.9.0 写的文件形状继续被识别,旧锁不会卡住新版本。
|
|
196
|
+
- 自查 164 项、Python 对等 30 项全过。
|
|
197
|
+
|
|
198
|
+
## 3.9.0 — 2026-11-06
|
|
199
|
+
|
|
200
|
+
- 修 `--chain` 在 Windows 上跑不了非 shell 钩子:串接文件保留 `.py`/`.js`/`.ps1`/`.cmd` 后缀,生成的钩子按后缀用 `python`/`node`/`powershell`/`cmd` 启动,`.local` 仍排第一(3.9.0 之前装的仓库不受影响);`uninstall` 按同一顺序找回并还原。
|
|
201
|
+
- 新增 `signoff p4 export --format {md,json,csv}`(默认 md):json 是记录数组,csv 是带表头的一行一条。
|
|
202
|
+
- 新增 `signoff doctor --fix`:重装缺失或被占的钩子、给 POSIX 钩子补执行位、删掉“什么都没暂存却留着”的 `.signoff/passed`;修完重新体检再出报告,没有可修的会明说。
|
|
203
|
+
- 自查 157 项、Python 对等 30 项全过。
|
|
204
|
+
|
|
205
|
+
## 3.8.0 — 2026-11-06
|
|
206
|
+
|
|
207
|
+
- 新增 `docs/gates.en.md`:与 `docs/gates.md` 一一对应的英文版(五关参数、P1 识别顺序、P4 `--merge`、钩子锁、运行时),两份互加链接;顺手修掉 gates.md 标题里的旧名「执印」。
|
|
208
|
+
- 新增钩子单实例锁 `.signoff/lock`:同一个仓库并发提交时,第二个 `pre-commit` / `pre-push` 退 1 并报出持有者 pid、阶段、时间;持有进程已死或锁超过 10 分钟自动作废;`SIGNOFF_LOCK_WAIT_MS` 可调等待(默认 8000 ms)。`commit-msg` 不加锁,它不能把 git 已接受的提交再挡回去。
|
|
209
|
+
- 自查 147 项、Python 对等 30 项全过。
|
|
210
|
+
|
|
211
|
+
## 3.7.0 — 2026-11-06
|
|
212
|
+
|
|
213
|
+
- 新增 `lib/detect.js`:P1 的测试命令改成“识别 + 说明来源”,顺序为 `package.json` 的 `test` 脚本 → vitest / jest / mocha 依赖 → `Cargo.toml` → `go.mod` → `Makefile` 的 `test` 目标 → pytest → unittest。`init` / `status` 打印 `<命令> (<来源>)`,`doctor` 多一条 `test-runner` 检查。
|
|
214
|
+
- 修:空 `tests/` 目录不再被当成测试套件(以前会让 p1 空跑一场、pytest 退 5 报“没收集到用例”)。目录里没有 `.py` 文件就不算。
|
|
215
|
+
- 新增 `signoff p4 export --merge OTHER...`:把别的仓库的 `audit.log` 合并成一张带 `repo` 列的表;每份都独立重算哈希链,链断的会警告并以 1 退出。
|
|
216
|
+
- 新增 `signoff uninstall --keep-config`:卸钩子 + CI,并清掉 `passed` / `cache.json` / `installed.json` 这些运行时状态,保留配置与账本。默认 `uninstall` 也开始清 `passed` 标记(以前会留一个让 `status` 看着像已安装)。
|
|
217
|
+
- 自查 143 项、Python 对等 30 项全过。
|
|
218
|
+
|
|
219
|
+
## 3.6.0 — 2026-11-06
|
|
220
|
+
|
|
221
|
+
- 新增 `signoff init --chain`:仓库已有钩子时不再只备份,而是存成 `<name>.local` 并在我们的钩子里**先执行**;它失败就停,`signoff uninstall` 把它原样装回 `<name>`。默认行为不变(`<name>.signoff-backup`,不串接)。
|
|
222
|
+
- 修:生成的 CI 工作流在浅克隆下会红。`git rev-parse HEAD~1` 找不到对象时会把名字原样打印到 stdout,导致 `audit --range "HEAD~1..HEAD"` 解析失败退 2。现在工作流 `fetch-depth: 0`、用 `git cat-file -e "$BASE^{commit}"` 判断、必要时 `--unshallow`,取不到就打印跳过。
|
|
223
|
+
- 修:`signoff --version` / `-v` 之前落到“未知命令”退 2;现在打印版本退 0。HELP 里的旧名「一诺过五关」改回「落印」。
|
|
224
|
+
- 新增 `.github/workflows/ci.yml`:node 18/20/22 × ubuntu/macos/windows 矩阵跑 `node test/selftest.js`,另一个 job 跑 python 对等,再一个 job 做 `npm pack` + 全局安装 + `init`/`commit`/`audit --since-install`/`doctor` 冒烟。
|
|
225
|
+
- 自查 126 项(新增 `--version`、HELP 名字、CI 取全历史、CI 取已验证 rev、串接 8 项)全过,Python 对等 30 项全过。
|
|
226
|
+
|
|
227
|
+
## 3.5.1 — 2026-11-06
|
|
228
|
+
|
|
229
|
+
- 修:重复 `signoff init` 时把 `.signoff/installed.json` 里的 `version` 更新成当前钩子版本(`sha`/`ts` 仍保留第一次安装点)。否则 `doctor` 每次升级后都会报一条永久的 `install-version` 警告——那正是 doctor 要避免的噪音。
|
|
230
|
+
- 自查新增 1 项(重复 init 后版本跟随钩子),共 112 项全过。
|
|
231
|
+
## 3.5.0 — 2026-11-06
|
|
232
|
+
|
|
233
|
+
- 新增 `signoff doctor [--json] [--quiet]`:回答“为什么它没按预期生效”,只读、不装不改不删。
|
|
234
|
+
- 检查项:Node 版本、git 是否在 PATH、引擎、钩子三件套是否在且可执行、钩子的旧钩子备份(备份了但没串接会警告)、`signoff` 是否在非交互 shell 的 PATH 里、CLI 版本与安装点记录是否一致、`config.json` 字段合法性、`test_cmd` 是否可启动、`.signoff/passed` 残留、`skips.log` 条数、账本链与别仓库条目、安装点之后的缺失提交。
|
|
235
|
+
- 组合既有命令(`status` / `audit --since-install` / `p4 verify`)而不是重算逻辑:doctor 说 ok 和闸门后面判绿不会互相矛盾。
|
|
236
|
+
- 退出码:全绿 0,有失败 1,不在 git 仓库 2;`--quiet` 只打非 ok 项。
|
|
237
|
+
- 自查新增 8 项(未装仓库判 1、装好判 0、`--json` 结构、`--quiet` 过滤、非仓库判 2、标记残留只警告且能被看见),共 111 项全过。
|
|
238
|
+
|
|
239
|
+
## 3.4.0 — 2026-11-06
|
|
240
|
+
|
|
241
|
+
- `signoff init` 记录安装点 `.signoff/installed.json`(`{sha, ts, version}`);重复 init 不覆盖第一个安装点——装钩子之前的历史是历史,不是失败。
|
|
242
|
+
- `signoff audit --since-install`:从安装点起算,不再手写 `--range`;没有安装点时直接报错退出 2,不猜。
|
|
243
|
+
- 普通 `audit` 遇到装钩子之前的缺失提交会多打一行:`N of M missing commit(s) predate the install point (<sha12>); use --since-install`;`--json` 增加 `install: {sha, pre_install_missing}`。
|
|
244
|
+
- 自查新增 5 项(安装点存在、带 sha、`--since-install` 空区间通过、重复 init 不改安装点、装钩子之前的缺失提交给出提示),共 103 项全过。
|
|
245
|
+
|
|
246
|
+
## 3.3.0 — 2026-11-06
|
|
247
|
+
|
|
248
|
+
- **账本改为仓库级**:默认写 `<repo>/.signoff/audit.log`(非仓库目录退回 `~/.signoff/audit.log`,`SIGNOFF_HOME` 仍可强制指定)。原来的用户级账本会把 A 仓库的回滚点拿去 B 仓库校验,`p4 verify` 在除写入者之外的任何仓库都报 `missing`。
|
|
249
|
+
- **记录新增 `repo` 字段**(参与哈希):`verify` 只校验属于本仓库的条目,别仓库的条目跳过。3.3.0 之前的记录没有 `repo`,仍按旧的 6 个字段重算哈希,所以老账本照常通过。
|
|
250
|
+
- **自动迁移**:第一次在某个仓库里用到账本时,若用户级 `~/.signoff/audit.log` 的整条链在本仓库全部能解析,就整份复制进来;有任何一条解析不了(说明它属于别的仓库)就不复制,从空链开始。
|
|
251
|
+
- `test/selftest.js` 新增 5 项:仓库级落点、`repo` 字段、旧链迁移、别仓库条目跳过、本仓库条目仍会红。96 项全过;Python 对等 30 项全过。
|
|
252
|
+
|
|
253
|
+
## 3.2.1 — 2026-11-06
|
|
254
|
+
|
|
255
|
+
- 中文名从「执印」改为 **落印**:动作词(印落纸面才算数),与英文名 SignOff 的“签了才放行”对应;曾用名「一诺过五关」「执印」。
|
|
256
|
+
- 只改展示名与描述,命令 `signoff`、包名 `dsh-signoff`、行为均不变。
|
|
257
|
+
|
|
258
|
+
## 3.2.0 — 2026-11-06
|
|
259
|
+
|
|
260
|
+
- 中文名定为 **执印**,原名「一诺过五关」保留为曾用名。英文名 SignOff、命令 `signoff`、包名 `dsh-signoff` 不变。
|
|
261
|
+
- 定名依据:GitHub 星标 >2000 的 34 022 个仓库里,按星标取前 1 000 个逐页扫描,名字含中文的为 0 个;中文开源项目成功的是「ASCII slug + 2–3 字中文品牌」(积木 48 389 / 芋道 40 278 / 若依 8 640),所以中文名取两字,五个字以上留给口号。
|
|
262
|
+
- README、`docs/gates.md`、`package.json` 描述同步;其余行为无改动。
|
|
263
|
+
|
|
264
|
+
## 3.1.2 — 2026-11-06
|
|
265
|
+
|
|
266
|
+
- `pre-push` 不再写 `.signoff/passed`:标记是 `pre-commit` 交给 `commit-msg` 的一次性凭据,push 时留下会让仓库里多一个与提交无关的残片。
|
|
267
|
+
- 自查补 1 项(pre-push 不留标记),共 91 项全绿。
|
|
268
|
+
|
|
269
|
+
## 3.1.1 — 2026-11-06
|
|
270
|
+
|
|
271
|
+
- 提交标记改为严格一次性:`commit-msg` 无论标记是否匹配当前树都会消费掉它,`pre-commit` 写新标记前先清旧的。原来“树变了”的标记会留在 `.signoff/passed`,下一次同树提交可能重复追加 trailer。
|
|
272
|
+
- 自查补 3 项(无标记、陈旧标记、陈旧标记被消费),共 89 项全绿。
|
|
273
|
+
|
|
274
|
+
## 3.1.0 — 2026-11-06
|
|
275
|
+
|
|
276
|
+
- 新增 `commit-msg` 钩子与提交标记:闸门通过后在提交信息里写 `Signoff-Pass: <tree>`,`SIGNOFF_SKIP=1` 时写 `Signoff-Skip:`——`git commit --no-verify` 从此不再是“无记录”,而是“没有标记的提交”。
|
|
277
|
+
- 新增 `signoff audit [--range A..B] [--json] [--strict]`:逐个提交核对标记与提交树是否一致;缺失判红,`--strict` 时“有记录的跳过”也判红;合并提交跳过并计数。生成的 CI 工作流自带这一步。
|
|
278
|
+
- `signoff init` 升级:安装第三个钩子、新增 `--quiet` 与 `--prepare`(把 `signoff init --quiet` 并入 `package.json` 的 `prepare`,队友 `npm install` 后自动装钩子,幂等);`status` 显示 `commit-msg` 与 `trailer` 状态。
|
|
279
|
+
- 自查 81 项(原 30 项 + 标记/审计/prepare/真实提交用例),Python 对拍仍 30/30。
|
|
280
|
+
|
|
281
|
+
## 3.0.0 — 2026-11-06
|
|
282
|
+
|
|
283
|
+
- 五关与自动守护全部改为纯 Node 实现(`lib/p1..p5.js`、`lib/guard.js`),**不再需要 Python**:`npm i -g dsh-signoff` 之后任何有 Node 18+ 的机器都能跑完整 P1–P5,没有降级模式、没有缺失的关。
|
|
284
|
+
- 与 Python 参考实现逐字节对拍:P1 43 例、P2 126 例、P3、P4 29 例(含真账本 7 条与混合引擎链)、P5 26 例;`npm test` 跑 Node 版 30 项自查,`npm run parity` 保留 Python 对拍。
|
|
285
|
+
- 自动守护同步改为 Node:钩子仍调 `signoff hook <stage>`,内部用 `node bin/signoff.js` 跑闸门;测试命令优先取 `package.json` 的 test,只在解释器可用时才探测 pytest。
|
|
286
|
+
- 修 Windows 上 `windowsHide` 导致 `cmd.exe` 输出 GBK 乱码、与 Python 不一致的问题。
|
|
287
|
+
|
|
288
|
+
## 2.0.2 — 2026-11-06
|
|
289
|
+
|
|
290
|
+
- CI 模式(`signoff guard --ci`)不再只看暂存区:改为对 `.signoff/config.json` 里声明的全部文档跑 P5,再跑 P1 与(有场景 fixture 时的)P2、P4。钩子模式仍只看本次暂存改动。
|
|
291
|
+
- 自查 30/30。
|
|
292
|
+
|
|
293
|
+
## 2.0.1 — 2026-11-06
|
|
294
|
+
|
|
295
|
+
- 修复:`guard --full`(pre-push 用的就是它)此前会强制跑 P2 `--strict`,导致没有 `verify/scenarios/` 的仓库(例如本项目)在 push 时被误判为覆盖不足。现在 P2 只在仓库确实有场景 fixture(或配置里声明了 `apps`)时才参与。
|
|
296
|
+
- 自查 30/30,行为其余不变。
|
|
297
|
+
|
|
298
|
+
## 2.0.0 — 2026-11-06
|
|
299
|
+
|
|
300
|
+
- 新增自动守护:`signoff init` 一次安装,写入 `.git/hooks/pre-commit`、`.git/hooks/pre-push`、`.github/workflows/signoff.yml`、`.signoff/config.json`,并把 `.signoff/` 加进 `.gitignore`。
|
|
301
|
+
- 新增 `signoff guard`(钩子与 CI 实际调用的入口)、`signoff status`、`signoff uninstall`;`signoff doctor` 增加 guard 一行。
|
|
302
|
+
- 稳定性:同一暂存树只判一次(缓存命中约 0 ms);失败只打印失败关的尾部,完整日志在 `.signoff/hook.log`;超预算判红;CLI 缺失判红;`SIGNOFF_SKIP=1` 跳过并记入 `.signoff/skips.log`。
|
|
303
|
+
- 自查 30/30(原 17 项 + 13 项 guard 用例:安装、缓存、失败阻断、跳过留痕、卸载、dry-run)。
|
|
304
|
+
- 只新增能力,五关的判定逻辑未变。
|
|
305
|
+
|
|
306
|
+
## 1.0.4 — 2026-11-06
|
|
307
|
+
|
|
308
|
+
- 承诺句改为与 P1–P5 实际边界一致的表述:「你照常干活;它不替你判断对错,只把“做完了”变成能核对的东西。」中英同步。
|
|
309
|
+
- 只改文档,五个 gate 与 CLI 行为未变;自测仍 17 passed / 0 failed。
|
|
310
|
+
|
|
311
|
+
## 1.0.3 — 2026-11-06
|
|
312
|
+
|
|
313
|
+
- 承诺句改为 HTML 二级标题(与「一、案例」同级大小)并带红色内联样式,中英同步。
|
|
314
|
+
- 只改文档,五个 gate 与 CLI 行为未变;自测仍 17 passed / 0 failed。
|
|
315
|
+
|
|
316
|
+
## 1.0.2 — 2026-11-06
|
|
317
|
+
|
|
318
|
+
- 承诺句改回纯文字(加粗、左对齐、正文大小),中英同步;移除 PNG 图片与 docs/assets/。
|
|
319
|
+
- 只改文档,五个 gate 与 CLI 行为未变;自测仍 17 passed / 0 failed。
|
|
320
|
+
|
|
321
|
+
## 1.0.1 — 2026-11-06
|
|
322
|
+
|
|
323
|
+
- README 第一节改为案例式标题:本次 DSH 2.0.22-next 升级后修复 dsh-session-fork-tree 0.9.34 的 bug 里五关各自做了什么(中英同步)。
|
|
324
|
+
- 第一节末尾新增红色加粗承诺句(PNG,18 px 左对齐):而你不需要做什么,照常进行任务,由它来守护这个过程;英文同款。
|
|
325
|
+
- 只改文档与图片,五个 gate 与 CLI 行为未变;自测仍 17 passed / 0 failed。
|
|
326
|
+
|
|
327
|
+
## 1.0.0 — 2026-11-06
|
|
328
|
+
|
|
329
|
+
- 首个发布版本:五道关各一条命令,退出码即判决。
|
|
330
|
+
- P1 `p1_verify.py`:跑项目的检查命令(可重复 `--run`),计时、解析用例数、写 `.signoff/p1.json`;`--install-hook` 写 git pre-commit 钩子。
|
|
331
|
+
- P2 `p2_coverage.py`:扫 `verify/scenarios/*.json`,四级分类(scenario / harness / smoke / missing),统计断言数,支持 `--strict`、`--min-scenario`、`--min-assertions`、`--md`。
|
|
332
|
+
- P3 `p3_queue.py`:任务卡校验(id / goal / scope / acceptance / rollback)、scope 冲突分波、`collect` 抓越界改动与空卡。
|
|
333
|
+
- P4 `p4_ledger.py`:单次取票(10 分钟过期)→ 消费 → 哈希链记账 → `verify` 复算链并校验回滚点必须是真实 git ref;`export` 出 Markdown 账本。
|
|
334
|
+
- P5 `p5_slop.py`:六条规则(`placeholder` / AI 味词表 / `绝对`化断言 / 空副词 / 无数字的`已验证` / 缺回滚),跳过代码块与表格行。
|
|
335
|
+
- 自测 `test/selftest.py`:在临时仓库里跑五关,17 条断言全覆盖(含篡改检测、假回滚点拒绝、票单次使用)。
|
|
336
|
+
- 兼容 Node 18+ 与 Python 3.9+;Windows 控制台输出全 ASCII,避免 GBK 乱码把 PASS 显示成乱码。
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ayuanxx-max
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|