The Plan Canvas library wrote ~/.claude/plan-canvas while the SessionStart
and Stop hooks read CLAUDE_CONFIG_DIR/plan-canvas. Under a second profile
SessionStart missed open reviews and Stop let a turn end with feedback
still queued.
Expand a leading ~ in CLAUDE_CONFIG_DIR the way scripts/lib/agent-data-home.js
does, so a profile written as ~/.claude-work resolves to one directory rather
than two.
Add hook-level coverage that spawns each hook with a distinct
CLAUDE_CONFIG_DIR and no ECC_* override, plus a producer-to-consumer round
trip. Eight of the nine cases fail against the previous revision.
getDefaultClaudeAgentDataHome() is one of the two roots
resolveAllowedProjectConfigHome() accepts, so following CLAUDE_CONFIG_DIR
moves a security boundary and not just a default. The case asserts the
containment holds at the new location and nowhere else: a path inside the
relocated root is accepted, while the old ~/.claude, a traversal out of the
new root, and an arbitrary home path are all still refused.
It bites. Re-adding ~/.claude as a third allowed root, which is the obvious
way to get this wrong, turns the case red.
Claude Code points every profile-local path at CLAUDE_CONFIG_DIR when it is
set, but ECC hooks kept reading and writing ~/.claude. A session launched
under a second profile left its bash log, cost tracker, metrics, session data
and skill runs in the default profile, where the other one reads them back.
Two groups, as reported:
- getDefaultClaudeAgentDataHome() in scripts/lib/agent-data-home.js now
follows the variable, which covers every hook reaching ~/.claude through
resolveAgentDataHome(). ECC_AGENT_DATA_HOME still wins, so the documented
workaround keeps working.
- plan-canvas-pending, plan-canvas-sessions, mcp-health-check and
post-bash-command-log hard-coded os.homedir()/.claude and now resolve the
same way, matching scripts/hooks/ecc-statusline.js:68.
A blank value is ignored rather than resolved, since path.resolve(' ')
returns the process cwd and would scatter profile data through whatever
directory the session started in.
Fixes#3266
The OpenCode install target resolves its root from OPENCODE_CONFIG_DIR,
then XDG_CONFIG_HOME/opencode, before falling back to HOME. Inheriting
either variable still let a developer's real OpenCode install-state reach
the spawned status CLI and fail the same four tests. Point both into the
isolated home.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The status CLI reconciles install-state discovered under $HOME. The
state-store tests spawned it with the developer's real environment, so on
any machine with ECC installed the real ~/.claude install was counted as an
extra warning and four status/work-items assertions failed (3 attention
items instead of 2). CI stays green only because runners have no install.
Point HOME and USERPROFILE at an empty temp dir for spawned CLIs, cleaned up
on exit. Callers can still override via options.env.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore: retire the Everything Claude Code name, ECC only
Replace the expanded product name and the everything-claude-code slug
with ECC across READMEs, translated docs, harness folders, skills,
commands, scripts and examples. Repo URLs now point at affaan-m/ECC.
Rename repo-internal artifacts to ecc forms (ecc-conventions skill,
ecc-guardrails, ecc-research-playbook, ecc-team-config, ecc-instincts
with ecc-* ids) and update .claude/ecc-tools.json.
Legacy install ids, plugin dirs, package names and MCP prefixes stay
where existing installs resolve against them. The codex global-state
check and harness-audit repo detection accept the new name first and
the legacy one as a fallback. The Discord bot prefers ~/GitHub/ECC and
falls back to the nested legacy checkout path.
Refresh the skill-triggers registryDigest for the changed skill text.
* fix(ecc-tools): drop managed paths to the removed Claude repo skill
.claude/skills/<repo-skill>/SKILL.md was deleted in #2770 but stayed listed in
ecc-tools.json and the team config. Remove those entries and point the Claude
Code adapter at the existing .agents/skills/ecc-conventions/SKILL.md.
getDefaultClaudeAgentDataHome ignored CLAUDE_CONFIG_DIR and always returned ~/.claude, so sessions with a relocated Claude config dir wrote ECC data to the wrong place when ECC_AGENT_DATA_HOME was unset. Fixes#3266.
- Ask class-specific first-touch questions (instruction, test, prose,
config, code); code questions are unchanged.
- Credit a completed Glob/Grep/LS or shell search from the current human
turn that covered the target; Read and exclusion globs never count.
- Collapse same-class new-file creations in one directory within a turn.
- Add opt-in GATEGUARD_FACT_FORCE_MAX_DENIALS session cap (from #2755).
- Always gate sensitive targets, judged on lexical and real paths.
- Canonicalize checked-path keys.
Closes#2608
Co-authored-by: SulimanAbdulrazzaq <suliman9000a@gmail.com>
The malformed-drawing rollback test took its marker baseline before the
malformed poll but only checked it after resizeAgain(). Resize redraws
the accepted view on its own, so the test still passed with the
immediate rollback redraw removed and the canvas left blank until the
operator resized.
Record the log position alongside the baseline and assert the retained
markers are on the canvas immediately after the malformed poll, before
any resize. Scoped to the drawing case, since the events and lanes
cases fail before draw() starts and correctly do not redraw.
Mutating the implementation confirms the assertion bites: disabling the
rollback draw and removing it entirely both fail it with the message
"the rollback must redraw the retained markers immediately".
Test-only change. control-plane-view-ui 27/27, control-plane-view
13/13, control-plane-view-ui-a11y 18/18, ESLint clean on the test file.
Preserve the original contributor histories and apply the exact independently reviewed repair.
Source-Parent: 5785183108
Review-Manifest-SHA256: e223d98c24e357715527b786257901d2ef0bebadb75ac61e5c000fe60da10f9a
Preserve the original contributor histories and apply the exact independently reviewed repair.
Source-Parent: 81df6475b2
Review-Manifest-SHA256: 272ae1970f0b94fe40dbb974b509b7333682176259f5a1493bbae12d9a7e70cb