@dsh-fly/dsh-plugin-fly-smart 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,129 @@
1
+ ---
2
+ name: smart-verify-claim
3
+ description: Use when 即将声称工作已完成、已修复、测试通过、可以提交或创建 PR,在做出任何成功声明之前加载:证据先于断言。
4
+ ---
5
+
6
+ <!-- Ported from obra/superpowers skills/verification-before-completion/ — MIT License, Copyright (c) 2025 Jesse Vincent. Adapted for DSH. -->
7
+
8
+ # 完成声明之前先验证
9
+
10
+ ## 概述
11
+
12
+ **核心原则:Evidence before claims, always.**
13
+
14
+ **Violating the letter of this rule is violating the spirit of this rule.**
15
+
16
+ ## 铁律
17
+
18
+ ```
19
+ NO COMPLETION CLAIMS WITHOUT FRESH VERIFICATION EVIDENCE
20
+ ```
21
+
22
+ 如果你在**这条消息里**没有跑过验证命令,你就不能声称它通过。"上次是绿的"、"应该是好的"、"我记得没问题" —— 都不是证据。
23
+
24
+ ## The Gate Function
25
+
26
+ ```
27
+ BEFORE claiming any status or expressing satisfaction:
28
+
29
+ 1. IDENTIFY: What command proves this claim?
30
+ 2. RUN: Execute the FULL command (fresh, complete)
31
+ 3. READ: Full output, check exit code, count failures
32
+ 4. VERIFY: Does output confirm the claim?
33
+ - If NO: State actual status with evidence
34
+ - If YES: State claim WITH evidence
35
+ 5. ONLY THEN: Make the claim
36
+
37
+ Skip any step = lying, not verifying
38
+ ```
39
+
40
+ ## Common Failures
41
+
42
+ | Claim | Requires | Not Sufficient |
43
+ |-------|----------|----------------|
44
+ | Tests pass | Test command output: 0 failures | Previous run, "should pass" |
45
+ | Linter clean | Linter output: 0 errors | Partial check, extrapolation |
46
+ | Build succeeds | Build command: exit 0 | Linter passing, logs look good |
47
+ | Bug fixed | Test original symptom: passes | Code changed, assumed fixed |
48
+ | Regression test works | Red-green cycle verified | Test passes once |
49
+ | Agent completed | `bash` diff shows changes | Agent reports "success" |
50
+ | Requirements met | Line-by-line checklist | Tests passing |
51
+
52
+ ## Red Flags —— 停下
53
+
54
+ - 使用 "should" / "probably" / "seems to"
55
+ - 验证之前表达满意("Great!"、"Perfect!"、"Done!" 等)
56
+ - 未经验证就想 commit / push / 开 PR
57
+ - 相信子代理的成功报告
58
+ - 依赖部分验证
59
+ - 心想"就这一次"
60
+ - 累了、想快点收工
61
+ - **任何暗示成功却没跑过验证的措辞**
62
+
63
+ ## Rationalization Prevention
64
+
65
+ | Excuse | Reality |
66
+ |--------|---------|
67
+ | "Should work now" | RUN the verification |
68
+ | "I'm confident" | Confidence ≠ evidence |
69
+ | "Just this once" | No exceptions |
70
+ | "Linter passed" | Linter ≠ compiler |
71
+ | "Agent said success" | 独立验证:`bash` 看 diff,`read` 看产出 |
72
+ | "I'm tired" | Exhaustion ≠ excuse |
73
+ | "Partial check is enough" | Partial proves nothing |
74
+ | "换种说法就不算违规" | Spirit over letter |
75
+
76
+ ## Key Patterns
77
+
78
+ **测试:**
79
+ ```
80
+ ✅ [跑测试命令] [看到: 34/34 pass] "All tests pass"
81
+ ❌ "Should pass now" / "Looks correct"
82
+ ```
83
+
84
+ **回归测试(TDD Red-Green):**
85
+ ```
86
+ ✅ 写 → 跑(过) → 撤销修复 → 跑(必须红) → 恢复 → 跑(过)
87
+ ❌ "我写了回归测试"(没做过红绿验证)
88
+ ```
89
+
90
+ **构建:**
91
+ ```
92
+ ✅ [跑构建] [看到: exit 0] "Build passes"
93
+ ❌ "Linter passed"(linter 不检查编译)
94
+ ```
95
+
96
+ **需求:**
97
+ ```
98
+ ✅ 重读计划 → 列清单 → 逐条验证 → 报告缺口或完成
99
+ ❌ "Tests pass, phase complete"
100
+ ```
101
+
102
+ **子代理委派:**
103
+ ```
104
+ ✅ 子代理报告成功 → bash 看 diff → 验证改动 → 报告实际状态
105
+ ❌ 相信子代理报告
106
+ ```
107
+
108
+ DSH 工具面:跑命令用 `bash`,读产出用 `read`,改文件用 `write` / `edit`,找内容用 `grep`;
109
+ 后台任务先 `job_list`、再用 `job_output` 收齐输出 —— **没读到输出 = 没跑过**。
110
+
111
+ ## When To Apply
112
+
113
+ **ALWAYS before:**
114
+ - 任何成功 / 完成声明的变体
115
+ - 任何满意表达
116
+ - 任何关于工作状态的正面陈述
117
+ - 提交、开 PR、宣布任务完成
118
+ - 转向下一项任务
119
+ - 把工作委派给子代理
120
+
121
+ **Rule applies to:**
122
+ - 原句
123
+ - 改述与同义词
124
+ - 暗示成功的表述
125
+ - 任何暗示完成 / 正确的沟通
126
+
127
+ ## 与 smart 工作流的关系
128
+
129
+ smart 工作流的 `smart_verify` 是这套纪律的工具化:它取证并把证据落成文件。但这条纪律适用于**任何**会话 —— 不需要开 smart 任务。
@@ -0,0 +1,182 @@
1
+ ---
2
+ name: smart-worktree
3
+ description: Use when 开始需要与当前工作区隔离的特性工作、或在执行实现计划之前加载:确保在隔离工作区里干活,绝不在 main/master 上开工。先探测是否已在隔离区,优先用 DSH 原生工作区,没有才落 git worktree。
4
+ ---
5
+
6
+ <!-- Ported from obra/superpowers skills/using-git-worktrees/ — MIT License, Copyright (c) 2025 Jesse Vincent. Adapted for DSH. -->
7
+
8
+ # 建立隔离工作区(git worktree / DSH 工作区)
9
+
10
+ ## 概述
11
+
12
+ 确保工作发生在隔离工作区里,而不是当前 checkout、更不是主干上。
13
+
14
+ **优先级(原句保留):** *Prefer your platform's native worktree tools. Fall back to manual git worktrees only when no native tool is available.*
15
+ **另一句同样保留:** *Never fight the harness.*
16
+
17
+ **Core principle(原句保留):** *Detect existing isolation first. Then use native tools. Then fall back to git. Never fight the harness.*
18
+
19
+ **开工先宣告:** "我正在使用 smart-worktree 技能建立隔离工作区。"
20
+
21
+ **铁律:绝不在 `main` / `master` 上开工。** 只有人类明确同意(原话点头),才允许直接在主干上改;否则一律先落隔离区(新分支 / worktree / DSH 工作区)。
22
+
23
+ ## Step 0: Detect Existing Isolation(先查有没有现成的隔离)
24
+
25
+ **在创建任何东西之前,先确认你是不是已经身处隔离工作区。**
26
+
27
+ 判据命令(用 `bash` 执行,命令与表达式保持原样、可直接复制):
28
+
29
+ ```bash
30
+ GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P)
31
+ GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P)
32
+ BRANCH=$(git branch --show-current)
33
+ ```
34
+
35
+ **Submodule guard(必须先排子模块):** 原文明确 *"`GIT_DIR != GIT_COMMON` 在子模块里也为真"*(*"`GIT_DIR != GIT_COMMON` is also true inside git submodules"*)。所以在断言"已经在 worktree 里"之前,先排除子模块:
36
+
37
+ ```bash
38
+ # If this returns a path, you're in a submodule, not a worktree — treat as normal repo
39
+ git rev-parse --show-superproject-working-tree 2>/dev/null
40
+ ```
41
+
42
+ 返回非空路径 ⇒ 你在子模块里、**不是** worktree ⇒ 按普通仓库处理。
43
+
44
+ **若 `GIT_DIR != GIT_COMMON`(且不在子模块里):** 你已经在 linked worktree 里。直接跳到 Step 2(项目装配),**不要再建第二个 worktree**。
45
+
46
+ 按分支状态如实报告:
47
+ - 在分支上:"Already in isolated workspace at `<path>` on branch `<name>`."
48
+ - Detached HEAD:"Already in isolated workspace at `<path>` (**detached HEAD, externally managed**). **Branch creation needed at finish time.**"
49
+ —— 外部托管的 detached HEAD 不要自作主张建分支;收尾(finish)时才建分支落盘。
50
+
51
+ **若 `GIT_DIR == GIT_COMMON`(或在子模块里):** 你在普通仓库 checkout 里。
52
+
53
+ 用户/上级指令里有没有已经声明的隔离偏好?没有的话,创建 worktree 前先征得同意:
54
+
55
+ > "要不要我建一个隔离工作区?它能保护你当前分支不被改动。"
56
+
57
+ 已有明确偏好的直接照办、不再问。用户拒绝 ⇒ 就地干活,跳到 Step 2。
58
+
59
+ ## Step 1: Create Isolated Workspace(两条机制,按顺序试)
60
+
61
+ ### 1a. 原生工具(优先):DSH 工作区 → 平台原生 worktree 工具
62
+
63
+ 1. **DSH 自带隔离能力:会话工作区(workspace)。** 先用它 —— 本技能运行在 DSH 里,session 的 workspace 就是现成的隔离区(独立目录、与当前 checkout 分离)。能在工作区里开分支/开目录干活的,就落在工作区里,跳到 Step 2。
64
+ 2. 再看有没有别的原生 worktree 工具(名字可能叫 `EnterWorktree`、`WorktreeCreate`、`/worktree` 命令或 `--worktree` 开关)。有就用它,跳到 Step 2。
65
+
66
+ 原生工具会自动处理目录摆放、分支创建和清理。**手里有原生工具却用 `git worktree add`,会制造 harness 看不见、也管不了的幻影状态(phantom state)—— 这是头号错误。**
67
+
68
+ 只有在**没有任何原生工具**时才进 1b。
69
+
70
+ ### 1b. Git Worktree 兜底(仅当 1a 不适用)
71
+
72
+ #### 目录选择(优先级从高到低;显式指令永远压过观察到的文件系统状态)
73
+
74
+ 1. **先看指令里有没有声明好的 worktree 目录偏好**(用 `read` 查计划/约束文件):有就直接用、不再问。
75
+ 2. **再查项目里有没有现成的 worktree 目录**(用 `glob` 或 `bash`):
76
+ ```bash
77
+ ls -d .worktrees 2>/dev/null # Preferred (hidden)
78
+ ls -d worktrees 2>/dev/null # Alternative
79
+ ```
80
+ 找到就用;两个都在 ⇒ `.worktrees` 赢。
81
+ 3. **没有任何别的指引** ⇒ 默认用项目根下的 `.worktrees/`。
82
+
83
+ #### 安全校验(仅项目内目录需要)
84
+
85
+ **创建前必须确认目录已被忽略:**
86
+
87
+ ```bash
88
+ git check-ignore -q .worktrees 2>/dev/null || git check-ignore -q worktrees 2>/dev/null
89
+ ```
90
+
91
+ **没被忽略:** 写进 `.gitignore`(`write` / `edit`),提交这次改动,再继续。
92
+
93
+ **为什么关键:** 没忽略的 worktree 目录会把整棵 worktree 内容提交进仓库。
94
+
95
+ #### 创建 worktree
96
+
97
+ ```bash
98
+ # Determine path based on chosen location
99
+ path="$LOCATION/$BRANCH_NAME"
100
+
101
+ git worktree add "$path" -b "$BRANCH_NAME"
102
+ cd "$path"
103
+ ```
104
+
105
+ **Sandbox fallback:** `git worktree add` 若因权限被拒(沙箱拦截),告诉用户"沙箱挡住了 worktree 创建、改为就地干活",然后在当前目录跑装配与基线测试。别跟 harness 较劲(*Never fight the harness.*)。
106
+
107
+ **分支名约束:** `$BRANCH_NAME` 从特性名派生,**不得**是 `main` / `master`;需要在主干上开工只有人类点头一条路。
108
+
109
+ ## Step 2: Project Setup(项目装配)
110
+
111
+ 自动探测并跑对应装配(用 `bash`):
112
+
113
+ ```bash
114
+ # Node.js
115
+ if [ -f package.json ]; then npm install; fi
116
+
117
+ # Rust
118
+ if [ -f Cargo.toml ]; then cargo build; fi
119
+
120
+ # Python
121
+ if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
122
+ if [ -f pyproject.toml ]; then poetry install; fi
123
+
124
+ # Go
125
+ if [ -f go.mod ]; then go mod download; fi
126
+ ```
127
+
128
+ 没有对应清单文件就跳过依赖安装。
129
+
130
+ ## Step 3: Verify Clean Baseline(干净基线)
131
+
132
+ 跑测试,确认工作区起点是干净的:
133
+
134
+ ```bash
135
+ # Use project-appropriate command
136
+ npm test / cargo test / pytest / go test ./...
137
+ ```
138
+
139
+ **测试挂了:** 如实报告失败项,问用户"继续还是先排查"—— 越过失败往下走是人类的决定。
140
+ **测试过了:** 报告就绪。
141
+
142
+ ### 报告格式
143
+
144
+ ```
145
+ Worktree ready at <full-path>
146
+ Tests passing (<N> tests, 0 failures)
147
+ Ready to implement <feature-name>
148
+ ```
149
+
150
+ ## Quick Reference
151
+
152
+ | 情况 | 动作 |
153
+ |------|------|
154
+ | 已在 linked worktree | 不再创建(Step 0) |
155
+ | 在子模块里 | 按普通仓库处理(Step 0 submodule guard) |
156
+ | 有 DSH 会话工作区 | 用它(Step 1a 第一优先) |
157
+ | 有原生 worktree 工具 | 用它(Step 1a) |
158
+ | 原生工具都没有 | git worktree 兜底(Step 1b) |
159
+ | `.worktrees/` 已存在 | 用它(先验 ignored) |
160
+ | `worktrees/` 已存在 | 用它(先验 ignored) |
161
+ | 两个都存在 | 用 `.worktrees/` |
162
+ | 都不存在 | 查指令偏好,否则默认 `.worktrees/` |
163
+ | 目录没被忽略 | 写 `.gitignore` + 提交 |
164
+ | detached HEAD | externally managed,收尾时才建分支 |
165
+ | 创建被沙箱拦 | Sandbox fallback,就地干活 |
166
+ | 基线测试挂 | 报告失败 + 问用户 |
167
+ | 没有 package.json/Cargo.toml | 跳过依赖安装 |
168
+
169
+ ## Common Rationalizations(常见自我开脱)
170
+
171
+ | 借口 | 现实 |
172
+ |------|------|
173
+ | "我显然不在 worktree 里 —— 不用查了" | 跑 Step 0。harness 造的隔离和子模块都能骗过肉眼;判据命令才能定案。 |
174
+ | "`git worktree add` 比找原生工具快" | 原生工具(如 DSH 工作区、`EnterWorktree`)拥有摆放、分支、清理的所有权。绕过它是头号错误 —— 会制造 harness 看不见、管不了的幻影状态。 |
175
+ | "worktree 目录肯定已经被忽略了" | 跑 `git check-ignore`。没忽略的 worktree 目录会把整棵树提交进仓库。 |
176
+ | "随便哪个目录名都行" | 显式指令 > 已有的项目内目录 > `.worktrees/` 默认。 |
177
+ | "工作区是新的 —— 基线测试可以等等" | 脏基线会让后面每个失败都变得说不清。现在就跑;要不要越过失败是人类的决定。 |
178
+ | "主干上开两分钟没事儿" | 绝不在 `main`/`master` 上开工,除非人类明确同意。隔离区不是仪式,是回滚点的载体。 |
179
+
180
+ ## 与 smart 工作流的关系
181
+
182
+ smart 的 `plan.md` 要求写回滚点,但没要求写『在哪条分支/哪个 worktree 干』。本技能补上这一格:开工前先定隔离区,把它写进计划的 Global Constraints。
@@ -0,0 +1,277 @@
1
+ ---
2
+ name: smart-write-skill
3
+ description: Use when 创建新技能、修改既有技能、或在部署前验证技能是否有效时加载:写技能就是把 TDD 用在流程文档上。
4
+ ---
5
+
6
+ <!-- Ported from obra/superpowers skills/writing-skills/ — MIT License, Copyright (c) 2025 Jesse Vincent. Adapted for DSH. -->
7
+
8
+ # 写技能(smart-write-skill)
9
+
10
+ ## 总览
11
+
12
+ **Writing skills IS Test-Driven Development applied to process documentation.**
13
+ (写技能就是把 TDD 用在流程文档上。)
14
+
15
+ 你写测试用例(用 `subagent` 跑压力场景),看着它失败(基线行为),写技能(文档),看着测试通过(agent 遵守),再重构(堵漏洞)。
16
+
17
+ **核心原则:If you didn't watch an agent fail without the skill, you don't know if the skill teaches the right thing.**
18
+ (没看过 agent 在没有技能时怎么失败,就不知道这个技能教的是不是对的东西 —— 对应 TDD 的"没看到失败就不知道测的是对的"。)
19
+
20
+ **REQUIRED BACKGROUND:** 使用本技能前,你 MUST 先懂 TDD(本插件的 `smart-tdd` 技能):RED-GREEN-REFACTOR 循环在那里定义,本技能只是把它适配到流程文档上。
21
+
22
+ ## 技能是什么 / 不是什么
23
+
24
+ *Skills are: Reusable techniques, patterns, tools, reference guides*
25
+ 技能是:可复用的技巧、模式、工具、参考指南。
26
+
27
+ *Skills are NOT: Narratives about how you solved a problem once*
28
+ 技能不是:关于"你某一次怎么解决了一个问题"的叙事。
29
+
30
+ ## TDD 映射表(灵魂,**原表 10 行一行不许少**)
31
+
32
+ | TDD Concept | Skill Creation |
33
+ |-------------|----------------|
34
+ | **Test case** | 压力场景(用 `subagent` 跑) |
35
+ | **Production code** | SKILL.md |
36
+ | **Test fails (RED)** | 没有技能时 agent 违反规则(基线) |
37
+ | **Test passes (GREEN)** | 有技能时 agent 遵守 |
38
+ | **Refactor** | 堵漏洞且保持合规 |
39
+ | **Write test first** | 写技能前先跑基线 |
40
+ | **Watch it fail** | 记下它用过的原话借口 |
41
+ | **Minimal code** | 只针对那些违规写技能(不写通用论文) |
42
+ | **Watch it pass** | 验证 agent 现在遵守了 |
43
+ | **Refactor cycle** | 找到新的借口 → 堵 → 重新验证 |
44
+
45
+ 整个技能创作流程都走 RED-GREEN-REFACTOR。
46
+
47
+ ## 什么时候建技能
48
+
49
+ **建:** 技巧不是你直觉就会的 / 跨项目会再用 / 模式普适(非项目专属)/ 对别人也有用。
50
+
51
+ **不建:** 一次性解法 / 别处已经写烂的标准做法 / 项目专属约定(写进 AGENTS.md 这类指令文件)/ 机械约束(能用正则、校验强制的就自动化 —— 文档留给需要判断力的地方)。
52
+
53
+ **三种类型:** Technique(技巧:有步骤可跟,如条件等待、根因追踪)/ Pattern(模式:看待问题的思维方式)/ Reference(参考:API 文档、语法指南、工具文档)。
54
+
55
+ ## 技能落盘位置(DSH)
56
+
57
+ 两处,别放错:
58
+
59
+ 1. **本插件自带技能**:包内 `assets/<name>/SKILL.md`(例:`assets/smart-tdd/SKILL.md`)。frontmatter 只有 `name` 与 `description` 两个键。
60
+ 2. **用户自己的技能**:放 harness 的技能目录 `~/.dsh/skills/<name>/SKILL.md`;项目级放仓库里的 `.dsh/skills/`(或 `.agents/skills/`)。
61
+
62
+ ```
63
+ <name>/
64
+ SKILL.md # 主文档(必须)
65
+ 其他文件 # 仅在需要时
66
+ ```
67
+
68
+ **分出去的只有两种:** ① 重型参考(100+ 行:完整 API、完整语法)② 可复用工具(脚本、模板)。**留在正文:** 原则与概念、代码模式(< 50 行)、其余一切。
69
+
70
+ **调用包内脚本要写解释器**:`bash scripts/tool.sh`、`node scripts/tool.js`,不要写裸路径 `scripts/tool.sh` —— 有些插件打包器会剥掉可执行位,裸路径在那里 `Permission denied`。
71
+
72
+ ## 写 SKILL.md 的 description(决定会不会被发现)
73
+
74
+ - `description` **只写什么时候用**(触发条件、症状),**绝不摘要技能的流程**:实测下来,描述里写了流程的技能,agent 会照描述做、跳过正文(描述说"任务间做一次 review",agent 就只做一次,尽管流程图写的是两次)。
75
+ - 以 "Use when" 开头;第三人称(它会被注入 system prompt);具体到症状与场景;铺搜索关键词(报错原文、症状词、工具名、同义词);尽量 < 500 字符。
76
+ - `name` 只用字母、数字、连字符;动名词/主动语态(`creating-skills` 优于 `skill-creation`);别叫 Helper / Utils / Tools。
77
+ - 正文 < 500 行,超了拆文件(渐进披露:SKILL.md 当目录);**引用只许一层深**(SKILL.md 直接指到参考文件,别再嵌套引用 —— 嵌套引用会被半读);100 行以上的参考文件顶部放目录。
78
+ - 全文术语一致(同一个东西别换着叫);路径一律正斜杠;避免时效性信息(旧做法收进 "old patterns" 折叠区)。
79
+ - 引用别的技能只写技能名 + 明确的强弱标记(`**REQUIRED BACKGROUND:**` / `**REQUIRED SUB-SKILL:**`),不要写会整份加载的 `@路径` 链接。
80
+
81
+ ## 铁律(同 TDD)
82
+
83
+ ```
84
+ NO SKILL WITHOUT A FAILING TEST FIRST
85
+ ```
86
+
87
+ 新技能和**改动**既有技能都算。先写技能再测试?删掉重来。没测试就改?同样违规。
88
+
89
+ **没有例外:** 不为"简单补充"开口子 / 不为"只是加一节"开口子 / 不为"文档更新"开口子 / 不许把没测过的改动留作"参考" / 不许边跑测试边"顺手调整" / 删就是删。
90
+
91
+ **REQUIRED BACKGROUND:** 为什么这么重要见 `smart-tdd`;文档和代码同理。
92
+
93
+ ## RED-GREEN-REFACTOR for Skills
94
+
95
+ 工具面(DSH):压力场景用 `subagent` 派全新上下文的子代理;技能文档用 `write` / `edit` 写、`read` 复核;用 `grep` / `glob` 查关键词覆盖与文件结构;用 `bash` 跑 `wc -l`、渲染流程图等。
96
+
97
+ ### RED:写失败的测试(基线)
98
+
99
+ 不给技能,用 `subagent` 跑压力场景,记录原文:
100
+ - 它做了什么选择?
101
+ - 它用了什么借口(**逐字记下**)?
102
+ - 哪种压力触发了违规?
103
+
104
+ 这就是"看着测试失败":写技能之前必须先看到 agent 自然会怎么做。
105
+
106
+ **压力场景怎么写:**
107
+ - 坏(没压力):"你要实现一个功能,技能怎么说?" —— 太学术,agent 只会背诵技能。
108
+ - 好(3+ 种压力叠加):具体时间、真实后果、真实文件路径、强制 A/B/C 选择、问"你怎么做?"而不是"你该怎么做?"、不许它用"我会先问用户"脱身、开头声明"这是真实场景,必须选择并行动"。
109
+ - 压力类型:时间 / 沉没成本 / 权威 / 经济 / 疲惫 / 社交(显得教条)/ "务实 vs 教条"。最佳测试叠加 3 种以上。
110
+
111
+ ### GREEN:写最小的技能
112
+
113
+ 只针对 RED 里记录到的具体失败写,不为假想情况加内容。同样场景带上技能再跑,agent 应当遵守。仍失败 = 技能写得不清或不全,改了再测。
114
+
115
+ ### REFACTOR:堵漏洞
116
+
117
+ agent 带着技能还违规?像测试回归一样处理:新借口逐字记下 → 加显式反制 → 重测,直到无懈可击。
118
+
119
+ **堵漏四件套:** ① 规则里显式封死具体逃路("写码在测试前?删掉重来。**没有例外:** 不许留作参考 / 不许边测边改 / 删就是删")② 合理化表加一行 ③ Warning Signs 加一条 ④ `description` 补上"快要违规时的症状"。
120
+
121
+ ### 先微测措辞,再跑完整场景
122
+
123
+ 完整压力场景是终检,但每次迭代太贵。先用微测试验证**措辞本身**:
124
+
125
+ 1. **每次调用一个全新上下文样本**(单发 `subagent`):system prompt = 技能真实语境(整份技能,不是孤立那段指导),user message = 一个诱惑它犯错的任务。
126
+ 2. **必须有无指导对照组。** 对照组不出这个毛病,就别写这段指导 —— 停手。
127
+ 3. **每个变体 5+ 次重复。** 单次样本会撒谎。
128
+ 4. **每条命中都要人读。** 模板回显、被引用的反例都会伪装成命中;自动计数会同时高估失败和成功。
129
+ 5. **方差本身是指标。** 指导生效时重复收敛到同一形状;5 次 5 种解读 = 措辞没约束力,先收紧形态再加字。
130
+
131
+ 微测试只验证措辞;纪律类技能仍要跑压力场景。
132
+
133
+ ### GREEN 不生效时:元测试
134
+
135
+ agent 选错了?问它:"你读了技能还是选了 C。这个技能该怎么写才能让你清楚只有 A 可选?"三种回答三种修法:**"技能很清楚,我无视了它"** → 不是文档问题,加基础原则("违反字面就是违反精神");**"技能该写上 X"** → 文档问题,照它说的逐字加;**"我没看到 Y 节"** → 组织问题,关键点提前、更醒目。
136
+
137
+ **无懈可击的标志:** 最大压力下选对 / 引用技能章节作理由 / 承认诱惑但照做 / 元测试答"技能很清楚,我该照做"。**还没到:** 找到新借口 / 辩称技能错了 / 造"折中方案" / 请求许可并强烈主张违规。
138
+
139
+ ## Testing All Skill Types(按类型测)
140
+
141
+ | 类型 | 怎么测 | 成功标准 |
142
+ |---|---|---|
143
+ | **Discipline-Enforcing**(规则/要求,如 TDD) | 学术提问 + 压力场景 + 多重压力叠加;找出借口逐条反制 | 最大压力下仍守规则 |
144
+ | **Technique**(操作指南) | 应用场景 + 变化场景 + 缺信息测试 | 能把技巧用到新场景 |
145
+ | **Pattern**(心智模型) | 识别场景 + 应用场景 + 反例 | 知道何时用、何时不用 |
146
+ | **Reference**(文档/API) | 检索场景 + 应用场景 + 缺口测试 | 找得到且用得对 |
147
+
148
+ 纯参考技能、没有可违反规则的技能不用压力测试(测检索即可)。
149
+
150
+ ## Match the Form to the Failure(形态匹配失败)
151
+
152
+ 写指导前先给基线失败分类。**一种形态能防住的失败,换一种形态会适得其反:**
153
+
154
+ | 基线失败 | 对的形态 | 错的形态 |
155
+ |---|---|---|
156
+ | 压力下明知故犯(知道规则却违反) | 禁令 + 合理化表 + Warning Signs | 软指导("优先…""建议…") |
157
+ | 合规但输出形状不对(prompt 臃肿、结论埋底、复述 spec) | 正面配方/契约:说清输出**是什么**、部件、顺序 | 禁令清单("别复述""绝不旁白") |
158
+ | 已产出的东西里漏了必备项 | 结构性的:模板里的 REQUIRED 字段/槽位 | 模板附近的散文提醒 |
159
+ | 行为该看条件 | 挂在可观察判据上的条件("如果 brief 存在,就引用它") | 无条件规则 + 豁免从句 |
160
+
161
+ **为什么禁令在塑形问题上会翻车:** 在竞争性激励下("让 prompt 自足"),agent 会跟"不要 X"讨价还价。措辞对照测试里,禁令组产出的坏内容比配方组更多,甚至比无指导对照组还差 —— 自己微测你的个案,但别默认抓禁令。配方没有可谈判的余地:输出对上形状就是对上,没对上就是没对上。
162
+
163
+ **两条铁则:** **不写"除非"从句**("不要 X,除非很重要"会重新打开谈判;给赢面的配方追加一个除非从句,就从一致变噪声。真有例外,写成挂在可观察判据上的独立条件);**豁免从句不生效**("代码块除外"照样压制代码块 —— 要豁免的部分重构到规则够不着的地方)。
164
+
165
+ ## Bulletproofing Against Rationalization(防合理化)
166
+
167
+ 基线失败是纪律失败(明知规则却在压力下跳过)时,用这套关漏洞:
168
+
169
+ - **显式关死每个逃路**:不只写规则,点名禁止具体变通("留作参考""边测边改""我只是看看")。
170
+ - **斩断"精神 vs 字面"**:早处放一句 **Violating the letter of the rules is violating the spirit of the rules.**(违反字面就是违反精神。)—— 一刀砍掉整类"我守的是精神"的借口。
171
+ - **合理化表**:基线测试里 agent 用过的每个借口都进表(见下节)。
172
+ - **Warning Signs(红旗清单)**:让 agent 能自检"正在合理化"的瞬间(见反模式节)。
173
+ - **说服原理有实验依据**:权威("MUST / 无例外")、承诺(公开声明、强制选择)、稀缺("在做 X 之前立刻")、社会认同("每次都…")等原则实测把遵守率从约 33% 提到约 72%(Meincke et al., 2025,N=28,000)。用它们保证关键实践在压力下被遵守,不是用来操纵。
174
+
175
+ ## Common Rationalizations(常见合理化借口)
176
+
177
+ | Excuse | Reality |
178
+ |--------|---------|
179
+ | "这技能显然很清楚" | 你清楚 ≠ 别的 agent 清楚。测它。 |
180
+ | "这只是参考文档" | 参考文档也有缺口、有含糊段落。测检索。 |
181
+ | "测试是小题大做" | 没测过的技能必有问题,每次都这样。测 15 分钟省后面几小时。 |
182
+ | "出了问题我再测" | "出问题" = agent 用不了这个技能。部署**前**测。 |
183
+ | "测试太麻烦" | 比在生产里调试一个坏技能省事。 |
184
+ | "我有信心它没问题" | 过度自信必然出问题。照测。 |
185
+ | "审一遍就够了" | 读 ≠ 用。测应用场景。 |
186
+ | "没时间测" | 部署没测过的技能,后面修它花的时间更多。 |
187
+ | "先写技能再补测试" | 你测的是**你以为**要防的东西,不是真要防的东西。删掉重来。 |
188
+ | "写完再测也一样" | 事后测试 = "这在干什么?"事前测试 = "它该干什么?" |
189
+
190
+ **以上每一条的意思都是:部署前测完,没有例外。**
191
+
192
+ ## Anti-Patterns(反模式 / Warning Signs)
193
+
194
+ - ❌ **叙事例**:"2025-10-03 那次会话里,我们发现空 projectDir 导致……" —— 太具体,不可复用。
195
+ - ❌ **多语言稀释**:example-js.js / example-py.py / example-go.go —— 质量平庸、维护负担。**一个优秀例子胜过多个平庸例子**;你很擅长移植,一种语言就够。
196
+ - ❌ **流程图里写代码**:`step1 [label="import fs"]` —— 没法复制,难读。
197
+ - ❌ **无语义标签**:helper1、step2、pattern4。
198
+ - ❌ **Warning Signs 触发却不回头**:先写技能后补基线 / 只跑了学术测试 / 单压力场景 / 只记"agent 错了"没记原话 / 加的是"别作弊"这种空泛反制 / 第一次通过就收工。
199
+ - ❌ **批量产技能**:写完一个必须停下走完部署清单,不许测试留到"批量一起测"。部署没测过的技能 = 部署没测过的代码。
200
+
201
+ ## Skill Creation Checklist(TDD 适配)
202
+
203
+ **每一条建一个 todo。**
204
+
205
+ **RED:**
206
+ - [ ] 写压力场景(纪律类技能 3+ 种压力叠加)
207
+ - [ ] 不带技能跑场景,逐字记录基线行为与借口
208
+ - [ ] 归纳失败/借口模式,找出有效的压力
209
+
210
+ **GREEN:**
211
+ - [ ] `name` 只用字母/数字/连字符;frontmatter 只带 `name` + `description`(≤1024 字符)
212
+ - [ ] `description` 以 "Use when" 开头、第三人称、只写触发条件、不摘要流程
213
+ - [ ] 全文铺搜索关键词(报错、症状、工具名)
214
+ - [ ] 有总览与核心原则;逐条对上 RED 的具体失败
215
+ - [ ] 指导形态匹配失败类型;行为塑造类措辞做过微测(纯参考技能 N/A)
216
+ - [ ] 代码内联或链到独立文件;一个优秀例子(不搞多语言)
217
+ - [ ] 带技能跑同样场景,验证 agent 遵守
218
+
219
+ **REFACTOR:**
220
+ - [ ] 从测试里抓出**新**借口,逐条加显式反制
221
+ - [ ] 合理化表、Warning Signs 汇总所有轮次
222
+ - [ ] `description` 补"快要违规的症状"
223
+ - [ ] 重测直到无懈可击,元测试确认是"清楚但被无视"还是文档问题
224
+
225
+ **质量检查:**
226
+ - [ ] 流程图只在决策不显然时用;有速查表;有常见错误节;无叙事
227
+ - [ ] 配套文件只为工具或重型参考
228
+
229
+ ## 写技能的通用做法(官方最佳实践摘要)
230
+
231
+ > 摘要自源技能的 references/anthropic-best-practices.md,内容进正文,不落独立文件。
232
+
233
+ - **简洁为王**:上下文窗口是公共品。默认假设 agent 已经很聪明,只加它没有的信息;每一段都过"这段值它的 token 吗"。
234
+ - **自由度匹配脆弱性**:多种路都对 → 文字指导(高自由);有偏好模式 → 伪代码/带参脚本(中);脆弱、必须按固定顺序 → 钉死的脚本(低)。"窄桥两侧是悬崖"给护栏,"旷野无险"给方向。
235
+ - **不同档位的模型各测一遍**:快而省的档位看指导够不够、均衡档位看是否清晰高效、最强档位看是否过度解释。给最强模型刚好的量,弱一点的档位会不够用。
236
+ - **渐进披露**:SKILL.md 当目录;正文 < 500 行,超了拆文件;引用一层深;长参考文件加目录。
237
+ - **复杂流程给可勾选清单**,别让 agent 跳过关键校验步;**反馈环**(跑校验 → 修错 → 重来)显著提升质量。
238
+ - **先建评测再写文档**:没有技能跑代表性任务找差距 → 建 3 个评测场景 → 量基线 → 写最小指令 → 迭代。这就是本文的 RED。
239
+ - **用 agent 迭代技能**:Agent A(帮你写/改技能)↔ Agent B(带技能干真活),把 B 的真实表现带回 A 改。观察 agent 怎么**导航**你的技能:意外的读取顺序 = 结构不直觉;从不读某文件 = 该删或该加强信号。
240
+ - **可执行脚本**:solve, don't punt —— 处理错误并给替代,别把异常原样抛给 agent;别留魔法常数(每个值写清理由);写清是"执行"还是"当参考读";别假设依赖已装(写出安装命令)。
241
+ - **反模式**:Windows 反斜杠路径;一次给 5 个库(给默认 + 逃生口);时效性信息(写进 old patterns 折叠区);同一个概念换着叫。
242
+
243
+ ## Flowcharts(流程图)
244
+
245
+ 流程图**只**用于:不显然的决策点 / 可能提前停下的循环 / "A 还是 B"的取舍。
246
+ **绝不**用于:参考资料(用表格)/ 代码示例(用 markdown 块)/ 线性步骤(用编号列表)/ 无语义标签。
247
+
248
+ 给用户渲图(抽出 SKILL.md 里语言标记为 `dot` 的围栏块,交给 graphviz 渲成 SVG;需要 graphviz):
249
+
250
+ ```bash
251
+ node scripts/render-graphs.js <技能目录> # 每张图单独渲
252
+ node scripts/render-graphs.js <技能目录> --combine # 全部合成一张
253
+ ```
254
+
255
+ 精简实现(源技能 render-graphs.js 的核心,可直接落成脚本;`--combine` 等完整版在同一脚本里):
256
+
257
+ ```js
258
+ // 从 SKILL.md 抽出 dot 围栏块,逐块交给 graphviz 渲成 SVG
259
+ import fs from 'node:fs';
260
+ import path from 'node:path';
261
+ import { execFileSync } from 'node:child_process';
262
+ const dir = path.resolve(process.argv[2]);
263
+ const md = fs.readFileSync(path.join(dir, 'SKILL.md'), 'utf-8');
264
+ const blocks = [...md.matchAll(/`{3}dot\n([\s\S]*?)`{3}/g)].map(m => m[1].trim());
265
+ if (!blocks.length) { console.log('no dot blocks'); process.exit(0); }
266
+ fs.mkdirSync(path.join(dir, 'diagrams'), { recursive: true });
267
+ for (const [i, dot] of blocks.entries()) {
268
+ const name = (dot.match(/digraph\s+(\w+)/) || [, `graph_${i + 1}`])[1];
269
+ const svg = execFileSync('dot', ['-Tsvg'], { input: dot, maxBuffer: 10 * 1024 * 1024 });
270
+ fs.writeFileSync(path.join(dir, 'diagrams', `${name}.svg`), svg);
271
+ console.log(`rendered ${name}.svg`);
272
+ }
273
+ ```
274
+
275
+ ## 与 smart 工作流的关系
276
+
277
+ 写技能本身不需要开 smart 任务。若你要交付一个带测试、要人验收的技能包,那才用 `smart_begin({ size: 'light' })`。
@@ -0,0 +1,12 @@
1
+ # @dsh-fly/dsh-plugin-fly-smart 的**宿主层**声明:只有 Fly 工作台那一页。
2
+ #
3
+ # **行名必须是包名本身**(读码:`dsh-client-modules/lib/index.js:82` 的 `exactPackageSpecifier()` ——
4
+ # 非 scoped 名不许带 `/`;scoped 名 `@scope/name` 必须**恰好两段** ⇒ `@a/b/tools` 这种子路径行
5
+ # 返回 undefined、客户端半边不登记、面板在浏览器里根本不出现)。
6
+ # 所以本包的**裸名 = 宿主平面的面板**(这一行),agent 平面的工具挪到包内子路径
7
+ # `tools/index.js`,由 preset 按会话挂载 —— 这样两条纪律同时满足:
8
+ # ① bundle patch 里**没有** `inject: ['tools']` 的行(宿主不会在开机激活工具插件);
9
+ # ② 面板这一行是裸名 ⇒ 它的客户端半边登记得上。
10
+ - insert:
11
+ - id: fly-smart-panel
12
+ name: '@dsh-fly/dsh-plugin-fly-smart'