v0.2.3
CW is now safe to run from many concurrent processes — state.json, the scheduler policy file, and the trust-audit log no longer lose updates or double-mint queue ids under a race, a Ctrl-C/SIGTERM mid-drive stops cleanly and resumes to completion, and a stuck agent times out and is SIGKILLed instead of hanging.
- Capability: A many-process safety release. Ten verified concurrency/robustness bugs are fixed:
state.json, the sched policy file, and the trust-audit log no longer lose updates under concurrent writers;withFileLock's stale-lock steal is race-free end to end (pid-liveness gate, single-winnerlink(2)acquire, and a serialized steal guard — each step forced by a real CI failure); two processes can no longer mint the same queue id and break throughmaxConcurrent; a chained trust-audit event with a droppedprevEventHashnow fails closed; a stuck agent is SIGKILLed and reported as a real timeout instead of "failed to spawn"; an escape-heavy batch job fails alone instead of ENOBUFSing every sibling; andcw <verb> --json | head -1exits quietly instead of an unhandled EPIPE crash. CLI polish:cw completion <bash|zsh|fish>, a documented--quietflag,--jsonin top-level help, grouped "More commands", acw doctoronramp pointer, a friendlier barecw quickstart, and structured workbench panels with a light theme. Security/CI: ed25519-signed release verdicts, CodeQL + gitleaks scanning, SHA-pinned workflow actions, and labeled stored text in MCP results. - Implementation: The lock work is concentrated in
shell/fs-atomic.ts— acquire by hard-linking a per-attempt temp file onto the lock path, steal only while holding a single-winner<lock>.stealguard with the verdict pinned to the judged inode+mtime. Every queue/policy mutator inscheduling-io.ts/run-registry-io.tsnow runs its whole read-modify-write insidewithFileLock, and queue ids are checked against the queue's own current entries under that same lock. The agent backend passeskillSignal: "SIGKILL"and classifies ETIMEDOUT honestly; the batch child caps the SERIALIZED NDJSON line (33MB), not just raw stdout; one process-level stdout/stderr 'error' listener incli/entry.tshandles EPIPE for every writer. - Tests: conformance 106/106, unit 160/160, full smoke suite green with 91.6% line coverage (floor 80%). The lock fixes were measured, not argued: an artificial-load stress rig (24 processes, 6-core load) reproduced each residual race red before its fix and ran 60/60 trials clean after.
- Risk: Low to moderate — the fixes are fail-closed guards and lock serialization on existing surfaces; no schema, exit code, or
--jsonshape changed, and the new CLI surfaces are additive. Zero new runtime dependencies.
Provenance & audit
- Reviewed commit:
35de8b2e98cc - Independent reviewer verdict (committed):
.cw-release/review-35de8b2e98cc783d0c0d1849f3567de1ba9c48f7.verdict - Full diff:
v0.2.2...v0.2.3 - npm (provenance-attested):
cool-workflow@0.2.3
Released through the gated flow: deterministic gate → independent release-reviewer (verdict above) → provenance-attested npm publish.