From 8ac45cf999385eb080d81d4f0e2084d7404aeb59 Mon Sep 17 00:00:00 2001 From: npc0-hue Date: Thu, 3 Sep 2026 01:10:49 +0800 Subject: [PATCH] Fix managed process helper command serialization --- AGENTS.md | 2 +- runtime/lifecycle.go | 2 +- runtime/lifecycle_test.go | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 6f86581..46389a4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -20,7 +20,7 @@ Protocol structs live in `protocol/`. Local runtime types live in `runtime/` or ## 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, 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. +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-owned component 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 diff --git a/runtime/lifecycle.go b/runtime/lifecycle.go index 2ca3194..4c6f740 100644 --- a/runtime/lifecycle.go +++ b/runtime/lifecycle.go @@ -926,7 +926,7 @@ type ProcessCommand struct { JobID string Capability string Action string - OutputLine func(string, string) + OutputLine func(string, string) `json:"-"` } type ProcessResult struct { diff --git a/runtime/lifecycle_test.go b/runtime/lifecycle_test.go index ebf3b5b..e766ec1 100644 --- a/runtime/lifecycle_test.go +++ b/runtime/lifecycle_test.go @@ -569,6 +569,22 @@ func TestOSProcessSupervisorRelaysRawCarriageReturn(t *testing.T) { } } +func TestProcessCommandJSONOmitsOutputCallback(t *testing.T) { + body, err := json.Marshal(ProcessCommand{ + WorkDir: "/workspace", + Args: []string{"cmd.exe", "/d", "/c", "call", "start.cmd"}, + OutputLine: func(stream string, line string) { + panic(stream + line) + }, + }) + if err != nil { + t.Fatalf("marshal process command with output callback: %v", err) + } + if strings.Contains(string(body), "OutputLine") || strings.Contains(string(body), "func") { + t.Fatalf("output callback leaked into helper JSON: %s", body) + } +} + type recordingLogSink struct { mu sync.Mutex lines []string