fix(spec): ToolExecutionContext fails closed on missing actor — system is an explicit isSystem opt-in (#2991)#3078
Merged
Conversation
…m is an explicit isSystem opt-in (#2991) The AI tool-execution contract documented system-level (RLS-bypassing) execution as the default for a missing actor / toolExecutionContext — a contract-level fall-open across all built-in data tools (ADR-0096 E4, D1 invariant: no identity is never a grant of authority). - ChatWithToolsOptions.toolExecutionContext: omission now means an unauthenticated (RLS-on, sees-nothing) principal; executors MUST NOT fall back to system-level behaviour. - ToolExecutionContext: documents the fail-closed identity derivation (actor → user context; isSystem → system; neither → anonymous) and adds an explicit isSystem?: boolean opt-in mirroring the IDataEngine / IKnowledgeService convention, so 'run as system' is a deliberate, greppable choice — not the consequence of a forgotten field. - content/docs/ai/actions-as-tools.mdx: docs no longer advertise omission as the way to keep system-level behaviour for cron/internal callers; they now point at the explicit isSystem opt-in. Mirror of the #2981 knowledge/RAG fail-closed fix, applied at the contract layer. Cloud-side executor work is tracked cross-repo. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rao3tuTpJ8HPQV5fyxBoz
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 98 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rao3tuTpJ8HPQV5fyxBoz
os-zhuang
marked this pull request as ready for review
July 16, 2026 16:28
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.
修复 #2991(ADR-0096 E4 收敛出的合同级 fall-open)。
问题
AI 工具执行合同(
packages/spec/src/contracts/ai-service.ts)把 system 级(绕过 RLS)执行 文档化为缺失actor/toolExecutionContext时的默认行为,覆盖所有内置数据工具(query/get/create/update/delete/run_action)。任何忘记从req.user填充 actor 的 cloud 或自定义路由,都会让 LLM 的工具以完全权限运行——违反 D1 不变式("无身份绝不等于授权")。修改内容
ChatWithToolsOptions.toolExecutionContext:省略不再意味着回退到 system 级行为。合同现在要求执行器在缺失上下文时以未认证(RLS 生效、什么都看不到)主体运行数据工具——fail-closed,绝不 fall-open。ToolExecutionContext:接口文档新增身份推导规则(actor→ 用户上下文;isSystem→ system;两者皆无 → 匿名,绝不是 system),并新增显式isSystem?: boolean字段,镜像IDataEngine/IKnowledgeService的isSystem约定——"以 system 运行"从此是一个可 grep 的、深思熟虑的选择,而不是漏填字段的后果。actor存在时isSystem被忽略(最小权限优先)。content/docs/ai/actions-as-tools.mdx:文档不再宣传"省略toolExecutionContext以保持 system 级行为(cron、内部调用)",改为指向显式的isSystem: true选择加入。@objectstack/specminor):含迁移说明——依赖旧省略默认值的内部调用方(cron、迁移、服务端任务)需显式传toolExecutionContext: { isSystem: true }。保持
actor可选(而非强制):内部调用方合法地没有终端用户,它们现在通过显式isSystem表达意图。与 #2981 / ADR-0096 的关系
这是 #2981(knowledge/RAG fail-closed 修复)在合同层的镜像——framework 没有
chatWithTools执行器(grep 确认合同仅在ai-service.ts中出现),所以诚实的修复位置就是合同本身。Cloud 侧(跨仓库) 仍需:(a) 每个 AI 路由从req.user填充actor;(b) 缺失 actor 时默认匿名/拒绝的ExecutionContext,绝不isSystem。验证
packages/spec类型检查通过(tsc --noEmit)pnpm build+check:api-surface通过(公共 API 面无变化——新增字段在既有接口内)pnpm test:254 个测试文件、6883 个用例全部通过🤖 Generated with Claude Code
https://claude.ai/code/session_019rao3tuTpJ8HPQV5fyxBoz
Generated by Claude Code