Skip to content

feat(api): add a REST route + CLI mirror for loopover_simulate_open_pr_pressure#6915

Merged
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
davion-knight:feat-open-pr-pressure-mirror-v2
Jul 17, 2026
Merged

feat(api): add a REST route + CLI mirror for loopover_simulate_open_pr_pressure#6915
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
davion-knight:feat-open-pr-pressure-mirror-v2

Conversation

@davion-knight

Copy link
Copy Markdown
Contributor

What & why

loopover_simulate_open_pr_pressure had neither a REST route nor a CLI mirror, though it's deterministic, public-safe, and read-only (no repo access, no GitHub writes) — the same tier as the lint routes that already have full parity.

One schema, not two

Rather than hand-copying the tool's input contract, the route parses with the tool's own simulateOpenPrPressureShape, now exported from src/mcp/server.ts (a one-word change). The two surfaces cannot diverge on accepted input, because there is only one schema. The route then delegates to the same pure simulateOpenPrPressure and adds no logic of its own.

That mattered here: the real queueHealth schema requires a nested signals object (8 counts + ageBuckets), a findings array, and is .nullable(). A hand-copy written from the issue text would have quietly diverged — exactly the failure mode that cost #6807.

Why this CLI mirror proxies

Consistent with the boundary-tests mirror (#6750): simulateOpenPrPressure lives app-side (src/services/open-pr-pressure-scenarios.ts), not in @loopover/engine, so the tool proxies to the route rather than computing in-process. The route stays the single source of truth for the ranking.

The bin can't import from src/ (package boundary), so its zod shape is the one hand-mirrored copy — reproduced verbatim including the nested signals, findings, and nullable queueHealth. Its tests pin that mirror directly: the fields the real schema requires are enforced in the tool rather than waved through to a route 400.

Tests

Route: output parity with the pure simulator across every queue-health level × both role lanes, the optional contributorOpenPrCount, the nullable queueHealth arm, and 400s for each rejected field plus an unparseable body. CLI: the proxied POST, the null-queueHealth arm, and that zod rejects bad input before any API call.

100% line and branch coverage on every changed line, measured against the changed-line set. tsc --noEmit clean.

Resubmit of #6894, which the gate closed for CI failing on test/unit/selfhost-sentry-release.test.ts — a suite this PR never touches. It was broken on main when that CI ran (a stale SENTRY_RELEASE assertion in scripts/deploy-selfhost-prebuilt.sh); main has since fixed it in 3f7388fd. This branch is rebased past that fix and the suite passes here.

Closes #6751

…r_pressure

loopover_simulate_open_pr_pressure had neither a REST route nor a CLI mirror, though it is
deterministic, public-safe, and read-only -- no repo access, no GitHub writes -- the same tier as the
lint routes that already have full REST/CLI parity.

Adds POST /v1/lint/open-pr-pressure beside them. Rather than hand-copying the tool's input contract,
the route parses with the tool's OWN simulateOpenPrPressureShape, now exported from src/mcp/server.ts
(a one-word change): the two surfaces cannot diverge on accepted input because there is only one
schema. It then delegates to the same pure simulateOpenPrPressure and adds no logic of its own.

Adds the loopover_simulate_open_pr_pressure stdio tool. Like the boundary-tests mirror it PROXIES to
the route rather than computing in-process: simulateOpenPrPressure lives app-side in
src/services/open-pr-pressure-scenarios.ts, not in @loopover/engine. The bin cannot import from src/
(package boundary), so its zod shape is the one hand-mirrored copy here -- reproduced VERBATIM,
including the nested signals object, findings, and the nullable queueHealth -- and its own tests pin
that the fields the real schema requires are enforced there too rather than waved through to a 400.

Route tests assert output parity with the pure simulator across every queue-health level and both role
lanes, the optional contributorOpenPrCount, the nullable queueHealth arm, and 400s for each rejected
field plus an unparseable body. The CLI test asserts the proxied POST, the null-queueHealth arm, and
that zod rejects bad input before any API call. 100% line and branch coverage on every changed line.

Closes JSONbored#6751
@davion-knight
davion-knight requested a review from JSONbored as a code owner July 17, 2026 12:55
@superagent-security

Copy link
Copy Markdown
Contributor

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

@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.70%. Comparing base (96ee9c4) to head (f7a1162).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6915   +/-   ##
=======================================
  Coverage   93.70%   93.70%           
=======================================
  Files         685      685           
  Lines       68331    68336    +5     
  Branches    18723    18724    +1     
=======================================
+ Hits        64032    64037    +5     
  Misses       3302     3302           
  Partials      997      997           
Flag Coverage Δ
shard-1 43.65% <33.33%> (-0.01%) ⬇️
shard-2 36.86% <33.33%> (+0.05%) ⬆️
shard-3 32.74% <100.00%> (+0.05%) ⬆️
shard-4 34.81% <33.33%> (-0.01%) ⬇️
shard-5 31.90% <33.33%> (-0.01%) ⬇️
shard-6 45.45% <33.33%> (-0.01%) ⬇️

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

Files with missing lines Coverage Δ
src/api/routes.ts 94.74% <100.00%> (+0.01%) ⬆️
src/mcp/server.ts 96.30% <100.00%> (ø)

@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 17, 2026
@loopover-orb

loopover-orb Bot commented Jul 17, 2026

Copy link
Copy Markdown

Tip

✅ LoopOver review result - approve/merge recommended

Review updated: 2026-07-17 13:04:39 UTC

7 files · 1 AI reviewer · no blockers · readiness 82/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
This adds a REST route (POST /v1/lint/open-pr-pressure) and a CLI mirror for the existing loopover_simulate_open_pr_pressure MCP tool, following the exact pattern of the prior #6750 boundary-tests parity work. The route correctly imports and reuses the tool's own exported simulateOpenPrPressureShape (now exported via a one-word change in src/mcp/server.ts) so the two surfaces can't diverge on input validation, and delegates to the same pure simulateOpenPrPressure function without adding new logic. The CLI's zod shape is necessarily a hand-mirrored duplicate (package boundary prevents importing from src/), but it's reproduced verbatim including the nested signals/findings/nullable queueHealth, and is pinned by dedicated tests. Test coverage is thorough: parity across queue-health levels and role lanes, the nullable queueHealth arm, and 400 rejections for each invalid field.

Nits — 4 non-blocking
  • packages/loopover-mcp/bin/loopover-mcp.js:583-591 duplicates the real schema's magic numbers (min(3).max(200) for repoFullName, count bounds) with no named constants tying it to the source schema, so a future bound change in src/mcp/server.ts could silently drift without either test failing.
  • test/unit/mcp-cli-open-pr-pressure-tool.test.ts's 'rejects input' test folds six different invalid payloads into one loop with a single assertion per case — a failure in one case won't clearly indicate which shape rule broke.
  • Consider a lightweight shared fixture or golden JSON snapshot of simulateOpenPrPressureShape's bounds (min/max literals) that both the route test and the CLI mirror test import, so a change to the real schema's bounds fails loudly in the CLI mirror test rather than requiring the contributor to notice a hand-copy drifted.
  • src/api/routes.ts:3283 — the safeParse error path returns parsed.error.issues directly; verify this doesn't leak any internal path info beyond what's already exposed by the sibling /v1/lint/slop-risk route (likely fine given precedent, just worth a quick check for parity).

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #6751
Related work ⚠️ 3 scoped overlaps Top overlaps are listed below; lower-confidence bulk is hidden.
Change scope ❌ 8/20 High review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 192 registered-repo PR(s), 122 merged, 0 issue(s).
Contributor context ✅ Confirmed Gittensor contributor davion-knight; Gittensor profile; 192 PR(s), 0 issue(s).
Improvement ✅ Minor risk: clean · value: minor · LLM: moderate
Linked issue satisfaction

Addressed
The PR adds POST /v1/lint/open-pr-pressure delegating to the pure simulateOpenPrPressure (parsed with the tool's own exported shape), adds a CLI mirror in the bin that proxies to the route, and includes new unit tests for both the route and CLI including a parity assertion across queue-health levels/role lanes and the nullable queueHealth case, matching all three deliverables and the slop-risk pre

Review context
  • Author: davion-knight
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: not available
  • Official Gittensor activity: 192 PR(s), 0 issue(s).
  • Related work: Titles/paths share 6 meaningful terms. (PR #6916)
  • Related work: Titles/paths share 8 meaningful terms. (issue #6744, issue #6751)
  • Related work: Titles/paths share 8 meaningful terms. (issue #6747, issue #6751)
  • Additional title-only matches omitted; title-only overlap does not block.
Contributor next steps
  • Start here: Review top overlaps.
  • Then work through the remaining 2 steps 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 &lt;question&gt; answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat &lt;question&gt; 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.

🟩 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

@loopover-orb loopover-orb Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LoopOver approves — the gate is satisfied and CI is green.

@loopover-orb
loopover-orb Bot merged commit 68b8694 into JSONbored:main Jul 17, 2026
16 checks passed
RealDiligent added a commit to RealDiligent/gittensory that referenced this pull request Jul 17, 2026
JSONbored#6915 registered loopover_simulate_open_pr_pressure without updating the
alias-retirement discovery invariant; merge CI was failing expected 69 got 70.

Co-authored-by: Cursor <cursoragent@cursor.com>
loopover-orb Bot pushed a commit that referenced this pull request Jul 17, 2026
* fix(miner): cover four omitted stores in doctor and migrate

governor-state, attempt-log, replay-snapshot, and worktree-allocator were only
migrated lazily; keep storeIntegrityChecks and migrate STORES in sync at eleven
entries. Tests seed the four stores so the worktree-allocator open adapter is
covered. Also bump the MCP discovery invariant 69→70 for #6915's
loopover_simulate_open_pr_pressure (merge CI pin drift on main).

Closes #6768

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(miner): type tempEnv as ProcessEnv for replay-snapshot resolve

validate-code failed: resolveReplaySnapshotDbPath expects NodeJS.ProcessEnv.

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(miner): cover only worktree-allocator migrate adapter

Avoid ProcessEnv-typed resolve helpers that reject the slim tempEnv object
under the repo's strict Env typing; the uncovered patch line is the adapter.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
This was referenced Jul 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

REST + CLI mirror for loopover_simulate_open_pr_pressure

1 participant