isolated exec: plan 3 carries the final-review recommendations for exit records
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YZ1ZvWj7naf73GjTX8MBv5
1 file changed,
+27
−3
docs/superpowers/plans/2026-09-11-isolated-exec-3-activator.md+27 −3
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 30fd9ca92..c47bc4806 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 |
| @@ -1711,7 +1711,9 @@ func (b *ExecBackend) observe(p *unitProc) { |
| // exitLine reads the advisory record for this invocation and words the |
| // event line as childProc does: a non-zero status is a warn line, a clean |
| -// exit is info, and no record is unknown. |
| +// exit is info, and no record is unknown. The record is tenant-writable |
| +// text (design §6.5, final review of plan 2), so every field that reaches |
| +// the line passes through recordToken first. |
| func exitLine(p *unitProc) string { |
| rec, ok := p.readRecord() |
| switch { |
| @@ -1720,12 +1722,28 @@ func exitLine(p *unitProc) string { |
| case rec.Result == "success" || (rec.Code == "exited" && rec.Status == "0"): |
| return "instance exited (exit 0)" |
| case rec.Code == "killed" || rec.Code == "dumped": |
| - return "instance exited: signal " + rec.Status |
| + return "instance exited: signal " + recordToken(rec.Status) |
| default: |
| - return fmt.Sprintf("instance exited: exit %s (%s)", rec.Status, rec.Result) |
| + return fmt.Sprintf("instance exited: exit %s (%s)", recordToken(rec.Status), recordToken(rec.Result)) |
| } |
| } |
| +// recordToken bounds a field of the exit record to what systemd itself |
| +// would write: at most 32 bytes of [A-Za-z0-9_-]. Anything else becomes |
| +// "?" so a tenant cannot put arbitrary text or control characters into |
| +// the platform's event stream. |
| +func recordToken(s string) string { |
| + if len(s) == 0 || len(s) > 32 { |
| + return "?" |
| + } |
| + for _, c := range s { |
| + if !(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c == '_' || c == '-') { |
| + return "?" |
| + } |
| + } |
| + return s |
| +} |
| + |
| func exitLevel(p *unitProc) string { |
| if rec, ok := p.readRecord(); ok && (rec.Result == "success" || (rec.Code == "exited" && rec.Status == "0")) { |
| return "info" |
| @@ -1810,6 +1828,12 @@ func (b *ExecBackend) startUnit(ctx context.Context, rt registry.Route) (Proc, s |
| if err != nil { |
| return fail(fmt.Errorf("%s: start unit: %w", rt.Host, err)) |
| } |
| + if inv == "" { |
| + // The server read the invocation after the start and found none: |
| + // the unit already exited (plan 2 final review). Nothing is |
| + // running, so there is nothing to stop; the wake failed. |
| + return fail(fmt.Errorf("%s: %s exited before it was observed", rt.Host, instancectl.UnitName(instancectl.RoleRun, rt.Host))) |
| + } |
| log.Printf("activator: %s: started %s memory.max=%d", rt.Host, instancectl.UnitName(instancectl.RoleRun, rt.Host), b.tier(rt).MemoryMax) |
| up := b.newUnitProc(rt, instancectl.RoleRun, p, inv, ctl, logs) |
| if b.Cache != nil { |