Task: Restore the UI primitives and port the journey runtime
Table of Contents
This page documents a task in the Implement the setup journeys in ores.web story. It captures the goal, current status, acceptance, and any notes or results.
1. Goal
The story has a rail model and no page that renders it. Restore the UI primitives the reduction commit deleted, and port the prototype's rail and step parts onto journeys/runtime.ts so that a journey is one page rendering an ordered list of step definitions.
2. Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Implement the setup journeys in ores.web |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-09-27 |
3. Acceptance
- The primitives, the password field, the password policy and its test, and the brand artwork are restored from
e47043269f^and pass the checks of the TypeScript Clean Standard. - The rail renders from
journeys/runtime.ts: one page renders any journey as an ordered rail of steps plus the current step, and the rail and the steps cannot disagree. - The step parts that read no unbuilt contract are ported from
prototype/first-run-journey, and the simulation is not: no stub, no canned profile data and no artificial failure switch enter the tree. The parts that read the seed-profile and progress contracts land with those contracts, in plan steps 5, 8, 10 and 11. - The password rules the field shows are the rules the server enforces in
password_validator, and the policy test proves each rule. - The workspace typechecks, lints and tests green.
4. Plan
Three units, in one commit each.
4.1. Unit 1 — restore what the reduction deleted
git checkout e47043269f^ -- for the seven paths: the primitives, the password
field, the password policy and its test, and the brand artwork. The password
keys survived in the three catalogues, so only the code comes back. The artwork
README says the images are back, and brand.ts is named as the one place a
screen reaches an image.
4.2. Unit 2 — port the rail onto the runtime
The prototype's JourneyPage becomes a component over journeys/runtime.ts.
The rail is derived with rail() from the same list the body comes from, the
position stays with the caller, and the footer rides the runtime's back rule.
The runtime gains stepAt so the page never indexes the step array, and the
range guard collapses into one function.
4.3. Unit 3 — tests
The render is tested without a DOM: react-dom/server renders the page to
static markup, and the tests assert the rail's order and states, the current
step's body, the footer's buttons, and the refusal of a position the journey
does not have. The runtime's own cases cover the ordering rules.
The journeys module moves to the package's two-space indentation in unit 2. It was the only four-space file in the package, because it was written after the package's own files were.
5. Measurements
Every number this task claims about a tree, with the command that produced it
and the commit it was measured at. A number without both is not a measurement,
because a clean-up record describes a tree and trunk moves under a branch: a
consumer count, a gate's component count and a suite's size all change with no
code changing, and the reader of a bare number cannot tell which tree it came
from. Where the raw output matters, put it in an evidence/ file beside the
task and name that file in the Command column.
| What | Value | Command | Commit |
|---|---|---|---|
Files restored from e47043269f^ |
7 | evidence/step2_census.txt section 1 |
6325b95f64 |
| Modules with no production importer | 3 | evidence/step2_census.txt section 2 |
6325b95f64 |
| Tests | 100, in 13 files | evidence/step2_census.txt section 3 |
6325b95f64 |
| Browser bundle | 247 modules transformed | evidence/step2_census.txt section 4 |
6325b95f64 |
6. Notes
- The prototype's footer made the back rule unreachable. It rendered Back
only on a step that also declared an action, so a step with no action and no
finalpredecessor offered no way back at all. The test that asserts a disabled Back button is what found it. The page now renders the footer whenever the step has an action or the runtime allows a move back. - Interaction is not covered. The package has no DOM test environment, and
scripts/verify-browser.tswent with the reduction. The one behaviour that a static render cannot reach is the failure path: a rejected action shows a notice and does not advance. It is written and unproven. The browser verification the story's acceptance asks for belongs to its last plan step. npm run format:checkis not a gate. Prettier reports 375 files across the workspace, including generated files and files this task does not touch, so the check cannot pass on trunk. The new files follow the package's own style instead of prettier's defaults.tsconfig.jsonexcludes =src/**/.test.ts(x)=*, sonpm run typecheckdoes not check the new test files; vitest transforms them. That gap is already filed as a capture, and it is why the render test's types are not proven by the type checker.- Three modules have no production importer:
ui/PasswordField.tsx,assets/brand.tsandjourneys/JourneyPage.tsx. Each names its intended consumer in its own header, which is what TS-B03 asks for.
7. Test Scenarios
Manual QA scenarios (scaffolded via compass add test_scenario)
that verify this task. Link
new ones here as they're created; the scenario doc itself links back
via its "Verifies task" field.
| Scenario | State | Notes |
|---|---|---|
8. PRs
| PR | Title |
|---|---|
| #2292 | [web] Restore the UI primitives and port the rail onto the journey runtime |
9. Review
| Comment summary | File | Decision | Notes |
|---|---|---|---|
10. Result
The primitives, the password field and its policy with its test, and the brand artwork are restored, and the rail is a component over the journey runtime.
JourneyPage renders any journey from its step list: the rail comes from
rail(), the current step from stepAt(), the forward move from
nextPosition() and the back rule from canGoBack(). A step's action is the
only place a step reaches the server, and an action that rejects shows a notice
and does not advance. The web package's suite is 32 tests in four files, of
which nine render the page and sixteen cover the runtime.
The step parts that read the seed-profile and progress contracts did not come across, and the acceptance says so: porting them now would mean inventing the shapes they read. The rail and the primitives need no contract.
Three modules have no production consumer yet, and each names the consumer it waits for. Interaction is not covered, because the package has no DOM test environment, and that limit is recorded rather than papered over.