Kgothatso Ngako 42dd38cfc4 test: pin the two invariants this session left unguarded
Both are silent when broken, which is why they are worth asserting rather
than reasoning about.

**The cache's reuse decision.** MlsGroupCache exists because quartz drops
a secret tree's skipped-generation keys on save, so rebuilding a group
between two messages loses any that arrives late. Its safety argument is
one comparison: reuse while the stored state is still what the cache last
wrote, rebuild when it is not. Get that wrong in either direction and
nothing complains -- reuse too eagerly and a group carries on from a
ratchet another writer already moved, which corrupts decryption rather
than failing it; reuse too rarely and the cache does nothing and the
original bug is back with no symptom.

That decision is now a generic LiveInstanceCache with MlsGroupCache as a
typed facade over it, so it can be tested without standing up an MLS
group. Splitting it also made two behaviours explicit that were previously
incidental: a failed build no longer leaves the old instance behind, and
an instance whose use threw is deliberately not cached -- it is
half-advanced and never persisted, so the next caller has to start from
disk.

**Rumor and row ids agreeing.** MantraDao writes an entity whose id comes
from fromXEventTemplate and separately builds the rumor it submits with
rumorOf, which hashes the template itself. Both are meant to produce one
id and nothing checked it. Diverging would mean submissions naming an
event nobody has, deleteByPayloadEventId silently un-queuing nothing so
superseded translations go out anyway, and every receiver creating a
second row instead of converging on the sender's -- all of it invisible,
since the ids are opaque hex either way. Asserted per kind, plus the whole
chain out through the submission envelope.

Both suites were mutation-checked rather than trusted: inverting the
staleness comparison fails one cache test, recording the pre-block state
fails another, and hashing the rumor under a different author fails all
six id tests.

Still uncovered, and not cheaply fixable: FrostSigningManager's and
MantraDao's state machines both need a Room harness, and commonTest has
none. The FROST crypto path is covered by FrostSigningRoundTest; the
message-driven parts around it are not.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 23:18:54 +02:00
2026-07-05 23:21:02 +02:00
2026-07-28 09:10:20 +02:00
2026-03-24 04:47:19 +02:00
2026-03-23 01:41:39 +02:00
2026-03-23 01:41:39 +02:00
2026-03-23 01:41:39 +02:00

This is a Kotlin Multiplatform project targeting Android, iOS, Desktop (JVM).

  • /composeApp is for code that will be shared across your Compose Multiplatform applications. It contains several subfolders:

    • commonMain is for code thats common for all targets.
    • Other folders are for Kotlin code that will be compiled for only the platform indicated in the folder name. For example, if you want to use Apples CoreCrypto for the iOS part of your Kotlin app, the iosMain folder would be the right place for such calls. Similarly, if you want to edit the Desktop (JVM) specific part, the jvmMain folder is the appropriate location.
  • /iosApp contains iOS applications. Even if youre sharing your UI with Compose Multiplatform, you need this entry point for your iOS app. This is also where you should add SwiftUI code for your project.

Build and Run Android Application

To build and run the development version of the Android app, use the run configuration from the run widget in your IDEs toolbar or build it directly from the terminal:

  • on macOS/Linux
    ./gradlew :composeApp:assembleDebug
    
  • on Windows
    .\gradlew.bat :composeApp:assembleDebug
    

Build and Run Desktop (JVM) Application

To build and run the development version of the desktop app, use the run configuration from the run widget in your IDEs toolbar or run it directly from the terminal:

  • on macOS/Linux
    ./gradlew :composeApp:run
    
  • on Windows
    .\gradlew.bat :composeApp:run
    

Build and Run iOS Application

To build and run the development version of the iOS app, use the run configuration from the run widget in your IDEs toolbar or open the /iosApp directory in Xcode and run it from there.


Learn more about Kotlin Multiplatform

Description
Mantra as a kotlin multiplatform project
https://mantra.press
Readme 8.2 MiB
Languages
Kotlin 100%