OceanWayOceanWay
运维事件与读模型

Operations Read Model

Versioned 运维投影、精确 ID 检索、Operation Timeline、查询授权与 Shadow Rebuild

Operations Read Model 是由 Core Operations 拥有的可重建投影,用于把 Run、Reservation、事件投递和低敏 Observation 关联成可诊断视图。它不改变任何领域状态,也不替代 Execution、Billing、Gateway、Asset 或 Audit 的事实源。

数据模型

首期建议使用独立 Schema,并按投影版本区分存储:

operations_read.projection_registry
  projection_name / active_version / shadow_version?
  status / switched_at / rollback_version?

operations_read.projection_builds
  projection_name / projection_version / build_id
  status / started_at / last_applied_at / finished_at?
  claim_mode(unbounded|paused|candidate_bound) / claim_fencing_token
  bound_candidate_boundary_id? / bound_candidate_boundary_schema_version?
  bound_candidate_boundary_digest_algorithm_version? / bound_candidate_boundary_digest?
  applicable_event_count / applicable_observation_count
  event_receipt_count / observation_receipt_count
  event_anti_join_remaining_count / observation_anti_join_remaining_count
  revision_gap_count / quarantine_count
  cutover_candidate_boundary_id? / cutover_candidate_boundary_schema_version?
  cutover_candidate_boundary_digest_algorithm_version? / cutover_candidate_boundary_digest?
  cutover_readiness_proof_id? / cutover_readiness_proof_schema_version?
  cutover_readiness_proof_digest_algorithm_version? / cutover_readiness_proof_digest? / cutover_readiness?
  evaluated_at / last_error_code?

operations_read.completeness_snapshots
  snapshot_id
  projection_name / projection_version / build_id?
  source_query_definition_version
  source_filter_digest_algorithm_version / source_filter_digest
  event_set_digest_algorithm_version / event_set_digest / event_count
  observation_set_digest_algorithm_version / observation_set_digest / observation_count
  proof_manifest_ref / proof_manifest_schema_version
  proof_manifest_digest_algorithm_version / proof_manifest_digest
  event_receipt_anti_join_count / observation_receipt_anti_join_count
  mandatory_delivery_definition_set_digest_algorithm_version / mandatory_delivery_definition_set_digest
  mandatory_delivery_definition_count
  mandatory_delivery_coordinate_set_digest_algorithm_version / mandatory_delivery_coordinate_set_digest
  mandatory_delivery_coordinate_count / mandatory_delivery_non_terminal_count
  revision_gap_set_digest_algorithm_version / revision_gap_set_digest / revision_gap_count
  quarantine_set_digest_algorithm_version / quarantine_set_digest / quarantine_count
  unsupported_schema_set_digest_algorithm_version / unsupported_schema_set_digest / unsupported_schema_count
  semantic_check_version
  semantic_check_input_digest_algorithm_version / semantic_check_input_digest
  semantic_check_result / result / evaluated_at

operations_read.completeness_proof_manifests
  proof_manifest_ref / proof_manifest_schema_version
  proof_manifest_digest_algorithm_version / proof_manifest_digest
  source_query_definition_version
  source_filter_digest_algorithm_version / source_filter_digest
  event_set_digest_algorithm_version / event_set_digest
  event_count / event_receipt_anti_join_count
  observation_set_digest_algorithm_version / observation_set_digest
  observation_count / observation_receipt_anti_join_count
  mandatory_delivery_definition_set_digest_algorithm_version / mandatory_delivery_definition_set_digest
  mandatory_delivery_definition_count
  mandatory_delivery_coordinate_set_digest_algorithm_version / mandatory_delivery_coordinate_set_digest
  mandatory_delivery_coordinate_count / mandatory_delivery_non_terminal_count
  revision_gap_set_digest_algorithm_version / revision_gap_set_digest / revision_gap_count
  quarantine_set_digest_algorithm_version / quarantine_set_digest / quarantine_count
  unsupported_schema_set_digest_algorithm_version / unsupported_schema_set_digest / unsupported_schema_count
  semantic_check_version
  semantic_check_input_digest_algorithm_version / semantic_check_input_digest
  semantic_check_result / result
  created_at

operations_read.completeness_snapshot_members
  snapshot_id / source_kind(event|accepted_observation)
  source_id
  source_digest =
    { kind=canonical_event_envelope; eventEnvelopeDigestAlgorithmVersion; eventEnvelopeSha256 }
    | { kind=accepted_observation_envelope; observationDigestAlgorithmVersion; acceptedEnvelopeSha256 }

operations_read.completeness_proof_mandatory_delivery_definitions
  proof_manifest_ref / sort_ordinal
  delivery_set_version / delivery_set_definition_schema_version
  delivery_set_definition_digest_algorithm_version / delivery_set_definition_digest

operations_read.completeness_proof_mandatory_delivery_members
  proof_manifest_ref / sort_ordinal
  event_id / destination / consumer_name
  delivery_set_version / delivery_set_definition_schema_version
  delivery_set_definition_digest_algorithm_version / delivery_set_definition_digest
  status_class(terminal|non_terminal)

operations_read.cutover_candidate_boundaries
  candidate_boundary_id / candidate_boundary_schema_version
  candidate_boundary_digest_algorithm_version / candidate_boundary_digest
  direction(upgrade|rollback)
  projection_name / from_version / to_version / build_id
  source_query_definition_version
  source_filter_digest_algorithm_version / source_filter_digest
  semantic_check_version
  event_set_digest_algorithm_version / event_set_digest / event_count
  observation_set_digest_algorithm_version / observation_set_digest / observation_count
  expected_receipt_coordinates_schema_version
  expected_receipt_coordinates_digest_algorithm_version / expected_receipt_coordinates_digest
  frozen_at

operations_read.cutover_candidate_members
  candidate_boundary_id / source_kind(event|accepted_observation)
  source_id / expected_receipt_coordinate
  source_digest =
    { kind=canonical_event_envelope; eventEnvelopeDigestAlgorithmVersion; eventEnvelopeSha256 }
    | { kind=accepted_observation_envelope; observationDigestAlgorithmVersion; acceptedEnvelopeSha256 }

operations_read.cutover_readiness_proofs
  readiness_proof_id / readiness_proof_schema_version
  readiness_proof_digest_algorithm_version / readiness_proof_digest
  candidate_boundary_id / candidate_boundary_schema_version
  candidate_boundary_digest_algorithm_version / candidate_boundary_digest
  event_receipt_anti_join_count / observation_receipt_anti_join_count
  revision_gap_count / quarantine_count / unsupported_schema_count
  semantic_check_version
  semantic_check_input_digest_algorithm_version / semantic_check_input_digest
  semantic_check_result
  result(ready_for_frozen_boundary|blocked) / evaluated_at

operations_read.event_receipts
  consumer_name / projection_name / projection_version / event_id
  event_type / event_schema_version
  event_envelope_digest_algorithm_version / event_envelope_sha256
  operations_projection_applied_receipt_ref / operations_projection_applied_receipt_schema_version
  operations_projection_applied_receipt_digest_algorithm_version / operations_projection_applied_receipt_digest
  applied_at

operations_read.observation_receipts
  consumer_name / projection_name / projection_version / observation_id
  observation_digest_algorithm_version / accepted_envelope_sha256 / applied_at

operations_read.operation_summaries_vN
  summary_id / summary_kind(operation|legacy_run)
  operation_id? / correlation_id?
  first_request_id? / latest_request_id?
  tenant_kind? / tenant_id? / workspace_id? / project_id?
  run_id / reservation_id?
  admission_snapshot_ref?
  surface? / api_version? / operation?
  admission_status?
  latest_trustworthy_boundary
  summary_evidence_kind=derived_summary
  limitations[] / section_support
  first_accepted_observation_at? / latest_accepted_observation_at?

operations_read.admission_snapshots_vN
  operation_id / request_id / run_id
  tenant_kind / tenant_id / workspace_id / project_id?
  actor_principal_id / execution_principal_id / billing_account_id
  authentication_kind
  developer_app_id? / environment_id? / service_account_id?
  developer_credential_id?
  playground_execution_grant_id? / playground_execution_grant_schema_version?
  playground_execution_grant_claims_digest_algorithm_version? / playground_execution_grant_claims_digest?
  customer_authentication_assertion_ref? / customer_authentication_assertion_schema_version?
  customer_authentication_assertion_claims_digest_algorithm_version? / customer_authentication_assertion_claims_digest?
  product_surface?
  delegation_grant_ref? / delegation_grant_schema_version?
  delegation_grant_claims_digest_algorithm_version? / delegation_grant_claims_digest?
  agent_revision_id? / originating_surface?
  authorization_decision_id / authorization_decision_schema_version
  authorization_decision_input_digest_algorithm_version / authorization_decision_input_digest
  authorization_evidence_evaluation_set_ref / authorization_evidence_evaluation_set_schema_version
  authorization_evidence_evaluation_set_digest_algorithm_version / authorization_evidence_evaluation_set_digest
  authorization_evidence_archive_cut_revision
  authorization_scope_snapshot_ref / authorization_scope_snapshot_schema_version
  authorization_scope_snapshot_digest_algorithm_version / authorization_scope_snapshot_digest
  authorization_action_count / authorization_action_ids[]=sorted
  authorization_evidence_evaluation_count
  surface / api_version / operation / product
  public_model_id / logical_model_id
  model_offering_revision_id / initial_model_deployment_id
  model_routing_policy_revision_id / gateway_pool
  output_contract_ref / output_contract_schema_version
  output_contract_digest_algorithm_version / output_contract_digest
  execution_manifest_ref / execution_manifest_schema_version
  reservation_id / pricing_snapshot_id / billing_policy_revision_id
  reservation_value? =
    { kind=credits; amount }
    | { kind=entitlement; entitlement_key; quantity; unit }
    | { kind=money; money={ amount; currency } }
  reservation_status?
  run_status / run_created_at / run_updated_at
  run_created_event_id / wallet_reserved_event_id?

operations_read.admission_authorization_evidence_evaluations_vN
  operation_id / run_id / sort_ordinal
  evidence_kind(authorization_decision|playground_execution_grant|
                customer_authentication_assertion|delegation_grant)
  authorization_evidence_evaluation_ref / authorization_evidence_evaluation_schema_version
  authorization_evidence_evaluation_digest_algorithm_version / authorization_evidence_evaluation_digest
  archive_revision

operations_read.pending_unlinked_reservations_vN
  wallet_reserved_event_id / event_envelope_digest_algorithm_version / event_envelope_sha256
  reservation_aggregate_id / reservation_id
  run_id / causation_event_id
  actor_principal_id
  tenant_kind / tenant_id / workspace_id / project_id?
  billing_account_id / correlation_id / operation_id
  pricing_snapshot_id / billing_policy_revision_id
  reservation_value =
    { kind=credits; amount }
    | { kind=entitlement; entitlement_key; quantity; unit }
    | { kind=money; money={ amount; currency } }
  state(pending_run_event|quarantined_conflict)
  first_seen_at / last_evaluated_at

operations_read.billing_economic_boundaries_vN
  event_id / event_type / event_schema_version
  event_envelope_digest_algorithm_version / event_envelope_sha256
  aggregate_id / aggregate_revision=1
  correlation_id / operation_id / causation_id
  actor_principal_id / tenant_kind / tenant_id / workspace_id / project_id?
  billing_reservation_id / billing_account_id / run_id
  run_step_id? / execution_attempt_id? / charge_dimension_key?
  settlement_economic_identity =
    { kind=credits }
    | { kind=entitlement; entitlement_key; unit }
    | { kind=money; currency }
  boundary_payload =
    { kind=finalization_committed; value=BillingFinalizationCommitted@1 }
    | { kind=settlement_transition_committed; value=BillingSettlementTransitionCommitted@1 }
    | { kind=late_settlement_exposure_case_requested; value=LateSettlementExposureCaseRequested@1 }
    | { kind=billing_case_resolution_applied; value=BillingCaseResolutionApplied@1 }
    | { kind=late_settlement_command_result_committed; value=LateSettlementCommandResultCommitted@1 }
  case_identity =
    { state=none }
    | { state=available; reconciliation_case_ref; case_generation;
        reconciliation_case_identity_reservation_ref / reconciliation_case_identity_reservation_schema_version;
        reconciliation_case_identity_reservation_digest_algorithm_version / reconciliation_case_identity_reservation_digest;
        predecessor_case =
          { state=root }
          | { state=supersedes; previous_case_generation; previous_reconciliation_case_ref;
              previous_identity_reservation_ref / previous_identity_reservation_schema_version;
              previous_identity_reservation_digest_algorithm_version / previous_identity_reservation_digest } }
operations_runtime.reconciliation_case_identity_reservations
  reconciliation_case_identity_reservation_ref / reconciliation_case_identity_reservation_schema_version
  reconciliation_case_identity_reservation_digest_algorithm_version / reconciliation_case_identity_reservation_digest
  reconciliation_case_ref
  source_owner=billing
  source_scope =
    { kind=late_settlement_dimension;
      tenant_kind / tenant_id / workspace_id / project_id?;
      billing_reservation_id / billing_account_id / run_id / run_step_id / execution_attempt_id / charge_dimension_key }
    | { kind=billing_finalization_run;
        tenant_kind / tenant_id / workspace_id / project_id?;
        billing_reservation_id / billing_account_id / run_id / billing_finalization_fence_id }
  case_generation / case_request_operation_id
  predecessor_case =
    { state=root }
    | { state=supersedes; previous_case_generation; previous_reconciliation_case_ref;
        previous_identity_reservation_ref / previous_identity_reservation_schema_version;
        previous_identity_reservation_digest_algorithm_version / previous_identity_reservation_digest }
  reserved_at

operations_read.reconciliation_cases_vN
  reconciliation_case_ref / case_generation
  reconciliation_case_identity_reservation_ref / reconciliation_case_identity_reservation_schema_version
  reconciliation_case_identity_reservation_digest_algorithm_version / reconciliation_case_identity_reservation_digest
  predecessor_case =
    { state=root }
    | { state=supersedes; previous_case_generation; previous_reconciliation_case_ref;
        previous_identity_reservation_ref / previous_identity_reservation_schema_version;
        previous_identity_reservation_digest_algorithm_version / previous_identity_reservation_digest }
  source_scope =
    { kind=late_settlement_dimension;
      tenant_kind / tenant_id / workspace_id / project_id?;
      billing_reservation_id / billing_account_id / run_id / run_step_id / execution_attempt_id / charge_dimension_key;
      settlement_economic_identity;
      current_source_exposure_ref / current_source_exposure_schema_version;
      current_source_exposure_digest_algorithm_version / current_source_exposure_digest / current_source_exposure_revision }
    | { kind=billing_finalization_run;
        tenant_kind / tenant_id / workspace_id / project_id?;
        billing_reservation_id / billing_account_id / run_id / billing_finalization_fence_id;
        expected_resolution_revision / billing_finalization_operation_id;
        case_request_event_id / case_request_event_type / case_request_event_schema_version;
        case_request_event_envelope_digest_algorithm_version / case_request_event_envelope_sha256;
        billing_finalization_decision_ref / billing_finalization_decision_schema_version;
        billing_finalization_decision_digest_algorithm_version / billing_finalization_decision_digest;
        triggering_work_ref / triggering_work_schema_version;
        triggering_work_digest_algorithm_version / triggering_work_digest / triggering_billing_finalization_work_generation;
        reason_code }
  state(open|investigating|awaiting_external_evidence|resolution_proposed|approval_required|resolving|resolved|rejected)
  case_revision
  applied_resolution_fact =
    { state=none }
    | { state=available;
        resolution =
          { kind=late_settlement;
            billing_case_resolution_applied_ref / billing_case_resolution_applied_schema_version;
            billing_case_resolution_applied_digest_algorithm_version / billing_case_resolution_applied_digest;
            resolved_exposure_revision }
          | { kind=billing_finalization;
              finalization_reconciliation_resolution_applied_ref / finalization_reconciliation_resolution_applied_schema_version;
              finalization_reconciliation_resolution_applied_digest_algorithm_version / finalization_reconciliation_resolution_applied_digest;
              resolution_revision / resolution_operation_id / actor_workforce_principal_id } }
  terminal_authority =
    { state=not_terminal }
    | { state=billing_owner_applied;
        owner_fact =
          { kind=late_settlement;
            billing_case_resolution_applied_ref / billing_case_resolution_applied_schema_version;
            billing_case_resolution_applied_digest_algorithm_version / billing_case_resolution_applied_digest }
          | { kind=billing_finalization;
              finalization_reconciliation_resolution_applied_ref / finalization_reconciliation_resolution_applied_schema_version;
              finalization_reconciliation_resolution_applied_digest_algorithm_version / finalization_reconciliation_resolution_applied_digest } }
  created_from_event_id / last_source_event_id / resolved_from_event_id?

operations_read.pending_case_resolutions_vN
  reconciliation_case_ref / case_generation / resolution_revision
  source_scope =
    { kind=late_settlement_dimension;
      tenant_kind / tenant_id / workspace_id / project_id?;
      billing_reservation_id / billing_account_id / run_id / run_step_id / execution_attempt_id / charge_dimension_key }
    | { kind=billing_finalization_run;
        tenant_kind / tenant_id / workspace_id / project_id?;
        billing_reservation_id / billing_account_id / run_id / billing_finalization_fence_id }
  owner_resolution_fact =
    { kind=late_settlement;
      billing_case_resolution_applied_ref / billing_case_resolution_applied_schema_version;
      billing_case_resolution_applied_digest_algorithm_version / billing_case_resolution_applied_digest;
      resolved_exposure_revision }
    | { kind=billing_finalization;
        finalization_reconciliation_resolution_applied_ref / finalization_reconciliation_resolution_applied_schema_version;
        finalization_reconciliation_resolution_applied_digest_algorithm_version / finalization_reconciliation_resolution_applied_digest;
        resolution_operation_id / actor_workforce_principal_id }
  reconciliation_case_identity_reservation_ref / reconciliation_case_identity_reservation_schema_version
  reconciliation_case_identity_reservation_digest_algorithm_version / reconciliation_case_identity_reservation_digest
  source_event_id / source_event_envelope_digest_algorithm_version / source_event_envelope_sha256
  outcome(pending_resolution|applied|superseded_noop|already_applied|conflict)
  first_seen_at / last_evaluated_at / applied_at?

operations_read.pending_case_successors_vN
  projection_name / projection_version
  source_owner=billing / source_kind=billing_finalization
  tenant_kind / tenant_id / workspace_id / project_id?
  billing_reservation_id / billing_account_id / run_id / billing_finalization_fence_id
  successor_reconciliation_case_ref / successor_reconciliation_generation
  successor_case_identity_reservation_ref / successor_case_identity_reservation_schema_version
  successor_case_identity_reservation_digest_algorithm_version / successor_case_identity_reservation_digest
  predecessor_case =
    { state=supersedes; previous_reconciliation_generation; previous_reconciliation_case_ref;
      previous_finalization_case_identity_reservation_ref / previous_finalization_case_identity_reservation_schema_version;
      previous_finalization_case_identity_reservation_digest_algorithm_version / previous_finalization_case_identity_reservation_digest }
  case_request_operation_id / billing_finalization_operation_id / expected_resolution_revision
  case_request_event_id / case_request_event_type / case_request_event_schema_version
  case_request_event_envelope_digest_algorithm_version / case_request_event_envelope_sha256
  billing_finalization_decision_ref / billing_finalization_decision_schema_version
  billing_finalization_decision_digest_algorithm_version / billing_finalization_decision_digest
  triggering_billing_finalization_work_ref / triggering_billing_finalization_work_schema_version
  triggering_billing_finalization_work_digest_algorithm_version / triggering_billing_finalization_work_digest
  triggering_billing_finalization_work_generation / reason_code
  state =
    { kind=pending }
    | { kind=consumed;
        predecessor_resolution_event_id / predecessor_resolution_event_type / predecessor_resolution_event_schema_version;
        predecessor_resolution_event_envelope_digest_algorithm_version / predecessor_resolution_event_envelope_sha256;
        predecessor_resolution_fact_ref / predecessor_resolution_fact_schema_version;
        predecessor_resolution_fact_digest_algorithm_version / predecessor_resolution_fact_digest;
        successor_materialized_case_revision; consumed_at }
  first_seen_at

operations_runtime.finalization_reconciliation_resolution_decisions
  finalization_reconciliation_resolution_decision_ref / finalization_reconciliation_resolution_decision_schema_version
  finalization_reconciliation_resolution_decision_digest_algorithm_version / finalization_reconciliation_resolution_decision_digest
  decision_input_digest_algorithm_version / decision_input_digest / decision_idempotency_key
  command_request_ref / command_request_schema_version
  command_request_digest_algorithm_version / command_request_digest
  admin_command_candidate_ref / admin_command_candidate_schema_version
  admin_command_candidate_digest_algorithm_version / admin_command_candidate_digest
  actor_workforce_principal_id
  tenant_kind / tenant_id / workspace_id / project_id?
  billing_account_id / billing_reservation_id / run_id / billing_finalization_fence_id
  reconciliation_case_ref / reconciliation_generation / expected_case_revision / expected_resolution_revision
  finalization_case_identity_reservation_ref / finalization_case_identity_reservation_schema_version
  finalization_case_identity_reservation_digest_algorithm_version / finalization_case_identity_reservation_digest
  case_request_event_id / case_request_event_type / case_request_event_schema_version
  case_request_event_envelope_digest_algorithm_version / case_request_event_envelope_sha256
  action=reevaluate_current_owner_state
  investigation_evidence_reference_set_digest_algorithm_version / investigation_evidence_reference_set_digest
  decision=authorized / decided_at

operations_read.record_field_evidence_vN
  record_type / record_id / field_path
  evidence_kind / source_ref / source_schema_version

operations_read.operation_timeline_vN
  operation_id / timeline_entry_id
  evidence_kind / source_ref
  phase / status
  occurred_at? / source_claimed_observed_at? / accepted_at? / derived_at? / applied_at?
  causation_id? / aggregate_id? / aggregate_revision?
  certainty / normalized_code?

operations_read.exact_identifier_index_vN
  identifier_type / identifier_value
  authorization_tenant_kind? / authorization_tenant_id? / operation_id?
  evidence_kind / source_ref

operations_read.edge_observations_vN
  observation_id / request_id
  operation_id? / correlation_id? / run_id?
  claimed_tenant_kind? / claimed_tenant_id? / claimed_workspace_id?
  association =
    { trust=producer_claimed; association_evidence={ state=none } }
    | { trust=domain_verified;
        association_evidence =
          { kind=domain_event;
            event_id; event_type; event_schema_version;
            event_envelope_digest_algorithm_version; event_envelope_sha256 }
          | { kind=admission_context;
              admission_context_ref; admission_context_schema_version;
              admission_context_digest_algorithm_version; admission_context_digest } }
  error_gateway_execution? = {
    gateway_pool / gateway_deployment_id
    attempt_route_binding_ref / attempt_route_binding_schema_version
    attempt_route_binding_digest_algorithm_version / attempt_route_binding_digest
    gateway_route_snapshot_ref / gateway_route_snapshot_schema_version
    gateway_route_snapshot_digest_algorithm_version / gateway_route_snapshot_digest
    execution_anchor =
      { kind=text_invocation; gateway_invocation_id }
      | { kind=media_task; gateway_task_id }
  }
  gateway_dispatch_identity? =
    { scope=attempt_bound;
      gateway_attempt_dispatch_slot_id; execution_attempt_id; gateway_deployment_id;
      attempt_route_binding_ref; attempt_route_binding_schema_version;
      attempt_route_binding_digest_algorithm_version; attempt_route_binding_digest;
      gateway_route_snapshot_ref; gateway_route_snapshot_schema_version;
      gateway_route_snapshot_digest_algorithm_version; gateway_route_snapshot_digest;
      execution_anchor =
        { kind=text_invocation; gateway_invocation_id }
        | { kind=media_task; gateway_task_id } }
    | { scope=pre_binding_no_execution;
        gateway_attempt_dispatch_slot_id; gateway_pre_binding_request_id; gateway_deployment_id }
  gateway_usage_evidence_availability? = {
    availability_ref / availability_schema_version
    availability_digest_algorithm_version / availability_digest / state_version
    provider_evidence_kind=provider_usage / evidence_dimension_key=attempt_aggregate@1
    availability_identity =
      { scope=attempt_bound; execution_attempt_id; gateway_deployment_id;
        attempt_route_binding_ref; attempt_route_binding_schema_version;
        attempt_route_binding_digest_algorithm_version; attempt_route_binding_digest;
        gateway_route_snapshot_ref; gateway_route_snapshot_schema_version;
        gateway_route_snapshot_digest_algorithm_version; gateway_route_snapshot_digest }
      | { scope=pre_binding_no_execution; gateway_attempt_dispatch_slot_id;
          gateway_pre_binding_request_id; gateway_deployment_id }
    supersedes_availability =
      { state=root }
      | { state=supersedes; supersedes_availability_ref; supersedes_availability_schema_version;
          supersedes_availability_digest_algorithm_version; supersedes_availability_digest;
          supersedes_availability_state_version }
    state_reason_code
    availability_state =
      { state=available; provider_usage_evidence_ref; provider_usage_evidence_schema_version;
        provider_usage_evidence_digest_algorithm_version; provider_usage_evidence_digest }
      | { state=not_reported|pending|unavailable|conflicting }
  }
  gateway_cost_evidence_availability? = {
    availability_ref / availability_schema_version
    availability_digest_algorithm_version / availability_digest / state_version
    provider_evidence_kind=provider_cost / evidence_dimension_key=attempt_aggregate@1
    availability_identity =
      { scope=attempt_bound; execution_attempt_id; gateway_deployment_id;
        attempt_route_binding_ref; attempt_route_binding_schema_version;
        attempt_route_binding_digest_algorithm_version; attempt_route_binding_digest;
        gateway_route_snapshot_ref; gateway_route_snapshot_schema_version;
        gateway_route_snapshot_digest_algorithm_version; gateway_route_snapshot_digest }
      | { scope=pre_binding_no_execution; gateway_attempt_dispatch_slot_id;
          gateway_pre_binding_request_id; gateway_deployment_id }
    supersedes_availability =
      { state=root }
      | { state=supersedes; supersedes_availability_ref; supersedes_availability_schema_version;
          supersedes_availability_digest_algorithm_version; supersedes_availability_digest;
          supersedes_availability_state_version }
    state_reason_code
    availability_state =
      { state=available; provider_cost_evidence_ref; provider_cost_evidence_schema_version;
        provider_cost_evidence_digest_algorithm_version; provider_cost_evidence_digest }
      | { state=not_reported|pending|unavailable|conflicting }
  }
  gateway_result_summary? =
    { state=not_available; reason=not_terminal|not_reported|not_applicable }
    | { state=available; output_disposition=no_output;
        output_item_count=0; output_modality_set=[] }
    | { state=available; output_disposition=reported;
        output_item_count=positive_integer_up_to_contract_limit;
        output_modality_set[]=sorted_unique(text|embedding|rerank|image|video|audio) }
  accepted_observation_summary = AcceptedObservationSummary@1 {
    observation_id / schema_version / request_id
    error_id? / trace_id? / correlation_id? / operation_id? / run_id?
    surface / api_version? / operation?
    claimed_tenant_kind? / claimed_tenant_id? / claimed_workspace_id?
    claimed_service_account_id? / claimed_developer_credential_id?
    source_claimed_observed_at? / accepted_at
    source = { workload_principal_id; service; environment; region?; deployment_id?; instance_id? }
    observation_digest_algorithm_version
    submission_payload_sha256 / accepted_envelope_sha256
    payload_summary =
      { kind=request_attempt;
        request_kind; outcome; submission_state; normalized_code?;
        http_status_class?; idempotency_disposition?;
        attributes_schema_version; attributes_digest_algorithm_version; attributes_digest }
      | { kind=error_occurrence;
          layer; phase; normalized_code; error_normalization_policy_version; severity;
          certainty; retry_disposition; compensation_disposition;
          message_template_key;
          sanitized_parameters_schema_version;
          sanitized_parameters_digest_algorithm_version; sanitized_parameters_digest;
          cause_error_id?; technical_detail_ref?; run_step_id?; execution_attempt_id?;
          error_fingerprint_version; error_fingerprint }
      | { kind=gateway_diagnostic;
          gateway_pool; gateway_deployment_id; provider_attempt_id?;
          capability; config_revision; normalized_status; gateway_state_version;
          submission_certainty; result_summary=GatewayDiagnosticResultSummary@1 }
  }

operations_runtime.operational_observations
  observation_id / schema_version
  observation_digest_algorithm_version
  submission_payload_sha256 / accepted_envelope_sha256
  envelope / accepted_at

operations_runtime.observation_id_registry
  observation_id / first_source_workload_principal_id
  observation_digest_algorithm_version
  submission_payload_sha256 / original_accepted_at / accepted_envelope_sha256

operations_runtime.observation_payload_purge_markers
  observation_id / purged_at / retention_audit_ref

authentication_kind 只能取 developer_credential | playground_execution_grant | customer_session | delegated_agent,并由数据库约束与 Projector 双重保证严格四选一。Developer Credential 分支必须且只能有 App/Environment/Service Account/Credential;Playground 必须且只能有 App/Environment/Service Account/Execution Grant 的 ID/Schema/Claims Digest;Customer Session 必须且只能有 Authentication Assertion Ref/Schema/Claims Digest/Product Surface,并要求 Actor=Execution Principal;Delegated Agent 必须且只能有 Delegation Grant Ref/Schema/Claims Digest/Agent Revision/Originating Surface,Execution Principal 必须是同 Run、同 Tenant且与 Agent Revision 绑定的 agent_run Principal。Authorization Decision 的 ID/Schema/Input Digest 对全部分支必填。Projector 从 run.created@2.0 原样映射并严格验证Evaluation Set四元组、统一Cut、Authorization Scope Snapshot四元组、规范排序去重的Action集合、Count与成员。authorization_action_count必须等于数组长度和Set Action Count;authorization_evidence_evaluation_count必须等于子表长度和Set Count。首次投影与Shadow Rebuild以Event自包含的Set四元组、Operation/AuthKind/主体/租户、Scope四元组、Action集合和Cut调用readAuthorizationEvidenceEvaluationSet,验证Purpose、Audience、Scope/Action、Cut、精确成员与result=valid,再按Set成员四元组和同一Cut读取Evaluation。不得要求从Manifest或当前授权补Scope/Action,不得把独立成员读拼成Set、以run_created_at或当前Revision重算。后到撤销不改写已冻结Set/Evaluation。Projector不能凭非空字段猜分支、接受扁平authenticationType、混合字段或后两分支伪造Service Account;它不解引用RunAdmissionManifest,也不声称在投影时比较Event↔Manifest。所有分支都要求product == source.surface;只有Delegated分支允许agent_revision_id。Output Contract四元组同样全部必填并只以Event自包含值投影。Contracts/Repository测试覆盖每分支round-trip、Set/Scope四元组、Cut、Action Count/排序/去重、成员Count/精确集合、Purpose/Operation/状态/Evidence错配、响应丢失重放、后到撤销后重建、跨分支/Principal/Product错配,以及Output Contract四元组缺项/未知算法/摘要错误;Event↔Manifest(含Set/Scope/Action)等值由Producer/Contracts Golden和Repository原子回滚测试保证。首批Producer Capability仍只启用Organization下前两个分支。

五类 Billing 经济边界 Event 只允许精确字面量 billing.finalization.committed@1 | billing.settlement-transition.committed@1 | billing.late-settlement-exposure.case-requested@1 | billing.case-resolution.applied@1 | billing.late-settlement-command-result.committed@1;别名、通配版本或宽松归一化一律按未知 Event 隔离。Projector 必须严格验证自包含 Event、Canonical Envelope Digest、aggregateId=Owner Fact/Result Ref + aggregateRevision=1、Correlation/Operation/Causation、Actor/Tenant、Reservation/Run/Dimension、Settlement Economic Identity,以及所选 Owner、Case、Exposure、Consumption、Ledger 四元组;Finalization/Transition还分别强制Envelope operationId == billingFinalizationOperationId | billingTransitionOperationId,其余三个分支按各自Payload Operation同值Refinement验证。Finalization分支还必须从Event完整取得Billing Finalization Fence ID/Revision、Closure Source Event ID/Type/Schema/Envelope摘要和Closure Consumer Receipt四元组,并要求readBillingFinalizationCommitted返回Fact与它们及Event逐项相等;任一缺项、错摘要或试图从相邻Closure Event/当前Fence补值都隔离。Transition Event中的billingTransitionValidationOperationId必须与Owner Fact/Consumption/Receipt相等,并按逻辑Operation、Dimension、From State Revision与Owner Basis完整摘要确定性派生;Projector不得把它当Envelope Operation或自行重用旧From Revision的Validation Operation。Transition的settlementInputLineage[]必须与Owner Fact完整同构、非空且严格有序,第一项从Owner fromLastEvaluatedInput直接后继、每个后项以前项完整五元组为直接前驱、末项等于Current Input;Projector逐项用readSettlementInput精确历史读取和重算,不要求中间项仍为Current,也不允许漏项、分叉或相邻Event补值。首个Transition的Causation固定指向Finalization;后续Transition必须指向同Dimension直接前一个推进State Revision的Transition或Late Result Event,并验证前驱toStateRevision == 当前 fromStateRevision,不得跳过Late Command边界或按投递顺序猜测。Transition resolve与Applied Fact还必须验证Source专属直接前驱和Resolution Operation:Settlement Transition按(billingTransitionOperationId, caseGeneration, predecessor Exposure完整四元组/Revision)确定性派生,Late Command固定等于lateSettlementOperationId。需要查证Owner正文时只用事件自带完整四元组和Payload Operation调用 readBillingFinalizationCommitted | readBillingSettlementTransition | readLateSettlementExposure | readBillingCaseResolutionApplied | readLateSettlementCommandResult 版本化定向契约;不得按裸Ref读“当前”、查询Wallet当前状态、从Ledger反推、或从相邻事件补Case/Exposure/Binding/Evidence字段。case_identity 是只用于索引的严格同值投影:Finalization固定none;Transition仅caseAction=none时为none,否则为available且Generation/Reservation/Predecessor与Payload及本地不可变Identity Reservation逐项相等;Case Requested、Applied与Late Result固定available且与Payload及本地Reservation逐项相等。每个Boundary Row、Timeline、Exact Index与Event Receipt在同一Projector事务提交;同eventId同摘要幂等,异摘要、同Owner Fact两个Event、Envelope/Payload Operation不等、错误Validation/Resolution Operation、Lineage缺项/分叉、错Aggregate/Revision/Causation、State Revision前驱断裂或跨经济身份绑定进入Quarantine且不产生Case副作用。

execution.attempt-eligibility.finalized@1gateway.evidence-availability.current-changed@1execution.run-finalization.closed@1metering.settlement-input.current-changed@1都是严格Canonical触发Event,但首期Mandatory Destination分别是metering_input_processor | billing_finalization_coordinator | billing_settlement_catch_up,不是core_operations,也不属于BillingEconomicBoundaryPayload@1五分支。它们只在Owner间耐久推进Input/Finalization/Settlement Watermark、Fence和Work;Operations Projector不得为其创建经济Boundary、从触发Event推断Eligibility/MeterEvent/Ledger/Transition,或用Operations Receipt满足另一Destination。它们的Owner Read/Worker确定性冲突分别以内容寻址ExecutionEligibilityConflictFact@1GatewayEvidenceConflictFact@1SettlementInputConflictFact@1RunExecutionFinalizationConflictFact@1与对应Blocked Fact完整四元组在Owner域内收敛,不携带reconciliationCaseRef。Eligibility/Settlement Input/Catch-up/Provider Cost若未来要进入可靠Admin队列,必须先新增对应Canonical Conflict/Processing Event、Mandatory core_operations Delivery、严格Owner Read和Projection;首期只能显示明确标注不完整的best-effort Telemetry,不能创建Case或声称Completeness。只有正式Billing Finalization Worker能把已验证的Run Finalization Conflict Fact纳入Decision,再按下述Run级Case协议创建Operations Case。

Gateway Binding Read的冲突锚点独立为GatewayBindingConflictFact@1,不得与GatewayEvidenceConflictFact@1或泛conflictRef互换。Eligibility Lane的Blocked Cause可直接使用gateway_binding_owner_conflict | gateway_usage_owner_conflict完整四元组;Provider Cost Lane只允许外层provider_cost_processing_conflict,再由ProviderCostProcessingConflictEvidence@1严格Cause联合引用两类Gateway Fact或携带Stage与冲突Candidate带算法摘要的本地确定性校验。Operations不能把任一Owner-local锚点投影成Case。

billing.finalization-reconciliation.case-requested@1billing.finalization-reconciliation-resolution.applied@1是独立的Operations Case编排事件:前者创建Run级Case,后者只能依Billing Owner Fact推进终态;两者都不是五类经济Boundary,不得写Ledger或改Billing Fence。当前Operations Source Query Definition与Event Receipt Anti-join只纳入冻结Definition中适用于operations_projector的精确Pair;其他Owner侧Delivery/Receipt不在本地快照中伪造。

ProviderCostAvailabilityProcessingFact@1.outcome=reconciliation_required也不扩展第三种Case Source Scope。该终态只允许outcome={state=reconciliation_required; availabilityState=conflicting; stateReasonCode},完整Processing Fact四元组是Metering-owned耐久锚点,并且只能由后继Gateway Availability Current Event创建新Generation恢复。available路径中的确定性Schema/Identity/Mapping/Normalization/Receipt/Repository冲突不写Processing Fact或Finish,而是写内容寻址ProviderCostProcessingConflictEvidence@1 + MeteringInputWorkAttemptBlocked@1,令Lane=blocked_on_processing_conflict、保留相同activeWork.state=pending/Operation/Generation并释放Lease;Owner修复后同Work重试。Owner暂不可读、超时、锁冲突等可重试错误连上述领域Conflict/Blocked也不写。当前Delivery Set没有Processing/Conflict Event与core_operations Member,因此Operations只可把显式标注为不完整的best-effort告警作为Telemetry Reference展示,sectionSupport必须保持partial/not-yet-supported,不能创建reconciliation_cases_vN、提供终态命令或声称队列完整。未来可靠Admin队列必须先增加Canonical Event、Mandatory Delivery、Owner Read、严格投影与Completeness成员;收到把本地确定性冲突伪装成terminal Processing Fact、Blocked夹带Finish/Case或暂态错误伪装成领域Fact的提示只能隔离,不能提升为Domain Fact。

Eligibility本地确定性冲突使用EligibilityProcessingConflictEvidence@1,其Stage封闭为eligibility_basis | availability_validation_receipt | eligibility_decision | meter_event | settlement_input,并绑定Run/Step/Attempt、Manifest/Execution Fact、Work/Operation/Generation、Lane Trigger与冲突Candidate摘要;它与MeteringInputWorkAttemptBlocked@1原子提交,Lane保持blocked_on_owner_conflict + activeWork.state=pending,不写Finished/CAS/Case。它与Execution/Gateway Owner返回的Conflict Fact是互斥来源,不能互相冒充。当前同样没有Conflict Event或core_operations Member,Operations只可显示不完整Telemetry Reference。

Metering Work可观测性必须把MeteringInputWorkAttemptFinished@1.outcome严格解码为Eligibility等待/应用、Provider Cost处理或两Lane通用{kind=eligibility_and_settlement_input|provider_cost; state=superseded; supersededByWorkGeneration}。新Generation事务与旧Worker只能insert-or-compare同一Superseded Finish;旧Token零业务写。未完成Started扫描遇到该Finish即停止,不能把旧Attempt长期展示为Running,也不能把Superseded误投影成失败、Reconciliation Case或成功业务结果。

Finalization Case Identity 使用独立受控 Primitive reserveFinalizationReconciliationCaseIdentity,而不是复用Dimension级Late-settlement身份。严格 FinalizationReconciliationCaseIdentityReservation@1 的内容与摘要固定覆盖规范化 tenantKind/tenantId/workspaceId/projectId? + billingAccountId + billingReservationId + runId + billingFinalizationFenceId + reconciliationCaseRef + reconciliationGeneration + caseRequestOperationId + predecessorCasecaseRequestOperationId由Contracts固定Namespace对同一稳定Source身份确定性派生。Identity及其Reserve/Read的Audience/Scope不得包含可能被更高Generation替换的Triggering Work四元组或billingFinalizationOperationId。第一代只允许root,后继必须完整引用直接前代Case与Identity Reservation四元组。readFinalizationReconciliationCaseIdentityBySource以完整Tenant、Account/Reservation/Run/Fence、Generation、确定性Operation与Predecessor定向读取,严格返回found{reservation=FinalizationReconciliationCaseIdentityReservation@1} | not_found | conflicting{conflict quartet};仅Billing Finalization Case Identity Workload可用,不提供Admin、列表、latest或裸Ref读取。服务端和调用方重算摘要及Operation并逐项验证Repository绑定。同Source/Generation/Operation重放返回原Identity,同Generation异候选冲突;reserve(G1) → G2 Work取代G1 → G1 CAS失败 → G2必须复用相同Identity并成功,不能因Identity绑定旧Work形成孤儿或生成第二个Case Ref。

Operations Projector消费两类Finalization Case事件时只能使用下面两个Owner定向Read;Event身份字段统一使用eventEnvelopeDigestAlgorithmVersion + eventEnvelopeSha256,禁止泛化成eventEnvelopeDigest

readBillingFinalizationDecisionForOperations(
  purpose=operations_finalization_case_projection,
  caseRequestedEvent={ eventId / eventType / eventSchemaVersion;
    eventEnvelopeDigestAlgorithmVersion / eventEnvelopeSha256 },
  expected tenantKind, tenantId, workspaceId, projectId?, billingAccountId,
  billingReservationId, runId, billingFinalizationFenceId,
  reconciliationCaseRef, reconciliationGeneration, expectedResolutionRevision=1,
  caseRequestOperationId, billingFinalizationOperationId,
  finalizationCaseIdentityReservation完整四元组,
  billingFinalizationDecision完整四元组,
  triggeringBillingFinalizationWork完整四元组, triggeringBillingFinalizationWorkGeneration
)
  -> found{ decision=BillingFinalizationDecision@1; triggeringWork=BillingFinalizationWork@1 }
   | not_found
   | conflicting{ conflictRef; conflictSchemaVersion; conflictDigestAlgorithmVersion; conflictDigest }

readFinalizationReconciliationResolutionAppliedForOperations(
  purpose=operations_finalization_case_projection,
  resolutionEvent={ eventId / eventType / eventSchemaVersion;
    eventEnvelopeDigestAlgorithmVersion / eventEnvelopeSha256 },
  expected tenantKind, tenantId, workspaceId, projectId?, billingAccountId,
  billingReservationId, runId, billingFinalizationFenceId,
  reconciliationCaseRef, reconciliationGeneration, resolutionRevision=1,
  resolutionOperationId, actorWorkforcePrincipalId,
  finalizationCaseIdentityReservation完整四元组,
  finalizationReconciliationResolutionApplied完整四元组
)
  -> found{ fact=FinalizationReconciliationResolutionApplied@1 }
   | not_found
   | conflicting{ conflictRef; conflictSchemaVersion; conflictDigestAlgorithmVersion; conflictDigest }

两个Read均使用只授予core_operations/operations_projector的独立Audience,Scope绑定完整Source Event四元组和全部Expected字段;Billing Owner从不可变Event/Repository正文重算摘要后返回,Projector再次重算并逐项比较。not_found可重试且不写Case、Pending、Outcome或Receipt;conflicting隔离。Case Requested验证通过后,Operations按Identity预分配Ref创建sourceScope.kind=billing_finalization_run Case,冻结最终winning billingFinalizationOperationId + Decision quartet + Triggering Work quartet/generation + reasonCode。每个Case Generation固定expectedResolutionRevision=1且最多一条resolutionRevision=1 Applied Event;重评仍冲突只能形成后继Case Generation。Resolution Applied先到时,只有Owner Fact与Identity完整验证后才耐久写pending_resolution及Operations Applied Receipt;Request后到应直接materialize Resolved。

后继Case Requested在直接前代尚未由Billing Owner Fact权威终结时不得创建第二个Open Case,也不得在Ack后丢弃。Projector必须锁定同Source的前代Case、pending_case_resolutions_vNpending_case_successors_vN,把完整验证的后继Tenant/Account/Reservation/Run/Fence、后继Identity四元组、直接前驱Identity联合、Case Requested Event完整Envelope摘要、Case/Generation、两Operation、Decision、最终Work四元组/Generation与Reason作为一个严格PendingFinalizationCaseSuccessor@1行insert-or-compare,并在同一Operations事务写该Case Requested Event的OperationsProjectionAppliedReceipt@1后Ack;同前代/后继代次异Event、Identity、Decision、Work或Reason必须冲突。前代Resolution到达且前代Case已存在时,同一事务必须按Owner Fact关闭前代、物化该直接后继并把Pending行推进为consumed,Consumption冻结前代Resolution Event完整Envelope、Applied Fact四元组与后继初始Case Revision。若前代Request尚未来到,则Resolution仍按既有规则写pending_case_resolutions_vN;前代Request最终到达时须在一个事务直接物化已Resolved前代、消费后继Pending并物化后继。存在多代合法乱序时按Generation与Predecessor Identity消费最大连续、全部已验证链,任一时刻至多最后一代可Open;不能按到达顺序把C1 Fact应用到C2。在线消费与Shadow Rebuild必须对C2 Request → C1 Resolution → C1 Request、Resolution先到、并发互锁和同代异Candidate得到相同结果;Owner暂不可读时保留原Delivery non-terminal,不提交deferred结果或Receipt。

Finalization Resolution命令属于ADR-031的Metering/Settlement门禁,当前ADR-030只读Explorer阶段只注册并可投影下列严格Schema,不启用命令入口。任何Producer可能进入reconciliation_required前,必须与完整命令链同批启用:

FinalizationReconciliationResolutionCommandRequest@1 = {
  finalizationReconciliationResolutionCommandRequestRef / finalizationReconciliationResolutionCommandRequestSchemaVersion
  finalizationReconciliationResolutionCommandRequestDigestAlgorithmVersion=jcs-sha256-v1
  finalizationReconciliationResolutionCommandRequestDigest
  adminCommandId / domainIdempotencyKey / actorWorkforcePrincipalId
  tenantKind / tenantId / workspaceId / projectId?
  billingAccountId / billingReservationId / runId / billingFinalizationFenceId
  reconciliationCaseRef / reconciliationGeneration / expectedCaseRevision / expectedResolutionRevision=1
  finalizationCaseIdentityReservationRef / finalizationCaseIdentityReservationSchemaVersion
  finalizationCaseIdentityReservationDigestAlgorithmVersion / finalizationCaseIdentityReservationDigest
  caseRequestEventId / caseRequestEventType / caseRequestEventSchemaVersion
  caseRequestEventEnvelopeDigestAlgorithmVersion / caseRequestEventEnvelopeSha256
  action=reevaluate_current_owner_state
  investigationEvidenceReferenceCount
  investigationEvidenceReferences[]=sorted { ownerDomain=execution|metering|gateway|billing; evidenceKind;
    evidenceRef / evidenceSchemaVersion / evidenceDigestAlgorithmVersion / evidenceDigest }
  reasonCode
}

FinalizationReconciliationResolutionDecision@1 = {
  resolutionDecisionRef / resolutionDecisionSchemaVersion
  resolutionDecisionDigestAlgorithmVersion=jcs-sha256-v1 / resolutionDecisionDigest
  resolutionDecisionInputDigestAlgorithmVersion=jcs-sha256-v1 / resolutionDecisionInputDigest
  resolutionDecisionIdempotencyKey
  finalizationReconciliationResolutionCommandRequest完整四元组
  adminCommandCandidate完整四元组
  actorWorkforcePrincipalId
  tenantKind / tenantId / workspaceId / projectId?
  billingAccountId / billingReservationId / runId / billingFinalizationFenceId
  reconciliationCaseRef / reconciliationGeneration / expectedCaseRevision / expectedResolutionRevision=1
  finalizationCaseIdentityReservation完整四元组
  caseRequestEventId / caseRequestEventType / caseRequestEventSchemaVersion
  caseRequestEventEnvelopeDigestAlgorithmVersion / caseRequestEventEnvelopeSha256
  action=reevaluate_current_owner_state
  investigationEvidenceReferenceCount
  investigationEvidenceReferences[]=FinalizationReconciliationResolutionCommandRequest@1.investigationEvidenceReferences[]
  decision=authorized / decidedAt
}

readFinalizationReconciliationResolutionAppliedByOperation(
  resolutionOperationId,
  expected tenantKind, tenantId, workspaceId, projectId?, billingAccountId, billingReservationId, runId,
  billingFinalizationFenceId, reconciliationCaseRef, reconciliationGeneration,
  resolutionRevision=1, actorWorkforcePrincipalId,
  finalizationCaseIdentityReservation完整四元组,
  finalizationReconciliationResolutionCommandRequest完整四元组,
  adminCommandCandidate完整四元组,
  finalizationReconciliationResolutionDecision完整四元组,
  signedWorkforceCommandExecutionGrant完整四元组 / commandGrantJti
)
  -> found{ fact=FinalizationReconciliationResolutionApplied@1 }
   | not_found
   | conflicting{ conflictRef; conflictSchemaVersion; conflictDigestAlgorithmVersion; conflictDigest }

Request、Decision摘要都排除Repository-owned Ref/Time与摘要自身;Request不含Candidate/Decision/Grant/Applied/Operation,Decision Input不含Decision quartet/Time/Idempotency Key及后续Grant/Operation,Key只由Decision Schema与带算法Input Digest确定性派生。通用AdminCommandCandidate@1使用commandType=finalization_reconciliation_resolution,其既有commandRequest.payload严格选择本Request分支并保存完整四元组;不得给Candidate再造第二个同义specialization字段。自由理由只留Operations/Candidate,跨域Request只用注册reasonCode。先冻结Request业务Payload,Preview/Approval/JIT基于它完成,最终Candidate聚合全部;Operations锁定Case后在Candidate之后insert-or-compare Decision。resolutionOperationId由Contracts固定Namespace仅按完整Decision四元组确定性派生,因此无摘要环。

SignedWorkforceCommandExecutionGrant@1必须使用同名strict specialization并保存Request、Candidate、Decision完整四元组和派生Operation;aud=billing_finalization_reconciliation_resolution_commandboundWorkload=Admin Command Gateway Workload Principal且等于实际呈递Domain调用的Caller JWT sub,Grant sub=actorWorkforcePrincipalId,JTI只允许Billing消费域一次。Billing处理入口调用上面的operation Read:found必须完整比较Actor、Request/Candidate/Decision/Grant/JTI后返回首次Fact,即使Grant已过期或JTI已消费;conflicting停写;只有not_found才检查当前Grant时间/JTI及Fence/Case。成功事务原子消费JTI并追加Applied Fact、Audit、Event和两条Mandatory Delivery。Fact是唯一稳定Result。整条链只允许reevaluate_current_owner_state,禁止金额、Ledger、Reservation终态、替代Snapshot、忽略冲突和自由Map。investigationEvidenceReferences[]必须非空、使用Contracts Registry封闭Tuple并排序去重,只是授权调查引用;Billing验证五个对象间集合等值和Schema注册,不解引用它们证明修复。随后仍由现有Finalization Owner Reads与Current Receipts重评真实Owner状态,冲突未消失时创建新Case代次。

Core Command Grant Exchange另持久化严格CommandGrantExchangeResult@1,保存自身四元组、commandGrantExchangeOperationIdactorAssertionIssuer + actorAssertionJticommandType=finalization_reconciliation_resolution、Actor、boundWorkload、Request Digest/Nonce、Admin Command Candidate quartet以及Signed Grant quartet/JTI;前两字段分别逐字节等于已验证Actor Assertion JWT的iss + jti,摘要排除Repository-owned Ref/Time和摘要自身。Operation由Contracts Namespace仅按actorAssertionIssuer + actorAssertionJti确定性派生,Candidate/Workload/Request/Actor不进入Operation而是必须insert-or-compare的Result正文。readCommandGrantExchangeResultByOperation(operationId, expected actorAssertionIssuer/actorAssertionJti/commandType/actor/boundWorkload/requestDigest+nonce/Candidate quartet)返回found{result; grant}|not_found|conflicting{conflict quartet}。Core先认证Caller Workload JWT并要求Subject等于Bound Workload,再在Assertion时间/JTI检查前执行Read;同输入found返回首次Grant,即使Assertion已过期/消费,任一正文不同则conflicting停写,仅not_found进入校验并原子写Grant、Result、JTI Consumption与签发Audit。负测覆盖提交后响应丢失跨Assertion到期、同JTI异Candidate/Request/Nonce/Actor/Workload、JTI重放、并发双签、Result或Audit失败回滚。

reserveReconciliationCaseIdentity 是 Operations Runtime的独立受控 Primitive,不经过 Event Projector才分配。它在同一事务对 (sourceOwner=billing, sourceKind=late_settlement, billingReservationId, billingAccountId, runId, runStepId, executionAttemptId, chargeDimensionKey, caseGeneration) 唯一,先生成稳定Case Ref,再持久化包含这组完整Source身份的Reservation严格DTO及其完整四元组;caseRequestOperationId由Contracts固定Namespace对同一组字段确定性派生,调用方不能覆盖,Operations必须重算并与请求相等。第一代必须 caseGeneration=1 + predecessorCase.state=root;后继必须恰好前代+1并在 predecessorCase.state=supersedes 中完整引用直接前代Case与Identity Reservation四元组。同Generation/Operation重放返回原Reservation,同Generation异Operation/Predecessor/Candidate返回 conflicting。预留不创建 reconciliation_cases_vN、不触发告警、审批或可见Open Case;未使用Reservation可以保留,但不能被另一个Account/Run/Step、经济身份、Exposure或Generation重绑。受限 readReconciliationCaseIdentityReservationBySource 以完整Source Key、Generation、期望确定性Operation与Predecessor为请求,返回 found{reservation=ReconciliationCaseIdentityReservation@1} | not_found | conflicting{conflict Reservation完整四元组};仅Billing Case Identity Workload Audience/Scope可调用,服务端与调用方都必须验证Source/Operation/Predecessor、摘要及Repository绑定,不提供列表、模糊查询或裸Ref读取。若reserve已提交而Billing在保存响应或Transition前崩溃,新Worker必须先以相同Source/Generation/Predecessor调用该Read或重放reserve,严格验证并采用既有Reservation,不能生成第二个Case Ref或让孤儿预留封锁Generation。

Lineage的每次readSettlementInput固定使用readPurpose=operations_transition_audit与独立Operations Projector Audience;请求Expected Identity与Scope同时绑定Tenant/Workspace/Project、Billing Account/Reservation、Run/Step/Attempt/Dimension、当前Event ID/Type/Schema/Envelope摘要、Transition完整四元组和单个目标Snapshot五元组,服务端与Projector逐项比较。Projector不得用Billing Purpose、Admin Token或同一个授权枚举/读取其他Event或Snapshot。

上述经济边界中的身份短写一律展开为Billing Account/Reservation/Run/Step/Attempt/Dimension。Transition、Case Requested、Applied与Late Result Event都必须自包含runStepId并与Owner Fact、Consumption、Settlement Input、Exposure、Case Reservation及Owner Read Expected Identity逐项相等;Event缺失Step、跨Step重绑或Attempt→Step隐式Bootstrap均在Owner Read前fail closed。billingTransitionValidationOperationId必须由Contracts固定Namespace对(billingTransitionOperationId, billingReservationId, runStepId, executionAttemptId, chargeDimensionKey, fromStateRevision, basisDigestAlgorithmVersion, basisDigest)确定性派生,并与Owner Fact、Consumption及Metering Receipt回显逐项相等。

Operations Runtime还必须实现下列版本化Case Create/Ack恢复Read:

readReconciliationCaseByReservedIdentity(
  ReconciliationCaseIdentityReservation完整四元组,
  expected reconciliationCaseRef, billingReservationId, billingAccountId, runId, runStepId, executionAttemptId,
  chargeDimensionKey, caseGeneration, caseRequestOperationId
)
  -> { result=not_created }
   | { result=found; reconciliationCaseRef; caseRevision;
       sourceExposureRef / sourceExposureSchemaVersion;
       sourceExposureDigestAlgorithmVersion / sourceExposureDigest / sourceExposureRevision;
       caseState }
   | { result=conflicting; conflictRef }

它只接受精确Billing Case Recovery Workload Audience/Scope。服务端以Reservation四元组读取并重算不可变Owner正文,逐项验证Source/Generation/Operation、Case Ref、Reservation、Account/Run/Step/Attempt/Dimension和Repository绑定;found的Exposure四元组/Revision必须等于Case当前冻结Source,调用方再次严格验证。not_created只允许在Reservation合法存在且尚无Case时返回;不存在、错摘要、缺Step、跨Step/其他身份或同Ref重绑必须fail-closed/conflicting,不能伪装为not_created。Create已提交但Ack丢失时,Billing重放该Read并采用同一Case;该Read不提供列表、latest、裸Ref或按Case文案模糊查询。

本节任何“Account/Run/Attempt/Dimension”简写都严格展开为“Account/Run/Step/Attempt/Dimension”;runStepId必须来自经济Event/Owner Fact自身,禁止通过Attempt映射、相邻Event或当前Run补值。

Case Requested消费先验证本地Case Identity Reservation完整四元组、Generation与Predecessor,再只凭Event自带的Transition四元组、billingTransitionOperationId + fromStateRevision + toStateRevisionAccount/Run/Step/Attempt/Dimension调用 readBillingSettlementTransition,并验证Exposure四元组与Event字段;即使Transition Event尚未投递也不得等待、从相邻Event补参数或从Attempt反查Step。验证后按预分配 (caseGeneration, Case Ref) 和同代单调Exposure Revision幂等创建/更新。一个或多个Resolution Applied先到时,Projector必须先验证Reservation/Generation、readBillingCaseResolutionApplied及Source专属Exposure前驱:Settlement Transition允许同代Current Open→Resolved以及连续零/负更正中的Current Resolved→Resolved直接后继,Late Command仍只允许授权Current Open→Resolved;跳过前驱、回指旧Open、跨Generation/Reservation全部冲突。Projector在同一事务以 (caseGeneration, reconciliationCaseRef, resolvedExposureRevision, Applied Fact完整四元组) 唯一逐条写入 pending_case_resolutions_vN.outcome=pending_resolution及Event Receipt;后到同代Case Requested选择最高连续、已验证Revision并在一个事务直接创建绑定对应Fact的Resolved Case,禁止出现中间Open提交。已有Case只在同Generation内按Exposure Revision产生 applied | superseded_noop | already_applied | conflict;已Resolved Case收到更高合法Resolved直接后继时追加Timeline并原子推进Source Binding且保持Resolved。中间Owner Fact不可读或链暂不完整时必须返回retryable,不写Outcome、不写Applied/Event Receipt、不提交Case Mutation、Boundary或Exact Index,让原Event Delivery保持non-terminal并按既有Lease重试;禁止把瞬态保存为deferredsource_owner=billing下的source_kind=late_settlement | billing_finalization都禁止任何本地普通命令、评论或“无动作关闭”写入resolved|rejected;前者只有完整验证的BillingCaseResolutionApplied@1、后者只有FinalizationReconciliationResolutionApplied@1能令其终结,且terminal_authority=billing_owner_applied必须按sourceKind逐项等于applied_resolution_fact。平台承担、供应损失或核销在Billing-owned Disposition契约发布前也不能绕过该Refinement。更高Generation使用新Case/Reservation,旧代Approval/JIT/Grant、本地评论或指派都不得迁移。晚到旧代/旧Revision Create/Ack不得覆盖新代或把Resolved恢复为Open。只有完整验证后的Case Mutation、Boundary/Outcome、Exact Index和Receipt才原子提交;失败只重试投影,不能回滚Billing已经提交的Ledger/State。

Late Command Result Event必须自包含 Result四元组、Case Identity Reservation、Open→Resolved Exposure和同事务 Applied Fact四元组,足以构造 readLateSettlementCommandResultreadBillingCaseResolutionApplied;不得依赖 Applied/Case Requested Event先到。Contracts/Repository测试覆盖五个 Event round-trip、所有四元组缺一、未知算法、同 Ref异摘要、Case Reservation错绑、Case Requested缺失/篡改Transition Operation或from/to Revision、Case Requested先于Transition Event仍独立验证Owner、F→T(open)→Late Result→T(correction)乱序、缺失/错误State边界前驱或Revision不连续、Billing停在S1而Metering已形成S2→S3时以完整[S2,S3]一次catch-up到S3、Lineage中间项Owner Read失败/摘要错配/漏项/分叉、resolve-before-create、多条Resolution先到后取最高连续版本、Finalization C2 Request → C1 Resolution → C1 Request的Pending Successor与Event Receipt同事务、同代异后继Candidate冲突、最大连续代次链和Shadow Rebuild同结果、Open O1→Resolved R2→Resolved R3与回指旧Open分叉、Transition随机/错误前驱派生Resolution Operation、Late Command Resolution Operation不等于Command Operation、Receipt前后崩溃、Create/Applied Ack丢失、Case Owner Read三分支、旧 Create晚到、更高 Exposure超越和 Shadow Rebuild相同收敛结果;另覆盖reserve提交后Billing保存响应或预提交Transition前崩溃,新Worker在相同或更新Snapshot下按Source/Generation/Predecessor读回并采用同一Reservation,且只存在一个Case Ref、该Generation仍可继续,Create已提交但Ack丢失时Billing读回同一Case,Metering Receipt提交后Billing预提交前崩溃时新Worker重建同一Resolution Operation/Basis/Validation Operation,F→旧Basis/Receipt→并发前驱提交→CAS失败→重读新From State/Basis→新Validation Operation→成功Event且旧Receipt或错误Validation Operation不得进入Projection,以及本地resolved|rejected|no-action与新Open Exposure或Owner Applied Fact并发时本地终态恒定fail closed、Applied/Create任一到达顺序都只产生一个Owner驱动终态。

operation_summaries_vN 不持久化 projection-level freshnessverificationStatesnapshotCurrencyprojectionCompleteness,避免新 Source、Delivery、Gap 或修复后留下 stale-green 第二事实源。Query Response 必须在同一个只读 Consistent Snapshot 中,从 Active Registry、最新可比 Completeness Snapshot、当前 Guard 与 Operations Runtime 状态现场组合这些元数据;记录自身的 limitations[] / sectionSupport 只表达 Event 版本与已接入产品阶段,不冒充投影完整性。

表名和物理分区可由实现调整,但投影持久化必须保留 projectionVersion、字段级 evidenceKind 与记录级 limitations[] / sectionSupport;Query Response/DTO 再现场附加 freshness / verificationState / snapshotCurrency / projectionCompletenesssummary_kind=operation 严格要求非空 operation_id + correlation_idrun.created@2.0 还必须完整生成 Versioned Admission Snapshot。携带合法 Operation 的 v1 Event 可以进入 operation 分支,但只投影事件实际字段并带 partial_legacy_event;缺少 Operation 的 v1 Event 只能成为 legacy_run,使用独立 summary_id 作为投影键,不生成或展示伪造的 Operation/Correlation/Request ID,也不能形成 Admission Snapshot。

Versioned Admission Snapshot 只能从 run.created@2.0 + wallet.reserved@2.0 显式字段构建,承载 Run Explorer 已承诺的全部低敏准入、主体、完整 Authentication/Authorization Evidence身份与准入时Evaluation Set、Product、模型、RunAdmissionManifest追踪引用、Output Contract四元组、Reservation/Price、Billing Policy、严格BillingValue与状态引用。Evaluation Set四元组、统一Archive Cut、Authorization Scope Snapshot四元组、Action Count/规范排序去重集合、成员Count/精确排序四元组与Revision缺一不可;这些字段使Projector无需Manifest即可构造Set历史Read。Output Contract四元组同样缺一不可。initial_model_deployment_id只表示首次准入目标;BillingValue保留规范Decimal,Kind、Entitlement Key/Unit与Money Currency都不可丢失。

Event↔Manifest 等值只由 Admission Producer 在同一事务 Append 前强制:Run Event 的Actor/Authentication/Authorization/Evaluation Set(含Set四元组/Cut/Scope Snapshot/Action集合/成员)/Product/Output Contract/账务引用与Manifest必须逐项相等;Event Scope四元组等于Manifest executionAuthorization.authorizationScopeSnapshot*,Event Scope/Action又与Evaluation Set逐项相等。Wallet Event的reservation.value必须与Manifest reservedValue同构等值。任一错配回滚Run、Manifest、Reservation、Event与Outbox。Projector不解引用Manifest;Authorization验证先按Event自包含Set/Scope/Action/Cut读取Set,再按成员和同一Cut读Evaluation,不使用当前Archive Revision重算。

只有 Wallet v2 到达且其 Event 自身通过严格 BillingValue 校验,并与 Run v2 通过双方都携带的因果、Actor、Tenant、Workspace/Project、Operation/Correlation、Billing Account、Reservation、Pricing 与 Billing Policy 等值验证后,reservation_value / reservation_status / wallet_reserved_event_id 才出现。跨 Event 冲突进入 Quarantine;Projector 不拿 Manifest 补值或比较。首个 Producer 只允许 tenant_kind=organization;Personal Space 等待完整门禁。两个 v1 只形成 Legacy/Partial 投影,不因原本可选字段缺失而隔离,也不能伪造完整 Admission Snapshot。

Wallet v2 先到时只进入 pending_unlinked_reservations_vN,并原样保存其 Pricing/Billing Policy 引用与完整严格 BillingValue,不能创建 Operation Summary;Run v2 到达后 Projector 在单一事务中校验 Causation、Run、Reservation Aggregate/ID、Actor Principal、Billing Account、Pricing、Billing Policy、Tenant、Workspace/Project、Correlation 与必填 Operation 全部相等,再链接 Snapshot、删除 Pending 投影视图项并写 Receipt。冲突进入 Quarantine,不合并任何字段。BillingValue 不与 Run Event 比较,因为它只存在于 Wallet Event;它与 Manifest reservedValue 的等值已经由 Admission Producer 同事务不变量保证。Wallet v1 的可选 Operation/Causation 只按原 Schema 进入 Legacy/Partial 分支,不走完整 v2 链接器。

Operation Summary 整体只能标为 derived_summary,Summary 与 Admission Snapshot 的每个对外字段都通过规范化 Field Evidence 或语义等价结构记录 recordType + recordId + fieldPath + evidenceKind + sourceRef + sourceSchemaVersion;不能因为记录含一个 Domain Fact 就把 Observation/Runtime 派生字段整体标为 domain_factfirst_accepted_observation_at/latest_accepted_observation_at 只聚合 Core accepted_atsource_claimed_observed_at 只保存在 Timeline,不进入 Summary。不保存或返回全局源位置、头部位置或连续位置等单值进度标记。普通查询不能把完整性依据藏起来。

Finalized Completeness Snapshot 与 Member 是 append-only 证据,只能由 Projector Workload 内的 Core Operations Verifier 模块在同一个 PostgreSQL Consistent Snapshot 事务中从当时可见的 Event/Accepted Observation 生成、完成 anti-join/Gap/Quarantine/Schema/语义验证并写入;Query Role 不能创建或更新。Snapshot 必须把 sourceQueryDefinitionVersion + sourceFilterDigestAlgorithmVersion + sourceFilterDigest 成组冻结;Filter Digest 对该版本严格 Source Filter DTO 的 Contracts Canonical JSON 计算,算法或字段集变化必须升级相应版本。Source Member 使用严格 sourceDigest 联合:Event 分支只能取覆盖完整 Envelope+Payload 的 Outbox Event eventEnvelopeDigestAlgorithmVersion + eventEnvelopeSha256,Accepted Observation 分支只能取 Accepted Envelope/Registry 的 observationDigestAlgorithmVersion + acceptedEnvelopeSha256,绝不能误用 Payload-only 或 Submission 摘要;sourceKind 必须与分支匹配。Event 与 Accepted Observation 的 Source Set 分别按 Contracts 固定排序与序列化完整 sourceKind + sourceId + sourceDigest.kind + algorithmVersion + sha256 成员,再以各自的 setDigestAlgorithmVersion=jcs-sha256-v1 计算摘要;算法版本与摘要成组持久化、返回并进入上层摘要,Count 只是摘要。完整 Source 成员保存在 completeness_snapshot_membersproofManifest 另外冻结 Source Filter、两类 Source Set、适用 Mandatory Delivery/Receipt、Revision Gap、Quarantine、Unsupported Schema 与 Semantic Check 的精确成员/输入,并以 proofManifestRef + proofManifestSchemaVersion + proofManifestDigestAlgorithmVersion + proofManifestDigest 内容寻址;只存 Count 或裸 Digest 不够。Mandatory Delivery 使用Definition Set,而非单一当前Definition;Semantic Check Input另行携带Schema/Definition Version、Digest Algorithm Version与Digest。所有本节新建内容摘要首期算法固定为 jcs-sha256-v1;未知算法拒绝,算法或覆盖字段变化必须升级对应 Digest Algorithm Version,结构变化同时升级所属 Schema/Definition Version。Proof Manifest、Candidate Boundary 与 Readiness Proof 的摘要都覆盖各自完整严格 Candidate(包括所有嵌套 Digest Algorithm Version),只排除 Repository-owned ID/Ref/Time 与摘要自身;Expected Receipt Coordinates Digest 覆盖按 Contracts 排序的完整坐标集合。Cutover Candidate/Member 使用相同 tagged Source Digest,并冻结相同的 Source Filter 三元组;Candidate Boundary、Expected Receipt Coordinates 与后置 Readiness Proof 都保存自身 Schema Version、Digest Algorithm Version 与 Digest,采用独立表与时序,不能塞进 Completeness Snapshot。createdAt、最大 Event/Observation ID、PostgreSQL Transaction ID 或扫描游标都不能代替精确集合边界。完成后的 Snapshot/Member/Manifest/Candidate/Proof 不可更新,Projection Build 只能引用其稳定 ID/Ref、Schema Version、Digest Algorithm Version 与 Digest。

同一Snapshot可以包含在不同时间Append、分别冻结不同Delivery Set Definition的Event。mandatoryDeliveryDefinitionSet必须把Source Event实际使用的deliverySetVersion + definitionSchemaVersion + definitionDigestAlgorithmVersion + definitionDigest按完整四元组排序去重,计算definitionSetDigestAlgorithmVersion=jcs-sha256-v1 + definitionSetDigest + definitionCount;每个Delivery坐标继续保存其Event的精确Definition四元组,要求该成员存在于Definition Set且与Canonical Event/Archive Source等值。Definition切换前后的Event可在同一Proof共存;禁止丢弃旧Source、从当前Registry覆盖历史Definition或任选一个Definition冒充全集。

Event Applied Receipt 使用内容可验证的OperationsProjectionAppliedReceipt@1:除唯一坐标(consumerName, projectionName, projectionVersion, eventId)外,必须持久化自身Ref/Schema Version/Digest Algorithm Version/Digest、destination=core_operations、Event Type/Schema Version以及与Source逐字节相等的eventEnvelopeDigestAlgorithmVersion + eventEnvelopeSha256;Receipt Candidate覆盖除Repository-owned Ref/appliedAt及摘要自身外的全部字段。Projection Mutation、Exact Index/Timeline/Case Outcome与该Receipt必须在同一Operations事务insert-or-compare。readOperationsProjectionAppliedReceipt(Receipt完整四元组, expected destination/consumer/projection/event ID/Type/Schema/Envelope摘要)的Expected Projection必须从Event冻结的DeliverySetDefinition@N匹配Member取得,Audience/Scope同时绑定Definition四元组与Member Target;不能复制Receipt正文来构造Expected。它只向原Producer Dispatcher返回found{receipt=OperationsProjectionAppliedReceipt@1} | not_found | conflicting,双方重算摘要并比较Target,不提供Admin、列表或latest。Observation Receipt仍固定为(consumerName, projectionName, projectionVersion, observationId)并保存与Source相等的observationDigestAlgorithmVersion + acceptedEnvelopeSha256。Delivery Set冻结Consumer、Expected Receipt与精确Projection Target,配合完整Receipt四元组/Ack校验,保证其他Consumer、其他Projection、不同摘要算法或Shadow Receipt不能完成该Delivery;跨库Billing等Producer不得伪造本地Receipt外键。

Evidence Kind、投影完整性与能力限制

每个 Timeline Entry 和 Summary 字段统一使用以下 evidenceKind

evidenceKind含义示例
domain_fact已由领域事务提交的权威事实run.created@2.0wallet.reserved@2.0
operational_observation某服务报告曾看到的状态Edge request_rejectedidempotency_replayed
operations_runtime运维管道自身的持久运行状态Delivery、Attempt、Receipt、Build、Gap、Quarantine
telemetry_reference指向可采样诊断证据Trace/Log Reference
derived_summary从已标注来源计算的摘要当前最可信边界、链路完整度

projectionCompleteness 只判断当前已支持投影范围的 Source 完整性,并且严格区分:

  • complete_for_supported_scope:在同一个 Consistent Snapshot 内,适用事件对当前 Projection Version 的 Event Receipt Anti-Join 为空、已接受 Observation 对当前版本的 Observation Receipt Anti-Join 为空,且对应 Mandatory Delivery、Revision Gap、Quarantine、Unsupported Schema 与 Semantic Check 全部通过。Observation 范围只覆盖 Core Accepted Source,不代表 Edge 请求全集。
  • partial_source_gap:已经确定存在新 Source/缺失 Receipt、未完成 Mandatory Delivery、Aggregate Revision Gap、影响查询范围的 Quarantine/Unsupported Schema 或 Semantic Check 失败。
  • unknown:无法证明完整,且当前证据也不足以确认具体 Gap 或影响范围。

记录与产品能力限制使用可并存的 limitations[],首期至少包含:partial_legacy_event(例如 v1 缺少 Admission Snapshot)和 not_yet_supported(存在尚未接入的阶段)。同时按 admission | gateway | output | asset | metering | settlement 返回 sectionSupport,每项为 supported_complete | supported_partial | not_yet_supported | unknown 并携带原因。

“完整”只针对当前支持范围,绝不等于完整执行链已经存在。这三组状态不得相互覆盖:v1 可以同时是 projectionCompleteness=partial_source_gap 且带 partial_legacy_event;已追平的 v2 可以是 complete_for_supported_scope,同时 Gateway、Output、Asset、Metering 和 Settlement 仍为 not_yet_supported。页面不能用一个绿色或 Partial 标签吞掉另一项事实。

持久化的 complete_for_supported_scope 只证明 completenessAsOf.snapshotId/evaluatedAt 的完整证明输入,不自动代表稍后的查询时点。Snapshot Result 必须保存可重新比较的 Proof Manifest 四元组:proofManifestRef + proofManifestSchemaVersion + proofManifestDigestAlgorithmVersion + proofManifestDigest;Manifest 内冻结 sourceQueryDefinitionVersion + sourceFilterDigestAlgorithmVersion + sourceFilterDigest、两类 tagged Source Set Digest/Member及Count/Receipt Anti-join、Mandatory Delivery Definition Set的tagged Digest/Count与完整排序四元组成员、带terminal|non_terminal状态分类且逐项绑定精确Definition四元组的Delivery坐标集合及其Set Digest/Count/Non-terminal Count、Revision Gap/Quarantine/Unsupported Schema的Set Digest/Count,以及 tagged Semantic Check Input Digest/Result和顶层结果。Proof Manifest Digest覆盖上述全部字段和Count/Result,只排除自身Digest与Repository创建时间;Snapshot列只是同值索引,必须与Manifest双向等值,不能在读取时从可变的Current Delivery、当前Definition Registry、当前Gap或当前Semantic状态回填历史Proof。

Query 若要返回 snapshotCurrency=verified_current,必须在同一个只读 Consistent Snapshot 中使用相同 sourceQueryDefinitionVersion + sourceFilterDigestAlgorithmVersion + sourceFilterDigest 和 Semantic Check Version,对全部 Proof Manifest 输入及其 Schema/Digest Algorithm Version与当前状态做双向精确集合/摘要比较,并确认 Active Projection Version 未变;Mandatory Delivery必须同时比较Definition Set Digest/Count/完整四元组成员、逐坐标绑定的Definition、精确坐标/状态Set Digest、Count和Non-terminal Count,不能只比较当前Registry或总数。只有完全相同才可沿用 Snapshot 的已验证结论。相同 Definition Version 下 Filter Algorithm/Digest 缺失、未知或与 Snapshot 不同属于定义漂移,必须返回 verificationState=unverified + verificationReason=definition_mismatch,不能降格成普通 stale,也不能因当前成员集合碰巧相等而声称 verified_current。只有定义三元组与 Semantic Definition 可比时,Guard 确认其他 Proof 输入变化才返回 snapshotCurrency=stale:当前有新/缺失 Source、Pending Delivery/Receipt、Gap/Quarantine/Unsupported Schema 或语义失败等确定负向事实时,projectionCompleteness=partial_source_gap;输入变化但当前没有确定负向事实(例如 Pending 已 Ack 或隔离已修复)时为 unknown,直到 Verifier 生成新 Snapshot。若没有已完成 Snapshot、Active/Query/Semantic Definition 不可比,或 Guard 无法执行/比较,则 snapshotCurrency=unknownverificationState=unverifiedprojectionCompleteness=unknown,不能误报 stale。时间差、Count、最大 ID 或缓存 TTL 不能替代这个 Guard。

Cutover Readiness 是另一维度。T1 前先把 Shadow Build 的 Claim Mode 切为 paused 并排空其 Event/Observation in-flight Mutation;T1 的短 Consistent Snapshot 事务再冻结不可变 CutoverCandidateBoundary(精确 Source Member及两类 tagged Set Digest、sourceQueryDefinitionVersion + sourceFilterDigestAlgorithmVersion + sourceFilterDigest、Semantic Definition Version 与 tagged Expected Receipt Coordinates Digest),并保存 Candidate 的 ID/Schema Version/Digest Algorithm Version/Digest;同时把 Shadow Build 原子绑定到该 Candidate、递增 Claim Fencing Token 并切为 candidate_bound。旧 Token 的晚到 Mutation 必须失败。此时不得预写 ready 或声称 Receipt anti-join 已为空。Shadow 恢复后只可 Claim Candidate Member 并 Catch-up;之后获取 Active Cutover Lock、停止新 Active Claim 并排空 Active in-flight。最终事务逐项复核 Candidate 的 ID/Schema/Digest Algorithm/Digest,并对该边界计算 Receipt anti-join、Gap、Quarantine、Unsupported Schema 与 tagged Semantic Check Input Digest;全部通过时才追加新的不可变 CutoverReadinessProof,保存自身 ID/Schema/Digest Algorithm/Digest并引用完整 Candidate 四元组,再在同一事务原子切 Pointer/Consumer Target并激活引用新精确Projection Target的Delivery Set Definition。边界之后的新 Source/Pending Delivery 不阻塞切换,恢复后只由新 Active 追平,并在完成前让 Query 显示 partial_source_gap;切换前已Append的Delivery仍按自己冻结的旧Definition Target收敛。普通 Completeness Snapshot 不走这个两阶段时序,仍可在一个 Consistent Snapshot 事务内同时冻结 Source 与 Proof。领域 Writer 与 Observation Intake 不暂停;如果实现不能原子绑定/精确过滤 Candidate,则必须改为在有界窗口短暂停 Writer/Intake,不能保留竞态。

Operation Summary 与 Timeline

首期 Operation Summary 回答:

  1. 哪个公开 Request 首次成功创建了 Operation;本次查询是否来自后续 Replay Observation。
  2. 哪个 Tenant、Workspace、可选 Project、Service Account 和 Billing Account 被准入。
  3. 哪个 Public Model、Offering Revision、Execution Target 与 Pricing Snapshot 被固定。
  4. Run 与 Reservation 是否已由权威事件确认。
  5. Outbox 是否已存储、Claim、投递、消费并投影;这些 operations_runtime 记录由 Core Query 直接组合,不递归生成领域事件。
  6. 当前能够信任的最远边界是什么,哪些后续阶段尚未实现或尚未观测。

这些字段来自 Versioned Admission Snapshot Projection 与字段级 Source Lineage,不允许 Query 或 Projector 回查当前 Run、Manifest、Developer Access、Authorization Evidence、Model 或 Billing 表补齐。Authentication 保持严格四分支联合;每个临时 Grant/Assertion 分支的 Ref/Schema/Claims Digest 必须成组投影,product 与分支 Surface 保持等值。Output Contract 也只能使用 run.created@2.0 自包含的 Ref/Schema/Digest Algorithm/Digest 四元组,不能从当前 Manifest 或产品配置补值;Reservation Value 只能使用 wallet.reserved@2.0 自包含的 BillingValue 联合,不能从 Manifest 或当前钱包推导。wallet.reserved@2.0 尚未到达时 Reservation/Value 保持缺失并显示来源延迟,而不是从账本读取当前值。

Timeline 不用时间相邻伪造全局因果。Versioned Timeline 直接保留可用的 occurredAtsourceClaimedObservedAt、Core acceptedAtderivedAtappliedAtcausationId、Aggregate ID/Revision 和 Source Ref;因果关系仍以因果边、阶段和 Revision 呈现。Observation 条目固定按 (acceptedAt, observationId) 稳定排序;sourceClaimedObservedAt 只作为标注清晰的来源声明时间展示,不参与排序,也不得覆盖 Core 接受/应用时间。

精确 ID 检索

首期只建立低敏、不透明稳定 ID 的精确索引:

  • requestId
  • operationId
  • correlationId
  • runId
  • reservationId
  • eventId
  • observationId
  • errorId(仅在已接受的 Error Observation 或后续 Error Occurrence 明确提供时)。

run.created@1.0 没有 requestId2.0 字段时,只索引事件真实携带的 ID,并返回 Partial 原因。准入前失败和每次 Replay 的 Request ID 只有在对应 Edge Observation 成功摄取时才可检索。由于 Edge 没有 Durable Spool 或连续 Sequence,页面只能显示已接受 Observation 的记录集合、时间范围与已知 Intake/Source 健康窗口,不能保证所有 Request ID 存在,也不能声称能够检测 Observation 缺口。

首期不提供 Prompt、输入内容、邮箱、IP、Provider 原始 Task ID 或任意文本模糊搜索。用户公开账号、受限邮箱、Gateway/Asset/Settlement 等搜索属于后续按领域授权扩展,不得为了页面便利提前复制 PII 或私有网关数据。

内部 Query Contract

Core 首期冻结三组版本化内部接口:

# Workforce Grant Exchange
POST /internal/v1/workforce/query-grants:issue

# Operations Query
POST /internal/v1/operations/search
POST /internal/v1/operations/explorer
POST /internal/v1/operations/projection-status

# Observation Intake
POST /internal/v1/operations/observations

Search 每次只接受一个符合 Contracts 类型与长度约束的精确 ID,枚举固定为 requestId | operationId | correlationId | runId | reservationId | eventId | observationId | errorId;后两者只在相应 Accepted Source 存在时命中。使用 POST 避免敏感标识进入 URL、代理访问日志和浏览器历史。查询接口返回统一内部 Envelope;Snapshot 相关字段是严格判别联合:

每次 Search 还固定 identifierNamespace=domain_fact | accepted_observation | auto,并由 Contracts 限制合法 Type/Namespace 组合;响应回显严格 negativeProofCapability=complete_source_guard | positive_match_only。首期只有从 Canonical Event/Archive Source 查询的 operationId | correlationId | runId | reservationId | eventIddomain_fact 组合可在完整 Guard 下使用 complete_source_guardrequestId(Admission Event + best-effort Observation)、errorId、所有 auto 查询,以及尚未把永久 Registry 纳入 Completeness Proof 的 observationId/accepted_observation 都是 positive_match_only:可以返回已授权命中,但空结果永远不能证明不存在。未来提升能力必须升级 Source Query Definition/Contracts,并把对应不可变 Namespace Registry 纳入 Member、Guard 与负向测试,不能只改 UI 文案。

OperationsEvidenceTimes@1 = {
  occurredAt?; sourceClaimedObservedAt?; acceptedAt?; derivedAt?; appliedAt?
}

OperationsFreshness@1 =
  { status=verified_current; evaluatedAt; latestAcceptedAt?; lastAppliedAt?; lastVerifiedAt }
| { status=stale; evaluatedAt; latestAcceptedAt?; lastAppliedAt?; lastVerifiedAt }
| { status=unknown; evaluatedAt; latestAcceptedAt?; lastAppliedAt?; lastVerifiedAt=null }

OperationsSectionSupport@1 = {
  section=admission|gateway|output|asset|metering|settlement
  status=supported_complete|supported_partial|not_yet_supported|unknown
  reasonCode?
}

MissingSourceDisclosure@1 =
  { state=none }
  | { state=redacted; itemCount }
  | { state=available; itemCount;
      items[]=sorted_unique {
        sourceKind=event|accepted_observation|mandatory_delivery
        sourceId; reasonCode
      } }

UnsupportedSchemaDisclosure@1 =
  { state=none }
  | { state=redacted; itemCount }
  | { state=available; itemCount;
      items[]=sorted_unique {
        sourceKind=event|accepted_observation
        sourceType; sourceSchemaVersion; affectedCount
      } }

OperationsObservationEvidence@1 = {
  acceptedObservationRange =
    { state=none }
    | { state=available; firstAcceptedAt; lastAcceptedAt; acceptedCount }
  acceptedHealthWindowCount
  acceptedHealthWindows[]=sorted {
    producerService; environment; deploymentId?
    windowStartAcceptedAt; windowEndAcceptedAt
    status=healthy|degraded|unknown
  }
  knownDeliveryFailures =
    { state=none }
    | { state=redacted; itemCount }
    | { state=available; itemCount;
        items[]=sorted_unique {
          producerService; deploymentId?; normalizedErrorCode; firstFailedAt; lastFailedAt
        } }
  completenessClaim=unknown|not_measurable
}

OperationsAuthorizationScope@1 = {
  action=operations:search:read|operations:explorer:read|operations:projection-status:read
  tenantScope =
    { kind=all_authorized }
    | { kind=tenant; tenantKind; tenantId; workspaceId?; projectId? }
  fieldClassifications[]=sorted_unique
  grantScopeDigestAlgorithmVersion=jcs-sha256-v1
  grantScopeDigest
}

verifiedCommon = {
  completenessAsOf = snapshotId / evaluatedAt / sourceQueryDefinitionVersion
                   / lastVerifiedProjectionCompleteness
  integrity@2 = {
    snapshotProof = {
      proofManifestRef / proofManifestSchemaVersion
      proofManifestDigestAlgorithmVersion = jcs-sha256-v1
      proofManifestDigest
      sourceFilterDigestAlgorithmVersion = jcs-sha256-v1
      sourceFilterDigest
      eventSource = setDigestAlgorithmVersion / setDigest / count / receiptAntiJoinCount
      acceptedObservationSource = setDigestAlgorithmVersion / setDigest / count / receiptAntiJoinCount
      mandatoryDelivery = definitionSetDigestAlgorithmVersion / definitionSetDigest / definitionCount
                          / authorizedDefinitions[]? sorted {
                              deliverySetVersion / definitionSchemaVersion
                              definitionDigestAlgorithmVersion / definitionDigest }
                          / coordinateSetDigestAlgorithmVersion / coordinateSetDigest / coordinateCount / nonTerminalCount
      revisionGaps = setDigestAlgorithmVersion / setDigest / count / authorizedRefs[]?
      quarantine = setDigestAlgorithmVersion / setDigest / count / authorizedRefs[]?
      unsupportedSchemas = setDigestAlgorithmVersion / setDigest / count / authorizedSchemas[]?
      semanticCheck = { version; inputDigestAlgorithmVersion; inputDigest;
        status=passed|failed|unknown; authorizedFailureCodes[]? }
    }
    currentGuard = {
      comparedSnapshotId / activeProjectionVersion / sourceQueryDefinitionVersion
      sourceFilterDigestAlgorithmVersion = jcs-sha256-v1
      sourceFilterDigest
      comparisonToSnapshot = equal | changed
      guardDigestAlgorithmVersion = jcs-sha256-v1
      guardInputDigest
      eventSource = setDigestAlgorithmVersion / setDigest / count / receiptAntiJoinCount
      acceptedObservationSource = setDigestAlgorithmVersion / setDigest / count / receiptAntiJoinCount
      mandatoryDelivery = definitionSetDigestAlgorithmVersion / definitionSetDigest / definitionCount
                          / authorizedDefinitions[]? sorted {
                              deliverySetVersion / definitionSchemaVersion
                              definitionDigestAlgorithmVersion / definitionDigest }
                          / coordinateSetDigestAlgorithmVersion / coordinateSetDigest / coordinateCount / nonTerminalCount
      revisionGaps = setDigestAlgorithmVersion / setDigest / count / authorizedRefs[]?
      quarantine = setDigestAlgorithmVersion / setDigest / count / authorizedRefs[]?
      unsupportedSchemas = setDigestAlgorithmVersion / setDigest / count / authorizedSchemas[]?
      semanticCheck = { version; inputDigestAlgorithmVersion; inputDigest;
        status=passed|failed|unknown; authorizedFailureCodes[]? }
      evaluatedAt
    }
  }
}

OperationsVerification@1 =
  verificationState=verified
  + snapshotCurrency=verified_current
  + projectionCompleteness=complete_for_supported_scope|partial_source_gap|unknown
  + verifiedCommon
| verificationState=verified
  + snapshotCurrency=stale
  + projectionCompleteness=partial_source_gap|unknown
  + verifiedCommon
| verificationState=unverified {
  projectionCompleteness = unknown
  completenessAsOf = null
  snapshotCurrency = unknown
  integrity = null
  verificationReason = no_completed_snapshot | definition_mismatch | guard_unavailable
}

OperationsQueryMetadata@1 = {
  projectionName; projectionVersion; generatedAt
  evidenceTimes=OperationsEvidenceTimes@1
  freshness=OperationsFreshness@1
  limitations[]=sorted_unique(partial_legacy_event|not_yet_supported|source_delay)
  sectionSupportCount
  sectionSupport[]=sorted(OperationsSectionSupport@1)
  missingSources=MissingSourceDisclosure@1
  unsupportedSchemas=UnsupportedSchemaDisclosure@1
  observationEvidence=OperationsObservationEvidence@1
  authorizationScope=OperationsAuthorizationScope@1
  verification=OperationsVerification@1
}

snapshotProof 只描述 completenessAsOf.snapshotId 已完成并持久化的历史 Proof Manifest;currentGuard 是本次 Query 在同一只读 Consistent Snapshot 中现场得到的当前输入,两者禁止互相覆盖。Snapshot Proof 必须返回 Proof Manifest 的 Ref/Schema Version/Digest Algorithm Version/Digest;两边都必须返回 sourceFilterDigestAlgorithmVersion + sourceFilterDigest,且它们与 sourceQueryDefinitionVersion 共同定义可比较的 Source Filter。guardInputDigest 按 Contracts jcs-sha256-v1 覆盖 Current Guard 的强制核心字段:Compared Snapshot、Active/Query/Semantic Version、Source Filter Digest Algorithm Version/Digest、Comparison、两类 Source Set Digest Algorithm Version/Digest/Count/Receipt Anti-join、Mandatory Delivery Definition Set Digest Algorithm Version/Digest/Definition Count、完整排序Definition四元组成员,以及逐坐标绑定精确Definition的状态Set Digest/Count/Non-terminal Count、Gap/Quarantine/Unsupported的Set Digest/Count与 Semantic Input Digest Algorithm Version/Digest/Status;不覆盖自身、evaluatedAt 或按 Grant 可裁剪的 authorizedDefinitions/authorizedRefs/authorizedSchemas/authorizedFailureCodes。这样字段裁剪不改变 Guard 身份,强制 Set Digest/Count/Status 又不能与摘要脱节。verified_current 强制 comparisonToSnapshot=equal,且 Current Guard 的 Projection/Query/Semantic Version、Source Filter、两类 Source Set、Mandatory Delivery Definition Set/完整成员/坐标状态集合与 Semantic Check 的Schema/Definition/Digest Algorithm Version/Digest、Receipt、Gap、Quarantine与Unsupported Schema输入和 Snapshot Proof 精确相等;任一算法未知、缺失、版本不等、Definition成员或坐标集合摘要不同、Count不等或摘要错配都不能声称相等。Source Filter 任一字段缺失、未知或错配必须改走 unverified + definition_mismatch,不能使用 changed/stalestale 强制 comparisonToSnapshot=changedstale 不得返回 complete_for_supported_scope;旧 Snapshot 的完整结论只保留在 completenessAsOf.lastVerifiedProjectionCompleteness,当前查询必须等新 Verifier Snapshot 后才能重新声明 Complete。

projectionCompleteness 只与 integrity@2.currentGuard 使用 Contracts Refinement 冻结双向条件,而不是拿历史 Snapshot Proof 判断当前状态:

  • complete_for_supported_scope 当且仅当 Event 与 Accepted Observation 的 receiptAntiJoinCount=0mandatoryDelivery.nonTerminalCount=0、Revision Gap/Quarantine/Unsupported Schema Count 全为 0,且 semanticCheck.status=passed;全部字段都必须是已知值;
  • 上述任一 Count 确定大于 0semanticCheck.status=failed 时,当前 projectionCompleteness 必须为 partial_source_gap
  • 没有已知负向项,但任一必要输入、Count 或 Semantic 结果为 unknown/unavailable 时必须为 unknown
  • stale 仍禁止 Complete,unverified 仍只能 Unknown。Search 的 not_found 只能依赖通过这组 Refinement 的 Complete。

Schema/Repository 负向测试必须逐项构造 Complete + Current Guard 非零 anti-join/nonTerminal/Gap/Quarantine/UnsupportedComplete + Current Guard semantic failed/unknownPartial + Current Guard 全零 passed、Current 与 Snapshot 比较标志错误、freshness.statusverification.snapshotCurrency 不等、Verified 缺少 lastVerifiedAt或其值不等于Current Guard evaluatedAt、Unverified却携带非空lastVerifiedAt、Proof Manifest 四元组缺项或篡改、Source Filter/Source Set/Mandatory Delivery/Semantic Input 的 Digest Algorithm Version 或 Digest 缺失/未知/错配、Mandatory Definition Set摘要/Count/成员四元组或坐标Definition绑定/集合Count/状态分类不等、同一 Definition Version 下 Filter Digest 漂移却返回 verified/stale、Guard Digest 未覆盖上述 tagged digest 及 Guard Digest 篡改等矛盾组合并拒绝;必须验证同一Snapshot跨Definition切换前后Event时完整保留两个Definition成员及各自坐标绑定,任一成员丢失、错序或被当前Registry替换都会失败;还必须验证旧Snapshot生成后Current Delivery从non-terminal变terminal不会改写旧Proof及其Count/Result,Snapshot索引列任一篡改会因与Manifest不等而失败,定义漂移只能得到 unverified + definition_mismatch。同时必须接受“Snapshot 全零 passed、Current Guard 出现确定 Gap、顶层 Stale + Partial”以及“Snapshot 有 Gap、Current Guard 已修复、顶层 Stale + Unknown”。任何 JSON round-trip 或数据库读取都不能产生“顶层绿色、当前证据红色”,也不能把历史红绿状态冒充当前 Guard。

verificationState=verified 表示 Query 找到已完成、定义可比的 Snapshot 并成功执行 Guard,不等于结论一定完整;snapshotCurrency=verified_current 要求全套输入精确相等,确认变化则为 stale。这里的“定义可比”要求 Query Definition Version、Source Filter Digest Algorithm Version/Digest 与 Semantic Definition 全部匹配;定义三元组漂移直接使用 unverified + definition_mismatchfreshness.status 必须与 verification.snapshotCurrency 逐字相等:两个 Verified 分支分别固定为 verified_current | stale,并要求 freshness.lastVerifiedAt = verification.integrity.currentGuard.evaluatedAt;Unverified 分支固定 freshness.status=unknown + freshness.lastVerifiedAt=null。因而 Verified 分支还要求 completenessAsOf 与完整 integrity@2.snapshotProof + currentGuard 非空;Unverified 用于空库/首次构建、定义不兼容或 Guard 不可用,三个 Snapshot 字段必须按上表显式为 null/unknown,禁止填零 Count、空 Digest 或虚构验证时间。

integrity@2 的 Snapshot Proof 与 Current Guard 都必须分别表达 Proof Manifest 四元组(仅 Snapshot)、Source Filter Digest Algorithm Version/Digest、两类 Source Set Digest Algorithm Version/Digest、Mandatory Delivery Definition Set Digest Algorithm Version/Digest/Definition Count、按授权返回的完整排序Definition四元组成员、逐坐标Definition绑定与状态Set Digest/Count/Non-terminal Count、两类 Receipt anti-join 与 Semantic Check Input Digest Algorithm Version/Digest,不能合并为一个总数或单一当前Definition;Schema Version、Canonical Digest/Count、比较状态和 Guard Digest 必须完整 round-trip。具体Definition成员、Missing Member、Gap、Quarantine、Schema 与失败参数属于受控明细,只在 Workforce Grant 同时允许对应 Tenant、Resource 与 Field Classification 时返回;裁剪明细不能删掉任何上述 tagged digest、汇总 Count/Status或比较字段,也不能泄露越权 ID。Contracts 必须测试完整 DTO、裁剪 DTO、同一Snapshot含多个Definition、空库/无 Snapshot 的 unverified round-trip、算法/摘要缺失或错配和跨租户负向路径。

sourceClaimedObservedAt 仅保留来源对时间的声明,只能在 Timeline 展示,不参与排序、Summary、Freshness、Retention、授权或健康结论。Observation 的稳定顺序使用 (acceptedAt, observationId);Operation Summary 的 first_accepted_observation_at/latest_accepted_observation_at、accepted health windows、Observation Freshness 与 Retention/Archive 资格都只使用 Core 权威 acceptedAt。Query 只读取已完成 Snapshot 并执行上述只读集合 Guard,不以 Query 身份写入 Snapshot;没有可验证 Snapshot 或 Guard 无法执行/比较时必须返回 verificationState=unverified

/search 的请求、分页和空结果都是严格判别语义,不能由空数组暗示“不存在”,也不能让一次 correlationId 查询退化成无界结果:

SearchNestedPageRequest@1 = {
  operationId
  section=billing_boundaries|reconciliation_cases
  cursor
  requestedPageSize?
}

OperationsSearchRequest@1 = {
  identifierType=requestId|operationId|correlationId|runId|reservationId|eventId|observationId|errorId
  identifierValue
  identifierNamespace=domain_fact|accepted_observation|auto
  projection = { kind=active } | { kind=exact; projectionName; projectionVersion }
  matchPage = { cursor?; requestedPageSize? }
  nestedPages[]=sorted_unique(SearchNestedPageRequest@1 by operationId,section)
}

OperationsSearchResult@1 =
  { searchOutcome=matched; negativeProofCapability;
    returnedMatchCount; nextMatchCursor?; data[]=sorted(SearchMatch@1) }
| { searchOutcome=not_found; negativeProofCapability=complete_source_guard; data=[] }
| { searchOutcome=inconclusive; data=[];
    negativeProofCapability;
    inconclusiveReason=projection_unverified | projection_incomplete |
                       unsupported_identifier_scope | negative_proof_unavailable |
                       authorization_non_disclosure }

OperationsSearchResponse@1 =
  { metadata={ state=available; value=OperationsQueryMetadata@1 };
    result=OperationsSearchResult@1 }
  | { metadata={ state=unavailable; reason=projection_unavailable };
      result={ searchOutcome=inconclusive; data=[];
               negativeProofCapability=positive_match_only;
               inconclusiveReason=projection_unavailable } }

matched 只返回已通过 Grant 过滤的非空有界页并携带当前 Verification 元数据,且 returnedMatchCount == data.lengthnextMatchCursor 存在当且仅当同一授权范围仍有下一页。nestedPages[] 只能继续上一次同一 Search Query 已返回的 operation_linked Match,每个 (operationId, section) 最多一项,首请求必须为空;不能借它枚举未命中的 Operation。Match 与 Nested Cursor 都由 Core 签名并绑定 Endpoint、原始 Identifier Type/Value/Namespace、Projection/Query Definition、Workforce Principal/Bound Workload、Grant/Tenant Scope、Page Size、排序末键和 Nested Operation/Section(若有);篡改、错Scope、错Projection、跨Grant/Section复用或策略过期统一 fail closed,且响应不得泄露是否存在更多结果。Match 稳定顺序由 Contracts 按 (matchKindOrder, operationId?, runId?, observationId?, summaryId) 冻结;分页尺寸必须为正且不超过部署容量策略给出的上限,不在实现中写拍脑袋常数。

not_found 只允许在 negativeProofCapability=complete_source_guardverificationState=verified + snapshotCurrency=verified_current + projectionCompleteness=complete_for_supported_scope、相同 Source Query Definition 支持该 Type/Namespace,且 Grant 足以对目标查询范围作出否定证明时返回。positive_match_only 的 miss、无完成 Snapshot、Guard 不可用/不可比、Stale、Gap/Quarantine/Pending、Identifier 尚未纳入当前 Projection,或可能触及 Grant 外资源而必须保持不可枚举时一律返回 inconclusiveauthorization_non_disclosure 对“其他租户存在”和“全局不存在”使用完全相同的 HTTP 状态、Envelope、字段与审计语义,不能通过原因细分、数量、时延或错误码泄露存在性。Contracts 必须拒绝 not_found + positive_match_onlynot_found + 非 verified_current/complete、空 matched、非空 not_found/inconclusivereturnedMatchCount 与数组不等、非法空页/Next Cursor、首请求携带 Nested Cursor、Nested Operation 未出现在前页,以及未知 Outcome/Reason/Type-Namespace 组合。

/search 的三个摘要 DTO 是 Contracts 可直接生成 JSON Schema/TypeScript 的封闭结构,不使用自由 Map 或未定义占位名:

AuthorizedOperationSummary@1 = {
  summaryId; summaryKind=operation; operationId; correlationId;
  firstRequestId?; latestRequestId?; runId; reservationId?;
  tenantScope =
    { state=known; tenantKind; tenantId; workspaceId; projectId? }
    | { state=unknown };
  surface?; apiVersion?; operation?; admissionStatus?;
  latestTrustworthyBoundary=none|admission|gateway|output|asset|metering|settlement;
  summaryEvidenceKind=derived_summary;
  limitations[]=sorted_unique(partial_legacy_event|not_yet_supported|source_delay);
  sectionSupportCount;
  sectionSupport[]=sorted {
    section=admission|gateway|output|asset|metering|settlement;
    status=supported_complete|supported_partial|not_yet_supported|unknown;
    reasonCode?
  };
  firstAcceptedObservationAt?; latestAcceptedObservationAt?
}

AuthorizedLegacyRunSummary@1 = {
  summaryId; summaryKind=legacy_run; runId; reservationId?;
  tenantScope =
    { state=known; tenantKind; tenantId; workspaceId; projectId? }
    | { state=unknown };
  surface?; apiVersion?; operation?; admissionStatus?;
  latestTrustworthyBoundary=none|admission|gateway|output|asset|metering|settlement;
  summaryEvidenceKind=derived_summary;
  limitations[]=sorted_unique(partial_legacy_event|not_yet_supported|source_delay);
  sectionSupportCount;
  sectionSupport[]=sorted {
    section=admission|gateway|output|asset|metering|settlement;
    status=supported_complete|supported_partial|not_yet_supported|unknown;
    reasonCode?
  };
  firstAcceptedObservationAt?; latestAcceptedObservationAt?
}

AcceptedObservationSummary@1 = {
  observationId; schemaVersion; requestId;
  errorId?; traceId?; correlationId?; operationId?; runId?;
  surface; apiVersion?; operation?;
  claimedTenantKind?; claimedTenantId?; claimedWorkspaceId?;
  claimedServiceAccountId?; claimedDeveloperCredentialId?;
  sourceClaimedObservedAt?; acceptedAt;
  source = { workloadPrincipalId; service; environment; region?; deploymentId?; instanceId? };
  observationDigestAlgorithmVersion;
  submissionPayloadSha256; acceptedEnvelopeSha256;
  payloadSummary =
    { kind=request_attempt;
      requestKind; outcome; submissionState; normalizedCode?;
      httpStatusClass?; idempotencyDisposition?;
      attributesSchemaVersion; attributesDigestAlgorithmVersion; attributesDigest }
    | { kind=error_occurrence;
        layer; phase; normalizedCode; errorNormalizationPolicyVersion; severity;
        certainty; retryDisposition; compensationDisposition;
        messageTemplateKey;
        sanitizedParametersSchemaVersion;
        sanitizedParametersDigestAlgorithmVersion; sanitizedParametersDigest;
        causeErrorId?; technicalDetailRef?; runStepId?; executionAttemptId?;
        errorFingerprintVersion; errorFingerprint }
    | { kind=gateway_diagnostic;
        gatewayPool; gatewayDeploymentId; providerAttemptId?;
        capability; configRevision; normalizedStatus; gatewayStateVersion;
      submissionCertainty; resultSummary=GatewayDiagnosticResultSummary@1 }
}

AuthorizedAdmissionSnapshotValue@1 = {
  identity =
    { state=redacted }
    | { state=available; operationId; requestId; runId;
        tenantKind; tenantId; workspaceId; projectId?;
        actorPrincipalId; executionPrincipalId; billingAccountId }
  source =
    { state=redacted }
    | { state=available; surface; apiVersion; operation; product }
  authentication =
    { state=redacted }
    | { state=available;
        value =
          { kind=developer_credential;
            developerAppId; environmentId; serviceAccountId; developerCredentialId }
          | { kind=playground_execution_grant;
              developerAppId; environmentId; serviceAccountId;
              playgroundExecutionGrantId; playgroundExecutionGrantSchemaVersion;
              playgroundExecutionGrantClaimsDigestAlgorithmVersion; playgroundExecutionGrantClaimsDigest }
          | { kind=customer_session;
              customerAuthenticationAssertionRef; customerAuthenticationAssertionSchemaVersion;
              customerAuthenticationAssertionClaimsDigestAlgorithmVersion;
              customerAuthenticationAssertionClaimsDigest; productSurface }
          | { kind=delegated_agent;
              delegationGrantRef; delegationGrantSchemaVersion;
              delegationGrantClaimsDigestAlgorithmVersion; delegationGrantClaimsDigest;
              agentRevisionId; originatingSurface } }
  authorization =
    { state=redacted }
    | { state=available;
        authorizationDecisionId / authorizationDecisionSchemaVersion;
        authorizationDecisionInputDigestAlgorithmVersion / authorizationDecisionInputDigest;
        authorizationEvidenceEvaluationSetRef / authorizationEvidenceEvaluationSetSchemaVersion;
        authorizationEvidenceEvaluationSetDigestAlgorithmVersion / authorizationEvidenceEvaluationSetDigest;
        authorizationEvidenceArchiveCutRevision;
        authorizationScopeSnapshotRef / authorizationScopeSnapshotSchemaVersion;
        authorizationScopeSnapshotDigestAlgorithmVersion / authorizationScopeSnapshotDigest;
        authorizationActionCount;
        authorizationActionIds[]=sorted_unique;
        authorizationEvidenceEvaluationCount;
        authorizationEvidenceEvaluations[]=sorted {
          evidenceKind=authorization_decision|playground_execution_grant|
                       customer_authentication_assertion|delegation_grant;
          authorizationEvidenceEvaluationRef / authorizationEvidenceEvaluationSchemaVersion;
          authorizationEvidenceEvaluationDigestAlgorithmVersion / authorizationEvidenceEvaluationDigest;
          archiveRevision
        } }
  model =
    { state=redacted }
    | { state=available; publicModelId; logicalModelId; modelOfferingRevisionId;
        initialModelDeploymentId; modelRoutingPolicyRevisionId; gatewayPool=text|media }
  outputContract =
    { state=redacted }
    | { state=available; outputContractRef / outputContractSchemaVersion;
        outputContractDigestAlgorithmVersion / outputContractDigest }
  executionManifest =
    { state=redacted }
    | { state=available; executionManifestRef; executionManifestSchemaVersion }
  billing =
    { state=redacted }
    | { state=available; reservationId; pricingSnapshotId; billingPolicyRevisionId;
        walletReservation =
          { state=pending_wallet_event }
          | { state=confirmed; reservationStatus=active; walletReservedEventId;
              reservationValue =
                { kind=credits; amount }
                | { kind=entitlement; entitlementKey; quantity; unit }
                | { kind=money; money={ amount; currency } } } }
  runState =
    { state=redacted }
    | { state=available; runStatus=reserved; runCreatedAt; runUpdatedAt; runCreatedEventId }
}

SettlementEconomicIdentity@1 =
  { kind=credits }
  | { kind=entitlement; entitlementKey; unit }
  | { kind=money; currency }

AuthorizedBillingEconomicBoundary@1 = {
  eventId; eventType; eventSchemaVersion
  eventEnvelopeDigestAlgorithmVersion; eventEnvelopeSha256
  aggregateId; aggregateRevision=1
  correlationId; operationId; causationId
  billingReservationId; billingAccountId; runId
  runStepId?; executionAttemptId?; chargeDimensionKey?
  settlementEconomicIdentity=SettlementEconomicIdentity@1
  boundaryPayload=BillingEconomicBoundaryPayload@1
  caseIdentity =
    { state=none }
    | { state=available; reconciliationCaseRef; caseGeneration;
        reconciliationCaseIdentityReservationRef / reconciliationCaseIdentityReservationSchemaVersion;
        reconciliationCaseIdentityReservationDigestAlgorithmVersion / reconciliationCaseIdentityReservationDigest;
        predecessorCase =
          { state=root }
          | { state=supersedes; previousCaseGeneration; previousReconciliationCaseRef;
              previousIdentityReservationRef / previousIdentityReservationSchemaVersion;
              previousIdentityReservationDigestAlgorithmVersion / previousIdentityReservationDigest } }
}

AuthorizedReconciliationCase@1 = {
  reconciliationCaseRef; caseGeneration
  sourceScope =
    { kind=late_settlement_dimension;
      tenantKind; tenantId; workspaceId; projectId?;
      billingReservationId; billingAccountId; runId; runStepId; executionAttemptId; chargeDimensionKey;
      reconciliationCaseIdentityReservationRef / reconciliationCaseIdentityReservationSchemaVersion;
      reconciliationCaseIdentityReservationDigestAlgorithmVersion / reconciliationCaseIdentityReservationDigest;
      predecessorCase =
        { state=root }
        | { state=supersedes; previousCaseGeneration; previousReconciliationCaseRef;
            previousIdentityReservationRef / previousIdentityReservationSchemaVersion;
            previousIdentityReservationDigestAlgorithmVersion / previousIdentityReservationDigest };
      settlementEconomicIdentity=SettlementEconomicIdentity@1;
      currentSourceExposureRef / currentSourceExposureSchemaVersion;
      currentSourceExposureDigestAlgorithmVersion / currentSourceExposureDigest / currentSourceExposureRevision;
      appliedResolutionFact =
        { state=none }
        | { state=available; billingCaseResolutionAppliedRef / billingCaseResolutionAppliedSchemaVersion;
            billingCaseResolutionAppliedDigestAlgorithmVersion / billingCaseResolutionAppliedDigest;
            resolvedExposureRevision } }
    | { kind=billing_finalization_run;
        tenantKind; tenantId; workspaceId; projectId?;
        billingReservationId; billingAccountId; runId; billingFinalizationFenceId;
        finalizationCaseIdentityReservationRef / finalizationCaseIdentityReservationSchemaVersion;
        finalizationCaseIdentityReservationDigestAlgorithmVersion / finalizationCaseIdentityReservationDigest;
        predecessorCase =
          { state=root }
          | { state=supersedes; previousReconciliationGeneration; previousReconciliationCaseRef;
              previousFinalizationCaseIdentityReservationRef / previousFinalizationCaseIdentityReservationSchemaVersion;
              previousFinalizationCaseIdentityReservationDigestAlgorithmVersion / previousFinalizationCaseIdentityReservationDigest };
        expectedResolutionRevision=1; caseRequestOperationId; billingFinalizationOperationId;
        caseRequestEventId / caseRequestEventType / caseRequestEventSchemaVersion;
        caseRequestEventEnvelopeDigestAlgorithmVersion / caseRequestEventEnvelopeSha256;
        billingFinalizationDecisionRef / billingFinalizationDecisionSchemaVersion;
        billingFinalizationDecisionDigestAlgorithmVersion / billingFinalizationDecisionDigest;
        triggeringBillingFinalizationWorkRef / triggeringBillingFinalizationWorkSchemaVersion;
        triggeringBillingFinalizationWorkDigestAlgorithmVersion / triggeringBillingFinalizationWorkDigest;
        triggeringBillingFinalizationWorkGeneration;
        reasonCode;
        appliedResolutionFact =
          { state=none }
          | { state=available;
              finalizationReconciliationResolutionAppliedRef / finalizationReconciliationResolutionAppliedSchemaVersion;
              finalizationReconciliationResolutionAppliedDigestAlgorithmVersion / finalizationReconciliationResolutionAppliedDigest;
              resolutionRevision=1; resolutionOperationId; actorWorkforcePrincipalId } }
  caseState; caseRevision
  terminalAuthority =
    { state=not_terminal }
    | { state=billing_owner_applied;
        ownerFact =
          { kind=late_settlement;
            billingCaseResolutionAppliedRef / billingCaseResolutionAppliedSchemaVersion;
            billingCaseResolutionAppliedDigestAlgorithmVersion / billingCaseResolutionAppliedDigest }
          | { kind=billing_finalization;
              finalizationReconciliationResolutionAppliedRef / finalizationReconciliationResolutionAppliedSchemaVersion;
              finalizationReconciliationResolutionAppliedDigestAlgorithmVersion / finalizationReconciliationResolutionAppliedDigest } }
}

sourceScope.kind=late_settlement_dimension | billing_finalization_run都采用Billing单一终态事实Owner:caseState非终态当且仅当appliedResolutionFact.state=none + terminalAuthority.state=not_terminalcaseState=resolved当且仅当同分支Applied Fact可用且terminalAuthority=billing_owner_applied引用逐字节相同四元组。两分支均禁止Operations/Admin本地resolved | rejected | no-action;任何本地终结命令与Billing Resolution Event并发时本地命令恒定fail closed且零Case终态副作用。未知Owner Kind、跨分支Fact、Resolved无Authority、非终态夹带Fact/Authority或Authority四元组不等均拒绝。权限不足时整个Case为redacted,不得只裁掉Authority。

Request Attributes与Error Sanitized Parameters不作为任意JSON返回:Projector按该Accepted Payload分支的Contracts子Schema计算并保存Schema Version + jcs-sha256-v1 Digest,需要正文时只能走另行授权的受控详情接口。Gateway Result Summary则完整使用封闭低敏联合,不得省略、裁剪或扩展。

/searchdata[] 是严格判别联合,不能假设所有命中都拥有 Operation:

OperationLinkedSearchMatch@1 = {
  matchKind=operation_linked
  operationId
  authorizedSummary =
    { state=available; value=AuthorizedOperationSummary@1 }
    | { state=redacted }
  explorerCapability=available
  authorizedAdmissionSnapshot =
    { state=available; value=AuthorizedAdmissionSnapshotValue@1 }
    | { state=not_available;
        reason=partial_legacy_event }

  authorizedBillingEconomicBoundaries =
    { state=available; returnedBoundaryCount; nextBoundaryCursor?;
      boundaries[]=sorted(AuthorizedBillingEconomicBoundary@1) }
    | { state=redacted }

  authorizedReconciliationCases =
    { state=not_applicable }
    | { state=available; returnedCaseCount; nextCaseCursor?;
        cases[]=sorted(AuthorizedReconciliationCase@1) }
    | { state=redacted }
}

AcceptedObservationAssociation@1 =
  { trust=producer_claimed; associationEvidence={ state=none } }
  | { trust=domain_verified;
      associationEvidence =
        { state=available;
          evidence =
            { kind=domain_event;
              eventId; eventType; eventSchemaVersion;
              eventEnvelopeDigestAlgorithmVersion; eventEnvelopeSha256 }
            | { kind=admission_context;
                admissionContextRef; admissionContextSchemaVersion;
                admissionContextDigestAlgorithmVersion; admissionContextDigest } }
        | { state=redacted } }

AcceptedObservationGatewayExecution@1 =
  { state=not_applicable }
  | { state=available;
      gatewayPool; gatewayDeploymentId;
      attemptRouteBindingRef; attemptRouteBindingSchemaVersion;
      attemptRouteBindingDigestAlgorithmVersion; attemptRouteBindingDigest;
      gatewayRouteSnapshotRef; gatewayRouteSnapshotSchemaVersion;
      gatewayRouteSnapshotDigestAlgorithmVersion; gatewayRouteSnapshotDigest;
      executionAnchor =
        { kind=text_invocation; gatewayInvocationId }
        | { kind=media_task; gatewayTaskId } }
  | { state=redacted }

AcceptedObservationGatewayDispatchIdentity@1 =
  { state=not_applicable }
  | { state=available;
      identity =
        { scope=attempt_bound;
          gatewayAttemptDispatchSlotId; executionAttemptId; gatewayDeploymentId;
          attemptRouteBindingRef; attemptRouteBindingSchemaVersion;
          attemptRouteBindingDigestAlgorithmVersion; attemptRouteBindingDigest;
          gatewayRouteSnapshotRef; gatewayRouteSnapshotSchemaVersion;
          gatewayRouteSnapshotDigestAlgorithmVersion; gatewayRouteSnapshotDigest;
          executionAnchor =
            { kind=text_invocation; gatewayInvocationId }
            | { kind=media_task; gatewayTaskId } }
        | { scope=pre_binding_no_execution;
            gatewayAttemptDispatchSlotId; gatewayPreBindingRequestId; gatewayDeploymentId } }
  | { state=redacted }

AcceptedObservationGatewayEvidenceAvailability@1 =
  { state=not_applicable }
  | { state=available;
      usageEvidenceAvailability = {
        availabilityRef; availabilitySchemaVersion;
        availabilityDigestAlgorithmVersion; availabilityDigest; stateVersion;
        providerEvidenceKind=provider_usage; evidenceDimensionKey=attempt_aggregate@1;
        availabilityIdentity =
          { scope=attempt_bound; executionAttemptId; gatewayDeploymentId;
            attemptRouteBindingRef; attemptRouteBindingSchemaVersion;
            attemptRouteBindingDigestAlgorithmVersion; attemptRouteBindingDigest;
            gatewayRouteSnapshotRef; gatewayRouteSnapshotSchemaVersion;
            gatewayRouteSnapshotDigestAlgorithmVersion; gatewayRouteSnapshotDigest }
          | { scope=pre_binding_no_execution; gatewayAttemptDispatchSlotId;
              gatewayPreBindingRequestId; gatewayDeploymentId };
        supersedesAvailability =
          { state=root }
          | { state=supersedes; supersedesAvailabilityRef; supersedesAvailabilitySchemaVersion;
              supersedesAvailabilityDigestAlgorithmVersion; supersedesAvailabilityDigest;
              supersedesAvailabilityStateVersion };
        stateReasonCode;
        availabilityState =
          { state=available; providerUsageEvidenceRef; providerUsageEvidenceSchemaVersion;
            providerUsageEvidenceDigestAlgorithmVersion; providerUsageEvidenceDigest }
          | { state=not_reported|pending|unavailable|conflicting }
      };
      costEvidenceAvailability = {
        availabilityRef; availabilitySchemaVersion;
        availabilityDigestAlgorithmVersion; availabilityDigest; stateVersion;
        providerEvidenceKind=provider_cost; evidenceDimensionKey=attempt_aggregate@1;
        availabilityIdentity =
          { scope=attempt_bound; executionAttemptId; gatewayDeploymentId;
            attemptRouteBindingRef; attemptRouteBindingSchemaVersion;
            attemptRouteBindingDigestAlgorithmVersion; attemptRouteBindingDigest;
            gatewayRouteSnapshotRef; gatewayRouteSnapshotSchemaVersion;
            gatewayRouteSnapshotDigestAlgorithmVersion; gatewayRouteSnapshotDigest }
          | { scope=pre_binding_no_execution; gatewayAttemptDispatchSlotId;
              gatewayPreBindingRequestId; gatewayDeploymentId };
        supersedesAvailability =
          { state=root }
          | { state=supersedes; supersedesAvailabilityRef; supersedesAvailabilitySchemaVersion;
              supersedesAvailabilityDigestAlgorithmVersion; supersedesAvailabilityDigest;
              supersedesAvailabilityStateVersion };
        stateReasonCode;
        availabilityState =
          { state=available; providerCostEvidenceRef; providerCostEvidenceSchemaVersion;
            providerCostEvidenceDigestAlgorithmVersion; providerCostEvidenceDigest }
          | { state=not_reported|pending|unavailable|conflicting }
      }
    }
  | { state=redacted }

SearchMatch@1 =
  OperationLinkedSearchMatch@1
  | { matchKind=observation_only;
      operationId=null;
      acceptedObservationDetails =
        { state=available;
          summary=AcceptedObservationSummary@1;
          association=AcceptedObservationAssociation@1;
          gatewayExecution=AcceptedObservationGatewayExecution@1;
          gatewayDispatchIdentity=AcceptedObservationGatewayDispatchIdentity@1;
          gatewayEvidenceAvailability=AcceptedObservationGatewayEvidenceAvailability@1 }
        | { state=redacted };
      explorerCapability=not_applicable }
  | { matchKind=legacy_run_only;
      operationId=null; runId;
      authorizedLegacyRunSummary =
        { state=available; value=AuthorizedLegacyRunSummary@1 }
        | { state=redacted };
      limitations=[partial_legacy_event];
      explorerCapability=not_applicable }

带合法 operationId 的 v1 Event 可以返回 operation_linked,但缺失字段必须保持缺失并带 partial_legacy_event。缺少 operationId 的 v1 Event 只能按真实 runId/eventId 返回 legacy_run_only,不生成 Operation/Correlation/Request ID;AuthorizedLegacyRunSummary@1limitations必须包含partial_legacy_event,且Schema禁止Operation/Correlation/Request与Admission Snapshot字段。Operation分支则强制summaryKind=operation + operationId + correlationId;两种Summary的Section必须按Contracts固定顺序唯一、Count等于数组长度,Latest Boundary不得超过其Section Support和真实Lineage。普通 /explorer 不接受Legacy分支。

AuthorizedAdmissionSnapshotValue@1逐组镜像持久Admission Snapshot,不允许Summary猜补:Identity、Source/Product、Authentication、Authorization、Model、Output Contract、Execution Manifest追踪、Billing与Run State各自只能available完整返回或整体redacted。Authentication的四个分支严格互斥,临时Grant/Assertion的Ref/Schema/Claims Digest必须成组;Authorization Available强制Decision、Evaluation Set、Archive Cut、Scope Snapshot、Action Count/排序去重集合、成员Count/排序四元组/Revision完整;Model强制Public/Logical/Offering/Initial Deployment/Routing Policy/Gateway Pool完整;Output Contract强制四元组;Manifest只返回Event冻结的低敏Ref/Schema,不解引用正文。Billing即使Wallet Event尚未到达也保持Run Event自带Reservation/Pricing/Policy并显式walletReservation=pending_wallet_event;确认后才完整增加Active Status、Wallet Event ID和三分支BillingValue,不能把Pending当成整个Admission不存在或从当前钱包补值。Run State只表达创建时reserved快照。Product必须等于Source Surface,并与Customer/Delegated分支Surface相等;Actor/Execution与Authentication Refinement沿用Event契约。任一组权限不足只能整体redacted,不能裁成半个Set、Authentication、Model、BillingValue或四元组。

Contracts/Repository/Query Golden与负测覆盖四种Authentication、三种BillingValue、每个分组完整/裁剪、Set/Scope/Action/成员缺项或错序、不同Cut拼接、当前Revision冒充历史、Product/Surface或Actor/Execution错配、Pending→Confirmed乱序、后到撤销与Shadow Rebuild;同一Snapshot的JSON/数据库round-trip必须保留全部字段。Wallet-first Pending Reservation在Run Event完成校验前不进入搜索联合。

BillingEconomicBoundaryPayload@1billing_economic_boundaries_vN.boundary_payload 的同构Camel Case严格封闭联合;五个 value 分支分别逐字段复用Event Contracts的完整 BillingFinalizationCommitted@1 | BillingSettlementTransitionCommitted@1 | LateSettlementExposureCaseRequested@1 | BillingCaseResolutionApplied@1 | LateSettlementCommandResultCommitted@1,不能在Read Model另造缩减版同名Schema。它完整保留所选Owner Fact/Result、Finalization Decision/Input/Bundle、Finalization Fence Revision与Closure Source Event/Consumer Receipt、Consumption、Exposure、Applied Fact与State Revision四元组;Query不得把它压成裸Ref、只返回Ref/Schema、混合两个Kind或用当前Wallet/Fence/Case状态补值。authorizedBillingEconomicBoundaries.boundaries[](eventType, aggregateId, aggregateRevision, eventId)排序,Event identity、Payload、Case identity与经济身份是不可分割的权限单元;字段权限不足时整组state=redacted,不得裁成无法调用Owner Read Contract的半联合。Reconciliation Case同理:Reservation或Current Exposure完整四元组、Revision与Applied Fact联合缺一即拒绝/隔离,权限不足整体redacted。Contracts/Repository/Query测试覆盖五个Kind round-trip、Owner/Case/Exposure/Closure Receipt任一四元组缺项或摘要篡改、Fence Revision或Closure Event身份错配、未知算法、错Aggregate/Causation、跨Tenant/Reservation/Generation/Dimension/经济身份重绑、resolve-before-create及redaction不泄漏存在性。

Finalization分支的dimensionCommitments[]ledgerEffects[]必须原样保留runStepId并分别按(runStepId, executionAttemptId, chargeDimensionKey)及再加Effect Ref规范排序;Query与Projector逐项验证它们和Owner Fact、Input Manifest、Consumption、Dimension State、Ledger/Event等值。缺Step、错Step、跨Step重绑、旧Attempt-only排序或JSON/数据库round-trip丢Step均拒绝,禁止通过Attempt查找Step补齐。

AcceptedObservationSummary@1只由同一条Accepted Envelope自包含字段确定;Projector逐字段映射Common和所选Payload分支并重算Envelope/子摘要,不能从相邻Observation、当前Run/Gateway或日志补值。Request分支要求Gateway Execution/Dispatch/Availability全部not_applicable;Error分支只允许同一Error Payload映射可选Gateway Execution,Dispatch/Availability固定not_applicable;Gateway分支要求Gateway Execution=not_applicable、Dispatch/Availability为完整可用分支,且Summary中的Pool/Deployment/Capability/State/Result Summary与同一Payload逐项相等。acceptedObservationDetails.state=redacted必须替换整个Summary、Association和三类Gateway详情,不能通过某个Sibling的not_applicable|available泄漏Payload Kind或对象存在性。Contracts/Repository/Query测试覆盖三分支JSON/数据库round-trip、未知字段、跨分支混合、Common/Payload错映射、Gateway Result Summary缺失或篡改、Request Attributes/Error Parameters子摘要错配、只裁剪一个Sibling以及整组redaction不可枚举性。

Observation 中的 Tenant、Workspace、Service Account、Credential、Operation 与 Run 关联都是 Producer Claim。持久化联合默认且只能是 producer_claimed + association_evidence.state=none;该分支不能写入 authorization_tenant_kind/authorization_tenant_id、不能作为 Tenant 授权分区,也不能产生 operation_linked。只有 Projector 用相同 operationId/runId 的 Canonical Domain Event,或 Core 签发且可验证的不可变 Admission Context 交叉验证关联和值一致后,才写 domain_verified 与恰好一个完整证据分支,并允许相应 Tenant-scoped Grant 命中。

domain_event 分支逐项保存 Event ID/Type/Schema Version 与覆盖完整 Envelope+Payload 的 eventEnvelopeDigestAlgorithmVersion + eventEnvelopeSha256admission_context 分支逐项保存 Context Ref/Schema Version/Digest Algorithm Version/Digest。后者必须来自 Core append-only、Ref 永不复用且内容寻址的 Admission Context Registry,摘要覆盖用于关联的 Actor/Tenant/Workspace/Developer Access/Operation/Run Claims。Projector 在写关联、授权索引与 Receipt 的同一事务中验证所选证据、Observation Claim 与目标领域事实逐项相等,不能只存裸 Ref、混合两分支、回查当前 Run/Session 补值或在摘要失败时降格为可信关联。错标 Tenant/Run、缺项、未知 Schema/算法、摘要错配、同 Ref 异正文或关联证据与授权分区不等时,保留低敏 Claim 并隔离关联,不得污染 Operation Timeline。

任何 Query DTO 返回关联状态时都使用上面的 acceptedObservationAssociation:可见 domain_verified 证据必须完整 round-trip 所选严格分支;Grant 不允许证据明细时只能返回整个 state=redacted,不能裁成裸 Ref、Ref/Schema 或无摘要的半联合。producer_claimed 禁止 available|redacted 证据,domain_verified 禁止 state=none。Contracts/Repository/Query 负向测试必须覆盖两分支同时/均不出现、Kind 与字段错配、四元组缺项、未知算法、Digest 篡改、同 Ref 异正文、Domain Event Type/Schema/Digest 错配、Context 跨 Tenant/Run 重绑、把 Producer Claim 提升为授权分区,以及 JSON/数据库 round-trip 丢失证据字段。

Error Observation 的 Gateway 执行身份也只能从同一条已接受 ErrorOccurrence@1.gatewayExecution 映射到 error_gateway_execution,并在允许返回时使用 acceptedObservationGatewayExecution.state=available 完整 round-trip;不存在该分支时固定为 not_applicable,字段权限不足时只能把整个分支替换为 redacted。Projector 与 Query 都不得按裸 Ref 查询“当前”Binding/Route Schema,或从同 Run 的 GatewayDiagnostic、相邻 Timeline Entry 补字段。Binding/Route各自的Ref/Schema Version/Digest Algorithm Version/Digest任一缺失、错Schema/算法/摘要、分支混合、Anchor both/neither/wrong-pool或数据库/JSON round-trip丢失任一四元组字段均拒绝或隔离,不能建立Attempt关联;Query也不能返回只含Ref/Schema的半联合。

GatewayDiagnostic 则必须从同一条 Accepted Envelope 投影完整 gateway_dispatch_identityattempt_bound 以Binding完整四元组、期望Attempt/Deployment和Audience调用Bootstrap readAttemptRouteBinding,从响应取得并验证Manifest/Slot/Route/Anchor后再要求Slot、Route和严格二选一的Execution Anchor与同一Observation外层值相等;Read请求不得反向要求Projector预知只存在于Binding正文的Manifest/Slot/Anchor。pre_binding_no_execution 的外层 Slot/Request ID 必须与 Usage、Cost 两份 Availability Identity 逐项相等,并禁止Execution Anchor。Query 使用 acceptedObservationGatewayDispatchIdentity:非 GatewayDiagnostic 返回 not_applicable,有字段权限时完整返回所选严格分支,权限不足时整体 redacted,不能裁掉 Slot、Request ID、Execution Anchor 或 Binding/Route任一四元组字段。Contracts/Repository/Query负向测试必须覆盖Slot缺失、两个Scope混合、两份Availability或外层Slot/Request ID不等、Attempt-bound Slot/Binding/Anchor任一不等、Anchor both/neither/wrong-pool、Pre-binding夹带Anchor、同Attempt换Slot、Binding/Route四元组缺项/错摘要/未知算法、半联合裁剪,以及JSON/数据库round-trip丢失Slot、Anchor或摘要字段;任一失败都不得建立Attempt/Tenant授权关联。

acceptedObservationGatewayEvidenceAvailability 必须把同一GatewayDiagnostic中的Usage与Cost两份Availability完整round-trip:Snapshot自身Ref/Schema/Digest Algorithm/Digest/State Version、Kind/Dimension、所选Identity中的Binding/Route完整四元组、Supersedes联合与Reason均必填;supersedesAvailability.state=supersedes 必须完整返回直接前驱 Snapshot 的Ref/Schema/Digest Algorithm/Digest/State Version五元组,root禁止任何前驱字段。只有availabilityState=available允许对应Usage/Cost Evidence完整四元组,其他状态禁止任何Evidence四元组;需要经Owner Read展开Evidence时,Evidence自身的supersedesEvidence同样只能是root或直接前驱完整四元组。两份Snapshot与外层Dispatch Identity的Scope、Slot/Request ID、Attempt/Deployment、Binding/Route必须逐项相等。有字段权限时完整返回两份严格DTO;权限不足整体redacted,不能只隐藏Digest、State Version或Evidence的一半。负向测试覆盖available缺Evidence四元组任一项、非available偷带Evidence、Usage/Cost错类、Snapshot/Evidence前驱半联合、同Ref/Schema异Digest、未知算法、前驱State Version错配、Identity错配和数据库/JSON round-trip丢字段。

准入前拒绝可能只有 requestId / observationId / errorId,且租户通常未知;它只能返回 observation_only 和职责允许的低敏 Accepted Source 摘要,不能伪造 Operation、Tenant 或关联关系。未验证 Claim 只能由明确拥有跨租户 Observation 调查 Scope 的 Workforce Grant 查询;普通 Tenant-scoped Grant 不得命中。/explorer 只接受 operation_linked 结果;相应 Accepted Source 未命中时沿用 not_found | inconclusive 的可判定性规则,Grant 外对象与不存在对象在相同 Scope 下始终不可区分。

这些都不是公共 API,不由 api.oceanway.tech/v1 暴露,也不接受 Customer Session 或 DeveloperCredential。Query Response 固定 Cache-Control: private, no-store,不得进入 CDN、Service Worker、浏览器持久化或前端 APM 的 Body/ID/Grant 采集。查询预算、速率、异常枚举告警按 Workforce Principal 与 Grant 由配置和容量证据确定,不通过固定延时伪装恒定响应时间。

Observation Intake与Projector验证attempt-bound Error/GatewayDiagnostic时使用readAttemptRouteBinding的独立operations_observation_intake | operations_observation_projectionAudience:前者Scope绑定Canonical Submission摘要,后者绑定Accepted Envelope摘要;两者都精确绑定Observation、Tenant/Run(若有)、Attempt/Deployment、Binding四元组与可选Operation,且只返回低敏不可变Binding正文。摘要类型互换、跨Observation/Attempt/Binding、Admin或普通Billing/Metering Token都拒绝,不能读取Availability/Evidence/Receipt或Route私有正文。

authorizedBillingEconomicBoundaries.state=available(eventType, aggregateId, aggregateRevision, eventId)稳定排序并有界分页,returnedBoundaryCount == boundaries.lengthnextBoundaryCursor存在当且仅当同一Operation、Scope与过滤条件仍有下一页。authorizedReconciliationCases.state=available使用跨联合固定顺序(sourceKindOrder, billingAccountId, billingReservationId, runId, sourceScopeSortKey, caseGeneration, reconciliationCaseRef)sourceKindOrder由Contracts固定,Dimension分支的sourceScopeSortKey=(runStepId,executionAttemptId,chargeDimensionKey),Run分支为(billingFinalizationFenceId);不得伪造空Step/Attempt/Dimension。returnedCaseCount == cases.lengthnextCaseCursor遵循同一存在条件。两类Cursor都只能通过OperationsSearchRequest@1.nestedPages[]回传,由Core签名并绑定原始Search Identifier、Projection Version、Query Definition、Workforce Grant/Tenant Scope、Operation/Run、严格sourceScope、Section、Page Size、排序末键与过滤条件。一个Operation可同时返回两种Scope、多个Boundary、Step、Attempt、Dimension和Generation,禁止任意选一、覆盖或拆成重复SearchMatch;游标错联合分支、Scope、版本、Section、篡改、过期策略或跨Grant重放统一fail closed且不泄露是否存在更多项。

Explorer 与 Projection Status 严格 DTO

/explorer不是把Search Row自由拼成页面JSON。Contracts冻结以下请求与响应;分页尺寸必须为正且不超过部署容量策略给出的上限,服务端不得用硬编码上限掩盖无界查询:

RequestedSectionPage@1 =
  { state=not_requested }
  | { state=requested; cursor?; requestedPageSize? }

OperationsExplorerRequest@1 = {
  operationId
  projection = { kind=active } | { kind=exact; projectionName; projectionVersion }
  sections = {
    admission=include|omit
    billingBoundaries=RequestedSectionPage@1
    reconciliationCases=RequestedSectionPage@1
    timeline=RequestedSectionPage@1
    observations=RequestedSectionPage@1
  }
}

AuthorizedTimelineEntry@1 = {
  timelineEntryId
  entryKind=domain_event|accepted_observation|operations_runtime|telemetry_reference|derived_boundary
  evidenceKind=domain_fact|operational_observation|operations_runtime|telemetry_reference|derived_summary
  stage=admission|gateway|output|asset|metering|settlement|delivery|projection
  sourceIdentity =
    { kind=domain_event; eventId; eventType; eventSchemaVersion;
      eventEnvelopeDigestAlgorithmVersion; eventEnvelopeSha256 }
    | { kind=accepted_observation; observationId; observationSchemaVersion;
        observationDigestAlgorithmVersion; acceptedEnvelopeSha256 }
    | { kind=operations_runtime; runtimeRecordType; runtimeRecordId; runtimeSchemaVersion }
    | { kind=telemetry_reference; telemetryKind=trace|log|metric;
        telemetryReferenceRef; telemetryReferenceSchemaVersion;
        telemetryReferenceDigestAlgorithmVersion; telemetryReferenceDigest }
    | { kind=derived_boundary; sourceSetDigestAlgorithmVersion; sourceSetDigest }
  occurredAt?; sourceClaimedObservedAt?; acceptedAt?; derivedAt?; appliedAt?
  causationId?; aggregateId?; aggregateRevision?
  certainty; normalizedCode?
}

AcceptedObservationDetails@1 = {
  summary=AcceptedObservationSummary@1
  association=AcceptedObservationAssociation@1
  gatewayExecution=AcceptedObservationGatewayExecution@1
  gatewayDispatchIdentity=AcceptedObservationGatewayDispatchIdentity@1
  gatewayEvidenceAvailability=AcceptedObservationGatewayEvidenceAvailability@1
}

OperationsExplorerResponse@1 =
  { result=available
    metadata={ state=available; value=OperationsQueryMetadata@1 }
    summary = { state=available; value=AuthorizedOperationSummary@1 } | { state=redacted }
    admission =
      { state=not_requested }
      | { state=available; value=AuthorizedAdmissionSnapshotValue@1 }
      | { state=not_available; reason=partial_legacy_event }
      | { state=redacted }
    billingBoundaries =
      { state=not_requested }
      | { state=available; itemCount; items[]=AuthorizedBillingEconomicBoundary@1; nextCursor? }
      | { state=redacted }
    reconciliationCases =
      { state=not_requested }
      | { state=available; itemCount; items[]=AuthorizedReconciliationCase@1; nextCursor? }
      | { state=redacted }
    timeline =
      { state=not_requested }
      | { state=available; itemCount; items[]=AuthorizedTimelineEntry@1; nextCursor? }
      | { state=redacted }
    observations =
      { state=not_requested }
      | { state=available; itemCount; items[]=AcceptedObservationDetails@1; nextCursor? }
      | { state=redacted } }
  | { result=inconclusive
      metadata={ state=available; value=OperationsQueryMetadata@1 }
      reason=not_found_or_not_authorized }
  | { result=inconclusive
      metadata={ state=unavailable; reason=projection_unavailable }
      reason=projection_unavailable }

Explorer分页顺序固定:Boundary按(eventType, aggregateId, aggregateRevision, eventId);Case按(sourceKindOrder, billingAccountId, billingReservationId, runId, sourceScopeSortKey, caseGeneration, reconciliationCaseRef),其中Dimension与Run分支分别使用上述不同sourceScopeSortKey;Timeline按各Source权威时间形成的(canonicalSortAt, entryKindOrder, timelineEntryId),Observation按(acceptedAt, observationId)sourceClaimedObservedAt永不进入排序。Timeline时间字段按分支冻结:accepted_observation + operational_observation强制acceptedAt、允许sourceClaimedObservedAt且禁止用它填occurredAt/canonicalSortAt;Domain Event强制occurredAt,Operations Runtime使用其Owner occurredAt|appliedAt,Telemetry Reference使用其不可变Reference声明并经授权返回的occurredAt,Derived只使用derivedAt,不合法组合拒绝而非静默删字段。Telemetry分支只返回内容寻址Reference四元组和trace|log|metric类别,不返回原始日志、Span或Metric标签。itemCount == items.length,空页只允许在合法首/末页,nextCursor存在当且仅当同Scope仍有下一页。Cursor由Core签名并绑定Endpoint/Section、Projection Version、Query Definition、Operation/Tenant/Run/严格Case Source Scope、Workforce Principal/Bound Workload、Grant Scope Digest、过滤条件、Page Size和最后排序键;错Endpoint/Section/联合分支/Scope/Projection/Grant、篡改或策略过期统一fail closed且不泄露对象或下一页存在性。分页只改变展示集合,不改变Verification Snapshot/Guard语义;跨页因果仍只看显式Causation/Revision,不按时间邻近推断。

/projection-status同样是封闭契约,不暴露数据库自由查询:

ProjectionStatusRequest@1 = {
  projectionName
  projection = { kind=active } | { kind=exact; projectionVersion }
  details =
    { state=not_requested }
    | { state=requested;
        detailKind=mandatory_delivery|revision_gap|quarantine|unsupported_schema;
        cursor?; requestedPageSize? }
}

ProjectionRuntimeDetail@1 =
  { kind=mandatory_delivery; eventId; destination; consumerName;
    deliverySetVersion; deliverySetDefinitionSchemaVersion;
    deliverySetDefinitionDigestAlgorithmVersion; deliverySetDefinitionDigest;
    status=pending|leased|acknowledged|quarantined;
    attemptCount; availableAt; deliveredAt?; normalizedErrorCode? }
  | { kind=revision_gap; aggregateType; aggregateId; expectedRevision; observedRevision; firstSeenAt }
  | { kind=quarantine; sourceKind=event|accepted_observation; sourceId;
      sourceSchemaVersion; reasonCode; quarantinedAt }
  | { kind=unsupported_schema; sourceKind=event|accepted_observation;
      sourceType; sourceSchemaVersion; affectedCount }

ProjectionStatusResponse@1 =
  { result=available
    metadata={ state=available; value=OperationsQueryMetadata@1 }
    registry = { activeVersion; shadowVersion?; status; switchedAt?; rollbackVersion? }
    build = { buildId; status; claimMode; claimFencingToken;
      boundCandidateBoundary =
        { state=none }
        | { state=available; candidateBoundaryId / candidateBoundarySchemaVersion;
            candidateBoundaryDigestAlgorithmVersion / candidateBoundaryDigest };
      startedAt; lastAppliedAt?; finishedAt? }
    runtimeSummary =
      { state=available;
        eventReceiptAntiJoinCount; observationReceiptAntiJoinCount;
        mandatoryDeliveryNonTerminalCount; revisionGapCount;
        quarantineCount; unsupportedSchemaCount }
      | { state=unavailable;
          reason=no_completed_snapshot|definition_mismatch|guard_unavailable }
    authorizedDetails =
      { state=not_requested }
      | { state=available; detailKind; itemCount;
          items[]=ProjectionRuntimeDetail@1; nextCursor? }
      | { state=redacted } }
  | { result=inconclusive
      metadata={ state=available; value=OperationsQueryMetadata@1 }
      reason=not_found_or_not_authorized }
  | { result=inconclusive
      metadata={ state=unavailable; reason=projection_unavailable }
      reason=projection_unavailable }

三个Response Root都必须实际引用同一个OperationsQueryMetadata@1,不允许BFF把散落的Projection/Freshness/Integrity字段重新拼成另一Wire Shape。Available或拥有可定位Projection的Inconclusive分支固定metadata.state=available;只有Projection本身不可读取时才允许metadata.state=unavailable + reason=projection_unavailable,且Payload也必须是同Reason的Inconclusive,不能返回任何Count、Cursor或对象存在性。Metadata内Freshness Status必须等于Verification的Snapshot Currency映射,Section Count与数组长度一致,Missing/Unsupported/Observation披露分支的Count与排序数组严格相等;字段权限不足使用整个redacted分支。

runtimeSummary.state=available 当且仅当同一响应 metadata.value.verification 为 Verified 且拥有完整 currentGuard,其中六个 Count 必须与该 Guard 逐项相等,不能用 Build 缓存或当前表 Count 覆盖历史 Snapshot Proof;verificationState=unverified 时只能返回 state=unavailable,Reason 必须等值映射同一 verificationReason,不得填零、保留旧 Count 或虚构 Guard。Detail的所有Item必须与请求detailKind相同并使用固定排序:Delivery (eventId,destination,consumerName)、Gap (aggregateType,aggregateId,expectedRevision)、Quarantine (sourceKind,sourceId)、Unsupported (sourceKind,sourceType,sourceSchemaVersion)。Projection Status Cursor沿用上述签名/Scope绑定并额外绑定Detail Kind。

两个端点只接受Admin Query BFF的Operations Query Workload JWT及Core Signed Workforce Grant。Explorer Action/Scope固定operations:explorer:read + operationId + Tenant + requested Sections/Fields + Projection;Status固定operations:projection-status:read + projectionName/version + detailKind/Fields,查看跨租户ID或Quarantine详情仍需相应Case/JIT。Core在同一只读Consistent Snapshot验证Grant、解析Cursor并构造响应;敏感查询继续执行query.authorized → query.released|inconclusive|failed两阶段Audit fail-closed。不存在、越权与错Scope统一使用相同inconclusive形状,不能通过Count、Cursor或Reason细分枚举。

Contracts必须发布Search/Explorer/Projection Status Request/Response、所有Page、Timeline/Boundary/Case/Observation和Status Detail的Golden JSON/Canonical Bytes;测试覆盖Admission Snapshot三种BillingValue分支、Settlement Economic Identity三分支、未知字段、非法Nullable、分支both/neither、Item Count不等、数组错序/重复/错Kind、Boundary/Case/Observation半联合、Result Summary或四元组丢失、Timeline用Claimed Time排序、非法空页/Next Cursor、游标篡改/错Endpoint/Section/Detail/Projection/Tenant/Grant Scope、跨页重放、Available Summary与Current Guard不等、Unverified却携带Count/Guard、Verified却返回Unavailable、Unavailable Reason与Verification Reason不等、越权与不存在不可区分,以及Audit任一步失败时零响应字节。

Workforce 授权

Signed Workforce Grant 的唯一签发者是 oceanway-core Authorization/Workforce Policy。Admin Query BFF 不能自行签名、转签或把浏览器声明包装成 Grant。

调用流程固定为:

  1. Admin BFF 在 admin.oceanway.tech 本地终止并验证 Host-only Workforce Cookie/Session;Cookie 与 Session ID 永不发往 Core。
  2. Admin BFF 使用面向 oceanway-core 的短期 Workload JWT,加 Workforce IdP/Identity Authorization 唯一签发或交换、面向 Grant Exchange 且防重放的 Actor Assertion,调用 POST /internal/v1/workforce/query-grants:issue;不能复用 Admin Audience ID Token,也不能由 BFF 自报 Actor。
  3. Core Authorization/Workforce Policy 验证 Workforce 身份、MFA、职责、租户范围、用途与可选 Incident/Case/JIT,并在同一事务中一次性消费 Assertion jti、记录 Grant、追加签发 Audit,再签发短期、定向且绑定呈递 Workload 的 Signed Workforce Grant;任一步失败都不返回 Grant,浏览器不能取得 Assertion 或 Grant。
  4. Admin BFF 使用同一 Workload 身份与该 Grant 调用 Operations Query。

Actor Assertion 至少冻结 iss/aud/subauth_timeacr/amr、Session/Authn Version、boundWorkload、Exchange Request Digest/Nonce、jtiiat/nbf/exp。Signed Workforce Grant 至少冻结 iss/aud/subboundWorkload(或 azp/cnf)、jtiiat/nbf/exp、Session/Authn Version、MFA Assurance、Policy Revision,以及 Action/Field/Resource/Tenant/Case Scope。Core Query 同时验证 Workload JWT 的 operations:query Scope、Grant 撤销状态与全部声明,并强制 boundWorkload == Workload JWT subject。Workload JWT 不能替代人类授权;Admin Body 自报的 Role、Organization 或 isAdmin=true 不可信。Grant 生命周期与 JIT 条件来自安全策略,不在应用代码写固定时长。

Grant 的签发、拒绝、撤销和使用全部 Audit;签发 Audit 失败时不得返回 Grant。跨租户、敏感标识或需要 JIT 的查询采用两阶段追加审计:先持久化 query.authorized,执行范围受限的查询,再在任何响应字节离开 Core 前持久化 query.released | query.not_found | query.inconclusive | query.failed;后一记录包含字段分类、结果数量、Projection Version、Search Outcome 与 Grant ID,提交失败时同样 fail closed。超出授权或无法证明覆盖范围时统一返回不可枚举的 inconclusive + authorization_non_disclosure;Identifier 是否真实存在不能改变状态码、响应形状、原因或摘要。详情字段继续按职责裁剪;拥有 Run Search 权限不自动获得 Billing、Gateway、内容或 Secret 权限。

Operations Query 运行身份只拥有批准 Projection/Runtime View 的 SELECT 和 Audit Append Procedure 的 EXECUTE。Observation Intake 使用不同身份,只能 EXECUTE 受控 accept_operational_observation Security Definer Primitive,对 Source/Registry/Purge Marker 没有直接表权限;Primitive 固定 search_path、撤销 PUBLIC EXECUTE,并在唯一约束下原子 insert-or-compare。只有当前受信 Source Workload 与 Submission 摘要都匹配时才返回 accepted_new | accepted_existing | accepted_existing_purged 之一;Purged 分支只返回 observationId + originalAcceptedAt,跨 Workload 同 ID 只返回通用完整性错误而不读取旧行。Admin Query BFF 和未来 Command Gateway 使用不同 Workload Principal、Audience、凭据和网络策略,不能因部署在同一后台产品就共享权限。

首期所有 Operations Query 和 Admin Explorer 都是只读的。页面不提供重试 Run、重投事件、释放 Reservation、修改 Projection、强制成功或直接执行 SQL 的操作。

Projection Build 与 Shadow Rebuild

投影版本不可在原表上破坏式重算。每次 Schema 或 Projector 语义升级采用:

active projection vN serves queries
→ create empty shadow projection vN+1
→ repeatedly anti-join applicable immutable events/observations against vN+1 receipts
→ pause Shadow claims and drain Shadow in-flight mutations
→ atomically freeze Candidate and bind Shadow to it with a new claim fencing token
→ catch up vN+1 only to that frozen member set; verify gaps, quarantine and semantics
→ compare vN / vN+1 invariants for that frozen set
→ acquire bounded cutover lock
→ stop new Event/Accepted Observation claims; drain vN Event leases/acks and Observation projection transactions
→ in a final transaction re-verify the same candidate members, compute and append a new readiness proof; do not add later Source
→ atomically persist the readiness proof and switch active pointer/consumer target version
→ resume claims; Source outside the frozen boundary enters/catches up only in vN+1
→ retain rollback candidate under governance policy; catch it up before any reverse cutover

Shadow Projector 使用独立 projectionVersion Receipt,不能复用 Active Receipt 跳过 Source Row。每轮重建都通过 Anti-join 找出当前版本尚未应用的适用 Event/Accepted Observation,不依赖扫描位置或单值进度。冻结 Candidate 前必须先暂停并排空 Shadow Claim;冻结 Candidate 四元组与把 Shadow Build 绑定到该四元组/新 Fencing Token 必须同事务。冻结后旧 Active 可以继续处理边界外 Source,但 Shadow 只能以当前 Token Claim Candidate Member,旧 Token 与边界外 Mutation 都被数据库拒绝。Active Cutover Lock 同时约束两类 Active Claim 与 Pointer:停新 Claim、排空旧版本 in-flight Event Lease/Ack 与 Observation Projection 事务,再在最终事务中逐项复核同一个 Candidate Boundary 的 ID/Schema Version/Digest Algorithm Version/Digest、计算并追加带自身四元组且引用完整 Candidate 四元组的 CutoverReadinessProof,并同事务切换 Pointer 和消费目标。Candidate、Expected Receipt Coordinates、Readiness Semantic Input 和 Proof 任一算法未知、摘要错配或四元组缺项都必须阻止切换。锁期间新提交的 Event/Accepted Observation 不进入 Frozen Boundary,保持 Pending;切换后解除 Candidate 限制,由新 Active 使用自身 Receipt anti-join 追平边界外 Source,并使查询在追平前显示 partial_source_gap。锁时长和资源边界必须由容量验证约束;超出边界则放弃切换。切换不更改 Event、Accepted Source、Domain Fact 或旧 Projection。验证失败时记录 blocked Proof、放弃切换并修复 Projector;不得修改历史 Payload 让测试通过。

Observation 不是永久权威事件。Intake 只有在当前 Workload JWT Subject 等于首次 source.workloadPrincipalId,且 observationDigestAlgorithmVersion + observationId + submissionPayloadSha256 相同时才判定提交幂等,并对首次生成的 Accepted Envelope 单独保存不可变 acceptedEnvelopeSha256;跨 Workload 同 ID、算法版本错配或同 Source 不同摘要都作为完整性冲突拒绝,且不返回首次 Source 内容。Observation Receipt 以 (consumerName, projectionName, projectionVersion, observationId) 为坐标保存 observationDigestAlgorithmVersion + acceptedEnvelopeSha256,并与 Projection Mutation 在同一事务;其他 Consumer/Projection Receipt 不能满足当前版本,Shadow 同样以自身 Receipt Anti-join 找出未应用记录。摘要规范与 Golden 制品以 Contracts 为唯一来源,Archive/Rebuild 不能使用数据库或语言运行时的默认 JSON 字节。若保留窗口不足以重建,页面只能标注可获得的接受记录时间范围,不能从日志补造 Observation 或声称请求 Coverage 完整。

Projection Row、Timeline、Exact Identifier Index 与派生摘要必须保留字段级 Source Lineage、Data Classification、Expiry 与 Legal Hold。Accepted Observation Payload 的到期资格只按 Core acceptedAt 与治理策略计算,不能使用 sourceClaimedObservedAt。到期并由受审计 Retention Procedure 删除时,所有只由它派生的索引、时间线字段和摘要按同一治理边界清除或降级;不能让派生副本无限期绕过源数据保留策略。Procedure 在同一事务清除独立 Envelope/派生内容,并追加唯一 observation_payload_purge_markers(observationId, purgedAt, retentionAuditRef);不能更新、删除或重绑 ID Registry。此后同 Source、同摘要重放返回不含原 Envelope 的 accepted_existing_purgedobservationId + originalAcceptedAt,不得重新插入 Payload;跨 Workload 同 ID 或同 Source 不同摘要仍返回不可枚举的完整性冲突。并发清理/重放、同源过期重放与跨源过期重放都必须有真实 PostgreSQL 测试。

Rollback Pointer 不是直接翻转开关。切回 vN 前,先在 vN+1 继续服务或在正确性受疑时关闭/降级 Query,把 vN 作为 Shadow 对 Event 与 Accepted Observation 两类 Source 反复 Receipt anti-join 追平;再暂停并排空该 Shadow,在短 Consistent Snapshot 事务中冻结新的 rollback Candidate Boundary、原子绑定新 Claim Fencing Token,随后只对该边界 Catch-up。然后获取同一 Active Cutover Lock、停止两类新 Active Claim、排空当前 Active in-flight,并在最终事务复核该 Candidate、生成新的不可变 Readiness Proof 后同事务切回 Active Pointer 与 Consumer Target。边界后 Source 不进入 Readiness,恢复后由切回版本追平。无法追平或验证失败时不得切回陈旧 vN。

新鲜度与自监控

Projection Status 至少显示:

  • Active/Shadow 版本与部署版本;
  • 最近成功应用时间、待应用 Receipt Anti-join 计数与最旧待处理时间;
  • Pending、Retry、Quarantine、Revision Gap 与 Schema Reject;
  • Shadow Rebuild 起点、进度、比较结果和切换状态;
  • Observation Intake 的可用性、已接受记录范围与已知健康窗口;健康窗口不代表请求级完整覆盖。

阈值由 SLO、容量测试和管理员配置决定。投影自身异常时,Admin 首页必须显示“运维数据延迟/不完整”,不能继续用陈旧结果断言客户业务状态。

On this page