Rebuild prototype · built from Fabian's concept spec · 2026-09-11

The screen
follows the object.

The concept spec's one sentence, built as a working thing you can click through on your phone. One continuous path, one forward action at a time, and real interactive versions of the two hero moments the spec grounds most concretely.

It runs on fixture state: the comparable listings, the search queries, the anchors and the identity blocks are copied out of the app's own live-run fixtures — real responses the API actually returned on 2026-08-22 and 2026-08-31. No model is called. No photograph leaves your device. No price is real.

D-450 OffsetD-615 The Ticket D-498 photos storedD-396 three bands fixture data only
Open the prototype →

Best judged on your phone. On a desktop it draws itself inside a 390 × 844 device frame; the Prototype tab at the top right switches that, and everything else.

What is genuinely real, and what is a marked placeholder

The brief was explicit about this: where the spec leaves a decision open, the prototype uses a reasonable placeholder and says so on the surface rather than picking quietly. Every open decision carries a dashed OPEN badge naming who holds it, and the Prototype drawer lets you switch most of them live and look at both answers.

Real and interactive
  • The spine. One render() switching on the spec's own state table. Ten states, each with one forward action, a state name in mono above the item title, and the Photos material demoted to a quiet disclosure instead of a peer tab.
  • Hero 1, the press run. A fixture event log replayed on a timer. The search log is live, the queries are the real ones, the plate's misregistration converges as results land, and the comparables stamp in by geo band at the end — not as a running count, because the pipeline does not produce one.
  • Hero 2, guided capture. Camera-first grid built from the real per-category angle data. On a phone, tapping a frame opens the real camera. The on-device sharpness check is the actual Laplacian-variance algorithm running on the actual shot, with the threshold exposed on a slider so it can be calibrated.
  • Hero 2, the identity card. The vision pass's identity_string, identity_confidence, identity_evidence and identity_alternates — all four computed today, none shown to anybody. Rendered from the real fixture, including the hard case where the model returned category_only.
  • Hero 3, preview and the paste rail. Six steps, one block at a time, real clipboard, the rail advancing itself, progress markers in the Ticket silhouette, state surviving a reload.
  • After. Listed, sold with the passed-on line, failed, removed, needs-photos.
  • Motion. View Transitions between screens, sheet slides, the copy inversion, the stamp, the press-down. All of it computes to nothing under Reduce Motion, which you can force from the drawer without changing a device setting.
Marked placeholder — somebody's decision
  • The product name. Defaults to the name that ships today, because that invents nothing. All five candidates are in the drawer and swap the wordmark, the sign-board and the home-screen name live.
  • The welcome headline. The spec's own placeholder, Auden's primary. The other three are named in the audit but not reproduced in the spec, so they appear as explicit empty slots rather than as invented copy.
  • The hero number. Built as the ask, per the spec's proposal. Switch it to the sells-at figure in the drawer and the two flanking numbers and their words swap with it.
  • Confidence as shape, or as the echo widening. Both built, both switchable, both driven by the real fixture confidences.
  • The ledger coin: circle or Ticket silhouette. Both carry identical status-colour logic, so it is a pure silhouette call.
  • Plates and paper artefacts: held warm, or re-inked in Offset. Both rendered.
  • Premium versus Playful. Both swatch groups are present, because the spec is written so either answer fits.
  • The retention sentence. A clearly-flagged stand-in. Adisa confirms the facts before Auden writes the sentence; the prototype does not write it.
  • The back-line wording, the tally line, the passed-on line: Auden's words, flagged.

Three things worth arguing with

Places where building it surfaced something the spec did not have, or got wrong. Each is flagged on the surface too, not just here.

The echo cannot go on the identity string

Spec 5.2 asks for the identity line "in the poster face, sitting slightly out of register." Built literally, that is the exact treatment Lance reported as "blury vision" on 2026-08-30, after which the shipped stylesheet pulled the echo off all running headline copy and wrote the rule down. So the misregistration moved off the letterforms and onto the plate and two registration crosshairs. Same device, same choreography, and it stops fighting the app's own legibility floor. The spec should be amended, or this overruled.

Four band tags is three too few

Spec 5.2 lists the stamp as four tags: Greater Victoria, Island, Mainland, Elsewhere. "Elsewhere" would put United States comparables in the same row as Canadian ones, and the pipeline's hardest rule is that CA and US never blend. The prototype stamps four Canadian bands and then a separate US row behind its own fence line.

An identity string can be too long to be a title

The wheels run's real identity refinement is a 300-character sentence. The vision pass's own schema asks for a short search phrase, so P1 output is usually fine — but nothing enforces it, and the card has no good behaviour when it is not. The prototype shows the long case and flags it rather than truncating quietly. It wants a length constraint in the P1 prompt.

What the build pass could not decide, and who holds it

OpenHolderWhere to look
Welcome headline, one of fourLanceWelcome screen · drawer
The hero number: ask or sells-atLanceAny ready item · drawer
Premium versus PlayfulLanceThe colour picker
Swatch trigger on drill-in screensLanceKept on every screen, per the standing instruction
The product nameLance · KahuaDrawer · five candidates
Plates, contact sheet, print: warm or re-inkedLinneaCapture screen · drawer
Ledger coin: circle or TicketLinneaOn the Table · drawer
Confidence as shape or as echoLinneaPrice hero · drawer
Retention facts: window, access, deletionAdisaConfirming screen · the one keepwarn
Preview card's distance from Facebook trade dressAdisaReady screen · "Before you go"
Every string in spec 9.2, and the retention sentenceAudenEverywhere a marker appears
Sequencing this rebuild against the D-499 payment specKwitondaNot touched by this pass

Two further open items the build pass created rather than inherited: the sharpness threshold is not calibrated and has to be set from real shots of the real first items on the actual phones; and the search log's per-search result counts and timings are fixture-shaped, not captured, because there is nowhere to log them until the events_json migration lands.

What production would need

Lifted from spec 12 so it is on one screen. All additive; no existing column changes meaning.

Migration 0022

  • research_runs.events_json — the capped event array the press run reads
  • items.rail_json — the rail's step and copied set, so the rail survives a device change
  • users.town — a plain municipality string, never a street

Routes and the worker

  • GET /reference returns each profile's full angles array, not just {key, name}
  • POST /items/:id/vision carries plan.identity to the client
  • GET /items/:id/package carries run.events while a run is live
  • PUT /items/:id/recompose — P3 only, never P1 or P2
  • consumeStream() gains an onEvent hook, best-effort like onHeartbeat
  • No change to the Queue, the Worker's deploy shape, the five-minute ceiling or the reaper