Lines 2555-2595javascript
2555// GitHub before trusting the snapshot. A soft existence check is
2556// enough — if the first issue genuinely 404s, treat the whole
2557// snapshot as stale (most likely a leftover from a prior
2558// project/repo that was purged) and let the caller drop it. One
2559// gh call per cache miss, wrapped in the existing
2560// BATCH_PROGRESS_TTL_MS cache upstream.
2563// "fresh" — first issue resolved, snapshot is trustworthy
2564// "gone" — first issue confirmed 404; snapshot should be dropped
2565// "unknown" — transient error (auth/network/timeout); leave
2566// snapshot alone and let the next cache miss retry
2567async function checkBatchSnapshotFreshness(repo, snapshot) {
2568 if (!snapshot || !Array.isArray(snapshot.issueNumbers) || snapshot.issueNumbers.length === 0) {
2571 const first = snapshot.issueNumbers[0];
2573 // #828 P1: REST, not `gh issue view` (GraphQL). We only need existence, so
2574 // the cheap REST issue endpoint suffices and keeps the whole batch-progress
2575 // path off GraphQL.
2576 await ghJsonExecAsync(["api", `repos/${repo}/issues/${first}`, "--jq", ".number"]);
2579 // gh surfaces a 404 via stderr text on a non-zero exit. Only
2580 // the unambiguous "not found" / "could not resolve" shapes
2581 // count as genuinely gone; anything else (network, auth,
2582 // timeout) is transient and must NOT delete the snapshot.
2583 const msg = String((err && (err.stderr || err.message)) || "").toLowerCase();
2584 if (msg.includes("could not resolve") || msg.includes("not found") || msg.includes("http 404")) {
2591// Decide which batch to render, combining the live parse of
2592// OVERNIGHT-QUEUE.md with the persistent snapshot. The snapshot is
2593// replaced whenever a new batch starts (explicit Batch: N bump OR
2594// the live Active Batch contains items the snapshot doesn't); in
2595// all other cases the snapshot wins, so items Head moved to Done