提问规则审计 + 撤出本机生成的两份契约 + 「一律用肯定表述」落进注入面
用户 10-09 三条令: ①「那两份 不说具体 我怎么知道,看看会话提问的规则是否有缺陷」 ②「A 方案」(撤出 session-mechanism/roots.env 与 references/manifest.md) ③「要用确定XXXX 这样的描述,避免 不要XXXXX 会导致上下文干扰的描述,除了经验沉淀和红线避坑外」 +「不只是修改 创建生成时也需要遵守」 一、提问规则审计(三条缺陷,全部修掉) 1、判据用错了维度:旧措辞「⛔ 提问正文不许出现的:包名·环境变量·文件路径·commit/sha·表名/字段名· 类名/函数名」是按**词性**一刀切,而同一段末尾又写「正文只留能决定下一步的内容」⇒ 两句自相矛盾。 我按前半句执行、把要撤的文件名删成了「那两份」⇒ 待拍板项不可答。 ✅ 改成按功能判:**少了这个标识,用户还能不能决定** —— 不能 ⇒ 写进正文;能 ⇒ 删、下沉技术附录。 2、同一判据散在 6 处、措辞各不同(违反本项目自己的「禁重复判定标准」):已收敛到同一句判据, 并互相标注「改这里必须同批改」。 3、🔴 最隐蔽:**每轮注入的那份 ≠ 包内那份**。钩子 `_core()` 是三级回退,① **本工作区 CODEBUDDY.md 的 `REPLY-CORE` 段**才是每轮注入的(包内那份只是换机器的兜底)。 我先只改包内 ⇒ 注入的仍是旧条文,而"文件都改了、自测全绿",看不出来。 ⇒ 两份都改 + 新增防漂移自测 `t_reply_core_same_source`(两份实质内容必须逐字一致)。 二、撤出两份「本机生成」的契约(用户选 A) - `git rm --cached session-mechanism/roots.env` 与 `session-mechanism/references/manifest.md` —— **本地文件一律保留**(实测 624 B / 18 568 B 仍在)。 - 为什么必须撤:别的电脑取仓时「同名覆盖」会把它们换成**我们这台机器**的路径 ⇒ 那台机器的 机制脚本去找不存在的目录。 - 新增入库样例 `session-mechanism/roots.env.example`(占位符,无本机路径)。 - `.gitignore`:加这两份的忽略行(⛔ 防 `git add -A` 捎回),并改掉原「刻意入库」那段注释。 三、「一律用肯定表述」写进注入面(原来只在 rules.md,注入面看不到) - 口径:**写或改技能与规则文件时一律写"要什么、怎么做";新建、生成时同样适用**; 例外=**以「经验沉淀」或「红线/避坑」为目的**的技能与规则(写法=正向目标 + 括号里的踩坑依据)。 - 落点:injected `REPLY-CORE` 段(工作区 + 包内,逐字一致)· `rules.md §9` · `改包纪律.md` 新增第 5 条硬纪律(「二、四条」→「五条」)· `01-文档索引.md` 指针同步 · 把我在注入块里加的那段负向表述改成**正向主导**。 四、🔴 顺带抓到并修掉一个我自己造成的净变差 - 注入块有 **1400 字上限、且从开头截** ⇒ 我加条文把它顶过上限(1274 → 1414+)⇒ 尾部三条(变相征询禁止 / 不用征询句收尾 / 本工作区另有定稿)**静默消失**、不再注入。 - 修:上限 1400 → **2000**;并在 `t_reply_core_same_source` 里加断言 **块长 ≤ 上限** —— 以后谁再顶破上限,自测直接报红,逼他"要么精简、要么显式抬上限"。 - 验证:`被截断=False`,尾部三条都回来了。 五、验证 - 全套自测 **PASS 109 / FAIL 0**;py 语法全绿;`install.py --manifest` 重算(78 份,语法失败 0)。 - 注入块实测:来源=工作区 CODEBUDDY.md,不截断,含「一律用肯定表述」「决定对象要点名到具体」 「新建、生成时同样适用」。
This commit is contained in:
1 parent
0204001a1b
commit
5004909267
12 files changed
+164
-219
No files matched your search
+8
-2
@@ -39,10 +39,16 @@ Thumbs.db
|
||||
*.swp
|
||||
*~
|
||||
|
||||
# 🔴 2026-10-09 改(用户令:「A 肯定要收回」+「别的电脑取仓时不要影响已有文件」):
|
||||
# 下面两份是 **install.py 在本机生成**的 ⇒ ⛔ 撤出仓库、改为本机各自生成。
|
||||
# 为什么必须撤(实测):别的电脑取仓时「同名覆盖」会把它们换成**我们这台机器**的路径
|
||||
# ⇒ 那台机器的机制脚本会去找不存在的目录(`roots.env` 里就是本机绝对路径)。
|
||||
# ✅ 样例仍入库:`session-mechanism/roots.env.example`(占位符,无本机路径)。
|
||||
session-mechanism/roots.env
|
||||
session-mechanism/references/manifest.md
|
||||
|
||||
# 📌 刻意**入库**的(⛔ 别误删):
|
||||
# roots.env —— 只有路径、无密钥;是 install.py 生成的**部署契约**,manifest 收录
|
||||
# assets/*.png —— 文档配图,是内容不是产物
|
||||
# references/manifest.md —— 包内文件清单(自身引用,写入即过期)
|
||||
|
||||
# 🔴 凭据类一律不入库(2026-10-06 发现「当前版本仍跟踪」)
|
||||
.neodata_token
|
||||
|
||||
@@ -44,9 +44,10 @@
|
||||
3. **历史记录按时间倒排** —— **新的在前面,旧的在后面**(⛔ 追加只能往前插,⛔ 不许接在末尾)。
|
||||
4. **简明扼要有效** —— **单条 ≤6 KB**;⛔ 论证过程/对比表格/逐条展开全删;
|
||||
⚠️ 但**判据要点一个不许丢**(长度达标而判据被删 = **更坏**,那是假绿)。
|
||||
5. 🔴 **只写正向范围,⛔ 不写「不用于 XXXX」**(2026-10-07 用户令)
|
||||
—— 规则正文在 **`rules.md §9`**(⛔ 只一处,本行只作指针)。一句话:技能/文档的"用途/范围"段
|
||||
一律写**用于什么**;列"不用于 A/B/C"会**把 A/B/C 喂进自动匹配面** ⇒ 反而更容易被误命中。
|
||||
5. 🔴 **一律用肯定表述(写 / 改技能与规则文件时,含新建与生成)**(2026-10-07 + 2026-10-09 用户令)
|
||||
—— 规则正文在 **`rules.md §9`**(⛔ 只一处,本行只作指针)。一句话:写**"要什么、怎么做"**;
|
||||
写"不要 A/B/C"会把 A/B/C **喂进自动匹配面 / 每轮注入面** ⇒ 反而更容易被误命中。
|
||||
例外(按文件性质):**以「经验沉淀」或「红线/避坑」为目的**的技能与规则(写法=正向目标 + 括号里的踩坑依据)。
|
||||
|
||||
## 三、🔴 为什么「存档」不等于「读得到」(10-04 实证)
|
||||
|
||||
|
||||
@@ -293,7 +293,7 @@ AI 交付时**先说功能,技术细节折叠在后**:
|
||||
| # | 铁律 | 反例(实证) |
|
||||
|---|---|---|
|
||||
| 1 | **回答主位 = 用户问的那件事**;AI 的进度 / 失误 / 计划**不得占前两节** | 用户问「是否已实现」,AI 先写「五、我自己的失误(一并交代)」+ 版本流水 → 用户被迫再追问一句才拿到结论 |
|
||||
| 2 | **结论层零技术标识**(版本号 / commit / 包名 / 内部函数名 / 路径 / 探针名)—— 最多放「技术附录」 | `0.2.19 / 0.2.20 / 0.2.23`、`TDZ`、`chr(10)`、`requestOverUnixSocket` 全在主线,用户读不出结论 |
|
||||
| 2 | **结论层零技术标识**(版本号 / commit / 包名 / 内部函数名 / 路径 / 探针名)—— 最多放「技术附录」;🔴🔴 **例外:决定对象必须点名**(要撤哪份文件 / 要改哪个技能 / 推哪个仓)—— ⛔ 抽象成「那两份」= 用户没法回答(2026-10-09 实测) | `0.2.19 / 0.2.20 / 0.2.23`、`TDZ`、`chr(10)`、`requestOverUnixSocket` 全在主线,用户读不出结论 |
|
||||
| 3 | **禁止征询式收尾**:「要我接着做吗 / 说一声即可 / 你看怎么弄」—— 下一步**已定**且不命中门禁(现行门禁 = **不可逆破坏性操作**,见 `CODEBUDDY.md §3 R8`)⇒ **直接做**,用陈述句交代。⚠️ 本条禁的是**形态**;**位置**要求见铁律 4 | 「要我现在接着做,说一声即可」—— 把本该自己拍的执行细节又推回用户(同 **X9** 一族) |
|
||||
| 4 | **能自决策的继续做;不能自决策的收到最后一节** —— 能按决策方法自决策 ⇒ **自决策 + 继续处理**(不为"要不要继续"而停);不能自决策(真门禁 / 需凭据·窗口)⇒ **收进整条回复的最后一节,按有序段落逐条编号**(每条 = 问题 + 选项**优缺点** + 我的倾向),⛔ 不许夹在中间,也不许散在正文里问 | 2026-09-15 用户原话:「**能根据决策方法 自行决策的就自决策继续处理,不能决策的问题和需确认内容放在回复的最后,按照有序段落展示**」—— 待拍板项夹在「进度 + 下一步」之间 ⇒ 用户扫不到、漏答 |
|
||||
| 5 | **提报给用户前先过「取舍筛」**:把候选各写 **优点 + 缺点** —— ① 某个**只有优点**(明显更优)或**只有缺点** ⇒ **不需要用户判断**,自己拍掉再陈述;② 只有**各有优有劣、客观标准分不出高下**(真取舍)才提报用户;③ 提报给用户时**必须逐项列出优点与缺点**(只写"差别在哪"不算);④ 候选**竖排成段**(A / B / C 各占一行),⛔ 不横排、不做成表格的列 | 2026-09-15 用户原话两段:「**需要我确认的方案需要说明优点和缺点,现在没法判断,假如只有优点或只有缺点那不需要我判断**」+「**每个需要我决策的问题的潜在解决方案 A B C 也按照段落式排版,别横着排列**」—— 此前只写"可感知差别"且**横排**,用户**没法判断** |
|
||||
@@ -374,6 +374,8 @@ AI 交付时**先说功能,技术细节折叠在后**:
|
||||
7. 技术选择我**记进档案**了吗(§2 的 9 类,做完要留痕,否则下次重新吵)。
|
||||
8. 用户问的是「是否 / 能不能 / 为什么不行」吗?—— 是 → 用 §5.1 结论骨架(**判定在前,过程在后**)。
|
||||
9. 结论层有没有技术标识(版本号 / commit / 包名 / 内部函数名 / 路径)?有 → 挪进「技术附录」。
|
||||
🔴 **但决定对象(要撤哪份文件 / 要改哪个技能 / 推哪个仓)必须留** —— 判据:**少了它,用户还能不能决定**;
|
||||
⛔ 抽象成「那两份」不是"零技术标识",是**把决定变成猜谜**(2026-10-09 实测)。
|
||||
10. 我有没有用「要我接着做吗 / 说一声即可」收尾?—— 有 → 改成陈述句,并**直接去做**(除非命中门禁 = 不可逆破坏性操作)。
|
||||
11. 这条回复**能被扫吗**?—— 首屏 3 行给判定 / 层级 ≤3 / 每节 ≤7 行 / 加粗 ≤2 处每节 / 表格 ≤5 列 / 一条信息只说一次 / **待拍板项在末节**(§5.4;执行信息·报障·提问**各有骨架**)
|
||||
12. **需要用户确认 / 决策的内容,在整条回复的最后一节吗**?—— 它后面若还有别的节 ⇒ **挪到最后**(2026-09-15 用户明令);且必须**逐条编号**(有序段落),不是散文一段;形态是**陈述句**,不是征询句。**反向也查一遍**:能自决策的事,我是不是停下来问了?
|
||||
|
||||
@@ -27,6 +27,15 @@
|
||||
` ` **说明**:为什么要你定(影响谁/断多久/花多少钱/有无不可逆)。
|
||||
` ` **候选 A**:优点…/缺点… —— **B、C 各占独立一行**,⛔ 不横排、⛔ 不挤进同一段。
|
||||
` ` **倾向**:我选哪个 + 一句理由。
|
||||
🔴🔴 **决定对象要点名到具体** —— 写清是**哪份文件 / 哪个技能 / 推哪个仓 / 动哪台机器**:
|
||||
🔑 判据=**少了这个标识,用户还能不能决定** —— 不能 ⇒ 必须写进正文;能 ⇒ 删掉,
|
||||
连同**只服务实现的细节**(函数名 / 变量名 / 行号 / sha / 表名字段名 / 内部编号)一起下沉「技术附录」。
|
||||
(避坑依据 2026-10-09:把要撤的文件名省成「那两份」⇒ 用户回「不说具体 我怎么知道」,该条报废。)
|
||||
- 🔴🔴 **一律用肯定表述**(2026-10-09 用户令):**写或改**技能与规则文件时 —— 本块 · 技能描述 ·
|
||||
钩子文案 · 用途/范围段 —— 都写**「要什么、怎么做」**(例:「要点名到具体是哪份文件」);
|
||||
**新建、生成时同样适用**(⛔ 不只管"修改")。
|
||||
✅ 例外:**以「经验沉淀」或「红线/避坑」为目的**的技能与规则(踩坑记录 · 红线清单 · 反例库)
|
||||
可以写负向 —— 写法=**先写正向目标,再把踩过的坑放括号里当依据**。
|
||||
- 🔴🔴 **「变相征询」同样禁止**(2026-10-06 用户据实况追认):凡是**要用户拿主意**的事 ——
|
||||
包括「**先只报不动**」「**等你发话**」「我倾向 X,你看呢」这类**不带选项的待定清单** ——
|
||||
**一律按上一条写成「待拍板项」**(问题 + 说明 + **各候选的优点与缺点** + 倾向)。
|
||||
|
||||
@@ -1,192 +0,0 @@
|
||||
# manifest · 包内文件清单
|
||||
|
||||
> 生成方式:逐文件 `compile()` / `json.loads` + md5 | **最近一次全量重算:2026-10-09 07:22 (清掉 product-planning 下 5 个外部会话遗留的 .bak(包体卫生)**
|
||||
> ⚠️ **2026-10-05 局部增量**:`references/pitfalls.md`(P0-77 拆条 + P0-73/P0-77 压缩)与
|
||||
> `scripts/goalctl.py`(`--switch-goal` 确认闸 + 旧目标归档)两行的 md5/大小已按当天实测值更新;**其余行仍是 10-04 基线**。
|
||||
> ⛔ 本表**不含** `install.log`(运行日志)与 `references/manifest.md`(自引用,写完即失真)。
|
||||
> ⚠️ **provenance 列里的 `skills/multi-session-collab/…`、`skills/workbuddy-session-forensics/…` 已是历史路径**
|
||||
> —— 那两个目录 2026-10-01 已移到 `<工作区>/归档/技能-退役-20261001/`(⛔ 不在技能根了)。
|
||||
|
||||
文件总数:**77** | 语法 / 结构检查失败:**0**
|
||||
|
||||
## ✅ 已完成 · 2026-10-05 「目标唯一性 + 换目标需确认」(用户口径落地)
|
||||
|
||||
> 用户原话逐字:**「一个工作区 同时只能执行一个目标,如果要切换目标,需要用户确认,然后切换和关注检查切换后的目标」**
|
||||
|
||||
- **改前取证(三条,全实测)**:① 载体 `goal.json` **本就是单文件** ⇒ 天然满足"同时一个";② **归档零实现**
|
||||
(`goalctl.py`/`collabd.py` 全文搜 `goals/` **零命中** ⇒ 那份归档件是**手工造的**);③ **确认闸零实现**
|
||||
(`declare` **直接覆盖** `title`,无任何准入判断)。
|
||||
- **修法(两道闸,均在 `goalctl.py::declare()`)**:① 标题变了 ⇒ **默认拒绝**(`rc=3`、**零写入**),
|
||||
必须带专用开关 `--switch-goal`(⛔ **不等于** `--yes`:前者=「用户已同意换目标」,后者只是「干跑转真写」,
|
||||
**混用 = 伪造用户授权**);② 确认后旧目标**整份**归档到 `goals/<旧标题≤40字>__<时间>.json` + 新目标留 `_前身目标`。
|
||||
- **验收(7 项全过)**:拒绝 rc=3 /同目标细化 rc=0 **不被拦** /归档 **32 字段 / 6186 B** 且与旧目标**同源** /
|
||||
**变异对照**(闸短路 ⇒ rc=0,还原 ⇒ rc=3,证判据非恒绿)/真区未污染 /副本 md5 全同。
|
||||
- ⚠️ **加闸带出的连带缺陷(已一并修)**:`declare` 没给 `--title` 时**回落成工作区名** ⇒ 把"纯细化"误判成
|
||||
"换目标" ⇒ 修成「**没给 ⇒ 保持现有标题**」(与 `--topics`/`--kpi` 同规矩)。
|
||||
- 📂 全文 ⇒ `references/pitfalls.md` **P0-78**;`lifecycle` 那条独立铁律 ⇒ **P0-79**(**从 P0-77 拆出**)。
|
||||
|
||||
### 📌 同批完成:`pitfalls.md` 沉淀纪律转绿(改前既有红,顺手修掉)
|
||||
|
||||
- 判据=「**单条 > 6 KB 且证据密度 < 4.0 ⇒ 判流水账**」。改前基线读数:`P0-73` 7590 B/2.8。
|
||||
- 修法(**两条腿**,⛔ 不靠删内容):① **拆条** —— P0-77 里"前缀改造"与"`lifecycle` 空转"是**两个主题**,
|
||||
拆出 **P0-79**(P0-77 7765→5107 B/P0-79 2141 B);② **删冗余展开**(P0-73 验收段的重复读数)7795→约 5.9 KB。
|
||||
- 结果:**沉淀纪律 ✓ 转绿**(5 项);自测 **`PASS 94/FAIL 3` → `PASS 95/FAIL 2`**(另 1 条报告型不计入)。
|
||||
- ⚠️ ⛔ 别为压体量**删判据要点** —— 判据自带关键词对账(`MUST` 表),删了就换一种方式报红。❗原编号 77 → 79,**不许再当 77 引用**
|
||||
|
||||
## ✅ 已完成 · 2026-10-05 三代术语收敛(本节替代原「待办」)
|
||||
|
||||
- **已执行**:包内 + 两个工作区副本三方同步,md5 一致(`collabd.py`/`goalctl.py`/`board.py`/`board_ext.py`/
|
||||
`selftest.py`/`collabctl.py`/`guard.py`/`init_workspace.py`/`session-rules-check.py`/`board.html` 全部 OK)。
|
||||
`selftest.py` 基线 **PASS 97 / FAIL 0**(报告型 1 条不计入);改名的 5 条 `@case` 均能按新名字 `-k` 找到。
|
||||
- **⛔ 三类不动,是判据不是遗漏**(下一次改名前照抄):
|
||||
① **「」引述内容逐字不动**(含跨行引述块)—— 引用用户口径只写原话;
|
||||
② **历史段整段不动** —— `SKILL.md` 19–27 行代际表、含 `旧称/旧词/一代/二代/第三代` 的行、`<hN> 历史…` 段落
|
||||
(要讲清三代分别叫什么,就必须留着旧名);
|
||||
③ **`.py` 里 `目标检查` 一律不动** —— 它是**检查会话类别名**(`_CHECK_TAGS`/`_CHECK_TOPICS`、
|
||||
`[检查]-[结果检查/目标检查]`),并散在字面断言里(`CHECK_KINDS["queue-empty"][1] == "目标检查"`、
|
||||
`rows.append(...)`、`【目标检查】` prompt 头)⇒ 改了直接断判据。
|
||||
- ⚠️ **一处同改对**:`board.py::_ROLE_LABEL["worker"]` 与 `board.html` 的 `role==='…'` 是同一处判据的两侧。
|
||||
- ⚠️ **本条暴露的存量缺陷(已一并修)**:`selftest.py` 的期望串原写 `才建立一轮任务会话`,而 `SKILL.md`
|
||||
引述里逐字是 `才建立一轮执行会话` ⇒ 该子项**改前就是红的**(被基线里的 97/0 掩盖)。
|
||||
- 工具:`tmp/term-apply-v3-20261005.py`(dry-run/`--apply`,写盘前自动备份)+ `tmp/term-sync-20261005.py`。
|
||||
|
||||
|
||||
## 2026-10-04 新增文件(⛔ 由 manifest 重算登记)
|
||||
|
||||
- `references/01-文档索引.md` — 3604 B |md5 `825999a411e2a4f6b740063f81c01b03`
|
||||
- `scripts/judge_audit.py` — 13562 B |md5 `8f14a973fa5709a3b9a60b065dc22d7d`
|
||||
- `scripts/workspace_mirror.py` — 17263 B |md5 `60f104b37df3133785abb13f686eea4f`
|
||||
- `assets/design-tokens.css` — 6364 B |md5 `0668feb3a4729f1022e579ac0c5d2569`
|
||||
|
||||
## 最近改动(⛔ 只记「什么时候改了什么」,不写流水账)
|
||||
|
||||
- **2026-10-02 07:0x · 开工第 0 步改名:会话「规划」→ 会话「规则机制」(本轮)**:
|
||||
① **用户纠正原话**:「**就应该是检查清楚 所有会话规则机制 是否配置完整且生效, 不是规划 是 规则**」
|
||||
⇒ 首版体检脚本**只查排期那一面**,当天实测出的三类失效(钩子注入指向已退役技能名 / 常驻快照写进幽灵目录 /
|
||||
每轮注入的记忆指针悬空)**一条都没覆盖** ⇒ 名字还叫「规划」=第二次「在册 ≠ 生效」。
|
||||
② **收敛成一个入口**:新增 `scripts/session-rules-check.py`(查 **三类十二项**:A 钩子在册·路径存在·
|
||||
注入技能名存在·闸门日志新鲜 | B 每轮注入记忆的技能指针·常驻快照不比权威旧 | C 周期钟·模型可用性·
|
||||
`cwds` 同形·投递心跳·活会话·`once` 从未运行的死排期);旧 `scripts/session-plan-check.py` **退役**
|
||||
到 `<WS>/归档/技能包-旧件-20261002/`,**能力不回退**。
|
||||
③ **状态标记改名**:`session-plan.json` → **`session-rules.json`**(旧的属过期件,⛔ 别拿来对照)。
|
||||
④ **判据收紧**:`cwds` 近失配原写成「同父目录 + 字面不同」⇒ 在 `AIProject/` 这种**多业务线平级目录**下
|
||||
把**别的线**报成失配(实跑当场 2 条假红)⇒ 改为「同父目录 + **名字去 `-`/`_` 后仍相同**」/「同名不同父目录」。
|
||||
⑤ **判据自验**:⑨⑫ 抽成**纯函数** + 合成样本夹具(`<WS>/tmp/rules-check-mutate.py`)—— 原版 10/0 绿、
|
||||
**四个变异体**逐一按预期报红。⚠️ 夹具**自己先红两次**(期望值写死:漏算样本 + 有序列表比中文名)。
|
||||
- **2026-10-01 18:5x · 外置根贯通 + 两处真缺陷(本轮)**:
|
||||
① `roots.env` 引导块从 9 份扩到 **16 份**(补齐 7 个非钩子脚本:`board` / `board_ext` / `collabd` /
|
||||
`deliver-gateway-token` / `goalctl` / `selftest` / `stop-collab`);
|
||||
② **盘符字面量清零**:配置目录兜底改 `~/.workbuddy`,工作区兜底改 `DSH_WS_ROOT`/cwd,
|
||||
覆盖网日志 glob 改 `DSH_OVERLAY_LOG_GLOB`(原为死路径 —— 本机 `E:/dsh-worker-dev` 不存在);
|
||||
③ 7 份加**输出编码兜底**;④ `roots.env` 增写 `CODEBUDDY_CONFIG_DIR`;
|
||||
⑤ 🔴 **修「钩子把技能包当工作区」**:`wb-result-hook.py` 的 `_WS_ROOT` 原按 `3×dirname(__file__)` 推,
|
||||
包内这份推出来=技能包自己 ⇒ 包里长出 `tmp/supervise-inbox/`;改为复用 `resolve_ws()`;
|
||||
⑥ 🔴 **修「重定向 + GBK ⇒ print 抛异常 ⇒ 顶层记 fatal、整轮失败」**(本机实测 4 次;
|
||||
这正是**常驻**跑不起来的拦路石 —— 常驻必须重定向 stdout);
|
||||
⑦ `install.py` 工作区模板路径纠错(原指 `scripts/collab/`,实际在 `scripts/`);
|
||||
⑧ `collabd.py` docstring + 两处活注释改**常驻定案**(上一轮漏传导);
|
||||
⑨ `lock/preflight-lock.sh` + `hooks/lock-guard-hook.py` 的盘符字面量清零;
|
||||
⑩ 新增 `install.py --manifest`(见下条);
|
||||
⑪ 🔴 **`scripts/selftest.py` 去掉最后一处项目绝对路径**:`t_tick_wired` 原先写死
|
||||
`<某工作区>/.workbuddy/tools/wb-result-hook.py` ⇒ 两处都不对:既违反「技能里只用相对路径」,
|
||||
又因宿主接线已改指**包内**那份而**恒走"文件不在,跳过"** ⇒ 看着绿、其实什么都没验(静默假绿)。
|
||||
现改按包内相对路径取 `hooks/wb-result-hook.py`,该用例从"跳过"变**真检**(4 项实跑通过)。
|
||||
- **2026-10-01 19:0x · `install.py --manifest`**:把「重算本表」固化成子命令
|
||||
(包一改表就过期 ⇒ 以前每轮临时手搓脚本、跑完即删,已因此误判两次)。
|
||||
只重写**表 + 计数行 + 重算时间**,⛔ 不碰上方散文;**行尾随原文件**(本表是 CRLF,写成 LF 会造成一次无声全文件 diff)。
|
||||
- **🔴 两份同源脚本「有意不一致」(⛔ 别当 bug 去修平)**:`preflight-lock.sh` 与 `lock-guard-hook.py` 在
|
||||
**技能包**与**文档库 `07-scripts/`** 各有一份。包内那份住在技能包里、**推不出文档库根** ⇒ 只能走
|
||||
`roots.env` +(`lock-guard-hook.py` 的)末位字面量兜底;库内那份住在 `<文档库>/07-scripts/` ⇒
|
||||
**按 `__file__` 往上两级即文档库根**。⇒ 包内有引导块、库内没有,是**位置决定的**,不是漏改。
|
||||
- **2026-10-01 18:2x · 瘦身(本轮)**:`references/collab-detail.md` 删去**原件 YAML 变更流水**(约 9.4 KB)+ 加**读法索引**+ 压缩 §12;
|
||||
`references/{manifest,taskgraph,pitfalls}.md` 去掉过期条目与旧抬头;包内 `__pycache__/`、`hooks/bak-*/`、`tmp/` 已清。
|
||||
**⛔ 本轮无机制代码改动。**
|
||||
- **2026-10-01 16:5x**:`scripts/hooks/session-log-guard.py` 新增「**硬档就地回收**」—— 到 8 MiB 先试**一次**把本会话
|
||||
`logs/<日期>/sdk/conversations/<sid>.log` 改名(后缀 `.recycled-<时间戳>`,⛔ 不删、⛔ 不以 `.log` 结尾故与清扫器不重叠)
|
||||
⇒ 宿主立刻重建并继续写 ⇒ **会话不必再因撞 10 MiB 而停手**;失败则**逐字退回**原「停手+建接续」口径。
|
||||
开关 `DSH_SLG_NO_RECYCLE=1`(只关回收、保留叫停)。⚠️ 文档库原件 `07-scripts/session-log-guard.py` **已同语义同步**。
|
||||
- **2026-10-01 16:0x**:原 `multi-session-collab` 的 `SKILL.md` 全文并入 `references/collab-detail.md`(治 8 处悬空引用:
|
||||
`§0.05` `§0.5.2` `§0.5.4` `§0.5.5` `§1.3` `§1.4a` `§3` `§6`);清掉 9 处旧技能路径/名的活文本;
|
||||
两个原技能目录移入 `<工作区>/归档/技能-退役-20261001/`。
|
||||
|
||||
## 逐文件清单
|
||||
|
||||
| 包内路径 | 字节 | md5 | 语法检查 |
|
||||
|---|---|---|---|
|
||||
| `SKILL.md` | 115645 | `fbf34519e32411b5491b94e0e515f667` | — |
|
||||
| `assets/board-launch.py.tpl` | 4355 | `7e9dfe1c4845f20dbb89f599d80e167b` | — |
|
||||
| `assets/board-render-probe.js` | 14398 | `a21bd1905b34537436ce778c6bfbc288` | — |
|
||||
| `assets/board.html` | 151811 | `c597cd7f21543542e9cdbe486c5ccd79` | — |
|
||||
| `assets/design-tokens.css` | 6364 | `0668feb3a4729f1022e579ac0c5d2569` | — |
|
||||
| `install.py` | 37297 | `55603c2e739e7b531998f5563f15f789` | ok |
|
||||
| `references/00-动手前必过.md` | 7181 | `33bc86e442ccd4fcbb930c79c4ad0641` | — |
|
||||
| `references/01-文档索引.md` | 4518 | `f401dd36b2d30cbc89ac91f9d633b72c` | — |
|
||||
| `references/02-功能优先协作协议.md` | 35529 | `9122a6715bde02ab549805d69866d1cf` | — |
|
||||
| `references/03-回复排版-核心块.md` | 7766 | `01277367d560383669ad493538e45587` | — |
|
||||
| `references/04-决策方法论.md` | 35566 | `eb5bdf8f100beb8eacb9f20b042df86c` | — |
|
||||
| `references/99-速查清单.md` | 9832 | `5c97728af7cb67e9be9a3e491bdc5fd9` | — |
|
||||
| `references/architecture.md` | 119631 | `5fc3b103bb846b6dd903df0b7e736d22` | — |
|
||||
| `references/collab-detail.md` | 98805 | `24bd0cfd10da66831f5d12f1716b7ebc` | — |
|
||||
| `references/collab.md` | 16560 | `97aa751f86d9b4ba8db401b5ec592695` | — |
|
||||
| `references/deploy.md` | 16754 | `4e382f7876f31754ec9629925340c2d8` | — |
|
||||
| `references/dsh-decision-method/素材库-A-AI推理.md` | 19914 | `89fc178e671c989d9079c1def20591da` | — |
|
||||
| `references/dsh-decision-method/素材库-U-用户决策.md` | 24597 | `94c9e860148f4265f1e21e5322346f94` | — |
|
||||
| `references/dsh-decision-method/素材库-反例-X.md` | 5712 | `8bce93e8c1ce71d17e6d33aa9a2d7724` | — |
|
||||
| `references/forensics.md` | 6067 | `1fb6deca9bb05bebe950d4f4e3adf043` | — |
|
||||
| `references/humanizer-en/LICENSE` | 1092 | `a8440fdde2a535efdd44813bce97df57` | — |
|
||||
| `references/humanizer-en/README.md` | 4204 | `f3f41dc19ef27b7591422a43140d17fe` | — |
|
||||
| `references/humanizer-en/SKILL.md` | 39490 | `3fd8d0d4175d1325cc942ce65733719d` | — |
|
||||
| `references/humanizer-en/references/always-on-templates.md` | 3066 | `1bbcc7aa145f5a8189f35af7f9477769` | — |
|
||||
| `references/humanizer-en/references/patterns.md` | 26186 | `830c68f9e07fb6bbee297b7a9004d994` | — |
|
||||
| `references/humanizer-en/references/patterns.zh.md` | 14867 | `2c661fde3d84751edc8053eedd36f930` | — |
|
||||
| `references/karpathy-output-ladder/SKILL.md` | 5252 | `f1e3b07003bbc544db52d32c122e6faf` | — |
|
||||
| `references/karpathy-output-ladder/assets/html-template/index.html` | 5883 | `b95c39d2cd41d8c0f21d4007e7ef3cef` | — |
|
||||
| `references/karpathy-output-ladder/references/ladder-workflow.md` | 2684 | `d49840707d19302d8f61f4e1d7f4ea2e` | — |
|
||||
| `references/karpathy-output-ladder/references/ste100.md` | 3022 | `fdbe3271c21a3c17f326d1e71de33b0d` | — |
|
||||
| `references/pitfalls.md` | 311254 | `d321a71e38dd246b8014b4c9100b12c7` | — |
|
||||
| `references/rules.md` | 11695 | `45c197444b94773034af2509443a4cb5` | — |
|
||||
| `references/supervise-persistence.md` | 34799 | `6f2a0b10f248ceaad3802188f97ecb74` | — |
|
||||
| `references/taskgraph.md` | 3521 | `be6c6540be86475bb3430688c2987afc` | — |
|
||||
| `references/作业规矩/00-作业总规矩(原 agent-operating-rules).md` | 70243 | `80fc5471015b237ee7aacd6976eda6fe` | — |
|
||||
| `references/作业规矩/02-工作区纪律.md` | 21351 | `1a679fdeb9cca0883a47f619d1aec85d` | — |
|
||||
| `references/作业规矩/03-多棒接力编排.md` | 13185 | `631b4b7455938b0c3a3a4f6f94d97eed` | — |
|
||||
| `references/作业规矩/04-去AI味与说话方式.md` | 14059 | `5100e1a26c3477541eafe1c7797d3b3a` | — |
|
||||
| `roots.env` | 624 | `ec38f15f9a4101d69c815aa2cdd7b477` | — |
|
||||
| `scripts/apply-reply-rules.py` | 7172 | `551b0ee5bf6c7a9f6b64c1b1d53bd343` | ok |
|
||||
| `scripts/board-launch.py` | 2794 | `998a66b9d335ab1863b5b871a527bf4f` | ok |
|
||||
| `scripts/board.py` | 146111 | `d90395d1f1a7c3f94419a33cdf444384` | ok |
|
||||
| `scripts/board_ext.py` | 45655 | `2319fb9d2d21bf961e03a42da9a1ad4b` | ok |
|
||||
| `scripts/collabctl.py` | 34007 | `d7769687e92bb878b22cad68e687fa15` | ok |
|
||||
| `scripts/collabd.config.example.json` | 1158 | `6655c15c411a84e3ca12fd136dbe2c60` | ok |
|
||||
| `scripts/collabd.py` | 442528 | `5906584e34210b37211a414d8a801c0c` | ok |
|
||||
| `scripts/deliver-gateway-token.py` | 5685 | `cbba9648d404ecd2683061e19dbdb24a` | ok |
|
||||
| `scripts/deploy_code.py` | 5325 | `a79cf5e5ffb3e8c60a31b4d0d8845f40` | ok |
|
||||
| `scripts/forensics/proc-parent.py` | 2347 | `8cdfff2dbb88303298752c3777da7b20` | ok |
|
||||
| `scripts/goalctl.py` | 53820 | `c4eb6c020ac102ca3ae7f0463c5d8051` | ok |
|
||||
| `scripts/guard.py` | 13653 | `43f4e279896090c6c6c3fcbdb4fa95d6` | ok |
|
||||
| `scripts/hooks/_env.py` | 17743 | `e08f33d97adb640dc1657c21ae59a2ad` | ok |
|
||||
| `scripts/hooks/bash-output-guard.py` | 17741 | `3f2fdfa17f66f7fcac42e06853433a26` | ok |
|
||||
| `scripts/hooks/decision-rules-hook.py` | 12399 | `c521237bada7487aecf5e54ad4d19ace` | ok |
|
||||
| `scripts/hooks/lock-guard-hook.py` | 20363 | `641457de0297ee7a812ccde57f67dc2b` | ok |
|
||||
| `scripts/hooks/prompt-guards.py` | 9332 | `0aa1d1fdd2bf5a40cda2e60d7a785534` | ok |
|
||||
| `scripts/hooks/reply-style-guard.py` | 13200 | `e044f5d3e52ae94775dfba2090e7ae8e` | ok |
|
||||
| `scripts/hooks/session-log-guard.py` | 24636 | `4dd13b24d541d1afc7b4874dba6bb1eb` | ok |
|
||||
| `scripts/hooks/skill-load-guard.py` | 30397 | `797cf48886233e452083f7855a84ac7f` | ok |
|
||||
| `scripts/hooks/stop-dialog-guard.py` | 51240 | `3e0791e42f41c37438601a9d2314dd8e` | ok |
|
||||
| `scripts/hooks/supervise-ensure-hook.py` | 14308 | `dc6f62584a8384baba0a1f2460828013` | ok |
|
||||
| `scripts/hooks/wb-result-hook.py` | 37199 | `2d4f694acd031222bf03b98a859b6e90` | ok |
|
||||
| `scripts/init_workspace.py` | 24042 | `dda53acd24bcc66d509bbdab3ebc0488` | ok |
|
||||
| `scripts/judge_audit.py` | 13562 | `8f14a973fa5709a3b9a60b065dc22d7d` | ok |
|
||||
| `scripts/keepalive.py` | 12265 | `b84c753917e0a34cf40800bda953e7a4` | ok |
|
||||
| `scripts/lock/handoff-guard.sh` | 35092 | `43f9b2616ea72c422d692653efdd6f7e` | — |
|
||||
| `scripts/lock/handoff-status.py` | 3923 | `3edb20f9c4021ebe2323478860bf8f6f` | ok |
|
||||
| `scripts/lock/op-lock.sh` | 4690 | `1a31eda3642e23693a65e1519860c744` | — |
|
||||
| `scripts/lock/orphan-lock.py` | 10179 | `3519ac8e0ae7fa3f15190601475e3850` | ok |
|
||||
| `scripts/lock/preflight-lock.sh` | 8673 | `e985ec1cb853fae4c351cd03b171355d` | — |
|
||||
| `scripts/mut_run.py` | 13323 | `3bffc12e1e57d5efc743bac55e584b62` | ok |
|
||||
| `scripts/selftest.py` | 504129 | `6dc2fb0fc945e8c4822ac3c2029170a0` | ok |
|
||||
| `scripts/session-rules-check.py` | 44412 | `b2b468992d80421106316eaf451e2477` | ok |
|
||||
| `scripts/stop-collab.py` | 10462 | `d8043bedd23b52b6642aaf7ec8b8c980` | ok |
|
||||
| `scripts/supervise-launch.py` | 2503 | `f416a2f197e5524a8859c1d227ba1d05` | ok |
|
||||
| `scripts/wake-session.py` | 11011 | `32c6038b541249730f322f933ee287c1` | ok |
|
||||
| `scripts/workspace_mirror.py` | 17263 | `60f104b37df3133785abb13f686eea4f` | ok |
|
||||
@@ -13,7 +13,10 @@
|
||||
- **提报用户标准 = 存在真取舍**:候选**只有优点或只有缺点 ⇒ 自己拍掉**;各有优劣才提报用户,且**逐项写优点 + 缺点**。
|
||||
- ⛔ **不许捆包**:要问红线**只问那一句**;技术方案自己定好、当**已定项**陈述。
|
||||
- ⛔ **禁用征询句收尾**(「要我…吗 / 请确认 / 你看怎么办」)⇒ 按三问重判,没命中就**删掉、自己做完**。
|
||||
- 🔴 **提报用户内容必须自包含**:① 一句话说清要决定什么(⛔ 不用指代)② 为什么要你定(影响谁 / 断多久 / 花多少钱)③ 每候选写优点 + 缺点,末行给倾向 ④ 一轮一问 ⑤ ⛔ 不出现包名 / 路径 / 变量名。
|
||||
- 🔴 **提报用户内容必须自包含**:① 一句话说清要决定什么(⛔ 不用指代;🔴 **决定对象必须点名**)② 为什么要你定(影响谁 / 断多久 / 花多少钱)③ 每候选写优点 + 缺点,末行给倾向 ④ 一轮一问 ⑤ ⛔ **只服务实现**的内部细节(函数名 / 变量名 / 行号 / sha / 表名字段名 / 内部编号)下沉「技术附录」。
|
||||
- 🔑 **⑤ 与 ① 的同一句判据**:**少了这个标识,用户还能不能决定?** 不能 ⇒ 必须写进正文;能 ⇒ 必须删。
|
||||
⚠️ 旧措辞是「⛔ 不出现包名 / 路径 / 变量名 / 类名」——按**词性**一刀切 ⇒ 把"决定对象"也删了
|
||||
(2026-10-09 实测:把要撤的两份文件写成「那两份」⇒ 用户回「不说具体 我怎么知道」)⇒ **已改成按功能判**。
|
||||
|
||||
## 2 回复排版(🔴 用户 2026-10-01 定稿,照抄即可)
|
||||
|
||||
@@ -81,18 +84,26 @@
|
||||
✅ 正解:结论**同时**落三处 —— `SKILL.md` 第一屏(会被读)+ `pitfalls.md` 一条(有来龙去脉)+ 本档一条规矩(约束以后怎么写)。
|
||||
- 🔴 **配套**:凡"换会话容易忘、忘了就会重来"的结论,**优先放第一屏**,⛔ 不要塞进长文档。
|
||||
|
||||
## 9 🔴 只写正向范围,⛔ 不写「不用于 XXXX」(2026-10-07 用户令)
|
||||
## 9 🔴 一律用肯定表述("要什么"优先)(2026-10-07 + 2026-10-09 用户令)
|
||||
|
||||
**技能与文档的「用途/范围」段一律写"用于什么"**,⛔ 不列"不用于 A/B/C"。
|
||||
**写或改技能与规则文件时,一律写"要什么、怎么做"** —— **新建、生成时同样适用**(⛔ 不只管"修改")。
|
||||
落点(都是「自动匹配面 / 每轮注入面」):技能的 `description` 与首屏 · **每轮注入的排版块与钩子文案** ·
|
||||
技能与文档的「用途/范围」段 · 其它规则正文。⛔ 不写「不要 A/B/C」这类负向描述。
|
||||
|
||||
- **为什么(机制性,不只"占地方")**:技能的 `description` 与首屏是**自动匹配面**(技能靠描述匹配被加载)
|
||||
⇒ 在里面列"不用于 X",等于**把 X 这些词喂进匹配面** ⇒ **反而更容易被不该命中的请求选中**
|
||||
(实测形态:`draw-ui` 描述里列了「不用于普通插画/海报/故事板」⇒ 用户说"做个海报"时它更可能被选上)。
|
||||
- **例外(用户 2026-10-07 明确给出)**:**经验沉淀可以写"如何避免踩坑"** ——
|
||||
禁令**不删**,但写成「**正向目标 + 依据(曾栽过什么)**」的形态
|
||||
(例:「本方法只出产品视角」+「曾因照英文商业框架产出而跑偏」)。
|
||||
- **为什么(机制性,不只"占地方")**:负向词进匹配面 = **把 X 这些词喂进去** ⇒ 反而更容易命中 X
|
||||
(实测形态:`draw-ui` 描述里列「不用于普通插画/海报/故事板」⇒ 用户说"做个海报"时它更可能被选上);
|
||||
进**注入面**是同一回事 —— 同样的反向拉高。
|
||||
- **例外(按文档性质定,⛔ 不按句子定)**:**以「经验沉淀」或「红线/避坑」为目的**的技能与规则
|
||||
(踩坑记录 · 红线清单 · 反例库 · `pitfalls.md` 这类)**可以写负向** ——
|
||||
写法=「**正向目标 + 依据(曾栽过什么)**」,⛔ 不把禁令单独摆在那儿。
|
||||
- 🔴 **落地(2026-10-09)**:这条口径已写进**每轮注入块**(工作区规则文件的 `REPLY-CORE` 段
|
||||
+ 包内 `03-回复排版-核心块.md`,两份逐字一致),并在 `改包纪律.md` 立为第 5 条硬纪律。
|
||||
此前它**只在本文里**、且只覆盖"用途/范围 段" ⇒ 注入面看不到 ⇒ 我又在注入块里写了一整段负向表述
|
||||
(用户 2026-10-09 点破)。防漂移判据=`selftest.py::t_reply_core_same_source`。
|
||||
- ⛔ **别与"事实陈述"混**:「配置里不含本工作区」「该目录不含 `board.py`」是在**描述事实**,
|
||||
不在本条管辖内 —— 一刀切会把它们误删。
|
||||
- ⚠️ **硬禁令(「三禁」这类)不在本条改写范围** —— 它们是约束本体,强度要留住;
|
||||
本条管的是**描述性文字**与**可选的举例**。
|
||||
|
||||
## 10 🔴 遇阻碍 ⇒ 把目标状态改成「阻碍」⇒ 机制暂停 ⇒ 让用户决策(2026-10-09 用户令)
|
||||
|
||||
|
||||
@@ -117,8 +117,25 @@ agent_created: true
|
||||
> **B 案**:<一句话做法>(优点:…;缺点:…)。
|
||||
> **倾向**:<A 案 或 B 案>。
|
||||
|
||||
**⛔ 提问正文不许出现的**:包名 · 环境变量 · 文件路径 · commit / sha · 表名 / 字段名 · 类名 / 函数名。
|
||||
技术细节一律下沉到「技术附录」,正文只留**能决定下一步**的内容。
|
||||
**🔴🔴 该写什么、不该写什么(判据 = 能不能决定下一步,⛔ 不按「是不是技术词」判)**(2026-10-09 修):
|
||||
|
||||
- ✅ **决定对象必须点名**:要撤哪份文件、要改哪个技能、要推哪个仓、要动哪台机器、要停哪个进程。
|
||||
⛔ 不许抽象成「那两份 / 那个文件 / 上述」——**那不是"自包含",那是把决定变成猜谜**。
|
||||
- ⛔ **只服务实现的内部细节一律下沉「技术附录」**:函数名 / 变量名 / 行号 / commit·sha /
|
||||
表名·字段名 / 内部编号(「涉及 R5 红线」「属边界外第③类」)。
|
||||
- 🔑 **一句判据(唯一)**:**少了这个标识,用户还能不能决定下一步?**
|
||||
不能 ⇒ **必须写进正文**;能 ⇒ **必须删/下沉附录**。
|
||||
|
||||
> **实测(2026-10-09 · 本条为何要重写)**:本条旧措辞是「⛔ 提问正文不许出现的:包名 · 环境变量 ·
|
||||
> 文件路径 · commit/sha · 表名/字段名 · 类名/函数名」——**按"类别"一刀切**。而同一段末尾又写着
|
||||
> 「正文只留**能决定下一步**的内容」⇒ **两句自相矛盾**。真遇到"要决定的对象本身就是两份文件"时,
|
||||
> AI 按前半句执行、把文件名全删了 ⇒ 用户的回复是「**那两份 不说具体 我怎么知道**」⇒
|
||||
> 待拍板项**不可答、整条作废**。⇒ 本轮把判据从"禁某几类词"改成**按功能判**(上面那句判据)。
|
||||
> ⚠️ 病根不是"名字太多",也不是"名字太少",是**判据本身用错了维度**(词性 ≠ 必要性)。
|
||||
|
||||
> ⚠️ **同一判据的另外三处载体**(改这里必须同批改,否则又是"改一处漏一处"):
|
||||
> `CODEBUDDY.md §1`(自动加载的实体章)· `references/rules.md` §「提报用户」条 ·
|
||||
> `references/03-回复排版-核心块.md`(**每轮注入**的排版块)。
|
||||
|
||||
**⛔ 五类半截问题(见到即改回去重写)**:
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
# session-mechanism · 根目录(由 install.py 生成,⛔ 请勿手改)
|
||||
# 说明:settings.json 的 hook 条目没有 env 字段 ⇒ 包内脚本靠本文件定位根目录。
|
||||
# 读取:各脚本头部 `_sm_load_roots()` 以 setdefault 注入 ⇒ **宿主 env 优先,本文件兜底**。
|
||||
DSH_WS_ROOT=E:/ProgramData/AIProject/ai1net-dsh-server
|
||||
WB_RESULT_HOOK_WS=E:/ProgramData/AIProject/ai1net-dsh-server
|
||||
COLLABD_PROD_CONFIG=E:/ProgramData/AIProject/ai1net-dsh-server/.workbuddy/collab/collabd.config.json
|
||||
CODEBUDDY_CONFIG_DIR=E:/ProgramData/.workbuddy
|
||||
DSH_DOCS_ROOT=D:/github/dsh_shenxian/dsh-server-docs
|
||||
@@ -0,0 +1,25 @@
|
||||
# session-mechanism · 根目录(样例 · ⛔ 请勿当成真文件用)
|
||||
#
|
||||
# 🔴 为什么有这份样例:真正的 `roots.env` 是**本机 `install.py --apply` 生成的**
|
||||
# (里面写的是**这台机器**的路径)⇒ ⛔ 不入库(入库会把别的电脑的路径覆盖掉)。
|
||||
# 本文件只示范**有哪些键、各填什么**,值一律是占位符。
|
||||
#
|
||||
# 用法:本机跑一次 `python install.py --apply` ⇒ 它会在包根生成真正的 `roots.env`。
|
||||
#
|
||||
# 读取机制:各脚本头部 `_sm_load_roots()` 以 setdefault 注入
|
||||
# ⇒ **宿主 env 优先,本文件兜底**。
|
||||
|
||||
# ① 工作区根(`state.py`、台账、心跳都在它下面)
|
||||
DSH_WS_ROOT=<工作区根>,例:E:/AIProject/<工作区别名>
|
||||
|
||||
# ② 结果钩子认的工作区(一般与 ① 同值)
|
||||
WB_RESULT_HOOK_WS=<同上>
|
||||
|
||||
# ③ 本工作区的协作机制部署配置(`COLLABD_CONFIG` 指向它;每个工作区一份)
|
||||
COLLABD_PROD_CONFIG=<工作区根>/.workbuddy/collab/collabd.config.json
|
||||
|
||||
# ④ WorkBuddy 的配置目录(宿主库 workbuddy.db 在它下面)
|
||||
CODEBUDDY_CONFIG_DIR=<WorkBuddy 配置目录>,例:E:/ProgramData/.workbuddy
|
||||
|
||||
# ⑤ 文档库根(锁目录 `05-交接单/.locks` 在它下面)
|
||||
DSH_DOCS_ROOT=<文档库根>
|
||||
@@ -57,7 +57,14 @@ except Exception: # 🔴 找不到就报错(⛔ 不静默
|
||||
CORE_REL = os.path.join('session-mechanism', 'references', '03-回复排版-核心块.md')
|
||||
BEGIN = '<!-- REPLY-CORE:BEGIN'
|
||||
END = '<!-- REPLY-CORE:END -->'
|
||||
MAX_CHARS = 1400
|
||||
MAX_CHARS = 2000
|
||||
# 🔴🔴 2026-10-09 由 1400 抬到 2000 —— **必须 ≥ 标记块实际长度**,否则是"净变差":
|
||||
# 本块**从开头截**,超出的部分(`变相征询禁止` / `不用征询句收尾` / `本工作区另有定稿` 三条)
|
||||
# 会**静默消失**,而模型那边看不出少了什么(只看到一句"超长已截断")。
|
||||
# 本轮实测:块 1274 字 ⇒ 全文注入;我加了约 300 字条文 ⇒ 1414+ ⇒ 尾部三条**当场失效**。
|
||||
# ✅ 配套判据:`selftest.py::t_reply_core_same_source` 断言 **块长 ≤ 本常量** ——
|
||||
# 以后谁再加条文顶破上限,自测直接报红,逼他"要么精简、要么显式抬上限"。
|
||||
# ⚖️ 取舍:抬高上限=每轮多带这点上下文;⛔ 但比「规则静默失效」便宜得多,所以选抬。
|
||||
LOG_REL = os.path.join('.workbuddy', 'reply-style-guard.log')
|
||||
DISABLE_REL = os.path.join('.workbuddy', 'reply-guard.disabled')
|
||||
|
||||
|
||||
@@ -7612,5 +7612,60 @@ def t_blocked_goal_pauses_check():
|
||||
return out
|
||||
|
||||
|
||||
@case("🔴 回复排版块:**每轮注入的那份**与**包内那份**必须同源(⛔ 别改一处漏一处)")
|
||||
def t_reply_core_same_source():
|
||||
"""🔴 2026-10-09 立(本轮实测踩到)。
|
||||
|
||||
钩子 `reply-style-guard.py::_core()` 是**三级回退**:① **本工作区 `CODEBUDDY.md` 里
|
||||
`<!-- REPLY-CORE:BEGIN…END -->` 标记之间那段 —— 每轮注入的就是它**;② 包内
|
||||
`references/03-回复排版-核心块.md`(单包自包含时的兜底);③ 外部技能那份。
|
||||
|
||||
⇒ **两份都要改**。本轮只改了 ②,注入到上下文里的仍是旧条文 —— 而表面上「文件都改了、自测也全绿」,
|
||||
根本查不出来。这就是「改一处漏一处」的同族,所以判据必须落在**两份一致**上。
|
||||
✅ 只允许首行 `BEGIN` 的注释不同(一份写给工作区看、一份写兜底说明)。
|
||||
"""
|
||||
def _blk(t):
|
||||
i = t.find("<!-- REPLY-CORE:BEGIN")
|
||||
j = t.find("<!-- REPLY-CORE:END")
|
||||
if i < 0 or j <= i:
|
||||
return ""
|
||||
return "\n".join(t[i:j].splitlines()[1:]).strip()
|
||||
|
||||
try:
|
||||
a = _blk((WS / "CODEBUDDY.md").read_text(encoding="utf-8", errors="replace"))
|
||||
except Exception:
|
||||
a = ""
|
||||
try:
|
||||
b = _blk((HERE.parent / "references" / "03-回复排版-核心块.md")
|
||||
.read_text(encoding="utf-8", errors="replace"))
|
||||
except Exception:
|
||||
b = ""
|
||||
|
||||
rows = [("包内那份标记块读得到(%d 字符)" % len(b), len(b) > 200)]
|
||||
if not a:
|
||||
rows.append(("本工作区没有该标记块 ⇒ 走包内兜底(跳过一致性比对)", True))
|
||||
return rows
|
||||
rows.append(("工作区那份标记块读得到(%d 字符)" % len(a), len(a) > 200))
|
||||
rows.append(("两份**实质内容逐字一致**(⛔ 改一份漏一份=注入的仍是旧条文)", a == b))
|
||||
rows.append(("两份都含「决定对象要点名到具体」(2026-10-09 修的那条判据)",
|
||||
"决定对象要点名到具体" in a and "决定对象要点名到具体" in b))
|
||||
rows.append(("两份都含「一律用肯定表述」(2026-10-09 用户令 · 此前只在 rules.md,注入面看不到)",
|
||||
"一律用肯定表述" in a and "一律用肯定表述" in b))
|
||||
# 🔴🔴 块长必须 ≤ 钩子的截断上限:本块**从开头截** ⇒ 超出的尾部是**静默消失**
|
||||
# (本轮实测:块 1274 时全文注入;加到 1414+ ⇒ 「变相征询禁止」「不用征询句收尾」当场失效)。
|
||||
try:
|
||||
import importlib.util as _ilu
|
||||
_sp = _ilu.spec_from_file_location("rsg_len", HERE / "hooks" / "reply-style-guard.py")
|
||||
_mm = _ilu.module_from_spec(_sp)
|
||||
_sp.loader.exec_module(_mm)
|
||||
_cap = int(getattr(_mm, "MAX_CHARS", 0))
|
||||
except Exception:
|
||||
_cap = 0
|
||||
_longest = max(len(a), len(b))
|
||||
rows.append(("块长 ≤ 钩子截断上限(上限=%d,实测最长=%d)—— ⛔ 超了就是尾部规则静默失效"
|
||||
% (_cap, _longest), _cap > 0 and _longest <= _cap))
|
||||
return rows
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
⚠️ 当时提交信息写的是「按**合并**落地」,实际效果是覆盖。这**不是恶意,是流程缺陷**:新稿的编写时点早于被覆盖文件的修改时点,落地时不做三方比对,就必然丢东西。
|
||||
|
||||
## 二、四条硬纪律
|
||||
## 二、五条硬纪律
|
||||
|
||||
### 1、⛔ 不许整文件覆盖
|
||||
|
||||
@@ -64,6 +64,18 @@ git diff --stat <上次收口提交> HEAD -- product-planning
|
||||
|
||||
拿「唯一权威处」这类**结构标记的计数**与上次收口版本比。计数掉了 ⇒ 先查结构,再看内容。
|
||||
|
||||
### 5、写 / 改规则文件:一律用肯定表述(2026-10-09 用户令)
|
||||
|
||||
**写或改**技能与规则的文字时,**写"要什么、怎么做"**,让读者照着就能做对;**新建、生成时同样适用**。
|
||||
|
||||
- ✅ 例:「要点名到具体是哪份文件」。
|
||||
- ✅ **例外(按文件性质定)**:**以「经验沉淀」或「红线/避坑」为目的**的技能与规则(踩坑记录 ·
|
||||
红线清单 · 反例库)可以写负向 —— 写法是「**先写正向目标,再把踩过的坑放括号里当依据**」。
|
||||
- **为什么**:这类文字是**每轮注入面 / 自动匹配面**(技能描述、注入块、钩子文案都在其中)。
|
||||
把「不要 X」喂进去 ⇒ **反而把 X 拉高命中**。实测形态:某技能描述里列了「不用于普通插画/海报/故事板」
|
||||
⇒ 用户说"做个海报"时它更容易被选上;2026-10-09 我在注入块里写了一整段负向表述,同族。
|
||||
- 规则正文(唯一权威)⇒ `session-mechanism/references/rules.md §9`。
|
||||
|
||||
## 三、出事后怎么修(照 2026-10-08 那次的流程)
|
||||
|
||||
1、**先定性,别急着改**。用可复现的方式坐实「是谁引入的」:
|
||||
|
||||
Reference in new issue
Block a user