Skip to content

fix: correct stale CLAUDE.md, serialize the build job, restore card descriptions - #73

Merged
philoserf merged 1 commit into
mainfrom
docs/correct-claude-md-and-deploy-concurrency
Sep 16, 2026
Merged

philoserf merged 1 commit into
mainfrom
docs/correct-claude-md-and-deploy-concurrency

Conversation

@philoserf

Copy link
Copy Markdown
Owner

Three findings from a review of the whole refactor range (c0843db..HEAD). All three are mine, introduced across the seven milestones.

CLAUDE.md went stale in exactly the paragraphs the refactor rewrote

I kept the Scenarios, Data and Push-and-deploy paragraphs current as those milestones landed, and missed the two that milestones 3 and 4 invalidated:

  • State still described Store<T> as a pub/sub whose set() "notifies subscribers, and persists", with a { session } top-level shape. All three were deleted — the store is load/save/clear and notifies nobody.
  • Play screen draft state still said the draft is a module-level currentDraft reset before onUpdate because "the store notifies synchronously". That's the file's most emphatic warning and it is now backwards: following it means re-introducing the module-level draft and the reset ordering that milestone 4 specifically removed.

Also corrected: the Architecture line claiming the root is replaced "on every store change" (repaints no longer go through the store), and the Game logic line sending readers to renderRollStep for reroll_highest (it's applyReroll in rules.ts now). Added a paragraph for src/paragraph.ts, which didn't exist when the file was written.

The build job wasn't serialized

Collapsing ci.yml into deploy.yml moved concurrency: {group: pages} off the workflow and onto deploy alone. That was right for keeping PR checks out of the deploy queue — but it left build unconstrained.

Two pushes in quick succession now build in parallel and reach deploy in whatever order they finish, so the older commit's artifact can publish last and leave the live site a commit behind until the next push. Previously workflow-level concurrency serialized the whole run and ordering was guaranteed.

build now shares the group; check stays free, which was the point of moving it. deploy also regains contents: read, dropped when its job-level permissions block replaced the workflow-level one.

This one is real and I merged two PRs in quick succession during this work, so it was live.

The card aria-label hid the attribute pips

#47 asked for "an explicit aria-label with just the archetype or scenario name", and that's what I wrote. But aria-label replaces the accessible name computed from the subtree — so the flavour text and the Penmanship/Language/Heart pips stopped being exposed to assistive technology at all.

A screen-reader user choosing a character heard "The Monk, button" with no way to reach the ratings the choice is entirely based on. That's worse than the run-on name it was meant to fix, and I should have caught it rather than following the issue's suggestion literally.

aria-labelledby now names the card from its title span, and aria-describedby points at the blurb and the pips:

hasAriaLabel     false
accessibleName   ["The Monk"]
description      ["The holiest of people, monks come from all walks of life…",
                  "Penmanship●●●Language●●○Heart●○○"]
stillOnlySpans   true
duplicateIds     []          (33 ids, all three steps rendered)

Clean name, detail still reachable, markup still conforming.

Not in this PR

aria-pressed on a mutually-exclusive group is toggle-button semantics where radio semantics are meant — AT announces three independently-pressable buttons rather than one choice of three. I flagged this in the milestone 6 plan and deferred it because proper role="radiogroup" changes keyboard navigation (arrows rather than tab). It deserves a decision rather than a quiet change.

THEORY.md and WALKTHROUGH.md are stale wholesale — the review is correct, and it is deliberate. They're frozen by standing instruction and their staleness is not tracked work.

bun run check:ci clean, 82 tests.

…escriptions

Three findings from a review of the whole refactor range, all mine.

**`CLAUDE.md` went stale in the two paragraphs the refactor rewrote.** I kept
the Scenarios, Data and Push-and-deploy paragraphs current as those milestones
landed, and missed the two that milestones 3 and 4 invalidated:

  - **State** still described `Store<T>` as a pub/sub whose `set()` "notifies
    subscribers, and persists", with a `{ session }` top-level shape. All three
    were deleted; the store is now `load`/`save`/`clear` and notifies nobody.
  - **Play screen draft state** still said the draft is a module-level
    `currentDraft` reset BEFORE `onUpdate` because "the store notifies
    synchronously". That is the file's most emphatic warning and it is now
    backwards — following it means re-introducing the module-level draft and
    the reset ordering that moving the draft into the closure removed.

Also corrected: the Architecture line claiming the root is replaced on every
store change (repaints no longer go through the store), and the Game logic
line sending readers to `renderRollStep` for `reroll_highest` (it lives in
`rules.ts` as `applyReroll` now). Added a paragraph for `src/paragraph.ts`,
which did not exist when the file was written.

**The build job was not serialized (deploy.yml).** Collapsing `ci.yml` into
`deploy.yml` moved `concurrency: {group: pages}` off the workflow and onto
`deploy` alone — correct for keeping PR checks out of the deploy queue, but it
left `build` unconstrained. Two pushes in quick succession then build in
parallel and reach `deploy` in whatever order they finish, so the older
commit's artifact can publish last and leave the site a commit behind. `build`
now shares the group; `check` stays free, which was the point of moving it.
`deploy` also regains `contents: read`, dropped when its job-level permissions
replaced the workflow-level block.

**The card `aria-label` hid the attribute pips (setup.ts).** #47 asked for an
explicit label carrying just the name, and that is what I wrote — but
`aria-label` *replaces* the accessible name computed from the subtree, so the
flavour text and the Penmanship/Language/Heart pips stopped being exposed at
all. A screen-reader user choosing a character heard "The Monk, button" and had
no way to reach the ratings the choice is actually based on — worse than the
run-on name the label was meant to fix.

Now `aria-labelledby` names the card from its title span and `aria-describedby`
points at the blurb and the pips, so the name is clean and the detail is still
reachable. Verified in the browser: name "The Monk", description carrying both
the flavour text and "Penmanship●●●Language●●○Heart●○○", no duplicate ids
across all three steps.

Not addressed here, and worth a decision rather than a quiet change:
`aria-pressed` on a mutually-exclusive group is toggle semantics where radio
semantics are meant.

Co-Authored-By: Claude
@philoserf
philoserf merged commit 463b7e4 into main Sep 16, 2026
3 checks passed
@philoserf
philoserf deleted the docs/correct-claude-md-and-deploy-concurrency branch September 16, 2026 12:28
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