feat(acp): Supervisor.Spawn extraEnv parameter

- extraEnv overrides agent_kinds.encrypted_env same-name keys (spec §6.1 #11)
- Prevents admin from hard-coding ACW_MCP_TOKEN in agent_kinds
- SessionService passes nil for now; system token wiring lands in I4
- BuildSpawnEnv exported for testing the override priority
- Fix app.go NewSupervisor call to match updated signature (from I5)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-08 12:46:50 +08:00
parent 3a448cee5f
commit d44ffc851f
5 changed files with 70 additions and 9 deletions
+29
View File
@@ -2,6 +2,7 @@ package acp_test
import (
"context"
"encoding/json"
"testing"
"time"
@@ -227,3 +228,31 @@ func TestAgentKindService_Update_PatchSemantics(t *testing.T) {
last := rec.entries[len(rec.entries)-1]
assert.Equal(t, "acp.agent_kind.update", last.Action)
}
func TestSupervisor_BuildSpawnEnv_ExtraEnvOverrides(t *testing.T) {
t.Parallel()
enc := testEncryptor(t)
plain, err := json.Marshal(map[string]string{"ACW_MCP_TOKEN": "kind-value", "OTHER": "kept"})
require.NoError(t, err)
encrypted, err := enc.Encrypt(plain)
require.NoError(t, err)
kind := &acp.AgentKind{EncryptedEnv: encrypted}
sup := acp.NewSupervisor(nil, nil, nil, nil, nil, nil, enc, acp.SupervisorConfig{}, nil)
env, err := sup.BuildSpawnEnv(kind, map[string]string{
"ACW_MCP_TOKEN": "system-value",
"ACW_MCP_URL": "http://x",
})
require.NoError(t, err)
assert.Contains(t, env, "ACW_MCP_TOKEN=system-value")
var hasOld bool
for _, e := range env {
if e == "ACW_MCP_TOKEN=kind-value" {
hasOld = true
}
}
assert.False(t, hasOld, "kind value must be overridden")
assert.Contains(t, env, "OTHER=kept")
assert.Contains(t, env, "ACW_MCP_URL=http://x")
}