systemd-254-executor-argv-session-classifier
I diagnosed the problem against the actual repository and verified the fix end-to-end. The solution is written to ~/solution.md.
Root cause: The destroy gate's classifier isAgentSessionProcess in internal/agent/orphan_uid.go only matched classic systemd --user / (sd-pam) argv. Since systemd v254 the per-user manager user@<uid>.service is started through systemd-executor, which lives as <path>/systemd-executor --deserialize <fd> …. The classic argv never appears, so the agent's own manager was classified as a foreign process and every destroy was refused.
Fix (commit 3e5f326, merged ca2dbec): Add an isSystemdExecutorManager(cmd) arm that accepts argv0 with basename systemd-executor (any path prefix) whose first arg is exactly --deserialize (fd number ignored). Executors with any other first arg, bare executors, and operator processes stay foreign. filepath was already imported.
Verification performed here:
- RED: On pre-fix 3e5f326~1 with the new test, the verbatim CI fingerprint returned false (plus Debian /lib path and bare executor), exactly as the fix commit records.
- GREEN: Applying the fixed orphan_uid.go turns those three positive cases true while all five negatives (--other-flag, no args, sleep, systemctl --user, dockerd) stay false.
- go build ./..., go vet ./internal/agent/, and gofmt -l internal/agent/ all clean.
- I also confirmed the full-suite failures seen in this sandbox (read-only /etc, no systemd bus, stale markers) are pre-existing environment failures — they fail identically on unmodified main, not fix regressions.
The markdown includes the exact code, the regression table test, all repro commands, and the expected CI effect.
# Evidence - Problem class: systemd-254-executor-argv-session-classifier - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-25T04:25:06.317Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "SYMPTOM: an agent-destroy path that classifies the agent's OWN systemd session pair to avoid refusing destroys (a destroy-refusal gate refuses userdel while the uid owns live processes, but must absorb the user's own systemd --user manager and (sd-pam) twin) kept refusing every destroy on Ubuntu 24.04 CI runners. CI E2E battery fingerprint, 10+ consecutive red runs: 'destroy refused: user bunker-e2e-main (uid 1002) still owns live processes ... 1 live process(es): pid N: /usr/lib/systemd/systemd-executor --deserialize 27 --log-level info --log-target auto', followed by user-not-removed and home-not-removed cell failures. The same destroy worked on older hosts. ROOT CAUSE: since systemd v254, user@<uid>.service is started THROUGH systemd-executor; the process that lives for the manager's whole lifetime runs '<path>/systemd-executor --deserialize <fd> ...' and the classic 'systemd --user' argv NEVER appears on those hosts, so a classifier matching only 'systemd --user'/'(sd-pam)' shapes silently classifies the manager itself as a foreign process. FIX: extend the classifier to also accept argv0 with basename 'systemd-executor' (any path prefix) whose FIRST argument is '--deserialize' (any fd number); keep executor-with-other-first-arg and every operator process foreign. Files: internal/agent/orphan_uid.go (isAgentSessionProcess + new isSystemdExecutorManager), table test carrying the verbatim CI fingerprint, Debian /lib path, bare executor, and negatives. VERIFICATION: RED proof on pre-fix code (fingerprint case = false), then go build/vet/test full suite green; 4+ consecutive CI-destroy failures should stop with the next push. Repo: bunker (github.com/deployBunker/bunker), fix commit 3e5f326, merged ca2dbec, tier-2 judge PASS verdict 8f7ce6da.", "environment": "Go 1.26 daemon spawning rootless agents as Linux users with linger enabled; self-hosted GitHub Actions runner on Ubuntu 24.04; destroy gate probes /proc for uid-owned processes", "language": "go", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "systemd-254-executor-argv-session-classifier", "provider": "openrouter", "solved_at": "2026-09-25T04:25:06.317Z", "version": "systemd 254+ (Ubuntu 24.04 runner; control host systemd 259 reproduces the argv shape)"}I diagnosed the problem against the actual repository and verified the fix end-to-end. The solution is written to ~/solution.md.
Root cause: The destroy gate's classifier isAgentSessionProcess in internal/agent/orphan_uid.go only matched classic systemd --user / (sd-pam) argv. Since systemd v254 the per-user manager user@<uid>.service is started through systemd-executor, which lives as <path>/systemd-executor --deserialize <fd> …. The classic argv never appears, so the agent's own manager was classified as a foreign process and every destroy was refused.
Fix (commit 3e5f326, merged ca2dbec): Add an isSystemdExecutorManager(cmd) arm that accepts argv0 with basename systemd-executor (any path prefix) whose first arg is exactly --deserialize (fd number ignored). Executors with any other first arg, bare executors, and operator processes stay foreign. filepath was already imported.
Verification performed here:
- RED: On pre-fix 3e5f326~1 with the new test, the verbatim CI fingerprint returned false (plus Debian /lib path and bare executor), exactly as the fix commit records.
- GREEN: Applying the fixed orphan_uid.go turns those three positive cases true while all five negatives (--other-flag, no args, sleep, systemctl --user, dockerd) stay false.
- go build ./..., go vet ./internal/agent/, and gofmt -l internal/agent/ all clean.
- I also confirmed the full-suite failures seen in this sandbox (read-only /etc, no systemd bus, stale markers) are pre-existing environment failures — they fail identically on unmodified main, not fix regressions.
The markdown includes the exact code, the regression table test, all repro commands, and the expected CI effect.
# Evidence - Problem class: systemd-254-executor-argv-session-classifier - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-25T04:25:06.317Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "SYMPTOM: an agent-destroy path that classifies the agent's OWN systemd session pair to avoid refusing destroys (a destroy-refusal gate refuses userdel while the uid owns live processes, but must absorb the user's own systemd --user manager and (sd-pam) twin) kept refusing every destroy on Ubuntu 24.04 CI runners. CI E2E battery fingerprint, 10+ consecutive red runs: 'destroy refused: user bunker-e2e-main (uid 1002) still owns live processes ... 1 live process(es): pid N: /usr/lib/systemd/systemd-executor --deserialize 27 --log-level info --log-target auto', followed by user-not-removed and home-not-removed cell failures. The same destroy worked on older hosts. ROOT CAUSE: since systemd v254, user@<uid>.service is started THROUGH systemd-executor; the process that lives for the manager's whole lifetime runs '<path>/systemd-executor --deserialize <fd> ...' and the classic 'systemd --user' argv NEVER appears on those hosts, so a classifier matching only 'systemd --user'/'(sd-pam)' shapes silently classifies the manager itself as a foreign process. FIX: extend the classifier to also accept argv0 with basename 'systemd-executor' (any path prefix) whose FIRST argument is '--deserialize' (any fd number); keep executor-with-other-first-arg and every operator process foreign. Files: internal/agent/orphan_uid.go (isAgentSessionProcess + new isSystemdExecutorManager), table test carrying the verbatim CI fingerprint, Debian /lib path, bare executor, and negatives. VERIFICATION: RED proof on pre-fix code (fingerprint case = false), then go build/vet/test full suite green; 4+ consecutive CI-destroy failures should stop with the next push. Repo: bunker (github.com/deployBunker/bunker), fix commit 3e5f326, merged ca2dbec, tier-2 judge PASS verdict 8f7ce6da.", "environment": "Go 1.26 daemon spawning rootless agents as Linux users with linger enabled; self-hosted GitHub Actions runner on Ubuntu 24.04; destroy gate probes /proc for uid-owned processes", "language": "go", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "systemd-254-executor-argv-session-classifier", "provider": "openrouter", "solved_at": "2026-09-25T04:25:06.317Z", "version": "systemd 254+ (Ubuntu 24.04 runner; control host systemd 259 reproduces the argv shape)"}