Skip to content

feat(formula): dateField == today() now matches — AST temporal-comparison rewrite (#3183)#3210

Merged
os-zhuang merged 2 commits into
mainfrom
claude/fix-conflict-twdtn7
Jul 18, 2026
Merged

feat(formula): dateField == today() now matches — AST temporal-comparison rewrite (#3183)#3210
os-zhuang merged 2 commits into
mainfrom
claude/fix-conflict-twdtn7

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Conflict-resolved version of #3205 (head claude/date-equality-runtime-hydration-3183), rebased onto the latest main via merge. Supersedes #3205.

What this is

The runtime fix for the date == today() silent-miss (#3183): celEngine.evaluate rewrites the parsed AST so that a ==/!= against today()/daysFromNow()/daysAgo()/now() wraps the field operand in date(...), comparing two Timestamps instead of a YYYY-MM-DD string vs a timestamp. Per-occurrence, type-blind-safe, idempotent, memoized. Removes the superseded #3192 advisory lint.

Conflict resolution

The only merge conflict was in packages/lint/src/validate-expressions.test.ts, where two independent deletions overlapped:

Resolved as the union: both describe blocks removed, main's trailing comment kept.

Verification

Built with turbo (dependency graph) and ran the affected suites — all green:

  • @objectstack/formula — 233 passed
  • @objectstack/lint — 228 passed
  • @objectstack/objectql — 946 passed

🤖 Generated with Claude Code


Generated by Claude Code

claude added 2 commits July 18, 2026 11:09
…arison rewrite (#3183)

A `Field.date` reads back as a "YYYY-MM-DD" string (ADR-0053 Phase 1), and
cel-js's equality treats a string and a timestamp as unequal without consulting
any overload, so `record.due_date == today()` silently returned false (and
`!= today()` silently true) even for a same-day record.

celEngine.evaluate now rewrites the parsed AST: for each `==`/`!=` whose one
operand is today()/daysFromNow()/daysAgo()/now(), the field operand is wrapped in
date(...) (the stdlib coercion), then serialized and evaluated — so
`record.due_date == today()` runs as `date(record.due_date) == today()`.

- Per-occurrence: a mixed `d == "literal" || d == today()` keeps the literal
  comparison intact while fixing the temporal one.
- Type-blind-safe: date() degrades gracefully (already-Date passes through;
  non-date string / null → Invalid Date → stays false), so no field types are
  needed and no currently-correct result is worsened.
- Cheap: reserializes only when such a comparison is present (plain-includes
  gate) and memoizes source → rewritten source. AST-based, no regex on input.

Covers every interpreter site (formulas, defaults, validation, hooks, flow
conditions) via the single evaluate chokepoint. RLS/sharing unaffected
(cel-to-filter rejects function calls loudly).

Supersedes the #3192 advisory lint (checkTemporalDateEquality + the
temporalEqualityFields helper), now removed — with the runtime fixed it would be
a false alarm. Flips the #3181 KNOWN GAP characterization test to assert the fix,
and adds an objectql end-to-end test (a date formula field read via find()).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SuiM565BZ3TR1VD3prMguB
…wdtn7

# Conflicts:
#	packages/lint/src/validate-expressions.test.ts
@vercel

vercel Bot commented Jul 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Building Building Preview, Comment Jul 18, 2026 12:31pm

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling labels Jul 18, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 3 package(s): @objectstack/formula, @objectstack/lint, @objectstack/objectql.

17 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/concepts/metadata-lifecycle.mdx (via @objectstack/objectql)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/formula, packages/objectql)
  • content/docs/data-modeling/validation.mdx (via @objectstack/formula)
  • content/docs/deployment/migration-from-objectql.mdx (via @objectstack/objectql)
  • content/docs/deployment/vercel.mdx (via @objectstack/objectql)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/objectql)
  • content/docs/kernel/services.mdx (via @objectstack/objectql)
  • content/docs/permissions/authentication.mdx (via @objectstack/objectql)
  • content/docs/permissions/authorization.mdx (via @objectstack/lint)
  • content/docs/plugins/index.mdx (via @objectstack/objectql)
  • content/docs/plugins/packages.mdx (via @objectstack/formula, @objectstack/objectql)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/objectql)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/objectql)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/formula)
  • content/docs/releases/implementation-status.mdx (via @objectstack/objectql)
  • content/docs/releases/v15.mdx (via @objectstack/formula)
  • content/docs/releases/v9.mdx (via @objectstack/objectql)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@os-zhuang
os-zhuang merged commit 3e9cabd into main Jul 18, 2026
15 of 16 checks passed
@os-zhuang
os-zhuang deleted the claude/fix-conflict-twdtn7 branch July 18, 2026 12:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants