# Files changed · PR \#23913 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/pull/23913/diffs)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

[fix\(server\): delegate cgroups to agent scopes](https://git.cafe/pingdotgg/t3code/pull/23913.md)

Version: 5

Head commit: 74c4ffc4ca044c6bfb63cb203237a6aacb3b238c

Base commit: 51273020db3245f4ec29514a419d29b5dcb012dc

Comparison base: 96bae5465bc5dfaedc890998a7a71672fb470ae2

Showing up to 20 entries from this revision. If the pull request changes, reopen the first page before continuing.

## apps/server/src/process/agentScope.test.ts

Status: modified; +18; −0

```diff
@@ -174,6 +174,24 @@
     ),
   );
 
+  it.effect("delegates every agent scope so rootless containers can manage their cgroups", () =>
+    withFakeSystemd(({ scope }) =>
+      Effect.gen(function* () {
+        const agent = yield* scope.wrap({ command: "agent", args: [], name: "t", threadId: "a" });
+        const codex = yield* launchCodex(scope, "a");
+        const terminal = yield* scope.wrap({
+          command: "agent",
+          args: [],
+          name: "terminal",
+          survivesRestart: true,
+        });
+        for (const launch of [agent, codex, terminal]) {
+          expect(launch.args).toContain("--property=Delegate=yes");
+        }
+      }),
+    ),
+  );
+
   it.effect("stops agents a killed server left before the first launch", () =>
     withFakeSystemd(({ scope, units, calls, stateDir }) =>
       Effect.gen(function* () {
```

## apps/server/src/process/agentScope.ts

Status: modified; +7; −6

```diff
@@ -82,9 +82,10 @@
   return match === null ? undefined : Number(match[1]);
 }
 
+// A stop sends SIGTERM, then SIGKILL after 10 s. systemd's 90 s default would
+// outlast the wait for a previous server's agents below. Delegation lets
+// rootless containers (Podman, kind) inside an agent manage their own cgroups.
+const SCOPE_OPTIONS = ["--property=TimeoutStopSec=10s", "--property=Delegate=yes"];
-// A stop sends SIGTERM, then SIGKILL after this long. systemd's 90 s default
-// would outlast the wait for a previous server's agents below.
-const STOP_TIMEOUT_OPTION = "--property=TimeoutStopSec=10s";
 const STOPPING_POLL_INTERVAL = "100 millis";
 const STOPPING_POLL_ATTEMPTS = 20;
 const CLEAR_FAILED_INTERVAL = "1 second";
@@ -168,8 +169,8 @@
           "true",
         ]).pipe(Effect.map((result) => result._tag === "Some" && result.value.code === 0));
       // Scopes take OOMPolicy from systemd 253; older managers still get scopes.
-      const supportsOomPolicy = yield* probe([STOP_TIMEOUT_OPTION, "--property=OOMPolicy=stop"]);
+      const supportsOomPolicy = yield* probe([...SCOPE_OPTIONS, "--property=OOMPolicy=stop"]);
-      if (!supportsOomPolicy && !(yield* probe([STOP_TIMEOUT_OPTION]))) {
+      if (!supportsOomPolicy && !(yield* probe(SCOPE_OPTIONS))) {
         yield* Effect.logInfo("Agent scopes are off: no systemd user manager");
         return undefined;
       }
@@ -334,7 +335,7 @@
         // Without an owning thread nothing reads the result, so let systemd
         // unload the unit even when it fails.
         options: [
+          ...SCOPE_OPTIONS,
-          STOP_TIMEOUT_OPTION,
           ...(scope.supportsOomPolicy
             ? [`--property=OOMPolicy=${continuing ? "continue" : "stop"}`]
             : []),
```
