@haaaiawd/loom 1.1.0 → 1.2.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.2.1 — 2026-07-31
4
+
5
+ ### Fixed
6
+
7
+ - `verify pass` 现在要求声明独立 Keeper 或人类复核来源,并将该来源写入验证记录;普通自检不能再被快捷命令包装成 `passed`。
8
+ - 高影响 capability 若选择 `adaptive`,必须留下为何不启用外部获取强门的理由;无理由的 `adaptive` 不再是静默绕过路径。
9
+ - Intent 模板不再默认引用不存在的质量契约章节,并增加叙事语义守恒与反例验证的提示。
10
+
11
+ ### Compatibility
12
+
13
+ - 旧版结构化验证记录仍可读取;新的 passed 记录(包括 `verify write`)必须声明验证来源。旧记录可供历史追溯,但不自动获得独立验证声明。
14
+
15
+ ## 1.2.0 — 2026-07-31
16
+
17
+ ### Added
18
+
19
+ - External Acquisition Gate:Capability Graph 只声明 `acquisition_mode`,Forge 按当前
20
+ Intent 信号派生 Search Plan,并实际通过 Skill registry、网络、官方文档或研究资料获取信息。
21
+ - revision-scoped Expertise Pack 与 `loom expertise init|get|validate`,以来源、检索证据和
22
+ Capability Capsules 形成类似 Skill 的项目化核心信息组,但不复制或内置第三方内容。
23
+ - `guide`、Forge/Keeper activation、`verify pass`、`intent done` 与 `doctor` 的外部能力
24
+ 获取强门;passed 记录绑定当前 Pack 内容摘要,Keeper 必须独立重开关键来源。
25
+
26
+ ### Compatibility
27
+
28
+ - 中低影响 capability 默认为 `adaptive`;高影响 capability 未显式豁免时,以及任意 capability
29
+ 显式声明 `external_required` 时启用持久化强门。
30
+ - `project_only` 保留内部协议与机械任务路径,但必须说明 `acquisition_rationale`。
31
+
3
32
  ## 1.1.0 — 2026-07-30
4
33
 
5
34
  ### Added
@@ -0,0 +1,143 @@
1
+ # External Acquisition Gate — 来源化能力网络设计
2
+
3
+ > 状态:Implemented
4
+ > 目标:阻止 AI 在专业能力不足时闭门生成,并把真实外部检索编译成当前 Intent 可使用、可追溯、会随 revision 失效的核心信息组。
5
+
6
+ ## 1. 问题
7
+
8
+ LOOM 已经能识别任务需要哪些能力,但“识别能力”不等于“获得能力”。如果 Forge 只根据模型已有知识临时生成一段设计原则,它仍可能做出结构正确、审美普通的结果,并把自洽误当成专业。
9
+
10
+ 本设计把能力链拆成四个不同事实:
11
+
12
+ 1. Capability Graph:项目为什么需要某项能力。
13
+ 2. Search Plan:本轮要用什么问题和关键词去外部寻找。
14
+ 3. Expertise Pack:实际打开来源后,哪些规则、工作流、判断门和失败模式可用于本 Intent。
15
+ 4. Quality Proof:这些判断是否真的让结果胜过基线。
16
+
17
+ Graph 不保存网站、Skill 名称或固定关键词;Pack 不复制第三方 Skill 或网页正文。
18
+
19
+ ## 2. 核心不变量
20
+
21
+ - AI 可以生成检索计划,不能把自己生成的内容登记为外部专业知识。
22
+ - `external_required` 能力必须实际使用 Skill registry、网络、官方文档或研究资料。
23
+ - 搜索结果标题、未打开的摘要、模型记忆和“行业通常如此”都不是来源。
24
+ - 每个 Capability Capsule 必须直接引用至少一个已打开、可回查的外部来源。
25
+ - Pack 绑定 `intent_revision`;Intent 修订后旧 Pack 自动失效。
26
+ - Forge 可以使用 Pack;Keeper 不继承 Forge 的结论,必须重新打开关键来源。
27
+ - 来源化不等于正确。CLI 证明结构与追溯,Keeper 证明来源是否真的支持判断。
28
+
29
+ ## 3. 触发模型
30
+
31
+ Capability 节点可选:
32
+
33
+ ```json
34
+ {
35
+ "acquisition_mode": "adaptive | external_required | project_only",
36
+ "acquisition_rationale": "project_only 时必填"
37
+ }
38
+ ```
39
+
40
+ 有效模式按以下顺序计算:
41
+
42
+ 1. Graph 显式声明的模式优先。
43
+ 2. 未声明时,高影响 capability 自动提升为 `external_required`。
44
+ 3. 中低影响 capability 默认为 `adaptive`。
45
+
46
+ `project_only` 只适合未公开内部协议、纯机械迁移等外部知识不会改变做法的任务,必须说明理由。外部交付依赖与只读研究访问是两件事:允许检索资料,不等于允许把外部服务写进产品架构。
47
+
48
+ ## 4. 运行流程
49
+
50
+ ```text
51
+ Capability Graph
52
+ → compile acquisition requirement
53
+ → derive Search Plan from project signals
54
+ → perform real external retrieval
55
+ → synthesize Capability Capsules
56
+ → validate Expertise Pack
57
+ → Author / Atelier / implementation
58
+ → independent Keeper source check
59
+ → passed record binds current Pack
60
+ ```
61
+
62
+ 搜索词由 Forge 根据以下信号动态派生:
63
+
64
+ - capability question 与 Brief;
65
+ - Intent narrative、quality contract 和 creative scope;
66
+ - 当前媒介、宿主、技术与许可约束;
67
+ - 基线中已经观察到的具体缺口;
68
+ - Authorial Stance 尚未解决的机制问题。
69
+
70
+ 关键词属于本轮工作证据,不回写 Graph。这样 LOOM 不会把“网页设计等于某几个灵感站”固化成框架偏见。
71
+
72
+ ## 5. Expertise Pack
73
+
74
+ 位置:
75
+
76
+ ```text
77
+ .loom/vN/10_EXPERTISE_PACKS/<intent-id>.json
78
+ ```
79
+
80
+ Pack 包含:
81
+
82
+ - `search_plan`:决策问题、项目信号、派生查询、约束和停止条件;
83
+ - `sources`:类型、权威层级、HTTPS 定位、获取时间、选择理由和已打开证据;
84
+ - `capsules`:专业问题、适用时机、规则、工作流、判断门、失败模式、验证信号和来源引用;
85
+ - `required_capability_refs` 与 `intent_revision`;
86
+ - `status: draft | ready | blocked`。
87
+
88
+ Capability Capsule 是“类似 Skill 的核心信息组”,但它有三个刻意限制:
89
+
90
+ 1. 只服务当前 Intent,不假装是通用知识;
91
+ 2. 只保存项目化综合,不复制来源内容;
92
+ 3. 未经多个真实任务和 Quality Proof 支持,不自动晋升为 Skill 或 Doctrine。
93
+
94
+ ## 6. Author 与自我更正
95
+
96
+ 外部获取发生在 Author/Atelier 之前。Authorial Stance 必须建立在已经来源化的机制和项目事实之上,而不是用人格、风格词或模型偏好代替研究。
97
+
98
+ 自我更正分三层:
99
+
100
+ - Capsule 解释错误、来源不支持规则:修正 Pack,重新验证;如果已 passed,必须由 Keeper 重验。
101
+ - 当前构图、措辞、动效或候选选择失效:写入 Atelier `corrections[]`,递增 `stance_revision`。
102
+ - 出现新的用户结果、约束、风险或能力缺口:提交 Capability Graph proposal,由 Architect 裁决。
103
+
104
+ Author 不能修改 Graph 后继续自证,也不能用一次局部修正把任务长期知识化。
105
+
106
+ ## 7. 强门与验证
107
+
108
+ 以下入口共同阻止绕过:
109
+
110
+ - `loom guide`:优先引导创建或补齐 Pack;
111
+ - `loom activate forge --intent <id>`:Pack 未 ready 时显示 OPEN 门,只允许勘察、基线和检索;
112
+ - `loom expertise validate <id>`:检查 revision、真实外部来源、直接引用和 Capsule 完整性;
113
+ - `loom verify pass`:强门未闭合时拒绝 passed,并把当前 Pack 的内容摘要绑定到验证记录;
114
+ - `loom intent done`:拒绝未绑定、内容摘要变化或已经过期的 Pack;
115
+ - `loom doctor`:报告缺失、失效和 passed 绑定漂移;
116
+ - Keeper Context Pack:只给出证据入口,不注入 Forge 的 Capsule 结论。
117
+
118
+ ## 8. 搜索预算与停止条件
119
+
120
+ LOOM 不规定固定网站数量,也不鼓励无限浏览。每个 Search Plan 必须写停止条件。通常在以下条件同时成立时停止:
121
+
122
+ - 每个 required capability 都有直接来源化 Capsule;
123
+ - 来源足以回答当前决策问题,而不只是提供视觉相似物;
124
+ - 已能写出可执行的判断门、失败模式和验证信号;
125
+ - 新来源只重复已有机制,不再改变候选或验证方法。
126
+
127
+ 如果来源互相冲突、关键资料不可访问或许可不清,Pack 应进入 `blocked`,而不是让模型补齐空白。
128
+
129
+ ## 9. 与现有系统的去重
130
+
131
+ - Capability Brief 负责“项目问题与获取边界”;Pack 负责“本轮实际获得了什么”。二者不重复。
132
+ - Authorship 负责“基于材料做什么独特选择”;Pack 负责“选择前有哪些可信材料”。二者不重复。
133
+ - Atelier Record 保存候选与修正;Pack 保存外部能力证据。二者不合并。
134
+ - Quality Proof 证明结果提升;Pack 只证明专业判断有来源。来源不能替代结果。
135
+ - Doctrine 保存长期项目判断;Pack 默认短命。未经重复外部结果支持,不进入 Doctrine。
136
+
137
+ ## 10. 非目标
138
+
139
+ - 不在 LOOM 仓库内安装、镜像或维护第三方 Skill。
140
+ - 不建立固定网站白名单或 UI 专用关键词表。
141
+ - 不声称只要检索就能突破基础模型的所有智能边界。
142
+ - 不用来源数量、星标或流行度替代任务适配性。
143
+ - 不让 CLI 自动编造 Capsule;CLI 只建模、校验、编译和阻断。
package/README.md CHANGED
@@ -29,7 +29,7 @@ LOOM 的核心机制:
29
29
  | **Intent** | 一个意图单元——不是"做什么"(任务),是"为什么做"(意图)。每个 Intent 有验收契约,Keeper 据此判定实现是否忠实 |
30
30
  | **Intent Map** | 所有 Intent 的依赖图(JSON)。Architect 绘制,定义拓扑序和依赖关系 |
31
31
  | **Capability Graph** | 在 Intent 前展开项目问题面、能力缺口、风险和证据;高影响节点必须路由,并回链到 Intent |
32
- | **Expertise Pack** | Forge 针对当前任务临时编译的专业认知,不成为永久规则 |
32
+ | **Expertise Pack** | Forge 通过真实外部检索为当前 Intent 编译的来源化核心信息组;绑定 revision,不成为永久规则 |
33
33
  | **Authorial Stance** | 针对单个 Intent 编译的创作命题、选择、拒绝项、媒介语法和验证视角,不是 Persona 扮演 |
34
34
  | **Atelier Path** | 可选创作深路径:冻结基线、形成机制不同候选、比较或保留原版,并把证据写入唯一 Atelier Record |
35
35
  | **Quality Arena** | 以基线和机制不同候选进行探索、比较、实现与观察 |
@@ -91,7 +91,7 @@ Agent 每完成一步都跑 guide 确认下一步。
91
91
  ### AUTO 模式
92
92
 
93
93
  ```bash
94
- loom auto on # Agent 自动连续执行,不等确认
94
+ loom auto on # Agent 在允许阶段连续推进;不会跳过契约、证据或 Keeper 门禁
95
95
  loom auto off # 每步需要用户确认
96
96
  ```
97
97
 
@@ -229,6 +229,7 @@ Agent 在用户说"看看进度 / 打开 preview / 看全局"时,先跑 `loom
229
229
  | `loom capability graph\|frontier\|get\|coverage\|compile` | 查看能力图谱、未路由前沿、覆盖缺口和当前 Intent 的能力编译输入 |
230
230
  | `loom capability proposal list\|get\|submit\|decide\|close` | 以 provenance 提交新发现,并由 Architect 裁决和闭合 |
231
231
  | `loom asset import\|list\|search\|get\|validate` | 管理带来源、许可、哈希、批准状态与 evidence 回链的本地素材 |
232
+ | `loom expertise init\|get\|validate <id>` | 创建和校验 revision-scoped Search Plan、外部来源与 Capability Capsules |
232
233
  | `loom atelier init\|get\|validate <id>` | 为显式 Atelier Intent 创建、读取和校验创作记录 |
233
234
  | `loom intent deprecate <id> --reason <text>` | 只读评估当前版本弃用影响;加 `--confirm` 并完整分类依赖方后原子写入 |
234
235
  | `loom intent narrative <id>` | Intent 意图叙事 |
@@ -292,6 +293,7 @@ LOOM/
292
293
  ├── CAPABILITY_GRAPH_TEMPLATE.json Capability Graph 起点
293
294
  ├── CAPABILITY_BRIEF_TEMPLATE.md Capability Brief 起点
294
295
  ├── ASSET_LIBRARY_MANIFEST_TEMPLATE.json Asset Library 起点
296
+ ├── EXPERTISE_PACK_TEMPLATE.json 外部能力获取记录起点
295
297
  └── ATELIER_RECORD_TEMPLATE.json Atelier Record 起点
296
298
  ```
297
299
 
@@ -312,6 +314,7 @@ LOOM/
312
314
  | 哲学文档长什么样 | `templates/PHILOSOPHY_TEMPLATE.md` |
313
315
  | 愿景文档长什么样 | `templates/VISION_TEMPLATE.md` |
314
316
  | Capability Graph 与 Brief 长什么样 | `cli/help/capability.md`、`templates/CAPABILITY_GRAPH_TEMPLATE.json` |
317
+ | 为什么必须外部检索、Expertise Pack 怎么闭合 | `cli/help/expertise.md`、`EXTERNAL_ACQUISITION_DESIGN.md` |
315
318
  | Author 与 Atelier 怎么工作 | `cli/help/atelier.md`、`dimensions/AUTHORSHIP.md` |
316
319
  | Intent Map 长什么样 | `templates/INTENT_MAP_TEMPLATE.json` |
317
320
  | 怎么搜索高质量参考 | `dimensions/SEARCH_METHODOLOGY.md` |
package/cli/bin/loom.js CHANGED
@@ -28,6 +28,7 @@ import { compileCapabilityInputs, getCapabilityCoverage, getCapabilityFrontier,
28
28
  import { getAsset, importAsset, listAssets, recoverAssetImportTransaction, searchAssets, validateAssetLibrary } from '../src/asset-library.js';
29
29
  import { closeCapabilityProposal, decideCapabilityProposal, getCapabilityProposal, listCapabilityProposals, submitCapabilityProposal } from '../src/capability-proposals.js';
30
30
  import { getAtelierRecord, initAtelierRecord, validateAtelierRecord } from '../src/atelier.js';
31
+ import { assertExpertiseReady, getExpertisePack, initExpertisePack, validateExpertisePack } from '../src/expertise-pack.js';
31
32
 
32
33
  // ─── 路径解析 ──────────────────────────────────────────
33
34
  // findLoomRoot / findVersionDir / readCurrentPointer 已提取到 shared/paths.js
@@ -184,6 +185,26 @@ try {
184
185
  break;
185
186
  }
186
187
 
188
+ case 'expertise': {
189
+ const versionDir = findVersionDir();
190
+ const intentId = rest[0];
191
+ if (!intentId) die(`用法: loom expertise ${sub || '<init|get|validate>'} <intent-id>`);
192
+ switch (sub) {
193
+ case 'init':
194
+ output(initExpertisePack(versionDir, intentId));
195
+ break;
196
+ case 'get':
197
+ output(getExpertisePack(versionDir, intentId));
198
+ break;
199
+ case 'validate':
200
+ output(validateExpertisePack(versionDir, intentId));
201
+ break;
202
+ default:
203
+ die(`未知 expertise 子命令: ${sub}\n用法: loom expertise [init|get|validate] <intent-id>`);
204
+ }
205
+ break;
206
+ }
207
+
187
208
  case 'intent': {
188
209
  const versionDir = findVersionDir();
189
210
  switch (sub) {
@@ -344,6 +365,14 @@ try {
344
365
  if (!isVerificationCurrent(intent, latest)) {
345
366
  die(`${id} 最新 passed 验证不属于当前 Intent revision ${intent.revision ?? 1}。先重新验证。`);
346
367
  }
368
+ const expertise = assertExpertiseReady(versionDir, id);
369
+ if (expertise && (latest.expertise?.record_ref !== `10_EXPERTISE_PACKS/${id}.json`
370
+ || latest.expertise?.intent_revision !== expertise.intent_revision
371
+ || latest.expertise?.source_count !== expertise.source_count
372
+ || latest.expertise?.capsule_count !== expertise.capsule_count
373
+ || latest.expertise?.pack_digest !== expertise.pack_digest)) {
374
+ die(`${id} 最新 passed 未绑定当前 Expertise Pack。请在新的 Keeper task 中重新打开来源并验证。`);
375
+ }
347
376
  if (intent.quality_strategy === 'atelier') {
348
377
  const atelier = validateAtelierRecord(versionDir, id);
349
378
  if (!['selected', 'baseline_retained'].includes(atelier.status)) {
@@ -563,7 +592,7 @@ try {
563
592
  }
564
593
  case 'pass':
565
594
  case 'fail': {
566
- // loom verify pass <id> --summary "..." [--reproduction-command "..."] [--preservation-evidence "..."] [--quality-proof "..."]
595
+ // loom verify pass <id> --summary "..." --verified-by <id> --verification-context <independent_thread|human_review>
567
596
  // loom verify fail <id> --summary "..." [--deviation "..."] [--reproduction-command "..."]
568
597
  const id = rest[0];
569
598
  if (!id) die(`用法: loom verify ${sub} <id> --summary "..." [--reproduction-command "..."]${sub === 'pass' ? ' [--preservation-evidence "..."] [--quality-proof "..."]' : ' [--deviation "..."]'}`);
@@ -572,6 +601,8 @@ try {
572
601
  const deviationIdx = argv.indexOf('--deviation');
573
602
  const qualityProofIdx = argv.indexOf('--quality-proof');
574
603
  const preservationIdx = argv.indexOf('--preservation-evidence');
604
+ const verifiedByIdx = argv.indexOf('--verified-by');
605
+ const verificationContextIdx = argv.indexOf('--verification-context');
575
606
  const summary = summaryIdx !== -1 ? argv[summaryIdx + 1] : null;
576
607
  if (!summary) die(`缺少 --summary: loom verify ${sub} ${id} --summary "..."`);
577
608
  const intent = getIntent(versionDir, id);
@@ -581,11 +612,15 @@ try {
581
612
  if (sub === 'pass' && intent.quality_contract && !(qualityProofIdx !== -1 && argv[qualityProofIdx + 1])) {
582
613
  die(`Intent ${id} 声明了 quality_contract;通过前必须提供 --quality-proof,指向项目内真实的 Quality Proof Markdown 锚点。`);
583
614
  }
615
+ if (sub === 'pass' && !(verifiedByIdx !== -1 && argv[verifiedByIdx + 1] && verificationContextIdx !== -1 && argv[verificationContextIdx + 1])) {
616
+ die(`Intent ${id} 通过前必须声明独立验证来源:--verified-by <thread/run/人类标识> --verification-context <independent_thread|human_review>。同一会话自检请记录为自检,不得写 passed。`);
617
+ }
584
618
  const extras = {};
585
619
  if (reproIdx !== -1 && argv[reproIdx + 1]) extras.reproduction_command = argv[reproIdx + 1];
586
620
  if (sub === 'fail' && deviationIdx !== -1 && argv[deviationIdx + 1]) extras.deviation_detail = argv[deviationIdx + 1];
587
621
  if (sub === 'pass' && qualityProofIdx !== -1 && argv[qualityProofIdx + 1]) extras.quality_proof_ref = argv[qualityProofIdx + 1];
588
622
  if (sub === 'pass' && preservationIdx !== -1 && argv[preservationIdx + 1]) extras.preservation_evidence = argv[preservationIdx + 1];
623
+ if (sub === 'pass') extras.verification_provenance = { verified_by: argv[verifiedByIdx + 1], context: argv[verificationContextIdx + 1] };
589
624
  const verdict = sub === 'pass' ? 'passed' : 'deviated';
590
625
  const result = createQuickVerification(versionDir, verificationsDir, id, verdict, summary, extras);
591
626
  console.log(`验证记录已写入: ${result.filePath}`);
@@ -930,6 +965,9 @@ To Human:
930
965
  loom capability get <id> 返回节点、关系、Brief 与 Intent 回链
931
966
  loom capability coverage 检查图谱覆盖、Brief 和 Intent 回链
932
967
  loom capability compile <id> 只读显示会进入该 Intent 的能力输入
968
+ loom expertise init <id> 创建当前 Intent 的外部能力获取记录
969
+ loom expertise get <id> 返回并校验当前 Expertise Pack
970
+ loom expertise validate <id> 校验检索、来源、Capsule 与 revision
933
971
  loom atelier init <id> 为 atelier Intent 创建唯一创作记录
934
972
  loom atelier get <id> 返回并校验当前 Atelier Record
935
973
  loom atelier validate <id> 校验 Record、revision、候选与证据引用
@@ -66,3 +66,8 @@ Visionary 给出 outcome、角色、非目标与项目事实。Architect 用项
66
66
  `loom capability compile <intent-id>` 只读显示会进入当前 Intent 的图谱节点与 Brief。Forge 激活
67
67
  Intent 时会获得同一份输入;发现新依赖、风险或能力缺口时必须回流 Architect 更新 Graph,不能静默
68
68
  扩展实现。Keeper 以图谱回链检查高影响问题是否真的被兑现。
69
+
70
+ Capability 节点可选声明 `acquisition_mode: adaptive | external_required | project_only`。
71
+ `project_only` 必须附 `acquisition_rationale`。未声明时,高影响 capability 自动提升为
72
+ `external_required`。Graph 只保存获取必要性,不保存网站、Skill 名称或
73
+ 搜索词;Forge 在本轮 Expertise Pack 中按项目信号派生查询并记录真实来源。
@@ -54,7 +54,10 @@ Forge 针对当前 Intent 临时组装一个 Expertise Pack。先由 Capability
54
54
  6. 如何验证专业质量。
55
55
 
56
56
  能力名称只表示“可发现”;只有真实加载并转化为任务判断的内容才算进入 Expertise Pack。
57
- Pack 仅服务当前任务,不成为长期 Doctrine。
57
+ External Acquisition Gate 为 required 时,Forge 只能自行派生 Search Plan,内容必须来自
58
+ 实际打开的 Skill、网络、官方文档或研究资料;Pack 写入当前 Intent revision 的
59
+ `10_EXPERTISE_PACKS`,每个 Capability Capsule 都直接回链来源。Pack 仅服务当前任务,不成为
60
+ 长期 Doctrine。
58
61
 
59
62
  ## Quality Arena
60
63
 
@@ -49,7 +49,9 @@ loom philosophy check
49
49
  快速命令:
50
50
 
51
51
  ```bash
52
- loom verify pass <id> --summary "<证据>" --quality-proof "<ref>"
52
+ loom verify pass <id> --summary "<证据>" --quality-proof "<ref>" \
53
+ --verified-by "<keeper-thread-or-human>" \
54
+ --verification-context independent_thread
53
55
  ```
54
56
 
55
57
  若只达到完成契约,写 `deviated` 或完整验证记录,不要伪造质量通过。
@@ -0,0 +1,51 @@
1
+ # External Acquisition 与 Expertise Pack
2
+
3
+ LOOM 把“知道任务需要某项能力”和“真正获得了这项能力”分开。Capability Graph 只决定是否
4
+ 需要外部获取;Forge 在当前 Intent 中派生查询、实际检索,再把有来源的核心信息编译成
5
+ Capability Capsules。
6
+
7
+ ```bash
8
+ loom capability compile <intent-id>
9
+ loom expertise init <intent-id>
10
+ # 编辑 .loom/vN/10_EXPERTISE_PACKS/<intent-id>.json,并实际执行检索
11
+ loom expertise validate <intent-id>
12
+ loom activate forge --intent <intent-id>
13
+ ```
14
+
15
+ ## 什么时候强制
16
+
17
+ - capability 显式声明 `acquisition_mode: external_required`;
18
+ - 或高影响 capability 没有显式声明其他模式。
19
+
20
+ 中低影响任务默认为 `adaptive`。高影响任务只有在 Architect 明确写 `adaptive` 时才按证据
21
+ 决定是否检索;仅依赖未公开内部协议、外部知识不会改变做法的机械任务可以用 `project_only`,
22
+ 但必须写 `acquisition_rationale`。
23
+
24
+ ## Search Plan
25
+
26
+ Forge 根据 capability question、Capability Brief、Intent narrative、质量契约、creative
27
+ scope、媒介约束和基线缺口派生查询。关键词是运行时证据,不写回 Graph。
28
+
29
+ 必须实际使用 Skill registry、网络、官方文档或研究资料。模型自行生成的原则、没有打开的
30
+ 搜索摘要和只看标题的结果都不能登记为来源。每个计划必须写停止条件,避免无边界浏览。
31
+
32
+ ## Capability Capsule
33
+
34
+ 每个 required capability 至少有一个 Capsule,包含:
35
+
36
+ - 专业问题与适用时机;
37
+ - 规则和工作流;
38
+ - 决策门与失败模式;
39
+ - 可观察验证信号;
40
+ - 至少一个直接外部来源引用。
41
+
42
+ Pack 只保存项目化综合和定位信息,不复制第三方 Skill 或网页正文,也不会自动变成 Doctrine
43
+ 或通用 Skill。Intent revision 改变后,旧 Pack 自动失效。
44
+
45
+ ## Keeper
46
+
47
+ CLI 能检查 Pack 当前、来源可定位、Capsule 直接引用外部资料,但不能仅凭 JSON 判断来源是否
48
+ 真的支持结论。Keeper 必须在独立 task 中重新打开至少一个关键来源,核对规则与判断门,并让
49
+ `loom verify pass` 将当前 Pack 的内容摘要绑定进验证记录;之后 Pack 内容发生变化必须重验。
50
+
51
+ 更多设计边界见 `EXTERNAL_ACQUISITION_DESIGN.md`。
package/cli/help/loop.md CHANGED
@@ -28,8 +28,10 @@ Forge 先形成任务级 Expertise Pack:
28
28
  - 已实际加载的技能、资料、工具及其用途。
29
29
  - Critic 视角与验证方法。
30
30
 
31
- Pack 是临时认知配置,不写成新的长期规范。明显任务可以很短;高质量任务应足以解释为什么
32
- 某个专业手法适合这个项目。
31
+ Pack 是任务级认知配置,不写成新的长期规范。高影响 capability 默认进入 External Acquisition Gate;若明确选择 `adaptive`,也必须写明为何此处不启用外部获取。Pack
32
+ 必须落盘到 `10_EXPERTISE_PACKS/<intent-id>.json`:Search Plan 可由 AI 派生,但 Capsule 内容
33
+ 必须来自实际打开的外部来源,并写出判断门、失败模式和验证信号。明显的机械任务可以保持
34
+ `adaptive`;高质量任务必须足以解释为什么某个专业手法适合这个项目。
33
35
 
34
36
  ## 3. Quality Arena
35
37
 
@@ -58,6 +60,10 @@ Keeper 独立检查基础四维;有质量契约时增加第五维:
58
60
  "verdict": "passed",
59
61
  "timestamp": "2026-07-28T12:00:00.000Z",
60
62
  "summary": "具体、可定位、可复现的判定摘要",
63
+ "verification_provenance": {
64
+ "verified_by": "keeper thread 或人类复核标识",
65
+ "context": "independent_thread"
66
+ },
61
67
  "reproduction_command": "npm test",
62
68
  "dimensions": {
63
69
  "intent_fidelity": {
@@ -85,6 +91,14 @@ Keeper 独立检查基础四维;有质量契约时增加第五维:
85
91
  }
86
92
  ```
87
93
 
94
+ 快捷写入 `passed` 时,也必须声明这一来源:
95
+
96
+ ```bash
97
+ loom verify pass INT-001 --summary "..." \
98
+ --verified-by "keeper-run-123" \
99
+ --verification-context independent_thread
100
+ ```
101
+
88
102
  若 Intent 声明 `continuity_required: true`,Keeper 还必须写入并通过:
89
103
 
90
104
  ```json
@@ -64,6 +64,16 @@ loom activate keeper --intent <id>
64
64
  Forge 编译 Expertise Pack,在 Quality Arena 中实现与比较。
65
65
  Keeper 从当前磁盘事实和契约独立验证,不继承 Forge 的解释。
66
66
 
67
+ 当 `loom capability compile <id>` 报告 `acquisition.required=true` 时,先运行:
68
+
69
+ ```bash
70
+ loom expertise init <id>
71
+ # 实际执行 find skill / web / official docs / research 检索并填写 Pack
72
+ loom expertise validate <id>
73
+ ```
74
+
75
+ 门未闭合时不能写入 passed。Keeper 会重新打开关键来源,passed 记录绑定当前 Pack。
76
+
67
77
  无质量契约时,四个基础维度通过即可闭合。存在质量契约时,额外验证
68
78
  `quality_achievement`;声明相对提升时,在该维度中链接 Quality Proof:
69
79
 
@@ -10,6 +10,7 @@ import { getVerificationContract } from './verify.js';
10
10
  import { extractMdSection } from './shared/md-utils.js';
11
11
  import { compileCapabilityInputs } from './capability-graph.js';
12
12
  import { getAtelierRecord } from './atelier.js';
13
+ import { formatExpertisePackForPrompt, getExpertisePack, getExpertisePackState } from './expertise-pack.js';
13
14
 
14
15
  const VALID_ROLES = ['weaver', 'visionary', 'architect', 'forge', 'keeper'];
15
16
 
@@ -262,8 +263,9 @@ function compileExpertiseInputs(role, versionDir, objective) {
262
263
  `- quality_strategy: ${qualityStrategy}`,
263
264
  '- Skill、工具和资产名称只代表可发现入口;实际检查并加载后才进入 Expertise Pack。',
264
265
  ];
266
+ let compiled = null;
265
267
  if (versionDir && objective.intent) {
266
- const compiled = compileCapabilityInputs(versionDir, objective.intent.id);
268
+ compiled = compileCapabilityInputs(versionDir, objective.intent.id);
267
269
  if (!compiled.available) {
268
270
  lines.push(`- Capability Graph: ${compiled.warnings.join(' ')}`);
269
271
  } else if (compiled.nodes.length === 0) {
@@ -279,6 +281,40 @@ function compileExpertiseInputs(role, versionDir, objective) {
279
281
  for (const warning of compiled.warnings) lines.push(`- Capability Graph warning: ${warning}`);
280
282
  }
281
283
  }
284
+ if (compiled?.acquisition?.nodes?.length) {
285
+ lines.push('- External acquisition modes:');
286
+ for (const node of compiled.acquisition.nodes) {
287
+ lines.push(` - ${node.node_id}: ${node.mode}(${node.reason})`);
288
+ }
289
+ }
290
+ if (versionDir && objective.intent && ['forge', 'keeper'].includes(role)) {
291
+ const state = getExpertisePackState(versionDir, subject.id);
292
+ if (state.required && !state.ready) {
293
+ lines.push(
294
+ '\n### External Acquisition Gate — OPEN',
295
+ `- required_capabilities: ${state.required_node_ids.join(', ')}`,
296
+ '- 先根据 Capability question、Authorial Stance/creative_scope、媒介约束与已观察缺口派生搜索词;搜索词属于本轮计划,不得写死进 Capability Graph。',
297
+ '- 必须实际使用外部 find skill、网络搜索、官方文档或研究资料获取信息。模型自行生成的常识、内部复述和未打开的搜索结果不能充当来源。',
298
+ `- ${state.reason === 'missing' ? `运行 \`loom expertise init ${subject.id}\`` : `修正 \`10_EXPERTISE_PACKS/${subject.id}.json\``},记录可回查来源与 Capability Capsules,再运行 \`loom expertise validate ${subject.id}\`。`,
299
+ '- 门未闭合时,只能完成机械性勘察、基线冻结与检索;不得声称专业方案已形成,也不得通过验证。',
300
+ );
301
+ } else if (state.required && role === 'forge') {
302
+ const pack = getExpertisePack(versionDir, subject.id);
303
+ lines.push(
304
+ '\n### External Acquisition Gate — READY',
305
+ '- 以下内容是本 Intent revision 的来源化核心信息组。它不是永久 Doctrine,也不是复制进仓库的第三方 Skill。',
306
+ `\n${formatExpertisePackForPrompt(pack)}`,
307
+ );
308
+ } else if (state.required && role === 'keeper') {
309
+ lines.push(
310
+ '\n### External Acquisition Evidence — PRESENT',
311
+ `- record_ref: 10_EXPERTISE_PACKS/${subject.id}.json`,
312
+ `- required_capabilities: ${state.required_node_ids.join(', ')}`,
313
+ `- source_count: ${state.validation.source_count}; capsule_count: ${state.validation.capsule_count}`,
314
+ '- 不继承 Forge 的 Capsule 结论。重新打开至少一个关键来源,检查来源确实支持规则与判断门,并把绑定写入本轮验证记录。',
315
+ );
316
+ }
317
+ }
282
318
  if (role === 'keeper') {
283
319
  lines.push('- 不继承 Forge Expertise Pack;按契约独立准备验证能力。');
284
320
  if (qualityStrategy === 'atelier') {