feat(fleet): route domain plugins to core scripts via bin/hermit-run - #661
Merged
Conversation
Installed domain plugins can't reach core's versioned cache dir from their
own ${CLAUDE_PLUGIN_ROOT}, so HA's ha-morning-brief re-implemented core's
micro-proposal writer inline and the domain-brainstorm skills told the model
to hunt for core's root. Route them through the project-resident bin/hermit-run
instead: harden its resolver (validate the env root by manifest, fail loud on
marketplace ambiguity) and add a hermit-exec.sh name guard so the new permission
globs can't reach a script outside core's scripts/. Add a micro-proposal.ts
brief-cycle verb so both briefs age the queue in one call, and move the
per-entry lifecycle into core's writer.
Also: hermit-evolve Step 8 now delegates the permission merge to apply-settings
allow (the hand-list had drifted and was denied under the strict hook profile);
evolve sibling resolution applies local > project precedence; dev's triplicated
findHermitDir collapses to one lib; and a root behavior test plus a path-scoped
workflow guard the three automode-env copies.
Both brief skills render "MP-YYYYMMDD-N (tier N): <question>" and are now told never to re-read the queue file, so the verdict is their only source for the tier — without it every morning brief rendered a wrong or missing tier. HA's Output Format block also still keyed its two "Awaiting decision" lines on the raw follow_up_count, which step 9a no longer exposes for fresh entries; relabelled to the `new`/`renudged` verdict keys.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Installed domain plugins can't reach core's versioned cache dir from their own
${CLAUDE_PLUGIN_ROOT}, so HA'sha-morning-briefhad re-implemented core's micro-proposal writer as two inlinebun -eblocks and thedomain-brainstormskills told the model to hunt for core's plugin root at runtime. This routes those call sites through the project-resident.claude-code-hermit/bin/hermit-run— a static, layout-independent path — and hardens that dispatcher so it's safe as a cross-plugin entry point. It also folds in three adjacent fixes surfaced while scoping the work.Changes
Shared-logic path (core + HA/dev/fitness)
bin/hermit-run: validateHERMIT_PLUGIN_ROOTby manifest name; collect all marketplace-scan matches and fail loud on ambiguity instead of taking glob order. NoclaudeCLI dependency (cron/systemd watchdog boot paths).hermit-exec.sh: reject a script name containing/or.., so the new permission globs can't reach a.tsoutside core'sscripts/.micro-proposal.ts: newbrief-cycleverb ages the whole queue in one call (re-nudge count-1, expire count-2+, record expiries, one atomic write, JSON verdict). Both briefs and HA's morning brief now drive the lifecycle through it; targetedresolve/nudgesemantics are unchanged.Bash(.claude-code-hermit/bin/hermit-run <script> *)allow entries (synced acrossapply-settings.tsand hatch Step 8).domain-brainstorm(dev/fitness/HA): read the metrics report viabin/hermit-run; a kill-criteria breach now escalates to the operator rather than instructing the skill to self-retire (the shared segment can't attribute noise to one skill).Permission ownership (core)
hermit-evolveStep 8 delegates the permission merge toapply-settings.ts <file> allowinstead of a hand-enumerated prose list that had drifted to 15 of 28 entries and instructed aWriterule the writer strips.apply-settings'sallowop now prints each newly-added entry for the run report. Fixes a live bug: the old Edit-based merge is denied under the strict hook profile.Scope precedence (core)
evolve-plan.tsapplieslocal > projectprecedence when a sibling is installed at both scopes, matchingresolve-siblings.ts; the leak-guard test is inverted accordingly.Dedupe guards
findHermitDircollapses to onescripts/lib/find-hermit-dir.ts.tests/cross-plugin/automode-env.behavior.test.tsfixture matrix guards the threeautomode-env.tscopies (including a previously-untested invalid-JSON refusal), run by a new path-scopedtest-cross-plugin.ymlworkflow so it never blocks unrelated releases.Test plan
scripts/test-all.sh),bunx tsc --noEmitclean.tests/hermit-run.test.ts(9) covers resolver env/scan/ambiguity +hermit-exectraversal rejection;brief-cyclecases added toscripts.test.ts; evolve leak-guard flipped; new evolve permission-delegation contract incontracts.test.ts; root cross-plugin behavior test (16).bun -eleft inha-morning-brief, no "cannot reach it" indomain-brainstorm, hatch call-path claim updated.automode-envcopy turns the guard red; reverted.Domain plugins (HA/dev/fitness) now depend on the core version shipping this;
required_core_versionis synced at release time via/fleet-release.