Releases: TheColliery/CoalHearth
Release list
v2.1.0 - transcript-GC recovery honesty + AG injectSteps contract
MINOR - two batches + close-out wording.
- Added - transcript-GC recovery honesty: the journal records the session's transcript path; the resume block flags a garbage-collected transcript (claude --resume is dead for this session) and, when CoalWash is installed, routes deeper recovery to its read-only estate-search/estate-restore (degrade-safe absent). CC transcript retention is version-dependent, not a guaranteed 30 days - field-confirmed.
- Fixed - Antigravity adapters re-derived to the current PreInvocation contract: workspacePaths[0]/conversationId first, emit = injectSteps/ephemeralMessage; the pilot-era additionalContext key retired (dead letter). Tier stays wired (hermetically tested; live AG delivery not yet validated).
- Fixed - descriptions: plugin/marketplace wording corrected budget-guardrail -> handover-journal (the guardrail was removed at v2.0.0).
Gate: 133/133 hermetic tests, VERIFY PASS. Full detail: CHANGELOG.
v2.0.2 - the v2.0 line: budget guardrail retired, journal hardened
The v2.0 major line — the dead budget guardrail retired, the journal hardened against five data-loss holes, CI green on every platform.
⚠️ BREAKING (v2.0.0)
- The advisory budget guardrail is removed —
BudgetTracker, thebudgets.maxTokens/budgets.warningTokenPercentageconfig group, the PostToolUse "prefer inline" nudge, and the never-writtenlimit_reachedstatus are all gone. It never fired under any realistic config: a fresh tracker per PostToolUse fed a single payload, so nothing accumulated across a session (tripping the 2M default needed one >6.8 MB tool payload). A gauge that only sees the hook's payload slice cannot be a budget safety device, and a config knob that does nothing is a false promise. A.coalhearth.jsonstill carrying abudgetsblock is now ignored at runtime and flagged as an unknown group. The recovery core (journal + warm-resume) is untouched.
Fixed — five journal data-loss holes (v2.0.0)
- Concurrency: N concurrent PostToolUse hooks no longer lose each other's journal — the load→merge→save is serialized under a per-workspace
O_EXCLlock (lossless to 30 simultaneous writers; a 30-way race dropped all 30 before). - A transient-corrupt journal is quarantined, not overwritten (bytes preserved to
session_handoff.corrupt.json). - A second session in the same workspace no longer discards the first's journal (keyed on the payload
session_id). - A wrong-typed journal field no longer eats the recovery block (array-coerce every field; mark-resumed moved after a successful prompt build).
- A file blocking
.claude/coalhearthnow signals on the sanctioned channel instead of leaving warm-resume silently off.
Changed (v2.0.0)
- All journal writes are atomic (per-pid temp + rename) — a crash mid-write can't leave a torn journal.
CI-green fix-forwards (v2.0.1 + v2.0.2)
- v2.0.1 — the read-only-journal regression test now simulates a true read-only fs on every platform (chmod the containing dir
0o555, not just the file0o444: POSIXrename(2)replaces a destination needing only directory write, so a file-only chmod let the atomic write succeed and the honesty note never fired — green on Windows, red on macOS/Linux). - v2.0.2 — the
sandbox()test helper realpath's its tmpdir dirs so ROOT2/H3 passes on macOS (os.tmpdir()is/var→/private/var, a symlink; a spawned hook'sprocess.cwd()is physical, sopath.relativeyielded absolute paths where the test asserts relative). Test-only; the production hot-path stays lexical, matching the other six sandbox helpers in the repo.
Zero-dependency, offline, no API keys. Full detail: CHANGELOG.
v2.0.1 - read-only-fs regression-test fix
PATCH - CI-green fix-forward for v2.0.0. Test-only; no shipped-code change.
Fixed
- The read-only-journal regression test now simulates a true read-only fs on every platform. v2.0.0 routed
markResumedthrough the atomic writer (per-pid temp + rename); the test chmod-ed only the journal FILE0o444, which on POSIXrename(2)replaces needing only DIRECTORY write - so the temp renamed over the read-only file, the write succeeded, the "may repeat" honesty note never fired. Green on Windows (MoveFileEx refuses a read-only destination) but red on macOS/Linux. The test now also chmods the containing DIR0o555and restores perms infinally- the honesty path is exercised on every platform, no skip. The v2.0.0 atomicmarkResumedis unchanged and correct.
(Release note corrected 2026-07-25: the earlier backfilled body described v2.0.2's sandbox-realpath topic - a cross-attribution caught by the room reviewer's R9 audit; this body now matches CHANGELOG [2.0.1] verbatim-in-substance.)
v2.0.0 - budget guardrail RETIRED (MAJOR) + journal hardening
BREAKING: the advisory budget guardrail is removed - BudgetTracker and the budgets config group are gone (the feature never fired in practice; a false promise removed rather than kept as decoration). The recovery core (journal + warm-resume) is untouched and remains the product.
Also hardens the handoff journal: 5 data-loss holes closed + atomic writes.
Back-dated Release for an already-published tag - full detail in CHANGELOG [2.0.0].
v1.4.0 - config-only hook platforms: Gemini CLI / Copilot CLI / Devin CLI / Kiro / Augment
MINOR - five wiring templates over the same two adapter entry points: Gemini CLI (SessionStart mode, nested hookSpecificOutput emit, advisory nudge suppressed - named divergence), Copilot CLI / Devin CLI / Kiro / Augment (FileCopy mode, plain CC stdout). Journal normalizer learns Gemini write_file/replace + camelCase payload probes. Excluded by design: Junie (SessionStart-only - no journal), Devin Desktop Cascade (no session-start-class event). Tier all five: wired (hermetic vs primary docs, not yet validated live). +7 tests -> 124.
Full detail: CHANGELOG.md 1.4.0
v1.3.2 - marker subdir symlink guard
PATCH - security hardening follow-up: closes the dir-symlink residual the wx-latch left open. mkdirSync(recursive) silently follows a symlink pre-planted at the marker subdir (bypassing the 0o700 mode) - an lstatSync no-follow check now rejects a symlink subdir and fail-closes. Completes the CodeQL js/insecure-temporary-file mitigation. One-flock across CoalMine/CoalHearth/CoalFace. Tests green; verify PASS.
v1.3.1 - AG resume marker hardened (CodeQL HIGH closed)
PATCH - the Antigravity resume shim's once-per-session marker is now an atomic create-exclusive latch (wx flag, private 0o700 tmp subdir): closes CodeQL js/insecure-temporary-file (HIGH), kills the TOCTOU race, refuses planted symlinks in one syscall. Named divergence kept: a non-EEXIST create failure still emits the recovery block with an honest "may repeat" note. Plus a hermetic-test sandbox-leak fix. Tests 19/19 - verify PASS.
v1.3.0 - Antigravity 2.0 port (no longer Claude-Code-only)
Warm-resume + the handoff journal now run on Antigravity 2.0. CoalHearth's Claude-Code-only, closed-by-design premise is retired - AG shipped a real IDE hooks.json engine.
- bin/ag-pre-invocation.js (warm-resume rides the first PreInvocation; AG never fires SessionStart) + bin/ag-post-tool-use.js (journal step) over a shared lib/journal-step.js core.
- Both honor payload.cwd so the journal lands at the workspace.
- Fixed: a cross-session journal-contamination path caught pre-release.
- Tier = wired: built + hermetically tested vs the verified AG spec; live delivery pending.
Gate: verify PASS + 115/115 tests.
v1.2.1 - CHANGELOG split + read-only-fs resume fix
Fixed
- CHANGELOG double-MINOR split: the v1.2.0 release had renamed the
[1.1.0]heading in place, stacking two MINOR change-sets under one heading - split back (both tags were always correct; doc-only). - Read-only-fs resume re-inject: the mark-resumed write ran after the recovery block printed with failures swallowed, so a read-only filesystem re-injected the identical block every boot with no explanation. The write now runs first; on failure the block carries an honest "may repeat" line. Phoenix-13 intact; +1 hermetic ro-fs regression (97).
Credit: the user's CoalBoard nasa audit (L6). Gate: 97/97.
v1.2.0 - Workflow run tracking
MINOR — the in-flight tracker learns the Workflow spawn shape.
Field-driven: a 52-agent Workflow run hit a session limit (8 workers dead) and the outer session had zero record the run existed — Workflow was not in the spawn-tool set, so the recovery block could not point the next session at the run's own journal.jsonl.
inFlightAgentsnow journals Workflow runs: the workflow'sname/scriptPathas the description,subagentType: "workflow", and the run'stranscriptDirprobed as the residue path — the recovery block after an interruption now names where the run's own journal lives.- Honest scope unchanged: CoalHearth records that the run existed and where its residue is; the per-agent truth stays in the run's own
journal.jsonl(a parent cannot force dead workers to journal).
Full detail: CHANGELOG.md.