fix(format.sh): stop matching a prettier devDependency as a prettier config - #7
Merged
Merged
Conversation
… census fix missed The v1.61.0 tag was destroyed a fourth time, and this time every part of the machinery was right. install-alpine runs the gate inside an alpine job container whose apk line predates check 63. The check skipped on "python3 not on PATH"; the lane's skip audit refused the undeclared skip, correctly; the job concluded failure for the exact tagged commit; require-checks-green read a live conclusion, correctly; cleanup deleted the tag, correctly. The defect was mine: the D2 fix provisioned python3 in tests/container-matrix.sh's three bootstraps and missed the one alpine container that gates releases. The lane's own header states the rule this follows: install the ONE package a needed behaviour requires and name the behaviour, rather than widening the approved-skip list. The named behaviour is check 63's census self-test, stdlib Python. Not added to the skip allowlist because the skip is not an environment fact of this lane -- the lane exists to prove the gate runs on Alpine, and a gate check that never runs on Alpine is not proven there. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1bfb133's commit -a in this shared checkout picked up another session's staged hook/test changes (skill-mandate.sh serial-tail mandate, inject-session-context.sh digest changes, three test files) alongside the alpine python3 fix it describes. That payload drift is what turned 'declared version matches what installs' and the inventory digest red against the in-flight v1.61.0. This restores those five paths to their 59c99f4 state; the mandate work continues on the auto-enforcement branch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
find_prettier_cfg() gated package.json on `grep -q '"prettier"[[:space:]]*:'`, which matches `"prettier": "^3.4.2"` inside devDependencies/dependencies just as happily as a real top-level "prettier" key. package.json is tried before .prettierrc in the same directory (matching prettier's own cosmiconfig search order), so a repo with prettier merely listed as a devDependency had its package.json win that slot, get handed to `prettier --config package.json`, find no real "prettier" field, and silently fall back to built-in defaults -- the sibling .prettierrc, with the project's real settings, was never reached. Replace the grep with pkg_has_top_level_prettier(), which parses the JSON via node (found through find_bin, falling back to `command -v node`) and checks Object.prototype.hasOwnProperty on the top-level key. No node, or a package.json that fails to parse, falls through via `continue` so the walk keeps going toward .prettierrc -- degrading to the dedicated config file is the safe direction, silently formatting with wrong defaults is not. Config filename order and the --config argument are unchanged; the cfg_has_plugins/is_project_trusted gate downstream still sees exactly which file will be loaded, and tests/repro/formatter-config.sh still passes. Adds tests/repro/formatter-config-devdep.sh: builds a repo with a devDependency-only "prettier" mention plus a sibling .prettierrc, proves the fixed hook picks .prettierrc, and re-runs the same case against the newest committed format.sh predating the pkg_has_top_level_prettier guard (derived from git history, not a pinned SHA) to prove the case is not vacuous.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
find_prettier_cfgacceptedpackage.jsonas a prettier config whenever this matched:That regex matches
"prettier": "^3.4.2"sitting indevDependencies, which is a version range, not config.package.jsonis first in the filename list, so the hook returned it, ranprettier --config package.json --write, and prettier found no top-levelprettierkey. It then fell back to its built-in defaults and reformatted the file. The repo's real.prettierrc, sitting in the same directory and next in the loop, was never reached.Caught in a live repo whose
.prettierrcsetssingleQuote: trueandprintWidth: 90. Every agent edit was silently rewritten to double quotes at width 80, fighting the committed config on every save.Fix
Parse instead of grep.
pkg_has_top_level_prettieruses node toJSON.parsethe file and checkhasOwnProperty("prettier")at the top level. If node is missing or the file does not parse, it returns non-zero so the caller'scontinuefalls through to.prettierrcin the same directory. Degrading to the dedicated config file is the safe direction; formatting with the wrong defaults is not.The filename order and the
--config "$cfg"argument are unchanged. Thecfg_has_plugins+is_project_trustedgate depends on knowing exactly which file prettier will load, andtests/repro/formatter-config.shexists to prove that gate. Node parsing apackage.jsonexecutes no repo code, so this does not widen the plugin-execution hole that test guards.Verification
tests/repro/formatter-config-devdep.sh(new) exits 0.tests/repro/formatter-config.shunchanged, exits 0. The plugin-trust gate did not regress.format.sh at 2792f2a does mistake the devDependency line for a config -- this test is not vacuous. The pre-fix blob leaves the file double-quoted; the fixed hook produces'hello'.🤖 Generated with Claude Code