docs: update design-principles for _Measure and fixed-point eval

Add VirtualMeasure to CategoryKind description, document _Measure as
third always-present virtual category, add section on fixed-point
formula evaluation strategy.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Edward Langley
2026-04-09 02:44:41 -07:00
parent 326e245c48
commit 001744f5cf

View File

@ -60,12 +60,14 @@ editing) is two commands composed at the binding level, not a monolithic handler
- `Binding` is `Cmd | Prefix | Sequence`. The keymap lookup returns one of these - `Binding` is `Cmd | Prefix | Sequence`. The keymap lookup returns one of these
three shapes; dispatch pattern-matches exhaustively. three shapes; dispatch pattern-matches exhaustively.
- `CategoryKind` is `Regular | VirtualIndex | VirtualDim | Label`. Business rules - `CategoryKind` is `Regular | VirtualIndex | VirtualDim | VirtualMeasure | Label`.
(e.g., the 12-category limit counts only `Regular`) are enforced by matching Business rules (e.g., the 12-category limit counts only `Regular`) are
on the enum, not by checking name prefixes. Virtual categories (`_Index`, enforced by matching on the enum, not by checking name prefixes. Virtual
`_Dim`) exist solely for drill-down mechanics and must never leak into categories (`_Index`, `_Dim`, `_Measure`) always exist: `_Index` and `_Dim`
user-facing logic — use `Model::regular_category_names()` when selecting a support drill-down/records mode; `_Measure` holds numeric data fields and
default category for formulas, prompts, or other user-visible choices. formula targets (added automatically by `add_formula`). Use
`Model::regular_category_names()` when selecting a default category for
prompts or other user-visible choices.
### When You Add a Variant, the Compiler Finds Every Call Site ### When You Add a Variant, the Compiler Finds Every Call Site
@ -157,6 +159,16 @@ A formula is a serializable struct: raw text, target name, category, AST, option
filter. It is stored in the model alongside regular data. The evaluator walks the filter. It is stored in the model alongside regular data. The evaluator walks the
AST at read time. Formulas never become closures or runtime-generated code. AST at read time. Formulas never become closures or runtime-generated code.
### Formula Evaluation Is Fixed-Point
`recompute_formulas(none_cats)` iterates formula evaluation until values
stabilize. Each pass evaluates all formula cells using the current cache
(for formula-derived values) and raw data aggregation (for data values).
This avoids recursive evaluation through `evaluate_aggregated` and
naturally handles chained formulas (`Margin = Profit / Revenue` where
`Profit = Revenue - Cost`). Circular references converge to
`CellValue::Error("circular")` after `MAX_EVAL_DEPTH` iterations.
### Display Rounding Is View-Only ### Display Rounding Is View-Only
Number formatting (`format_f64`) rounds for display. Formula evaluation always Number formatting (`format_f64`) rounds for display. Formula evaluation always