feat(core): add a property catalog and derive its discovery channels#16
Merged
Conversation
PlotX had a command catalog but no parameter catalog. Around 150 controls were scattered across separate windows with no shared registration, and the command palette matched only a command's label, so no parameter was in the searchable set at all. Contour settings were the extreme case: base, count and ratio were hard-coded constants with no way to reach them. Introduce a catalog where registering a parameter once yields its description, addressing, reading, validation, and every way a user can find it. A definition carries identity, scope, schema, capability-based applicability, default policy and panel tier; presentation carries localized labels and the route back to the control. Each rule is declared once: tier lives on the definition and presentation reads it, and a numeric bound is a single declaration that a control's range and the writer's validation both consult. Real parameters stay in their strongly typed domain models. The catalog describes, addresses, reads and validates, then compiles an edit into a typed Action; there is no `HashMap<PropertyId, PropertyValue>` state store. A contour setting is addressed as a plot object plus a `SeriesId` component, not as the dataset that happens to hold the data, and not as the field the series draws from. The panel, the palette, the context menu and the canvas gesture reach the same planner and the same typed Action. The gesture passes a direction rather than a value, so the step is computed and validated where a typed value would be. Page and object activation likewise share one path, so navigating from the palette cannot leave a selection pointing at a page-local id that now names a different object. Reads aggregate instead of electing a representative. A contour ladder keeps a positive and a negative half that share base, count and ratio, so even a single-target read is an aggregate: when the halves or the selected series disagree, the value is mixed, the control shows no number, and no resolved level is captioned beside it. Writes are validated against a working copy and folded into one atomic Composite Action, so a rejected value lands nowhere; a reset stays inside the encoding it names and re-derives the value under the policy in force rather than under the one the factory would have chosen. Contour levels are anchored to a noise floor rather than to thermal noise alone. A homonuclear phase-sensitive plane carries t1 ridges and solvent residual that scale with its strongest feature, far above the thermal sigma a robust estimator measures: on a 2048x8192 NOESY the whole 5-sigma ladder topped out at 0.125% of peak, entirely inside that structure, and asked the renderer for 8.4 million segments — a gigabyte of index buffer, which is a crash rather than a plot. The anchor now multiplies the larger of the estimated scale and a fraction of the field's peak, calibrated at the knee where contours stop following the artefact floor, and the readout names which term is in force. A field whose sigma clears the floor resolves exactly as before. Geometry is additionally bounded by what the renderer can draw, dropping whole magnitudes from both signs together and saying which and why, so no field can take the process down. Discovery derives from that single registration: search over commands, parameters and resources; a Ribbon and context-menu landing point that opens, expands, scrolls and highlights by declared route; and bare `+`/`-` on the canvas, which multiplies or divides the lowest level by the ladder's own ratio so one press moves it by exactly one drawn rung at any magnitude. A hit with no applicable target is disabled with a reason instead of navigating nowhere, and the level shown on the plot is read from the series the gesture would edit. While an estimate or a geometry is being computed the status line says so, so a plot that is still empty is never silent about why.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PlotX has a command catalog but no parameter catalog. Around 150 controls are
spread across separate windows with no shared registration, and the command
palette matches only a command's label — so no parameter is in the searchable set
at all. 2D contour settings were the extreme case: base, count and ratio were
hard-coded constants with no way to reach them.
This adds a parameter catalog where registering a parameter once yields its
description, addressing, reading, validation, and every way a user can find it:
search, a Ribbon and right-click landing point, and — where the parameter has a
direction — a canvas gesture. Contour settings are the first parameters to go
through it, so they are now adjustable, findable, and readable in the units they
actually mean.
Reviewing the result against a real spectrum turned up a crash that already
exists on
main, so it is fixed here too — see Contour levels below.What changed
Three-layer separation
plotx-coreholds the semantic definition: identity, scope, value schema,access, capability-based applicability, default policy, tier, canonical label
and aliases. The app crate holds presentation: localized label, aliases, and
the route back to the control.
reads it; a numeric bound is a single declaration that a control's range and
the writer's validation both consult, so a value the panel accepts cannot be
one the writer rejects.
describes, addresses, reads and validates, then compiles an edit into a typed
Action. There is no
HashMap<PropertyId, PropertyValue>state store.Addressing
Seriescomponent —not as the dataset that happens to hold the data, and not as the field the
series draws from. Two series of one object that read the same field are
edited independently.
lookup, so a malformed address is rejected by identity rather than by
accident.
One canonical home, several editors
planner and the same typed Action. The gesture passes a direction, not a
value: the step is computed inside the planner against the same working copy
and validated by the same write path, and a test asserts a stepped result is
identical to the one a typed value produces.
from the palette carries the selection and data focus with it. Object ids are
page-local, so a selection left behind by a page switch could otherwise name a
different object entirely.
Reads aggregate rather than pick a representative
and ratio, so even a single-target read is an aggregate. When the halves — or
the selected series — disagree, the value reports
Mixed, the control shows nonumber, and no resolved level is captioned beside it. An edit then applies to
all of them, which the control says up front.
can mask the other. A definition declares how many copies of the value a
single target holds, so the interface can say which kind of disagreement it is
without knowing what a contour is.
including the fallback to a page's active plot and the aggregate over several
selected plots — so a setting the Ribbon offers is a setting the panel shows.
Writes are atomic and stay in scope
returns before any action exists, so nothing lands. Every series of an object
folds into one binding edit, and the whole set commits as one Composite Action
with normal undo. Targets that cannot take the value are reported with a
reason rather than dropped.
leaves a heatmap or line overlaid on the same plot untouched. Resetting a
single value re-derives it under the policy currently in force rather than the
one the factory would have chosen, so a reset cannot advertise a value the
current anchor would refuse.
Contour levels
fraction of the field's peak. A homonuclear phase-sensitive plane carries t1
ridges and solvent residual that scale with its strongest feature, far above
the thermal sigma a robust estimator correctly measures — so a ladder anchored
to sigma alone can sit entirely inside that structure. The peak fraction is
calibrated at the knee where contours stop following the artefact floor, and
the readout names which term is in force, so a floored level never reads as a
multiple of sigma.
a test pins by resolving the same field with and without the floor.
would exceed it, whole magnitudes are dropped from both signs together — never
a partial trace — and the status line says how many, below which level, and
what to raise the lowest level to in order to see them all.
million segments and a gigabyte of index buffer, which aborts the process.
That default reached
mainearlier in this series; the plot it produces isempty until the moment it crashes.
Discovery derived from one registration
matching identifier tokens, canonical labels and aliases, and locale terms. A
hit with no applicable target is shown disabled with the reason, rather than
navigating to a row that is not there.
the panel, expands the section, scrolls and highlights briefly. Navigation is
data — a route no panel declares is rejected rather than scrolling nowhere.
+/-raise and lower the lowest contour level, multiplyingor dividing by the ladder's own ratio so one press moves the floor by exactly
one drawn rung at any magnitude. The level shown on the plot is read from the
series the keys would edit, and several series that disagree say so rather
than showing the first one's.
with no second registration, which is asserted by registering a parameter that
exists nowhere else and checking each channel picks it up. A brand-new group
still needs one group entry — a label, icon and placement cannot be inferred —
and a test fails the build if a section lacks one.
Nothing waits in silence
so a plot that is still empty is never unexplained. The messages name the work
rather than the plot, since the jobs are content-addressed and shared across
objects.
materialized, so repeated rebuilds during the wait no longer copy the whole
field each frame.
Panel budget
Essentialby default withAdvanced/Expertcollapsed.Non-default values carry a modified marker with the default on hover and a
one-click reset. A test fails the build when a section exceeds its Essential
budget, naming the offending entries and asking for re-tiering rather than a
higher limit. Only the lowest contour level is Essential.
Two contour defaults corrected
longer hand a signed magnitude to a field that has both signs. The result is
unchanged on the single-signed fields the capability admits.
literal, which silently drew nothing whenever a field's peak was below one.
Compatibility
Pre-release: no backward compatibility is kept for older project files. The
project schema version is unchanged. The catalog stores no parameter values of
its own, so it adds nothing to the saved project.
+and-were unbound;existing zoom shortcuts use them only with a modifier.
Out of scope
Automation access to properties, and migrating the remaining parameters into the
catalog, are separate changes. The level readout is currently specific to
contours; a second steppable encoding would want it generalized. The noise-floor
fraction is calibrated against one real spectrum plus synthetics, and the
constant carries a note saying when to re-measure it.
Testing
cargo pr-checkpasses: formatting, the source-size limit, dependency policy,Clippy with warnings denied, and the test suite on both the reference and
DataFusion backends.
npm run buildpasses for the documentation.Catalog consistency is enforced by tests: every user-visible parameter has a
presentation, every presentation points at a valid definition and reads its tier
rather than repeating it, stable ids are unique, every route resolves to a
declared section, every section has a group, aliases are reachable from the
search index, and at most one parameter claims the canvas gesture.
Behavioural tests cover addressing a contour setting by series and rejecting the
object, dataset and field addresses; the source field not acting as the
component; component shape being rejected before any document lookup; several
series of one object folding into a single action; a rejected value aborting the
whole commit; a stepped value landing exactly where a typed value would; an
asymmetric ladder reading as
Mixeduntil a write converges it; a ladder with nonegative half reading as uniform; both directions of cross-target and
within-target aggregation reaching the panel; a page activation not carrying a
stale selection onto the new page; an encoding reset leaving a stacked encoding
untouched; a reset re-deriving under the anchor in force; a mixed row carrying no
resolved level; a field whose sigma clears the floor resolving identically with
and without it; both halves sharing one floor; a dense ladder being bounded and
reporting what it dropped; and a pending estimate or build naming itself.
The derived-data invariants established for contour geometry still hold and are
extended: repeated readouts against warm caches queue no estimates, queue no
geometry, materialize no field payload, and run no marching squares on the
calling thread — and rebuilding while a job is in flight adds no materialization
at all.