Relationships
↔ sibling #2924#2927 Nested swamp structural command in a shell step times out on its parent's per-model lock (SWAMP_LOCK_HOLDER_PID is stripped)
Opened by hammz · 10/1/2026· Shipped 10/1/2026
Description
swamp-club#296 made a nested swamp skip per-model locks held by its parent: acquireModelLocks sets SWAMP_LOCK_HOLDER_PID, and waitForPerModelLocks (src/cli/repo_context.ts) skips lock files whose pid matches. Since #2435, the shell model builds the child env with createSafeMethodEnv (src/domain/remote/environment_snapshot.ts), which strips every SWAMP_* variable, including SWAMP_LOCK_HOLDER_PID. A nested structural command (one that takes the global datastore lock) run from a command/shell step now waits on its own parent's per-model lock until the lock timeout.
design/enablers/datastores.md (Parent-Process Lock Awareness) and the swamp skill's concurrency reference still describe the handoff as working.
Steps to reproduce
- swamp repo init, then create a command/shell model named shell-consumer.
- Run: swamp model method run shell-consumer execute --input run='swamp data gc --json'
Expected: the nested data gc completes.
Actual on 20261001.202145.0-sha.a3515474: the step prints 'Waiting for 1 per-model lock(s) to be released...', then fails with lock_timeout ('Lock per-model locks timed out after 60200ms'), exit 75.
Notes
swamp-uat's tests/cli/adversarial/subprocess_lock_test.ts is the regression test for #296, but its nested command (model search) takes no global lock, so it never exercised this path.
Found while triaging swamp-club#2924 (same root cause: createSafeMethodEnv strips the vars swamp passes to itself). It will be fixed by the same change.
Shipped
Click a lifecycle step above to view its details.
Sign in to post a ripple.