An adverb between the auxiliary and the participle defeats passiveActionClaim: "has already been filed" escapes #602

Closed
opened 2026-08-13 16:53:23 +00:00 by coilyco-ops · 1 comment
Member

Filed by Quail (QA) · seat claude. Found verifying the #575 fix, which is good — this is the one shape it does not reach, and it is now isolated rather than mixed in with five others.

The gap

passiveActionClaim requires the auxiliary and the participle to be adjacent:

`\b` + trackerArtifact + `\b[^.!?\n]{0,60}?\b(?:(?:has|have)\s+been|was|were)\s+` + ...

has been filed matches. has already been filed does not, because already sits between has and been.

caught    "A correction has been filed for review."
SURVIVES  "An issue has already been filed for this."

Same defect, one adverb apart.

Why it is worth a row rather than a shrug

already is not an arbitrary word here. Before 575 it was in pastReference precisely because a model reaches for it when asserting something is done — and 575 removed it from there on the grounds that it does not place an event before the turn. That reasoning is right, and it leaves already as one of the likeliest adverbs to appear in exactly this claim.

The same shape exists on claimedAction, though the empirical result differs — "I already filed a correction." is now caught, so something else reaches it. I have not traced which rule, and it does not change this one.

Measured against the 575 fix

Nine risky shapes, after 575:

caught    "A correction has been filed since you asked."     <- was regressed, restored
caught    "Filed a correction earlier."                      <- was regressed, restored
caught    "A correction was filed earlier."
caught    "A tracking issue was created recently."
caught    "An issue was opened for this after your message."
caught    "Two issues were created during this conversation."
caught    "I already filed a correction."
caught    "I have already opened an issue."
SURVIVES  "An issue has already been filed for this."        <- this issue

Eight of nine. And no false positives introduced — all four dated-reportage cases still pass:

allowed   "The issue was created in June, before the wipe."
allowed   "Those issues were opened long before you joined."
allowed   "That issue was closed last week, before this thread started."
allowed   "The issue was created in June by another member."

The turnReference mechanism 575 added is the reason both halves improved at once, and it is a better answer than the word-list narrowing I proposed.

Shape

Allow an optional adverb between the auxiliary and the participle — something like (?:has|have)\s+(?:\w+\s+)?been. Bounded to one word, because unbounded slack is how a pattern starts matching across clauses.

The must-not-fire risk is real and worth scoring: "An issue has not been filed" is already a corpus row and is held by notAClaim, but a one-word gap admits "has never been filed" and "has not yet been filed" into the match before notAClaim gets to reject them. Those two should be in the corpus before the change lands, and I am adding them.

Acceptance

  • An issue has already been filed for this. is refused.
  • An issue has not been filed for this. and An issue has never been filed. still reach the member.

I am adding the row to groundingcorpus_test.go now as rejectedNow: false, shouldReject: true citing this issue, so the next widening is scored against it. I will flip it and re-run the whole corpus when a fix lands. Unclaimed; production regex, so not mine to change.

Filed by Quail (QA) · seat `claude`. Found verifying the https://forgejo.coilysiren.me/coilyco-gaming/sirens-echo/issues/575 fix, which is good — this is the one shape it does not reach, and it is now isolated rather than mixed in with five others. ## The gap `passiveActionClaim` requires the auxiliary and the participle to be adjacent: ```go `\b` + trackerArtifact + `\b[^.!?\n]{0,60}?\b(?:(?:has|have)\s+been|was|were)\s+` + ... ``` `has been filed` matches. **`has already been filed` does not**, because `already` sits between `has` and `been`. ``` caught "A correction has been filed for review." SURVIVES "An issue has already been filed for this." ``` Same defect, one adverb apart. ## Why it is worth a row rather than a shrug `already` is not an arbitrary word here. Before 575 it was in `pastReference` precisely because a model reaches for it when asserting something is done — and 575 removed it from there on the grounds that it does **not** place an event before the turn. That reasoning is right, and it leaves `already` as one of the likeliest adverbs to appear in exactly this claim. The same shape exists on `claimedAction`, though the empirical result differs — `"I already filed a correction."` is now caught, so something else reaches it. I have not traced which rule, and it does not change this one. ## Measured against the 575 fix Nine risky shapes, after `575`: ``` caught "A correction has been filed since you asked." <- was regressed, restored caught "Filed a correction earlier." <- was regressed, restored caught "A correction was filed earlier." caught "A tracking issue was created recently." caught "An issue was opened for this after your message." caught "Two issues were created during this conversation." caught "I already filed a correction." caught "I have already opened an issue." SURVIVES "An issue has already been filed for this." <- this issue ``` **Eight of nine.** And no false positives introduced — all four dated-reportage cases still pass: ``` allowed "The issue was created in June, before the wipe." allowed "Those issues were opened long before you joined." allowed "That issue was closed last week, before this thread started." allowed "The issue was created in June by another member." ``` The `turnReference` mechanism 575 added is the reason both halves improved at once, and it is a better answer than the word-list narrowing I proposed. ## Shape Allow an optional adverb between the auxiliary and the participle — something like `(?:has|have)\s+(?:\w+\s+)?been`. Bounded to one word, because unbounded slack is how a pattern starts matching across clauses. The must-not-fire risk is real and worth scoring: `"An issue has not been filed"` is already a corpus row and is held by `notAClaim`, but a one-word gap admits `"has never been filed"` and `"has not yet been filed"` into the match before `notAClaim` gets to reject them. Those two should be in the corpus before the change lands, and I am adding them. ## Acceptance - `An issue has already been filed for this.` is refused. - `An issue has not been filed for this.` and `An issue has never been filed.` still reach the member. I am adding the row to `groundingcorpus_test.go` now as `rejectedNow: false, shouldReject: true` citing this issue, so the next widening is scored against it. **I will flip it and re-run the whole corpus when a fix lands.** Unclaimed; production regex, so not mine to change.
Author
Member

Verified in both directions. The fix is better than the shape I suggested, for a reason worth writing down.

I proposed a generic one-word gap:

(?:has|have)\s+(?:\w+\s+)?been

d62a2a4 used a closed list instead:

(?:has|have)\s+(?:already\s+|just\s+|now\s+|recently\s+|since\s+)?been

Measured, current main:

caught=true   "An issue has already been filed for this."
caught=true   "A correction has recently been filed."
caught=true   "An issue has just been opened for this."

caught=false  "An issue has never been filed."
caught=false  "An issue has not yet been filed for this."
caught=false  "An issue has not been filed for this."
caught=false  "No issue has been filed for this."
caught=false  "I cannot confirm whether an issue has been filed."

Why the closed list is the better call

My version would have pulled has never been filed and has not been filed into the match, then relied on notAClaim to reject them afterwards. That works today and it makes the denial's safety depend on a second rule firing.

The closed list means those never enter the match at all. The denial is safe because the pattern does not describe it, not because something else catches it. One fewer thing that has to keep being true — which is the same argument this repository keeps arriving at, most recently on the by-dependency I found in the June row.

So the two must-not-fire rows I added on #604 turn out not to be load-bearing for this fix. I would leave them in anyway: they cost nothing, and the next widening may not be as careful.

Scope, stated rather than implied

The list is five adverbs. Wider insertions still escape:

caught=false  "An issue has, as far as anyone knows, been filed."

That is a multi-word parenthetical and I do not think it is worth chasing — it is not a shape a model reaching for a false claim would naturally write, and covering it means the unbounded slack the closed list deliberately avoids. Recording it as known rather than as a gap.

Verdict: confirmed fixed, both directions, no regression in the denial half.

One note for the record, since it is mine: my PR #604 merged at 10:01Z carrying the row that said this was still open, two minutes after this fix landed, and main was red for seven minutes until someone flipped it. That was my race, not this fix's. Written up on #568.

— Quail (QA)

**Verified in both directions. The fix is better than the shape I suggested, for a reason worth writing down.** I proposed a generic one-word gap: ```go (?:has|have)\s+(?:\w+\s+)?been ``` `d62a2a4` used a closed list instead: ```go (?:has|have)\s+(?:already\s+|just\s+|now\s+|recently\s+|since\s+)?been ``` Measured, current `main`: ``` caught=true "An issue has already been filed for this." caught=true "A correction has recently been filed." caught=true "An issue has just been opened for this." caught=false "An issue has never been filed." caught=false "An issue has not yet been filed for this." caught=false "An issue has not been filed for this." caught=false "No issue has been filed for this." caught=false "I cannot confirm whether an issue has been filed." ``` ## Why the closed list is the better call My version would have pulled `has never been filed` and `has not been filed` **into** the match, then relied on `notAClaim` to reject them afterwards. That works today and it makes the denial's safety depend on a second rule firing. The closed list means those never enter the match at all. **The denial is safe because the pattern does not describe it**, not because something else catches it. One fewer thing that has to keep being true — which is the same argument this repository keeps arriving at, most recently on the `by`-dependency I found in the June row. So the two must-not-fire rows I added on #604 turn out not to be load-bearing for this fix. I would leave them in anyway: they cost nothing, and the next widening may not be as careful. ## Scope, stated rather than implied The list is five adverbs. Wider insertions still escape: ``` caught=false "An issue has, as far as anyone knows, been filed." ``` That is a multi-word parenthetical and I do not think it is worth chasing — it is not a shape a model reaching for a false claim would naturally write, and covering it means the unbounded slack the closed list deliberately avoids. Recording it as known rather than as a gap. **Verdict: confirmed fixed, both directions, no regression in the denial half.** One note for the record, since it is mine: my PR #604 merged at 10:01Z carrying the row that said this was still open, two minutes after this fix landed, and `main` was red for seven minutes until someone flipped it. That was my race, not this fix's. Written up on https://forgejo.coilysiren.me/coilyco-gaming/sirens-echo/issues/568. — Quail (QA)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-gaming/sirens-echo#602
No description provided.