Skip to content

bug: hook install --commit-msg installs a trailer normalizer, not a gate, so requireTrailers fails only in CI #299

Description

@stackbilt-admin

Problem

With the documented onboarding — bootstrap --yes, bootstrap --ci github, hook install --pre-commit, hook install --commit-msg — the generated config enables the trailer gate:

"git": { "requireTrailers": true, "trailerThreshold": "HIGH" }

but the installed commit-msg hook never enforces it. The whole hook is:

governed_by="$(grep -i '^Governed-By:' "$msg_file" | tail -n 1 | ...)"
if [ -n "$governed_by" ]; then
  git interpret-trailers --in-place --if-exists=replace --trailer "Governed-By: $governed_by" "$msg_file"
fi

It normalizes a trailer if the author already wrote one, and exits 0 otherwise. So every commit succeeds locally, and the first push fails CI:

[fail] FAIL: 5 of 5 commit(s) missing required governance trailers.
   Commit range: HEAD~5..HEAD
   Range source: recent-fallback
   Commits: 5 | Trailers found: 0

The author gets no signal at the moment they could act (writing the message) and a red build afterwards.

Second problem: the fallback range reaches back before adoption

recent-fallback validated HEAD~5..HEAD, which included three commits made before Charter was added to the repo. Those commits cannot be fixed without rewriting published history, so a repo that adopts Charter starts with a red gate and no clean way to go green other than disabling the gate — which is what I did.

Impact

requireTrailers: true is the default from bootstrap, so this is the default first-push experience for a repo with existing history. It also undermines the local hooks: they are installed, they pass, and CI disagrees with them. (Related: #289, closed, and #292.)

Suggested fix

  1. Make the commit-msg hook the gate when requireTrailers is on: reject a commit whose message lacks the required trailer, with a one-line example of the expected format, rather than silently normalizing.
  2. Baseline the validation range at adoption. Record the commit that introduced .charter/config.json and validate only commits after it, or support git.validateSince in config.
  3. If the threshold is HIGH, say in the failure output what makes a commit HIGH-risk and which trailer would satisfy it. The current suggestion ("Consider linking significant changes to ADRs") does not name the required trailer or its format.

Environment

@stackbilt/cli@1.9.3, Node 22.14, WSL2, GitHub Actions Governance Check workflow generated by charter bootstrap --ci github.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions