Skip to content

check_apr_bin_pinned: an opener INSIDE a quoted string is a latent false positive (sixth wrong pattern in this class) #3836

Description

@noahgift

On PR #3835 guard-cargo failed with two BARE-APR hits that were prose, not invocations:

check_crux_inference_judge.sh:444   ok "... distinct GREEN cells; apr serve's backend unverified"
crux_inference_dogfood.sh:709       "thinking ON (apr has no toggle until #3723)",

The first is an assertion message; the second a descriptive row in a not_covered JSON array. In both, what BARE_APR read as a command opener — ; and ( — sits inside a quoted string, invisible to a line-oriented regex.

The class is specific and worth stating precisely: "apr serve's backend is unverified..." two lines above the second hit does not trigger, because " is not an opener while ( is. So it is not "apr in prose" — it is an opener character occurring inside quoted prose.

Why this was fixed at the call site, not in the regex

Both strings were reworded (72b8b07). An exemption would have to teach the pattern to ignore ; and ( before apr, and those are exactly the openers a real violation uses:

cd foo; apr qa model.apr      # real violation
(apr qa model.apr &)          # real violation

Weakening the opener class to fix a prose false positive would blind the guard to two of the commonest real shapes. The guard is right to be strict.

The work

Decide between, and implement one:

  1. Strip quoted spans before matching. A shell-aware pre-pass that removes "..." and '...' content from the line before applying BARE_APR. Cheap in awk; must handle escaped quotes and lines with unbalanced quotes (a here-doc body, a multi-line string) by failing OPEN rather than closed.
  2. Accept the limitation and document it, with a named exemption mechanism for prose lines that is narrower than "ignore this opener" — e.g. an end-of-line marker the case table covers.

Either way the 78-case table gains must-not-match rows for both shapes above and must-match rows for cd foo; apr qa and (apr qa &), so the fix cannot be made by widening the exemption into the real cases. Re-run --self-test rather than reading the pattern.

Why the priority is real but not P0

CLAUDE.md already records that this pattern class "has been wrong five times; every one was caught by a must-match/must-not-match table, none by review." This is the sixth, and the first where the correct fix was the call site rather than the regex — which is itself the finding: the guard blocked a release-night CI run on two English sentences. A guard that false-positives on prose gets exemptions added under time pressure, and an exemption added under time pressure is how the opener class gets weakened into uselessness.

Refs #2360, #2361

🤖 Generated with 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

    Labels

    P2Medium prioritygate-framework-newnew gate framework — excluded from 0.71kind:codeWork is a code change (derived rule, #4159)parkedClosed over epic budget (APR-EPIC-001 rule 5). Reopen = pull.

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions