Skip to content

Han config expansion fix - #184

Merged
mxriverlynn merged 8 commits into
v5.4.0-betafrom
han-config-expansion-fix
Aug 19, 2026
Merged

mxriverlynn merged 8 commits into
v5.4.0-betafrom
han-config-expansion-fix

Conversation

@mxriverlynn

@mxriverlynn mxriverlynn commented Aug 18, 2026 •

Copy link
Copy Markdown
Collaborator

fixing config.md file loading with a shared script via symlinks, as documented in anthropics plugin config pages

Claude Code 2.1.228 rejects any load-time context probe whose text
contains shell variable expansion, so the personal-config probe carried
by all 42 skills aborts the skill before its body loads.

Record the root cause, the evidence, and a fix that deletes the probe
and resolves the configuration directory during the run instead, where a
failure degrades silently rather than aborting.

Refs #178
Reproduce the abort locally and map what the skill loader actually
accepts by running eleven probe forms through fresh sessions across five
permission modes. Bare $HOME is permitted; brace syntax is refused even
for $HOME, every other variable name is refused, and printenv is refused
outright.

Adversarial validation killed the previous fix: no skill can read an
environment variable at run time, and the Read tool expands ~ to the home
directory, so the run would have applied the wrong profile's config.

Adopt the one form measured to load in every permission mode, and record
that the CLAUDE_CONFIG_DIR override is no longer reachable from a probe.

Refs #178
Section 1 told contributors to run ./install-hooks.sh, which rebuilds a
dist/claude-marketplace/ directory. Neither exists anywhere in the repo.
Point at the contributor guide's environment setup instead, and state
that the checked-in marketplace manifest needs no build step.

Add the claude plugin CLI equivalents of the /plugin click-through
steps, verified against a local and a GitHub-source marketplace.
Measured a third route the earlier passes never tested: a probe can run
a shell script when the skill grants that one command, and a script
reads CLAUDE_CONFIG_DIR in an ordinary shell. That keeps the override
the other two options gave up.

Add evidence E26 through E30 covering the grant as the deciding factor,
the CLAUDE_PLUGIN_ROOT substitution ordering, the mandatory guard, the
install behavior from a directory and a GitHub source, and the grant
scope test. Add V14 and V15 recording where a first reading was wrong
and what corrected it.

Rewrite the Changes section to implement option 3, per the operator's
decision.
The skill loader refuses almost every environment-variable reference in
a load-time probe, so the probe all 42 skills used to locate the
personal config directory aborted the skill before its body loaded.

A probe can still run a shell script when the skill grants that exact
command, and a script reads CLAUDE_CONFIG_DIR in an ordinary shell.
Add scripts/han-config-dir.sh at the repo root, symlink it into the 12
plugins carrying config-consuming skills, and point every probe at it
behind a one-command Bash grant. Installation copies the symlink target
as a regular file, so the script ships without any plugin depending on
another to reach it.

The braces around CLAUDE_PLUGIN_ROOT are required, and so is the
2>/dev/null || echo fallback: a missing or failing script otherwise
aborts the skill the same silent way the old probe did.

Verified across all 12 plugins in default mode, and end to end through
a GitHub-source marketplace install.
V8 read only the first line beginning allowed-tools: in each skill.
Eight skills spell that value as a YAML plain scalar across
continuation lines, so the first line is the bare key and the tools sit
underneath. Parsing the full value shows all eight already carry Bash
grants.

Five skills carry none, not 13, which makes the main cost of options 2
and 3 smaller than every earlier pass recorded. Add V16.
The CLAUDE_CONFIG_DIR promise survives the probe fix, so the contract
bullet describing it needs no change. Three things did need one.

Correct config-rule.md on tilde handling: the Read tool does expand a
leading ~, but always to the home directory and never to a configured
one, so a value meant to sit beside the personal config cannot rely on
it. Record the new degradation path, where a missing or failing
resolver script drops the lookup back to the home directory with no
note, and mirror that in the operator guide. Re-sync all 11 vendored
copies.

Replace the failing probe the authoring guidance still taught in two
places, add the measured results table, and document reaching an
environment variable through a script: grant the exact command, use the
braced CLAUDE_PLUGIN_ROOT, verify inside a plugin, and guard the call.

Add scripts/han-config-dir.bats, which keeps each skill's grant and
probe in step and each plugin's copy of the script reachable. Verified
it fails on a mismatched grant and on a missing script.
@mxriverlynn
mxriverlynn changed the base branch from main to v5.4.0-beta August 19, 2026 13:50
@mxriverlynn
mxriverlynn marked this pull request as ready for review August 19, 2026 13:51
@mxriverlynn
mxriverlynn merged commit 52abdf4 into v5.4.0-beta Aug 19, 2026
2 checks passed
@mxriverlynn
mxriverlynn deleted the han-config-expansion-fix branch August 19, 2026 13:51
mxriverlynn added a commit that referenced this pull request Aug 20, 2026
collecting updates for a v5.4.0 release

* #184 
* #186 
* #189
* #190
* #191
* #192 
* misc documentation updates
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant