Problem
Per the empirical verdict on #245, the baked /opt/claude/.claude/ tree in the runtime overlay images (claude-runtime-{review,fix,explain}) is not reachable from the Claude CLI at job runtime. GitHub Actions sets HOME=/github/home at container start, and the CLI's standard discovery chain looks at $HOME/.claude/ rather than /opt/claude/.claude/.
The pr-review composite action already contains a workaround that copies the persona CLAUDE.md from the bake into $HOME/.claude/CLAUDE.md — but the workaround stops there. Agents, skills, plugins, and hooks remain orphaned.
There is also a second structural barrier (originally documented in #245's body): the ALLOWED_TOOLS allowlist passed to claude-code-action@v1 for review runs is currently extremely narrow — Glob, Grep, LS, Read, mcp__github_comment__update_claude_comment, Bash(git add:*), … — and does not include Task or Skill. Even if reachability is fixed, the LLM cannot dispatch baked sub-agents or invoke baked skills in a review run until the allowlist is widened to match the agent set the overlay carries. Reachability and invocability must land together to deliver value; this issue covers both.
Concrete consequence today:
Acceptance criteria
Design options to evaluate
These should be weighed in the implementation plan, not pre-committed here.
Reachability options
| Option |
Sketch |
Pros |
Cons |
| A. Extend the persona-copy step to mirror the full tree |
Replace cp .../CLAUDE.md $HOME/.claude/CLAUDE.md with a recursive copy or rsync of /opt/claude/.claude/ → $HOME/.claude/. |
Local to the composite action; no entrypoint change; matches the existing pattern. |
Cost on every job start (size: ~600 KB review + 135 KB shared); collisions with consumer-repo .claude/ need a merge strategy decision. |
B. Symlink $HOME/.claude → /opt/claude/.claude in entrypoint |
Container entrypoint creates the symlink before the action runs. |
Zero copy cost; single source of truth. |
Read-only behavior — any CLI write into $HOME/.claude/ would either fail or write into the image's writable layer; needs verification of CLI's expectations. May break consumer-repo overrides. |
C. Honor a CLAUDE_HOME env var |
If the CLI supports a discovery override env var, set CLAUDE_HOME=/opt/claude/.claude in the overlay's ENV. |
Cleanest; no filesystem manipulation; consumer-repo .claude/ stays addressable separately. |
Depends on CLI honoring such a var — needs verification (anthropics/claude-code source / docs). If unsupported, ruled out. |
| D. Hybrid: CLAUDE_HOME if supported, else extended copy |
Probe (C) first; fall back to (A). |
Resilient to CLI version drift. |
Larger blast radius; two code paths to maintain. |
Verifying which of A/B/C is viable is part of the remediation plan, not a deliverable of this issue's framing.
ALLOWED_TOOLS options
The allowlist update is mostly mechanical, but the design question is whether the allowlist is per-overlay (declared in the overlay's persona / metadata) or per-composite-action (declared in each action.yml that calls claude-code-action@v1). The latter is where it lives today; moving it to the overlay would centralize "what this verb is allowed to do" alongside the agent set, but requires the composite action to read the overlay's allowlist at invocation time. Implementation plan should pick.
Out of scope
Related
🤖 Generated by Claude Code on behalf of @cbeaulieu-gt
Problem
Per the empirical verdict on #245, the baked
/opt/claude/.claude/tree in the runtime overlay images (claude-runtime-{review,fix,explain}) is not reachable from the Claude CLI at job runtime. GitHub Actions setsHOME=/github/homeat container start, and the CLI's standard discovery chain looks at$HOME/.claude/rather than/opt/claude/.claude/.The
pr-reviewcomposite action already contains a workaround that copies the personaCLAUDE.mdfrom the bake into$HOME/.claude/CLAUDE.md— but the workaround stops there. Agents, skills, plugins, and hooks remain orphaned.There is also a second structural barrier (originally documented in #245's body): the
ALLOWED_TOOLSallowlist passed toclaude-code-action@v1for review runs is currently extremely narrow —Glob, Grep, LS, Read, mcp__github_comment__update_claude_comment, Bash(git add:*), …— and does not includeTaskorSkill. Even if reachability is fixed, the LLM cannot dispatch baked sub-agents or invoke baked skills in a review run until the allowlist is widened to match the agent set the overlay carries. Reachability and invocability must land together to deliver value; this issue covers both.Concrete consequence today:
Acceptance criteria
$HOME/.claude/resolves to a tree where the full baked agent/skill/plugin/hook set is enumerable by the CLI — not justCLAUDE.md.claude-runtime-reviewcan resolveinquisitor(or another review-only agent) and a job running onclaude-runtime-fixcannot, mirroring theexpected.yamlinventory contracts.ALLOWED_TOOLSaligned with overlay agent set. Theclaude-code-action@v1invocation in each composite action (pr-review/,apply-fix/,lint-failure/,tag-claude/,claude-command-router/consumers) is updated to includeTaskandSkillso the LLM can dispatch baked agents and invoke baked skills. Per-verb scoping is preserved: the review allowlist remains write-free (noEdit, noWrite, no generalBash(*)); fix-class allowlists permit write tools per their existing scope. The exact allowlist for each overlay must be documented in the runtime spec so future edits don't silently re-narrow it.runtime/scripts/smoke-test.sh) gains a reachability probe that runs the CLI under GHA-equivalent env (HOME=/github/home, GHA UID) and asserts at least one baked agent is enumerable. This codifies the gap so it cannot drift back.CLAUDE.mdmust continue to load.runtime/README and the runtime spec (§3.4 layer 2) so future overlay edits don't reintroduce the orphan or re-narrow the allowlist.Design options to evaluate
These should be weighed in the implementation plan, not pre-committed here.
Reachability options
cp .../CLAUDE.md $HOME/.claude/CLAUDE.mdwith a recursive copy or rsync of/opt/claude/.claude/→$HOME/.claude/..claude/need a merge strategy decision.$HOME/.claude → /opt/claude/.claudein entrypoint$HOME/.claude/would either fail or write into the image's writable layer; needs verification of CLI's expectations. May break consumer-repo overrides.CLAUDE_HOMEenv varCLAUDE_HOME=/opt/claude/.claudein the overlay'sENV..claude/stays addressable separately.anthropics/claude-codesource / docs). If unsupported, ruled out.Verifying which of A/B/C is viable is part of the remediation plan, not a deliverable of this issue's framing.
ALLOWED_TOOLS options
The allowlist update is mostly mechanical, but the design question is whether the allowlist is per-overlay (declared in the overlay's persona / metadata) or per-composite-action (declared in each
action.ymlthat callsclaude-code-action@v1). The latter is where it lives today; moving it to the overlay would centralize "what this verb is allowed to do" alongside the agent set, but requires the composite action to read the overlay's allowlist at invocation time. Implementation plan should pick.Out of scope
expected.yamlinventory contracts — the bake side is fine; this issue is purely about reachability + invocability.Related
🤖 Generated by Claude Code on behalf of @cbeaulieu-gt