From 495b2c86382a99130c9de146fe2ca3fc64574836 Mon Sep 17 00:00:00 2001 From: Gabriel Tavares Date: Sat, 25 Jul 2026 16:00:06 +0100 Subject: [PATCH 1/9] refactor(claude-code-hermit): make apply-settings the sole owner of hermit permissions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The allow-list lived in three places — apply-settings.ts's sealed array, a copied JSON block in hatch/SKILL.md, and a prose list in hermit-evolve/reference.md that had already drifted to 15 of 33 entries. Nothing could remove a stale entry either: scrubbing was hand-written prose the model executed, so a deleted script's permission lingered in every hatched hermit forever. apply-settings.ts gains permissions-plan (read-only diff) and permissions-sync (apply it). Removal is filtered through a sealed HERMIT_OBSOLETE registry, so an operator's own rules can never be caught by it. hatch and hermit-evolve now call the verbs; both copies of the list are gone, and future script deletions reach installed hermits by appending one registry line. next-prop-id.ts goes with it — no production caller, since proposal.ts create claims IDs atomically via exclusive create. Its prediction-only helpers (nextPropId, resolveSuffix, PropIdParts) are deleted too; the slug and numbering cases they covered move to direct lib unit tests. A no-op sync deliberately skips the write so an upgrade never reformats a settings file it had nothing to change. --- plugins/claude-code-hermit/CHANGELOG.md | 9 +- .../scripts/apply-settings.ts | 96 ++++++++++-- .../claude-code-hermit/scripts/lib/prop-id.ts | 45 +----- .../scripts/next-prop-id.ts | 48 ------ .../claude-code-hermit/skills/hatch/SKILL.md | 69 ++------- .../skills/hermit-evolve/reference.md | 15 +- .../tests/apply-settings-permissions.test.ts | 144 ++++++++++++++++++ .../tests/contracts.test.ts | 29 ++-- .../tests/proposal-lib.test.ts | 81 ++++++---- .../claude-code-hermit/tests/scripts.test.ts | 78 ---------- .../tests/template-skill-sync.test.ts | 36 +++-- 11 files changed, 345 insertions(+), 305 deletions(-) delete mode 100644 plugins/claude-code-hermit/scripts/next-prop-id.ts create mode 100644 plugins/claude-code-hermit/tests/apply-settings-permissions.test.ts diff --git a/plugins/claude-code-hermit/CHANGELOG.md b/plugins/claude-code-hermit/CHANGELOG.md index 544035a4..82ff39cb 100644 --- a/plugins/claude-code-hermit/CHANGELOG.md +++ b/plugins/claude-code-hermit/CHANGELOG.md @@ -7,6 +7,7 @@ - `config.effort` — passed as `--effort` on every `hermit-start`, mirroring `config.model`, so a channel effort change reverts on restart instead of persisting. Ships `null` (no flag, model default); set it to opt into the revert-on-restart guarantee. Not the same lever as `config.env.CLAUDE_CODE_EFFORT_LEVEL`, which pins the session and makes a runtime `/effort` a no-op. - `micro-proposal.ts brief-cycle` — ages the whole micro-approval queue in one call (re-nudges `follow_up_count` 1 entries, expires 2+ entries, records each expiry) and returns a JSON verdict, replacing the per-entry `nudge`/`resolve` calls both briefs used to issue one at a time. - Two `Bash(.claude-code-hermit/bin/hermit-run