From 03ef397bc33de1b4fa95e9f48f702798d7f61a1e Mon Sep 17 00:00:00 2001 From: NiveditJain Date: Mon, 10 Aug 2026 11:50:37 +0530 Subject: [PATCH 1/7] fix: bump postcss override to clear nanoid OSV advisory Supply Chain CI was failing on GHSA-2v37-7h3g-55p8 (high, nanoid 3.3.16), pulled in transitively through the pinned postcss@8.5.23 (nanoid ^3.3.16). Bumping the override to postcss@8.5.26 (nanoid ^3.3.17) resolves it. Co-Authored-By: Claude Sonnet 5 --- CHANGELOG.md | 1 + bun.lock | 6 +++--- package.json | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0108aee13..bcb9feaa0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 1.0.0-beta.13 — 2026-08-07 ### Fixes +- Bump the `postcss` override from `8.5.23` to `8.5.26` to pull in `nanoid@^3.3.17`, clearing a high-severity OSV advisory (GHSA-2v37-7h3g-55p8) against the transitively-locked `nanoid@3.3.16`. (#PR) - Make `failproofai config` refuse setup on an unsupported platform (Windows, today) instead of completing it unenforced. The wizard used to skip the daemon requirement and finish anyway, leaving the machine reading as configured while enforcing in-process with no fail-closed guarantee — now it prints why and exits 1 before drawing a single prompt, writing nothing. (#664) ## 1.0.0-beta.12 — 2026-08-07 diff --git a/bun.lock b/bun.lock index f2943e937..4f74b7cbb 100644 --- a/bun.lock +++ b/bun.lock @@ -42,7 +42,7 @@ "overrides": { "brace-expansion": "5.0.9", "eslint-plugin-react-hooks": "7.0.1", - "postcss": "8.5.23", + "postcss": "8.5.26", "sharp": "0.35.0", "undici": "7.29.0", "vite": "8.0.16", @@ -978,7 +978,7 @@ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - "nanoid": ["nanoid@3.3.16", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q=="], + "nanoid": ["nanoid@3.3.18", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w=="], "napi-postinstall": ["napi-postinstall@0.3.4", "", { "bin": { "napi-postinstall": "lib/cli.js" } }, "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ=="], @@ -1034,7 +1034,7 @@ "possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="], - "postcss": ["postcss@8.5.23", "", { "dependencies": { "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg=="], + "postcss": ["postcss@8.5.26", "", { "dependencies": { "nanoid": "^3.3.17", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ=="], "posthog-node": ["posthog-node@5.47.7", "", { "dependencies": { "@posthog/core": "^1.46.4" }, "peerDependencies": { "rxjs": "^7.0.0" }, "optionalPeers": ["rxjs"] }, "sha512-ZfvGL2DQB9mQmM+9hFRtX8h4WeXRANA6ASK/6eLJuAg2BPxvLpihRyB8pmgFm6Ye+t2drZJkDklEARPj/3OWAA=="], diff --git a/package.json b/package.json index dd2476a2e..c1baf61d0 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "yaml": "^2.9.0" }, "overrides": { - "postcss": "8.5.23", + "postcss": "8.5.26", "eslint-plugin-react-hooks": "7.0.1", "vite": "8.0.16", "undici": "7.29.0", From eac91f098d3ce3a979efc794fae5300545bef72c Mon Sep 17 00:00:00 2001 From: NiveditJain Date: Mon, 10 Aug 2026 11:51:27 +0530 Subject: [PATCH 2/7] docs: date the changelog entry under today's date, not beta.13's original date Version didn't bump, but beta.13's changelog section was dated 2026-08-07; per repo convention (see the two 0.0.14-beta.1 sections a few days apart) a same-version entry landing later gets its own dated section. Co-Authored-By: Claude Sonnet 5 --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bcb9feaa0..4bc04a257 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,13 @@ # Changelog -## 1.0.0-beta.13 — 2026-08-07 +## 1.0.0-beta.13 — 2026-08-10 ### Fixes - Bump the `postcss` override from `8.5.23` to `8.5.26` to pull in `nanoid@^3.3.17`, clearing a high-severity OSV advisory (GHSA-2v37-7h3g-55p8) against the transitively-locked `nanoid@3.3.16`. (#PR) + +## 1.0.0-beta.13 — 2026-08-07 + +### Fixes - Make `failproofai config` refuse setup on an unsupported platform (Windows, today) instead of completing it unenforced. The wizard used to skip the daemon requirement and finish anyway, leaving the machine reading as configured while enforcing in-process with no fail-closed guarantee — now it prints why and exits 1 before drawing a single prompt, writing nothing. (#664) ## 1.0.0-beta.12 — 2026-08-07 From a295f95e32ac87282c7d70e5561b40594e81c217 Mon Sep 17 00:00:00 2001 From: NiveditJain Date: Mon, 10 Aug 2026 11:55:47 +0530 Subject: [PATCH 3/7] docs: fill in changelog PR number Addresses CodeRabbit review comment on #670. Co-Authored-By: Claude Sonnet 5 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bc04a257..c6dbd309e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## 1.0.0-beta.13 — 2026-08-10 ### Fixes -- Bump the `postcss` override from `8.5.23` to `8.5.26` to pull in `nanoid@^3.3.17`, clearing a high-severity OSV advisory (GHSA-2v37-7h3g-55p8) against the transitively-locked `nanoid@3.3.16`. (#PR) +- Bump the `postcss` override from `8.5.23` to `8.5.26` to pull in `nanoid@^3.3.17`, clearing a high-severity OSV advisory (GHSA-2v37-7h3g-55p8) against the transitively-locked `nanoid@3.3.16`. (#670) ## 1.0.0-beta.13 — 2026-08-07 From 0467c4e52819a0f8aa3b89e48e08d4cedd143108 Mon Sep 17 00:00:00 2001 From: NiveditJain Date: Mon, 10 Aug 2026 12:02:53 +0530 Subject: [PATCH 4/7] ci: run Supply Chain scan daily, alert Slack on scheduled failure Weekly meant a red run on main sat unnoticed until the next PR happened to touch the lockfile - the reason this PR's own nanoid advisory was only caught via a PR check rather than earlier on main. PR/push runs stay silent (already visible to the PR author); only the schedule run (no lockfile change on main, nobody watching) posts to Slack, reusing the same webhook + node -e | curl idiom integration-suite/run.sh uses. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/osv-scanner.yml | 34 ++++++++++++++++++++++++++++--- CHANGELOG.md | 1 + 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/.github/workflows/osv-scanner.yml b/.github/workflows/osv-scanner.yml index 70d1f0e63..82433d8cf 100644 --- a/.github/workflows/osv-scanner.yml +++ b/.github/workflows/osv-scanner.yml @@ -6,8 +6,15 @@ # package (block-on-any-finding policy). OSV-Scanner exits non-zero when it finds # anything, which fails this job. # -# Runs on every PR (incl. Dependabot bumps), on pushes to main, and weekly to -# catch advisories disclosed after a dependency was already merged. +# Runs on every PR (incl. Dependabot bumps), on pushes to main, and daily to +# catch advisories disclosed after a dependency was already merged — a PR is +# the only thing that surfaced a scheduled failure before this, so a scan that +# broke on `main` between PRs went unnoticed until the next one happened to +# touch the lockfile. +# +# A daily `main` failure also posts to Slack (see the notify step below) — +# the PR/push runs don't, since those failures are already visible to whoever +# opened the PR without needing a second channel. # # Triage / allow-listing unfixable advisories: see SECURITY.md and osv-scanner.toml # (auto-loaded from the repo root by OSV-Scanner). @@ -22,7 +29,7 @@ on: push: branches: [main] schedule: - - cron: "17 4 * * 1" # Mondays 04:17 UTC + - cron: "17 4 * * *" # daily, 04:17 UTC workflow_dispatch: # Least privilege: the scan only needs to read the checked-out source. @@ -51,3 +58,24 @@ jobs: scan-args: |- --lockfile=bun.lock --lockfile=Cargo.lock + # PR/push runs skip this — a failure there is already visible to whoever + # opened the PR. It's the schedule run (nothing on main touched the + # lockfile, so nobody is watching) that needs a channel of its own; same + # webhook + `node -e … | curl` idiom integration-suite/run.sh uses. + - name: Notify Slack on failure + if: failure() && github.event_name != 'pull_request' + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + run: | + if [ -z "$SLACK_WEBHOOK_URL" ]; then + echo "(no SLACK_WEBHOOK_URL set — not posted)" >&2 + exit 0 + fi + run_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" + text="🔴 *Supply Chain scan failed* on \`${GITHUB_REF_NAME}\` (${GITHUB_EVENT_NAME}) — known-vulnerable or known-malicious dependency detected. <${run_url}|View run>" + payload="$(node -e 'const t=require("fs").readFileSync(0,"utf8");process.stdout.write(JSON.stringify({text:t}))' <<<"$text")" + code="$(curl -sS --connect-timeout 10 --max-time 30 \ + -o /dev/null -w '%{http_code}' -X POST -H 'Content-type: application/json' \ + --data "$payload" "$SLACK_WEBHOOK_URL" 2>/dev/null || echo 000)" + if [ "$code" = 200 ]; then echo "✓ posted to Slack webhook" + else echo "⚠️ Slack webhook POST returned HTTP $code" >&2; fi diff --git a/CHANGELOG.md b/CHANGELOG.md index c6dbd309e..d9417eec3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Fixes - Bump the `postcss` override from `8.5.23` to `8.5.26` to pull in `nanoid@^3.3.17`, clearing a high-severity OSV advisory (GHSA-2v37-7h3g-55p8) against the transitively-locked `nanoid@3.3.16`. (#670) +- Move the `Supply Chain` workflow's scheduled OSV-Scanner run from weekly to daily, and post to Slack when it fails — a scheduled failure on `main` previously surfaced only when the next PR happened to touch the lockfile, since a red scheduled run has no PR author to notice it. (#670) ## 1.0.0-beta.13 — 2026-08-07 From f43bc85061940bd96fe7707df2608fbb8427ef05 Mon Sep 17 00:00:00 2001 From: NiveditJain Date: Mon, 10 Aug 2026 12:03:34 +0530 Subject: [PATCH 5/7] docs: reflect the daily schedule + Slack alert in SECURITY.md Co-Authored-By: Claude Sonnet 5 --- SECURITY.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 2b1cd813e..24ba3dc7b 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -35,8 +35,10 @@ advisories **and** the [OpenSSF malicious-packages feed](https://github.com/ossf **Policy: block on any finding.** The gate fails on *any* known-vulnerable or malicious package in the tree — not just newly introduced ones. It runs on every -PR, on pushes to `main`, and weekly (to catch advisories disclosed after a -dependency was already merged). +PR, on pushes to `main`, and daily (to catch advisories disclosed after a +dependency was already merged). A daily run that fails on `main` — where there's +no PR author already looking at the check — also posts to Slack, via the +`SLACK_WEBHOOK_URL` repository secret. ### 2. Socket — behavioral early-warning @@ -71,3 +73,7 @@ These steps live outside the repo and require admin access: 3. *(Optional)* For a Socket CI gate in addition to the App, add a `SOCKET_SECURITY_API_KEY` repository secret and the Socket CI action — deferred until tuned, since behavioral findings can have false positives. +4. **Slack alert on a failed daily scan**: set the `SLACK_WEBHOOK_URL` repository + secret to a Slack Incoming Webhook URL (the same secret `integration-suite` + already posts to). Without it, the daily job still runs and still fails CI on a + finding — it just skips the Slack POST and logs that the secret is unset. From 6f4a19efc88d138c9d70b59a58c509a4321dd2c5 Mon Sep 17 00:00:00 2001 From: NiveditJain Date: Mon, 10 Aug 2026 12:10:56 +0530 Subject: [PATCH 6/7] fix: gate Slack alert on schedule runs only, not push CodeRabbit caught the mismatch: the comment said push runs skip the alert, but the condition only excluded pull_request, so a failed push would have posted too. Narrows to `steps.scan.outcome == 'failure' && github.event_name == 'schedule'` (also pins the check to the scan step's own outcome rather than the whole job's), and reflects the optional/schedule-only framing in the CHANGELOG entry. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/osv-scanner.yml | 17 ++++++++++------- CHANGELOG.md | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/osv-scanner.yml b/.github/workflows/osv-scanner.yml index 82433d8cf..60a8fde92 100644 --- a/.github/workflows/osv-scanner.yml +++ b/.github/workflows/osv-scanner.yml @@ -12,9 +12,11 @@ # broke on `main` between PRs went unnoticed until the next one happened to # touch the lockfile. # -# A daily `main` failure also posts to Slack (see the notify step below) — -# the PR/push runs don't, since those failures are already visible to whoever -# opened the PR without needing a second channel. +# A daily scheduled failure also posts to Slack (see the notify step below, +# gated on github.event_name == 'schedule') — PR and push runs don't, since +# those failures are already visible to whoever opened or merged the PR +# without needing a second channel. Posting is itself optional: it silently +# no-ops when the SLACK_WEBHOOK_URL repository secret isn't set. # # Triage / allow-listing unfixable advisories: see SECURITY.md and osv-scanner.toml # (auto-loaded from the repo root by OSV-Scanner). @@ -53,17 +55,18 @@ jobs: # not Dependabot, which had no `cargo` ecosystem — for a TLS stack that # compiles into a root-installed system service. - name: Scan bun.lock and Cargo.lock for known-vulnerable / malicious dependencies + id: scan uses: google/osv-scanner-action/osv-scanner-action@9fd1bcce27f67e3bd819a0a7620e332803dc43bc # v2.3.8 with: scan-args: |- --lockfile=bun.lock --lockfile=Cargo.lock - # PR/push runs skip this — a failure there is already visible to whoever - # opened the PR. It's the schedule run (nothing on main touched the - # lockfile, so nobody is watching) that needs a channel of its own; same + # Only the schedule run notifies — nothing on main touched the lockfile, + # so nobody is watching it the way a PR author watches their own checks + # or a push failure shows up against the commit they just merged. Same # webhook + `node -e … | curl` idiom integration-suite/run.sh uses. - name: Notify Slack on failure - if: failure() && github.event_name != 'pull_request' + if: steps.scan.outcome == 'failure' && github.event_name == 'schedule' env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index d9417eec3..e794e22f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### Fixes - Bump the `postcss` override from `8.5.23` to `8.5.26` to pull in `nanoid@^3.3.17`, clearing a high-severity OSV advisory (GHSA-2v37-7h3g-55p8) against the transitively-locked `nanoid@3.3.16`. (#670) -- Move the `Supply Chain` workflow's scheduled OSV-Scanner run from weekly to daily, and post to Slack when it fails — a scheduled failure on `main` previously surfaced only when the next PR happened to touch the lockfile, since a red scheduled run has no PR author to notice it. (#670) +- Move the `Supply Chain` workflow's scheduled OSV-Scanner run from weekly to daily, and optionally post the daily run's failures to Slack when `SLACK_WEBHOOK_URL` is configured — a scheduled failure on `main` previously surfaced only when the next PR happened to touch the lockfile, since a red scheduled run has no PR author to notice it. PR and push runs don't post; those failures are already visible to whoever opened or merged the PR. (#670) ## 1.0.0-beta.13 — 2026-08-07 From a691442721ee8421a1535ddb643c428c1fa7d889 Mon Sep 17 00:00:00 2001 From: NiveditJain Date: Mon, 10 Aug 2026 12:16:33 +0530 Subject: [PATCH 7/7] fix: notify step never fired, and a broken webhook failed silently Two CodeRabbit findings on the Slack notify step, both real: 1. `if: steps.scan.outcome == 'failure' && ...` has no failure()/ always()/cancelled() in it, so GitHub implicitly ANDs it with success() - the step would have been skipped every time, since it only makes sense to run once the job has already failed. Added failure() explicitly. 2. A curl exit code was captured but never checked past a warning echo, so a non-200 response (or network failure) still exited 0. Added 3 bounded retries, exiting nonzero after the last one fails. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/osv-scanner.yml | 21 +++++++++++++++------ CHANGELOG.md | 2 +- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.github/workflows/osv-scanner.yml b/.github/workflows/osv-scanner.yml index 60a8fde92..2b2eae4c3 100644 --- a/.github/workflows/osv-scanner.yml +++ b/.github/workflows/osv-scanner.yml @@ -65,8 +65,12 @@ jobs: # so nobody is watching it the way a PR author watches their own checks # or a push failure shows up against the commit they just merged. Same # webhook + `node -e … | curl` idiom integration-suite/run.sh uses. + # `failure()` is required, not decorative: a bare `if:` expression is + # implicitly ANDed with success(), so without it this step would be + # skipped every time — the one time it's meant to run is exactly when + # the job already failed. - name: Notify Slack on failure - if: steps.scan.outcome == 'failure' && github.event_name == 'schedule' + if: failure() && steps.scan.outcome == 'failure' && github.event_name == 'schedule' env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} run: | @@ -77,8 +81,13 @@ jobs: run_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" text="🔴 *Supply Chain scan failed* on \`${GITHUB_REF_NAME}\` (${GITHUB_EVENT_NAME}) — known-vulnerable or known-malicious dependency detected. <${run_url}|View run>" payload="$(node -e 'const t=require("fs").readFileSync(0,"utf8");process.stdout.write(JSON.stringify({text:t}))' <<<"$text")" - code="$(curl -sS --connect-timeout 10 --max-time 30 \ - -o /dev/null -w '%{http_code}' -X POST -H 'Content-type: application/json' \ - --data "$payload" "$SLACK_WEBHOOK_URL" 2>/dev/null || echo 000)" - if [ "$code" = 200 ]; then echo "✓ posted to Slack webhook" - else echo "⚠️ Slack webhook POST returned HTTP $code" >&2; fi + for attempt in 1 2 3; do + code="$(curl -sS --connect-timeout 10 --max-time 30 \ + -o /dev/null -w '%{http_code}' -X POST -H 'Content-type: application/json' \ + --data "$payload" "$SLACK_WEBHOOK_URL" 2>/dev/null || echo 000)" + if [ "$code" = 200 ]; then echo "✓ posted to Slack webhook"; exit 0; fi + echo "⚠️ Slack webhook POST attempt $attempt returned HTTP $code" >&2 + [ "$attempt" -lt 3 ] && sleep 5 + done + echo "✗ Slack webhook POST failed after 3 attempts" >&2 + exit 1 diff --git a/CHANGELOG.md b/CHANGELOG.md index e794e22f1..8c3011fda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### Fixes - Bump the `postcss` override from `8.5.23` to `8.5.26` to pull in `nanoid@^3.3.17`, clearing a high-severity OSV advisory (GHSA-2v37-7h3g-55p8) against the transitively-locked `nanoid@3.3.16`. (#670) -- Move the `Supply Chain` workflow's scheduled OSV-Scanner run from weekly to daily, and optionally post the daily run's failures to Slack when `SLACK_WEBHOOK_URL` is configured — a scheduled failure on `main` previously surfaced only when the next PR happened to touch the lockfile, since a red scheduled run has no PR author to notice it. PR and push runs don't post; those failures are already visible to whoever opened or merged the PR. (#670) +- Move the `Supply Chain` workflow's scheduled OSV-Scanner run from weekly to daily, and optionally post the daily run's failures to Slack when `SLACK_WEBHOOK_URL` is configured — a scheduled failure on `main` previously surfaced only when the next PR happened to touch the lockfile, since a red scheduled run has no PR author to notice it. PR and push runs don't post; those failures are already visible to whoever opened or merged the PR. The notify step needed its own `failure()` clause — a bare `if:` without one is implicitly ANDed with `success()`, so without it the step would have been silently skipped every single time (the one time it's meant to run is exactly when the job already failed) — and now retries the webhook POST 3 times, exiting nonzero on exhaustion so a broken webhook fails visibly instead of a green step that posted nothing. (#670) ## 1.0.0-beta.13 — 2026-08-07