Repository navigation
registry: cars apart from chargers, their ops and car.which - #92
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
ftw-webapp | 9433bdc | Commit Preview URL Branch Preview URL |
Oct 15 2026, 08:36 PM |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1aad863d03
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| # and more than one car. Once per plug-in. The event names the charger | ||
| # and the cars by opaque id; the phone shows one button per car, fills | ||
| # in their names from its own table, and a tap sends session.car.set. | ||
| title: Which car is plugged in? | ||
| body: "Tap the car so the box plans for its level and goal." |
There was a problem hiding this comment.
Implement the car selection flow before advertising this push
When a box emits car.which, the promised interaction cannot occur: src/sw.ts only preserves loadpoint_id for charging.* notifications, supplies no notification actions, and handles a click by opening the root page, while no app code reads the car IDs or sends session.car.set. The user therefore sees “Tap the car” but has no car to tap, leaving the session unidentified and preventing planning from using the intended level and goal. Wire this event to a picker/action handler, or defer the event until that flow exists.
Useful? React with 👍 / 👎.
A car belongs to its owner and visits chargers. The registry names the car, its level and goal, the ops that set them, the session a tap names, how the box knows which car is on a charger, and the car.which push. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
0907c27 to
9433bdc
Compare
What
A car belongs to its owner, not to the home, and visits chargers. These are the names for it, edited here first as the registry rule says. The design is
design/vehicles/car-entity-2026-10-15.mdin the FTW stack workspace (Fredrik, 15 Oct 2026); the wire and the rules aredocs/cars.mdin srcfl/ftw (the paired PR below). Rebased onto main after #90 (agents) as one commit. Two reviews shaped it.car_fields: id (128 bits; the owner's app mints it),boxMinted, a reservedownerId, name, make, VIN, capacity, the car's own charger limits, the level (socPermille,socSource,socAgeS,energySinceWh,socEstimate,chargeLimitPermille), the goal (targetPermille,readyByMin,days,finishAtLimit),surplusOnly, identifiers and sources.socPermilleis the car's own number untilsocEstimate. Ages count from send, never the box's wall clock.car_soc_sources:vehicle,manual,assumed. A visitor gets no level at all. A level read before the car last left a charger is an estimate.car_identified_by:charger,car,only,tap,asking,none.askingis the box waiting for a tap aftercar.which.charger_car_fields:session(the plug-in's id, which a tap names),carId,carIdentifiedBy,carCorrected,carCorrectedFrom,choose(at most four cars a tap may pick).car.goal.set,car.soc.setandsession.car.setunderftw.dispatch.write, so a watch can make the one tap.car.add,car.updateandcar.removeunderftw.cars.write, which only the owner role carries. Arguments follow the box's convention: snake_case,id, fractions;car.goal.settakes its goal flat (target,ready_by_min,days,finish_at_limit,clear), asagent_argsneeds.car.goal.setandcar.soc.setcarryagent: ftw.goals.request, withagent_argsnaming the car by kindcar(new; the opaque id fromcars.get) or the charger by kindloadpoint.session.car.setand car CRUD stay closed to agents.ftw.cars.read(the unredacted list) andftw.cars.write. RefusalsE_DUPLICATE; an unknown car or charger is registry: agents, their scopes, refusals and push kinds #90'sE_NOT_FOUND. Capabilityder.car. Push kindcar.which.In this app:
contract.tsgets the scopes,messages.tsthe op constants and the refusals,kinds.tsthe push toggle, and the simulator answers the car ops withE_UNKNOWN_OP, as a box withoutder.cardoes.registry-contract.test.tschecks the car blocks' shape. Nothing visible changes until a box sendscar.which.With #90 (agents)
#90 landed first. This branch is rebased onto it: one
E_NOT_FOUND, the agent keys andagent_argsabove, agreed with the core-agent-role session. Core resolves kindcaronce srcfl/ftw#1646 (agents in Core) and srcfl/ftw#1650 have both landed; whichever is second wires it.Paired PRs
go/protocoltypes, FTW Cloud'scarclass with an opaque id cut withcar\0, anddocs/cars.md.Contract.swiftand the push text in English and Swedish.Merge order: this PR, then srcfl/ftw#1647 and srcfl/ftw-app#70, then srcfl/ftw#1650. The pair lines name commits rather than branches, so they still resolve once the other side has merged and its branch is gone.
Contract-pair: srcfl/ftw@a515d7d
Tests
npm run verifyon the rebased commit 9433bdc: 1,104 tests passed, 1 skipped, withsvelte-checkand the build.🤖 Generated with Claude Code