实施计划与验收
Contracts、Core、Admin 与 Infrastructure 的 Outbox/Ops Explorer 固定实施顺序和门禁
本阶段按 Contracts → Core Schema/Worker/Projector/Query → Admin BFF/UI → Infrastructure Evidence 顺序实施。后一个仓只能依赖前一个仓已发布的固定制品或已通过的内部契约;不使用本地相对依赖、Git 分支或复制类型文件联调。
在整个阶段内:
PUBLIC_ADMISSION_MODE=disabled;- 不接 Text/Media Gateway,不生成模型输出;
- 不新增 Meter Usage、Settlement、Release 或 Refund;
- 不迁移 Console/Studio Writer;
- 不引入外部 Broker;
- 不在 Admin 暴露写操作。
Stage 0:基线冻结
先把当前事实记录为回归起点:
- Run Admission 已原子产生 Run、Run Input、Manifest、Reservation、幂等结果和两条 Outbox。
- 当前事件是
run.created@1.0与wallet.reserved@1.0。 - 当前 Outbox 没有正式 Publisher、Delivery/Attempt、Consumer、Projection 或 Query。
- API Edge 准入前失败和 Replay 只有最小脱敏日志。
- Gateway 执行、模型 Output、Asset 登记、Meter Usage 与 Settlement 均未实施;本阶段不得用规划态页面或文档字段宣称已有这些事实。
冻结当前受控跨服务证据,避免新阶段测试把“创建 Outbox 行”误写成“已完成投递”。
Stage 1:Contracts
oceanway-contracts 发布新的精确版本,至少包含:
run.created@2.0严格 Payload 与 JSON Schema,包括指向 Run-levelRunAdmissionManifest的低敏executionManifestRef + executionManifestSchemaVersion、完整 Output Contract Ref/Schema/Digest Algorithm/Digest 四元组,并把operationId + correlationIdRefinement 为必填非空稳定 ID。事件与 Manifest 的 Actor/Tenant/Access/Authentication/Authorization/Product/Offering/Initial Deployment/Routing Policy/Gateway Pool/Output Contract/Pricing/Billing Policy/Reservation 等值是 Admission Producer 的同事务不变量;Projector 只消费自包含 Event,不跨服务解引用 Manifest。- 新增 Tenant-aware
wallet.reserved@2.0:强制operationId + correlationId + causationId与 Reservation/Pricing/Billing Policy 字段,并以严格BillingValue = credits | entitlement | money判别联合保存预占值;Credits Amount、Entitlement Key/Quantity/Unit 与 Money Amount/Currency 不得互换或丢失。它与同事务run.created@2.0、RunAdmissionManifest冻结 Reservation Aggregate/ID、Run、Actor Principal、Billing Account、Pricing、Billing Policy、Tenant、Workspace/Project、Operation/Correlation 的跨记录等值,以及reservation.value == budgetAuthorization.reservedValue的完整联合逐项等值,都由 Admission Producer 在 Append 前验证;同时保留wallet.reserved@1.0的原发布 Schema 作为 Legacy/Partial Consumer,绝不收紧其可选字段。 OperationalObservationSubmission@1.0与AcceptedOperationalObservationEnvelope@1.0、严格 Payload 判别、枚举、保留字段和白名单属性;Producer 只可提供可选sourceClaimedObservedAt,acceptedAt、source.*、Digest Algorithm Version 与 Submission 摘要只允许 Core 注入,Tenant/Run/Operation 字段明确为 Producer Claim。Observation 摘要固定jcs-sha256-v1:UTF-8 严格解码/重复 Key 拒绝、Member Name 与字符串 NFC/规范化重名拒绝、严格 Schema、缺失不注入默认且非法 Null 拒绝、RFC 8785、SHA-256 小写十六进制;Accepted Envelope 摘要包含算法版本和 Submission 摘要但排除自身 Registry 字段。Error Producer 必须携带实际 Adapter 使用的errorNormalizationPolicyVersion,Intake 校验 Workload/Deployment 支持矩阵和 Code 注册值;Producer 不提交 Service/Fingerprint,Core Projector 按 Contracts 的七字段、UTF-8 NFC、RFC 8785、SHA-256 与固定向量计算版本化 Fingerprint。- Operations Query/Intake、
/internal/v1/workforce/query-grants:issue、Projection Status、Evidence Kind、projectionCompleteness + limitations[] + sectionSupport、associationTrust与accepted_new | accepted_existing | accepted_existing_purgedSchema;Search 是operation_linked | observation_only | legacy_run_only,Snapshot 元数据是verificationState=verified | unverified严格联合。 - Canonical Payload 序列化/摘要固定向量,以及随 Contracts Release 发布、供 Intake/Projector/Archive/Rebuild 共用的完整 Submission 与 Accepted Envelope Golden 制品。
- 统一
evidenceKind = domain_fact | operational_observation | operations_runtime | telemetry_reference | derived_summary。 - Delivery Set Version、Definition Digest 与 Mandatory Destination 定义;定义一经激活不可原地修改。
- Workforce Actor Assertion 与 Signed Workforce Grant 的严格 Schema:唯一 Issuer、精确 Audience、
iss/aud/sub、Workload/Request Binding、jti、时间、Session/Authn/Policy Version、MFA 与 Action/Field/Resource/Tenant/Case Scope,以及 Assertion JTI 一次性消费契约。 - Error Template Key、白名单参数、长度与编码约束,以及
occurredAt? / sourceClaimedObservedAt? / acceptedAt? / derivedAt?按evidenceKind的条件 Schema;Observation 的 claimed time 只可进入 Timeline,错误摘要不能保留任意“已脱敏”自由文本逃逸口。 - 公共导出负向门禁:Site、Web 与 Public API 包入口不能导入内部 Operations 契约。
验收:运行时 Schema、TypeScript、JSON Schema、Node/Web 消费、严格未知字段、摘要/Fingerprint 固定向量、Package/Release 制品比对和依赖审计全部通过。缺失/空白 Run v2 operationId/correlationId 或 Wallet v2 operationId/correlationId/causationId/pricingSnapshotId/billingPolicyRevisionId、Run v2 Output Contract 四元组缺项/未知算法/非法摘要、Wallet v2 BillingValue 分支缺项/混合/非法 Decimal、Run Event 与 RunAdmissionManifest 的 Actor/Tenant/Access/Authentication/Authorization/Product/Offering/Initial Deployment/Routing Policy/Gateway Pool/Output Contract/Pricing/Billing Policy/Reservation 任一错配、Wallet Event reservation.value 与 Manifest reservedValue 的 Kind/Amount/Quantity/Entitlement Key/Unit/Currency 任一不等、Wallet v2 因果链或 Run↔Wallet 共同字段任一不一致、MeterEvent 与 RunAdmission/Attempt/Route Binding 任一错配、单值状态吞掉并存限制、Producer Claim 被当成 Tenant 授权、Producer 自报 Service/Fingerprint 均有负向测试。Event↔Manifest 与 Wallet Value↔Manifest 的错配必须证明整笔 Admission 原子回滚;Projector 测试不伪造 Manifest Read 能力,只隔离 Event 自身错误与两个已提交 Event 之间的冲突。既有两个 v1 完全按原 Schema 接受,缺少旧版可选字段不隔离且只形成 Legacy/Partial。
Stage 2:Core 数据库迁移
Core Operations 新增:
- Outbox
eventEnvelopeDigestAlgorithmVersion + eventEnvelopeSha256覆盖完整 Canonical Envelope+Payload,另含冻结的deliverySetVersion + deliverySetDefinitionSchemaVersion + deliverySetDefinitionDigestAlgorithmVersion + deliverySetDefinitionDigest与必要的不变量约束;Event Ack/Receipt 必须携带并校验相同算法版本与摘要,Payload-only 摘要不能满足投递或完整性门禁; - 不可变
delivery_set_versions/delivery_set_members或等价固定制品摘要模型,并冻结destination → consumerName;DeliverySetDefinition@N对 Version、适用 Event Type/Schema 与规范排序的完整 Member 集合内容寻址,Contracts 发布 Golden,未知 Schema/算法、同 Version 异定义或裸 Digest 拒绝; - 独立 Delivery State(含 Current Attempt)、不可变
delivery_attempt_started与每个 Attempt 至多一个delivery_attempt_finished、Ack Receipt 坐标和 Quarantine; - Event 以
consumerName + projectionName + projectionVersion + eventId、Observation 以相同前缀加observationId为坐标的 Versioned Consumer Receipt,以及 Projection Build 与 Aggregate Revision Gap; - Intake 已接受后按
observationDigestAlgorithmVersion + observationId + submissionPayloadSha256幂等保存的 append-only Observation Source、首次 Accepted Envelope 的独立acceptedEnvelopeSha256、环境命名空间生命周期内保留的observation_id_registry,以及 Payload 清理时追加的唯一 Purge Marker;Registry 和 Observation Receipt 都保存算法版本,禁止跨版本比较摘要; - Versioned
operation | legacy_runSummary、完整承载run.created@2.0 + wallet.reserved@2.0低敏字段的 Admission Snapshot Projection、Wallet-first Pending Unlinked Reservation、逐字段 Evidence/Source Lineage、Timeline、Exact Identifier Index 与 Observation;两个 v1 只形成 Legacy/Partial,缺少 Operation 时不得伪造 Operation/Correlation/Request ID; - append-only
completeness_snapshots + completeness_snapshot_members:普通查询完整性在同一 Consistent Snapshot 事务记录 Projection/Query Definition Version、Source Filter Digest 三元组、双 Source 精确成员及 Canonical Set Digest/Count;每个 Source Member 使用严格 Tagged Digest,Event 只能用覆盖完整 Envelope+Payload 的 Canonical Event 算法版本/SHA,Accepted Observation 只能用 Observation 算法版本/Accepted Envelope SHA,禁止使用 Payload-only 或 Submission SHA。Proof 另含 Mandatory Delivery/Receipt、Gap、Quarantine、Unsupported Schema 和 Semantic Check Version/Input/Result;另建cutover_candidate_boundaries + cutover_candidate_members以同一 Tagged Digest 冻结切换/回滚候选 Source、定义与 Expected Receipt Coordinates,并在 Shadow 追平后的最终事务才写cutover_readiness_proofs。三类对象不得用一个可选字段表混合;仅 Projector Workload 内的 Core Operations Verifier 模块可写,Query Role 不可写;只存 Count 不足,禁止以最大 ID、时间戳、Transaction ID 或扫描游标代替成员边界; - Active/Shadow Projection Registry。
迁移必须:
- 通过 Trigger 与 Column Grant 保证 Event Envelope、Payload、Canonical Event Digest Algorithm Version/SHA-256、
deliverySetVersion、Delivery Attempt Start/Finish、Applied Receipt、完成后的 Source Snapshot Result/Member、Accepted Observation、Observation ID Registry/Purge Marker 和 Sensitive Query Audit 不可原地修改;运行角色不得删除。Claim 与 Start 同事务,正常结果用 Current Attempt+Lease Fencing 追加唯一 Finish,恢复者仅在旧 Lease 失效且无 Finish 时追加lease_expired_unknown;不使用可变的单行 started→terminal Attempt。受控 Retention/Archive Procedure 只可按治理边界删除 Accepted Observation Payload/Envelope 及对应派生内容并追加唯一 Purge Marker;ID Registry 与已存在 Purge Marker 只能保留或迁入 Intake 每次必查的不可变完整性归档,不得更新、删除、重绑或绕过; - Source Snapshot 与全量 Projection State Snapshot 都不能替代 Canonical Source。Outbox Event 离开热表后必须以完整不可变 Envelope/Payload、Digest 与 Delivery Set Definition 进入 Rebuild/Verifier 每次读取的批准归档 Source View,逻辑 Source 成员不消失,并保留固定 Schema/运行时及隔离 Restore Drill 证据;缺失/错摘要/不可读归档必须阻止 Complete 与 Cutover。Active/Shadow Receipt、Delivery Ack 引用的 Receipt、对应 Source 仍可投递/重建时的 Receipt 禁删;版本退休且回滚窗结束、Pointer/Delivery/Quarantine/Legal Hold 无引用后,只可成组清理该退休版本 Receipt 与派生 Projection,不删除归档 Canonical Event Source。Accepted Observation 合规清理必须通过版本化 Retention Source 范围、Purge Marker 与 Audit 缩小当前支持范围,不声称恢复已删除 Payload;
- Dispatcher 不拥有
published_at直接 UPDATE 权限;数据库受控函数在同一确认事务验证冻结destination → consumerName、Mandatory Delivery terminal 状态与匹配 Ack Receipt 坐标全集后才允许首次NULL → timestamp,禁止回空或覆盖; - Producer Append 在原业务事务内从数据库不可变 Registry 冻结
deliverySetVersion + deliverySetDefinitionSchemaVersion + deliverySetDefinitionDigestAlgorithmVersion + deliverySetDefinitionDigest,并原子创建该定义全部 Mandatory Delivery Row;Deferred Constraint 或事务末 anti-join 证明无缺失、无多余,否则整个事务失败; - 为全部既有 Event 创建显式、不可变的 Bootstrap Delivery Set Version,并在同一受控迁移事务中创建精确 Delivery Row;支持的 Schema 进入 Projector,不支持或损坏的 Schema 进入可见 Quarantine,不留下无 Delivery Set 的悬空 Event,也不能把部署时当前 Destination Set 隐式套到历史事件;
- 当前受控 Admission 在迁移窗口必须关闭并排空所有旧 v1 Writer;在数据库 Append Migration Lock 内完成 Registry 激活、历史 Bootstrap、非空/精确集合约束与直接 Event Insert 权限撤销。释放数据库锁后仍保持 Admission Gate 关闭,由数据库权限阻止旧实例绕过 Primitive,直到所有 Core Writer 实例都已部署为调用同一受控 Append Primitive。禁止旧 Writer 与新约束无保护地并行;Worker 只能在证明不存在“有 Event、无精确 Delivery Set”的记录后启动;
- Observation 已接受 Source 由 Trigger/Column Grant 保证 append-only;
- 把现有
run.created@1.0明确标记为可消费但 Partial,而不是补造2.0字段; - 允许新 Admission 原子提交
run.created@2.0 + wallet.reserved@2.0; - 不删除现有 Outbox、Run、Reservation 或幂等事实;
- 使用真实 PostgreSQL 集成测试,并对共享测试库关闭文件级并行。
项目尚未上线,不构造无需求的生产旧数据兼容层;但已经存在的受控测试事实和 v1 Schema 语义仍需可验证、可诊断。
Stage 3:Core Dispatcher 与 Consumer
同一 Core 镜像首期只增加一个独立 Operations Worker Role:
core-api → 领域与 Internal HTTP、Observation Intake、Query
core-operations-worker → Dispatcher + Projector + Shadow RebuildDispatcher 与 Projector 保持独立代码模块、健康状态、数据库权限和 Metrics,但首期由同一受托管 Worker 进程承载,避免制造无证据的部署单元。只有容量或故障域证据要求时再拆 Process Role。API 实例不能在请求完成后启动无托管后台 Promise 代替 Worker。
验收场景:
- 多 Worker 并发 Claim 时同一 Delivery 同时只有一个有效 Lease Token。
- Dispatcher 始终从显式未完成 Delivery Row Claim;不存在依赖全局顺序游标或单值进度标记的扫描路径。
- Worker 在 Claim 后、投递前崩溃,Lease 到期后可恢复。
- Consumer 提交后 Ack 丢失导致重投,Receipt 阻止重复 Mutation。
- Active Consumer Ack 携带并验证冻结的 Destination/Consumer、Event/Hash 与 Applied Receipt 坐标;Shadow Receipt 不能满足 Active Delivery。
- 成功 Attempt、Delivery terminal Ack、Ack Receipt 引用和
published_at受控函数在同一 Lease-fenced 确认事务提交;函数对非法 Ack/Receipt/Member/Fencing 抛错回滚,其他 Mandatory Pending 时返回not_complete并提交当前 Delivery,最后一个完成时返回complete并 CAS 写时间。 - 多 Mandatory Destination 测试必须证明首个合法 Ack 可以在
published_at=NULL时提交,最后一个 Ack 原子设置时间,错误 Consumer/Receipt 或旧 Fencing Token 才会回滚。 - 旧 Lease Owner 晚到 Ack 无法覆盖新 Owner。
- 同
eventId同摘要幂等 Ack;同 ID 不同摘要隔离。 - 未知 Schema、严格解析失败、Aggregate Revision Gap 和数据库暂时故障各自进入正确状态。
- Receipt 与 Projection Mutation 任一步故障全部回滚。
- Observation Receipt 与 Observation Projection Mutation 任一步故障也全部回滚;只有同 Workload Source 的算法版本、
observationId + submissionPayloadSha256全部相同才返回首次 Accepted 结果,跨 Workload 同 ID、算法版本错配、规范化重名、非法 Null 或任一摘要篡改必须拒绝且不泄露首次 Source,Receipt 以observationDigestAlgorithmVersion + acceptedEnvelopeSha256防止重复应用或摘要混用;Archive Replay/Rebuild 必须通过同一 Golden 制品。 - Observation 时间负测使用 claimed time 与
acceptedAt顺序相反、未来 claimed time、Retention 边界两侧以及相同acceptedAt的样本;排序、趋势桶、accepted health window、Retention/Archive、Freshness 和 Operation Summary 的first_accepted_observation_at/latest_accepted_observation_at必须只由acceptedAt决定,相同时间以observationId稳定排序。operational_observation缺少acceptedAt、携带伪造occurredAt或把 claimed time 写入 Summary 必须拒绝/隔离。 run.created@2.0与wallet.reserved@2.0无论到达先后都经operationId + causationId + runId形成正确链;Wallet-first 先进入保存 Pricing/Billing Policy 引用的 Pending Unlinked,不创建 Summary。首个 Producer 要求两者tenantKind=organization,Reservation Aggregate/ID、Actor Principal、Billing Account、Pricing、Billing Policy、Tenant、Workspace/Project、Operation/Correlation 逐项一致,并与 Manifest 的冻结账务字段一致。v2 缺失/非法关联字段或任何跨记录错配进入 Quarantine/Semantic Check,且不创建/更新完整 Admission Snapshot;两个 v1 按原 Schema 合法消费,只形成 Legacy/Partial,缺失 Operation 的 v1 为legacy_run_only。- Admission Snapshot Projection 能仅从两类 Event 重建 Actor/Execution Principal、Tenant、Developer Access、Authorization、Billing Account、Model/Offering/Deployment/Gateway Pool、Manifest Ref/Version、Reservation/Pricing/Billing Policy/精确 Value 与 Run/Reservation 状态;每个字段保留 Evidence/Source Lineage,禁止回查当前领域表补齐。
- 停机排空不会丢失已 Claim 但未完成的 Delivery。
- 在同一 Consistent Snapshot 内冻结适用 Event/Accepted Observation 的精确 Member、Canonical Set Digest/Count 与 Query Definition Version;两类 Source 对当前 Projection Version 的 Receipt Anti-join 均为空,且未完成 Mandatory Delivery、Revision Gap、Quarantine、Unsupported Schema 和语义校验全部通过时,才允许得到
complete_for_supported_scope;该结论不覆盖未被 Intake 接受的 Edge 请求。 - Cutover Readiness 与当前查询完整性分离:T1 前暂停并排空 Shadow Claim;T1 同事务冻结 Candidate Source/定义/Expected Receipt Coordinates,并把 Shadow Build 绑定 Candidate、递增 Claim Fencing Token、切到
candidate_bound,旧 Token/边界外 Mutation 必须失败。Shadow 只对该边界 Catch-up;再停 Active Claim、排空 Active in-flight,最终事务复核同一 Candidate,现场计算 anti-join/Gap/Quarantine/Schema/Semantic 结果,全部通过时才追加新的不可变CutoverReadinessProof并同事务切 Pointer/Consumer Target。边界后 Source 不进入 Readiness,恢复后由新 Active 追平;无法原子绑定/精确过滤时必须短暂停 Writer/Intake。测试必须覆盖 T1 前 Shadow drain、T1 Commit 与恢复 Claim 间持续写入、旧 Shadow Lease 晚到、相同 Count 但成员/Payload 不同、追平前错误 Ready。 - 持久化完整性只对
completenessAsOf.snapshotId/evaluatedAt的完整 Proof Manifest 生效。只读 Query 在一个 Consistent Snapshot 中,用相同 Query/Semantic Definition 对当前双 Source、Mandatory Delivery/Receipt、Gap、Quarantine、Unsupported Schema 和 Semantic Check 全部输入与 Manifest 做精确比较并验证 Active Version;响应使用integrity@2.snapshotProof + currentGuard分开表达历史证明与本次现场输入,并以版本化 Guard Digest 绑定当前强制字段。全部不变才返回verificationState=verified + snapshotCurrency=verified_current + comparisonToSnapshot=equal。projectionCompleteness只由 Current Guard 判定:双 Receipt anti-join、Mandatory 非终态、Gap/Quarantine/Unsupported 全为已知 0 且 Semantic passed 才为 Complete;任一确定非零/failed 为 Partial,无确定负向但任一 unknown 为 Unknown。存在已完成且定义可比的 Snapshot、Guard 确认变化时返回verified + stale + comparisonToSnapshot=changed,且禁止 Complete;无完成 Snapshot、定义不可比或 Guard 无法执行/比较时返回unverified + completenessAsOf=null + integrity=null + snapshotCurrency=unknown + projectionCompleteness=unknown + verificationReason。Query 不得为此写 Snapshot;测试逐项拒绝顶层 Complete 与 Current Guard 非零/failed/unknown 证据并存、Comparison/Digest 错配,并接受历史 Snapshot 与当前 Guard 状态不同的合法 Stale DTO,覆盖空库/no-snapshot、stale-known-gap、pending→ack 和修复后重新验证。 - Delivery、Attempt、Receipt、Build、Gap 与 Quarantine 作为
operations_runtime由 Core Query 直接组合;不得为记录 Publisher 状态递归写回 Outbox。
批次、Lease、退避、并发和隔离阈值通过测试配置注入;测试验证语义,不把测试常数固化成生产策略。
Stage 4:Core Observation Intake 与 Query
实现受限 Internal Contract:
- Observation Intake 验证 Workload JWT Audience/Issuer/Subject/Expiry 与
operations-observation:writeScope;按 Workload Registry 注入 Producer/Environment/Deployment,使用配置化 Payload/批次/字段上限、per-workload 配额和背压,再调用唯一允许的accept_operational_observationPrimitive 原子 insert-or-compare。幂等要求当前 JWT Subject 等于 Registry 首次 Workload;Source 尚存返回accepted_existing原 Envelope,已有 Purge Marker 返回只含observationId + originalAcceptedAt的accepted_existing_purged,不得复活 Source。跨 Workload 同observationId是完整性冲突并进入低敏 Audit/告警,只返回通用错误而不返回首次记录。acceptedAt是 Core 权威时间;Producer 的可选sourceClaimedObservedAt只保存到 Timeline,不参与排序、Summary、健康窗口、Retention 或 Freshness。 - Observation 的 claimed Tenant/Developer Access/Operation/Run 不参与授权分区或 Operation 关联;Projector 仅在 Domain Event 或 Core 可验证 Admission Context 交叉验证后产生
domain_verified关联。错标值进入隔离,未验证 Claim 仅可由显式跨租户 Observation 调查 Scope 查询。 oceanway-coreAuthorization/Workforce Policy 是 Signed Workforce Grant 唯一签发者。Admin BFF 在本地终止并验证 Host-only Session,再以自身 Workload JWT 加 Workforce IdP/Identity Authorization 唯一签发或交换的 Actor Assertion,通过/internal/v1/workforce/query-grants:issue换取定向 Grant;Assertion 的 Audience 精确指向该 Exchange,携带 Workforce、认证/MFA、Session Version、boundWorkload、Exchange Request Digest/Nonce、jti与时间声明,不能复用 Admin ID Token 或由 BFF 自报。Core 在同一事务内一次性消费 Assertion JTI、记录 Grant 并追加签发 Audit;Cookie/Session ID 不离开 Admin Host,浏览器不能取得 Assertion,也不能取得、签发或转签 Grant。- Query 同时验证 Admin BFF Workload JWT 和 Core 签发的 Signed Workforce Grant/JIT,并强制 Grant 绑定的 Workload 等于 JWT Subject。
- Search 每次仅接受一个受支持 Identifier Type 的规范化精确值,并固定合法
identifierNamespace=domain_fact | accepted_observation | auto;响应携带negativeProofCapability=complete_source_guard | positive_match_only。首期只有 Canonical Event/Archive Source 上的 Operation、Correlation、Run、Reservation、Event ID 的domain_fact查询可在完整 Guard 下否定;Request/Error/Auto 与尚未把永久 Registry 纳入 Completeness Proof 的 Observation 查询均为positive_match_only,miss 必须inconclusive + negative_proof_unavailable。 - Grant 签发/拒绝/撤销/使用全部 Audit,签发 Audit 失败时关闭。跨租户、敏感标识和 JIT 查询先提交
query.authorized,查询后在响应字节离开 Core 前提交query.released | query.not_found | query.inconclusive | query.failed;任一必需 Audit 失败均 fail closed。只有complete_source_guard + verified_current + complete_for_supported_scope + 足够 Grant才能not_found;Snapshot/Guard/范围不足、positive_match_onlymiss 或潜在越权统一返回不可枚举inconclusive,越权原因固定authorization_non_disclosure且对象存在与否响应完全相同。 - Response 始终携带 Projection Version、Freshness、
verificationState + projectionCompleteness + snapshotCurrency + limitations[] + sectionSupport、已接受 Observation 范围与已知健康窗口。verified分支要求非空completenessAsOf + integrity@2;其snapshotProof与currentGuard分别返回 Event/Accepted Observation Set Digest/Count/Receipt Anti-join,以及 Delivery、Gap、Quarantine、Unsupported Schema 与 Semantic Check,Current Guard 另带 Comparison 与版本化摘要。unverified分支要求completenessAsOf=null + integrity=null + verificationReason。受限明细按 Grant 裁剪,并存事实不得压成单值优先级,旧 Snapshot 不得冒充当前完整。 - Query Response 使用
Cache-Control: private, no-store,禁止 CDN/Service Worker/浏览器持久化与前端 APM 采集正文、ID 或 Grant;查询预算、速率和枚举告警由策略配置,不用固定延时掩盖滥用。
API Edge 随后接入 best-effort Observation。Intake 失败不得改变公共 API 响应,也不得在 Edge 建立 Prompt/Secret/Body 持久队列。Edge 没有 Durable Spool 或连续 Sequence,Core 只能报告已接受记录集合、接受时间范围和已知 Intake/Source 健康窗口;不得宣称请求 Coverage 完整或检测丢失 Observation。必须验证 Raw Secret、Credential Digest、Request Fingerprint、Authorization、Prompt 和请求 Body 不进入 Observation、日志或普通业务投影;受控 integrity@2 Snapshot/Guard Digest 只能按独立分类返回。
Stage 5:Admin BFF 与首版 Explorer
oceanway-admin 只实现 Workforce Query BFF/UI:
- 精确输入 Request、Operation、Correlation、Run、Reservation、Event、Observation 或 Error ID;
- 展示请求摘要、Run、Reservation、Outbox、Delivery、Receipt 与 Projection Timeline;
- 从 Versioned Admission Snapshot 展示主体、Developer Access、Authorization、模型、Manifest Ref/Version、Billing/Reservation/Pricing/Billing Policy 等低敏字段,并保留字段级来源;v1 或尚未到达的 Wallet Event 明确显示缺失原因;
- 每条记录展示统一
evidenceKind与 Source;页头展示 Projection Freshness、verificationState + projectionCompleteness + snapshotCurrency、可并存limitations[]与逐阶段sectionSupport;只有verified分支展示非空completenessAsOf + integrity@2.snapshotProof/currentGuard,unverified显示空值和原因; - Gateway、Output、Asset、Metering、Settlement 显式显示“本阶段未支持/未观测”;
- v1 Event 在
limitations[]显示partial_legacy_event;未被 Intake 接受的未知 Observation 范围和 Projection Lag 分别显示限制与projectionCompleteness,不得展示虚构的 Observation Gap 数量或让一个状态覆盖另一个; - 无任何 Retry、Replay、Force Success、Reservation 操作或 SQL 工具。
Admin 不直连 Core PostgreSQL、Text/Media Gateway 数据库、Telemetry Store 或对象存储。受限 Trace/Log 只显示经过授权的 Reference,不把原始内容复制到页面。
Stage 6:Infrastructure 与证据
Infrastructure 为 Core Worker Roles、Internal Routes 和 Admin Query 配置最小权限:
- Core API 与 Operations Worker 使用独立 Service Account、健康检查与资源配置;Worker 内 Dispatcher/Projector 使用最小数据库 Role 与分别可观测的模块状态;
- Query BFF、Observation Intake、Dispatcher、Projector(内含 Verifier 模块)与未来 Command Gateway 使用独立 Workload Principal、Audience/Scope、凭据和网络策略;Verifier 不新增独立公网/内部 API 身份;
- Core Authorization/Workforce Policy 的 Grant 签发、Admin 私网 Exchange、Actor Assertion 唯一签发者/精确 Audience、JTI 一次性消费、Workload/Request Binding、撤销、验证材料和轮换;
- PostgreSQL Role 限制:Query 只读批准 View 并执行 Audit Append Procedure;Intake 只能执行固定
search_path、撤销PUBLIC EXECUTE的accept_operational_observationSecurity Definer Primitive,对 Source/Registry/Purge Marker 无直接表权限;Dispatcher 只操作 Delivery/Attempt/Quarantine 并调用published_at受控函数;Projector 只读批准的 Event/Accepted Observation 与 Operations Runtime Source View,只操作目标 Projection/Receipt/Build/Gap,并可追加 Completeness Snapshot/Member、Cutover Candidate/Member 与 Readiness Proof;Active Pointer 只能通过校验 Candidate、Proof、Lock 与 Fencing Token 的受控 Cutover Primitive 更新,不能直接 UPDATE; - PostgreSQL Trigger/Column Grant 负向验证:Event、Delivery Attempt Start/Finish、Applied Receipt、完成后的 Completeness Snapshot/Member、Cutover Candidate/Member/Readiness Proof、Accepted Observation、Observation ID Registry/Purge Marker 与 Sensitive Query Audit 不可原地更新/运行时删除;Attempt 测试覆盖调用前/调用后崩溃、恢复者与旧 Worker 竞态、旧 Lease 晚到、重复 Finish/Ack,并证明每个 Start 至多一个 Finish且 stale token 不改变 Delivery。
published_at函数必须先验证冻结 Mandatory Receipt 全集;Owner/迁移/Retention Role 与运行 Role 分离。Retention 负测拒绝以 Snapshot/Proof/Projection State Snapshot 冒充 Canonical Source、错/缺归档仍 Complete/Cutover、先删 Receipt、删除 Active/Shadow/Ack 引用 Receipt,以及保留可重放 Source 却删除其幂等 Receipt; - Metrics、Alert、部署回滚、Worker 排空和 Shadow Switch Runbook;
- 网络策略禁止 Admin 直连数据库和 Gateway。
正式跨进程证据使用固定 Contracts Release、真实 PostgreSQL、真实 Workload JWT/JWKS、多个 Worker 进程和独立 Admin BFF 调用。Observation 证据必须覆盖同 Source 同 ID/同摘要并发收敛为首次 acceptedAt、同 Source 不同摘要冲突、跨 Workload 同 ID 冲突且不泄露旧 Source、Payload 清理与重放并发、accepted_existing_purged 不复活 Source、Producer 错标 Tenant/Run 不进入 Tenant 授权/Operation、claimed time 反序/未来/Retention 边界不影响基于 acceptedAt 的排序/窗口/保留/新鲜度/Summary,以及 Intake Role 不能直接读取或写入 Source/Registry/Purge Marker。证据脱敏并绑定 Contracts/Core/API Edge/Admin/Infrastructure 的精确 Commit 与 Workflow Run。
迁移与发布顺序
1. 发布 Contracts
2. 仅部署向后兼容的扩展 Schema 与 v1/v2 Consumer 代码,Worker 仍关闭
3. 关闭受控 Admission、排空全部旧 Writer,并取得数据库 Append Migration Lock
4. 在锁内激活不可变 Delivery Set Registry,为全部既有 Event 创建显式 Bootstrap Version/精确 Delivery Row,启用非空与精确集合约束并撤销直接 Event Insert;释放数据库锁但继续保持 Admission Gate 关闭
5. 将全部 Core Writer 实例改为使用同一受控 Append Primitive;证明旧实例无法绕过、且不存在“Event 无精确 Delivery Set”后仅恢复受控 Admission,再开启 Core Projector Shadow;Public Admission 仍关闭
6. 在同一发布门禁原子切换 Admission Producer 到 `run.created@2.0 + wallet.reserved@2.0`;不得出现 Run v2 搭配 Wallet v1 的窗口
7. 预先收敛 Shadow;先暂停 Shadow Claim 并排空 in-flight,再用短 Consistent Snapshot 事务原子冻结 Candidate Source Member/Canonical Source Digest/定义/Expected Receipt Coordinates、绑定 Candidate 与新 Claim Fencing Token;随后恢复仅 Candidate Claim 并 Catch-up。再停新 Active Claim、排空旧 Active in-flight,在最终事务复核同一 Candidate、生成新的不可变 Readiness Proof,并同事务切 Pointer 与消费目标版本。边界后 Source 不进入 Readiness,切换后解除 Candidate 限制并由新 Active 追平
8. 启用 Operations Query Internal Route
9. 部署 Admin 只读 Explorer
10. 接入 Edge best-effort Observation
11. 固化 Infrastructure 端到端证据回滚时先停止或降级 Query,把旧 Projection 作为 Shadow 对 Event 与 Accepted Observation 两类 Source Receipt anti-join 追平;用短事务冻结精确 Candidate 并让该 Shadow 停在边界,再停止两类新 Claim、排空当前 Active in-flight,在最终事务复核同一 Candidate、生成新 Readiness Proof 并原子切回 Pointer 与 Consumer Target。边界后 Source 由切回版本在恢复 Claim 后追平。不能直接翻转到自上次切换后未消费新 Source 的旧版本;无法追平时 Query 保持关闭。不能回滚 Contracts 后继续产生未知事件;已经提交的 Run/Wallet v2 保持不可变并由兼容 Consumer 处理或进入明确隔离,也不能恢复成 Run v2 搭 Wallet v1 的混合 Producer。
验收矩阵
| 维度 | 必须证明 | 不得据此宣称 |
|---|---|---|
| Producer 原子性 | Run/Reservation/两事件、不可变 Delivery Set 定义摘要与全部精确 Mandatory Delivery Row 同事务,缺失或多余均回滚 | Gateway 已执行、模型已有输出 |
| Delivery | Claim、Lease Fencing、Retry、Quarantine、崩溃恢复 | 网络 exactly-once |
| Consumer | Event/Accepted Observation Receipt + Mutation 同事务,重投无重复;完整性使用同一 Consistent Snapshot 中冻结的双 Source 精确成员/Digest、Receipt anti-join、Gap/Quarantine/Schema/语义判定;查询时用双向集合 Guard 标注 Currency | 任意未来消费者都完成、旧 Snapshot 自动代表当前,或 Edge 请求全集完整 |
| 契约 | Run/Wallet v2 配对且自包含;Run 的 operationId + correlationId 与 Wallet 的 operationId + correlationId + causationId + pricingSnapshotId + billingPolicyRevisionId 必填,Reservation Aggregate/ID、Actor Principal、Billing Account、Pricing、Billing Policy、Tenant/Workspace/Project/Operation/Correlation 与 Manifest 等值;两个 v1 按原 Schema 使用 partial_legacy_event | 收紧 v1 Optionality、声称 v1 拥有不存在的字段、产生 Run v2 + Wallet v1,或合并矛盾事实 |
| Observation | 准入前错误和 Replay 在 Intake 已接受时可检索;无 Domain-verified Association 时返回 observation_only;ID Registry 在 Payload Retention 后继续绑定首次 Workload/摘要,Purged 重放不复活 Source | 每次 Edge 请求都永久保存、Producer Claim 可用于租户授权、能检测 Observation 丢失,或能为拒绝请求伪造 Operation/Tenant |
| Projection | Shadow 通过双 Source Receipt Anti-join 重建;Cutover/回滚先短事务冻结 Candidate、让 Shadow 停在该精确集合,再停 Claim/排空并在最终事务复核同一集合、原子切 Pointer/消费目标;边界后 Source 由新 Active 追平并使 Query 暂为 partial_source_gap | Read Model 是领域事实源、时间/计数/单值进度能证明完整、最终事务临时扩张边界、Shadow 带未验证边界外状态切换,或旧 Pointer 可直接翻转 |
| Security | Session 只在 Admin BFF 终止;Actor Assertion 仅由受信 Workforce IdP/Identity Authorization 签发或交换并由 Core 一次性消费;Grant 仅由 Core 签发并绑定 Workload;数据释放前两阶段 Audit 全部提交 | Super Admin 可以绕过 Query Policy,或 BFF 可以自报 Actor |
| Admin | 精确 ID、Evidence Kind、Freshness、verificationState + projectionCompleteness + snapshotCurrency + limitations[] + sectionSupport、只读;verified 才有 completenessAsOf + integrity@2.snapshotProof/currentGuard,完整/裁剪/无 Snapshot DTO 均通过 Schema/权限测试 | 可以修 Run、改 Wallet 或重投事件,用一个状态吞掉并存限制,或把历史快照显示为当前 |
| Operations | 低基数 Metrics、Runbook、部署/回滚证据 | 固定阈值适用于所有环境 |
| Public Boundary | Admission 继续 disabled,无公网切流 | /v1/responses 已生产可用 |
阶段完成定义
只有以下条件同时满足,才可以进入 Metering/Settlement:
- Contracts 新版本和全部消费仓固定依赖已经发布、比对并通过独立 CI;
- 一次受控 Admission 可以通过 Event/Receipt/Projection 还原到 Run 与 Reservation;
- 重投、乱序、崩溃、Lease 过期、Schema 错误、Delivery Set 精确冻结、Receipt Consumer/Projection 身份、Event/Accepted Observation 双 Source 精确 Snapshot Member/Digest 与 Receipt anti-join、Observation Registry/Purge 并发与错标关联隔离、跨 Workload Observation ID 冲突、全部 append-only 对象、
published_at受控函数,以及持续写入下 Frozen Boundary Cutover、切换后partial_source_gap → complete_for_supported_scope收敛、带新增 Source 的对称回滚有真实 PostgreSQL 负向与并发证据; - Admin 可以按授权精确查询,并以正交的
verificationState + projectionCompleteness + snapshotCurrency + limitations[] + sectionSupport清楚表达 Snapshot 时点、Projection Gap、Legacy、Unknown 与 Not Supported;只有verified分支存在completenessAsOf + integrity@2.snapshotProof/currentGuard,无 Snapshot 分支显式为空并说明原因; - Secret、Prompt、输入正文、签名 URL 和高基数标识没有进入不该进入的数据面;
- 所有仓的精确 Commit、CI 与跨服务证据已登记;
- 公网、Gateway、Metering、Settlement 与产品 Writer 仍保持关闭或未接入。
完成本阶段只代表 OceanWay 拥有可诊断的准入事件链;下一阶段仍需单独实现 Gateway 不可变 ProviderUsageEvidence / ProviderCostEvidence 与 source ref、Metering 独占的规范 MeterEvent / ProviderCostFact、Settlement/Release 和 Reconciliation,之后才能接 Text Gateway canary。Operational Observation 即使引用 Evidence,也不能代替规范 Fact 或驱动结算。