Repository navigation
feat(cache): negative probe cache — 10-min memo for no-notes chains - #143
Merged
Merged
Conversation
…s chains Field-instrumented (2026-08-25): a fresh process re-served 27 responses from the on-disk HTTP cache, yet the run still took ~3 minutes — the 10 no-notes packages re-probe their full chains every run because FAILED fetches are deliberately never cached (a cached 'no notes' result would freeze the unknown state). The dominant cost is the non-GitHub probe chain: up to ~14 URLs with retries per package. The negative probe cache memoizes that chain-level outcome, not any response: when fetch_non_github_release_notes concludes nothing for package@version, a 10-minute negative entry (HTTP_CACHE_NEGATIVE_TTL_ SECONDS=600) is written; the wrapper consults it first and skips the entire chain on a fresh hit. A successful chain clears the entry immediately (regained notes are seen next run), TTL expiry re-probes, --fresh clears the namespace, pruning budgets apply, and it changes no classification — these rows stay unknown. It is a performance memo, never evidence; no tokens, no provenance, no events. Implementation: three helpers (get/put/clear) beside the HTTP cache in utils.sh sharing its namespace and hashing; the probe chain renamed to _fetch_non_github_release_notes_chain with a thin wrapper holding the hook (all three production call sites route through it; existing test stubs unaffected). Tests: tests/test-negative-cache.sh (14 assertions; runner 31 -> 32) — helper roundtrip/TTL-expiry/corrupt-fails-closed, chain integration with curl-call counting (first run probes N URLs, immediate re-run performs ZERO), expiry re-probe, success clears, --fresh clears. Suite gotchas fixed en route: BREW_CHANGE_CACHE_DIR/MAX_RETRIES must be exported BEFORE config.sh resolves them readonly; fake-curl arg parsing needs a while-shift loop (for-loop snapshots desync $2); fetch_url_with_retry validates kind=json so winner fixtures must serve valid JSON. 🤖 Generated with [Claude Code](https://claude.ai/code) - GLM-5.3 Co-Authored-By: Claude <noreply@anthropic.com>
shrwnsan
force-pushed
the
feat/negative-cache
branch
from
August 27, 2026 10:08
624855a to
abcc92c
Compare
…arisons
The load-based job auto-adjust can halve the pinned BREW_CHANGE_JOBS on
a busy runner between the two compared invocations ('max 2 jobs' vs
'max 4 jobs'), flaking the NO_COLOR byte-identity assertion. Observed
once on the macOS CI runner; three consecutive local runs green after
normalization. Latent since the suite was created — not caused by the
negative cache.
Co-Authored-By: Claude <noreply@anthropic.com>
Owner
Author
|
Merge process note (recorded for transparency): maintainer-approved in-session ('Word' on the merge proposal). Same disclosed lift-merge-restore as #122–#142; protection restored immediately after, verified by API diff. Also carries a latent-flake fix in the verdict suite (jobs-line normalization) documented in the commit history. 🤖 Generated with Claude Code - GLM-5.3 |
This was referenced Sep 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the parked idea from the v1.19.0 cache investigation: negative caching with a short TTL for concluded no-notes probes.
The measured problem
Instrumented runs showed a fresh process re-served 27 responses from the on-disk HTTP cache yet still took ~3 minutes. Attribution: the ~10 no-notes packages re-probe their entire non-GitHub chains (up to ~14 URLs with retries each) every run, because failed probes are deliberately never cached — caching "no notes" would freeze the unknown state.
The design (performance memo, never evidence)
fetch_non_github_release_notesconcludes nothing forpackage@version, a 10-minute negative entry is written (HTTP_CACHE_NEGATIVE_TTL_SECONDS=600).--freshclears it; prune budgets apply; same namespace/hashing as the HTTP cache; no tokens, no provenance, no events.Effect on the motivating case
Immediate re-run: the 10 no-notes packages go from ~14 network attempts each to zero; remaining time is legit evidence fetches. No
--freshsemantic changes.Tests
New
tests/test-negative-cache.sh(14 assertions; runner 31 → 32): helper roundtrip/TTL-expiry/corrupt-fails-closed; chain integration with curl-call counting (run 1 probes N URLs → run 2 performs zero); expiry re-probe; success clears;--freshclears. Three suite-infrastructure gotchas fixed en route (documented in the commit): CACHE_DIR/MAX_RETRIES must be exported before config.sh resolves them readonly; fake-curl arg parsing needs while-shift; json-kind validation means winner fixtures must serve valid JSON.🤖 Generated with Claude Code - GLM-5.3
Co-Authored-By: Claude noreply@anthropic.com