Skip to content

sync: release-from-main-2026-05-27 (Phase C onto culture/release)#578

Closed
ChBrain wants to merge 4 commits into
culture/releasefrom
sync/release-from-main-2026-05-27
Closed

sync: release-from-main-2026-05-27 (Phase C onto culture/release)#578
ChBrain wants to merge 4 commits into
culture/releasefrom
sync/release-from-main-2026-05-27

Conversation

@ChBrain

@ChBrain ChBrain commented May 27, 2026

Copy link
Copy Markdown
Owner

Funnels main's HEAD into culture/release so the integration branch carries the recent governance work before the next promotion runs.

This is a snapshot of main — the branch carries no commits of its own.

What this brings to culture/release

main is ahead of culture/release on Phase C of the unified-contract rollout and one related governance fix. Key changes:

PR on main What it brings to culture/release
#576 (governance/unified-manifest) scripts/generate_groupings.py deleted; its logic folded into generate_available_json.py. Deliver workflow drops the second regen step. Branch-scope lists drop the entry for the deleted script. 7 new tests in TestGroupings.
#574 (governance/drop-website-badge-job) auto-release.yml drops the dead update-website-badge job (-65 lines).

These are no-op on regions/** content — they only change scripts, workflows, and tests.

Why this PR is needed before the next culture/release → main promotion

Without it, a direct culture/release → main promotion would regress Phase C: it would re-add generate_groupings.py, revert the unified generate_available_json.py, restore the two-step deliver workflow, and re-add the dead update-website-badge job to auto-release.yml. Bringing main into culture/release first means the promotion PR after this one carries only the culture content delta (+ engine gender anchor) without governance regressions.

Sequence

  1. This PR (mainculture/release) — alignment
  2. After merge: I open culture/release → main — the actual promotion, carrying:

Refs: #576, #574, #577


Generated by Claude Code

claude and others added 4 commits May 27, 2026 08:46
The job is dead code. KAIHACKS PR #273 (merged) put the version badge
on a self-updating path: cultures-map.js reads data.release from
available.json on page load and writes both the href and the visible
text dynamically. The hardcoded vX.Y.Z patterns the job tried to
sed-replace in map/index.html no longer exist there:

  href="https://github.com/ChBrain/Cultures/releases"      (no /tag/v...)
  >download &nearr;<                                       (no vX.Y.Z prefix)

So on every Cultures release the job currently runs both regex
substitutions, matches nothing, has no file changes to commit, and
either errors on git commit or opens an empty PR against KAIHACKS.
That noise stops once this PR lands.

After this change, a Cultures release opens exactly ONE PR against
KAIHACKS -- the deliver-available-json job's PR carrying
available.json (and groupings.json once that pipeline is live).
The badge updates client-side from that same available.json on the
next page load, no PR needed.

Files:
- .github/workflows/auto-release.yml: -65 lines (entire
  update-website-badge job and its leading comment).

Remaining jobs in this workflow are unchanged:
- release (cuts the release on main)
- deliver-available-json (opens the KAIHACKS PR with manifests)
- build-zips (publishes culture/engine/groups zips to the release)
- build-pdfs (publishes PDFs to the release)

Ref: ChBrain/KAIHACKS#273, ChBrain/KAIHACKS#268 (superseded)
governance(auto-release): drop update-website-badge job
Step 2 of the unified-contract rollout. KAIHACKS #274 (step 1) taught
the consumer to read groupings from available.json, with a fallback
fetch of the legacy groupings.json during the transition. This change
teaches the producer to ship the unified shape.

What used to be two scripts and two delivered files is now one:

  scripts/generate_available_json.py   produces:
    {
      schemaVersion: 1,
      release:       <tag>,
      downloadBase:  <url>,
      cultures:      [...]      <-- from data/countries.json
      groupings:     [...]      <-- NEW: from groups/*/*_position.md
    }

  scripts/generate_groupings.py        DELETED

  .github/workflows/deliver-available-json.yml
    Drops the "Regenerate groupings.json" step.
    PR title + body now reference one file (available.json), the
    unified release manifest, rather than two.
    Adds an explicit `pip install pyyaml` step (the frontmatter
    parser was previously pulled in by the now-removed second
    script's import).

Why one file (recap from KAIHACKS #274):

  Release tag, cultures, and groupings are three concerns of the same
  release. Splitting them across two files leaves no atomicity
  guarantee -- a DACH grouping could name a culture id that the
  cultures[] array does not contain, or the badge could point to a
  release tag whose cultures the page is not showing. One file. One
  schema. Atomic versioning. One fetch on the consumer side.

What this commit preserves exactly:

  - Groupings pickup mechanism: walk groups/<dir>/*_position.md, take
    every file whose YAML frontmatter has `grouping: true`. The id,
    name, blurb, and members fields project verbatim. id and name
    fall back to the directory name when unset. Behavior is bit-for-
    bit identical to the deleted generate_groupings.py.
  - Producer-side grouping invariants: id pattern ^[a-z0-9_-]+$,
    unique ids, non-empty members[], non-empty blurb. Same checks,
    now in check_manifest() alongside the culture invariants.
  - Culture id regex unchanged (^[a-z0-9-]+$, no underscore). The
    two regexes are now named _CULTURE_ID_RE and _GROUPING_ID_RE
    to make the per-shape rule explicit at the call site.

Schema compatibility: the unified manifest still validates against
available.schema.json on KAIHACKS, because step 1 (#274) added the
optional `groupings` field at schemaVersion 1. No bump needed; the
addition is additive at v1.

Tests:
  +7 new tests in TestGroupings (clean shape, bad id, underscore id
  allowed, duplicate id, empty members, empty blurb, empty list is
  valid). _manifest() helper grew an optional groupings= kwarg
  (defaults to []), test_top_level_shape() now asserts the field is
  present.
  All 24 tests in test_generate_available_json.py pass.
  branch_scope.py and test_branch_scope.py drop the
  scripts/generate_groupings.py entry from the governance scope
  list (the file no longer exists). 259 branch-scope tests pass.

Smoke-test against the live tree:
  python scripts/generate_available_json.py --release v0.99.0 ...
  -> "wrote 16 cultures and 0 groupings"
  (0 groupings because the local tree has no groups/ directory yet;
   the legacy generator also returned 0 -- behavior preserved.)

Rollout step left (step 3, after one release cycle proves the
unified shape in production):

  KAIHACKS: drop the legacy fallback fetch from cultures-map.js,
  delete groupings.json, bump schemaVersion to 2 with `groupings`
  required.

Refs: ChBrain/KAIHACKS#274
governance: ship unified Cultures release manifest (Phase C step 2)
@ChBrain ChBrain closed this May 27, 2026
ChBrain added a commit that referenced this pull request May 27, 2026
sync: release-from-main-2026-05-27 (Phase C onto culture/release) [reopen of #578]
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.

2 participants