Skip to content

fix(work-unblock): count a lane-token-stopped notice only inside the mint step - #11268

Merged
kyle-sexton merged 1 commit into
mainfrom
fix/stopped-match-comments
Oct 30, 2026
Merged

kyle-sexton merged 1 commit into
mainfrom
fix/stopped-match-comments

Conversation

@kyle-sexton

Copy link
Copy Markdown
Member

No related issue: follow-up to review SUGGESTIONs on #11224 and #11236

Summary

Two comments described behaviour the code does not have, and label-unblocked's stop mode matched a kill-switch notice anywhere in a job log. The notice now counts only inside the request-lane-token mint step's section of the log.

Fix

  • .github/scripts/work-unblock/label-unblocked.mjs: in stop mode, refusalReader finds the job's first ##[start-action display=Request the lane token;id=<step>.request] line, then that id's ##[end-action id=<step>.request;...] line, and counts a STOPPED notice only between them. With no start or no end marker the result is null, so the run stays a failed mint (mint-failed). The section boundary comes from a real job log (job 120970852314, the broker-check job the existing denial fixtures cite). The runner wraps the composite's one inner step in those markers, and the step's output, the notice included, comes after the inner ##[group]Run set -euo pipefail group closes. A ##[group]Run boundary would cut the section before the notice. Only the composite's first start marker counts, because later steps in a stopped job could print a fake block.
  • refusalReader's comment said "no other line of it is read". It now says check and token modes read one line, and a STOPPED line outside the section never counts.
  • .github/workflows/pr-run-activity-read.yml: the prune-list comment said "Not re-derived". The Publish the checked issue fields step keeps only the names the re-derived --find-prior check also names, and the comment now says so, along with the prune job's own re-check.
  • Test fixture: stoppedLog now uses the observed log shape (outer Run ./.base/.github/actions/request-lane-token group, start-action, inner script group, notice, end-action, next step). The old fixture's Run request-lane-token header did not match a real log.
  • No changelog fragment: .changes/ holds per-plugin directories only. This change touches no plugin, and the earlier .github/ changes to these files (ci: end a work-resolve-issue kill-switch deny neutral, keeping work-unblock's re-fire #11236, fix(intake-triage): route a report-delivered blocker's dependent to re-triage #11241) added none.

Verification

  • New test "a kill-switch notice outside the mint step's section is a failed mint, never a breaker trip" covers four cases: the notice in a later step, before the mint step, in a second start/end block after the real one, and in a section with no end-action marker. On the old code it failed on its first case (235 pass, 1 fail). With the fix, node --test label-unblocked.test.mjs job-log.test.mjs passes 240/240.
  • The existing stopped-mint tests still pass against the corrected fixture (breaker trip, one log read, plus the lookalike, no-timestamp, warning, over-cap and no-log negatives).
  • Tests that read pr-run-activity-read.yml pass: callers.test.mjs 208/208; seal.test.mjs, decide.test.mjs, check-signed-commits.test.mjs, fix-ci-dispatch.test.mjs and fix-docs-dispatch.test.mjs 206/206 together. actionlint is clean on the workflow.

Related

🤖 Generated with Claude Code

…mint step

label-unblocked's stop mode counted a STOPPED notice on any line of the
job log. It now counts one only between the runner's start-action marker
for request-lane-token's `Request the lane token` step and that step's
end-action marker, the shape job 120970852314's log shows.

Also corrects two comments: refusalReader's said no other log line is
read, and pr-run-activity-read.yml's said the prune list is not
re-derived, though the checked step keeps only names the re-derived
earlier-work check also names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton marked this pull request as ready for review October 30, 2026 13:41
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-30T13:42:39.038848Z 1c68a0b Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

Copy link
Copy Markdown
Contributor

claude-security-review reviewed 1c68a0b325e03dc7d6cad4895371cc63613fa738: 0 finding(s), 0 as inline comments.

No security issues found in this pull request.

  • .github/scripts/work-unblock/label-unblocked.mjs: The change narrows when a lane-token-stopped notice counts as a kill-switch trip. It now has to sit between the job's first Request the lane token start-action marker and that step's end-action marker. With no start or no end marker the result is null and the run stays a failed mint. The old code matched the notice anywhere in the log, so this widens nothing. Matching is still a strict regex on the timestamp-prefixed notice. The id captured from the log is limited to [\w-]+\.request, and its only regex metacharacter, ., is escaped before it goes into the end-marker regex, so a crafted log line can't inject a pattern. A step that runs before the mint step could print a fake start marker, because the first marker wins. That would only count a breaker trip, which the old code allowed more easily. It touches no token, scope or kill-switch control, and it doesn't make the kill switch unable to stop a lane.
  • .github/workflows/pr-run-activity-read.yml (trusted path): The only change is a comment about the prune list. It alters no code, permissions: block, trigger or gate. The trusted-path match is not a finding.
  • .github/scripts/work-unblock/label-unblocked.test.mjs: Test-only changes: a fixture reshaped to the observed log layout, plus a new negative test.

manifest fields: not touched.

critical-findings: 0

@github-actions

Copy link
Copy Markdown
Contributor

claude-review reviewed 1c68a0b325e03dc7d6cad4895371cc63613fa738: 0 finding(s), 0 as inline comments.

No findings. I read the full diff and the PR context. I ran no tests, so the PR's 240/240 and 208/208 pass counts are author-claimed and unverified by me.

label-unblocked.mjs stop-mode scoping.

  • refusalReader now takes the job's first MINT_START line and its matching mintEnd(id) line. It counts STOPPED only between them. A missing start or end marker returns null, which stays a failed mint.
  • The id is limited to [\w-]+\.request, and mintEnd escapes the dot. The stop > 0 check is redundant but harmless.
  • MINT_START ends with \]$ and the log is split on "\n" only, so a CRLF log would fail to match and return null (a failed mint, the safe direction). STEP_FAILED at line 279 already makes the same assumption, so this is consistent with the existing code.
  • A step before the mint step could print a fake start marker. That cannot mint a breaker trip on its own, because a STOPPED line must still sit inside the section, and the PR documents the first-marker rule.

Tests.

  • The new test covers four negative cases: a notice in a later step, before the mint step, in a second block after the first, and with no end marker. Each case builds the right log shape from stoppedLog() and should return null.
  • The fixture now matches the observed log shape. The existing positive tests still pass through the same reader.

pr-run-activity-read.yml. Comment-only change. It makes the prune-list note accurate and affects no behaviour.

Hold. None, since the change spends no money. No manifest items are hit. No closing issue or settled-threads file was supplied.

@kyle-sexton
kyle-sexton added this pull request to the merge queue Oct 30, 2026
Merged via the queue into main with commit 12c347d Oct 30, 2026
80 checks passed
@kyle-sexton
kyle-sexton deleted the fix/stopped-match-comments branch October 30, 2026 13:53
@github-actions

Copy link
Copy Markdown
Contributor

Post-merge mutation testing

Killed 2, survived 5, timeout 0, no coverage 0, invalid 0, not run 0.
Covered-code score 29%; mutation score 29%.

File Killed Survived Timeout No coverage Invalid Not run
.github/scripts/work-unblock/label-unblocked.mjs 2 5 0 0 0 0

Surviving mutants

Location Operator Disposition Cause
.github/scripts/work-unblock/label-unblocked.mjs:289 other productive input-gap
.github/scripts/work-unblock/label-unblocked.mjs:290 other productive input-gap
.github/scripts/work-unblock/label-unblocked.mjs:1158 ROR productive input-gap
.github/scripts/work-unblock/label-unblocked.mjs:1162 ROR unclassified none
.github/scripts/work-unblock/label-unblocked.mjs:1163 ROR unclassified none

The run's summary has the full report.

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.

1 participant