- 变更规模:新增 514 / 修改 62 / 重命名 155 / 删除 4(归档重组与文档轮次) - .gitignore 修:`归档/**/db-cwd归一-备份-*/` —— 原规则写绝对层级(归档/db-cwd归一-…), 目录搬进 归档/配置与备份/ 后**静默失效**,43 MB 的 DB 备份又变成未跟踪 - .gitignore 补:嵌套 git 内部数据(归档/内嵌git-20261008/、归档/skills-git-旧线-20261007/dotgit-原样移出/) - .gitignore 补:运行态与部署副本(.workbuddy/collab/、.workbuddy/tools/、.workbuddy/.load-pending、.workbuddy/tmp-*) - .gitignore 补:备份件(*.bak-*) - 未跟踪文件从 2190 降到 890(其余为 归档/ 归档件与 .workbuddy/memory/ 知识文件,按口径入库)
6.0 KiB
补回三个闸门 + 闸门体检两处修复(2026-09-30)
用户指令原话:「A」(=「另外三个闸门(锁纪律 / 技能加载 / 输出限流)一并补回」) 配套:
交付物/接续机制未运行的根因与强化-20260930.md(上一棒:只补回了接续机制的触发源) 本棒持全局独占锁(补回三闸门-6ecf6d98),收尾已释放。
§0 一句话结论
三个闸门已补回并逐条端到端跑通(⛔ 不是"配置改完了");顺手修掉两处让闸门体检自己瞎掉的缺陷—— 其中一处正是本轮开场那条【门禁自检】假警报的来源:它拿 4 天前的陈旧日志报"最近 4 次 Bash 有 4 次被拦"。
§1 补回了什么(对照 09-24 备用配置逐字复原)
| 事件 | matcher | 脚本 | 作用 |
|---|---|---|---|
PreToolUse |
Write|Edit |
lock-guard-hook.py |
无锁不许改文档库 / 代码库 |
PreToolUse |
Bash|Read |
bash-output-guard.py |
拦下会灌爆上下文的读命令 |
SessionStart |
startup|resume |
lock-guard-hook.py |
开工即告知锁状态 |
UserPromptSubmit |
(无) | skill-load-guard.py |
用户点名方法 ⇒ 强制加载技能 |
复原依据:归档/文档整理/dsh-server-docs-微调-20260924/settings.json.bak(mtime 09-24 06:01)——唯一保存了完整注册表的副本。
现状:state.py 显示 ✅ 关键闸门在册 | PreToolUse×4 SessionEnd×2 SessionStart×2 UserPromptSubmit×4(12 条,exists=True 全绿)。
备份:settings.json.bak-restore3gates-20260930-1840。
§2 端到端验证(⛔ 判据只认"真的跑出了一轮")
| 闸门 | 验证方式 | 读数 |
|---|---|---|
| lock-guard-hook | 我自己的 Edit / Write 真实触发 | lock-hook.log 18:40:25 PreToolUse|tool=Edit、18:40:31 tool=Write;18:40:24 SessionStart 旧全局锁被占 owner=补回三闸门-6ecf6d98 |
| bash-output-guard | 我自己的 Bash 真实触发 + 直喂超阈值文件 | bash-guard.log 18:40:34 / 18:40:46;喂 3.6 MB 文件 ⇒ permissionDecision: deny + 给出 offset/limit、grep -n|head 等价写法;喂 4.6 KB 文件 ⇒ 放行 |
| skill-load-guard | 直喂「点名方法」载荷 | 产出 additionalContext:强制先 Skill(dsh-decision-method) |
| stop-dialog-guard(上一棒) | 真实用户发言触发 | stop-dialog-guard.log 18:38:05 / 18:38:14 |
⇒ state.py 新增一行把它们一次说清:
· 各闸门日志最后一行:收口=2026-09-30 18:38 技能=2026-09-30 18:41 限流=2026-09-30 18:42 锁=2026-09-30 18:42
四条日志全是今天 = 四条闸门全活。「日志最后一行时间」= 该闸门最后一次真被调用的时刻,这是以后一眼看出"谁掉线了"的判据。
§3 顺手修的两处(都属"让闸门体检别再瞎")
| # | 缺陷 | 症状 | 修法 | 验证 |
|---|---|---|---|---|
| 1 | stop-dialog-guard.py::path_health() 读 WORKBUDDY_CONFIG_DIR / ~/.workbuddy |
本机真根是 CODEBUDDY_CONFIG_DIR=E:\ProgramData\.workbuddy ⇒ 读到不存在的文件 ⇒ 异常被吞 ⇒ 路径自检恒静默(上一棒实测) |
优先认 CODEBUDDY_CONFIG_DIR,再回退旧变量(服务器上未设 ⇒ 行为不变) |
反向单测:喂一份"指向不存在脚本"的配置 ⇒ 正确报出 🚨【路径自检】…不存在 ⇒ 机制可能已静默失效 |
| 2 | guard_health() 按"最后 40 条 DENY"统计、不看时间 |
拿 09-26(且指向已改名的旧工作区 aliyun-dsh-server)的 4 条 DENY,每轮报「最近 4 次 Bash 里有 4 次被拦」⇒ 把「闸门已停用」伪装成「闸门在乱拦」 |
加 _fresh():只认近 24h 的行;取不到时间 ⇒ 不报 |
单测:09-26 行 ⇒ False、今日行 ⇒ True、无时间前缀 ⇒ False;guard_health() 现返回 ''(假警报消失) |
⇒ 🔴 结论:不需要把 bash-guard-mode 写成 off。本轮开场那条【门禁自检】不是规则太严,是体检工具拿了陈旧日志。
(stop-dialog-guard.py 已备份 tmp/_bak-stop-dialog-guard-20260930-1845.py,原 md5 5fe59a4200893a240dc96dbeff6de029。)
§4 顺带纠正的三条过时注记(文档库 07-scripts/ 内)
skill-load-guard.py安装示例里推荐"<python>" -S -E "<stop-dialog-guard.py>"——-E是禁止项(屏蔽PYTHONUTF8⇒ 含中文 payload 静默解析失败)。已删-E,并写明-S可选。- 两份脚本都写"装完必须完全重启 WorkBuddy" —— 已不成立:2026-09-30 实测 18:32 改配置、18:38 起就在真实用户发言上热生效;
PreToolUse同理。已改为"热生效,但仍须喂模拟载荷自证"。 bash-output-guard.py安装示例 matcher 只写Bash—— 但脚本有两条规则(cat>200 KB 走 Bash、Read>400 KB 走 Read 工具)⇒ 只挂Bash会让 Read 那条静默失效。已改为Bash|Read并注明原因。
§5 未动 / 待拍板
- ⛔ 未改
resolve_main的前缀判据缺陷 A/B(机制层,另开一棒)。 - ⚠️ 机制仍指向休眠中的
67dfd365:下次投递会报「主会话不在活会话里」并拒投(loud)。回退=把它的标题改掉。 - ⚠️
stop-collab.py::_gw_port()会把20090(设备接入垫片)误认成网关(真网关 56975)—— 上一棒遗留,建议另开一棒。 - ⚠️ 本会话已 660+ 次工具调用 ⇒ 按预算纪律本轮收口后开新会话。
§6 出处
- 注册表复原依据:
归档/文档整理/dsh-server-docs-微调-20260924/settings.json.bak(09-24 06:01) - 备份:
E:/ProgramData/.workbuddy/settings.json.bak-restore3gates-20260930-1840 - 自测脚本(可复跑):
tmp/_gates_dump.py、tmp/_gates_selftest.py、tmp/_gates_selftest2.py、tmp/_guard_health_test.py、tmp/_path_health_test.py - 脚本:
D:/github/dsh_shenxian/dsh-server-docs/07-scripts/{lock-guard-hook,bash-output-guard,skill-load-guard,stop-dialog-guard}.py