Case study · First Week
A checklist that admits
what it does not know
An enrolment checklist for Vietnamese students, written by the cohort before them. Every task carries where its claim came from, and a school nobody has filled in yet renders as thin as it really is.
- TESTS
- SOURCE
- DEVICE QA
- DESIGN
- REPORT
Problem
A new student needs to know what to do and by when. The answers exist, but they are scattered across announcements, group chats and the memory of the cohort above — and those three sources do not carry the same weight.
So the product decision is about standing, not layout: a deadline the school published and a rumour from one senior must never render the same way, and where nobody knows, the screen has to say so rather than produce something plausible.
Implementation
Contract first
openapi.yaml carries 9 operations, each answering exactly one thing a screen does. An in-process mock implements it, so the UI is written against the contract rather than against a server.
Seeded, then frozen
271 real Vietnamese universities pulled once from a public API, normalised and committed. The public API is a seed, never a runtime dependency — the app makes no network calls.
Provenance in the type system
A task cannot be constructed without a trust level: official, community-confirmed, or one senior's tip. There is no code path that produces an unattributed claim.
The argument, on a real phone
Redmi Note 10 · release build · driven by hand



One checklist reads ten steps and seven real deadlines; the other reads four steps and none. The gap is the product working, not a fixture left half-filled — and the device pass caught a counting defect the green test suite had missed.
What was actually verified
The repository is public, so the test command reproduces for anyone who clones it. The one thing this project does not have is continuous integration — that row says so rather than being left out.
| Claim supported | Status | Evidence |
|---|---|---|
The whole application is public and clonable Flutter app, contract, fixtures, tooling and device evidence | VERIFIED | Open ↗ |
The offline suite passes at the current head of the repository flutter test --exclude-tags live at 3cba674 — 79 of 80 declared tests. The excluded one is tagged live and hits a real endpoint. Public, so it reproduces | VERIFIED | Open ↗ |
Rendered and driven by hand on an Android device Redmi Note 10, release build, 14 captured screens. The pass caught a defect the green test suite had missed | VERIFIED | Open ↗ |
The screen behaviour is written down as a contract first openapi.yaml — 9 operations, each answering one thing a screen does. The in-process mock implements it | VERIFIED | Open ↗ |
Data provenance is recorded rather than asserted 271 schools seeded from a public API; 160 have no region and the screen says so instead of guessing | VERIFIED | Open ↗ |
Continuous integration There is none. The repository has no GitHub Actions workflow — the gates run locally through tool/check.sh, and no hosted run backs them | UNAVAILABLE | Open ↗ |
Dependencies & limitations
Stated here rather than left for a client to discover.
- —There is no CI. The repository has no GitHub Actions workflow at all — the gates run locally through tool/check.sh and no hosted run stands behind them. The test output committed on this site is the artifact.
- —No accounts, no server, no sync. Contributions live only inside the session.
- —No moderation of contributions and no verification that a contributor is a real student.
- —Two pilot cohorts only. This is not deployed to any institution and has no production users.