mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-10-07 20:32:10 -04:00
fix(cutting): fingerprint settings state without executing foreign code
Delta review found three Important defects and a Minor one in the settings fingerprint that closed the first freshness gap: - Accepted settings state was silently omitted: dictionary entries render as KeyValuePair structs whose Key/Value are properties, property-backed custom structs contribute no public fields, and graphs past the depth limit wrote a constant marker, so all three edits fingerprinted equal and a changed plate still applied. - Reading public properties executed arbitrary getters, so a capture documented as read-only could mutate live settings (Bump => ++Kerf). - An enumerable settings member was enumerated at Apply, where its enumerator could throw out of the public commit call. - Fingerprint text used ambient-culture interpolation, so an invariant capture compared unequal under a digit-substituting culture. Traversal is now a closed boundary. OpenNest types render their public readable properties and fields. Foreign types render only declared instance fields, which include auto-property backing fields, because a field read executes no code. Only arrays and List/Dictionary/HashSet/ KeyValuePair are enumerated, with insertion-ordered containers sorted; other enumerables, delegates and unrepresentable shapes refuse to an Invalid marker that never compares equal, so refused state is Stale rather than silently equal. Doubles fingerprint by bit pattern rendered with invariant formatting, and depth or budget overflow refuses instead of truncating. A reference already on the path renders as a cycle marker; built-in lead and tab objects reference settings back. Capture stores refusals as-is, so a plate with uncaptureable settings stays plannable and every commit against it reports Stale without re-reading live state, and a fingerprint that fails on re-read is likewise Stale, never an exception.
This commit is contained in:
1 parent
ea36c47a30
commit
bb104a07bb
4 files changed
+420
-72
No files matched your search
@@ -164,7 +164,14 @@ difference on any plate returns `Stale` and changes nothing, so a proposal that
|
||||
changes a plate can be applied once; an unchanged (no-op) proposal stays current.
|
||||
A malformed live program is also `Stale`, not an exception. A part repeated on
|
||||
two plates of one scope is `InvalidInput`. Caller-confirmed planning settings are
|
||||
input, not plate state: editing them after capture does not stale the result.
|
||||
input, not plate state: editing a separate confirmed-settings object after
|
||||
capture does not stale the result (confirmed settings that are also a part's or
|
||||
the plate's live settings are live state, and editing them does). Settings state
|
||||
whose exact capture would require executing foreign code — custom property
|
||||
getters, behavioral enumerables, structures beyond the capture limits — is
|
||||
recorded as refused at capture: the plate stays plannable, but every commit
|
||||
against it reports `Stale`, and capture or commit never runs or enumerates
|
||||
foreign code.
|
||||
|
||||
The whole scope is validated and its bounds staged first; cancellation is checked
|
||||
immediately before the install. Order changes through `ObservableList.Reorder`
|
||||
|
||||
Reference in new issue
Block a user