dsh-gate-agent 0.1.1 → 0.1.2
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.
- package/README.md +315 -285
- package/cordis.patch.yml +144 -144
- package/icon.svg +4 -4
- package/launchers/verify-notes.mjs +20 -20
- package/launchers/verify-notes.yml +34 -34
- package/locale/en.json +6 -6
- package/locale/zh.json +6 -6
- package/package.json +34 -34
- package/skills/gate-code-review/SKILL.md +2 -2
- package/skills/gate-code-review/assets/worker-briefs/gate-implement-review.md +17 -17
- package/skills/gate-domain-modeling/CONTEXT-FORMAT.md +3 -3
- package/skills/gate-domain-modeling/GLOSSARY-FORMAT.md +3 -3
- package/skills/gate-fix-bug/assets/worker-briefs/fix-bug-review.md +20 -20
- package/skills/gate-fix-bug/assets/worker-briefs/gate-fix-bug.md +30 -30
- package/skills/gate-implement/SKILL.md +78 -78
- package/skills/gate-implement/assets/worker-briefs/gate-enter-implement.md +22 -22
- package/skills/gate-plan-review/assets/worker-briefs/plan-review.md +17 -17
- package/skills/gate-planning/assets/worker-briefs/gate-enter-plan.md +24 -24
- package/skills/gate-planning/proposal.md +49 -49
- package/skills/gate-user-verify/assets/worker-briefs/gate-code-verify.md +32 -32
- package/skills/gate-verify/SKILL.md +71 -71
- package/skills/gate-verify/assets/worker-briefs/gate-verify.md +21 -21
- package/skills/gate-write-agent-notes/SKILL.md +1 -1
- package/skills/gate-write-agent-notes/scripts/verify-agent-note-lifecycle.ts +74 -74
- package/skills/gate-writing-for-agents/SKILL-MECHANICS.md +4 -4
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: gate-verify
|
|
3
|
-
description: Gate 验收方法:主 agent 读取后提炼并派发;worker 不加载技能。
|
|
4
|
-
user-invocable: false
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Main agent use
|
|
8
|
-
|
|
9
|
-
主 agent 在派发前自行读取本方法,给 verify worker:工作项、验收条件、受保护基线和验证规则。worker 不应加载本技能或其他 gate 方法文件。
|
|
10
|
-
|
|
11
|
-
任务模板:本技能 `assets/worker-briefs/gate-verify.md`。
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
## 验收
|
|
16
|
-
|
|
17
|
-
用证据确认授权工作满足其权威合同,完成工程闭环。验收包含授权范围内的修正与再验证。
|
|
18
|
-
|
|
19
|
-
## 1. 建立验收合同与覆盖
|
|
20
|
-
|
|
21
|
-
确定工作项及其批准要求、验收条件、设计约束和兼容性预期。验收对象是实现,不能把实现当作期望行为的来源。验证保持在已同意合同内。
|
|
22
|
-
|
|
23
|
-
对每个必需验收条件,选择能证明它的最高稳定边界,例如用户可见行为、公开 API/CLI、集成或领域边界。使用最小充分检查;更低层测试、构建和静态检查可在适当处支持证据。
|
|
24
|
-
|
|
25
|
-
已有检查能证明合同时复用。测试通过、CI 或 code review 本身不等于验收通过;不要因为检查存在就运行。
|
|
26
|
-
|
|
27
|
-
## 2. 执行验证
|
|
28
|
-
|
|
29
|
-
条件允许时实际执行交付行为。逐项记录必需条件、证据和当前结果:
|
|
30
|
-
|
|
31
|
-
- **PASS**:证据证明必需行为;
|
|
32
|
-
- **FAIL**:观察行为与必需行为矛盾;
|
|
33
|
-
- **BLOCKED**:歧义或可靠证据不足,无法判定。
|
|
34
|
-
|
|
35
|
-
没有观察到失败不等于 PASS。发现失败或 blocker 后仍继续检查相互独立的条件。改动可能影响既有相邻行为时,按影响和风险比例做回归检查。
|
|
36
|
-
|
|
37
|
-
## 3. 诊断失败并交回
|
|
38
|
-
|
|
39
|
-
对每个失败,确定合同期望、触发条件、观察行为和支撑证据。改变任何东西前确认原因和属主;未解决原因要明确记录,不能猜:
|
|
40
|
-
|
|
41
|
-
- **实现缺陷**:报告给 implement worker;不要在这里修。
|
|
42
|
-
- **验证缺陷**:把错误检查报告给 gate;不要在这里改检查。
|
|
43
|
-
- **合同歧义或缺陷**:停止受影响验证并报告;gate 把合同退回 planning。
|
|
44
|
-
- **环境或工具失败**:报告什么阻止继续验证,以及是否在范围内。
|
|
45
|
-
- **既有失败**:记录其对验收的影响和属主;不要自动扩大修复范围,也不要忽略它阻止通过的必需条件。
|
|
46
|
-
|
|
47
|
-
已证明的合同违反即使根因未解决也保持 FAIL。
|
|
48
|
-
|
|
49
|
-
gate 把修正路由给属主 worker,然后再次验证。授权合同变更改变验收基线时,重做 §1。
|
|
50
|
-
|
|
51
|
-
不要为了通过验证而削弱已同意合同。
|
|
52
|
-
|
|
53
|
-
## 4. 最终结果与完成
|
|
54
|
-
|
|
55
|
-
先给最终验收结果,再按影响排序未解决失败和 blocker。随后给每个必需条件的简洁覆盖和证据、已完成修正及再验证证据、相关回归结果、实质验证缺口或残余风险。阻止可靠判定的缺口必须反映到对应条件的 BLOCKED。
|
|
56
|
-
|
|
57
|
-
报告最新已验证状态:修正后通过再验证的条件为 PASS,并把它此前的失败概括为已完成修正。未解决事项按影响排序,写明合同引用、期望与观察行为、原因或不确定性、所需下一步。
|
|
58
|
-
|
|
59
|
-
按当前必需条件确定总体结果:
|
|
60
|
-
|
|
61
|
-
- **PASS**:每个必需条件都通过;
|
|
62
|
-
- **FAIL**:任一必需条件仍失败,即使其他条件 blocked;
|
|
63
|
-
- **BLOCKED**:没有失败,但一项或多项无法可靠验证。
|
|
64
|
-
|
|
65
|
-
### 完成
|
|
66
|
-
|
|
67
|
-
报告 PASS/FAIL/BLOCKED 和证据。不要更新工作项、转换决策记录或完成 gate;这些由 gate 接受报告后处理。
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
1
|
+
---
|
|
2
|
+
name: gate-verify
|
|
3
|
+
description: Gate 验收方法:主 agent 读取后提炼并派发;worker 不加载技能。
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Main agent use
|
|
8
|
+
|
|
9
|
+
主 agent 在派发前自行读取本方法,给 verify worker:工作项、验收条件、受保护基线和验证规则。worker 不应加载本技能或其他 gate 方法文件。
|
|
10
|
+
|
|
11
|
+
任务模板:本技能 `assets/worker-briefs/gate-verify.md`。
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## 验收
|
|
16
|
+
|
|
17
|
+
用证据确认授权工作满足其权威合同,完成工程闭环。验收包含授权范围内的修正与再验证。
|
|
18
|
+
|
|
19
|
+
## 1. 建立验收合同与覆盖
|
|
20
|
+
|
|
21
|
+
确定工作项及其批准要求、验收条件、设计约束和兼容性预期。验收对象是实现,不能把实现当作期望行为的来源。验证保持在已同意合同内。
|
|
22
|
+
|
|
23
|
+
对每个必需验收条件,选择能证明它的最高稳定边界,例如用户可见行为、公开 API/CLI、集成或领域边界。使用最小充分检查;更低层测试、构建和静态检查可在适当处支持证据。
|
|
24
|
+
|
|
25
|
+
已有检查能证明合同时复用。测试通过、CI 或 code review 本身不等于验收通过;不要因为检查存在就运行。
|
|
26
|
+
|
|
27
|
+
## 2. 执行验证
|
|
28
|
+
|
|
29
|
+
条件允许时实际执行交付行为。逐项记录必需条件、证据和当前结果:
|
|
30
|
+
|
|
31
|
+
- **PASS**:证据证明必需行为;
|
|
32
|
+
- **FAIL**:观察行为与必需行为矛盾;
|
|
33
|
+
- **BLOCKED**:歧义或可靠证据不足,无法判定。
|
|
34
|
+
|
|
35
|
+
没有观察到失败不等于 PASS。发现失败或 blocker 后仍继续检查相互独立的条件。改动可能影响既有相邻行为时,按影响和风险比例做回归检查。
|
|
36
|
+
|
|
37
|
+
## 3. 诊断失败并交回
|
|
38
|
+
|
|
39
|
+
对每个失败,确定合同期望、触发条件、观察行为和支撑证据。改变任何东西前确认原因和属主;未解决原因要明确记录,不能猜:
|
|
40
|
+
|
|
41
|
+
- **实现缺陷**:报告给 implement worker;不要在这里修。
|
|
42
|
+
- **验证缺陷**:把错误检查报告给 gate;不要在这里改检查。
|
|
43
|
+
- **合同歧义或缺陷**:停止受影响验证并报告;gate 把合同退回 planning。
|
|
44
|
+
- **环境或工具失败**:报告什么阻止继续验证,以及是否在范围内。
|
|
45
|
+
- **既有失败**:记录其对验收的影响和属主;不要自动扩大修复范围,也不要忽略它阻止通过的必需条件。
|
|
46
|
+
|
|
47
|
+
已证明的合同违反即使根因未解决也保持 FAIL。
|
|
48
|
+
|
|
49
|
+
gate 把修正路由给属主 worker,然后再次验证。授权合同变更改变验收基线时,重做 §1。
|
|
50
|
+
|
|
51
|
+
不要为了通过验证而削弱已同意合同。
|
|
52
|
+
|
|
53
|
+
## 4. 最终结果与完成
|
|
54
|
+
|
|
55
|
+
先给最终验收结果,再按影响排序未解决失败和 blocker。随后给每个必需条件的简洁覆盖和证据、已完成修正及再验证证据、相关回归结果、实质验证缺口或残余风险。阻止可靠判定的缺口必须反映到对应条件的 BLOCKED。
|
|
56
|
+
|
|
57
|
+
报告最新已验证状态:修正后通过再验证的条件为 PASS,并把它此前的失败概括为已完成修正。未解决事项按影响排序,写明合同引用、期望与观察行为、原因或不确定性、所需下一步。
|
|
58
|
+
|
|
59
|
+
按当前必需条件确定总体结果:
|
|
60
|
+
|
|
61
|
+
- **PASS**:每个必需条件都通过;
|
|
62
|
+
- **FAIL**:任一必需条件仍失败,即使其他条件 blocked;
|
|
63
|
+
- **BLOCKED**:没有失败,但一项或多项无法可靠验证。
|
|
64
|
+
|
|
65
|
+
### 完成
|
|
66
|
+
|
|
67
|
+
报告 PASS/FAIL/BLOCKED 和证据。不要更新工作项、转换决策记录或完成 gate;这些由 gate 接受报告后处理。
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
72
|
|
|
73
73
|
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
# gate-verify worker
|
|
2
|
-
|
|
3
|
-
```markdown
|
|
4
|
-
你是 Gate 的 verify worker。使用 gate-verify 的验收方法确认交付满足权威合同。
|
|
5
|
-
|
|
6
|
-
## 验收对象
|
|
7
|
-
<工作项、交付范围、固定点>
|
|
8
|
-
|
|
9
|
-
## 验收合同
|
|
10
|
-
<需求、验收条件、兼容性/设计约束>
|
|
11
|
-
|
|
12
|
-
## 证据要求
|
|
13
|
-
- 用可观察 seam 验证,不只依赖测试通过。
|
|
14
|
-
- 记录实际执行的命令、证据文件和结果。
|
|
15
|
-
- 无法可靠判断时报告失败或阻塞,不猜 PASS。
|
|
16
|
-
|
|
17
|
-
## 输出
|
|
18
|
-
返回验收结果、失败项、证据、回归检查和剩余风险;同时返回你实际使用的 `call_...` tool result id 列表,供 root 填 `verification.toolResults`。不做无关修复。
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
# gate-verify worker
|
|
2
|
+
|
|
3
|
+
```markdown
|
|
4
|
+
你是 Gate 的 verify worker。使用 gate-verify 的验收方法确认交付满足权威合同。
|
|
5
|
+
|
|
6
|
+
## 验收对象
|
|
7
|
+
<工作项、交付范围、固定点>
|
|
8
|
+
|
|
9
|
+
## 验收合同
|
|
10
|
+
<需求、验收条件、兼容性/设计约束>
|
|
11
|
+
|
|
12
|
+
## 证据要求
|
|
13
|
+
- 用可观察 seam 验证,不只依赖测试通过。
|
|
14
|
+
- 记录实际执行的命令、证据文件和结果。
|
|
15
|
+
- 无法可靠判断时报告失败或阻塞,不猜 PASS。
|
|
16
|
+
|
|
17
|
+
## 输出
|
|
18
|
+
返回验收结果、失败项、证据、回归检查和剩余风险;同时返回你实际使用的 `call_...` tool result id 列表,供 root 填 `verification.toolResults`。不做无关修复。
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
|
|
@@ -160,7 +160,7 @@ Status: <状态>
|
|
|
160
160
|
|
|
161
161
|
这个启动器只调用插件内置脚本,不复制技能。
|
|
162
162
|
|
|
163
|
-
- 计划完成前或提交前,运行 `npm run verify-notes`,检查 tree、format、lifecycle、archived。
|
|
163
|
+
- 计划完成前或提交前,运行 `npm run verify-notes`,检查 tree、format、lifecycle、archived。
|
|
164
164
|
- `/gate-init` 同时生成 `.github/workflows/verify-notes.yml` 和 `.agents/gate/ci/` 校验脚本副本;CI 使用项目内副本,不依赖插件安装路径。
|
|
165
165
|
- gate 会话内也可以用 `/gate-note-verify` 做同样的只读检查。
|
|
166
166
|
- Verify PASS 后由 gate 执行 `gate_note_finalize` → `gate_note_verify` 工具 → `gate_record({node:'note-lifecycle'})`;lifecycle 不要用 npm 代替。
|
|
@@ -1,74 +1,74 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Lifecycle check for Agent Notes: one topic, one active lifecycle.
|
|
3
|
-
*
|
|
4
|
-
* This is the generic part of the rule; it does not read the capability ledger.
|
|
5
|
-
* A project may add a wrapper for product-specific status.
|
|
6
|
-
*/
|
|
7
|
-
import { readdirSync, readFileSync } from 'node:fs'
|
|
8
|
-
import path from 'node:path'
|
|
9
|
-
|
|
10
|
-
const ROOT = process.argv.includes('--root')
|
|
11
|
-
? process.argv[process.argv.indexOf('--root') + 1]
|
|
12
|
-
: process.argv.find(arg => arg.startsWith('--root='))?.slice('--root='.length) ?? '.agents/notes'
|
|
13
|
-
const LIFEcycles = ['proposed', 'implemented', 'rejected']
|
|
14
|
-
const STATUS = { proposed: 'proposed', implemented: 'implemented', rejected: 'rejected' }
|
|
15
|
-
const errors = []
|
|
16
|
-
const byTopic = new Map()
|
|
17
|
-
|
|
18
|
-
function normalize(value) {
|
|
19
|
-
return String(value).toLowerCase().replace(/[^a-z0-9]+/gu, '-').replace(/^-|-$/gu, '')
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function topicOf(file) {
|
|
23
|
-
const base = path.basename(file, '.md')
|
|
24
|
-
return normalize(base.replace(/^\d{4}-\d{2}-\d{2}-/u, '').replace(/-implemented$/u, ''))
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function walk(lifecycle) {
|
|
28
|
-
const dir = path.join(ROOT, lifecycle)
|
|
29
|
-
const files = []
|
|
30
|
-
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
31
|
-
if (entry.isDirectory()) {
|
|
32
|
-
const sub = path.join(dir, entry.name)
|
|
33
|
-
for (const nested of readdirSync(sub, { withFileTypes: true })) {
|
|
34
|
-
if (nested.isFile() && nested.name.endsWith('.md')) files.push(path.join(sub, nested.name))
|
|
35
|
-
}
|
|
36
|
-
} else if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
37
|
-
files.push(path.join(dir, entry.name))
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return files
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
for (const lifecycle of LIFEcycles) {
|
|
44
|
-
for (const file of walk(lifecycle)) {
|
|
45
|
-
const topic = topicOf(file)
|
|
46
|
-
if (topic === '') {
|
|
47
|
-
errors.push(`${file}: 无法从文件名得到 topic`)
|
|
48
|
-
continue
|
|
49
|
-
}
|
|
50
|
-
const status = /^Status:\s*(\S+)/mu.exec(readFileSync(file, 'utf8'))?.[1]
|
|
51
|
-
if (status !== STATUS[lifecycle]) {
|
|
52
|
-
errors.push(`${file}: Status=${String(status)},目录要求 ${STATUS[lifecycle]}`)
|
|
53
|
-
}
|
|
54
|
-
const entry = byTopic.get(topic) ?? []
|
|
55
|
-
entry.push({ lifecycle, file })
|
|
56
|
-
byTopic.set(topic, entry)
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
for (const [topic, entries] of byTopic) {
|
|
61
|
-
if (entries.length > 1) {
|
|
62
|
-
errors.push(`${topic}: 同主题多份(${entries.map(entry => `${entry.lifecycle}:${path.basename(entry.file)}`).join(';')})`)
|
|
63
|
-
}
|
|
64
|
-
const lifecycles = new Set(entries.map(entry => entry.lifecycle))
|
|
65
|
-
if (lifecycles.has('proposed') && lifecycles.has('implemented')) {
|
|
66
|
-
errors.push(`${topic}: proposed 与 implemented 不能并存`)
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (errors.length > 0) {
|
|
71
|
-
for (const error of errors) console.error(`FAIL ${error}`)
|
|
72
|
-
process.exit(1)
|
|
73
|
-
}
|
|
74
|
-
console.log(`ok: ${byTopic.size} note topics, one lifecycle each`)
|
|
1
|
+
/**
|
|
2
|
+
* Lifecycle check for Agent Notes: one topic, one active lifecycle.
|
|
3
|
+
*
|
|
4
|
+
* This is the generic part of the rule; it does not read the capability ledger.
|
|
5
|
+
* A project may add a wrapper for product-specific status.
|
|
6
|
+
*/
|
|
7
|
+
import { readdirSync, readFileSync } from 'node:fs'
|
|
8
|
+
import path from 'node:path'
|
|
9
|
+
|
|
10
|
+
const ROOT = process.argv.includes('--root')
|
|
11
|
+
? process.argv[process.argv.indexOf('--root') + 1]
|
|
12
|
+
: process.argv.find(arg => arg.startsWith('--root='))?.slice('--root='.length) ?? '.agents/notes'
|
|
13
|
+
const LIFEcycles = ['proposed', 'implemented', 'rejected']
|
|
14
|
+
const STATUS = { proposed: 'proposed', implemented: 'implemented', rejected: 'rejected' }
|
|
15
|
+
const errors = []
|
|
16
|
+
const byTopic = new Map()
|
|
17
|
+
|
|
18
|
+
function normalize(value) {
|
|
19
|
+
return String(value).toLowerCase().replace(/[^a-z0-9]+/gu, '-').replace(/^-|-$/gu, '')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function topicOf(file) {
|
|
23
|
+
const base = path.basename(file, '.md')
|
|
24
|
+
return normalize(base.replace(/^\d{4}-\d{2}-\d{2}-/u, '').replace(/-implemented$/u, ''))
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function walk(lifecycle) {
|
|
28
|
+
const dir = path.join(ROOT, lifecycle)
|
|
29
|
+
const files = []
|
|
30
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
31
|
+
if (entry.isDirectory()) {
|
|
32
|
+
const sub = path.join(dir, entry.name)
|
|
33
|
+
for (const nested of readdirSync(sub, { withFileTypes: true })) {
|
|
34
|
+
if (nested.isFile() && nested.name.endsWith('.md')) files.push(path.join(sub, nested.name))
|
|
35
|
+
}
|
|
36
|
+
} else if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
37
|
+
files.push(path.join(dir, entry.name))
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return files
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
for (const lifecycle of LIFEcycles) {
|
|
44
|
+
for (const file of walk(lifecycle)) {
|
|
45
|
+
const topic = topicOf(file)
|
|
46
|
+
if (topic === '') {
|
|
47
|
+
errors.push(`${file}: 无法从文件名得到 topic`)
|
|
48
|
+
continue
|
|
49
|
+
}
|
|
50
|
+
const status = /^Status:\s*(\S+)/mu.exec(readFileSync(file, 'utf8'))?.[1]
|
|
51
|
+
if (status !== STATUS[lifecycle]) {
|
|
52
|
+
errors.push(`${file}: Status=${String(status)},目录要求 ${STATUS[lifecycle]}`)
|
|
53
|
+
}
|
|
54
|
+
const entry = byTopic.get(topic) ?? []
|
|
55
|
+
entry.push({ lifecycle, file })
|
|
56
|
+
byTopic.set(topic, entry)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
for (const [topic, entries] of byTopic) {
|
|
61
|
+
if (entries.length > 1) {
|
|
62
|
+
errors.push(`${topic}: 同主题多份(${entries.map(entry => `${entry.lifecycle}:${path.basename(entry.file)}`).join(';')})`)
|
|
63
|
+
}
|
|
64
|
+
const lifecycles = new Set(entries.map(entry => entry.lifecycle))
|
|
65
|
+
if (lifecycles.has('proposed') && lifecycles.has('implemented')) {
|
|
66
|
+
errors.push(`${topic}: proposed 与 implemented 不能并存`)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (errors.length > 0) {
|
|
71
|
+
for (const error of errors) console.error(`FAIL ${error}`)
|
|
72
|
+
process.exit(1)
|
|
73
|
+
}
|
|
74
|
+
console.log(`ok: ${byTopic.size} note topics, one lifecycle each`)
|
|
@@ -6,12 +6,12 @@ The skill-specific branch of [`gate-writing-for-agents`](SKILL.md): what changes
|
|
|
6
6
|
|
|
7
7
|
Two choices, trading the two loads:
|
|
8
8
|
|
|
9
|
-
- A **model-invoked** skill keeps a `description`, so the agent can fire it autonomously — and other skills can reach it. You can still type its name: model-invocation always _includes_ user reach; a description only ever adds agent discovery, never removes the human's. The description is the skill's top-level context pointer, forced to stay loaded at all times — permanent context load in exchange for discoverability. A model-invoked skill whose content is all reference is also one home for shared reference: another skill can invoke it, so reference needed by several skills lives in one place. Mechanics: omit `policy.allow_implicit_invocation` from `agents/openai.yaml` (or leave it enabled), and write a model-facing description carrying the trigger branches (the pointer-writing rules in `SKILL.md` apply in full).
|
|
10
|
-
- A **user-invoked** skill is not eligible for automatic activation: only the human typing its name can invoke it. It spends cognitive load — you are the index that must remember it exists. Mechanics: set `policy.allow_implicit_invocation: false` in `agents/openai.yaml`; keep the `description` as a concise human-facing summary with trigger lists stripped.
|
|
9
|
+
- A **model-invoked** skill keeps a `description`, so the agent can fire it autonomously — and other skills can reach it. You can still type its name: model-invocation always _includes_ user reach; a description only ever adds agent discovery, never removes the human's. The description is the skill's top-level context pointer, forced to stay loaded at all times — permanent context load in exchange for discoverability. A model-invoked skill whose content is all reference is also one home for shared reference: another skill can invoke it, so reference needed by several skills lives in one place. Mechanics: omit `policy.allow_implicit_invocation` from `agents/openai.yaml` (or leave it enabled), and write a model-facing description carrying the trigger branches (the pointer-writing rules in `SKILL.md` apply in full).
|
|
10
|
+
- A **user-invoked** skill is not eligible for automatic activation: only the human typing its name can invoke it. It spends cognitive load — you are the index that must remember it exists. Mechanics: set `policy.allow_implicit_invocation: false` in `agents/openai.yaml`; keep the `description` as a concise human-facing summary with trigger lists stripped.
|
|
11
11
|
|
|
12
12
|
Pick model-invocation only when the agent must reach the skill on its own, or another skill must. If it only ever fires by hand, make it user-invoked and pay no context load.
|
|
13
13
|
|
|
14
|
-
Shared reference that two user-invoked skills both need can live in neither because neither is eligible for automatic activation. Push it to a plain file outside the skill system: external reference any skill can point at.
|
|
14
|
+
Shared reference that two user-invoked skills both need can live in neither because neither is eligible for automatic activation. Push it to a plain file outside the skill system: external reference any skill can point at.
|
|
15
15
|
|
|
16
16
|
## Splitting by invocation
|
|
17
17
|
|
|
@@ -19,6 +19,6 @@ The invocation cut of splitting (the sequence cut lives in `SKILL.md`): split of
|
|
|
19
19
|
|
|
20
20
|
## Router skills
|
|
21
21
|
|
|
22
|
-
When user-invoked skills multiply past what you can remember, that piled-up cognitive load is cured by a **router skill**: one user-invoked skill that names the others and when to reach for each, so the human has one skill to remember instead of many. It can only hint, never fire them: user-invoked skills are not eligible for automatic activation, so nothing but the human can reach them.
|
|
22
|
+
When user-invoked skills multiply past what you can remember, that piled-up cognitive load is cured by a **router skill**: one user-invoked skill that names the others and when to reach for each, so the human has one skill to remember instead of many. It can only hint, never fire them: user-invoked skills are not eligible for automatic activation, so nothing but the human can reach them.
|
|
23
23
|
|
|
24
24
|
|