Skip to content

Add hermetic template recording and replay - #2114

Open
martelogan wants to merge 3 commits into
Shopify:mainfrom
martelogan:martelogan/liquid-hermetic-recording
Open

Add hermetic template recording and replay#2114
martelogan wants to merge 3 commits into
Shopify:mainfrom
martelogan:martelogan/liquid-hermetic-recording

Conversation

@martelogan

@martelogan martelogan commented Sep 3, 2026

Copy link
Copy Markdown
Member

Summary

This carries forward the hermetic recording and deterministic replay work from #1975 while preserving its authorship lineage:

  • Tobi's original recorder change is retained as its own Tobi-authored commit, with the source commit recorded in the message.
  • Storefront integration fixes are isolated in a Logan-authored follow-up commit.
  • The disabled-path performance gate is isolated in a second Logan-authored follow-up commit.
  • A parent-dependent strict2 test expectation from the original branch is intentionally omitted because it is unrelated to recording.

Branch ancestry

The PR head is intentionally rooted at v5.13.0 rather than the current main. The intervening main commit changes strict2 rendering independently of the recorder; excluding it keeps direct consumers of this immutable head recorder-only. The PR still targets main. Its single-file overlap in lib/liquid/template.rb can be resolved when preparing the upstream merge, after consumers no longer depend on this exact head tree.

Follow-up fixes

  • keep recorder hooks inert when a host application assigns a context without Liquid registers
  • record only bytes produced by the template, excluding an existing output-buffer prefix and later caller mutations
  • do not add memory-limited, truncated renders to the recording corpus
  • let strict replay parse application-only inline and block tags by replacing them with recorded-output stubs
  • disable recorder hooks by default behind the boot-time LIQUID_TEMPLATE_RECORDER_HOOKS gate
  • fail loudly if recording is requested without enabling the hooks before Liquid loads
  • exercise the normal hooks-disabled suite and recorder-enabled tests separately from the default Rake task
  • add regression coverage and documentation for the gated behavior

The boot-time gate addresses a Storefront verifier result of +1.59% allocations per request with the ungated hooks disabled at the feature level, versus a 0.2% gate. Offline recording processes explicitly enable the hooks; other hosts avoid recorder/session lookups on their render paths.

Current BLAKE3 for lib/liquid/template_recorder.rb: fc979294a7523b48e9d8cf21aed3a4c1b9e944a6ee611406eb0c7cc2439be44f.

Test plan

  • bundle exec rake (hooks-disabled lax, strict, and strict2 suites; hooks-enabled recorder tests; RuboCop)
  • bundle exec ruby -Itest test/integration/template_recorder_disabled_test.rb (1 run, 3 assertions)
  • LIQUID_TEMPLATE_RECORDER_HOOKS=1 bundle exec ruby -Itest test/integration/template_recorder_test.rb (24 runs, 57 assertions)

tobi and others added 2 commits September 2, 2026 23:45
Keep recorder hooks inert for host contexts without Liquid registers, capture only bytes produced by the template, and exclude memory-limited renders from the corpus. Strict replay now stubs application-only inline and block tags from the recorded sources.

Assisted-By: devx/948e6cb4-458b-480b-8d99-d726473b381b
@martelogan
martelogan force-pushed the martelogan/liquid-hermetic-recording branch from 394edbf to 2578979 Compare September 3, 2026 03:45
The hooks sit on the hottest paths a host has - every drop read, filter
call, tag and variable - and a host that never records should not pay for
them. Storefront's verifier measured the ungated hooks at +1.59% allocations
per request with recording switched off, against a 0.2% gate.

HOOKS_ENABLED is deliberately boot-time: a constant is what makes the
disabled path free. Recording is generated offline, so the processes that
need it set LIQUID_TEMPLATE_RECORDER_HOOKS at boot and nothing else pays.
TemplateRecorder.record now raises when the hooks are off, so a misconfigured
host fails loudly instead of silently recording nothing.

Assisted-By: devx/948e6cb4-458b-480b-8d99-d726473b381b
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