mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-09 08:04:45 +00:00
docs(napplets): document the two-process model for future contributors/AIs
Add a heads-up to the Amethyst Application KDoc and .claude/CLAUDE.md that the app runs in two OS processes (main + :napplet), that Android reuses the single Application class in both, and that statics/objects (Amethyst.instance, LocalCache, NappletLaunchRegistry) are per-process — so code must not assume `instance` exists off the main process or share singletons across the boundary. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016ncMHuBBVHEf7spAoSssde
This commit is contained in:
@@ -84,6 +84,32 @@ amethyst/
|
||||
module's `plans/YYYY-MM-DD-<slug>.md` (e.g. `cli/plans/`, `commons/plans/`).
|
||||
The global `docs/plans/` folder is frozen — don't add new plans there.
|
||||
|
||||
## Android Runtime Processes (IMPORTANT — the app runs in TWO processes)
|
||||
|
||||
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`, declared `android:process=":napplet"`). It holds **no**
|
||||
account or keys; `Amethyst.onCreate()` early-returns here so `Amethyst.instance`
|
||||
is **left unset** (touching it throws `UninitializedPropertyAccessException`).
|
||||
|
||||
Consequences — don't get caught assuming one process:
|
||||
|
||||
- **Processes don't share memory.** Every `object`/companion/`static` is a
|
||||
*separate copy per process*: `LocalCache` (an `object`), `NappletLaunchRegistry`,
|
||||
etc. The populated `LocalCache` lives 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.instance` exists.** Any code reachable from `:napplet`
|
||||
(the host activity, content server, or an Application lifecycle callback like
|
||||
`onTrimMemory`) must guard on the process and never reach for `instance`.
|
||||
- **Cross-process state goes over Messenger IPC**, never a shared singleton — this
|
||||
is why the broker (main) owns `NappletLaunchRegistry` and the sandbox only relays
|
||||
an opaque token. See `amethyst/plans/2026-06-22-napplet-nsite-security.md`.
|
||||
|
||||
## Tech Stack
|
||||
|
||||
Exact versions live in `gradle/libs.versions.toml` (the source of truth — check
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user