From 5c5272569f6da83591480b88a5f5bc902d2b4866 Mon Sep 17 00:00:00 2001 From: maogeigei Date: Thu, 15 Oct 2026 23:33:44 +0800 Subject: [PATCH] =?UTF-8?q?session-mechanism=EF=BC=9A=E6=8C=89=2021=20?= =?UTF-8?q?=E6=9D=A1=E6=80=BB=E8=A1=A8=E8=87=AA=E5=AE=A1=2005=EF=BC=8F06?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E6=8E=89=207=20=E5=A4=84=E8=87=AA=E8=BA=AB?= =?UTF-8?q?=E8=BF=9D=E8=A7=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用 06 自己的判据过了一遍 06 与 05,查出并修掉: - ㉑ 一页纸:06 原文 134 行 > 120 ⇒ 压到 113 行(合并重复段、删重复触发词) - ⑥ 单一真源:05 的 ⑤~⑨ 与 06 的 A②③④⑤/B⑨ 逐字重复 ⇒ 05 改采读数,判据指回 06 - ⑥ 单一真源:总表 A/B/D 的判据列与正文 12 项重复 ⇒ 改成锚点(判据正本在正文) - ⑧ 命名一致:正文「工程/结构/表述层」vs 总表「A/B/C/D 层」⇒ 统一成 A/B/D,并写明 C 层来路 - ⑨ 不自相矛盾:入口段与「一句话调用」各列一份触发词 ⇒ 合并到入口一处 - ⑦ 注入面同源:SKILL.md 写「技能太长」、06 写「技能太长了」⇒ 统一 - ④ 路径形态:05 引 06 缺 references/ 前缀;06 引 selftest.py 缺 scripts/ 前缀;跨根路径改正斜杠 新增自测 t_skill_entry_triggers_same_source(10 项):SKILL.md §0 ⑧⑨ 的触发词与 05/06 文首集合相等,且 01-文档索引.md 里列的词 ⊆ 真源。 已做变异对照(SKILL.md 改一个字/索引里塞一个真源没有的词 ⇒ 报红;复原 ⇒ 绿)。 --- session-mechanism/SKILL.md | 16 +-- .../references/05-技能库盘点规程.md | 32 +++--- .../references/06-技能优化规程.md | 105 +++++++----------- session-mechanism/scripts/selftest.py | 86 ++++++++++++++ 4 files changed, 155 insertions(+), 84 deletions(-) diff --git a/session-mechanism/SKILL.md b/session-mechanism/SKILL.md index 907e1fb..a2988e0 100644 --- a/session-mechanism/SKILL.md +++ b/session-mechanism/SKILL.md @@ -459,23 +459,25 @@ python .workbuddy/collab/collabd.py --set-life 进行中 --by "主会话"  ✅ **判据实体就在本档正文里**(2026-10-04 改,原文写「权威在 `agent-operating-rules §1.6`」——现已改为**本档即权威**)⇒ 🔴 **只复制这一个技能到别的机器,这些功能全部可用,⛔ 不依赖任何其他技能**。📌 来路:2026-10-04 从 `dsh-decision/references/01` 逐行搬入;⛔ `dsh-decision` 那份视为副本,**改判据以本档为准**。  🔴 **配合任务会话的六阶段一起用**(见 `references/collab.md` §5):**需求识别 → 调研 → 规划 → 执行 → 验证 → 归档**——每个阶段都能撞上"该自己定还是该问用户",本档就是那一刻的判据。 -**⑧ 我要盘点技能库**(用户说「**盘点技能库**」「**技能库体检**」「**技能清单**」「**技能已无作用**」——任一句即触发)⇒ 读 **`references/05-技能库盘点规程.md`**(2026-10-15 立)。 +**⑧ 我要盘点技能库**(用户说「**盘点技能库**」「**技能库体检**」「**技能清理**」「**技能清单**」「**技能已无作用**」——任一句即触发)⇒ 读 **`references/05-技能库盘点规程.md`**(2026-10-15 立)。  它把 2026-10-06 ~ 10-15 里**零散做过的 6 次"技能盘点"**归纳成 **11 项可执行的检查**,分四段走:  · **先测再判** —— ① 盘点技能根下每一层(含**非技能散件**)② 判"在用/没用"(判据=**实际被加载过几次**,扫会话转录)。  · **分类** —— ③ 按"**删了会丢什么**"分四档(能力型/知识方法型/散件/绝不能动)④ 查功能重叠(列出合并落点)。  · **查隐患** —— ⑤ 白名单对不对 ⑥ 本机生成的契约有没有被误入库 ⑦ 入库代码里有没有"写死这台机器" ⑧ 路径形态对不对 ⑨ 正文有没有自相矛盾 ⑩ 有没有多份副本 ⑪ 待提交清单。 +  🔴 这一段的**判据正本 = `06-技能优化规程.md` 的 A/B 两层**,05 只管采集读数。  · **输出** —— 产物落 `交付物/技能清单-<日期>.md`,必须含「**这份读数能说明什么、不能说明什么**」一节。  🔴 开头就摆着两条**已证过的坑**:**零值必须先自证**(拿一个已知非零的样本做对照,否则"全 0"分不清真没有与没测到)· **"在册" ≠ "在跑"**(判机制生效看**新鲜调用时间戳**,⛔ 不看配置文件里有没有)。  ⛔ 本规程只交「清单 + 分档 + 读数」,**删/改/并的判据只有用户能给**;要动手另按 `references/00-动手前必过.md` 走。 **⑨ 我要优化技能本身**(用户说「**优化技能**」「**技能怎么改更好**」「**梳理技能**」「**梳理一下技能的要求和描述**」「**技能太长**」「**这条规则写在哪**」「**这个技能能不能拷到别的机器用**」——任一句即触发)⇒ 读 **`references/06-技能优化规程.md`**(2026-10-15 立)。  **一句话判据**:**写技能时,假设读者是"另一台机器上的另一个会话"** —— 拿它回放一遍,毛病自己浮出来。 - **三层,按顺序做(⛔ 别从第三层开始)**: - · **工程层**(换机器能不能活)—— ① 配置外置 ② 不写死本机 ③ 本机生成的契约不入库 ④ 路径形态统一 ⑤ 入仓按白名单。 - · **结构层**(后续会不会漂)—— ⑥ 单一真源 ⑦ 注入面与真源同源(🔴 每轮注入的面**改文字必须量长度**)⑧ 命名一致 ⑨ 正文不自相矛盾。 - · **表述层**(读起来对不对)—— ⑩ 肯定表述(正本 ⇒ `references/rules.md §9`)⑪ 说人话 ⑫ 一页纸。 - 🔴 **优先级判断**:工程层会**让人出事**(搞坏别的机器)> 结构层会**让后续每次都漂**> 表述层**只是效果差**。 - 🔴 **验法分三层**:工程层 ⇒ **拷到别处跑一遍**(能不能换机器跑通,是最硬的一条);结构层 ⇒ 同源比对/md5/判据;表述层 ⇒ 人读(⛔ 别假装它有自动结论)。 + **三层,按 A → B → D 这个顺序做**(层名与文末总表对齐): + · **A 工程层**(换机器能不能活)—— ① 配置外置 ② 不写死本机 ③ 本机生成的契约不入库 ④ 路径形态统一 ⑤ 入仓按白名单。 + · **B 结构层**(后续会不会漂)—— ⑥ 单一真源 ⑦ 注入面与真源同源(🔴 每轮注入的面**改文字必须量长度**)⑧ 命名一致 ⑨ 正文不自相矛盾。 + · **D 表述层**(读起来对不对)—— ⑩ 肯定表述(正本 ⇒ `references/rules.md §9`)⑪ 说人话 ⑫ 一页纸。 + 🔴 **优先级判断**:A 工程会**让人出事**(搞坏别的机器)> B 结构会**让后续每次都漂**> D 表述**只是效果差**。 + 🔴 **文末附「技能优化描述 · 总表」21 条四层**:A/B/D = 上面三层;**C 流程层**(步骤顺序/编号连续/无跳步/职责不越界/字段归属/上下游不断裂/引用路径/字段不缺失/产物链完整)来自另一来源,判据正本只在表里。A/B/D 判据正本在正文,表里是指针。 + 🔴 **验法按层不同**:A ⇒ **拷到别处跑一遍**(能不能换机器跑通,是最硬的一条);B ⇒ 同源比对/md5/判据;C ⇒ 画数据流看断点;D ⇒ 人读(⛔ 别假装它有自动结论)。 --- diff --git a/session-mechanism/references/05-技能库盘点规程.md b/session-mechanism/references/05-技能库盘点规程.md index 8294d6a..d7399d1 100644 --- a/session-mechanism/references/05-技能库盘点规程.md +++ b/session-mechanism/references/05-技能库盘点规程.md @@ -2,7 +2,7 @@ > **什么时候用**(本规程只管**库**:有哪些技能、在用没用、该不该入仓):用户说「**盘点技能库**」 > 「**技能库体检**」「**技能清理**」「**技能清单**」「**技能已无作用**」—— 任一句即触发本规程。 -> 📌 用户说「**梳理技能**」「**梳理一下技能的要求和描述**」指的是**改描述**,走 `06-技能优化规程.md`。 +> 📌 用户说「**梳理技能**」「**梳理一下技能的要求和描述**」指的是**改描述**,走 `references/06-技能优化规程.md`。 > **一句话判据**:**先把读数拿到手,再谈分类;分类之后只报"删了会丢什么",删不删由用户定。** ## 为什么要有这篇(2026-10-06 ~ 10-15 的实证) @@ -44,28 +44,32 @@ ## 第三段 · 查隐患(这一段的每一项都对应过一次真实事故) +🔴 **判据正本 = `references/06-技能优化规程.md` 的 A/B 两层**。本段只管**采集读数**, +不重复写判据 —— 某项查出问题,按 06 的对应项修。 + **⑤ 白名单对不对** -技能仓用白名单收(`/*` 全挡 + 逐个放行)。逐条问:**在仓里的,是不是都该在**。 -- 新增独立技能后,记得同步放行(2026-10-11:`video-capture` 独立了但白名单没加 ⇒ 仓里只剩一份指向仓外的交接说明)。 +读数:列出仓内已跟踪的目录 + 技能根下未被放行的技能目录,两边对照。 +🔴 判据 ⇒ 06 的 **A⑤**。漏放行的实证:2026-10-11 `video-capture` 独立了但白名单没加, +仓里只剩一份指向仓外的交接说明。 **⑥ 本机生成的契约有没有被误入库** -`env/roots.env`、`references/manifest.md` 这类**每台机器各不同**的产物,入仓即污染。 -判据:**它是不是由本机某个脚本生成** —— 是 ⇒ ⛔ 不入库。 +读数:在 `git ls-files` 里搜 `env/roots.env`、`references/manifest.md` 这类候选。 +🔴 判据 ⇒ 06 的 **A③**。 **⑦ 入库代码里有没有"写死这台机器"** -逐项查:盘符字面量 / 绝对机器路径 / 工作区清单。这些一旦入仓,同步到别的机器就搞坏对方环境 -(2026-10-11 用户报障原话:「这个环境都是针对一台机器的,同步到别的机器把环境都搞坏了」)。 -✅ 修法:**配置外置**(`env/roots.env`)+ **推不出来就如实报错留痕**。 +读数:对已入仓文件扫三样 —— 盘符字面量 / 绝对机器路径 / 工作区清单,逐条记位置。 +🔴 判据 ⇒ 06 的 **A②**;修法 ⇒ 06 的 **A① + A②**。 **⑧ 路径形态对不对** -包内引用**本包自己或同根技能**的位置 ⇒ 写 `<技能根>/<技能名>/` 或包内相对路径。 -**跨根引用**(工作区根 / 文档库根 / 本机软件安装位 / 宿主数据目录)⇒ 才落到具体位置,且优先读环境变量。 +读数:逐个引用点记下它引的是包内还是跨根。 +🔴 判据 ⇒ 06 的 **A④**。 **⑨ 正文有没有自相矛盾** -同一件事在技能里出现两种写法(尤其是正文与规则段之间)。逐条对:**同一个概念只留一处定义**。 +读数:同一概念在各篇出现的位置与写法,成对列出。 +🔴 判据 ⇒ 06 的 **B⑨**;同一件事散在多处的,收敛口径见 06 的 **B⑥**。 **⑩ 有没有多份副本** -同一技能存在 ≥2 份 ⇒ 定"唯一形态",其余归档(⛔ 不直删,留取回路径)。 +同一技能存在 ≥2 份 ⇒ 定"唯一形态",其余归档(留取回路径,⛔ 不直删)。 **⑪ 待提交清单** 技能库相对 HEAD 有哪些改动(已跟踪 + 未跟踪分开列),逐条注明"谁在什么时候改的、为什么"。 @@ -86,6 +90,6 @@ ## 一句话调用 -用户说「**盘点技能库**」「**技能库体检**」「**技能清单**」⇒ 按本文件跑一遍,产物落 `交付物/技能清单-<日期>.md`。 -用户点名范围(如"只盘 X 区""只看白名单")⇒ 只跑对应那几项。 +用户点名范围(如"只盘 X 区""只看白名单")⇒ 只跑对应那几项,触发词清单见文首。 +产物落 `交付物/技能清单-<日期>.md`。 📌 姊妹篇:**改技能描述**(一条规则写在哪、怎么表述、能不能换机器用)⇒ `references/06-技能优化规程.md`。 diff --git a/session-mechanism/references/06-技能优化规程.md b/session-mechanism/references/06-技能优化规程.md index 53e7fce..29d1258 100644 --- a/session-mechanism/references/06-技能优化规程.md +++ b/session-mechanism/references/06-技能优化规程.md @@ -1,41 +1,37 @@ # 06 · 技能优化规程 > **什么时候用**(本规程只管**描述与结构**:这条规则写在哪、怎么表述、换台机器还灵不灵):用户说 -> 「**优化技能**」「**技能怎么改更好**」「**梳理技能**」「**梳理一下技能的要求和描述**」「**技能太长了**」 -> 「**这条规则写在哪**」「**这个技能能不能拷到别的机器用**」—— 任一句即触发。 +> 「**优化技能**」「**技能怎么改更好**」「**梳理技能**」「**梳理一下技能的要求和描述**」「**技能太长**」 +> 「**这条规则写在哪**」「**这个技能能不能拷到别的机器用**」—— 任一句即触发;点名某一层(如"只看工程层")⇒ 只跑那一层。 > **一句话判据**:**写技能时,假设读者是"另一台机器上的另一个会话"。** +> 📌 姊妹篇:**盘点技能库**(有哪些技能、在用没用、该不该入仓)⇒ `references/05-技能库盘点规程.md`。 -## 为什么是这一句(模型判断,依据=2026-10-05 ~ 10-15 的六次实操) +## 为什么是这一句(依据=2026-10-05 ~ 10-15 的六次实操) -近 10 天里「技能怎么改」被反复提过,表面看是六件不相关的事 —— -写死盘符、肯定表述、规则散落、注入被截断、命名混用、旧稿覆盖新稿。 -把它们摆在一起看,**根因是同一个**:**技能是「跨机器、跨会话共享的文本」,但作者在按「本机、本会话」的假设写它。** - -- 按"本机"写 ⇒ 写死 `E:/...` ⇒ 换台机器就坏别人的环境(2026-10-11 用户报障原话: - 「这个环境都是针对一台机器的,同步到别的机器把环境都搞坏了」)。 -- 按"本会话"写 ⇒ 规则散在六处,改一处漏一处;注入面有长度上限,超了**静默丢**, - 而下游只看到一句"已截断",看不出少了哪几条。 -- 按"我读得懂"写 ⇒ 描述里写负向("不用于海报"),而描述是**自动匹配面** ⇒ 反而把"海报"喂进去。 - -⚠️ 反过来说:**任何一条技能优化,只要拿"另一台机器 + 另一个会话"回放一遍,毛病就自己浮出来。** -这就是本规程的判据来源,也是它比"清单"更该先看的那一条。 +近 10 天里「技能怎么改」被反复提过,表面是六件不相关的事 —— 写死盘符、肯定表述、规则散落、 +注入被截断、命名混用、旧稿覆盖新稿。摆在一起看**根因是同一个**:**技能是「跨机器、跨会话共享的文本」, +作者却在按「本机、本会话」的假设写它** —— 按"本机"写就写死 `E:/...`(2026-10-11 用户原话: +「这个环境都是针对一台机器的,同步到别的机器把环境都搞坏了」);按"本会话"写就把规则散在多处。 +⚠️ **拿"另一台机器 + 另一个会话"回放一遍,毛病自己就浮出来** —— 这是本规程的第一判据。 --- -## 三层优化(🔴 按这个顺序做,⛔ 别从第三层开始) +## 三层(🔴 就按 A → B → D 这个顺序做) -**先看一条优先级判断**:工程层的毛病**会让人出事**(搞坏别的机器);结构层的毛病**会让后续每次都漂**; -表述层的毛病**只是效果差**。⇒ **工程 > 结构 > 表述。** +优先级:**A 工程 > B 结构 > D 表述** —— 工程层的毛病会**让人出事**(搞坏别人的机器); +结构层的毛病会**让后续每次都漂**;表述层的毛病**只是效果差**。 +📌 **层名对齐**:本文三层 = 文末总表的 **A/B/D**;总表另有一层 **C 流程**(多步流程与数据流维度,来自另一来源,全文只在总表)。 +🔴 **判据正本 = 本文这三层**:总表里 A/B/D 的"判据"列是锚点,指回本节的 ① ~ ⑫,改判据只改本节这一处。 -### 第一层 · 工程层(换机器能不能活) +### A 工程层(换机器能不能活) **① 配置外置** 每台机器各不同的东西(工作区根 / 配置目录 / 文档库根 / 本机软件安装位)放包内 `env/`; 入仓的只有 `env/*.example`(占位符、无本机路径)。真文件由 `install.py --apply` 生成。 **② 不写死本机** -包内代码里留:盘符字面量 / 绝对机器路径 / 工作区清单 —— 都属"写死本机"。 ✅ 写法:能从 `__file__` 推导的就推导;推不出来的读 `env/roots.env`;**推不出来又没有配置 ⇒ 如实报错 + 留痕**。 +⚠️ 判"写死本机"就看这三样(反例依据):盘符字面量 / 绝对机器路径 / 工作区清单。 **③ 本机生成的契约不入库** 判据:**它是不是由本机某个脚本生成** —— 是(`env/roots.env`、`references/manifest.md` 这类)⇒ ⛔ 不入库。 @@ -47,14 +43,14 @@ **⑤ 入仓按白名单** 仓用 `/*` 全挡 + 逐个放行。**新增独立技能后要同步放行**(漏了 ⇒ 仓里只剩一份指向仓外的引用)。 -### 第二层 · 结构层(后续会不会漂) +### B 结构层(后续会不会漂) **⑥ 单一真源** 同一件事**只留一处定义**,其余位置写指针。判据:**改它的时候,我需不需要改第二个地方** —— 需要 ⇒ 那就是两处真源,该收敛。 **⑦ 注入面与真源同源** -每轮注入的那份与包内那份**逐字一致**(防漂移判据:`selftest.py::t_reply_core_same_source`)。 +每轮注入的那份与包内那份**逐字一致**(防漂移判据:`scripts/selftest.py::t_reply_core_same_source`)。 🔴 配套:**凡"每轮注入 / 有长度上限"的面,改文字必须量长度** —— "改完自测全绿"不等于"改的内容真进了上下文"(已经栽过一次:加条文把尾部三条规则顶掉了)。 @@ -64,7 +60,7 @@ **⑨ 正文不自相矛盾** 同一件事在技能里出现两种写法(尤其"正文"与"规则段"之间)⇒ 逐条对,留一处。 -### 第三层 · 表述层(读起来对不对) +### D 表述层(读起来对不对) **⑩ 肯定表述** 写「要什么、怎么做」。⛔ 不写「不要 A/B/C」—— 负向词进匹配面/注入面,**反而把 X 拉高命中**。 @@ -81,54 +77,37 @@ --- -## 怎么验(三层验法不同,⛔ 别拿一种验法套三层) - -- **工程层** ⇒ **拷到别处跑一遍**(把技能包复制到一个没有 `env/` 的位置,看它是如实报错还是静默扫空)。 - 这是最硬的一条:**能换机器跑通才算真的优化过。** -- **结构层** ⇒ 同源比对 / md5 / 判据(有机器可查的部分)。 -- **表述层** ⇒ 人读。⛔ 这部分**验不出自动结论**,别假装它通过了。 - ---- - -## 一句话调用 - -用户说「**优化技能**」「**技能怎么改更好**」「**梳理技能**」「**这条规则写在哪**」⇒ 按本文件的三层顺序过一遍。 -用户点名某一层(如"只看工程层")⇒ 只跑那一层。 -📌 姊妹篇:**盘点技能库**(有哪些技能、在用没用、该不该入仓)⇒ `references/05-技能库盘点规程.md`。 - ---- - ## 技能优化描述 · 总表(21 条,四层) -> **怎么来的**:本表把两个来源合并去重 —— -> ① 本规程的三层 12 项;② 另一工作区的 `技能审计检查清单.md` -> (路径 `E:\ProgramData\AIProject\mcn-short-video\技能审计检查清单.md`,2026-08-10 创作流程全量审计归纳的 13 项, -> 覆盖**流程与数据流**维度)。 -> **用法**:审计一个技能时按 **A → B → C → D** 顺序逐条过,⛔ 别从 D 开始。 -> **发现的问题分级**:**P0 = 会让人出事或断链**(A 层 + C 层第 18 条)/**P1 = 不一致或冗余**(B 层 + C 层其余)/**P2 = 效果差**(D 层)。 +> **怎么来的**:合并两个来源并去重 —— ① 本文三层 12 项;② 另一工作区的 `技能审计检查清单.md` +> (`E:/ProgramData/AIProject/mcn-short-video/技能审计检查清单.md`,2026-08-10 创作流程全量审计的 13 项, +> 覆盖**流程与数据流**维度;跨根引用,仅作来路说明)。 +> **用法**:按 **A → B → C → D** 顺序逐条过。**怎么验**按层不同 —— A ⇒ **拷到别处跑一遍**(最硬, +> 把包复制到一个没有 `env/` 的位置,看它如实报错还是静默扫空);B ⇒ 同源比对 / md5 / 判据; +> C ⇒ 画数据流看断点;D ⇒ 人读(这层**验不出自动结论**,别假装它通过了)。 +> **分级**:**P0 = 会让人出事或断链**(A 层 + C 层 #18)/**P1 = 不一致或冗余**(B 层 + C 层其余)/**P2 = 效果差**(D 层)。 +> 🔴 A/B/D 三层的"判据"列是**锚点**(指回上文对应项);**C 流程层的判据正本就在本表**。 -| # | 层 | 检查点 | 判据(怎么算过) | 典型反例(实测过的) | +| # | 层 | 检查点 | 判据 | 典型反例(实测过的) | |---|---|---|---|---| -| 1 | A 工程 | 配置外置 | 每台机器各不同的值都在包内 `env/`;入仓的只有 `env/*.example` | 本机路径写进入库代码 | -| 2 | A 工程 | 不写死本机 | 包内代码无盘符字面量/绝对机器路径/工作区清单 | `or r"D:\github\..."` 兜底;工作区清单写死 | -| 3 | A 工程 | 本机生成契约不入库 | 由本机脚本生成的产物(`env/roots.env`、`manifest.md`)不进仓 | 入仓后换机器"同名覆盖"改掉对方配置 | -| 4 | A 工程 | 路径形态统一 | 本包/同根技能 ⇒ `<技能根>/<名>/` 或包内相对;跨根 ⇒ 读环境变量 | 同一件事三处三说地写文档库路径 | -| 5 | A 工程 | 入仓按白名单 | 仓用 `/*` 全挡 + 逐个放行;新增独立技能后已同步放行 | 新技能独立了但白名单没加 ⇒ 仓里只剩指向仓外的引用 | -| 6 | B 结构 | 单一真源 | 同一件事只有一处定义,其余写指针 | 同一条判据散在 6 处,改一处漏一处 | -| 7 | B 结构 | 注入面与真源同源 | 逐字一致 + **有长度上限的面改文字必须量长度** | 加条文顶破上限 ⇒ 尾部规则静默消失,下游只看到"已截断" | -| 8 | B 结构 | 命名一致 | 同一概念全包一个叫法;改名先列伴随物清单 | 「任务会话 31 处 / 执行会话 29 处」混用 | -| 9 | B 结构 | 正文不自相矛盾 | 同一件事不出现两种写法(尤其正文 vs 规则段) | 技能正文缺起实例命令、与另一处说法冲突 | +| 1 | A 工程 | 配置外置 | 见 A① | 本机路径写进入库代码 | +| 2 | A 工程 | 不写死本机 | 见 A② | `or r"D:\..."` 兜底;工作区清单写死 | +| 3 | A 工程 | 本机生成契约不入库 | 见 A③ | 入仓后换机器"同名覆盖"改掉对方配置 | +| 4 | A 工程 | 路径形态统一 | 见 A④ | 同一件事三处三说地写文档库路径 | +| 5 | A 工程 | 入仓按白名单 | 见 A⑤ | 新技能独立了但白名单没加 ⇒ 仓里只剩指向仓外的引用 | +| 6 | B 结构 | 单一真源 | 见 B⑥ | 同一条判据散在 6 处,改一处漏一处 | +| 7 | B 结构 | 注入面与真源同源 | 见 B⑦ | 加条文顶破上限 ⇒ 尾部规则静默消失,下游只看到"已截断" | +| 8 | B 结构 | 命名一致 | 见 B⑧ | 「任务会话 31 处 / 执行会话 29 处」混用 | +| 9 | B 结构 | 正文不自相矛盾 | 见 B⑨ | 技能正文缺起实例命令、与另一处说法冲突 | | 10 | C 流程 | 步骤顺序正确 | 全流程步骤顺序无错乱 | 步骤排反 | | 11 | C 流程 | 编号连续 | 步骤内部编号不跳号 | 第一步→第三步缺第二步 | -| 12 | C 流程 | 无跳步 | 不跳过中间步骤 | 产物链 5→6→7 禁止跳 | +| 12 | C 流程 | 无跳步 | 不跳过中间步骤 | 产物链 5→6→7 跳了一步 | | 13 | C 流程 | 步骤间职责不越界 | 各步骤各管一段,不越界产出 | 后一棒把前一棒的场次表+情绪卡全塞进去 | | 14 | C 流程 | 字段归属正确 | 字段由哪个步骤产出就标哪个 | 情绪设计卡标成后一棒,实际是前一棒 | | 15 | C 流程 | 上游→下游不断裂 | 上游输出的字段,下游输入列表要引用 | 「目标体感」字段后两棒都没引用 | | 16 | C 流程 | 引用路径正确 | 引用走对层级(流程→知识库→素材库) | 素材库误走直接路径,应走知识库间接引用 | | 17 | C 流程 | 字段不缺失 | 每步的输入列表字段完整 | 某步输入缺「框架方案」 | -| 18 | C 流程 | 产物链完整 | 中间产物必须落盘,**P0**:禁止只出最终产物 | 只在对话里输出、没落盘 | -| 19 | D 表述 | 肯定表述 | 写「要什么、怎么做」;例外=经验沉淀/红线避坑类(正向目标 + 括号里的踩坑依据) | 描述里写「不用于海报」⇒ 匹配面反而把"海报"拉高 | -| 20 | D 表述 | 说人话 | 落盘文字过"像不像人写的"这一关 | 四种 AI 味:三段式排比连用/"…着"结尾的肤浅分析/模糊归因/拆成加粗小标题+竖排碎句 | -| 21 | D 表述 | 一页纸 | 单份产出 ≤120 行,超长就拆 | 一份 300 行的"速查" | - -**验法按层不同**:A 层 ⇒ **拷到别处跑一遍**(最硬);B 层 ⇒ 同源比对/md5/判据;C 层 ⇒ 画数据流看断点;D 层 ⇒ 人读。 +| 18 | C 流程 | 产物链完整 | 中间产物必须落盘(**P0**:只出最终产物=断链) | 只在对话里输出、没落盘 | +| 19 | D 表述 | 肯定表述 | 见 D⑩ | 描述里写「不用于海报」⇒ 匹配面反而把"海报"拉高 | +| 20 | D 表述 | 说人话 | 见 D⑪ | 四种 AI 味:三段式排比连用/"…着"结尾的肤浅分析/模糊归因/拆成加粗小标题+竖排碎句 | +| 21 | D 表述 | 一页纸 | 见 D⑫ | 一份 300 行的"速查" | diff --git a/session-mechanism/scripts/selftest.py b/session-mechanism/scripts/selftest.py index d8cd05d..f24afad 100644 --- a/session-mechanism/scripts/selftest.py +++ b/session-mechanism/scripts/selftest.py @@ -7795,5 +7795,91 @@ def t_reply_core_same_source(): return rows +@case("🔴 技能入口触发词:SKILL.md §0 与 05/06 文首必须同源(⛔ 差一个字=用户按原话喊不到)") +def t_skill_entry_triggers_same_source(): + """🔴 2026-10-15 立(本轮自审 `06` 时实测踩到)。 + + 判据来源:`references/06-技能优化规程.md` 的 **B⑦ 注入面与真源同源**。 + `SKILL.md` §0 的第 ⑧/⑨ 项是**匹配面**(用户按原话喊,靠这里的词命中), + `05 / 06` 文首的「什么时候用」是**真源**。 + + 实测:`SKILL.md` 写「技能太长」、`06` 写「技能太长了」—— 差一个字,两边都不报错, + 用户按「技能太长」喊时命中与否全靠运气。 + ⇒ 判据落在**两个集合相等**(⛔ 不是"包含"):少一个词或多一个词都报红。 + """ + import re as _re + + def _trigs(text): + """抓 `「**词**」` 与 `「词」` **两种形态** —— + 🔴 `01-文档索引.md` 的索引行是**不加粗**的,只认加粗会抓成空集 ⇒ 判据恒绿(2026-10-15 实测踩到)。""" + out = set(_re.findall(r"「\*\*(.+?)\*\*」", text)) + out |= set(_re.findall(r"「([^「」*]+?)」", text)) + return {s.strip() for s in out if s.strip()} + + def _entry_block(md, start_mark): + """从 `start_mark` 起,取到 `**一句话判据**` 或 `📌` 之前的正文。""" + i = md.find(start_mark) + if i < 0: + return "" + j = len(md) + for stop in ("**一句话判据**", "📌"): + k = md.find(stop, i) + if 0 <= k < j: + j = k + return md[i:j] + + try: + skill = (HERE.parent / "SKILL.md").read_text(encoding="utf-8", errors="replace") + p05 = (HERE.parent / "references" / "05-技能库盘点规程.md").read_text( + encoding="utf-8", errors="replace") + p06 = (HERE.parent / "references" / "06-技能优化规程.md").read_text( + encoding="utf-8", errors="replace") + except Exception as exc: + return [("读到 SKILL.md/05/06:%r" % exc, False)] + + rows = [] + for tag, skill_mark, doc, doc_name in ( + ("⑧", "**⑧ 我要盘点技能库**", p05, "05-技能库盘点规程.md"), + ("⑨", "**⑨ 我要优化技能本身**", p06, "06-技能优化规程.md"), + ): + i = skill.find(skill_mark) + # 🔴 只取**触发词那一段**(`(用户说…任一句即触发)`),⛔ 不取整块 —— + # ⑧/⑨ 的条目正文里还会出现别的「**…**」(如"这份读数能说明什么"), + # 取整块会把它们当成触发词,报出一个假红(2026-10-15 实测)。 + k = skill.find("(用户说", i) + m = skill.find("任一句即触发", k) + block = skill[k:m] if i >= 0 and 0 <= k < m else "" + a, b = _trigs(block), _trigs(_entry_block(doc, "**什么时候用**")) + rows.append(("§0 第 %s 项读得到触发词(%d 个)" % (tag, len(a)), len(a) >= 4)) + rows.append(("%s 文首读得到触发词(%d 个)" % (doc_name, len(b)), len(b) >= 4)) + only_a, only_b = sorted(a - b), sorted(b - a) + rows.append(("§0 第 %s 项 与 %s **触发词集合相等**%s" + % (tag, doc_name, + "" if not (only_a or only_b) else + "(⛔ 只在 §0:%s;⛔ 只在 %s:%s)" % (only_a, doc_name, only_b)), + not only_a and not only_b)) + + # 同一批词还有**第三处**:`references/01-文档索引.md` 的索引行。 + # 🔴 它是"代表词"视图 ⇒ 判据是**包含**(索引里列的每个词都得在真源里),⛔ 不是相等。 + # (⛔ 索引里冒出一个真源没有的词 ⇒ 用户照着索引喊也喊不到。) + try: + idx = (HERE.parent / "references" / "01-文档索引.md").read_text( + encoding="utf-8", errors="replace") + except Exception as exc: + return rows + [("读到 references/01-文档索引.md:%r" % exc, False)] + + for doc_name, doc in (("05-技能库盘点规程.md", p05), ("06-技能优化规程.md", p06)): + line = next((ln for ln in idx.splitlines() if doc_name in ln), "") + rows.append(("索引里有 %s 那一行" % doc_name, bool(line.strip()))) + if not line.strip(): + continue + a, b = _trigs(line), _trigs(_entry_block(doc, "**什么时候用**")) + extra = sorted(a - b) + rows.append(("索引里列的触发词都在 %s 真源里%s" + % (doc_name, "" if not extra else "(⛔ 真源没有:%s)" % extra), + not extra)) + return rows + + if __name__ == "__main__": sys.exit(main()) \ No newline at end of file