# Commit-message repair APPS-406 specifies reversible corrections for agent-authored commit messages. The governing rules are Corpus `COMMIT-STYLE.md`, its Scoped Commits grammar, and the fidelity requirements in `policies/PROSE.md`. ## Contract `gate commit-message install --repo PATH` enrolls one repository's native `commit-msg` and `post-commit` hooks. Installation is idempotent and refuses unrelated existing hooks rather than overwriting or guessing how to chain them. It does not set global Git configuration. Linked worktrees share enrollment. An effective `core.hooksPath` outside the repository's common Git directory is refused. The installed runner pins its interpreter and trusted package path; target-checkout Python modules cannot replace the adapter. The `commit-msg` adapter operates on Git's actual message file before signing. The terminal trailer block must identify automated authorship with `Assisted-by:`. Human messages, merge/fixup/squash messages and an explicit `GATE_COMMIT_REPAIR=0` override remain byte-identical. Missing or conflicting authorship produces no invented provenance. `gate.commit_message.normalize_message(message, *, automated=False, scope=None)` returns an immutable result with `message`, `changes`, `findings`, and `eligible`. Changes name stable COMMIT rule IDs. Findings carry `rule_id`, `line`, and `message`. Calling the normalizer twice produces no second correction. Symbolic corrections include ordinary body-line wrapping at 72 columns, unambiguous `type(scope):` conversion, scope casing and colon spacing, ordinary sentence-case imperative initials, a single terminal subject period, canonical trailer keys/order, splitting valid task references, identical duplicate AI/reference trailers, and a finite documented model-spelling table. An explicit scope may repair a missing or change-kind scope. Unknown model identities survive unchanged. Never infer a version, agent identity or task. Retain claims, negation, quantities, qualifications and domain verbs. Never truncate a long subject or token. Preserve fenced/indented code, quotations, commands, URLs, tables, Markdown hard breaks and non-AI trailer continuations. A breaking-change marker needs an explicit textual account; report it instead of erasing its meaning. Ambiguous footer structure is diagnostic-only. Each correction resolves a named rule without hiding remaining violations. Messages are bounded to 64 KiB. ## Recovery and failure Before mutation, the adapter durably saves a private receipt with original and candidate bytes, hashes, rule changes and repository identity. Gate's admission receipt remains content-free; originals belong only to this private adapter store. The adapter rechecks the message before writing and does not change the index, tree, signing options or commit invocation. Failed persistence means no correction. A notice reports corrections and the receipt path. The `post-commit` adapter binds the pending receipt to the exact committed HEAD, tree and message, and verifies that both hooks belong to the same invoking Git process. This adapter uses Linux `/proc` process identity; an unavailable identity prevents correction and produces an advisory notice. Stale or mismatched pending records never become undo authority. `gate commit-message undo RECEIPT` refuses unless repository identity, HEAD, tree, current message and a clean index/worktree match the bound receipt. It explicitly amends only the message using normal Git signing and a one-call repair override. It never pushes, changes signing configuration or automatically rewrites history. Missing post-commit evidence leaves the original recoverable but disables automatic undo. Repeated undo refuses safely. `gate commit-message check FILE` prints structured checks without mutation. Hook failures are advisory and visible: unavailable checks are not passes. Ordinary clean messages cause no model calls and no receipt writes. ## Corpus integration Gate owns the pure normalizer, admission policy, native adapter and CLI. Corpus owns worktree enrollment, agent-tool notification transport, and its existing protected-span-aware PROSE parser/scanner. MEMY-1785 enrolls newly provisioned agent worktrees and exposes bounded post-tool advisory verification through Corpus's canonical hook registry. Claude Code supports successful Write/Edit/MultiEdit events and structured Tact results; Codex supports structured Tact results. Unknown result envelopes and unsupported harnesses abstain. Private reports, including journal entries without explicit public visibility, are excluded. The advisory reports rule IDs, source locations, classes and limits. It does not enqueue rewriting or modify document bytes. The grammar is one `my-basis` `RegexStore` (`gate.commit_message.COMMIT_RGXS`): the task projects, change kinds and command words are each defined once as an alternation and invoked as subroutines by the rules that need them, so a vocabulary change is one edit. ```python COMMIT_RGXS = RegexStore.new( options=dict(separator='', lazy_load=False), _project=('|:', ['MEMY', 'LIBS', 'APPS', 'TOOLS', 'SITES', 'SUBL', 'SELF']), _change_kind=('|:', ['feat', 'fix', 'chore', 'refactor', 'style', 'perf', 'revert']), sid=r'^(?P>_project)-[1-9][0-9]*$', type_scope=r'^(?P>_change_kind)\((?P[^()]+)\):\s*(?P.+)$', ..., ) assert COMMIT_RGXS.fullmatch('sid', 'APPS-413') assert COMMIT_RGXS.fullmatch('type_scope', 'fix(api): x').flat['scope'] == 'api' ``` `tests/test_commit_grammar.py` keeps the retired stdlib patterns verbatim and checks the store against them on positives, negatives, near-misses and captures. Semantic rewriting has no measured acceptance corpus yet. This wave does not let an uncalibrated GLM response certify and apply its own rewrite; explicit model proposals may be added only with bounded inputs and fidelity review. ## Acceptance evidence Tests must exercise the reported 73-column body-line failure, ordinary Git `-m` and `-F` commits through installed hooks, human/override preservation, idempotence, conflicting provenance, protected syntax, hooks already installed, stale pending receipts, stale HEAD/message, signing failure and successful undo. Run focused checks, full relevant Gate gates, independent Terra review, and normal Gate merge review. Verify the merged implementation and Corpus integration separately from live-harness delivery and release claims. Git explicitly permits `commit-msg` to edit its message file: [Git hook contract](https://git-scm.com/docs/githooks#_commit_msg). The subject shape follows [Scoped Commits](https://scopedcommits.com/).