IronClaw 权威词汇层 ironclaw_host_api:零依赖契约 crate 的工作规则、密封证据与安全边界解析
2026/9/23 15:48:22 网站建设 项目流程
  • 人工智能
  • AI 应用
  • 交互助手
  • AI Agent

【免费下载链接】ironclaw

IronClaw is an Agent OS focused on privacy, security and extensibility

项目地址:https://gitcode.com/gh_mirrors/iro/ironclaw
点击查看免费下载

ironclaw_host_api是 IronClaw(一个聚焦隐私、安全与可扩展性的 Agent OS)中全工作区共享的权威词汇层:它描述跨越所有特权边界的事物——身份、作用域、路径、挂载、能力、动作、决策、审批、密封的Authorized见证与CapabilityDispatcher端口、净化后的解析与失败词汇、进出站描述符、运行时与信任词汇,以及完整的规范 turn 词汇——但不执行其中任何一项。这篇指南以该 crate 的规范工作规则文档(AGENTS.md)为主体,结合其 README.md 与源码实现,讲解它的边界纪律、六条工作规则、两个关键陷阱、密封证据机制以及本地验证方法,帮助你在该仓库中正确命名权威类型、规避常见误用。

一、先定位:这个 crate 是什么,以及为什么它必须"零依赖"

1.1 契约层家族中的地基

ironclaw_host_api位于crates/contracts/家族(全部 6 个契约 crate 之一),是整套系统的词汇层:全家族只描述跨越权威、宿主或产品边界的概念,不执行、不持久化、不做决策。家族规则(crates/contracts/AGENTS.md)给出了类型入驻此层的四部分录取测试

  1. 它命名了一个跨越权威、宿主或产品边界的概念;
  2. 它对厂商、运行时、存储和部署保持中立;
  3. 两个或更多消费者需要它且无需导入所有者;
  4. 它不携带执行、持久化、策略引擎或工作流。

对于依赖倒置端口,两个消费者是"声明方调用者"与"实现方所有者"——一个调用方 crate 加一个实现方 crate 的端口通过(这种分离正是端口的意义),而调用方与实现方同属一个 crate 的端口不通过

从依赖矩阵看,该家族处于contracts < substrates < runtimes < kernel < loops < products < app层级的最底层,向下没有任何依赖——"往下是死路,本家族即地板"。这正是ironclaw_host_api被称为"整个系统零依赖权威词汇"的原因。

1.2 为什么零内部依赖是安全属性而非风格偏好

README 明示:约 53 个工作区 manifest 依赖此 crate(可在仓库根目录复现:grep -rl '^ironclaw_host_api = ' --include=Cargo.toml crates tests Cargo.toml | wc -l),几乎覆盖每个家族。因此,ironclaw_host_api的零内部依赖姿态就是整个系统的安全属性:任何添加在此处的依赖都会变成整个系统的依赖。对应的强制执行门是ironclaw_architecture_tests中的reborn_crate_dependency_boundaries_hold(见 crates/app/ironclaw_architecture_tests)。

与其配套的还有一系列不变式:

  • 无框架/驱动依赖——不允许 axum/hyper/tower/reqwest/tonic、libsql/rusqlite/sqlx、wasmtime 等(reborn_contracts_crates_hold_no_framework_dependencies);
  • 尺寸上限——每个契约 crate 有生产行数上限,由显式评审才能提高(reborn_contracts_crates_carry_a_checked_size_ceiling);
  • 无通配符再导出——仅模块限定导入(规则写在 src/lib.rs)。

从 Cargo.toml 看,其实际依赖全部是通用基础设施:serdeserde_jsonuuidchronothiserrortracingsha2zeroizerust_decimalasync-trait,以及唯一可选特性test-supportdep:jsonschema)——这是仅开发期的接缝,用于编译共享的TestDispatcher双倍实现与消息契约一致性辅助,任何发布产物都不会启用。

二、从哪里开始:面向贡献者的上手路径

工作规则文档(AGENTS.md)给出清晰的起点:

  1. 先读 README,了解 crate 是什么;再读 Cargo.toml,看清真实的依赖与特性形状(注意test-support特性只在cargo test或明确开启时生效)。
  2. 契约文档优先于直觉——在改变任何行为之前,必须查阅三份冻结契约文档:
    • docs/internal/reborn/contracts/host-api.md
    • docs/internal/reborn/contracts/kernel-boundary.md
    • docs/internal/reborn/contracts/capability-access.md
  3. 契约与代码冲突时,停止:不要静默地"顺手修正"行为,而应把任务当作一次契约变更请求来处理——这正是"契约高于实现"的纪律体现。

此外,README.md 还给出使用边界:需要扩展表面时去ironclaw_extension_contracts,产品膜或线上 DTO 去ironclaw_product_contracts,循环端口去ironclaw_loop_contracts,任何需要执行、持久化或记录日志的东西去上层的所有者 crate。

三、六条工作规则:词汇层的行为边界

3.1 只拥有共享权威词汇,行为保持在类型自身形状上

本 crate 只保留类型自身形状上的校验/序列化辅助不包含运行时执行、持久化、HTTP 客户端、策略引擎或产品工作流,也不得依赖任何其他ironclaw_*crate。这条规则由reborn_crate_dependency_boundaries_hold断言强制执行——如前所述,这是整套系统的安全属性。在 src/lib.rs 的文档注释中可看到明确声明:"本 crate 有意只包含承载权威的类型、校验与序列化契约;运行时行为属于 system-service crate(filesystem、resources、extensions、WASM、MCP、auth、network、kernel)"。

3.2 能力表面策略是"中立的可见性词汇"

capability_surface模块拥有CapabilitySurfacePolicy及其能力 ID 作用域代数(见 src/capability_surface.rs)。关键纪律:

  • 策略只收窄模型可见的能力绝不授予调度权威
  • 解析与强制执行仍然留在ironclaw_loop_hostironclaw_host_runtime
  • 策略默认失败关闭CapabilityIdScope默认是Only(空集),即不显示任何能力 ID;allow_all()才开放全部运行时与效果种类(Wasm/Mcp/Script/Sandbox/FirstParty/System,以及 ReadFilesystem、WriteFilesystem、Network、UseSecret、ExecuteCode、SpawnProcess、DispatchCapability、ModifyExtension、ModifyApproval、ModifyBudget、ExternalWrite、Financial 等效果)。

源码提供了allow_onlynarrow_to_capability_idsdeny_capability_idswithout_approval_gated等组合算子,并在intersect/without中实现了OnlyAllExcept两种作用域的归并代数——例如两个Only求交集、OnlyAllExcept合并后收窄为Only、两个AllExcept合并后取并集。测试断言了"默认策略失败关闭"、"allow_only 再 deny 归并为一个作用域"、"无审批门控后不再渲染可询问能力"等行为。

3.3turn是完整规范语言,不是部分语言

如果某个 crate 需要命名一个 turn——作用域、ID、引用、状态、门种类、事件游标、起源适配器——它就应该依赖本 crate,绝不要依赖ironclaw_turns。当 turn 类型必须在 turn 内核之外被命名时,答案是把它移到这里,而不是从ironclaw_turns再导出。这在 src/turn.rs 模块头部有完整说明:ironclaw_turns拥有协调、准入、调度、持久化与状态转换;而本模块拥有这些服务、产品表面与通道适配器之间交换的完整稳定语言——类型化 ID 与引用、turn 作用域/参与者/所有者、运行状态及其门对应、事件游标、运行起源适配器身份、净化后的失败/取消形状。

turn模块的实打实内容包括(见 src/turn.rs):

  • 类型化 ID 家族TurnIdTurnRunIdCapabilityActivityIdTurnCheckpointIdTurnLeaseTokenTurnRunnerIdEventCursor(单调位置,用于投影与投递交接的断点续读),均为基于Uuid的 newtype;
  • 有界引用宏bounded_ref!loop_ref!:前者校验非空、≤256 字节、无控制字符;后者额外要求前缀(exit:msg:result:gate:);
  • TurnScope/TurnActor/TurnOwner:turn 的作用域、参与者与所有者词汇(个人Personal{user}与共享代理SharedAgent{agent,project}),以及product_ownerto_resource_scope等推导辅助;
  • TurnStatus状态机QueuedRunning、五种Blocked*(Approval/Auth/Resource/DependentRun/ExternalTool)、CancelRequestedCancelledCompletedFailedRecoveryRequired,并提供is_terminalis_blockedkeeps_active_lock谓词;BlockedExternalTool是非终态、保持活动锁的特殊状态(模型调用了调用方声明的外部工具,运行被暂停并交还控制权给 API 客户端);
  • GateKind权威对应表:每类阻塞状态唯一对应一种门种类,from_status/blocked_status是"添加一种门 = 编译器强制在此处编辑"的单点对应关系;BlockedReason是其携带数据的形态(Auth门还携带凭证要求);
  • 净化失败词汇SanitizedFailure(类别必须是蛇形小写 ASCII,细节字段可被public_projection()剥离)、SanitizedCancelReasonModelInvalidOutputDetailReason(九种固定安全摘要 + 512 字节上限 + 纯 ASCII 校验);
  • 产品上下文ProductTurnContextTurnOriginKind:WebUi/Inbound/ScheduledTrigger;TurnSurfaceType:Direct/Channel;RunOriginAdapter(1..=512 字节有界适配器名);channel_context(通道侧第三方文本,仅作咨询);execution_policy(无人值守执行的主机密封限制))与SubmitTurnResponse::Accepted(携带 turn_id、run_id、状态、解析出的运行画像、事件游标、已接受消息引用)。

turn.rs内置测试还验证了"TurnGateRef仅做有界校验而LoopGateRef做前缀校验"的对比、RunOriginAdapter在 512 字节边界上的接受/拒绝、旧 JSON 的无损加载与序列化省略规则等。

3.4 无通配符再导出:模块限定导入

lib.rs只暴露模块,绝不暴露扁平的 prelude;消费者必须写成ironclaw_host_api::<module>::<Type>(例如scope::ExecutionContextids::ExtensionId)。crate 根唯一的条目是Timestamp别名pub type Timestamp = chrono::DateTime<chrono::Utc>)。理由很务实:按模块粒度的 glob 再导出会隐藏消费者到底依赖哪个模块——而这正是将来把某个词汇族从本 crate 切分出去时需要看清的东西。源码注释明确警告:"不要在这里重新加入按模块的 glob 再导出"。

3.5 HTTP 入口契约只含路由/策略词汇

监听器绑定、路由器挂载、认证执行、作用域提取、请求体/速率限制、CORS/Origin 校验、审计发射与效果分发,全部属于宿主组合与传输层(例如ironclaw_host_ingress、webui transport),不属于本 crate。本 crate 的ingress/http模块只承载描述性词汇:路由/策略/监听器描述符与RuntimeHttpEgress端口。

3.6 可序列化 API 类型的三条红线与一个例外

可序列化 API 类型不得包含:裸HostPath、机密(secrets)、后端特定错误细节——无论是在错误、事件、快照、日志还是文档中。唯一狭窄例外是有界ModelDiagnostic:生产者必须先擦除凭证值并围栏注入形状的文本,才能携带模型恢复所需的原因。这体现了"模型可见内容必须净化"的一致设计哲学,与SanitizedFailure::public_projection()剥离细节的行为一脉相承。

3.7 其他规则:host-port 目录、强类型优先、编辑范围

  • Host-port 目录:新的 host-port 常量必须添加到host_port::default_host_port_catalog里、常量名的旁边——而不是在某个内核调用方里。目录只是校验辅助,不是权威来源。
  • 强类型优先:形状已知时,优先使用强枚举/newtype 而非字符串。
  • 编辑范围:除非契约明确要求修改相邻 crate,否则把改动保持在本 crate 内部。

四、两个关键陷阱:类型混淆与薄授权令牌

4.1TurnGateRefids::GateRefLoopGateRef是三种不同的类型

这是文档列出的第一个也是最重要的陷阱:

类型职责校验
turn::TurnGateRef面向循环的路由引用(bounded_ref!仅非空、≤256 字节、无控制字符
loop_ref!(..., "gate:")生成的LoopGateRef带前缀校验的循环门引用必须以gate:开头,后缀仅限 ASCII 字母/数字/_/-/.
ids::GateRef不透明的 uuidGateRecord无前缀概念

关键纪律:生产环境铸造gate:approval-{id}/gate:auth-{id}is_auth_gate_ref之类的谓词按此前缀匹配——但前缀只是约定,类型本身并不强制。因此:

  • 不要"修复"传无前缀值的调用方或测试夹具;
  • 不要未经迁移所有已持久化引用就收紧构造函数;
  • 二者互不为别名,任何 crate 都不得把其中一个再别名为另一个的名字。

src/turn.rs 的测试turn_gate_ref_is_bounded_only_unlike_the_prefix_validated_loop_gate_ref直接验证了这一对比:"gate-alpha""custom-auth-gate""approval:missing""gate:auth-1"都是合法的TurnGateRef,而LoopGateRef::new("gate-alpha")必须失败;空串、257 字节、含控制字符的TurnGateRef也必须失败。

4.2HostPortGrant是有意保持薄的"作用域视图授权令牌"

HostPortGrant是包裹HostPortId薄作用域视图授权令牌。文档明确禁止给它添加衰减(attenuation)/作用域/过期字段——如果将来需要这类行为,应引入一个独立的、带衰减的授权类型,而不是扩大这个线上形状。

五、密封证据:不要扩大验证边界

5.1 两个唯一实现者与一个禁令

  • 不要实现HostProtocolAuthenticatorChannelIngressVerifier也不要添加第三个授权类型
  • 每个 trait恰好允许一个生产实现者ironclaw_webui(bearer/session,信任阶段 T1)和ironclaw_extension_host(channel/webhook,T2)。
  • 这由reborn_sealed_evidence_mint_ratchet固定,因为第二个实现者可以为未经认证的请求伪造已验证声明

5.2 见证令牌模式:编译器半与测试半

授权类型与authorized::AuthorizationGrant使用同样的见证令牌模式:字段对本 crate 私有,提供的 trait 方法体是唯一来源,覆盖实现无法构造一个实例。保持它们Clone/ 非Default/ 非Deserialize。这构成结构屏障(私有字段 + 授权门控构造),而 companion 的ironclaw_architecture_tests测试把impl CapabilityAuthorizer限制在 kernel crate——即"类型密封 + 测试密封"双保险。

这一点在 src/authorized.rs 有完整实现:Authorized::seal消费AuthorizationGrant(零尺寸见证,其唯一构造函数是CapabilityAuthorizer::authorization_grant);Authorized一次性、绑定运行通道、有截止期限的密封证明——字段私有、不可Clonedispatch()消费它、is_expired超过截止期限即失败关闭、未分发的见证走abort()显式释放资源预留(绝不使用Drop,因为析构器不做异步 I/O,泄漏的见证由租约过期回收)。seal还会校验描述符能力 ID 与调用能力 ID 一致,不匹配则返回AuthorizedSealError::CapabilityMismatch

5.3 测试接缝与特性门的历史教训

  • 需要已验证证据的测试使用ProtocolAuthEvidence::test_verifiedtest-support接缝);必须持有授权的测试双倍放到tests/目录下(如 tests/authorized_seal.rs)——绝不放在内联#[cfg(test)]模块里,因为棘轮(ratchet)按生产代码扫描内联模块。
  • 这取代了旧的host-auth-mintcargo 特性。不要在此处重新引入特性门:cargo 会在一次构建中统一特性,一个消费者的 opt-in 会在整个工作区重新打开该特性。

六、验证:本地检查与边界门

文档给出的验证路径分三层(对应cargo命令):

# 快速本地检查:本 crate 测试套件 cargo test -p ironclaw_host_api # 依赖或 API 变更后:边界 / 密封 / 上限门 cargo test -p ironclaw_architecture_tests

第三层是调用方层测试优先:当辅助函数为调度、持久化、网络、机密、审批、资源、事件或进程副作用设门时,优先写调用方层测试(而不是在本 crate 内写行为测试)。README.md 的 Tests 一节给出了同样的两条命令,并补充说明test-support特性是 dev-only 接缝(共享TestDispatcher双倍与消息一致性辅助),从不被发布产物启用。

从实现证据看,本 crate 的测试面相当完整:tests/下有authorized_seal.rshost_api_contract.rsmodel_result_preview_contract.rsprotocol_auth_evidence_seal.rs四个集成测试文件;turn.rscapability_surface.rs等模块内置大量单元测试,覆盖线上形状的序列化往返、失败关闭默认值、旧 JSON 兼容加载等契约细节。此外Cargo.toml的 dev-dependencies 无条件编译 32 个规范 JSON Schema 文件(schemas/messaging/*.json)以确认它们是合法的 draft-07 JSON Schema,保证纯cargo test -p ironclaw_host_api(不带--features test-support)也能运行该套件。

七、总结:这套规则的深层逻辑

把 AGENTS.md 的规则串联起来,可以看到一条清晰的安全主线:

  1. 零依赖→ 全工作区共享词汇而不引入传递依赖风险;
  2. 只命名、不执行→ 权威类型与机制实现彻底分离,任何执行、持久化、网络行为都留在上层所有者 crate;
  3. 密封证据→ 唯一的授权铸造路径被"编译器半 + 测试半"双保险锁定,伪造一个已验证声明在结构上不可能;
  4. 净化输出→ 一切可能到达模型或外界的序列化类型都经过擦除与围栏;
  5. 单一权威对应→ 门种类、状态、前缀约定、host-port 目录都收敛到单点定义,避免分散的 match 表漂移。

对于在 IronClaw 仓库中工作的开发者,这份文档的实际价值在于:当需要命名一个权威、身份或 turn 概念时,先问自己它是否符合四部分录取测试;当它属于本 crate 时,严格遵守零依赖、无 prelude、密封铸造与净化序列化四条红线;当契约与代码冲突时,把它当作契约变更请求而非顺手修复。这样,ironclaw_host_api才能持续扮演整个 Agent OS 的"安全词汇地基"角色。

  • 人工智能
  • AI 应用
  • 交互助手
  • AI Agent

【免费下载链接】ironclaw

IronClaw is an Agent OS focused on privacy, security and extensibility

项目地址:https://gitcode.com/gh_mirrors/iro/ironclaw
点击查看免费下载

相关推荐

上一篇:Ramalama 项目使用教程
下一篇:为什么选择WebGui:终极轻量级Web端IMGUI解决方案的优势分析

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询