Concept B · built from Fabian's spec · 2026-09-12
Nobody clears a garage one object at a time. You walk the room with the camera, you put the phone down, and later you sit and go through a stack of finished ads like a stack of mail.
Two jobs — shoot and sort. The machine owns everything between them, and you are not expected to be there while it works.
Fixture state. No model is called, no photograph leaves your device, no price is real, no notification is real. The wheels, Ray-Ban and mixer searches, comparables and confidences are copied from the app's own live runs of 22 August and 31 August; the golf clubs, the bowl and the drill are written, not captured, and the fixture file says which is which field by field.
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.
The screen follows the object.
Six things means six five-minute waits, serially, with the phone in your hand for all of them.
The unit of work is the pile.
Six things means one absence. The confirmations move to the finished card, where you can judge them against a price and an ad at the same time.
They are not in conflict about the data. The item lifecycle is identical, and each Sort card is "the screen follows the object" for one object. What changes is which moments you are present for. The genuine fork is Home, Shoot and Sort, and it is a fork about what the app is for: one object's life, or a household's Saturday.
"Put your phone down, we'll handle it" is the concept's most distinctive moment and the easiest thing in the world to render as one progress bar and a spinner. That would be a lie about what the backend does. There is no single piece of work to measure: there are six independent lookups, three of them in flight, the rest sitting on a deliberate delay, each finishing when it finishes.
The default after you finish shooting. One Ticket per thing, each breathing on its own period and its own phase — six marks in sync would read as one thing with six parts. A colour legend, because colour is the only carrier of state on this screen. And a ticker that rotates one true sentence at a time from whichever run is actually moving. No bar, anywhere.
The opt-in detail view. One lane per thing, each reading its own event log on its own timer, so the lanes genuinely drift apart — different search text, different rates, different finishing moments. The lane's ground fill is the search progress; there is no second bar. A finished lane stamps, flips to ink and migrates up out of "running" into "finished".
Three at a time, ninety seconds apart, shown rather than hidden — with the reason, and a live countdown on the next one. A person who can see the stagger has a true model of why the fourth thing has not started yet. Both constants live in one place and drive the server's delay, the ready-by estimate and this bar.
Same rule as the first prototype: where the spec leaves a decision open, use a reasonable placeholder and say so on the surface rather than picking quietly. Every open decision carries a dashed OPEN badge naming who holds it, and the five that are yours are switchable live in the Prototype drawer.
gateAfterVision() is the real pure function from spec 5.1, and every
downstream state is a consequence of it. The bowl and the sunglasses are genuinely held by it and
genuinely never spend a lookup.webkitSpeechRecognition where the browser has it, wired to a
real gesture, landing in a real editable field. Where it does not exist the control says so and the
text field beside it is always there.Places where building it surfaced something the spec did not have, or got wrong.
Spec 4.3 says the code is "assigned from the general profile's prefix" and worries about
re-lettering it when the category resolves. It reads nextCode() one step off: the prefix
comes from the owner id, not from the profile, so there is nothing to re-letter and the whole
concern dissolves. The prototype uses the real shape (RA-12). The spec paragraph should
be struck rather than implemented.
Built literally, the Sort counter read 1 of 5, then 1 of 4, then 1 of 3 — telling a person who had just made three decisions that they had made no progress. It now counts through, and when an answered hold finishes and rejoins the stack, n grows rather than k jumping backwards. Small, and exactly the kind of thing the cohort this is for cannot absorb.
The cleaning rule falls back to the raw model query when it cannot name a venue, which is right — it never invents a label. But a raw query truncated mid-phrase is the wrong thing to put on a screen whose entire job is to be glanceable from across a kitchen. The Floor shows the search line; the Face shows the stage, which is always a readable sentence. The spec treats both surfaces as the same material.
| Open decision | Holder | Where it shows |
|---|---|---|
| Does "one at a time" still stand? (spec: "this decides the concept") | Lance | Drawer · adds a second entry on Home |
| Spending before you confirm | Lance | Drawer · changes Done-for-now and the Floor |
| Push notifications at all | Lance | Drawer · the ask, and the simulated banner |
| Post order: shot order or highest price | Lance | Drawer · re-sorts Ready to post |
| Machine-guessed condition | Lance | Drawer · every condition chip in Sort |
| Home: stacks above rows, without becoming a dashboard | Linnea | Home |
| The Shoot tray, the chips, "Next thing", the three fixed words | Linnea | Shoot |
| The Sort card in six states, and the Fix sheet | Linnea | Sort |
| The hold-to-talk control: present, and how quiet | Linnea | Shoot |
| The ready-by sentence and the countdown | Linnea | Done for now · the Face |
| Push endpoints as stored data; retention and deletion | Adisa | More |
| Voice routing through Apple's recognition service | Adisa | Shoot · under the control |
| Charging before confirmation, paying cohort | Adisa + D-499 | Done for now · the reserved slot |
| Every string, and the condition-chip sentences | Auden | Everywhere a marker appears |
| The word "pile"; whether Shoot / Sort / Post ever surface as words | Kahua | Throughout |
| Sequencing against the D-499 payment and onboarding spec | Kwitonda | Not touched by this pass |
Lifted from spec 12 so it is on one screen. All additive; no existing column changes meaning. This is a bigger build than the first concept's — one new table, six columns, five routes, a worker hook, a service worker and a push path, against the spine's two columns and one new route.
0023_piles.sqlpiles — id, owner, started_at, closed_at, labelitems + pile_id, pile_position, hold_json, sort_decision, sorted_at, condition_sourcephoto_plans.condition_guess_jsonresearch_runs.auto_startedpush_subscriptions, and users.push_declined_atitems.rail_json and users.town if not already landedPOST /piles, and /state gains the pile block with server-derived countsstartResearch() extracted from researchRoute, called by the route and by
visionRoute — one function, two callers, so the two paths cannot driftgateAfterVision(), pure and unit-tested per confidence valuePOST /items/:id/answer · POST /items/:id/split · PUT /items/:id/sortdelaySeconds at enqueue — no worker change, no in-flight counternotifyIfPileComplete() in the worker, plus VAPID secrets and a Workers-compatible signerTwo things the prototype cannot prove and does not claim to. Whether three concurrent fourteen-search calls trip the Anthropic rate limit is unmeasured — the stagger constant is a guess and production staging has to test it with a real pile of six before the family sees it. And the push path can only be proven on a real home-screen install; the banner here is drawn by the prototype and says SIMULATED on it.