商业交付的核心不是“把仓库压缩后发给客户”,而是把产品源码、客户代码和发布证据分清楚。BitzOrcas 用包、模板、许可证和独立门禁建立这条边界。
三个世界
| 世界 | 包含什么 | 允许的依赖方式 |
|---|---|---|
| 产品仓库 | Framework、Platform、Profiles、Hosts、Tooling 的完整源码 | 产品内部可用 ProjectReference 集成 |
| Consumer Solution | 客户拥有的 Host、业务模块和测试 | 通过私有 Feed 使用 PackageReference |
| 发布批次 | 不可变 nupkg、签名、provenance、SBOM、策略证据 | 只能由受控发布与 GA workflow 读取 |
产品仓库的集成便利不能泄漏到客户项目。模板输出不得引用产品仓库路径,也不得复制 Framework、Platform 或 Licensing 核心实现。
交付链
产品源码 → build / test / Release publish → pack 不可变 NuGet 包 → 生成 hash / provenance / SBOM / policy evidence → 签名和可信时间戳 → 上传认证私有 Feed → 模板生成 Consumer Solution → PackageReference restore → Runtime License 激活 → Commercial GA每一段解决不同问题:
- 包目录与 Profile决定“客户应该拿到哪些包”。
- 模板决定“客户拥有哪部分源码”。
- Feed entitlement决定“客户有权下载哪些版本”。
- Runtime License决定“部署实例有权运行哪些能力”。
- Commercial GA证明“这批包、证据和外部消费结果来自同一可信发布”。
包与 Profile
可发布项目登记在机器可读商业包目录中。Profile 是一组可复用包闭包,不包含重复实现。模板组合把 Profile、Host role、Generator、Endpoint/Job assembly 和 License Feature 一起投影到 Consumer Solution。
Generator 作为 PrivateAssets=all analyzer 直接进入声明的 Host,不能依赖 NuGet 的传递传播。这样生成行为对每个 Host 都是显式、可审计的。
发布列车与不可变性
同一个商业发布批次必须绑定:完整 40 位提交、统一包版本、包集合、每个 nupkg 的 SHA-256、签名者、provenance、SBOM、策略结果和外部 Consumer。只要其中一项变化,就应产生新批次;已经发布的包版本不能覆盖。
| 变化 | 能否沿用原批次 | 正确动作 |
|---|---|---|
| 只修改发布说明文字 | 取决于证据是否入 provenance | 保留审计记录并重新验证索引 |
| nupkg 内容或依赖变化 | 不能 | 升版本、重新打包和签名 |
| signer 轮换 | 不能悄悄替换 | 更新可信指纹并产生新证据 |
| SBOM/漏洞结果变化 | 不能忽略 | 重新执行策略门禁 |
| Consumer 模板变化 | 不能 | 新候选批次重新做仓库外消费 |
“同版本重新上传”会破坏缓存、签名、hash 和客户复现能力,因此不是补发方案。
谁对哪段负责
| 角色 | 核心责任 | 交付物 |
|---|---|---|
| 框架维护者 | 包依赖、公开 API、Generator 和模板边界 | 可打包源码与测试 |
| Release workflow | 可重复构建、pack、签名、上传、证据索引 | 不可变 artifact |
| 包平台 | Feed 可用性、认证、版本不可覆盖 | HTTPS restore 入口 |
| 安全/开源治理 | signer、漏洞阈值、第三方许可证策略 | 策略证据 |
| 商业运营 | Entitlement 与 Runtime License 签发 | 客户/部署授权 |
| 应用交付团队 | Consumer 配置、数据迁移、切换和回滚 | 目标环境验收 |
没有任何单一团队可以用“我的 Job 绿了”替代完整证据链。
一个例子:多租户授权平台的真实生成路径
以公开 Profile default-business-multi-authorization(RuntimeAdapter 任选其一)为例。注意边界:当前 15 个 Profile 都只生成 API Host——JobHost、Website 等属于后续独立采用,不能通过参数幻象出来。
- 模板把 ProfileChoice 推导为
default-business-multi+PlatformModule=authorization,从对应 ORM 的原生资产树复制; - 只生成 Consumer 拥有的
BitzConsumer.ApiHost 壳、Business Starter 业务模块骨架和 Unit/Architecture 两类测试; - AppHost 编排 SQL Server、Schema Migrator、API 与 RabbitMQ,authorization 变体追加授权 bootstrap 与独立持久化身份参数;
- Endpoint / DI / ORM Fluent Config 由 analyzer 形态的 Generator(
PrivateAssets=all)进入声明的 Host,不经传递传播; - 全部
BitzOrcas.*从私有 Feed restore 同一 releaseTrain 的包版本; - Profile 的 License Feature 闭包固化为静态要求,本地 Consumer Contract 在四类缓存隔离下验证 restore→build→test→publish。
如果模板生成了 src/Framework 副本,或出现指向产品仓库的 ProjectReference,这不是“方便调试”,而是交付边界失败。
验证机器可读清单
产品仓库中的商业包目录和 Profile closure 是交付事实源,文档不能手写另一份包列表。
# 校验目录、Profile 闭包和项目可打包性。dotnet test tests/BitzOrcas.Architecture.Tests \ --configuration Release \ --filter 'FullyQualifiedName~CommercialPackageCatalogTests'
# 在隔离 Feed 中验证真实 Consumer 能否恢复、构建、测试和 Release publish。dotnet test tests/BitzOrcas.Framework.ConsumerContract.Tests \ --configuration Release --blame-hang-timeout 12m目录测试通过说明声明内部一致;Consumer Contract 通过说明当前候选包可被仓库外项目消费;两者都不等于正式 Feed artifact 已通过 GA。
失败应该归到哪一层
| 失败 | 所属边界 | 不应采用的“修复” |
|---|---|---|
| Restore 403 | Package Entitlement | 给所有客户长期共享 Token |
| Host 报 License Unavailable | Runtime License | 关闭 License gate |
| 某租户功能不可用 | Tenant Feature | 修改全局 Runtime License |
| Consumer 缺包 | Profile/package closure | 复制产品源码到客户项目 |
| provenance hash 不一致 | 发布批次身份 | 从当前分支现场重打包 |
| readiness 不健康 | 运行环境 | 只看 /health/live 强行切流 |
当前状态怎么看
仓库已经实现商业包目录、Profile 闭包、Consumer 模板矩阵、本地 Consumer Contract、Runtime License 契约和 Commercial GA 验证逻辑。正式 GA 仍需商业发布环境提供真实私有 Feed、短期凭据、签名者、SBOM、策略证据和外部 Consumer artifact。
所以正确表述是:“GA 门禁能力已具备,等待真实发布批次输入”,而不是“代码合并后 GA 自动完成”。
交付完成的准确口径
只有目标发布批次同时满足以下条件,才能说商业交付完成:包和证据不可变、正式 Feed 可恢复、签名与策略通过、外部 Consumer 全流程通过、Runtime License 与部署上下文匹配、目标环境 readiness 和迁移完成、回滚条件可执行、观察期没有触发停止线。
若真实 Feed、短期凭据、signer、SBOM 或外部 Consumer artifact 尚未提供,状态应明确记录为“外部前置条件未就绪”,不能把本地合同测试的绿色结果改名为 GA。
本章导读
- Consumer 合同:为什么必须站到产品仓库外验证。
- 私有 NuGet Feed:如何初始化、配置、分发和轮换访问权。
- Runtime License:在线、离线、Grace、过期和撤销行为。
- 在线许可证签发:如何通过前端完成四眼审批、异步签发和分发。
- GA 门禁:发布 artifact 需要哪些输入与证据。
本章核心导航
- 01/05
Consumer 合同测试
用隔离 Feed 和仓库外项目验证 BitzOrcas 包闭包、模板边界、Generator 资产与 Release 发布。
- 02/05
私有 NuGet Feed 配置与运维
从 Feed 建立、Consumer 初始化、短期凭据分发,到候选包发布、GA 验证、轮换与事故处置的完整操作指南。
- 03/05
Runtime License
理解 BitzOrcas Runtime License 的自动管线强制、签名验证,以及 30 人以内内建社区权益的计量、配置与恢复边界。
- 04/05
在线许可证签发与分发
配置厂商许可证控制面、独立签名宿主与 Azure KMS/HSM,通过前端完成四眼审批、异步签发、下载、分发和吊销。
- 05/05
Commercial GA 门禁
准备 BitzOrcas 正式商业发布所需的 Feed、签名、provenance、SBOM、策略证据和外部 Consumer。