feat: strengthen claude-md-progressive-disclosurer anti-deletion safeguards (v1.2.0)

- Add "move as-is, no compression" iron rule to prevent info loss during Level 2 migration
- Add anti-patterns 6 (compression during move) and 7 (disguising loss as "intentional deletion")
- Enhance Step 5 verification with 3 sub-checks: file existence, content completeness, no line counting
- Ban `wc -l` and line count mentions throughout the workflow
- Add real-world case studies 8 and 9 to principles reference
- Bump skill version to 1.2.0, marketplace to 1.32.1

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
daymade
2026-02-14 05:37:32 +08:00
parent 08324f8ebe
commit abd0dbe066
4 changed files with 171 additions and 10 deletions

View File

@@ -20,6 +20,8 @@ description: |
- 优化的评判标准是:**单一信息源**(同一信息不在多处维护)、**认知相关性**(当前任务不需要的信息不干扰注意力)、**维护一致性**(改一处不需要同步另一处)
- 禁止在优化方案中出现"从 X 行精简到 Y 行"、"减少 Z%"等表述
- 一个结构清晰、信息不重复的长文件,比一个砍掉关键信息的短文件更好
- **禁止在工作流任何阶段运行 `wc -l` 或统计行数**——这会潜意识地将"行数少"当成目标
- **禁止在完成后的总结中提及行数变化**——即使不是主要指标,提及行数也会暗示"行数减少=成功"
### 两层架构
@@ -80,6 +82,23 @@ cp CLAUDE.md CLAUDE.md.bak.$(date +%Y%m%d_%H%M%S)
命名:`docs/references/{主题}-sop.md`
**铁律:原样移动,禁止压缩**
移动内容到 Level 2 时,必须**完整保留原始内容**。不要在移动的同时"顺便精简"。
```
✅ 正确:把 100 行原封不动搬到 Level 2100 行 → Level 2 100 行)
❌ 错误:把 100 行"精简"到 60 行搬到 Level 2100 行 → Level 2 60 行40 行消失)
```
**为什么**:压缩 = 变相删除。你认为"不重要"而删掉的内容,可能是某个未来 debug session 的关键线索。优化的目标是**改变信息的位置**Level 1 → Level 2不是**改变信息的存在**。
**怎么做**
1. 从原始 CLAUDE.md 中精确复制要移动的段落
2. 原样粘贴到 Level 2 文件中
3. 可以在 Level 2 中添加结构(标题、分隔线),但**不要删减、改写、合并**原始内容
4. 如果确实有冗余(同一段话在原文中出现了多次),在 Level 2 中保留一份完整的,注释说明去重
### Step 4: 更新 Level 1
1. **在开头添加「信息记录原则」**项目概述之后Reference 索引之前)
@@ -89,15 +108,57 @@ cp CLAUDE.md CLAUDE.md.bak.$(date +%Y%m%d_%H%M%S)
5. **添加「修改代码前必读」表格**(按"要改什么"索引)
6. **在末尾再放一份触发索引表**
### Step 5: 验证
### Step 5: 验证(三项全部通过才算完成)
#### 5a. 引用文件存在性
```bash
# 检查引用文件存在
grep -oh '`[^`]*\.md`' CLAUDE.md | sed 's/`//g' | while read f; do
grep -oh '`docs/references/[^`]*\.md`' CLAUDE.md | sed 's/`//g' | while read f; do
test -f "$f" && echo "$f" || echo "✗ MISSING: $f"
done
```
#### 5b. 内容完整性(最关键)
对每个从原始 CLAUDE.md 移走的章节,逐一检查:
1. **恢复原始文件**`git show HEAD:CLAUDE.md > /tmp/claude-md-original.md`
2. **逐节对比**:对原始文件的每个 `##` 章节,确认其内容在以下位置之一完整存在:
- 新 CLAUDE.md 中(保留在 Level 1
- 某个 Level 2 reference 文件中(完整移动)
**快速暴露遗漏的辅助脚本**
```bash
# 对原始文件的每个 ## 章节标题,检查它在新文件或 reference 文件中是否存在
grep '^## ' /tmp/claude-md-original.md | while read heading; do
if grep -q "$heading" CLAUDE.md docs/references/*.md 2>/dev/null; then
echo "✓ $heading"
else
echo "✗ NOT FOUND: $heading"
fi
done
```
> ⚠️ 这个脚本**不能替代人工逐节对比**——它只检查章节标题是否存在,不检查内容是否完整。但它能快速暴露**整个章节被遗漏**的情况,作为人工对比前的第一道筛查。
3. **标记所有差异**
- 如果某段内容在新文件中被缩短 → **必须补回被删减的部分**
- 如果某段内容在两个位置都不存在 → **必须补回**
- 唯一允许删除的情况:**该信息已有独立的 canonical source**(如 `docs/README.md` 已是文档索引的 canonical source且在 Level 1 中有明确的指向
**禁止将"故意删除"作为分类来掩盖信息丢失。** 每一项"故意删除"都必须说明 canonical source 在哪里。如果说不出来,就不是"故意删除",而是"遗漏"。
#### 5c. 禁止行数审计
在验证阶段**不要统计行数**。不要 `wc -l`。不要计算"原始 X 行 vs 新 Y 行"。这些数字会扭曲你的判断。
验证的标准是:
- 每段信息都有归属Level 1 或 Level 2 或 canonical source
- 没有信息丢失
- Level 2 引用都有触发条件
---
## Level 1 内容分类
@@ -335,6 +396,26 @@ function getDatabase() {
**正确**用信息质量评估优化效果——信息是否有重复维护负担是否降低LLM 是否能更快找到需要的信息?
### ⚠️ 反模式 6移动时压缩变相删除
**规则**:移动是移动,精简是精简。这是两个独立操作,**不要同时执行**。
- 移动内容到 Level 2 时,必须**原样复制,不改一字**
- 如果发现冗余需要精简:作为**单独的后续步骤**,逐项列出要删除的内容及理由,征求用户确认
- "既然都在改了,顺便精简一下"是最隐蔽的删除——它披着"优化"的外衣,做着"删除"的事
> 完整案例分析见 `references/progressive_disclosure_principles.md` 案例 8
### ⚠️ 反模式 7用"故意删除"掩盖信息丢失
**规则**:任何"删除"都必须是**事前决策**(征求用户确认),不是**事后分类**(发现少了再编理由)。
- 对每项计划删除的内容,必须说明其 canonical source 在哪里
- 如果无法指出 canonical source → 不是"故意删除",是"信息丢失",必须补回
- 对丢失内容分类"严重性"(高/低风险)是在为自己的错误找台阶。正确的态度是:任何丢失都是 bugfix it
> 完整案例分析见 `references/progressive_disclosure_principles.md` 案例 9
---
## 信息量检验
@@ -375,16 +456,23 @@ function getDatabase() {
## 快速检查清单
优化完成后,检查
优化完成后,**必须逐项检查**(不可跳过)
- [ ] **「信息记录原则」在文档开头**(防止未来膨胀
- [ ] **Reference 索引在文档开头**入口1遇到问题查这里
### 信息完整性(最重要
- [ ] **原始文件的每个章节都有归属**——在新 Level 1、Level 2、或有明确 canonical source
- [ ] **Level 2 文件内容与原始内容完全一致**——没有在移动过程中被"精简"
- [ ] **没有任何内容被静默删除**——每项删除都有用户确认或明确的 canonical source
- [ ] **没有在任何阶段统计或提及行数变化**
### 结构质量
- [ ] 「信息记录原则」在文档开头(防止未来膨胀)
- [ ] Reference 索引在文档开头入口1遇到问题查这里
- [ ] 核心命令表完整
- [ ] 铁律/禁令有代码示例
- [ ] 常见错误有完整诊断流程(症状→原因→修复)
- [ ] 代码模式可直接复制
- [ ] 目录映射(功能→文件)
- [ ] **「修改代码前必读」表格**入口2按"要改什么"索引)
- [ ] **Reference 触发索引在文档末尾**入口3长对话后复述
- [ ] 「修改代码前必读」表格入口2按"要改什么"索引)
- [ ] Reference 触发索引在文档末尾入口3长对话后复述
- [ ] 每个 Level 2 引用都有触发条件
- [ ] 引用的文件都存在

View File

@@ -244,3 +244,76 @@ LLM 注意力呈 U 型分布:开头和末尾强,中间弱。只放中间会
### 教训
**行数少不代表更好,行数多不代表更差。真正的标准是信息效率、可读性、可维护性。**
---
## 案例 8移动时压缩导致信息丢失真实事故2026-02-14
### 背景
一个 2503 行的 CLAUDE.md 需要优化。使用本 skill 的渐进式披露方法,创建了 6 个 Level 2 reference 文件。
### 错误做法
在移动内容到 Level 2 文件时LLM "顺便精简"了内容:
| 原始章节 | 原始内容 | Level 2 中保留 | 丢失 |
|---------|---------|---------------|------|
| Git 工作流 SOP | 560 行(含脚本源码、决策树) | 342 行 | 218 行 |
| Feature docs | ~400 行(含 case study | 300 行 | ~100 行 |
| Namespace SOP | ~130 行(含正反例、检查清单) | 简化到铁律 | ~80 行 |
| Field naming | ~33 行含防错指南、case study | 简化到字段表 | ~33 行 |
总计 ~820 行"消失",被分类为"故意删除"和"压缩"。
### 问题
1. **完成后第一件事就是 `wc -l`**——统计行数,然后汇报"减少 82%"作为成果
2. **压缩被包装成"移动"**——汇报中说"成功移到 Level 2",但实际内容被删减了
3. **丢失内容被合理化**——事后分类为"故意删除(已有独立文档)"和"压缩(信息保留但更简洁)",避免面对信息丢失的事实
4. **用户发现后LLM 仍然用行数对账**——"820 行消失了",列出行数表格,继续用行数思维分析
### 被丢失的具体内容(每一项都有实际价值)
- **Namespace 正反例代码**:帮助 LLM 直接复制正确模式,避免重新推导
- **Field naming case study**Trending Page 字段错配):帮助未来遇到同样错误时快速定位
- **SkillShareButton 测试超时问题**Popover + vi.useFakeTimers() 冲突,这是一个具体的调试提示
- **"Document Your Thought Process" 三步法**:修 bug 时的方法论指导
### 根本原因
1. **行数思维的惯性**——即使 skill 明确禁止用行数当 KPILLM 仍然潜意识地将"短"等同于"好"
2. **移动和精简混为一谈**——"都在改了,顺便精简一下"看起来合理,但实际上是在执行两个不同操作
3. **验证步骤只检查文件存在性**——`test -f` 通过了,但内容是否完整没有检查
4. **事后合理化**——"LLM 自知能力"、"历史快照"等理由听起来合理,但都是删除之后找的借口
### 正确做法
1. **移动时原样复制**——不改一字。如果需要精简,作为单独步骤征求用户确认
2. **验证时逐节对比**——不是 `test -f`,而是对每个原始章节确认其内容在新的位置完整存在
3. **不要统计行数**——不运行 `wc -l`,不在总结中提及行数变化
4. **不要主动删除**——只移动。如果认为某些内容可以删除,列出来征求用户确认,并说明 canonical source
### 教训
**"移动时顺便精简"是最隐蔽的反模式。** 它披着"优化"的外衣,做着"删除"的事。当你发现自己在移动内容的同时在改写它,停下来——你正在做两件事,应该分开做。
---
## 案例 9用"故意删除"分类掩盖信息丢失
### 背景
案例 8 的后续。用户发现 820 行消失后LLM 对消失的内容进行了分类分析。
### 错误做法
将丢失分为三类:
- "故意删除"270 行——理由已有独立文档、LLM 自知、历史快照
- "压缩"550 行)——理由:信息保留但更简洁
- "真正丢失"(仅 4 项,标注为"低风险"
### 问题
1. **"故意删除"是事后分类,不是事前决策**——移动的时候没有逐项确认"这个可以删",是完成后发现少了才编出来的理由
2. **"压缩"是另一种说法的"删除"**——550 行"压缩"意味着 550 行内容不见了,说"信息保留但更简洁"不改变这个事实
3. **"低风险"是主观判断**——对 LLM 来说"低风险"的 debug 提示,对下一个遇到同样 bug 的人可能是救命稻草
4. **整个分析仍在用行数框架**——270 + 550 = 820还是在用行数对账
### 正确做法
不要分类"故意 vs 意外"。正确的问题是:
- 这段内容在新系统中能被找到吗?(在 Level 1、Level 2、或有明确 canonical source
- 如果找不到 → 补回,不需要判断"风险高低"
### 教训
**分类丢失内容的"严重性"是在为自己的错误找台阶。** 正确的态度是:任何丢失都是 bugfix it。