Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -398,6 +398,52 @@ ls <dir>/* | wc -l # 两个数不等 ⇒ 工
于钩子。有意例外:`OS_ALLOW_TREE_ENUM=1`。改这个钩子?重跑
`.claude/hooks/guard-tree-enum.selftest.sh`。

#### ⭐ 对照挂在**通道**上,不只挂在查询上 —— 而且**每次查询**都要跑一遍

上面两条写的都是**查询**级的对照(总体 vs 逐项、对照必须有能力失败)。还差一层:**通道本身也会静默
失灵,而且是间歇性的 —— 间歇比全坏更危险,因为第一次拿到命中的席位会学会信任它。**

实测(objectui#7185,同一容器、同一小时、两条 lane):MCP `search_issues` 对一个 `issue_read` 能直接
读出来的 issue 返回 `total_count: 0`;而另一条 lane 用一个**短关键词**查询在同一个工具上拿到 **3 条
命中**。⇒ ⛔ **不是通道不可用** —— 死通道不会返回 3 条。失灵的是那一次查询(失败的那条是**长的、近
乎逐字的标题**,可用的那条是短关键词)。所以规则不是「别用 search」,而是:

- **非空结果自我验证,不需要对照;空结果永远需要一个「已知必中」的对照** —— 例如某个你能用 `issue_read` 直接读到的 issue 的近逐字标题。⛔ **没跑对照的空结果不是一次读数**:它不携带任何信息,而它渲染出来恰好就是去重步骤想要的那个答案(「没有重复」),与真负例**不可区分**,不做对照就**不可证伪**。失败形态不是「报错然后重试」,是「立了一张重复卡、没人纠正、下一个席位再立一次」。
- **每次查询都跑,不是每个会话跑一次。**「这个通道十分钟前还好好的」不是关于你眼前这次查询的证据。
- **兜底通道**:零配额的 GitHub 网页 payload 通道实测可用(同一次去重里返回 8 个 issue 号,含 `search_issues` 看不见的那个),**它要跑同一条对照** —— 它只是「某一天、某一个容器里被测过可用」,不是永久答案。
- ⚠️ **未解,别当已答问题用**:`search_issues` 为何对一个直读得到的 issue 返回 0 —— 索引延迟,还是读路径与搜索路径的 scope / 查询形状差异?两者的补救完全不同(前者自愈,后者会永久地、静默地收窄每一次去重),本仓尚未诊断。

### ⚠️ GitHub 会改写你写进 issue/PR 正文的字节 —— 每次发布后回读

**六种已实测的改写,共享同一个失败模式:正文在写入之后被静默改变,而且不回读就看不见**
(objectui#6970、#6452;多个 agent 在同一个工作会话里各自独立撞到,重复发现率本身就是把它写下来的
理由)。

- **① tag 形状的片段在保存时被删掉** —— 反引号和围栏代码块**都不保护**。实测:一张 `.d.ts` 的 before/after 对照表,两列的泛型参数被吃掉后**双双塌成同一个字符串**,于是一张专为展示类型变化而写的表,渲染出来正好读作「什么都没变」。⚠️ 单独占据第一行的 HTML 注释标记同样被吃掉 —— 首行位置不提供任何保护,靠标记扫描找报告的机制会因此完全看不见那条评论。
- **② `PATCH` 把 session-URL 形式的 attribution footer 降级为 bare 形式**,丢掉 session 引用。
- **③ `PATCH` 无条件追加第二个 footer** —— 哪怕提交的正文已经以一个 footer 结尾。逐字节回读实测:存储的正文比发出的多**恰好 58 字节**,unified diff 只有那几行追加的 footer、没有内容被吃 ⇒ 与 ①② 都不同,这一种是**加**,不是**减**。
- **④ `issue_write` 创建 issue 时,attribution footer 被整块删除**(不是降级,是消失)。⭐ 定位方式值得单独记住,因为它把「删除」和「截断」分开了:发出的是 body + footer + 尾部 sentinel,回读结果是 **sentinel 在、footer 不在** ⇒ 被删的是**中间**那一块,是针对 attribution 的定向剥离。⚠️ 没有这个 sentinel 对照项,唯一能得出的结论是「正文被截断了」,那会把人指向完全错误的方向(比如去查长度上限)。
- **⑤ `create_pull_request` 把 bare footer 归一化为 session-URL 形式** —— 与 ② 恰好**反向**。⇒ ⭐ 两条合起来才是完整后果:**一个 PR 正文只要被创建之后再编辑一次,就会丢掉 session 引用**,单看任一条都看不出来。⚠️ 而且那个 session id 是**席位**的,不是具体那次实现的 —— 任何想靠它回溯「是哪个 agent 做的这次改动」的机制,只会拿到席位粒度的答案,比看上去弱一档。
- **⑥ ⛔ 关单关键词解析器无视否定 —— 这一种最危险。** 解析器扫的是 `close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved` 紧跟一个 issue 引用,**它不解析句子**:一句「本 PR 并不关闭某卡」若按英文否定式写成 does-NOT-close 加卡号,合并时照样把那张卡关掉。⚠️ 前五种在检视时**看得见**,这一种看不见:损害是**延迟**的(合并那一刻才发生,可能是几天后的另一个会话),而且**反转作者的明确意图** —— 那句话之所以存在,正因为作者在小心行事;卡被静默关掉后不再出现在任何队列普查里,于是它在跟踪的后续不是「可见地被阻塞」,而是直接丢失。安全写法:`Part of #<n>`、`Refs: #<n>`、`Related: #<n>`、裸 `objectui#<n>`(不带关键词)。

**实测有效的缓解,四条 —— 合起来才够,单独任何一条都不够:**

- **泛型和占位符写成大写单词**(例如 "OPT of `z.ZodNever`"),⛔ 永不字面写成尖括号形状,并在正文里说明为什么这么写。
- **session URL 写进正文散文、并作为反引号代码跨度** —— 实测原样穿过 `PATCH`;⛔ 别指望 markdown 链接形式的 footer 活下来。
- **issue 正文里的 attribution 写成散文**,⛔ 别依赖 footer 块(见 ④)。
- **每次发布之后回读到正文末尾,并数一次尖括号命中**;开 PR 之前额外扫一遍自己的正文 —— `grep -nEi '(clos|fix|resolv)' <file>`,确认每一个靠近 `#` 的命中都是你**有意**要关的那张卡。

**占位符不是特例:普通散文和围栏代码块里的占位符同样被吃掉** —— 实测一行命令配方里的两个占位符双
双塌成一个裸 `-`,而那一行存在的意义正是给出那两个占位符。权威措辞在 `../objectstack` 的 `AGENTS.md`
(「GitHub mutates body BYTES — spell poison-shaped tokens out in words, never literally」那一条),
⛔ 本仓不复制它的正文,免得两处漂移;这里只留指针,并**逐字**保留其中最要紧、也最容易被漏掉的那半
句:

> A body reading short only through the API is probably intact — check the rendered page before "repairing" it; a rewrite destroys a correct card.

⇒ ⭐ **回读发现正文「变短」时,先看渲染后的页面,再决定要不要修。** 一次不必要的重写会毁掉一张本
来正确的卡 —— 而在受管面上,那是不可恢复的。

### ⛔ 受管面(governed surface):agent 起草,人类合并

维护者裁决(2026-08-18),**原文照录、不翻译** —— 提问明确点名了本仓:
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -398,6 +398,52 @@ ls <dir>/* | wc -l # 两个数不等 ⇒ 工
于钩子。有意例外:`OS_ALLOW_TREE_ENUM=1`。改这个钩子?重跑
`.claude/hooks/guard-tree-enum.selftest.sh`。

#### ⭐ 对照挂在**通道**上,不只挂在查询上 —— 而且**每次查询**都要跑一遍

上面两条写的都是**查询**级的对照(总体 vs 逐项、对照必须有能力失败)。还差一层:**通道本身也会静默
失灵,而且是间歇性的 —— 间歇比全坏更危险,因为第一次拿到命中的席位会学会信任它。**

实测(objectui#7185,同一容器、同一小时、两条 lane):MCP `search_issues` 对一个 `issue_read` 能直接
读出来的 issue 返回 `total_count: 0`;而另一条 lane 用一个**短关键词**查询在同一个工具上拿到 **3 条
命中**。⇒ ⛔ **不是通道不可用** —— 死通道不会返回 3 条。失灵的是那一次查询(失败的那条是**长的、近
乎逐字的标题**,可用的那条是短关键词)。所以规则不是「别用 search」,而是:

- **非空结果自我验证,不需要对照;空结果永远需要一个「已知必中」的对照** —— 例如某个你能用 `issue_read` 直接读到的 issue 的近逐字标题。⛔ **没跑对照的空结果不是一次读数**:它不携带任何信息,而它渲染出来恰好就是去重步骤想要的那个答案(「没有重复」),与真负例**不可区分**,不做对照就**不可证伪**。失败形态不是「报错然后重试」,是「立了一张重复卡、没人纠正、下一个席位再立一次」。
- **每次查询都跑,不是每个会话跑一次。**「这个通道十分钟前还好好的」不是关于你眼前这次查询的证据。
- **兜底通道**:零配额的 GitHub 网页 payload 通道实测可用(同一次去重里返回 8 个 issue 号,含 `search_issues` 看不见的那个),**它要跑同一条对照** —— 它只是「某一天、某一个容器里被测过可用」,不是永久答案。
- ⚠️ **未解,别当已答问题用**:`search_issues` 为何对一个直读得到的 issue 返回 0 —— 索引延迟,还是读路径与搜索路径的 scope / 查询形状差异?两者的补救完全不同(前者自愈,后者会永久地、静默地收窄每一次去重),本仓尚未诊断。

### ⚠️ GitHub 会改写你写进 issue/PR 正文的字节 —— 每次发布后回读

**六种已实测的改写,共享同一个失败模式:正文在写入之后被静默改变,而且不回读就看不见**
(objectui#6970、#6452;多个 agent 在同一个工作会话里各自独立撞到,重复发现率本身就是把它写下来的
理由)。

- **① tag 形状的片段在保存时被删掉** —— 反引号和围栏代码块**都不保护**。实测:一张 `.d.ts` 的 before/after 对照表,两列的泛型参数被吃掉后**双双塌成同一个字符串**,于是一张专为展示类型变化而写的表,渲染出来正好读作「什么都没变」。⚠️ 单独占据第一行的 HTML 注释标记同样被吃掉 —— 首行位置不提供任何保护,靠标记扫描找报告的机制会因此完全看不见那条评论。
- **② `PATCH` 把 session-URL 形式的 attribution footer 降级为 bare 形式**,丢掉 session 引用。
- **③ `PATCH` 无条件追加第二个 footer** —— 哪怕提交的正文已经以一个 footer 结尾。逐字节回读实测:存储的正文比发出的多**恰好 58 字节**,unified diff 只有那几行追加的 footer、没有内容被吃 ⇒ 与 ①② 都不同,这一种是**加**,不是**减**。
- **④ `issue_write` 创建 issue 时,attribution footer 被整块删除**(不是降级,是消失)。⭐ 定位方式值得单独记住,因为它把「删除」和「截断」分开了:发出的是 body + footer + 尾部 sentinel,回读结果是 **sentinel 在、footer 不在** ⇒ 被删的是**中间**那一块,是针对 attribution 的定向剥离。⚠️ 没有这个 sentinel 对照项,唯一能得出的结论是「正文被截断了」,那会把人指向完全错误的方向(比如去查长度上限)。
- **⑤ `create_pull_request` 把 bare footer 归一化为 session-URL 形式** —— 与 ② 恰好**反向**。⇒ ⭐ 两条合起来才是完整后果:**一个 PR 正文只要被创建之后再编辑一次,就会丢掉 session 引用**,单看任一条都看不出来。⚠️ 而且那个 session id 是**席位**的,不是具体那次实现的 —— 任何想靠它回溯「是哪个 agent 做的这次改动」的机制,只会拿到席位粒度的答案,比看上去弱一档。
- **⑥ ⛔ 关单关键词解析器无视否定 —— 这一种最危险。** 解析器扫的是 `close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved` 紧跟一个 issue 引用,**它不解析句子**:一句「本 PR 并不关闭某卡」若按英文否定式写成 does-NOT-close 加卡号,合并时照样把那张卡关掉。⚠️ 前五种在检视时**看得见**,这一种看不见:损害是**延迟**的(合并那一刻才发生,可能是几天后的另一个会话),而且**反转作者的明确意图** —— 那句话之所以存在,正因为作者在小心行事;卡被静默关掉后不再出现在任何队列普查里,于是它在跟踪的后续不是「可见地被阻塞」,而是直接丢失。安全写法:`Part of #<n>`、`Refs: #<n>`、`Related: #<n>`、裸 `objectui#<n>`(不带关键词)。

**实测有效的缓解,四条 —— 合起来才够,单独任何一条都不够:**

- **泛型和占位符写成大写单词**(例如 "OPT of `z.ZodNever`"),⛔ 永不字面写成尖括号形状,并在正文里说明为什么这么写。
- **session URL 写进正文散文、并作为反引号代码跨度** —— 实测原样穿过 `PATCH`;⛔ 别指望 markdown 链接形式的 footer 活下来。
- **issue 正文里的 attribution 写成散文**,⛔ 别依赖 footer 块(见 ④)。
- **每次发布之后回读到正文末尾,并数一次尖括号命中**;开 PR 之前额外扫一遍自己的正文 —— `grep -nEi '(clos|fix|resolv)' <file>`,确认每一个靠近 `#` 的命中都是你**有意**要关的那张卡。

**占位符不是特例:普通散文和围栏代码块里的占位符同样被吃掉** —— 实测一行命令配方里的两个占位符双
双塌成一个裸 `-`,而那一行存在的意义正是给出那两个占位符。权威措辞在 `../objectstack` 的 `AGENTS.md`
(「GitHub mutates body BYTES — spell poison-shaped tokens out in words, never literally」那一条),
⛔ 本仓不复制它的正文,免得两处漂移;这里只留指针,并**逐字**保留其中最要紧、也最容易被漏掉的那半
句:

> A body reading short only through the API is probably intact — check the rendered page before "repairing" it; a rewrite destroys a correct card.

⇒ ⭐ **回读发现正文「变短」时,先看渲染后的页面,再决定要不要修。** 一次不必要的重写会毁掉一张本
来正确的卡 —— 而在受管面上,那是不可恢复的。

### ⛔ 受管面(governed surface):agent 起草,人类合并

维护者裁决(2026-08-18),**原文照录、不翻译** —— 提问明确点名了本仓:
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -398,6 +398,52 @@ ls <dir>/* | wc -l # 两个数不等 ⇒ 工
于钩子。有意例外:`OS_ALLOW_TREE_ENUM=1`。改这个钩子?重跑
`.claude/hooks/guard-tree-enum.selftest.sh`。

#### ⭐ 对照挂在**通道**上,不只挂在查询上 —— 而且**每次查询**都要跑一遍

上面两条写的都是**查询**级的对照(总体 vs 逐项、对照必须有能力失败)。还差一层:**通道本身也会静默
失灵,而且是间歇性的 —— 间歇比全坏更危险,因为第一次拿到命中的席位会学会信任它。**

实测(objectui#7185,同一容器、同一小时、两条 lane):MCP `search_issues` 对一个 `issue_read` 能直接
读出来的 issue 返回 `total_count: 0`;而另一条 lane 用一个**短关键词**查询在同一个工具上拿到 **3 条
命中**。⇒ ⛔ **不是通道不可用** —— 死通道不会返回 3 条。失灵的是那一次查询(失败的那条是**长的、近
乎逐字的标题**,可用的那条是短关键词)。所以规则不是「别用 search」,而是:

- **非空结果自我验证,不需要对照;空结果永远需要一个「已知必中」的对照** —— 例如某个你能用 `issue_read` 直接读到的 issue 的近逐字标题。⛔ **没跑对照的空结果不是一次读数**:它不携带任何信息,而它渲染出来恰好就是去重步骤想要的那个答案(「没有重复」),与真负例**不可区分**,不做对照就**不可证伪**。失败形态不是「报错然后重试」,是「立了一张重复卡、没人纠正、下一个席位再立一次」。
- **每次查询都跑,不是每个会话跑一次。**「这个通道十分钟前还好好的」不是关于你眼前这次查询的证据。
- **兜底通道**:零配额的 GitHub 网页 payload 通道实测可用(同一次去重里返回 8 个 issue 号,含 `search_issues` 看不见的那个),**它要跑同一条对照** —— 它只是「某一天、某一个容器里被测过可用」,不是永久答案。
- ⚠️ **未解,别当已答问题用**:`search_issues` 为何对一个直读得到的 issue 返回 0 —— 索引延迟,还是读路径与搜索路径的 scope / 查询形状差异?两者的补救完全不同(前者自愈,后者会永久地、静默地收窄每一次去重),本仓尚未诊断。

### ⚠️ GitHub 会改写你写进 issue/PR 正文的字节 —— 每次发布后回读

**六种已实测的改写,共享同一个失败模式:正文在写入之后被静默改变,而且不回读就看不见**
(objectui#6970、#6452;多个 agent 在同一个工作会话里各自独立撞到,重复发现率本身就是把它写下来的
理由)。

- **① tag 形状的片段在保存时被删掉** —— 反引号和围栏代码块**都不保护**。实测:一张 `.d.ts` 的 before/after 对照表,两列的泛型参数被吃掉后**双双塌成同一个字符串**,于是一张专为展示类型变化而写的表,渲染出来正好读作「什么都没变」。⚠️ 单独占据第一行的 HTML 注释标记同样被吃掉 —— 首行位置不提供任何保护,靠标记扫描找报告的机制会因此完全看不见那条评论。
- **② `PATCH` 把 session-URL 形式的 attribution footer 降级为 bare 形式**,丢掉 session 引用。
- **③ `PATCH` 无条件追加第二个 footer** —— 哪怕提交的正文已经以一个 footer 结尾。逐字节回读实测:存储的正文比发出的多**恰好 58 字节**,unified diff 只有那几行追加的 footer、没有内容被吃 ⇒ 与 ①② 都不同,这一种是**加**,不是**减**。
- **④ `issue_write` 创建 issue 时,attribution footer 被整块删除**(不是降级,是消失)。⭐ 定位方式值得单独记住,因为它把「删除」和「截断」分开了:发出的是 body + footer + 尾部 sentinel,回读结果是 **sentinel 在、footer 不在** ⇒ 被删的是**中间**那一块,是针对 attribution 的定向剥离。⚠️ 没有这个 sentinel 对照项,唯一能得出的结论是「正文被截断了」,那会把人指向完全错误的方向(比如去查长度上限)。
- **⑤ `create_pull_request` 把 bare footer 归一化为 session-URL 形式** —— 与 ② 恰好**反向**。⇒ ⭐ 两条合起来才是完整后果:**一个 PR 正文只要被创建之后再编辑一次,就会丢掉 session 引用**,单看任一条都看不出来。⚠️ 而且那个 session id 是**席位**的,不是具体那次实现的 —— 任何想靠它回溯「是哪个 agent 做的这次改动」的机制,只会拿到席位粒度的答案,比看上去弱一档。
- **⑥ ⛔ 关单关键词解析器无视否定 —— 这一种最危险。** 解析器扫的是 `close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved` 紧跟一个 issue 引用,**它不解析句子**:一句「本 PR 并不关闭某卡」若按英文否定式写成 does-NOT-close 加卡号,合并时照样把那张卡关掉。⚠️ 前五种在检视时**看得见**,这一种看不见:损害是**延迟**的(合并那一刻才发生,可能是几天后的另一个会话),而且**反转作者的明确意图** —— 那句话之所以存在,正因为作者在小心行事;卡被静默关掉后不再出现在任何队列普查里,于是它在跟踪的后续不是「可见地被阻塞」,而是直接丢失。安全写法:`Part of #<n>`、`Refs: #<n>`、`Related: #<n>`、裸 `objectui#<n>`(不带关键词)。

**实测有效的缓解,四条 —— 合起来才够,单独任何一条都不够:**

- **泛型和占位符写成大写单词**(例如 "OPT of `z.ZodNever`"),⛔ 永不字面写成尖括号形状,并在正文里说明为什么这么写。
- **session URL 写进正文散文、并作为反引号代码跨度** —— 实测原样穿过 `PATCH`;⛔ 别指望 markdown 链接形式的 footer 活下来。
- **issue 正文里的 attribution 写成散文**,⛔ 别依赖 footer 块(见 ④)。
- **每次发布之后回读到正文末尾,并数一次尖括号命中**;开 PR 之前额外扫一遍自己的正文 —— `grep -nEi '(clos|fix|resolv)' <file>`,确认每一个靠近 `#` 的命中都是你**有意**要关的那张卡。

**占位符不是特例:普通散文和围栏代码块里的占位符同样被吃掉** —— 实测一行命令配方里的两个占位符双
双塌成一个裸 `-`,而那一行存在的意义正是给出那两个占位符。权威措辞在 `../objectstack` 的 `AGENTS.md`
(「GitHub mutates body BYTES — spell poison-shaped tokens out in words, never literally」那一条),
⛔ 本仓不复制它的正文,免得两处漂移;这里只留指针,并**逐字**保留其中最要紧、也最容易被漏掉的那半
句:

> A body reading short only through the API is probably intact — check the rendered page before "repairing" it; a rewrite destroys a correct card.

⇒ ⭐ **回读发现正文「变短」时,先看渲染后的页面,再决定要不要修。** 一次不必要的重写会毁掉一张本
来正确的卡 —— 而在受管面上,那是不可恢复的。

### ⛔ 受管面(governed surface):agent 起草,人类合并

维护者裁决(2026-08-18),**原文照录、不翻译** —— 提问明确点名了本仓:
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -398,6 +398,52 @@ ls <dir>/* | wc -l # 两个数不等 ⇒ 工
于钩子。有意例外:`OS_ALLOW_TREE_ENUM=1`。改这个钩子?重跑
`.claude/hooks/guard-tree-enum.selftest.sh`。

#### ⭐ 对照挂在**通道**上,不只挂在查询上 —— 而且**每次查询**都要跑一遍

上面两条写的都是**查询**级的对照(总体 vs 逐项、对照必须有能力失败)。还差一层:**通道本身也会静默
失灵,而且是间歇性的 —— 间歇比全坏更危险,因为第一次拿到命中的席位会学会信任它。**

实测(objectui#7185,同一容器、同一小时、两条 lane):MCP `search_issues` 对一个 `issue_read` 能直接
读出来的 issue 返回 `total_count: 0`;而另一条 lane 用一个**短关键词**查询在同一个工具上拿到 **3 条
命中**。⇒ ⛔ **不是通道不可用** —— 死通道不会返回 3 条。失灵的是那一次查询(失败的那条是**长的、近
乎逐字的标题**,可用的那条是短关键词)。所以规则不是「别用 search」,而是:

- **非空结果自我验证,不需要对照;空结果永远需要一个「已知必中」的对照** —— 例如某个你能用 `issue_read` 直接读到的 issue 的近逐字标题。⛔ **没跑对照的空结果不是一次读数**:它不携带任何信息,而它渲染出来恰好就是去重步骤想要的那个答案(「没有重复」),与真负例**不可区分**,不做对照就**不可证伪**。失败形态不是「报错然后重试」,是「立了一张重复卡、没人纠正、下一个席位再立一次」。
- **每次查询都跑,不是每个会话跑一次。**「这个通道十分钟前还好好的」不是关于你眼前这次查询的证据。
- **兜底通道**:零配额的 GitHub 网页 payload 通道实测可用(同一次去重里返回 8 个 issue 号,含 `search_issues` 看不见的那个),**它要跑同一条对照** —— 它只是「某一天、某一个容器里被测过可用」,不是永久答案。
- ⚠️ **未解,别当已答问题用**:`search_issues` 为何对一个直读得到的 issue 返回 0 —— 索引延迟,还是读路径与搜索路径的 scope / 查询形状差异?两者的补救完全不同(前者自愈,后者会永久地、静默地收窄每一次去重),本仓尚未诊断。

### ⚠️ GitHub 会改写你写进 issue/PR 正文的字节 —— 每次发布后回读

**六种已实测的改写,共享同一个失败模式:正文在写入之后被静默改变,而且不回读就看不见**
(objectui#6970、#6452;多个 agent 在同一个工作会话里各自独立撞到,重复发现率本身就是把它写下来的
理由)。

- **① tag 形状的片段在保存时被删掉** —— 反引号和围栏代码块**都不保护**。实测:一张 `.d.ts` 的 before/after 对照表,两列的泛型参数被吃掉后**双双塌成同一个字符串**,于是一张专为展示类型变化而写的表,渲染出来正好读作「什么都没变」。⚠️ 单独占据第一行的 HTML 注释标记同样被吃掉 —— 首行位置不提供任何保护,靠标记扫描找报告的机制会因此完全看不见那条评论。
- **② `PATCH` 把 session-URL 形式的 attribution footer 降级为 bare 形式**,丢掉 session 引用。
- **③ `PATCH` 无条件追加第二个 footer** —— 哪怕提交的正文已经以一个 footer 结尾。逐字节回读实测:存储的正文比发出的多**恰好 58 字节**,unified diff 只有那几行追加的 footer、没有内容被吃 ⇒ 与 ①② 都不同,这一种是**加**,不是**减**。
- **④ `issue_write` 创建 issue 时,attribution footer 被整块删除**(不是降级,是消失)。⭐ 定位方式值得单独记住,因为它把「删除」和「截断」分开了:发出的是 body + footer + 尾部 sentinel,回读结果是 **sentinel 在、footer 不在** ⇒ 被删的是**中间**那一块,是针对 attribution 的定向剥离。⚠️ 没有这个 sentinel 对照项,唯一能得出的结论是「正文被截断了」,那会把人指向完全错误的方向(比如去查长度上限)。
- **⑤ `create_pull_request` 把 bare footer 归一化为 session-URL 形式** —— 与 ② 恰好**反向**。⇒ ⭐ 两条合起来才是完整后果:**一个 PR 正文只要被创建之后再编辑一次,就会丢掉 session 引用**,单看任一条都看不出来。⚠️ 而且那个 session id 是**席位**的,不是具体那次实现的 —— 任何想靠它回溯「是哪个 agent 做的这次改动」的机制,只会拿到席位粒度的答案,比看上去弱一档。
- **⑥ ⛔ 关单关键词解析器无视否定 —— 这一种最危险。** 解析器扫的是 `close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved` 紧跟一个 issue 引用,**它不解析句子**:一句「本 PR 并不关闭某卡」若按英文否定式写成 does-NOT-close 加卡号,合并时照样把那张卡关掉。⚠️ 前五种在检视时**看得见**,这一种看不见:损害是**延迟**的(合并那一刻才发生,可能是几天后的另一个会话),而且**反转作者的明确意图** —— 那句话之所以存在,正因为作者在小心行事;卡被静默关掉后不再出现在任何队列普查里,于是它在跟踪的后续不是「可见地被阻塞」,而是直接丢失。安全写法:`Part of #<n>`、`Refs: #<n>`、`Related: #<n>`、裸 `objectui#<n>`(不带关键词)。

**实测有效的缓解,四条 —— 合起来才够,单独任何一条都不够:**

- **泛型和占位符写成大写单词**(例如 "OPT of `z.ZodNever`"),⛔ 永不字面写成尖括号形状,并在正文里说明为什么这么写。
- **session URL 写进正文散文、并作为反引号代码跨度** —— 实测原样穿过 `PATCH`;⛔ 别指望 markdown 链接形式的 footer 活下来。
- **issue 正文里的 attribution 写成散文**,⛔ 别依赖 footer 块(见 ④)。
- **每次发布之后回读到正文末尾,并数一次尖括号命中**;开 PR 之前额外扫一遍自己的正文 —— `grep -nEi '(clos|fix|resolv)' <file>`,确认每一个靠近 `#` 的命中都是你**有意**要关的那张卡。

**占位符不是特例:普通散文和围栏代码块里的占位符同样被吃掉** —— 实测一行命令配方里的两个占位符双
双塌成一个裸 `-`,而那一行存在的意义正是给出那两个占位符。权威措辞在 `../objectstack` 的 `AGENTS.md`
(「GitHub mutates body BYTES — spell poison-shaped tokens out in words, never literally」那一条),
⛔ 本仓不复制它的正文,免得两处漂移;这里只留指针,并**逐字**保留其中最要紧、也最容易被漏掉的那半
句:

> A body reading short only through the API is probably intact — check the rendered page before "repairing" it; a rewrite destroys a correct card.

⇒ ⭐ **回读发现正文「变短」时,先看渲染后的页面,再决定要不要修。** 一次不必要的重写会毁掉一张本
来正确的卡 —— 而在受管面上,那是不可恢复的。

### ⛔ 受管面(governed surface):agent 起草,人类合并

维护者裁决(2026-08-18),**原文照录、不翻译** —— 提问明确点名了本仓:
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -398,6 +398,52 @@ ls <dir>/* | wc -l # 两个数不等 ⇒ 工
于钩子。有意例外:`OS_ALLOW_TREE_ENUM=1`。改这个钩子?重跑
`.claude/hooks/guard-tree-enum.selftest.sh`。

#### ⭐ 对照挂在**通道**上,不只挂在查询上 —— 而且**每次查询**都要跑一遍

上面两条写的都是**查询**级的对照(总体 vs 逐项、对照必须有能力失败)。还差一层:**通道本身也会静默
失灵,而且是间歇性的 —— 间歇比全坏更危险,因为第一次拿到命中的席位会学会信任它。**

实测(objectui#7185,同一容器、同一小时、两条 lane):MCP `search_issues` 对一个 `issue_read` 能直接
读出来的 issue 返回 `total_count: 0`;而另一条 lane 用一个**短关键词**查询在同一个工具上拿到 **3 条
命中**。⇒ ⛔ **不是通道不可用** —— 死通道不会返回 3 条。失灵的是那一次查询(失败的那条是**长的、近
乎逐字的标题**,可用的那条是短关键词)。所以规则不是「别用 search」,而是:

- **非空结果自我验证,不需要对照;空结果永远需要一个「已知必中」的对照** —— 例如某个你能用 `issue_read` 直接读到的 issue 的近逐字标题。⛔ **没跑对照的空结果不是一次读数**:它不携带任何信息,而它渲染出来恰好就是去重步骤想要的那个答案(「没有重复」),与真负例**不可区分**,不做对照就**不可证伪**。失败形态不是「报错然后重试」,是「立了一张重复卡、没人纠正、下一个席位再立一次」。
- **每次查询都跑,不是每个会话跑一次。**「这个通道十分钟前还好好的」不是关于你眼前这次查询的证据。
- **兜底通道**:零配额的 GitHub 网页 payload 通道实测可用(同一次去重里返回 8 个 issue 号,含 `search_issues` 看不见的那个),**它要跑同一条对照** —— 它只是「某一天、某一个容器里被测过可用」,不是永久答案。
- ⚠️ **未解,别当已答问题用**:`search_issues` 为何对一个直读得到的 issue 返回 0 —— 索引延迟,还是读路径与搜索路径的 scope / 查询形状差异?两者的补救完全不同(前者自愈,后者会永久地、静默地收窄每一次去重),本仓尚未诊断。

### ⚠️ GitHub 会改写你写进 issue/PR 正文的字节 —— 每次发布后回读

**六种已实测的改写,共享同一个失败模式:正文在写入之后被静默改变,而且不回读就看不见**
(objectui#6970、#6452;多个 agent 在同一个工作会话里各自独立撞到,重复发现率本身就是把它写下来的
理由)。

- **① tag 形状的片段在保存时被删掉** —— 反引号和围栏代码块**都不保护**。实测:一张 `.d.ts` 的 before/after 对照表,两列的泛型参数被吃掉后**双双塌成同一个字符串**,于是一张专为展示类型变化而写的表,渲染出来正好读作「什么都没变」。⚠️ 单独占据第一行的 HTML 注释标记同样被吃掉 —— 首行位置不提供任何保护,靠标记扫描找报告的机制会因此完全看不见那条评论。
- **② `PATCH` 把 session-URL 形式的 attribution footer 降级为 bare 形式**,丢掉 session 引用。
- **③ `PATCH` 无条件追加第二个 footer** —— 哪怕提交的正文已经以一个 footer 结尾。逐字节回读实测:存储的正文比发出的多**恰好 58 字节**,unified diff 只有那几行追加的 footer、没有内容被吃 ⇒ 与 ①② 都不同,这一种是**加**,不是**减**。
- **④ `issue_write` 创建 issue 时,attribution footer 被整块删除**(不是降级,是消失)。⭐ 定位方式值得单独记住,因为它把「删除」和「截断」分开了:发出的是 body + footer + 尾部 sentinel,回读结果是 **sentinel 在、footer 不在** ⇒ 被删的是**中间**那一块,是针对 attribution 的定向剥离。⚠️ 没有这个 sentinel 对照项,唯一能得出的结论是「正文被截断了」,那会把人指向完全错误的方向(比如去查长度上限)。
- **⑤ `create_pull_request` 把 bare footer 归一化为 session-URL 形式** —— 与 ② 恰好**反向**。⇒ ⭐ 两条合起来才是完整后果:**一个 PR 正文只要被创建之后再编辑一次,就会丢掉 session 引用**,单看任一条都看不出来。⚠️ 而且那个 session id 是**席位**的,不是具体那次实现的 —— 任何想靠它回溯「是哪个 agent 做的这次改动」的机制,只会拿到席位粒度的答案,比看上去弱一档。
- **⑥ ⛔ 关单关键词解析器无视否定 —— 这一种最危险。** 解析器扫的是 `close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved` 紧跟一个 issue 引用,**它不解析句子**:一句「本 PR 并不关闭某卡」若按英文否定式写成 does-NOT-close 加卡号,合并时照样把那张卡关掉。⚠️ 前五种在检视时**看得见**,这一种看不见:损害是**延迟**的(合并那一刻才发生,可能是几天后的另一个会话),而且**反转作者的明确意图** —— 那句话之所以存在,正因为作者在小心行事;卡被静默关掉后不再出现在任何队列普查里,于是它在跟踪的后续不是「可见地被阻塞」,而是直接丢失。安全写法:`Part of #<n>`、`Refs: #<n>`、`Related: #<n>`、裸 `objectui#<n>`(不带关键词)。

**实测有效的缓解,四条 —— 合起来才够,单独任何一条都不够:**

- **泛型和占位符写成大写单词**(例如 "OPT of `z.ZodNever`"),⛔ 永不字面写成尖括号形状,并在正文里说明为什么这么写。
- **session URL 写进正文散文、并作为反引号代码跨度** —— 实测原样穿过 `PATCH`;⛔ 别指望 markdown 链接形式的 footer 活下来。
- **issue 正文里的 attribution 写成散文**,⛔ 别依赖 footer 块(见 ④)。
- **每次发布之后回读到正文末尾,并数一次尖括号命中**;开 PR 之前额外扫一遍自己的正文 —— `grep -nEi '(clos|fix|resolv)' <file>`,确认每一个靠近 `#` 的命中都是你**有意**要关的那张卡。

**占位符不是特例:普通散文和围栏代码块里的占位符同样被吃掉** —— 实测一行命令配方里的两个占位符双
双塌成一个裸 `-`,而那一行存在的意义正是给出那两个占位符。权威措辞在 `../objectstack` 的 `AGENTS.md`
(「GitHub mutates body BYTES — spell poison-shaped tokens out in words, never literally」那一条),
⛔ 本仓不复制它的正文,免得两处漂移;这里只留指针,并**逐字**保留其中最要紧、也最容易被漏掉的那半
句:

> A body reading short only through the API is probably intact — check the rendered page before "repairing" it; a rewrite destroys a correct card.

⇒ ⭐ **回读发现正文「变短」时,先看渲染后的页面,再决定要不要修。** 一次不必要的重写会毁掉一张本
来正确的卡 —— 而在受管面上,那是不可恢复的。

### ⛔ 受管面(governed surface):agent 起草,人类合并

维护者裁决(2026-08-18),**原文照录、不翻译** —— 提问明确点名了本仓:
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -398,6 +398,52 @@ ls <dir>/* | wc -l # 两个数不等 ⇒ 工
于钩子。有意例外:`OS_ALLOW_TREE_ENUM=1`。改这个钩子?重跑
`.claude/hooks/guard-tree-enum.selftest.sh`。

#### ⭐ 对照挂在**通道**上,不只挂在查询上 —— 而且**每次查询**都要跑一遍

上面两条写的都是**查询**级的对照(总体 vs 逐项、对照必须有能力失败)。还差一层:**通道本身也会静默
失灵,而且是间歇性的 —— 间歇比全坏更危险,因为第一次拿到命中的席位会学会信任它。**

实测(objectui#7185,同一容器、同一小时、两条 lane):MCP `search_issues` 对一个 `issue_read` 能直接
读出来的 issue 返回 `total_count: 0`;而另一条 lane 用一个**短关键词**查询在同一个工具上拿到 **3 条
命中**。⇒ ⛔ **不是通道不可用** —— 死通道不会返回 3 条。失灵的是那一次查询(失败的那条是**长的、近
乎逐字的标题**,可用的那条是短关键词)。所以规则不是「别用 search」,而是:

- **非空结果自我验证,不需要对照;空结果永远需要一个「已知必中」的对照** —— 例如某个你能用 `issue_read` 直接读到的 issue 的近逐字标题。⛔ **没跑对照的空结果不是一次读数**:它不携带任何信息,而它渲染出来恰好就是去重步骤想要的那个答案(「没有重复」),与真负例**不可区分**,不做对照就**不可证伪**。失败形态不是「报错然后重试」,是「立了一张重复卡、没人纠正、下一个席位再立一次」。
- **每次查询都跑,不是每个会话跑一次。**「这个通道十分钟前还好好的」不是关于你眼前这次查询的证据。
- **兜底通道**:零配额的 GitHub 网页 payload 通道实测可用(同一次去重里返回 8 个 issue 号,含 `search_issues` 看不见的那个),**它要跑同一条对照** —— 它只是「某一天、某一个容器里被测过可用」,不是永久答案。
- ⚠️ **未解,别当已答问题用**:`search_issues` 为何对一个直读得到的 issue 返回 0 —— 索引延迟,还是读路径与搜索路径的 scope / 查询形状差异?两者的补救完全不同(前者自愈,后者会永久地、静默地收窄每一次去重),本仓尚未诊断。

### ⚠️ GitHub 会改写你写进 issue/PR 正文的字节 —— 每次发布后回读

**六种已实测的改写,共享同一个失败模式:正文在写入之后被静默改变,而且不回读就看不见**
(objectui#6970、#6452;多个 agent 在同一个工作会话里各自独立撞到,重复发现率本身就是把它写下来的
理由)。

- **① tag 形状的片段在保存时被删掉** —— 反引号和围栏代码块**都不保护**。实测:一张 `.d.ts` 的 before/after 对照表,两列的泛型参数被吃掉后**双双塌成同一个字符串**,于是一张专为展示类型变化而写的表,渲染出来正好读作「什么都没变」。⚠️ 单独占据第一行的 HTML 注释标记同样被吃掉 —— 首行位置不提供任何保护,靠标记扫描找报告的机制会因此完全看不见那条评论。
- **② `PATCH` 把 session-URL 形式的 attribution footer 降级为 bare 形式**,丢掉 session 引用。
- **③ `PATCH` 无条件追加第二个 footer** —— 哪怕提交的正文已经以一个 footer 结尾。逐字节回读实测:存储的正文比发出的多**恰好 58 字节**,unified diff 只有那几行追加的 footer、没有内容被吃 ⇒ 与 ①② 都不同,这一种是**加**,不是**减**。
- **④ `issue_write` 创建 issue 时,attribution footer 被整块删除**(不是降级,是消失)。⭐ 定位方式值得单独记住,因为它把「删除」和「截断」分开了:发出的是 body + footer + 尾部 sentinel,回读结果是 **sentinel 在、footer 不在** ⇒ 被删的是**中间**那一块,是针对 attribution 的定向剥离。⚠️ 没有这个 sentinel 对照项,唯一能得出的结论是「正文被截断了」,那会把人指向完全错误的方向(比如去查长度上限)。
- **⑤ `create_pull_request` 把 bare footer 归一化为 session-URL 形式** —— 与 ② 恰好**反向**。⇒ ⭐ 两条合起来才是完整后果:**一个 PR 正文只要被创建之后再编辑一次,就会丢掉 session 引用**,单看任一条都看不出来。⚠️ 而且那个 session id 是**席位**的,不是具体那次实现的 —— 任何想靠它回溯「是哪个 agent 做的这次改动」的机制,只会拿到席位粒度的答案,比看上去弱一档。
- **⑥ ⛔ 关单关键词解析器无视否定 —— 这一种最危险。** 解析器扫的是 `close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved` 紧跟一个 issue 引用,**它不解析句子**:一句「本 PR 并不关闭某卡」若按英文否定式写成 does-NOT-close 加卡号,合并时照样把那张卡关掉。⚠️ 前五种在检视时**看得见**,这一种看不见:损害是**延迟**的(合并那一刻才发生,可能是几天后的另一个会话),而且**反转作者的明确意图** —— 那句话之所以存在,正因为作者在小心行事;卡被静默关掉后不再出现在任何队列普查里,于是它在跟踪的后续不是「可见地被阻塞」,而是直接丢失。安全写法:`Part of #<n>`、`Refs: #<n>`、`Related: #<n>`、裸 `objectui#<n>`(不带关键词)。

**实测有效的缓解,四条 —— 合起来才够,单独任何一条都不够:**

- **泛型和占位符写成大写单词**(例如 "OPT of `z.ZodNever`"),⛔ 永不字面写成尖括号形状,并在正文里说明为什么这么写。
- **session URL 写进正文散文、并作为反引号代码跨度** —— 实测原样穿过 `PATCH`;⛔ 别指望 markdown 链接形式的 footer 活下来。
- **issue 正文里的 attribution 写成散文**,⛔ 别依赖 footer 块(见 ④)。
- **每次发布之后回读到正文末尾,并数一次尖括号命中**;开 PR 之前额外扫一遍自己的正文 —— `grep -nEi '(clos|fix|resolv)' <file>`,确认每一个靠近 `#` 的命中都是你**有意**要关的那张卡。

**占位符不是特例:普通散文和围栏代码块里的占位符同样被吃掉** —— 实测一行命令配方里的两个占位符双
双塌成一个裸 `-`,而那一行存在的意义正是给出那两个占位符。权威措辞在 `../objectstack` 的 `AGENTS.md`
(「GitHub mutates body BYTES — spell poison-shaped tokens out in words, never literally」那一条),
⛔ 本仓不复制它的正文,免得两处漂移;这里只留指针,并**逐字**保留其中最要紧、也最容易被漏掉的那半
句:

> A body reading short only through the API is probably intact — check the rendered page before "repairing" it; a rewrite destroys a correct card.

⇒ ⭐ **回读发现正文「变短」时,先看渲染后的页面,再决定要不要修。** 一次不必要的重写会毁掉一张本
来正确的卡 —— 而在受管面上,那是不可恢复的。

### ⛔ 受管面(governed surface):agent 起草,人类合并

维护者裁决(2026-08-18),**原文照录、不翻译** —— 提问明确点名了本仓:
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -398,6 +398,52 @@ ls <dir>/* | wc -l # 两个数不等 ⇒ 工
于钩子。有意例外:`OS_ALLOW_TREE_ENUM=1`。改这个钩子?重跑
`.claude/hooks/guard-tree-enum.selftest.sh`。

#### ⭐ 对照挂在**通道**上,不只挂在查询上 —— 而且**每次查询**都要跑一遍

上面两条写的都是**查询**级的对照(总体 vs 逐项、对照必须有能力失败)。还差一层:**通道本身也会静默
失灵,而且是间歇性的 —— 间歇比全坏更危险,因为第一次拿到命中的席位会学会信任它。**

实测(objectui#7185,同一容器、同一小时、两条 lane):MCP `search_issues` 对一个 `issue_read` 能直接
读出来的 issue 返回 `total_count: 0`;而另一条 lane 用一个**短关键词**查询在同一个工具上拿到 **3 条
命中**。⇒ ⛔ **不是通道不可用** —— 死通道不会返回 3 条。失灵的是那一次查询(失败的那条是**长的、近
乎逐字的标题**,可用的那条是短关键词)。所以规则不是「别用 search」,而是:

- **非空结果自我验证,不需要对照;空结果永远需要一个「已知必中」的对照** —— 例如某个你能用 `issue_read` 直接读到的 issue 的近逐字标题。⛔ **没跑对照的空结果不是一次读数**:它不携带任何信息,而它渲染出来恰好就是去重步骤想要的那个答案(「没有重复」),与真负例**不可区分**,不做对照就**不可证伪**。失败形态不是「报错然后重试」,是「立了一张重复卡、没人纠正、下一个席位再立一次」。
- **每次查询都跑,不是每个会话跑一次。**「这个通道十分钟前还好好的」不是关于你眼前这次查询的证据。
- **兜底通道**:零配额的 GitHub 网页 payload 通道实测可用(同一次去重里返回 8 个 issue 号,含 `search_issues` 看不见的那个),**它要跑同一条对照** —— 它只是「某一天、某一个容器里被测过可用」,不是永久答案。
- ⚠️ **未解,别当已答问题用**:`search_issues` 为何对一个直读得到的 issue 返回 0 —— 索引延迟,还是读路径与搜索路径的 scope / 查询形状差异?两者的补救完全不同(前者自愈,后者会永久地、静默地收窄每一次去重),本仓尚未诊断。

### ⚠️ GitHub 会改写你写进 issue/PR 正文的字节 —— 每次发布后回读

**六种已实测的改写,共享同一个失败模式:正文在写入之后被静默改变,而且不回读就看不见**
(objectui#6970、#6452;多个 agent 在同一个工作会话里各自独立撞到,重复发现率本身就是把它写下来的
理由)。

- **① tag 形状的片段在保存时被删掉** —— 反引号和围栏代码块**都不保护**。实测:一张 `.d.ts` 的 before/after 对照表,两列的泛型参数被吃掉后**双双塌成同一个字符串**,于是一张专为展示类型变化而写的表,渲染出来正好读作「什么都没变」。⚠️ 单独占据第一行的 HTML 注释标记同样被吃掉 —— 首行位置不提供任何保护,靠标记扫描找报告的机制会因此完全看不见那条评论。
- **② `PATCH` 把 session-URL 形式的 attribution footer 降级为 bare 形式**,丢掉 session 引用。
- **③ `PATCH` 无条件追加第二个 footer** —— 哪怕提交的正文已经以一个 footer 结尾。逐字节回读实测:存储的正文比发出的多**恰好 58 字节**,unified diff 只有那几行追加的 footer、没有内容被吃 ⇒ 与 ①② 都不同,这一种是**加**,不是**减**。
- **④ `issue_write` 创建 issue 时,attribution footer 被整块删除**(不是降级,是消失)。⭐ 定位方式值得单独记住,因为它把「删除」和「截断」分开了:发出的是 body + footer + 尾部 sentinel,回读结果是 **sentinel 在、footer 不在** ⇒ 被删的是**中间**那一块,是针对 attribution 的定向剥离。⚠️ 没有这个 sentinel 对照项,唯一能得出的结论是「正文被截断了」,那会把人指向完全错误的方向(比如去查长度上限)。
- **⑤ `create_pull_request` 把 bare footer 归一化为 session-URL 形式** —— 与 ② 恰好**反向**。⇒ ⭐ 两条合起来才是完整后果:**一个 PR 正文只要被创建之后再编辑一次,就会丢掉 session 引用**,单看任一条都看不出来。⚠️ 而且那个 session id 是**席位**的,不是具体那次实现的 —— 任何想靠它回溯「是哪个 agent 做的这次改动」的机制,只会拿到席位粒度的答案,比看上去弱一档。
- **⑥ ⛔ 关单关键词解析器无视否定 —— 这一种最危险。** 解析器扫的是 `close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved` 紧跟一个 issue 引用,**它不解析句子**:一句「本 PR 并不关闭某卡」若按英文否定式写成 does-NOT-close 加卡号,合并时照样把那张卡关掉。⚠️ 前五种在检视时**看得见**,这一种看不见:损害是**延迟**的(合并那一刻才发生,可能是几天后的另一个会话),而且**反转作者的明确意图** —— 那句话之所以存在,正因为作者在小心行事;卡被静默关掉后不再出现在任何队列普查里,于是它在跟踪的后续不是「可见地被阻塞」,而是直接丢失。安全写法:`Part of #<n>`、`Refs: #<n>`、`Related: #<n>`、裸 `objectui#<n>`(不带关键词)。

**实测有效的缓解,四条 —— 合起来才够,单独任何一条都不够:**

- **泛型和占位符写成大写单词**(例如 "OPT of `z.ZodNever`"),⛔ 永不字面写成尖括号形状,并在正文里说明为什么这么写。
- **session URL 写进正文散文、并作为反引号代码跨度** —— 实测原样穿过 `PATCH`;⛔ 别指望 markdown 链接形式的 footer 活下来。
- **issue 正文里的 attribution 写成散文**,⛔ 别依赖 footer 块(见 ④)。
- **每次发布之后回读到正文末尾,并数一次尖括号命中**;开 PR 之前额外扫一遍自己的正文 —— `grep -nEi '(clos|fix|resolv)' <file>`,确认每一个靠近 `#` 的命中都是你**有意**要关的那张卡。

**占位符不是特例:普通散文和围栏代码块里的占位符同样被吃掉** —— 实测一行命令配方里的两个占位符双
双塌成一个裸 `-`,而那一行存在的意义正是给出那两个占位符。权威措辞在 `../objectstack` 的 `AGENTS.md`
(「GitHub mutates body BYTES — spell poison-shaped tokens out in words, never literally」那一条),
⛔ 本仓不复制它的正文,免得两处漂移;这里只留指针,并**逐字**保留其中最要紧、也最容易被漏掉的那半
句:

> A body reading short only through the API is probably intact — check the rendered page before "repairing" it; a rewrite destroys a correct card.

⇒ ⭐ **回读发现正文「变短」时,先看渲染后的页面,再决定要不要修。** 一次不必要的重写会毁掉一张本
来正确的卡 —— 而在受管面上,那是不可恢复的。

### ⛔ 受管面(governed surface):agent 起草,人类合并

维护者裁决(2026-08-18),**原文照录、不翻译** —— 提问明确点名了本仓:
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -398,6 +398,52 @@ ls <dir>/* | wc -l # 两个数不等 ⇒ 工
于钩子。有意例外:`OS_ALLOW_TREE_ENUM=1`。改这个钩子?重跑
`.claude/hooks/guard-tree-enum.selftest.sh`。

#### ⭐ 对照挂在**通道**上,不只挂在查询上 —— 而且**每次查询**都要跑一遍

上面两条写的都是**查询**级的对照(总体 vs 逐项、对照必须有能力失败)。还差一层:**通道本身也会静默
失灵,而且是间歇性的 —— 间歇比全坏更危险,因为第一次拿到命中的席位会学会信任它。**

实测(objectui#7185,同一容器、同一小时、两条 lane):MCP `search_issues` 对一个 `issue_read` 能直接
读出来的 issue 返回 `total_count: 0`;而另一条 lane 用一个**短关键词**查询在同一个工具上拿到 **3 条
命中**。⇒ ⛔ **不是通道不可用** —— 死通道不会返回 3 条。失灵的是那一次查询(失败的那条是**长的、近
乎逐字的标题**,可用的那条是短关键词)。所以规则不是「别用 search」,而是:

- **非空结果自我验证,不需要对照;空结果永远需要一个「已知必中」的对照** —— 例如某个你能用 `issue_read` 直接读到的 issue 的近逐字标题。⛔ **没跑对照的空结果不是一次读数**:它不携带任何信息,而它渲染出来恰好就是去重步骤想要的那个答案(「没有重复」),与真负例**不可区分**,不做对照就**不可证伪**。失败形态不是「报错然后重试」,是「立了一张重复卡、没人纠正、下一个席位再立一次」。
- **每次查询都跑,不是每个会话跑一次。**「这个通道十分钟前还好好的」不是关于你眼前这次查询的证据。
- **兜底通道**:零配额的 GitHub 网页 payload 通道实测可用(同一次去重里返回 8 个 issue 号,含 `search_issues` 看不见的那个),**它要跑同一条对照** —— 它只是「某一天、某一个容器里被测过可用」,不是永久答案。
- ⚠️ **未解,别当已答问题用**:`search_issues` 为何对一个直读得到的 issue 返回 0 —— 索引延迟,还是读路径与搜索路径的 scope / 查询形状差异?两者的补救完全不同(前者自愈,后者会永久地、静默地收窄每一次去重),本仓尚未诊断。

### ⚠️ GitHub 会改写你写进 issue/PR 正文的字节 —— 每次发布后回读

**六种已实测的改写,共享同一个失败模式:正文在写入之后被静默改变,而且不回读就看不见**
(objectui#6970、#6452;多个 agent 在同一个工作会话里各自独立撞到,重复发现率本身就是把它写下来的
理由)。

- **① tag 形状的片段在保存时被删掉** —— 反引号和围栏代码块**都不保护**。实测:一张 `.d.ts` 的 before/after 对照表,两列的泛型参数被吃掉后**双双塌成同一个字符串**,于是一张专为展示类型变化而写的表,渲染出来正好读作「什么都没变」。⚠️ 单独占据第一行的 HTML 注释标记同样被吃掉 —— 首行位置不提供任何保护,靠标记扫描找报告的机制会因此完全看不见那条评论。
- **② `PATCH` 把 session-URL 形式的 attribution footer 降级为 bare 形式**,丢掉 session 引用。
- **③ `PATCH` 无条件追加第二个 footer** —— 哪怕提交的正文已经以一个 footer 结尾。逐字节回读实测:存储的正文比发出的多**恰好 58 字节**,unified diff 只有那几行追加的 footer、没有内容被吃 ⇒ 与 ①② 都不同,这一种是**加**,不是**减**。
- **④ `issue_write` 创建 issue 时,attribution footer 被整块删除**(不是降级,是消失)。⭐ 定位方式值得单独记住,因为它把「删除」和「截断」分开了:发出的是 body + footer + 尾部 sentinel,回读结果是 **sentinel 在、footer 不在** ⇒ 被删的是**中间**那一块,是针对 attribution 的定向剥离。⚠️ 没有这个 sentinel 对照项,唯一能得出的结论是「正文被截断了」,那会把人指向完全错误的方向(比如去查长度上限)。
- **⑤ `create_pull_request` 把 bare footer 归一化为 session-URL 形式** —— 与 ② 恰好**反向**。⇒ ⭐ 两条合起来才是完整后果:**一个 PR 正文只要被创建之后再编辑一次,就会丢掉 session 引用**,单看任一条都看不出来。⚠️ 而且那个 session id 是**席位**的,不是具体那次实现的 —— 任何想靠它回溯「是哪个 agent 做的这次改动」的机制,只会拿到席位粒度的答案,比看上去弱一档。
- **⑥ ⛔ 关单关键词解析器无视否定 —— 这一种最危险。** 解析器扫的是 `close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved` 紧跟一个 issue 引用,**它不解析句子**:一句「本 PR 并不关闭某卡」若按英文否定式写成 does-NOT-close 加卡号,合并时照样把那张卡关掉。⚠️ 前五种在检视时**看得见**,这一种看不见:损害是**延迟**的(合并那一刻才发生,可能是几天后的另一个会话),而且**反转作者的明确意图** —— 那句话之所以存在,正因为作者在小心行事;卡被静默关掉后不再出现在任何队列普查里,于是它在跟踪的后续不是「可见地被阻塞」,而是直接丢失。安全写法:`Part of #<n>`、`Refs: #<n>`、`Related: #<n>`、裸 `objectui#<n>`(不带关键词)。

**实测有效的缓解,四条 —— 合起来才够,单独任何一条都不够:**

- **泛型和占位符写成大写单词**(例如 "OPT of `z.ZodNever`"),⛔ 永不字面写成尖括号形状,并在正文里说明为什么这么写。
- **session URL 写进正文散文、并作为反引号代码跨度** —— 实测原样穿过 `PATCH`;⛔ 别指望 markdown 链接形式的 footer 活下来。
- **issue 正文里的 attribution 写成散文**,⛔ 别依赖 footer 块(见 ④)。
- **每次发布之后回读到正文末尾,并数一次尖括号命中**;开 PR 之前额外扫一遍自己的正文 —— `grep -nEi '(clos|fix|resolv)' <file>`,确认每一个靠近 `#` 的命中都是你**有意**要关的那张卡。

**占位符不是特例:普通散文和围栏代码块里的占位符同样被吃掉** —— 实测一行命令配方里的两个占位符双
双塌成一个裸 `-`,而那一行存在的意义正是给出那两个占位符。权威措辞在 `../objectstack` 的 `AGENTS.md`
(「GitHub mutates body BYTES — spell poison-shaped tokens out in words, never literally」那一条),
⛔ 本仓不复制它的正文,免得两处漂移;这里只留指针,并**逐字**保留其中最要紧、也最容易被漏掉的那半
句:

> A body reading short only through the API is probably intact — check the rendered page before "repairing" it; a rewrite destroys a correct card.

⇒ ⭐ **回读发现正文「变短」时,先看渲染后的页面,再决定要不要修。** 一次不必要的重写会毁掉一张本
来正确的卡 —— 而在受管面上,那是不可恢复的。

### ⛔ 受管面(governed surface):agent 起草,人类合并

维护者裁决(2026-08-18),**原文照录、不翻译** —— 提问明确点名了本仓:
Expand Down