release: v2.3.6 "Sounding" - #395
Conversation
The cut. Workspace version 2.3.5 -> 2.3.6, the CHANGELOG [2.3.6] section, the maintainer-authored release body, STATUS.md, VERSION-PLAN.md, the README badge, AGENTS.md and CLAUDE.local.md. The version bump immediately tripped `libretro_info_audit`, which pins the local `.info`'s `display_version` against the workspace manifest. That is the guard working: it exists because v2.3.5 shipped a `.info` whose version had drifted from the crate for eleven days, and it caught this in one run. A gap it CANNOT close remains — RetroArch reads `libretro-super`'s copy, which will still say v2.3.5 after this release, so an upstream PR is a release-time step, on the same trigger the v2.2.9 licence drift set. Two claims in AGENTS.md were true when written and are now false; both are corrected. `libretro-super#2069` merged, so RetroArch reads `GPLv3+`, and `RetroArch#19416` merged, so `rustynes` is in `appstore_cores` — verified against `master` rather than the PR state. Being in the build list is not being installable: it arrives with the next App Store RetroArch build. Only `libretro/docs#1180` is still open. Six standing rules are added to AGENTS.md, each earned by a defect in this release rather than invented: a fix touching one call site of a shared path may not fix the bug and will report that it did; a test asserting "not empty" passes while a second defect remains; prose asserting an intent is how a defect survives releases; `ab_check.sh` benches the reference straight after a ~45-second fat-LTO compile, so read the order-bias control first; "inert on almost every cycle" predicts a win only if the work is actually executed; and the bot ceremony has a third hiding place in plain issue comments. A seventh covers panel state outliving the `Nes` it describes, now funnelled through one `clear_rom_bound_analysis` hook. The CHANGELOG and release notes also record the three defects the RAM Atlas review caught after the feature was written — the dead audio observable, the missing locked-session gate, and the `Inert` verdict for an address that was never perturbed. Verified: workspace clippy, 124 test binaries, version consistent across the manifest, the README badge and the libretro `.info`, and — though this commit touches no core code — AccuracyCoin 141/141 on the authoritative RAM decoder with nestest 0-diff.
…EADME Both files carried a "not fixed by this release" note from the v2.3.5 cut saying RetroArch shows the wrong licence and RustyNES is absent on iOS/iPadOS/tvOS. Both were true when written and both merged upstream on 2026-08-16 — `libretro-super#2069` and `RetroArch#19416`. The v2.3.6 blocks at the top of each file already said so, which made the files internally contradictory: a reader reaching the older passage would take the stale claim as current. Caught in review, and it is the same class as the AGENTS.md corrections in this cut — a release note is written in the present tense and then silently becomes history. Rewritten to say what is true now, including the distinction that matters: being in `appstore_cores` is not being installable. It arrives with the next App Store RetroArch build, on libretro's cadence. `libretro/docs#1180` is the one item still open.
|
Important Review available on request
Reviews should be triggered manually for repositories with fewer than 10 stars. Select Trigger review above or comment ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR performs the v2.3.6 “Sounding” release cut for RustyNES, updating the workspace version and synchronizing all release surfaces (metadata, changelog, status docs, and the maintainer-authored release body) to reflect the new release.
Changes:
- Bump workspace/package version to 2.3.6 and update
Cargo.lockaccordingly. - Update release documentation surfaces (README “Current Release”,
docs/STATUS.md,VERSION-PLAN.md,CHANGELOG.md) to describe v2.3.6. - Update libretro core metadata (
rustynes_libretro.info) and add.github/release-notes/v2.3.6.mdfor the automated release workflow.
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
VERSION-PLAN.md |
Updates “Current release” narrative to v2.3.6 and shifts v2.3.5 to “Built on”. |
README.md |
Updates version badge and “Current Release” section to v2.3.6. |
docs/STATUS.md |
Advances the status matrix header to v2.3.6 and updates upstream-resolution notes. |
crates/rustynes-libretro/rustynes_libretro.info |
Bumps display_version to v2.3.6 (audit-visible metadata). |
CHANGELOG.md |
Adds the [2.3.6] section with release highlights and categorized changes. |
Cargo.toml |
Bumps [workspace.package] version to 2.3.6. |
Cargo.lock |
Updates workspace crate versions from 2.3.5 → 2.3.6. |
.github/release-notes/v2.3.6.md |
Adds the maintainer-authored release body for release-auto.yml. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Maintainer decision at the v2.3.6 cut: the next upstream sync is v2.4.0. Recorded in three places because the alternative is that it reads as an oversight — which is exactly what the v2.2.9 incident was. RetroArch reads `dist/info/rustynes_libretro.info` from `libretro/libretro-super`, a separate copy nothing syncs automatically and nothing compares. Through the v2.3.6-v2.3.9 line it will therefore read `display_version = "v2.3.5"`. The standing `libretro_info_audit` pins the LOCAL file against the workspace manifest and the core's own `retro_get_system_info`, so the sync stays a copy rather than a re-derivation whenever it does happen; the audit cannot see upstream, so the divergence is invisible to CI by construction and has to be a written decision instead. The distinction that makes deferring safe is the one UPSTREAM_SYNC.md exists for. A stale `display_version` misreports a NUMBER. A stale `license` misreports the terms under which the software is distributed, which is what actually went wrong in v2.2.9 — RetroArch advertised a GPL-3.0-or-later emulator as MIT/Apache-2.0 for eleven days. So the existing rule stands unchanged: licence, supported extensions, and declared capabilities sync immediately regardless of where the version line sits. Only the version-bump-alone case is batched.
Antigravity review (Gemini via Ultra)This PR cuts the v2.3.6 "Sounding" release by bumping versions and updating documentation, making it a trivial metadata change with no code modifications. Blocking issuesNone found. Suggestions
Nitpicks
Automated first-pass review by |
* release: v2.3.6 "Sounding" — measuring, and what a measurement may claim The cut. Workspace version 2.3.5 -> 2.3.6, the CHANGELOG [2.3.6] section, the maintainer-authored release body, STATUS.md, VERSION-PLAN.md, the README badge, AGENTS.md and CLAUDE.local.md. The version bump immediately tripped `libretro_info_audit`, which pins the local `.info`'s `display_version` against the workspace manifest. That is the guard working: it exists because v2.3.5 shipped a `.info` whose version had drifted from the crate for eleven days, and it caught this in one run. A gap it CANNOT close remains — RetroArch reads `libretro-super`'s copy, which will still say v2.3.5 after this release, so an upstream PR is a release-time step, on the same trigger the v2.2.9 licence drift set. Two claims in AGENTS.md were true when written and are now false; both are corrected. `libretro-super#2069` merged, so RetroArch reads `GPLv3+`, and `RetroArch#19416` merged, so `rustynes` is in `appstore_cores` — verified against `master` rather than the PR state. Being in the build list is not being installable: it arrives with the next App Store RetroArch build. Only `libretro/docs#1180` is still open. Six standing rules are added to AGENTS.md, each earned by a defect in this release rather than invented: a fix touching one call site of a shared path may not fix the bug and will report that it did; a test asserting "not empty" passes while a second defect remains; prose asserting an intent is how a defect survives releases; `ab_check.sh` benches the reference straight after a ~45-second fat-LTO compile, so read the order-bias control first; "inert on almost every cycle" predicts a win only if the work is actually executed; and the bot ceremony has a third hiding place in plain issue comments. A seventh covers panel state outliving the `Nes` it describes, now funnelled through one `clear_rom_bound_analysis` hook. The CHANGELOG and release notes also record the three defects the RAM Atlas review caught after the feature was written — the dead audio observable, the missing locked-session gate, and the `Inert` verdict for an address that was never perturbed. Verified: workspace clippy, 124 test binaries, version consistent across the manifest, the README badge and the libretro `.info`, and — though this commit touches no core code — AccuracyCoin 141/141 on the authoritative RAM decoder with nestest 0-diff. * docs: correct two stale upstream claims further down STATUS and the README Both files carried a "not fixed by this release" note from the v2.3.5 cut saying RetroArch shows the wrong licence and RustyNES is absent on iOS/iPadOS/tvOS. Both were true when written and both merged upstream on 2026-08-16 — `libretro-super#2069` and `RetroArch#19416`. The v2.3.6 blocks at the top of each file already said so, which made the files internally contradictory: a reader reaching the older passage would take the stale claim as current. Caught in review, and it is the same class as the AGENTS.md corrections in this cut — a release note is written in the present tense and then silently becomes history. Rewritten to say what is true now, including the distinction that matters: being in `appstore_cores` is not being installable. It arrives with the next App Store RetroArch build, on libretro's cadence. `libretro/docs#1180` is the one item still open. * docs(libretro): batch upstream .info syncs to MINOR releases Maintainer decision at the v2.3.6 cut: the next upstream sync is v2.4.0. Recorded in three places because the alternative is that it reads as an oversight — which is exactly what the v2.2.9 incident was. RetroArch reads `dist/info/rustynes_libretro.info` from `libretro/libretro-super`, a separate copy nothing syncs automatically and nothing compares. Through the v2.3.6-v2.3.9 line it will therefore read `display_version = "v2.3.5"`. The standing `libretro_info_audit` pins the LOCAL file against the workspace manifest and the core's own `retro_get_system_info`, so the sync stays a copy rather than a re-derivation whenever it does happen; the audit cannot see upstream, so the divergence is invisible to CI by construction and has to be a written decision instead. The distinction that makes deferring safe is the one UPSTREAM_SYNC.md exists for. A stale `display_version` misreports a NUMBER. A stale `license` misreports the terms under which the software is distributed, which is what actually went wrong in v2.2.9 — RetroArch advertised a GPL-3.0-or-later emulator as MIT/Apache-2.0 for eleven days. So the existing rule stands unchanged: licence, supported extensions, and declared capabilities sync immediately regardless of where the version line sits. Only the version-bump-alone case is batched.
The v2.3.6 "Sounding" release cut. A sounding is a depth measured with its uncertainty attached, which is what every workstream in this release has in common.
Ceremony
Cargo.toml2.3.5→2.3.6(+Cargo.lock)crates/rustynes-libretro/rustynes_libretro.infodisplay_version→v2.3.6CHANGELOG.md[2.3.6] - 2026-08-17 - "Sounding"with Added / Fixed / Changed / Documented.github/release-notes/v2.3.6.mddocs/STATUS.md,VERSION-PLAN.mdREADME.mdAGENTS.mdCLAUDE.local.mdThe version bump tripped a standing audit, which is the guard working
libretro_info_auditfailed immediately on the bump: it pins the local.info'sdisplay_versionagainst the workspace manifest, and the manifest had moved. That test exists because v2.3.5 shipped a.infowhose version had drifted from the crate for eleven days. It caught this in one run.A known gap remains and is not fixable here: the audit can only see the local copy. RetroArch reads
dist/info/rustynes_libretro.infofromlibretro/libretro-super, which will still sayv2.3.5after this release. That needs an upstream PR at cut time — the same trigger the v2.2.9 licence drift established.Two claims in
AGENTS.mdwere false and are correctedBoth were true when written and have since been resolved upstream:
libretro-super#2069merged 2026-08-16 — RetroArch now readsGPLv3+.RetroArch#19416merged76f60626984a—rustynesis now line 268 ofpkg/apple/update-cores.sh, betweenreminiscenceandsameboy. Verified againstmaster, not the PR state. Being in the build list is not being installable: it arrives with the next App Store RetroArch build, on libretro's cadence.Only
libretro/docs#1180remains open.Six new standing rules in
AGENTS.mdEach earned by a defect in this release rather than invented:
measure_in_place's final restore only; all 21 per-trial restores still cleared the ring.ab_check.shbenchmarks the reference immediately after a ~45 s fat-LTO compile — read the order-bias control before the candidate column.reviews[].bodyread.Plus a seventh on panel state outliving the
Nesit describes, now funnelled through oneclear_rom_bound_analysishook.Not in this release, named so it reads as a decision
perf.rsalready tracks). It reports the game's internal lag only, and says so.Verification
release-auto.ymltags and publishes on final-greenmain; do not tag by hand, it races. PRs run Linux-only whilemainruns the full Windows/macOS matrix, somainCI must go green after merge or the release workflow skips.