让一个产品“接入 Agent Foundation”,最容易写成几行配置:打开 Memory、打开 Evidence、打开 Graph,再给调用方一把 credential。这个方案看起来快,却会留下一个根本问题:这些布尔值到底是在表达产品愿望,还是在证明运行时真的具备能力?
如果产品能靠自己的配置声称“我有 ReviewDecision”“我有 Graph executor”,Registration 就不再是权威,只是一张自填表格。如果不同入口各自创建身份、能力和 scope,同一个产品还会出现两套互相矛盾的 Registration。
Agent Foundation 最终收敛成一条唯一链路:
Product Recipe 表达需求;Compiler 解析需求;accepted Provider Claims 证明 provider 保证;Runtime assembler 找到唯一真实 component owner;Registration Authority 重新校验并持久化 receipt;actual principal 最后打开受限句柄。
技术解释图:Recipe、compiled plan、Provider Claims、Runtime owner 与 Registration 必须连续成立;任何一环缺失都会 fail closed。
查看 Agent Foundation 项目总览 · 打开本文交互图
Recipe 只能说“我需要什么”
一个 Product Recipe 可以声明:
- 需要 Context read;
- 需要 Memory governance;
- 需要 Evidence authority;
- Graph Proposal 采用
proposal_only还是review_required; - dependency profile、operation budget、failure semantics 和目标范围。
但 Recipe 不能声明“这些能力已经存在”。这是第一条关键不变量:需求声明不是授权证明。
这个区别看似语义化,实际防止了 adopter 通过自定义 boolean 或伪造 service claim 绕过 Foundation。产品可以选择能力,却不能成为 Foundation 能力的证明者。
编译阶段不是拼 JSON,而是验证依赖闭包
Compiler 会把 Recipe 变成 capability plan。它检查的不只是能力名称,还包括依赖、边界和组合是否合法。
例如,review_required 的 Graph Proposal 不只是“多一个审核按钮”。它要求至少存在:
- Graph data plane;
- Evidence authority;
- Graph Proposal authority;
- ReviewDecision execution;
- 能够承担这些能力的真实 Runtime component。
任何一项 unresolved,编译结果就不能被包装成一个可用 Registration。普通 Recipe 也不会因为系统里存在高级 provider,就自动继承 Graph 或 Review 权限。
Provider Claims 与 Runtime ownership 必须同时成立
Provider Claim 回答“这个 provider 承诺什么”,Runtime component ownership 回答“运行时究竟由哪个组件承担”。两者缺一不可。
只接受 claim 而不检查 component,会出现纸面能力:编译结果说支持 Graph,真正打开 Runtime 时却没有组件负责。只检查 component 而不验证 accepted claim,则会让一个对象因为恰好实现了某个接口,就获得未经合同接受的权威。
Foundation 因此要求三项一致:
| 层次 | 回答的问题 | 不能替代什么 |
|---|---|---|
| Compiled plan | 这份 Recipe 需要哪些能力和依赖 | 不能证明 provider 已被接受 |
| Accepted Provider Claims | provider 对能力、限制和失败语义作出什么保证 | 不能证明 Runtime 已装配 |
| Runtime component owner | 哪个唯一组件真正承担能力 | 不能自行扩大 Recipe 需求 |
当 adopter 尝试注入 Foundation service claims 时,公共链路会以稳定错误拒绝,而不是“尽量继续”。
Register V2 为什么还要重新校验
编译成功不代表可以永远注册。编译到注册之间,Provider identity、Registration lineage、policy fingerprint 或 component binding 都可能漂移。
V2 Registration 因此不是简单保存 compiler 输出,而是在权威边界重新检查完整 binding set,然后原子持久化:
- Registration identity 与 lineage;
- exact compiled capability plan;
- accepted Provider Claims;
- selected Runtime components;
- scopes、role ceilings 与 policy fingerprints;
- 可供后续 open 验证的 receipt。
这使 Registration 成为可以被重读和核对的权威事实,而不是进程内临时对象。
一个 Registration,不等于一把超级凭据
同一个产品可以有 Agent、reviewer、revalidator、executor 等不同角色,但它们不应该共享 memory:admin 或万能 token。
Foundation 在 Registration 上冻结角色上限,再根据实际认证 principal 打开最小权限句柄:
- Agent 可以读取 Context 或提交候选,但不能审批自己;
- reviewer 可以读取被授权的治理状态并形成 ReviewDecision,但不能直接执行 Graph mutation;
- revalidator 可以消费 Evidence lifecycle 任务并更新支持投影,不能改变业务提案;
- executor 可以消费 durable outbox 并写真实副作用,但不能伪装成业务 owner。
实际 actor 与 represented business owner 被明确分开。请求体自报的 actor 不会覆盖认证 principal。
为什么要消除多条 Registration 接线
平台演进时,最危险的兼容方式是保留两套都能产生权威身份的入口。它会带来重复 identity、不同 scope 推导和无法判断哪个 Registration 才是真的。
Foundation 的处理不是给每个旧入口继续打补丁,而是保留兼容 facade,同时让所有入口最终投影到同一条 compose → assemble → register → open 权威链。V1 兼容只允许在语义完全一致时做精确投影,不能静默升级为 V2 高级能力。
AF-RA01 进一步移除了 Registration 建立过程对旧 Memory-shaped credential handoff 的依赖。Registration 使用自己的 read/write scopes,角色上限从 sealed binding set 推导,不再借用 memory:admin 代表跨域管理权。
一个采用方的实际接入顺序
对高级采用方,推荐的工程顺序是:
- 用业务语言列出需要的 Foundation 能力和明确非目标;
- 选择官方 Recipe fragment 或构造 capability-neutral Recipe;
- 提交 compiler,检查每项 requirement 是否被真实 accepted claim 满足;
- 检查每项 enabled capability 是否只有一个 Runtime owner;
- 创建并持久化 V2 Registration;
- 用实际 principal 打开最小权限 handle;
- 分别验证正常路径、缺 capability、伪造 claim、scope 不足和 lineage 漂移;
- 最后才运行产品工作流。
这里最重要的不是 SDK 调用顺序,而是不要在 Registration 尚未成立时,用产品私有 adapter、伪造 provider ownership 或直接数据库写入绕过去。
真实反例如何暴露了接线缺陷
TraceWise 的高级 Graph 接入曾经出现过一个有价值的失败:官方 capability helper 可以描述四项需求,但 compiler 找不到 accepted Provider Claims;使用产品自定义 requirement 后,assembler 又报告 enabled capability 没有 Runtime component owner。
这个反例说明 Graph Proposal 的底层实现本身存在,却还不能被一个外部高级 adopter 通过公共 Recipe 接线使用。修复没有发生在 TraceWise 的私有代码里,而是回到 Foundation 的 Provider Claim 和 Runtime ownership 根因层。修复后,fresh installed wheel 才真正完成 Registration、Evidence admission、Graph binding、review、outbox、独立执行和 receipt。
这也是 Registration 设计的价值:它让“内部测试能跑”和“外部产品能安全接入”成为两个必须分别证明的问题。
当前证据与边界
当前正式基线已经验证 capability-neutral Registration authority、公共 Recipe compiler、真实 Runtime ownership、principal-scoped handles、installed-package 工作流和限定 PostgreSQL/Neo4j 路径。完整源码回归记录为 305 passed、9 skipped。
仍然不能把这些结果描述成生产 IAM、TLS、Secret rotation、HA/DR 或多租户部署证明。Registration 解决的是能力、身份与权限合同,不会自动解决基础设施运维,也不会证明 adopter 的模型质量或业务效果。
最后的判断
一个安全接入模型的关键,不是“配置项够不够多”,而是系统能否证明:产品请求的能力、provider 承诺的能力、Runtime 真正承担的能力和 principal 最终获得的权限,是同一件事。
Product Recipe 到 Registration 的唯一链路,就是把这个证明变成可执行、可持久化、可复核的产品合同。
