Current state of the project in a few lines. Update it when a milestone moves, a decision is taken or something is blocked; prune anything that is no longer current. This is a snapshot, not a changelog — git history is the changelog.
Last updated: 2026-09-13
docs/TODO.md are done and Step
3 is nearly done: a formula can now be parsed, planned, thrown as real dice,
read off their faces and pinned against a recorded outcome, end to end. What
is left of Step 3 needs a screen to land on, which is Step 4.1 — now in
progress — plus the shake on real hardware and the smaller items listed
there.v0.0.1 — the skeleton, cut mainly to prove the release
pipeline. Signed, fingerprint-checked, published with its SHA-256.main is
green. Step 4.1, the roll screen, is what is being built now.README.md, docs/ and the clickable prototype in
design/, cross-referenced in both directions and published at
https://drehtuer.github.io/dInfinityApp/. GPL-2.0-or-later.docs/architecture.md describes, the Compose theme from the Modernist
tokens, the navigation graph for all ten screens, APK naming. Settings picks
the accent and DataStore remembers it — the one screen that exists.gradle.properties, so the half
SonarQube has no counter for is still enforced. Every dependency is pinned
by SHA-256. main requires its checks; a vX.Y.Z tag cuts a signed,
fingerprint-checked, immutable release.dinfinity-phone, which remembers where the phone was). The emulator is
API 36 on x86_64 and the phone API 37 on arm64-v8a, so between them they
cover the API the app targets and the ABI it ships. Step 5 has somewhere to
land, and a regression in the physics can be caught before the phone.core/notation), graphed exactly — checked against the
evaluator itself by rolling small formulas every possible way
(core/probability) — planned against the tray’s capacity rule, settled and
read face by face (simulation/api), watched by a renderer that cannot
touch it (render/headless), thrown by a shake that replays to itself
(input/shake) and written down in one transaction (core/stats, data).
A package from a stranger is validated rule by rule with a file:line
report (dicesets/format) and installed without leaving anything behind if
it fails (dicesets/install); the bundled dice go through that same
validator on every launch. Every catalogue solid carries its corners as well
as its face normals, from one construction — which is how two geometry bugs
were found.docs/architecture.md, decision 37), and now a working
bridge. Dice spawn on a staggered grid, are shaken by an inverse acceleration
rather than by a moving tray, settle, and are read off their faces. The
engine is native but every decision about a roll is Kotlin over an
interface (decision 40), so the rule that matters most — nothing touches a
die that has come to rest — is proved by JVM tests rather than sampled on a
phone. Built for arm64-v8a and x86_64 on every CI run.StrictMath first, so that
agreement rests on a guarantee rather than on two libms happening to match
(docs/architecture.md, decisions 43 and 44).docs/architecture.md,
decision 48). The tray now draws onto a real surface from its own thread, and
survives the surface going away and coming back without the roll noticing
(decision 49). The state behind the screen is built too: a typed formula
becomes a throw, a throw’s faces become a result, 500d6 is refused before a
body exists, and an exploding die is thrown again through the simulator
rather than decided. What is still missing before the phone can be shaken is
the composable that hands a surface over, and the screen to put it in.docs/ (designer
3D preview, picker remembering the last set per group) — see docs/TODO.md.x86_64, API 36) and the Pixel 10a (arm64-v8a, API 37), and
fails if either moves. What is still unproven is determinism across devices
of the same ABI and across time, which is the same suite run somewhere else.targetSdk. It answers “does this run”, not
“does this look right” — the phone remains the only answer to the second.