Files
dsh_ai1net_server/归档/代码与机制清退/guard与副本清退-20260924/dsh-ai1net-desktop__guard
admin c1b5e4d966 chore(工作区): 全量入库 + 补齐 .gitignore(以工作区为准)
- 变更规模:新增 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/ 知识文件,按口径入库)
2026-10-10 23:13:22 +08:00
..

guard/ —— 本工作区专用的 hook 副本(已于 2026-09-22 退役挂载)

🔴 2026-09-22 状态变更:本目录的两条挂载已撤下

退役原因:本目录的存在理由(源脚本作用域写死成单工作区)已被消除。 用户 2026-09-22 拍板「B」后,源脚本 dsh-server-docs/scripts/{skill,stop-dialog}-guard.py 自己改成了多作用域(_SCOPES_DEFAULT 含 aliyun-dsh-server + dsh-ai1net-desktop, 且支持 env DSH_GUARD_SCOPES)⇒ 源脚本单条即可覆盖本工作区。

若两套继续并存 ⇒ 本工作区每轮收到两份完全相同的注入指令 (2026-09-22 实测:副本与源脚本在同一秒各写一条 HIT,时间戳逐字相同)。 ⇒ 已从全局 settings.json 的 hooks.UserPromptSubmit 撤下本目录的 2 条。 备份:E:/ProgramData/.workbuddy/settings.json.bak-20260922-061649-retire-desktop-replica

⛔ 本目录保留作"回滚锚点"与历史记录,未删除。 需要重新启用时: 把本目录两条 command 加回 settings.json 的 hooks.UserPromptSubmit,并完全重启 WorkBuddy。 ⚠️ 重新启用前请先确认源脚本的 _SCOPES_DEFAULT 不再含 dsh-ai1net-desktop(否则又会双注入)。

下面 §1–§9 是退役前的历史说明,保留供追溯。

本目录是 dsh-ai1net-desktop 的 hook 作用域副本,2026-09-17 建立。 ⛔ 不要手改 skill-load-guard.py / stop-dialog-guard.py —— 它们是生成物,下次同步即被覆盖。要改就改源脚本。

1. 为什么要有这个目录(历史)

源项目 aliyun-dsh-server 的两个 hook 脚本把作用域写死成单个工作区:

SCOPE = 'aliyun-dsh-server'
...
if SCOPE not in tp: return          # stop-dialog-guard.py
if not workdir or SCOPE not in workdir: return   # skill-load-guard.py

⇒ 本工作区被一律判为"作用域外",这两条钩子静默空转(日志里 in_scope=False)。

按用户 2026-09-17 的决定:不改源项目脚本(那是别人的 lane,且在全局执行锁保护下), 改为在本工作区新建副本 + 同步机制。

第 3 条脚本 bash-output-guard.py 不在本目录 —— 它没有任何作用域门禁,对所有工作空间生效,无需副本。 lock-guard-hook.py 按文件路径(文档库 / 代码仓)判定,与本工作区无关。

2. 三个文件

文件 角色
sync-scoped-guards.py 同步器(手写、可改):读源脚本 → 只变换「作用域」那一层 → 写副本
skill-load-guard.py 副本(生成物)—— 用户点名方法时注入"必须加载技能"
stop-dialog-guard.py 副本(生成物)—— 注入收尾征询句纠正 / 分级水位 / 门禁·路径自检

状态文件:.guard-sync-state(记录每个副本对应的源脚本指纹,用于判定是否需要重新生成)。

3. 同步机制(三重,正常情况下无需人工介入)

# 触发 动作
1 自动(主路径) 副本每次被宿主调用时执行 self_refresh() ⇒ 比对源脚本指纹 ⇒ 有变化就地重新生成。⚠️ 带廉价前置判断:只在本工作区的会话里才真跑,其他工作区直接 return(不 spawn 子进程、不留痕)
2 手动 "<python>" sync-scoped-guards.py(--force 无视指纹强制重生成)
3 检查 "<python>" sync-scoped-guards.py --check —— 只报状态、不写盘

因为副本自己会在每次调用时自检,不需要额外的定时任务(等价的"持续同步",比"定期同步"更及时且零成本)。

4. 变换规则(只动作用域,其余逐字保留)

  1. SCOPE = '<单值>' → 提升为文件头的 _scopes() / _in_scope()(可用 env DSH_GUARD_SCOPES 覆盖,逗号分隔)
  2. SCOPE not in <expr> → not _in_scope(<expr>)
  3. SCOPE in <expr> → _in_scope(<expr>)
  4. 在 if __name__ == '__main__': 前挂一行 self_refresh()

叠加修正 C1(本工作区专有,幂等):源脚本 session_budget() 在「文件超大 / 不存在」两个分支 return None, None(2 值),而正常分支 3 值、调用处按 3 值解包 ⇒ 转录缺失时抛 ValueError。 源项目因作用域提前 return 而从未暴露;本工作区打通作用域后即成为每轮可达路径 ⇒ 生成时补齐为 3 值。 (源脚本若自行修复,本规则自动失效,不会重复动手。)

5. 安全设计

  • 生成后再校验:ast.parse 通过 + 变换后不得残留裸 SCOPE ⇒ 才落盘
  • 原子替换:写 .tmp 后 os.replace(并发调用不会读到半截文件)
  • 失败不动盘:源文件缺失 / 变换失配 / 语法不过 ⇒ 保留旧副本 + 非零退出码,绝不写坏
  • 只读源项目:只读源脚本、只写本目录;⛔ 永不修改源项目
  • 跨工作区零副作用:self_refresh() 有前置判断;副本的 scope 判定会让其他工作区直接 return

6. 挂在哪儿 / 怎么生效

两条副本已追加进全局配置 E:\ProgramData\.workbuddy\settings.json 的 hooks.UserPromptSubmit (现有 2 条源项目脚本之后,共 4 条)。备份:settings.json.bak-20260917-guard。

⚠️ hooks 是应用启动时的快照 ⇒ 新增条目必须完全重启 WorkBuddy(关窗 ≠ 退出)才加载。 (但脚本内容的改动不需要重启 —— 每次调用都现读磁盘。)

本工作区配套:.workbuddy/stop-guard-mode = inject(缺省 probe 只记日志、不注入提醒)。

7. 常见操作

PY="E:/ProgramData/.workbuddy/binaries/python/versions/3.13.12/python.exe"
G="E:/ProgramData/AI技能/dsh-ai1net-desktop/.workbuddy/guard"

"$PY" "$G/sync-scoped-guards.py" --check     # 看状态
"$PY" "$G/sync-scoped-guards.py"             # 同步(源变才动)
"$PY" "$G/sync-scoped-guards.py" --force     # 强制重生成

回滚(三档,从轻到重):

  1. 临时收窄:设 env DSH_GUARD_SCOPES=aliyun-dsh-server
  2. 单点急停:本工作区建 .workbuddy/skill-guard.disabled,或设 env DSH_STOP_GUARD_OFF=1
  3. 彻底卸载:把 settings.json 里那两条 command 删掉(或整体用 .bak-20260917-guard 还原),再删本目录

8. 扩展:再加一个工作区

在源脚本里扩展(推荐,一份实现)只改 3 处定义 + 判定; 或用本目录的方式:把新工作区加进 TARGETS 之外的 —— 只需把该工作区的路径标记传给生成器:

DSH_GUARD_WS_MARK=新工作区名 "$PY" "$G/sync-scoped-guards.py"

⛔ 若采用后者,不要原地覆盖本目录(会串作用域)—— 复制整个 guard/ 到新工作区的 .workbuddy/ 下再生成。