Skip to content

fix(sdlc): harden authority-case-check.yml against grep|head SIGPIPE on long PR bodies#3836

Merged
ryanklee merged 2 commits into
mainfrom
epsilon/reform-fix-authority-case-check-sigpipe-20260601
Jun 1, 2026
Merged

fix(sdlc): harden authority-case-check.yml against grep|head SIGPIPE on long PR bodies#3836
ryanklee merged 2 commits into
mainfrom
epsilon/reform-fix-authority-case-check-sigpipe-20260601

Conversation

@ryanklee
Copy link
Copy Markdown
Collaborator

@ryanklee ryanklee commented Jun 1, 2026

AuthorityCase: CASE-SDLC-REFORM-001
cc-task: reform-fix-authority-case-check-sigpipe-20260601

What

The authority-case-check.yml "Parse AuthorityCase reference from PR body" step extracted ids with grep -oiE 'PATTERN' | head -1 under set -euo pipefail. When grep's -o output exceeds its ~4 KiB stdio buffer it flushes in pieces; head -1 closes the pipe after the first line, so grep's next write takes SIGPIPE -> exit 141 -> pipefail + set -e -> the step exits 1. This deterministically red-blocked any methodology PR whose body carried enough CASE-/cc-task matches (this is what blocked hapax-dev #3834).

Fix

The three extraction pipes now use grep -m1 -oiE ... <<<"$PR_BODY" || true plus a first-match parameter-expansion trim:

  • grep -m1 stops after the first matching line, so grep never keeps writing into a pipe a downstream stage closed early -- no SIGPIPE.
  • || true keeps a no-match from tripping set -e, retiring the redundant echo | grep -q guards (themselves a latent echo-pipe SIGPIPE on >64 KiB bodies).
  • the trim keeps only the first match when -o emits several on one line, preserving the old head -1 semantics and keeping a multi-line value out of $GITHUB_OUTPUT.

set -euo pipefail is retained.

Test

tests/test_authority_case_check_sigpipe.py lifts the real run block from the workflow YAML and executes it against crafted bodies. The many-match body exits 141 pre-fix and 0 post-fix; the >2 KiB single-ref body parses cleanly; same-line multi-match yields a single newline-free id. uv run pytest tests/test_authority_case_check_sigpipe.py -> 6 passed.

This PR's own AuthorityCase Check runs the patched workflow from the PR head, proving the fix end-to-end.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved stability of metadata extraction from pull requests, preventing failures when processing long or complex pull request bodies.
  • Tests

    • Added regression tests covering multiple parsing scenarios and edge cases to ensure consistent, reliable metadata parsing.

…on long PR bodies

The "Parse AuthorityCase reference from PR body" step extracted ids with
`grep -oiE 'PATTERN' | head -1` under `set -euo pipefail`. When grep's -o
output exceeds its ~4KiB stdio buffer it flushes in pieces; head -1 closes the
pipe after the first line, so grep's next write takes SIGPIPE -> exit 141 ->
pipefail + set -e -> the step exits 1. This deterministically red-blocked any
methodology PR whose body carried enough CASE-/cc-task matches (reproduced
through the actual run block: exit 141).

Replace the three extraction pipes with grep -m1 -oiE ... here-string + || true
plus a first-match parameter-expansion trim:
- grep -m1 stops after the first matching line, so grep never keeps writing
  into a pipe a downstream stage closed early -- no SIGPIPE.
- || true keeps a no-match (grep exit 1) from tripping set -e, retiring the
  now-redundant `if echo | grep -q` guards (themselves a latent echo-pipe
  SIGPIPE for >64KiB bodies).
- the trim keeps only the first match when -o emits several on one line,
  preserving the original head -1 semantics and keeping a multi-line value out
  of GITHUB_OUTPUT.
- the pre-methodology guard now reads from a here-string (no echo pipe).
set -euo pipefail is retained.

Regression test tests/test_authority_case_check_sigpipe.py lifts the real run
block from the workflow YAML and executes it: a >2KiB single-ref body parses to
exit 0, a many-match body that exits 141 pre-fix now exits 0, and same-line
multi-match yields a single newline-free id.

Task: reform-fix-authority-case-check-sigpipe-20260601
AuthorityCase: CASE-SDLC-REFORM-001

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d4d3e0b4-827a-4e68-9267-02332f3bbcd9

📥 Commits

Reviewing files that changed from the base of the PR and between 08170f5 and 1b62404.

📒 Files selected for processing (1)
  • .github/workflows/authority-case-check.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/authority-case-check.yml

📝 Walkthrough

Walkthrough

The workflow step parsing AuthorityCase metadata from PR bodies is rewritten to avoid SIGPIPE failures using here-strings and parameter expansion instead of piped grep/head operations. A regression test module is added that executes the actual parse step against crafted PR bodies to validate extraction across edge cases.

Changes

AuthorityCase metadata parsing robustness

Layer / File(s) Summary
Workflow SIGPIPE-safe parsing
.github/workflows/authority-case-check.yml
Replaced grep pipe chains with grep here-strings (<<<"$PR_BODY"), sed, and parameter expansion (${var%%$'\n'*}) to extract case_id, slice_id, cc_task, and pre_methodology. Added `
Regression test module: infrastructure and scenarios
tests/test_authority_case_check_sigpipe.py
New pytest module that locates the workflow file, extracts the id: parse step run script, and executes it in subprocesses with crafted PR_BODY and GITHUB_OUTPUT. Includes tests for long bodies, many matches, same-line multi-matches, no references, slice/pre-methodology detection, and legacy cc-task-only parsing; asserts exit code 0, key=value output format, and expected identifiers.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nibbled bytes of long PR prose,
I pushed them through grep where the wild wind blows,
No SIGPIPE snapped, no head did fall,
Outputs tidy, one key=value for all,
Hop, test, repeat — the pipeline's whole.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description includes a structured explanation of the problem, fix, and test plan, but is missing required AuthorityCase template fields (Case and Slice) and CLAUDE.md hygiene checklist. Add required template sections: populate 'Case:' with 'CASE-SDLC-REFORM-001' and 'Slice:' with the appropriate value, and complete the CLAUDE.md hygiene checklist by checking applicable boxes.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: hardening the authority-case-check.yml workflow against a SIGPIPE failure caused by grep piped to head on long PR bodies.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch epsilon/reform-fix-authority-case-check-sigpipe-20260601

Comment @coderabbitai help to get the list of available commands and usage tips.

… SC2001)

Feeding sed a here-string (single variable) trips shellcheck SC2001, which the
CI actionlint gate fails on. Reading from the grep stream (as the original did)
is shellcheck-clean and equally SIGPIPE-safe: grep -m1 bounds the output and sed
reads it to EOF, so nothing closes the pipe early.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ryanklee ryanklee added this pull request to the merge queue Jun 1, 2026
Merged via the queue into main with commit 75f437c Jun 1, 2026
31 checks passed
@ryanklee ryanklee deleted the epsilon/reform-fix-authority-case-check-sigpipe-20260601 branch June 1, 2026 15:53
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