Skip to content

release: v2.3.6 "Sounding" - #395

Merged
doublegate merged 3 commits into
mainfrom
release/v2.3.6-final
Aug 18, 2026
Merged

release: v2.3.6 "Sounding"#395
doublegate merged 3 commits into
mainfrom
release/v2.3.6-final

Conversation

@doublegate

Copy link
Copy Markdown
Owner

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

Surface Change
Cargo.toml workspace version 2.3.52.3.6 (+ Cargo.lock)
crates/rustynes-libretro/rustynes_libretro.info display_versionv2.3.6
CHANGELOG.md [2.3.6] - 2026-08-17 - "Sounding" with Added / Fixed / Changed / Documented
.github/release-notes/v2.3.6.md the maintainer-authored release body
docs/STATUS.md, VERSION-PLAN.md current release, v2.3.5 demoted to "built on"
README.md version badge + current-release prose
AGENTS.md release block, six new standing rules, two now-false claims corrected
CLAUDE.local.md volatile session state refreshed

The version bump tripped a standing audit, which is the guard working

libretro_info_audit failed immediately on the bump: it pins the local .info's display_version against the workspace manifest, and the manifest had moved. That test exists because v2.3.5 shipped a .info whose 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.info from libretro/libretro-super, which will still say v2.3.5 after this release. That needs an upstream PR at cut time — the same trigger the v2.2.9 licence drift established.

Two claims in AGENTS.md were false and are corrected

Both were true when written and have since been resolved upstream:

  • libretro-super#2069 merged 2026-08-16 — RetroArch now reads GPLv3+.
  • RetroArch#19416 merged 76f60626984arustynes is now line 268 of pkg/apple/update-cores.sh, between reminiscence and sameboy. Verified against master, 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#1180 remains open.

Six new standing rules in AGENTS.md

Each earned by a defect in this release rather than invented:

  1. A fix touching one call site of a shared path may not fix the bug — and will report that it did. The rewind fix changed measure_in_place's final restore only; all 21 per-trial restores still cleared the ring.
  2. A test asserting "not empty" passes while a second defect remains. With the wipe fixed the ring grew instead. Assert exact equality.
  3. Prose asserting an intent is how a defect survives releases. Pixel Provenance shipped broken for four releases behind a comment claiming the opposite of its own code.
  4. ab_check.sh benchmarks the reference immediately after a ~45 s fat-LTO compile — read the order-bias control before the candidate column.
  5. "Inert on almost every cycle" predicts a win only if the work is actually executed — the fat-LTO mechanism behind three APU nulls.
  6. The bot ceremony has a third hiding place: plain issue comments. Antigravity posts its entire review as an ordinary PR comment, invisible to both a thread sweep and a reviews[].body read.

Plus a seventh on panel state outliving the Nes it describes, now funnelled through one clear_rom_bound_analysis hook.

Not in this release, named so it reads as a decision

  • Latency Oracle and RAM Atlas per-game persistence and export paths (Watch/Cheat seeding, Lua API, RetroAchievements authoring) — additive, and better shaped once the labels have been used in anger.
  • The Latency Oracle's end-to-end millisecond figure (internal lag plus the frontend pipeline cost perf.rs already tracks). It reports the game's internal lag only, and says so.
  • APU D2 and D4 — unmeasured on purpose; their prior is a null, not an unknown.
  • Workstream 0's "treat it as a class" audit — deferred to v2.3.9's quality release, where it belongs.

Verification

release-auto.yml tags and publishes on final-green main; do not tag by hand, it races. PRs run Linux-only while main runs the full Windows/macOS matrix, so main CI must go green after merge or the release workflow skips.

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.
Copilot AI lite review requested due to automatic review settings August 17, 2026 22:21
@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

Important

Review available on request

  • 🔍 Trigger review

Reviews should be triggered manually for repositories with fewer than 10 stars. Select Trigger review above or comment @coderabbitai review to review the latest changes. For a full review, comment @coderabbitai full review.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9c7dafb1-0548-4075-b512-b4c814d5b47b


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.lock accordingly.
  • 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.md for 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.52.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.
@github-actions

Copy link
Copy Markdown

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 issues

None found.

Suggestions

  • The PR title (release: v2.3.6 "Sounding") does not follow the Conventional Commits format required by the style guide. Use a standard prefix like chore: or docs:.

Nitpicks

  • CHANGELOG.md: The ## [2.3.6] heading was inserted below ## [Unreleased]. The comment above version in Cargo.toml explicitly instructs to perform an [Unreleased] -> [X.Y.Z] rename instead.

Automated first-pass review by agy on a self-hosted runner -- not a human review.

@doublegate
doublegate merged commit 3f99a3d into main Aug 18, 2026
44 of 47 checks passed
@doublegate
doublegate deleted the release/v2.3.6-final branch August 18, 2026 01:56
doublegate added a commit that referenced this pull request Aug 18, 2026
* 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.
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