Kgothatso Ngako 2089fdf8f0 test: cover the ceremony a robust room is created with
0c240a3 made a claim about a room's first message and de3b355 made one about
its second ceremony, and neither is visible from any of the pieces already
under test. ChillDkgRitualOrderingTest runs the ChillDKG calls, DkgSession-
DaoJvmTest pins the state a ritual resumes from, NostrNip17DaoJvmTest covers
the room. What none of them can see is a room and a ceremony together: that
the room is empty until the ceremony, and that the ceremony is what fills it.

This runs the real thing against a real database. Room's in-memory builder,
the host's bundled SQLite, actual secp256k1 -- the room id is derived by
doing point work over the member set, and each member's ChillDKG host key is
derived from their nostr secret, so the keys are real KeyPairs rather than
hex filler. Nothing is stubbed; createNip17ChatRoom and proposeRitual are
called exactly as the view model calls them.

jvmTest rather than commonTest because it needs a database. jvmTest goes
333 -> 336; commonTest is unchanged at 217.

## What is pinned

  - A robust room has no chat messages and nothing queued until the ceremony
    opens, and the first line in it afterwards is TYPE_DKG_STARTED. That is
    the whole of "the ceremony is the room's first message", stated as the
    before and the after rather than as a count.
  - The first event out is the 30310 proposal, authored by the creator.
  - It carries the whole membership. Receivers derive `n` from the p-tags
    plus the sender rather than from their own view of the room, so this is
    the claim that decides whether three devices can agree on one ceremony.
  - It carries the quorum that was picked, and the session id it opens.
  - The session runs at that quorum, over three participants, coordinated by
    the room's creator.
  - The creator's host key is already out, and hostKeyApprovedAt is set:
    opening a ceremony is the act of agreeing to be in it, so the member who
    opened it is not asked again.
  - Creating the same group twice returns the same room and the same
    ceremony -- asked for a different quorum the second time, and answered
    with the running one. One proposal on the wire, one line in the chat.
  - A FAILED ceremony is replaced rather than handed back, and the group
    proposes again.

## Checked against a mutation, not just run

The re-entry test is the one that could pass for the wrong reason, so the
guard it covers was deliberately broken -- `takeIf { false }`, which is
de3b355 reverted -- and it failed on its own while the other two passed.

Ordering is read off the autoincrement id rather than createdAt. Both chat
rows are written inside one proposeRitual call and can land on the same
timestamp, which would make an ORDER BY createdAt assertion pass or fail on
timing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-06 04:09:06 +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%