fix(core): a model over a source refuses every write in every build and drops its own cells (improvise-rnak)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
This commit is contained in:
committed by
Edward Langley
parent
7c5f77708c
commit
bebaeb2d61
@@ -65,10 +65,13 @@ the owned `DataStore`. That is the whole evaluator hook (improvise-rnak, bw4p.14
|
||||
there is still one evaluator, `Model`'s, and it computes every formula value, over a source whose
|
||||
cells it never owns.
|
||||
|
||||
1. **A model over a source is read-only.** `set_cell` and `clear_cell` `debug_assert` that no source
|
||||
is set, because they write the owned store, which is then not read. A release build would drop the
|
||||
write silently; the assert is the guard, not the design. The design is that a caller who holds a
|
||||
source writes to the source (ADR 003: the trait has no writes), and the model is built over it.
|
||||
1. **A model over a source is read-only, in every build.** `set_cell`, `clear_cell`, `remove_category` and
|
||||
`remove_item` `assert!` that no source is set (a `debug_assert` first shipped and was lost in release:
|
||||
the write went to the owned store, which nothing reads). A caller who holds a source writes to the
|
||||
source (ADR 003: the trait has no writes). `Model::over` drops the model's own cells, so no stale copy
|
||||
is left for `get_cell`, persistence or the harness to read. `data` is `pub`, so a caller can still write
|
||||
it directly; it is not read, and nothing prevents that. Structural edits (a category or item removed)
|
||||
are refused too, because the source's cells would still carry them.
|
||||
2. **A shared source changes behind its readers by interior mutability of its own.** The model holds
|
||||
an `Arc`, so a database connection or a test double behind a lock is the same object the
|
||||
backend feeds from.
|
||||
|
||||
@@ -2397,3 +2397,28 @@ Extremes with no numbers, and a NaN as an extreme, are dropped by `Numbers::from
|
||||
Review of #356 (Codex): `DataStore::keys` went through `cells` and cloned every value. It reads keys
|
||||
only now; the test pins the keys and their order against `cells`. No clone-count test: a value clone is
|
||||
not observable from outside, so the equality is all that can be asserted.
|
||||
|
||||
### a_model_over_a_source_refuses_a_clear
|
||||
|
||||
Review of #357: the `clear_cell` guard had no test. The refusal is an `assert!`, so the test holds in a
|
||||
release build too (`cargo test --release -p improvise-core --lib over_tests` was run: the earlier
|
||||
`debug_assert!` failed all four refusal tests there, `a_model_over_a_source_refuses_a_write` among
|
||||
them, and was the bug). Rival: the guard removed from `clear_cell` fails this test only.
|
||||
|
||||
### a_model_over_a_source_refuses_to_remove_a_category
|
||||
|
||||
`remove_category` swept the owned store with no guard. Rival: the guard removed.
|
||||
|
||||
### a_model_over_a_source_refuses_to_remove_an_item
|
||||
|
||||
The same for `remove_item`.
|
||||
|
||||
### putting_a_populated_model_over_a_source_drops_its_own_cells
|
||||
|
||||
`Model::over` empties the owned store, so `get_cell` on an over-model is `None` for a cell the
|
||||
source holds, and the evaluator still reads the source's value.
|
||||
|
||||
### records_mode_reads_the_records_from_a_source
|
||||
|
||||
Review of #357: a records-mode `GridLayout` over a source. `group_records` reading the owned store
|
||||
left all 563 tests green; with this test it fails (the grid has no rows).
|
||||
|
||||
Reference in New Issue
Block a user