功能修改

This commit is contained in:
npc0-hue
2026-07-20 16:42:33 +08:00
parent 48b8ad8d6c
commit a0e69417db
224 changed files with 22015 additions and 884 deletions
+2
View File
@@ -25,6 +25,8 @@ type AIConfigRecommendation struct {
Key string
SuggestedConfig string
DiffSummary string
DiffID string
ExpiresAt string
}
type AIInvocationSafeError struct {
@@ -52,6 +52,8 @@ const (
JobCapabilityClientManagerUninstall = "client-manager.uninstall"
)
const ClientManagerCompanionConfigSchemaVersion = 1
type ClientManagerSessionStatus string
const (
@@ -246,6 +248,37 @@ type ClientManagerLifecycleInput struct {
StopTimeoutSeconds int
HealthConfirmationSeconds int
IdempotencyKey string
CompanionConfig *ClientManagerCompanionConfigInput
}
type ClientManagerCompanionConfigInput struct {
SchemaVersion int
ConfigTemplateKey string
ConfigTemplateRef string
ConfigOutputRef string
ConfigSchemaRef string
ConfigFormat string
PlatformBaseURLSource string
InstallationID string
ServerInstanceID string
PluginID string
ProfileKey string
ArtifactID string
Version string
SourceRevision string
TargetOS string
TargetArch string
KeyGeneration int
DeploymentGeneration int
Capabilities []string
RegistrationProof string
ProofMaterialSource string
ProofMaterialEnv string
SessionMode string
TLSPolicy string
HeartbeatIntervalSeconds int
CommandPollIntervalSeconds int
RequestTimeoutSeconds int
}
type ClientManagerRegisterRequest struct {
@@ -336,6 +369,15 @@ func CopyClientManagerLifecycleView(value ClientManagerLifecycleView) ClientMana
func CopyClientManagerLifecycleInput(value ClientManagerLifecycleInput) ClientManagerLifecycleInput {
value.Arguments = CopyStringSlice(value.Arguments)
if value.CompanionConfig != nil {
companion := CopyClientManagerCompanionConfigInput(*value.CompanionConfig)
value.CompanionConfig = &companion
}
return value
}
func CopyClientManagerCompanionConfigInput(value ClientManagerCompanionConfigInput) ClientManagerCompanionConfigInput {
value.Capabilities = CopyStringSlice(value.Capabilities)
return value
}
@@ -0,0 +1,22 @@
package domain
import "testing"
func TestCopyClientManagerLifecycleInputDeepCopiesCompanionCapabilities(t *testing.T) {
original := ClientManagerLifecycleInput{
Arguments: []string{"--foreground"},
CompanionConfig: &ClientManagerCompanionConfigInput{
Capabilities: []string{"component.register", "game-client.bridge"},
},
}
cloned := CopyClientManagerLifecycleInput(original)
cloned.Arguments[0] = "--changed"
cloned.CompanionConfig.Capabilities[0] = "changed"
if original.Arguments[0] != "--foreground" {
t.Fatalf("arguments were not deeply copied: %+v", original.Arguments)
}
if original.CompanionConfig.Capabilities[0] != "component.register" {
t.Fatalf("companion capabilities were not deeply copied: %+v", original.CompanionConfig.Capabilities)
}
}
+389
View File
@@ -0,0 +1,389 @@
package domain
import "time"
type GameClientBridgeCommandState string
const (
GameClientBridgeCommandPending GameClientBridgeCommandState = "pending"
GameClientBridgeCommandClaimed GameClientBridgeCommandState = "claimed"
GameClientBridgeCommandSucceeded GameClientBridgeCommandState = "succeeded"
GameClientBridgeCommandFailed GameClientBridgeCommandState = "failed"
GameClientBridgeCommandCancelled GameClientBridgeCommandState = "cancelled"
GameClientBridgeCommandExpired GameClientBridgeCommandState = "expired"
)
type GameClientBridgeApprovalState string
const (
GameClientBridgeApprovalNotRequired GameClientBridgeApprovalState = "not_required"
GameClientBridgeApprovalPending GameClientBridgeApprovalState = "pending"
GameClientBridgeApprovalApproved GameClientBridgeApprovalState = "approved"
GameClientBridgeApprovalRejected GameClientBridgeApprovalState = "rejected"
)
type GameClientBridgeApprovalLevel string
const (
GameClientBridgeApprovalLevelNone GameClientBridgeApprovalLevel = "none"
GameClientBridgeApprovalLevelOperator GameClientBridgeApprovalLevel = "operator"
GameClientBridgeApprovalLevelPlatformAdmin GameClientBridgeApprovalLevel = "platform-admin"
)
type GameClientBridgeCommandDeclaration struct {
Type string
Title string
Permission string
ApprovalLevel GameClientBridgeApprovalLevel
PayloadSchemaRef string
ResultSchemaRef string
TimeoutSeconds int
MaxPayloadBytes int
}
type GameClientBridgeSnapshotDeclaration struct {
Type string
SchemaVersion string
SchemaRef string
Retention GameClientBridgeRetention
}
type GameClientBridgeQueryTemplateDeclaration struct {
Key string
Title string
Permission string
Engine string
TransportKey string
TargetKey string
ParameterSchemaRef string
ResultSchemaRef string
MaxRows int
TimeoutSeconds int
}
type GameClientBridgePageContract struct {
PageKey string
CommandTypes []string
SnapshotTypes []string
QueryTemplateKeys []string
}
type GameClientBridgeCompanionDeclaration struct {
ProfileKey string
ConfigTemplateKey string
ConfigSchemaRef string
ConfigFormat string
PlatformBaseURLSource string
RegistrationProof string
ProofMaterialSource string
ProofMaterialEnv string
SessionMode string
TLSPolicy string
HeartbeatIntervalSeconds int
CommandPollIntervalSeconds int
RequestTimeoutSeconds int
}
type GameClientBridgeManifest struct {
Commands []GameClientBridgeCommandDeclaration
Snapshots []GameClientBridgeSnapshotDeclaration
QueryTemplates []GameClientBridgeQueryTemplateDeclaration
Retention GameClientBridgeRetention
Pages []GameClientBridgePageContract
Companion GameClientBridgeCompanionDeclaration
}
type GameClientBridgeResultStatus string
const (
GameClientBridgeResultSucceeded GameClientBridgeResultStatus = "succeeded"
GameClientBridgeResultFailed GameClientBridgeResultStatus = "failed"
GameClientBridgeResultCancelled GameClientBridgeResultStatus = "cancelled"
)
type GameClientBridgeCommand struct {
ID string
ServerInstanceID string
PluginID string
ProfileKey string
CommandType string
Payload map[string]any
IdempotencyKey string
Priority int
State GameClientBridgeCommandState
ApprovalState GameClientBridgeApprovalState
RequesterID string
Claim GameClientBridgeClaim
Cancellation GameClientBridgeCancellation
Result GameClientBridgeResult
AuditReferences []string
ExpiresAt time.Time
CreatedAt time.Time
UpdatedAt time.Time
CompletedAt time.Time
}
type GameClientBridgeClaim struct {
SessionID string
InstallationID string
DeploymentGeneration int
FencingToken uint64
LeaseExpiresAt time.Time
ClaimedAt time.Time
AcknowledgedAt time.Time
}
type GameClientBridgeCancellation struct {
RequestedBy string
Reason string
CancelledAt time.Time
}
type GameClientBridgeResult struct {
Status GameClientBridgeResultStatus
Summary string
Payload map[string]any
CompletedBy string
CompletedAt time.Time
}
type GameClientBridgeSnapshot struct {
ID string
ServerInstanceID string
PluginID string
ProfileKey string
Type string
SchemaVersion string
StreamKey string
Sequence uint64
SourceSessionID string
ObservedAt time.Time
Payload map[string]any
Retention GameClientBridgeRetention
AuditReferences []string
CreatedAt time.Time
ExpiresAt time.Time
}
type GameClientBridgeSnapshotStream struct {
ID string
ServerInstanceID string
PluginID string
ProfileKey string
Type string
StreamKey string
LatestSequence uint64
UpdatedAt time.Time
}
type GameClientBridgeRetention struct {
KeepForSeconds int
MaxRecords int
}
type GameClientBridgeAuditReference struct {
ID string
CommandID string
SnapshotID string
AuditEventID string
CreatedAt time.Time
}
type GameClientBridgeCommandFilter struct {
ServerInstanceID string
PluginID string
ProfileKey string
State GameClientBridgeCommandState
RequesterID string
CommandType string
IdempotencyKey string
ExpiresBefore time.Time
CompletedBefore time.Time
}
type GameClientBridgeSnapshotStreamFilter struct {
ServerInstanceID string
PluginID string
ProfileKey string
Type string
StreamKey string
}
type GameClientBridgeSnapshotFilter struct {
ServerInstanceID string
PluginID string
ProfileKey string
Type string
StreamKey string
ObservedAfter time.Time
ExpiresBefore time.Time
Limit int
}
type GameClientBridgeQueueRequest struct {
ServerInstanceID string
PluginID string
ProfileKey string
CommandType string
Payload map[string]any
IdempotencyKey string
Priority int
ExpiresAt time.Time
}
type GameClientBridgeClaimRequest struct {
SessionToken string
Limit int
}
type GameClientBridgeAckRequest struct {
SessionToken string
CommandID string
FencingToken uint64
}
type GameClientBridgeResultRequest struct {
SessionToken string
CommandID string
FencingToken uint64
Status GameClientBridgeResultStatus
Summary string
Payload map[string]any
}
type GameClientBridgeCancelRequest struct {
CommandID string
Reason string
}
type GameClientBridgeSnapshotIngestRequest struct {
SessionToken string
Type string
SchemaVersion string
StreamKey string
Sequence uint64
ObservedAt time.Time
Payload map[string]any
Retention GameClientBridgeRetention
}
type GameClientBridgeSnapshotQuery struct {
ServerInstanceID string
PluginID string
ProfileKey string
Type string
StreamKey string
ObservedAfter time.Time
Limit int
}
type GameClientBridgeProfileDeclaration struct {
PluginID string
ProfileKey string
Available bool
Reason string
CommandTypes []string
SnapshotTypes []string
QueryTemplateKeys []string
}
type GameClientBridgeStatus struct {
ServerInstanceID string
PluginID string
Available bool
Reason string
Profiles []GameClientBridgeProfileDeclaration
}
func CopyGameClientBridgeProfileDeclaration(value GameClientBridgeProfileDeclaration) GameClientBridgeProfileDeclaration {
value.CommandTypes = CopyStringSlice(value.CommandTypes)
value.SnapshotTypes = CopyStringSlice(value.SnapshotTypes)
value.QueryTemplateKeys = CopyStringSlice(value.QueryTemplateKeys)
return value
}
func CopyGameClientBridgeStatus(value GameClientBridgeStatus) GameClientBridgeStatus {
value.Profiles = append([]GameClientBridgeProfileDeclaration(nil), value.Profiles...)
for index := range value.Profiles {
value.Profiles[index] = CopyGameClientBridgeProfileDeclaration(value.Profiles[index])
}
return value
}
func CopyGameClientBridgeCommand(value GameClientBridgeCommand) GameClientBridgeCommand {
value.Payload = CopyGameClientBridgePayload(value.Payload)
value.Claim = CopyGameClientBridgeClaim(value.Claim)
value.Cancellation = CopyGameClientBridgeCancellation(value.Cancellation)
value.Result = CopyGameClientBridgeResult(value.Result)
value.AuditReferences = CopyStringSlice(value.AuditReferences)
return value
}
func CopyGameClientBridgeClaim(value GameClientBridgeClaim) GameClientBridgeClaim { return value }
func CopyGameClientBridgeCancellation(value GameClientBridgeCancellation) GameClientBridgeCancellation {
return value
}
func CopyGameClientBridgeResult(value GameClientBridgeResult) GameClientBridgeResult {
value.Payload = CopyGameClientBridgePayload(value.Payload)
return value
}
func CopyGameClientBridgeSnapshot(value GameClientBridgeSnapshot) GameClientBridgeSnapshot {
value.Payload = CopyGameClientBridgePayload(value.Payload)
value.Retention = CopyGameClientBridgeRetention(value.Retention)
value.AuditReferences = CopyStringSlice(value.AuditReferences)
return value
}
func CopyGameClientBridgeSnapshotStream(value GameClientBridgeSnapshotStream) GameClientBridgeSnapshotStream {
return value
}
func CopyGameClientBridgeRetention(value GameClientBridgeRetention) GameClientBridgeRetention {
return value
}
func CopyGameClientBridgeAuditReference(value GameClientBridgeAuditReference) GameClientBridgeAuditReference {
return value
}
func CopyGameClientBridgePayload(value map[string]any) map[string]any {
if value == nil {
return nil
}
copy := make(map[string]any, len(value))
for key, item := range value {
copy[key] = copyGameClientBridgePayloadValue(item)
}
return copy
}
func CopyGameClientBridgeManifest(value GameClientBridgeManifest) GameClientBridgeManifest {
value.Commands = append([]GameClientBridgeCommandDeclaration(nil), value.Commands...)
value.Snapshots = append([]GameClientBridgeSnapshotDeclaration(nil), value.Snapshots...)
value.QueryTemplates = append([]GameClientBridgeQueryTemplateDeclaration(nil), value.QueryTemplates...)
value.Pages = append([]GameClientBridgePageContract(nil), value.Pages...)
for index := range value.Pages {
value.Pages[index].CommandTypes = CopyStringSlice(value.Pages[index].CommandTypes)
value.Pages[index].SnapshotTypes = CopyStringSlice(value.Pages[index].SnapshotTypes)
value.Pages[index].QueryTemplateKeys = CopyStringSlice(value.Pages[index].QueryTemplateKeys)
}
return value
}
func copyGameClientBridgePayloadValue(value any) any {
switch typed := value.(type) {
case map[string]any:
return CopyGameClientBridgePayload(typed)
case []any:
copy := make([]any, len(typed))
for index, item := range typed {
copy[index] = copyGameClientBridgePayloadValue(item)
}
return copy
default:
return typed
}
}
@@ -0,0 +1,23 @@
package domain
import "testing"
func TestCopyGameClientBridgeDeclarationsCopiesQueryTemplateSlices(t *testing.T) {
manifest := GameClientBridgeManifest{
QueryTemplates: []GameClientBridgeQueryTemplateDeclaration{{Key: "player.lookup"}},
Pages: []GameClientBridgePageContract{{PageKey: "players", QueryTemplateKeys: []string{"player.lookup"}}},
}
manifestCopy := CopyGameClientBridgeManifest(manifest)
manifestCopy.QueryTemplates[0].Key = "mutated"
manifestCopy.Pages[0].QueryTemplateKeys[0] = "mutated"
if manifest.QueryTemplates[0].Key != "player.lookup" || manifest.Pages[0].QueryTemplateKeys[0] != "player.lookup" {
t.Fatalf("manifest copy aliases query template declarations: source=%#v copy=%#v", manifest, manifestCopy)
}
status := GameClientBridgeStatus{Profiles: []GameClientBridgeProfileDeclaration{{QueryTemplateKeys: []string{"player.lookup"}}}}
statusCopy := CopyGameClientBridgeStatus(status)
statusCopy.Profiles[0].QueryTemplateKeys[0] = "mutated"
if status.Profiles[0].QueryTemplateKeys[0] != "player.lookup" {
t.Fatalf("status copy aliases query template keys: source=%#v copy=%#v", status, statusCopy)
}
}
+4 -1
View File
@@ -276,6 +276,7 @@ type RunJobReconcileResult struct {
}
func CopyRunJobAssignment(assignment RunJobAssignment) RunJobAssignment {
assignment.ExecutionInput.Inputs = CopyStringMap(assignment.ExecutionInput.Inputs)
return assignment
}
@@ -315,7 +316,9 @@ func CopyRunJobAssignments(assignments []RunJobAssignment) []RunJobAssignment {
return nil
}
out := make([]RunJobAssignment, len(assignments))
copy(out, assignments)
for index, assignment := range assignments {
out[index] = CopyRunJobAssignment(assignment)
}
return out
}
+7 -2
View File
@@ -94,6 +94,8 @@ type RemoteAdapterRequest struct {
TimeoutSeconds int
MaxAttempts int
IdempotencyKey string
InputRef string
Inputs map[string]string
}
type RemoteAdapterResult struct {
@@ -181,5 +183,8 @@ func CopyRemoteAdapterDeclarations(declarations []RemoteAdapterDeclaration) []Re
return out
}
func CopyRemoteAdapterRequest(request RemoteAdapterRequest) RemoteAdapterRequest { return request }
func CopyRemoteAdapterResult(result RemoteAdapterResult) RemoteAdapterResult { return result }
func CopyRemoteAdapterRequest(request RemoteAdapterRequest) RemoteAdapterRequest {
request.Inputs = CopyStringMap(request.Inputs)
return request
}
func CopyRemoteAdapterResult(result RemoteAdapterResult) RemoteAdapterResult { return result }
+352
View File
@@ -0,0 +1,352 @@
package domain
import "time"
type CapacityAdmissionState string
const (
CapacityAdmissionAccepted CapacityAdmissionState = "accepted"
CapacityAdmissionDeferred CapacityAdmissionState = "deferred"
CapacityAdmissionDenied CapacityAdmissionState = "denied"
)
type CapacityPressureCode string
const (
CapacityPressureEndpointOffline CapacityPressureCode = "endpoint.offline"
CapacityPressureEndpointStale CapacityPressureCode = "endpoint.stale"
CapacityPressureCapabilityGap CapacityPressureCode = "capability.missing"
CapacityPressureJobLimit CapacityPressureCode = "job.limit"
CapacityPressureQueueLimit CapacityPressureCode = "queue.limit"
CapacityPressureBacklog CapacityPressureCode = "spool.backlog"
)
type CapacityAdmissionRequest struct {
ServerInstanceID string
RunEndpointID string
Capability string
TargetKey string
IdempotencyKey string
}
type CapacityAdmissionDecision struct {
Accepted bool
State CapacityAdmissionState
Reason string
RetryAfterSeconds int
ServerInstanceID string
RunEndpointID string
Capability string
TargetKey string
MaxJobs int
RunningJobs int
QueuedJobs int
PressureCodes []CapacityPressureCode
CheckedAt time.Time
AlertID string
AuditEventID string
}
type EndpointCapacityProjection struct {
RunEndpointID string
DisplayName string
Status RunEndpointStatus
Capabilities []string
MaxJobs int
RunningJobs int
QueuedJobs int
LogBacklogBatches int
ArtifactBacklogChunks int
PressureCodes []CapacityPressureCode
Summary string
LastHeartbeatAt time.Time
LastAdmissionDecision CapacityAdmissionState
LastAdmissionReason string
LastAdmissionCheckedAt time.Time
}
type ProductionCapacitySummary struct {
Endpoints []EndpointCapacityProjection
TotalMaxJobs int
TotalRunningJobs int
TotalQueuedJobs int
ActiveAlerts int
GeneratedAt time.Time
}
type AlertSeverity string
const (
AlertSeverityInfo AlertSeverity = "info"
AlertSeverityWarning AlertSeverity = "warning"
AlertSeverityCritical AlertSeverity = "critical"
)
type AlertState string
const (
AlertStateActive AlertState = "active"
AlertStateAcknowledged AlertState = "acknowledged"
AlertStateResolved AlertState = "resolved"
)
type AlertRecord struct {
ID string
SourceKind string
SourceID string
RuleKey string
Severity AlertSeverity
State AlertState
Title string
Message string
OccurrenceCount int
Retryable bool
RetryAfterSeconds int
LastJobID string
LastAuditEventID string
LastSeenAt time.Time
AcknowledgedBy string
AcknowledgedAt time.Time
ResolvedBy string
ResolvedAt time.Time
ResolutionNote string
CreatedAt time.Time
UpdatedAt time.Time
}
type AlertFilter struct {
State AlertState
SourceKind string
SourceID string
Severity AlertSeverity
}
type AlertAcknowledgeRequest struct {
AlertID string
Note string
}
type AlertResolveRequest struct {
AlertID string
Note string
}
type AlertRetryRequest struct {
AlertID string
IdempotencyKey string
}
type AlertRetryResult struct {
Alert AlertRecord
Decision CapacityAdmissionDecision
Status string
}
type PluginLifecycleState string
const (
PluginLifecycleStatePending PluginLifecycleState = "pending"
PluginLifecycleStateInstalled PluginLifecycleState = "installed"
PluginLifecycleStateEnabled PluginLifecycleState = "enabled"
PluginLifecycleStateDisabled PluginLifecycleState = "disabled"
PluginLifecycleStateUpgrading PluginLifecycleState = "upgrading"
PluginLifecycleStateRollingBack PluginLifecycleState = "rolling_back"
PluginLifecycleStateRetired PluginLifecycleState = "retired"
PluginLifecycleStateFailed PluginLifecycleState = "failed"
)
type PluginLifecycleOperation string
const (
PluginLifecycleOperationInstall PluginLifecycleOperation = "install"
PluginLifecycleOperationEnable PluginLifecycleOperation = "enable"
PluginLifecycleOperationDisable PluginLifecycleOperation = "disable"
PluginLifecycleOperationUpgrade PluginLifecycleOperation = "upgrade"
PluginLifecycleOperationRollback PluginLifecycleOperation = "rollback"
PluginLifecycleOperationRetire PluginLifecycleOperation = "retire"
PluginLifecycleOperationDependencyCheck PluginLifecycleOperation = "dependency-check"
)
type PluginLifecycleInstallation struct {
ID string
PluginID string
ServerInstanceID string
CurrentVersion string
TargetVersion string
PreviousVersion string
DesiredState PluginLifecycleState
CurrentState PluginLifecycleState
LastOperation PluginLifecycleOperation
Compatibility string
DependencyState DependencyState
JobID string
AlertID string
AuditEventID string
FailureReason string
IdempotencyKey string
CreatedAt time.Time
UpdatedAt time.Time
}
type PluginLifecycleFilter struct {
PluginID string
ServerInstanceID string
CurrentState PluginLifecycleState
}
type PluginLifecycleRequest struct {
PluginID string
ServerInstanceID string
Operation PluginLifecycleOperation
TargetVersion string
IdempotencyKey string
Confirmed bool
}
type PluginLifecycleResult struct {
Installation PluginLifecycleInstallation
Job Job
Decision CapacityAdmissionDecision
Alert *AlertRecord
Status string
}
type AIConfigDiffState string
const (
AIConfigDiffStatePending AIConfigDiffState = "pending"
AIConfigDiffStateApproved AIConfigDiffState = "approved"
AIConfigDiffStateCancelled AIConfigDiffState = "cancelled"
AIConfigDiffStateExpired AIConfigDiffState = "expired"
)
type AIConfigDiffPreview struct {
ID string
RequestID string
CreatedBy string
ServerInstanceID string
PluginID string
ProviderID string
Model string
Key string
ConfigVersion int
CurrentConfigChecksum string
ProposedConfig string
DiffSummary string
State AIConfigDiffState
ExpiresAt time.Time
ApprovedBy string
ApprovedAt time.Time
ApprovalIdempotencyKey string
CancelledBy string
CancelledAt time.Time
JobID string
CreatedAt time.Time
UpdatedAt time.Time
}
type AIConfigDiffFilter struct {
ServerInstanceID string
PluginID string
State AIConfigDiffState
}
type AIConfigDiffApprovalRequest struct {
DiffID string
IdempotencyKey string
}
type AIConfigDiffApprovalResult struct {
Preview AIConfigDiffPreview
Dispatch ServerConfigWriteDispatch
}
func CopyCapacityAdmissionDecision(decision CapacityAdmissionDecision) CapacityAdmissionDecision {
decision.PressureCodes = CopyCapacityPressureCodes(decision.PressureCodes)
return decision
}
func CopyEndpointCapacityProjection(projection EndpointCapacityProjection) EndpointCapacityProjection {
projection.Capabilities = CopyStringSlice(projection.Capabilities)
projection.PressureCodes = CopyCapacityPressureCodes(projection.PressureCodes)
return projection
}
func CopyProductionCapacitySummary(summary ProductionCapacitySummary) ProductionCapacitySummary {
if summary.Endpoints != nil {
summary.Endpoints = append([]EndpointCapacityProjection(nil), summary.Endpoints...)
for i := range summary.Endpoints {
summary.Endpoints[i] = CopyEndpointCapacityProjection(summary.Endpoints[i])
}
}
return summary
}
func CopyCapacityPressureCodes(codes []CapacityPressureCode) []CapacityPressureCode {
if codes == nil {
return nil
}
out := make([]CapacityPressureCode, len(codes))
copy(out, codes)
return out
}
func CopyAlertRecord(alert AlertRecord) AlertRecord { return alert }
func CopyAlertRecords(alerts []AlertRecord) []AlertRecord {
if alerts == nil {
return nil
}
out := make([]AlertRecord, len(alerts))
copy(out, alerts)
return out
}
func CopyAlertRetryResult(result AlertRetryResult) AlertRetryResult {
result.Alert = CopyAlertRecord(result.Alert)
result.Decision = CopyCapacityAdmissionDecision(result.Decision)
return result
}
func CopyPluginLifecycleInstallation(installation PluginLifecycleInstallation) PluginLifecycleInstallation {
return installation
}
func CopyPluginLifecycleInstallations(installations []PluginLifecycleInstallation) []PluginLifecycleInstallation {
if installations == nil {
return nil
}
out := make([]PluginLifecycleInstallation, len(installations))
copy(out, installations)
return out
}
func CopyPluginLifecycleResult(result PluginLifecycleResult) PluginLifecycleResult {
result.Installation = CopyPluginLifecycleInstallation(result.Installation)
result.Job = CopyJob(result.Job)
result.Decision = CopyCapacityAdmissionDecision(result.Decision)
if result.Alert != nil {
alert := CopyAlertRecord(*result.Alert)
result.Alert = &alert
}
return result
}
func CopyAIConfigDiffPreview(preview AIConfigDiffPreview) AIConfigDiffPreview {
return preview
}
func CopyAIConfigDiffPreviews(previews []AIConfigDiffPreview) []AIConfigDiffPreview {
if previews == nil {
return nil
}
out := make([]AIConfigDiffPreview, len(previews))
copy(out, previews)
return out
}
func CopyAIConfigDiffApprovalResult(result AIConfigDiffApprovalResult) AIConfigDiffApprovalResult {
result.Preview = CopyAIConfigDiffPreview(result.Preview)
result.Dispatch = CopyServerConfigWriteDispatch(result.Dispatch)
return result
}
+86 -28
View File
@@ -328,7 +328,15 @@ type GamePluginManifestServer struct {
}
type GamePluginManifestAI struct {
Purposes []string
Purposes []string
Mediation string
ConfigWritePolicy string
}
type GamePluginProductionLifecycle struct {
Operations []string
DependencyPolicy string
ApprovalRequired []string
}
type GamePluginRemoteAccess struct {
@@ -398,6 +406,26 @@ type RuntimeLogSource struct {
RetentionDays int
}
type RuntimeLogEventSeverity string
const (
RuntimeLogEventSeverityInfo RuntimeLogEventSeverity = "info"
RuntimeLogEventSeverityNotice RuntimeLogEventSeverity = "notice"
RuntimeLogEventSeverityWarning RuntimeLogEventSeverity = "warning"
RuntimeLogEventSeverityCritical RuntimeLogEventSeverity = "critical"
)
type RuntimeLogEvent struct {
Key string
Title string
SourceKey string
EventType string
Permission string
SchemaRef string
RetentionDays int
Severity RuntimeLogEventSeverity
}
type RuntimeTransportProfile struct {
Key string
Kind string
@@ -439,26 +467,29 @@ type GamePluginRuntimeProfiles struct {
DependencyProbes []RuntimeDependencyProbe
InstallPlans []RuntimeInstallPlan
LogSources []RuntimeLogSource
LogEvents []RuntimeLogEvent
TransportProfiles []RuntimeTransportProfile
ClientManagers []RuntimeClientManagerProfile
}
type GamePluginManifest struct {
ID string
Name string
Description string
Version string
Kind string
Tags []string
Server GamePluginManifestServer
Bridge GamePluginBridge
Capabilities []string
Permissions []string
Actions PluginLifecycleActions
Pages []GamePluginPage
AI GamePluginManifestAI
RemoteAccess GamePluginRemoteAccess
RuntimeProfiles GamePluginRuntimeProfiles
ID string
Name string
Description string
Version string
Kind string
Tags []string
Server GamePluginManifestServer
Bridge GamePluginBridge
Capabilities []string
Permissions []string
Actions PluginLifecycleActions
Pages []GamePluginPage
AI GamePluginManifestAI
ProductionLifecycle GamePluginProductionLifecycle
RemoteAccess GamePluginRemoteAccess
RuntimeProfiles GamePluginRuntimeProfiles
GameClientBridge GameClientBridgeManifest
}
type GamePluginManifestRegistration struct {
@@ -484,8 +515,10 @@ type GamePlugin struct {
Pages []GamePluginPage
Tags []string
AIPurposes []string
ProductionLifecycle GamePluginProductionLifecycle
RemoteAccess GamePluginRemoteAccess
RuntimeProfiles GamePluginRuntimeProfiles
GameClientBridge GameClientBridgeManifest
ValidationViolations []string
Status GamePluginStatus
}
@@ -508,8 +541,10 @@ type PluginMarketplacePlugin struct {
Pages []GamePluginPage
Tags []string
AIPurposes []string
ProductionLifecycle GamePluginProductionLifecycle
RemoteAccess GamePluginRemoteAccess
RuntimeProfiles GamePluginRuntimeProfiles
GameClientBridge GameClientBridgeManifest
ValidationViolations []string
Status GamePluginStatus
Source string
@@ -528,6 +563,7 @@ const (
PluginBridgeActionDependenciesRequest PluginBridgeAction = "dependencies.request"
PluginBridgeActionLogsBackfillRequest PluginBridgeAction = "logs.backfill.request"
PluginBridgeActionClientManager PluginBridgeAction = "client-manager.request"
PluginBridgeActionPluginLifecycle PluginBridgeAction = "plugin-lifecycle.request"
PluginBridgeActionAIInvoke PluginBridgeAction = "ai.invoke"
)
@@ -708,10 +744,13 @@ type FileOperationDispatchResult struct {
}
type RunCapacity struct {
MaxJobs int
RunningJobs int
QueuedJobs int
Summary string
MaxJobs int
RunningJobs int
QueuedJobs int
LogBacklogBatches int
ArtifactBacklogChunks int
PressureCodes []string
Summary string
}
const (
@@ -761,14 +800,18 @@ type JobRetryPolicy struct {
}
type JobExecutionInput struct {
WorkspaceScope string
Content string
ExpectedVersion int
ExpectedChecksum string
MaxReadBytes int
RemoteAdapterKey string
RemoteAdapterKind string
TimeoutSeconds int
WorkspaceScope string
Content string
ExpectedVersion int
ExpectedChecksum string
MaxReadBytes int
RemoteAdapterKey string
RemoteAdapterKind string
TimeoutSeconds int
PluginID string
LifecycleOperation string
TargetVersion string
Inputs map[string]string
}
type JobExecutionResult struct {
@@ -1284,8 +1327,10 @@ func CopyGamePlugin(plugin GamePlugin) GamePlugin {
plugin.Pages = CopyGamePluginPageSlice(plugin.Pages)
plugin.Tags = CopyStringSlice(plugin.Tags)
plugin.AIPurposes = CopyStringSlice(plugin.AIPurposes)
plugin.ProductionLifecycle = CopyGamePluginProductionLifecycle(plugin.ProductionLifecycle)
plugin.RemoteAccess = CopyGamePluginRemoteAccess(plugin.RemoteAccess)
plugin.RuntimeProfiles = CopyGamePluginRuntimeProfiles(plugin.RuntimeProfiles)
plugin.GameClientBridge = CopyGameClientBridgeManifest(plugin.GameClientBridge)
plugin.ValidationViolations = CopyStringSlice(plugin.ValidationViolations)
return plugin
}
@@ -1298,8 +1343,10 @@ func CopyPluginMarketplacePlugin(plugin PluginMarketplacePlugin) PluginMarketpla
plugin.Pages = CopyGamePluginPageSlice(plugin.Pages)
plugin.Tags = CopyStringSlice(plugin.Tags)
plugin.AIPurposes = CopyStringSlice(plugin.AIPurposes)
plugin.ProductionLifecycle = CopyGamePluginProductionLifecycle(plugin.ProductionLifecycle)
plugin.RemoteAccess = CopyGamePluginRemoteAccess(plugin.RemoteAccess)
plugin.RuntimeProfiles = CopyGamePluginRuntimeProfiles(plugin.RuntimeProfiles)
plugin.GameClientBridge = CopyGameClientBridgeManifest(plugin.GameClientBridge)
plugin.ValidationViolations = CopyStringSlice(plugin.ValidationViolations)
return plugin
}
@@ -1328,11 +1375,19 @@ func CopyGamePluginManifest(manifest GamePluginManifest) GamePluginManifest {
manifest.Permissions = CopyStringSlice(manifest.Permissions)
manifest.Pages = CopyGamePluginPageSlice(manifest.Pages)
manifest.AI.Purposes = CopyStringSlice(manifest.AI.Purposes)
manifest.ProductionLifecycle = CopyGamePluginProductionLifecycle(manifest.ProductionLifecycle)
manifest.RemoteAccess = CopyGamePluginRemoteAccess(manifest.RemoteAccess)
manifest.RuntimeProfiles = CopyGamePluginRuntimeProfiles(manifest.RuntimeProfiles)
manifest.GameClientBridge = CopyGameClientBridgeManifest(manifest.GameClientBridge)
return manifest
}
func CopyGamePluginProductionLifecycle(lifecycle GamePluginProductionLifecycle) GamePluginProductionLifecycle {
lifecycle.Operations = CopyStringSlice(lifecycle.Operations)
lifecycle.ApprovalRequired = CopyStringSlice(lifecycle.ApprovalRequired)
return lifecycle
}
func CopyGamePluginRuntimeProfiles(profiles GamePluginRuntimeProfiles) GamePluginRuntimeProfiles {
profiles.Discovery = append([]RuntimeDiscoveryProbe(nil), profiles.Discovery...)
for i := range profiles.Discovery {
@@ -1354,6 +1409,7 @@ func CopyGamePluginRuntimeProfiles(profiles GamePluginRuntimeProfiles) GamePlugi
profiles.InstallPlans[i].Steps = append([]RuntimeInstallStep(nil), profiles.InstallPlans[i].Steps...)
}
profiles.LogSources = append([]RuntimeLogSource(nil), profiles.LogSources...)
profiles.LogEvents = append([]RuntimeLogEvent(nil), profiles.LogEvents...)
profiles.TransportProfiles = append([]RuntimeTransportProfile(nil), profiles.TransportProfiles...)
for i := range profiles.TransportProfiles {
profiles.TransportProfiles[i].Capabilities = CopyStringSlice(profiles.TransportProfiles[i].Capabilities)
@@ -1465,10 +1521,12 @@ func CopyFileOperationDispatchResult(result FileOperationDispatchResult) FileOpe
func CopyRunEndpoint(endpoint RunEndpoint) RunEndpoint {
endpoint.Capabilities = CopyStringSlice(endpoint.Capabilities)
endpoint.Capacity.PressureCodes = CopyStringSlice(endpoint.Capacity.PressureCodes)
return endpoint
}
func CopyJob(job Job) Job {
job.ExecutionInput.Inputs = CopyStringMap(job.ExecutionInput.Inputs)
return job
}
+3
View File
@@ -192,3 +192,6 @@ Failed or cancelled lifecycle jobs project the server instance to `failed`. Acti
- `result`: `success`, `denied`, `failed`, or `queued`.
- `summary`: bounded redacted summary.
- `createdAt`: event time.
# Client Manager lifecycle aggregates
`ClientManagerInstallation` owns desired/active/previous artifact and version metadata, target and key/deployment generations, the current job, logical health/last-seen projection, retry/fencing flags, and uninstall history. Valid statuses are `requested`, `building`, `available`, `deploying`, `installed`, `registering`, `online`, `degraded`, `offline`, `updating`, `rolling_back`, `stopping`, `failed`, and `uninstalled`. `ClientManagerSession` is a separate short-lived component identity bound to installation, endpoint, artifact, key generation, and deployment generation; it is not a Run session or lease.
@@ -0,0 +1,19 @@
package domain
import "testing"
func TestCopyGamePluginRuntimeProfilesCopiesLogEvents(t *testing.T) {
profiles := GamePluginRuntimeProfiles{
LogEvents: []RuntimeLogEvent{{
Key: "chat-message", Title: "Chat message", SourceKey: "chat-log", EventType: "chat.message",
Permission: "server.logs.read", SchemaRef: "schemas/log-events/chat-message.schema.json", RetentionDays: 30, Severity: "info",
}},
}
copied := CopyGamePluginRuntimeProfiles(profiles)
copied.LogEvents[0].Title = "Mutated"
if profiles.LogEvents[0].Title != "Chat message" {
t.Fatalf("expected log event declarations to be copied, got %+v", profiles.LogEvents)
}
}