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
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Aug 3, 2026
… 进入 v17 (objectstack-ai#4732)

* chore: bump objectui to 785b8a5d432c

fix(fields)!: FieldWidgetComponentProps stops claiming to have every key (objectstack-ai#3221) (objectstack-ai#3230)

objectui@785b8a5d432cf009389a1a9180fdac2a8297543f

* docs(changeset): carry the objectui batch's authoring semantics into the pin changeset

The auto-generated pin changeset lists commit subjects only, so the one
author-BREAKING change in the range (objectui#3203 — `ActionParam` loses the
nine resolved-only picker keys) would have reached the release notes as a
one-line Chinese subject with no migration and no rationale. Spell out the
FROM/TO prescription and why the removal is not a regression (the keys were
never storable: `ActionParamSchema` is `.strict()` and its alias table names
`referenceto -> reference`), plus the author-visible halves of objectui#3196 /
objectstack-ai#3204 / objectstack-ai#3210.

Also drops the two `fix(ci)` lines from the enumerated range: they release
nothing and are not in the shipped bundle, so listing them as "frontend
changes" overstates what the artifact carries.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Br2xsJsczFsTR9bvbh2Ny

---------

Co-authored-by: Claude <noreply@anthropic.com>
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