Skip to content

fix(template): prefer the newer of live-cache and bundled snapshot#396

Merged
askalf merged 1 commit into
masterfrom
fix/loadtemplate-prefer-newer
May 28, 2026
Merged

fix(template): prefer the newer of live-cache and bundled snapshot#396
askalf merged 1 commit into
masterfrom
fix/loadtemplate-prefer-newer

Conversation

@askalf
Copy link
Copy Markdown
Owner

@askalf askalf commented May 28, 2026

The bug

loadTemplate() returns the live cache (~/.dario/cc-template.live.json) whenever it exists — at any age. Both the fresh and the stale branch just return cached, on the assumption that a live capture is always at least as fresh as the bundled snapshot.

That assumption inverts in a no-CC deployment (the Hetzner askalf-dario container, which has no claude binary): the async refreshLiveFingerprintAsync() can never run, so the volume's live cache freezes at its last capture while shipped releases advance the bundled template. The stale cache then shadows every bundled-template update until the cache file is removed by hand.

Observed

2026-05-28: a May-10 CC 2.1.138 live cache shadowed the freshly baked 2.1.154 bundle in dario 4.8.14. dario doctor read Template: live capture, CC v2.1.138 (18d old) despite the new image — the re-bake + release + container pull had zero effect on the served fingerprint. It only updated after the cache file was moved aside and dario restarted.

The fix

On a stale cache (age ≥ TTL), prefer whichever of the live cache and the bundled snapshot was captured more recently, instead of blindly keeping the cache:

  • Fresh cache (age < TTL) → still always wins (unchanged dev-machine behavior).
  • Stale cache newer than the bundle → cache wins (preserves the original intent).
  • Stale cache older than the bundle → bundle wins (fixes the no-CC container case — a shipped template update now takes effect on the next start, no manual cache removal).

Number.isFinite guards a malformed bundle date (falls back to the cache). No infra change, no CC required in the container. tsc --noEmit clean.

loadTemplate() returned the live cache whenever it existed, at any age,
assuming a live capture is always at least as fresh as the bundle. That
inverts in a no-CC deployment (the Hetzner container): the async refresh can
never run there, so the volume's live cache freezes at its last capture while
shipped releases advance the bundled template. The stale cache then shadows
every bundled-template update until the cache file is removed by hand.

Observed 2026-05-28: a May-10 CC 2.1.138 live cache shadowed the freshly baked
2.1.154 bundle in dario 4.8.14 — `dario doctor` read "live capture, CC v2.1.138
(18d old)" despite the new image, and the template only updated after the cache
was moved aside manually.

Now a stale cache wins only if it was captured more recently than the bundle;
otherwise the bundle is used. A fresh cache (age < TTL) still always wins. No
infra change and no CC required in the container.
@github-actions
Copy link
Copy Markdown
Contributor

Compat test: ✅ PASSED

Ran node test/compat.mjs against dario proxy --passthrough on the self-hosted runner for commit fce9b014533fd43b51e9700f9b0b25788d611c13.

Output
============================================================
  dario Compatibility Validation (direct Anthropic, x-api-key)
  2026-05-28T23:13:26.076Z
============================================================

--- Anthropic Messages API (Hermes) ---
✅ #1 Anthropic non-stream: "COMPAT OK" | thinking_injected=false | service_tier=-
✅ #2 Anthropic stream: 8 events | order=correct | "**STREAM COMPAT**"
✅ #3 SSE framing: event:/data: pairs correctly paired

--- Passthrough Verification --- (skipped: requires routing through dario)
--- OpenAI Compat --- (skipped: requires dario OpenAI shim)

--- Tool Use (OpenClaw) ---
✅ #4 Tool use: tool=get_weather | input={"location":"Tokyo"}
✅ #5 Tool use stream: 11 events | tool_use=true | input_json_delta=true

--- Header Visibility ---
✅ #6 Header visibility: request-id=true | ratelimit=true (12 headers)

============================================================
  RESULTS: 6 passed, 0 failed, 0 warnings
============================================================

Full workflow run

@askalf askalf merged commit a0b141d into master May 28, 2026
11 checks passed
@askalf askalf deleted the fix/loadtemplate-prefer-newer branch May 28, 2026 23:15
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.

1 participant