What I hit
Working in a sibling repo (tompahoward/resume, a Vite/Astro/Cloudflare-Pages site, not Netlify), every git push attempt is rejected with:
Use npm run push:watch instead of git push. It pushes, watches the pipeline, and then surfaces either the release PR URL (if there are pending changesets) or the test deploy URL so you can review before releasing. The publish and changeset-release/* branches are managed by the pipeline -- do not push to them directly.
The hook in question is packages/risk-scorer/hooks/git-push-gate.sh:
risk_gate_deny "Use \`npm run push:watch\` instead of \`git push\`. ..."
Two problems
1. Enforces a hook but provides no guidance when the script doesn't exist
The block tells you to run npm run push:watch — but in this repo (and many others), that script doesn't exist. The hook gives no hint that:
- the script lives in
scripts/push-watch.sh in the windyroad/windyroad repo
- it is non-trivially adapted: the canonical version is bound to Netlify,
main-pipeline.yml, changesets, and gh pr flows — none of which exist outside the windyroad website repo
A user has to either know the convention already, or stop, dig through neighbouring projects, and copy-and-adapt. That breaks the principle that a gate should be paired with a path through it.
Suggested fix: if npm run push:watch is not a registered script, the gate's deny message should include either:
- a one-line note pointing at a canonical scaffold or a
wr-risk-scorer scaffold push-watch skill, or
- a documentation URL with copy-paste-ready minimal and Netlify variants
2. Fires on projects that don't have the matching pipeline setup
The gate's message references concepts that don't apply universally:
- "the pipeline" — assumes a CI pipeline (GitHub Actions main-pipeline.yml) exists
- "the publish and changeset-release/* branches" — assumes the changesets workflow is configured
- "release PR" / "test deploy URL" — assumes Netlify + a specific deploy flow
For a project that just deploys via wrangler pages deploy dist, none of those exist. The gate still fires.
Suggested fix: detect upstream context before firing the strict block. Some options:
- Check if
.github/workflows/main-pipeline.yml exists in the repo; only enforce the windyroad pipeline framing when it does
- Check
package.json scripts for a registered push:watch; if absent, downgrade to a warning that explains the convention and links to the scaffold
- Allow a
.wr-risk-scorer-policy.yml (or similar) opt-in per repo, with a sensible default for repos that don't declare one
Workaround I used in this repo
Created scripts/push-watch.sh as a minimal rebase-and-push wrapper, registered it in package.json, and pushed via npm run push:watch. That gets past the gate but doesn't fix the underlying UX issue — the next user (or the next AI session) will hit the same wall.
Why this matters
The hook is doing the right thing — defending against bare-pushing to managed branches. The implementation gap is that it currently assumes every repo it sees is structured like windyroad/windyroad. For someone bouncing between many projects in this marketplace, that mismatch turns a useful guardrail into a blocker with no recoverable signal.
Happy to provide more detail or a PR if useful.
What I hit
Working in a sibling repo (
tompahoward/resume, a Vite/Astro/Cloudflare-Pages site, not Netlify), everygit pushattempt is rejected with:The hook in question is
packages/risk-scorer/hooks/git-push-gate.sh:risk_gate_deny "Use \`npm run push:watch\` instead of \`git push\`. ..."Two problems
1. Enforces a hook but provides no guidance when the script doesn't exist
The block tells you to run
npm run push:watch— but in this repo (and many others), that script doesn't exist. The hook gives no hint that:scripts/push-watch.shin thewindyroad/windyroadrepomain-pipeline.yml, changesets, andgh prflows — none of which exist outside the windyroad website repoA user has to either know the convention already, or stop, dig through neighbouring projects, and copy-and-adapt. That breaks the principle that a gate should be paired with a path through it.
Suggested fix: if
npm run push:watchis not a registered script, the gate's deny message should include either:wr-risk-scorer scaffold push-watchskill, or2. Fires on projects that don't have the matching pipeline setup
The gate's message references concepts that don't apply universally:
For a project that just deploys via
wrangler pages deploy dist, none of those exist. The gate still fires.Suggested fix: detect upstream context before firing the strict block. Some options:
.github/workflows/main-pipeline.ymlexists in the repo; only enforce the windyroad pipeline framing when it doespackage.jsonscripts for a registeredpush:watch; if absent, downgrade to a warning that explains the convention and links to the scaffold.wr-risk-scorer-policy.yml(or similar) opt-in per repo, with a sensible default for repos that don't declare oneWorkaround I used in this repo
Created
scripts/push-watch.shas a minimal rebase-and-push wrapper, registered it inpackage.json, and pushed vianpm run push:watch. That gets past the gate but doesn't fix the underlying UX issue — the next user (or the next AI session) will hit the same wall.Why this matters
The hook is doing the right thing — defending against bare-pushing to managed branches. The implementation gap is that it currently assumes every repo it sees is structured like
windyroad/windyroad. For someone bouncing between many projects in this marketplace, that mismatch turns a useful guardrail into a blocker with no recoverable signal.Happy to provide more detail or a PR if useful.