Skip to content

Normalize the 14 charset-drift callers: wxyc-shared-ref, @main pins, permissions, corpus pin #327

Description

@jakebromberg

Problem

The 14 callers of check-charset-corpus-drift.yml have drifted apart along four independent axes. Every one currently passes, so nothing is broken — but "pinned to gha/v1" is not presently a true statement about what most of them run, and the inconsistency will produce a confusing incident eventually.

Full fleet as of 2026-08-07 (enumerated by walking .github/workflows/ in all 54 WXYC repos via gh api; gh search code returns only 6 of these and is not a valid enumeration method here):

Consumer uses: ref wxyc-shared-ref permissions: pinned-sha256 / package-version
Backend-Service @gha/v1 gha/v1 contents+packages read 41a18c5c / 0.12.0
dj-site @gha/v1 gha/v1 contents+packages read 41a18c5c / 0.12.0
library-metadata-lookup @gha/v1 gha/v1 contents+packages read 41a18c5c / 0.12.0
semantic-index @gha/v1 gha/v1 contents+packages read 41a18c5c / 0.12.0
tubafrenzy @gha/v1 gha/v1 contents+packages read 41a18c5c / 0.12.0
discogs-xml-converter @gha/v1 gha/v1 contents+packages read 41a18c5c / 0.12.0
wxyc-etl @gha/v1 gha/v1 contents+packages read 41a18c5c / 1.6.0
musicbrainz-cache @gha/v1 gha/v1 contents+packages read 75a3395b / 0.10.0
catalog-audits @gha/v1 gha/v1 contents+packages read 75a3395b / 0.10.0
discogs-etl @gha/v1 gha/v1 contents+packages read 75a3395b / 0.10.0
request-o-matic @gha/v1 unset → main contents+packages read 41a18c5c / 1.6.0
wikidata-cache @gha/v1 unset → main contents+packages read 41a18c5c / 1.6.0
archive @main unset → main none declared 75a3395b / 0.10.0
wxyc-archive-search @main unset → main none declared 75a3395b / 0.10.0

The four axes

1. wxyc-shared-ref unset in 4 repos. This input selects which tree the reusable workflow checks out to get scripts/check-corpus-drift.sh, and it defaults to main. So request-o-matic, wikidata-cache, archive and wxyc-archive-search run tagged YAML against main's script. Harmless today only because that script happens to be byte-identical at gha/v1 and main. The moment it isn't, four repos silently run unreleased logic while their config says gha/v1.

2. Two repos pin @main outright. archive and wxyc-archive-search bypass the tag entirely. Note this cuts both ways: archive being on @main is what made it a usable canary for the actions/checkout@v7 bump (see #319), so the fix is not "nobody may track main" — it is that tracking main should be a deliberate, documented choice rather than the result of nobody repointing them.

3. Two repos declare no permissions: block. archive and wxyc-archive-search grant the workflow-default token scope. They pass today, but CLAUDE.md's caller-permissions contract requires contents: read + packages: read, and the documented failure mode when the intersection narrows is an opaque 401 from npm pack with the message suppressed by --silent — the 2026-05-12 → 2026-05-14 org-wide drift outage. These two are one default-permissions change away from that.

4. Corpus-pin and package-version drift. Five repos sit on 75a3395b / 0.10.0 while the rest are on 41a18c5c / 0.12.0+. Whether that matters depends on what the pin is asserting; it should at least be a decision rather than sediment.

One likely-dead workflow

wxyc-archive-search's last charset run was 2026-07-13 04:31 PDT, before the v7 bumps landed. The repo has gone quiet and GitHub auto-disables scheduled workflows in inactive repos. It should be re-enabled or retired, not left as a caller that never fires — an inert caller is indistinguishable from a passing one on a dashboard.

Desired end state

Every caller's configuration is a deliberate statement. Where a repo tracks main, that is written down and intentional; where a repo pins the tag, it pins the tag for both the YAML and the script; every caller declares the permissions the contract requires.

Suggested approach

Per-repo PRs, each tiny. Sequence after the gha/v1 move in #319/#323 lands and is verified, so callers are not repointed at a tag that is about to move under them.

  1. Set wxyc-shared-ref: gha/v1 in request-o-matic and wikidata-cache — or drop the input from all 14 if tracking main's script is the intent. Pick one and apply it uniformly; the current split is the actual problem.
  2. Repoint archive and wxyc-archive-search to @gha/v1 and add the contents: read + packages: read block. If keeping one on @main as a deliberate canary, leave a comment in the workflow saying so and why.
  3. Decide on the corpus pin / package version spread; align or document.
  4. Re-enable or retire wxyc-archive-search's schedule.

Constraints

  • Verify each repo's next run after changing it. These are scheduled workflows; a broken caller is silent until its cron fires, which for most of the fleet is weekly.
  • Do not batch all 14 into one sweep. The value here is low and the blast radius of a wrong uniform edit is 14 repos.
  • If Split gha/v1 into per-workflow tags: one tag now covers two independent contracts #326 (per-workflow tags) lands first, repoint to charset/v1 instead of gha/v1 and skip the intermediate step.

Acceptance criteria

  • Every caller either sets wxyc-shared-ref explicitly or the input is gone from all callers.
  • No caller pins @main unintentionally; any that does carries a written reason.
  • Every caller declares contents: read + packages: read.
  • wxyc-archive-search's workflow is confirmed running or deliberately retired.
  • Corpus pin / package version spread is aligned or its variance is documented.
  • Each changed repo has one green post-change run, not just a green PR.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    github_actionsPull requests that update GitHub Actions codekind:followupPost-MVP follow-up (paired with cross-cache-identity-followup)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions