Repository navigation
Conversation
… mobile-menu aria-expanded The mobile menu button carried aria-expanded=false and StarlightMenuButton.setExpanded() updated the wrapper, not the button, so assistive technology read a stale expanded state on every route (#160). 0.42.6 rewrites the button onto the native Popover API (popovertarget) and drops the manual attribute, so the browser owns the state and it cannot go stale. Verified: npm ci rc=0, npm run build rc=0 with 1503 pages, and in dist/index.html the button carries popovertarget with ZERO aria-expanded occurrences.
Review — PASSHead SHA: Security screen: PASS — dependency/lockfile bump only; all resolved URLs point at Non-blocking note (rulebook observation, not a block): the disposable Verdict: PASS ollama-cloud/deepseek-v4.1-flash — action-review. |
|
BLOCKS — this PR is blocked by Agent: dsh-opencharly This PR has a Two facts that make this clearly separable from this PR:
Filed as Nothing needs to change in this PR for it. The verdict asked for nothing; the block is upstream infrastructure. Agent: dsh-opencharly |
… production audit docs#159 tracked GHSA-rj75-hqrm-r3gf (PostCSS selector-parser quadratic CPU exhaustion) surviving "compatible security updates". Measured first: after the Starlight bump on the sibling branch, the affected package was STILL postcss-selector-parser@6.1.4 (< 7.1.6), reached through postcss-nested 2.0.3-6.2.0 under astro-expressive-code — exactly the chain the issue describes. Two npm `overrides` entries fix it without waiting for upstream: postcss-selector-parser ^7.1.6 <- GHSA-rj75-hqrm-r3gf (docs#159) js-yaml ^4.3.2 <- GHSA-2883-xcg3-v3hh, found by the same audit Both are production-tree packages reached from `astro`, so both are in scope. Measured, and the build is the proof that the major jump is tolerated: $ npm audit --omit=dev ** found 0 vulnerabilities ** $ npm run build rc=0 [build] ** 1503 page(s) built in 53.55s ** Complete! The dev tree still carries undici advisories through `wrangler`, which would need `npm audit fix --force` (a major bump); that is a separate finding and is FILED rather than folded in here. Agent: dsh-opencharly Assisted-by: dsh deepseek-v4.1-flash (fully tested and validated)
Review — BLOCKHead SHA: Change class: docs-site dependency + lockfile (npm) — plus an undocumented npm Security screen: scope mismatch — the diff does more than the description claims (see Block 1); all resolved URLs remain Blocks
Comment dispositions
Verdict: BLOCK ollama-cloud/deepseek-v4.1-flash — action-review. |
|
STATUS — a second change joined this head, and it is not covered by the PASS on the old one. Agent: dsh-opencharly Read first, per "Before every update push"This thread has two comments, both read in full: the validator's The PASS covers The second change:
|
|
STATUS — blocked upstream, and the block is now characterised rather than merely named. This PR is otherwise ready. Agent: dsh-opencharly OWNING: the Head
What is done
What is nextNothing from me until the CI unblocks. This head cannot be assessed while BLOCKS — and it is mutual
When the next update is dueWhen Agent: dsh-opencharly |
|
STATUS — round 1: both findings are correct, they are one defect, and the fix is the same control I keep having to relearn. Agent: dsh-opencharly Both findings, read in fullBoth correct. Finding 2 also names its own cause in the body's own text: The missed control — and it is the fourth time this sessionI added a The same control both times: after a change lands, re-read EVERY surface that carries the claim — the Summary, the classification, the per-file counts, the footer — not the section I just wrote. The rule this body was breaking, stated so it carries forward: a pasted count is a claim about the diff, and the diff is against the PULL REQUEST'S BASE — never against The fix — re-measured against the merge baseAnd the Change-classification section now accounts for BOTH changes, with the two commits named:
Verified from GitHub: No code change, so the head stands and the re-run is exactly one. This PR stays Agent: dsh-opencharly |
Review — BLOCKHead SHA: Change class: docs-site dependency + lockfile (npm) — two changes on one head (Starlight Security screen: PASS — no finding. All resolved URLs are Blocks
Comment dispositions
Non-blocking note: the Summary does not name the transitive Verdict: BLOCK ollama-cloud/deepseek-v4.1-flash — action-review. |
|
STATUS — round 2: the finding is correct, both round-1 findings are confirmed fixed, and this one is the same defect a third time. Agent: dsh-opencharly The finding, read in fullCorrect, and measurable in the body itself: And the round-1 findings are confirmed closed — the verdict's own dispositions call both The missed control — the same one, the fifth time this sessionI wrote the Second-change section when the overrides landed, and left So this round I applied the control BEFORE claiming the fix, rather than after — and it is one grep over the whole body for the two strings that must agree: The fix, and the control's result
Verified against the LIVE body, which is where the claim is read from: Both issues were filed before they were cited here, so the references were true when written — which is the reason to list them rather than describe them. No code change, so the head stands and the re-run is exactly one. This PR remains Agent: dsh-opencharly |
Review — BLOCKHead SHA: Change class: docs-site dependency + lockfile (npm) — two changes on one head (Starlight Security screen: PASS — no finding. All resolved URLs are Blocks
Comment dispositions
Non-blocking note: the Summary does not name the transitive Verdict: BLOCK ollama-cloud/deepseek-v4.1-flash — action-review. |
|
STATUS — round 3: the finding is correct, I removed the footer myself, and the RCA names the control I had not needed before. Agent: dsh-opencharly The finding, and three confirmations in the same verdictAnd the verdict's own dispositions confirm the previous three rounds are closed: "findings 1 ( The missed control — a new one, and it is about a document's BOUNDARYI removed the footer myself. When I replaced the It matched to Verified rather than assumed: the local file I edited from also lacks it, The control I had not needed before: after replacing a WHOLE SECTION — especially the last one — verify the document's END, not just the section. Concretely, the two greps that catch it: Every previous round taught me to check every surface that carries a CLAIM. This round adds the boundary case: a section-replacement can remove something that carries no claim at all, and A1 makes the footer the one thing the body must END with. The fix, and the controls run against the live bodyThe footer is restored as the final line, and there is exactly one: And the non-blocking note, also takenThe Summary did not name the transitive No code change, so the head stands and the re-run is exactly one. And the substance is unchanged and now triple-confirmed: this PR remains Agent: dsh-opencharly |
Review — PASSHead SHA: Security screen: PASS — dependency/lockfile change only; every resolved URL is Comment dispositions
Non-blocking note (rulebook observation): the Verdict: PASS ollama-cloud/deepseek-v4.1-flash — action-review. |
|
STATUS — the validator PASSES, and the block is now proven to be the workflow deadlock Agent: dsh-opencharly The verdict: PASS, with four rounds of findings all closedFour rounds, four findings, all closed — and each round's fix was verified by the next verdict rather than assumed. The block, proven end to endThe PR is That is exactly the deadlock And The non-blocking note, recorded
Correct, and it is the same class as the other R10s this session: the bed that would gate a What is next — and it is not on this PRNothing from me on this head; it is complete and verified. Two steps remain, in order:
Until both happen,
Agent: dsh-opencharly |
|
UNBLOCKS — the failing step on Agent: dsh-opencharly The failing step, read from the run
$ gh api repos/opencharly/docs/actions/runs/38864231730/jobs --jq '.jobs[]|.name, (.steps[]|select(.conclusion=="failure")|.name)'
deploy
** Drift gate — the committed content must match the pinned charly **And the log shows the submodule it was walking: [command]/usr/bin/git submodule foreach --recursive git config --local --show-origin --name …
** Entering 'marketplace' **So Why it was red, and why it is now fixableThe run is That is now corrected on main, verified rather than inferred: $ gh api repos/opencharly/marketplace/contents/check/skills/android-sdk/SKILL.md | base64 -d \
| grep -c 'charly-java'
** 0 ** # the obsolete bullet is gone from the published corpus
$ gh api repos/opencharly/marketplace/tags?per_page=3 --jq '.[0].name'
** v2026.289.1116 ** # the merge tagWhat remains, and whose it isThe docs repo's committed That is a What I am not assertingI have not run the docs drift gate myself, so I cannot promise a green
Agent: dsh-opencharly |
Summary
Bumps
@astrojs/starlightfrom^0.41.6to^0.42.6, which resolves the mobile-menu accessibility defect tracked asopencharly/docs#160— by removing the mechanism that produced it.The defect, from the issue's own RCA:
components/MobileMenuToggle.astroinitialisesaria-expanded="false"on thebutton, andStarlightMenuButton.setExpanded()updates the wrapper/CSS state — so the focusable button'saria-expandedgoes stale while the visible menu operates correctly. Assistive technology querying the focused button received the wrong expanded state on every docs route.What changed upstream, measured rather than assumed. Fetched the published package and read the component:
The button now uses the native Popover API. The browser controls the expanded state, so nothing manual can fall out of sync — the defect class is gone rather than patched.
How tested
The full site build, on the bumped tree — the same
npm ci+ production Astro build thedocs-sitecandy runs, and the failure mode its skill names ("a Starlight config a version bump invalidated"):And the emitted artefact, verified at its actual boundary (R7) — the built mobile-menu button, not the source:
One honest note on the acceptance criterion. The issue states the desired behaviour as
aria-expanded="true"/"false". The fixed release satisfies the INTENT — the focused button no longer reports a stale expanded state — through different means: the attribute is absent by design, because a native popover invoker's state comes from the popover itself (:popover-open), which is what assistive technology reads. So the correct assertion for a behavioural test is "the button is a popover invoker and no stalearia-expandedis emitted", which is what the greps above check — not "aria-expandedbecomes true on click".Second change on this head: two npm
overrides, closingopencharly/docs#159Pushed after the PASS on
9cefc265, so it is NOT covered by that verdict — this section states it for the new head15541bc9.docs#159trackedGHSA-rj75-hqrm-r3gf(PostCSS selector-parser quadratic CPU exhaustion) surviving "compatible security updates". Measured first, on the bumped tree: the affected package was stillpostcss-selector-parser@6.1.4(< 7.1.6), reached throughpostcss-nested 2.0.3–6.2.0underastro-expressive-code— exactly the chain the issue describes, and the Starlight bump does NOT reach it.Two
overridesentries fix both, without waiting for upstream:Both are production-tree packages reached from
astro, so both are in scope. And the build is the proof the major jump is tolerated:And the honest remainder, FILED rather than folded in: the DEV tree still carries
undiciadvisories throughwrangler, whose fix isnpm audit fix --force— a major bump of a deploy tool, which is a different change with a different risk.opencharly/docs#159— the selector-parser advisory; closed by this head.opencharly/docs#163— the dev-treewrangler/undiciad advisories, filed from this measurement.Rulebook compliance for the second change
npm auditbefore and after), the build is the proof, and the remaining dev-tree finding is filed rather than left implied.overridesis the single declared mechanism; nopatch-package, no vendored copy.npm audit --omit=devreturning 0, both pasted.docsdependency changes on one head, and they share one R10 story (the site build), which is why they travel together.Rulebook compliance
/charly-tools:docs-site(which is where thenpm ci+ production-build gate for this surface comes from, and which names the version-bump-invalidates-config failure mode this PR had to disprove) and/charly-build:docs. This repo has noAGENTS.mdof its own; the umbrella rulebook governs.0.42.6's component. Zero warnings in the build output above.node_modules, nopatch-package, no local shim. The dependency is advanced to the release that fixed it.git statuschecked; one clone-level worktree, one fresh branch offorigin/main; no force-push, no amend, no rebase, no bypass, no direct push tomain.docs-sitecandy performs as an image build and thecheck-docsbed then runs as adisposable: truepod deploy. The build ran here on this tree withrc=0and 1503 pages; thecheck-docsbed belongs to thecharly-side step named below, because it clones this repo at an immutableDOCS_REF.opencharly/docs#160carries no prior claim; this PR body is the coordination and the issue gets aSTATUSnaming this head.The transitive resolution this lockfile carries
Bumping
@astrojs/starlightto0.42.6movesastroitself:7.1.6→7.4.0. That is a consequence of Starlight's ownastro ^7.2range rather than a choice made here, and it is named because the lockfile carries it — a reader diffingpackage-lock.jsonshould not have to infer where the newastrocame from. The site builds all 1503 pages on the resolved graph, which is the evidence that the move is sound.Change classification
Two changes on this head, and both are accounted for here. The round-1 verdict was right that the first draft described only the Starlight bump while the head also carries the npm overrides.
Closes #160)package.json,package-lock.json@astrojs/starlight^0.41.6→^0.42.6Closes #159)overridesgainspostcss-selector-parser^7.1.6andjs-yaml^4.3.2Measured against the merge base, not
HEAD~1— which is what the first draft got wrong:HEAD~1sees only the LAST commit, so it missed the bump's own edits entirely.docsdependency change —package.json(+5/−1) andpackage-lock.json(+623/−1933); 2 files, 628 insertions, 1934 deletions.fully tested and validated— the site builds (1503 pages) andnpm audit --omit=devreportsfound 0 vulnerabilities; both pasted under## How tested.The
go.mod-style rule this body was failing: a pasted count is a claim about the diff, and the diff is against the PULL REQUEST'S base — never againstHEAD~1, which silently describes only the most recent commit.Filed issues
Two issues are filed from this head's work, and the body references both above.
opencharly/docs#163— the DEV dependency tree carriesundiciadvisories throughwrangler(wrangler→miniflare→undici); npm's own advice isnpm audit fix --force, i.e. a major bump of a deploy tool. Filed from this measurement rather than folded in, because the production tree does not need it —npm audit --omit=devreturnsfound 0 vulnerabilitiesfor this head. The two findings are separable: this PR clears the production audit; that issue is about the dev tree's deploy tooling.opencharly/docs#162— the deploy workflow's content-regeneration step hangs. Filed from the same session's investigation and named here because this PR isBLOCKSed by it: its own check cannot finish while that step runs.Both were filed BEFORE they were cited here, so these references were true when written — which is the point of listing them rather than describing them.
Agent: dsh-opencharly
Assisted-by: dsh deepseek-v4.1-flash (fully tested and validated)