gds module update-pin --apply re-runs the module's required verification lanes inside its precondition observer. For the GDS module that takes over two minutes. The CLI's default deadline is 2m0s (core/cli/root.go:86, options{cwd: ".", timeout: 2 * time.Minute}). So the deadline fires mid-observation, Observe returns an error, and the engine reports:
GDS_STALE_PLAN — Repository "repo_…" changed before its first mutation step;
its action handler was not called.
Nothing changed. The command ran out of its own time.
Measured
| attempt |
flag |
result |
wall |
| 1 |
default |
blocked GDS_STALE_PLAN |
2m00.158s |
| 2 |
default |
blocked GDS_STALE_PLAN |
2m00.1s |
| 3 |
default |
blocked GDS_STALE_PLAN |
2m00.1s |
| 4 |
--timeout 20m |
succeeded, gitlink staged |
2m27s |
The plan's own worktree_fingerprint was byte-identical across consecutive plans, and gds status on the consumer was byte-identical before and after planning — so the state genuinely did not move. The operation journal records preconditions-verified and then operation-blocked, which is the second, per-step re-check timing out where the first one had room.
Two things worth separating
The deadline is too short for what the command does. A command that executes another repository's test lanes twice — once to plan, once to re-observe — cannot share a default sized for a read.
An expired deadline is not a changed repository. GDS_STALE_PLAN sends the reader to look for a concurrent writer that does not exist. context.DeadlineExceeded should surface as its own class.
Found while advancing the estate's own GDS pin after #56.
https://claude.ai/code/session_01BjpW1NtF1oik18aEMMGtMP
gds module update-pin --applyre-runs the module's required verification lanes inside its precondition observer. For the GDS module that takes over two minutes. The CLI's default deadline is2m0s(core/cli/root.go:86,options{cwd: ".", timeout: 2 * time.Minute}). So the deadline fires mid-observation,Observereturns an error, and the engine reports:Nothing changed. The command ran out of its own time.
Measured
blockedGDS_STALE_PLANblockedGDS_STALE_PLANblockedGDS_STALE_PLAN--timeout 20msucceeded, gitlink stagedThe plan's own
worktree_fingerprintwas byte-identical across consecutive plans, andgds statuson the consumer was byte-identical before and after planning — so the state genuinely did not move. The operation journal recordspreconditions-verifiedand thenoperation-blocked, which is the second, per-step re-check timing out where the first one had room.Two things worth separating
The deadline is too short for what the command does. A command that executes another repository's test lanes twice — once to plan, once to re-observe — cannot share a default sized for a read.
An expired deadline is not a changed repository.
GDS_STALE_PLANsends the reader to look for a concurrent writer that does not exist.context.DeadlineExceededshould surface as its own class.Found while advancing the estate's own GDS pin after #56.
https://claude.ai/code/session_01BjpW1NtF1oik18aEMMGtMP