milestones
The road to MVP is climbed one rung at a time; a rung is only "done" when its E2E harness proves it repeatably, and each rung builds on the one below. (North Star: README.md. Boundary rules: docs/architecture-boundary.md.)
Rung 1 β Phase 1 alone: installer produces a boot-ready diskβ
Claim: on a virgin Windows machine, wootc (GUI or headless) ends with
the system armed: a raw root.disk exists (VDL-extended so Linux ntfs3
can write it over loop β VHDX was retired in 8136ae6), the signed
chain + deployer pair are on the ESP, the BCD one-shot is set, vault.json
holds only a hash, state.json = armed.
Harness: tests/e2e/phase1/run-phase1.sh (~2 min against a kept VM,
no deployer boot). Runs the real wootc.exe over QGA.
Status (2026-07-17): GREEN β 24/24 assertions pass on dilli (virgin Windows VM, real wootc.exe over QGA). The suite earned its keep immediately: it caught the sha512-crypt salt-prefix bug and non-idempotent BCD arming (retried installs piled up firmware entries β now swept). Known WARN, deliberate: the User Data Bridge matches Linux username to Windows profile by exact name; the dashboard should grow profile mapping (tracked for rung 3).
Rung 2 β Phase 1 β Phase 2: armed system boots into Linuxβ
Claim: rebooting the rung-1 system runs the deployer unattended
(pull β fisherman β verification β ESP sync), and the following boot
reaches the installed system's login on native Phase-2 boot.
state.json walks armed β deploying β deployed, then healthy written
by the installed system.
Harness: extends the phase-1 run with the reboot + serial-console
monitoring from run-e2e.sh; asserts the healthy state and an SSH/QGA
sign of life from Linux.
Status (2026-07-23): GREEN. The raw-root.disk + losetup --partscan format won (8136ae6; docs/phase2-attach-postmortem.md tells
the debugging story). Proven repeatably by run-e2e.sh on himachal.
Rung 3 β Phase 1 β 2 β 3: migration works where the user livesβ
Claim: on the Phase-2 system, the User Data Bridge is live (Windows folders visible in $HOME, Steam library registered, browser imports work) and the migration dashboard performs a reversible category conversion; Windows still boots afterwards.
Harness: QGA/SSH-driven checks inside the Phase-2 system β bind
mounts present for the vault-created user, wootc-convert-dir round-trip
on a seeded folder, dashboard backend (GetMigrationCategories) sane;
then reboot back to Windows and assert it comes up clean.
Status (2026-07-23): GREEN end-to-end. The full three-phase run β
Windows seed β deployer β Phase-2 boot β User Data Bridge in $HOME β
Phase-3 graduation to a native disk β native boot β seeded file on the
native disk β passed 29/29 (just remote-e2e-phase3, wootc bd11049
- fisherman 5025d4d).
tests/migration/test-bridge.shis 54/54 green in a container (passthrough + write-through, Steam registration, browser import, reversible folder conversion + marker, DE look mapping GNOME/KDE, ESP sync on BLS and classic layouts, MS OfficeβLibreOffice). Live proof β binds actually appearing in a booted Phase-2$HOMEβ is part of the 29/29 run, measured over the Phase-2 QGA channel. Session token migration is split out to GitHub issues #1 (DPAPI rewrap) and #2 (guided re-link) β needs real per-service testing, not automation now; #3 tracks dashboard integration.
Working agreementβ
- Fix at the lowest rung that reproduces a failure; never debug rung 3 symptoms while rung 2 is red.
- Every rung's harness must run on any of the E2E hosts (kanpur, himachal, dilli) β host-specific setup goes in a bootstrap recipe, not in engineers' heads.
- A rung's harness is part of its definition of done: no green harness, no claimed rung.
Rung 3b β GUI-driven full run: the product arms the machineβ
Claim: the same three-phase run, except Phase 1 is armed by the REAL
wootc.exe GUI β form filled and Install clicked through the app's own
GoβJS bridge (drive mode, WOOTC_E2E_DRIVE=1), then the app's Reboot
hands off to the deployer. The GUI pipeline must match setup-wootc.ps1
(the proven reference implementation) step for step.
Harness: run-e2e.sh --gui-install (just remote-e2e-gui).
Status (2026-08-11): GREEN end-to-end. Drive mode (the app drives its
own live form, WOOTC_E2E_DRIVE=1) arms and completes the full
Phase-1 β 2 β 3 chain on bluefin:lts; the timelapse at the top of the
README is that run (pages/e2e/latest). Real findings already fixed by
this rung: custom-OCI refs guessed systemd-boot (backend-contract
violation), the Go installer still made a VHDX Phase 2 can no longer
attach, missing bcd-guid.txt, missing elevation, missing console=ttyS0,
and the missing BCD one-shot seen at reboot in run 20260723T1144 (the Go
pipeline was aligned with setup-wootc.ps1 in 6961461). CDP is
impossible in stock wails (both WebView2 loaders discard the env var once
the framework passes its own browser args) β hence drive mode.