The Kraken demo-video pipeline had to patch App.kt to hardcode darkTheme = true before
building, then revert — a brittle, CI-unfriendly workaround. First-run TOS and PIN screens
also required blind xdotool coordinate clicks that break whenever the layout shifts.
Two missing seams:
DarkBlueGrayTheme defaulted to isSystemInDarkTheme() with no way to override it from
outside the process. Under bare Xvfb there is no desktop colour scheme, so the result was
always light.JvmOnboardingStore and JvmClientPinStore only accepted TOS / stored a PIN through the
interactive UI. There was no non-interactive path to seed them before the app opened.expect fun headlessThemeOverride(): Boolean? in composeApp/commonMain. The JVM
desktop actual reads KRILL_THEME env var or -Dkrill.theme system property (dark /
light; anything else returns null). Non-JVM platforms return null.App.kt now passes headlessThemeOverride() ?: isSystemInDarkTheme() to DarkBlueGrayTheme.bootstrapPin: String? to JvmClientPinStore (defaults to KRILL_CLUSTER_PIN env var
or -Dkrill.cluster.pin). When non-null and no token exists on disk, storePin() is called
at construction, deriving and persisting the bearer token.bootstrapAccepted: Boolean to JvmOnboardingStore (defaults to true when
KRILL_CLUSTER_PIN is set or KRILL_ACCEPT_TOS=1). When true and the marker file is
absent, markTosAccepted() is called at construction so subsequent launches work without
the env var.bootstrapPin, bootstrapAccepted) makes
the env-var path testable without actually setting process environment variables.JvmOnboardingStoreTest and JvmClientPinStoreTest cover both the bootstrap
path and the “bootstrap writes to disk so subsequent launches don’t need the env var” invariant.