From 21e7a4a8f84975295649589356cc63288e2bcb86 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Thu, 30 Jul 2026 13:20:27 +0800 Subject: [PATCH 1/3] chore: remove CircleCI from repo CircleCI's ci/circleci: verify check has been persistently red on main's own tip independent of any PR content, is not part of this repo's required-checks set, and duplicates coverage already provided by .github/workflows/ci.yml. Co-Authored-By: Claude Fable 5 --- .circleci/config.yml | 88 -------------------------------------------- 1 file changed, 88 deletions(-) delete mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 94ff5ff680..0000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,88 +0,0 @@ -# See: https://circleci.com/docs/reference/configuration-reference/ -# Note: CircleCI config v2.1 treats the double left-angle merge marker as a -# special tag — never use shell heredocs in run steps. -version: 2.1 - -jobs: - verify: - docker: - # Node >=24.11.0 is required by current lockfile packages (e.g. @babel/parser - # engines "^22.18.0 || >=24.11.0") under .npmrc engine-strict=true. - # cimg/node:24.9 fails npm ci immediately; 24.18 matches .nvmrc major and - # the Cloud Agent runtime. Prefer the floating patch tag: digest pin plus - # resource_class: small failed this project's executor before steps ran. - - image: cimg/node:24.18 - steps: - - checkout - - run: - name: Skip verification on docs-only changes - command: | - # CircleCI checkouts often restrict the origin fetch refspec to the - # branch under test, so force main into the remote-tracking ref. - if ! git fetch --depth 100 origin "main:refs/remotes/origin/main"; then - echo "Could not fetch origin/main; running full verification." - exit 0 - fi - BASE_SHA="$(git rev-parse origin/main)" - HEAD_SHA="$(git rev-parse HEAD)" - # Reuse scripts/ci-change-scope.mjs so policy-bearing Markdown - # (AGENTS.md, .github/pull_request_template.md, docs/codex-review-protocol.md, …) - # is not false-greened as docs-only. - node scripts/ci-change-scope.mjs --base "$BASE_SHA" --head "$HEAD_SHA" | tee /tmp/ci-change-scope.txt - if grep -qx 'docs_only=true' /tmp/ci-change-scope.txt; then - echo "Docs-only change (ci-change-scope); skipping install and verification." - circleci-agent step halt - else - echo "Non-docs changes detected; running verification." - fi - - run: - name: Assert node/npm engine majors - # Image-bundled npm 11.x satisfies package.json engines; avoid non-root - # global reinstalls (cimg installs Node under /usr/local). - command: | - node --version - npm --version - node -e 'const major=Number(process.version.slice(1).split(".")[0]); if(major!==24){console.error("expected node 24.x, got",process.version); process.exit(1)}' - node -e 'const {execSync}=require("node:child_process"); const v=execSync("npm --version",{encoding:"utf8"}).trim(); if(!/^11\./.test(v)){console.error("expected npm 11.x, got",v); process.exit(1)}' - node -e 'const [maj,min]=process.versions.node.split(".").map(Number); if(maj===24 && min<11){console.error("lockfile requires Node >=24.11.0 under engine-strict; got",process.versions.node); process.exit(1)}' - - restore_cache: - keys: - - npm-deps-v2-{{ checksum "package-lock.json" }} - - run: - name: Install dependencies - no_output_timeout: 15m - command: npm ci - - save_cache: - key: npm-deps-v2-{{ checksum "package-lock.json" }} - paths: - - ~/.npm - - run: - name: Format check - command: npm run format:check - - run: - name: Lint - command: npm run lint - - run: - name: Typecheck - command: npm run typecheck - - run: - name: Install deterministic Python PDF test prerequisite - # Same PyMuPDF pin as .github/workflows/ci.yml. cimg/base only ships - # python-is-python3 (no pip), and Ubuntu 24.04 blocks system pip installs - # (PEP 668), so bootstrap a venv and point PYTHON_BIN at it for tests. - command: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends python3-pip python3-venv - python3 -m venv /tmp/ci-pdf-venv - /tmp/ci-pdf-venv/bin/pip install --disable-pip-version-check "PyMuPDF==1.28.0" - /tmp/ci-pdf-venv/bin/python -c "import fitz; print('PyMuPDF', fitz.version)" - - run: - name: Unit tests - environment: - PYTHON_BIN: /tmp/ci-pdf-venv/bin/python - command: npm run test - -workflows: - verify: - jobs: - - verify From f20ac6d10f511f3e5d56e78328a2faee9ad93520 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Thu, 30 Jul 2026 13:22:36 +0800 Subject: [PATCH 2/3] docs(ledger): record PR #1412 review outcome Co-Authored-By: Claude Fable 5 --- docs/branch-review-ledger.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/branch-review-ledger.md b/docs/branch-review-ledger.md index c7c2da3c74..37f1e564cc 100644 --- a/docs/branch-review-ledger.md +++ b/docs/branch-review-ledger.md @@ -1318,3 +1318,4 @@ Records before 2026-07-28 were written by hand and had drifted: 146 lines carrie | 2026-07-30 | cursor/pr-1394-ledger-closeout-c2bf | f734dc4d4c8b19d5fec43bbd388c2a421e47668a | PR #1399 babysit / CI+Bugbot closeout | MERGE-READY. No failing CI, no unresolved review threads, merge-tree clean vs origin/main, Bugbot no bugs. Docs-only ledger append for merged #1394; no code fix required. | hosted PR required SUCCESS; Static PR SUCCESS (lint/typecheck/format/ledger); CircleCI verify SUCCESS; local check:branch-review-ledger PASS; prettier PASS; lint PASS; Bugbot pr-bugbot no findings | | 2026-07-30 | claude/test-coverage-analysis-2vcd8a | d5842e62238237ff5c47da0b32ef8d9f12819714 | PR #1398 babysit | COMPLETE for tip: cleared main conflict; fixed Codex P2 (reject refs/*→origin/* nesting); prior Codex P2 (destination check) already fixed in de594186 and resolved; 0 unresolved threads; merge-tree clean. Hosted CI re-running. | repo-hygiene 40/40; verify:cheap earlier PASS on pre-tip; format:changed PASS; Bugbot none; Codex P2 resolved | | 2026-07-30 | claude/white-element-positioning-t607pk | b82ff088436cd936d219a4eb54a54d09a88fbd7c | pr-babysit | Product tip sound; no code fix. Hosted CI fully green once at e7a27bbf (Production UI+PR required). Recurring blocker: repeated Merge main into PR cancels Production UI mid-run so PR required fails with production-ui=cancelled. merge-tree clean / MERGEABLE when left alone. No review threads. Bugbot: no cursor[bot] findings; suite stays queued. Local A/B: 3 Playwright fails identical on --surface/--background. | verify:cheap:pass; hosted:e7a27bbf:PR-required+Production-UI:pass; A/B-playwright:env-flake; bugbot:no-findings; churn:main-merges-cancel-ui | +| 2026-07-30 | claude/remove-circleci | 21e7a4a8f84975295649589356cc63288e2bcb86 | Remove CircleCI (persistent non-required red check) | Opened PR #1412. Diagnosed ci/circleci:verify red on both PR #1401 and main's own tip; proved via faithful shallow-clone repro that the docs-only classifier (ci-change-scope.mjs) is not the cause; stopped local repro test run per explicit user request; user chose to remove CircleCI outright rather than keep debugging | format:check PASS, lint PASS, typecheck PASS (all against main tip in a fresh worktree); npm test not run (stopped early); grepped repo for other CircleCI references - none found; no provider-backed checks | From 8a6d3da5cb5c3eaa75d59993da312fee3f9f4dac Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Thu, 30 Jul 2026 13:35:46 +0800 Subject: [PATCH 3/3] test: remove circleci-config-contract test Its subject (.circleci/config.yml) no longer exists. Co-Authored-By: Claude Fable 5 --- tests/circleci-config-contract.test.ts | 60 -------------------------- 1 file changed, 60 deletions(-) delete mode 100644 tests/circleci-config-contract.test.ts diff --git a/tests/circleci-config-contract.test.ts b/tests/circleci-config-contract.test.ts deleted file mode 100644 index 7df6d2c6d0..0000000000 --- a/tests/circleci-config-contract.test.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { readFileSync } from "node:fs"; - -import { describe, expect, it } from "vitest"; - -const read = (path: string) => readFileSync(new URL(`../${path}`, import.meta.url), "utf8"); - -describe("CircleCI config contract", () => { - const config = read(".circleci/config.yml"); - const engines = JSON.parse(read("package.json")).engines as { node: string; npm: string }; - const expectedNodeMajor = engines.node.match(/^(\d+)/)?.[1]; - const expectedNpmMajor = engines.npm.match(/^(\d+)/)?.[1]; - - it("pins the executor image to a Node 24.11+ cimg tag (lockfile engine-strict)", () => { - const image = config.match(/image:\s*cimg\/node:(\d+)\.(\d+)/); - expect(image, "expected a cimg/node:. docker image").not.toBeNull(); - expect(image?.[1]).toBe(expectedNodeMajor); - expect(Number(image?.[2]), "Node minor must be >= 11 for @babel/parser engines").toBeGreaterThanOrEqual(11); - }); - - it("asserts npm matches the package.json npm engine major (no broken global reinstall)", () => { - expect(config).not.toMatch(/npm install -g npm@/); - expect(config).toContain(`expected npm ${expectedNpmMajor}.x`); - expect(config).toContain("Node >=24.11.0"); - // CircleCI config v2.1 rejects unescaped shell heredocs. - expect(config).not.toMatch(/(? { - expect(config).not.toContain("say-hello"); - expect(config).not.toContain("Hello, World!"); - expect(config).not.toContain("cimg/base:"); - - for (const command of ["npm ci", "npm run format:check", "npm run lint", "npm run typecheck", "npm run test"]) { - expect(config, `missing step: ${command}`).toContain(command); - } - }); - - it("reuses scripts/ci-change-scope.mjs for the docs-only skip (no naive md regex)", () => { - expect(config).toContain("scripts/ci-change-scope.mjs"); - expect(config).toContain("docs_only=true"); - expect(config).toContain("main:refs/remotes/origin/main"); - expect(config).not.toMatch(/\^\(docs\/\|\.\*\\?\.md\$\)/); - }); - - it("bootstraps a venv + pinned PyMuPDF and exports PYTHON_BIN for tests", () => { - expect(config).toContain("python3-venv"); - expect(config).toContain("PyMuPDF==1.28.0"); - expect(config).toContain("PYTHON_BIN: /tmp/ci-pdf-venv/bin/python"); - const actions = read(".github/workflows/ci.yml"); - const actionsPin = actions.match(/PyMuPDF==[\d.]+/)?.[0]; - const circlePin = config.match(/PyMuPDF==[\d.]+/)?.[0]; - expect(circlePin).toBe(actionsPin); - expect(config.indexOf("PyMuPDF==1.28.0")).toBeLessThan(config.indexOf("npm run test")); - }); - - it("avoids the executor knobs that failed before any step ran on this project", () => { - expect(config).not.toMatch(/^\s*resource_class:\s*small\s*$/m); - expect(config).not.toMatch(/^\s*-\s*image:\s*cimg\/node:[^\n]*@sha256:/m); - }); -});