Documentation index for the watch face generator. The app has no default face:
it ships styles, and people name what they make. See
../DECISIONS.md 2026-08-26 and 2026-08-27 for why that
distinction is load-bearing.
SPEC.md — architecture and the constraints you cannot relax../CLAUDE.md — ground rules, commands, current state of play./gradlew :workbench:workbench and open http://localhost:7777Almost all design work happens in the workbench. You do not need an Android SDK, an emulator, or a watch to change geometry, colour, layout or ambient behaviour.
SPEC.md § Build order — step one gates everything after itSPEC.md § Watch Face Push — the packaging rules that reject an APKscripts/setup-emulators.sh, then scripts/deploy.sh../DECISIONS.md — dated, with the reasoning and what was
rejected. Read it before proposing a change to the file format, the build, or
the renderer; several obvious-looking improvements are recorded there as already
tried and rejected for reasons that are not visible from the code.
docs/
├── README.md # this index
└── SPEC.md # architecture, constraints, build order
../CLAUDE.md # AI entry point: rules, commands, state of play
../DECISIONS.md # dated decision record (see note below)
../README.md # human entry point: quick start
../CONTRIBUTING.md # contribution guide
This repo keeps decisions in a single dated ../DECISIONS.md
rather than the docs/architecture/adr/ADR-XXX-*.md layout the fleet doc
standard recommends. That is a deliberate deviation for a repo this size: the
decisions are tightly coupled to one another and read better as a single
narrative than as numbered files. If this repo grows a second major subsystem,
splitting into ADRs is the right move.
| Command | What |
|---|---|
scripts/bootstrap.sh |
Fetch WFF schemas, XSD 1.1 jars, Gradle wrapper |
./gradlew :generator:test |
Engines, params, WFF emission |
./gradlew :workbench:test |
Rasterizer, quantizer, ambient budget, face store |
./gradlew :workbench:workbench |
The app at http://localhost:7777 |
./gradlew :workbench:bake |
Generate dial_bg.png, preview.png, watchface.xml |
cd watchface-template && ./build.sh |
Validate, build and sign the APK |
make docs-check |
markdownlint + cspell over the docs |
| Constraint | Consequence if ignored |
|---|---|
Colours are #AARRGGBB, alpha first |
Six-digit values are silently wrong, not rejected |
| Canvas is 456×456 | Wrong geometry on Pixel Watch 4 and 5 |
Ambient is per-element <Variant> |
A second scene is not how WFF does it |
| APK may contain only four path families | Watch Face Push rejects the package |
| Schema validity is not checked at runtime | Face installs, then never appears in the carousel |
| Never change engine geometry in place | Every stored community face silently re-renders |
The last two are the expensive ones. Both fail silently.
| Module | Depends on | Ships to a device |
|---|---|---|
generator/ |
nothing | via mobile/ |
workbench/ |
generator/ |
no — dev tooling |
mobile/, wear/ |
generator/ |
yes (scaffolds only today) |
generator/ is deliberately dependency-free: it is the definition of the stored
file format, so nothing may make it harder to test on a plain JVM.