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
3400 – 3050 diagnostic — “probe may not be in soil”
Dry DRY
3050 – 2140 needs water
Drying needs water
2140 – 1830 thirsty, no rush
Ideal OK
1830 – 1520 comfortable
Moist well watered
1520 – 1150 thriving
Wet overwatered
1150 – 1050 refreshed
Saturated submerged
1050 – 900 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.