fix(smoke): publish cassettes 0644 so the nightly refresh can commit them - #1118
fix(smoke): publish cassettes 0644 so the nightly refresh can commit them#1118aminsamir45 wants to merge 1 commit into
Conversation
…y refresh Every replay-only smoke run has failed since #1101 merged, on PRs that change nothing about the request path. Two independent bugs. Cassette keys were not run-stable. #1101 began injecting prompt_cache_key into the upstream body as a session-affinity hint. It is derived from the API key id, and run.sh seeds a brand-new router key on every run, so the key hashed differently each time — a guaranteed `cassette: cache miss: POST /v1/responses` on TestOpenAIResponsesAPI. The observed per-branch keys were the symptom: same scenario, different hash each run. requestKey now canonicalizes the body, stripping the per-run router-derived fields listed in volatileBodyFields. The nightly cassette refresh has been red for a month and would not have healed this on its own. save() published cassettes via CreateTemp's 0600, owned by the container's root, into a repo bind mount — so the runner's git could not read what it had just recorded and died with "Permission denied" (exit 128) before opening a refresh PR. Cassettes are now chmod 0644 before the atomic rename. Tests cover both halves of the key contract — one scenario hashes the same across runs, genuinely different requests still do not collide — and pin the published file mode. Verified end to end: the full suite reproduces the CI failure on the unfixed store and passes with it. Co-Authored-By: Weave Router <router@workweave.ai>
What T-Rex did
Reviews (1): Last reviewed commit: "fix(smoke): make cassette keys stable ac..." | Re-trigger Greptile |
| h.Write([]byte(path)) | ||
| h.Write([]byte{0}) | ||
| h.Write(body) | ||
| h.Write(canonicalizeBody(body)) |
There was a problem hiding this comment.
Legacy cassette keys are unreachable
Canonicalizing prompt_cache_key changes the hash—and therefore filename—for every existing JSON cassette recorded with that field. Replay-only lookup uses only this new key, so a cassette stored under its prior raw-body hash now produces a cache miss until it is rerecorded. Rename or migrate affected cassettes in this change, or fall back to the legacy raw-body key after a canonical-key miss until the migration is complete.
Artifacts
Focused legacy cassette compatibility test source
- This authored Go test computes the pre-change and PR fix(smoke): publish cassettes 0644 so the nightly refresh can commit them #1118 keys, stores a cassette under the old filename, and invokes the replay-only resolver with the new key.
Focused replay-only compatibility test output
- This executed test output shows distinct old and new hashes and the observed replay-only cache miss despite the old-key cassette being readable.
PR request-key regression suite output
- This executed regression suite shows the PR’s new-key stability and cassette-mode tests pass while not covering legacy filename compatibility.
Summary
The nightly cassette refresh has failed every night since it was added — every scheduled run back to 2026-07-19 is red.
save()published cassettes withCreateTemp's0600, owned by the container's root, into a directory bind-mounted from the repo. The runner's git then could not read what the recording had just written:The step dies before
gh pr create, so no refresh PR has ever opened. That's why the committed cassettes are still the original 2026-07-23 recording and a month of provider drift has gone undetected. This chmods0644before the atomic rename.Relationship to #1117
This PR originally also fixed the cassette-key determinism bug that was turning every replay-only PR run red (
cassette: cache miss: POST /v1/responsesonTestOpenAIResponsesAPI, caused by #1101 injecting a per-runprompt_cache_key). #1117 landed that fix ~10 minutes earlier, so I've rebased onto it and dropped my duplicate — this is now only the remaining half.Worth stating explicitly, since the two bugs look redundant but aren't: #1117 stops the bleeding on PR runs, and this is the reason that bug could never have healed on its own. A stale-cassette problem is supposed to be caught and auto-corrected by the nightly refresh; with the refresh silently dead, the next drift would have gone unnoticed the same way.
Verification
got 600 want 644) and passes after.ok workweave/router/smoke, all six tests includingTestOpenAIResponsesAPI.gofmt,go vet ./smoke/..., andgo test ./smoke/mitmproxy/clean.The mode can't be verified end-to-end from a PR run (it needs a
record-mode run with a key), so the test pins it directly. Follow-up worth watching: confirm the next nightly actually opens its refresh PR — and expect that PR to carry a month of accumulated drift, so review it rather than rubber-stamping.🤖 Generated with Weave Router