You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(formula,service-analytics): 类型盲后端把 Date 与线上文本比出错——storage-form 轴指过去当场测出两个真缺陷 (#4191) (#4223)
* test(driver-memory): pin D-E3 schema-arrival convergence with the storage-form axis (#4191)
D-E3 promises this driver converges the rows ALREADY in a table when the
schema arrives — the population initialData fixtures and persistence
restores create, both landing before any schema is declared. Nothing
asserted it: every existing sweep seeds through create(), which is the
one path that cannot produce a pre-convention form.
Two describes seed the raw pre-#4047 forms via initialData (native → a
JS Date, wire → zone-naive text; the time twin → an epoch-day Date and a
full timestamp), let syncSchema run its retroactive pass, then run the
shared tables. Each carries a premise assertion on the converged values
so the sweep cannot pass vacuously.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SWHvwFgUU2U8M9nbV1g1iQ
* fix(formula,service-analytics,spec,core): order a Date against wire text on the type-blind filter backends (#4191)
Pointing the storage-form axis at the two backends that have no storage
found the same defect in both, and neither needed a legacy fixture to
reach it — the cross-type pairing arrives from real callers:
- the RLS `check` post-image is the caller's RAW write payload
(`{ ...opCtx.data }`, before any driver formatInput), so an SDK write
of `new Date()` lands in matchesFilterCondition as a Date against
wire-text comparands; the mirror pairing arrives too, since a CEL
`today()` lowers to a Date;
- a preview row from a mongo-backed dataset arrives as a BSON Date
(D-E2), against the same comparands.
JS relational operators cannot order that pair: they coerce with hint
number, so the Date becomes its epoch and the string becomes NaN. 10 of
the 16 shared cases diverged on each backend. Fail-closed made formula's
half a DENIED write — the write-side twin of #4047, the direction D-D2
recorded for the bare-day upper bound. The preview's half was worse:
falling back to String(value) puts 'Mon Jul 27 2026 …' after every
'2026-…' comparand, so windows both lost rows and gained them, and a
drafted chart's numbers changed at publish.
utcInstantMs joins nextUtcCalendarDay in spec/data/calendar-day.ts (core
re-exports it) — one definition for both, the D-D2 discipline. It accepts
only unambiguous spellings, so the answer never depends on the process
zone, and returns null for a bare wall clock, which denotes no instant:
the Field.time table and the date column stay out of the sweep by the
same scope rule this matrix already applies to $gt-on-datetime.
Deliberately narrow: the lift runs only when one operand is a Date and
both read as instants, so every comparison that worked before is
byte-identical and the security posture never loosens beyond what the
operands justify.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SWHvwFgUU2U8M9nbV1g1iQ
---------
Co-authored-by: Claude <noreply@anthropic.com>
0 commit comments