Skip to content

test(gate,ai,rate-limit): recover coverage work orphaned by the #9501/#9504/#9505 merges - #9509

Merged
JSONbored merged 5 commits into
mainfrom
fix/orphaned-coverage-followup
Jul 28, 2026
Merged

test(gate,ai,rate-limit): recover coverage work orphaned by the #9501/#9504/#9505 merges#9509
JSONbored merged 5 commits into
mainfrom
fix/orphaned-coverage-followup

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

Recovers coverage work for #9460, #9462, #9476, #9479 and #9494 that was orphaned when PRs #9501, #9504 and #9505 merged while the follow-up commits were still in flight.

No behaviour change beyond two dead-code removals — this is the test and annotation work those three PRs were missing when they landed, plus the codecov/patch gap that was open on each at merge time.

What happened

#9501, #9503, #9504 and #9505 merged at 00:27–00:48 UTC. I had pushed additional coverage commits to those branches shortly before and after, and the squash-merges took the branch state as of the merge, so five commits never reached main:

Commit Content In main?
test(gate): fail-safe marker-clear path queue-3
refactor(gate): unreachable spread arm + defensive guard annotation processors
test(ai): exclude two unreachable cleanup arms ai.ts
test(ai): real-subprocess EPIPE + non-Error stall guard selfhost-ai, ai-review
test(rate-limit): inline-retry break for an over-budget Retry-After github-app

Verified by content rather than SHA (squash-merge rewrites SHAs): greping origin/main for each change's distinguishing marker. The metrics registration and the marker-clear-on-exhaustion test did land and are not re-applied here.

Each commit is cherry-picked with -x, so the original SHA is recorded in its message.

Contents

#9462 — fail-safe marker clear. A rejecting clearPullRequestVisualCaptureRetryPending must not throw out of the pass; a failed clear only means the gate stays deferred until the head moves. Mirrors the sibling visual-capture-satisfied fail-safe test.

#9462 — dead code. screenshotTableEvidenceUnresolved is computed as a plain boolean, so the !== undefined arm of its conditional spread was unreachable; it is passed directly now. The head-SHA guard in the budget-exhausted branch is genuinely defensive (a recapture-preview job is only minted for a PR that had one, and the sibling mark write carries the identical guard), so it gets a documented reason rather than a contrived test.

#9479 — EPIPE, as a real regression. This one matters: it drives the real subprocess via the existing fake-CLI-on-PATH harness rather than a stubbed spawn, so the child.stdin error listener is genuinely exercised. A fake CLI exits immediately without draining stdin, and the test asserts no uncaughtException reaches the process. Verified to fail without the listener — it captures an uncaught EPIPE, which is exactly the crash that took down every in-flight queue job in the container.

#9476 — non-Error stall guard. isStalledNoOutput must reject a non-Error value rather than throwing on .message; a provider adapter can reject with a string, and misclassifying that as a deadline signal would silently skip the retry budget.

#9479 — two unreachable cleanup arms annotated with their reasons: rm with force: true does not throw for a missing path, and the unset-cwd guard is only reachable when mkdtemp itself threw.

#9494 — inline-retry break. Asserts the attempt count, not just the classification: a 60s Retry-After yields exactly one attempt instead of four, while a short one still uses the full inline budget so the break stays narrow.

Validation

  • npx tsc --noEmit -p tsconfig.json — clean
  • 1052 passed across queue-3, selfhost-ai, ai-review, github-app, agent-actions
  • Patch coverage measured against this diff: 0 uncovered changed lines

Note for future PRs in this series

The lesson is recorded rather than just fixed: pushing a follow-up commit to a branch whose PR is eligible to merge races the merge, and the squash takes whatever the branch held at that instant. For the remaining PRs in this series I'm verifying landed content by grepping origin/main for a distinguishing marker rather than trusting that a push to the branch implies a change in main.

Mirrors the sibling visual-capture-satisfied fail-safe test: a rejecting clear must not throw
out of the pass, since a failed clear only means the gate stays deferred until the head moves.

(cherry picked from commit efa6472)
…sive head-SHA guard (#9462)

screenshotTableEvidenceUnresolved is computed as a plain boolean, so the undefined arm of its
conditional spread was dead code -- pass it directly. The head-SHA guard in the exhausted branch
is genuinely defensive (a recapture-preview job is only minted for a PR that had one), matching
the sibling mark write, so it carries a reason rather than a contrived test.

(cherry picked from commit 4f59499)
…age (#9479)

rm with force:true does not throw for a missing path, so the catch needs a filesystem-level
failure no unit test can portably induce; the unset-cwd guard is only reachable when mkdtemp
itself threw, i.e. no directory was ever created. Both annotated with their reason, matching
the file's existing convention.

(cherry picked from commit bf3efe6)
…l guard (#9476, #9479)

The EPIPE regression uses the existing real-subprocess harness rather than a stubbed spawn, so
the stdin error listener is genuinely exercised: a fake CLI exits immediately without draining
stdin, and the test asserts no uncaughtException reaches the process. Verified to fail without
the listener (it captures an uncaught EPIPE), which is precisely the crash that took down every
in-flight queue job in the container.

Also covers isStalledNoOutput rejecting a non-Error throw -- a provider adapter can reject with
a string, and misclassifying that as a deadline signal would silently skip the retry budget.

(cherry picked from commit c770cc1)
…ry-After (#9494)

Asserts the attempt COUNT, not just the classification: a 60s Retry-After yields exactly one
attempt instead of four, and a short one still uses the full inline budget so the break stays
narrow.

(cherry picked from commit 92813bf)
@loopover-orb

loopover-orb Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Warning

⏸️ LoopOver review result - manual review recommended

Review updated: 2026-07-28 02:00:10 UTC

6 files · 1 AI reviewer · 1 blocker · CI green · clean

⏸️ Suggested Action - Manual Review

Review summary
This PR recovers five test/annotation commits that were dropped when three prior PRs squash-merged mid-flight, plus two small dead-code cleanups (an unreachable conditional-spread arm in processors.ts and an already-handled falsy-cwd/rm-failure v8 ignore in ai.ts). The changes are low-risk: the processors.ts edit collapses `...(x !== undefined ? {x} : {})` to a plain `x` assignment since `screenshotTableEvidenceUnresolved` is always a boolean, which is a correct no-op simplification, and the new tests exercise real fail-safe/retry/EPIPE paths rather than fabricated scenarios. CI is fully green including codecov/patch, and the diff matches its stated intent of recovering orphaned coverage work with no new behavior beyond the two documented dead-code removals.

Nits — 3 non-blocking
  • The PR title/description frames this as pure test/annotation recovery, but the `screenshotTableEvidenceUnresolved` change in src/queue/processors.ts:2862 is a real (if trivial) behavioral simplification of production code, not just a v8-ignore annotation — worth calling out explicitly as such rather than bundling it under 'dead-code removal' framing.
  • The PR description doesn't link an eligible open issue per repo convention for external contributor PRs; confirm this qualifies as maintainer-authorized recovery work rather than needing its own issue reference.
  • Consider a one-line note in the PR body confirming that `screenshotTableEvidenceUnresolved` was verified to always be boolean-typed at its call site, since that's the load-bearing assumption behind the src/queue/processors.ts:2862 simplification.

Concerns raised — review before merging

  • No linked issue detected: No closing reference or linked issue number was found in the PR metadata/body. — If this PR is intended to solve an issue, link it explicitly in the PR body.
📋 Copy for AI agents — paste into your coding agent
Fix the following blocker(s) from this PR review:

1. No linked issue detected: No closing reference or linked issue number was found in the PR metadata/body. — If this PR is intended to solve an issue, link it explicitly in the PR body.

Decision drivers

  • ❌ Code review — 1 blocker (1 reviewer)
  • ❌ Gate result — Blocking (Repo-configured hard blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ No-issue rationale PR body explains why no issue is linked.
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (no linked issue context).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 14 registered-repo PR(s), 13 merged, 334 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 14 PR(s), 334 issue(s).
Improvement ✅ Minor risk: clean · value: minor
Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Python, TypeScript, Ruby, Go, MDX, Shell, Solidity, JavaScript
  • Official Gittensor activity: 14 PR(s), 334 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Start here: Treat this as maintainer-lane context rather than normal contributor-lane activity.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask <question> answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat <question> answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

Decision record
  • action: hold · clause: missing_linked_issue
  • config: 5230634cccebbe5e9acd25bdbc68514ef6c5367c540fb643e25f647301ee7e29 · pack: oss-anti-slop · ci: passed
  • record: fd1f88b6288a1a342ee74951a9fa4e764574ac0ad4dae5080cdc11520615f428 (schema v5, head 3f8f2b5)

🟩 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 LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.65%. Comparing base (bf1d500) to head (3f8f2b5).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #9509      +/-   ##
==========================================
- Coverage   89.55%   88.65%   -0.90%     
==========================================
  Files         843      843              
  Lines      110106   110101       -5     
  Branches    26203    26200       -3     
==========================================
- Hits        98601    97610     -991     
- Misses      10239    11520    +1281     
+ Partials     1266      971     -295     
Flag Coverage Δ
backend 93.62% <ø> (-1.64%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/queue/processors.ts 94.82% <ø> (+0.08%) ⬆️
src/selfhost/ai.ts 98.30% <ø> (-0.01%) ⬇️

... and 5 files with indirect coverage changes

@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 28, 2026
@JSONbored
JSONbored merged commit d1c770c into main Jul 28, 2026
7 checks passed
@JSONbored
JSONbored deleted the fix/orphaned-coverage-followup branch July 28, 2026 02:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

manual-review Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant