From d3bd9c60986338713da98558352d03854a0ccfed Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 2 Sep 2026 20:02:12 +0000 Subject: [PATCH] ci: run the half-state sweeper's 1551-case self-test in the build job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `scripts/pm/check-half-states.mjs` declares `--self-test` and carries 1551 cases, and nothing in this repo ran them. The self-test registry cannot reach it: `tools/ci-scripts/run-self-tests.mjs` scans `.github/scripts` top level only, and that property is load-bearing — it is what lets `.github/scripts/lib/` exist without tripping the unregistered-self-test rule. So this lands as one step in the existing `build` job rather than as a registry entry, leaving the scan surface and gate topology untouched. Ablation, run on a throwaway copy so the pinned upstream file was never written: mutating `DEFAULT_SWEEP_REPO` reddens 2 of the 1551 cases and exits 1. The step is therefore a live drift detector for behaviour-changing edits to this verbatim copy — not a hash-pin, which needs a cross-repo credential and is a separate decision. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01ChPQM8jamxLUfUAxwFpJ8S --- .github/workflows/ci.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 674e533..fda9fd0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,6 +54,29 @@ jobs: cache: pnpm - run: pnpm install --frozen-lockfile + # `scripts/pm/check-half-states.mjs` is a verbatim upstream copy (#237) + # whose 1551 cases were run by nothing here. It is a STEP and not a + # registry entry because `tools/ci-scripts/run-self-tests.mjs` scans + # `.github/scripts` top level only, and that is load-bearing — it is what + # lets `.github/scripts/lib/` exist without tripping the + # unregistered-self-test rule. Widening the scan to reach one script would + # change this repo's gate topology; a step changes nothing. + # + # What it buys is a drift detector, not a hash-pin: #237's ablation + # mutated `DEFAULT_SWEEP_REPO` in this copy and 2 of the 1551 went red, so + # an edit here that changes BEHAVIOUR fails. One that changes bytes + # without changing behaviour still passes — pinning this copy to upstream + # byte for byte needs a cross-repo credential and is a separate decision. + # + # `--self-test` is the whole of it. Without the flag the script runs a + # live sweep needing a transport prerequisite this job does not have; that + # caller is `.github/workflows/half-state-patrol.yml`, on its own + # schedule. Zero-dependency and about a second, so it runs before the + # build rather than behind it. + - name: Half-state sweeper self-test + shell: bash + run: node scripts/pm/check-half-states.mjs --self-test + # `content/docs/**/*.zh-Hant.mdx` and `meta.zh-Hant.json` are generated # from the Simplified siblings by `apps/docs/scripts/gen-zh-hant.mjs` and # committed, because `lib/seo.ts` tells a real translation from an English