Files
admin 5004909267 提问规则审计 + 撤出本机生成的两份契约 + 「一律用肯定表述」落进注入面
用户 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,不截断,含「一律用肯定表述」「决定对象要点名到具体」
  「新建、生成时同样适用」。
2026-10-09 10:45:00 +08:00

13 KiB
Raw Permalink Blame History

会话机制 · 规矩与判据(照它做,⛔ 别自己另发明)

⚠️ 本文件是作业规矩;机制全貌 ⇒ references/architecture.md;坑 ⇒ references/pitfalls.md。 🔴 与项目层 CODEBUDDY.md §1 冲突时以项目层为准(那里有裁决顺序)。

1 提问判据(唯一一条)

只问「超过现有判断方法边界」的问题。

  • 边界内 ⇒ 自决策,不要问:技术选型 / 实现路径 / 命名与数据结构 / 调参 / 部署与同步 / 排查方法 / 版本依赖 / 兼容降级 / 方案取舍 / 文档技术内容。 「部署上线」属此项 ⇒ 做完即上线,不要问;生产变更直接做,只需动手前一句话说明。
  • 边界外 ⇒ 必须问:① 业务目标与优先级 ② 花钱与资源承诺 ③ 对外承诺 ④ 需用户提供的凭据或审批 ⑤ 无客观优劣的偏好 ⑥ 影响面超出本平台 ⑦ 红线门禁 ⑧ 判不准。
  • 判据:有没有客观可判的优劣?有 ⇒ 自决策;没有 ⇒ 问。
  • 提报用户标准 = 存在真取舍:候选只有优点或只有缺点 ⇒ 自己拍掉;各有优劣才提报用户,且逐项写优点 + 缺点。
  • ⛔ 不许捆包:要问红线只问那一句;技术方案自己定好、当已定项陈述。
  • ⛔ 禁用征询句收尾(「要我…吗 / 请确认 / 你看怎么办」)⇒ 按三问重判,没命中就删掉、自己做完。
  • 🔴 提报用户内容必须自包含:① 一句话说清要决定什么(⛔ 不用指代;🔴 决定对象必须点名)② 为什么要你定(影响谁 / 断多久 / 花多少钱)③ 每候选写优点 + 缺点,末行给倾向 ④ 一轮一问 ⑤ ⛔ 只服务实现的内部细节(函数名 / 变量名 / 行号 / sha / 表名字段名 / 内部编号)下沉「技术附录」。
  • 🔑 ⑤ 与 ① 的同一句判据:少了这个标识,用户还能不能决定? 不能 ⇒ 必须写进正文;能 ⇒ 必须删。 ⚠️ 旧措辞是「⛔ 不出现包名 / 路径 / 变量名 / 类名」——按词性一刀切 ⇒ 把"决定对象"也删了 (2026-10-09 实测:把要撤的两份文件写成「那两份」⇒ 用户回「不说具体 我怎么知道」)⇒ 已改成按功能判。

2 回复排版(🔴 用户 2026-10-01 定稿,照抄即可)

  • 骨架:# 大类(已完成 / 待处理任务)→ ## 任务名 → 每件事两段:当前状态 + 待处理事项。
  • 🔴 大类标题必须比任务名大一号(大类用 #、任务名用 ##;⛔ 不许同号,否则层级压平)。
  • 当前状态:每条一个圆点,一句陈述句说重点;复杂情况放句末圆括号。
  • 待处理事项:用序号(1、2、,⛔ 不是 1.);每条写完整句子。
  • 附件:写在该板块最末一行(附件:<路径>)。
  • 大类顺序:已完成的放最前,待处理任务放最后。
  • 三禁:⛔ 表格(=省略讲理)|⛔ 长散文(不是写小说)|⛔ 碎标签堆叠。
  • ⚠️ 本条只管给人读的回复;注释 / 日志 / 解析字段不受限。

3 锁

  • 开工先抢锁(是"抢"不是"看");抢不到 ⇒ 停手 + 报告(红线 R9:⛔ 不删锁、⛔ 不接管)。
  • 🔴 R9 的唯一例外(用户 2026-10-09 授权):「工作区项目机制对应的会话异常导致未解锁 ⇒ 检查会话可自解除孤儿锁」。 判据不靠猜:scripts/lock/orphan-lock.py 去宿主库 sessions 表读持有者真身状态 —— 只有 terminated/error/archived,或 completed 且静默 ≥30 分钟 ⇒ 可解除;working ⇒ 一律不动。 ⛔ 唯一执行面就是这支脚本(--dry-run 先看;⛔ 别自己写 rm -rf 删锁);⛔ 例外只给检查会话、只覆盖这一种情形。
  • 🔴 默认一律带域(--domains <本工作区域>/);⛔ 别省略 —— 省略=全局独占,别人连域锁都抢不了。
  • 🔴 只有真正"全平台共用"的改动(配置 / 加解密 / 隔离 / 锁与钩子本身、技能文件)才用独占。
  • 🔴 释放必须反序且带会话名:--release → --release-exec "<会话名>";⛔ 不带名 ⇒ 拒释放。
  • 🔴 锁的生命周期 = 任务的生命周期:⛔ 禁抢锁做一半、不解锁就结束回合(带锁结束=把所有人挡在门外);中途要停 ⇒ 先释放。
  • 🔴 域键算法 shell/hook 必须逐字一致,否则静默失效。

4 日志闸(会话"活多久"的物理边界)

  • 本工作区闸值:文件软 5 MiB / 硬 8 MiB;工具调用软 200 / 硬 250。命中 ⇒ 开接续会话。
  • 🔴 宿主侧还有一个 10 MiB 硬上限:撞顶即拒写 ⇒ 界面静默哑掉、用户零感知,而投递方仍记 ok:true(假绿)。
  • 🔴 病根是"调用次数多",不是"每次调用贵";增长只与"工具在跑"成正比(实测:活跃 ≈630 KB/分 ↔ 空闲 34 分钟 0 行)。
  • 压增长三条硬纪律:① 大输出先落盘、只读关键行 ② 命令层限流(| head -30 / grep -c 代替裸 grep)③ 让脚本内部聚合、只 print 摘要。⛔ 禁 cat 大文件、无 head 的 grep -r。
  • ⛔ 不要在会话里起常驻后台长跑任务:它每次输出都把会话反复唤醒 ⇒ 永远回不到 idle ⇒ 用户看到"卡死"(已复现多次)。✅ 正确起法=会话后台任务 + stdout 全重定向到文件;或干脆做成独立进程(见 §6)。

5 钩子与脚本的写法约束

  • 🔴 hook 脚本必须走 sys.stdout.buffer.write(bytes) 输出 —— 否则文案含非 ASCII 符号时抛 UnicodeEncodeError ⇒ stdout 为空 ⇒ 静默放行。
  • 🔴 不要按位置推导根目录:钩子脚本被搬一次就会静默指错(历史事故:台账写到别处、测试却全绿)⇒ 用外置的 roots.env(本包由 install.py 生成)。
  • ⚠️ settings.json 的 hook 条目没有 env 字段 ⇒ ⛔ 别指望用 env 给钩子传参。
  • 🔴 作用域⛔ 不许静默排除:被跳过必须留下痕迹(写跳过清单 + stderr),否则"没动作"与"坏了"长得一模一样。
  • ⚠️ 钩子脚本内容改动即时生效;但 settings.json 的 hooks 条目是应用启动时快照 ⇒ 改条目要完全重启(关窗 ≠ 退出)。

6 常驻的精确边界

  • 🔴 「协作与投递一直运行(常驻)」是已定案项(09-29 定案,2026-10-01 用户再确认)⇒ ⛔ 不得拿"进程数=0"去否它。
  • 🔴 ⛔ 禁的是"在会干活的会话里起":会话自己的后台任务会压制该会话的 idle 钩子(实测被僵尸任务压 6h20m) ⇒ 载体应用专用容器会话;且输出必须完全静默(stdout 全重定向到文件,⛔ 否则反复唤醒宿主 ⇒ 看着像卡死)。
  • ✅ 独立进程不在禁令内(输出不接回任何会话 ⇒ 不唤醒宿主);但它读不到网关口令 ⇒ 不能投递,只能做只读判定 / 告警。
  • 存活边界一句话:「后台任务跟着应用活,不跟着会话活」⇒ 要"关了应用也还在"必须做成独立进程(⚠️ 但那就没口令了)。

7 其他硬约束

  • 🔴 技术讨论不谈法规:⛔ 不引条文当论据、⛔ 不主动提合规、⛔ 不前置提报用户;只在你问起、或对象就是"对外承诺 / 资质 / 合同"时才谈。
  • 🔴 红线 R5 / R7 / R9 / R10 永远硬约束(内容见项目层 CODEBUDDY.md §3 红线全表)。
  • 🎯 要解决问题,不将就妥协:降级 / 延期 / 静默兜底都不算解决;🟢 只做正向迭代。
  • 🔴 接手前人结论先做最小取证,⛔ 别拿旧结论当既成事实;取现状一律按 mtime 取最新那份。

8 🔴 验证通过的机制 ⇒ 必须写进技能(2026-10-05 用户明令)

用户原话:「这个也是会话规则,验证通过的机制要写进技能中」。

  • 🔴 一条机制实测跑通之后,落点只能是技能(SKILL.md 或 references/),⛔ 不许只留在工作区日志或当次对话里。
  • 判据:换一个新会话、不读任何历史,只看技能能不能照着做出来。做不到 ⇒ 等于没立。
  • ⚠️ 写的位置决定会不会被读到:SKILL.md 第一屏/「必读三篇」/索引表 ⇒ 每次都会读到;长文档正文底部 ⇒ 基本没人会翻到(等于没写)。
  • ⛔ 反例(10-05,同一件事栽到第四次):常驻的起法只写在当天日志里 ⇒ 之后每一轮都重新折腾一遍、每一轮都得出同样的结论。 ✅ 正解:结论同时落三处 —— SKILL.md 第一屏(会被读)+ pitfalls.md 一条(有来龙去脉)+ 本档一条规矩(约束以后怎么写)。
  • 🔴 配套:凡"换会话容易忘、忘了就会重来"的结论,优先放第一屏,⛔ 不要塞进长文档。

9 🔴 一律用肯定表述("要什么"优先)(2026-10-07 + 2026-10-09 用户令)

写或改技能与规则文件时,一律写"要什么、怎么做" —— 新建、生成时同样适用(⛔ 不只管"修改")。 落点(都是「自动匹配面 / 每轮注入面」):技能的 description 与首屏 · 每轮注入的排版块与钩子文案 · 技能与文档的「用途/范围」段 · 其它规则正文。⛔ 不写「不要 A/B/C」这类负向描述。

  • 为什么(机制性,不只"占地方"):负向词进匹配面 = 把 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 用户令)

口径(用户原话:「其他类型 阻碍 遇到阻碍修改目标状态 暂停机制 让用户决策」): 阻碍解不了时,正确动作不是反复重试,而是改目标状态把机制停住、交回用户。

  • 什么叫"阻碍"(三条全中):① 队列里那条 blocked 确认解不了 (含跑过孤儿锁判定仍判「不动」的);② 它是在等人,不是等某个会话;③ 原因已写进台账与 NEED-USER.md。
  • 谁去做:🔴 结果检查会话 —— 它是唯一能看见 blocked 的那条腿(靠"队列非空"触发); 「目标检查会话」虽有权改状态,却要队列为空才触发 ⇒ 队列里躺着 blocked 时它永不触发。 ⇒ 不给结果检查这一个出口,两条腿会互相锁死、只剩空转(2026-10-09 contentm_agent 实测: 连开 11 棒、约 5 小时、零派活,每 30 分钟一棒)。
  • 怎么做:collabd.py --set-life 阻碍 --by "<会话名>" --check-why "<一句现状>" ⇒ 闸① 随即生效、不再建检查棒(这就是"暂停机制")。 ⚠️ 「为什么」的旗标是 --check-why,⛔ 不是 --why(那是 --retire 的,写错会被静默忽略)。 ⚠️ 写完必须回读 goal.json 确认(本项目栽过「命令不存在却 rc=0 静默放行」)。
  • 怎么恢复:用户处置完 ⇒ 主会话跑 --set-life 进行中 ⇒ 机制自动复跑。 ⛔ 阻碍时不关后台任务与协作程序(用户口径第②条),只是不派活、不建检查。
  • ⛔ 别越界:「已完成」不归结果检查 —— 那是「目标检查会话」的活(判据是完成度,不是队列)。