fix(review): key the durable CI-state cache on resolved required contexts - #3036
Conversation
…exts cachedFetchLiveCiAggregate (#2984) keyed its durable pull_request_detail_sync_state row from the raw, unresolved settings.expectedCiContexts config instead of the actually-resolved required-contexts set that cachedRequiredStatusContexts returns (branch protection merged with config, via mergeRequiredCiContexts). If branch protection changes server-side while expectedCiContexts config and head_sha stay the same, the durable key was unchanged, so the readiness path could keep serving a stale aggregate computed against the old required-context set for up to the cache's TTL. Derive the key from the resolved set instead. Also hardens deserializeCachedCiAggregate: JSON.parse succeeding does not guarantee the parsed value is an array, so a corrupted/malformed row's failingDetails/nonRequiredFailingDetails now fail open to a cache miss via an explicit Array.isArray check rather than handing callers a wrong shape.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3036 +/- ##
=======================================
Coverage 96.08% 96.08%
=======================================
Files 260 260
Lines 28774 28777 +3
Branches 10475 10477 +2
=======================================
+ Hits 27647 27650 +3
Misses 492 492
Partials 635 635
🚀 New features to boost your workflow:
|
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ Gittensory review result - manual review recommendedReview updated: 2026-07-04 09:45:32 UTC
⏸️ Suggested Action - Manual Review
Review summary Nits — 4 non-blocking
Concerns raised — review before merging
Review context
Contributor next steps
Signal definitions
🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
Summary
pull_request_detail_sync_state), butcachedFetchLiveCiAggregate's durable-row key was derived from the raw, unresolvedsettings.expectedCiContextsconfig instead of the actually-resolved required-contexts set thatcachedRequiredStatusContextscomputes (branch protection merged with config, viamergeRequiredCiContexts).expectedCiContextsconfig and the PR'shead_shastay the same, the durable cache key was unchanged, so the readiness path could keep serving a stale aggregate computed against the old required-context set for up to the cache's 60s TTL — a wrong merge/close verdict window. This PR derives the durable key from the resolved set (resolvedRequiredContextsKeyPart) instead.deserializeCachedCiAggregate:JSON.parsesucceeding does not guarantee the parsed value is an array, so a corrupted/malformed row'sfailingDetails/nonRequiredFailingDetailsnow fail open to a cache miss via an explicitArray.isArraycheck rather than handing callers a wrong shape.Scope
type(scope): short summaryConventional Commit format, for examplefix(api): restore profile access checks.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Validation
git diff --checknpm run actionlint(not run — no workflow files touched)npm run typechecknpx vitest run test/unit/queue.test.ts test/unit/pr-detail-durable-cache.test.ts, 527/527 passing); full unshardednpm run test:coveragenot re-run locally per this repo's own guidance to trust CI for the full suite on a narrowly-scoped fix.npm run test:workers(not run — no Cloudflare-Workers-pool-specific code touched)npm run build:mcp/npm run test:mcp-pack(not run — no MCP package changes)npm run ui:openapi:check/npm run ui:lint/npm run ui:typecheck/npm run ui:build(not run — no API/OpenAPI surface orapps/gittensory-uichanges)npm audit --audit-level=moderate(unaffected by this diff; last known-clean from the same working tree)If any required check was skipped, explain why:
validatejob runs them as a backstop.Safety
UI Evidencesection below with screenshots. (N/A — no visible UI changes.)Notes