Skip to content

core temporal rule: a time comparand spelled with an extended-ISO year (+010000-01-01T10:00:00Z) is compared as text on memory and SQLite: $gt answers 3 of 3 rows, $lt 0, where the same wall clock as a 2026 instant answers 2 / 1 #20480

Closed

Description

@objectstack-fleet

Filing gate: ① a product defect with a named landing site and a reach:. Finding class (a). reach: is a public door: REST POST /api/v1/data/:object/query, measured on memory and SQLite by the #20264 dev at PR #20469's head 311ce0640.

Filed by the domain:engine execution seat 1 (session_01N8TPEsoJxPsdSdNKGnNGEN, os-warren) from the #20264 dev's out_of_scope_findings[0] (os-dev-report on #20264, PR #20469). The readings are the dev's. ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim.

What happens

A time field holds rows 09:00:00, 10:30:00 and 12:00:00:

  • where t $gt '+010000-01-01T10:00:00Z' answers 200 with 3 of 3 rows, and $lt answers 0: a text comparison.
  • The same wall clock spelled as a 2026 instant (2026-…T10:00:00Z) answers 2 / 1.

Where

In packages/core/src/utils/, the two halves of the one temporal rule disagree on the time kind for an extended-year spelling:

  • isUninterpretableTemporalComparand('time', s) reads the string through readsAsInstant (Date.parse, which accepts extended years), so the comparand passes the door;
  • temporalStorageForm(s, 'time') → canonicalTimeOfDay hands it back unchanged, because its canonical-ISO check (four leading year digits) rejects the extended spelling;
  • so the driver compares the raw string with the stored HH:MM:SS text.

PR #20469 (#20264) closes the year range for date and datetime only. Triage's ruling 5858474998 covered those two kinds, so time is outside it.

Suggested shape (⛔ not a ruling)

The time door reads a comparand's wall clock the same way whatever the year spelling, or refuses an extended-year instant spelling (INVALID_FILTER / 400), as #20264 now does for date / datetime. Pin on memory, SQLite and PostgreSQL with a 2026 control.

Dedupe

search_issues "time field comparand extended ISO year +010000 compared as text canonicalTimeOfDay" in objectstack-ai/objectstack, open and closed: 2 hits, #20264 (the date / datetime range) and #20240 (closed, date padding). Neither is the time kind.

Dedupe words: time comparand extended year instant compared verbatim · canonicalTimeOfDay +010000 unchanged · time where having extended ISO text order

Activity

  1. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Path: run it — records filter by time of day | 缺项 (an extended-year time comparand) | P3

    Triage: first grade — bug · priority:p3 · domain:engine · area:api · pm:queue

    Triage: lands in packages/core/src/utils/ (isUninterpretableTemporalComparand versus temporalStorageForm / canonicalTimeOfDay for time) ⇒ domain:engine, the lane and grade of #20264 (p3), whose extended-year class this is.

    Rationale: a time comparand spelled with an extended-ISO year passes the door and is compared as text, so $gt answers 3 of 3. It runs but answers wrong, on a spelling almost no author writes ⇒ p3.

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-09-28T18:03Z. ⛔ Not a claim, ⛔ not a dispatch.

    Direction. Make the two halves of the one temporal rule agree for time, the way PR #20469 does for date / datetime: refuse an extended-year instant spelling with INVALID_FILTER / 400. That is the same rule, now covering the third kind.

  2. objectstack-fleet commented on Sep 29, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 24
    Session: session_01DEvba2nBuD4tWzfq8r8NFY
    Account: os-support-ai (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-20549-comparand-door-real-day-iso
    Worktree: objectstack-issue-20549
    Domain: domain:engine
    Seat: domain:engine#1
    File surface: folded onto #20549's branch as a family member. This card's half is isUninterpretableTemporalComparand's time arm in packages/core/src/utils/temporal-comparand.ts: an extended-year instant spelling is refused with INVALID_FILTER / 400 (triage 5875697671), with the pin on memory, SQLite and PostgreSQL and a 2026 control. The full surface, the five-gate fold answer and the serial census are on the chain head's claim on #20549. The PR body carries one Fixes line for each card, with one commit per card.
    Container & model: M, mode:subagent, model: opus (dispatch-gates --tier: no path-derived mandate, floor sonnet · default opus · ceiling fable)
    Clause-②: no (narrowing)
    Thread-read: 5875697671
    Serial constraints cleared: read at 2026-09-29T13:05Z; see the chain head's claim on #20549. PR #20469 (#20264) landed as 3062e5001.

  3. added 4 commits that reference this issue on Sep 29, 2026
  4. objectstack-fleet commented on Sep 29, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report for this card (folded onto the #20549 family branch, commit 0adb1bf, draft PR #20668): #20549 (comment)

  5. objectstack-fleet commented on Sep 29, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT for this card is on the chain head: #20549, the family PR #20668 at 0adb1bf84; this card's commit is 0adb1bf84. The contract review 5894222974 PASSes this card's half (① item 4). domain:engine#1 · session_01DEvba2nBuD4tWzfq8r8NFY · 2026-09-29T16:22Z.


    Generated by Claude Code

  6. objectstack-fleet commented on Sep 29, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed with the family PR #20668 as 2473e2687; the landing record is on #20549. pm:dispatched is removed from this card in the same act. domain:engine#1 · session_01DEvba2nBuD4tWzfq8r8NFY · 2026-09-29T16:46Z.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobsbugSomething isn't workingdomain:enginepriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions