Skip to content

Card trailers in commit messages are caught pre-push, not post-push — a .githooks/pre-push refusal, the Part-of: colon gap in check:partof-closing-keyword, and the gate's re-scope once the squash message comes from the PR body #17727

Description

@os-tesla

Filed by the director seat executing the maintainer's ruling A on #17606 + #15913 (2026-09-12, decision batch #116, 「其他同意」). domain:skills (the gate's SUBJECT is the card↔PR relation the PM loop governs); pm:queue; priority:p2 (each occurrence costs a full round — two measured on 2026-09-11, #17649#17653 and #17652). ⛔ Not claimed.

What is ruled

The repository's squash message will be sourced from the PR body (squash_merge_commit_message = PR_BODY; the maintainer's setting change is tracked on #17606 as pm:awaiting-maintainer). Once that lands, a card trailer inside a branch commit no longer reaches main — but the branch is still pushed with it, and check:partof-closing-keyword still reads the commit list and still goes red on a PR nobody can repair without a redo. The gate is a post-push detector for a pre-push mistake. This card moves the detection to where it is cheap.

Deliverables

  1. A pre-push check in .githooks/pre-push (or a check:* script it calls) that refuses a push whose commits carry a card relation in the message — Fixes|Closes|Resolves|Part of|Part-of|Refs #N and a bare #N in a trailer position — with the message naming the commit and the line; the grep the spec seat already runs by hand (comment 5631707212 on The part-of gate prescribes a discharge the repo's merge settings make unreachable — squash lands COMMIT_MESSAGES, the gate requires PR_BODY #17606) is the shape. Lit/dark controls in a --self-test.
  2. Close the Part-of: gap the spec seat measured (comment 5637102799 on The part-of gate prescribes a discharge the repo's merge settings make unreachable — squash lands COMMIT_MESSAGES, the gate requires PR_BODY #17606): partOfRe in scripts/check-partof-closing-keyword.mjs requires a space, so Part-of: #N in a commit message passes RULE 2 while every dispatch order forbids it — make the colon spelling a hit in both the gate and the new pre-push check.
  3. Re-scope the PR-time gate after PR_BODY lands: check:partof-closing-keyword then judges the PR body (the text that will land) and no longer refuses a pushed branch on its commit list; until the setting flips, the gate stays as is and this card's pre-push check prevents the red from being reachable.
  4. .claude/agents/os-dev.md gains one sentence pointing at the pre-push check (governed surface — human merge; keep it one line).

Acceptance

  • A branch pushed with Part of #N (space or colon) in any commit message is refused at push with the offending commit named; a clean branch pushes.
  • check:partof-closing-keyword --self-test covers Part-of:.
  • No change to what merges: the queue's required set is untouched.

Refs: #17606 (the setting; pm:awaiting-maintainer) · #15913 (corrected claims shipping in history — same setting) · #17280 (model-identifier trailers in landed history, same mechanism) · #17649 / #17653 / #17652 (the two rounds paid).

Filed by the director seat, session_01QsCVSivtpwT6ZXs5Rtvqxe.


Generated by Claude Code

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions