app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit 1b9433aa57e0357d684def3721257e9375e0e38e
parent e838b07de442113040a0c11a224b34cdf26cf9d7
Author: triesap <tyson@radroots.org>
Date:   Sun,  2 Aug 2026 20:35:50 +0000

review: reconcile final Nostr runtime acceptance

- map every approved acceptance criterion to implemented evidence
- record final Rust Kotlin FFI loader and package validation
- document skipped interactive keyring and cross-platform checks honestly
- close all twelve RCLDs with no remaining implementation checkpoint

Diffstat:
Mdocs/implementation/nostr-runtime-rcld.md | 18+++++++++---------
Adocs/testing/final-validation-ledger.md | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 89 insertions(+), 9 deletions(-)

diff --git a/docs/implementation/nostr-runtime-rcld.md b/docs/implementation/nostr-runtime-rcld.md @@ -2,7 +2,7 @@ ## Status -- Program status: in progress. +- Program status: completed. - Active RCLD: none. - Active atomic checkpoint: none. - Repository: `oss/studio_app` standalone Git repository. @@ -128,9 +128,9 @@ RCLDs. Do not modify the parent repository or the legacy `/studio_app` tree. cleared on acknowledgement, replacement, or application disposal. - Copying generated nsec is explicit. Clear the clipboard after 60 seconds only when it still contains the copied value. -- Imported key text is masked, submitted once, and cleared immediately after - the FFI call. The JVM limitation is documented and tested as far as the - platform permits. +- Imported key text is masked, submitted once, and cleared as soon as the + command is accepted, before coroutine or native execution. The JVM + limitation is documented and tested as far as the platform permits. ### Persistence and recovery @@ -430,7 +430,7 @@ Compose tests, native-loader smoke, and repeated runs for async determinism. ### RCLD-12: Documentation and acceptance reconciliation -Status: pending. +Status: completed. Scope: checkpoints 60 through 63. Complete dependency/license, architecture, security, testing, local-relay, FFI lifecycle, recovery, and platform validation @@ -450,7 +450,7 @@ forbidden-path and forbidden-term guards, Git status, and full diff audit. ## Atomic checkpoint ledger -All checkpoints are pending. Their order and titles are inherited from the +All checkpoints are complete. Their order and titles are inherited from the handoff commit sequence. ### RCLD-01 @@ -553,9 +553,9 @@ handoff commit sequence. - [x] 61. Complete architecture, security, testing, and runbook documentation. - [x] 62. Add Makefile-governed final validation tasks and platform ledger. Do not add `.github/**` or `scripts/**`. -- [ ] 63. Perform final source audit and acceptance reconciliation. +- [x] 63. Perform final source audit and acceptance reconciliation. -## Unfinished RCLD ledger +## RCLD completion ledger - [x] RCLD-01: Authority and dependency baseline. - [x] RCLD-02: Rust workspace and domain. @@ -568,4 +568,4 @@ handoff commit sequence. - [x] RCLD-09: UniFFI and native build integration. - [x] RCLD-10: Thin Kotlin shell and minimal UI. - [x] RCLD-11: End-to-end integration hardening. -- [ ] RCLD-12: Documentation and acceptance reconciliation. +- [x] RCLD-12: Documentation and acceptance reconciliation. diff --git a/docs/testing/final-validation-ledger.md b/docs/testing/final-validation-ledger.md @@ -0,0 +1,80 @@ +# Final validation ledger + +## Result + +Validation completed on 2026-08-02 for macOS 26.5 arm64. All 30 acceptance +criteria in the authoritative handoff are satisfied by implemented source, +tests, or an explicit documented platform-validation contract. No test uses a +public relay. + +## Acceptance reconciliation + +| # | Result | Evidence | +| --- | --- | --- | +| 1 | Pass | `core/Cargo.toml` defines the Rust workspace and all five runtime crates build together. | +| 2 | Pass | `radroots-studio-application::AppCore` owns canonical snapshots, transitions, commands, observers, sessions, recovery, and refresh orchestration. | +| 3 | Pass | `StudioAppStore` maps generated UniFFI DTOs into presentation models and forwards commands without duplicating the reducer or persistence policy. | +| 4 | Pass | Domain, persistence, FFI, and Kotlin models use canonical lowercase 64-character Nostr public-key hex; forbidden UUID guards are clean. | +| 5 | Pass | The generate command, UniFFI method, Compose control, and behavior tests create a persisted local Nostr key. | +| 6 | Pass | Masked nsec/hex import is implemented through the Rust key boundary and covered by valid, invalid, duplicate, and repair tests. | +| 7 | Pass | Storage and Compose tests cover multiple saved accounts; the chooser remains scrollable within the available window. | +| 8 | Pass | Activation is available for each saved account and Rust tests prove safe session replacement. | +| 9 | Pass | Sign-out drops the active signer/session while retaining metadata, selection, and credential. | +| 10 | Pass | Removal uses a single-use target-and-revision-bound confirmation token, deterministic fallback, and recovery journal. | +| 11 | Pass | Production wiring uses `OsKeyringSecretStore` with service `org.radroots.studio.nostr` and no file fallback. | +| 12 | Pass | Redaction, schema-byte, DTO, snapshot, error, journal, and source guards keep secrets out of forbidden surfaces. | +| 13 | Pass | Generated nsec exists only in `GenerateAccountReceipt` and the transient backup UI; acknowledgement, replacement, timeout, and disposal clear it. | +| 14 | Pass | SQLite restart tests restore account metadata and selection while startup remains signed out. | +| 15 | Pass | Typed repository and restart-isolation tests prove account-local values are partitioned by owner pubkey. | +| 16 | Pass | Production relay configuration is read from `RADROOTS_NOSTR_RELAYS`. | +| 17 | Pass | Development mode alone defaults to `ws://localhost:8080`. | +| 18 | Pass | Relay parsing accepts governed WebSocket URLs only; generic account-server terms and fields are absent. | +| 19 | Pass | Activation emits cached profile state before verified kind-0 refresh; failure and stale completion preserve safe state. | +| 20 | Pass | The active screen renders `radroots`, pubkey, npub, bounded profile metadata, relay list, and profile/relay status. | +| 21 | Pass | Source guards find no generic server URL field or onboarding language. | +| 22 | Pass | The previous Kotlin `AccountsReducer` and `AccountsStore` are absent; `StudioAppStore` is an FFI adapter only. | +| 23 | Pass | `make check` passed Rust, FFI, storage, security, restart, local-relay, Kotlin-store, native-loader, and Compose UI lanes. | +| 24 | Pass | The RCLD history contains ordered, independently verified commit-sized checkpoints plus separately committed audit fixes. | +| 25 | Pass | Source, tests, generated-boundary policy, package contents, forbidden terms, and all handoff criteria were audited at checkpoint 63. | +| 26 | Pass | The command ledger below distinguishes executed checks from intentionally skipped interactive, destructive, or foreign-platform checks. | +| 27 | Pass | `docs/architecture/reference-research.md` records reviewed revisions, paths, adopted/rejected patterns, license boundaries, and dependency decisions. | +| 28 | Pass | Required ADR, architecture, security, testing, and local-relay runbook documentation exists and matches the runtime. | +| 29 | Pass | `docs/testing/platform-validation.md` defines the current-host evidence and the required Linux/Windows loader, keyring, and packaging matrix. | +| 30 | Pass | Network tests use an ephemeral loopback relay; configuration tests do not contact the network. | + +## Commands executed + +| Command | Result | +| --- | --- | +| `make check` | Passed Rust formatting, all-target Clippy with denied warnings, all workspace tests, desktop tests, and Gradle check. | +| `make build` | Passed the Rust workspace and Compose Desktop build. | +| `make bindings` | Passed UniFFI Kotlin generation and current-host native-library staging. | +| `make package` | Produced `app/desktop/build/compose/binaries/main/dmg/Radroots-1.0.0.dmg`. | +| `codesign --verify --deep --strict .../Radroots.app` | Passed. | +| `PlistBuddy` bundle inspection | Confirmed bundle ID `org.radroots.studio` and installer version `1.0.0`. | +| Packaged application JAR inspection | Confirmed `darwin-aarch64/libradroots_studio_ffi.dylib`, `icons/radroots.icns`, and `icons/radroots.png`. | +| Tracked-path guards | Found no build output, generated UniFFI source, native binary, `.github/**`, or `scripts/**` path. | +| Forbidden-term guards | Found no old package/version, UUID account, Kotlin reducer/store, generic account-server, or server-URL term. | +| Nested-repository status and history inspection | Confirmed the standalone capsule boundary and local commit sequence. | + +`make check` executed 35 application tests plus its redaction test, 21 domain +tests, 6 FFI tests, 6 Nostr tests, 19 passing storage unit tests, three storage +integration tests, the bindgen test, all documentation tests, and the complete +Kotlin/Compose test task. The one ignored storage test is the intentionally +opt-in real operating-system keyring smoke. + +## Intentionally not executed + +- The real OS keyring smoke was not enabled because it mutates the current + user's credential store. Its adapter contract tests passed. +- Linux and Windows loader, keyring, and packaging checks cannot run on this + macOS host. Their required native-host matrix is recorded in + `platform-validation.md`. +- `make dev` and `make run` are interactive launchers and were not held open. +- `make clean` was not run because it only destroys recoverable build output + and is not an acceptance behavior. + +The application/runtime artifacts retain version `0.1.0-alpha`. The macOS +installer uses `1.0.0` because `jpackage` rejects the prerelease form; this +mapping is deliberate and documented. No source-level acceptance blocker +remains.