Skip to content

wr-risk-scorer git-push-gate: blocks git push without guidance when npm run push:watch doesn't exist; also fires on non-npm projects #235

@tompahoward

Description

@tompahoward

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions