From 5f8677b23d114e6793e80e10ee119f11c62ecda4 Mon Sep 17 00:00:00 2001 From: Jose Montes de Oca Date: Thu, 6 Aug 2026 14:13:24 -0400 Subject: [PATCH 1/3] chore: pin pnpm 10.34.5 and add 48h release cooldown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit minimumReleaseAge, available since pnpm 10.16, keeps freshly published versions unresolvable for 48 hours — the window in which registry compromises are typically caught and yanked. minimumReleaseAgeExclude is the escape hatch when a security fix is needed sooner: a reviewable config change rather than a standing hole. The pnpm bump also carries the fix for the fail-open integrity check in CVE-2026-50021. The new workspace file is settings-only; this repo is a single package, not a pnpm workspace. --- package.json | 2 +- pnpm-workspace.yaml | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 pnpm-workspace.yaml diff --git a/package.json b/package.json index 11d1fe8..cbf5891 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "url": "https://github.com/openprose/docs.git" }, "homepage": "https://docs.prose.md", - "packageManager": "pnpm@10.11.0", + "packageManager": "pnpm@10.34.5", "scripts": { "postinstall": "fumadocs-mdx", "prebuild": "claude -p 'prose run .prose/generate-agent-skills.prose && prose run .prose/changelog-sync.prose'", diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..ce81532 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,7 @@ +# Settings only — this repo is a single package, not a pnpm workspace. +# +# Freshly published versions are not resolvable for 48h (supply-chain cooldown). +# Urgent security fix needed sooner? Add the package to minimumReleaseAgeExclude, +# install, then remove it — a reviewable config change, not a standing hole. +minimumReleaseAge: 2880 +minimumReleaseAgeExclude: [] From a403c790f2bd554d8f2c7a1f63e9dab615563297 Mon Sep 17 00:00:00 2001 From: Jose Montes de Oca Date: Thu, 6 Aug 2026 15:08:23 -0400 Subject: [PATCH 2/3] ci: pin third-party actions to commit SHAs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit setup-flyctl tracked @master in the deploy job — an arbitrary future commit executing with the Fly deploy token in scope. It now takes the same SHA platform already pins, which master, 1.6 and v1 all point at, so nothing moves except the mutability. pnpm/action-setup follows the same principle: a tag can be retagged at a malicious commit without any version string in the workflow changing. Each SHA is what its tag resolves to today, and the trailing version comment keeps the diff readable. --- .github/workflows/deploy-docs.yml | 2 +- .github/workflows/verify.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 43ffa71..a7b700c 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -19,7 +19,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Fly CLI - uses: superfly/flyctl-actions/setup-flyctl@master + uses: superfly/flyctl-actions/setup-flyctl@ed8efb33836e8b2096c7fd3ba1c8afe303ebbff1 # 1.6 - name: Deploy to Fly.io run: | diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index a7c44bc..c6ed6d1 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -14,7 +14,7 @@ jobs: timeout-minutes: 15 steps: - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v4 + - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 - uses: actions/setup-node@v4 with: node-version: 22 From d32e9b601505d1626d1eb3e3555634fbe961050f Mon Sep 17 00:00:00 2001 From: Jose Montes de Oca Date: Fri, 7 Aug 2026 12:09:50 -0400 Subject: [PATCH 3/3] ci: surface dependency advisories during verify MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reports known advisories in the production graph without gating the build — the graph carries a sizeable transitive backlog, so a blocking gate would be red on its first run and ignored soon after. The number being visible and trending is the point. Dependabot's github-actions entry keeps the pinned action SHAs current; without it they silently rot. --- .github/dependabot.yml | 23 +++++++++++++++++++++++ .github/workflows/verify.yml | 5 +++++ 2 files changed, 28 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..16c02f9 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,23 @@ +version: 2 + +# Third-party actions are pinned to immutable commit SHAs. SHAs never move on +# their own, so this entry is what keeps them current — without it the pins rot. +# +# Only the github-actions ecosystem is enabled. npm version-update PRs are +# deliberately off: frozen-lockfile installs plus the release cooldown in +# pnpm-workspace.yaml already manage dependency drift, and a PR per release is +# noise nobody reads. Dependabot *alerts* are enabled in repo settings and are +# the signal layer we do want; automated *security-update* PRs are off for the +# same reason — advisories get triaged against real exposure, not auto-patched. +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + # One PR for all action bumps instead of one per action. + groups: + actions: + patterns: + - "*" + commit-message: + prefix: "ci" diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index c6ed6d1..8e4c955 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -20,6 +20,11 @@ jobs: node-version: 22 cache: pnpm - run: pnpm install --frozen-lockfile + # Informational, not a gate: advisories here are dominated by deep + # transitive packages we do not control, and a permanently red step + # teaches everyone to ignore it. Read the output. + - run: pnpm audit --prod + continue-on-error: true - run: pnpm typecheck - run: pnpm lint - run: pnpm spell