Skip to content

feat(gate): add the block tier, so an enforcing screenshot gate holds a PR instead of destroying it - #9964

Merged
JSONbored merged 1 commit into
mainfrom
feat/screenshot-gate-block-tier
Jul 30, 2026
Merged

feat(gate): add the block tier, so an enforcing screenshot gate holds a PR instead of destroying it#9964
JSONbored merged 1 commit into
mainfrom
feat/screenshot-gate-block-tier

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Closes #9881 (second half — the first, degrading enforcement where the bot cannot produce evidence, is already on main)

Why a middle tier

close and advisory were the only options: destroy the PR, or enforce nothing.

That middle matters here specifically because reviews are one-shot for contributor work. There is no "changes requested, try again" state, so an enforcing gate converted every miss into unrecoverable loss — right for genuine slop, wrong for a PR that simply has not attached screenshots yet. The contributor cannot reopen.

block holds the PR (no merge, never a close) and says exactly what is missing, so the hold is actionable rather than a silent stall. It clears itself the moment evidence appears — a body table, or a successful bot capture.

Correct by construction

The hold joins MERGE_HOLD_INPUTS, so every surface folds it in automatically rather than through three edits that can each be forgotten — the table exists precisely because a hold once got declared and silently not honoured.

It respects the same two exemptions the close does: a live capture retry (the evidence may still be coming) and a degraded enforcement (the bot cannot produce evidence in this repo at all). A hold with an unmeetable condition is just a slower close.

Both label paths carry the message — the merge-authorized fallback and the disposition ternary. They serve different repo configurations (merge-autonomy vs label-only), and either one missing it would hand half the fleet a bare label with no reason.

A dead-branch cleanup found on the way

That comment ternary restated its eligibility guard (!linkedIssueCloseInFlight && !unlinkedIssueMatchViolated && reviewGood) in all six arms. Reaching a later arm already proved the earlier arm’s identical guard true, so every copy after the first was structurally unreachable-false — dead sub-branches that could never be covered because they could never be hit. Hoisted to a single evaluation; the whole chain is now reachable.

That is also what surfaced the one genuinely untested configuration: the disposition ternary only fires where merge autonomy is off and review_state_label is on, because the fallback otherwise claims the label first. Now covered.

Verification

Full suite: 25,895 passing, zero failures. Changed-line coverage: zero uncovered statements, zero uncovered branches (measured against a full-suite run, not a scoped one). contract:api-schemas, ui:openapi, db:schema-drift, dead-exports and fixture-clock-races all clean.

block is additive — no repo gets it without opting in, so existing close/advisory behaviour is byte-identical.

… a PR instead of destroying it

`close` and `advisory` were the only options: destroy the PR, or enforce
nothing. That middle matters because reviews here are ONE-SHOT for contributor
work -- there is no "changes requested, try again" state -- so an enforcing
gate converted every miss into unrecoverable loss. Right for genuine slop,
wrong for a PR that simply has not attached screenshots yet, and the
contributor cannot reopen.

`block` holds the PR (no merge, never a close) and says exactly what is
missing, so the hold is actionable rather than a silent stall. It clears itself
the moment evidence appears -- a body table, or a successful bot capture.

The hold joins MERGE_HOLD_INPUTS, so every surface folds it in by construction
rather than by three edits that can each be forgotten. It respects the same two
exemptions the close does: a live capture retry (the evidence may still be
coming) and a degraded enforcement (#9881's first half -- the bot cannot
produce evidence in this repo at all). A hold with an unmeetable condition is
just a slower close.

Both label paths carry the message: the merge-authorized fallback and the
disposition ternary. They cover different repo configurations -- the fallback
serves merge-autonomy repos, the ternary serves label-only ones -- and either
missing it would hand half the fleet a bare label with no reason.

Also hoists that comment ternary's eligibility guard, which was restated in
all six arms. Reaching a later arm already proved the earlier arm's identical
guard true, so every copy after the first was structurally unreachable-false --
dead sub-branches that could never be covered because they could never be hit.
Evaluated once now, and the whole chain is reachable.

Closes #9881
@loopover-orb

loopover-orb Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Warning

⏸️ LoopOver review result - manual review recommended

Review updated: 2026-07-30 22:20:14 UTC

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

⏸️ Suggested Action - Manual Review

Review summary
Adds a new `block` action to the screenshot-table gate as a middle tier between `close` and `advisory`, wiring it through the type/schema/OpenAPI surfaces, the merge-hold plan input, the disposition-label comment ternary, and the processor that computes the hold reason from the existing evaluator/degradation/retry signals. The refactor of the six-arm comment ternary into a single hoisted eligibility check is a real and correct simplification (each later arm's repeated guard was indeed unreachable-false once an earlier arm was known false), and both the merge-fallback and disposition-label paths carry the comment as claimed. Tests cover the plan-level unit behavior and one processor-level integration scenario; CI is green across the board.

Nits — 6 non-blocking
  • src/queue/processors.ts: `screenshotBlockReason` is computed from `screenshotTableGateResult.violated`, `.action === "block"`, `!botCaptureRetryPending`, `!screenshotTableEnforcementDegraded` — worth double-checking this exactly mirrors the equivalent `close` gating condition elsewhere in the file so the two paths can't drift (not visible in the diff whether they're derived from one shared predicate).
  • test/unit/queue-3.test.ts: the new integration test explicitly defers asserting the hold's exact comment string to agent-actions.test.ts — reasonable given the reviewGood gating explained in the comment, but worth a one-line pointer comment at the top of the block-tier describe block in agent-actions.test.ts back to this integration test for symmetry.
  • packages/loopover-engine/src/review/screenshot-table-gate.ts: `VALID_ACTIONS` now includes `block` and is asserted in screenshot-table-gate-engine.test.ts, but I could not view the full evaluator file in this pass to confirm no other place normalizes/validates the action string independently.
  • Consider a short changelog/doc note (if the repo has a config reference doc for `screenshotTableGate.action`) enumerating the new `block` value alongside `close`/`advisory`, since it's a public-facing config option surfaced in the OpenAPI schema.
  • In src/settings/agent-actions.ts, the merge-fallback block for `screenshotEvidenceHold` duplicates the priorityEligibilityHold block almost verbatim (same shape, different fields) — worth flagging as a nit-level DRY opportunity, but not one to block on given the surrounding code already accepts this pattern per-hold.
  • PR author also opened the linked issue — Link an issue that was opened by a different contributor, or provide a rationale for why this self-authored issue represents genuine discovery work.

Concerns raised — review before merging

  • No linked issue detected: The PR cites an issue number, but it could not be verified as a currently open issue. — 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: The PR cites an issue number, but it could not be verified as a currently open issue. — 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 ✅ Linked #9881
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 (1 linked issue).
Validation posture ⚠️ 20/25 Preflight is ready, but the PR body does not name the validation run.
Contributor workload ✅ 10/10 Author activity: 9 registered-repo PR(s), 8 merged, 287 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 9 PR(s), 287 issue(s).
Improvement ✅ Minor risk: clean · value: minor
Linked issue satisfaction

Addressed
The PR adds a real "block" tier to ScreenshotTableGateAction (types, schemas, gate config, openapi), wires a screenshotEvidenceHold that suppresses merge without closing, ensures the hold's comment is carried on both the merge-authorized and label-only disposition paths, and adds tests confirming the PR survives (no close, no merge) with an actionable message.

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: 9 PR(s), 287 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Start here: Treat this as maintainer-lane context rather than normal contributor-lane activity.
  • Then work through the remaining 1 step in the Signals table above.
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: 622f6c30882b926f4f90099dd7df2a6b55c0096a8f8e4a4139290d970dd7bdf7 · pack: oss-anti-slop · ci: passed
  • record: 08df43937da44ac5a0780db99ba0de12713ecb6eba058222da120ece9b0d24ec (schema v6, head 0149387)
Visual preview
Route Viewport Before (production) After (this PR's preview) Diff
/ desktop before /
before /
after /
after /
/ mobile before / (mobile)
before / (mobile)
after / (mobile)
after / (mobile)

Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy.

Scroll preview
Route Before (production) After (this PR's preview)
/ before / (scroll)
before / (scroll)
after / (scroll)
after / (scroll)

A short scroll-through clip (desktop) — click either thumbnail to open the full animation. Evidence for scroll-linked behavior a single screenshot can't show.

🟩 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.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
loopover-ui 0149387 Commit Preview URL

Branch Preview URL
Jul 30 2026, 09:56 PM

@codecov

codecov Bot commented Jul 30, 2026

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 35 bytes (0.0%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
loopover-ui 7.89MB 35 bytes (0.0%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: loopover-ui

Assets Changed:

Asset Name Size Change Total Size Change (%)
assets/add-scalar-classes-BxegsTgr.js (New) 2.16MB 2.16MB 100.0% 🚀
assets/tanstack-vendor-2HUdJ24L.js (New) 955.23kB 955.23kB 100.0% 🚀
openapi.json 27 bytes 760.24kB 0.0%
assets/docs.fumadocs-spike-api-reference-CtJoniJB.js (New) 443.45kB 443.45kB 100.0% 🚀
assets/AgentScalarChatInterface.vue-C5lck9R9.js (New) 201.69kB 201.69kB 100.0% 🚀
assets/modal-BVY7PGtO.js (New) 184.5kB 184.5kB 100.0% 🚀
assets/client-OhODnFip.js (New) 151.47kB 151.47kB 100.0% 🚀
assets/maintainer-panel-DFTt3CzE.js (New) 78.97kB 78.97kB 100.0% 🚀
assets/routes-CRKnP2kU.js (New) 35.88kB 35.88kB 100.0% 🚀
assets/owner-panel-C9b24fyh.js (New) 28.26kB 28.26kB 100.0% 🚀
assets/app-hg5LFwdQ.js (New) 25.82kB 25.82kB 100.0% 🚀
assets/ui-vendor-RbhJ8-YK.js (New) 24.57kB 24.57kB 100.0% 🚀
assets/fairness-DdU3y00d.js (New) 23.13kB 23.13kB 100.0% 🚀
assets/miner-panel-DL08jmFm.js (New) 20.49kB 20.49kB 100.0% 🚀
assets/api._op-vuP3sJml.js (New) 17.51kB 17.51kB 100.0% 🚀
assets/self-hosting-docs-audit-8tZ_kOgH.js (New) 16.6kB 16.6kB 100.0% 🚀
assets/docs-client-loader-_NMQAk_n.js (New) 15.51kB 15.51kB 100.0% 🚀
assets/playground-panel-IjFqreXU.js (New) 14.35kB 14.35kB 100.0% 🚀
assets/app.audit-EUv3ruNu.js (New) 10.22kB 10.22kB 100.0% 🚀
assets/app.config-generator-BsT88wIJ.js (New) 10.06kB 10.06kB 100.0% 🚀
assets/maintainers-B-jZ_wAb.js (New) 8.06kB 8.06kB 100.0% 🚀
assets/miners-CYCTUFNb.js (New) 7.91kB 7.91kB 100.0% 🚀
assets/agents-B8pehFIy.js (New) 7.74kB 7.74kB 100.0% 🚀
assets/commands-panel-jPoTmg95.js (New) 6.74kB 6.74kB 100.0% 🚀
assets/maintainer-workflow-DnhdUeAf.js (New) 6.52kB 6.52kB 100.0% 🚀
assets/digest-panel-CqHYQnCC.js (New) 6.15kB 6.15kB 100.0% 🚀
assets/repos._owner._repo.quality-DZieMPL4.js (New) 6.14kB 6.14kB 100.0% 🚀
assets/docs-nav-Cb1K5Guh.js (New) 6.12kB 6.12kB 100.0% 🚀
assets/docs.index-DTMxYYYS.js (New) 6.01kB 6.01kB 100.0% 🚀
assets/api.index-CBYYth35.js (New) 4.7kB 4.7kB 100.0% 🚀
assets/docs-D_SXna4G.js (New) 3.01kB 3.01kB 100.0% 🚀
assets/api-BGWA0R3s.js (New) 2.66kB 2.66kB 100.0% 🚀
assets/docs-page-BsiyKcQU.js (New) 2.14kB 2.14kB 100.0% 🚀
assets/table-NAZu7-5C.js (New) 1.75kB 1.75kB 100.0% 🚀
assets/app.workbench-C1MXRspm.js (New) 1.58kB 1.58kB 100.0% 🚀
assets/tabs-X8ijsoJS.js (New) 1.39kB 1.39kB 100.0% 🚀
assets/app.repos-6HrI7jMk.js (New) 1.07kB 1.07kB 100.0% 🚀
assets/input-DpE2m1D-.js (New) 796 bytes 796 bytes 100.0% 🚀
assets/file-cog-DrfgdnCt.js (New) 758 bytes 758 bytes 100.0% 🚀
assets/docs._slug-CxRNRrTx.js (New) 549 bytes 549 bytes 100.0% 🚀
assets/app.maintainer-CnuCWZDF.js (New) 502 bytes 502 bytes 100.0% 🚀
assets/app.owner-u-ay0H-I.js (New) 474 bytes 474 bytes 100.0% 🚀
assets/app.commands-DwuEGu23.js (New) 455 bytes 455 bytes 100.0% 🚀
assets/app.playground-DARQvRB2.js (New) 442 bytes 442 bytes 100.0% 🚀
assets/index-DwwUSC7s.js (New) 438 bytes 438 bytes 100.0% 🚀
assets/app.digest-DLW_fKcR.js (New) 430 bytes 430 bytes 100.0% 🚀
assets/eye-off-C_kr8xkZ.js (New) 430 bytes 430 bytes 100.0% 🚀
assets/app.miner-DNilhSXo.js (New) 422 bytes 422 bytes 100.0% 🚀
assets/key-round-nLMcHTgq.js (New) 355 bytes 355 bytes 100.0% 🚀
assets/bot-CV-pzkU-.js (New) 328 bytes 328 bytes 100.0% 🚀
assets/git-pull-request-arrow-wSANITH4.js (New) 321 bytes 321 bytes 100.0% 🚀
assets/list-checks-DloCy6An.js (New) 279 bytes 279 bytes 100.0% 🚀
assets/compass-BJ7LoyL1.js (New) 251 bytes 251 bytes 100.0% 🚀
assets/history-CtBB2Rpi.js (New) 237 bytes 237 bytes 100.0% 🚀
assets/message-square-DY1DwnTu.js (New) 233 bytes 233 bytes 100.0% 🚀
assets/lock-D_IhjTr8.js (New) 206 bytes 206 bytes 100.0% 🚀
assets/play-BUsxDXYp.js (New) 190 bytes 190 bytes 100.0% 🚀
assets/circle-check-_NZCUse9.js (New) 178 bytes 178 bytes 100.0% 🚀
assets/add-scalar-classes-BBxa0HJK.js (Deleted) -2.16MB 0 bytes -100.0% 🗑️
assets/tanstack-vendor-BscK54hV.js (Deleted) -955.23kB 0 bytes -100.0% 🗑️
assets/docs.fumadocs-spike-api-reference-Dh2O9Ona.js (Deleted) -443.45kB 0 bytes -100.0% 🗑️
assets/AgentScalarChatInterface.vue-zXJgkw7Q.js (Deleted) -201.69kB 0 bytes -100.0% 🗑️
assets/modal-xT_MNFKy.js (Deleted) -184.5kB 0 bytes -100.0% 🗑️
assets/client-_huv1Wig.js (Deleted) -151.47kB 0 bytes -100.0% 🗑️
assets/maintainer-panel-DoMpuSt1.js (Deleted) -78.97kB 0 bytes -100.0% 🗑️
assets/routes-PJKca5B7.js (Deleted) -35.88kB 0 bytes -100.0% 🗑️
assets/owner-panel-CMF1dooA.js (Deleted) -28.26kB 0 bytes -100.0% 🗑️
assets/app-CJT73Xi1.js (Deleted) -25.82kB 0 bytes -100.0% 🗑️
assets/ui-vendor-BaxrNVXE.js (Deleted) -24.57kB 0 bytes -100.0% 🗑️
assets/fairness-CrTEYvbM.js (Deleted) -23.13kB 0 bytes -100.0% 🗑️
assets/miner-panel-CCF36kER.js (Deleted) -20.49kB 0 bytes -100.0% 🗑️
assets/api._op-B1C7_57x.js (Deleted) -17.51kB 0 bytes -100.0% 🗑️
assets/self-hosting-docs-audit-B8E1d0ta.js (Deleted) -16.6kB 0 bytes -100.0% 🗑️
assets/docs-client-loader-lg5Zecm9.js (Deleted) -15.51kB 0 bytes -100.0% 🗑️
assets/playground-panel-B_b3kPqb.js (Deleted) -14.35kB 0 bytes -100.0% 🗑️
assets/app.audit-CYi1azDe.js (Deleted) -10.22kB 0 bytes -100.0% 🗑️
assets/app.config-generator-CnCmLbq7.js (Deleted) -10.06kB 0 bytes -100.0% 🗑️
assets/maintainers-CcdJbh4Q.js (Deleted) -8.06kB 0 bytes -100.0% 🗑️
assets/miners-DLD4Gd0m.js (Deleted) -7.91kB 0 bytes -100.0% 🗑️
assets/agents-DNo2Rn0e.js (Deleted) -7.74kB 0 bytes -100.0% 🗑️
assets/commands-panel-5XIhC5g_.js (Deleted) -6.74kB 0 bytes -100.0% 🗑️
assets/maintainer-workflow-BRhD8rP_.js (Deleted) -6.52kB 0 bytes -100.0% 🗑️
assets/digest-panel-DdRAjF0M.js (Deleted) -6.15kB 0 bytes -100.0% 🗑️
assets/repos._owner._repo.quality-Br5PRjoH.js (Deleted) -6.14kB 0 bytes -100.0% 🗑️
assets/docs-nav-cRgG82lE.js (Deleted) -6.12kB 0 bytes -100.0% 🗑️
assets/docs.index-DNuzSZqa.js (Deleted) -6.01kB 0 bytes -100.0% 🗑️
assets/api.index-Ce4fHHPq.js (Deleted) -4.7kB 0 bytes -100.0% 🗑️
assets/docs-63PiP8gi.js (Deleted) -3.01kB 0 bytes -100.0% 🗑️
assets/api-OMmcKtFX.js (Deleted) -2.66kB 0 bytes -100.0% 🗑️
assets/docs-page-O-Miwa9B.js (Deleted) -2.14kB 0 bytes -100.0% 🗑️
assets/table-Baec_jlt.js (Deleted) -1.75kB 0 bytes -100.0% 🗑️
assets/app.workbench-BShL47m6.js (Deleted) -1.58kB 0 bytes -100.0% 🗑️
assets/tabs-UPZqhlz8.js (Deleted) -1.39kB 0 bytes -100.0% 🗑️
assets/app.repos-Dwl2GQm2.js (Deleted) -1.07kB 0 bytes -100.0% 🗑️
assets/input-DfKENsaY.js (Deleted) -796 bytes 0 bytes -100.0% 🗑️
assets/file-cog-Cuhlcf-X.js (Deleted) -758 bytes 0 bytes -100.0% 🗑️
assets/docs._slug-Dx9Rkmw0.js (Deleted) -549 bytes 0 bytes -100.0% 🗑️
assets/app.maintainer-DRMPsFDD.js (Deleted) -502 bytes 0 bytes -100.0% 🗑️
assets/app.owner-TbTiS7J8.js (Deleted) -474 bytes 0 bytes -100.0% 🗑️
assets/app.commands-DrLEkaDq.js (Deleted) -455 bytes 0 bytes -100.0% 🗑️
assets/app.playground-BGehCUnK.js (Deleted) -442 bytes 0 bytes -100.0% 🗑️
assets/index-B071sGIW.js (Deleted) -438 bytes 0 bytes -100.0% 🗑️
assets/app.digest-DXoY7IQs.js (Deleted) -430 bytes 0 bytes -100.0% 🗑️
assets/eye-off-C9ob5Mxl.js (Deleted) -430 bytes 0 bytes -100.0% 🗑️
assets/app.miner-CgAM1c4M.js (Deleted) -422 bytes 0 bytes -100.0% 🗑️
assets/key-round-Pr1tMLVl.js (Deleted) -355 bytes 0 bytes -100.0% 🗑️
assets/bot-BzxXGcgY.js (Deleted) -328 bytes 0 bytes -100.0% 🗑️
assets/git-pull-request-arrow-G7kikbWW.js (Deleted) -321 bytes 0 bytes -100.0% 🗑️
assets/list-checks-DcBahiru.js (Deleted) -279 bytes 0 bytes -100.0% 🗑️
assets/compass-DnhQUV2q.js (Deleted) -251 bytes 0 bytes -100.0% 🗑️
assets/history-D2gG_epm.js (Deleted) -237 bytes 0 bytes -100.0% 🗑️
assets/message-square-WFMzHFx7.js (Deleted) -233 bytes 0 bytes -100.0% 🗑️
assets/lock-IFq8QM6p.js (Deleted) -206 bytes 0 bytes -100.0% 🗑️
assets/play-n17WmBmc.js (Deleted) -190 bytes 0 bytes -100.0% 🗑️
assets/circle-check-xg9XeuYn.js (Deleted) -178 bytes 0 bytes -100.0% 🗑️

@codecov

codecov Bot commented Jul 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.87%. Comparing base (81f28ca) to head (0149387).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #9964      +/-   ##
==========================================
- Coverage   91.87%   91.87%   -0.01%     
==========================================
  Files         928      928              
  Lines      113697   113704       +7     
  Branches    27421    27427       +6     
==========================================
+ Hits       104460   104463       +3     
  Misses       7936     7936              
- Partials     1301     1305       +4     
Flag Coverage Δ
backend 95.65% <100.00%> (-0.01%) ⬇️
engine 72.35% <100.00%> (ø)

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

Files with missing lines Coverage Δ
packages/loopover-contract/src/api-schemas.ts 100.00% <ø> (ø)
...oopover-engine/src/review/screenshot-table-gate.ts 70.25% <100.00%> (ø)
src/openapi/schemas.ts 100.00% <ø> (ø)
src/queue/processors.ts 94.60% <100.00%> (+<0.01%) ⬆️
src/settings/agent-actions.ts 98.31% <100.00%> (+0.02%) ⬆️
src/settings/pr-disposition.ts 100.00% <ø> (ø)
src/types.ts 100.00% <ø> (ø)

... and 1 file with indirect coverage changes

@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 30, 2026
@JSONbored
JSONbored merged commit 3ed97dc into main Jul 30, 2026
14 checks passed
@JSONbored
JSONbored deleted the feat/screenshot-gate-block-tier branch July 30, 2026 22:23
bitfathers94 added a commit to bitfathers94/loopover that referenced this pull request Jul 31, 2026
…om VALID_ACTIONS

The warning still named only close/advisory after JSONbored#9964 added the block tier, so
an operator who mistyped the action was pointed at a vocabulary that no longer
matched what the gate actually accepts. Interpolate VALID_ACTIONS and the
resolved default instead of restating them as a literal, mirroring
normalizeSelfLoopAutonomy's derived-vocabulary pattern in ams-policy-spec.ts.
loopover-orb Bot pushed a commit that referenced this pull request Jul 31, 2026
…om VALID_ACTIONS (#10105)

The warning still named only close/advisory after #9964 added the block tier, so
an operator who mistyped the action was pointed at a vocabulary that no longer
matched what the gate actually accepts. Interpolate VALID_ACTIONS and the
resolved default instead of restating them as a literal, mirroring
normalizeSelfLoopAutonomy's derived-vocabulary pattern in ams-policy-spec.ts.

Co-authored-by: bitfathers94 <237535319+bitfathers94@users.noreply.github.com>
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.

The screenshot-table gate can close PRs for evidence the bot is structurally unable to produce

1 participant