Skip to content

feat: add v2-compat mode to evaluation entry points - #364

Merged
santiagocardo merged 2 commits into
release/3-0-0from
feat/v2-compat-mode
Jul 27, 2026
Merged

feat: add v2-compat mode to evaluation entry points#364
santiagocardo merged 2 commits into
release/3-0-0from
feat/v2-compat-mode

Conversation

@santiagocardo

@santiagocardo santiagocardo commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Purpose

Give consumers a per-evaluation v2-compat mode so v2- and v3-semantics evaluations can run side by side in one VM.

What's in here

  • mode: :v2 on all evaluation entry pointsevaluate!/4, evaluate/4, evaluate_block!/4, evaluate_block/4, evaluate_as_string!/4, evaluate_as_boolean!/4, evaluate_template!/4 now take a trailing options list. mode: :v2 expands to lowercase_keys: true, coerce_strings: true; explicitly passed flags win over the expansion; mode: :v3/no mode keeps v3 defaults. Implementation is a single normalize_opts/1 + passing opts to the Context.new/2 calls the entry points already make.
  • Compat test corpus (test/expression/v2_compat_test.exs, 15 tests): proves v2 semantics under the mode (coercion, lowercasing, entry-point coverage, nested-template behavior, flag precedence) and pins the two audit findings below.
  • Release-notes corrections (CHANGELOG.md, V3_PLAN.md), from the audit of develop..release/3-0-0:
    1. The binary-literal recursion removal was reverted before rc.0 (6e8355a) — literals still resolve as templates exactly as in v2, so no compat flag and no consumer migration is needed. The notes previously listed it as a shipped break.
    2. The DateTime = "fix" targeted unreachable code: OperatorHelpers.eq/1 collapses = and == into :== at parse time in both v2 and v3, so = on DateTimes always full-compared. No behavior changed; no compat flag needed. (An earlier revision of this branch threaded a legacy_datetime_equality flag through Eval — removed once the corpus proved the path dead.)

The net v2→v3 runtime delta is exactly the Context.new/2 default flip, which is why the compat mode is only the two context flags.

Verification

  • Full suite: 413 doctests + 255 tests, 0 failures (includes the new corpus)
  • mix credo --strict and mix format --check-formatted clean
  • No changes to Eval, the parser, or any evaluation path when opts are omitted — a bare mix diff-level no-op for existing callers

🤖 Generated with Claude Code

santiagocardo and others added 2 commits July 27, 2026 14:39
All evaluation entry points now accept a trailing options list; mode: :v2
expands to the v2 context-normalization flags (lowercase_keys: true,
coerce_strings: true), with explicitly passed flags winning over the
expansion. This lets consumers select v2 or v3 semantics per evaluation
in the same VM - the mechanism engage uses to keep existing journeys on
v2 behavior while new journeys adopt v3.

The audit for this work corrected two stale claims in the release notes:
the binary-literal recursion removal was reverted before rc.0 (6e8355a),
and the documented v2 date-only DateTime = comparison was unreachable
dead code because the parser collapses = and == into the same operator
in both versions. Neither needs a compat flag; the compat test corpus
pins both findings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@santiagocardo santiagocardo self-assigned this Jul 27, 2026
@santiagocardo
santiagocardo requested a review from smn July 27, 2026 19:58
@santiagocardo
santiagocardo merged commit 2762e40 into release/3-0-0 Jul 27, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants