Skip to content

fix(rules): WH013 reads steps with the shared workflow reader - #1006

Merged
hyperpolymath merged 8 commits into
claude/eager-wright-zwwbe2-workflow-yamlfrom
claude/eager-wright-zwwbe2-wh013-reader
Nov 5, 2026
Merged

hyperpolymath merged 8 commits into
claude/eager-wright-zwwbe2-workflow-yamlfrom
claude/eager-wright-zwwbe2-wh013-reader

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Summary

Step 2 of 2, stacked on #1005. Merge that first; this PR's base is its branch.

WH013's masked-write check (continue-on-error: true on the step that writes) used its own step splitter. Codex found three valid YAML shapes it missed on #950 (threads 4326052772, 4326052783, 4326052793):

Shape Before After
A steps: line inside an earlier step's run: | script (a heredoc that writes a workflow) the splitter reset to the embedded list and never saw the real sibling steps, so a later masked credentialed write was missed WH013 reads steps only under the job's own steps: key
An indentless sequence: steps: with its - items at the key's column the steps value ended before its first item items at the key's column are read
A step opened by - and a comment (- # publication step) the comment's column was taken as the step's key column, so the flag never matched a comment-only opener is a bare -

WH013 now reads jobs and steps through Hypatia.WorkflowYaml, which drops comment lines, expands aliases and finds steps by the job's field column. That removes the first gap by construction. The other two are fixed in the shared reader, so RE001 gets them too:

  • an indentless steps: sequence is read, so a harden-runner step there now counts;
  • a comment-opened step keeps its run:, so its exposures are seen.

WH013's own step_bodies parser is deleted. masked_write?/1 stays public; its steps now come from the shared reader.

Type of change

  • 🐛 Bug fix (false negatives in WH013 and RE001)

How has this been verified?

  • Compiled the modules standalone (Elixir 1.14, --warnings-as-errors). hex.pm is unreachable here.
  • research_extensions_test + workflow_hardening_test: 195/195. That is the 188 existing tests plus 7 new ones.
  • Control: 6 of the 7 new tests fail on main:
    • the 3 WH013 shapes;
    • RE001's 3 tests for the two reader fixes (one comment-opened step, two indentless sequences).
    • The seventh guards the sibling-step rule in the indentless shape and passes on both.
  • Blast radius: WH013 and ResearchExtensions.scan/1 give identical results before and after on the hypatia, echidna and standards trees. The fix closes the gaps without new noise.
  • mix format --check-formatted: clean.

Notes for reviewers

  • WH013 now reads the workflow through read_workflow/1, so a KYAML workflow is read as block layout too. Block YAML is returned byte-identical.
  • A file whose jobs the reader can't split is still judged as one body, by its shell masks; its steps aren't searched for continue-on-error. That is the same safe direction as before.
  • The issue's other route, a full YAML parser (yamerl, later kyq), would replace WorkflowYaml's internals and leave WH013 and RE001 alone.

Checklist

  • My commits are signed. Signing is handled by the session's platform shim.
  • I ran the project's own checks/tests locally and they pass (scoped as above).
  • Docs are updated (CHANGELOG, comments, masked_write?/1 doc).
  • I have not introduced a soundness hole. The findings on real trees are unchanged, and the new tests pin each gap.

Generated by Claude Code

WH013's masked-write check carried its own step splitter, which missed
three valid shapes Codex reported on #950:

- a literal `steps:` inside an earlier step's `run: |` script reset the
  splitter, so the real sibling steps after it were never seen;
- an indentless sequence (`steps:` with `- ` items at the key's column)
  ended the steps value before its first item;
- a step opened by `-` and a comment took the comment's column as the
  step's key column, so `continue-on-error: true` never matched.

WH013 now reads jobs and steps through Hypatia.WorkflowYaml (comment
lines dropped, aliases expanded, steps only under the job's own `steps:`
key), so the first is gone by construction. The other two are fixed in
the reader, which RE001 shares: its indentless `steps:` items are now
read (a harden-runner step there counts), and a comment-opened step keeps
its `run:`.

Tests: 7 new (4 WH013, 3 RE001); 6 fail on main, one per gap, and the
seventh guards the sibling-step rule in the indentless shape. WH013 and
RE001 findings on the hypatia, echidna and standards trees are identical
before and after.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CYR5bf5FBLS7cXQK72aVNM
@coderabbitai

coderabbitai Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 35 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: c6584b82-1122-4601-96ce-cb04c1b0ec82
Commits

Reviewing files that changed from the base of the PR and between 7fc2a8a and ea09e55.

Files selected for processing: 5

  • CHANGELOG.adoc
  • lib/hypatia/workflow_yaml.ex
  • lib/rules/workflow_hardening.ex
  • test/research_extensions_test.exs
  • test/workflow_hardening_test.exs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@hyperpolymath
hyperpolymath marked this pull request as ready for review November 4, 2026 22:43
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 4, 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-11-05T00:58:05.603164Z ea09e55 New commits
ℹ️ 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.

Copy link
Copy Markdown
Owner Author

This PR's red E2E — Elixir Scanner Pipeline and Allowlist Preflight checks come from main, not from this PR (details on #1005). The full suite here is 2339 tests, and its 13 failures are all test/learning_scheduler_test.exs, which fails on main too. #1002 fixes both.

Merge-order note: #1002 adds WH014 code that calls WorkflowHardening.step_bodies/1, which this PR replaces with the shared Hypatia.WorkflowYaml reader. The hunks don't conflict textually, but whichever PR merges second won't compile until that call is moved. Plan: #1002 first, then I merge main into this stack and point WH014 at WorkflowYaml.job_steps/1 here, with its tests.


Generated by Claude Code

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b0658ca684

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread lib/rules/workflow_hardening.ex Resolved
The shared reader splits jobs under `jobs:`, `"jobs":` or `'jobs':`,
but workflow_preamble/1 still split only on a bare `jobs:`. With a
quoted key the "preamble" was the whole file, so one job's PAT marked
every writing job as credentialed and hid a starved GITHUB_TOKEN push.
The boundary now accepts the same three forms. (Codex, #1006.)

The new test passes on main (whose own job splitter did not split a
quoted key either), fails without this fix, and passes with it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CYR5bf5FBLS7cXQK72aVNM
@hyperpolymath
hyperpolymath added this pull request to stack #1007 November 4, 2026 23:07
@coderabbitai

coderabbitai Bot commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Add Carrot credits or activate Agent usage billing to use Autofix

#1002 added WH014, which split a job body into steps with
WorkflowHardening.step_bodies/1. This branch replaces that splitter with
Hypatia.WorkflowYaml, so after merging main WH014 no longer compiled.

WH014 now gets each job's step texts from WorkflowYaml.job_steps/1 (only
the job's own `steps:` key, comment lines dropped), the same reader WH013
and RE001 use. blank_or_comment?/1, which WH014 also calls, is restored.

All 220 RE and WH tests pass (including #1002's WH014 suite), and WH013,
WH014 and RE001 give identical results to main on the hypatia, echidna
and standards trees.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CYR5bf5FBLS7cXQK72aVNM

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 602241520e

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread lib/rules/workflow_hardening.ex Resolved
Comment thread lib/rules/workflow_hardening.ex Resolved
…H014

Two places still recognised fewer YAML spellings than the shared reader
(Codex, #1006):

- `jobs: &all_jobs` (an anchor or tag on the jobs key) did not start the
  jobs mapping in WorkflowYaml.workflow_job_lines/1, so WH013 fell back to
  one body with no steps and reported a write masked only by its step's
  continue-on-error as an ordinary starved write. The old splitter found
  it, so this was a regression. The key now accepts node properties.
- WH014 split a job's preamble only on a bare `steps:`, so with a quoted
  `"steps":` a step-level working-directory was read as the job default
  and the SARIF path no longer matched. The split now accepts the same
  three spellings as the reader (pre-existing on main, exposed here).

Two tests, one per gap; both fail without the fix. All 222 RE and WH
tests pass, and WH013, WH014 and RE001 are unchanged from main on the
hypatia, echidna and standards trees.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CYR5bf5FBLS7cXQK72aVNM
@sonarqubecloud

sonarqubecloud Bot commented Nov 5, 2026

Copy link
Copy Markdown

Copy link
Copy Markdown
Owner Author

Replying here because GitHub is refusing review-thread replies on this PR right now (422 "abuse" on both threads). Both Codex P2s on 6022415 are fixed in b955f86:

  • jobs: &all_jobs (thread): confirmed, and it was a regression from this PR. main's old step splitter didn't depend on the jobs line. WorkflowYaml.workflow_job_lines/1 now accepts YAML node properties after the key (an anchor or a tag), so the jobs split and the step's continue-on-error is seen again. The new test passes on main, fails without the fix and passes with it.
  • Quoted "steps": in WH014 (thread): confirmed. On main a quoted key meant WH014 found no steps at all, so the gap predates this PR, but the shared reader made the mismatch reachable. The preamble split now accepts steps:, "steps": and 'steps':. The new test runs your scenario under all three spellings: it fails without the fix for both quoted spellings and passes with it.

All 222 RE and WH tests pass. WH013, WH014 and RE001 give the same results as main on the hypatia, echidna and standards trees.


Generated by Claude Code

@hyperpolymath
hyperpolymath merged commit a6411e3 into main Nov 5, 2026
96 checks passed
@hyperpolymath
hyperpolymath deleted the claude/eager-wright-zwwbe2-wh013-reader branch November 5, 2026 17:04
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.

2 participants