Ironbank 是 Capsem 的黑盒验收测试体系,用于发布、VM、网络、模型、MCP、凭据代理、包管理器、doctor、基准与安全等验收工作。核心规则是不查看 Rust 或产品内部实现来决定预期行为,测试只依据公开契约、CLI 帮助、文档、路由响应、生成的 schema、封闭夹具定义、日志、数据库行和已安装包元数据编写;若契约缺失,则为缺失契约编写 RED 测试。
一致性规则要求每个可移植发布门禁都放在 just test 中。本地 just test 会重建两类产物并运行完整配方;二进制与 profile 发布 CI 复用同一批已检入模块,同时拉取未变更的产物族,绿色拆分任务不能替代这些模块。共享入口包括工作区/运行时测试、覆盖率下限、capsem-doctor、Ironbank 验收、基准、产物检查、所有 Web 界面,以及 Docker/systemd Linux 安装加真实 guest-shell 证明。只有不可避免的平台边界可留在外部,且每个都必须指明其权威最终门禁。
just test 是可移植 CI 工作的严格超集。CI 工作流可运行较小的相关切片,但任何可移植产物都不能只在 workflow YAML 中构建。VM 资产发布使用与 just test 相同的 just _build-kernel 和 just _build-rootfs 原语,通过 just _gate-assets 完成;规范门禁会为 arm64 和 x86_64 重建每个 profile,校验所有必需产物与清单,并启动每个重建的主机架构镜像到 guest-shell 标记。输入契约测试不能替代对实际构建产物的测试。
该核算也适用于主机包:macOS 本地 just test 必须构建真实 release 模式 .pkg 和两种 release 模式 Linux .deb 架构,然后对这批确切包执行生产 host-SBOM 生成器。仅 Linux 的 Rust 分支必须在 Docker 中以非 root 用户通过 Linux CI 使用的同一已检入 runner 本地运行。生成文件必须通过生成并比较的幂等门禁;静默刷新过期输出不算绿色测试。
硬编码发布选择同样属于未核算状态。规范门禁必须运行基于 grep 的选择守卫,覆盖当前与计划中的 profile 名称(code、co-work/cowork、terminal、termional、gui)、公开渠道名、清单 URL、面向用户的请求体、原生 postinstall 脚本以及两个序列化发布命令。默认值可在 API 边界显式声明,但下游 profile/channel 路由必须携带所选值,损坏的包必须失败关闭而非回退到 stable。
多架构包中,required 适用于匹配发布主机的包。交叉产物仍会构建并做结构校验,但不能仅因无法在相反架构 runner 上原生执行而提前失败。带标签的 arm64 CI 必须安装并验证其确切包/服务,即使该托管 runner 缺少 KVM;x86_64 CI 还负责强制的确切包 guest-shell 证明。
经常接近托管 runner 观测生命周期的确切门禁不构成发布证明。运行时余量是账本的一部分:记录各阶段耗时,将重复的同龄终止视为确定性预算缺陷,并要求昂贵的生产轨道在花费另一次 CI 运行前先在本地通过。并行工作只有在隐藏工作区、容器标签、输出和清理相互隔离并有测试覆盖时才可接受。
在并发产物通道开始前,通过 /dev-cache 和通用类型化注册表强制 Docker 缓存。策略拥有每个缓存的描述、范围、热大小、最大大小和清理策略;验收代码不得检查 Docker 数据根或重建后端特定容量逻辑。
必需形态:套件位于 tests/ironbank/;runner 为通过 Capsem、capsem-doctor、VM 会话、封闭本地服务、UDS 路由、HTTP 路由、日志和 SQLite 账本运行的 Python 黑盒测试;一个确定性刺激断言完整路径:客户端结果、解析事实、CEL/安全决策、检测/执行行、协议行、结构化日志、状态计数器、UDS 路由、HTTP 路由和 UI JSON 形状;每个发出的字段都做精确值断言、类型不变量断言或明确标记不适用;未知 DB/日志/路由字段会使测试失败,直到字段账本更新。
禁止项:将 Rust 解析器/单元证明作为 Ironbank 门禁;公共网络依赖;对 Capsem 路径的 mock;回退路由;仅状态码重放;行存在检查;skip、skipif、slow、optional 标记或手动 OAuth/客户端流程作为发布证明。
包管理器方面:安装不是证明。对于 apt、npm、uv、pip、node 或 profile 包轨道,需断言二进制存在/版本/哈希(如相关),并运行命令证明包能完成其工作。例如 zstd 必须压缩和解压已知字节并与原始匹配。