band-lane visual language · #625 · PRD-0007 · slice 1 · reuses the calibration ladder

Where a plant lived, and how it moved.

The range & movement band-lane view is the live counterpart to the calibration ladder: the same seven bands, same order, same --band-* tokens — but reading a chosen window instead of a static config. This page rules the visual language Data builds against: the marker set, the range whisker, the movement connector, the window selector, and the calm-empty & excluded states. Every choice is weighed against one test: does it claim more than the calibration can back?

The substrate: seven shared lanes

R1 · same names · order · tokens

Driest at the top, wettest at the bottom — the calibration ladder's exact orientation, so the two views read as one instrument. Bands are the only vertical scale; entities are placed onto these lanes, never given their own axis.

Parched air-dry
34003050 diagnostic — “probe may not be in soil”
Dry DRY
30502140 needs water
Drying needs water
21401830 thirsty, no rush
Ideal OK
18301520 comfortable
Moist well watered
15201150 thriving
Wet overwatered
11501050 refreshed
Saturated submerged
1050900 soaking it all in
interior boundaries A2-pending · solid = ratified endpoint (air-dry ceiling · submerged floor)

One window, three plants, five marks

the whole vocabulary at once

A 7-day window. Each plant is one column of marks on the shared lanes — a soft reach field (where it lived), a now dot (where it is), a from triangle + dotted connector (its last move), and reach diamonds capping the span.

Monstera · s1
Fern · s2
S3 · s4 provisional
Parched
Dry
Drying
Ideal
Moist
Wet
Saturated
provisional
① Monstera · s1
Ranged drying → wet this week; last move ideal → moist; sitting moist now.
② Fern · s2
Ranged dry → ideal; last move ideal → drying; drying now — thirsty, no rush.
③ S3 · s4
One reading, cal_verified=false — an open ring, no reach or move claimed until it ratifies.

Marker set — the ruling

reconciles the one-off · R2 · R4 · R7

The one-off reached for filled/open circle, triangle and diamond. Ratified into five marks, each with exactly one job — so a shape never means two things, and no mark ever claims a reading we don't have.

Now dot — filled circle
Current band, from a cal_verified=true reading. Filled in the band's own color. Exactly one per entity.
Provisional ring — open circle
Same “now” role, but cal_verified=false. The hollow centre is the absence signal — a lane we can place but not yet certify. Never earns a reach or connector.
From triangle — hollow triangle
Where the entity started this window. The apex points toward the now dot — that's the direction of travel. Hollow, so it never reads as a live reading.
Reach diamond — hollow diamond, ×2
Caps the reach field at the wettest and driest bands touched. A distinct shape on purpose — an extent mark, not “a reading is here now.”
Movement connector — dotted, stepped
Links observed positions from-dot to now. Dotted, never solid — a transition between two readings, not a continuous path. See below.
hard rule
No mark ever lands on the Parched (air-dry) lane for an unwired or NO_SIGNAL entity. Air-dry doubles as “probe may not be in soil” — a dot there would fabricate “bone-dry.” Those entities get no mark at all.

Reach: band-span, not raw min–max

R3 · evidence-weighted

The open question: a band-span whisker, or raw min–max mapped onto the lanes? While the interior boundaries are A2-pending, sub-lane precision is precision we can't back. Band-span wins for v1.

✓ chosen — band-span
Drying
Ideal
Moist

Caps snap to whole lanes. Claims only “it was in these bands” — exactly what calibration supports today.

✗ deferred — raw min–max
Drying
Ideal
Moist
↑ implies exact interior cut

Sub-lane caps read as exact ADC boundaries — but those cuts are A2-pending. Returns once interior boundaries ratify.

Movement: discrete, never continuous

R4

Movement is drawn from the readings we actually took. A smooth diagonal invents the moments between them; a dotted step-connector says “was here, now here” and nothing more.

✓ chosen — dotted step + from-triangle
Drying
Ideal
Moist

Two readings, two marks, a dotted link. Reads as a jump between observations — faithful to what we saw.

✗ rejected — solid interpolated line
Drying
Ideal
Moist
invents every band in between

A continuous slope claims the plant passed smoothly through Ideal at a known rate — a reading we never took.

Window selector

R5 · reuses the range vocabulary

One segmented control, the same words the rest of Sprout already uses for ranges. Two anchors: a short event (~15 min — watch one watering play out) and a long horizon (a dry-down cycle).

15 min 1 h 24 h 7 d since last re-water
event · 15 min
Dry → watered → diffusing → resettling to a new moist median. Marks are dense; connector shows each observed step.
horizon · 24 h / 7 d
A full dry-down. Reach field is the story; the connector reduces to the net from → now move.
provisional · since last re-water
Needs a watering-event stream that doesn't exist yet. Ships disabled with a dot until that anchor lands — never guessed from a wet jump.

Calm-empty & excluded states

R7 · R8 · consistent with #486

An unearned mark is the one thing this view must never draw. Four ways a row can have nothing to place — each says so plainly, in Sprout's voice.

— NO_SIGNAL / unwired
no band placed
“I can barely feel my soil — am I truly bone-dry, or has my sensor slipped?”
No mark on any lane — least of all Parched. The row holds its place; the reason is named, not dramatized.
cal_verified = false
open ring · provisional
Position placed, authority withheld — a hollow ring and a provisional tag.
No reach or connector until the band ratifies (C1 · #170). Bands render, authority doesn't.
EMPTY WINDOW
lanes drawn · no marks this window
The entity is wired and calibrated — it simply hasn't reported inside the chosen window yet.
Lanes stay visible so the scale is legible; a quiet line says “no readings in this window yet.”
EXCLUDED · per-device fence
belongs to another device group
An entity belongs to exactly one device — no cross-device roll-up onto shared lanes.
Filtered-out entities are named as out-of-scope, never silently merged into another device's picture.

Guardrails

what stays true no matter how the live view is built
1
Bands are the only scale. Raw + band words, never a %. The lanes carry wet→dry; a mark's job is position and identity, not a number.
2
Never claim an unobserved reading. Reach snaps to whole bands; movement is dotted and discrete; empty is empty. Precision we don't have is precision we don't draw.
3
Air-dry is ambiguous, so it's diagnostic. A NO_SIGNAL or unwired entity earns no mark — never a false “bone-dry” on the Parched lane.
4
One device, one fence. Entities never roll up across devices; the shared lanes are a scale, not a merge.
the split Design rules the marker set, the reach/movement semantics, the window vocabulary and the calm-empty states here. Data builds the live view against them — R6 live cadence, R9 identity/provenance from the registry, and the interior-boundary refit once A2 ratifies.