Plan reference
Design spec (it lives in GitLfsCache, where it was written):
https://github.com/ktsu-dev/GitLfsCache/blob/4f67a33a5218f991784698181030e9eb5a2fc9ae/docs/superpowers/specs/2026-08-19-gitbranchstatecache-design.md#L221-L223
A ktsu.GitBranchStateCache meter: state requests, diff cache hits and misses, fetches, fetch failures, fetch duration, diff computation duration, … The ratio to watch is diff cache hits against misses …
What exists today
GitBranchStateCache/Observability/BranchStateMetrics.cs:75 creates the gitbranchstatecache.fetch_duration histogram, and :134 defines RecordFetchDuration(string upstream, TimeSpan elapsed).
- Nothing calls
RecordFetchDuration. A repo-wide grep finds only the definition. MirrorFetcher.CloneAsync (Mirrors/MirrorFetcher.cs:~124-188) and FetchAsync (~190-226) never time their git call.
DiffCache.ComputeAsync (Diffs/DiffCache.cs:~228-231) counts a diff that fails or times out only in diff_failures, never in diff_cache_misses.
Why it matters
- A dashboard or alert on fetch latency shows nothing, even after clones and fetches run. Checked with a
MeterListener on fetch_duration: recorded=0 after a request that ran a clone.
- The README names the hit/miss ratio as the one to watch. Because failed diffs aren't counted as misses, that ratio leaves out the slowest, most expensive diffs, which are exactly the ones that matter, so it looks healthier than it is.
Acceptance criteria
Dependencies
None.
Plan reference
Design spec (it lives in GitLfsCache, where it was written):
https://github.com/ktsu-dev/GitLfsCache/blob/4f67a33a5218f991784698181030e9eb5a2fc9ae/docs/superpowers/specs/2026-08-19-gitbranchstatecache-design.md#L221-L223What exists today
GitBranchStateCache/Observability/BranchStateMetrics.cs:75creates thegitbranchstatecache.fetch_durationhistogram, and:134definesRecordFetchDuration(string upstream, TimeSpan elapsed).RecordFetchDuration. A repo-wide grep finds only the definition.MirrorFetcher.CloneAsync(Mirrors/MirrorFetcher.cs:~124-188) andFetchAsync(~190-226) never time their git call.DiffCache.ComputeAsync(Diffs/DiffCache.cs:~228-231) counts a diff that fails or times out only indiff_failures, never indiff_cache_misses.Why it matters
MeterListeneronfetch_duration:recorded=0after a request that ran a clone.Acceptance criteria
fetch_duration, tagged with the upstream, on success and on failure or timeout. Optionally add akind=clone|fetchtag.MeterListenerassert that both are recorded, for example withScriptedGitrunning one clone and one fetch, plus one timed-out diff.Dependencies
None.