fix(server): delegate cgroups to agent scopes#23913

open3
main
fix/issue-21730
opened2d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 1d ago

Problem

On Linux with systemd and cgroup v2, rootless kind fails inside T3 agent sessions with requires setting systemd property "Delegate=yes". Agent scopes do not delegate their cgroups.

Change

Pass Delegate=yes in the shared scope launch options and startup probes. Existing memory limits, stop timeouts, and OOM policy handling remain in place.

Scope and approval

Fixes #21730

Triaged bug via the automated issue flow. Fixes existing Linux scope behavior across agents, shared Codex processes, and app terminals.

Verification

  • Regression test committed red: 1 failed / 5 passed because scope launch arguments lacked delegation.
  • After merging main: vp test run src/process/agentScope.test.ts in apps/server: 6 passed.
  • Targeted lint passed; server tsc-rs --noEmit completed with exit code 0.
  • Real dev app browser terminal on Ubuntu, systemd 255, cgroup v2: before, kind fails its delegation check; after, the scope reports Delegate=yes and kind reaches node preparation.
  • Before/after runtime transcript, commands, revisions, and test output. Server-only change; visual matrix is empty.
  • Full cluster creation could not be checked: this VM lacks /lib/modules. Its user manager exposes cpu memory pids; no claim is made that the fix adds controllers unavailable from the host. Older systemd versions and packaged Electron were not run.

Models: Claude Opus 5.5 and GPT-6.1-Sol. Harnesses: Claude Agent SDK and Codex through T3 Code.

Checks

All checks passed

Added 3 commits

  • Merge remote-tracking branch 'origin/main' into fix/issue-2173074c4ffc
  • test(server): reproduce issue 21730, agent scopes are not delegated7e3b309
  • fix(server): agents can run rootless kind and Podman inside their scope9e4abdd
Synced from GitHub

Approvability

Verdict: Approved at 74c4ffc

Macroscope's review found this PR approvable — This is a small, self-contained Linux launcher fix that adds cgroup delegation to existing systemd agent scopes and tests agent, Codex, and detached-terminal paths. Existing timeout, memory, OOM, slice, and non-Linux behavior remain unchanged.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire5.0 KiB5.0 KiB0 B (0.0%)6.8 KiB✅
CodexThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
CodexLive turn WebSocket wire1.2 KiB1.2 KiB0 B (0.0%)2.0 KiB✅
CodexLive turn WebSocket decoded20.9 KiB20.9 KiB0 B (0.0%)29.3 KiB✅
CodexLive turn messages220 (0.0%)8✅
ClaudeTotal thread wire5.0 KiB5.0 KiB+24 B (+0.5%)6.8 KiB✅
ClaudeThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
ClaudeLive turn WebSocket wire1.2 KiB1.2 KiB+24 B (+2.0%)2.0 KiB✅
ClaudeLive turn WebSocket decoded21.2 KiB21.2 KiB+41 B (+0.2%)29.3 KiB✅
ClaudeLive turn messages12+1 (+100.0%)8✅

Baseline: 5127302 · PR result: 74c4ffc · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
📥 Commits

Reviewing files that changed from the base of the PR and between 51273020db3245f4ec29514a419d29b5dcb012dc and 74c4ffc4ca044c6bfb63cb203237a6aacb3b238c.

📒 Files selected for processing: 2
  • apps/server/src/process/agentScope.test.ts
  • apps/server/src/process/agentScope.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

📝 Walkthrough

Systemd scope options and capability probes now request Delegate=yes alongside the stop timeout. A test checks that agent, Codex, and restart-surviving terminal launches include the delegation property.

Changes: Systemd Scope Delegation

Layer / File(s)Summary
Add delegation to scope options and verify launches
apps/server/src/process/agentScope.ts, apps/server/src/process/agentScope.test.ts
The shared options, capability probes, and agent scope options include Delegate=yes alongside the stop timeout. A test checks agent, Codex, and restart-surviving terminal launches.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: only21mil, t3dotgg

Merge Risk: ⚪ Minimal · up to 74c4f

The delegation change has no established merge-blocking issue. Compatibility with older systemd versions remains unverified.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title clearly and concisely describes the main change: enabling cgroup delegation for server agent scopes.
Description checkPassedThe description includes all required sections. It explains the Linux systemd problem, the implementation, issue and scope context, focused test results, runtime verification, limitations, and the mod…
Linked Issues checkPassed[#21730] Requirement: agent systemd scopes must delegate cgroups so rootless nested containers (kind with Podman or Docker rootless) can manage their cgroups. At head, apps/server/src/process/agentSco…
Out of Scope Changes checkPassedThe change touches two files: apps/server/src/process/agentScope.ts and its test file. The agentScope.ts change adds Delegate=yes to the shared scope options. It keeps the stop timeout and OOM policy …
Full details: Description check

Explanation

The description includes all required sections. It explains the Linux systemd problem, the implementation, issue and scope context, focused test results, runtime verification, limitations, and the models and harnesses used.

Full details: Linked Issues check

Explanation

[#21730] Requirement: agent systemd scopes must delegate cgroups so rootless nested containers (kind with Podman or Docker rootless) can manage their cgroups. At head, apps/server/src/process/agentScope.ts defines SCOPE_OPTIONS = ["--property=TimeoutStopSec=10s", "--property=Delegate=yes"]. These options feed both startup capability probes (with and without --property=OOMPolicy=stop) and the scope launch options in wrap. The Codex app-server launch path uses the same scope wrap, and the test asserts Delegate=yes for the agent, Codex, and restart-surviving terminal launches (apps/server/src/process/agentScope.test.ts, 'delegates every agent scope so rootless containers can manage their cgroups'). Existing TimeoutStopSec and OOMPolicy handling is kept. The issue proposed an explicit controller list (Delegate=cpu cpuset io memory pids); the PR uses Delegate=yes, which meets the stated expected behavior. Limits of evidence: the PR diff for the test file was unavailable, so the test was verified by reading the file at head, not by diff. The full kind cluster creation was not verified; the PR reports a runtime check that reached node preparation, based on an external transcript that I did not read. The delegation requirement itself is met by code and test evidence at head.

Full details: Out of Scope Changes check

Explanation

The change touches two files: apps/server/src/process/agentScope.ts and its test file. The agentScope.ts change adds Delegate=yes to the shared scope options. It keeps the stop timeout and OOM policy behavior. The test file adds a delegation assertion. Both files directly implement the delegation requirement of #21730. The option applies to all scopes that use the shared launch path: agent processes, shared Codex app-server processes, and restart-surviving terminals. Per the test, terminal scopes use the same app-t3code-agents.slice as agent scopes, so delegation for terminals follows from the shared launch path. It is not an unrelated change. No unrelated refactoring or documentation changes were found in the inspected evidence. The test diff could not be read, so the check of the test file rests on the file content at head.

✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.