Skip to content

feat: opt-in auto-verify hook and release CI safety net - #1

Merged
subinium merged 5 commits into
mainfrom
feat/auto-verify-and-ci
Apr 26, 2026
Merged

feat: opt-in auto-verify hook and release CI safety net#1
subinium merged 5 commits into
mainfrom
feat/auto-verify-and-ci

Conversation

@subinium

Copy link
Copy Markdown
Owner

Summary

  • Add opt-in PostToolUse hook (plugins/vibesubin/hooks/auto-verify.sh, gated by VIBESUBIN_AUTO_VERIFY=1) that emits a stderr advisory after MultiEdit ≥5 or signature-changing edits (export/def/class/pub fn/func/fn/async function/interface/type), nudging the user to run /vibesubin:refactor-verify. Defaults OFF — no behavior change for existing installs. PostToolUse cannot block (exit 0 always); the hook is purely advisory.
  • Add .github/workflows/release.yml on v*.*.* tag push: runs validate_skills.py + pytest, HARD-checks manifest version sync (tag == marketplace.json == plugin.json) and forbidden file types (\.env$|\.pem$|id_rsa|\.key$), then creates a draft release for human-curated notes per CLAUDE.md step 8.
  • marketplace.json: add category: "developer-tools" and keywords for marketplace discoverability. Schema verified against claude-plugins-official (160 plugins union) — keywords is the standard discovery field; repository/tags are not in the spec.
  • install.sh: replace emoji prefix with ERROR: text in the 3 error paths. Avoids broken rendering on non-UTF-8 terminals; aligns with the pack's no-emoji ethos.
  • CHANGELOG.md: [Unreleased] entries in functional-only style.

What this is NOT

  • ❌ Not a README rewrite (invariant feat: opt-in auto-verify hook and release CI safety net #1 — preserved verbatim).
  • ❌ Not a new skill (invariant #2 — auto-verify is a hook that extends refactor-verify; 10+1 cap unchanged).
  • ❌ Not a version bump (manifests stay at 0.7.0; entries accumulate under [Unreleased] for the next release decision).
  • ❌ Not the vibesubin-mcp server bundle (deferred — Cursor/Cline don't auto-discover Claude Code plugin MCPs, runtime friction outweighs benefit at this stage).

Test plan

  • python3 scripts/validate_skills.py passes (12 skills, manifests synced)
  • Hook gate-off: invocation without env var produces no stderr output
  • Hook gate-on + signature line in diff: emits advisory
  • Hook gate-on + MultiEdit ≥5: emits advisory
  • Hook gate-on + small non-signature edit: stays silent
  • marketplace.json and hooks.json valid JSON
  • No forbidden files (git ls-files | grep -iE '\.env\$|\.pem\$|id_rsa|\.key\$' returns nothing)
  • Manual: enable in a real session (VIBESUBIN_AUTO_VERIFY=1 claude), make a signature-changing edit, confirm advisory appears in panel
  • Manual: cut a test tag (v0.7.1 or similar) on a fork, confirm draft release is created with all gates green

Self-review rounds

5 commits, 3 review rounds caught:

  1. Round 1: auto-verify.sh was calling symbol-diff.sh HEAD HEAD — useless self-comparison. Switched to advisory-only (the actual symbol-diff belongs to /vibesubin:refactor-verify which captures a proper snapshot). release.yml was auto-publishing — switched to draft: true to honor CLAUDE.md step 8.
  2. Round 2: Schema correctness — dropped repository (not in spec), replaced tags with keywords (standard field). release.yml body: conflicted with generate_release_notes — dropped body:, added version-extract step so release title renders as vibesubin 0.8.0 instead of vibesubin v0.8.0.
  3. Round 3: Advisory wording precision — dropped "signature-changing" qualifier (incorrect for the MultiEdit volume path).

🤖 Generated with Claude Code

subinium and others added 5 commits April 26, 2026 12:22
Add opt-in PostToolUse hook (VIBESUBIN_AUTO_VERIFY=1) that runs
refactor-verify's symbol-diff after MultiEdit >=5 or signature-changing
edits. Defaults OFF — no behavior change for existing installs. Extends
refactor-verify per invariant #2 (no new skill, no cap impact).

Add release.yml workflow on tag push (v*.*.*) — validates skills,
runs pytest, enforces manifest version sync (tag = marketplace = plugin),
and checks for forbidden file types before creating the GitHub release.
The manual gh release create policy stays; this is the safety net.

Add marketplace.json metadata (category, tags, repository) for plugin
discoverability. install.sh: ERROR: text replaces ❌ emoji prefix.

Validator: OK (12 skills, manifests synced).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Functional-only style per CLAUDE.md invariant #4. Documents the
auto-verify hook (opt-in), release.yml safety net, marketplace.json
metadata, and install.sh emoji removal added in the prior commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
auto-verify.sh: remove symbol-diff inline invocation. The PostToolUse
hook fired symbol-diff.sh with HEAD HEAD (comparing HEAD to itself,
always 0 dropped) because at edit time there is no meaningful "before"
snapshot. Advisory message alone is the correct behavior; the actual
verification belongs to /vibesubin:refactor-verify which captures its
own snapshot.

release.yml: switch to draft: true. Auto-publishing conflicts with
CLAUDE.md step 8 ("write release notes to a temp file, functional-only
style"). CI now validates and creates a draft release the human edits
before publishing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
marketplace.json: drop `repository` (not in plugin schema — 0 of 160
plugins in claude-plugins-official use it; `homepage` covers the role).
Replace `tags` with `keywords` to match the standard discovery field
(vercel, openai-codex, and most plugins use `keywords`).

release.yml: drop the instructional `body:` (conflicts with
`generate_release_notes`). Add a version-extract step so the release
title renders as "vibesubin 0.8.0" (matching CLAUDE.md step 9 example)
instead of "vibesubin v0.8.0". Human still curates the notes from
CHANGELOG.md before publishing.

auto-verify.sh: defensive `EDITS="${EDITS:-0}"` guard before the
numeric `-lt` comparison.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The advisory fired for two paths (MultiEdit >=5 OR signature line in
diff) but always claimed "signature-changing", which is wrong for the
MultiEdit volume path. Drop the qualifier; the directive to run
/vibesubin:refactor-verify is sufficient context.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@subinium
subinium merged commit 6ed0664 into main Apr 26, 2026
1 check passed
@subinium
subinium deleted the feat/auto-verify-and-ci branch April 26, 2026 04:53
subinium added a commit that referenced this pull request Apr 27, 2026
…ygiene workers

Two AI-native failure modes the pack now actively guards against per-worker:

1. Chesterton's Fence — workers refuse to recommend removal or replacement
   of unfamiliar code, files, env vars, assets, or conventions without
   identifying the *why* first. Internalized in fight-repo-rot,
   manage-assets, manage-secrets-env, refactor-verify, audit-security,
   project-conventions. Confidence tier verified requires both zero refs
   AND known origin; unclear origin downgrades to candidate-for-removal
   (or candidate-with-context-needed for convention changes).

2. Goodhart protection — workers refuse to recommend gate-gaming patterns
   (as any, eslint-disable, .skip, weakened assertions, suppression
   comments without CVE, continue-on-error: true on quality gates) as
   fixes when verification fails. Internalized in refactor-verify,
   audit-security, setup-ci, codex-fix. The wrapper (codex-fix) enforces
   the canonical pattern list at the wrapper boundary, no duplication.

Framing: operationalizing existing invariants #2 (well-meaning junior
developer — stop-and-ask before destructive action) and #1 (Done is
proven, not claimed — proof for tier upgrades and gate passes), not
new ideology. Per-skill bullets carry the rule, not the principle name
— Karpathy precedent (no external shoutout in SKILL.md).

No new skills (10+1 cap unchanged). No interface change. No README touch.
Net diff +16 -2 across 11 files.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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