# 2026-10-09 工作日志 ## R9 唯一例外落地:授权检查会话自解除孤儿锁(用户令) **用户原话**(当日): > 「如果 工作区 项目机制 对应的会话异常 导致未解锁的情况下, 可以授权 检查会话自解除孤儿锁」 **起因(实测病例)**:`contentm_agent` 一把域锁 `contentm_agent/执行会话` 的持有者会话 `a257d30f` 被 terminated(起跑 00:48、末次活动 00:53)⇒ 锁没人释放 ⇒ 目标第 4 步 blocked。 R9「AI 一律不得删锁 / 不得接管」只有行为约定、**没有任何执行面**,理由写的是 「平台无心跳机制、AI 没有任何判据能确认对方已死」⇒ 检查会话连开 **11 棒**(22–31,约 5 小时) 每棒都撞同一面墙、零派活,每 30 min 一棒(`CHECK_COOLDOWN_S`)。 **判据(本次补上的"判据",直接推翻上面那句理由)**:宿主库 `workbuddy.db` → `sessions.status` + `last_activity_at`(只读 SQL): | 持有者状态 | 处置 | |---|---| | `working` | **一律不动**(R9 原样) | | `terminated` / `error` / `archived` | **可解除**(异常退出/已归档,不会再来释放) | | `completed` 且静默 ≥ 30 min | 可解除(已不在执行;时间闸只为不掐掉"刚收工、随时续聊"的会话) | | 查不到 sid / 库读不到 / `OWNER` 没记 sid | **一律不动**(fail-closed) | 实测两个存量孤儿:`e17c96e0`(`completed`,挂 10 天,`ai1net-dsh-anywhere`)、 `a257d30f`(`terminated`,`contentm_agent`)——**两种状态都会留孤儿锁**,故 `completed` 档必须收。 **落地(6 处,单一执行面)**: 1. 🆕 `session-mechanism/scripts/lock/orphan-lock.py` —— 判定 + 解除的**唯一执行面**; `--dry-run` 先看;写 `.locks/.orphan-release.log` 流水。⛔ 别自己写 `rm -rf`。 2. `collabd.py` 检查会话 prompt(**结果检查** + **目标检查**两条都加了):遇「域锁被占」 先跑 orphan-lock.py 判死活,判"已退出"⇒ **授权自解除后继续派活**;判"活着/判不出"⇒ 照旧停手。 同时补上「写明阻碍」的**出口**:台账 `--report … --state blocked --reason` + `NEED-USER.md` 里**明确喊「需用户介入」**(原先只说"写明阻碍",没说写哪儿 = 用户看不到)。 ⚠️ prompt 注入用「标记 + 事后 replace」,⛔ 不往 `%s` 实参元组加位(那处位置对齐,错位即 fatal 静默)。 3. `selftest.py` 新增用例(**16 项,含变异对照**):`working` 的锁一把都不许动、 宿主库读不到 ⇒ 一把都不动 —— 只验"terminated 能解除"的野实现同样会全绿,故反向断言非有不可。 ⇒ 全套 **PASS 107 / FAIL 0**(原 106)。 4. R9 条文同步(原先只有"绝对禁止",不改就是两份打架): 工作区 `CODEBUDDY.md §3` R9 行(**定义处**)、文档库 `dsh-server-docs/CODEBUDDY.md`、 技能 `references/rules.md`、`SKILL.md`;另两份 `handoff-guard.sh`(技能包 + 文档库 `07-scripts/`) 的"抢域锁失败"提示里加指针。 **验证(进程级)**: - `orphan-lock.py --dry-run` 活体对照 —— `cc07347c`(`working`)判 **不动** ✅ / `e17c96e0` 判可解除 ✅。 - 现场自愈:孤儿锁 06:26 被释放后,第 32 棒检查会话**真派了活** ⇒ 06:33 新执行棒 `cc07347c`「重做界面补闸门与上报(第二棒)」持域锁 `working` ⇒ 目标第 4 步重新推进。 - 分发 + 重启(「部署≠生效」):`deploy_code.py` 三区,`collabd.py` md5=**58e17cf0**; `collabctl.py off/on` 重启 `ai1net-dsh-server`(pid 73304→**37040**)、`vibe-product`(26992→**54096**), 心跳 <90 s、看板 20099 仍在监听。 ## 遗留(未做,需另起) - 🔴 **空转闸缺口仍在**:`queue_pending_of()` / `queue_pending()` 的四态口径里 `blocked` 与 `pending`/`running` **同样计入"未完成"** ⇒ 队列只剩一条 `blocked` 时,闸③「`sessions-ended` 必须队列非空」**恒真** ⇒ 唯一节流只有 `CHECK_COOLDOWN_S=30 min` ⇒ **每 30 min 空转一棒、无上限**。 本次只是把"能自解的那类阻碍"消掉了;**其它类型的阻碍照样会一直空转**。 拟补法(未实施):队列**无 `pending`/`running` 且只剩 `blocked`** ⇒ 冷却从 30 min 抬到 2 h(含兜底复检)。 - 🔴 **`contentm_agent` 总闸 = `off`,常驻却仍在跑**(pid 40016,08-08 08:21 设 off、08:45 起进程)—— 违反「只有 `collabctl` 能起进程」的总闸不变式。⇒ 该区**未重启**,检查会话仍是旧文案。 未擅自改(那是它的配置)。要切 on 并重启:`collabctl.py on --ws contentm_agent`。 - ⚠️ `handoff-guard.sh` **有两份且已漂移 18 行**(技能包 = 新,术语已收敛"任务会话"+roots.env 外置; 文档库 `07-scripts/` = 旧)。会话两条路径都在用(转录取证:`07-scripts/…` 32 次、技能包路径 20 次)。 - ⚠️ 未推送:技能仓(`E:/ProgramData/.workbuddy/skills`)与文档库均有本次未提交改动。 ⚠️ 当时另有一条会话 `a80f300d`「复制技能并推送」在跑,避免抢 `git add` 竞争 ⇒ 本轮不推。 ## 补:空转缺口改走「既有规则」—— 遇阻碍 ⇒ 置「阻碍」⇒ 机制暂停(用户纠正) **用户纠正原话**:> 「其他类型 阻碍 遇到阻碍修改目标状态 暂停机制 让用户决策 ,不是有这个规则吗」 🔴 **我上一轮的结论被纠正**:我提"降频冷却(30 min→2 h)"是**绕开既有规则**,⛔ 已作废。 既有规则(用户口径第①/②条:完成就收工;**阻碍也不用开**)确实存在,问题只是**没接上**。 **真因(三条腿互相锁死,缺一即空转)**: 1. 闸③「`sessions-ended` 队列必须非空」对一条 `blocked` **恒真** ⇒ 唯一节流只剩 `CHECK_COOLDOWN_S`。 2. 闸① 2026-10-04 收窄时把 `sessions-ended` **整条腿**从"目标状态闸"摘了出去 ⇒ **就算置了「阻碍」也照样建**。 3. `CHECK_PROMPT_RESULT` 第 3 条明写「⛔ 本轮你没有「改目标状态」的出口」⇒ **看得见的没权**; 而有权改状态的「目标检查」要**队列为空**才触发 ⇒ 队列里躺着 `blocked` 时**永不触发** ⇒ **有权的看不见**。 ⇒ 结果:每 30 分钟空转一棒、连开 11 棒、约 5 小时、零派活。 **落地(本轮)**: - `collabd.py` `CHECK_PROMPT_RESULT` 第 3 条改写:结果检查**开一个出口**(只此一个)—— `collabd.py --set-life 阻碍 --by "<会话名>" --check-why "<一句现状>"`; ⚠️ 「为什么」旗标是 **`--check-why`**(⛔ 不是 `--why`,那是 `--retire` 的,写错**静默忽略**); 要求**回读** `goal.json`;写明恢复=**主会话**跑 `--set-life 进行中`。 - `collabd.py` 闸① 改**两档**:`queue-empty` 非「进行中」⇒ 不建(原样);`sessions-ended` **只拦「阻碍」**, **「已完成」仍放行**(⛔ 别把 2026-10-04 修的病搬回来)。docstring「五道闸」→「六道闸」。 - prompt 注入用**第二个标记** `@@COLLABD_PY@@`(同样事后 replace,⛔ 不动位置对齐的实参元组)。 - `selftest.py`:新增用例(6 项含变异对照:阻碍⇒不建/已完成⇒**仍要建**); **改了旧断言**——`t_check_prompt_cmds_exist` 的「结果检查 ⛔ 一个 `--set-life` 都不许有」改为新口径; `t_two_kinds_of_check_agent` 里那两行**删除**(同一判据写两处 ⇒ 改一处漏一处,本轮实测就是这么报红的), 旗标级校验**只保留一处**。⇒ 全套 **PASS 108 / FAIL 0**。 - 规则文本:`references/rules.md` 新增 **§10「遇阻碍 ⇒ 改目标状态「阻碍」⇒ 机制暂停 ⇒ 让用户决策」** (此前这条口径**只在代码注释里**,规则文件一个字没有 —— 这也是它没生效的原因之一)。 **部署与验证**:`deploy_code.py` 三区,`collabd.py` md5=**5906584e**; `collabctl off/on` 重启 `ai1net-dsh-server`(74244)/`vibe-product`(52452); `contentm_agent` 被跨区自愈拉起(40016→**7388**)⇒ **三区进程全部跑上新代码**(未动它的总闸)。 判据:启动器 `supervise-launch.py` 只跑**本区副本** `/.workbuddy/collab/collabd.py`,该副本 md5 == 源。 ## 待拍板(挂起) - 🔴 **`contentm_agent` 总闸 = `off`,常驻却仍在跑**(且被跨区自愈反复拉起)—— 违反「只有 `collabctl` 能起进程」的总闸不变式;`off` 状态下任何 `ensure` 都可能把它**全停**。 - ⚠️ `selftest.py` 里 `t_check_cooldown_no_pileup` **被定义了两次**(同名,后者覆盖前者)⇒ 实际只跑一份。 - ⚠️ 未推送:技能仓与文档库均有本次改动未提交。 ## 提交(用户令:「确认修改无误后,提交仓库(知道应该提交哪里吗)」) **技能仓 = `E:/ProgramData/.workbuddy/skills` 本身**,远端唯一一个: `git@ssh.alotbuy.com:admin/workbuddy_skills.git`(master,`core.autocrlf=true`)⇒ 已提交并推送。 - 提交 `c76f5be`:7 份、+532/−29。**只 `git add` 自己改的**(⛔ 不用 `-A`): `SKILL.md`、`references/{manifest,rules}.md`、`scripts/{collabd,selftest}.py`、 `scripts/lock/handoff-guard.sh`、新增 `scripts/lock/orphan-lock.py`。 - 推送 `c36a3f4..c76f5be master -> master`;本地 == `origin/master`,工作区未提交 **0** 个。 - 提交前按「改完包必跑」跑 `install.py --manifest`(77 份、语法失败 0),新文件登记在 manifest 第 184 行。 - 入库前扫凭据:命中 `token`/`PASSWORD` 全是 `CODEBUDDY_GATEWAY_PASSWORD` 这类**变量名**与散文 (`design-tokens.css`、「零 token」)⇒ 无明文;改动集里也没有凭据类文件名。 - 一致性判据:**仓库存档 == 工作副本 == 三区运行副本**,四处 md5 全等 `5906584e…`。 **另两处改动不在技能仓里**(本轮**未提交**,就地保留): | 落点 | 所属仓 | 远端现状 | |---|---|---| | 工作区 `CODEBUDDY.md` | `E:/ProgramData/AIProject/ai1net-dsh-server`(511 存量改动) | `git@work.alotbuy.com:maogeigei/dsh_shenxian_workspace.git` ⇒ **SSH 主机密钥已变更、连不上** | | 文档库 `CODEBUDDY.md` + `07-scripts/handoff-guard.sh` | `D:/github/dsh_shenxian`(174 存量改动;`dsh-server-docs` 是它的子目录,本身不是仓) | origin **双推**:work.alotbuy.com(连不上)+ `https://cnb.cool/maogeigei/dsh-shenxian.git`(实测**可达**) | ⚠️ 新增两条环境事实:① `work.alotbuy.com` 的 SSH **主机密钥已变更**(`REMOTE HOST IDENTIFICATION HAS CHANGED`)⇒ 凡指向该主机的远端**一律推不出去**(两个仓都中);② 文档库仓在 `D:/github/dsh_shenxian`,⛔ 不是 `dsh-server-docs` 自己。 **用户裁定(同日):「不用处理」** ⇒ 文档库那两处(`CODEBUDDY.md` R9 例外、`07-scripts/handoff-guard.sh` 提示指针) **不提交、不推**,就地保留。⚠️ 后果已知并接受:文档库那份 R9 条文仍是「绝对禁止」,与已上线的机制口径不一致 ⇒ ⛔ **将来别再为这件事重新提问**;哪天要动文档库时顺手带上即可。 ## 用户追问:「同步仓库不是应该遵循忽略的规则吗,谁让把所有技能都提交仓库的」 **核实结论(三条,都有读数)**: 1. **不是我这轮干的**。`c76f5be` 的 `--stat` 只有 7 个文件、全在 `session-mechanism/` 下(+532/−29); 推送输出 `c36a3f4..c76f5be` ⇒ 远端只前进 **1** 个提交。 2. **忽略规则在生效、且 0 项违规**:`git status --ignored` 显示 13 项被正确挡在仓外 (`session-mechanism/install.log`、`session-mechanism/logs/`、`browser-harness/.venv/`、 `browser-harness/uv.lock`、`*.egg-info/`、两处 `__pycache__/`、4 个宿主迁移标记 JSON、 `browser-harness/.browser-harness-dev/`);`git ls-files -i -c --exclude-standard` = **空** (=已跟踪文件里没有被忽略规则本应挡住的)。唯一像凭据的 `browser-harness/.env.example` 是**示例**、无密钥。 3. **是 10-08 那条提交 `e03465c` 把技能全加进来的**(提交信息写「按用户令提交:把此前未纳管的 9 个技能目录一并入库」)—— 不是本线。仓库演化:`19101ac`(10-05) 只收 session-mechanism → `777f7fe`(10-07) 改推五个 → `9721876`(10-07) 加 product-planning/oil-ui-pro → **`e03465c`(10-08) 再加 9 个** ⇒ 现为 **15 个目录 / 4945 个文件**。 ⚠️ 用户当时口头点名的是 **5 个**(browser-harness/humanizer/humanizer-zh/product-planning/session-mechanism)。 ⚠️ 体积大头=`product-planning` 的 open-design 素材(2192 个 html、939 个 json、若干 1.4–2.0 MB 的 png)。 4. ⚠️ **别把"提交信息自称按用户令"当作用户原话**(本轮教训):要引用口径就引原话,认不下来就说不确定。 ⇒ **待用户拍板**:要不要把仓库从 15 个目录收回到点名的那几个(撤销当前版本 / 保持 / 重写历史三档, 倾向只撤当前版本——可逆、不动历史)。⛔ 未获指示前**不动仓库**。 ## 用户裁定「A 肯定要收回」⇒ 已收回(提交 `0204001`) **做法**:`git rm -r --cached` 撤出 2026-10-08 `e03465c` 一次并入的 **9 个目录** (AI HOT、draw-ui、dsh-diagnose、dsh-knowledge、dsh-local-env、dsh-opensource-release、 dsh-workflow、oil-motion、skills-security-check)—— **203 个文件**,**本地一个都没删** (撤销前后本地磁盘都是 **5711** 个文件,这是本轮的硬判据)。 **🔴 根因修法(对应「不是应该遵循忽略的规则吗」)**:`.gitignore` 由**黑名单改白名单** —— 根下 `/*` 一律挡掉,再逐个放行 6 个技能 + `.gitignore` + `改包纪律.md`。 为什么非改不可:黑名单只列"已知不要的",**新冒出来的技能目录会被任何一次 `git add -A` 顺手捎进仓库** —— 2026-10-08 那 9 个就是这么进来的。白名单从机制上堵死这条路。 ✅ 验证:`git check-ignore` 对撤出的 9 个全部命中(⛔ 不会被 add),对保留的 6 个全部不命中。 **保留范围(6 个)**:browser-harness、humanizer、humanizer-zh、product-planning、session-mechanism, **外加 oil-ui-pro** —— 它是 product-planning 第③段的**功能依赖**,撤掉两边都会留悬空引用。 **读数**:跟踪文件 4945 → **4742**(−203,与撤出数逐字吻合);顶层条目 7(6 技能 + `.gitignore` + `改包纪律.md`); `HEAD == origin/master == 0204001`,未提交 **0**;推送 `c76f5be..0204001`。本地磁盘仍 5711。 ⚠️ **已知代价(本轮不处理)**:撤出的目录仍留在**历史**里 ⇒ 新克隆体积不变(要缩得重写历史,用户选的就是不动历史); session-mechanism 里几处「⇒ 技能 X」的散文指针会指向不在仓的技能(不影响运行)。 ⚠️ **补记**:`contentm_agent` 总闸仍是 `off` 而常驻仍在跑(pid 7388→**39204**,被跨区自愈反复拉起)——仍未裁定。 ## 「别的电脑在那个技能夹里取仓,会不会动到已有文件」—— 已实测(git 2.55) 实验脚本:`tmp/probes/_clone_test.sh`、`_clone_test2.sh`(⛔ 全程在临时目录,不碰真仓)。 **① 默认行为=不动已有文件(fail-closed)**:在已有 `zz-other-skill/`、`note-local.txt`、 `session-mechanism/roots.env` 的目录里 `git checkout master`(**不带 `-f`**)⇒ git **直接中止**: `error: The following untracked working tree files would be overwritten by checkout: … Aborting`,**rc=1**。 ⇒ 已有文件**一个都没变**;代价是内容也拿不到。 **② 带 `-f`**:`zz-other-skill/`、`note-local.txt` **仍在**(未跟踪文件不删); 但 `session-mechanism/roots.env` **被仓库版本覆盖**(本机路径丢了)⚠️ —— 因为它是**已入库**的文件。 **③ 按需取(推荐做法,实测 0 改动)**: ``` git init git remote add origin <仓地址> git config core.sparseCheckout true printf '%s\n' product-planning/ humanizer/ > .git/info/sparse-checkout # ← 只点名你要的 git fetch origin master git checkout master ``` ⇒ 实测:已有文件 **0 改动**、`roots.env` 未被碰、只写入点名的两个目录。 ⚠️ 但它**取不到你已有的同名技能**(git 会因同名文件中止)——那种场景得先把旧的挪开。 **④ 白名单的连带收益(在别的电脑上)**:`git status` 保持**干净** ⇒ 那台机器自己别的技能 既不会被误当作"待提交",也不会被 `git add -A` 捎进仓库。 **⑤ 🔴 唯一的真例外**:`session-mechanism/roots.env`(本机路径契约)与 `session-mechanism/references/manifest.md`(本机 md5 清单)都是 **install.py 本机生成**的、 却**入了库**(`.gitignore` 里还专门写了"刻意入库")。⇒ 整目录取会把别人的路径换成我们的。 **修法(已列待拍板,未动)**:从库里撤出这两份(改入库 `*.example` / 由本机生成), ⛔ 本地文件保留(`git rm --cached`)。 ### 追加:用户澄清语义 ⇒ 「同名的该覆盖就覆盖,不要影响其他文件」(已实测,`_clone_test3.sh`) **结论:这正是 `git checkout -f` 的原生语义,不需要改仓库。** 做法:`git init` → `git remote add origin <地址>` → `git fetch origin master` → `git checkout -f -b master FETCH_HEAD`。 ⚠️ **关键就是那个 `-f`**:不带它时 git 会因同名文件**直接中止**(`_clone_test.sh` 实测 rc=1、什么都取不到)。 **实测读数(6 个预制文件,三组对照)**: - 同名 ⇒ **被覆盖**:`product-planning/SKILL.md`、`session-mechanism/roots.env` 都换成了仓库版本 ✅ - 本机独有 ⇒ **原封不动**:根目录文件、别的技能目录、**以及同一技能目录里的本机独有文件** (`session-mechanism/我的便签.md`、`product-planning/本机旧文档.md`)**全在** ✅ - 本机独有技能目录(`zz-other-skill/`)完整保留 ✅ ⚠️ **该模式的固有代价**(由"checkout 从不删未跟踪文件"直接推得,同一轮实测坐实): **仓库里删过的旧文件不会从本机自动清掉** ⇒ 会新旧共存,要清得自己删。 ⇒ 这也解释了为什么之前撤出 9 个技能目录后,别的机器上那 9 个不会被清走(它们只是不再被跟踪)。 ## 用户令:「那两份 不说具体 我怎么知道,看看会话提问的规则是否有缺陷」⇒ 审计并修 **先答**:那两份 = `session-mechanism/roots.env`(路径契约)+ `session-mechanism/references/manifest.md`(包内清单)。 **审计结论:有缺陷,而且三条**。 1. 🔴🔴 **判据用错了维度**(主因):旧措辞「⛔ 提问正文不许出现的:包名 · 环境变量 · 文件路径 · commit/sha · 表名/字段名 · 类名/函数名」——**按"词性"一刀切**;而同一段末尾又写「正文只留 **能决定下一步**的内容」⇒ **两句自相矛盾**。真遇到"要决定的对象本身就是两份文件"时, AI(我)按前半句执行、把文件名删了 ⇒ 待拍板项**不可答**。 2. 🔴 **同一判据散在 6 处、措辞各不同**(违反本项目自己的「禁重复判定标准」): `CODEBUDDY.md §1`(4 类)/`rules.md`(3 类,少"类名")/`作业总规矩 §1.7`(6 类)/ `02-功能优先协作协议`(结论层零技术标识)/`素材库-U-用户决策`(零技术标识)/注入块(0 类,只有"不用指代")。 3. 🔴🔴 **"每轮注入的那份"与"包内那份"是两份**(本轮实测坐实,最隐蔽): `reply-style-guard.py::_core()` 是**三级回退** —— ① **本工作区 `CODEBUDDY.md` 里 `` 之间那段**(每轮注入的就是它)② 包内 `references/03-回复排版-核心块.md` ③ 外部技能那份。⇒ 我先只改了 ② ⇒ **注入的仍是旧条文**, 而表面上"文件都改了、自测全绿",查不出来。 **修法(判据改成按功能判,一句话)**: > 🔑 **少了这个标识,用户还能不能决定下一步?** 不能 ⇒ 必须写进正文;能 ⇒ 必须删/下沉「技术附录」。 - ✅ 决定对象**必须点名**(要撤哪份文件 / 改哪个技能 / 推哪个仓 / 动哪台机器); - ⛔ 只服务实现的细节下沉附录(函数名/变量名/行号/sha/表名字段名/内部编号)。 **改动(6 个文件,全部改完并验证)**: `AIProject/ai1net-dsh-server/CODEBUDDY.md`(§1 那条 + **标记块内**)/ `references/03-回复排版-核心块.md`/`references/rules.md`/`references/02-功能优先协作协议.md`(2 处)/ `references/作业规矩/00-作业总规矩…md` §1.7/`scripts/selftest.py`。 **新增防漂移自测**:`t_reply_core_same_source` —— **工作区块 与 包内块 实质内容必须逐字一致** (⛔ 只允许首行注释不同)⇒ 从机制上堵住"改一处漏一处"。**全套 PASS 109 / FAIL 0**。 ✅ 验证:`_core()` 现从 `CODEBUDDY.md` 取块、长度 1274→**1814**、"含新判据=True、含旧禁令=False" ⇒ 下一轮起注入的就是新条文(钩子现读现用,⛔ 不必重启宿主)。 ⚠️ 未提交(按「未明确要求 ⇒ 不 commit/push」);改动**已即时生效**,不影响运行。 ## 用户令:①「A 方案」②「写/改技能规则文件时一律用肯定表述(新建、生成也一样;经验沉淀/红线避坑类除外)」 **① A 方案落地(仓操作,提交 `5004909`)**: `git rm --cached session-mechanism/roots.env` + `session-mechanism/references/manifest.md` (**本地文件一律保留**:实测 624 B / 18 568 B 仍在);新增入库样例 `roots.env.example`(占位符、无本机路径); `.gitignore` 加这两份的忽略行(⛔ 防 `git add -A` 捎回)并改掉原「刻意入库」注释。 ⇒ 别的电脑取仓时不再被"同名覆盖"换成我们的路径。 **② 「一律用肯定表述」写进注入面**(原来只在 `rules.md`,**注入面看不到** ⇒ 所以我又写了一批负向表述) - 口径(用户逐字):**写或改**技能与规则文件时一律写「要什么、怎么做」;**新建、生成时同样适用**; 例外=**以「经验沉淀」或「红线/避坑」为目的**的技能与规则(写法=正向目标 + 括号里的踩坑依据)。 - 落点:`REPLY-CORE` 段(工作区 + 包内,逐字一致)· `rules.md §9` · `改包纪律.md` 新增**第 5 条硬纪律**(「二、四条」→「五条」)· `01-文档索引.md` 指针 · 并把我在注入块里加的那段负向表述改成**正向主导**。 **🔴🔴 顺带抓到并修掉一个「我自己造成的净变差」(值得记住)**: 注入块**有 1400 字上限、且从开头截** ⇒ 我加条文把它从 1274 顶到 1414+ ⇒ 尾部三条(「变相征询同样禁止」「不用征询句收尾」「本工作区另有定稿」)**静默消失、不再注入**; 而模型那边只看到一句"超长已截断",看不出少了哪几条规则。 ⇒ 修:上限 1400 → **2000**;并在 `t_reply_core_same_source` 加断言 **块长 ≤ 上限**(以后顶破就报红)。 ✅ 验证:`被截断=False`;尾部三条都回来。 📌 **教训(通用)**:**凡"每轮注入 / 有长度上限"的面,改文字必须量长度** —— "改完自测全绿"不等于"改的内容真进了上下文"(同族:`_core` 三级回退那份)。 **验证**:全套自测 **PASS 109 / FAIL 0**;py 语法全绿;`install.py --manifest` 重算(78 份,语法失败 0); `HEAD == origin/master == 5004909`,工作区干净;`roots.env` / `manifest.md` 仓里已删、盘上仍在。 ⚠️ **未推送**:工作区 `CODEBUDDY.md`(注入块真源)也改了,但它属 `dsh_shenxian_workspace` 仓、 远端 `work.alotbuy.com` 已失效(SSH 主机密钥变更)⇒ 推不出去,本地生效。