feat(train): equipment by place and a plate calculator (ADR 0034)

The places a person trains at (home, a gym), each a sealed, synced
`training_place` row with its equipment: bars and handles with their own
weight, plates by weight and count, dumbbells and kettlebells, the rest
by count, the person's own by name. A new place starts from what a home
or a gym usually has. The place last chosen is remembered on the device,
never its location.

The plate calculator loads each weight both sides alike, the heaviest
load not above it with the fewest plates, heavier inside, and over a
series of sets picks the loads making the fewest plate moves, listing
what comes off and goes on. Equipment is in Settings; strength plans
are to build on it.

The migration only creates the table, its space index and its cascade
to the sync engine's spaces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-11-02 11:59:24 +01:00
commit 064b911aa2
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -0,0 +1,88 @@
# ADR 0034: Train's equipment by place, and plate maths
- **Status:** decided 2 Nov 2026, by the developer (D1–D4, the agent's recommendations
taken), the rest proposed by the agent and flagged where it chose.
- **Numbering:** 0025–0029 are held (ADR 0030's note); this is the next free number.
- **Builds on:** ADR 0030 (Halkyon Train): D7 (sealed rows), D12 and D60 (the shell, its
Profile and Settings), D19 (no background location), D42 (interval plans); ADR 0002
(the envelope a row is sealed in).
## Context
On 1 Nov 2026 the developer asked whether Train has an inventory: whether they can tell
it that they own dip bars, dumbbells, barbells and so on, with how many weight plates of
which weight; that training plans then use it and work out "the least number and amount
of work necessary to change the weight plates from one [weight] to another"; and that the
inventory be bound to a place, home's apart from a gym's, the training offered adjusting
to it.
Train has nothing of it: it records cardio and runs interval plans (D42), whose steps end
after a time, a distance or a lap, with targets of pace, heart rate, power or stroke rate.
No model holds an exercise, a set, a repetition or a weight.
## Decision
1. **This step builds the inventory and the plate maths; strength plans and recording
them come next**, on top of them (D1, the developer's choice of 2 Nov 2026). A plan's
sets, their order and the plate changes between them need both, and both are worth
having alone: the inventory says what a place has, the plate calculator what to load.
2. **The inventory is a catalogue with the person's own items beside it** (D2). Train
knows the kinds it can reason about, so that plans can rely on them:
- **loadable**, taking plates, each with its own weight: barbell, EZ bar, trap bar,
dumbbell handle;
- **plates**, by weight and count, one set a place;
- **weights by weight and count**, not loadable: fixed dumbbells, kettlebells;
- **present or not, with a count**: bench, rack, pull-up bar, dip bars, cable
machine, resistance bands;
- **the person's own**, by name and count, which plans can name but not reason about.
Weights are kept in grams, whole numbers, so that sums are exact (1.25 kg is 1250 g);
they are shown and typed in kilograms. Plates in pounds are left for later (the
person types their kilograms, 20.41 kg for a 45 lb plate).
3. **Plate maths: both sides alike, the heaviest load not above the target, the heavier
plates inside** (D3).
- A barbell's load is its own weight and the plates on its two sides, the same on
each: a plate is used on a side only as often as the place has it twice over. A pair
of dumbbells takes four of each plate (two handles, two sides).
- The load chosen is the heaviest the plates make that isn't above the target, and the
calculator says how far below it is; among loads of that weight, the one of fewest
plates.
- Plates go on heaviest first, so that a side reads from the inside out as heavier to
lighter, as in a gym.
- **Between loads, only what must come off does**: a side is a stack, its innermost
plates stay as long as the next load starts with them, the rest come off from the
outside and the next load's go on. For a series of targets (a plan's sets, later),
among the loads of each target's weight, those are chosen that make the fewest plate
moves over the whole series (a shortest path through them). The calculator lists the
moves per side: "take off 1 × 5 kg, put on 2 × 10 kg".
4. **A place is chosen, and the last one remembered** (D4). The person picks the place
(Home, Gym…) where its equipment matters, the plate calculator now and plans later;
Train remembers the last on the device. It never asks for the device's location for
it, keeping D19.
5. **A place is a sealed, synced row of its own** (the agent's, following plans and
routes): the table `training_place`, its payload a place's name and items, versioned
JSON, sealed with the person's key (D7); one row a place, so two devices editing two
places never collide, and the same place the last writer wins, as with plans. The
migration only creates the table, its space index and its cascade to the sync engine's
spaces, as `routes` did; deleting a person deletes their places with their space.
6. **Where it shows** (the agent's): Settings gets *Equipment*, beside the body's figures:
the places, each with its items, a new place starting from what a home or a gym
usually has, every item editable; and the plate calculator, from Equipment and from a
place: a target, the bar or handle, the plates per side, and for several targets the
moves between them.
## Consequences
- Strength plans (exercises, sets, repetitions, weights, rest) are the next step: a plan
names its place's equipment, and the plate maths of D3 orders the moves between its
sets. What an exercise needs (a bench, a rack, dip bars) is checked against the place
chosen, which is how "the training offered adjusts" to it.
- Gyms' bars sometimes weigh other than 20 kg, and collars add weight; both are items a
person edits (a barbell's own weight), collars left out of the maths for now.
- Pounds, micro-plates' own increments and a sleeve's length (how many plates fit) are
left for later; the calculator never loads more plates than a place has.