fix(server): delegate cgroups to agent scopes#23913
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.tsinapps/server: 6 passed. - Targeted lint passed; server
tsc-rs --noEmitcompleted 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=yesand 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 exposescpu 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
- SuccessfulCodeRabbitGitHub
Review completed
- SkippedBuild preview JS bundleGitHub
- SkippedEAS PreviewGitHub
- SkippedDeploy web previewGitHub
- SkippedEAS PreviewGitHub
- SkippedBuild preview JS bundleGitHub
- SkippedDeploy web previewGitHub
- SuccessfulCheckGitHub
- Skipped
- SkippedRelease SmokeGitHub
- SkippedTest WebGitHub
- SkippedRustGitHub
- SuccessfulBuild and TypecheckGitHub
- SuccessfulTestGitHub
- Skipped
- SuccessfulLabel PR sizeGitHub
- SuccessfulLabel PR 23913GitHub
- Skipped
- Successful
- Successful
- SkippedEAS PreviewGitHub
- SuccessfulTest Server 8GitHub
- SuccessfulNative fingerprint diffGitHub
- SuccessfulTest Server 7GitHub
- SuccessfulTest Server 4GitHub
- SuccessfulTest Server 2GitHub
- SuccessfulTest Server 5GitHub
- SuccessfulTest Server 1GitHub
- SuccessfulTest Server 3GitHub
- SuccessfulTest Server 6GitHub
- SuccessfulLintGitHub
- SuccessfulChangesGitHub
- SuccessfulCollect PR targetsGitHub
- SuccessfulPrepare PR size configGitHub
Added 3 commits
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.
Thread transfer impact
✅ Thread transfer remains within every enforced ceiling.
| Provider | Metric | Main baseline | This PR | Impact | PR ceiling | |
|---|---|---|---|---|---|---|
| Codex | Total thread wire | 5.0 KiB | 5.0 KiB | 0 B (0.0%) | 6.8 KiB | ✅ |
| Codex | Thread snapshot wire | 3.8 KiB | 3.8 KiB | 0 B (0.0%) | 4.9 KiB | ✅ |
| Codex | Live turn WebSocket wire | 1.2 KiB | 1.2 KiB | 0 B (0.0%) | 2.0 KiB | ✅ |
| Codex | Live turn WebSocket decoded | 20.9 KiB | 20.9 KiB | 0 B (0.0%) | 29.3 KiB | ✅ |
| Codex | Live turn messages | 2 | 2 | 0 (0.0%) | 8 | ✅ |
| Claude | Total thread wire | 5.0 KiB | 5.0 KiB | +24 B (+0.5%) | 6.8 KiB | ✅ |
| Claude | Thread snapshot wire | 3.8 KiB | 3.8 KiB | 0 B (0.0%) | 4.9 KiB | ✅ |
| Claude | Live turn WebSocket wire | 1.2 KiB | 1.2 KiB | +24 B (+2.0%) | 2.0 KiB | ✅ |
| Claude | Live turn WebSocket decoded | 21.2 KiB | 21.2 KiB | +41 B (+0.2%) | 29.3 KiB | ✅ |
| Claude | Live turn messages | 1 | 2 | +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.
No actionable comments were generated in the recent review. 🎉
ℹ️ Recent review info
⚙️ Run configuration
- Source mode: Auto
- Repository: pingdotgg/t3code
- Branch: fix/issue-21730
- File: .coderabbit.config.ts
- Commit: 74c4ffc
- Layers: Repository TS config
- Review profile: CHILL
- Plan: Team
- Run ID:
a42a1fc4-0ba0-48f2-a518-04c6c0c9f7b2
📥 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.tsapps/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=yesalongside 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.tsThe shared options, capability probes, and agent scope options include Delegate=yesalongside 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 name Status Explanation Title check Passed The title clearly and concisely describes the main change: enabling cgroup delegation for server agent scopes. Description check Passed 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 mod… Linked Issues check Passed [ #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 check Passed 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 … 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.