Skip to content

Math signals reach the plot, the signal views and an MDF export - #474

Draft
thebhef wants to merge 1 commit into
task135-editorfrom
task135-surfaces
Draft

Math signals reach the plot, the signal views and an MDF export#474
thebhef wants to merge 1 commit into
task135-editorfrom
task135-surfaces

Conversation

@thebhef

@thebhef thebhef commented Sep 6, 2026

Copy link
Copy Markdown
Owner

A math signal was created and edited under the Database panel's
Computed branch and went no further: it could not be dragged, no plot
or signal view could show one, and a save carried none. This finishes
the surface.

The drag payload gains a math provenance slot, so a Computed row drags
like any other signal — carrying the definition's stable id, never its
display name. The plot's side list and a signal view's rows both grow a
math row: the app's standard disclosure, one bus color chip per bus
feeding the series (transitively, through any math operands, resolved
host-side), and "Math - Multiple Busses" when several do. Expanding a
row opens the same in-place editor phase 2 built, on whichever surface
invoked it.

Three things had to be built under that.

The math flag was dropped from the plot's sample_signals and
signal_min_max queries, so a math series dropped on a plot would have
been keyed as a DBC identity nothing decodes and served empty. Both
queries now carry it, and the panel test asserts the points reach the
canvas rather than only the request.

A signal view's math rows are host rows: select_math is
select_file_backed's shape one provenance further — only a manual key
selects one, since a math series has no canonical path for a pattern to
match. Their values come through math_latest, which runs
slice_many's prologue: a math pyramid is session-scoped, so a row has
to drive the fill rather than read what happens to be there. Expansion
made the row pitch variable, using the VariableRowHeights the shared
viewport scaffold already offers the by-id table.

hline and statistic now draw solid. Both are two points spanning the
capture, and ADR 0026's first rule would dash both wings as a hold past
their own data — but a value the user authored is the data, not the plot
inferring. The suppression is in the model, at the one place that
classifies, so the renderer still styles what it is told. ADR 0026
records the exception and its scope: a decoded one-sample series is
still dashed.

Export: MDF carries each math series as an already-decoded channel under
a Computed acquisition group, on the file-backed precedent. The
definition is not written — there is nowhere in the format to say "the
median of these six signals" that a reader would understand, and the
project file keeps it. BLF carries none and now names the computed
signals it drops beside the file-backed ones.

The ADR 0031 harness grows its math case behind --math-on-start: a set
function over a live pattern, an exponential filter, a capture-wide
statistic, and one math-over-math chain, defined over whatever project
the launch opened. A flag rather than a project of its own because
growing examples/ev-zonal would invalidate every reading taken against
it. Defining costs nothing on its own — a math pyramid is built by a
serve — so the flag also puts the series into the open plot areas and
signal views, which is what a person measuring would do by dragging them
there; nothing reaches the project file.

Reviewers should look at select_math and math_latest (a signal
view's poll now drives a fill), at MathFill::constant and the ADR
amendment beside it, and at withPerfMathCase, which writes into live
element configs at launch.

thebhef commented Sep 6, 2026

Copy link
Copy Markdown
Owner Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

A math signal was created and edited under the Database panel's
Computed branch and went no further: it could not be dragged, no plot
or signal view could show one, and a save carried none. This finishes
the surface.

The drag payload gains a math provenance slot, so a Computed row drags
like any other signal — carrying the definition's stable id, never its
display name. The plot's side list and a signal view's rows both grow a
math row: the app's standard disclosure, one bus color chip per bus
feeding the series (transitively, through any math operands, resolved
host-side), and "Math - Multiple Busses" when several do. Expanding a
row opens the same in-place editor phase 2 built, on whichever surface
invoked it.

Every drop target that can now receive that payload forwards the flag:
the plot's side list, a signal view's wire selection, and — the one this
branch first missed — the math editor's own operand sections, which
narrow a dragged ref to a `MathOperandRef` field by field. Math-on-math
is documented and already worked through the operand combobox, so a
dropped math signal that arrived with the flag stripped named a DBC
identity nothing decodes and read back as "operand missing". A DOM test
drops a `math: true` payload on a `Signal` section and pins the
committed pick.

The Database panel's own value column carries computed signals as well,
so a definition shows what it currently evaluates to right where it is
edited. A math row keys like every other value row — ADR 0052's rule
one provenance further: no bus, message id 0, the definition's stable
id in the signal slot under a `math` flag — so the panel's existing
paged `fetch_signal_page` serves a computed value beside a decoded one,
for the viewport's rows only. The listing those rows read moved out of
the panel into a shared `mathSignalsContext`, on one set of host
events, which is what keeps this panel, a plot's side list and a signal
view from answering differently about the same definition.

That column also made the row's layout matter. `.dbc-row` is a flex row
whose items shrank in proportion to their content, so a long comment
kept a large share of the width while the name ellipsized and the value
cell lost its tail — which is where the unit sits, and a value without
its unit is the one thing on the row that misleads. The comment yields
first now (a shrink factor that swamps the others', down to a `6ch`
stub that still says a comment is there); the name and the value hold
their content until it is spent. It is flex geometry, so jsdom cannot
assert it: both rules carry the constraint they encode as a comment,
and the check is an eyeball on a narrow panel.

Three things had to be built under that.

The `math` flag was dropped from the plot's `sample_signals` and
`signal_min_max` queries, so a math series dropped on a plot would have
been keyed as a DBC identity nothing decodes and served empty. Both
queries now carry it, and the panel test asserts the points reach the
canvas rather than only the request.

A signal view's math rows are host rows: `select_math` is
`select_file_backed`'s shape one provenance further — only a manual key
selects one, since a math series has no canonical path for a pattern to
match. Their values come through `math_latest`, which runs
`slice_many`'s prologue: a math pyramid is session-scoped, so a row has
to drive the fill rather than read what happens to be there. Expansion
made the row pitch variable, using the `VariableRowHeights` the shared
viewport scaffold already offers the by-id table.

Math series stay out of the **View signals** panel. That panel is a
database-mapping repair surface — every status it reports is a claim
about what a DBC now says — and no database ever bore on a math series:
pushed, one appeared there under its definition's stable id, flagged
over a unit only its own editor can set. The two builders that turn a
view's configuration into pushed references (`viewSignalsPush.ts`) drop
math-provenance picks. The frontend can decide that on its own, because
provenance rides on every persisted pick, so the wire shape needs no
math flag; and a pattern can never reach one either, since the catalog
those views match against holds no math signals.

`hline` and `statistic` each draw as one solid horizontal line, and the
model owes them two separate things to get there.

*What the series holds.* A capture reaches a serve in pieces — a live
bus grows it, a stopped one decodes under a budget — so a constant's
fill runs several rounds, and a statistic's answer over what has decoded
moves with every one of them. Appending each round's answer left the
earlier, partial ones beneath the line, so a statistic drew as the
rising staircase that produced it rather than as the line it names. A
round now returns the *whole* line at the value it holds and replaces
the series with it (`SignalCache::rewrite`), which also resets the
widen-only extent the plot auto-normalises against: a stale floor there
scales the axis to a value the series no longer holds. It costs two
pushes, a constant being two points, and it keeps a live `hline` at two
points rather than one per serve as well.

*How it is styled.* Two points spanning the capture is the shape ADR
0026's first rule dashes on both wings, as a hold past their own data —
but a value the user authored is the data, not the plot inferring. The
suppression is in the model, at the one place that classifies, so the
renderer still styles what it is told. ADR 0026 records the exception
and its scope: a decoded one-sample series is still dashed.

Export: MDF carries each math series as an already-decoded channel under
a Computed acquisition group, on the file-backed precedent. The
definition is not written — there is nowhere in the format to say "the
median of these six signals" that a reader would understand, and the
project file keeps it. BLF carries none and now names the computed
signals it drops beside the file-backed ones.

The ADR 0031 harness grows its math case behind `--math-on-start`: a set
function over a live pattern, an exponential filter, a capture-wide
statistic, and one math-over-math chain, defined over whatever project
the launch opened. A flag rather than a project of its own because
growing `examples/ev-zonal` would invalidate every reading taken against
it. Defining costs nothing on its own — a math pyramid is built by a
serve — so the flag also puts the series into the open plot areas and
signal views, which is what a person measuring would do by dragging them
there; nothing reaches the project file.

Reviewers should look at `select_math` and `math_latest` (a signal
view's poll now drives a fill), at `MathFill::constant` — which is what
both the rewrite and the styling turn on — and the ADR amendment beside
it, and at `withPerfMathCase`, which writes into live element configs at
launch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant