Skip to content

v0.4.0

Choose a tag to compare

@Melosic Melosic released this 17 Oct 19:59
· 29 commits to main since this release
c1ecf43

中文 | English

v0.4.0

新增

  • 技能补上「谁在做什么」与「守卫到哪儿为止」。开头一节说明三种角色(插件自动执行、AI 助手必须遵守、人类做决定)和三份文档的分工;新增「工具与守卫的边界」一节,写明守卫看的是工具参数而不是运行中的进程,各守卫可配置的粒度并不相同。这两块此前只存在于代码注释和 SECURITY.md 里,模型读技能时看不到。
  • 提交信息一节补 scope 对照表与「同一变更两种写法」的示例;PR 一节补「评审者这一侧」;发布一节补「发版中断在半路」的恢复路径;CHANGELOG 一节补并发编辑的处置。
  • client.js 进入类型检查。面板是手写的浏览器 JS,此前不在任何 tsconfig 里——宿主改了方法名,编译期毫无反应,要等用户打开一个空白面板才知道。现在 pnpm typecheck:client 在 CI 与发布前都会跑。

修复

  • timeout 120 <命令> 让所有守卫和触发器都看不见被包住的命令。 timeout、nice、stdbuf、ionice、watch 不在包装词表里,程序名就成了包装词本身,于是 timeout 120 git push --force、timeout 120 rm -rf /、timeout 120 cat .env 全部放行。
  • Windows 上的删除与擦盘全部放行。程序名按原样比较,而 PowerShell 写 Remove-Item -Recurse、cmd 写 rd /s /q、卷擦除是 format C:——一个都不命中。现在程序名统一小写比较,cmd 开关只在 cmd 内建命令上生效。
  • 参数位置上的命令替换被吸收进外层命令。echo $(rm -rf /) 曾被读成「echo 带三个参数」这一条无害命令,替换里的程序从未被判定。
  • sh -lc / bash -ec 这类短选项簇里的 -c 不被识别,于是 bash -lc 'rm -rf /' 把整个脚本当不透明参数放行。
  • pnpm -r publish 与 pnpm --filter pkg publish 完全看不见:-r 会把工作区里每个包都推上去,而发版检查与对外守卫都不触发。
  • git restore <path> 与 git checkout -f 丢弃本地改动却不被拦;git push --mirror 只命中对外推送,一旦放宽推送档位就连带绕过强推与删分支。
  • 搜索类命令把自己的搜索词当成了要打开的文件——grep -rn "credentials" . 会被拒,而这恰好是「查密钥有没有进仓库」的那条命令。
  • 递归删除一个操作数都没留下时静默放行(rm -rf $(cat list))。
  • 审计只记配置档位而非实际决策,也没有 callId;allow 档不计数不审计。

移除

  • 删掉三项从未被任何代码读取的配置:rules.branchPattern、rules.commitPattern、docs.adrDir。它们只有声明、面板展示和一枚「当前不生效」徽标,没有任何行为。旧配置文件里留着这三项不会报错,只是被忽略。

升级

dsh plugin --profile <profile> add @melosic/dsh-dev-workflow@0.4.0

无破坏性变更:删掉的三项配置本来就不生效,删掉它们不改变任何行为。技能章节数由 28 增至 35。

已知问题

  • 解释器内部仍不可见:node -e、python -c、eval 里的命令不会被守卫检查。这是词法层的固有限制,已写进 docs/SECURITY.md。

v0.4.0

Added

  • The skill now explains who does what and where the guard stops. A new opening section covers the three roles (the plugin acts, the assistant must, the human decides) and the division between the three documents; a new section on tool and guard boundaries states that a guard inspects tool arguments rather than a running process, and that the configurable granularity differs per guard. Both existed only in code comments and SECURITY.md, which a model reading the skill never sees.
  • A scope table and a worked bad/good pair in the commit section; a reviewer's-side section under pull requests; recovery paths for a release that stops half-way; and how to handle concurrent CHANGELOG edits.
  • client.js is now typechecked. The panel is hand-written browser JS and was in no tsconfig, so a renamed host method produced no compile error — you found out by opening a blank panel. pnpm typecheck:client runs in CI and before publishing.

Fixed

  • A timeout 120 <command> prefix hid the wrapped command from every guard and trigger. timeout, nice, stdbuf, ionice, and watch were missing from the wrapper list, so the wrapper word became the program name and timeout 120 git push --force, timeout 120 rm -rf /, timeout 120 cat .env all passed.
  • Windows deletion and disk wiping passed entirely. Program names were compared verbatim, so PowerShell's Remove-Item -Recurse, cmd's rd /s /q, and format C: matched nothing.
  • A command substitution in argument position was absorbed into the enclosing command: echo $(rm -rf /) was read as one harmless command with three arguments, and the inner program was never judged.
  • A clustered shell flag (bash -lc, sh -ec) was not recognised as running a command string, so the whole script passed as one opaque argument.
  • pnpm -r publish and pnpm --filter pkg publish were invisible — -r pushes every package in the workspace while neither the release check nor the outward guard fired.
  • git restore <path> and git checkout -f discard local work without being guarded; git push --mirror matched only the outward push, so relaxing that tier also bypassed force-push and branch-delete.
  • Search commands had their search expression treated as a filename, so grep -rn "credentials" . was denied — the very command you run to check whether a secret is committed.
  • A recursive delete left with no operand passed silently (rm -rf $(cat list)).
  • The audit recorded the configured tier rather than the actual decision, had no callId, and skipped the allow tier entirely.

Removed

  • Three configuration fields that no code ever read: rules.branchPattern, rules.commitPattern, docs.adrDir. They had a declaration, a panel row, and a "currently inactive" badge, and no behaviour. Leaving them in an existing config file is harmless — they are ignored.

Upgrade

dsh plugin --profile <profile> add @melosic/dsh-dev-workflow@0.4.0

No breaking change: the three removed fields never took effect, so removing them changes nothing. The skill grew from 28 sections to 35.

Known issues

  • Interpreter bodies remain invisible: a command inside node -e, python -c, or eval is not inspected. That is an inherent limit of the lexical layer and is documented in docs/SECURITY.md.

Full Changelog: v0.3.0...v0.4.0