Skip to content

fix(tri): gates preview reads the PR body the way the issue gate does (Closes #5744) - #5745

Merged
gHashTag merged 1 commit into
fix/preview-required-contextsfrom
fix/preview-linked-issue-prose
Oct 4, 2026
Merged

gHashTag merged 1 commit into
fix/preview-required-contextsfrom
fix/preview-linked-issue-prose

Conversation

@dmitrii-f-t27

Copy link
Copy Markdown
Collaborator

Closes #5744

Stacked on #5732, which restructures the same code. The base moves to master once #5732 merges, and master is merged in then.

tri gates preview asked the required context check-linked-issue by matching issue-gate.yml's pattern against the pull request's whole body. The gate does not grep the body as written: its step "Check for linked issues in PR" first runs the body through an awk program (added under #3388) that drops every line inside a three-backtick fence and every line that opens with >, then greps the title and what is left. A PR whose only Closes #N sat in a fence or a quote read PASS in the preview and was refused by the gate: a false PASS on a required context.

Measured on #5732's head (ad43b60), the gate's own step under bash against the preview's old matcher (the cases used a real number; it is written #N here so this description links no issue):

body (title feat: x) gate step old preview
Closes #N inside a three-backtick fence exit 1 PASS
> Closes #N exit 1 PASS
This refs and #N on two lines exit 1 PASS
Closes #N in prose (control) exit 0 PASS

What changed

cli/tri/src/gates.rs:

  • prose_filter reads the awk program out of issue-gate.yml at run time, from the job that posts check-linked-issue: the text between awk ' and the closing ') on the BODY_PROSE= line. The row runs it with the system awk on the body, fed as the gate feeds it (printf '%s\n'). The shape around the program is read too: exactly one BODY_PROSE assignment, the body piped straight into awk, the substitution closing right after the program, and the grep reading "$PR_TITLE" "$BODY_PROSE". Anything else reads UNAVAILABLE, never PASS, and so does an awk that cannot run.
  • The pattern is matched one line at a time, as grep matches it. The regex over the whole text let \s* cross a newline (third row above). The commit proxy uses the same line rule, which is how l1-traceability.yml greps commits; it still reads PROXY, never PASS.
  • The title is matched as written. gh pr view --json title,body is parsed into title and body apart instead of joined with --jq.

docs/BRANCH-PROTECTION.md: the table row for check-linked-issue said "the pull request title or body references an issue", the reading that produced this defect. It now says the title, or the body outside code fences and > quotes.

Tests (preview_tests, +7)

  • a_reference_only_inside_a_fence_does_not_pass, a_reference_only_in_a_quote_does_not_pass, a_reference_in_plain_prose_still_passes (also prose after a fence, and a quote-shaped title), a_keyword_and_its_number_on_two_lines_are_not_a_reference.
  • the_body_filter_is_read_out_of_the_gate_that_enforces_it: the program comes from the real issue-gate.yml and strips what the gate strips.
  • a_gate_that_filters_or_greps_otherwise_has_no_filter_this_can_read: five altered gates read None (a pipe stage before or after awk, a grep of the raw body, another job, a second assignment).
  • the_row_answers_as_the_gate_s_own_step_does: 13 cases, each run through the gate's own step under bash and through the row, both checked against a stated answer. The gate's quirks stay: a ~~~ fence, a four-space indent and prefs #N count for the gate, so they count for the preview. Whether the gate should strip those is not decided here.
  • The new tests are anchored on closing braces; tri gates tests --gate reads 0 registered twice and 0 that do not run.

Mutations that restore part of the old behaviour, each run against the suite: grepping the raw body fails 3 tests, whole-text matching fails 2, filtering the title fails 2.

Verified locally

  • cargo build -p tri --all-targets: ok
  • cargo test -p tri -- --nocapture --test-threads=1: 841 passed, 0 failed (834 on fix(tri): gates preview asks the contexts the ruleset requires, parse-ratchet among them (Closes #5725) #5732's head, plus 7); cli/tri/skipwatch.py: no new runtime skips
  • tri gates tests --gate, tri skill check, tri census pin --gate: exit 0; no pinned census moved
  • python3 scripts/ci/test_now_gate_writes_nothing.py --tri ./target/debug/tri: ok
  • python3 scripts/ci/test_required_gates_name_their_subject.py: ok; tri gates required: 5 claims, 2 hollow, 3 required, 0 unclaimed (unchanged)
  • python3 tools/check_now_entry_shape.py --check-files docs/now/2026-10-03-tri-gates-preview-reads-the-body-the-issue-gate-reads.md: ok

🤖 Generated with Claude Code

…Closes #5744)

The check-linked-issue row matched issue-gate.yml's pattern against the
whole pull-request body. The gate greps the title as written and only the
prose of the body: its awk program (added under #3388) drops lines inside a
three-backtick fence and lines that open with `>`. So a PR whose only
`Closes #N` sat in a fence or a quote read PASS in the preview and was
refused by the gate -- a false PASS on a required context.

- prose_filter reads the awk program out of issue-gate.yml at run time,
  from the job that posts check-linked-issue, and the row runs it with the
  system awk on the body, fed as the gate feeds it (printf '%s\n'). The
  shape around it is read too: one BODY_PROSE assignment, the body piped
  straight into awk, the substitution closing after the program, the grep
  reading "$PR_TITLE" "$BODY_PROSE". Anything else reads UNAVAILABLE.
- The pattern is matched one line at a time, as grep matches it. The regex
  over the whole text let `\s*` cross a newline, so `refs` ending one line
  and `#N` opening the next read PASS and failed the gate. The commit proxy
  uses the same line rule.
- The title is matched as written; gh pr view now returns title and body
  apart.
- docs/BRANCH-PROTECTION.md: the check-linked-issue row said "title or
  body"; it now says the body outside code fences and `>` quotes.

Tests (preview_tests, +7): fence-only and quote-only references do not
pass, plain prose still passes, two-line references are none, the program
is read out of the real issue-gate.yml, five altered gates read None, and a
13-case table runs the gate's own step under bash beside the row against
stated answers. Mutations (raw body, whole-text match, filtered title) each
fail 2 or 3 of them. cargo test -p tri: 841 passed. No census moved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

This notebook contains session context, decisions, and artifacts for this work.

This was referenced Oct 3, 2026
This was referenced Oct 4, 2026
@gHashTag
gHashTag merged commit 6f9976e into fix/preview-required-contexts Oct 4, 2026
40 of 42 checks passed
@gHashTag
gHashTag deleted the fix/preview-linked-issue-prose branch October 4, 2026 17:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants