session-mechanism:决策判据补每轮通路 + preflight-lock 补回落修复

用户问:「为什么决策方法 每次都要说一遍才会加载,是否需要把它纳入 hook」

一、根因(实测,⛔ 不是猜)
`decision-rules-hook.py` 早就存在、也早就接线(SessionStart,install.py 声明表第 11 条),
但它**只挂 SessionStart** ⇒ 会话开头注入一次,而**长会话被压缩后那段会一起丢掉**。
本机实测:一个由压缩接续而来的会话,上下文里**没有**那段注入。
用户的会话基本都很长 ⇒ 每次都丢 ⇒ 外在就是「不点名就不加载」,
而 `skill-load-guard.py` 只在**点名时**才提醒 ⇒ 形成「必须说一遍」的循环。

二、修法(零新增进程)
`decision-rules-hook.py` 增加 `UserPromptSubmit` 分支,注入极短版 `RULES_BRIEF`(四行);
由 `prompt-guards.py`(UserPromptSubmit 的多守卫合并入口)把本文件作为**第 5 个 guard**
合进同一进程调用 —— 实测 `decision=0.002 s`,⛔ 不新增 Python 冷启动
(该入口存在的理由正是"别再往 UserPromptSubmit 上串新进程")。
全量仍在 SessionStart 那份;每轮只补"最常被违反的四条"。

三、preflight-lock.sh 补回落修复(22799fc 漏了它)
`DOCS_ROOT` 的回落原与 `handoff-guard.sh` 同款(`$_SM_HERE/..` = 回落进技能包 `scripts/`)
⇒ 现改为「取不到就如实报错 + 留痕 + 退出码 2」。
⚠️ `handoff-guard.sh` / `lock-guard-hook.py` / `collabd.py` / `install.py` 四处已由 22799fc 落地。

验收:
· 语法:两个 .py 走 ast.parse、两个 .sh 走 bash -n(PortableGit 1.3.0)—— 全过
· 实跑 `prompt-guards.py`(UserPromptSubmit 载荷):注入 2387 字符,含「决策判据 / 技术实现自己定 /
  只提报用户三类 / 回复排版闸门」四项;各 guard 耗时 0.002–0.013 s
· 实跑 `handoff-guard.sh --status` ⇒ `root=D:/github/dsh_shenxian/dsh-server-docs`(正确落文档库,⛔ 不是技能包)
· 实跑 `collabd.py --domain-status` ⇒ 正常列出在册域锁(读侧已能读到锁)
· 全量自测 PASS 110 / FAIL 0
This commit is contained in:
admin committed 2026-10-15 22:44:59 +08:00
1 parent 22799fc9c2
commit 9b839e7a02
3 files changed
+72 -8

No files matched your search

@@ -27,7 +27,20 @@ _SM_HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
_SM_PKG="$(cd "$_SM_HERE/../.." && pwd)"
if [ -f "$_SM_PKG/env/roots.env" ]; then . "$_SM_PKG/env/roots.env"
elif [ -f "$_SM_PKG/roots.env" ]; then . "$_SM_PKG/roots.env"; fi
DOCS_ROOT="${DSH_DOCS_ROOT:-$(cd "$_SM_HERE/.." && pwd)}"
# 🔴 2026-10-15 修(第 11 条禁令 + D 盘实测事故):原写
# `DOCS_ROOT="${DSH_DOCS_ROOT:-$(cd "$_SM_HERE/.." && pwd)}"` —— 回落值是
# `$_SM_HERE/..` = **本技能包自己的 `scripts/`** ⇒ 锁根落进技能包。
# ✅ 现行:取不到 ⇒ **如实报错 + 留痕 + 退出码 2**,⛔ 不回落到包内、⛔ 不猜路径。
if [ -z "${DSH_DOCS_ROOT:-}" ]; then
_SM_ERR="${_SM_PKG}/logs/preflight-lock.err.log"
mkdir -p "$(dirname "$_SM_ERR")" 2>/dev/null || true
printf '%s ⛔ 取不到 DSH_DOCS_ROOT(本包 env/roots.env 缺该键)⇒ 退出码 2\n' \
"$(date '+%Y-%m-%d %H:%M:%S')" >> "$_SM_ERR" 2>/dev/null || true
printf '⛔ 取不到文档库根(DSH_DOCS_ROOT)—— 锁根无法定位 ⇒ 停手(退出码 2)。\n' >&2
printf ' ✅ 修法:把本工作区根写进 <技能包>/env/roots.env 的 DSH_DOCS_ROOT,或跑 install.py --apply。\n' >&2
exit 2
fi
DOCS_ROOT="$DSH_DOCS_ROOT"
CODE_ROOT="${DSH_CODE_REPO:-${DOCS_ROOT%/*}}" # ⛔ 不留盘符:代码库=文档库的上一级(纯 bash 展开,⛔ 不调 dirname)
WS_ROOT="${DSH_WS_ROOT:-$(pwd)}" # ⛔ 不留盘符:默认=当前工作目录(本文件内未被使用)
LOCKROOT="$DOCS_ROOT/05-交接单/.locks"