Commit Graph

2 Commits

Author SHA1 Message Date
rcourtman 3699dca826 Make prepare-commit-msg executable so worktree commits keep the trailer
.husky/pre-commit and .husky/pre-push are tracked 755 but
prepare-commit-msg was 644. In the main checkout that never shows, because
git runs husky's generated executable .husky/_ shim, which sources this
file regardless of its own mode.

Committing from a linked worktree is different. The gitignored .husky/_
does not exist there, so the documented workaround is
git -c core.hooksPath=.husky commit, which points git straight at this
file. Git then skips it as not executable, prints a one line hint, and
commits anyway.

That hook is what records PULSE_ALLOW_CONTRACT_NEUTRAL_COMMIT as the
Contract-Neutral trailer. Without it a bypassed worktree commit lands with
no trailer, passes every local check including Pre-commit checks passed,
and is then failed by the canonical governance workflow, which reads the
trailer back per commit. The only signal is a red CI run later.

Marking the file executable makes the tracked hook run directly under
core.hooksPath=.husky. Behaviour in the main checkout is unchanged, since
the shim path is unaffected.
2026-08-04 11:28:05 +01:00
rcourtman eb5a477dc9 fix(governance): make commit-time guard verdicts survive to CI
Canonical Governance failed on nearly every push today (6 of the last 8
commits) because the local pre-commit hook and the CI workflow disagreed
about the canonical completion guard in two ways.

Frontend-only commits skipped the guard entirely: the hook gated ALL
governance checks behind governance-path detection as a perf
optimization, but subsystem contracts name canonical frontend files, so
those commits landed locally and failed the same guard in CI. The hook
now always runs the (cheap) completion guard; only the multi-minute Go
test and audit battery stays path-gated.

Contract-neutral bypasses did not travel: PULSE_ALLOW_CONTRACT_NEUTRAL_COMMIT
authorized the commit in the local shell and vanished, so CI re-ran the
guard without it and went red. A new prepare-commit-msg hook records the
reason as a Contract-Neutral trailer in the commit message, and the
workflow now evaluates the guard per commit (each commit's file list
against its own parent), honoring the trailer exactly as the commit-time
hook honored the env var. Per-commit evaluation also stops a compliant
commit from being blamed for range-mates.

The new hook is registered as a worktree-sensitive governance file in
governance_stage_guard.py with a matching unit test assert.
2026-07-17 14:35:34 +01:00