carlos / platform Public

moves: T3 rejects a target-only layout variable off the flat layout; test diagnostics name keys, never values (Task 9 fix round 1)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 6b3fd93585d5a337cf4f86765f6890766acb1cf1 parent 82c58a8
3 files changed, +31 −11
  • internal/activator/backend_exec_test.go +8 −6
  • internal/moves/envreport.go +6 −0
  • internal/moves/envreport_test.go +17 −5
diff --git a/internal/activator/backend_exec_test.go b/internal/activator/backend_exec_test.go
index a3602a38c..7bba0776c 100644
--- a/internal/activator/backend_exec_test.go
+++ b/internal/activator/backend_exec_test.go
@@ -336,27 +336,29 @@ func TestLaunchEnvironmentComposesTheSpawnEnvironment(t *testing.T) {
t.Fatal(err)
}
if len(shadowed) != 1 || shadowed[0] != "MINE" || env["FROM_CONFIG"] != "c" {
- t.Fatalf("shadowed %v (env values withheld: the agent's own environment is in it)", shadowed)
+ t.Fatalf("shadowed names %v, want [MINE]; FROM_CONFIG: want set from the config file, got set=%v", shadowed, env["FROM_CONFIG"] != "")
}
if env["MINE"] != "1" || env["UNRELATED"] != "yes" || env["CARLOS_SECRETS_KEY"] != "" || env["CARLOS_ADMIN_TOKEN"] != "t" {
- t.Fatalf("launch env: MINE=%q SECRETS_KEY set=%v UNRELATED=%q", env["MINE"], env["CARLOS_SECRETS_KEY"] != "", env["UNRELATED"])
+ t.Fatalf("launch env: MINE matches the own file: %v; UNRELATED passed through: %v; CARLOS_SECRETS_KEY: want unset, got set=%v; CARLOS_ADMIN_TOKEN matches the own file: %v",
+ env["MINE"] == "1", env["UNRELATED"] == "yes", env["CARLOS_SECRETS_KEY"] != "", env["CARLOS_ADMIN_TOKEN"] == "t")
}
// The agent-owned layer, exactly as agentOwnedVars composes it: the
// tenant's region and purge values are overridden or removed.
if env["CARLOS_REGION"] != "ie" || env["CARLOS_CONTROL_SOCKET"] != rt.Socket+".control" {
- t.Fatalf("agent-owned vars: region %q control %q", env["CARLOS_REGION"], env["CARLOS_CONTROL_SOCKET"])
+ t.Fatalf("agent-owned vars: CARLOS_REGION is the backend's: %v; CARLOS_CONTROL_SOCKET is the route's control path: %v",
+ env["CARLOS_REGION"] == "ie", env["CARLOS_CONTROL_SOCKET"] == rt.Socket+".control")
}
if _, ok := env["CARLOS_PURGE"]; ok {
t.Fatal("CARLOS_PURGE survived on a box without a cache")
}
b.Cache = edge.NewCache(16, 1<<20)
if env, _, _ = b.LaunchEnvironment(rt); env["CARLOS_PURGE"] != "header" {
- t.Fatalf("CARLOS_PURGE on a box with a cache: %q", env["CARLOS_PURGE"])
+ t.Fatalf("CARLOS_PURGE on a box with a cache: want header, got set=%v", env["CARLOS_PURGE"] != "")
}
// A box with no region strips the tenant's value rather than keeping it.
b.Region = ""
if env, _, _ = b.LaunchEnvironment(rt); env["CARLOS_REGION"] != "" {
- t.Fatalf("CARLOS_REGION survived on a box with no region: %q", env["CARLOS_REGION"])
+ t.Fatal("CARLOS_REGION: want unset on a box with no region, got set")
}
}
@@ -367,6 +369,6 @@ func TestLaunchEnvironmentNoFiles(t *testing.T) {
rt := registry.Route{Host: "b.go.example.com", Socket: filepath.Join(b.DataDir, "b.sock")}
env, shadowed, err := b.LaunchEnvironment(rt)
if err != nil || len(shadowed) != 0 || env["CARLOS_REGION"] != "ie" {
- t.Fatalf("region %q shadowed %v err %v", env["CARLOS_REGION"], shadowed, err)
+ t.Fatalf("CARLOS_REGION is the backend's: %v; shadowed %v; err %v", env["CARLOS_REGION"] == "ie", shadowed, err)
}
}
diff --git a/internal/moves/envreport.go b/internal/moves/envreport.go
index 6837fb41c..24ea7a4e8 100644
--- a/internal/moves/envreport.go
+++ b/internal/moves/envreport.go
@@ -156,6 +156,12 @@ func CompareEnv(source, target EnvReport, flatLayout bool) []EnvDiff {
diffs = append(diffs, EnvDiff{name, "extra"})
case "advisory":
diffs = append(diffs, EnvDiff{name, "advisory-differs"})
+ case "layout":
+ // present iff the flat layout provides it: a target-only
+ // layout variable is wrong on a non-flat landing
+ if !flatLayout {
+ diffs = append(diffs, EnvDiff{name, "layout-present"})
+ }
}
}
// layout names absent from BOTH reports are still checked: a flat
diff --git a/internal/moves/envreport_test.go b/internal/moves/envreport_test.go
index bf6ffd09a..f5739830f 100644
--- a/internal/moves/envreport_test.go
+++ b/internal/moves/envreport_test.go
@@ -83,17 +83,29 @@ func TestCompareEnvNestedLayout(t *testing.T) {
key := []byte("0123456789abcdef0123456789abcdef")
src := ReportEnv(key, map[string]string{"A": "1", "CARLOS_REGION": "ie"})
tgt := ReportEnv(key, map[string]string{"A": "1", "CARLOS_REGION": "uk", "CARLOS_CONTROL_SOCKET": "/run/y"})
- diffs := CompareEnv(src, tgt, false)
- // a layout name only the target carries is not "extra": the not-flat
- // rule (layout-present) fires only for a name in the source report, so
- // the target-only case is pinned here as the current behaviour.
- if len(diffs) != 0 {
+ // T3's "present iff the flat layout provides it": a layout variable
+ // only the target carries is a diff on a non-flat landing, and
+ // nothing on a flat one.
+ if diffs := CompareEnv(src, tgt, false); len(diffs) != 1 || diffs[0].Name != "CARLOS_CONTROL_SOCKET" || diffs[0].Kind != "layout-present" {
t.Fatalf("target-only layout var, non-flat: %v", diffs)
}
+ if diffs := CompareEnv(src, tgt, true); len(diffs) != 0 {
+ t.Fatalf("target-only layout var, flat: %v", diffs)
+ }
src2 := ReportEnv(key, map[string]string{"A": "1", "CARLOS_REGION": "ie", "CARLOS_CONTROL_SOCKET": "/run/x"})
if diffs := CompareEnv(src2, tgt, false); len(diffs) != 1 || diffs[0].Kind != "layout-present" {
t.Fatalf("layout-present: %v", diffs)
}
+ // neither side carries it, non-flat: clean
+ none := ReportEnv(key, map[string]string{"A": "1", "CARLOS_REGION": "uk"})
+ if diffs := CompareEnv(src, none, false); len(diffs) != 0 {
+ t.Fatalf("no layout var anywhere, non-flat: %v", diffs)
+ }
+ // the advisory exception holds: a target-only CARLOS_PURGE is a note
+ purge := ReportEnv(key, map[string]string{"A": "1", "CARLOS_REGION": "uk", "CARLOS_PURGE": "header"})
+ if diffs := CompareEnv(src, purge, false); len(diffs) != 1 || !diffs[0].Note() {
+ t.Fatalf("target-only purge, non-flat: %v", diffs)
+ }
}
func TestReportEnvIsDeterministicAndDigestCoversNamesAndValues(t *testing.T) {