Keep supervised log entries verbatim

This commit is contained in:
npc0-hue
2026-09-02 12:22:41 +08:00
parent 386a295f20
commit 8de49f2dd3
5 changed files with 5 additions and 11 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ Protocol structs live in `protocol/`. Local runtime types live in `runtime/` or
## Safety Rules ## Safety Rules
Run must enforce scoped paths and never expose raw host paths, local secrets, or unrestricted command execution to platform_web or plugins. Do not apply game-specific redaction to plugin-declared game records or SQL query rows: return those bounded typed fields faithfully through Platform channels. Supervised stdout/stderr and plugin-declared file tails are opaque verbatim channels: do not inspect, parse, filter, redact, truncate by content, transform, or special-case their payloads. Run only spools and forwards these bytes; a plugin companion may parse its own declared stream and derive its own users or business records after receipt. This pass-through rule does not grant plugins or the browser a direct host-path, credential, key, or socket API outside that log channel. Run must enforce scoped paths and never expose raw host paths, local secrets, or unrestricted command execution to platform_web or plugins. Do not apply game-specific redaction to plugin-declared game records or SQL query rows: return those bounded typed fields faithfully through Platform channels. Supervised stdout/stderr and plugin-declared file tails are opaque verbatim channels: do not inspect, parse, filter, redact, truncate by content, normalize, correlate, transform, or special-case their payloads. Run only assigns transport metadata, spools, and forwards the exact body bytes. A plugin companion may consume its declared raw stream, parse it, and derive its own typed users or business records after receipt; Run neither performs nor repeats that plugin work. This pass-through rule does not grant plugins or the browser a direct host-path, credential, key, or socket API outside that log channel.
## Generic Executor Boundary ## Generic Executor Boundary
-1
View File
@@ -8,7 +8,6 @@ type LogEntry struct {
Level string `json:"level,omitempty"` Level string `json:"level,omitempty"`
Line string `json:"line"` Line string `json:"line"`
Fields map[string]string `json:"fields,omitempty"` Fields map[string]string `json:"fields,omitempty"`
Redacted bool `json:"redacted"`
} }
type LogBatchIngestRequest struct { type LogBatchIngestRequest struct {
-3
View File
@@ -63,9 +63,6 @@ func TestWorkerExecutesFencedProtectedProgramAndSpoolsDedicatedLogs(t *testing.T
t.Fatalf("program output used wrong log source: %+v", batch) t.Fatalf("program output used wrong log source: %+v", batch)
} }
for _, entry := range batch.Entries { for _, entry := range batch.Entries {
if entry.Redacted {
t.Fatalf("program log must remain verbatim, got %+v", entry)
}
logLines = append(logLines, entry.Line) logLines = append(logLines, entry.Line)
} }
} }
+2 -4
View File
@@ -1404,7 +1404,6 @@ func checksumForLogEntries(entries []protocol.LogEntry) (string, error) {
Level: entry.Level, Level: entry.Level,
Line: entry.Line, Line: entry.Line,
Fields: entry.Fields, Fields: entry.Fields,
Redacted: entry.Redacted,
} }
} }
encoded, err := json.Marshal(stable) encoded, err := json.Marshal(stable)
@@ -1421,7 +1420,6 @@ type logEntryChecksumBody struct {
Level string `json:"level,omitempty"` Level string `json:"level,omitempty"`
Line string `json:"line"` Line string `json:"line"`
Fields map[string]string `json:"fields,omitempty"` Fields map[string]string `json:"fields,omitempty"`
Redacted bool `json:"redacted"`
} }
func (worker *Worker) capacityReport() protocol.RunCapacityReport { func (worker *Worker) capacityReport() protocol.RunCapacityReport {
@@ -1524,7 +1522,7 @@ func (sink *LiveLogSink) append(assignment protocol.RunJobAssignment, stream str
FirstSeq: sequence, FirstSeq: sequence,
LastSeq: sequence, LastSeq: sequence,
Compression: "none", Compression: "none",
Entries: []protocol.LogEntry{{Seq: sequence, Timestamp: time.Now().UTC(), Level: "info", Line: line, Redacted: false}}, Entries: []protocol.LogEntry{{Seq: sequence, Timestamp: time.Now().UTC(), Level: "info", Line: line}},
} }
batch.Checksum, _ = checksumForLogEntries(batch.Entries) batch.Checksum, _ = checksumForLogEntries(batch.Entries)
select { select {
@@ -1576,7 +1574,7 @@ func (sink *SpoolLogSink) append(ctx context.Context, assignment protocol.RunJob
defer sink.mu.Unlock() defer sink.mu.Unlock()
streamKey := declaredProcessStreamKey(assignment, stream) streamKey := declaredProcessStreamKey(assignment, stream)
logStreamID := logStreamIDForAssignment(assignment, streamKey) logStreamID := logStreamIDForAssignment(assignment, streamKey)
entry := protocol.LogEntry{Timestamp: time.Now().UTC(), Level: "info", Line: line, Redacted: false} entry := protocol.LogEntry{Timestamp: time.Now().UTC(), Level: "info", Line: line}
source := "process" source := "process"
if strings.HasPrefix(stream, "management-program.") { if strings.HasPrefix(stream, "management-program.") {
source = "management-program" source = "management-program"
+2 -2
View File
@@ -392,7 +392,7 @@ func TestWorkerSpoolHooksUseRegisteredSession(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("pending logs: %v", err) t.Fatalf("pending logs: %v", err)
} }
if len(logs) != 1 || logs[0].RunEndpointID != "run-test" || logs[0].SessionToken != "session-token" || logs[0].StreamKey != "game.console.stdout" || logs[0].Entries[0].Line != "started password=hidden" || logs[0].Entries[0].Redacted { if len(logs) != 1 || logs[0].RunEndpointID != "run-test" || logs[0].SessionToken != "session-token" || logs[0].StreamKey != "game.console.stdout" || logs[0].Entries[0].Line != "started password=hidden" {
t.Fatalf("unexpected spooled logs: %+v", logs) t.Fatalf("unexpected spooled logs: %+v", logs)
} }
chunks, err := artifactQueue.Pending() chunks, err := artifactQueue.Pending()
@@ -623,7 +623,7 @@ func TestSpoolLogSinkKeepsSequencesIndependentAndDurable(t *testing.T) {
func TestSessionLogBatchClientOverridesSpooledIdentityAndChecksum(t *testing.T) { func TestSessionLogBatchClientOverridesSpooledIdentityAndChecksum(t *testing.T) {
recorder := &recordingDurableLogClient{} recorder := &recordingDurableLogClient{}
entry := protocol.LogEntry{Seq: 7, Timestamp: workerTestTime(), Level: "info", Line: "server ready", Redacted: false} entry := protocol.LogEntry{Seq: 7, Timestamp: workerTestTime(), Level: "info", Line: "server ready"}
batch := protocol.LogBatchIngestRequest{ batch := protocol.LogBatchIngestRequest{
RunEndpointID: "old-endpoint", RunEndpointID: "old-endpoint",
SessionToken: "old-token", SessionToken: "old-token",