← ClaudeAtlas

ref-diagnosis-time-caslisted

Diagnosis-time compare-and-swap reference — how a batched drain captures each node's base blob at diagnosis time and pins it through park-node/clear-park --base, and why an exit-3 stale-diagnosis refusal must route back to re-diagnosis rather than to a park.
natb1/commons.systems · ★ 3 · AI & Automation · score 66
Install: claude install-skill natb1/commons.systems
# Diagnosis-Time Compare-and-Swap ## When this applies The rule is stated by shape, not by caller class: any caller that makes a decision from a read of a node and later writes that node must capture the blob at the deciding read and pin it through `--base`. It does not matter whether the gap is a human interview or a loop over subprocess calls — what matters is whether a decision was made from a read that a later write could silently invalidate. Canonical case: a batched office-hours drain diagnoses several parked nodes, then interviews the human author about each proposed disposition before executing any of them — minutes can pass. Without a pin, a fleet write landing during that interview window would be silently absorbed by park-node's / clear-park's own execution-time self-refresh of origin/main, including one that changes what the human should have decided. This is the widest instance of the shape, not the only one. Worked example of a narrower instance: `dispatch-tick`'s `frozen_session_sweep` and `terminal_without_disposition_sweep` (`.claude/skills/dispatch-propagate/scripts/lib-frozen-session-park.sh`) fetch `origin/main` once per sweep, then loop over N candidates, each candidate's already-parked guard read served from that single fetch, each candidate's `park-node` call bounded by a 120s timeout over a 60s landing-lock wait. Observed windows were not "a handful of subprocesses": 351s, 441s, and 809s. `park-node`'s own fresh `origin/main` re-read is not the gua