diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e658a05..0ffbb088 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,12 @@ ## 0.0.11-beta.3 — 2026-05-28 ### Fixes +- Treat GitHub `neutral` check-run conclusions as non-failing in the `require-ci-green-before-stop` policy (e.g. Socket Security: Pull Request Alerts when the head branch is from an outside contributor and Socket can't process it). Previously the policy treated anything other than `success` / `skipped` / `cancelled` as failing, producing false-positive Stop blocks on PRs whose only "non-green" check was an explicit `neutral` (#410). - Fix the `bump-platform-submodule.yml` workflow's first post-merge push, which failed with `fatal: could not read Username for 'https://github.com'`. The `persist-credentials: false` hardening from #394 left the cross-repo `git push`/`fetch` unauthenticated, and the inline `Authorization: bearer …` extraheader only authenticates GitHub's REST API — git-over-HTTPS smart-protocol expects Basic auth with `x-access-token:`. Switch to a base64-encoded Basic header (matching `actions/checkout`'s own internal extraheader format) so the push and the rebase-and-retry fetch in the loop both authenticate (#395). +### Docs +- Add `docs/.vale.ini` and a `Mintlify` Vocab accept-list to suppress noisy `Mintlify Validation (exosphere) - vale-spellcheck` CI failures. Disables `Vale.Spelling` on the 14 translated language subdirs (`ar/`, `de/`, …, `zh/`) and `i18n/`, since running an English dictionary over auto-translated content produces only noise; keeps spellcheck active on the canonical English `*.{md,mdx}` files with a project Vocab covering brand names (`failproofai`, `Claude`, `Codex`, …), CLI tooling (`npx`, `bunx`, `gcloud`, `systemctl`, …), and Claude Code event names (`PreToolUse`, `SessionStart`, …) (#410). + ### Features - Add a `bump-platform-submodule.yml` workflow that pushes a matching `failproofai/oss` gitlink bump to `FailproofAI/platform` `main` on every merge into this repo's `main`, so the monorepo's pinned submodule commit tracks upstream automatically. Uses a `PLATFORM_BUMP_TOKEN` repo secret (fine-grained PAT, contents: read & write on `FailproofAI/platform`) for cross-repo auth, a concurrency group to serialize back-to-back merges, and a rebase-and-retry loop to stay race-safe against humans pushing to platform `main` between checkout and push (#394). - Add a supply-chain security CI gate: OSV-Scanner (`.github/workflows/osv-scanner.yml`) scans the resolved `bun.lock` tree against OSV.dev (GitHub/npm advisories + the OpenSSF malicious-packages feed) on every PR (incl. Dependabot bumps), on pushes to `main`, and weekly, and **blocks on any known-vulnerable or malicious dependency**. Adds a Socket GitHub App behavioral early-warning layer, an `osv-scanner.toml` allow-list for unfixable advisories, a README supply-chain status badge, and a `SECURITY.md` policy/runbook. Remediates the 18 pre-existing transitive advisories surfaced by the new gate (brace-expansion, flatted, minimatch, picomatch, postcss, vite, ws) by refreshing `bun.lock` within range, with `overrides` pinning `postcss` to the patched 8.5.x line (Next.js pins the vulnerable 8.4.31) and holding `eslint-plugin-react-hooks` at main's 7.0.1 so the refresh doesn't also bump the linter (#391). diff --git a/__tests__/hooks/builtin-policies.test.ts b/__tests__/hooks/builtin-policies.test.ts index b0effdcb..3aae34a0 100644 --- a/__tests__/hooks/builtin-policies.test.ts +++ b/__tests__/hooks/builtin-policies.test.ts @@ -3312,6 +3312,16 @@ describe("hooks/builtin-policies", () => { expect(result.decision).toBe("allow"); }); + it("treats neutral conclusions as non-failing (e.g. Socket on outside-contributor PRs)", async () => { + mockCiScenario("feat/branch", JSON.stringify([ + { status: "completed", conclusion: "neutral", name: "Socket Security: Pull Request Alerts" }, + { status: "completed", conclusion: "success", name: "build" }, + ])); + const ctx = makeCtx({ eventType: "Stop", session: { cwd: "/repo" } }); + const result = await policy.fn(ctx); + expect(result.decision).toBe("allow"); + }); + it("failing checks take priority over pending checks", async () => { mockCiScenario("feat/branch", JSON.stringify([ { status: "completed", conclusion: "failure", name: "test" }, diff --git a/docs/.vale.ini b/docs/.vale.ini new file mode 100644 index 00000000..8f7f572b --- /dev/null +++ b/docs/.vale.ini @@ -0,0 +1,6 @@ +StylesPath = styles + +Vocab = Mintlify + +[{ar,de,es,fr,he,hi,it,ja,ko,pt-br,ru,tr,vi,zh,i18n}/**] +Vale.Spelling = NO diff --git a/docs/built-in-policies.mdx b/docs/built-in-policies.mdx index 845d20e4..55093ffe 100644 --- a/docs/built-in-policies.mdx +++ b/docs/built-in-policies.mdx @@ -811,7 +811,7 @@ short-circuits to allow. Run `gh auth login` with a personal access token that h ### `require-ci-green-before-stop` **Event:** Stop -**Default:** Denies stopping when CI checks are failing or still running on the current branch. Checks both GitHub Actions workflow runs and third-party bot checks (e.g. CodeRabbit, SonarCloud, Codecov). Treats `skipped` and `cancelled` conclusions as success. Returns an informational message when all checks pass. +**Default:** Denies stopping when CI checks are failing or still running on the current branch. Checks both GitHub Actions workflow runs and third-party bot checks (e.g. CodeRabbit, SonarCloud, Codecov). Treats `skipped`, `cancelled`, and `neutral` conclusions as non-failing (the latter covers e.g. Socket Security alerts on outside contributor PRs, where the app intentionally reports neutral rather than success/failure). Returns an informational message when all checks pass. No parameters. diff --git a/docs/styles/config/vocabularies/Mintlify/accept.txt b/docs/styles/config/vocabularies/Mintlify/accept.txt new file mode 100644 index 00000000..c7f9498d --- /dev/null +++ b/docs/styles/config/vocabularies/Mintlify/accept.txt @@ -0,0 +1,53 @@ +failproofai +Claude +Anthropic +Codex +Copilot +Cursor +Gemini +OpenCode +PreToolUse +PostToolUse +SessionStart +SessionEnd +UserPromptSubmit +SubagentStop +PreCompact +Notification +CLIs +Namespaces +namespace +allowlist +denylist +blocklist +subcommands +argv +metacharacters +Codecov +CodeRabbit +SonarCloud +LiteLLM +Mintlify +MCP +dogfood +bun +bunx +npx +pnpx +pnpm +uv +pipenv +conda +gcloud +systemctl +kubectl +terraform +helm +curl +wget +mjs +cjs +tsx +jsx +failopen +failclosed diff --git a/src/hooks/builtin-policies.ts b/src/hooks/builtin-policies.ts index 54db64c8..30eaa8c3 100644 --- a/src/hooks/builtin-policies.ts +++ b/src/hooks/builtin-policies.ts @@ -1471,7 +1471,8 @@ function requireCiGreenBeforeStop(ctx: PolicyContext): PolicyResult { r.status === "completed" && r.conclusion !== "success" && r.conclusion !== "skipped" && - r.conclusion !== "cancelled", + r.conclusion !== "cancelled" && + r.conclusion !== "neutral", ); if (failing.length > 0) { const names = failing.map((r) => `"${r.name}"`).join(", ");