Skip to content
Huy Tran

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.

PORTFOLIO PROJECT

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

First Week on Android — A task, opened
A task, openedtrust level, deadline and source above the instructions
First Week on Android — Two pilots, side by side
Two pilots, side by side1,240 students against 3
First Week on Android — The thin checklist
The thin checklistsays it is new before you rely on it

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.

Evidence supporting each claim, with verification status and link.
Claim supportedStatusEvidence
The whole application is public and clonable
Flutter app, contract, fixtures, tooling and device evidence
VERIFIEDOpen ↗
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
VERIFIEDOpen ↗
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
VERIFIEDOpen ↗
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
VERIFIEDOpen ↗
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
VERIFIEDOpen ↗
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
UNAVAILABLEOpen ↗
+79: All tests passed! — read the unedited output ↗

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.