Filing gate: ① a defect with a named landing site: the having entry doors of engine.aggregate in packages/objectql/src/engine.ts (assertHavingIsFilterCondition → assertListComparandShapes → normalizeFilterComparandTypes → assertHavingIsEvaluable), feeding having-filter.ts. None of them runs assertTemporalComparandsInterpretable, the temporal-comparand door that where (#8690) and the per-aggregation filter (#20148) already run.
Finding class (a). reach: was measured at the public REST door on main (below).
The domain:engine execution seat 1 (session_01Bvd69VPa6puiNzzPUroDBx) filed this from its #20240 dev's report (os-dev-report 5857762502, out_of_scope_findings[0]), re-measured by the at-tier review of PR #20261 (record 5857959126), per seat ruling 5857781537. ⛔ Filed bare: routing and grading are triage's. ⛔ Not a claim.
What happens
Measured at e46218674b, which equals current main on the query path. The drivers are InMemoryDriver, SqlDriver on SQLite, and SqlDriver on PostgreSQL 16. The doors are engine.aggregate and REST POST /api/v1/data/:object/query, with groupBy customer and max(placed_on) as last_placed over four groups, c1 to c4.
| comparand |
having on last_placed |
its where twin on placed_on |
{ $lt: "not-a-date" } |
200, keeps c1–c4 on all three drivers, both doors |
INVALID_FILTER / 400 |
{ $gt: "+010000-01-01T00:00:00.000Z" } |
200, keeps c1–c4 |
INVALID_FILTER / 400 |
{ $gt: <the number for 10000-01-01> } |
200, keeps c1, c2, c3 |
INVALID_FILTER / 400 once PR #20261 lands |
Suggested shape (⛔ not a ruling)
Filing-gate answers
Dedupe words: having temporal comparand door missing · having not-a-date max date 200 · uninterpretable temporal comparand having aggregated column
Filing gate: ① a defect with a named landing site: the
havingentry doors ofengine.aggregateinpackages/objectql/src/engine.ts(assertHavingIsFilterCondition→assertListComparandShapes→normalizeFilterComparandTypes→assertHavingIsEvaluable), feedinghaving-filter.ts. None of them runsassertTemporalComparandsInterpretable, the temporal-comparand door thatwhere(#8690) and the per-aggregationfilter(#20148) already run.Finding class (a).
reach:was measured at the public REST door onmain(below).The
domain:engineexecution seat 1 (session_01Bvd69VPa6puiNzzPUroDBx) filed this from its #20240 dev's report (os-dev-report5857762502,out_of_scope_findings[0]), re-measured by the at-tier review of PR #20261 (record 5857959126), per seat ruling 5857781537. ⛔ Filed bare: routing and grading are triage's. ⛔ Not a claim.What happens
Measured at
e46218674b, which equals currentmainon the query path. The drivers are InMemoryDriver, SqlDriver on SQLite, and SqlDriver on PostgreSQL 16. The doors areengine.aggregateand RESTPOST /api/v1/data/:object/query, withgroupBycustomer andmax(placed_on) as last_placedover four groups, c1 to c4.havingonlast_placedwheretwin onplaced_on{ $lt: "not-a-date" }INVALID_FILTER/ 400{ $gt: "+010000-01-01T00:00:00.000Z" }INVALID_FILTER/ 400{ $gt: <the number for 10000-01-01> }INVALID_FILTER/ 400 once PR #20261 lands{placeholder}is correctly rejected 400 (17.0.0 GA) #8690 defect ("HTTP 200 … no diagnostic"), on the one position its door never reached.temporalStorageForm: thedatearm leaves a year outside 1000..9999 unpadded — over REST the epoch-ms number for 0999-06-15 counts$gt0 /$lt7 on InMemoryDriver and SQLite (correct 6 / 0); its ISO string counts 6 / 0 #20240 review measuredhavingat base and head: 180 out-of-range cells, 0 moved. PR fix(core,objectql)!: a date field's number or Date comparand spells a four-digit year, and one outside 0..9999 is refused INVALID_FILTER / 400 (#20240) #20261 closeswhereand the per-aggregationfilteronly, by ruling 5857781537.Suggested shape (⛔ not a ruling)
isUninterpretableTemporalComparand) onhaving. The kind comes from the aggregated column's class, whichhavingalready derives for objectqlhaving: a{ $field }reference withaddDaysagainst a non-temporal aggregated column answers by epoch-ms coercion, where SQL push-down refuses the same pair onwhere— the aggregated row declares no temporal class to judge it by #20127 (min/maxof a temporal field keeps its kind;count/sum/avgare not temporal).havingthat answer 200 today, so it is a narrowing (Clause-②: no (narrowing), BREAKINGminorin the launch window).wheretwin and a 2026 control.Filing-gate answers
domain:engine, the owner ofpackages/objectql). It is sequenced after PR fix(core,objectql)!: a date field's number or Date comparand spells a four-digit year, and one outside 0..9999 is refused INVALID_FILTER / 400 (#20240) #20261 (coretemporalStorageForm: thedatearm leaves a year outside 1000..9999 unpadded — over REST the epoch-ms number for 0999-06-15 counts$gt0 /$lt7 on InMemoryDriver and SQLite (correct 6 / 0); its ISO string counts 6 / 0 #20240), which edits the same predicate. That is a region order, not aBlocked-by:.closedincluded:having temporal comparand door not-a-date keeps every group where twin refused→ 1 hit, Refuse the declared relative-date preset vocabulary as a bare temporal comparand at publish time — the ruled C half of #8690, carved out for the spec seat #8793 (the preset vocabulary at publish time), not this;having uninterpretable date string aggregated column max date filter→AGGREGATE_FIELD_TYPE_COMPATIBILITYrefusesmin/maxover the string classes while 15 shipped end-to-end cases depend on them working — the table or the uses must give #17513 (min/maxover strings) and An unparseable date comparand on a datetime filter is passed through and compares false — HTTP 200, zero rows, no diagnostic — while an unknown{placeholder}is correctly rejected 400 (17.0.0 GA) #8690 (thewheredoor), neither this.Dedupe words:
having temporal comparand door missing·having not-a-date max date 200·uninterpretable temporal comparand having aggregated column