Kgothatso Ngako b10c79f9ed feat(subgroups): the refusals that are about capability, not preference
Phase 8 of docs/subgroups.md. Four of the seven refusals landed with the code
they guard; these are the three that did not, and two of them are about what this
device *can* do rather than what the user should pick.

**No share of the parent's key.** `FrostSigningManager.proposeSigningBatch` throws
outright for a device with no share, so without this the button crashes rather
than declines. It is checked first because it is the one refusal a user cannot fix
by picking differently -- every other message says "pick differently" and this one
cannot.

**Not an admin of the parent.** A non-admin proposing the group's signature is a
proposal the admins have to decline by hand, which is worse than not offering it.
Read off `Participant.adminAt`, which is the epoch-0 admin list MIP-01 carries and
the same reading every side of the group makes.

Both are checked in `refuseCeremonyRoom` as well as at the button that hides
itself on `canAddSubgroup`, because a screen not drawing something is not a guard
-- and a resumed flow reaches the manager without passing that screen at all.

**A child already certified.** One certificate per child: a second is a `d`-tag
replacement of the first rather than a second subgroup, and spending a quorum's
attention to restate something they have already signed is worse than doing
nothing. This is a `check` at propose time rather than a picker refusal, since the
child's id does not exist until the ceremony finishes.

It deliberately does not try to stop the race. Two coordinators can each propose a
certificate for the same child, neither able to see the other's session before it
completes; `certificateFor` folds those together because both say the same true
thing. This only stops the case somebody can actually see.

The blank-name `require` gets a test of its own for the same reason the name
exists at all: without it the parent's admins would be approving a hash.

Six tests in `SubgroupManagerJvmTest`, and the fixture had to grow to carry them.
`parentWith` now gives the parent a completed ceremony and marks the coordinator
an admin, with both switchable, because a fixture missing either tests only the
first refusal -- which is how the two new checks were found to short-circuit the
existing cases the moment they were added.

The plan called for a pure `SubgroupGuardsTest` in commonTest. It is not one:
every refusal here reads the database -- a key-holding session, an admin flag, a
ceremony in the derived room -- so the tests live in jvmTest beside the manager's
others rather than being reshaped into something pure that would test less.

397 common tests, 705 jvm tests, `m3Audit` meets every budget.

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