Repository navigation
chore(deps): bump sharp from 0.35.4 to 0.35.5 in /services/hosted in the npm_and_yarn group across 1 directory - #615
Conversation
Bumps the npm_and_yarn group with 1 update in the /services/hosted directory: [sharp](https://github.com/lovell/sharp). Updates `sharp` from 0.35.4 to 0.35.5 - [Release notes](https://github.com/lovell/sharp/releases) - [Commits](lovell/sharp@v0.35.4...v0.35.5) --- updated-dependencies: - dependency-name: sharp dependency-version: 0.35.5 dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] <support@github.com>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Antigravity review (Gemini via Ultra)Bumps Blocking issuesNone found. Suggestions
Nitpicks
Automated first-pass review by |
Folds in the three open Dependabot PRs (#614 cosim sha2 0.11.1, #615 sharp 0.35.5, #616 the production-dependencies group) and takes the rest of the tree to its newest compatible versions, checked rather than assumed: - Cargo: `cargo update` on the workspace (43 packages, among them sha2 0.11.1, tokio 1.53.3, serde_json 1.0.154, proptest 1.12.0, cc 1.8.0, arboard 3.7.0, uuid 1.28, zip 9.0.5) and on rustynes-cosim; libc's requirement raised to 0.2.191 in rustynes-cheevos and rustynes-libretro, the only direct requirement `cargo upgrade --incompatible allow` found behind. `cargo update --verbose` holds four transitive packages, none ours to move: getrandom 0.2 and 0.3 (the deliberate wasm32 shims in rustynes-frontend), generic-array 0.14.9 and psm 0.1.32 (newer releases need a newer rustc than the MSRV-aware resolver allows). wasm-bindgen stays 0.2.129, equal to the Trunk.toml CLI pin. - Rust 1.99.0 -> 1.99.1 (rust-toolchain.toml and .gitlab-ci.yml's RUSTUP_TOOLCHAIN together; every buildbot job runs `rustup toolchain install`, so a patch move needs nothing from the image). rust-version stays "1.99". - dtolnay/rust-toolchain 7e38f4b4 -> 683b588c (refs/tags/v1). The four commits were read, as rust-setup's comment requires: `${{ }}` interpolations into run scripts moved into env variables (closing a script-injection path), the flag step folded into a bash array, 1.99.1 in the patch table. taiki-e/install-action 2.87.28 -> 2.87.29; every other action's floating major already resolves to its newest release. - Hosted Worker: TypeScript 5.9.3 -> 7.0.2, vitest 4.1.11 -> 5.0.5, @cloudflare/vitest-plugin 1.4.4 (peer: vitest ^4.1 || ^5), workers-types 5.20261019.1 (wrangler 4.151.1 wants >= 5.20261006.1), wrangler 4.151.1; package version 3.4.1. npm audit: 0 vulnerabilities. `wrangler deploy --dry-run` bundles (37.45 KiB). - ruff-pre-commit v0.16.10 -> v0.17.1 (passes on the repo). - MkDocs on Python 3.15 (3.15.0 released 2026-10-09): verified first in a scratch venv, mkdocs-material[imaging] installs from wheels (Pillow 13.0.0) and `mkdocs build --strict` completes with no warning. Held, with reasons: Node 24 (26 becomes LTS on 2026-10-28), JDK 25 (the current LTS; 27 is not), NDK r30 16248370 (already newest). Android (Gradle 9.8.1, AGP 9.4.1, Kotlin 2.4.21, Compose BOM 2026.09.00, every androidx and Play artifact) was already at its newest stable releases. Verified on 1.99.1: fmt; clippy -D warnings for the workspace, the scripting / hd-pack / retroachievements / full feature sets, both wasm32 targets and rustynes-cosim; the thumbv7em no_std build; rustdoc -D warnings; cargo test --workspace 3,183 passed / 0 failed / 9 ignored; the Worker's 114 tests and tsc. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj
|
Superseded by #618 (v3.4.1 "Beacon"), commit 005226c, which takes this update and every other dependency to its newest compatible version: both Cargo lockfiles updated (sha2 0.11.1 in the workspace and in rustynes-cosim, the production-dependencies group, and the rest), sharp 0.35.5 in services/hosted with TypeScript 7, vitest 5 and wrangler 4.151, Rust 1.99.1, and the newest action pins. Verified on 1.99.1: clippy -D warnings on every feature set and both wasm32 targets, the no_std build, rustdoc, and cargo test --workspace (3,183 passed, 0 failed). |
|
This pull request was built based on a group rule. Closing it will not ignore any of these versions in future pull requests. To ignore these dependencies, configure ignore rules in dependabot.yml |
* docs(mister): release bitstreams are version-named on GitHub On 2026-10-18 the maintainer chose the version-named style for every release's bitstream assets, after first having the version-named duplicates deleted the same day. All 49 datecoded .rbf assets on both repositories were renamed in place (RustyNES_MiSTer-<tag>.rbf, and RustyNES_MiSTer-v3.4.0-lite.rbf for v3.4.0's on-die build); the bytes and the GitHub-recorded SHA-256 digests are unchanged, and 44 release bodies were rewritten to name the attached file by its version. The sibling's release-rbf.sh now uploads that form (sibling 4e71c79), while its releases/ keeps the datecoded names Distribution_MiSTer parses. Three docs here still described the brief datecoded-only state: docs/mister.md, to-dos/mister/TASKS.md and the v3.x hardware-verification plan. They now say: datecoded in the sibling's releases/, version-named on the releases. .github/release-notes/v3.4.0.md is synced to the live v3.4.0 body, which differs from the committed file in exactly the three asset names (checked by diff, ignoring trailing blank lines GitHub appended). Verified: pre-commit markdownlint passes on all four files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * docs(salvage): record the v340 scratch move Records the post-release tmp-salvage pass over the v3.4.0 scratch tree (moved into the gitignored salvaged/tmp-scratch/f63c2db0/ with relative paths kept). The files themselves are untracked by design; this entry is the only tracked record of what moved and from where. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * fix(web): make the browser-cheevos build load rcheevos at all Building the web frontend with `--features browser-cheevos`, as the v3.4.1 hosted plan needs, found three packaging defects. Each one alone stopped the browser RetroAchievements glue from ever reaching rcheevos; none was visible to a gate, because no CI job builds that feature and the Pages build uses the default set. 1. index.html carried `data-cargo-features=""`. Trunk lets that attribute override its command line, and an EMPTY value silently discarded `trunk build --features ...` and `--no-default-features`. Measured: the documented lightweight build (`--no-default-features --features wasm-canvas`) produced the default 12.6 MB winit build; with the attribute gone it produces 1,336,570 bytes, and the browser-cheevos build now emits the RA glue snippet. The Pages build (`trunk build --release`, default features) is unaffected, since an empty list on top of the defaults was the defaults. A comment at the site says why the attribute must stay absent. 2. ra_glue.js imported "./rcheevos.js". `#[wasm_bindgen(module = ...)]` makes trunk emit the glue as `snippets/<crate>-<hash>/web/cheevos/ ra_glue.js`, and nothing copies the Emscripten module there, so the relative import resolved inside snippets/ and 404ed. The module is now resolved against the PAGE: `<meta name="rustynes-rcheevos-base">` when present, else `cheevos/` beside the page. `locateFile` points the loader at rcheevos.wasm under the same base, so both paths are stated in one place rather than relying on Emscripten resolving the .wasm against its own script. 3. build_rcheevos_wasm.sh emitted a MODULARIZE UMD module, which has no default export, so the glue's `const { default: ... } = await import(...)` got undefined. `-sEXPORT_ES6=1` makes it an ES module. Verified in headless Chromium against a Pages-layout copy of dist/ (served on 127.0.0.1:18765): `ra_rcheevos_version()` returned 12.5 and every request was 200. Control: the old glue against the same layout 404s on snippets/.../rcheevos.js. The README's wiring steps and the two script-tag passages in docs/cheevos-browser.md are corrected to match; markdownlint passes on both. Not done, deliberately: browser-cheevos is NOT enabled on Pages and no RA proxy meta tag is added. The maintainer is holding web RA until the RetroAchievements integration request is sent; this change only makes the feature work when it is turned on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * ci: bake the deployed hosted base into every shipped build v3.4.0 shipped services/hosted/ as code with no workflow setting RUSTYNES_HOSTED_BASE, because the maintainer was away and the deploy moved to v3.4.1. The account is now provisioned (budget alerts, the TURN key `rustynes-hosted`, its two secrets on the `rustynes-hosted` Worker), so the shipped builds point at it: https://rustynes-hosted.parobek.workers.dev (account subdomain `parobek`). Scope, as the maintainer chose it: the Pages build (web.yml), the desktop release binaries (release.yml), the Android Play and sideload bridge builds (android.yml, cargo-ndk) and the iOS TestFlight xcframework (ios.yml). F-Droid is excluded; its recipe builds from source under its own rules. Each workflow gets the variable in its top-level env block, so every job in it compiles the same base and no step can silently miss it. Why env and not a flag: rustynes-netplay reads it with option_env!, so it is a compile-time constant (BUILD_HOSTED_BASE). A build without it keeps v3.4.0's behaviour, and a user's `hosted_base_url` config still wins over the baked value. ci.yml is deliberately left alone: hosted.rs's a_stock_build_has_no_hosted_base asserts the constant is None, guarded on the variable being absent at test time, so setting it there would turn that test into a no-op rather than fail it. The Worker's ALLOWED_ORIGINS already lists https://doublegate.github.io and index.html carries no CSP, so the Pages origin needs nothing more. The live smoke gates (healthz, the lobby test, POST /turn-credentials, the rate limit, the kill switch) run against the deploy, not here. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * feat(hosted): deploy configuration for v3.4.1, RA proxy held off The v3.4.1 deploy puts the lobby and TURN credentials live and leaves the RetroAchievements proxy switched off. The maintainer is holding web RA until RetroAchievements answers the integration request (D31), and the Pages build ships without browser-cheevos, so no client would use the proxy; leaving it enabled would only let anyone forward RA calls under the RustyNES/ User-Agent before RA has agreed to that. RA_ENABLED is therefore "false" in wrangler.jsonc, with the reason at the site. ra.ts refuses every /ra/ request unless the value is exactly "true", so the off state is the kill switch path, already tested. Turning it on is a dashboard variable change, no code. RA_USER_AGENT moves to RustyNES/3.4.1 (Web wasm32) rcheevos/12.5.0, the release this config ships in. bump_release.py does not touch it, so it is bumped by hand. The Worker tests run against wrangler.jsonc's own vars, so turning the proxy off there would have stopped the proxy being tested at all. vitest.config.ts now binds RA_ENABLED "true" for the tests (the kill-switch test still sets "false" itself). Mutation: with that binding flipped to "false", 26 of 111 tests fail; with it "true", 111 pass. tsc --noEmit is clean. Also: docs/agents/tooling-traps.md records the trunk trap behind the earlier web fix (an empty data-cargo-features attribute silently overrides --features and --no-default-features). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * docs(plan): the v3.4.1 plan and its CHANGELOG entries to-dos/plans/v3.4.1-plan.md records the patch release v3.4.0 left: the hosted deploy (done 2026-10-18, live gates passed: healthz, the live lobby test, credentials with ttl 10800 that relay in a browser, the 429 on the 7th request, the 405, the kill switch), the client wiring, the browser RA packaging fix, the two save-engine defects and the two refusal findings (sibling 419ee1b, 9e7ef9c), the version-named release assets, and what stays open: the credential-expiry check after 2026-10-19T02:44Z, the two-browser and two-NAT sessions (maintainer), the RA unlock (held for D31), the v3.4.1 bitstreams and the release-rbf.sh run before the release PR merges. It also records the agent's call that follows from holding web RA: the Worker is deployed with RA_ENABLED false. CHANGELOG [Unreleased] gains Added / Changed / Fixed entries for the same. release_anchor_audit (14), release_state_prose_audit (16), contribution_checklist_audit (4) and release_notes_render_audit (9) pass; markdownlint passes on both files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * chore(release): bump to v3.4.1 "Beacon" The CHANGELOG [Unreleased] entries become [3.4.1] - 2026-10-19 - "Beacon" (the codename the maintainer chose), and scripts/release-automation/bump_release.py moved every anchor from it: the workspace and cosim manifests and both lockfiles, the libretro .info display_version, Android versionName 3.4.1 / versionCode 30401, iOS MARKETING_VERSION, and the current-release prose in AGENTS.md, README, ROADMAP, SECURITY, SUPPORT, OVERVIEW, ARCHITECTURE, STATUS and VERSION-PLAN, each demoting "Waypoint" rather than overwriting it. The script first refused: to-dos/ROADMAP.md's release-line chain still ended "v3.4.0, the current release". That chain now has a v3.4.1 clause saying what the release did, and v3.4.0's clause lost the tail. VERSION-PLAN's v3.4.1 row is marked shipped with what it shipped, and a v3.4.1 history row sits above v3.4.0's. The date is 2026-10-19 because the MiSTer bitstreams are compiled that day: BUILD_DATE is the wall-clock date, and a compile on a different day is a different design and a different file name. Verified: every harness audit target (12) passes, among them release_anchor_audit 14, release_state_prose_audit 16; markdownlint passes. .github/release-notes/v3.4.1.md is written after the compiles, when its figures exist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * build(deps): every dependency at its newest compatible version Folds in the three open Dependabot PRs (#614 cosim sha2 0.11.1, #615 sharp 0.35.5, #616 the production-dependencies group) and takes the rest of the tree to its newest compatible versions, checked rather than assumed: - Cargo: `cargo update` on the workspace (43 packages, among them sha2 0.11.1, tokio 1.53.3, serde_json 1.0.154, proptest 1.12.0, cc 1.8.0, arboard 3.7.0, uuid 1.28, zip 9.0.5) and on rustynes-cosim; libc's requirement raised to 0.2.191 in rustynes-cheevos and rustynes-libretro, the only direct requirement `cargo upgrade --incompatible allow` found behind. `cargo update --verbose` holds four transitive packages, none ours to move: getrandom 0.2 and 0.3 (the deliberate wasm32 shims in rustynes-frontend), generic-array 0.14.9 and psm 0.1.32 (newer releases need a newer rustc than the MSRV-aware resolver allows). wasm-bindgen stays 0.2.129, equal to the Trunk.toml CLI pin. - Rust 1.99.0 -> 1.99.1 (rust-toolchain.toml and .gitlab-ci.yml's RUSTUP_TOOLCHAIN together; every buildbot job runs `rustup toolchain install`, so a patch move needs nothing from the image). rust-version stays "1.99". - dtolnay/rust-toolchain 7e38f4b4 -> 683b588c (refs/tags/v1). The four commits were read, as rust-setup's comment requires: `${{ }}` interpolations into run scripts moved into env variables (closing a script-injection path), the flag step folded into a bash array, 1.99.1 in the patch table. taiki-e/install-action 2.87.28 -> 2.87.29; every other action's floating major already resolves to its newest release. - Hosted Worker: TypeScript 5.9.3 -> 7.0.2, vitest 4.1.11 -> 5.0.5, @cloudflare/vitest-plugin 1.4.4 (peer: vitest ^4.1 || ^5), workers-types 5.20261019.1 (wrangler 4.151.1 wants >= 5.20261006.1), wrangler 4.151.1; package version 3.4.1. npm audit: 0 vulnerabilities. `wrangler deploy --dry-run` bundles (37.45 KiB). - ruff-pre-commit v0.16.10 -> v0.17.1 (passes on the repo). - MkDocs on Python 3.15 (3.15.0 released 2026-10-09): verified first in a scratch venv, mkdocs-material[imaging] installs from wheels (Pillow 13.0.0) and `mkdocs build --strict` completes with no warning. Held, with reasons: Node 24 (26 becomes LTS on 2026-10-28), JDK 25 (the current LTS; 27 is not), NDK r30 16248370 (already newest). Android (Gradle 9.8.1, AGP 9.4.1, Kotlin 2.4.21, Compose BOM 2026.09.00, every androidx and Play artifact) was already at its newest stable releases. Verified on 1.99.1: fmt; clippy -D warnings for the workspace, the scripting / hd-pack / retroachievements / full feature sets, both wasm32 targets and rustynes-cosim; the thumbv7em no_std build; rustdoc -D warnings; cargo test --workspace 3,183 passed / 0 failed / 9 ignored; the Worker's 114 tests and tsc. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * fix(netplay): let the mobile apps use the compiled-in hosted lobby Codex and Copilot on #618: baking RUSTYNES_HOSTED_BASE into the Android and iOS CI builds made no difference to a fresh install, because both apps stopped short of the bridge. NpNetConfig::to_nat_config substitutes the hosted lobby only for an EMPTY signaling URL, and: - Android's Settings default is the placeholder `wss://relay.rustynes.example`. netplayConfig() forwarded it (non-empty, so never substituted) and MainActivity disabled room-code play on it. - iOS's `signalingConfigured` accepted only an explicit ws:// or wss:// URL, so NetplayView disabled both room buttons and hostRoom/joinRoom returned before reaching the bridge. The fix gives the shells the fact they lacked: - rustynes-mobile exports `np_hosted_available()` (true exactly when `hosted::resolve_base("")` finds a compiled-in base); UniFFI makes it `npHostedAvailable()` in Kotlin and Swift. Test: hosted_availability_follows_the_compiled_base pins it to BUILD_HOSTED_BASE. - Android: `userSignalingUrl()` maps the placeholder (and blank) to "no override", so the bridge fills in the hosted lobby; any other value is the user's relay and wins. `onlineNetplayConfigured()` = a user relay OR a compiled-in base, replacing MainActivity's inline check. - iOS: an empty URL counts as configured when npHostedAvailable(); an explicit URL is still checked for a WebSocket scheme. The Settings header reads "(optional)" in such a build. A build without a base (F-Droid, plain source) behaves exactly as before: the placeholder still means unconfigured and the caveat shows. Verified: clippy and rustdoc clean for rustynes-mobile; its five hosted tests pass. NOT compiled here: the Kotlin and Swift halves (no Xcode on Linux). android.yml builds the Kotlin on the PR; ios.yml is dispatched once on this branch before merge to compile the Swift (a one-time check at the maintainer's direction; Apple runs are not a default). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * fix(web): trim the rcheevos base and share an in-flight module load agy on #618, on the v3.4.1 glue change: - rcheevosBase() did not trim the `rustynes-rcheevos-base` meta value (resolveProxyBase() trims its own). A value with surrounding spaces produced a URL with the spaces in it, and a whitespace-only value was taken as a base. It is trimmed now, and blank falls back to `cheevos/`. - loadModule() cached only the finished module, so ra_init() and ra_rcheevos_version() called before the first load finished each imported and instantiated their own rcheevos.wasm. The in-flight promise is cached; a failed load clears it so a later call can retry. - rcheevosBase is exported, and services/hosted/test/ra-glue.test.ts covers it with a stubbed `document` (the Workers runtime has no DOM): the default resolves against the page, not the snippet; the meta value is trimmed and given a trailing slash; a blank value counts as absent. Mutation: `.trim()` removed -> 2 of the new tests fail. Verified: the Worker suite 114 passed, tsc (TypeScript 7.0.2) clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * docs: answer #618's documentation findings and record the review work - .github/release-notes/v3.4.0.md (CodeRabbit): the "Two builds" line named the date-coded files without saying where they live; it now says MiSTer's updater installs them from the RustyNES_MiSTer repository's `releases/`, and that the attached files carry the same bytes under version names. The live v3.4.0 release body was updated from the file. - docs/cheevos-browser.md:200 (CodeRabbit, outside the diff): the step told maintainers to set `RA_PROXY_BASE` in ra_glue.js, which no longer exists as a setting; it now names the `rustynes-ra-proxy-base` meta tag that resolveProxyBase() reads. - to-dos/plans/v3.4.1-plan.md (CodeRabbit): row 10 split into 10a-10e so the waived checks read as waived (the seed sweep skipped and the ladders not waited for, both by the maintainer on 2026-10-18) and the remaining ones (one compile per build, VERIFY=1 at the new pin) carry their own status; rows 12-14 record the mobile, PGO and dependency work. - CHANGELOG: the Added entry now says the profile-guided Linux binary and every CI-built Android artifact (the FOSS flavour too, agy's nitpick) carry the base, and that a fresh mobile install can host and join; a Changed entry records the dependency sweep. markdownlint passes on every file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * fix(release): keep the hosted base in the promoted PGO binary Copilot and Antigravity on #618: release.yml set RUSTYNES_HOSTED_BASE in its workflow-level env, but its `pgo` job calls the reusable pgo.yml, and a called workflow inherits no `env:`. When the PGO gate promoted, pgo-linux-asset replaced the Linux release archive (`--clobber`) with a binary compiled without the base, silently dropping the hosted lobby from the one platform whose binary is rebuilt. - pgo.yml's workflow_call gains a `hosted_base` input (default empty), exported as RUSTYNES_HOSTED_BASE for the instrument/train/rebuild step only, and only when non-empty (an empty string would reach option_env! as a value). The dispatch-only BOLT job is unchanged. - release.yml passes the URL as a literal: `env` is not an allowed context in a reusable workflow's `with:`. Two literals that must agree are a drift waiting to happen, so release_anchor_audit gains: - every_shipped_build_compiles_the_same_hosted_base: web, release, android and ios set RUSTYNES_HOSTED_BASE exactly once, release.yml passes hosted_base exactly once, all name the same https URL, pgo.yml exports the input, and ci.yml sets none (a_stock_build_has_no_hosted_base asserts the default only when the variable is absent). Mutation: the PGO literal changed to another host -> FAILED; restored -> 18 passed. - the_hosted_worker_names_the_workspace_version (agy's suggestion): wrangler.jsonc's RA_USER_AGENT, package.json's root and both package-lock root entries name the workspace version. bump_release.py's MANIFESTS now moves all four (each pattern matches exactly once; the lockfile entries carry the name line, since a bare "version" matches dependencies too). --selftest passes. actionlint passes on both workflows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * docs(salvage): record the pre-reboot scratch salvage 29 files moved into the gitignored salvaged/tmp-scratch/f63c2db0/ under the maintainer's scope (this session, strong, only what cannot be rebuilt): the pre-rewrite snapshots of every release body in both repositories (the only copy, as GitHub keeps no body history), the v3.4.0 session notes and the v4 research write-up. The manifest entry records how 4,629 candidates were cut to 29 by measurement (505 byte-identical to git blobs, the rest run output, generated code, downloads or already-published text) and what was left, including a live TURN credential that must not be kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * fix(mobile): describe the hosted defaults in both settings screens CodeRabbit on #618, round 2: with 0a4c6e9 a build that carries a hosted base uses the hosted lobby for an empty signaling URL and fetches TURN credentials when no TURN trio is set, but both apps' settings still said otherwise. - iOS SettingsView: the signaling footer said "the maintainer must deploy and host it", and the TURN footer said that empty fields mean punch-or-fail. In a build where npHostedAvailable() is true they now say to leave the fields empty for the hosted lobby and short-lived credentials, or to fill them in to use another server. A build without a base keeps the old wording, which is still accurate there. - Android Settings: the online-netplay hint ("the default URL is a placeholder") gains a hosted variant, settings_netplay_online_hint_hosted in values/ and values-es/, chosen the same way. Also, CodeRabbit's outside-diff note on SECURITY.md: the matrix still named 3.3.x "the current line" (v3.4.0's cut missed it too). 3.4.x is now current and 3.3.x moves to "Partial" with every older line. Not compiled here: the Swift and Kotlin (ios.yml's one-time dispatch run 39188696837 predates this change; android.yml builds the Kotlin on the PR). markdownlint passes on SECURITY.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * fix(release): ship the PGO binary Stage 2 built, not Stage 4's test build agy on #618 (round of 02:28): pgo.yml's Stage 2 builds target/<triple>/release/rustynes with `--features full` (and, since fecc1e5, the hosted base). Stage 4 then runs `cargo pgo optimize test -- --workspace --release --features test-roms`, and cargo builds a package's binaries for its integration tests, so it rebuilt the same path with test-roms only and no base. Stage 6 uploaded that path. Every promoted PGO Linux archive therefore shipped the test build: no RetroAchievements, scripting, script-ipc, HD packs, debug hooks or AV recording, and from v3.4.1 no hosted lobby. That half of the defect predates this release; the promotion threshold seldom passed, which is why no user report traced it. - Stage 2 copies the binary it built to pgo-out/rustynes before anything else runs, and the upload reads that copy. - The promotion gate refuses (never fails the job, which would redden a release whose plain assets are fine) when a hosted base was asked for and the kept binary does not contain it: option_env! compiles the URL in as a literal, so `grep -aF` finds it. - release_anchor_audit now pins the copy, the upload path, the gate's check, and the absence of the old target/ upload path. Mutation: the old path put back -> FAILED; restored -> 18 passed. Its workflow value parser now drops a trailing YAML comment and either quote style (agy's nitpick). agy also suggested hoisting the base into job-level env for Stage 4 and the BOLT job. Not done: Stage 4 must keep running a_stock_build_has_no_hosted_base with the variable absent, and the BOLT job is workflow_dispatch-only (a dispatch run passes no base). Also from the same review, the mobile follow-ups: - Android: a custom relay must be a ws:// or wss:// URL to enable room codes, matching iOS; the Settings field no longer shows the dead placeholder URL (a stored placeholder reads as empty, "no override"). - iOS: the room-code hint and the Settings warning tell a hosted build's user to clear an invalid URL to get the hosted lobby back. actionlint passes. Kotlin and Swift are not compiled here: android.yml runs on this PR; the Swift change is two text expressions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * fix(ppu): make the emphasis table a module so CodeQL can parse it The code-scanning banner ("CodeQL is reporting errors") traced to the Rust extractor, which reported 25 of 544 files "extracted with errors" on main and on #618 alike. Reproduced locally with the CodeQL 2.27.2 bundle (checksum-verified) against the same tree: 0 extraction errors and 138 extraction warnings, in exactly 25 distinct files, so the status page's count is the warning count. 101 of the 138 came from crates/rustynes-ppu/src/emphasis_delta_table.rs: 100 "expected an item" plus "Too many diagnostic messages". The file was a bare array expression, valid only through `include!` in emphasis.rs, and the extractor parses every `.rs` file as a module. Renaming it to `.in` was tried and does not help: that extractor loads only `.rs` files, so `include!` then failed inside emphasis.rs instead ("failed to load file", "the macro 'include' expands to ERROR"). The fix makes it an ordinary module: emphasis_delta_table.rs now holds `pub const EMPHASIS_DELTA_TABLE: [[i16; 3]; 512] = [...]` (rows byte for byte as before), lib.rs declares `mod emphasis_delta_table;`, and `EMPHASIS_DELTA` is that constant. The generator, print_emphasis_delta_table, emits the module form, and its output is byte-identical to the committed file (diffed). Verified: the 118 rustynes-ppu tests pass, including the_committed_table_is_the_documented_model; clippy -D warnings and rustdoc -D warnings clean; the thumbv7em no_std build. CodeQL rerun on the changed tree: 0 errors, 36 warnings, 24 files. The 24 left are 18 third-party macros the build-less extractor cannot expand (criterion, bitflags, proptest, uniffi, retro_core) and 6 stray .rs files outside any Cargo target (three under scripts/, three under tests/framework/), a cleanup that is the maintainer's to decide. Whether the banner itself clears can only be seen after main's next analysis; the status page is not readable through the API. Also: the v3.4.1 CHANGELOG entries for the PGO fix (with the v2.9.6 promotion found in the release history), the Android and iOS settings follow-ups, the real 10027 fix in the MiSTer core, and this change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * fix(hosted): revoke each TURN credential when its TTL ends The v3.4.1 live expiry gate failed (T-HOSTED-TURN-EXPIRY). The Worker asks Cloudflare for credentials with {"ttl": 10800}, and Cloudflare's generate-credentials page says the ttl expires the credential and its FAQ that an expired allocation is disconnected "after a short delay". Measured on 2026-10-19 with relay-only ICE gathers in fresh Chromium profiles, it does not refuse them: a 3-hour credential 2 h 38 min past its expiresAt, and a 600 s credential (minted on a briefly redeployed Worker, production restored within the minute) 6.6 minutes past its own, both still obtained `relay udp` candidates. The spend guards bound how many credentials exist; nothing bounded how long a leaked one worked. The maintainer chose to fix it in v3.4.1 rather than ship it as a known issue. The Worker now enforces the TTL itself: - handleTurn hands every TURN username in the minted ICE list to the global Budget object with its expiry (expiresAt * 1000). - Budget.scheduleRevoke stores `revoke:<due ms, 15 digits>:<username>` (keys sort by due time, and survive eviction) and pulls the object's single alarm in to the due time if it was later. - The alarm now revokes due credentials before its hourly sweep: POST rtc.live.cloudflare.com/v1/turn/keys/<id>/credentials/<user>/revoke with the key's token. 204 (and 404, which means Cloudflare no longer knows it) deletes the entry; anything else is retried every 5 minutes, REVOKE_MAX_ATTEMPTS (6) attempts in all, then dropped rather than retried forever. At most 50 per alarm, so one alarm stays short; the rest follow a second later. The alarm re-arms for the earlier of the next sweep and the next revocation. - A failed mint schedules nothing. Revocation is never earlier than the TTL, so a session within its three hours is untouched. Tests (TDD: the four new behaviours failed first): scheduling at expiry, nothing on a failed mint, revoking only due credentials with the bearer token and re-arming for the next one, a 404 as done, retry then give-up. Mutations: the scheduling call removed -> 1 fails; the re-arm ignoring the next revocation -> 2 fail. 119 passed; tsc (TypeScript 7.0.2) clean. PRIVACY.md now says the service keeps each credential's username (a random identifier Cloudflare issues, not linked to the user or their address) until the TTL ends, then revokes it and deletes the username; the secret half is never stored. The README's guard table, its "Why 3 hours", backstop and live-gate steps, and turn.ts's TTL comment say the TTL is enforced by revocation and why. Not covered: credentials minted before this deploy (yesterday's gates and today's two tests) are not in the schedule and stay usable until whatever limit Cloudflare applies; none was shared beyond this machine. The live re-run of the expiry gate follows the deploy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * fix(hosted): never drop a TURN revocation silently or delay it The automated security review of 960ff9f raised two findings; both hold. 1. Fail-open retries. A missing key, a 401 or a 403 used up the six attempts in 30 minutes and then deleted the revocation, and a 404 was accepted as done with no trace, so a token rotated or revoked by mistake would have let every credential minted meanwhile live on. Now: - 2xx: done. 404: done (Cloudflare does not know the credential), logged as a warning, because a 404 from a wrong key id would look the same. - Missing key / 401 / 403: a configuration fault, logged as an error, retried hourly WITHOUT counting as an attempt. - Anything else: backoff from 5 minutes, doubling to an hour. - An entry is dropped only REVOKE_GIVE_UP_MS (48 h, Cloudflare's maximum TTL) past the credential's expiry, with an error log. A retry is re-keyed under its next attempt time, so the key order stays the order of work; the value keeps `dueMs` (the original expiry) and the attempt count. Logs carry the status and attempt count only, never the username, and Workers Logs are off in production. 2. A delayed revocation. alarm() computed the next revocation before awaiting Cloudflare; a credential minted during those awaits set its own earlier alarm, which the final setAlarm then pushed later (up to the next hourly sweep, past a 600 s TTL). The re-arm now reads the first pending key fresh after the sweep, and keeps any alarm already set earlier. Tests: backoff and re-keying, kept until 48 h past expiry and dropped after, 401/403 retried hourly with attempts unchanged, and a credential scheduled from inside the revoke call (a mint landing mid-alarm) keeping its alarm. Mutations: the fresh re-arm read removed -> 1 fails; configuration failures counted as attempts -> 1 fails. 121 passed; tsc clean. Deployed (version 6496919c) ahead of the live expiry re-run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * fix(mobile,web): an unusable relay URL disables room codes on Android Review of 148ee28 on #618: - Cursor Bugbot (medium): f6cb343 made Android's onlineNetplayConfigured require a ws:// or wss:// relay, "matching iOS", but on Android it only chose the caveat text; the Host online and Join buttons still called the bridge with the malformed URL, and the caveat said "no relay is configured". Both buttons are now disabled while it is false, as iOS disables its room buttons, and in a build that carries the hosted lobby the caveat says the Settings URL is not a WebSocket address and that clearing it restores the hosted lobby. A build without a base keeps the old caveat. - Antigravity (suggestion): rcheevosBase() passed the meta value straight to `new URL(...)`, so a malformed value threw out of ra_init. It now falls back to `cheevos/` beside the page, as resolveProxyBase() refuses a bad proxy base. New test: a value of "http://[bad" resolves to the default (122 passed). Not changed: agy's nitpick that the package-version anchors in release_anchor_audit and bump_release.py match "\n" and would miss on a CRLF checkout. Both read files this repository stores with LF (.editorconfig mandates LF), and a CRLF checkout makes the audit FAIL, loudly, rather than pass wrongly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * fix(hosted): ship TURN switched off; Cloudflare honours revoked credentials Revocation (960ff9f, 2f78987) was deployed and tested live on 2026-10-19 with a 600 s credential and `wrangler tail` attached: the Budget alarm fired at expiry and logged "turn revoke: 1 revoked" (a 2xx from Cloudflare's revoke endpoint; a 404 would have logged its own warning). Two minutes later the credential still obtained 8 `relay udp` candidates in a fresh Chromium profile. So did the earlier 600 s credential, revoked about 15 minutes before, and the 3-hour credential from 14:35, expired since 16:35. The control: a credential with a random username and password got NO relay candidate, so Cloudflare does authenticate and the gather does distinguish. Cloudflare creates allocations for credentials that are expired AND revoked, at least for these intervals, contrary to its generate-credentials page and FAQ. Its FAQ also says an expired credential stops being billed at once and is disconnected shortly after; neither was measured. The maintainer chose to ship with the relay off: - wrangler.jsonc: TURN_ENABLED "false", with the reason at the site. Deployed (version 764bc2e4); POST /turn-credentials answers 503 turn-disabled (after about 15 s of propagation, during which one credential was issued; it is scheduled for revocation and its response was not kept). Clients already treat turn-disabled as "connect directly (STUN only)". - vitest.config.ts binds TURN_ENABLED "true", as for RA_ENABLED, so the TURN and revocation code stays under test (122 passed). - budget.ts logs a count after a revocation pass ("turn revoke: N revoked"), no usernames, so an operator tailing the Worker can see it work; that line is how the 2xx above was established. - Docs: the release headline in every anchor (AGENTS, README, ROADMAP, SUPPORT, OVERVIEW, VERSION-PLAN, STATUS, to-dos/ROADMAP, CHANGELOG), the CHANGELOG entry and the release notes say the lobby is live and the relay is deployed but off, and why; the Worker README gains "TURN is off"; plan row 3 records both failed gates; T-HOSTED-TURN-EXPIRY now lists what remains (measure billing and allocation lifetime, report to Cloudflare, switch back on). Verified: release_anchor_audit 18, release_notes_render_audit 9 and release_state_prose_audit pass; markdownlint passes on every changed file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * docs: v3.4.1 verification figures, and the TURN backstop and research - .github/release-notes/v3.4.1.md: Verification filled from the full local suites at 148ee28 on Rust 1.99.1 (no Rust file has changed since): test-roms 3,550 passed / 0 failed / 13 ignored over 172 binaries, with commercial-roms 3,801 / 0 / 18 over 182. The iOS line says what was compiled: the one CI run built 3a6f97e; f6cb343's later Swift edits (two hint strings, a label) were not rebuilt. - services/hosted/README.md: the backstop step now says expiry and revocation were measured not to stop new allocations, that deleting the TURN key is the likely stop (untested), and that the budget alert is the backstop known to work. - to-dos/ROADMAP.md: T-HOSTED-TURN-EXPIRY gains the key-deletion test, the stricter two-peer billing test, and the alternatives from the 2026-10-19 research (self-hosted eturnal with strict_expiry on a throttling VPS; STUN plus user-supplied TURN). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * fix(hosted,mobile): answer #618's latest review round CodeRabbit on d215275 (six inline, one outside the diff), all valid: - budget.ts (outside the diff, CWE-359): admit() armed the hourly sweep only when no alarm was set. Since revocations share the object's one alarm, a pending revocation hours out could keep a salted IP hash past PRIVACY.md's "at most two hours". It now re-arms for the sweep when the set alarm is more than an hour away. Test (failed first): a revocation 3 h out, one admission, the alarm within the hour. 123 passed. - Netplay.kt / NetplayModel.swift: a bare "ws://" passed the prefix check and enabled room codes with no host. Android now requires `^wss?://` plus a host before any path; iOS parses with URL and requires a ws/wss scheme and a non-empty host. The Swift is not compiled here. - services/hosted/README.md: every passage that said revocation bounds a credential now says it is attempted and that its effect is unverified (the guard table row, the revocation paragraph, "What the guards do not bound", the backstop step), the live-gate step says it still fails as of v3.4.1, the guard table shows the deployed TURN_ENABLED and RA_ENABLED values ("false"), and the retry policy is described as budget.ts implements it (2xx / 404 done, config errors hourly without counting, backoff 5 min doubling to 1 h, drop 48 h past expiry). - CHANGELOG: revocation described as requested, not effective. - PRIVACY.md: the username retention states the 48 h worst case and the configurable lifetime (3 h deployed, up to 24 h), and that with the relay off nothing is kept; effective date 2026-10-19 (v3.4.1). The release notes state the change, as the policy itself requires. - The release notes' iOS line also names the relay-URL check among the uncompiled Swift edits. The [GATES] finding was already fixed in d215275. Also to-dos/mister/TASKS.md: T-MISTER-SS-ABANDON-STATES for v3.4.2, Antigravity's blocking claim on sibling #67 read against the RTL (the four unlisted states are safe as shipped; the comment is wrong and an earlier abandon in E_PUT would keep the previous slot), deferred because any rtl/ edit makes release-rbf.sh refuse the compiled bitstreams. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * fix(hosted,mobile): take a fresh clock after revocations; tighten relay URLs Answers Antigravity's latest #618 round (no blocking findings) and the older round's copy note. Worker (services/hosted/src/budget.ts): - alarm() read `now` once and reused it after up to REVOKE_BATCH (50) revocation fetches, each bounded by REVOKE_TIMEOUT_MS. A slow batch could therefore schedule the next alarm, and judge the 48 h give-up, against a clock minutes stale. revokeDue now takes Date.now() after each revokeOne for the give-up and the retry time, and the alarm's final scheduling reads the clock again before nextRevocation(). - revokeDue listed every pending revocation key and stopped after a batch. The list is now bounded ({ prefix, limit: REVOKE_BATCH + 1 }); keys sort by attempt time, so the first batch is the right one. - A retry wrote the new key after deleting the old one. An eviction between the two lost the revocation; the order is now put then delete, whose worst case is one harmless duplicate revoke. - revokeKey truncates the time before zero-padding, so a fractional millisecond can never widen the fixed 15-digit field and break the lexical order the list relies on. TURN stays switched off in production (TURN_ENABLED "false"); this code runs only when it is re-enabled, and vitest binds it on. Mobile: - Android RELAY_URL accepted "wss://:8080" (no host) and whitespace after the host. The host must now start with a non-colon character and no whitespace is allowed anywhere; case-insensitive. Checked: ws://, wss://:8080 and "wss://h/p q" refused; wss://relay.example, WSS://Relay.example/x and ws://10.0.0.2:9000 accepted. - iOS compares the URL scheme case-insensitively. - Copy no longer promises a hosted relay or short-lived TURN credentials while the relay is off (Android EN/ES hint, iOS TURN footer), and the non-hosted Android hint no longer calls the empty default a placeholder. Verified: vitest 123 passed; tsc --noEmit clean. No Rust changed. The Kotlin and Swift edits are uncompiled locally (no Android/iOS run for this commit; the release runs ios.yml). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * test(hosted): never arm a past alarm in the revocation tests CI on ce80d0f failed "the alarm revokes every due credential ... and only due ones": runDurableObjectAlarm returned false. The test's seed() armed the Durable Object alarm at the credential's due time, which the tests set in the past. workerd fires a past-due alarm by itself, so it could run (and clear) between seed() and the test's explicit runDurableObjectAlarm, which then found no alarm. Locally the race was lost every time (123 passed); on the CI runner it was won once. seed() now arms at max(due, now + 60 s). runDurableObjectAlarm runs an armed alarm immediately regardless of its time, so every test still drives the alarm explicitly, and the automatic one can no longer fire first. The first test's final assertion (next alarm = the later credential's due time, an hour out) is unaffected: that key's time is later than the 60 s floor. No production code changed. Verified: vitest 123 passed, three runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj * fix(hosted): withhold a credential whose revocation was not recorded Answers Antigravity's two newest #618 rounds (no blocking findings). - turn.ts: handleTurn mints the credential upstream, then records its revocation in the budget object. If that call threw (a transient Durable Object or storage failure), the request ended in an unhandled 500 with the admission still charged and a live credential nobody would ever revoke. It now fails closed: the credential is withheld, the admission refunded, and the client gets a 503 telling it to connect directly. Withholding rather than returning was chosen because the whole point of the record is that no handed-out credential escapes revocation; the minted one is used by no one and lapses at its TTL. - budget.ts: one alarm could spend up to REVOKE_BATCH x REVOKE_TIMEOUT_MS (50 x 5 s = 250 s) on revocation requests against a hung upstream, and the object is single-threaded, so admissions would queue behind it. The loop now stops after a 15 s wall-clock budget; the keys it did not reach are still due, so the alarm's own re-arm (nextRevocation) fires again at once. - to-dos/plans/v3.4.1-plan.md: rows 10b and 10c described the state of 2026-10-18 (ladders "not waited for", bitstreams "compiling"). 10b now records the ladders as cancelled at the maintainer's word, 10c the 2026-10-19 compiles and their margins. 10e ("after the oracle merges") is still true and is unchanged. Not done, with reasons (replied on the PR): - bolt job forwarding hosted_base: hosted_base is a workflow_call input only, and bolt runs only on workflow_dispatch, where it is always empty; bolt's output is never promoted to a release. - Android validating relay URLs through a shared Rust parser: a UniFFI export plus both apps is a v3.4.2-sized change; the regex now refuses the empty-host and whitespace cases, and a malformed port still fails at connect. - ra_glue.js reading RA_PROXY_BASE at import: browser RA is held off (D31); recorded for when it is enabled. TURN stays off in production (TURN_ENABLED "false"), so neither Worker change runs there until it is re-enabled. Verified: vitest 123 passed, tsc --noEmit clean. No new test: the storage failure and the 15 s budget both need fault injection or fake timers inside workerd, which the suite does not have; stated rather than faked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Bumps the npm_and_yarn group with 1 update in the /services/hosted directory: sharp.
Updates
sharpfrom 0.35.4 to 0.35.5Release notes
Sourced from sharp's releases.
... (truncated)
Commits
51a990fRelease v0.35.596de105Upgrade to sharp-libvips v1.3.43a61390CI: Configure Dependabot with all package.json locations4940c50Improve gain map support for rotate/flip/flop ops20654aaPrerelease v0.35.5-rc.1ef4f934CI: Upgrade to Ubuntu 26.04358df95Upgrade to libvips v8.18.749f4903Improve gain map support for rotate-then-extract #46060e2e55eSilence a couple of compiler/static analysis warningscef3b8cImprove gain map support for extract operation #4606Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting
@dependabot rebase.Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
@dependabot rebasewill rebase this PR@dependabot recreatewill recreate this PR, overwriting any edits that have been made to it@dependabot show <dependency name> ignore conditionswill show all of the ignore conditions of the specified dependency@dependabot ignore <dependency name> major versionwill close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself)@dependabot ignore <dependency name> minor versionwill close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself)@dependabot ignore <dependency name>will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself)@dependabot unignore <dependency name>will remove all of the ignore conditions of the specified dependency@dependabot unignore <dependency name> <ignore condition>will remove the ignore condition of the specified dependency and ignore conditionsYou can disable automated security fix PRs for this repo from the Security Alerts page.
Summary by CodeRabbit