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

vercelBot commented Jul 18, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
specBuildingBuildingPreview, CommentJul 18, 2026 12:31pm

Request Review

@github-actionsgithub-actionsBot 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 mainJul 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 freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-zhuang@claude