Phase 9 of docs/subgroups.md. Most of the plan's test work landed with the phase it guarded -- 13 pure cases in Phase 1, 10 more in Phase 3, 21 over a real database in Phases 2, 5 and 8. What was left is the one thing none of them can reach. `GroupKeyStateTest` settles Phase 3's rules purely and exhaustively, and `SubgroupDaoJvmTest` settles that schema 17 holds four columns. Neither can settle the **join**: that a parentage put on a proposal survives a real signing session, a real FROST aggregate and a real `record`, and lands on the *row* on every device rather than only in the event. That is a schema question wearing a protocol question's clothes, and it is exactly the sort of thing that breaks without failing -- `record` could drop both fields and every existing test would still pass. Three cases on the existing two-device harness in `SignedGroupKeyStateTest`, which already runs a whole session across two databases with nothing shared but what is ferried: - a quorum signing a subgroup's state puts the parent and the whole certificate on both devices, neither of which was sent a row -- each derived the event from its own items, re-ran `certifies` against the parent's id, and wrote the same two columns; - a real certificate really signed by the parent but naming another room is refused by `propose` before anything is published, and neither device ends up with a state; - a state signed with no parentage keeps both columns null, which is how every group made before subgroups reads and every top-level group made after. The parent is a second `KeyMaterial` and its signature is a real FROST aggregate assembled by hand. Standing up three more databases to get one would have tested the harness rather than the join. 397 common tests, 708 jvm tests, `m3Audit` meets every budget. All nine phases of docs/subgroups.md are built. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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 that’s 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 Apple’s 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 you’re 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 IDE’s 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 IDE’s 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 IDE’s toolbar or open the /iosApp directory in Xcode and run it from there.
Learn more about Kotlin Multiplatform…