BoRoKnowledge baseGitHub

Review call — 21 August 2026

CJ and Brad, stage by stage. Two ratified decisions reversed and the action-control question opened.

RecordUpdated 2026-08-24

Field Value
Version 1.2
Call BoRo Chat Lifecycle Review — CJ & Brad · 2026-08-21 · transcript
Speakers CJ Oltman, Brad Larson. Jaydan Nguyen was not on this call.
Against Review method v2.0 · Build state v2.0
Recording note Capture begins at 17:37 — the first seventeen minutes are a single stray word and silence. Anything said before 17:37 is not in the transcript.

BLUF

Brad walked all 23 stages and approved essentially the whole visual layer — the chip tint, the display timer, the dark theme, the sidebar, the gated menus — without a single objection. Two ratified decisions were reversed: the action dock comes back in some form, and the own-message bubble goes from surface-inverse to blue. The blue has no token behind it. And it was a walkthrough, not a decisions review: of the 17 open questions, one moved partially, and all eight Brad-only blockers are still blockers with the Jay workshop at 9:00 AM tomorrow.


Corrections to v1.0

Two explicit gaps were in the transcript and v1.0 dropped them. Both are CJ acknowledging missing work out loud, which is the strongest kind of finding in a walkthrough, and both are recoverable only because he raised them again afterwards.

  • The scheduling form was named as missing, on the call. Brad, 19:40: “You didn’t do, like, the step to, like, do the form for it or whatever? We still have to do that.” CJ, 19:44: “Oh, yeah, I got to do the form.” Brad: “You’re right.” v1.0 folded this into the generic §7 form-stage queue instead of recording it as an acknowledged gap with a named owner. Now S-2.
  • The QR screen was named as missing, on the call. CJ, 24:40: “Yeah, I didn’t do the QR one though. I just realized I got to do that.” v1.0 did not mention it at all. Now S-4.

A third thing v1.0 got at the wrong altitude: it recorded the action-control debate as a placement argument (dock vs in-thread) and missed that the content of those controls — which buttons, on which screens, with which labels — was never specified anywhere. That is S-1.


Confirmations

Reviewed and explicitly approved. Nothing here needs rework.

  • The chip tint tier, both themes — Brad, 26:14: “I like how we have that little bit of color. It’s not, like, overwhelming color. Yeah, it’s looking good.” And 26:22: “On dark mode, that looks nice too.” This is Lab 14 passing review in front of the developer.
  • The display timer — Brad, 27:15: “I like the timer. That’s sick.”
  • The sidebar rebuild, filter and dropdown (batch 6) — Brad, 22:39 “Cool.”, 22:49 “Yeah, that’s cool.”, 23:06 “Okay, that’s looking good.”
  • The interest stage — Brad, 19:25: “I think this one was always fine.”
  • The check-in chain states — Brad, 24:35 “Nice.” on One arrived; no objection to Nobody-here-yet or Both-arrived.
  • The cumulative thread, in principle — Brad, 34:21: “it captures like an actual timeline of what happened in what order and stuff… that’s the real goal.” He then asked for it to collapse — see change requests, not a reversal.

Silence is data. Nobody raised the map plate, date separators, the 12px card rhythm, full-width card actions, the closed badge vocabulary, the bolding pass, the 760px column, or the mobile header — including the batch-4 map rework that was the most recent visual change. Read as accepted.


Answers to open questions

Moved

Q3 · Cancelled vs Terminated on a no-show — partial, not settled. Brad did not settle the naming, but he ruled on the treatment. 35:54, Brad: “the no show meetup should probably — I guess it says closed, but if there’s a no show, there might be more to that because I think there’s like… locks on, like the commitment hold. Because people, if there’s no shows, they get charged and stuff. And maybe it’s red.” CJ: “Yeah.” Brad, 36:11: “Instead of gray.” Then he deferred: 36:12 “But some of this we could talk about with Jay.” → No-show carries error tone and states the hold consequence. The Cancelled/Terminated naming stays open. See conflict C5 — this cannot be done without touching a ratified rule.

Q17 · Badge spread on a long thread — addressed structurally, not as a badge decision. The answer to the long thread turned out to be collapsing it. Brad, 34:34: “it should try to make that information as digestible as possible for a user. So like collapsing it into like little summaries and stuff of like what the renter or lender would want to see and then if there’s more information like exact timestamps or location… price and taxes and whatever. It’s all in there.” If past cards collapse to a summary line, the column of Completed badges stops being the problem it is today.

Q15 · Past segment pips in success — likely moot, pending the Lane B change. Not discussed as a colour question. But the direction in the Lane B exchange (change request CR-8) is that segments accrue as they are consumed rather than pre-rendering all five, which removes the past/future distinction the question was about. Do not resolve Q15 until CR-8 lands.

Not addressed

Fourteen of seventeen went untouched. Naming them, because a blocker that stayed blocked is the finding here:

  • Brad-only: Q1 (Late chip), Q2 (extension chip), Q4 (close-while-accepted), Q5 (composer in review window / dispute), Q6 (hold amount on the pending card), Q7 (late card copy + BoRo Recovery), Q8 (SESSION_MINUTES 30 → 45).
  • Integration: Q9 (no semantic tokens in boro-theme.cssthe integration blocker), Q10, Q11, Q12, Q13 (RentalStageChip.tsx AA failures).
  • CJ’s: Q14 (line timer treatment — the one unratified lab), Q16 (does the Lane toggle earn its place).

Two near-misses worth recording:

  • Q8 came close without landing. CJ, 33:38: “45 Minutes to test. I don’t know if we’re gonna have a timer up again.” Brad, 33:41: “We probably need a timer up again for condition assessment.” He accepted a 45-minute figure without comment, but never addressed the live inspection_duration_minutes field his gap note is about. Treat Q8 as open.
  • Q12 got an adjacent signal, not an answer. CJ, 44:02: “it’s just a matter of, like, getting all this back into the actual… design of the figma.” Brad, 49:46: “I almost feel like we don’t even need Figma anymore.” Those point opposite ways. Worth settling before anyone spends a day on Figma parity.

The pattern. Stages late, dispute and not-returned were never opened, which is why Q1 and Q7 could not come up. A stage-by-stage walkthrough will not surface a decisions list — it surfaces whatever is on screen. If the eight Brad-only items matter before build, they need a targeted pass with the list in front of him, not another walkthrough.


Change requests

Against things that already exist.

CR-1 · Next-step action controls are missing on most stages. The single largest theme of the call, raised five times. Brad, 21:42: “we definitely need those action items because obviously every state, every step is going to need that, like that next step sort of action item.” And 42:16: “try to make sure that, like, we’re not missing those next step buttons at each stage. And then I think we’re good to, like, show Jay.” This is Brad’s stated gate on the workshop. See conflict C1 — it reverses a ratified decision, and where the control lives is unsettled.

CR-2 · Initiating actions must not be thread cards. Brad drew the distinction himself, 20:56: “why would it be in the conversation, though? Because they’ll be talking and at any point, they would be able to do it. It wouldn’t be a card until it happened.” And 22:06: “to initiate like the try on or those things, there needs to be like a button for that.” → A card is a record of something that happened. Starting something is a persistent control. Useful rule — it resolves how the eight form stages get reached.

CR-3 · Real item images, not icons. Brad, 19:10: “can we put in some images for the items?… Just have, like, some real images or whatever.” CJ: “Definitely.” Re-raised at 42:26 as the second half of his workshop gate. → The three sample items already carry real make-and-model names and all three are PERMITTED under Terms v2.5 §8.4, so images of them raise no screening question. Any new item introduced with an image needs screening by make and model.

CR-4 · Drop the “Generate QR” button — show the code automatically. Brad, 26:38: “I don’t know if we need to generate it. If you’re both checked in, it should just show the QR code probably… we didn’t want to, like, generate it, should just have one.” → Clean, and consistent with FSD §10.1 (the code is displayable inside the geofence). Actionable now. But see C3 — his very next sentence complicates it.

CR-5 · An explicit “I’m here” button rather than continuous geofence polling. Brad, 25:45: “I think we probably need a button to check in. Like, we don’t want it, like, constantly checking the geofence stuff. We probably want a button to, like, initiate for it to check. Like, hey, I’m here. And then it, like, verifies… And then if that verification fails, then you can do the manual.” CJ, 26:08: “We can add a little button.”

CR-6 · Past cards collapse to a summary with an expand affordance. CJ, 34:08: “I’m also wondering if… these should have like a little arrow or something.” Brad, 34:16: “Yeah, I think so… more details for each one or whatever if we wanted to see more.” Detail behind the fold: timestamps, location, price and taxes. → Refines the cumulative thread rather than reversing it. Also folds return-assessment and rental-concluded into one “Rental completed + summary” card — CJ, 34:00; Brad, 34:05: “Exactly like the rental completed and just have like the summary of it.”

CR-7 · A display timer on the return / condition assessment. Brad, 33:41: “We probably need a timer up again for condition assessment.” He was unsure of the duration — 33:49 “maybe that’s also part of the like there’s a standard time. But yeah, I don’t know.”FSD §10.2 already answers the duration: one 45-minute session per phase, and the return session is the lender’s. Build it at 45. Only one live display timer per thread still holds — the return one is live only at that stage.

CR-8 · Lane B segments should accrue, not pre-render. CJ, 30:57: “maybe each segment, like when it comes then it will have like the first segment’s done here and it creates two, and then the second segment is starting… and then it turns into three.” Brad, 30:46: “do we need that up the whole time, or… do we have the normal return in X and then there’s like a more info that pulls out the segments.” Brad, 31:17: “So we could just keep it all in here potentially.” → Default view is the plain return date; segments live behind a disclosure and accumulate as they are consumed. Changes the ratified “five pips, current one amber” and probably moots Q15.

CR-9 · A review action on review-pending. Brad, 35:20: “If we’re going to have review pending, we should probably have like a review the person kind of thing.”

CR-10 · Exception and terminal stages need a next step too. Brad, 36:28: “we always want to have that, like, next step.” CJ suggested contact-support as the action on dead-end states, 36:20.

CR-11 · Gating rule: scheduling controls hide during an inspection and return when it concludes. Brad, 28:22: “when the try-on’s complete, that’s when those buttons would show back up to like schedule the rental or schedule yet another try-on.” And 28:33: “you wouldn’t have those buttons during the inspection but you would like when they’re done.”

CR-12 · Possibly drop the ⓘ from the ⋮ menu. CJ, 22:51: “I guess I don’t need the [ⓘ]. I could probably drop that one.” Brad, 22:54: “Well, we wanted the — yeah, we drop it from the other menu, right.”Low confidence. The transcript renders the object as “the Aya”; reading it as the info control is inference from context, and Brad’s sentence is half-finished. Confirm before acting — info is currently duplicated between the header and the sheet, which is the only reading that makes sense of it.


Second-pass findings

A block-by-block coverage pass over the whole transcript, run after v1.1. Seven items the first two passes did not carry.

N-1 · Brad blessed card-borne next steps — which shrinks CR-1 substantially. The action-control ask is not all-or-nothing, and v1.0–1.1 read it as though it were. Brad, 21:57: “Some of the stuff being in the card is fine because it’s like, oh, this card happened, like, oh, they did the inspection. So the next step can be like on that card. That makes sense. But to initiate like the try-on or those things, there needs to be like a button for that.” → Two categories, one rule: a next step that follows an event lives on that event’s card; a next step that initiates something needs a persistent control. Most of the 23 stages are the first kind and already have somewhere to put the action. Only the initiating actions — S-1’s two — need the contested persistent placement. This meaningfully de-risks the C1 dock argument: it is a fight about two buttons, not about every stage.

N-2 · A one-day window to decline an extension, which is not in canon. CJ, 31:44, on the lender’s extension view: “Obviously you can decline it if you want to, back within that one day.” FSD §13.2 sets the commit model and the increments but names no response window for the lender. Either a one-day window exists somewhere this doc has not read, or it is an assumption that got spoken as fact and will otherwise get built. [BRAD-CONFIRM] — and it belongs in the FSD if it is real.

N-3 · The expanded card detail opens a financial surface that does not exist yet. Brad, 34:34, listing what sits behind the fold: “exact like timestamps or location, like whatever that additional information is, like price and taxes and whatever.” → No card in the file shows a money breakdown today. Doing this means surfacing the 7% / 3% split (FSD §6.3), travel (§8.7), and sales tax — which FSD §16.2 lists as a cross-document dependency, i.e. not settled. Scope it deliberately or the detail pane becomes the first screen to state fee mechanics, and it will be read as authoritative.

N-4 · An unanswered design question from CJ. 43:00: “Wondering if I should make these thicker. The active one.” Brad’s only response is a “Yeah” forty-five seconds later, after a long silence — too detached to read as agreement. Unclear what “these” are; from where he was in the walkthrough the two candidates are the segment pips (which would fold into Q15) and the display timer’s progress bar. Worth resolving rather than leaving in the file as a half-thought.

N-5 · An adjacent signal on Q16 — Brad values the lane modelling. v1.1 recorded Q16 as untouched. It was not answered, but it was praised. Brad, 44:32: “I’m glad you even, like, you’re like, oh, we need this. And you put that, like, route A versus route B or whatever, for the Shield or whatever. Like, that’s what we need.” → That endorses the lane distinction being modelled, not the capture-bar toggle specifically. Q16 asks whether the toggle earns its place. Still open, but the modelling behind it has the developer’s explicit support, which is the harder half.

N-6 · Brad named the next two designs, and one of them carries a compliance gate. 51:18: “I know you did some mobile designs for, like, searching for an item, but if we had, like, full designs for creating a new item.” → v1.1 said “the remaining screens” generically. Naming it matters: the listing-creation flow is where FSD §14.5 puts the category gate — “The restriction screen runs FIRST in the listing flow, before any other field” — screening against Terms v2.5 §8.4, with prohibited-term matching on title and description that blocks rather than warns. That is not a screen to design and retrofit a gate into later.

N-7 · CJ stated an accessibility pass is in progress. 26:27: “I’m making sure everything’s compliant as well, you know, going through for accessibility stuff.” Recorded because Q13 — RentalStageChip.tsx failing AA on five of twelve states — is a live-app defect and this pass is on the simulator. The two must not get conflated into “accessibility is handled.”


Safeguards — so this does not recur

The misses came from sorting into output buckets, which discards whatever fits no bucket. These belong in Review method §8 so the next session inherits them rather than depending on whoever reads the call.

# Safeguard Catches
1 Coverage ledger, not a bucket sort. Split the transcript into blocks — per stage on a walkthrough call, ~2 minutes otherwise. Every block yields a numbered note or an explicit “no action.” A block with neither is an unread block. Makes coverage checkable instead of felt. This is the root fix.
2 A sixth bucket: Acknowledged gaps. Anything either party says is not done, still to do, or forgotten. Distinct from New Scope (nobody has claimed it) and Change Requests (it exists and is wrong). Both v1.0 misses were exactly this and nothing else would have caught them.
3 Mechanical owner-statement scan, before writing. Grep for I (got to|need to|didn't|haven't|have to), we (still have to|need to|didn't), missing, forgot, gotta. Owner statements are spoken in five seconds with no emphasis. They do not stand out on a read; they do stand out to a regex.
4 Unanswered-question scan. Every ? from either speaker: was it answered within ~10 lines? If not, it is an open item. N-2 and N-4.
5 Hedge scan near decisions. I guess, we'll see, for now, I don't know, maybe, probably. Keeps a direction from being written up as a ratification — what kept the blue bubble honest in v1.0.
6 Two-pass rule. Pass 1 extracts. Pass 2 re-reads the transcript against the written notes, looking only for content the notes do not cite. Never write from a single read. The pass that produced N-1 through N-7.

Also worth fixing at the source: the brief’s §8 format is an output spec with no input obligation. It says how to shape the notes but never says every part of the call must be accounted for. Safeguards 1 and 2 close that, and they are two lines to add.


Specifications — detail added by CJ after the first pass

These are CJ’s, not the transcript’s. Recorded separately so the build session can tell a decision from a reconstruction, and so the two ratified reversals inside them are visible rather than buried.

S-1 · The interest screen’s two actions

Renter view of interest carries exactly two controls:

  1. Schedule Rental
  2. Request Inspection — or Request Try-On where the item is worn

Label derives from the item, not the stage. Wearable → “Request Try-On”; everything else → “Request Inspection”. That is a chipLabel()-shaped derivation, so it stays out of STAGES[] and clears hard rule 1. The sample set already gives one of each: the Dyson Airwrap is a styler, not worn, so on the current three items the label is “Request Inspection” throughout — a wearable sample item would be needed to exercise the other branch. Worth adding one, screened by make and model against Terms v2.5 §8.4.

Gating — these two controls appear on exactly two screens: renter interest, and renter inspection-concluded. Nowhere else, and never on the lender view. This tightens CR-11 into a rule rather than a direction, and it matches Brad, 28:33: “you wouldn’t have those buttons during the inspection but you would like when they’re done.”

S-2 · The two request forms, and their preview

Hitting either control opens a form the renter fills in — a new screen in each case. What the renter submits is then rendered as a preview on the corresponding requested screen:

Control Form Preview lands on
Schedule Rental Propose rental pickup rental-requested, renter view
Request Inspection / Try-On Propose inspection inspection-requested, renter view

The preview is the point: today those two stages show the renter a pending card with no record of what they actually asked for. This is the acknowledged gap from 19:40.

Slots into HANDOFF §7 item 4 (eight form stages) — these are two of the eight, and they are now the two that block the workshop, so they come out of that batch and go first.

S-3 · Check-in states get the family treatment — four, viewer-relative

A dot and descriptor matching the Inspection family:

  • Check-in · Nobody arrived
  • Check-in · I arrived first
  • Check-in · They arrived first
  • Check-in · Both arrived

The “I / They” pair is one state seen from two sides, so it stays one stage with a derived label — no new entry in STAGES[].

Three things this exposes:

  • It reverses part of the batch-3 chip dictionary. See conflict C7 — and note I am recommending “Check-in ·” over “GPS Check-in ·” for a reason that came out of Brad’s own ask.
  • The current implementation cannot express “they arrived first.” CHIP_LABEL["gps-one-arrived"] is role === "renter" ? "You're here" : "Check-in · Waiting" — it hardcodes the renter as the early arriver, and the card copy underneath says “Brad checked in · Jun 24, 9:58 AM. Waiting for Zach.” To render all four labels honestly the card needs a who-arrived-first dimension, or the file documents renter-first as a fixed simplification. Pick one deliberately — silently keeping the hardcode while shipping a label that implies both directions is the worse outcome.
  • The checkin-one card body has to swap by viewer alongside the chip, or the chip will say “They arrived first” over copy naming the renter.

S-4 · The “I’m here” button, and a real QR code

“I’m here” appears on exactly two of the four states — the two where the viewer has not yet checked in:

  • Check-in · Nobody arrived
  • Check-in · They arrived first

Not on “I arrived first” (already in), not on “Both arrived” (past it).

Keep this distinct from Brad’s manual fallback. They are two different controls and v1.0 nearly merged them:

Control What it is Source
“I’m here” The tap that initiates a geofence check, instead of polling continuously Brad, 25:45 — CR-5
Manual check-in The fallback when that check fails — assert presence, evidenced by a photo of where you are Brad, 25:08 — NS-3, deferred to Jay

The second only exists because the first can fail. Building one and calling it done loses the failure path.

Real QR code, not a Generate button. The control lives on the checkin-both card, lender view: today role === "lender" ? [{label: "Generate QR"}] : [{label: "Scan QR"}]. Replace the lender’s button with an actual rendered code. Two things to settle before it is drawn — see conflict C8, because what the code is on decides a question the FSD and Brad currently answer differently. Also decide what it encodes; a spec document showing a scannable code that resolves to nothing is a small trap for whoever points a phone at it in the workshop.


New scope

Things that do not exist yet, and where they slot into HANDOFF §7.

# Item Slots
NS-1 Next-step action controls across all 23 stages (CR-1) Ahead of everything. Brad gates the Jay workshop on it, and it is his only structural objection. Displaces nothing — the check-in chains and form stages both need it to exist first, since it is how they are reached.
NS-2 Real item images (CR-3) Ahead of the workshop. Small, and it is the other half of Brad’s gate.
NS-3 Manual check-in fallback — button, plus photo-of-location evidence when the geofence fails §7 item 3, the check-in chains. Brad, 25:18: “that’s something that Jay wanted so that you could say, oh, I’m actually here, but then you have to take a picture of where you’re at or something.” Explicitly deferred: 25:30 “We could probably wait to talk to Jay on that.” The enums already carry MANUAL_PENDING / MANUAL_CONFIRMED / MANUAL_FAILED.
NS-4 “Request a change” on an agreed return — a bounded time/place adjustment, not a renegotiation §7 item 4, as a ninth form. Replaces any notion of a propose-return form.
NS-5 Collapsible past cards + a merged “Rental completed” summary (CR-6) New. Sits on top of the cumulative thread; do it before the all-stages view (§7 item 6), since the all-stages view inherits whatever the thread does.
NS-6 Simulated conversation woven between milestone cards New, and it is what makes the Chat and Timeline tabs differ. Brad, 37:22: “It pretty much looks like the timeline view is the same because there’s not a bunch of chatting between… I don’t know if you can have AI throw a bunch of stuff in there that might happen between some of these steps.” See conflict C4.
NS-7 Return-confirmation window — is there a deadline to confirm the item came back? Open question, not scope yet. Brad, 27:44: “do they have up until the last 1 second to return the item? Is there a time window for the person to confirm it was returned?” FSD §10.4 answers the analogous check-in case (auto-accept on expiry outside the geofence; dual-confirmation handback inside it) but does not obviously cover the try-on handback confirm. Route to Brad or the FSD.

Also raised and deliberately parked: edit / cancel controls on an already-scheduled meetup, and letting a party signal “I’ll be late.” CJ proposed it at 24:04; Brad parked it at 24:05“we can see what Jay says too… these are things we can add maybe later” — with the reason at 24:10: “I’m trying not to over-engineer the very first version we’re going to test.” Adjacent to Q4 but does not settle it.


Conflicts to resolve

C1 · The action dock — reversal of a ratified decision, and unsettled. Ratified (HANDOFF §5): No action dock, no brand header. Both were built and then removed by decision. The next-step copy now lives only in the capture notes; all actions live in the chat.” Brad, 36:44: “I don’t want the next step to be lost in the thing. That’s why I docked it above the message.” CJ, 21:18: “Feels like it covers up so much of the chat.” CJ’s counter-proposal, 28:48: “there’s more space here and it shows in the chat at the bottom but everything comes up above it… so it’s like the natural next step.” Brad’s response, 29:01: “I mean we can see how that feels. It feels weird that as you chat… I guess we can see how it feels. We can certainly do it that way until it’s built. We don’t really know, I guess.” And 36:53: “if you want to try, like docking it in the conversation where it can scroll away and see how that feels, we can do that for Jay.”Agreed: the controls come back. Not agreed: docked above the composer (Brad’s original, persistent) or in-thread above the composer (CJ’s, scrolls away). Brad conceded trying CJ’s version for the Jay review without endorsing it. Build CJ’s, label it as under test in the Styles panel, and put the choice in front of Jay. Whatever wins, the “no action dock” flag needs rewriting as a reversal with its reason so nobody restores it.

C2 · Blue own-message bubble — reversal, and no token exists. Ratified: “My chat bubble is surface-inverse, not brand red.” Brad, 39:15: “the white just feels… it feels off to me… It feels wrong. It just doesn’t feel right.” Brad, 40:08: “almost every single one of them is blue that I’ve looked at.” CJ, 41:04: “Oh, let’s do blue then.” Brad, 41:54: “Let’s just go with blue, I guess, for now. Because blue is like every single app. So maybe not depart from it too much for now.”Two problems. First, hedged: “for now”, “we’ll see”, “I guess” — three times. This is a direction, not a ratification. Second and harder: there is no blue in the BoRo token set. The DS carries the brand red ramp, stone surfaces and the status hues. Hard rule 2 says a colour value change is a DS-doc-first change, never a local edit. Adding a blue chat bubble is a new semantic token and a DS amendment — it belongs on the HANDOFF §9 list, which already has eight entries and none applied. Do not hand-add a hex to the file. → Also dropped mid-thread: CJ, 39:40, argued the counterparty’s bubble should carry the emphasis — “if we were to pop one the most, it should probably be the other side of the person you’re actually talking to, because you know what you’re texting and sending.” Brad answered with convention rather than reasoning (39:51: “your bubbles are the ones with the color”) and CJ let it go. CJ’s point is the better argument and was never actually answered.

C3 · Mutual QR — conflicts with the FSD, for the second call running. FSD §10.1: BoRo generates one code tied to the booking, displayable only inside the 100-ft geofence, valid only when both devices are inside at scan time. Brad, 26:56: “they should both have a QR code, or scan the other person’s QR code. Like, it should have, like, either or. So, like, one person can scan the other person’s. Whoever wants to do it.” → Note this sits one sentence after CR-4, where he says “should just have one.” The two are hard to reconcile; the charitable reading is one booking code displayed on both devices with either party able to scan. That reading is compatible with §10.1 and is what I would build. The literal reading — two codes, mutual scan — is an FSD amendment. Brad has now asked for mutual scan on two consecutive calls, so this is a settled preference, not a slip. Get the reading confirmed before the check-in chains are built, because both chains depend on it.

C4 · Simulated inter-milestone chat vs. SAMPLE_CHAT being Brad’s master. Hard rule 1: STAGES[], SAMPLE_CHAT and ALWAYS are Brad’s master” — byte-identical on every deploy, with labels, dates and copy derived in the presentation layer instead. NS-6 requires new messages. The obvious move — extending SAMPLE_CHAT — breaks the rule and the deploy check. → Resolution: build the filler as a separate presentation-layer array keyed by phase, leaving SAMPLE_CHAT untouched, or have Brad extend his own master. He asked for it, so he may well prefer the latter. Ask before writing.

C5 · A red no-show conflicts with “chip tone derives from status.” Ratified: tone comes from TONE_BY_STATUS, never a hand-picked hue; needsViewerAction / amberFor is the only override. terminated-noshow carries status terminated, which maps to neutral. Brad wants it red (36:11: “Instead of gray”). → Cannot be a one-off colour. Either terminated moves to error tone platform-wide — which would also repaint ordinary terminations — or a no-show becomes its own status. That is a data-model question, so it is Brad’s, and it is close enough to Q3 that both should be settled together.

C7 · “GPS Check-in” reverses a ratified rename — and Brad’s own ask argues against restoring it. Ratified in batch 3, and the file states the reason at line 2939: “three stages shared GPS Check-in, which named the technology rather than the state.” The rename produced Check-in · Waiting / You're here / Pair to start. S-3 proposes four labels prefixed GPS Check-in ·, putting the technology back. → Two separate changes are tangled here, and only one of them is a reversal. The four-state, viewer-relative structure is a clear improvement — it restores the Family · State pattern that You're here and Pair to start break, and it makes the two sides of one-arrived legible. The GPS prefix is the reversal, and I would not take it: Brad asked for a manual check-in fallback in the same call (NS-3), and the moment someone checks in manually a chip reading “GPS Check-in” is describing a mechanism that was not used. Check-in · survives both paths; GPS Check-in · does not. Recommend adopting S-3’s four states under the Check-in · prefix — CJ’s structure, the batch-3 reasoning intact. [CJ-DECIDE]

C8 · A real QR on the lender card quietly settles the QR model — the one thing still in dispute. Three positions are now live on the same mechanic:

  • FSD §10.1one code tied to the booking, displayable only inside the 100-ft geofence, valid only when both devices are inside.
  • Brad, 26:56“they should both have a QR code, or scan the other person’s… whoever wants to do it.”
  • S-4 — a real code rendered on the lender card, renter keeps “Scan QR.” That is lender-displays / renter-scans, which is a third model: not mutual, and not obviously the booking-code model either. → Drawing it is deciding it, and it is the substrate for both check-in chains (HANDOFF §7 item 3), so it gets built on twice. Settle C3 before this is drawn. The reading that satisfies all three: one booking code, rendered on whichever device is looking, either party able to scan the other’s screen — that is FSD-compliant, matches Brad’s “whoever wants to do it,” and means the lender card simply stops hiding it behind a button. If that is the intent, say so explicitly in the Styles panel, because the current asymmetric Generate/Scan split reads as a deliberate role assignment and nobody will know it was not.

C6 · A misstatement of the Lane B rule, spoken not built. CJ, 29:33, described Lane B as “the 30 day returns, you know, five 30 days segments.” Canon is five six-day segments to a 30-day maximum (FSD §13.1). The file is correct; only the spoken description was wrong, and Brad did not repeat it. Flagged only so it does not get quoted onward — worth a clean restatement at the Jay workshop, since Jay was not on this call to hear the correction.


Not actionable

Workshop with Jay confirmed for 9:00 AM Brad’s time tomorrow, and the two forms in S-2 plus the images in CR-3 are what Brad gated it on; with Brad aiming to have something testable by Tuesday if it lands (45:01); Brad re-confirmed the chat is the whole job — 51:35 “this chat thing is the biggest… It’s the whole ball game” — and asked for designs on the remaining screens only once it is done; CJ plans to move this work to Cursor. Cross-venture and tooling-cost discussion is out of scope for this doc.


Changelog

v1.2 — 2026-08-21. Added §Second-pass findings (N-1 to N-7) from a block-by-block coverage pass, and §Safeguards. N-1 materially narrows CR-1 — Brad blessed card-borne next steps, so only the two initiating actions need the contested placement. N-6 connects the next design ask to the FSD §14.5 listing gate. Nothing removed.

v1.1 — 2026-08-21. Added §Specifications (S-1 to S-4) from CJ’s post-review detail: the interest screen’s two actions and their derived labels, the two request forms and their preview, the four viewer-relative check-in states, and the “I’m here” gating plus the real QR code. Added conflicts C7 (the GPS prefix reverses the batch-3 rename) and C8 (a lender-side QR settles the disputed QR model by drawing it). Added §Corrections naming two gaps v1.0 dropped — the scheduling form at [19:40] and the QR screen at [24:40], both acknowledged on the call. Nothing from v1.0 was removed; CR-11 is now superseded in detail by S-1’s gating rule and CR-4 by S-4, and both originals are left in place.

v1.0 — 2026-08-21. First pass from the transcript, in the Review method v2.0 §8 format.