Freeze SCUM guarded mutation run contract
This commit is contained in:
@@ -163,6 +163,51 @@ func TestValidateSCUMTypedRCONTemplateResultRejectsUnconfirmedSuccessAndUnsafeSu
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateSCUMGuardedMutationRequestAllowsBoundedGenericTemplate(t *testing.T) {
|
||||
request := validatorSCUMGuardedMutationRequest()
|
||||
|
||||
if err := ValidateSCUMGuardedMutationRequest(request); err != nil {
|
||||
t.Fatalf("expected valid guarded mutation request, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateSCUMGuardedMutationRequestRejectsRawXMLSQL855AndMissingGuards(t *testing.T) {
|
||||
request := validatorSCUMGuardedMutationRequest()
|
||||
request.Payload = map[string]any{"rawXml": "<CharacterTemplate><Attribute name=\"Strength\" value=\"9\" /></CharacterTemplate>", "fieldKey855": "855"}
|
||||
request.BackupEvidenceDigest = ""
|
||||
request.OfflineEvidenceDigest = ""
|
||||
request.DangerConfirmationDigest = ""
|
||||
request.ReadbackExpectationDigest = ""
|
||||
request.ReviewReason = "update sqlite:///private/tmp/SCUM.db directly"
|
||||
request.Bounds.MaxAffectedRows = 2
|
||||
|
||||
err := ValidateSCUMGuardedMutationRequest(request)
|
||||
if err == nil || !strings.Contains(err.Error(), "payload key is unsafe") || !strings.Contains(err.Error(), "payload value is unsafe") || !strings.Contains(err.Error(), "backupEvidenceDigest") || !strings.Contains(err.Error(), "offlineEvidenceDigest") || !strings.Contains(err.Error(), "dangerConfirmationDigest") || !strings.Contains(err.Error(), "readbackExpectationDigest") || !strings.Contains(err.Error(), "maxAffectedRows") || !strings.Contains(err.Error(), "reviewReason") {
|
||||
t.Fatalf("expected guarded mutation safety violations, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateSCUMGuardedMutationResultAcceptsConfirmedSingleRowEnvelope(t *testing.T) {
|
||||
result := validatorSCUMGuardedMutationResult()
|
||||
|
||||
if err := ValidateSCUMGuardedMutationResult(result); err != nil {
|
||||
t.Fatalf("expected valid guarded mutation result, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateSCUMGuardedMutationResultRejectsMultiRowMissingReadbackAndUnsafeSummary(t *testing.T) {
|
||||
result := validatorSCUMGuardedMutationResult()
|
||||
result.AffectedRows = 2
|
||||
result.ReadbackStatus = domain.SCUMMutationReadbackUnknown
|
||||
result.ReadbackDigest = ""
|
||||
result.SafeSummary = "raw <CharacterTemplate /> leaked"
|
||||
|
||||
err := ValidateSCUMGuardedMutationResult(result)
|
||||
if err == nil || !strings.Contains(err.Error(), "exactly one affected row") || !strings.Contains(err.Error(), "readback") || !strings.Contains(err.Error(), "safeSummary") {
|
||||
t.Fatalf("expected affected-row/readback/summary violations, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateSCUMCapabilityEvidenceRequiresSafeCurrentServiceIdentity(t *testing.T) {
|
||||
evidence := domain.SCUMCapabilityEvidence{Capability: domain.SCUMDataCapabilityPlayerRead, Status: domain.SCUMCapabilityEvidenceCompatible, Binding: validatorSCUMBinding(), AdapterVersion: "adapter-1", SchemaFingerprint: scumProbeHash, ProbeResultDigest: scumProbeHash, AssetDigests: []string{scumProbeHash}, SafeError: domain.SCUMSafeError{Code: domain.SCUMSafeErrorNone}}
|
||||
if err := ValidateSCUMCapabilityEvidence(evidence); err != nil {
|
||||
@@ -196,3 +241,12 @@ func validatorSCUMTypedRCONTemplateResult() domain.SCUMTypedRCONTemplateResult {
|
||||
request := validatorSCUMTypedRCONTemplateRequest()
|
||||
return domain.SCUMTypedRCONTemplateResult{RequestID: request.RequestID, JobID: request.JobID, Binding: request.Binding, Status: domain.SCUMTerminalResultSucceeded, Capability: request.Capability, TransportKey: request.TransportKey, TargetKey: request.TargetKey, TemplateKey: request.TemplateKey, AdapterVersion: request.AdapterVersion, SchemaFingerprint: request.RequiredSchemaFingerprint, AssetDigest: request.AssetDigest, PayloadDigest: request.PayloadDigest, ConfirmationDigest: request.ConfirmationDigest, TargetIdentityDigest: request.TargetIdentityDigest, ObservedAt: time.Now(), ResultDigest: scumProbeHash, ResponseDigest: scumProbeHash, ConfirmationStatus: domain.SCUMRCONConfirmationConfirmed, ConfirmationDigestID: scumProbeHash, SafeSummary: "confirmed by declared readback", Limits: request.Bounds, SafeError: domain.SCUMSafeError{Code: domain.SCUMSafeErrorNone}}
|
||||
}
|
||||
|
||||
func validatorSCUMGuardedMutationRequest() domain.SCUMGuardedMutationRequest {
|
||||
return domain.SCUMGuardedMutationRequest{RequestID: "request-mutation-1", JobID: "job-mutation-1", Binding: validatorSCUMBinding(), Capability: domain.SCUMDataCapabilityProfileXMLWrite, TargetKey: "scum-mutation-db", TemplateKey: "profile.attributes.patch.v1", AdapterVersion: "adapter-1", RequiredSchemaFingerprint: scumProbeHash, AssetDigest: scumProbeHash, TargetIdentityDigest: scumProbeHash, ExpectedRowDigest: scumProbeHash, ExpectedValueDigest: scumProbeHash, ExpectedXMLDigest: scumProbeHash, PatchDigest: scumProbeHash, BackupEvidenceDigest: scumProbeHash, OfflineEvidenceDigest: scumProbeHash, DangerConfirmationDigest: scumProbeHash, ReadbackExpectationDigest: scumProbeHash, IdempotencyKey: "idem-mutation-1", Payload: map[string]any{"attributeKey": "Strength", "absoluteValue": 8.5}, ReviewReason: "operator confirmed offline profile attribute patch", Bounds: domain.DefaultSCUMGuardedMutationBounds(), RequestedAt: time.Now()}
|
||||
}
|
||||
|
||||
func validatorSCUMGuardedMutationResult() domain.SCUMGuardedMutationResult {
|
||||
request := validatorSCUMGuardedMutationRequest()
|
||||
return domain.SCUMGuardedMutationResult{RequestID: request.RequestID, JobID: request.JobID, Binding: request.Binding, Status: domain.SCUMTerminalResultSucceeded, Capability: request.Capability, TargetKey: request.TargetKey, TemplateKey: request.TemplateKey, AdapterVersion: request.AdapterVersion, SchemaFingerprint: request.RequiredSchemaFingerprint, AssetDigest: request.AssetDigest, SourceFingerprint: scumProbeHash, TargetIdentityDigest: request.TargetIdentityDigest, ExpectedRowDigest: request.ExpectedRowDigest, ExpectedValueDigest: request.ExpectedValueDigest, ExpectedXMLDigest: request.ExpectedXMLDigest, PatchDigest: request.PatchDigest, BackupEvidenceDigest: request.BackupEvidenceDigest, OfflineEvidenceDigest: request.OfflineEvidenceDigest, DangerConfirmationDigest: request.DangerConfirmationDigest, ReadbackExpectationDigest: request.ReadbackExpectationDigest, ObservedAt: time.Now(), ResultDigest: scumProbeHash, BeforeDigest: scumProbeHash, AfterDigest: scumProbeHash, ReadbackDigest: scumProbeHash, AffectedRows: 1, ReadbackStatus: domain.SCUMMutationReadbackConfirmed, SafeSummary: "confirmed by declared readback", SafeError: domain.SCUMSafeError{Code: domain.SCUMSafeErrorNone}, Limits: request.Bounds}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user