carlos / platform Public

isolated exec: plan 3 pre-flight rulings (SocketDir in LayoutInputs, prepare returns the env)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YZ1ZvWj7naf73GjTX8MBv5
Paul Campbell pushed by paul@keymail.dev d10585f8f70ab84e2e6d2e4266b3a89b17c2e72d parent a1949df
1 file changed, +22 −6
  • docs/superpowers/plans/2026-09-11-isolated-exec-3-activator.md +22 −6
diff --git a/docs/superpowers/plans/2026-09-11-isolated-exec-3-activator.md b/docs/superpowers/plans/2026-09-11-isolated-exec-3-activator.md
index c47bc4806..bc00d9855 100644
--- a/docs/superpowers/plans/2026-09-11-isolated-exec-3-activator.md
+++ b/docs/superpowers/plans/2026-09-11-isolated-exec-3-activator.md
@@ -604,13 +604,28 @@ const (
// tests without a box want.
type LayoutInputs struct {
DataDir string
- Journal func(host string) bool
- Peers func() ([]registry.Route, error)
+ // SocketDir is where flat sockets live and under which the nested
+ // instances directory sits. Empty means provision.SocketDir; a test
+ // points it at a temp dir so a route can classify as nested without
+ // writing to /run/carlos.
+ SocketDir string
+ Journal func(host string) bool
+ Peers func() ([]registry.Route, error)
// SameID reports whether two hosts share an instance identifier. Nil
// means provision.InstanceID equality; tests inject a collision.
SameID func(a, b string) bool
}
+// sockets returns the flat and nested socket paths for host under the
+// configured socket directory.
+func (in LayoutInputs) sockets(host string) (flat, nested string) {
+ dir := in.SocketDir
+ if dir == "" {
+ dir = provision.SocketDir
+ }
+ return filepath.Join(dir, host+".sock"), filepath.Join(dir, "instances", provision.InstanceID(host), "app.sock")
+}
+
// ActivatorManaged is the activator's own predicate for a route it owns
// (activator.go's per-host gate and edge.go's proxy decision): an instance
// route, hibernate-flagged, with a socket, not unit-backed, not
@@ -640,10 +655,11 @@ func Classify(rt registry.Route, in LayoutInputs) (Layout, string) {
}
}
}
+ flatSock, nestedSock := in.sockets(rt.Host)
switch {
- case rt.DBPath == provision.DefaultDBPath(in.DataDir, rt.Host) && rt.Socket == provision.DefaultSocket(rt.Host):
+ case rt.DBPath == provision.DefaultDBPath(in.DataDir, rt.Host) && rt.Socket == flatSock:
return LayoutFlat, ""
- case rt.DBPath == provision.NestedDBPath(in.DataDir, rt.Host) && rt.Socket == provision.NestedSocket(rt.Host):
+ case rt.DBPath == provision.NestedDBPath(in.DataDir, rt.Host) && rt.Socket == nestedSock:
return LayoutNested, ""
}
return LayoutForeign, fmt.Sprintf("db %q socket %q are neither the flat nor the nested defaults", rt.DBPath, rt.Socket)
@@ -1100,7 +1116,7 @@ git commit -m "activator: deduplicated child env, the Control seam, the per-role
type unitProc struct { host string; role instancectl.Role; unit, slice, invocation string; ctl *edge.ControlListener; logs *logListener; exited atomic.Bool; done chan struct{}; stopRequested atomic.Bool }
func (p *unitProc) Stop(ctx context.Context) error
func (p *unitProc) Exited() bool
- func (b *ExecBackend) prepare(rt registry.Route, role instancectl.Role, extraEnv map[string]string) (paths instancePaths, ctl *edge.ControlListener, logs *logListener, err error)
+ func (b *ExecBackend) prepare(rt registry.Route, role instancectl.Role) (paths instancePaths, ctl *edge.ControlListener, logs *logListener, fileEnv map[string]string, err error)
func (b *ExecBackend) writeLaunch(paths instancePaths, role instancectl.Role, host string, argv, env []string) error
func (b *ExecBackend) startUnit(ctx context.Context, rt registry.Route) (Proc, string, error)
func (b *ExecBackend) seedUnit(ctx context.Context, rt registry.Route) error
@@ -1217,7 +1233,7 @@ func nestedBackend(t *testing.T, ctl *fakeControl, unit *fakeUnit) (*ExecBackend
}
```
-`RunDirOverride` is a test-only field: `pathsFor` uses it as the socket dir when non-empty (so a test can point `/run/carlos` at a temp dir); `Classify` compares `rt.Socket` against `provision.NestedSocket(host)` and would call this row foreign, so `pathsFor` passes a `LayoutInputs` whose `SocketDir` overrides `provision.SocketDir`: add `SocketDir string` to `LayoutInputs` (empty = `provision.SocketDir`) and use it in `Classify`'s two socket comparisons and in `pathsFor`. Update Task 2's `Classify` accordingly (flat: `filepath.Join(sockDir, host+".sock")`; nested: `filepath.Join(sockDir, "instances", provision.InstanceID(host), "app.sock")`); the Task 2 tests keep passing with an empty `SocketDir`.
+`RunDirOverride` is a test-only field on `ExecBackend`: when non-empty, `layoutInputs()` sets `LayoutInputs.SocketDir` to it and `pathsFor` uses it in place of `provision.SocketDir` for `runDir` (nested: `<RunDirOverride>/instances/<iid>`), so a test can point `/run/carlos` at a temp dir and the row still classifies as nested through Task 2's `sockets` helper.
```go
func TestStartUnitWritesTheLaunchFileAndReturnsAUnitProc(t *testing.T) {