own-language pre-commit hook refuses any merge of master: master's pr-budget.yml and cli/tri/src/gates.rs are not in foreign-exceptions #10414
Description
@gHashTag, the local own-language pre-commit hook refuses every merge of current master into a branch, so a fork PR cannot be brought up to date without --no-verify, which the hook's own comment forbids.
What happens
On 2026-10-18 I merged master fdeb1db into #8890 (spec/trinet-top). The commit is refused:
.github/workflows/pr-budget.yml: hand-written .yml is forbidden (owner rule 2026-10-05) ...
cli/tri/src/gates.rs: hand-written .rs is forbidden (owner rule 2026-10-05) ...
Neither file is part of #8890. Both came in from master:
.github/workflows/pr-budget.yml— ba78d6d (gate(policy): wire pr_budget.t27 into a pull_request_target gate -- draft the 21st open PR, promote held drafts, exempt queen-* (Closes #10074) #10087);cli/tri/src/gates.rs— 0963a63 (fix(cli-tri): delete the stale brain-seal-refresh.yml test, re-bless census (Closes #9634) #10111).
Neither is listed in tools/policy/foreign-exceptions.txt on master.
Why
lefthook.yml feeds the gate git diff --name-status --cached. During a merge that diff is everything master brought in, not only what the branch changes. The CI twin (own-language, required) judges the PR's own diff, so it does not see these files.
Either of these fixes it
- Add
.github/workflows/pr-budget.ymlandcli/tri/src/gates.rstotools/policy/foreign-exceptions.txton master, if they are owner-approved. - Make the hook judge only what the branch changes during a merge, for example the staged diff against
MERGE_HEADwhen it exists, decided inspecs/policy/own_language.t27.
#8890 waits with the merge resolved locally (including pin declarations on master's new inout ports, #10188) and is not committed until one of these lands.
Dmitrii Fedorov (@dmitrii-f-t27)
Boundary
- tools/policy/foreign-exceptions.txt
- specs/policy/own_language.t27
- gen/c/policy/own_language.c
- lefthook.yml
User Scenarios
- Given a fork branch behind master, When its owner merges current master (which brings
.github/workflows/pr-budget.ymlandcli/tri/src/gates.rs), Then theown-languagepre-commit hook accepts the merge commit, because those files are master's, not the branch's. - Given a branch that itself adds a hand-written
.ymlor.rs, When it commits, Then the hook still refuses it, as today.
Requirements
- FR-001: The pre-commit
own-languagegate MUST NOT refuse a merge commit for foreign files whose content equals master's (files the merge brings in unchanged). - FR-002: The gate MUST keep refusing hand-written foreign files the branch itself adds or changes.
- FR-003: The decision MUST live in
specs/policy/own_language.t27(or the files MUST be listed intools/policy/foreign-exceptions.txton master), not in a bypass.
Success Criteria
git merge origin/mastercommitted on t27b verilog: pin declarations, and the TRI-NET board top in .t27 with no hand Verilog or XDC (Closes #8889) #8890 (spec/trinet-top) passes the pre-commit hook withexit 0and without--no-verify.- The same on fix(fpga): eth_reply.t27 sends one frame per receipt, to the sender, with a real checksum #8532 and fpga: the TRI-NET node's 100 Mb/s board logic in t27 (MDIO, RGMII nibbles, JTAG status) (Closes #8770) #8772.
Activity
github-actions commentedon Oct 18, 2026
Closed by the issue-shape gate (specs/policy/issue_shape.t27, #7498): an issue must have the template's sections. Edit the body; an edit that passes reopens it.
- specs/x.t27); without it the Queen reserves nothing and no bee can take the issueFR-001: ... MUST ...exit 0, or a backticked commanddmitrii-f-t27 commentedon Oct 18, 2026
The same hook blocks updating #8532 and #8772 (E2 job link) from master; together with #8890 that is three PRs waiting on this.
Dmitrii Fedorov (@dmitrii-f-t27)
github-actions commentedon Oct 18, 2026
The shape check passes now (specs/policy/issue_shape.t27); reopened.
gHashTag commentedon Oct 18, 2026
Same failure from the
foreign-budgetcommand, measured 2026-10-19 on branchclaude/t27f-beat-overlay(PR #10610) while mergingorigin/master:None of those lines are from the branch. They come from master's #10587 (
b3a226322,tri t27o-sweep). With a merge in progress,git diff --numstat --cachedcompares the index toHEAD, so everything master brings in counts as "added by this commit".A candidate fix for whoever owns
lefthook.yml: when.git/MERGE_HEADexists, diff againstMERGE_HEADrather thanHEAD. That diff holds only the branch's own work, which is what the PR-side twin inown-language.ymlmeasures anyway.Workaround used here: I aborted the merge and did not use
--no-verify. #10610 is carried by #10627, which is a branch on top of it and is mergeable with master.gHashTag commentedon Oct 18, 2026
Workaround that keeps every hook on, used on #10551 (head f3aa394):
git merge origin/master. With no conflicts left, git writes the merge commit itself, and lefthook defines no pre-merge-commit stage.This does not fix the gate: a conflict inside master's big foreign commit would still be refused.