You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A project config written where the walk does not read it is now REPORTED, not silently ignored (UMB-133). The session-start
conductor checks a fixed, closed list of plausible wrong homes -- <project>/.agents/.coalmine.json, <project>/.gemini/.coalmine.json, <project>/coal/coalmine.json (agent dir dropped) and <project>/.claude/coalmine.json (coal/ dropped) -- and, if one exists, adds one context line IGNORED: <path> is not a config path; canonical = .claude/coal/coalmine.json for the agent to relay (settings in
that file have NO effect). It rides the channel each mode already has (Claude Code session context, Antigravity injectSteps, Gemini additionalContext) -- no new channel, nothing on stderr (Phoenix #13). The probe is existsSync on those fixed paths: no directory walk, and the text around each path is constant, so a cloned repo
cannot steer what the line says. HONEST BOUND: a config anywhere outside that list is not reported -- this is
a report of the likely typos, not a search of the project.
Cost, stated: a project still on a legacy path (see Deprecated) now carries one extra context line per session
start until it migrates (roughly 40 tokens).
Deprecated
Both legacy per-project config paths -- <project>/.claude/.coalmine.json and <project>/.coalmine.json (UMB-133).
Marker + replacement: both are marked DEPRECATED in the README's Configure section, which names the canonical path <project>/.claude/coal/coalmine.json verbatim as the replacement. A canonical file always wins over both.
Window: deprecated at this MINOR, removable no earlier than the next MAJOR -- this series' own SemVer boundary
(scripts-quality.md §3), not a calendar count. Until then both keep being read, exactly as before.
Owner: CoalMine. node scripts/configure.mjs moves either legacy file to the canonical path on its next write
(nothing is moved on a mere read).
Channel: this entry and the README note. No hook prints a deprecation warning -- Phoenix #13 keeps hooks
silent on stdout/stderr, so nothing appears in the terminal. The one runtime signal is the conductor's single
migration-notice context line described under Added, sent only when the config actually read is a legacy one.
Fixed
A project config at <project>/.claude/.coalmine.json was silently ignored (UMB-133). It was never a candidate in the
per-project read order -- only the root dotfile was honoured as legacy -- so a config written where a user reasonably
expects it had no effect and nothing said so. The order is now canonical (own agent dir, then .agents, then .gemini),
then <project>/.claude/.coalmine.json, then <project>/.coalmine.json; first found wins, and the merge, the safer-value
clamp and the global layer are untouched. configure.mjs and install.mjs honour both shapes too (a writer blind to the
nested one would have written a fresh canonical file that shadowed it and silently dropped every setting in it).
A guard the change needed: when the project root IS the home directory, <root>/.claude/.coalmine.json is the
GLOBAL config. It is compared by identity (both sides through realpathSync.native) and never treated as a project
config, so the walk does not anchor at ~ and configure.mjs does not migrate -- move and delete -- the file the
hooks read as the global layer.
The cascade wording on eight agent-instruction surfaces named only ONE legacy shape -- the shared language header
rendered into all nine skills, rot-canary's fix-mode rail, /coalmine:stats, /coalmine:update and the four platform-configs/*.template files -- so an agent following it would have skipped a config the hook reads. All eight now
name both shapes, in order.
PowerShell fallback: not ported, and the gap is named (alt/powershell/README.md): the twins still read only <gitroot>/.coalmine.json, so the second legacy shape is one more config they do not see.
On the Antigravity and Gemini adapters the conductor read the project config from the hook process's own working
directory, not from the workspace it was reporting on (UMB-133). The workspace is named by the hook's stdin payload
(Antigravity: workspacePaths[0], falling back to the payload's cwd; Gemini: the payload's cwd). The conductor now
reads that workspace's project config, and the config gates follow it -- enableConductor, disabledCanaries, updateMode -- not only the new migration / IGNORED lines. Before, the gates and the config both came from wherever
the hook process happened to start, while the lines beside them were computed for the workspace, so a workspace's
own config had no effect when the two differed. User-visible: on those two adapters, a workspace whose config sets enableConductor: false, a disabledCanaries list or an updateMode now takes effect where it silently did not;
and a config sitting only in the hook process's start directory no longer governs a different workspace.
Unchanged: Claude Code and the file-copy platforms (they read from the process directory as before), a payload that
names no workspace (falls back to the process directory), and rot-canary's own hooks (they still read from the
process directory).
The safer-value clamp is unaffected: it runs inside the config merge for whatever directory is read, so a
workspace config can quieten updateMode but never escalate it past the global layer.
A Coal uninstall could delete a repo's own TRACKED hook files (CWK-096).* uninstallGitHooks()
resolves core.hooksPath (correct since d1c917f) but then unlinked whatever it found there with
no tracked-ness check -- in any repo whose core.hooksPath points at a versioned directory (this
room's own .githooks/ included), that deleted the repo maintainer's tracked hooks. Tracked-ness is
now asked of git (git ls-files --error-unmatch), never inferred: a confirmed tracked or an unknown (could-not-tell) answer REFUSES loudly and exits non-zero, naming the file and why; only a
confirmed untracked answer deletes. The question is asked only when the resolved hooks dir sits
INSIDE the worktree -- the ordinary <gitDir>/hooks case is untracked by construction and is
unaffected. Distributed via the Universal Installer (scripts/install.mjs), a surface outside plugin/ (Option B) -- same shipped-surface-outside-the-dist precedent as d1c917f.