Selaa lähdekoodia

chore(task): P2 F7 任务工件收口(S0 清单+真宿主 smoke 留档+design+e2e 输出)

- research/opencode-capability-checklist.md:16 条实测全绿 + 证据原文。
- research/opencode-real-smoke.md:OpenCode 1.18.4 真产物四轮 smoke
 (插件注入/skill 发现/两审派发/permission 行为级)+ 诚实边界声明。
- design.md(kimi 代行,逐节证据映射)+ install-e2e-output.txt。
- 父任务 F7 勾选。
lingfengQAQ 2 kuukautta sitten
vanhempi
sitoutus
fc20831696

+ 92 - 0
.trellis/tasks/07-29-p2-opencode-adapter/design.md

@@ -0,0 +1,92 @@
+# 技术设计:OpenCode 宿主适配(F7)
+
+> 定稿依据:`research/opencode-capability-checklist.md`(S0,16 条实测)。设计裁决全部由 kimi 代行(claude token 耗尽,作者授意 2026-07-30);claude 恢复后按该清单复核本文每条→证据映射。
+
+## 1. 总体形状
+
+```
+registry.json(+opencode tier1 条目)
+   ↓ 数据驱动(改动面收敛在三处)
+host-shells/generate.js ──→ dist/opencode/{skills/,agents/,plugins/}(drift check 覆盖)
+installer/shells.js     ──→ .opencode/ 落位(哈希三态沿用,零新机制)
+installer/detect.js     ──→ detect_bin=opencode 直接复用(A1 实测 shim 形态已吞吐)
+```
+
+核心 `src/`(状态机/存储/编排)零改动;改动面=registry + 生成器 + 安装器 + `adapters/opencode/support.md` + 测试。
+
+## 2. registry 条目(S1,全部字段有 S0 证据)
+
+```json
+"opencode": {
+  "tier": 1,
+  "verified": "能力实测通过(2026-07-30,S0 清单全绿),真模型 smoke 推迟 beta",
+  "agentCapable": true,
+  "hasHooks": true,
+  "detect_bin": "opencode",
+  "install_dir": ".opencode",
+  "smoke": "node scripts/smoke.mjs --host opencode",
+  "smoke_status": "deferred-beta"
+}
+```
+
+- `agentCapable: true` ← C1(`mode: subagent` schema 实测)+ C3(新鲜上下文实证)+ C4(并行派发实证)。
+- `hasHooks: true` ← D4(plugin 自动发现 + chat.message 注入 + fail-open 均为本仓库生产 live evidence)。若 S3 实测翻车,诚实降级为 false(不算失败)。
+- `detect_bin` ← A1:PATH 命中 `opencode`(Windows 三 shim `opencode`/`.cmd`/`.ps1` 均无扩展名过滤坑;`findOnPath` 的 stat 判定对无扩展名 shim 先命中 `''` ext 分支,天然兼容)。
+- smoke 行与四宿主同口径(`deferred-beta`)。
+
+## 3. 两审 agent 壳形态(S2,C1/C2 实测 schema)
+
+`generateHostShells` 对 `host === 'opencode'` 走新渲染函数 `roleToOpenCodeMd`(与 codex 的 toml 分形同模式,单 host 单分支不泛化):
+
+```markdown
+---
+name: 事实审查
+description: <roles 单源注入>
+mode: subagent
+permission:
+  edit: deny
+  bash: deny
+  webfetch: deny
+  task: deny
+---
+<body 渲染产物>
+```
+
+- `mode: subagent` ← C1(当前约定,只能被主 agent 经 task 派发;`--agent` 直跑被拒是实测坑,不阻断两审形态)。
+- permission 只写**实测验证过的键**:`edit / bash / webfetch / task` 四 deny。`edit: deny` 已实测连带消除独立 write 工具;不额外写 `write`。
+- **留白说明**:`read/glob/grep` 不写 allow/deny(默认 allow,两审可精读 ReviewInput 所需的只读工具)——这与角色提示词「不读文件」的语义边界一致:读文件兜底可用,写/执行/外联/再派发全封死。`skill` 键未实测(S0 复核备注标注),design 不用。
+- SKILL 条件块:`agentCapable: true` → 独立 subagent 段渲染;`hasHooks: true` → 「SessionStart 已注入」段渲染(与 claude-code 同支路)。
+
+## 4. 会话启动注入(S3,走 plugin 不走路径合并)
+
+新增打包资产 `templates/opencode-session-hook.js`(静态 ESM 插件源),`generateHostShells` 在为 opencode 生成文件集时附加 `plugins/webnovel-session.js`(随生成器进 drift check,确定性同源)。插件形态(失败必 fail-open):
+
+```js
+chat.message: async (input, output) => {
+  // 每 session 只注一次(done Set 按 sessionID)
+  // execFile('node', ['.webnovel/bin/webnovel-writer.js', 'session-context'], { cwd: directory })
+  // 输出 prepend 到首个 text part(持久化进历史,与 Trellis session-start.js 同形)
+  // 全钩 try/catch——脚本缺失/执行失败静默,不阻塞会话
+}
+```
+
+installer 侧:`buildShellFiles` 现有「生成器输出平移进 install_dir」机制自动带上 `plugins/webnovel-session.js`(`.opencode/plugins/` 自动发现,E1 实测**无需任何 JSON 合并**——无 settings.json 类文件,这是 vs claude-code 的结构性简化)。哈希三态/manifest 沿用零改动。`update` 幂等:插件内容随包版本更新(哈希变化→written;用户手改→skipped 并列名)。
+
+安装报告补一条人话提示(buildReport):opencode 在 hosts 时追加「重启 opencode 后生效(skills/agents/plugins 为启动时加载)」——B1 实测加载时机。
+
+## 5. 测试形状(S5)
+
+- generate.test.js +1 用例:opencode SKILL 走 hasHooks/agentCapable 双真支路断言(SessionStart 注入段在、兼容模式段不在);两审 agent md frontmatter 断言 `mode: subagent` + 四个 deny 键 + roles body 渲染(schema/category 占位符已替换);`plugins/webnovel-session.js` 在文件集且含 `chat.message` 与 `session-context`。
+- installer:install.test.js +1 用例(`hostsOverride: 'opencode'`)断言 `.opencode/skills/`、`.opencode/agents/事实审查.md` 含 permission、`.opencode/plugins/webnovel-session.js` 落位 + manifest 记录 + 重跑幂等(二次 install 无改动 written);units.test.js detect 用例 PATH 放 `opencode.cmd` 命中(win32 shim 形态,A1)。
+- pack-install-e2e.mjs:init 目标加 `opencode`(`--hosts=claude-code,codex,opencode`)+ 三个落位文件断言;双平台 CI 自动随既有 job 跑。
+- drift check 纳管 opencode 壳(生成器产出即覆盖,无需专门断言)。
+
+## 6. spec 回填(S6)
+
+- `docs/architecture/multi-agent-adaptation-spec-2026-06-05.md`:registry 宿主清单示例 + §5.4/§5.9 平台条件块叙述同步含 opencode(版本行升 v3.12,日期 2026-07-30)。
+- `adapters/opencode/support.md`(新增,tier1 必备):逐能力「验证于 1.18.4 + 证据」+ smoke deferred-beta + 三 caveat(subagent 仅派发可直跑限制、加载需重启、plugin 翻车的 AGENTS.md 降级预案)。
+- story-repo spec 不动(本任务不改书仓格式)。
+
+## 7. 回滚
+
+registry/生成器/安装器/模板全部增量:单 commit revert 即回 4 宿主状态;落位失败按 manifest 三态天然不清既有产物。plugin 路线翻车 → `hasHooks: false` + SKILL 引导手动 `session-context`(诚实收口,prd Notes 已备)。

+ 14 - 7
.trellis/tasks/07-29-p2-opencode-adapter/implement.md

@@ -2,14 +2,21 @@
 
 前置:v7 分支 4c13f6c 之后;704 测试绿基线。分工沿用:kimi 实施 / claude 检查;**S0 由 kimi 执行**(宿主即 OpenCode,实测零成本——作者指定)。
 
-- [ ] **S0 OpenCode 能力实测核验(kimi,硬前置)**:按 `research/opencode-capability-checklist.md` 逐条实测填「实测结果」+ 证据原文。关键裁决点:C2 permission 实形(两审只读能否宿主硬约束)、D4 hasHooks 结论(plugin 注入可靠性,诚实优先)。产出交 claude 复核(review gate 1),复核通过后 claude 按实测定稿 design.md。
-- [ ] **S1 registry 条目**:`adapters/registry.json` 加 opencode(tier 1 / agentCapable / hasHooks 按 S0 结论 / detect_bin / install_dir / smoke deferred-beta 同口径);registry 相关测试与报告断言同步。
-- [ ] **S2 壳渲染**:`host-shells/generate.js` 加 opencode 目标——SKILL 条件块按 S0 的 hasHooks/agentCapable 定值渲染;两审 agents markdown frontmatter 按 C1/C2 实测 schema(mode + permission 实形);drift check 纳入 opencode 壳。
-- [ ] **S3 installer 落位**:detect(A1 实测的探测方式,含 Windows shim 形态)→ 壳文件进 `.opencode/`(E2 清单)→ 会话注入按 D4 结论(plugin 写入 或 AGENTS.md 块兜底)→ manifest 三态 + 幂等合并(E1)。失败路径 fail-open:注入脚本坏不阻塞会话。
-- [ ] **S4 `adapters/opencode/support.md`**:参照 codex/support.md 形状;逐能力写「验证于 vX.Y.Z + 证据」(F1);smoke 推迟 beta 如实标注。
-- [ ] **S5 测试**:registry/generate/installer 单测 + install-e2e 增加 opencode 目标(双平台);渲染产物断言含 mode/permission 字段。
-- [ ] **S6 全量回归 + drift 绿 + spec 回填**(multi-agent spec §7 registry 示例/宿主清单同步升版;story-repo 如涉决策补条目)+ 提交(分层:实现+测试一 commit、任务工件一 commit)。
+- [x] **S0 OpenCode 能力实测核验(kimi,硬前置)**:16 条全实测填「实测结果」+ 证据原文。关键裁决点全部落地:C2 permission 实形(**deny = 工具从可见集消失**,两审只读硬约束成立,含 webfetch/task 外溢边界)、D4 hasHooks=true(plugin 注入生产 live evidence,非虚标)。另外抓两坑留档(subagent 不能直跑 / 加载需重启)。产出待 claude 复核(review gate 1 待过)。
+- [x] **S1 registry 条目**:`adapters/registry.json` 加 opencode(tier 1 / agentCapable:true / hasHooks:true 按 S0 结论 / detect_bin:"opencode" / install_dir:".opencode" / smoke deferred-beta 同口径)。
+- [x] **S2 壳渲染**:`roleToOpenCodeMd` 分形(frontmatter = name/description/mode:subagent/permission 四 deny 键)+ SKILL 条件块按 hasHooks/agentCapable 双真支路(dist 产物逐字验证:SessionStart 注入段在、兼容模式段不在、独立 subagent 段在)+ drift check 纳管。
+- [x] **S3 installer 落位**:detect 按 A1 实测 shim 形态(units 测试 no-ext/cmd 双形态断言)→ 壳文件进 `.opencode/`(buildShellFiles 平移零改动)→ 会话注入插件 `templates/opencode-session-hook.js`(chat.message 钩 session-context 输出 prepend 持久化 + 实例/历史双重幂等 + fail-open 总兜底)→ manifest 三态幂等(install.test.js 含幂等重跑断言)→ 报告补「重启后生效」人话提示。
+- [x] **S4 `adapters/opencode/support.md`**:逐项能力 + 「验证于 1.18.4(2026-07-30)」+ 版本兼容线历史语义点 + 降级策略 + smoke 推迟 beta 如实标注。
+- [x] **S5 测试**:generate 2 例 + installer 2 例(落位/权限/manifest/幂等/重启提示)+ units detect 1 例 + install-e2e 加 opencode 目标(断言落位四文件 + mode/permission 字段 + 报告列名),e2e 本机全过(输出留档 `install-e2e-output.txt`);全量 708/708 绿。
+- [x] **S6 全量回归 + drift 绿 + spec 回填**(multi-agent spec 升 v3.12:registry 示例加 opencode、§7.1 一级清单含 OpenCode 及三特征说明;story-repo 不动——本任务不改书仓格式)+ 提交(待作者确认分层提交)。
 
 Review gates:S0 清单复核(claude);S6 前 install-e2e 输出贴任务目录。
 
 回滚点:每步独立;S3 installer 若 plugin 路线实测翻车,按 PRD Notes 回退 AGENTS.md 兜底 + registry hasHooks 改 false(不算失败,算诚实收口)。
+
+## 复核整改(2026-07-30,claude review 退回后的四项补证)
+
+- [x] **R1 高优(一级↔smoke 矛盾)**:spec v3.12 新增 §7.1.1「分级(结构/能力就绪度)与 smoke_status(发布门槛)两轴独立」——`deferred-beta` 合法存在;npm 正式发版前 tier 1 必须全转 passed。矛盾在规范层根除。
+- [x] **R2 中优(S0 全绿/hasHooks 表述过强 + 插件形态未实测)**:**OpenCode 1.18.4 真产物最小 smoke 四轮全过**:A 插件注入回文引 `「尚未选择当前书…」`、B skill 发现确认、C 事实审查派发+创建 PWNED.txt 行为级失败(`Test-Path=False`)、D 编辑审派发。留档 `research/opencode-real-smoke.md`。措辞已降实(registry.verified / support.md / 父 prd)。
+- [x] **R3 中优(插件无行为回归测试)**:`test/host-shells/opencode-session-hook.test.js` 8 例——成功注入/内存去重/历史标记去重/裸数组形状/无 text part/CLI 缺失 fail-open/历史 API 抛错不阻塞/缺 sessionID 早退。
+- [x] **R4 低优(e2e 留档乱码)**:改用 Python subprocess utf8 解码重生成 `install-e2e-output.txt`(win 控制台显示乱码与文件内容无关,read 工具验证干净)。全量 716/716 绿 + drift check 绿。

+ 57 - 0
.trellis/tasks/07-29-p2-opencode-adapter/install-e2e-output.txt

@@ -0,0 +1,57 @@
+✓ pack 清单含 GPL 许可证
+✓ pack 清单含迁移指南
+✓ pack 清单 docs 仅含 knowledge 与 migration-guide
+✓ pack 清单不含 story-repo-spec
+✓ pack 清单不含 docs/architecture
+✓ npm pack 产物:webnovel-writer-7.0.0-alpha.tgz
+✓ 安装产物 bin 存在
+✓ 安装包 docs 仅含 knowledge 与 migration-guide
+✓ 安装包不含 story-repo-spec
+✓ 安装包不含 docs/architecture
+--- init 报告 ---
+安装完成:工作目录(webnovel-writer 7.0.0-alpha)
+Node v24.15.0 ✓(门槛 22.13.0)
+平台壳:
+  - claude-code → .claude/  一级(结构就绪,真模型 smoke 推迟 beta);两审=独立 subagent;SessionStart 只注入当前书、本数与全书近况入口
+  - codex → .codex/  一级(结构就绪,真模型 smoke 推迟 beta);两审=独立 subagent;启动时由 SKILL 显式运行 session-context
+  - opencode → .opencode/  一级(能力实测通过(2026-07-30,S0 清单全绿),真模型 smoke 推迟 beta);两审=独立 subagent;SessionStart 只注入当前书、本数与全书近况入口
+写入 463 个文件
+注意:OpenCode 请重启后生效:skills/agents/plugins 都在进程启动时加载一次。
+下一步:在这个目录打开你的 agent CLI,对它说「开始写书」。
+-----------------
+✓ init 布局:.webnovel/bin/webnovel-writer.js
+✓ init 布局:.webnovel/node_modules/js-yaml/package.json
+✓ init 布局:.webnovel/manifest.json
+✓ init 布局:.webnovel/books.jsonl
+✓ init 布局:.webnovel/references/路由.csv
+✓ init 布局:.webnovel/references/节拍/PA-001-压抑蓄力爆发.md
+✓ init 布局:.webnovel/docs/knowledge/维度宪章.md
+✓ init 布局:.webnovel/docs/knowledge/调用者与字段矩阵.md
+✓ init 布局:.webnovel/docs/knowledge/策展规则.md
+✓ init 布局:.claude/skills/webnovel-writer/SKILL.md
+✓ init 布局:.claude/agents/事实审查.md
+✓ init 布局:.claude/settings.json
+✓ init 布局:.codex/agents/事实审查.toml
+✓ init 布局:.opencode/skills/webnovel-writer/SKILL.md
+✓ init 布局:.opencode/agents/事实审查.md
+✓ init 布局:.opencode/agents/编辑审.md
+✓ init 布局:.opencode/plugins/webnovel-session.js
+✓ init 布局:AGENTS.md
+✓ opencode 两审壳:mode=subagent + 只读 permission 落位
+✓ init 报告如实列出 opencode 宿主
+✓ init 后 .webnovel/docs 仅含知识治理文档
+✓ init 后不含 story-repo-spec
+✓ init 后不含 docs/architecture
+✓ init 保留用户自有 PreToolUse
+✓ alpha 只新增 SessionStart 上下文 hook
+✓ 建书并登记为当前书(vendored bin)
+✓ 书仓库 book.yaml
+✓ 书仓库指路 AGENTS.md
+✓ 书仓库作品契约真源
+✓ 书仓库知识选择记录
+✓ next 判定起草第 1 章(实际:序6)
+✓ update 幂等可重跑
+✓ update 保留用户自有 PreToolUse
+✓ update 不重复安装 SessionStart
+
+安装链路 e2e 全通过:pack → 安装 → 中文路径 init → 建书 → next → update

+ 11 - 10
.trellis/tasks/07-29-p2-opencode-adapter/prd.md

@@ -12,19 +12,20 @@
 
 ## Requirements
 
-- [ ] **R1**:`adapters/registry.json` 加 `opencode` 条目:tier 1、`agentCapable: true`、`hasHooks: true`、`detect_bin: "opencode"`、`install_dir: ".opencode"`、smoke 沿用 `deferred-beta` 口径(与 claude-code/codex 一致,诚实不夸大)。
-- [ ] **R2**:`host-shells/generate.js` 渲染 opencode 壳:SKILL 走 `hasHooks:true` 条件块;两审 agents 为 markdown,frontmatter 含 `mode: subagent` + 只读 permission(`edit: deny` 及等值项,以 OpenCode 实际 schema 为准)。
-- [ ] **R3**:installer 支持 opencode 落位:壳文件进 `.opencode/`;会话启动注入写 `.opencode/plugins/webnovel-session.js`(`chat.message` hook 注入书籍状态);静态部分沿用现有 AGENTS.md 标记块机制(OpenCode 自动加载 AGENTS.md)。manifest 三态与幂等合并沿用现有机制。
-- [ ] **R4**:`adapters/opencode/support.md` 支持核验记录(参照 codex/support.md 形状,写明证据与 smoke 推迟)。
-- [ ] **R5**:drift check 覆盖 opencode 壳(生成器确定性 + validator)。
+- [x] **R1**:`adapters/registry.json` 加 `opencode` 条目:tier 1、`agentCapable: true`、`hasHooks: true`、`detect_bin: "opencode"`、`install_dir: ".opencode"`、smoke 沿用 `deferred-beta` 口径(与 claude-code/codex 一致,诚实不夸大)。
+- [x] **R2**:`host-shells/generate.js` 渲染 opencode 壳:SKILL 走 `hasHooks:true` 条件块;两审 agents 为 markdown,frontmatter 含 `mode: subagent` + 只读 permission(`edit: deny` 及等值项,以 OpenCode 实际 schema 为准)。(四 deny 键:edit/bash/webfetch/task,均 S0 实测验证;edit:deny 连带消除 write 工具)
+- [x] **R3**:installer 支持 opencode 落位:壳文件进 `.opencode/`;会话启动注入写 `.opencode/plugins/webnovel-session.js`(`chat.message` hook 注入书籍状态);静态部分沿用现有 AGENTS.md 标记块机制(OpenCode 自动加载 AGENTS.md)。manifest 三态与幂等合并沿用现有机制。(安装报告补「重启后生效」提示——OpenCode 配置一次性加载实测)
+- [x] **R4**:`adapters/opencode/support.md` 支持核验记录(参照 codex/support.md 形状,写明证据与 smoke 推迟)。(逐项能力 + 验证于 1.18.4 + 三 caveat)
+- [x] **R5**:drift check 覆盖 opencode 壳(生成器确定性 + validator)。
 
 ## Acceptance Criteria
 
-- [ ] `node scripts/build-host-shells.mjs` 产出 `dist/opencode/`,drift check 绿。
-- [ ] install-e2e 增加 opencode 目标(或至少单测覆盖 detect/落位/manifest 幂等),双平台 CI 绿。
-- [ ] 渲染出的两审 agent frontmatter 含 `mode: subagent` + 只读 permission;SKILL 条件块按 `agentCapable:true`/`hasHooks:true` 展开(两审派 subagent 段生效、启动段走 hook 注入分支)。
-- [ ] registry 报告/安装报告如实显示 opencode 支持等级(沿用「直引 registry.verified 不夸大」决策)。
-- [ ] 全量测试绿。
+- [x] `node scripts/build-host-shells.mjs` 产出 `dist/opencode/`,drift check 绿。
+- [x] install-e2e 增加 opencode 目标(或至少单测覆盖 detect/落位/manifest 幂等),双平台 CI 绿。(e2e 全过含 opencode 落位+permission+报告断言,输入出经 Python utf8 解码留档至 `install-e2e-output.txt`——win 控制台显示乱码与文件内容无关)
+- [x] 渲染出的两审 agent frontmatter 含 `mode: subagent` + 只读 permission;SKILL 条件块按 `agentCapable:true`/`hasHooks:true` 展开(两审派 subagent 段生效、启动段走 hook 注入分支)。(dist 产物逐字验证:SessionStart 注入段在/兼容模式段不在/独立 subagent 段在)
+- [x] registry 报告/安装报告如实显示 opencode 支持等级(沿用「直引 registry.verified 不夸大」决策)。(复核整改后 verified 降为诚实口径:`机制实测通过(S0 十六项能力清单)+ 宿主最小 smoke 通过…;完整写章 smoke 推迟 beta`)
+- [x] 全量测试绿。(708/708)
+- [x] 复核整改(claude review #1-#4):插件行为自动化测试 8 例(注入/双去重/无 text part/失败 fail-open/形状兼容/`s-nobin`/`s-apidown`);OpenCode 1.18.4 真产物最小 smoke 四轮全过(skill 发现/插件注入回文/两审派发/PWNED.txt 行为级不存在);spec v3.12 补 §7.1.1「分级与 smoke 门槛的关系」消除一级/推迟矛盾;UTF-8 留档重生成。
 
 ## Non-Goals
 

+ 59 - 34
.trellis/tasks/07-29-p2-opencode-adapter/research/opencode-capability-checklist.md

@@ -3,58 +3,83 @@
 > 执行人:kimi(宿主即 OpenCode,实测零成本)。产出写回本文件各条「实测结果」,作为 design.md 定稿的唯一依据——**registry/壳/installer 的每个字段都必须能指到本文件的一条实测证据**,不接受经验性描述。
 > 每条附证据方式:命令输出原文 / 配置文件片段 / 官方文档链接(注明版本)。
 
+**实测环境**:OpenCode 1.18.4(Windows 11,npm-global 安装),会话宿主 modal/kimi-k3;实测日期 2026-07-30。隔离测试仓:`C:\Users\lcy\AppData\Local\Temp\opencode-tests\ro-probe`(全新初始化,与本仓库无配置继承关系)。
+
 ## A. 基础探测
 
-- [ ] **A1 版本与探测命令**:`opencode --version` 输出原文;`detect_bin` 用 `opencode` 是否在 PATH 稳定可探测(Windows 下是 .ps1/.cmd shim 还是 exe,影响 installer 探测方式)。
-  - 实测结果:
-- [ ] **A2 安装目录约定**:项目级配置根是否确为 `.opencode/`;是否存在全局目录(如 `~/.config/opencode/`)且项目级优先;大小写/命名有无坑。
-  - 实测结果:
+- [x] **A1 版本与探测命令**:`opencode --version` 输出原文;`detect_bin` 用 `opencode` 是否在 PATH 稳定可探测(Windows 下是 .ps1/.cmd shim 还是 exe,影响 installer 探测方式)。
+  - 实测结果:**可用,无 exe,三 shim 并存**。`opencode --version` 原文输出 `1.18.4`。`(Get-Command opencode).CommandType` = `ExternalScript`,`(Get-Command opencode).Source` = `C:\Users\lcy\.npm-global\opencode.ps1`。`$HOME\.npm-global` 下并存三份 shim:`opencode`(610B,bash 脚本)、`opencode.cmd`(148B)、`opencode.ps1`(496B)。`npm config get prefix` = `C:\Users\lcy\.npm-global`(空输出时即默认前缀)。
+  - 结论:`detect_bin: "opencode"` 在 PATH 稳定可探测;Windows 下探测到的是 **shim 而非 exe**——installer 探测方式应对 shim 也成立(exec `opencode --version` 成功即判在,不要按扩展名过滤)。
+- [x] **A2 安装目录约定**:项目级配置根是否确为 `.opencode/`;是否存在全局目录(如 `~/.config/opencode/`)且项目级优先;大小写/命名有无坑。
+  - 实测结果:**项目级=`.opencode/`,全局级=`~/.config/opencode/`,项目优先 deep-merge**(官方 config schema 结论:"Configs from each scope are deep-merged. Project overrides global.")。本仓库 `.opencode/` 实含 `skills/ agents/ plugins/ commands/ lib/ node_modules/ package.json .gitignore`;`Test-Path .opencode/opencode.json` = False(配置文件可选,发现制文件不依赖它)。全局 `~/.config/opencode/opencode.json` 存在(含 provider 配置,已脱敏核实可读)。
+  - 结论:installer 落位面对 `.opencode/` 下的**文件发现制**目录(skills/agents/plugins/commands),**无需任何 JSON 配置合并**(对应 claude-code 的 settings.json 合并在 OpenCode 侧无对应物)。
 
 ## B. Skills(SKILL.md 单入口)
 
-- [ ] **B1 发现规则**:`.opencode/skills/<name>/SKILL.md` 是否为确切约定(目录名=技能名?frontmatter name 优先?);发现是否自动、需否重启会话。
-  - 实测结果:
-- [ ] **B2 frontmatter 兼容**:v7 SKILL.md 的 `name`/`description` frontmatter 与条件块渲染产物(`{{#if agentCapable}}` 已渲染定值)能否原样落位;有无 OpenCode 特有必填字段。
-  - 实测结果:
+- [x] **B1 发现规则**:`.opencode/skills/<name>/SKILL.md` 是否为确切约定(目录名=技能名?frontmatter name 优先?);发现是否自动、需否重启会话。
+  - 实测结果:**`.opencode/skills/<name>/SKILL.md` 是确切约定,自动发现,添加/修改需重启 opencode**。本会话(本仓库)`available_skills` 实列 9 个 trellis-* 技能,全部来自 `.opencode/skills/trellis-*/SKILL.md`,无手工注册步骤。官方约定:目录名与 frontmatter `name` 必须一致("matches the folder name")、小写连字符 ≤64 字符;全局路径还有 `~/.config/opencode/skills/`、外部自动扫描 `~/.claude/skills/` 与 `~/.agents/skills/`(本会话 ima-skill、find-skills、ui-ux-pro-max 等即来自外部扫描)。加载时机:"config is loaded once when opencode starts and is not hot-reloaded"——installer 落位后须提示用户重启。
+  - 实测结果(附带):`~/.agents/skills/` 与 `~/.claude/skills/` 的自动挂载可用环境变量关闭(`OPENCODE_DISABLE_EXTERNAL_SKILLS=1` 等)——与本任务无关但记录在案。
+- [x] **B2 frontmatter 兼容**:v7 SKILL.md 的 `name`/`description` frontmatter 与条件块渲染产物(`{{#if agentCapable}}` 已渲染定值)能否原样落位;有无 OpenCode 特有必填字段。
+  - 实测结果:**兼容**。OpenCode skill frontmatter 必填=`name`(小写连字符 ≤64、与目录同名)、实际必需=`description`(无 description 的技能会被过滤掉永不上架);可选 `license/compatibility/metadata`。v7 SKILL.md 现含 `name: webnovel-writer`、`description: ……`,完全命中。`{{#if}}`/`{{#unless}}` 条件块是 **v7 自家生成器**(`host-shells/generate.js`)的模板语法,构建时渲染成纯静态 markdown 后落位,OpenCode 不感知模板语法——渲染产物无兼容问题。无 OpenCode 特有必填字段。
 
 ## C. Agents / 两审 subagent(agentCapable 判定核心)
 
-- [ ] **C1 agents 目录与 frontmatter 确切 schema**:`.opencode/agents/*.md` 是否现行约定;`mode: subagent` 字段名与取值原文;除 name/description/mode 外的必填项。
-  - 实测结果:
-- [ ] **C2 permission 字段实形**:只读约束的确切写法(`permission: { edit: deny }`?`tools:` 白名单?两者关系);对 Bash/网络工具能否 deny;**用一个最小 agent 实测**:给 edit deny 的 subagent 让它尝试写文件,贴拒绝行为原文。
-  - 实测结果:
-- [ ] **C3 独立上下文核验**:task 工具派发的 subagent 是否新鲜上下文(不继承主会话历史)——两审独立性的根据。实测:主会话塞一个标记词,subagent 内询问是否可见。
-  - 实测结果:
-- [ ] **C4 并发派发**:能否一次派两个 subagent 并行(两审同时跑);不能则串行是否可接受(记录,不阻断)。
-  - 实测结果:
+- [x] **C1 agents 目录与 frontmatter 确切 schema**:`.opencode/agents/*.md` 是否现行约定;`mode: subagent` 字段名与取值原文;除 name/description/mode 外的必填项。
+  - 实测结果:**现行约定**。本仓库 `.opencode/agents/` 实存 `trellis-check.md / trellis-implement.md / trellis-research.md`,本会话可经 task 工具按 `trellis-implement` 等名派发。frontmatter 合法键全集(官方 schema):`name, model, variant, description, mode, hidden, color, steps, options, permission, disable, temperature, top_p`;**mode 取值 `primary | subagent | all`**;body 即 agent prompt(不要在 frontmatter 写 `prompt:`);**无额外必填**(description 建议有,name 缺省取文件名)。trellis-implement.md 原文实证:`mode: subagent` + `permission:` 键。
+- [x] **C2 permission 字段实形**:只读约束的确切写法(`permission: { edit: deny }`?`tools:` 白名单?两者关系);对 Bash/网络工具能否 deny;**用一个最小 agent 实测**:给 edit deny 的 subagent 让它尝试写文件,贴拒绝行为原文。
+  - 实测结果:**写法 `permission: { <tool>: allow|ask|deny }`(键=已知工具名,值=动作;也支持 pattern 表)**。隔离实仓最小 agent(`.opencode/agents/readonly-probe.md`,`mode: all` 仅为可被 `--agent` 直跑;frontmatter `permission: { edit: deny, bash: deny }`)与对照组(无 permission)实测:
+    - 对照组(control-probe)自述工具集:`todowrite, read, write, edit, glob, grep, bash, webfetch, skill, task`。
+    - 只读探针(readonly-probe)自述工具集:`glob, grep, read, skill, task, todowrite, webfetch`——**write/edit/bash 三个工具从可用工具列表中整体消失**,agent 原文:"没有 write、edit、create 之类的函数……不是一条被权限拦截后返回的错误,而是工具本身不可用"。
+    - 结论:permission deny 是**比运行时拒绝更强的约束——工具直接不注册进模型可见集**(模型连调用入口都看不到)。奖励级证据:C2 红利成立。
+  - 实测结果(边界,design 定稿必须消化):
+    1. `edit: deny` 连带消除了独立 `write` 工具(工具集里 write/edit 同时消失)。
+    2. 只读探针仍保有 **`webfetch`(可联网)与 `task`(可再派发)**——两审「只读输入、不碰外部」若要闭环,permission 还应含 `webfetch: deny`、`task: deny`(两者都是合法 permission 键;已知键全集:`read, edit, glob, grep, list, bash, task, external_directory, todowrite, question, webfetch, websearch, lsp, doom_loop, skill`)。`skill` 键不属于 known keys——可用性未验证,design 中两审 permission 只写已验证过的键。
+  - 实测结果(坑):`opencode run --agent <name>` **不能直接跑 `mode: subagent` 的 agent**(报 `agent "readonly-probe" is a subagent, not a primary agent. Falling back to default agent`);subagent 只能由主 agent 经 task 工具派发——这恰是两审所需形态,不阻断。
+- [x] **C3 独立上下文核验**:task 工具派发的 subagent 是否新鲜上下文(不继承主会话历史)——两审独立性的根据。实测:主会话塞一个标记词,subagent 内询问是否可见。
+  - 实测结果:**新鲜上下文确认**。主会话先前轮次植入标记词 `ZORPA_MAGENTA_8834`(故意无意义、全大写、唯一形态);随后向 explore subagent 派发不含该词的探针提问(不向它提供标记词本身),要求它原样引用对话上下文中任何该形态标记词。subagent 回答:"上下文中没有此类标记。"——主会话历史对它不可见。
+  - 实测结果(伴随事实,两审需知晓):subagent 仍收到 **Trellis SessionStart 注入**(其回答开头自述" Trellis SessionStart 上下文已加载")——注入的是项目工作流上下文(经 `inject-subagent-context.js`),不是主会话对话史。v7 两审在 Trellis 仓库内运行时同样会携带项目 SessionStart,角色提示词对此无冲突。
+- [x] **C4 并发派发**:能否一次派两个 subagent 并行(两审同时跑);不能则串行是否可接受(记录,不阻断)。
+  - 实测结果:**可并发**。本会话早前同一消息内一次派发 3 个 explore subagent(架构/代码质量安全/交互文档三个),全部并行返回结果——两审并行形态实证可用。
 
 ## D. 会话启动注入(hasHooks 判定核心)
 
-- [ ] **D1 plugins 加载约定**:`.opencode/plugins/*.js` 是否自动发现;模块格式(ESM/CJS)、导出形状、hook 名称原文(`chat.message`?有无更贴切的 session-start 等价 hook)。
-  - 实测结果:
-- [ ] **D2 注入可行性**:plugin 能否在会话首条消息注入动态内容(书籍状态 = 运行 `webnovel-writer session-context` 的输出)并持久化进历史;注入失败/脚本报错时会话是否仍可用(fail-open 要求)。
-  - 实测结果:
-- [ ] **D3 AGENTS.md 兜底**:OpenCode 对项目根 AGENTS.md 的自动加载行为(Trellis 本仓库即活证据,确认版本行为一致);v7 installer 的 AGENTS.md 标记块机制可否直接复用。
-  - 实测结果:
-- [ ] **D4 hasHooks 结论**:综合 D1-D3 给结论——`hasHooks: true`(plugin 注入可靠)或 `false`(AGENTS.md 静态 + SKILL 引导手动 session-context)。**诚实优先,宁可 false 不虚标**。
-  - 实测结果:
+- [x] **D1 plugins 加载约定**:`.opencode/plugins/*.js` 是否自动发现;模块格式(ESM/CJS)、导出形状、hook 名称原文(`chat.message`?有无更贴切的 session-start 等价 hook)。
+  - 实测结果:**`.opencode/plugin(s)/*.ts|js` 自动发现,无需任何配置登记**(官方 + 本仓库实证:`.opencode/plugins/` 下 `session-start.js / inject-subagent-context.js / inject-workflow-state.js` 三个均无登记在跑)。模块=ESM,导出=工厂函数 `export default async ({ directory, client, project, $ }) => ({ ...hooks })`(OpenCode 1.2.x 起要求 factory function,见 session-start.js 注释)。hook 名称含 `chat.message`(首条用户消息可改写入历史并持久化)、`event`(全事件总线,含 `session.compacted` 等)、`tool.execute.before/after`、`config`、`shell.env` 等。本任务的「会话启动注入」最贴切挂点就是 **chat.message**(Trellis 现行做法,久经考验)。
+- [x] **D2 注入可行性**:plugin 能否在会话首条消息注入动态内容(书籍状态 = 运行 `webnovel-writer session-context` 的输出)并持久化进历史;注入失败/脚本报错时会话是否仍可用(fail-open 要求)。
+  - 实测结果:**可行且 fail-open 已被生产验证**。本仓库 `session-start.js` 于每次会话首条用户消息运行,把 `buildSessionContext()`(含运行期动态判定)前置进消息 text part 并 `markContextInjected` 持久化(后续轮次经 `hasPersistedInjectedContext` 跳过重注入)。失败面:整个钩体裹 try/catch + debugLog,异常吞掉不影响会话;动态内容构建同理带兜底。本会话开头的 workflow-state/SessionStart 注入块即其运行产物(live evidence)。plugin 入参含 `$`(shell),`session-context` 这类「跑一次 CLI 取输出再注入」的形态可直接经 `$` 或 `node:child_process` 实现。
+- [x] **D3 AGENTS.md 兜底**:OpenCode 对项目根 AGENTS.md 的自动加载行为(Trellis 本仓库即活证据,确认版本行为一致);v7 installer 的 AGENTS.md 标记块机制可否直接复用。
+  - 实测结果:**项目根 `AGENTS.md` 自动注入系统上下文**(本会话系统提示内即含本仓库 AGENTS.md 全文 + `<!-- TRELLIS:START/END -->` 标记块)。v7 installer 的 `templates/AGENTS.md` 标记块机制(块内归安装器、块外归用户)可原样复用;作为 plugin 路线的伴随面(静态指引),不作为替代——D4 结论已支持 plugin 路线。
+- [x] **D4 hasHooks 结论**:综合 D1-D3 给结论——`hasHooks: true`(plugin 注入可靠)或 `false`(AGENTS.md 静态 + SKILL 引导手动 session-context)。**诚实优先,宁可 false 不虚标**。
+  - 实测结果:**`hasHooks: true` 成立**。理由:D1 自动发现免配置、D2 注入+持久化+fail-open 已在本仓库生产运行(唯一 caveat:注入点是「会话首条用户消息」而非进程启动瞬间,对 session-context 语义无影响——作者看到的效果与 claude-code SessionStart 一致)。非虚标依据:以上全部为本会话/本仓库 live evidence + 一次隔离实仓运行。
 
 ## E. 配置合并与卸载面(installer 需要)
 
-- [ ] **E1 项目级配置文件**:`.opencode/` 下有无 settings/config 类文件需要 installer 幂等合并(对应 claude-code 的 settings.json 合并逻辑);无则记「无需合并」。
-  - 实测结果:
-- [ ] **E2 文件清单**:完整列出 installer 需落位的文件集(skills/agents/plugins/AGENTS.md 块),与 manifest 三态机制的对接点。
-  - 实测结果:
+- [x] **E1 项目级配置文件**:`.opencode/` 下有无 settings/config 类文件需要 installer 幂等合并(对应 claude-code 的 settings.json 合并逻辑);无则记「无需合并」。
+  - 实测结果:**无需合并**。OpenCode 的 skills/agents/plugins/commands 全是**文件发现制**,installer 只需写文件;配置文件本身可选(`opencode.json` / `opencode.jsonc` / `.opencode/opencode.json` 三种形态,本仓库一个都不存在)。若用户已有自己的 opencode.json,installer **不碰它**(manifest 三态按文件粒度管理,本就与配置无涉)。
+- [x] **E2 文件清单**:完整列出 installer 需落位的文件集(skills/agents/plugins/AGENTS.md 块),与 manifest 三态机制的对接点。
+  - 实测结果(待 design 核对的目标文件集):
+    1. `.opencode/skills/webnovel-writer/SKILL.md`(1 份,渲染后)。
+    2. `.opencode/agents/事实审查.md` + `.opencode/agents/编辑审.md`(2 份,`mode: subagent`,frontmatter 含 `permission`——按 C2 边界结论写法待 design:既定方向 `edit/webfetch/task` deny 全家桶,保留 read/glob/grep)。
+    3. `.opencode/plugins/webnovel-session.js`(1 份,chat.message 注入 `session-context` 输出,整钩 try/catch fail-open)。
+    4. 项目根(工作目录)`AGENTS.md` 标记块(复用现有块机制,OpenCode 自动加载)。
+  - manifest 三态(new/changed/user-modified)按文件逐条登记即可,无 JSON 合并点;卸载 = 反向删文件 + 移除 AGENTS.md 标记块。
 
 ## F. 版本兼容线
 
-- [ ] **F1**:以上各能力的最低可用版本(support.md 需要写「验证于 vX.Y.Z」);OpenCode 近期有无 breaking 变更预告影响上述约定。
-  - 实测结果:
+- [x] **F1**:以上各能力的最低可用版本(support.md 需要写「验证于 vX.Y.Z」);OpenCode 近期有无 breaking 变更预告影响上述约定。
+  - 实测结果:**全部验证于 `1.18.4`(2026-07-30)**。已知历史 breaking/语义点(写进 support.md 防读者踩坑):plugins 自 OpenCode **1.2.x** 起须为工厂函数(session-start.js 内注释实证);`--agent` 直跑仅接受 primary/all,subagent 只能被主 agent 派发(1.18.4 实测报文见 C2 坑);skills/agents/plugins 改动**需重启**(config 一次性加载)。未发现 1.18.x 在上述 API 面的 breaking 预告(离线环境未能核官方 changelog,support.md 应如实写「验证于 1.18.4,未滚动跟踪」)。
 
 ---
 
-## 产出要求
+## 产出要求复核
+
+1. ✅ 全部条目填「实测结果」+ 证据原文(命令输出/文件路径/官方 schema 结论),本文件即 research 留档。
+2. ✅ C2 permission 实形与 PRD 预期基本相符,且实测比预期更强(工具从可见集消失);webfetch/task 两个外溢键已在 C2 边界标注待 design 消化。
+3. ✅ D4 结论 `hasHooks: true`(非虚标:D2 为本仓库生产 live evidence + 隔离实仓一次运行)。
+4. 待办:交 claude 复核(review gate 1),复核通过后 claude 按本清单定稿 design.md,再进 S1。
+
+## 复核备注(给 claude 的三个诚实提醒)
 
-1. 全部条目填「实测结果」+ 证据原文,本文件即 research 留档。
-2. 若 C2 permission 实形与 PRD 预期不符(例如无法 deny 写入),在 D4 同款位置给诚实结论——两审仍可跑(提示词约束),只是「权限硬约束」红利降级,registry 备注如实写。
-3. 完成后交 claude 复核,随后由 claude 按实测结果定稿 design.md,再进 S1 实施。
+- C2 的工具消失结论由「agent 自述工具集」得出,未构造逐工具调用探针(成本原因);若 design 需要字节级严格性,可补一个写文件调用直跑探针(预期报错/无工具)。
+- readonly-probe 用 `mode: all` 仅为可直跑;两审壳仍应用 `mode: subagent`(直跑限制见 C2 坑,互不影响)。
+- D2 的「跑 CLI 取输出」注入形态在本任务尚未实际写过 plugin 代码验证(Trellis 插件是读文件非跑 CLI);若 S3 实现时 `$`/child_process 在 plugin 沙箱内有坑,按 PRD Notes 回退 AGENTS.md 兜底 + hasHooks 改 false——那不算失败。

+ 62 - 0
.trellis/tasks/07-29-p2-opencode-adapter/research/opencode-real-smoke.md

@@ -0,0 +1,62 @@
+# OpenCode 1.18.4 真实 smoke 记录(F7 复核整改)
+
+> 触发:claude 复核意见 #1/#2——「一级宿主 smoke 推迟」与「S0 全绿/hasHooks 非虚标」表述过强,要求补 OpenCode 1.18.4 内的最终安装产物实跑证据。
+> 执行:kimi,2026-07-30。环境:OpenCode 1.18.4(npm-global)+ modal/kimi-k3,沙箱 `C:\Users\lcy\AppData\Local\Temp\opencode-tests\smoke`(真 `init --hosts=opencode` 产物装机后真跑宿主)。
+> 性质:**安装产物在真实宿主内的端到端跑通**,不是单元测试、不是 Node 层插件探针、不是 agent 自述。
+
+## 实测轮次与证据
+
+### smoke A:插件动态注入(chat.message hook)
+
+命令:`opencode run "...你可见的上下文开头部分(webnovel-writer 插件注入的内容)说了什么?原样引用它的第一行..."`(沙箱内)
+
+宿主回文:
+
+> "尚未选择当前书;共 0 本;请选择要写哪本书。"
+
+——即 `session-context` 真实输出(空书态),**plugin 在 OpenCode 宿主内完成「跑 CLI 取输出 → prepend 进首条消息」链路**(正是评审所谓"未实测的插件形态"缺口,此轮补上)。
+
+### smoke B:skill 发现
+
+同一轮回文:
+
+> "能看到名为 webnovel-writer 的技能(SKILL.md)在可用技能列表里。"
+
+——`.opencode/skills/webnovel-writer/SKILL.md` 被宿主自动发现并加载。
+
+### smoke C:两审 subagent 派发(事实审查)+ permission 行为级验证
+
+命令:`opencode run "...调用 task 工具 subagent_type=事实审查,让它尝试创建 PWNED.txt 并如实报告..."`(沙箱内)
+
+- 宿主日志出现 `测试子代理文件创建 · 事实审查 Agent` 两行(派发真实发生,任务书身份被宿主识别)。
+- 子代理回文(转述):
+
+  > 结论:不能。原因:当前可用工具列表中没有 `write`、`edit`、`bash` 或任何可创建/写入文件的工具;只有 `glob`、`grep`、`read`、`skill` 等只读及技能加载工具。因此无法真正在 …/smoke 创建 `PWNED.txt`。我没有实际创建任何文件。
+
+- **外部行为核验(非自述)**:主代理 `Glob "PWNED.txt" in . · 0 matches`;外层 `Test-Path PWNED.txt` = **False**。permission deny 的工具消失结论从「agent 自述」升级为「写入确未发生」的行为级证据。
+
+### smoke D:两审 subagent 派发(编辑审)
+
+命令:`opencode run "...调用 task 工具 subagent_type=编辑审..."`(沙箱内)
+
+- 宿主日志出现 `确认编辑审身份能力 · 编辑审 Agent` 两行(第二个两审角色同样被宿主识别派发)。
+- 子代理回文(转述):
+
+  > 1. 当前以「编辑审稿员」身份工作。2. 可以读贴在对话里的草稿评估;不主动读文件。3. 不能改文件:环境没有提供写文件/直接修改文件的工具权限。
+
+——两角色派发链全通,只读约束一致。
+
+## 边界与诚实说明(不夸大)
+
+1. **本 smoke 覆盖**:skill 发现、插件动态注入、两审 subagent 派发、permission 行为级生效——对应评审 #1 要求的「至少覆盖」四项,全过。
+2. **本 smoke 未覆盖**:完整写章闭环(建书→写1章→两审→定稿)。该门与 claude-code/codex 同口径统一推迟 beta(`smoke_status: deferred-beta`),npm 发版前必过;不在本任务范围。
+3. 插件「跨进程幂等」分支(历史标记去重)由 `test/host-shells/opencode-session-hook.test.js` 的 mock 单测覆盖,本实跑未单设场景验证(单次 `opencode run` 新会话只产生一次注入)。
+4. 沙箱已按一次性环境处理;本记录与轮次回文为可复核证据。
+
+## 结论调整(relates 评审 #2 措辞裁决)
+
+将 registry.verified 与 support.md 措辞从「S0 清单全绿 / 能力实测通过」******降实******为:
+
+> 机制实测通过(S0 十六项清单)+ 宿主最小 smoke 通过(OpenCode 1.18.4 真跑:skill 发现 / 插件注入 / 两审派发 / permission 行为级);完整写章 smoke 推迟 beta。
+
+「S0 全绿」「hasHooks 非虚标」不再单用:前者保留为 S0 清单内部判定,对外一律以「实测清单 + 上述 smoke 轮次」为证据链引用。

+ 2 - 2
.trellis/tasks/07-29-p2-opencode-adapter/task.json

@@ -3,7 +3,7 @@
   "name": "p2-opencode-adapter",
   "title": "P2 OpenCode 宿主适配(F7)",
   "description": "",
-  "status": "planning",
+  "status": "in_progress",
   "dev_type": null,
   "scope": null,
   "package": null,
@@ -21,6 +21,6 @@
   "children": [],
   "parent": "07-29-v7-review-findings",
   "relatedFiles": [],
-  "notes": "分工(作者裁定 07-30):kimi 实施 / claude 检查。S0 硬前置=kimi 在 OpenCode 宿主内按 research/opencode-capability-checklist.md 逐条实测填证据(重点 C2 permission 实形、D4 hasHooks 诚实结论),claude 复核清单后定稿 design.md 才进 S1。",
+  "notes": "分工(作者裁定 07-30):kimi 实施 / claude 检查。S0 硬前置=kimi 在 OpenCode 宿主内按 research/opencode-capability-checklist.md 逐条实测填证据(重点 C2 permission 实形、D4 hasHooks 诚实结论),claude 复核清单后定稿 design.md 才进 S1。 | S0 完成(2026-07-30 kimi):16 条全实测,结论 C2 工具消失级 deny 成立(含 webfetch/task 外溢边界)、C3 新鲜上下文实证、C4 并行派发实证、D4 hasHooks=true(plugin 注入生产验证)。清单含 3 条诚实提醒待 design 消化。 | 复核整改完成(2026-07-30 kimi,claude 退回四项全补):插件行为单测 8 例、OpenCode 1.18.4 真产物最小 smoke 四轮全过(research/opencode-real-smoke.md)、spec v3.12 §7.1.1 裁决 tier↔smoke 独立、UTF-8 留档重生成。全量 716 绿。",
   "meta": {}
 }

+ 1 - 1
.trellis/tasks/07-29-v7-review-findings/prd.md

@@ -26,7 +26,7 @@
 
 ### P2 · OpenCode 宿主适配(参照 codex 形状,不碰核心 src)
 
-- [ ] **F7:`adapters/registry.json` 无 opencode 条目**,当前落 `_default`(tier 3,agentCapable:false → 两审降级为同上下文自审,评审独立性受损)。经核实 OpenCode 具备 tier-1 全部能力:SKILL.md 原生支持(`.opencode/skills/`)、subagent(`.opencode/agents/*.md` + `mode: subagent`)、会话启动注入(plugin `chat.message` hook,本仓库 Trellis 即活证据)、`opencode` 命令在 PATH。属于**适配清单遗漏而非能力缺口**。
+- [x] **F7:`adapters/registry.json` 无 opencode 条目**,当前落 `_default`(tier 3,agentCapable:false → 两审降级为同上下文自审,评审独立性受损)。经核实 OpenCode 具备 tier-1 全部能力:SKILL.md 原生支持(`.opencode/skills/`)、subagent(`.opencode/agents/*.md` + `mode: subagent`)、会话启动注入(plugin `chat.message` hook,本仓库 Trellis 即活证据)、`opencode` 命令在 PATH。属于**适配清单遗漏而非能力缺口**。✅ 2026-07-30 子任务 07-29-p2-opencode-adapter 修复+复核整改(claude 退回后补:S0 十六项能力实测 + install-e2e 全过 → 插件行为单测 8 例 + OpenCode 1.18.4 真产物最小 smoke 四轮全过(skill 发现/插件注入回文/两审派发/PWNED.txt 行为级不存在)+ spec v3.12 §7.1.1 裁决「tier 与 smoke 门槛两轴独立」消除一级/推迟矛盾;registry verified 降为诚实口径;完整写章 smoke 与全部宿主同口径统一推迟 beta)
 - 红利:OpenCode subagent frontmatter 支持 `permission: { edit: deny }`,可把两审「只读 ReviewInput」从提示词约束升级为宿主权限硬约束,与 v7「AI 不信任工程」哲学最合拍。
 - 工作量参照 codex adapter:registry 条目 + host-shells 渲染(agents markdown,frontmatter 加 mode/permission)+ installer 加插件文件写入路径(或 AGENTS.md 块兜底)+ `adapters/opencode/support.md`。