Freeze SCUM guarded mutation run contract

This commit is contained in:
npc0-hue
2026-08-13 14:04:44 +08:00
parent ac6f5419fe
commit 41c109128d
17 changed files with 741 additions and 37 deletions
+21 -2
View File
@@ -373,6 +373,21 @@ func validateExecutionResultForJob(job domain.Job, result domain.RunJobResult) e
return err
}
}
case domain.JobCapabilityRemoteRunProtectedSQL:
if job.ExecutionInput.GuardedMutation == nil {
break
}
if result.ExecutionResult.Kind != "" && result.ExecutionResult.Kind != scumGuardedMutationExecutionKind {
return validationError("guarded mutation result type is invalid")
}
if result.State == domain.JobStateSucceeded {
if result.ExecutionResult.GuardedMutation == nil {
return validationError("guarded mutation terminal result is required")
}
if err := validateSCUMGuardedMutationResultForJob(job, *result.ExecutionResult.GuardedMutation); err != nil {
return err
}
}
case domain.JobCapabilityClientManagerDeploy:
if result.State == domain.JobStateSucceeded && result.ExecutionResult.Kind != "client-manager.deployed" {
return validationError("client-manager deploy result type is invalid")
@@ -678,7 +693,7 @@ func assignmentFromJob(job domain.Job, leaseToken string) domain.RunJobAssignmen
State: job.State,
Progress: domain.RunJobProgressReport{Percent: job.Progress.Percent, Phase: job.Progress.Phase, Message: job.Progress.Message},
ResultRef: job.ResultRef,
ExecutionInput: domain.JobExecutionInput{WorkspaceScope: job.ExecutionInput.WorkspaceScope, Content: job.ExecutionInput.Content, ExpectedVersion: job.ExecutionInput.ExpectedVersion, ExpectedChecksum: job.ExecutionInput.ExpectedChecksum, MaxReadBytes: job.ExecutionInput.MaxReadBytes, RemoteAdapterKey: job.ExecutionInput.RemoteAdapterKey, RemoteAdapterKind: job.ExecutionInput.RemoteAdapterKind, TimeoutSeconds: job.ExecutionInput.TimeoutSeconds, PluginID: job.ExecutionInput.PluginID, LifecycleOperation: job.ExecutionInput.LifecycleOperation, TargetVersion: job.ExecutionInput.TargetVersion, Inputs: domain.CopyStringMap(job.ExecutionInput.Inputs), LogSource: domain.CopyRuntimeLogSourcePtr(job.ExecutionInput.LogSource), LogSources: domain.CopyRuntimeLogSources(job.ExecutionInput.LogSources), DLLExtensions: append([]domain.RuntimeDLLExtensionPlan(nil), job.ExecutionInput.DLLExtensions...), SourceRCON: domain.CopyRuntimeSourceRCONPlan(job.ExecutionInput.SourceRCON), Deployment: deploymentPlanForDispatchValue(job.ExecutionInput.Deployment), ServerDeploymentPlan: domain.CopyServerDeploymentPlan(job.ExecutionInput.ServerDeploymentPlan), SQLiteSchemaProbe: domain.CopySCUMSchemaProbeRequestPtr(job.ExecutionInput.SQLiteSchemaProbe), SQLiteTemplate: domain.CopySCUMSQLiteTemplateRequestPtr(job.ExecutionInput.SQLiteTemplate), RCONTemplate: domain.CopySCUMTypedRCONTemplateRequestPtr(job.ExecutionInput.RCONTemplate)},
ExecutionInput: domain.JobExecutionInput{WorkspaceScope: job.ExecutionInput.WorkspaceScope, Content: job.ExecutionInput.Content, ExpectedVersion: job.ExecutionInput.ExpectedVersion, ExpectedChecksum: job.ExecutionInput.ExpectedChecksum, MaxReadBytes: job.ExecutionInput.MaxReadBytes, RemoteAdapterKey: job.ExecutionInput.RemoteAdapterKey, RemoteAdapterKind: job.ExecutionInput.RemoteAdapterKind, TimeoutSeconds: job.ExecutionInput.TimeoutSeconds, PluginID: job.ExecutionInput.PluginID, LifecycleOperation: job.ExecutionInput.LifecycleOperation, TargetVersion: job.ExecutionInput.TargetVersion, Inputs: domain.CopyStringMap(job.ExecutionInput.Inputs), LogSource: domain.CopyRuntimeLogSourcePtr(job.ExecutionInput.LogSource), LogSources: domain.CopyRuntimeLogSources(job.ExecutionInput.LogSources), DLLExtensions: append([]domain.RuntimeDLLExtensionPlan(nil), job.ExecutionInput.DLLExtensions...), SourceRCON: domain.CopyRuntimeSourceRCONPlan(job.ExecutionInput.SourceRCON), Deployment: deploymentPlanForDispatchValue(job.ExecutionInput.Deployment), ServerDeploymentPlan: domain.CopyServerDeploymentPlan(job.ExecutionInput.ServerDeploymentPlan), SQLiteSchemaProbe: domain.CopySCUMSchemaProbeRequestPtr(job.ExecutionInput.SQLiteSchemaProbe), SQLiteTemplate: domain.CopySCUMSQLiteTemplateRequestPtr(job.ExecutionInput.SQLiteTemplate), RCONTemplate: domain.CopySCUMTypedRCONTemplateRequestPtr(job.ExecutionInput.RCONTemplate), GuardedMutation: domain.CopySCUMGuardedMutationRequestPtr(job.ExecutionInput.GuardedMutation)},
LeaseToken: leaseToken,
Attempt: job.Attempt,
FencingToken: fencingToken,
@@ -768,7 +783,11 @@ func terminalFingerprint(result domain.RunJobResult) string {
if result.ExecutionResult.RCONTemplate != nil {
rconTemplateFingerprint = fmt.Sprintf("%s|%s|%s|%s|%s", result.ExecutionResult.RCONTemplate.ResultDigest, result.ExecutionResult.RCONTemplate.AssetDigest, result.ExecutionResult.RCONTemplate.PayloadDigest, result.ExecutionResult.RCONTemplate.ConfirmationDigest, result.ExecutionResult.RCONTemplate.ConfirmationStatus)
}
return fmt.Sprintf("%s|%d|%s|%s|%s|%s|%t|%s|%s|%s|%s|%s", result.State, result.Progress.Percent, result.ResultRef, result.Message, result.ErrorCode, result.Progress.Message, result.Retryable, result.ExecutionResult.Kind, result.ExecutionResult.Checksum, schemaProbeFingerprint, sqliteTemplateFingerprint, rconTemplateFingerprint)
guardedMutationFingerprint := ""
if result.ExecutionResult.GuardedMutation != nil {
guardedMutationFingerprint = fmt.Sprintf("%s|%s|%s|%d|%s", result.ExecutionResult.GuardedMutation.ResultDigest, result.ExecutionResult.GuardedMutation.AssetDigest, result.ExecutionResult.GuardedMutation.PatchDigest, result.ExecutionResult.GuardedMutation.AffectedRows, result.ExecutionResult.GuardedMutation.ReadbackStatus)
}
return fmt.Sprintf("%s|%d|%s|%s|%s|%s|%t|%s|%s|%s|%s|%s|%s", result.State, result.Progress.Percent, result.ResultRef, result.Message, result.ErrorCode, result.Progress.Message, result.Retryable, result.ExecutionResult.Kind, result.ExecutionResult.Checksum, schemaProbeFingerprint, sqliteTemplateFingerprint, rconTemplateFingerprint, guardedMutationFingerprint)
}
func terminalMessage(result domain.RunJobResult) string {