Skip to content

feat(guardrails): enforce a user-private commit convention only where the team tracks none #9776

Description

@kyle-sexton

Parent

Refs #5948

Depends on

Outcome

An operator can gate their own commits in a repository whose team tracks no commit convention, without changing
the repository's tracked files: a subject_pattern (one POSIX ERE) in the personal layer
<home>/source-control.local.yaml (gitignored, or excluded through .git/info/exclude) applies only when the
team layer sets none, and is never merged with a team pattern.

Decisions

  • Owner, 2026-10-13: fallback-only; a user pattern applies only when the team tracks none and never weakens or
    merges with a team pattern. Amend the resolver's policy-floor header and docs/conventions/commit-convention
    together, and test all three consumers: block-noncanonical-commit, the Claude Code content gate
    (block-convention-violation) and the commit-msg hook.
  • ADR 0075: the personal layer is <home>/<concern>.local.<ext>, and a personal value may only tighten a policy
    floor. Adding enforcement where the team sets none is tightening. A git hook cannot read userConfig, so the
    personal file is the source.

Key interfaces

  • lib/resolve-convention-pattern.sh (canonical) and copies, docs/conventions/commit-convention, the three
    consumers above.

Done when

  • scripts/run-test-file.sh lib/resolve-convention-pattern.test.sh exits 0 with cases: personal pattern used when the team sets none; team pattern used and personal ignored when both exist; neither gives no enforcement.
  • scripts/run-test-file.sh exits 0 on plugins/guardrails/hooks/block-noncanonical-commit.test.sh, plugins/guardrails/hooks/block-convention-violation.test.sh and plugins/guardrails/git-hooks/commit-msg-convention.test.sh, each with a personal-layer case.
  • grep -n "local" docs/conventions/commit-convention/README.md prints the amended layer rule, and the resolver header states the fallback-only personal layer.
  • scripts/sync-shared-copies.sh --check exits 0.
  • scripts/check-changelog-fragments.sh --check-required origin/main exits 0.
  • The PR body carries Hold: a human merges this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: mediumReal value, no hard deadline; normal backlog flow.status: readyTriaged, unblocked, and fully specified; eligible to pick up.

    Fields

    No fields configured for Feature.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions