chore: de-monetize — RustyNES is permanently OSS/income-free (v2.2.6 "Almanac") - #343
Conversation
…"Almanac") v2.2.6 "Almanac" is a de-monetization and provenance release. The maintainer has decided RustyNES is and will remain open-source and income/profit-free forever (ADR 0035): all planned monetization is removed, and the native Android/iOS apps are kept as free FOSS apps — no ads, no tracking, no paid unlock, every feature available. This opens the v2.2.6 -> v2.3.0 line that addresses NESdev-forum feedback (audio, video/gamma, TAS/UX, and a PPU accuracy capstone). Zero emulation-core behavior changes: no crate under the deterministic #![no_std] chip stack depended on the removed monetization crate, so the core, save-state / TAS / netplay formats, and every golden vector are byte-identical. AccuracyCoin holds 141/141 (100.00%) and nestest is 0-diff by construction. Removed - The rustynes-monetization crate (AdPolicy / freemium / ad-policy core, its UniFFI bindgen, and the android/ios reference shells) and docs/monetization/ (the 8-file freemium design + compliance set); the workspace member is dropped and Cargo.lock regenerated clean. - Android paid layer: Play Billing (LicenseManager), the AppLovin MAX / RevenueCat MonetizationGate + ad gates (monetization/ package), the demo/paywall/unlock UI and its strings, the AdMob/AppLovin manifest entries, the billing/ad Gradle deps + BuildConfig keys + the AppLovin Maven repo, and the monetization cargo/uniffi Gradle tasks. MainActivity no longer threads an `unlocked` flag or gates any feature (save-states, auto-resume, cloud-pull) behind an unlock/demo. - iOS paid layer: the StoreKit StoreManager (Entitlements.swift), the appStore monetization build channel, and the StoreKit/Entitlements project.yml linkage. Kept (free, non-monetization) - The foss/play Android flavor split, now distinguishing only the pure-AOSP build from the build carrying the free Google-Play services (Play Games achievements, Cast, Play Integrity, in-app update, cloud save). All PgsIds achievement unlocks remain. Nightly Rust is now used only by cargo fuzz. Provenance accuracy (ADR 0035 + ADR 0030) - NOTICE and docs/originality-and-provenance.md now disclose honestly that the PPU octal-latch / hybrid-address *timing* (COPY_V_DELAY / delayed-CopyV) was calibrated to TriCNES's per-dot behavior rather than derived independently from hardware documentation — beyond black-box oracle use. That reproduced a TriCNES-specific artifact that mis-renders games doing mid-render $2006 writes (e.g. Rad Racer's road/horizon split). No TriCNES code is incorporated (it is MIT regardless); the issue is behavioral fidelity, and the fix is to make the behavior documentation-derived in v2.3.0 "Datum II". Docs / ADRs - Added ADR 0035 "RustyNES is permanently non-commercial (no monetization)"; marked ADR 0025 Superseded (its play ad/billing layer collapses; the flavor split stands for free services) and amended ADR 0027 (removes the ad-bearing App-Store flavor / ATT / StoreKit-unlock; keeps the section 4.7 ROM-compliance rules, valid for a free app). - Reframed ROADMAP / docs/STATUS.md / README / AGENTS / the version plans to the OSS/income-free position; the freed v2.3.0 slot is repurposed as the accuracy capstone of the v2.2.6 -> v2.3.0 line, and any future mobile store listing is a later, unversioned free-app step with no monetization. Verification - cargo check --workspace: pass. cargo fmt --all --check: pass. markdownlint (pinned v0.39.0): pass. No CI/config/code references to the removed crate remain (only annotated history + "absence" comments). No dangling mkdocs nav or doc links. The Android/iOS Kotlin/Swift shells are internally consistent (no dangling LicenseManager/MonetizationGate/StoreManager references) but were not compile-built in this environment — a local assembleFossDebug / Xcode build is the on-device confirmation step. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 43 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (6)
📝 WalkthroughWalkthroughThe change removes Android and iOS monetization infrastructure, deletes the dormant Rust monetization crate, updates workspace metadata to v2.2.6, and revises release, provenance, architecture, build, and roadmap documentation. ChangesDe-monetization and release alignment
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 8 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (8 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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 removes the previously staged monetization system from RustyNES (crate, Android/iOS shell scaffolding, and related app-layer gates) and updates project documentation/ADRs to reflect a permanent OSS/income-free stance for the mobile apps, while also adding provenance disclosures related to TriCNES calibration.
Changes:
- Deleted the
rustynes-monetizationcrate and removed it from the workspace and lockfile. - Removed Android/iOS app-shell monetization scaffolding (billing/ad gate overlays, paywall strings, StoreKit scaffolding) and updated iOS/Android documentation to reflect the new posture.
- Added ADR 0035 and updated existing ADRs / docs (
NOTICE, provenance docs, mkdocs config, roadmap/plans) to reflect the policy and disclosure changes.
Reviewed changes
Copilot reviewed 73 out of 74 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| to-dos/README.md | Reframes historical mobile plan notes to reflect monetization removal. |
| to-dos/plans/v2.0.x-mobile-finalization-plan.md | Adds a “superseded” banner for monetization items; retains flavor split as non-monetization. |
| to-dos/plans/v1.9.x-ios-train-plan.md | Adds historical-context note that monetization references are superseded/removed. |
| to-dos/plans/v1.8.0-android-plan.md | Adds historical-context note that monetization plan was removed per ADR 0035. |
| to-dos/DEFERRED-AND-CARRYOVER-FEATURES.md | Updates carryover items to remove monetization expectations and keep the flavor split only for free services. |
| NOTICE | Adds provenance disclosure note about TriCNES calibration and planned remediation. |
| mkdocs.yml | Removes docs/monetization/ from excluded docs list (since docs are removed). |
| ios/RustyNES/RustyNESApp.swift | Removes app-wide Entitlements injection and refresh call. |
| ios/RustyNES/PrivacyInfo.xcprivacy | Updates privacy/ATT wording to “none, ever” per new policy. |
| ios/RustyNES/Entitlements.swift | Deletes dormant entitlement + StoreKit scaffold. |
| ios/RustyNES/DebuggerView.swift | Updates comment to align with single-channel posture (still uses BuildChannel.isFoss). |
| ios/RustyNES/BuildChannel.swift | Collapses to a constant “single free channel” implementation. |
| ios/project.yml | Removes App-Store flavor instructions and drops StoreKit.framework linkage. |
| docs/originality-and-provenance.md | Adds explicit caveat about TriCNES timing calibration and planned documentation-derived rework. |
| docs/ios.md | Updates iOS doc to state entitlement scaffolding was removed entirely. |
| docs/ios-v1.9.9-readiness.md | Updates readiness doc to remove StoreKit/monetization wiring expectations. |
| docs/DOCUMENTATION_INDEX.md | Removes documentation index entry for monetization docs. |
| docs/dev/BUILD.md | Updates Android build notes to remove monetization crate mention. |
| docs/build-and-tooling.md | Updates toolchain/nightly and workspace layout notes to remove monetization references. |
| docs/architecture.md | Updates crate layout diagram to remove rustynes-monetization. |
| docs/adr/0035-rustynes-is-permanently-non-commercial.md | Adds new ADR formalizing the no-monetization decision. |
| docs/adr/0027-ios-distribution-and-app-store-compliance.md | Amends ADR status to note monetization portions removed by ADR 0035. |
| docs/adr/0025-foss-play-android-flavor-split.md | Marks ADR as superseded for monetization portions; retains split for free Play services. |
| crates/rustynes-monetization/uniffi.toml | Deleted (crate removal). |
| crates/rustynes-monetization/uniffi-bindgen.rs | Deleted (crate removal). |
| crates/rustynes-monetization/src/lib.rs | Deleted (crate removal). |
| crates/rustynes-monetization/shells/README.md | Deleted (crate removal). |
| crates/rustynes-monetization/shells/ios/RustyNesApp.swift | Deleted (crate removal). |
| crates/rustynes-monetization/shells/ios/RewardedGate.swift | Deleted (crate removal). |
| crates/rustynes-monetization/shells/ios/Package.swift | Deleted (crate removal). |
| crates/rustynes-monetization/shells/ios/Billing.swift | Deleted (crate removal). |
| crates/rustynes-monetization/shells/ios/AdGate.swift | Deleted (crate removal). |
| crates/rustynes-monetization/shells/android/RustyNesApp.kt | Deleted (crate removal). |
| crates/rustynes-monetization/shells/android/RewardedGate.kt | Deleted (crate removal). |
| crates/rustynes-monetization/shells/android/build.gradle.kts | Deleted (crate removal). |
| crates/rustynes-monetization/shells/android/Billing.kt | Deleted (crate removal). |
| crates/rustynes-monetization/shells/android/AdGate.kt | Deleted (crate removal). |
| crates/rustynes-monetization/Cargo.toml | Deleted (crate removal). |
| CHANGELOG.md | Adds v2.2.6 release entry describing de-monetization + provenance disclosure. |
| Cargo.toml | Removes crates/rustynes-monetization from workspace members; bumps workspace version to 2.2.6. |
| Cargo.lock | Removes the rustynes-monetization package entry. |
| android/settings.gradle.kts | Removes AppLovin Maven repository. |
| android/app/src/play/res/values/strings.xml | Deletes play-flavor paywall strings. |
| android/app/src/play/res/values-es/strings.xml | Deletes play-flavor paywall strings (es). |
| android/app/src/play/java/com/doublegate/rustynes/monetization/RewardedGate.kt | Deletes play-flavor rewarded-ad gate. |
| android/app/src/play/java/com/doublegate/rustynes/monetization/AdGate.kt | Deletes play-flavor interstitial-ad gate. |
| android/app/src/play/java/com/doublegate/rustynes/Integrity.kt | Updates Integrity docs/comments to reflect advisory-only role (no gating). |
| android/app/src/play/AndroidManifest.xml | Removes ad/billing-specific overlay content; keeps empty overlay to preserve explicit flavor split. |
| android/app/src/main/res/values/strings.xml | Removes unlock/demo strings from shared resources. |
| android/app/src/main/res/values-es/strings.xml | Removes unlock/demo strings from shared resources (es). |
| android/app/src/main/java/com/doublegate/rustynes/PlayFacadeShared.kt | Removes demo-session constant; updates comments to reflect no monetization. |
| android/app/src/foss/java/com/doublegate/rustynes/MonetizationGate.kt | Deletes FOSS no-op monetization gate facade. |
| android/app/src/foss/java/com/doublegate/rustynes/Billing.kt | Deletes FOSS no-op billing facade. |
| android/app/proguard-rules.pro | Removes keep rules for monetization UniFFI + ad/billing SDKs; updates commentary accordingly. |
| .markdownlintignore | Removes ignore for docs/monetization/ (docs removed). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@AGENTS.md`:
- Line 188: The release-history text incorrectly labels v2.2.2 “Conduit” as the
prior release. Update the relevant wording in the release narrative to identify
v2.2.5 “Colophon” as the prior release, while preserving the existing v2.2.6
current-release ordering and history.
In `@Cargo.toml`:
- Line 20: Change the indentation of the "crates/rustynes-libretro" workspace
member entry from four spaces to two spaces to align with the project's TOML
indentation standard. Update only the leading whitespace of this line while
preserving the member name and its position in the workspace members list.
In `@docs/android.md`:
- Around line 171-176: Update the privacy statement referenced near the flavor
documentation to distinguish the foss and play flavors: retain the
no-network/no-collection claim only for foss, and document play’s network access
and account-data behavior consistently with its Google Play services features.
Verify the Android manifest and existing privacy declarations before finalizing
the wording.
In `@docs/architecture.md`:
- Line 68: Update the workspace crate count in the architecture documentation
from 16 to 15 so it matches the 15 crates listed in both workspace trees. Verify
the documented count against the current workspace using cargo metadata, without
adding a removed crate.
In `@docs/STATUS.md`:
- Around line 3-19: Update release policy documentation across six sites to
align with the v2.2.6 release and reflect the permanent open-source,
de-monetization direction. At docs/STATUS.md lines 3-19 (anchor), the entry has
been updated to v2.2.6; at AGENTS.md lines 46-46, remove the stale v2.2.4
current-release label and the v2.3.0 joint-store-launch plan; at AGENTS.md lines
188-188, replace the v2.2.2 prior-release label with the correct chronological
release order; at README.md lines 925-932, rewrite the roadmap introduction to
remove framing tied to a joint store launch; at docs/STATUS.md lines 1885-1891,
mark the old v2.3.0 joint-store-launch plan as historical or replace it to
reflect the new direction; at
docs/adr/0027-ios-distribution-and-app-store-compliance.md lines 7-16, mark the
v2.1.0 distribution and appstore monetization decisions as historical since
those policies are no longer active. Ensure all six locations reference the
current v2.2.6 release and consistent roadmap expectations without
joint-store-launch references.
In `@to-dos/DEFERRED-AND-CARRYOVER-FEATURES.md`:
- Around line 83-92: Reconcile the mobile app-store launch schedule across three
documentation files to align with the current policy of optional distribution
without a fixed release timeline. At to-dos/DEFERRED-AND-CARRYOVER-FEATURES.md
lines 83-92, replace the fixed v2.0.1–v2.0.4 target statement with the current
implementation status or mark the entire Android flavor block as historical
context. At to-dos/README.md lines 101-104, remove or revise the active v2.1.0
joint store launch claim to reflect that the timeline is no longer guaranteed.
At to-dos/ROADMAP.md lines 113-115, update the mobile finalization paragraph to
explicitly state that store distribution is optional and may occur after v2.0
without a committed release version. Ensure all three locations consistently
reflect that the v2.1.0 target no longer drives the mobile launch schedule.
In `@to-dos/ROADMAP.md`:
- Around line 30-35: Align the roadmap’s Status section and related
current-release pointers with v2.2.6, replacing any remaining v2.2.4
current-release references while preserving historical mentions. Ensure the
document identifies only one active release line and remains consistent with the
v2.2.6-to-v2.3.0 roadmap context.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 55dc34ce-5f49-45e5-9261-b66a03155860
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock,!Cargo.lock
📒 Files selected for processing (73)
.markdownlintignoreAGENTS.mdCHANGELOG.mdCargo.tomlNOTICEREADME.mdandroid/app/build.gradle.ktsandroid/app/proguard-rules.proandroid/app/src/foss/java/com/doublegate/rustynes/Billing.ktandroid/app/src/foss/java/com/doublegate/rustynes/MonetizationGate.ktandroid/app/src/main/java/com/doublegate/rustynes/MainActivity.ktandroid/app/src/main/java/com/doublegate/rustynes/PlayFacadeShared.ktandroid/app/src/main/res/values-es/strings.xmlandroid/app/src/main/res/values/strings.xmlandroid/app/src/play/AndroidManifest.xmlandroid/app/src/play/java/com/doublegate/rustynes/Billing.ktandroid/app/src/play/java/com/doublegate/rustynes/Integrity.ktandroid/app/src/play/java/com/doublegate/rustynes/MonetizationGate.ktandroid/app/src/play/java/com/doublegate/rustynes/monetization/AdGate.ktandroid/app/src/play/java/com/doublegate/rustynes/monetization/RcBilling.ktandroid/app/src/play/java/com/doublegate/rustynes/monetization/RewardedGate.ktandroid/app/src/play/res/values-es/strings.xmlandroid/app/src/play/res/values/strings.xmlandroid/settings.gradle.ktscrates/rustynes-monetization/Cargo.tomlcrates/rustynes-monetization/shells/README.mdcrates/rustynes-monetization/shells/android/AdGate.ktcrates/rustynes-monetization/shells/android/Billing.ktcrates/rustynes-monetization/shells/android/RewardedGate.ktcrates/rustynes-monetization/shells/android/RustyNesApp.ktcrates/rustynes-monetization/shells/android/build.gradle.ktscrates/rustynes-monetization/shells/ios/AdGate.swiftcrates/rustynes-monetization/shells/ios/Billing.swiftcrates/rustynes-monetization/shells/ios/Package.swiftcrates/rustynes-monetization/shells/ios/RewardedGate.swiftcrates/rustynes-monetization/shells/ios/RustyNesApp.swiftcrates/rustynes-monetization/src/lib.rscrates/rustynes-monetization/src/monetization.rscrates/rustynes-monetization/uniffi-bindgen.rscrates/rustynes-monetization/uniffi.tomldocs/DOCUMENTATION_INDEX.mddocs/STATUS.mddocs/adr/0025-foss-play-android-flavor-split.mddocs/adr/0027-ios-distribution-and-app-store-compliance.mddocs/adr/0035-rustynes-is-permanently-non-commercial.mddocs/android.mddocs/architecture.mddocs/build-and-tooling.mddocs/dev/BUILD.mddocs/ios-v1.9.9-readiness.mddocs/ios.mddocs/monetization/AGENT-GUIDANCE.mddocs/monetization/README.mddocs/monetization/build-and-bindings.mddocs/monetization/implementation-brief.mddocs/monetization/platform-setup-runbook.mddocs/monetization/pre-implementation-addendum.mddocs/monetization/recommendations.mddocs/monetization/rustynes-integration.mddocs/originality-and-provenance.mdios/RustyNES/BuildChannel.swiftios/RustyNES/DebuggerView.swiftios/RustyNES/Entitlements.swiftios/RustyNES/PrivacyInfo.xcprivacyios/RustyNES/RustyNESApp.swiftios/project.ymlmkdocs.ymlto-dos/DEFERRED-AND-CARRYOVER-FEATURES.mdto-dos/README.mdto-dos/ROADMAP.mdto-dos/plans/v1.8.0-android-plan.mdto-dos/plans/v1.9.x-ios-train-plan.mdto-dos/plans/v2.0.x-mobile-finalization-plan.md
💤 Files with no reviewable changes (40)
- android/settings.gradle.kts
- ios/RustyNES/RustyNESApp.swift
- crates/rustynes-monetization/uniffi.toml
- crates/rustynes-monetization/shells/README.md
- docs/DOCUMENTATION_INDEX.md
- docs/monetization/platform-setup-runbook.md
- android/app/src/main/res/values-es/strings.xml
- docs/monetization/implementation-brief.md
- android/app/src/play/java/com/doublegate/rustynes/monetization/RcBilling.kt
- docs/monetization/README.md
- .markdownlintignore
- docs/monetization/pre-implementation-addendum.md
- docs/monetization/AGENT-GUIDANCE.md
- crates/rustynes-monetization/shells/android/build.gradle.kts
- docs/monetization/recommendations.md
- crates/rustynes-monetization/shells/ios/Package.swift
- docs/monetization/rustynes-integration.md
- crates/rustynes-monetization/shells/ios/AdGate.swift
- crates/rustynes-monetization/uniffi-bindgen.rs
- crates/rustynes-monetization/shells/android/RewardedGate.kt
- ios/RustyNES/Entitlements.swift
- crates/rustynes-monetization/Cargo.toml
- android/app/src/play/java/com/doublegate/rustynes/MonetizationGate.kt
- android/app/src/play/java/com/doublegate/rustynes/Billing.kt
- crates/rustynes-monetization/shells/android/RustyNesApp.kt
- android/app/src/foss/java/com/doublegate/rustynes/MonetizationGate.kt
- crates/rustynes-monetization/shells/ios/RewardedGate.swift
- docs/monetization/build-and-bindings.md
- android/app/src/play/res/values-es/strings.xml
- android/app/src/foss/java/com/doublegate/rustynes/Billing.kt
- crates/rustynes-monetization/src/lib.rs
- crates/rustynes-monetization/shells/android/AdGate.kt
- android/app/src/play/java/com/doublegate/rustynes/monetization/RewardedGate.kt
- crates/rustynes-monetization/shells/android/Billing.kt
- android/app/src/main/res/values/strings.xml
- crates/rustynes-monetization/shells/ios/Billing.swift
- android/app/src/play/res/values/strings.xml
- crates/rustynes-monetization/shells/ios/RustyNesApp.swift
- android/app/src/play/java/com/doublegate/rustynes/monetization/AdGate.kt
- crates/rustynes-monetization/src/monetization.rs
- docs/architecture.md: workspace crate count 16 -> 15 (monetization crate removed). - AGENTS.md: drop the now-stale "(the prior release)" tag on v2.2.2 "Conduit" (v2.2.5 "Colophon" is the prior release now that v2.2.6 is current). - docs/STATUS.md: the freed v2.3.0 slot is the accuracy capstone, not a store launch; a free store listing is a later, unversioned step (retire the stale v2.1.0/v2.2.0/v2.3.0 joint-store-launch targets). - to-dos/DEFERRED-AND-CARRYOVER-FEATURES.md: replace the fixed v2.0.1-v2.0.4 store-launch target with a no-fixed-timeline free-listing note (ADR 0035). - Cargo.lock: regenerate the workspace crate versions 2.2.5 -> 2.2.6 to match the Cargo.toml bump (the v2.2.6 commit bumped the manifest but not the lock). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… current-release) - docs/android.md: scope the no-network/no-collection privacy claim to the `foss` build; note the `play` build's optional free Google Play services use network + Google-account data (no ads/tracking/billing). - to-dos/ROADMAP.md: the Status section's current-release is now v2.2.6 "Almanac" (single active release line); the v2.2.4 "Cartridge" libretro-cut detail is retained as historical, with docs/STATUS.md + CHANGELOG.md as the source of truth. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Antigravity review (Gemini via Ultra)Error: timeout waiting for response Automated first-pass review by |
v2.2.6 "Almanac" — de-monetization + provenance accuracy
RustyNES is now permanently open-source and income-free, forever (ADR 0035). All
planned monetization is removed, and the native Android/iOS apps are kept as free FOSS
apps — no ads, no tracking, no paid unlock, every feature available. This opens the
v2.2.6 → v2.3.0 line addressing the NESdev-forum feedback (audio, video/gamma,
TAS/UX, and a PPU left-edge + hybrid-address accuracy capstone).
Zero emulation-core behavior change
No crate under the deterministic
#![no_std]chip stack depended on the removedmonetization crate, so the core, save-state / TAS / netplay formats, and every golden
vector are byte-identical. AccuracyCoin holds 141/141 (100.00%) and nestest is
0-diff by construction.
Removed
rustynes-monetizationcrate (AdPolicy / freemium policy core + UniFFI bindgen +android/ios reference shells) and
docs/monetization/(the 8-file freemium design +compliance set); the workspace member is dropped and
Cargo.lockregenerated clean.LicenseManager), the AppLovin MAX / RevenueCatMonetizationGate+ ad gates, the demo/paywall/unlock UI + strings, the AdMob/AppLovinmanifest entries, the billing/ad Gradle deps + BuildConfig keys + AppLovin Maven repo,
and the monetization cargo/uniffi tasks.
MainActivityno longer threads anunlockedflag or gates any feature behind an unlock/demo.
StoreManager(Entitlements.swift), theappStorebuild channel, and the StoreKit/Entitlements
project.ymllinkage.Kept (free, non-monetization)
foss/playAndroid flavor split, now distinguishing only the pure-AOSP buildfrom the build carrying the free Google-Play services (Play Games achievements,
Cast, Integrity, in-app update, cloud save). All
PgsIdsachievement unlocks remain.Nightly Rust is now used only by
cargo fuzz.Provenance accuracy (ADR 0035 + ADR 0030)
NOTICEanddocs/originality-and-provenance.mdnow disclose honestly that the PPUoctal-latch / hybrid-address timing was calibrated to TriCNES's per-dot behavior
(beyond black-box oracle use), which reproduces a TriCNES-specific artifact that
mis-renders mid-render
$2006writes (e.g. Rad Racer). No TriCNES code isincorporated (MIT regardless); the issue is behavioral fidelity, and the fix is to make
the behavior documentation-derived in v2.3.0 "Datum II".
ADRs
flavor / ATT / StoreKit-unlock; keeps the §4.7 ROM-compliance rules — valid for a free
app).
Checks run
cargo check --workspace✅ ·cargo fmt --all --check✅ · markdownlint (pinnedv0.39.0) ✅ · version consistency (Cargo.toml / README badge / CHANGELOG) ✅ · no
CI/config/code references to the removed crate · no dangling mkdocs nav / doc links.
LicenseManager/MonetizationGate/StoreManagerreferences) but were notcompile-built in this environment — a local
assembleFossDebug/ Xcode build is theon-device confirmation step.
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation