Skip to content

docs(ci): stop describing this repo as the mirror — workflow comments still document the pre-cutover topology - #21

Merged
wshallwshall merged 1 commit into
mainfrom
slug-rot-sweep
Jul 28, 2026
Merged

docs(ci): stop describing this repo as the mirror — workflow comments still document the pre-cutover topology#21
wshallwshall merged 1 commit into
mainfrom
slug-rot-sweep

Conversation

@wshallwshall

Copy link
Copy Markdown
Collaborator

A systematic sweep for damage left by the retired publish.ps1 slug rewrite, rather than finding these one failure at a time.

Detectors, across every tracked file

class hits verdict
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 a line 6 README badges, benign
D — present-tense private/mirror prose 87 the real finding
E — retired publish machinery 28 benign, see below
F — private slug/owner 23 mostly the maintainer's handle

E is benign. The scripts/publish/ mentions in test_anon_parity.py are comments about the retired path — part of the fix for a silent skip. test_feature_map_claims.py treats an absent deny-list as a documented branch and has its own test asserting that branch actually fails on a bad link.

F is mostly correct. CODEOWNERS and the CLA allowlist name a user, not a repo, and @wshallwshall is a collaborator on the org repo (verified: HTTP 204), so code-owner assignment works.

D is the same failure that broke releases

The guards are all correct (== MEFORORG) and are untouched here — git diff shows no change to any github.repository / $GITHUB_REPOSITORY condition. But the comments around them still call MEFORORG "the mirror" and describe a private source repo that runs CI.

That's precisely the belief that left release.yml gated != MEFORORG, disabling releases entirely until a tag failed and I traced it back. Someone maintaining these files today reads that this repo is a mirror.

A 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 2×-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 comments-only.

Also fixed in release.yml: the SLSA provenance note claimed the step is skipped "while this repo is private". It's public now, so the step runs and every release carries provenance. That comment described the opposite of current behaviour.

Scope

Workflows only — 30 of the 87 lines, in the four files where 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 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 parse, every slug guard is byte-identical, and the release/scaffold/lint-parity suites pass.

🤖 Generated with Claude Code

…ents still document the pre-cutover topology

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.
@wshallwshall
wshallwshall merged commit b7d5920 into main Jul 28, 2026
47 of 48 checks passed
@wshallwshall
wshallwshall deleted the slug-rot-sweep branch July 28, 2026 19:00
wshallwshall added a commit that referenced this pull request Jul 28, 2026
…ap advertising a deleted pipeline, a skip reason for a dead topology (#22)

The docs half of the slug-rot sweep (#21 did the workflows). Of the 55 remaining detector hits, most
were FALSE POSITIVES and are deliberately untouched:

  * INSTALL-GUIDE / VERSION-CONTROL "private repo" = the ADOPTER's own repo, correct advice;
  * "mirror image" in PLAN-PHASE4-GROUP-COMMIT and test_ledger_check = the English idiom;
  * SECURITY.md's "GHAS on a private repo" = a true statement about GitHub's pricing;
  * test comments narrating what "failed on the mirror" = accurate history of a past failure.

A detector that flags an idiom and a genuine defect identically is why this was triaged by hand rather
than swept with sed. Fixed here are the ones that assert something FALSE about the project today:

FEATURE-MAP.md advertised "Public OSS mirror + curated publish pipeline (forbidden-string/gitleaks
gate) | ✅ | Owner runs the push (exfil guard)". The mirror and the publish pipeline were deleted at the
cutover; what actually ships is the leak gate, on every commit and in CI. A feature map is what an
adopter or auditor reads to learn what exists, so a ✅ against a removed capability is the most
expensive kind of stale doc. Rewritten to describe the gate that exists, including that it fails closed
without a token source.

test_backlog_status_check.py skipped with reason "docs/BACKLOG.md is private-only (OSS-mirror
deny-list); absent on the mirror snapshot". True while the backlog was git-ignored; false since it was
committed. The skip cannot fire in a source checkout now, but had it fired, that reason would have told
the reader it was EXPECTED rather than a missing file -- the same "green for the wrong reason" shape as
the guard the test protects. Reason and docstring now say the skip should never fire here.

CI-SELFHOSTED-RUNNER.md explained the retirement as "the OSS mirror is a public repo ... hosted minutes
are free THERE", and described the per-repo matrix as "ubuntu-only on the private source repo". Both
inverted: this repo is the public one, and that matrix branch now serves FORKS.

.github/SECURITY.md offered the advisory channel "on both this repository and the public mirror" --
there is one repository, so the sentence pointed a reporter at somewhere to choose between.

pyproject.toml's sdist allowlist rationale credited "the mirror's leak gate (publish.ps1 +
scan_forbidden.py)" for governing the git side. publish.ps1 is gone; the leak gate governs what is
COMMITTED, never what an sdist packages. That separation is the reason the allowlist exists at all, so
the comment was undermining its own guard -- restated, with why the allowlist still matters now that
those docs are git-ignored rather than deny-listed.

Verified: pyproject still parses with its version source intact, the feature-map / backlog /
release-pipeline / docs-pathway suites pass (49), and the backlog skip does NOT fire (15 passed, 0
skipped) -- i.e. the corrected reason describes a branch that genuinely never runs here.
wshallwshall added a commit that referenced this pull request Jul 28, 2026
…y measured something (#25)

* feat(ci): add a gate-liveness check — prove each quality gate actually measured something

Three defects across two of this workflow's gates spent months green. Two were gates measuring
nothing: diff-coverage (a shallow fetch destroyed its merge base, and the empty report looked clean)
and mutation (mutmut crashed before producing a mutant, and `|| true` made that green in 37s). The
third was the close cousin — a gate that measured correctly and published a wrong number (`killed=0`
from a grep for a line mutmut never prints).

The rubric's anti-metric rule guards against trusting a NUMBER too much. Nothing guarded against
trusting a GREEN CHECK THAT NEVER RAN. This is that control.

Each measurement job now emits a JSON receipt as a job output; a new `liveness` job reads
toJSON(needs) and rules on all four. It is the ONLY job here allowed to go red — no
continue-on-error, no `|| true` — and it still blocks nothing, since these contexts are not required
and must never become required.

THE DISTINCTION IT RESTS ON: liveness is not "the gate found something". A clean repo legitimately
has zero clones, and a check that fires on good news gets muted, which would leave us worse off than
before. Receipts count units EXAMINED — files scanned, mutants processed, changed lines analysed —
non-zero whenever the tool ran, whatever it concluded. A gate with nothing to measure passes by
saying so explicitly, with a reason.

VERIFIED AGAINST REAL DATA, not fixtures: complexity 256 files scanned / 122 findings, clone 234
files / 39 clones, mutation 461 mutants (87 killed, 19 survived, 355 not covered) parsed from the
actual artifact of run 30308667584. All four failure modes replayed through the real CLI and caught.

AN ADVERSARIAL REVIEW BEFORE MERGE FOUND THIS CONTROL CARRYING THE SAME WEAKNESS IT WAS BUILT TO
CATCH, IN THREE PLACES. All fixed here:

* A dead coverage gate could pass by claiming `not-applicable`. Reproduced: a valid-but-EMPTY
  coverage.xml makes diff-cover print the identical "No lines with coverage information in this diff"
  as the legitimate case, because its console template branches on whether any source has measured
  lines and never consults the diff. Same string, opposite meaning — the exact ambiguity this control
  exists to resolve, one layer up. Now the receipt proves coverage.xml measured files first, a
  missing file is `failed` rather than inapplicable, and verify() refuses a `not-applicable` receipt
  from a job whose result is `failure`.
* An empty mutmut results file reported a FLAWLESS score. LISTED=0 gives killed=TOTAL, survived=0 —
  461/461 killed, reconciling perfectly. A 100% kill rate with nothing listed is a tool that produced
  no output, not a triumph. Now `failed`.
* The reconciliation was algebraically BLIND to the count it claimed to protect. Since
  killed = total - listed, the sum killed+survived+no_tests+other == total reduces to
  survived+no_tests+other == listed: total cancels, and any derived killed satisfies it. So the
  incident-3 test was replaying numbers the production path can no longer produce. Fixed by
  cross-checking killed against mutmut's OWN progress counter — two independent derivations that must
  agree (verified: derived 87 == reported 87). The sum's blindness is now asserted by its own test
  rather than quietly deleted, so nobody mistakes it for protection it does not give.

Also here: `other` is counted independently rather than as a remainder (a remainder would make the
sum true by construction), across mutmut's full status vocabulary so the check cannot redden a
healthy run; a non-numeric killed count emits `failed` instead of malformed JSON; and the coverage
receipt step gets BASE_REF, which it was missing.

Slug rot carried along, since this commit is already in the file: the coverage job's "move it to the
mirror if that cost bites" is gone — there is no mirror post-cutover. Adjacent to the sweep in #21,
which does not touch this workflow.

* docs: record the liveness rule as rubric section 4.0, and clear the pre-cutover rot in these files

Documents the gate-liveness control and promotes it to a rule in the rubric, because the failure it
addresses is general rather than specific to this repo: an advisory gate that silently stops
measuring is worse than an absent one, since the scorecard still counts it.

Code_Quality_Standards.md gains section 4.0 (the liveness rule) and a v0.11 history entry. The rule
has three parts, each written from a real failure rather than from theory: prove execution via units
EXAMINED, never units found (a clean repo reports zero and must still pass); "nothing to measure" is
acceptable only when stated with a reason; and any derived headline figure must be cross-checked
against an independently produced measurement of the same quantity.

That third part was rewritten during review. It originally said only "the parts must sum to the
whole, each counted independently" — true but insufficient, because a sum containing a derived term
can be algebraically blind to that term, and ours was. The rubric now says what actually protects a
number, and the v0.11 entry records that the control was found carrying the same weakness it was
built to catch. Leaving that out would have been the more flattering and less useful choice.

Corrected two miscounts of my own from v0.10 and docs/CI.md: it was three defects across TWO gates,
not three gates, and the killed=0 bug is a different category (a gate that ran correctly and
published a wrong number) rather than a third instance of measuring nothing. The distinction was
already drawn correctly in the rules; only the narrative sentences conflated them.

PRE-CUTOVER SLUG ROT, in the files this commit already touches and which the open sweep does not
cover:
* HANDOFF-mutation-coverage.md was worse than stale. It instructed a future session to gate the
  mutation job with `if: github.repository == 'MEFORORG/MessageFoundry'` "(free minutes)" — the exact
  repo-slug gate removed when mutation started running on PRs. Following it would have made the job a
  no-op on every PR while looking deliberate. Left an explicit do-not-re-add marker rather than
  deleting the sentence, so the reasoning survives.
* Code_Quality_Standards.md had one live "mirror-nightly" description of how the mutation job runs.
  Corrected and annotated.

DELIBERATELY NOT SWEPT in that file: the mirror references in the control-parity narrative and in the
v0.8 history row are dated incident records — the account of the fixed PyPI-sdist leak, which is the
rubric's own worked example. Rewriting them would falsify the record.
wshallwshall added a commit that referenced this pull request Aug 1, 2026
…ard say (#111)

Four lines, four files. No behavior changes -- docs and workflow COMMENTS only;
cla.yml's triggers are unchanged and re-verified after the edit.

1. Secure_Development_Standards.md:378 -- ASVS V3 marked out of scope, reason
   "No browser-delivered UI (PySide6 desktop + APIs) ... Re-scope if a web/admin
   UI is added". That trigger fired and nobody pulled it: BACKLOG #103 retired
   the desktop console 2026-07-13 and made /ui the SOLE operator UI. The
   assessment of record already scores V3 in full (31 reqs: 18 Pass / 9 Partial
   / 0 Fail / 4 N/A) and claims no exclusion -- so this was stale prose
   contradicting the scorecard, not a scope decision. SECURITY-LOOSENING.md:396
   had already mapped serve_web_console to V3. Also corrects the :394 roll-up
   (12 -> 13 chapters; "exclusions: V3, V17" -> "exclusion: V17").

2. EARLY-ADOPTER-GUIDE.md:636 -- "there is no Prometheus exporter". There is:
   api/metrics.py IS the exporter and app.py:4147 serves GET /metrics as
   Prometheus exposition, gated by monitoring:read, PHI-safe by construction
   (BACKLOG #21). The fix with real cost -- that line sent adopters to build
   log parsing for a shipped capability.

3. security.yml:16 and cla.yml:19 -- "this private repo". The repo is PUBLIC.
   CodeQL running as a required context on every PR is its own disproof of
   security.yml's claim. cla.yml matters more: it justified omitting the
   `closed` trigger as moot "on this private repo", while its own re-add
   condition (fork PRs from non-allowlisted contributors) is possible on a
   public repo today. Corrected to say the ALLOWLIST, not visibility, is what
   makes on-close behavior unnecessary. Flags the decision; does not make it.

Left alone deliberately: release.yml:84 (past-tense history of a removed step),
release.yml:271 and scorecard.yml:9 (both already state the repo IS public), and
Secure_Build_Scorecard_MEFOR.md:64 (a dated 2026-07-14 reconciliation record
citing a superseded assessment -- editing it would revise history).

Verified: 117 tests green (test_security_doc_drift, test_security_static,
test_security_posture, test_dast_claims); both workflows re-parsed with
cla.yml's pull_request_target.types confirmed still [opened, synchronize];
24 CI checks green.
wshallwshall added a commit that referenced this pull request Aug 7, 2026
…napshot, file #1095 (#276)

Three corrections to the ledger's own accuracy, in one commit because they
cross-reference: #1094 and the ranking note both point at #1095, so splitting
them leaves an intermediate commit citing an item that does not exist yet.

1. #1094 CLOSED as already satisfied when filed; no work performed.

   Its premise is false on origin/main. The repoint it asks for merged as
   befe997 (PR #271) ONE COMMIT BEFORE the item itself landed (7ecff8a, PR
   #272) -- a filing race, not a wrong finding. Re-verified after both: CLAUDE.md
   section 12 now reads "BACKLOG #26 -- closed, so it lives in
   docs/archive/backlog/BACKLOG-CLOSED.md, not in the live ledger", same for #27.

   Banner flipped from the OPEN glyph to a CLOSED one -- replaced, not added, so
   the item still declares exactly one status. The analysis is kept: its point
   that no gate in this repo can catch the class is the argument any future
   check has to answer, and it is now attached to #1095 at true scale.

2. The "Connector & feature-breadth gaps vs. Mirth Connect" section marked a
   historical snapshot.

   All TEN backlog numbers it cites -- #7, #20-#27, #35 -- have closed and moved
   to the archive; none is in this file. So "#7 above" and "#35 below" are false
   directions out of the document, and "P1 -- close first" names work that
   shipped: #20 (FHIR, ADR 0022) and #21 (observability, PR #407). The section
   marks #24 and #35 SHIPPED inline, which makes the unmarked #20/#21 read as
   still open. A reader planning from this picks up finished work.

   Deliberately NOT repointed per-number. Every cited item is archived, so
   attaching an archive path to only the two decline-by-design lines would assert
   by contrast that the other eight are live. Uniform staleness is at least
   detectable; differentiated staleness is not.

3. #1095 filed for the systemic class. Number allocated via
   scripts/coord/alloc.ps1, never grepped.

   Measured on origin/main with parse_items (imported, not re-derived): of 129
   path-bearing BACKLOG.md citations, AT LEAST 69 distinct sites across AT LEAST
   35 files name the live ledger for an archived item. Plus 13 hrefs that do not
   resolve at all, 12 line anchors past EOF (file is 6318 lines; one cites 8429),
   and 31 in-range anchors that drifted onto unrelated text.

   The item's central point is DETECTABILITY, because getting this wrong means
   someone closes it with a linter having fixed a third of it: the 13 broken
   hrefs and 12 past-EOF anchors are catchable, but the 69 wrong-file citations
   and the 31 drifted anchors are NOT -- those links resolve perfectly, and what
   rots is the number or the line beside them.

   It also records that the test is "does the cited FILE contain the item", not
   "is the item CLOSED". Those differ: #1073 is closed and still legitimately in
   the live ledger, so a sweep keyed on closure would corrupt correct citations.

   Prior art found and named rather than duplicated: MIG-35 is already "the
   BACKLOG-reference classifier" folding into MIG-74 in the master test plan
   (:128). The item notes MIG-74 as worded -- "every doc path resolves" -- would
   pass the largest class untouched, since those paths do resolve.

Verification:
  - parse_items diffed before and after: exactly two items changed state, #1094
    (open -> closed) and #1095 (new). No unintended banner churn.
  - backlog_status_check.py: OK, 365 items, each declaring exactly one status.
  - All 7 link targets introduced were resolved from docs/, with a known-missing
    path run through the same checker to prove it can report a miss.
  - The MIG-74 quote was confirmed verbatim in the source file, not paraphrased
    from an agent's summary.
  - Line endings normalized to CRLF to match the file; diff stayed at 50/2
    rather than whole-file churn.

Not included: the ~69-site sweep itself and any gate. Those are #1095's scope,
and a partial repoint is worse than none for the reason given in item 2.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant