Keep Run and Platform logs opaque

This commit is contained in:
npc0-hue
2026-09-02 12:23:16 +08:00
parent aeda833294
commit 6e614d3fa3
15 changed files with 282 additions and 20 deletions
+2
View File
@@ -29,6 +29,8 @@ Platform may read plugin manifests, validate lifecycle/action declarations, pack
Platform may persist desired lifecycle state, last-known run reports, and UI projections. It must not treat those persisted fields as the authoritative source for the current machine/process state; current runtime status must come from the registered run endpoint's reports, heartbeats, supervised process facts, and job/log channels.
Log bodies from supervised stdout/stderr and plugin-declared file tails are opaque verbatim payloads. Platform may validate the transport envelope, sequence, checksum, and source binding, then persist, relay, and display the body unchanged. It must not inspect, parse, filter, redact, normalize, correlate, or derive player, login, user, or other plugin records from a log body. A plugin companion owns any game-specific parsing and its typed records arrive through the component boundary, never as a Platform log projection.
Do not add platform service code that hardcodes a game's executable path, Steam app ID, SteamCMD command line, process name, default launch flags, or update policy. For SCUM specifically, `SCUMServer.exe`, app `3792580`, `+app_update 3792580 validate`, `-port`, `-MaxPlayers`, and `-log` must come from the SCUM plugin action assets or plugin-declared startup fields.
If a lifecycle job requires checking whether game files exist, installing missing files, updating existing files, stopping before update, or building the final launch command, dispatch the plugin-owned action and keep platform limited to authorization, input validation, job creation, and result handling.
+1 -1
View File
@@ -497,7 +497,7 @@ func retimestampLogBatchRequest(t *testing.T, request *dto.LogBatchIngestRequest
domainEntries := make([]domain.LogEntry, 0, len(request.Entries))
for index := range request.Entries {
request.Entries[index].Timestamp = first.Add(time.Duration(index) * time.Millisecond).UTC()
domainEntries = append(domainEntries, domain.LogEntry{Seq: request.Entries[index].Seq, Timestamp: request.Entries[index].Timestamp, Level: request.Entries[index].Level, Line: request.Entries[index].Line, Fields: request.Entries[index].Fields, Redacted: request.Entries[index].Redacted})
domainEntries = append(domainEntries, domain.LogEntry{Seq: request.Entries[index].Seq, Timestamp: request.Entries[index].Timestamp, Level: request.Entries[index].Level, Line: request.Entries[index].Line, Fields: request.Entries[index].Fields})
}
checksum, err := validator.LogEntriesChecksum(domainEntries)
if err != nil {
-1
View File
@@ -8,7 +8,6 @@ type LogEntry struct {
Level string
Line string
Fields map[string]string
Redacted bool
}
type LogBatchIngest struct {
-3
View File
@@ -12,7 +12,6 @@ type LogEntryBody struct {
Level string `json:"level,omitempty"`
Line string `json:"line"`
Fields map[string]string `json:"fields,omitempty"`
Redacted bool `json:"redacted"`
}
type LogBatchIngestRequest struct {
@@ -178,7 +177,6 @@ func logEntriesToDomain(entries []LogEntryBody) []domain.LogEntry {
Level: entry.Level,
Line: entry.Line,
Fields: copyStringMap(entry.Fields),
Redacted: entry.Redacted,
}
}
return out
@@ -191,7 +189,6 @@ func logEntryFromDomain(entry domain.LogEntry) LogEntryBody {
Level: entry.Level,
Line: entry.Line,
Fields: copyStringMap(entry.Fields),
Redacted: entry.Redacted,
}
}
-2
View File
@@ -109,7 +109,6 @@ func LogEntriesChecksum(entries []domain.LogEntry) (string, error) {
Level: entry.Level,
Line: entry.Line,
Fields: entry.Fields,
Redacted: entry.Redacted,
}
}
encoded, err := json.Marshal(stable)
@@ -138,5 +137,4 @@ type logEntryChecksumBody struct {
Level string `json:"level,omitempty"`
Line string `json:"line"`
Fields map[string]string `json:"fields,omitempty"`
Redacted bool `json:"redacted"`
}