feat: require production infrastructure evidence

This commit is contained in:
Codex Local
2026-08-26 22:56:19 +08:00
parent 3786db0de8
commit feb99de192
19 changed files with 237 additions and 61 deletions
+84 -25
View File
@@ -82,6 +82,15 @@ type AcceptancePlatformHealthState struct {
GateSatisfied bool `json:"gate_satisfied"`
}
type AcceptanceProductionInfrastructureState struct {
Applicable bool `json:"applicable"`
DeploymentProfile string `json:"deployment_profile"`
OffsiteBackupReady bool `json:"offsite_backup_ready"`
ExternalAlertReceiverReady bool `json:"external_alert_receiver_ready"`
MockServicesDisabled bool `json:"mock_services_disabled"`
GateSatisfied bool `json:"gate_satisfied"`
}
type AcceptanceBlockingAlert struct {
ID string `json:"id"`
RuleCode string `json:"rule_code"`
@@ -101,25 +110,26 @@ type AcceptanceGate struct {
}
type AcceptanceSnapshot struct {
ID string `json:"id"`
GeneratedAt time.Time `json:"generated_at"`
TenantID string `json:"tenant_id"`
CandidateVersion string `json:"candidate_version"`
BuildDigest string `json:"build_digest"`
Environment string `json:"environment"`
RunType string `json:"run_type"`
Scope string `json:"scope"`
RedactionPolicy string `json:"redaction_policy"`
RuntimeBuild buildinfo.Info `json:"runtime_build"`
Database AcceptanceDatabaseState `json:"database"`
IntegrationIssues IntegrationIssueSummary `json:"integration_issues"`
ExternalDependencies []AcceptanceDependencyState `json:"external_dependencies"`
Outbox AcceptanceOutboxState `json:"outbox"`
Alerts AcceptanceAlertState `json:"alerts"`
PlatformHealth AcceptancePlatformHealthState `json:"platform_health"`
Gates []AcceptanceGate `json:"gates"`
OverallGateSatisfied bool `json:"overall_gate_satisfied"`
Disclaimer string `json:"disclaimer"`
ID string `json:"id"`
GeneratedAt time.Time `json:"generated_at"`
TenantID string `json:"tenant_id"`
CandidateVersion string `json:"candidate_version"`
BuildDigest string `json:"build_digest"`
Environment string `json:"environment"`
RunType string `json:"run_type"`
Scope string `json:"scope"`
RedactionPolicy string `json:"redaction_policy"`
RuntimeBuild buildinfo.Info `json:"runtime_build"`
Database AcceptanceDatabaseState `json:"database"`
IntegrationIssues IntegrationIssueSummary `json:"integration_issues"`
ExternalDependencies []AcceptanceDependencyState `json:"external_dependencies"`
Outbox AcceptanceOutboxState `json:"outbox"`
Alerts AcceptanceAlertState `json:"alerts"`
PlatformHealth AcceptancePlatformHealthState `json:"platform_health"`
ProductionInfrastructure AcceptanceProductionInfrastructureState `json:"production_infrastructure"`
Gates []AcceptanceGate `json:"gates"`
OverallGateSatisfied bool `json:"overall_gate_satisfied"`
Disclaimer string `json:"disclaimer"`
}
func (s *Service) ExportAcceptanceSnapshot(ctx context.Context, principal identity.Principal, tenantPublicID, key, requestID string, input AcceptanceSnapshotInput) (AcceptanceSnapshot, bool, error) {
@@ -289,11 +299,12 @@ func buildAcceptanceSnapshot(ctx context.Context, tx pgx.Tx, tenantPublicID, ten
); err != nil {
return AcceptanceSnapshot{}, err
}
platformHealth, err := loadAcceptancePlatformHealth(ctx, tx, now)
platformHealth, productionInfrastructure, err := loadAcceptancePlatformHealth(ctx, tx, now, input.Environment)
if err != nil {
return AcceptanceSnapshot{}, err
}
snapshot.PlatformHealth = platformHealth
snapshot.ProductionInfrastructure = productionInfrastructure
runtimeSatisfied := input.Environment == "LAB" || (snapshot.RuntimeBuild.Version == input.CandidateVersion && snapshot.RuntimeBuild.Commit != "unknown" && snapshot.RuntimeBuild.BuildTime != "unknown")
dependenciesSatisfied := true
@@ -310,6 +321,7 @@ func buildAcceptanceSnapshot(ctx context.Context, tx pgx.Tx, tenantPublicID, ten
{Code: "outbox_clear", Satisfied: outboxSatisfied, Summary: "租户及平台级待处理、处理中和死信任务必须清零"},
{Code: "critical_alerts_clear", Satisfied: alertsSatisfied, Summary: "不得存在未解决的高或严重级告警"},
{Code: "platform_health_current", Satisfied: snapshot.PlatformHealth.GateSatisfied, Summary: acceptancePlatformHealthSummary(snapshot.PlatformHealth)},
{Code: "production_infrastructure_ready", Satisfied: snapshot.ProductionInfrastructure.GateSatisfied, Summary: acceptanceProductionInfrastructureSummary(snapshot.ProductionInfrastructure)},
}
snapshot.OverallGateSatisfied = true
for _, gate := range snapshot.Gates {
@@ -318,7 +330,7 @@ func buildAcceptanceSnapshot(ctx context.Context, tx pgx.Tx, tenantPublicID, ten
return snapshot, nil
}
func loadAcceptancePlatformHealth(ctx context.Context, tx pgx.Tx, now time.Time) (AcceptancePlatformHealthState, error) {
func loadAcceptancePlatformHealth(ctx context.Context, tx pgx.Tx, now time.Time, environment string) (AcceptancePlatformHealthState, AcceptanceProductionInfrastructureState, error) {
state := AcceptancePlatformHealthState{State: "MISSING"}
var observedAt, receivedAt time.Time
var checksJSON []byte
@@ -328,16 +340,16 @@ func loadAcceptancePlatformHealth(ctx context.Context, tx pgx.Tx, now time.Time)
&state.Status, &observedAt, &receivedAt, &checksJSON,
)
if errors.Is(err, pgx.ErrNoRows) {
return state, nil
return state, evaluateAcceptanceProductionInfrastructure(environment, nil), nil
}
if err != nil {
return AcceptancePlatformHealthState{}, err
return AcceptancePlatformHealthState{}, AcceptanceProductionInfrastructureState{}, err
}
var checks []PlatformHealthCheck
if err = json.Unmarshal(checksJSON, &checks); err != nil {
return AcceptancePlatformHealthState{}, err
return AcceptancePlatformHealthState{}, AcceptanceProductionInfrastructureState{}, err
}
return evaluateAcceptancePlatformHealth(state.Status, observedAt, receivedAt, checks, now), nil
return evaluateAcceptancePlatformHealth(state.Status, observedAt, receivedAt, checks, now), evaluateAcceptanceProductionInfrastructure(environment, checks), nil
}
func evaluateAcceptancePlatformHealth(status string, observedAt, receivedAt time.Time, checks []PlatformHealthCheck, now time.Time) AcceptancePlatformHealthState {
@@ -372,6 +384,53 @@ func acceptancePlatformHealthSummary(state AcceptancePlatformHealthState) string
return fmt.Sprintf("云端主机健康快照当前有效,共%d项检查", state.CheckCount)
}
func evaluateAcceptanceProductionInfrastructure(environment string, checks []PlatformHealthCheck) AcceptanceProductionInfrastructureState {
state := AcceptanceProductionInfrastructureState{Applicable: environment == "PRODUCTION", DeploymentProfile: "MISSING"}
if !state.Applicable {
state.GateSatisfied = true
return state
}
profileReady := false
for _, check := range checks {
switch check.Name {
case "deployment_profile":
state.DeploymentProfile = check.Value
profileReady = check.Status == "healthy" && check.Value == "production"
case "offsite_backup":
state.OffsiteBackupReady = check.Status == "healthy" && strings.HasPrefix(check.Value, "age_seconds=")
case "external_alert_receiver":
state.ExternalAlertReceiverReady = check.Status == "healthy" && check.Value == "configured"
case "mock_services":
state.MockServicesDisabled = check.Status == "healthy" && check.Value == "disabled"
}
}
state.GateSatisfied = profileReady && state.OffsiteBackupReady && state.ExternalAlertReceiverReady && state.MockServicesDisabled
return state
}
func acceptanceProductionInfrastructureSummary(state AcceptanceProductionInfrastructureState) string {
if !state.Applicable {
return "非生产候选不适用生产基础设施强制门禁"
}
missing := make([]string, 0, 4)
if state.DeploymentProfile != "production" {
missing = append(missing, "生产部署模式")
}
if !state.OffsiteBackupReady {
missing = append(missing, "已验证异地备份")
}
if !state.ExternalAlertReceiverReady {
missing = append(missing, "真实外部告警接收器")
}
if !state.MockServicesDisabled {
missing = append(missing, "关闭模拟服务")
}
if len(missing) > 0 {
return "生产基础设施尚缺:" + strings.Join(missing, "、")
}
return "生产部署模式、异地备份、外部告警和模拟服务退出均已确认"
}
func acceptanceRuntimeSummary(environment string) string {
if environment == "LAB" {
return "实验室环境允许开发构建,但候选版本与镜像摘要必须明确"
@@ -59,7 +59,7 @@ func TestAcceptanceSnapshotIsAuditedIdempotentAndTenantScoped(t *testing.T) {
if err != nil || !created {
t.Fatalf("first=%+v created=%t err=%v", first, created, err)
}
if first.ID == "" || first.Database.MigrationVersion < 39 || first.Database.Dirty || first.RedactionPolicy != "ops-acceptance-minimal-v1" || len(first.ExternalDependencies) != 1 || len(first.Gates) != 7 {
if first.ID == "" || first.Database.MigrationVersion < 39 || first.Database.Dirty || first.RedactionPolicy != "ops-acceptance-minimal-v1" || len(first.ExternalDependencies) != 1 || len(first.Gates) != 8 {
t.Fatalf("unexpected snapshot=%+v", first)
}
if first.ExternalDependencies[0].Dependency != "oidc_jwks" || first.ExternalDependencies[0].ServiceName != "api" {
@@ -77,6 +77,9 @@ func TestAcceptanceSnapshotIsAuditedIdempotentAndTenantScoped(t *testing.T) {
if first.Gates[6].Code != "platform_health_current" || first.PlatformHealth.State == "" {
t.Fatalf("platform health=%+v gates=%+v", first.PlatformHealth, first.Gates)
}
if first.Gates[7].Code != "production_infrastructure_ready" || !first.Gates[7].Satisfied || first.ProductionInfrastructure.Applicable {
t.Fatalf("production infrastructure=%+v gates=%+v", first.ProductionInfrastructure, first.Gates)
}
replayed, createdAgain, err := service.ExportAcceptanceSnapshot(ctx, admin, tenantPublicID, key, requestID, input)
if err != nil || createdAgain || replayed.ID != first.ID || !replayed.GeneratedAt.Equal(first.GeneratedAt) {
t.Fatalf("replayed=%+v created=%t err=%v", replayed, createdAgain, err)
@@ -71,6 +71,32 @@ func TestAcceptancePlatformHealthSummaryCoversMissingAndCounts(t *testing.T) {
}
}
func TestEvaluateAcceptanceProductionInfrastructure(t *testing.T) {
readyChecks := []PlatformHealthCheck{
{Name: "deployment_profile", Status: "healthy", Value: "production"},
{Name: "offsite_backup", Status: "healthy", Value: "age_seconds=120"},
{Name: "external_alert_receiver", Status: "healthy", Value: "configured"},
{Name: "mock_services", Status: "healthy", Value: "disabled"},
}
ready := evaluateAcceptanceProductionInfrastructure("PRODUCTION", readyChecks)
if !ready.Applicable || !ready.GateSatisfied || !ready.OffsiteBackupReady || !ready.ExternalAlertReceiverReady || !ready.MockServicesDisabled {
t.Fatalf("ready=%+v", ready)
}
demo := evaluateAcceptanceProductionInfrastructure("PRODUCTION", []PlatformHealthCheck{
{Name: "deployment_profile", Status: "healthy", Value: "demo"},
{Name: "offsite_backup", Status: "healthy", Value: "not_required"},
{Name: "external_alert_receiver", Status: "healthy", Value: "not_configured"},
{Name: "mock_services", Status: "healthy", Value: "enabled_for_demo"},
})
if demo.GateSatisfied || demo.DeploymentProfile != "demo" || !strings.Contains(acceptanceProductionInfrastructureSummary(demo), "异地备份") {
t.Fatalf("demo=%+v summary=%q", demo, acceptanceProductionInfrastructureSummary(demo))
}
lab := evaluateAcceptanceProductionInfrastructure("LAB", nil)
if lab.Applicable || !lab.GateSatisfied {
t.Fatalf("lab=%+v", lab)
}
}
func TestAcceptanceSnapshotAllowsAllProductionExternalDependencies(t *testing.T) {
input := AcceptanceSnapshotInput{
CandidateVersion: "0.64.0-rc.1", BuildDigest: "sha256:" + strings.Repeat("b", 64),