From 4f90578291c19fcf991bca84a717972689adef5a Mon Sep 17 00:00:00 2001 From: wshallwshall Date: Tue, 28 Jul 2026 13:24:13 -0500 Subject: [PATCH] =?UTF-8?q?docs(ci):=20stop=20describing=20this=20repo=20a?= =?UTF-8?q?s=20the=20mirror=20=E2=80=94=20the=20workflow=20comments=20stil?= =?UTF-8?q?l=20document=20the=20pre-cutover=20topology?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A systematic sweep for damage left by the retired publish.ps1 slug rewrite. Detectors for six classes across every tracked file: A self-substitution `s#X#X#` 0 (fixed earlier — release.yml) B slug compared against itself 0 (fixed earlier — release.yml) C same slug twice on one line 6 (README badges — benign) D present-tense private/mirror prose 87 <- this commit addresses the workflow share E references to retired publish machinery 28 (all explanatory or deliberately optional) F private-slug/owner references 23 (mostly @wshallwshall the USER, correct) Classes A and B are clean. E turned out benign: the scripts/publish/ mentions in test_anon_parity.py are comments ABOUT the retired path (part of the fix for a silent skip), and test_feature_map_claims.py treats an absent deny-list as a documented branch with its own non-vacuity test. F is mostly the maintainer's GitHub handle -- CODEOWNERS and the CLA allowlist name a USER, not a repo, and @wshallwshall is a collaborator on the org repo (verified 204), so code-owner assignment works. D is the real finding, and it is the same failure that produced the release-guard bug. The GUARDS are all correct (`== MEFORORG`) and are untouched here -- byte-identical -- but the comments around them still call MEFORORG "the mirror" and describe a private source repo that runs CI. Anyone maintaining these files reads that MEFORORG is a mirror, which is exactly the belief that left release.yml gated `!= MEFORORG` and disabled releases entirely until a tag failed. One correction the sweep produced: the per-repo `else` branches are NOT dead. A fork has GITHUB_REPOSITORY != MEFORORG, so that branch now serves FORKS -- keeping 2x-billed Windows legs off a contributor's own minutes -- rather than the retired private repo. So the logic stays and only the labels change, which is why this is a comments-only diff. Also corrected in release.yml: the SLSA provenance step's note claimed the step is skipped "while this repo is private". It is public now, so the step RUNS and every release carries provenance; the gate remains for a private fork. That comment described the opposite of current behaviour. SCOPE. Workflows only -- 30 of the 87 lines, in the four files where the inverted framing can cause a bug rather than merely mislead. The remaining ~57 are in docs/ and tests/ (INSTALL-GUIDE, Secure_AI_Development_Standards, handoff notes, a few test docstrings); same rot, no execution consequence, and folding them in would bury a CI diff under prose. Left for a follow-up. Verified: all four workflows still parse, `git diff` shows no change to any `github.repository` / $GITHUB_REPOSITORY guard, and the release/scaffold/lint-parity suites pass. --- .github/workflows/ci.yml | 50 ++++++++++++++++++--------------- .github/workflows/codeql.yml | 21 ++++++++------ .github/workflows/release.yml | 7 +++-- .github/workflows/scorecard.yml | 16 ++++++----- 4 files changed, 53 insertions(+), 41 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f50f4f89..25327fb2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -267,18 +267,19 @@ jobs: # push-to-main + workflow_dispatch (full coverage), and PRs that touch ide/** or this workflow (the # `changes.ide` path-gate) — a pure-Python PR can't change the isolated npm project's result, so it's # skipped there. Not on the nightly cron: the engine heavy legs need that safety net, an isolated npm - # build gated on its own paths does not. The per-repo os matrix below keeps the 2x-billed windows-latest - # electron leg off the private repo while still running it free on the mirror. + # build gated on its own paths does not. The per-repo os matrix below runs the 2x-billed + # windows-latest electron leg here (this repo is public, so hosted runners are free) and drops it on + # a fork, where those minutes come out of the fork owner's own allowance. needs: changes if: github.event_name == 'workflow_dispatch' || needs.changes.outputs.ide == 'true' runs-on: ${{ matrix.os }} strategy: fail-fast: false - # Per-repo os matrix (built in `changes`): ubuntu-only on the private repo; ubuntu + windows-latest - # on the mirror. The windows-latest leg is the 2x-billed one that runs the @vscode/test-electron - # integration suite — running it ONLY on the free public mirror keeps that Windows cost off the - # private repo without losing the coverage. `ide` is not a required check and ci-gate does not - # `needs` it, so dropping the windows leg here can't wedge anything. + # Per-repo os matrix (built in `changes`): ubuntu + windows-latest on THIS repo, ubuntu-only on a + # fork. The windows-latest leg is the 2x-billed one that runs the @vscode/test-electron integration + # suite; this repo is public so hosted minutes are free, while on a fork they are billed to the + # fork owner. `ide` is not a required check and ci-gate does not `needs` it, so dropping the + # windows leg on a fork can't wedge anything. matrix: ${{ fromJSON(needs.changes.outputs.ide_matrix) }} defaults: run: @@ -304,9 +305,9 @@ jobs: # The vscode-free suites (the pure model layer: the engine link state + its two frozen boundary # allowlists, the settings-scope SEC-005 invariant, the graph/steps/HL7 models, …). They need no - # Extension Host, so they run on EVERY leg — including ubuntu on the private repo, where PRs land. - # Before this step they ran NOWHERE here: `npm test` is Windows-only and the private repo's ide - # matrix is ubuntu-only, so the entire node-side estate was type-checked and never executed. + # Extension Host, so they run on EVERY leg — including the ubuntu-only leg a fork gets. + # Before this step they ran NOWHERE on an ubuntu-only matrix: `npm test` is Windows-only, so the + # entire node-side estate was type-checked and never executed there. # ADR 0110's allowlists are only "asserted in CI" because of this line. - name: Unit tests (node-side, no VS Code) run: npm run test:unit @@ -340,12 +341,12 @@ jobs: # `ide`: run the ide build job only when a PR touches ide/** or this workflow (true on # push/dispatch for full coverage; false on the nightly cron). Not a required check. ide: ${{ steps.f.outputs.ide }} - # `matrix`: the `test` job's include list, per-repo — ubuntu-only on the private repo (the - # self-hosted Windows runners are retired), full ubuntu+windows matrix on the mirror (free - # hosted). Consumed as `matrix: ${{ fromJSON(needs.changes.outputs.matrix) }}` in `test`. + # `matrix`: the `test` job's include list, per-repo — full ubuntu+windows matrix HERE (this repo is + # public, so hosted runners are free; the self-hosted Windows runners are retired), ubuntu-only on + # a fork. Consumed as `matrix: ${{ fromJSON(needs.changes.outputs.matrix) }}` in `test`. matrix: ${{ steps.f.outputs.matrix }} - # `ide_matrix`: the `ide` job's os matrix, per-repo — ubuntu-only on the private repo; ubuntu + - # windows-latest on the mirror, where the 2x-billed VS Code electron leg runs FREE. Consumed as + # `ide_matrix`: the `ide` job's os matrix, per-repo — ubuntu + windows-latest HERE, where the + # 2x-billed VS Code electron leg runs free; ubuntu-only on a fork. Consumed as # `matrix: ${{ fromJSON(needs.changes.outputs.ide_matrix) }}` in `ide`. ide_matrix: ${{ steps.f.outputs.ide_matrix }} steps: @@ -360,9 +361,13 @@ jobs: BASE_SHA: ${{ github.event.pull_request.base.sha }} run: | # test matrix, per-repo — computed FIRST (independent of the event, before any early exit). - # Mirror (MEFORORG): full ubuntu + windows-2022 + windows-2025 on FREE hosted runners. - # Private repo (wshallwshall): the UBUNTU leg ONLY — the self-hosted Windows NucBox runners - # are retired. `hosted` = the runner labels (an array; see the `test` job's runs-on). + # THIS repo (MEFORORG/MessageFoundry, the source since the cutover): full ubuntu + windows-2022 + # + windows-2025 on FREE hosted runners — free because the repo is public. + # Anywhere else (a FORK): the UBUNTU leg ONLY, so a contributor's own minutes are not spent on + # the 2x-billed Windows legs. This branch used to mean "the private source repo"; that repo is + # now an inactive archive with Actions disabled, so a fork is the only thing that reaches it. + # The self-hosted Windows NucBox runners are retired either way. + # `hosted` = the runner labels (an array; see the `test` job's runs-on). # $GITHUB_REPOSITORY is a built-in runner env var, read here as plain shell (NOT a workflow- # expression interpolation into the run body), so it is zizmor-safe and cannot be misparsed as # an Actions expression the way a literal double-brace token in a run: block would be. @@ -375,7 +380,7 @@ jobs: echo "matrix={\"include\":[$U]}" >> "$GITHUB_OUTPUT" fi # ide matrix, per-repo (computed here with the test matrix, before any early exit): the - # 2x-billed windows-latest electron leg runs ONLY on the FREE public mirror; the private repo + # 2x-billed windows-latest electron leg runs only HERE, where hosted minutes are free; a fork # builds + type-checks the extension on ubuntu only. Consumed as # matrix: fromJSON(needs.changes.outputs.ide_matrix) in the ide job. (No shell vars here, so a # single-quoted literal JSON needs no escaping and carries no run-block workflow expression.) @@ -1075,9 +1080,10 @@ jobs: # re-validates a specific merge on demand. windows-service-smoke: name: windows service smoke (${{ matrix.os }}, py${{ matrix.python-version }}) - # Mirror-only: this spins up 2x-billed hosted Windows runners on BOTH Server SKUs, so run it FREE on - # the public mirror's nightly schedule and never on the private repo. ci-gate `needs` this job, but a - # `skipped` leg counts as a pass there, so gating it off the private repo cannot wedge the gate. + # This repo only: it spins up 2x-billed hosted Windows runners on BOTH Server SKUs, which is free + # here (public) and billed to the owner of a fork. Nightly schedule + manual dispatch only. ci-gate + # `needs` this job, but a `skipped` leg counts as a pass there, so gating it off a fork cannot wedge + # the gate. if: (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.repository == 'MEFORORG/MessageFoundry' runs-on: ${{ matrix.os }} strategy: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index c5d17e54..8ee0669e 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -4,19 +4,21 @@ name: CodeQL # rules in security.yml — it finds vulnerable flows those pattern matchers can't, e.g. untrusted # HL7/config data reaching a sink across function boundaries. # -# WHY THIS IS GUARDED TO THE MIRROR: CodeQL uploads results to GitHub code scanning, which on a -# PRIVATE repo requires paid GitHub Advanced Security (see security.yml's header note). This repo's -# source of truth is private, but the OSS mirror MEFORORG/MessageFoundry is PUBLIC, where CodeQL + -# code scanning are FREE. So the analyze job is gated on the repo slug: it is SKIPPED (a no-op) on the -# private source repo and runs only once publish.ps1 mirrors this file to MEFORORG/MessageFoundry. -# Nothing to pay, nothing to fail on the private side. +# WHY THIS IS GUARDED TO THE REPO SLUG: CodeQL uploads results to GitHub code scanning, which on a +# PRIVATE repo requires paid GitHub Advanced Security (see security.yml's header note). THIS repo is +# PUBLIC, so CodeQL + code scanning are FREE here. The analyze job is gated on the slug so it stays a +# skipped no-op anywhere the upload would fail or be billed — a fork, or the retired private archive. +# +# (Pre-cutover this described MEFORORG as "the OSS mirror" of a private source repo, and said the job +# ran "once publish.ps1 mirrors this file". Both premises are gone: MEFORORG is the source, and the +# publish machinery was deleted. The GUARD was already right — only its rationale had rotted.) # # PINNING CAVEAT: this repo SHA-pins every Action for supply-chain integrity. actions/checkout below # reuses the repo's existing v7.0.0 pin; the github/codeql-action steps are on the v3 tag for now # because the live commit SHA must be looked up at authoring — SHA-pin them before treating this as a # hardened gate (OSSF Scorecard / zizmor would flag the unpinned tags). # -# ALTERNATIVE (no file): on the public mirror you can instead enable CodeQL "default setup" from +# ALTERNATIVE (no file): you can instead enable CodeQL "default setup" from # Settings -> Security -> Code scanning (one toggle, auto-pinned, auto-updated). Default setup and this # advanced workflow are mutually exclusive — if you turn default setup ON, delete this file. on: @@ -36,8 +38,9 @@ permissions: jobs: analyze: name: CodeQL (${{ matrix.language }}) - # ONLY on the public mirror — code scanning is free there; on the private source repo it would need - # paid GHAS, so this is a skipped no-op there. (GitHub Actions string == is case-insensitive.) + # ONLY on this repo — it is public, so code scanning is free; anywhere else (a fork, or the retired + # private archive) it would need paid GHAS, so this stays a skipped no-op there. (GitHub Actions + # string == is case-insensitive.) if: github.repository == 'MEFORORG/MessageFoundry' runs-on: ubuntu-latest permissions: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d1938f35..cc9f868f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -228,9 +228,10 @@ jobs: # gh attestation verify dist/ --repo MEFORORG/MessageFoundry # GATED to PUBLIC repos: the GitHub attestation API (actions/attest-build-provenance) is "not # available for user-owned private repositories" and FAILS there, aborting the job BEFORE the PyPI - # publish below. While this repo is private the step is SKIPPED (skip != fail, so the release - # proceeds); provenance is still covered by the Sigstore bundle (above) and the PyPI-side PEP 740 - # attestations (publish step below). Auto-resumes if a release ever runs from the public mirror. + # publish below. THIS repo is public since the cutover, so the step now RUNS and every release + # carries SLSA provenance. The gate remains for a private fork, where it SKIPS rather than fails + # (skip != fail, so the release proceeds) and provenance is still covered by the Sigstore bundle + # above plus the PyPI-side PEP 740 attestations from the publish step. # `github.event.repository.private` is populated on the tag-push event. - name: Attest build provenance (SLSA) for sdist + wheel if: ${{ !github.event.repository.private }} diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index e534b481..09e187d8 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -5,12 +5,14 @@ name: Scorecard # repo already does (SHA-pinned Actions, least-privilege tokens) and catches regressions, and yields a # public OpenSSF badge. # -# WHY GUARDED TO THE MIRROR: like CodeQL, Scorecard uploads SARIF to GitHub code scanning (paid GHAS on -# a private repo) and `publish_results: true` requires a PUBLIC repo. So this is gated to the public -# mirror MEFORORG/MessageFoundry — a skipped no-op on the private source repo, free on the mirror after -# publish.ps1 mirrors this file. NOTE: the Branch-Protection check then reflects the MIRROR's settings, -# not the private repo's; the workflow-hardening checks (Pinned-Dependencies / Dangerous-Workflow / -# Token-Permissions) assess the shared source and are the signal that transfers. +# WHY GUARDED TO THE REPO SLUG: like CodeQL, Scorecard uploads SARIF to GitHub code scanning (paid GHAS +# on a private repo) and `publish_results: true` requires a PUBLIC repo. THIS repo is public, so both +# are free here; the slug gate keeps it a skipped no-op anywhere else — a fork, or the retired private +# archive. Every check now assesses this repo directly, including Branch-Protection. +# +# (Pre-cutover MEFORORG was the published mirror, so the Branch-Protection score reflected the MIRROR's +# settings rather than the private source's, and this file only ran once publish.ps1 copied it across. +# Both caveats are obsolete: there is one repo, and the publish machinery was deleted.) # # PINNING CAVEAT: actions/checkout + actions/upload-artifact reuse this repo's existing SHA pins; the # ossf/scorecard-action and github/codeql-action/upload-sarif steps are on version tags pending a @@ -28,7 +30,7 @@ permissions: read-all jobs: analysis: name: Scorecard analysis - # ONLY on the public mirror (free code scanning + public badge); skipped no-op on the private repo. + # ONLY on this repo — public, so code scanning and the badge are free; skipped no-op on a fork. if: github.repository == 'MEFORORG/MessageFoundry' runs-on: ubuntu-latest permissions: