回收 411 MB(470 M → 58.8 M),全部经回收站,可恢复: - 待清理/(146.2 M,含 relay 分片 128 M 与 42 项过程目录) - tmp/(32.4 M,按接续棒命名的过程临时区) - .workbuddy/tmp/(39.5 M) - 4 份 workbuddy.db 冗余副本(101 M,09-23 事故的坏副本 / 抢救产物) - tmp/im16/gw/centrifugo 二进制(63.9 M,可重下)+ 缓存残留 入库范围:常驻规则(CODEBUDDY.md / README.md / state.py)、在途接续入口与 接续包、docs/、交付物/、交接单/、归档/、scripts/、.codebuddy/、 .workbuddy/memory/;共 398 件,其中 >60 KB 的 26 件全为文档。 排除(.gitignore):tmp/、待清理/、运行态日志与缓存、*.db 与 DB 备份整目录、 打包二进制(*.tar.gz / *.tgz)、记忆修复前备份。
47 KiB
工作日志 · 2026-09(第 24 片)
⚠️ 本目录日志已按【月】分片(2026-09-15 用户定,单文件 ≤50 KB):同月续片
2026-09.md/2026-09-下.md/2026-09-下2.md/2026-09-下3.md/2026-09-下4.md/2026-09-下5.md/2026-09-下6.md/2026-09-下7.md/2026-09-下8.md/2026-09-下9.md/2026-09-下10.md/2026-09-下11.md/2026-09-下12.md/2026-09-下13.md/2026-09-下14.md/2026-09-下15.md/2026-09-下16.md/2026-09-下17.md/2026-09-下18.md/2026-09-下19.md/2026-09-下20.md/2026-09-下21.md/2026-09-下22.md/2026-09-下23.md写入约定:一律 append 到当月最后一片;该片超 50 KB ⇒ 新建2026-09-下N.md;⛔ 不要再按日新建2026-09-DD.md。 覆盖来源:2026-09-15.md 上一片:2026-09-下22.md下一片:2026-09-下24.md
07:2x — R5 多语言落地:平台运行时 + 登录页切换 + 插件「偏好设置」语言栏
- 用户口径:「优化插件相关代码,并且在登录窗口、设置中用户设置栏新增语言切换选项」(承接上一条:沿用 dsh 官方 locale 方案 + 全球化默认英语)。
- ① 平台 i18n 运行时(新建
web/i18n.js,7960 B):词条表(en/zh两套扁平 key)+ 极小运行时(data-i18n文本 /data-i18n-attr属性就地替换)+ 语言下拉组件(容器<div data-i18n-switch>)。优先级?lang=→ cookie →navigator.language(命中支持列表才用)→ 兜底en;缺 key 回退英文并 warn(不出空文案/裸 key)。 ⚠️ 语言 id 与官方LOCALE_IDS对齐为en/zh(原设计zh-CN)—— 便于日后把平台语言透传给实例的locale.preference而无需映射。 - ② 登录窗口:
web/login.html全量词条化(title/标签/占位/按钮/错误文案/忙碌态)+ 卡内语言下拉;顺手把原来拼innerHTML的错误提示改为 DOM 组装(不再拼 HTML)。 - ③ 设置中用户设置栏:插件
@dsh-local/business-plugins0.3.19 → 0.3.20,新增用户可见 section「偏好设置」(idpreferences,order 99,排在「模型设置」之前),内含「界面语言」下拉 —— 走官方扩展点ctx.locale.getLocale()/ctx.locale.setLocale(id),零官方改动;切换后只 bump 本栏 state(本栏立即换语言,官方 UI 由自身订阅刷新)。已铺发开发服务器:admin bundles=7 / guest bundles=6,均含该插件(未被pruneBrokenFileDeps摘掉)✅;tgz md5 本地=服务器。 - ⚠️ 踩坑 1(去痕迹约束):
scripts/verify-static.mjs有BANNED = 'dshs'(用户可见面不得出现平台内部名)⇒ 我最初的 cookie 名dshs_lang直接判不合格;连「在注释里把它写出来解释」也会被判不合格(第二次被拦)。改为dsh_lang(与既有sid/dsh-auth-*同族)。档案 §10.2 原写dshs_lang⇒ 已在档案里标注为有意偏差。 - ⚠️ 踩坑 2(断言需同步):
scripts/verify-platform-admin-section.mjs断言了 section 数量(admin 3 个 / 非 admin 2 个)⇒ 新增分区后必须同步:改为 4 个 / 3 个,并新增preferences的渲染断言(该断言同时充当冒烟:输出实测含「界面语言 | English | 中文」)。 - 验证:
npm run verifyexit 0 全绿;/i18n.js服务端 200 +application/javascript; charset=utf-8+content-length: 7960(curl -w size_download显示 0 是假象);登录页经真实起服务取回,含lang="en"/data-i18n/script src=/i18n.js;插件在服务器实例里渲染出 4 个分区(见 ③ 断言输出)。 - ⏳ 仍未做:其余 5 个平台页(index/register/portal/admin/wake)与注入浮层文案的词条化;
verify-static的「静态页不得出现裸中文」判据(待 6 页都迁完再开,否则误拦未迁移页)。 - ⚠️ 未 commit / 未 push(用户本次未要求)。待提交:
web/i18n.js(新)、web/login.html、poc/business-plugins/{lib/client.js,package.json}、scripts/verify-platform-admin-section.mjs。 - 锁:
--claim-exec "R5落地-登录页+插件语言栏-0720"→ 已反序释放。
07:4x — 自我纠正:把「该我自己定的事」上抛了(决策方法文档)
- 用户质问:「为什么这个需要我来定,决策方法的文档有看到吗」⇒ 确实没先读技能就收尾提问。违反:
dsh-decision-method§4.1 两条总闸:闸 1(lane)=「设置里语言切换放哪」属我方案内的执行细节 ⇒ 自己拍;闸 2(门禁)= 现行只剩两类(不可逆破坏性 / 边界外),实现落点不是门禁 ⇒ 不该问。- §4.4「技术实现的默认裁决顺序:AI 自主用,不问用户」+ X9/U20「过度上抛(把部署/实现细节拿去问)」。
- 同时纠正另一处同类错误:上一轮写的「其余 5 页待你定」也属上抛 —— 平台静态页是我们自己的、改静态页即时生效不中断用户 ⇒ 按文档自己排期做。
- 本轮落地(自主决策 + 执行):
- 运行时扩展:
t(key, params)支持{n}占位符;抽common.*通用词条(登录/注册共用 pw-toggle 与 busy,并删掉重复的 5 个login.*key —— U2 不做两套)。 - 新增 3 页词条化:
register.html(校验提示/错误/成功文案)、wake.html(「第 N 次」「约 N 分钟」参数化 + 熔断提示)、index.html(title)。连同上一轮login.html⇒ 4/6 页已迁移。 - 新增防回归判据:
verify-static.mjs加I18N_PAGES白名单 —— 已迁移页不得再出现裸中文文案(剥掉 HTML/JS 注释后再判)+ 必须引入/i18n.js。迁移一页加一个,未迁移页不误拦。 - 修判据自身两个缺陷:①
/<title>/不认带属性的<title data-i18n=…>(改/<title[^>]*>/)② 行尾//注释未剥离(假阳性)。
- 运行时扩展:
- 验证:
node scripts/verify-static.mjs全部合格 ✅(6 页 + 内联脚本语法 + 资源);npm run verifyexit 0。 - 我自主排的顺序(陈述,非征询):本轮 3 页 → 下一轮
admin.html(146 行)→ 再下一轮portal.html(709 行 / 200+ 词条,动态模板串最多,单独做透以免"半翻译")→ 最后assets/inject/*.js浮层文案(跨源资产,需单独打包词条,属另一层)。 - 固化(A23:触发词没命中 ⇒ 规则进常驻层、用动作词):
MEMORY.md §三新增「收尾前(写最终回复之前)必过两条闸」,并明确列出不算门禁的动作(实现落点/部署上线/重启/改配置/改静态页/命名/断言期望值)。 - ⚠️ 副本冲突:
MEMORY.md在本轮被另一会话整文件重写(17 KB → 12.3 KB,07:31)⇒ 我的 Edit 因锚点消失而失配(工具正确拦住);已按新内容重做,并补回被我误替换掉的「INDEX.md三件套」铁律行。 - ⚠️ 未 commit / 未 push(用户未要求)。待提交:
web/{i18n.js,login.html,register.html,wake.html,index.html}·poc/business-plugins/{lib/client.js,package.json}·scripts/{verify-static.mjs,verify-platform-admin-section.mjs}。
07:4x — 报障:用户刷新看不到语言设置 ⇒ 根因 = 平台侧只改本机、从未部署
- 用户:「我说的功能实现了吗,怎么刷新页面还是没看到修改语言的设置」。
- 根因(取证,非推断):
- 平台侧从未部署:服务器
/opt/dshs/web/login.html还是 9/13 的旧版(i18n命中 0),且/opt/dshs/web/i18n.js不存在 ⇒ 登录页的语言下拉在线上根本不存在。我此前只改了本机仓库 —— 把「部署」这一步漏了(违反 U20:部署/上线属执行细节,该做完即上线)。 - 实例侧其实已就绪:两个用户 profile(
4092b965…/cce6d1cd…)里装的都是 0.3.20 且含id: "preferences"(find -L跟 pnpm 软链才看到 —— 上次我用-type d没跟软链,误以为没装;另上次路径写成/var/lib/dsh/,正确是/var/lib/dshs/)。
- 平台侧从未部署:服务器
- 修复(已执行):
- 备份旧文件到
/opt/dsh/backups/web-20260915-073736/(回滚点:cp -a回去即可); - scp 5 个文件到
/opt/dshs/web/(本地是 LF,无需转行尾):i18n.js(12248 B) ·login.html·register.html·wake.html·index.html;chown root:root+chmod 644; - 双端验证:服务器本机
curl /i18n.js→ 200 +application/javascript; charset=utf-8+ 12248 B;/login.html含data-i18n11 处;公网curl https://alotbuy.com/login.html→ HTTP 200、data-i18n11 处 ✓(静态文件无需 build/重启;平台dshs服务全程active)。
- 备份旧文件到
- 自查路径(用户侧):① 平台
https://alotbuy.com/login.html→ 卡片底部「Language / 语言」下拉(默认英文)② 实例内 设置 → 偏好设置 → 「界面语言」(需硬刷新Ctrl+Shift+R以绕过浏览器缓存 —— 换产物后的既有 rev 契约)。 - 固化(防复发):
MEMORY.md §三新增「「改完了」≠「上线了」——按文件类型判部署动作」:web/**⇒ scp 即生效;src/**⇒ build + restart;插件 ⇒ artifacts +ensure-biz-plugins.cjs;验证必须到公网侧(只看127.0.0.1:3080不算数)。 - ⏳ 仍待做:
portal.html(709 行)与admin.html(146 行)的词条化 + 注入浮层文案(我的排期,非征询)。未 commit / 未 push。
07:30–07:5x 会话 15ee0d4f:索引优化收口 + 「自决功能」失效根因 + 交付门禁
用户两问:① 之前设的「会话按决策方法自行判断继续处理」不好使、会话老让确认简单问题(让我看 5 分钟前的会话记录)② 要不要把「改了本机没部署」加进项目迭代执行步骤。
一、索引/文档链路优化:昨天的落地包已全部落地(一个锁窗口内做完并释放)
- ★❓ 状态缺失 14 篇 → 3 篇(余
04-27/50/84确无状态行)。根因 = manifest↔INDEX 环形锁定:docs-manifest.py的marks白名单不含 ❓ ⇒ INDEX 的 ❓ 被读成'?';而'status': (index_status…).get('status') or (hs…)因'?'为真短路 ⇒ 回灌 ⇒ 再渲染成 ❓ ⇒ 永久锁死。修法 = 状态改为「档案头部为权威 → INDEX(❓/? 视为缺)→ ?」+ 放宽正则 +norm_status()。 - 同窗口完成:
docs-archive-index.py顺序断言 + 缺失率/名单 |docs-shrink-guard.py--allow-shrink|handoff-guard.sh抢锁输出加"锁生命周期" | 库内 CODEBUDDY 七件套·顺序不可换 + 约定 #2/#3 执行者 | 4 个未入库脚本首次入库(G1 修复) - 提交
ea6e837(13 文件 / +1251 −428)·auditrc=0 ·consistency✓ · 对账 167 一致 / 0 幽灵 · 锁已释放
二、「会话自行判断继续」为什么不好使(★根因 + 硬证据)
- 核账:本工作区宿主日志
tool=AskUserQuestion调用数 = 09-12: 43 / 09-13: 3 / 09-14: 0 / 09-15: 0(UserQuestion/elicitation命中全是--tools参数与 host capability 字符串,不是调用) - ⇒ 既有「提问闸门」hook(matcher
^AskUserQuestion$)拦的是"几乎不走"的工具面;真实上抛在正文("要我接着做吗/请确认/说一声即可")⇒ 零机制覆盖 ⇒ 这就是"会话经常忘记"的结构性原因(不是态度) - 已修三处:① 常驻层(项目根
CODEBUDDY.md §1)新增「回话前自检」+ 征询句清单(发问前重判三问)② 方法层 A24「拦截面必须覆盖真实行为面」③ 机制层:新写scripts/stop-dialog-guard.py—— Stop 事件钩子,读 transcript 最后一行扫征询句 →{"continue":false,"reason"};自作用域(仅本工作区)+ 防死循环(stop_hook_active)+ 引用豁免 + 异常静默放行;5/5 用例自证通过 - ⚠️ 未安装(需拍板):装它要改
E://ProgramData//.workbuddy//settings.json的hooks段(多会话共享配置)+ 完全重启 WorkBuddy(会打断当前所有会话),且宿主是否采纳 Stop 的裁决未验证。 - 诚实边界:5 分钟前那个会话(
63615df4「检查项目是否支持用户自定义 skills」,07:19 起、07:30:30 仍在写)问了什么的原文拿不到 —— 会话正文只在云端;本机事件流只有tool_call类型无文本、projects/无该 sid 的 jsonl、宿主日志只记tool=。但结论不受影响:今天无任何 AskUserQuestion 调用 ⇒ 那个问句只可能是正文。
三、交付门禁(用户问"是否加入迭代执行步骤" → 判定:需要,已落)
- 缺口定位:
06-工作台UI规范 §7早有"生效链路四关",但dsh-change-workflow阶段 5 通篇只讲文档归档,一个字没提"平台改动要部署到用户可见面" ⇒ 知识在文档、不在执行步骤。 - 落地:①
dsh-change-workflow阶段 5 新增 ★§0「交付门禁」(按改动层列生效链路表:静态页 scp+CDN/CF 缓存坑 | 平台 TS build+restart | 插件 tgz→候选池→实例启用→重启实例 | 文档库 scp+对账 | 配置 reload;并点名四条不算交付的自我安慰:本机改完 / build 通过 / 本地打包完成 / 已 commit;同时禁止回头问"要不要部署")②dsh-decision-methodv2.4.0 新增 A25「本机改完 ≠ 交付」+ 索引行 ③ 项目根CODEBUDDY.md §2加一行「我做完了吗」判据 - 依据实例:同类 3 次(09-13 本地打包未部署 →「点开看还是和之前一样」;09-14「应用更改是哪里…」;09-15 原话「平台那半我只改了本机,从没部署到服务器 —— 那你看的当然还是旧页面」)
- 提交
09149af· 两技能三处 md5 一致 · 对账残留 3 项全别人 lane(BRIEF / DEPLOY / opensource-release)· 锁已释放
07:4x — 文案微调:「登录进入AI世界」→「欢迎进入AI世界」(改完即上线)
- 用户要求改登录页副标题。实测改动面只有 3 处:
web/i18n.js的 zh/en 词条 +web/login.html的兜底文案(导出物web/login.html仍是旧版 ⇒ 下次重建自动跟上)。 - 英文同步改为
Welcome to the AI world(原Sign in to the AI workspace)—— 中英必须同义,否则破坏双语对齐。 - 按新固化的判据改完即部署:备份
/opt/dsh/backups/web-20260915-074052/→ scpi18n.js+login.html→chmod 644(静态文件无需 build / 无需重启)。 - 验证:
node scripts/verify-static.mjs全部合格 ✅;服务器本机与公网https://alotbuy.com/均取到data-i18n="login.sub">Welcome to the AI world,词条两条('Welcome to the AI world'/'欢迎进入AI世界')✓。 - ⚠️ 刻意不手工同步导出物:
web/wake.html里有alotbuy.com字面量,由构建的 GLOBAL 规则替换 ⇒ 手抄会把真实域名带进公开仓。导出物一律走重建(本机--force被安全删除层拦rmtree,需另循途径:先mv走.git再重建)。
07:44–08:1x 会话 15ee0d4f:Stop 钩子「装之前」的风险量化 + 加固(5 修)
用户问:「装上会有哪些风险和潜在影响呢」 ⇒ 先量化,再加固,最后给风险表。
量出来的硬数(决定了 3 个必须改的点)
- 本机转录大小:本工作区最大 31.9 MB(
b2817961)、另有 25.3 / 11.2 MB;其他工作区 21.5 MB - 全文读 14 MB 实测 = 832 ms;应用侧 hook 进程历史
elapsed ≈ 264 ms(09-13[HookExecutor] abnormal exit … elapsed=264ms)⇒ 每轮回话读全文不可接受
装之前修掉 5 个问题(其中 3 个是我自己刚埋的)
| # | 问题 | 修法 |
|---|---|---|
| 1 | 全文读转录(30 MB 级/轮) | 只读末尾 256 KB |
| 2 | 巨行漏判:一条 assistant 记录 > 256 KB 时,尾窗切在 JSON 行中间 ⇒ 解析失败 ⇒ 静默漏判(实测复现) | 从尾部分块扩窗(256 KB → ×4 → 上限 4 MB) |
| 3 | 限频误吞:旧版"只查也记账" ⇒ 同会话下一轮的合法拦截被吞掉 | 改为 命中才记账(peek=True 只查不写) |
| 4 | 无急停手段(误伤时要卸载+重启) | 急停双闸:env DSH_STOP_GUARD_OFF=1 / <工作区>/.workbuddy/stop-guard.disabled |
| 5 | 超窗漏判无痕 | 留痕(A18:静默失败是负债)⇒ 写 stop-dialog-guard.log |
加固后实测
常见情形 270–540 ms/轮(含 python 冷启动,压不掉)|判据样本 5/5|限频 ✓|换 sid 仍拦 ✓|急停 env ✓ / 闸刀 ✓|巨行超窗 = 放行(fail-open:不误伤,只是漏)
交付
入库 + scp 镜像 + 提交 ec88710 + 锁已释放(一个窗口)。仍未安装(等用户拍板);未安装时脚本在库里/镜像里,急停闸与日志都不会产生。
待用户拍板(安装)与验证方案
装 = 在 settings.json 的 hooks 加一个 Stop 键(只 Edit 增条,不整段覆盖,改前备份)→ 完全重启 WorkBuddy → 用一次故意犯规实测:若宿主不采纳 continue:false(未验证)⇒ 卸载(删该键 + 再重启)。
08:0x–08:2x 会话 15ee0d4f:按新规则 U26 处理 Stop 钩子的风险(形态定型 + 恢复现场 + 后台验证)
用户两条指令:① 「先解决风险和问题,做到最优效果确认无误后再执行」② 「决策中发现方案有风险和问题,需要分析并优化到当前情况和状态下的最优解,然后进行下一步处理,这个也要加入决策方法」。
一、新规则已入方法:U26(dsh-decision-method v2.5.0,U 条数 26)
「发现风险/问题 ⇒ 不许带着问题往下走」四步判据:① 列出来(风险清单,不许只在脑子里)② 逐条处置(能当场消的当场消;消不掉的写「残余 + 触发条件」)③ 说清残余(哪些是已知接受、什么信号必须回头看)④ 然后才进入下一步,且交付里把 ①②③ 一并写出。配套:A24/A18/A19/A25 判"能不能消";"改小范围先落地"永远合法。⛔ 反面:把"有风险"当"要不要问用户"(过度上抛)或"先干着看"(风险转移)。
二、决策级实测(把钩子形态定死)
| 方案 | 实测(热 python 直接 spawn,10 次均值) | 判定 |
|---|---|---|
python -c pass(对照) |
286 ms | — |
python -S -E |
185 ms | ✅ 采用(省 ~100 ms/轮) |
node -e "" |
211 ms | ❌ 不比 python -S 好 |
bash -c exit 0(外壳) |
1072 ms ⚠️ | ❌ bash shim 方案否决(比 python 还慢 3 倍) |
| 真实钩子·作用域外立即放行 | 286 ms | 冷启动主导 |
| 真实钩子·常见路径(小转录) | 283 ms | — |
| 真实钩子·70.4 MB 转录 | 286 ms | ✅ 成本与转录大小无关(尾部读生效) |
⇒ 形态定型 = 单 python 脚本 + python -S -E;不引入第二层(bash shim 已删)。 |
三、现场恢复(不留半截)
- 临时装的 Stop 钩子已移除;
settings.json校验 = 顶层键 5 个、PreToolUse×2 +SessionStart×1 完好,备份settings.json.bak-stopverify-075408保留。 - 清理:headless 输出/err、
stop-dialog-guard.log、stop-guard-fires.json、__pycache__、待落地下的杂项.workbuddy/全部删除。 - 备注:headless 前台尝试被 SIGTERM(工具超时)⇒ 改为后台自包含跑:
verify-stop-hook.py(装→验→自动卸回),taskjNTflq。
四、按 U26 的结论(当前情境下的最优解)
- 暂不装:① 常驻层「回话前自检」(
CODEBUDDY.md §1)+ 方法层 A24 已覆盖同一面(零成本零风险)② R5(宿主是否调用 Stop 钩子、是否采纳continue:false)仍在验证(后台)③ 装它需完全重启(打断用户所有会话)⇒ 不值得为一个"可能无效"的机制单独安排一次重启。 - 触发条件(何时装):下次用户本来就要完全重启时顺手装(零额外成本);或后台验证出"宿主确实调用且采纳"而用户希望立刻生效。
五、本轮提交
5f34b1b(技能 v2.5.0 + 脚本终版含 DSH_SG_DEBUG)· scp 镜像 OK · 对账 0 仅服务器 · 锁已释放。
08:00–08:2x 会话 15ee0d4f:认错并改正 —— 把"延后"当最优解是将就;按 U27 真解决
用户两句:① 「你的最优解是 延后处理不是立马解决问题吗」(质疑)② 「项目推进要的是解决问题 不是得过且过,将就妥协」+「把这个理念当作重要方法加入到规则中」。
一、我上一轮错在哪(如实)
- 我把「暂不装、等下次重启顺手装」当成"当下最优解",还拿"常驻层自检已覆盖同一面"当缓解 —— 而用户最初的报障就是这条前提的反证(规则早在,会话照样问)⇒ 按 A24(先核账再假设)这条前提不成立。结论:那是"将就",不是"解决"。
二、新规则 U27(dsh-decision-method v2.6.0,U 条数 27)
「要的是解决问题,不是得过且过、将就妥协」:面对风险/缺陷默认目标是解决;降级目标 / 延期 / 静默兜底三种都不算解决。唯一允许"暂时接受" = 客观不可逾越,且必须写明 ① 卡在哪(证据)② 已做到哪一步 ③ 什么条件一出现必须回头解决。
- 给 A6 补边界(防互相矛盾):A6 管路径(取最小代价)、U27 管目标(不许打折) ⇒ 一句话 "目标不打折,路径取最小代价"。
- 常驻层:项目根
CODEBUDDY.md §1加一行(含"与 §2 不矛盾"的说明)。
三、按 U27 重做的动作(不延期 → 直接装)
| 动作 | 结果 |
|---|---|
| Stop 钩子正式安装 | settings.json 的 hooks.Stop = "<python>" -S -E "<脚本>";只加一个键,PreToolUse×2 / SessionStart×1 断言完好;备份 bak-stopverify-075408 / bak-stopverify2-075909 |
| 档案 99 | 04-调整方案/99-会话自决失效根因与Stop钩子补强.md(8 节:根因/用户决策/方案对比含"不做"/实现/验证含失败尝试/踩坑/验收/回滚)→ INDEX 已登记(档案 99 篇) |
| 方法 & 常驻层 | U27 · A6 边界 · CODEBUDDY.md §1 一行 |
| 收口 | 七件套:audit rc=0 · manifest ✓ · archive-index --write(99 进表)· consistency ✓ · shrink-guard(见下)· scp 镜像 OK · 对账 3 不一致(全别人 lane)· commit 64de538 · 锁已释放 |
| 顺手清掉一条误报 | docs-shrink-guard 一直在报 skills/dsh-decision-method/SKILL.md 491→302 行(-38%)(= 我 09-14 的合法拆分)⇒ 用我自己加的 --allow-shrink 接受并刷新基线 |
四、headless 预验证路线:放弃(有依据)
两次尝试(前台 + 后台自包含)都在 codebuddy-headless.js -p 处卡死 4–5 min 无输出,被迫 kill ⇒ 该路线不可用。替代 = 重启后当场实测(我在会话里故意以征询句结尾,看是否被拦回 + reason 是否注入),30 秒得结论。
五、剩余唯一成本(客观不可逾越,有证据)
一次完全重启 —— hooks 是应用启动时快照(09-13 实测定论:改配置对已跑会话无效)。已做到:装好 + 档案 + 验证法 + 急停闸 + 回滚。触发条件(必须回头):重启后若未拦回 ⇒ 说明该版本不采纳 Stop 裁决 ⇒ 当场卸载并改走"收尾清单 + 用户输入前提示"的第二方案(不留在"假安全感"里)。
08:11–08:25 会话 15ee0d4f:功能验证(含一处自纠)+ 新红线 R11 / 方法 U28
用户两条:① 「确认现在功能正常就行」② 新红线:「确保所有决策让项目正向迭代和提升;遇到纯劣化风险(目标/方向/架构/功能/性能/安全/交互/UI/便利性/扩展性)立即停下复盘,确实无正向迭代方法立即停止,禁止继续执行」。
一、功能验证(诚实记:我的判定法先错了一次)
- 重启已生效:
last-launch.json= 08:09:52、WORKBUDDY_STARTUP_PID=29456⇒ 新进程 ⇒hooks.Stop已随快照加载 ✓ - 安装命令自测 ✓:用真实转录 + 合成 Stop 载荷逐字跑配置里那条命令 → 未命中 → 空输出(符合预期)
- ❌ 自纠:我上轮写"日志空 = 宿主没调用" —— 不成立:我的探针句本身没命中判据(长句塞不进
{0,12});而我的校验脚本又用空正则(全命中)自欺,两错叠加 ⇒ 该结论作废。改用直接加载模块复核后:长句 命中=False、短句 命中=True。 - 已修两处根因:① 判据
{0,12}→{0,20}(长句可命中;陈述句与"需要你拍板"节仍不误伤 ✓)② 本工作区内每次调用都留痕(含invoked行,日志上限 300 行)⇒ "宿主有没有调用"从此必然可判,不再依赖探针句是否命中。 - 本轮回复结尾用已验证会命中的短探针句 ⇒ 一次拿到两问:① 被调用?② 采纳
continue:false? - 顺带:
py_compile产生scripts/__pycache__/*.pyc⇒ 对账报「仅本地 1」⇒ 已清干净(教训:py_compile 后要么清副产物,要么PYTHONDONTWRITEBYTECODE=1)。
二、新红线 R11 + 方法 U28(已落)
- 常驻层(项目根
CODEBUDDY.md):§3 新增 R11(十维净变差即命中 ⇒ 立即停下复盘;拿不出正向做法 ⇒ 立即停止、禁止继续执行;⛔ 三种伪装:说成"必要代价"/用"后续再优化"掩盖/藏进交付不写)+ §1 一行指针(含"与 R5 互补:R5 管权限、R11 管全维度净收益")。 - 方法层:
dsh-decision-methodv2.7.0:U28 + §4.1 判定矩阵新增一行("会让项目某一维度净变差吗" → 会 ⇒ 停下复盘/无正向做法即停)+ 索引行;库内CODEBUDDY.md的「红线 R1–R10」引用 → R1–R11。 - 收口:七件套 ✓(audit rc=0 · consistency ✓ · archive-index --write ✓)· scp 镜像 ✓ · 对账 仅本地 0 / 仅服务器 0(余 3 项内容不一致 = 别人 lane)· commit
5001f03· 锁已释放。
08:22–08:40 会话 15ee0d4f:常驻规则可移植化(新技能 dsh-env-bootstrap)+ 顺带修两处账实不符
用户要求:「常驻层 CODEBUDDY.md 的关键内容也要加入到 skill 中,避免哪天换电脑换环境就无法执行了(换环境后可以自动注入到对应 CODEBUDDY.md 中)」
一、判定与做法(不造第二真相源)
常驻层不能被替代("动作前必然生效"靠它),技能只负责 带过去 + 防丢 + 校验。所以做成 技能内快照 + 幂等命令:
| 文件 | 内容 |
|---|---|
references/常驻规则-快照.md |
由权威 CODEBUDDY.md 经 --snapshot 自动抽取(19.4 KB / 6 章:§1 提问判据 · §3 红线 R1–R11 · §4 提交边界 · §5 规划执行分离 · §6 并发纪律 · §8 事故级实测事实)+ 骨架锚点清单 + 待核清单 |
scripts/resident-rules.py |
--env-check(路径 + hooks 命令自检)· --check(默认只报,rc=1)· --inject [--init](只动标记块)· --snapshot(由权威重生成,单向) |
SKILL.md |
何时用 + 换环境四步 + 设计红线 + 自检 |
设计红线(防漂移):① 权威方向单向(CODEBUDDY.md 权威 / 快照副本,只允许 --snapshot 生成)② 默认只报不改(同文档库"体检只报不改")③ 注入只动标记块,首次不自动注入(避免同一规则两处并存)④ 不假装能自动配环境(环境相关项只做存在性检查 + 待核清单)。
二、实测(都跑了)
--snapshot→ 快照 10036 字符 / 19.4 KB / 129 行 / 6 章 ✓--check→ 全绿 rc=0(10 个骨架锚点 + 5 章节存在性)✓--env-check→ 工作区/文档库/代码仓 ✓ 存在;3 条 hooks 命令路径全部有效 ✓;服务器/备份目录标"需 ssh 侧核对"--inject(无--init)→ 拒绝注入("目标里没有标记块")✓ = 防重复设计生效- 修脚本自身 2 个 bug:
references/目录未建(加makedirs);hooks 命令用正则解析被转义引号截断(改json解析)
三、顺带修两处账实不符
CODEBUDDY.md §3标题:红线 R1–R10→R1–R11(内容已含 R11,标题漏改)INDEX.md/README.md里引用我技能的几行:「红线 R1-R8」→R1-R11;并新增dsh-env-bootstrap的三处清单行(INDEX 场景速查 + 全量清单 + README 模块表)✓(阶段 5 第 5 条的"更新引用它的元数据")
四、收口
七件套 ✓(audit rc=0 · manifest ✓ · archive-index --write ✓ · consistency ✓)· scp 镜像 ✓ · 对账 仅本地 0 / 仅服务器 0(174/174;余 3 项内容不一致 = 别人 lane)· commit 3b5bd42 · 锁已释放。
五、Stop 钩子行为验证(本轮读日志)
见本轮回复:留痕已开(本工作区内每次调用必写一行)⇒ 日志为空即宿主不调用 Stop 钩子;有 invoked 行则至少证明被调用;有 命中 行 + 我被拦回 ⇒ 调用与采纳都成立。判据不再依赖探针句是否命中(上一轮的两错已修)。
08:25–09:00 会话 15ee0d4f:Stop 结论 + 第二方案落地 + 我的一个真违规(已沉淀)
一、功能确认(Stop 线程定论,决定性实测)
- 重启已生效(
last-launch.json=08:09:52、新 PID)+ 探针句已验证会命中 + 脚本已改为本工作区内每次调用必写一行 ⇒ 日志仍为空 ⇒ WorkBuddy 5.5.6 桌面版不调用Stop钩子 ⇒ 按「不留假安全感」已卸载(备份settings.json.bak-stopuninstall-082503)。 - 第二方案
UserPromptSubmit已装(官方契约:输入同样带transcript_path,且支持additionalContext注入;每轮必触发): · 两级模式:probe(只写日志、零风险)→inject(命中才注入上下文);切换 = 改<工作区>/.workbuddy/stop-guard-mode,即时生效、无需再重启(只有 settings 的 hooks 条目是启动快照) · 自测 4/4(probe 不注入 / inject 命中才注入 / 陈述句与"需要你拍板"节不误伤 / 每次调用必留痕) · 当前 = probe:下次你自然重启后读stop-dialog-guard.log:有invoked(user-prompt)⇒ 该面可用 ⇒ 我切inject;仍空 ⇒ 只余"常驻规则+每轮自检"那层,如实收口。 - 顺带修真 bug:脚本
main()的except: pass把NameError: out is not defined藏了半小时(我调了本文件不存在的out())⇒ 改为异常必留痕(A18 教科书案例)。
二、🔴 我的真违规(如实记):无锁改库
- 我在同一命令里用
... --claim-exec ... | grep -E "已持全局执行锁|停手"判抢锁 ⇒ 抢锁其实失败(有会话持锁), 但失败提示里也含关键词("…必须--release-exec才算完成")⇒ grep 假命中 ⇒ 我据此在无锁状态下改了档案 99 + scp + commit。 - 损害核对(无实际损害):我的 commit
cbf51ba只含 3 个文件(档案 99 / manifest / 我的脚本),未带走别人的半成品;档案 99 是我自己当天新建、别人不会改。 - 已沉淀为硬判据(项目根
CODEBUDDY.md §6+ 素材库 A18 姊妹坑):① 检查退出码(不要接管道)② 复读交接单/.exec-lock/OWNER并断言等于自己的会话名;"输出了像成功的话" ≠ 成功。
三、上一条要求已交付:常驻规则可移植化
- 新技能
dsh-env-bootstrap(SKILL.md +references/常驻规则-快照.md(19.4 KB / 6 章,由权威 CODEBUDDY.md 经--snapshot生成)+scripts/resident-rules.py) - 四命令实测 ✓:
--check全绿 rc=0(10 骨架锚点 + 5 章节)|--env-check✓(3 条 hooks 命令路径有效)|--inject(无--init)拒绝(防两处重复)|--snapshot✓ - 设计红线:权威方向单向(CODEBUDDY.md 权威 / 快照副本)· 默认只报不改 · 注入只动标记块 · 不假装能自动配环境
- 顺带修账实不符:
CODEBUDDY.md §3标题 R1–R10 → R1–R11;INDEX/README 的「红线 R1-R8」→ R1-R11 + 新增三处技能清单行 - 另:项目根 §7 加一条 —— 语法检查别用
python -m py_compile(必落__pycache__/*.pyc⇒ 污染对账「仅本地」)⇒ 用ast.parse不落盘写法。
四、收口 / 现状
- commits:
cbf51ba(Stop→第二方案 + 档案 99 修正节)·f3b475d(抢锁校验教训沉淀)·3b5bd42(env-bootstrap 入库)·5001f03(R11/U28) - 对账:仅本地 1 =
04-调整方案/100-实例内我的技能-并入功能管理分组.md—— 别的会话的在途产物(不在我清单 ⇒ 按 §6 不动、只报告);内容不一致 3 项亦全为别人 lane。 - 锁:当前空闲(每次均严格反序释放)。
13:53–14:05 会话 15ee0d4f:新增排版规范(可扫读)—— dsh-feature-first §5.4
用户要求:「和 AI 对话过程中 AI 返回执行信息和问题排版格式很不方便阅读,看看如何优化内容排版做到 内容结构清晰、重点突出、细节完整、方便快速浏览和阅读」
一、落在哪(三处 + 一处自检)
| 载体 | 内容 |
|---|---|
dsh-feature-first §5.4 排版规范(实体) |
A 六条硬约束(可自检)· B 五类回答的现成骨架(执行信息/是否已实现/报障/提问/长清单,不新造)· C 十条反模式 · D "细节完整 ≠ 全塞正文" |
dsh-feature-first §6 自检清单 |
加第 11 条:「这条回复能被扫吗?」(逐项数得出来) |
项目根 CODEBUDDY.md §1 |
一行指针(含六条摘要)—— 常驻、每轮生效 |
用户级 ~/.workbuddy/MEMORY.md |
一行跨项目偏好(所有项目都生效,不只 dsh) |
二、六条硬约束(都是"数得出来"的,不是感觉)
首屏 3 行给判定(✅/⚠️/❌ + 一句)· 层级 ≤3(不出 ####)· 每节 ≤7 行、连续 >12 行无结构 = 文字墙 · 加粗每节 ≤2 处且不整句加粗 · 表格 ≤5 列且单元格不塞整句 · 一条信息只出现一次。
三、五类回答的骨架(避免"每次都即兴排版")
执行信息 → §5.2 交付回执|是否已实现 → §5.1 结论骨架|报障 → 判定/证据(代码块 ≤10 行)/处置/未闭环|提问 → 问题 + 为什么问你 + 选项(推荐置首)|长清单 → 表格。
四、十条反模式(见到就改)
文字墙 · 嵌套 >2 层 · 结论埋段中 · 整句加粗 · 表格超宽 · 同信息重复三遍 · "如下所述"指代不清 · emoji 堆砌(只用于状态/分级)· 术语路径混进结论层 · 标题层级跳跃。
五、为什么这么定(不是审美)
用户要的四点 → 分别对应可检验的动作:结构清晰 = 层级≤3 + 五类骨架;重点突出 = 首屏判定 + 节首句给结论 + 加粗只留关键词;细节完整 = 细节进附录/代码块/表格附列(不删信息);快速浏览 = 每节≤7 行 + 表格 ≤5 列 + 一条信息只说一次。
六、收口
commits 4498b42(§5.4 + 自检第 11 条 + 两处指针)|严格抢锁(校验退出码 + 断言 OWNER)→ 同步归档(md5 20d601b5 双端一致)→ scp 镜像 OK → audit rc=0 / consistency ✓ → 锁已释放。
对账:仅本地 1 = 交接单/T08-集群化落地-兼容单例模式.md(别人的在途产物,不在我清单 ⇒ 不动、只报告);内容不一致 6 项亦全为别人 lane。
14:15–14:30 会话 15ee0d4f:「继续处理」—— 推进可做的部分 + 把两个客观卡点点明
用户:「继续处理」。
一、先判定两条线的卡点(都不是"我不想做",是客观条件)
| 线程 | 卡在哪(证据) | 已做到哪 | 什么条件回头 |
|---|---|---|---|
| UserPromptSubmit 探针定论 | 应用未重启:last-launch.json 仍 = 08:09:52、PID 29456 未变 ⇒ 钩子(08:26 装)尚未加载 ⇒ 日志空是预期,不是"不可用" |
钩子已装(probe)· 脚本自测 4/4 · 切换只需 echo inject > .workbuddy/stop-guard-mode(免重启) |
你下次完全重启后读日志:有 invoked(user-prompt) ⇒ 切 inject;仍空 ⇒ 卸载并如实收口 |
| 技能归档同步(本轮改动) | 全局锁被 exec-cluster-1a 持有(14:15 起 = T08 集群化在跑)⇒ R9 禁抢禁接管 |
3 个技能的工作副本已改好(库外、本地加载即生效) | 锁释放后:同步归档副本 + 镜像 + bump patch 版本 + commit |
二、本轮「继续处理」实际做完的事
- 排版规范一致性推广(避免"规范只活在一个技能里"的半截状态):
dsh-change-workflow阶段 5 第 4 条(汇总表交付)·dsh-decision-method§附自检第 12 条 ·dsh-env-bootstrap§4 自检第 5 条 —— 各加一行指向dsh-feature-first §5.4。 待落地/重启后待办.md(新):把"重启后必须做的两件事(探针定论 + 顺手核对)"写成显式文件,放待落地/⇒ 重启那一刻必然被看到;含判负前提(先看last-launch.json是否晚于 08:26,避免把"还没重启"误判成"不可用")。- 严格抢锁(校验退出码 + 断言 OWNER)→ 失败即停、未动库 ✓(这次判据正确,与上午那次违规形成对照)。
三、我 lane 待办扫描(只读)
交接单 §一:T03 ✅ 已归档;T08 集群化 = 🔄 执行中(占用者exec-cluster-1a,11:19 开工)—— 不是我的单,不动。- 对账:仅本地 1(
交接单/T08-…md)+ 内容不一致 6 项 —— 全为别人 lane。
15:0x 技能三处同步 + 工具缺陷修复(执行会话 排版指针归档-0718)
背景:上轮把 dsh-feature-first §5.4 排版指针加进 3 个技能的工作副本(~/.workbuddy/skills/),
但文档库归档副本(dsh-server-docs/skills/)没跟着,本次补齐并收口。
抢锁:--claim-exec "排版指针归档-0718" → 退出码 0 + 复读 .exec-lock/OWNER 断言一致
(⛔ 不接管道 —— 上次「假命中导致无锁改库」正是接管道造成的)。完工后 --release-exec + 断言目录消失。
改了什么
- 归档补齐 3 处:
dsh-change-workflow(汇总表那行)·dsh-decision-method(自检第 12 条)·dsh-env-bootstrap(自检第 5 条) - 顺路修 2 个真缺陷(都在本次要冻结的文件内):
①
dsh-decision-method活副本自检清单被插成…10, 12, 11(编号乱序)⇒ 改回…10, 11, 12②dsh-change-workflow §5指docs-status/文档库状态备注.md,该机制已不存在(照做必然失败)⇒ 改指「README.md模块表行 +INDEX.md场景速查行 + 全量清单行」 - 版本 patch bump:
2.9.0→2.9.1-playwright-banned/2.7.0→2.7.1/1.0.0→1.0.1;三者updated_at → 2026-09-15 README.md模块表:3 行版本号校正(原 v2.8.0/v1.0.0/v1.0.0)+ decision-method 素材库计数U1-U12/A1-A13/X1-X8 → U1-U28/A1-A25/X1-X14(已拆references/)- 修
handoff-guard.sh两处「双引号内未转义反引号」(L45 / L127):被 shell 当命令替换执行 ⇒ 印刷出来变成「必须 才算完成;」+ 每次抢锁往 stderr 抛command not found。恰坏在「教锁纪律」那句话上,命令名消失 ⇒ 读的人无从照做
新技术判据(已写进 MEMORY §三)
- ⚠️ 判行尾只能信字节级:
grep -c $'\r$'在本机把纯 LF 文件误报成"全部带 CR"(本轮先据此得出错结论, 被 Pythonb.count(b'\r')推翻)。实测分布:BRIEF / README /skills/**/.workbuddy/memory/**= 纯 LF;INDEX.md= 历史遗留混合(裸 CR ~472 + 裸 LF ~102 +\r\n双 CR ~120)⇒ 动它按字节处理 - 技能归档验收四件:① 两副本 md5 一致 ② 镜像 md5 一致 ③
README.md模块表 /INDEX.md登记行跟着改 ④ 七件套
验收(全部实测)
- 8 个文件(3 SKILL + 3 references + 1 script + README)两副本 md5 全一致,行尾保持纯 LF
- 镜像就位后 md5 一致;权限 600 / 700 root:root —— ⚠️ README 服务器现状即 600(规范文字写 644)
⇒ 按 R5「权限只准收窄」未放大;原件已备份
/opt/dsh/backups/docs-skills/(TS20260915_145751/_145933) - 七件套:
manifest/archive-index(只读模式,自报「表内容与 INDEX.md 一致」)/audit/consistency/shrink-guard/search全绿(退出码 0) docs-sync-check:本次 5 个文件已离开差异表(一致 165 → 169);剩余 ❌ 全是别人的在途
提交:391495a(4 文件)+ 82d3e49(脚本修复)—— 只 add 自己改的 5 个文件;未 push(§4 提交边界)
没动(别人的 lane ⇒ 只报告):INDEX.md(T01 在改)· BRIEF.md / DEPLOY-本部署.md / 交接单/README.md(T08)·
skills/dsh-opensource-release/SKILL.md(导出会话)· docs-manifest.json · 04-100 · 交接单/T08-*
顺带办完:工作区 MEMORY.md 15.5 KB → 12.0 KB(12,271 B) —— 注入超限被截断 ⇒ 整编:
合并重复条目、§四 与 PLAYBOOK 去重(章节标题一一对应)、状态更新为「T08 在途」、新增行尾判据。
原名备份 = .workbuddy/tmp/MEMORY.md.bak-pre-shrink-20260915(回滚 = cp 回去)。关键项抽查零丢失。
未决 / 下轮
README.md技能表第 4 行dsh-feature-first仍写v1.0.0(实际 1.4.0)—— 不在本次范围,未动INDEX.mdline 151 的U1-U12 / A1-A13 / X1-X8计数陈旧(同因,未动,避免与 T01 会话撞同一文件)UserPromptSubmit探针定论仍待完全重启后读.workbuddy/stop-dialog-guard.log(有日志 → 切inject)- 本次脚本与备份在
.workbuddy/tmp/:sync-skill-archive-20260915.py、bak-skill-sync-20260915/
16:40–16:53 新增交互规则「待确认 / 待决策内容放最后 + 有序段落」;并沉淀「跨载体扫描」
用户原话(两段,第二段补全)
- 「ai会话 要把需要我确认或决策的内容放在 最后,别隐藏在回复内容中间」
- 「是能根据决策方法 自行决策的就自决策继续处理,不能决策的问题和需确认内容放在回复的最后,按照有序段落展示」
关键发现:钩子文案与新规则直接对撞
scripts/stop-dialog-guard.py 的 REASON / CONTEXT 原写「…不要在结尾甩问题」——
会被读成把「位置」也一并否掉,与用户要求正相反。
裁决:用户管位置(放最后),钩子管形态(禁征询句) ⇒ 二者不冲突,但文案必须改写。
(user_prompt_mode 里 tail = tail_lines(text, 1) ⇒ 钩子只看最后一行,故"末节用陈述句列选项"不会触发 RE_BAN。)
一条规则 → 6 个载体全改(只改一处 ⇒ 其余立刻自相矛盾)
| 载体 | 改了什么 |
|---|---|
dsh-feature-first 1.4.0→1.5.0 |
§5.1 骨架 ③④ 对调(拍板项 = 末节)+ 骨架改逐条编号;§5.3 三条→四条铁律(新增铁律 4;铁律 3 标注"禁的是形态");§5.4 硬约束 六条→七条 + 骨架表同步 + 反模式 十条→十一条;§6 自检加第 12 条 |
scripts/stop-dialog-guard.py |
REASON / CONTEXT:「不要在结尾甩问题」→「放到最后一节、且逐条编号」 |
项目根 CODEBUDDY.md §1 |
📌 口径改写(自决/位置/有序段落/陈述句四件事)+ 排版指针行同步 |
用户级 ~/.workbuddy/MEMORY.md |
跨项目指针同步 |
dsh-decision-method 2.7.1→2.7.2 |
references/素材库-U-用户决策.md U21:③④ 对调 + 追加「修正(2026-09-15)」 |
dsh-env-bootstrap 1.0.1→1.0.2 |
references/常驻规则-快照.md 重生成(--snapshot;权威方向单向,勿手改),--check RC=0 |
README.md |
模块表 4 行版本号(含 feature-first 那行此前的陈旧 v1.0.0 → v1.5.0,本次因改动它而校正) |
顺带修的真实缺陷(同类复发):dsh-feature-first §6 自检清单编号乱序(原 11 排在 10 前面)——
与上轮 dsh-decision-method 那处一模一样,都是"插入新条时插错位"。
治本沉淀:dsh-change-workflow §5 新增「改跨载体规则时必做全载体扫描」(2.9.1→2.9.2):
6 类载体清单(技能正文 / 项目根常驻层 / 用户级记忆 / 钩子文案 / 生成物勿手改 / 登记行)+
判据「改完再 grep,命中应只在已改处」+ 点名「钩子文案最关键(每轮都在教训 AI 该怎么做,
与规则打架危害最大)」+ 收口四件。
验收(全部实测)
- 四个技能共 9 个文件两副本 md5 全一致,行尾纯 LF(CR=0)
- 镜像:本轮共推 9 件(两批 TS
20260915_164907/20260915_165149),就位后 md5 与本机一致; 权限 600 root:root(按现状,R5 未放大);原件全部备份/opt/dsh/backups/docs-skills/ - 七件套(两轮各跑一次)全绿;
resident-rules.py --check✅ 关键规则齐备;stop-dialog-guard.pyast 语法通过 grep -rn "有序段落"回扫 ⇒ 只命中已改处(无遗留矛盾表述)docs-sync-check:我的文件全在差异表外;剩余 ❌ 全为别人的在途
提交:f975aad(7 文件)+ b0fd279(2 文件);均未 push(§4 提交边界)
锁:两次 --claim-exec 都按硬判据校验(不接管道查退出码 + 复读 OWNER 断言),两次均 --release-exec + 断言目录消失
未纳入(别人的在途,只报告不动):INDEX.md / BRIEF.md / docs-manifest.json /
交接单/README.md / DEPLOY-本部署.md / skills/dsh-opensource-release/SKILL.md / 04-100 / 交接单/T08
仍待办:UserPromptSubmit 探针定论 —— 需完全重启后读 .workbuddy/stop-dialog-guard.log;
有日志 ⇒ echo inject > .workbuddy/stop-guard-mode 切 inject 模式(此后钩子会真的注入自检上下文)。