mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-30 07:37:38 +00:00
- Leaving uses MarmotManager.leave in the app and amy: the heir is chosen among the members (a listed admin who already left no longer counts), the last member of a group can leave (it used to throw), and amy no longer publishes the step-down commit a second time. - The member menu and revokeMarmotGroupAdmin use MarmotGroupPermissions, so demotion is checked against the members rather than the list's length. - The feed asks MarmotAppEvent.isTimelineRow and the edit overlay asks MarmotMessageEdit instead of keeping their own copies of those rules. - The media policy is built with EncryptedMediaPolicyV2.forBlossom, so amy's set-policy accepts a base URL without a trailing slash too. - Group creation moves from CreateGroupScreen into BaseAccountViewModel.createMarmotGroup, and drops the profile commit that repeated the name already set at epoch 0. - Removed: the unused commons viewmodels.MarmotGroupFeedViewModel and the MIP-04 send path nothing reached. - cordn: the exposure card and amy stop calling the deprecated differsFromMarmot; CordnRuntimeTest moves to commons/src/jvmTest. - AGENTS.md keeps a short version of the two-process rules; the detail moves to android-expert's references (31.6 KB of Codex's 32 KB). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BSSNWvwXdNnNwYnLoEvNcq
1.9 KiB
1.9 KiB
The two Android processes
Moved from AGENTS.md, which keeps the short version.
The Android app is not single-process. Android instantiates the one Amethyst
Application class (there is no per-process Application in the manifest) in both:
- main — the normal app: UI, account, signer,
LocalCache, relay client.Amethyst.instance(AppModules) is built here. :napplet— the sandboxed WebView host for NIP-5D napplets / NIP-5A nSites (NappletHostActivity, declaredandroid:process=":napplet"). It holds no account or keys;Amethyst.onCreate()early-returns here soAmethyst.instanceis left unset (touching it throwsUninitializedPropertyAccessException). The sandbox runtime lives in its own module:nappletHost(depends on:commons,:commonsUI— the shell's web contract and Compose resources — and quartz; never:amethyst) so it cannot importAmethyst/LocalCache/Account— the broker-side (signer, gateways, registry) stays in:amethystand the two halves talk over Messenger IPC.
Consequences — don't get caught assuming one process:
- Processes don't share memory. Every
object/companion/staticis a separate copy per process:LocalCache(anobject),NappletLaunchRegistry, etc. The populatedLocalCachelives only in main; the sandbox neither builds nor should reference it (a stray reference would lazily create a second, empty cache there). - Don't assume
Amethyst.instanceexists. Any code reachable from:napplet(the host activity, content server, or an Application lifecycle callback likeonTrimMemory) must guard on the process and never reach forinstance. - Cross-process state goes over Messenger IPC, never a shared singleton — this
is why the broker (main) owns
NappletLaunchRegistryand the sandbox only relays an opaque token. Seeamethyst/plans/archive/2026-06-22-napplet-nsite-security.md.