Filed by the domain:services seat 2 (seat post #21118) · session_01DiCSbmJrkzNhuEAier4VoJ · from the os-dev report on #21376 (PR #21424), out_of_scope_findings[0]. Bare, for triage's first grade.
What was measured
On SQLite at 78e4f3eb2, through AnalyticsService.query, the handler POST /api/v1/analytics/query relays verbatim. The query used the native-SQL face over a declared number field (amount).
where |
native face |
engine-aggregate (ObjectQL) face |
{ amount: "abc" } |
200, count 0 |
INVALID_FILTER / 400 |
{ amount: { $lte: "9999-12-31" } } |
200, count 2 |
400 |
{ amount: { $ne: "abc" } } |
200, count 2 |
400 |
{ amount: true } |
200, count 0 |
400 |
Contract
@objectstack/spec/data's filter-number-comparand-declared-type.ts: "the door refuses a non-numeric string against a number field with INVALID_FILTER / 400, naming the field, on every driver and position, before any bind." The native strategy compiles its own SQL past the engine door, so it skips the verdict. #21376 is the boolean arm of the same skip, and PR #21424 adds a judgedBooleanComparands walk over the same positions: where (including the dataset runtimeFilter), each measure filter, and the dataset scope.
Seam: spec:numberComparandDoorVerdict → runtime:NativeSQLStrategy.compileClauses (packages/services/service-analytics/src/strategies/native-sql-strategy.ts).
Direction (triage's to rule, not a ruling)
The number verdict as a second arm of PR #21424's walk, at the same positions, with the same refusal (invalidFilterError, 400). ⛔ No second rule. Pins mirror #21424's: each cell answers the engine face's column on SQLite and PostgreSQL.
Serial: native-sql-strategy.ts is held by PR #21424 (#21376) until it lands.
Dedupe: searched "analytics native SQL number comparand non-numeric string not refused INVALID_FILTER numberComparandDoorVerdict". The hits are #21376 (the boolean twin, open), #20351 (the engine door's number half, closed) and #21382 (the boolean non-string half, closed). None covers the native face's number arm.
Generated by Claude Code · https://claude.ai/code/session_01DiCSbmJrkzNhuEAier4VoJ
Filed by the
domain:servicesseat 2 (seat post #21118) ·session_01DiCSbmJrkzNhuEAier4VoJ· from the os-dev report on #21376 (PR #21424),out_of_scope_findings[0]. Bare, for triage's first grade.What was measured
On SQLite at
78e4f3eb2, throughAnalyticsService.query, the handlerPOST /api/v1/analytics/queryrelays verbatim. The query used the native-SQL face over a declared number field (amount).where{ amount: "abc" }INVALID_FILTER/ 400{ amount: { $lte: "9999-12-31" } }{ amount: { $ne: "abc" } }{ amount: true }Contract
@objectstack/spec/data'sfilter-number-comparand-declared-type.ts: "the door refuses a non-numeric string against a number field with INVALID_FILTER / 400, naming the field, on every driver and position, before any bind." The native strategy compiles its own SQL past the engine door, so it skips the verdict. #21376 is the boolean arm of the same skip, and PR #21424 adds ajudgedBooleanComparandswalk over the same positions:where(including the datasetruntimeFilter), each measure filter, and the dataset scope.Seam:
spec:numberComparandDoorVerdict→runtime:NativeSQLStrategy.compileClauses(packages/services/service-analytics/src/strategies/native-sql-strategy.ts).Direction (triage's to rule, not a ruling)
The number verdict as a second arm of PR #21424's walk, at the same positions, with the same refusal (
invalidFilterError, 400). ⛔ No second rule. Pins mirror #21424's: each cell answers the engine face's column on SQLite and PostgreSQL.Serial:
native-sql-strategy.tsis held by PR #21424 (#21376) until it lands.Dedupe: searched "analytics native SQL number comparand non-numeric string not refused INVALID_FILTER numberComparandDoorVerdict". The hits are #21376 (the boolean twin, open), #20351 (the engine door's number half, closed) and #21382 (the boolean non-string half, closed). None covers the native face's number arm.
Generated by Claude Code · https://claude.ai/code/session_01DiCSbmJrkzNhuEAier4VoJ