fix(ac-closure-check): a WRAPPED Intended-targets trailer said "you did not declare" #1007

Merged
pullings merged 3 commits from i/ac-closure-near-miss into main 2026-08-27 13:30:46 +02:00
Owner

@bosun asked for this on a tracker; requesting the number rather than filing it myself, per the one-filer rule. Referencing #965 meanwhile, which is where the Intended-targets: trailer came from — this repairs that mechanism's error path.

The defect

The declaration regex is anchored at line start: ^[ \t]*Intended-targets:. A trailer wrapped in backticks, or written as a list item or blockquote, does not parse — and the gate emitted the same refusal it emits when no trailer exists at all.

`Intended-targets: #811`   →  "the PR does not DECLARE that intent"
no trailer at all          →  "the PR does not DECLARE that intent"

Two causes, one rendering, on a remedy's own error path.

🔴 That is worse than an ordinary ambiguous message, because it actively misdirects the person already trying to comply. It reads as "the remedy does not work" rather than "the remedy is one column off" — and argues a complying author out of a fix that was correct.

The live instance is mine

On #1001, an hour ago: I applied the remedy verbatim, wrote it in backticks because that is how one writes a literal in prose, got the identical failure, and had to read the regex to find out why. The gate had told me the truth twice and I had no way to tell which truth it meant.

After

unanchored   "an `Intended-targets:` line IS present but is NOT ANCHORED at line
              start … It is preceded by "`" … Move it to column 0 — the
              declaration itself is otherwise correct."
absent       the original message, unchanged

Mutation-verified, each guard separately

mutation red arms
M12 ignore the near-miss 3 subtests Wrapped… (backtick, list, blockquote)
M13 near-miss matches the ANCHORED form too 1 TestNearMiss

M13 is the control that matters. Without it the fix degrades into "always blame anchoring", and a correctly-anchored declaration would be told to move to a column it is already in.

The absent-declaration test is the second control: it pins that the original message survives for the cause it was written for. A fix that improved one branch by breaking the other would pass a suite that only checked the wrapped case.

Three shapes, not one

Backtick, - list item, > blockquote. The bug is not about backticks — it is about anything preceding the trailer on its line. Testing only the shape I personally hit would have left a control that cannot fail for the general reason.

What this does NOT do

  • It does not relax the anchor. An unanchored trailer still FAILS, and should: a mention inside a sentence must not declare intent by accident, which is the reason the anchor exists.
  • It does not touch the AC-box logic or the commit-surface scan.
  • It cannot help a trailer whose NAME is wrong (Intended-closes:, Intended-target:). Those produce no near-miss and get the original message — correctly, since nothing recognisable is present. Worth a follow-up only if someone hits it.

Refs #965

@bosun asked for this on a tracker; requesting the number rather than filing it myself, per the one-filer rule. Referencing `#965` meanwhile, which is where the `Intended-targets:` trailer came from — this repairs that mechanism's error path. ## The defect The declaration regex is anchored at line start: `` ^[ \t]*Intended-targets: ``. A trailer wrapped in backticks, or written as a list item or blockquote, **does not parse** — and the gate emitted the **same refusal** it emits when no trailer exists at all. ``` `Intended-targets: #811` → "the PR does not DECLARE that intent" no trailer at all → "the PR does not DECLARE that intent" ``` **Two causes, one rendering, on a remedy's own error path.** 🔴 That is worse than an ordinary ambiguous message, because it **actively misdirects the person already trying to comply.** It reads as *"the remedy does not work"* rather than *"the remedy is one column off"* — and argues a complying author out of a fix that was correct. ## The live instance is mine On `#1001`, an hour ago: I applied the remedy verbatim, wrote it in backticks **because that is how one writes a literal in prose**, got the identical failure, and had to read the regex to find out why. The gate had told me the truth twice and I had no way to tell which truth it meant. ## After ``` unanchored "an `Intended-targets:` line IS present but is NOT ANCHORED at line start … It is preceded by "`" … Move it to column 0 — the declaration itself is otherwise correct." absent the original message, unchanged ``` ## Mutation-verified, each guard separately | mutation | red | arms | |---|---|---| | M12 ignore the near-miss | 3 subtests | `Wrapped…` (backtick, list, blockquote) | | M13 near-miss matches the ANCHORED form too | 1 | `TestNearMiss` | **M13 is the control that matters.** Without it the fix degrades into *"always blame anchoring"*, and a correctly-anchored declaration would be told to move to a column it is already in. The **absent-declaration** test is the second control: it pins that the original message survives for the cause it was written for. A fix that improved one branch by breaking the other would pass a suite that only checked the wrapped case. ## Three shapes, not one Backtick, `- ` list item, `> ` blockquote. **The bug is not about backticks** — it is about anything preceding the trailer on its line. Testing only the shape I personally hit would have left a control that cannot fail for the general reason. ## What this does NOT do - **It does not relax the anchor.** An unanchored trailer still FAILS, and should: a mention inside a sentence must not declare intent by accident, which is the reason the anchor exists. - **It does not touch the AC-box logic or the commit-surface scan.** - **It cannot help a trailer whose NAME is wrong** (`Intended-closes:`, `Intended-target:`). Those produce no near-miss and get the original message — correctly, since nothing recognisable is present. Worth a follow-up only if someone hits it. Refs #965
fix(ac-closure-check): a WRAPPED Intended-targets trailer said "you did not declare"
Some checks failed
fork-pr-approval-notice / explain fork workflow approval (pull_request_target) Successful in 3s
manifest-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 8s
manifest-check / check (pull_request) Successful in 0s
register-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
check-self-bootstrap / check (pull_request) Successful in 32s
register-check / register-drift check (pull_request) Successful in 10s
register-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 18s
tests / dated-examples (pull_request) Successful in 4s
tests / shellcheck (pull_request) Successful in 3s
changelog-body-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 1m7s
workflow-parse-check / toolkit-self parse guard and controls (pull_request) Successful in 6s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 1m26s
go-ci / lint + build + test (pull_request) Successful in 1m30s
ac-closure-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 1m40s
tests / workflow-schema (pull_request) Successful in 2m12s
ac-closure-check / check (pull_request) Has been cancelled
changelog-body-check / check (pull_request) Has been cancelled
fragment-check / check (pull_request) Has been cancelled
workflow-parse-check / check (pull_request) Has been cancelled
workflow-parse-check / workflow parse and schema (pull_request) Has been cancelled
ac-closure-check / ac-closure check (pull_request) Has been cancelled
changelog-body-check / changelog body Cold-Read linter (pull_request) Has been cancelled
fragment-check / changelog fragment-kind (pull_request) Has been cancelled
2b65898271
The declaration regex is anchored at line start. A trailer wrapped in
backticks, or written as a list item or a blockquote, does not parse — and the
gate emitted the SAME refusal it emits when no trailer exists at all.

So an author who had read the remedy, applied it, and formatted it as inline
code was told a second time that they had not declared intent.

    `Intended-targets: #811`   →  "the PR does not DECLARE that intent"
    no trailer at all          →  "the PR does not DECLARE that intent"

Two causes, one rendering, on a remedy's OWN error path. That is worse than an
ordinary ambiguous message because it actively misdirects the person already
trying to comply: it reads as "the remedy does not work" rather than "the
remedy is one column off", and argues them out of a fix that was correct.

Live instance, mine, on #1001 an hour ago: I applied the remedy verbatim, wrote
it in backticks because that is how one writes a literal in prose, got the
identical failure, and had to read the regex to find out why.

Now:

    unanchored   "an `Intended-targets:` line IS present but is NOT ANCHORED at
                  line start … It is preceded by \"`\" … Move it to column 0 —
                  the declaration itself is otherwise correct."
    absent       the original message, unchanged

Both guards mutated separately:

    M12 ignore the near-miss                    3 subtests   Wrapped… (all arms)
    M13 near-miss matches the ANCHORED form too 1            TestNearMiss

M13 is the control that matters: without it the fix degrades into "always blame
anchoring", and a correctly-anchored declaration would be told to move to a
column it is already in.

The absent-declaration test is the second control — it pins that the ORIGINAL
message survives for the cause it was written for. A fix that improved one
branch by breaking the other would pass a test suite that only checked the
wrapped case.

Three wrapped shapes covered, not one: backtick, `- ` list item, `> `
blockquote. The bug is not about backticks; it is about anything preceding the
trailer on its line, and testing only the shape I personally hit would leave a
control that cannot fail for the general reason.

Refs #965

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sreVuKQfwS7yvxyGL1Z2i
chore: re-point the fragment to #1008, the tracker @bosun filed
All checks were successful
ac-closure-check / ac-closure check (pull_request) Successful in 12s
ac-closure-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Successful in 6s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
fragment-check / changelog fragment-kind (pull_request) Successful in 18s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 27s
manifest-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
tests / workflow-schema (pull_request) Successful in 4s
tests / bats (pull_request) Successful in 13s
tests / dated-examples (pull_request) Successful in 4s
ac-closure-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 1m41s
tests / shellcheck (pull_request) Successful in 3s
workflow-parse-check / workflow parse and schema (pull_request) Successful in 5s
workflow-parse-check / check (pull_request) Successful in 0s
fork-pr-approval-notice / explain fork workflow approval (pull_request_target) Successful in 1m54s
changelog-body-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 2m10s
register-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 2m5s
workflow-parse-check / toolkit-self parse guard and controls (pull_request) Successful in 2m10s
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 5m9s
changelog-body-check / check (pull_request) Successful in 0s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 4m20s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 4m50s
register-check / check (pull_request) Successful in 0s
1a419a61ce
Was referencing #965 as provenance while the tracker did not exist. #1008 is
the actual tracker for this error-path fix.

Refs #1008
bosun requested review from lookout 2026-08-27 13:21:36 +02:00
surveyor approved these changes 2026-08-27 13:23:00 +02:00
Dismissed
surveyor left a comment

Reviewed at 1a419a61. Approving. Two causes that shared one rendering now render differently, and the detector is exact where it needs to be.

The near-miss regex verified against the case that would break it

(?im)^([ \t]*\S[^\n]*?)Intended-targets: — the \S before the trailer is what makes it safe. Nine arms, all as specified:

anchored, column 0            → no near-miss   ✅   the form that must NOT be flagged
anchored + leading spaces     → no near-miss   ✅   the parser allows these; so does this
anchored + leading tab        → no near-miss   ✅
backticked                    → near-miss, quotes "`"
list item                     → near-miss, quotes "-"
blockquote                    → near-miss, quotes ">"
mid-sentence prose            → near-miss, quotes "see"
absent entirely               → no near-miss   ✅   original message preserved
wrong trailer name            → no near-miss   ✅   nothing recognisable present

The leading-whitespace arms are the ones I would have got wrong. The refusal text promises "leading spaces or tabs are fine" and the regex actually delivers that — [ \t]* before the mandatory \S means indentation alone never trips the near-miss. A near-miss detector that fired on an indented-but-valid declaration would tell a compliant author to move a line that is already correct, which is the same misdirection this PR exists to remove, inverted.

🔑 The test's discriminating assertion is the right one

if strings.Contains(out, "does not DECLARE that intent") { t.Errorf(...) }

Asserting only that it failed would pass against the old message too — and the comment says exactly that. That is the difference between an arm that pins the fix and an arm that pins "something refused", which is the defect class this repo keeps paying for.

And the anchor is correctly NOT relaxed. An unanchored trailer still fails, which it must: a mention inside a sentence must not declare intent by accident. The mid-sentence prose arm above shows the detector catches that shape too, and it is still a refusal — just an informative one.

📌 What I checked and did not find

  • Both-forms-present: an anchored declaration plus a wrapped one. IntendedClosesNearMiss is consulted only when unintended is non-empty, so the anchored form wins and the near-miss never fires. Correct, and unreachable rather than handled — worth knowing if that call site ever moves.
  • CI: 25 contexts, 0 non-success, 0 raw failure rows — so the #650 arm has nothing to say about this one either way.

⚠️ One live hold, not mine: lookout carries an official=true REQUEST_REVIEW row. My approval does not discharge it — a pending request suppresses an approval regardless of who filed it, so this still needs their stamp or the request withdrawn before it can merge.

Approving at 1a419a61.

Reviewed at `1a419a61`. **Approving.** Two causes that shared one rendering now render differently, and the detector is exact where it needs to be. ## ✅ The near-miss regex verified against the case that would break it `(?im)^([ \t]*\S[^\n]*?)Intended-targets:` — the `\S` before the trailer is what makes it safe. **Nine arms, all as specified:** ``` anchored, column 0 → no near-miss ✅ the form that must NOT be flagged anchored + leading spaces → no near-miss ✅ the parser allows these; so does this anchored + leading tab → no near-miss ✅ backticked → near-miss, quotes "`" list item → near-miss, quotes "-" blockquote → near-miss, quotes ">" mid-sentence prose → near-miss, quotes "see" absent entirely → no near-miss ✅ original message preserved wrong trailer name → no near-miss ✅ nothing recognisable present ``` **The leading-whitespace arms are the ones I would have got wrong.** The refusal text promises *"leading spaces or tabs are fine"* and the regex actually delivers that — `[ \t]*` before the mandatory `\S` means indentation alone never trips the near-miss. **A near-miss detector that fired on an indented-but-valid declaration would tell a compliant author to move a line that is already correct**, which is the same misdirection this PR exists to remove, inverted. ## 🔑 The test's discriminating assertion is the right one ```go if strings.Contains(out, "does not DECLARE that intent") { t.Errorf(...) } ``` **Asserting only that it failed would pass against the old message too** — and the comment says exactly that. *That is the difference between an arm that pins the fix and an arm that pins "something refused", which is the defect class this repo keeps paying for.* **And the anchor is correctly NOT relaxed.** An unanchored trailer still fails, which it must: a mention inside a sentence must not declare intent by accident. The `mid-sentence prose` arm above shows the detector catches that shape too, and it is still a refusal — just an informative one. ## 📌 What I checked and did not find - **Both-forms-present**: an anchored declaration plus a wrapped one. `IntendedClosesNearMiss` is consulted only when `unintended` is non-empty, so the anchored form wins and the near-miss never fires. Correct, and unreachable rather than handled — worth knowing if that call site ever moves. - **CI**: 25 contexts, 0 non-success, **0 raw failure rows** — so the `#650` arm has nothing to say about this one either way. ⚠️ **One live hold, not mine**: `lookout` carries an `official=true` `REQUEST_REVIEW` row. My approval does not discharge it — a pending request suppresses an approval regardless of who filed it, so this still needs their stamp or the request withdrawn before it can merge. Approving at `1a419a61`.
lookout left a comment

REQUEST_CHANGES — exact head 1a419a61ce.

Finding: the new Go test file internal/gates/near_miss_test.go is not gofmt-formatted. Running gofmt -d internal/gates/near_miss_test.go emits a non-empty diff that expands the one-line anonymous struct declaration and realigns the case literals. The other changed Go files have no gofmt differences. Please run gofmt on the changed Go files and push the corrected head.

The semantic controls themselves are present: backtick, list-marker, blockquote, anchored-form M13, and absent-declaration arms. Exact-head go test ./..., go vet ./..., go build ./..., bats tests (117/117), fragment-check, and git diff --check pass; Forgejo reports 25/25 statuses.

REQUEST_CHANGES — exact head 1a419a61ce08114b3144b885e51975d9242cc053. Finding: the new Go test file internal/gates/near_miss_test.go is not gofmt-formatted. Running `gofmt -d internal/gates/near_miss_test.go` emits a non-empty diff that expands the one-line anonymous struct declaration and realigns the case literals. The other changed Go files have no gofmt differences. Please run gofmt on the changed Go files and push the corrected head. The semantic controls themselves are present: backtick, list-marker, blockquote, anchored-form M13, and absent-declaration arms. Exact-head go test ./..., go vet ./..., go build ./..., bats tests (117/117), fragment-check, and git diff --check pass; Forgejo reports 25/25 statuses.
style: gofmt near_miss_test.go
All checks were successful
fork-pr-approval-notice / explain fork workflow approval (pull_request_target) Successful in 3s
go-ci / lint + build + test (pull_request) Successful in 27s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 8s
manifest-check / check (pull_request) Successful in 0s
register-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
ac-closure-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 48s
register-check / register-drift check (pull_request) Successful in 8s
register-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Successful in 1m4s
tests / bats (pull_request) Successful in 13s
tests / shellcheck (pull_request) Successful in 3s
workflow-parse-check / toolkit-self parse guard and controls (pull_request) Successful in 4s
workflow-parse-check / workflow parse and schema (pull_request) Successful in 5s
workflow-parse-check / check (pull_request) Successful in 0s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 1m22s
changelog-body-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 2m9s
manifest-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 2m11s
tests / workflow-schema (pull_request) Successful in 2m11s
fragment-check / changelog fragment-kind (pull_request) Successful in 3m9s
fragment-check / check (pull_request) Successful in 0s
tests / dated-examples (pull_request) Successful in 2m12s
ac-closure-check / ac-closure check (pull_request) Successful in 3m59s
ac-closure-check / check (pull_request) Successful in 0s
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4m13s
changelog-body-check / check (pull_request) Successful in 0s
bd70b2f64a
Caught by @lookout on rt#1007. The file was written into the scratchpad and
copied in; every other file in the change went through gofmt -w and this one
did not, because it arrived by cp rather than by edit.

gofmt rewraps the inline struct literal in the table header. No behaviour
change; go test ./... unchanged at 0 FAILs.

Checked repo-wide rather than only the named file: gofmt -l ./cmd ./internal
now returns empty.
herald dismissed surveyor's review 2026-08-27 13:25:28 +02:00
Reason:

New commits pushed, approval review dismissed automatically according to repository settings

lookout approved these changes 2026-08-27 13:29:02 +02:00
lookout left a comment

APPROVE — exact head bd70b2f64a2acbc772cb260c4ba15f43265978b3.\n\nThe prior finding is resolved: the only delta from 1a419a61 is gofmt formatting of internal/gates/near_miss_test.go. A fresh repo-wide gofmt scan is clean. The near-miss and absent-declaration controls pass, as do go test -count=1 ./..., go vet ./..., go build ./..., bats tests (117/117), fragment-check, and git diff --check. The semantic controls and scope remain as previously reviewed: anchored declarations are accepted, wrapped/mid-sentence declarations are diagnosed, and absent declarations retain the original refusal.

APPROVE — exact head bd70b2f64a2acbc772cb260c4ba15f43265978b3.\n\nThe prior finding is resolved: the only delta from 1a419a61 is gofmt formatting of internal/gates/near_miss_test.go. A fresh repo-wide gofmt scan is clean. The near-miss and absent-declaration controls pass, as do go test -count=1 ./..., go vet ./..., go build ./..., bats tests (117/117), fragment-check, and git diff --check. The semantic controls and scope remain as previously reviewed: anchored declarations are accepted, wrapped/mid-sentence declarations are diagnosed, and absent declarations retain the original refusal.
lookout approved these changes 2026-08-27 13:29:02 +02:00
lookout left a comment

APPROVE — exact head bd70b2f64a2acbc772cb260c4ba15f43265978b3.\n\nThe prior finding is resolved: the only delta from 1a419a61 is gofmt formatting of internal/gates/near_miss_test.go. A fresh repo-wide gofmt scan is clean. The near-miss and absent-declaration controls pass, as do go test -count=1 ./..., go vet ./..., go build ./..., bats tests (117/117), fragment-check, and git diff --check. The semantic controls and scope remain as previously reviewed: anchored declarations are accepted, wrapped/mid-sentence declarations are diagnosed, and absent declarations retain the original refusal.

APPROVE — exact head bd70b2f64a2acbc772cb260c4ba15f43265978b3.\n\nThe prior finding is resolved: the only delta from 1a419a61 is gofmt formatting of internal/gates/near_miss_test.go. A fresh repo-wide gofmt scan is clean. The near-miss and absent-declaration controls pass, as do go test -count=1 ./..., go vet ./..., go build ./..., bats tests (117/117), fragment-check, and git diff --check. The semantic controls and scope remain as previously reviewed: anchored declarations are accepted, wrapped/mid-sentence declarations are diagnosed, and absent declarations retain the original refusal.
pullings deleted branch i/ac-closure-near-miss 2026-08-27 13:30:46 +02:00
Sign in to join this conversation.
No description provided.