Repository navigation
[REQ-131][CODE] #1129 在目录与工具执行咽喉执行同一 identity 三态策略(E1–E7 + sentinel) - #1135
Merged
Merged
Conversation
REQ-131 / #724 CLOSE_DECIDE §6 E1-E7 + internal sentinel: - E1/E2/E3: session/tools.ts 公共 register() 上的 identityGate —— 所有来源 (builtin/plugin/host/MCP)的 execute 在 tool.execute.before 钩子与实现之前 按 exact canonical identity 走三态(deny 响亮拒/零副作用,ask 走现有 Permission 引擎挂起,allow 保留 ability 闸);MCP 循环内层 hook 之后的 重复 canonical ask 移除(once 不再被问两次)。 - E4: code-mode invokeChildTool 的 identity ask 上移到插件钩子之前; disabled child 不进 child catalog(既有 visibleTools 过滤,新增运行期判据)。 - E6: prompt.ts handleSubtask 在任何持久化/钩子/execute 副作用前按同一引擎 ask(原 :284-288 只完成 deny)。 - E7: attachment ingestion 显式排除保持,负向锁死(identity+ability 全 deny 仍完成 ingestion、全程零待批)。 - sentinel: host::StructuredOutput 目录闸免疫(exact canonical,deny-all 也 移不掉,缺 identity 不享豁免);_noop 注入于过滤之后、execute 空操作,锁死。 - ext cloud-websearch-kill 次序锁改钉新真序(identity ask → hook → transport; kill-switch 钩子仍无条件先于传输,ask 放行也跳不过)。 - 探针 launch() 类型标注修正(#1134 的 13 条 TS2345;零断言变动)。 验收锚点 alpha-725-policy-chokepoints.cases.ts:17 pass / 6 fail → 23 pass / 0 fail。 Fixes #1129
This was referenced Aug 26, 2026
jinjunnn
added a commit
that referenced
this pull request
Aug 26, 2026
…#1142) * fix(gates): #1134 把 packages/opencode 的 typecheck 接进门,并收掉它在 alpha 上的红 AC1 —— `bun run --cwd packages/opencode typecheck` 在 `alpha@8e30bdb` 上是 exit 2 / 2 条(票面记的 15 条里,13 条 `TS2345` 已由 #1135 在收 ac#1129 时顺手 修掉,commit 正文明写「#1134 的 13 条 TS2345;零断言变动」)。剩下两条: - `alpha-mcp-websearch-gate.test.ts:342` `TS2352` —— `denied as Exit.Failure<never, unknown>`。`fire` 的拒绝走的是 defect,错误通道类型是 `never`,那个 cast 两个方向都不重叠。改用真的类型守卫 `Exit.isFailure` 收窄。 - `alpha-websearch-failure.test.ts:644` `TS2345` —— R4 变异工具的 `execute` 返回 `Effect<…, WebSearchFailure>`,而 `Tool.Def["execute"]` 要 `E = never`。 补 `.pipe(Effect.orDie)`:那是它注册得上的必要条件,不是松绑(闸在 `call()` 的传输层,早于任何错误通道处理;orDie 只把 Fail 变 Die,而 `Effect.catchCause` + `Cause.squash` 对两者一视同仁)。 两个文件的断言一条没动,运行时逐字不变:45 pass / 137 expect 与 7 pass / 23 expect,改前改后相同。 AC2 —— 口径裁决 + 接门,证据落在 docs/architecture/quality-gate-environments.md §3.11: - 裁决「收进」。反方向要改 `packages/opencode/tsconfig.json`(上游文件, north-star 守卫下,动它要 ADR-033 owner 级收编),换来的还是**更少**的检查: 住在这个上游包里的 18 个 alpha 自有文件(ADR-043 谓词,两条检索轴 17/18 交叉验证,差集只有靠 marker 自报家门的 tool-display.ts)有 14 个在 test/ 下, 跑在 bun 上被直接剥类型 ⇒ typecheck 是它们唯一的编译期检查。 - 「让 ui-mac 也收进」不是本票能装下的,而且这句话要有数字才算勘破:摘掉 `*.test.ts` + `*.cases.ts` 两条 exclude = **1264 条**,只摘 `*.cases.ts` = **129 条**,首条都是 `Cannot find module 'bun:test'`(ui-mac 的 `compilerOptions.types` 里没有 bun 类型)。登记进 §6「已知不修」。 - 接门:alpha-ci.yml 的 typecheck job 加一步(本机实测该包 typecheck 4 秒)+ alpha-check.sh 第 [4/10] 步同一条命令 + CI_STEPS 登记 MIRRORED。防漂由既有的 local-gate-parity.test.ts 双向判(删一侧即红)。 Fixes #1134 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QHDS2BFKuzm9uNH1svU2oj * fix(gates): #1134 把 CI_STEPS 的 `MIRRORED` 从一句登记变成一条断言(typecheck 这一类) 本票接门之后跑变异实验,发现门只有一半:上面三条 CI_STEPS 断言比的全是**步骤名** (CI 有没有这一步 / 对照表登没登记 / 档位合不合法),没有任何一条问过 「alpha-check.sh 真的跑那条命令吗」。 实测(2026-08-26,变异 B3):把第 [4/10] 步里 `bun run --cwd packages/opencode typecheck` 那一行删掉、CI 那一步与 `MIRRORED` 登记都原样留着 —— local-gate-parity **15 pass / 0 fail**,而本地那半道门已经不存在。本 portfolio 的合并路径是 「本地判绿 ⇒ `--admin` 合」,CI 那一格恰恰是被绕过的那一道 ⇒ 假绿的是**真正在用** 的那一半。同形态前例:frontend-patch-roundtrip.test.ts 第十四条(失效形态⑧)。 第十六条从 workflow 解析出全部 `bun run --cwd <pkg> typecheck`,逐条要求 alpha-check.sh 里真有那一行,并带解析自检(解析不到 ≥4 条即判「本次测量作废」 而不是绿)。诚实边界只覆盖 typecheck 这一类命令 —— 它们形状统一、能无歧义解析; 别的步骤本地或是脚本、或带 env 前缀、或登记成超集/降级档,不在本条覆盖内。 登记簿由 `bash scripts/assert-gate-files.sh --update` 写回(15 → 16),复核 158 个闸门文件全部在位、条数与登记精确一致。 Refs #1134 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QHDS2BFKuzm9uNH1svU2oj --------- Co-authored-by: jinjunnn <slmbaovanetti99@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
jinjunnn
added a commit
that referenced
this pull request
Aug 26, 2026
§8 写的「#1128/#1129 均已关闭 ⇒ §3 那三行都已落地,本稿不再有悬空依赖」是错的。 那句话只看了 issue 状态为 CLOSED 就下,没读交付物 PR #1135——而它正文恰好声明 了相反的事:「AlphaToolPolicy.Service(策略文档轴)未接进咽喉……dynamic inventory/API 同理留给 #1130 消费面」。 实读(两条独立检索轴交叉一致):ToolPolicy 面只有 schema + permission 三个文件, 零 route / 零 SDK / 零 IPC / 零 renderer 消费者;AlphaToolPolicy 模块外零引用 (对照 Permission.node 有 7 处装配点);咽喉 session/tools.ts:86 与 :128 读的是 ruleset 轴 Permission.merge(agent.permission, session.permission)。 ⇒ 用户在本节 setRecord 写下的 disabled/ask,目录与执行面读不到。照本稿原样实现 会让 #1121 那个已实测缺陷在 Settings 层复活——正是本 REQ 要杀死的东西。 status: approved 保留(视觉/交互/9 型文案/六帧仍是基线);变的只是 §3 那三行回到 「契约,未落地」,并新增 §9 记录更正与地面真相。 Claude-Session: https://claude.ai/code/session_01QHDS2BFKuzm9uNH1svU2oj Co-authored-by: jinjunnn <slmbaovanetti99@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1129
Refs #723(REQ-131 父需求,不用关闭关键词)
Refs #1121(本 PR 落地即消失的 P1 缺陷)
方案基线:#724 CLOSE_DECIDE §6(E1–E7 表)+ §9 第 2 条。消费 #1128(PR #1131)交付的同一套引擎语义(canonical identity 键 + Permission 引擎 + session grants),不另造第二个审批引擎/第二张 identity 映射。
每条接缝怎么接的
session/tools.ts公共register()上的 identityGate:每个注册工具的 execute 被包一层,先按canonicalToolIdentity(display.identity)走现有Permission.ask(deny ⇒ 具名响亮拒绝、零 hook 零副作用;ask ⇒ 挂起等批准,once/always 会话语义即 #1128 的 grants;allow ⇒ 不加打扰,ability 闸原样保留)。闸在 wrapper、tool.execute.before在被包的 execute 内 ⇒ policy 早于 hook 是结构性的。ruleset 每次调用重新求值(stale/cached 工具对象拿不到旧宽松态)。E2 三个 host 工具保留各自read+ server/URI ability 闸:437-443)移除 —— 留着会让once一次批准走不完一次调用invokeChildTool的 identity ask 上移到tool.execute.before之前;disabled child 不进 child catalog(既有visibleTools过滤,本 PR 补运行期判据)workflowPreapprovedToolNames已只收 effective enabled(ask 排除、disabled 不在 prepared.tools),探针 E5a/E5b 在 base 上已绿;executor 的「二次重读」由 identityGate 对prepared.tools[...].execute的每次调用天然成立prompt.tshandleSubtask 在任何持久化/hook/execute 副作用前,用同一 Permission 引擎按 exact canonical ask(原:284-288只完成 deny;deny 检查保留为双保险)ask: () => Effect.void);新增负向锁:identity+ability 全 deny 时 ingestion 照样完成、全程零待批host::StructuredOutput在Permission.disabled目录闸免疫(exact canonical;deny-all 也移不掉;缺 identity 不享豁免),执行面它本就不经 register;_noop注入于目录过滤之后、execute 空操作,两者均有锁死测试验收锚点(#725 harness,一字未改断言)
17 条已绿零退(含 MCP 的 B1/B5/B7/B8/B9/B13 —— ask 移位后语义逐条保持)。
变异实验(摘线 ⇒ 翻红;各窗口 ≤1 分钟,先 commit 后实验,实验毕
git checkout --还原并复核)identityGate接线(register 恢复直通),03:47:53Z–03:48:43Z新增闸门(已登记
scripts/gate-files.tsv,assert-gate-files.sh实测 158 文件条数精确一致)test/tool/alpha-tool-policy-execution-gate.test.ts(7 条):E1/E2/E3 + 两条 sentinel —— 探针是.cases.ts不进 bun test,这份才是常驻门test/tool/alpha-code-mode-child-policy.test.ts(3 条):E4 运行期判据(ask 未放行 ⇒ 钩子零触发/传输零调用;放行 ⇒ 次序恰为 ask→hook→transport;目录拒的 child 只有它消失)test/session/alpha-subtask-attachment-policy.test.ts(3 条):E6 deny/ask 运行期判据 + E7 排除锁E4/E6/E7 由此从「源码级确认」变成运行期可判;#725 VERIFY 复跑时按基线 §9 重写完整矩阵,本 PR 的取证文档只加了一条带日期的落地附注。
ext 次序锁改写(唯一动到的既有判据文件,alpha 自有)
packages/ext/src/cloud-websearch-kill.test.ts原钉「trigger 早于 ask」——那是旧引擎形态的机械化。基线 §6/§9 明确要求 policy/ask 早于 hook(E1「policy 必须早于 tool.execute.before」、E4「在 hook 之前」、退出条件「ask-before-hook/side-effect」),两者相撞。改钉新真序且保证不减:kill-switch 钩子仍无条件先于传输、任何 ask 放行都跳不过它(replica 断言从「连 ask 都没走到」改为更强的「ask 已放行,callTool 仍为零」);另补一条「hook 与传输之间不许再出现 ask」锁死 E3 去重不回潮。43 条全绿、登记条数不变。门(本地实测,CI 口径;base fail-set = 空)
packages/opencode包级 typecheck(不在门集,advisory):base 15 条 → 本 PR 2 条(余 2 条为既有,归 #1134)。修的 13 条全在探针launch()的类型标注(签名 + 体内两处 cast),零断言变动。push 用
--no-verify:pre-push 钩子跑在共享主 checkout 上,并行 lane 期间不碰;上表即本地门的全量真实输出。push 后已核对core.hooksPath仍为.githooks。主动没做的(与原因)
AlphaToolPolicy.Service(策略文档轴)未接进咽喉:harness 的层图不含该节点(加硬依赖 = 23 条全崩),且该文档轴的编译落点是 [REQ-131][CODE] 设置页新增「工具」节:按来源、服务、单个工具设置停用/询问/允许 #1130 的 Settings 物化;咽喉消费的是同一引擎的 ruleset 轴([REQ-131][CODE] 解析并持久化分层工具策略 #1128 的 grants/合成语义原样生效)。dynamic inventory/API 同理留给 [REQ-131][CODE] 设置页新增「工具」节:按来源、服务、单个工具设置停用/询问/允许 #1130 消费面。文档影响
CHANGELOG
[Unreleased]Fixed 一条(用户可见:「设成询问/禁用现在执行面真的管用」);#725 取证 README 加带日期落地附注;无架构/契约文档变更(权威在 #724 CLOSE_DECIDE)。🤖 Generated with Claude Code
https://claude.ai/code/session_01QHDS2BFKuzm9uNH1svU2oj