Skip to content

Consume the gated-workflow plugin, own the git hooks - #21

Open
miridius wants to merge 1 commit into
mainfrom
consume-gated-workflow-plugin
Open

Consume the gated-workflow plugin, own the git hooks#21
miridius wants to merge 1 commit into
mainfrom
consume-gated-workflow-plugin

Conversation

@miridius

@miridius miridius commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Problem

The workflow skills, review agents, and gate scripts were vendored into .claude/, duplicating what the gated-workflow plugin already ships. The plugin is a Claude Code plugin published from the miridius/claude-plugins GitHub marketplace, and keeping the copies current meant re-copying its files into this repo on every plugin release.

Hook installation was fragile in both directions. Reading simple-git-hooks' postinstall: it locates .git by walking the filesystem rather than asking git, it unlinks any hook the config does not declare, and it exits 0 when it cannot write one. The first two are latent hazards under the bind-mounted dev and test services, where an install inside a container can find and rewrite the host's hooks; the third means an install that failed to wire the commit gate said nothing at all.

Fix

The plugin becomes the source of truth: .claude/settings.json enables gated-workflow@miridius-plugins at project scope, the vendored skills, agents, and gate scripts are deleted, and CLAUDE.md gains the repo-specific QA, e2e, deploy, and check commands the plugin's generalised skills defer to the consuming repo. The Stop hook that blocked finishing with uncommitted work moved into the plugin rather than staying inline here.

simple-git-hooks is gone. scripts/install-hooks.sh writes both hooks itself: it resolves the hooks directory through git rev-parse --git-path, so a linked worktree wires the shared directory rather than a private one git would never run, and it fails the install outright when the plugin's commit gate is not present, so a hook can never be left pointing at a gate that is not there. It runs under umask 022 because bun runs lifecycle scripts under umask 0000, which would otherwise create a missing hooks directory world-writable; the hook files themselves are chmod 755 explicitly. Verified by running the install inside the dev container, which bind-mounts the repo including .git, and confirming the host's hooks were unchanged.

CI and both images install with --ignore-scripts, so prepare is a host-only step and containers and CI never need the plugin present.

Decision: the plugin is tracked unpinned from the marketplace, so an upstream change reaches this repo without a commit here, and that now covers the pre-commit gate, the PR merge gate, the review agents, and the human-approval skill. The alternative was re-vendoring on every plugin release, which is what this PR removes.

Decision: the hook execs the gate through Claude Code's plugin layout (plugins/marketplaces/<marketplace>/plugins/<plugin>/...), resolved at commit time rather than install time. The cost is that a layout or marketplace rename upstream breaks every commit until the hooks are rewritten; the alternative, copying the gate script into the repo, is the vendoring this PR removes.

Decision: a host bun install fails outright when the plugin is missing rather than warning. That blocks a plain host checkout from installing dependencies until Claude Code and the plugin are set up; the alternative is the silent no-gate state described above.

Decision: the script exits 0 without installing anything when git is not on PATH, which is how a container install leaves the host's hooks alone. The cost is that a host missing git also gets no hooks and no warning, the one silent-no-gate case kept deliberately.

Claude Code creates a git worktree per agent and copies the gitignored files listed in .worktreeinclude into it, so this adds the three env files, because every compose service names one in env_file and a worktree without them cannot start anything. Prod credentials are therefore duplicated into each worktree directory; .claude/worktrees/ is gitignored so they cannot be committed from there.

Every container entry point (test.sh, check.sh, e2e.sh, and the docker compose run command documented in CLAUDE.md) now passes --build, so a run can no longer validate whatever image happened to be cached. The cost is an image-freshness check on each invocation.

Written by Claude Opus 5

@miridius
miridius force-pushed the consume-gated-workflow-plugin branch from f404ba0 to 5c7e105 Compare July 24, 2026 20:31
@miridius
miridius force-pushed the consume-gated-workflow-plugin branch 2 times, most recently from 2c88e46 to 2b30700 Compare August 30, 2026 09:23
The workflow skills, review agents, and gate scripts come from the
gated-workflow plugin (miridius/claude-plugins) instead of in-repo copies.
.claude/settings.json enables it at project scope, and its Stop hook (plugin
1.0.18) replaces the uncommitted-work hook this repo carried inline.

simple-git-hooks is gone. scripts/install-hooks.sh writes both hooks itself,
resolving the hooks dir through git so a worktree wires the shared one, and
fails the install when the plugin's commit gate is missing, so a hook can
never point at a gate that is not there. The images ship no git, so an
install inside a container stops before it can reach the bind-mounted host
.git; CI and both images also install with --ignore-scripts, which keeps
prepare a host-only step.

Every container entry point (test.sh, check.sh, e2e.sh, and the documented
docker compose run) now passes --build, so a run can no longer validate
whatever image happened to be cached.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVFsAKqvL47RDvfis2YaP2
@miridius
miridius force-pushed the consume-gated-workflow-plugin branch from 2b30700 to 93445bb Compare August 30, 2026 09:30
@miridius miridius changed the title Consume the gated-workflow plugin, drop the vendored copies Consume the gated-workflow plugin, own the git hooks Aug 30, 2026
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