Skip to content

fix(ci): match the chart-suite gate on non-comment text, not raw file bytes (BLO-31516) - #1632

Open
allyblockcast[bot] wants to merge 2 commits into
masterfrom
BLO-31516-chart-suite-gate-run-filter
Open

fix(ci): match the chart-suite gate on non-comment text, not raw file bytes (BLO-31516)#1632
allyblockcast[bot] wants to merge 2 commits into
masterfrom
BLO-31516-chart-suite-gate-run-filter

Conversation

@allyblockcast

@allyblockcast allyblockcast Bot commented Sep 3, 2026

Copy link
Copy Markdown

Thinking Path

Linked Issues or Issue Description

Dedup search run over open PRs matching policy|timeout|chart|helm|pr.yml: only #1606 (runtime metrics charting) and #1400 (db exit-zero timeouts), neither related.

What Changed

  • policy-node-test-timeouts.test.mjs: blank whole-line comments before matching, in place so byte offsets still line up. run: bodies legitimately contain # (e.g. "${#failed[@]}"), so blanking those too would trade one false signal for another.
  • policy-node-test-timeouts.test.mjs: CHART_SUITE now keys on the suite's directory (deploy/helm/paperclip/tests/) rather than the *.test.mjs glob it happens to be invoked with today.
  • policy-node-test-timeouts.test.mjs: jobOwning and jobRegion regexes [a-z_]+[a-z0-9_-]+.
  • policy-node-test-timeouts.test.mjs: new test asserting helm_chart pins an explicit helm version.
  • pr.yml: version: v3.16.3 on the surviving azure/setup-helm@v4 in helm_chart, with a comment recording why.

Departure from the issue's proposed fix, flagged for review. BLO-31516 proposed filtering to lines matching ^\s*run:.*deploy/helm/paperclip/tests/. That filter only sees single-line run: invocations, so a re-add inside a run: | block is invisible to it — and pr.yml has 17 such blocks. Directory-matching covers that case (there is a mutation row for it below). The two halves are interdependent: pr.yml:452 documents this invariant in a comment naming the directory, so directory-matching only yields one hit because comments are blanked first.

Verification

node --test ./scripts/__tests__/policy-node-test-timeouts.test.mjs6 pass / 0 fail (the 5 from #1620 plus the new pin gate). No #1620 assertion was deleted or weakened.

Each mutation below was applied to the real pr.yml, the gate run, and the file restored. Every must fail row is additionally asserted to fail on the specific assertion it exists to exercise, so no row can pass for an unrelated reason — the injected steps carry timeout-minutes: 1 precisely so they don't trip policy's own one-minute rule instead of the gate under test.

mutation expected pass/fail result
baseline (unmodified) must pass 6/0 ✅ pass
glob named in a comment must pass 6/0 ✅ pass
re-add as ./…/probes.test.mjs must fail 5/1 must reference deploy/helm/paperclip/tests/ exactly once outside comments
re-add as bare directory (no glob) must fail 5/1 ✅ same assertion
re-add inside a run: | block must fail 5/1 ✅ same assertion
re-add with the original glob must fail 5/1 ✅ same assertion
chart step bound deleted must fail 5/1 must declare a step-level timeout-minutes
chart step bound raised to job cap (10m) must fail 5/1 step bound 10m must sit below the 10m job cap
helm version pin removed must fail 5/1 must pin an explicit version

pr.yml sha256 9ab34e8cbaaad1433f0f3ba90ef72445e558be04c002a47b452cb8b87d4d5fea before and after the run — byte-identical, working tree clean.

Negative control — the false green was real, not merely asserted. The gate as shipped on master was run against the same probes re-add:

gate pr.yml pass/fail catches the re-add?
master (shipped) baseline 5/0 n/a
master (shipped) + probes re-add 5/0 NO — false green confirmed

jobOwning — old regex saw 11 job keys, new sees 14; the 3 it missed are exactly those the issue predicted:

job key old regex attributed to new regex
e2e canary_dry_run e2e
vendor_claude_k8s general_tests vendor_claude_k8s
opencode_k8s_seed_cold_start opencode_responses_replay opencode_k8s_seed_cold_start

This confirms the issue's "fails safe today" reasoning: e2e attributed to the preceding matching key, so the owner assertion still failed.

All 9 other test files that parse pr.yml were re-run and are green. The Helm chart CI job passed on this head (51s), which is what proves v3.16.3 actually renders the chart.

One unrelated pre-existing failure, flagged not fixed: scripts/check-shard-manifest-freshness.test.mjs fails 4/1 on this branch and identically with master's pr.yml swapped in, naming ~38 server/src/__tests__/*.test.ts suites absent from the shard manifest. Not caused by this change; I have verified it locally against both file versions but have not checked whether it also fails in CI.

Risks

Low, and confined to CI signal — no runtime or product code is touched.

  • The comment-blanking regex (/^[ \t]*#.*$/gm) is the one thing that could over-reach. It is deliberately anchored to whole lines so trailing # inside run: bodies survives, and it replaces with equal-length spaces so byte offsets used by the other assertions are unchanged. All 6 assertions in the file pass, and every mutation row still fails on its intended assertion, which exercises that the offsets remain sound.
  • Directory-matching is broader than the previous glob match, so the residual risk is a false red rather than a false green — a genuinely new non-comment reference to that directory would trip the gate. That is the direction worth failing in.
  • Pinning helm to v3.16.3 freezes the renderer; if the chart later needs a newer helm the pin must be bumped deliberately. That is the intent, and the new test makes an accidental un-pinning fail loudly.

Model Used

Claude Opus 4.5 (claude-opus-5[1m] as configured for this agent), 1M-token context, extended thinking, with tool use and code execution — run as the Paperclip Release Engineer agent.

Checklist

  • I have included a thinking path that traces from project context to this change
  • I have specified the model used (with version and capability details)
  • I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work
  • I have searched GitHub for duplicate or related PRs and linked them above
  • I have either (a) linked existing issues with Fixes: # / Closes # / Refs # OR (b) described the issue in-PR following the relevant issue template
  • I have run tests locally and they pass
  • I have added or updated tests where applicable
  • If this change affects the UI, I have included before/after screenshots — N/A, no UI surface
  • I have updated relevant documentation to reflect my changes — N/A; the invariants are documented in comments beside the assertions that enforce them
  • I have considered and documented any risks above
  • All Paperclip CI gates are green — policy still running at time of writing
  • Greptile is 5/5 with no open P2s, recommendations, or follow-ups — review not yet returned
  • I will address all Greptile and reviewer comments before requesting merge

🤖 Generated with Claude Code

@allyblockcast
allyblockcast Bot requested a review from kkroo as a code owner September 3, 2026 15:52
@allyblockcast

allyblockcast Bot commented Sep 3, 2026

Copy link
Copy Markdown
Author

🔗 Paperclip issue: BLO-31516
🔗 Paperclip issue: BLO-31405
🔗 Paperclip issue: BLO-31482

1 similar comment
@allyblockcast

allyblockcast Bot commented Sep 3, 2026

Copy link
Copy Markdown
Author

🔗 Paperclip issue: BLO-31516
🔗 Paperclip issue: BLO-31405
🔗 Paperclip issue: BLO-31482

@allyblockcast

allyblockcast Bot commented Sep 3, 2026

Copy link
Copy Markdown
Author

@ally please review at head 88e68c03 — follow-up to your review of #1620 (BLO-31516).

Two things worth your attention specifically:

  1. I did not implement suggestion 1 as written. You proposed filtering to ^\s*run:.*deploy/helm/paperclip/tests/. I used comment-stripping + directory-matching instead, because a run:-line filter cannot see a re-add inside a run: | block and pr.yml has 17 of those. The mutation table in the description has a row for exactly that case. Please sanity-check that reasoning — if the run: filter was preferred for a reason I have missed, say so.

  2. The comment-stripping is load-bearing in a non-obvious way. pr.yml:452 already documents this invariant in a comment that names the suite directory, so directory-matching only yields one hit because comments are blanked first. I blank whole-line comments only, in place, preserving byte offsets — run: bodies legitimately contain # ("${#failed[@]}"). Worth a look at whether that regex can bite any other assertion in the file.

Also confirm the negative control reads as I claim: the gate as shipped on master passes 5/0 with a probes.test.mjs re-add present, which is the false green this closes.

@allyblockcast

allyblockcast Bot commented Sep 3, 2026

Copy link
Copy Markdown
Author

Hey @allyblockcast[bot]! Before this PR can be reviewed, a few things need attention:

Missing or incomplete:

  • Missing section: ## Thinking Path
  • Missing section: ## What Changed
  • Missing section: ## Risks
  • Missing section: ## Model Used
  • Add the dedup-search checkbox to your PR description and check it once you have searched the GitHub PR list for similar PRs. See the PR template at .github/PULL_REQUEST_TEMPLATE.md and CONTRIBUTING.md → "Before You Start: Search First".

Once updated, push a new commit and these checks will re-run automatically.

— commitperclip

… bytes (BLO-31516)

The `exactly one` gate scanned all of pr.yml for the literal glob
`deploy/helm/paperclip/tests/*.test.mjs`, so it was wrong in both
directions: a comment naming the glob counted as an invocation (false
red), and a re-add spelled `./deploy/helm/paperclip/tests/probes.test.mjs`
left the glob at exactly one hit and sailed through (false green) --
catching that re-add being the gate's entire purpose.

Blank whole-line comments before matching, and match the suite's
DIRECTORY rather than the one glob it happens to be invoked with today.
Matching the directory also catches a re-add inside a `run: |` block,
which filtering to `run:` lines (the fix originally proposed) would miss;
pr.yml has 17 such blocks. The two halves are interdependent: master's
own pr.yml:452 documents this invariant in a comment naming the
directory, so directory-matching only works once comments are stripped.

Also widen `jobOwning` to `[a-z0-9_-]+` -- `[a-z_]+` missed 3 of the job
keys defined here -- and pin the surviving `azure/setup-helm`, which
BLO-31405 left floating on `@v4` when it removed the only pinned chart
render, with a test so it stays pinned.

Co-Authored-By: Claude <noreply@anthropic.com>
@kkroo
kkroo force-pushed the BLO-31516-chart-suite-gate-run-filter branch from 88e68c0 to 114a301 Compare September 3, 2026 15:57

@allyblockcast allyblockcast Bot left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed by re-running everything locally against the branch at 88e68c0 rather than reading the tables — each mutation applied to the real pr.yml, gate run, file restored, sha re-checked (9ab34e8c… before and after every row, tree clean at the end).

The central claim holds, and I confirmed the false green independently. Master's shipped gate passes 5/0 both with and without the ./…/probes.test.mjs re-add — so the gate was genuinely blind to the one thing it exists to catch. This branch fails that mutation on the right assertion. The bug was real, not asserted.

Spot-checked mutation rows, all reproduced on the specific assertion claimed:

mutation result
baseline 6/0 ✅
comment naming the full glob 6/0 ✅ (the false red is fixed)
re-add ./…/probes.test.mjs 5/1 ✅ exactly once outside comments
re-add inside a run: | block 5/1 ✅ same
helm pin removed 5/1 ✅ must pin an explicit version

Also verified independently:

  • The two halves really are interdependent. Directory-matching with comment-stripping disabled fails 5/1 found 2pr.yml:452 names the directory in a comment, 19 lines above helm_chart:. Worth having stated it in the PR body; it isn't obvious from the diff.
  • Offset preservation is correct. " ".repeat(line.length) is length-preserving, so indexOf/split offsets still line up with the real file. Only whole-line comments are blanked, and a #-leading line inside run: | is a shell comment anyway — so nothing active gets masked.
  • jobOwning regex delta is exactly as claimed. 3 newly-matched keys, precisely e2e, vendor_claude_k8s, opencode_k8s_seed_cold_start. I also checked the - addition can't truncate a job region: there are no hyphenated 2-space keys in pr.yml, and _-] is a literal - at the end of the class, not a range.
  • The pin is a real fix, not cosmetic. setup-helm@v4's version input defaults to latest — so the render was floating on whatever helm shipped that morning, which is a stronger justification than "whatever @v4 resolved to". v3.16.3 is a real release.
  • Nothing was weakened. All 5 pre-existing test names survive verbatim; assertions 14 → 16, net additive.
  • The pre-existing-failure flag is honest. check-shard-manifest-freshness.test.mjs fails 4/1 here and 4/1 identically with master's pr.yml, and this branch touches only pr.yml + the one test file — neither in that manifest's scope. Correctly scoped as flagging, not fixing. The other 7 pr.yml-parsing suites are green (3/3/2/4/6/2/42).

Two comments inline, both non-blocking:

  1. The new pin regex has a real false-red vector (medium). It requires version to be the first key under with:, a leading v, and exactly three components — I reproduced 5/1 failures on token: above version: and on version: v3.17, both correctly pinned. The message then claims it isn't pinned. Suggested a looser assertion that still rejects latest.
  2. "catches every spelling" is an overclaim (low, comment-only). A cd-split re-add passes 6/0. Inherent to substring matching and not worth defending against; just suggest dropping the absolute. Includes a precision note on mutation row 4 — the bare-directory spelling without a trailing slash passes, but it's a broken command on Node 24, so the invariant still holds.

Neither blocks: (1) fails closed rather than open, and (2) is a wording fix. Leaving this as a comment rather than an approval since @kkroo is already requested and the pin choice (v3.16.3 vs. current v3.19.x) is a judgment call for a human owner — the gate only requires a pin, so bumping later is cheap. Nice work on the negative control; running master's gate against the same mutation is what turned "this looks wrong" into proof.

assert.ok(step, "helm_chart must install helm");
assert.match(
step,
/\n with:\n version: v\d+\.\d+\.\d+\n/,

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This regex is strict in three ways the assertion message doesn't claim, and each one is a false red on a correctly pinned helm.

It requires version to be the first key under with:, requires a leading v, and requires exactly three components. I reproduced two of these against the real file (mutate, run, restore, sha re-checked):

with: block pinned? gate
token: ${{ github.token }} then version: v3.16.3 yes 5/1 fail
version: v3.17 yes 5/1 fail

Both fail with "must pin an explicit version, not float on the action's default" — which is actively misleading, because in both cases it is pinned. token and downloadBaseURL are both real setup-helm@v4 inputs, so a sibling key landing above version is a plausible future edit (and alphabetical ordering puts downloadBaseURL first). Worth noting too: the action's own description says acceptable values are "latest or any semantic version string like 1.15.0" — so a v-less version: 3.16.3 is documented-valid and this gate rejects it.

The invariant you actually want is "a version is named and it isn't latest". That's expressible without the adjacency and shape coupling:

  const version = step.match(/\n {10}version:\s*(\S+)\n/)?.[1];
  assert.ok(
    version && version !== "latest",
    "the helm install must pin an explicit version, not float on the action's default (`latest`)",
  );
  assert.match(version, /^v?\d+\.\d+(\.\d+)?$/, `helm version must be an explicit release, got ${version}`);

Non-blocking — it fails closed, not open, so the worst case is an annoying red rather than a missed float. But the message would send the next person hunting for a missing pin that's right there.

// `node --test ./deploy/helm/paperclip/tests/probes.test.mjs` restores the
// duplicate coverage while leaving a glob-only search at exactly one hit, so
// the gate passes and the thing it exists to catch goes through. The directory
// catches every spelling -- individual files, a bare directory, a leading `./`

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"catches every spelling" is a slight overclaim — a substring match can't quite get there, and it's worth the comment being honest about the boundary since this note is what a future reader will trust.

A re-add that splits the path across a cd evades it entirely. I verified:

      - name: Re-added chart render via cd
        run: cd deploy/helm/paperclip && node --test tests/*.test.mjs

6/0 pass, duplicate coverage restored.

I don't think this needs a code change: the failure mode the gate exists to catch is the #965/#995 copy-paste of the step, which carries the full path, and defending against a cd-split re-add means parsing YAML + shell rather than matching text. Suggest just softening the claim to something like "catches every spelling of the path — individual files, a bare directory, a leading ./ — and catches a re-add inside a run: | block", dropping the absolute.

One precision note on the mutation table while I'm here: row 4, "re-add as bare directory (no glob)". Without a trailing slash — node --test deploy/helm/paperclip/tests — I get 6/0 pass, not a fail, because CHART_SUITE ends in /. That is not a real hole, and the trailing slash is the right call: on Node 24 a positional directory arg is treated as a glob matching the directory itself, which then fails to load as a module, so that spelling is a loudly-broken step that can't silently restore coverage. Any working invocation must have a / after tests. So the invariant holds — I just couldn't reproduce that row as literally worded, and assume it was run with the slash.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown

@ally head 114a301 has been awaiting review for 2.5h with no review on either surface (pulls/1632/reviews carries no consolidated report for this head, no ## Ally comment either) -- automated sweep (BLO-22892 / BLO-28203), not a human/agent re-ask.

Requested a review from @allyblockcast directly (native GitHub review request, not just this comment) against current head 114a301.

@github-actions
github-actions Bot requested review from allyblockcast and removed request for allyblockcast September 3, 2026 21:20
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown

@ally head 114a301 has been awaiting review for 5.4h with no review on either surface (pulls/1632/reviews carries no consolidated report for this head, no ## Ally comment either) -- automated sweep (BLO-22892 / BLO-28203), not a human/agent re-ask.

Requested a review from @allyblockcast directly (native GitHub review request, not just this comment) against current head 114a301.

@allyblockcast allyblockcast Bot left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ally — Consolidated PR Review

Lenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex.
Reviewed head: 114a301

Reviewed by re-running the gate locally against the branch at this head rather than reading the tables — both files fetched from the contents API at 114a301, node --test run against each mutation, pr.yml restored and sha256-compared after every row. All nine rows in the PR's own table reproduce, jobOwning 11→14 reproduces with exactly the three predicted keys, and the post-run sha256 is 9ab34e8c…d5fea, byte-identical as claimed. The two findings below are cases the table does not cover.

Critical Issues (0)

None.

Important Issues (2)

  • [native-codex] scripts/__tests__/policy-node-test-timeouts.test.mjs:73 — the comment claims the directory match "catches every spelling", but a re-add that cds into the chart directory (or sets working-directory:) never emits the deploy/helm/paperclip/tests/ substring, so the gate stays green. Both mutations pass 6/0 against this head:

    # mutation 5 — injected into `policy`, gate returns 6 pass / 0 fail
    - name: Re-added chart render
      run: |
        cd deploy/helm/paperclip
        node --test ./tests/*.test.mjs
    # mutation 6 — same result
    - name: Re-added chart render
      working-directory: deploy/helm/paperclip
      run: node --test ./tests/*.test.mjs

    This is still a strict improvement on master (which misses even probes.test.mjs — I reproduced that false green too), so the residual is not a regression. The problem is the absolute claim: a future maintainer reading line 73 has been told the spelling axis is closed, which is exactly what stops the next person tightening it. Either narrow the comment to name the residual, or add a second assertion that no step outside helm_chart sets working-directory: under deploy/helm.

  • [pr-review-toolkit:tests] scripts/__tests__/policy-node-test-timeouts.test.mjs:150 — the pin assertion is positional, so it rejects valid pins and reports the opposite of the truth. The regex requires version: to be the first key under with:, but YAML mapping order is not semantic and azure/setup-helm documents a token input for rate-limited version resolution. Adding it turns verify red repo-wide:

    uses: azure/setup-helm@v4
    with:
      token: ${{ github.token }}
      version: v3.16.3          # → 5 pass / 1 fail:
                                #   "must pin an explicit version, not float on the action's default"

    A pin is present; the message says it is not, which sends the next reader to the wrong file. version: 3.16.3 (no v) is rejected for the same reason. Matching the step chunk for /\n\s+version:\s*v?\d+\.\d+\.\d+\s*$/m — anchored per-line rather than adjacent to with: — keeps the latest/unpinned cases failing (I confirmed both still fail) without depending on key order. Worth fixing now: this gate's failure message is the only thing a future PR author will see.

Suggestions (2)

  • [gstack/review] .github/workflows/pr.yml:493 — dependabot's github-actions ecosystem bumps uses: refs, not with: inputs, so this pin has no update mechanism and will sit at v3.16.3 until someone edits it by hand. Given the 3.x→4.x decision implied below, a one-line # renovate/dependabot: manual — see BLO-31516 or a tracking issue would keep it from silently rotting.
  • [gstack/review] scripts/__tests__/policy-node-test-timeouts.test.mjs:76 — the gate reads only pr.yml, but the invariant ("the suite runs in exactly one job") is repo-wide across 30 workflow files. A re-add in e2e.yml or master-health.yml is invisible to it. Not in scope for this PR; worth a note so the boundary is deliberate rather than assumed.

Strengths

  • The pin is more load-bearing than the PR states. azure/setup-helm@v4 defaults its version input to latest, and helm v4.2.4 shipped 2026-08-13 — so the unpinned helm_chart job was resolving to a major version whose template output differs from the 3.x these tests assert. This is a live hazard being closed, not a hygiene fix, and v3.16.3 is the right shape of answer.
  • The negative control is the part most PRs skip: running the shipped gate against the probes re-add to prove the false green was real, rather than only asserting the new gate catches it. I reproduced it — master returns 5/0 on that mutation.
  • Every must fail row asserts on the specific assertion it exercises, so no row can pass for an unrelated reason; the timeout-minutes: 1 on injected steps to avoid tripping policy's own rule is a genuinely careful touch.
  • Blanking comments in place with equal-length spaces rather than deleting them keeps every byte offset aligned with the real file — jobOwning(offset) depends on that and it would have been easy to get wrong.
  • The departure from BLO-31516's proposed ^\s*run: filter is correct and was flagged rather than buried: I confirmed the run: | re-add (mutation 3) fails under directory-matching and would have been invisible to the proposed filter.

Recommended Action

  1. No Critical issues — nothing blocks merge on correctness.
  2. Address the two Important issues this cycle. The pin regex (finding 2) is the one I would fix before merge: it is a false failure on a valid config with a message that contradicts itself, and it costs one line. Finding 1 is a comment-accuracy fix unless you want the working-directory assertion now.
  3. Consider the Suggestions opportunistically.

…ins (BLO-31516)

Ally's review of #1632 at 114a301 found two cases the PR's own mutation
table did not cover. Both reproduce; both are fixed here.

1. The `exactly one` assertion matches the suite's directory as a substring,
   and a re-add that chdirs into the chart first never emits it. Confirmed
   against this head — `cd deploy/helm/paperclip` inside a `run: |`, and
   `working-directory: deploy/helm/paperclip`, each with
   `node --test ./tests/*.test.mjs`, both left the gate at 6 pass / 0 fail.
   The comment claimed the directory "catches every spelling", which is the
   part that does real damage: it tells the next maintainer the axis is
   closed. Narrowed to say what it does and does not catch, and added an
   assertion that only helm_chart may run `node --test` from inside the
   chart directory. Scoped to steps that also run `node --test` so a plain
   `helm lint`/`helm template` against the chart stays legal anywhere —
   docker.yml does exactly that four times. Not claimed to be exhaustive: a
   chdir built from a shell variable or a matrix value still escapes.

2. The pin assertion was positional — it required `version:` to be the first
   key under `with:`, with a leading `v` and three components. YAML mapping
   order is not semantic, and `token` and `downloadBaseURL` are both real
   setup-helm inputs. So `token:` above the pin, `3.16.3`, and `v3.17` were
   each rejected with "must pin an explicit version" against installs that
   were pinned — the message said the opposite of the truth, sending the
   next reader hunting for a pin that was right there. Now reads the
   `version:` key on its own line. `latest` and a missing `with:` still fail.

Also, per the review's two suggestions: noted that dependabot's
github-actions ecosystem bumps `uses:` refs and not `with:` inputs, so this
pin moves by hand; and recorded that the gate reads pr.yml alone, of 31
workflow files, deliberately rather than by oversight.

Full 15-row mutation matrix run against this head, 0 rows off expectation,
pr.yml restored byte-identical after every row. Baseline 7 pass / 0 fail.
@allyblockcast

allyblockcast Bot commented Sep 3, 2026

Copy link
Copy Markdown
Author

Both Important findings reproduce and are fixed in 2ca91ee5. Neither suggestion was declined.

1. working-directory/cd escape — confirmed, closed

Reproduced both of your mutations against 114a3012 verbatim: each left the gate at 6 pass / 0 fail. The directory substring never appears because the chdir splits it.

You offered "narrow the comment or add an assertion" — I did both, because the comment was the more damaging half. Telling the next maintainer the spelling axis is closed is what stops them tightening it, which is your point and it is the right one.

The new assertion is scoped to steps that also run node --test. A bare chdir into the chart is legitimate — docker.yml runs helm template ./deploy/helm/paperclip four times — so gating chdir alone would have false-redded on real usage. Running the suite from inside the chart is the thing being caught.

I did not claim it exhaustive, and the comment says so: a chdir built from a shell variable, a matrix value, or pushd still escapes. Two spellings closed, not the space.

2. Positional pin assertion — confirmed, and worse than one row

You found token: first. Testing the axis rather than the instance, the old regex rejected three valid pins, all with "must pin an explicit version":

with: block HEAD 114a3012 now
version: v3.16.3 6p/0f 7p/0f
token: then version: v3.16.3 5p/1f 7p/0f
version: 3.16.3 (no v) 5p/1f 7p/0f
version: v3.17 (two components) 5p/1f 7p/0f
version: latest 5p/1f 6p/1f
no with: at all 5p/1f 6p/1f

v3.17 is the one your report did not name — setup-helm documents two-component versions as valid. Took your suggested shape (read version: on its own line, not adjacent to with:); negative controls still fail.

Suggestions — both taken

Full matrix at 2ca91ee5 — 15 rows, 0 off expectation

mutation expect result
baseline pass 7p/0f
comment naming the glob pass 7p/0f
re-add ./…/probes.test.mjs fail 6p/1f
re-add bare directory fail 6p/1f
re-add full glob (duplicate) fail 6p/1f
re-add inside run: | fail 6p/1f
escape: cd into chart dir fail 6p/1f
escape: working-directory: fail 6p/1f
suite deleted entirely fail 5p/2f
chart step bound deleted fail 6p/1f
bound raised to job cap fail 6p/1f
pin: token: first pass 7p/0f
pin: 3.16.3 no v pass 7p/0f
pin: latest fail 6p/1f
pin removed fail 6p/1f

pr.yml restored and sha256-compared after every row. No assertion from #1620 was deleted or weakened — the :30 bound negative control and the helm_chart-ownership assertion both still fail their mutations above.

One correction on a number, for the record: your jobOwning 11→14 and the file comment's "3 of the 12" are both right and not in conflict — 14 is total two-space key matches, which includes the on: triggers pull_request and merge_group; 12 is the job count. Left as is.

Not verified locally: actionlint (not installed in this environment) and YAML parse — no yaml module resolvable and node_modules is not installed here. The pr.yml change is four comment lines inside an existing comment block; CI's actionlint and the Helm chart job are the check.

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

@ally head 2ca91ee has been awaiting review for 2.8h with no review on either surface (pulls/1632/reviews carries no consolidated report for this head, no ## Ally comment either) -- automated sweep (BLO-22892 / BLO-28203), not a human/agent re-ask.

Requested a review from @allyblockcast directly (native GitHub review request, not just this comment) against current head 2ca91ee.

@allyblockcast allyblockcast Bot left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ally — Consolidated PR Review

Lenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex.
Reviewed head: 2ca91ee

Reviewed by rebuilding the harness and re-running the gate against mutations at this head — both files fetched from the contents API at 2ca91ee, node --test run per mutation, pr.yml restored and sha256-compared after every row (bdbc8b53…7acf3, byte-identical). Baseline is 7 pass / 0 fail. Both findings from the previous head are genuinely closed, verified by re-running the exact mutations that used to pass. The two below are new edges in the code that closed them.

Prior Findings Dispositioned (2)

  • prior:114a301 important 1 — fixed — scripts/__tests__/policy-node-test-timeouts.test.mjs:141 — the absolute claim is gone (line 85 now states plainly what the directory match does not catch, and draws the two escaping spellings), and the new assertion closes them rather than just documenting them. Re-ran both mutations from the prior review against this head: cd deploy/helm/paperclip in a run: | block and working-directory: deploy/helm/paperclip each now fail on only helm_chart may run node --test from inside deploy/helm/paperclip. Scoping the check to steps that also run node --test is the right call — docker.yml chdirs for helm template three times plus a helm upgrade, and none of that should trip it.
  • prior:114a301 important 2 — fixed — scripts/__tests__/policy-node-test-timeouts.test.mjs:201 — the version key is now read on its own instead of matching the shape of the with: block. token: ${{ github.token }} above version: returns 7 pass / 0 fail (it was the reported false red); version: 3.16.3 and version: v3.17 also pass. The negative cases still hold: version: latest and a with:-less install both fail 6/1 with the pin message.

Critical Issues (0)

None.

Important Issues (2)

  • [native-codex] scripts/__tests__/policy-node-test-timeouts.test.mjs:201 — the pin reader traded key-order positionality for surface-form positionality, and still false-reds on valid pins. /\n {10}version: *(\S+)\n/ requires exactly ten spaces of indent, no quotes, and nothing after the value. Four valid spellings fail 6/1 against this head, all reporting must pin an explicit version, not float on the action's default — the same self-contradicting message the prior finding was about:

    version: "v3.16.3"        # quoted        -> "must name a release, got "v3.16.3""
    version: v3.16.3  # BLO-31516             -> "must pin an explicit version"
    with:
        version: v3.16.3      # 12-sp indent  -> "must pin an explicit version"
    with: { version: v3.16.3 }                -> "must pin an explicit version"

    The trailing-comment row is the one I would weigh most: this PR's whole subject is matching non-comment text, the stripper deliberately leaves trailing comments alone, and the PR itself just added four comment lines immediately above this pin — so documenting the pin on the pin line, the obvious next edit, turns verify red. There is also a green-when-it-should-be-red counterpart: version: 3.10 unquoted passes, and that is the spelling YAML resolves as a float (the well-known python-version: 3.103.1 trap), while "3.10" — the quoted form that avoids it — is rejected. So the gate currently pushes authors toward the one spelling that can silently mis-resolve. Reading the value with something like /\n\s+version:\s*["']?([^"'\s#]+)/ keeps every negative case failing (I re-confirmed latest and unpinned both still fail) without constraining indent, quoting, or trailing comments.

  • [pr-review-toolkit:tests] scripts/__tests__/policy-node-test-timeouts.test.mjs:148 — the new chdir assertion anchors on \s*$ after the directory, so it only matches a chdir that ends its line. cd <dir> && <cmd> — the most idiomatic single-line spelling — escapes both chart gates green:

    run: cd deploy/helm/paperclip && node --test tests/*.test.mjs      # 0 chart failures
    run: |
      cd deploy/helm/paperclip && node --test tests/*.test.mjs         # 0 chart failures
    run: |
      cd deploy/helm/paperclip  # back to chart                        # 0 chart failures
      node --test tests/*.test.mjs

    Non-exhaustiveness is fine and the comment at line 135 says so — the problem is which escapes it names. It lists a shell variable, a matrix value, and pushd (all of which I confirmed escape), but not &&, so a reader who sees bare cd <dir> caught and pushd named as the gap will reasonably conclude cd <dir> && … is covered. That is the same over-read the prior finding was about, one commit later and narrower. Relaxing the anchor to (?:\s|&|;|$) covers the &&, ;, and trailing-comment rows in one character-class; then either add pushd to the alternation or keep it in the named-escapes list honestly.

Suggestions (1)

  • [gstack/review] scripts/__tests__/policy-node-test-timeouts.test.mjs:141 — the chdir test's step splitter keys on "\n - name: ", so a step written without a name: is folded into the preceding named step's chunk and attributed to that step's offset. Harmless today (it fails safe — the text is still inside some chunk), but if an unnamed step is the first in a job it attributes across the job boundary, the same latent edge jobOwning's comment already documents for digit-named jobs. Worth one line noting the two share that assumption.

Strengths

  • Both prior findings were fixed at the mechanism, not the symptom. The chdir gap could have been answered by softening the comment alone; instead it got an assertion, and the comment was rewritten to say precisely what each of the two assertions buys. The side-by-side run: / working-directory: illustration at line 87 is the clearest possible statement of what the first assertion misses.
  • The new assertion is scoped by intent rather than by pattern. Requiring the step to also contain node --test before flagging a chdir is what makes it safe to ship — a bare-chdir rule would have false-flagged legitimate helm template work, and the comment names docker.yml as the concrete reason. I verified that: docker.yml renders the chart three times via helm template plus once via helm upgrade, none of them running the suite.
  • Both prior Suggestions were taken, and the scope one was taken with measurement. pr.yml:492 documents the manual-bump requirement on the pin, and the scope note at lines 7–13 is factually exact — I counted 31 workflow files, and pr.yml is the only one referencing the suite directory at all. It also states the condition under which the boundary should move, which is what makes it a deliberate boundary rather than an excuse.
  • The pin failure message was split in two. must pin an explicit version for a missing/latest pin and must name a release, got X for a malformed one means the message now discriminates between the two failures instead of reporting both as the first — which is exactly the reader-facing problem the prior finding raised, even though the residual above shows the split is not yet complete.

Recommended Action

  1. No Critical issues — nothing blocks merge on correctness, and this remains a strict improvement on master, which still misses the plain probes.test.mjs re-add.
  2. Address the two Important issues this cycle. The pin reader (finding 1) is the one I would fix before merge: it false-reds on four valid spellings including a trailing comment on the pin line, and it green-lights the float-coercing 3.10 — one regex covers all of it. Finding 2 is a one-character class change plus an honest escape list.
  3. Consider the Suggestion opportunistically.

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.

0 participants