Skip to content

feat(hooks): enforce conventional commits and pre-commit checks - #110

Merged
striderZA merged 3 commits into
masterfrom
feat/git-hooks-conventional-commits
Nov 3, 2026
Merged

striderZA merged 3 commits into
masterfrom
feat/git-hooks-conventional-commits

Conversation

@striderZA

@striderZA striderZA commented Nov 3, 2026 •

Copy link
Copy Markdown
Owner

Summary

Adds tracked, dependency-free git hooks that enforce the commit conventions already documented in CONTRIBUTING.md and the repository rules in AGENTS.md.

Related Issues

None (tooling/process hardening). Supersedes nothing.

Type of Change

  • Bug fix
  • New feature
  • Documentation
  • Refactor
  • CI/Build

Changes

  • .githooks/commit-msg → tools/git-hooks/validate-commit-msg.mjs
    • blocks: non-conventional header, unknown/uppercase type, empty or malformed scope, trailing period, header over 100 chars, missing blank line before the body, ! without a BREAKING CHANGE: footer
    • exempt: Merge ..., Revert "...", fixup!/squash!, Initial commit
    • warns only: missing issue/design reference, sentence-case summary, header over 72, body lines over 100
  • .githooks/pre-commit → tools/git-hooks/pre-commit.mjs
    • blocks: private keys and known token shapes (AWS, GitHub, Slack, sk-, Google) in added lines, unresolved conflict markers, files over 20 MB, broken .opencode/* redirect stubs
    • gates: node tests/agents/validate.mjs --no-report and node tests/workflow/run-all.mjs when .agents/, tests/agents/ or AGENTS.md is staged; npm run test:plugins when .opencode/plugins/ is staged
  • tools/git-hooks/install.mjs — sets core.hooksPath=.githooks, chmods hooks, records the exec bit in the index; --uninstall reverts; no-op outside a git work tree
  • package.json — prepare, hooks:install, test:hooks; npm test now runs plugin and hook tests
  • tests/agents/validate.mjs — --no-report so hook gates never mutate the work tree
  • Docs: CONTRIBUTING.md (Git hooks section), docs/CONTRIBUTING.md (PR process), AGENTS.md (structure map + quality gates; plugin counts corrected to 19 suites / 177 tests)

Testing

  • npm run test:hooks — 54/54 pass
  • npm test — 177 plugin tests + 54 hook tests pass
  • node tests/workflow/run-all.mjs — 4/4 suites pass (invariant I5 fixed)
  • Real git commit --allow-empty -m "Update stuff" rejected, HEAD unchanged
  • Staged file containing a GitHub token blocked by pre-commit, HEAD unchanged (probe removed)
  • Staged tests/agents/validate.mjs → framework validation + workflow integrity both passed
  • Staged .opencode/plugins/ probe → plugin tests passed
  • Entire changeset staged and passed its own pre-commit
  • hooks:install -- --uninstall round-trip; installer exits 0 outside a work tree

Checklist

  • Conventional Commits style used in branch commits
  • No secrets or credentials committed
  • README unchanged (no public interface change)

Notes

  • No new npm dependencies (no husky/commitlint).
  • A missing issue reference is a warning, not an error: existing history does not consistently include one, so blocking would reject most commits.
  • Contributors run npm run hooks:install once per clone (also triggers on npm install via prepare); bypass a single commit with git commit --no-verify, or skip only the heavy gates with OCGS_SKIP_HOOK_CHECKS=1.
  • The first CI run caught an AGENTS.md invariant (I5) that the hook originally missed; the framework gate now runs the workflow suite too, so this class of break is caught before push.

Add dependency-free tracked git hooks wired through core.hooksPath:

- commit-msg rejects non-conventional headers, unknown or uppercase types,
  empty or malformed scopes, trailing periods, over-long headers, a missing
  blank line before the body, and "!" without a BREAKING CHANGE footer.
  Merge, revert, fixup/squash and Initial commit messages are exempt.
- pre-commit blocks staged credentials (private keys plus AWS, GitHub, Slack,
  sk- and Google token shapes), unresolved conflict markers, files over
  20 MB and broken .opencode/* redirect stubs. It runs framework validation
  when .agents/ or tests/agents/ is staged, and plugin tests when
  .opencode/plugins/ is staged.

Supporting changes:
- tests/agents/validate.mjs gains --no-report so hook gates never mutate the
  work tree.
- package.json exposes hooks:install and test:hooks, runs the installer from
  prepare, and npm test now covers plugins and hooks.

Verified: 51 new hook tests pass; bad-message and staged-token commits are
rejected with HEAD unchanged; both gates pass on a real staged tree.

Refs: CONTRIBUTING.md#commit-conventions
Record the commit-msg and pre-commit rules in CONTRIBUTING.md, note hook
enforcement in the PR process in docs/CONTRIBUTING.md, and add .githooks/
plus tools/git-hooks/ to the AGENTS.md structure map and quality gates.

Refs: CONTRIBUTING.md#git-hooks
CI's Workflow Integrity suite failed because invariant I5 treats every
single-backtick token in AGENTS.md as an agent reference, so the new hook
entries were reported as unknown agents.

- Reference the hooks by path (.githooks/...) in the AGENTS.md quality gates.
- Run tests/workflow/run-all.mjs alongside tests/agents/validate.mjs in the
  pre-commit framework gate, so AGENTS.md invariant breaks are caught locally
  instead of only in CI.
- Cover both gate commands and the skip switch in test-pre-commit.mjs.

Verified: node tests/workflow/run-all.mjs 4/4 suites; npm run test:hooks 54
tests pass.

Refs: tests/workflow/invariants.mjs
@striderZA
striderZA merged commit a23e8d4 into master Nov 3, 2026
5 checks passed
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