An agent identity can be admitted whose PTY session socket path exceeds the kernel's sun_path limit. Such a seat can never spawn, and the failure surfaces on every supervisor reconcile pass forever instead of once, at authoring time.
Reported by dev3.cos from dev3 evidence, 2026-09-03. Three identities of the form 2026-09-02-new-agent-sam.schickling-assistant-202.request.* yield a 108-byte socket path against the 104-byte limit. They can never spawn. Because they fail every pass, reconcile result is a dead signal on that host until the names or PTY_SESSION_DIR change: every pass before the unrelated stall in #431 ended result="fail" with errors=3, always the same three identities.
Why this is an authoring-time gap
st2 already knows this limit exists, but only checks it late and only on one path:
src/run.rs:414 documents it directly — an eval run uses a short /tmp/stev-<runid> specifically "that dodges the 104-byte unix-socket-path limit".
crates/agent-spec/tests/discovery.rs:2198 records the portable bound: 104 on Darwin, 108 on Linux.
src/codex_app_server.rs:3672 has a runtime check, "Codex app-server socket path is too long".
So the constraint is understood, but nothing rejects an identity that violates it when the declaration is admitted. Admission is the only place where the failure is cheap, attributable, and fixable by the author.
Ask
Reject at authoring time an identity whose resulting PTY session socket path would exceed the platform limit. The diagnostic should state the byte overage and the resolved path, so the author can shorten the identity rather than discover the failure as a spawn error later.
Compute the bound from the resolved session directory actually in use, not a hardcoded assumption, since PTY_SESSION_DIR changes it. Prefer the portable 104-byte bound so a declaration admitted on Linux does not fail on Darwin.
Relationship to #431
Separate mechanism, identical shape: a fail-closed check that belongs at authoring time and currently lands on the supervisor on every pass, forever. Owned by the same lane as #431 at dev3.cos's request. A pre-triage feedback row already exists for this; this issue is the st2-side defect, not a duplicate of that row.
Not verified here
The 108-byte figure is dev3.cos's measurement, not independently re-measured in this issue. Confirm the exact resolved path and overage before implementing, since the naming scheme and session directory determine it.
2026-09-04 — overage independently confirmed, and the runtime states it itself
The "not verified here" caveat above is discharged. The spawn failure names the overage directly, so it is not a reconstructed figure:
spawning pty '<id>' failed: Session name "<id>" produces a socket path of 108 bytes,
which exceeds the 104-byte kernel limit by 4. Shorten the name or set PTY_SESSION_DIR to a shorter path.
108 bytes, 4 over 104. Source: schickling/dotfiles#2388, whose body carries this text verbatim. Route implementer questions there.
Attribution correction: an earlier revision of this issue credited the error text to dev3.dotfiles-lead, which is wrong and they corrected it. Every agent in the fleet files as the shared schickling-assistant account, so GitHub authorship cannot identify which seat produced a finding, and anything filed inside another seat's working window reads as plausibly theirs. dev3.cos measured the original 108-byte figure; dev3.dotfiles-lead contributed the journal-reading rule that reconcile result="fail" with errors=3 was permanently dead as a health signal on this host.
Note the runtime already computes the exact overage and already knows the remedy. Admission has everything it needs to say the same thing at authoring time, before a seat exists.
The budget is not a constant
The usable identity length is 104 - len(PTY_SESSION_DIR prefix). A longer catalog state path shrinks the identity budget for every seat on the host. So the check must derive its bound from the resolved session directory in use, and a fixed maximum identity length would be wrong.
Blast radius observed
Ten such tasks flapped. Every reconcile pass reported result="fail", and each pass re-delivered ten park notices to seats across the host. The instances have since been retired, so schickling/dotfiles#2388 is green — but the guard does not exist, so the next long request identity reproduces it exactly.
Two secondary defects in scope for this issue
The park notice steers recipients into the one harmful action. It tells every recipient st2 unpark <id> to recover just this task. For an admission-class cause that advice cannot work: unpark relaunches into the identical spawn failure and restarts the storm. A park notice whose cause is structurally unrecoverable should say so instead of offering a recovery verb.
The storm's cost is not only attention. Each arriving notice preempts the receiving agent's in-flight tool call, which returns skipped rather than completing. Measured independently by three seats on dev3, at roughly eight, six and five preempted calls, none of which set out to measure it. So a notice storm does not merely distract agents on the host, it actively destroys their in-progress work.
Relationship to schickling/dotfiles#2388
#2388 is the dotfiles-side view of this defect and references this issue rather than duplicating it. The admission-time length guard is owned here, in the same lane as #431.
Posted on behalf of @schickling
| field |
value |
agent_identity |
dev3.compoundingtech-lead |
session |
dev3.17885923 |
agent_persona |
teamlead |
agent_supervisor |
dev3.cos |
agent_tool |
OMP |
agent_tool_version |
18.1.2 |
agent_runtime |
OMP 18.1.2 |
tooling_profile |
dotfiles@3fdc95b-dirty |
An agent identity can be admitted whose PTY session socket path exceeds the kernel's
sun_pathlimit. Such a seat can never spawn, and the failure surfaces on every supervisor reconcile pass forever instead of once, at authoring time.Reported by dev3.cos from dev3 evidence, 2026-09-03. Three identities of the form
2026-09-02-new-agent-sam.schickling-assistant-202.request.*yield a 108-byte socket path against the 104-byte limit. They can never spawn. Because they fail every pass, reconcileresultis a dead signal on that host until the names orPTY_SESSION_DIRchange: every pass before the unrelated stall in #431 endedresult="fail"witherrors=3, always the same three identities.Why this is an authoring-time gap
st2 already knows this limit exists, but only checks it late and only on one path:
src/run.rs:414documents it directly — an eval run uses a short/tmp/stev-<runid>specifically "that dodges the 104-byte unix-socket-path limit".crates/agent-spec/tests/discovery.rs:2198records the portable bound: 104 on Darwin, 108 on Linux.src/codex_app_server.rs:3672has a runtime check, "Codex app-server socket path is too long".So the constraint is understood, but nothing rejects an identity that violates it when the declaration is admitted. Admission is the only place where the failure is cheap, attributable, and fixable by the author.
Ask
Reject at authoring time an identity whose resulting PTY session socket path would exceed the platform limit. The diagnostic should state the byte overage and the resolved path, so the author can shorten the identity rather than discover the failure as a spawn error later.
Compute the bound from the resolved session directory actually in use, not a hardcoded assumption, since
PTY_SESSION_DIRchanges it. Prefer the portable 104-byte bound so a declaration admitted on Linux does not fail on Darwin.Relationship to #431
Separate mechanism, identical shape: a fail-closed check that belongs at authoring time and currently lands on the supervisor on every pass, forever. Owned by the same lane as #431 at dev3.cos's request. A pre-triage feedback row already exists for this; this issue is the st2-side defect, not a duplicate of that row.
Not verified here
The 108-byte figure is dev3.cos's measurement, not independently re-measured in this issue. Confirm the exact resolved path and overage before implementing, since the naming scheme and session directory determine it.
2026-09-04 — overage independently confirmed, and the runtime states it itself
The "not verified here" caveat above is discharged. The spawn failure names the overage directly, so it is not a reconstructed figure:
108 bytes, 4 over 104. Source:
schickling/dotfiles#2388, whose body carries this text verbatim. Route implementer questions there.Attribution correction: an earlier revision of this issue credited the error text to dev3.dotfiles-lead, which is wrong and they corrected it. Every agent in the fleet files as the shared
schickling-assistantaccount, so GitHub authorship cannot identify which seat produced a finding, and anything filed inside another seat's working window reads as plausibly theirs. dev3.cos measured the original 108-byte figure; dev3.dotfiles-lead contributed the journal-reading rule that reconcileresult="fail"witherrors=3was permanently dead as a health signal on this host.Note the runtime already computes the exact overage and already knows the remedy. Admission has everything it needs to say the same thing at authoring time, before a seat exists.
The budget is not a constant
The usable identity length is
104 - len(PTY_SESSION_DIR prefix). A longer catalog state path shrinks the identity budget for every seat on the host. So the check must derive its bound from the resolved session directory in use, and a fixed maximum identity length would be wrong.Blast radius observed
Ten such tasks flapped. Every reconcile pass reported
result="fail", and each pass re-delivered ten park notices to seats across the host. The instances have since been retired, soschickling/dotfiles#2388is green — but the guard does not exist, so the next long request identity reproduces it exactly.Two secondary defects in scope for this issue
The park notice steers recipients into the one harmful action. It tells every recipient
st2 unpark <id> to recover just this task. For an admission-class cause that advice cannot work: unpark relaunches into the identical spawn failure and restarts the storm. A park notice whose cause is structurally unrecoverable should say so instead of offering a recovery verb.The storm's cost is not only attention. Each arriving notice preempts the receiving agent's in-flight tool call, which returns skipped rather than completing. Measured independently by three seats on dev3, at roughly eight, six and five preempted calls, none of which set out to measure it. So a notice storm does not merely distract agents on the host, it actively destroys their in-progress work.
Relationship to schickling/dotfiles#2388
#2388is the dotfiles-side view of this defect and references this issue rather than duplicating it. The admission-time length guard is owned here, in the same lane as #431.Posted on behalf of @schickling
agent_identitysessionagent_personaagent_supervisoragent_toolagent_tool_versionagent_runtimetooling_profile