React web app → Expo mobile app
Port the app. Prove every screen.
Wemora rewrites a React single-page app as an Expo app, one screen at a time. A screen gets into the app only after the tests written against the web original pass on the phone build, unchanged.
Lista za kupovinu
| Kupljeno | Namirnica |
|---|---|
| ☐ | Hleb |
- goto /kupovinaweb ✓app ✓
- fill "Namirnica" = "Hleb"✓✓
- tap button "Dodaj"✓✓
- expect "Kupljeno: 0 od 1"✓✓
- expectNot "…je prazna"✓✓
Lista za kupovinu
Layout is free to change: the sidebar becomes a bottom bar and the table becomes a card. Field labels, button names and visible text stay the same, so the web test finds everything on the phone.
A real run
The same steps on the original and on the app Wemora built.
TodoMVC, recorded in a browser. Three todos are added with Enter, one is completed, the filters switch and completed todos are cleared, using the same field label, link names and button text on both.
From npm run migrate:mock -- examples/todomvc: builder answers are recorded, while the Gatekeeper, the tests and the app are real. todo-list: proven in round 2, 5 of 5 tests on the phone build. Fonts, sizes and colors come from the web CSS through the shared theme.
How a run works
Agents write the code. Tests decide what stays.
Each step is a Mozaik participant. Agents get a fresh context per task, events carry only IDs, and the shared board holds the plan, tests and results.
Analyze
Parse routes, imports and web-only APIs, then describe every screen with its exact texts.
analyzer · haiku-4-5Plan
Split the app into screens and shared units, with obligations each screen must still meet.
architect · sonnet-4-6Scaffold
Create an empty Expo app with one route per screen and blank placeholder screens.
scaffoldTest
Write scenarios on the original. A test is kept only if it passes there and fails on the blank screen.
tester · haiku-4-5Build
Rewrite each screen in React Native, in its own staging folder. Builders never see the tests.
builder · haiku-4-5 → sonnet-4-6Gatekeeper
Check every draft, promote it into the app, and roll it back if an older screen breaks.
deterministic · no model
The Gatekeeper
Five gates, in order. The first failure goes back to the builder.
Every message names the file, the line and what is missing, so the next round fixes that one thing instead of starting over.
- 1parseThe draft is valid TypeScript. One syntax error would take down every screen.
- 2forbiddenApisNo
div,window,localStorageorreact-router-dom, with the React Native replacement for each. - 3tscThe draft type-checks against the rest of the app.
- 4labelsEvery label and button name the tests use is in the code, copied from the original.
- 5scenariosThe tests pass on the phone build, then the tests of every promoted screen run again.
builder-1 draft.submitted todo-list round 1 gatekeeper gate.failed todo-list round 1 forbiddenApis screens/todo-list/index.tsx:19: <div> ne postoji u React Native, koristi <View>.conductor same builder, round 2, with the message above builder-1 draft.submitted todo-list round 2 gatekeeper parse ✓ forbiddenApis ✓ tsc ✓ labels ✓ gatekeeper scenarios ✓ 5/5 at 390×844 gatekeeper unit.promoted todo-list status proven
From a TodoMVC run. Gate messages are written for the builder; the team wrote them in Serbian.
What the report claims
Every screen gets one of four statuses.
All tests pass on the phone, every obligation is covered, and every interactive element is tested or marked as not portable.
All existing tests pass, but some obligation or element has no test yet. The report lists which.
The screen is in the app, but no validated test exists for it.
Tests exist and the screen still fails them after its last round.
A screen with zero tests is never proven.
Check it yourself
Rerun the proof without a model or an API key.
The whole flow with recorded model answers. Costs $0.
Runs every saved test against the finished app again. Same result every time.
Breaks one screen on purpose, so you can watch verify catch it.
Built on Mozaik
Many small agents, one shared board.
Builders write only to their staging folder. An OwnershipGuard intercepts every write outside it before it happens.
Only the Gatekeeper writes to the app. Promotion is a copy, and rollback restores the exact previous files.
One loop per agent, fresh context per task. Parallel work comes from more builders and testers, scaled to the size of the app.
Events carry IDs. Plans, tests and results live on the board and on disk, so every run can be replayed and reported.
Team
Four people, four layers.
Luka Javorić
Contracts, runtime and the Conductor that hands out work and scales the team.
Nebojša Vujić
The test language, the tester agent, verify and sabotage.
Milica Antić
The Expo template, scaffold, the builder agent and the Gatekeeper.
Milomir Kuzmić
App analysis, the architect agent and the report.