Repository navigation
v0.3.0
v0.3.0
新增
- 发版检查的四条规则各自可关:版本号须是 SemVer、须有
[Unreleased]段、分类标题须是 Keep a Changelog 六类、预发布版本不得推latest。此前规则全硬编码,想放宽一条只能把三个触发器整体关掉。默认值与原行为逐字相同。 gitGuard.checkoutDiscard:丢弃工作区改动的档位。git checkout -- <path>、git checkout .、git restore .会丢掉未提交的改动,此前完全没有守卫。- 密钥前缀库由四种扩到九种:新增 npm token、GitLab token、GitHub fine-grained token、JWT、
Authorization头里的 Bearer 值。 - 面板标注「尚未生效」的配置,与「只读」区分开。
tests/与scripts/终于参与类型检查(pnpm typecheck:tests)。pnpm ci:checks由五项增至七项:新增镜像对成对变更、版本三处对齐。- 新增集成用例
tests/chain.spec.ts、命令行为用例tests/commands.spec.ts、词法层用例tests/shell.spec.ts。
修复
这一版集中收掉了二十多条审计发现,都是「规则写在文档里、代码里没有」那一类:
- 触发器不再被守卫的询问吞掉。 默认档下
gh pr create先被对外守卫以ask拦下,PR 标题与描述检查、发版的版本号与 CHANGELOG 检查一行都不评估;用户批准那次泛泛的确认后命令直接执行。现在触发器即使下游是ask也先完成评估,把发现合并进那道询问。 - 触发器「先记后问」改为「真问过才记」。 此前用户点「拒绝」后重跑同一条命令会直接放行——一次否决被降级成一次提醒。
/dev-workflow off的三处状态机缺陷:off把命令自己也注销导致无法再on;任何一次无关设置写入都会把插件重新激活;status不区分运行期 off 与配置 off。git commit -am "..."不再让提交信息检查静默失效。 短选项簇此前不认识,消息为undefined,类型与 CHANGELOG 检查全部跳过,结论直接是ok。- 文档同步改为按「本次提交」判定。 此前按整个工作区判定:README 只改一半挂在工作区时,任何无关提交都被拦下;一条未暂存的 CHANGELOG 改动就能满足规则。
- shell 词法层的六种静默绕过:
sudo -u root git push --force、sh -c "rm -rf /"、echo $(git push --force)、反引号、find / -exec rm -rf {} +。 - Windows 上敏感文件守卫对 shell 读取全部失效:
\被无条件当转义符,type C:\Users\x\.env匹配失败放行。 grep/glob的搜索模式不再被当成路径:此前grep pattern=".env"被硬拒,而这正是「查密钥有没有入库」的那条命令。- 命令守卫的目标判定差一:
rm -rf ~/*、rm -rf $HOME/*、rm -rf //、rm -r /etc全部放行,而rm -rf ~被拦。 - git 守卫的漏报:
git restore .、git checkout .完全无守卫;git push --mirror只命中对外推送;yarn publish/bun publish无任何守卫。 - 提示疲劳:每次
rebase都问,连--continue/--abort/--skip也问;会话内记忆开关此前只护 git 守卫。 - pre-pr 与 pre-release 的识别盲区与误报:
--fill静默全过、git tag v$(cat VERSION)误报非 SemVer、## v1.0.0风格永远匹配不上、npm version patch三层门禁全不触发。 - 审计与命中计数:
action记的是配置档位而非实际决策、没有callId、写盘失败静默断档、allow档不计数不审计。 - locale 切换后工具与命令描述停在旧语言。
- 无 git 或非仓库时文档检查静默消失,现在降级事实作为 warning 进入结论。
升级
dsh plugin --profile <profile> add @melosic/dsh-dev-workflow@0.3.0无破坏性变更。新增的 releaseCheck.* 与 gitGuard.checkoutDiscard 默认值复现旧行为。
已知问题
- 解释器内部(
node -e、python -c、eval)仍不被检查,这是词法层的固有限制。
v0.3.0
Added
- The four release rules are now individually switchable: the version must be SemVer, an
[Unreleased]section must exist, category headings must be the Keep a Changelog six, and a prerelease must not go tolatest. Previously the rules were hardcoded and the only way to relax one was to turn off all three triggers. Defaults reproduce the old behaviour exactly. gitGuard.checkoutDiscardcovers discarding working-tree changes:git checkout -- <path>,git checkout .,git restore .had no guard at all.- The secret prefix library grew from four patterns to nine: npm tokens, GitLab tokens, GitHub fine-grained tokens, JWTs, and Bearer values in an
Authorizationheader. - Fields that do not take effect are now marked as such in the panel, distinct from "read-only".
tests/andscripts/finally participate in typechecking (pnpm typecheck:tests).pnpm ci:checksgrew from five guards to seven: mirrored pairs must change together, and the package version must have a matching changelog heading.- New integration, command-behaviour, and lexer test suites.
Fixed
This release closes twenty-odd audit findings, all of the "the rule is in the docs but not in the code" kind:
- A guard's prompt no longer swallows the convention checks. Under the default configuration
gh pr createwas stopped by the outward guard withaskbefore the PR title, description, version, and CHANGELOG checks were evaluated at all — approving the generic prompt ran the command unchanged. Triggers now evaluate even when the downstream answer isask, and merge their findings into that one prompt. - A trigger now remembers only when it actually asked. After a rejection, re-running the same command passed silently — a one-time veto had been downgraded to a one-time reminder.
- Three
/dev-workflow offstate-machine defects:offunregistered the command itself soonwas unknown; any unrelated settings write reactivated the plugin;statusdid not distinguish a runtime off from a configured off. git commit -am "..."no longer silently disables the message checks. Clustered short options were not parsed, the message came backundefined, and the type and CHANGELOG checks were skipped with anokverdict.- Documentation sync is judged against this commit, not the whole working tree. A half-finished README used to block any unrelated commit, and an unstaged CHANGELOG edit satisfied the rule without being committed.
- Six silent lexer bypasses:
sudo -u root git push --force,sh -c "rm -rf /",echo $(git push --force), backticks, andfind / -exec rm -rf {} +. - The sensitive-file guard did not work for shell reads on Windows: a backslash was treated as an escape unconditionally, so
type C:\Users\x\.envfailed to match and passed. - A
grep/globsearch expression is no longer treated as a path —grep pattern=".env"was hard-denied, which is exactly the command you run to check whether a secret is committed. - The destructive-command target check was off by one, so
rm -rf ~/*,rm -rf $HOME/*,rm -rf //, andrm -r /etcall passed whilerm -rf ~was caught. - Missing git guards:
git restore .andgit checkout .had none;git push --mirrormatched only the outward tier;yarn publishandbun publishmatched nothing. - Prompt fatigue: every
rebaseasked, including--continue/--abort/--skip; the in-session memory switch only covered the git guard. - pre-pr and pre-release blind spots and false positives:
--fillpassed silently,git tag v$(cat VERSION)was reported as not SemVer, the## v1.0.0changelog style never matched, andnpm version patchtriggered none of the three gates. - Audit and hit counting:
actionrecorded the configured tier rather than the actual decision, there was nocallId, write failures were silent, and theallowtier was not counted. - Tool and command descriptions stayed in the old language after a locale switch.
- A missing or non-git directory made the documentation checks vanish silently; the degraded fact is now a warning in the outcome.
Upgrade
dsh plugin --profile <profile> add @melosic/dsh-dev-workflow@0.3.0No breaking change. The new releaseCheck.* and gitGuard.checkoutDiscard defaults reproduce the old behaviour.
Known issues
- Interpreter bodies (
node -e,python -c,eval) are still not inspected; that is an inherent limit of the lexical layer.
Full Changelog: v0.2.0...v0.3.0