Skip to content

fix(prettier): fail-safe changed-file scoping; never autofix workflow files#118

Merged
topcoder1 merged 1 commit into
mainfrom
fix/prettier-scope-failsafe
Jul 17, 2026
Merged

fix(prettier): fail-safe changed-file scoping; never autofix workflow files#118
topcoder1 merged 1 commit into
mainfrom
fix/prettier-scope-failsafe

Conversation

@topcoder1

Copy link
Copy Markdown
Owner

Root cause (wxa-secrets#27, job log)

A transient GitHub API error (HTML 5xx body → gh --jq died with invalid character '<' looking for beginning of value) failed the PR changed-file listing on a Python-only PR. The listing-failure branch fell open to full-glob mode: prettier --write ran on the entire tree, reformatted pre-existing drift in .github/workflows/pr-review.yml (a file the PR never touched), and the push was rejected — refusing to allow a Personal Access Token to create or update workflow ... without 'workflow' scope (AUTOMERGE_PAT correctly lacks that scope). Net effect: every such PR goes red in any repo carrying workflow-file drift.

Note the empty-intersection path (mode=none) was already correct — the fall-open was specifically the listing-failure branch. The job token had PullRequests: read; the old warning text blaming caller permissions was misleading.

Fix

  1. lint.yml + prettier-autofix.yml — retry the paginated files API 3× (2s/4s backoff), then skip (mode=none) with a loud ::warning::. A scoping failure is never widened to a full-tree pass. Blocks kept byte-identical; the new selftest drift-checks them.
  2. prettier-autofix.yml — commit-step guard: revert any prettier write under .github/workflows/ before staging. automerge_pat will never have workflow scope by fleet policy, so such pushes are always rejected. Covers changed_only: false callers and PRs that legitimately touch a misformatted workflow file (explicit glob mode remains caller opt-in).
  3. selftest/test_prettier_scope_failsafe.sh — extracts and executes the shipped bash: listing failure → mode=none (never glob, incl. behavioral run of the extracted block with a failing gh stub); guard reverts workflow writes and keeps the rest; python-only PR → skip; positive control → mode=files. Wired into test_workflow_guards.py. RED before this fix (fall-open + missing guard), GREEN after.

Verification

  • uv run pytest -q: 9 passed (includes new selftest)
  • prettier --check clean on edited files; actionlint clean
  • Codex rounds: 2 (both clean, gate PASS)

Follow-up (separate, human-pushed): one-time format commit on wxa-secrets main to clear the pre-existing .github/workflows/pr-review.yml drift.

Auto-merge rationale: manual-merge category — PRs to topcoder1/ci-workflows are always manual merge (fleet policy) and this touches .github/workflows/** (production infrastructure). Opened as draft so automerge stays disarmed.

🤖 Generated with Claude Code

…files

A transient GitHub API error (HTML 5xx body -> gh --jq 'invalid
character <' parse failure) failed the PR changed-file listing on
whois-api-llc/wxa-secrets#27, and the failure branch fell OPEN to
full-glob mode: prettier --write ran on the whole tree, reformatted
pre-existing drift in .github/workflows/pr-review.yml (a file the PR
never touched), and the push died on the workflow-scope check — a red X
on every yml-less PR in any repo with workflow-file drift.

- lint.yml + prettier-autofix.yml: retry the files API 3x, then SKIP
  (mode=none) instead of widening scope to the full tree. Blocks kept
  byte-identical; drift-checked by the new selftest.
- prettier-autofix.yml: revert any prettier write under
  .github/workflows/ before committing — automerge_pat deliberately
  lacks workflow scope (fleet policy), so such pushes are always
  rejected. Covers changed_only=false callers and PRs that legitimately
  touch a misformatted workflow file.
- selftest/test_prettier_scope_failsafe.sh: extracts and executes the
  shipped bash — listing failure -> mode=none (never glob), guard
  reverts workflow writes and keeps the rest, python-only PR -> skip,
  positive control -> mode=files. Wired into test_workflow_guards.py.

Co-Authored-By: Claude Fable 5 <[email protected]>
@github-actions

Copy link
Copy Markdown

Coverage Floor — mode: enforce

metric value
measured 100.0%
floor (current) 99.0%
target 100.0%
last bumped 2026-05-12

@topcoder1

Copy link
Copy Markdown
Owner Author

Independent verification from the session that babysat wxa-secrets#27 (where this incident fired twice, attempts 1+2 of run 29542573990):

  • Coverage confirmed against the live incident. Observed chain was: changed-file listing died on an HTML 5xx (invalid character '<' looking for beginning of value) → fell open to full-glob → prettier rewrote pre-existing drift in .github/workflows/pr-review.yml (untouched by the PR) → push rejected on AUTOMERGE_PAT's missing workflow scope. This diff kills it at both links: listing failure → retry 3× → mode=none skip (never full-tree), and any .github/workflows/ write is reverted before staging regardless of how it got there.
  • Selftests pass locally on macOS (7/7 assertions; full-script scenarios skipped on bash 3.2 as documented — CI enforces them). actionlint clean on both changed workflows. The lint.yml/prettier-autofix.yml listing blocks verified byte-identical by the selftest's drift check.

Ready for human review + manual merge (fleet policy for this repo). Until it lands, every yml-less PR fleet-wide stays exposed to the same red-X during API turbulence.

@topcoder1
topcoder1 marked this pull request as ready for review July 17, 2026 04:34
@github-actions github-actions Bot added the risk:blocked Risk class: blocked label Jul 17, 2026
@github-actions

Copy link
Copy Markdown

Risk class: blocked — manual merge required.

This PR touches one of the blocked path categories from .github/risk-paths.yml (Dockerfiles, docker-compose, .github/workflows/**, **/.env*, **/secrets*, infra/, terraform/, k8s/, or the classifier config itself).

Auto-merge is refused by claude-author-automerge.yml. A maintainer should review the diff and click "Squash and merge" themselves.

(This is a policy notice, not a code-quality failure. The classify job itself does not fail — required CI checks remain authoritative for "is the code green.")

@claude

claude Bot commented Jul 17, 2026

Copy link
Copy Markdown

No issues found. Fail-safe flips listing failure to mode=none (skip+pass, handled in both case blocks), retry loop is -e-safe, and the workflow-file revert guard runs before staging without touching PR-authored commits. Blocks are byte-identical and selftest-covered.

@topcoder1
topcoder1 merged commit 5cdf86b into main Jul 17, 2026
16 checks passed
@topcoder1
topcoder1 deleted the fix/prettier-scope-failsafe branch July 17, 2026 05:10
topcoder1 added a commit to whois-api-llc/ProfessionalServices that referenced this pull request Jul 17, 2026
prettier-autofix can never push workflow-file fixes (AUTOMERGE_PAT lacks
workflow scope by design), so pre-existing drift here redlines any PR
that touches these files. Fleet-wide one-time clear; the full-tree
fall-open that surfaced it is fixed in topcoder1/ci-workflows#118.

Co-Authored-By: Claude Fable 5 <[email protected]>
topcoder1 added a commit that referenced this pull request Jul 17, 2026
prettier-autofix can never push workflow-file fixes (AUTOMERGE_PAT lacks
workflow scope by design), so pre-existing drift here redlines any PR
that touches these files. Fleet-wide one-time clear; the full-tree
fall-open that surfaced it is fixed in #118.

Co-Authored-By: Claude Fable 5 <[email protected]>
topcoder1 added a commit to topcoder1/jz_skills that referenced this pull request Jul 17, 2026
prettier-autofix can never push workflow-file fixes (AUTOMERGE_PAT lacks
workflow scope by design), so pre-existing drift here redlines any PR
that touches these files. Fleet-wide one-time clear; the full-tree
fall-open that surfaced it is fixed in topcoder1/ci-workflows#118.

Co-Authored-By: Claude Fable 5 <[email protected]>
topcoder1 added a commit to topcoder1/nanoclaw that referenced this pull request Jul 17, 2026
prettier-autofix can never push workflow-file fixes (AUTOMERGE_PAT lacks
workflow scope by design), so pre-existing drift here redlines any PR
that touches these files. Fleet-wide one-time clear; the full-tree
fall-open that surfaced it is fixed in topcoder1/ci-workflows#118.

Co-Authored-By: Claude Fable 5 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:blocked Risk class: blocked

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant