Skip to content

feat(miner): wire chat action-dispatch to the existing discover/attempt routes - #6855

Merged
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
luciferlive112116:feat/chat-discover-attempt-actions-6837
Jul 17, 2026
Merged

feat(miner): wire chat action-dispatch to the existing discover/attempt routes#6855
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
luciferlive112116:feat/chat-discover-attempt-actions-6837

Conversation

@luciferlive112116

Copy link
Copy Markdown
Contributor

Summary

The last of the three chat action families. chat-action-registry.js:4-5 names them all — "portfolio release/requeue, governor pause/resume, discover/attempt" — and the first two now ship. This registers the pair:

  • discover → the miner-ui client requestDiscover
  • attempt → the miner-ui client requestAttempt

Both POST the existing /api/discover and /api/attempt routes — never discover-cli.js/attempt-cli.js directly, and never a hand-rolled fetch. The clients are injected by the wire module, so this module structurally cannot reach the CLI even by accident. It owns only the registration contract + params validators, exactly like its two siblings.

Deliverable 1 is already shipped — please check this claim first

The issue's first deliverable asks for "new discover/attempt API routes", on the premise that they're "CLI-only today ... with no HTTP route". That premise is stale. #6522 already shipped both:

  • apps/loopover-miner-ui/vite-discover-api.ts and vite-attempt-api.ts
  • Registered live at vite.config.ts:36-37 (discoverApiPlugin(), attemptApiPlugin())
  • Already tested by src/discover-api.test.ts and src/attempt-api.test.ts

So adding a second pair would duplicate live routes. That is not a hypothetical concern: main was red earlier today because #6706 and #6709 — two PRs for two duplicate issues — each added the same import pair and both merged 72 seconds apart, leaving routes.ts unparseable. I'd rather flag a stale deliverable than recreate that.

This PR therefore delivers the only unbuilt part: the chat wiring (deliverable 2) and its tests (deliverable 3).

The gate lives at the endpoint — deliberately, and I verified it

The issue also asks that the routes "route through the same Governor chokepoint / PreToolUse deny-hook path". The house architecture is inherit, don't re-implement, and the existing code says so directly:

  • vite-attempt-api.ts:7-9 — "Because it calls the real, unmodified runAttempt, it inherits that command's Governor chokepoint gate for free" (attempt-runner.js gates every write at :203 before executing at :223).
  • vite-discover-api.ts:13-14 — "discover has no Governor chokepoint of its own (it only fans out + ranks + enqueues, none of the gated write actions), so — matching the CLI exactly — this route adds none either."
  • vite-governor-api.ts:10 — "this file never touches governor-chokepoint.js".

No miner-ui route invokes the chokepoint. Re-evaluating it in this module would be a second, competing gate on a path that already has one (attempt) or needs none (discover) — and would gate chat more strictly than the identical CLI invocation. So this mirrors chat-governor-actions.js and chat-portfolio-actions.js: satisfy the registry's governorGatedHandler brand with an allow-stage evaluateGate, keep it injectable.

Worth noting PreToolUse can't be wired here even in principle: buildHouseRulesPreToolUseHook is a factory for a Claude Agent SDK hook callback, not an HTTP-callable gate.

The safety properties remain structural, not conventional: register() refuses any handler not produced by governorGatedHandler() (private unforgeable Symbol), and the flag is checked first, before the registry is touched.

Params validation

discover and attempt differ deliberately, matching their clients' real contracts:

  • discover — every DiscoverActionInput field is optional (the CLI defaults them all), so nullish/{} is a valid "discover with defaults" and is forwarded as {} rather than undefined, since the client always POSTs a JSON body. targets: [] is accepted as an explicit empty list.
  • attemptrepoFullName/issueNumber/minerLogin are required: there is no default issue to attempt. issueNumber must be a positive integer, so 0, -3, 1.5, NaN and "12" all reject rather than reaching the CLI as a nonsense issue reference.
  • Both reject unknown keys rather than ignoring them. These params can be model-authored, so a typo'd flag must fail loudly instead of silently running something different.

Validation

  • Patch coverage 100%, measured from the v8 JSON report — the file is new, so every line is patch: 60/60 statements, 61/61 branches, 8/8 functions, zero partials. Clears the 99% codecov/patch wall on packages/loopover-miner/lib/** (root vitest.config.ts includes packages/loopover-miner/lib/**/*.js, so this file is gated).
  • 22/22 new tests pass. All chat suites together — this one plus portfolio, registry, dispatch, governor-actions73/73.
  • npm run typecheck0 errors, matching clean main exactly.
  • npm run build:miner — added to the miner package's explicit node --check list, alphabetically beside its three siblings; package.json re-validated as parseable JSON.
  • eslint — 0 errors/0 warnings · git diff --check clean · rebased on latest main, no base conflict.

Rebasing surfaced a real conflict worth mentioning: #6850 (the portfolio sibling) merged mid-work and edits the same node --check list. Resolved so both entries survive — chat-discover-attempt-actions.js, chat-governor-actions.js, and chat-portfolio-actions.js are all present and alphabetical, and the full chat suite passes against the merged base.

Scope

  • Four files: the module + its .d.ts, the package build list, and the root test suite. Wanted paths (packages/, test/).
  • No UI: this is the registration layer, so there is no visual change and no screenshot table applies.
  • The routes, the CLIs, the registry, the dispatcher, and both sibling action modules are all untouched.
  • No secrets; no changelog, site/, CNAME, or lovable changes.

Safety

  • Off by default: LOOPOVER_MINER_CHAT_ACTIONS gates execution and is checked before anything else. With the flag unset, behavior is byte-identical to today.
  • attempt — the one family that performs real writes — reaches them only through runAttempt, which carries the persisted chokepoint gate. Chat gets no privilege the CLI doesn't already have.
  • Registration is idempotent (registry.has guarded), so double-wiring can't throw.

Closes #6837

…pt routes (JSONbored#6837)

Registers discover / attempt into the chat-action registry the scaffolding (JSONbored#6519)
ships empty -- the third and last family its own docstring names. Handlers call the
miner-ui clients requestDiscover / requestAttempt, so chat POSTs the same
/api/discover and /api/attempt routes that already exist (JSONbored#6522, registered at
vite.config.ts:36-37).

The issue's first deliverable ('add new API routes') is already satisfied: JSONbored#6522
shipped both routes and their plugins. Adding a second pair would duplicate live
routes, so this delivers the only unbuilt part -- the chat wiring.

The gate lives at the endpoint, deliberately: attempt inherits the real chokepoint
via runAttempt -> attempt-runner.js, and discover performs no gated write so neither
the CLI nor the route has one. Re-evaluating it here would be a second, competing
gate. Mirrors chat-governor-actions.js / chat-portfolio-actions.js exactly.

Closes JSONbored#6837
@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.64%. Comparing base (61202e3) to head (0e66381).
⚠️ Report is 7 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6855   +/-   ##
=======================================
  Coverage   93.64%   93.64%           
=======================================
  Files         684      685    +1     
  Lines       68192    68237   +45     
  Branches    18706    18706           
=======================================
+ Hits        63856    63901   +45     
  Misses       3350     3350           
  Partials      986      986           
Flag Coverage Δ
shard-1 43.23% <0.00%> (-0.45%) ⬇️
shard-2 36.93% <0.00%> (+0.10%) ⬆️
shard-3 32.59% <0.00%> (-0.03%) ⬇️
shard-4 34.36% <0.00%> (-0.48%) ⬇️
shard-5 31.47% <100.00%> (-0.08%) ⬇️
shard-6 45.97% <0.00%> (+0.23%) ⬆️

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

Files with missing lines Coverage Δ
...oopover-miner/lib/chat-discover-attempt-actions.js 100.00% <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
Contributor

Tip

✅ LoopOver review result - approve/merge recommended

Review updated: 2026-07-17 08:52:00 UTC

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

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
This PR follows the exact pattern established by chat-governor-actions.js and chat-portfolio-actions.js: it registers `discover`/`attempt` chat actions wired to injected miner-ui clients (`requestDiscover`/`requestAttempt`), never touching the CLI or raw fetch directly. The gating rationale (endpoint owns the gate, discover has no chokepoint, attempt inherits one via `runAttempt`) is consistent with the existing `vite-attempt-api.ts` comments shown in context, and the params validators plus idempotent registration are well-tested with real dispatch-path tests (gate-deny, disabled-flag, invalid-params, empty-params-forwarded-as-{} cases all covered). The `package.json` build-script addition is a mechanical one-line insertion matching the existing pattern.

Nits — 5 non-blocking
  • packages/loopover-miner/lib/chat-discover-attempt-actions.js:57 and :84 — `isDiscoverChatParams`/`isAttemptChatParams` each have fairly high branch density (per the complexity note); consider extracting the per-key type-check loops into a small shared `validateShape(record, spec)` helper shared with the sibling chat-action files to reduce duplication across all three registrations.
  • The PR description states deliverable-1 API routes are 'already shipped' via Chat action-dispatch: discover/attempt (new HTTP routes mirroring vite-governor-api.ts) #6522 and cites `vite.config.ts:36-37` — this diff itself doesn't touch those files, so that claim isn't independently verifiable from the diff alone; worth double-checking in review before treating deliverable 1 as closed.
  • packages/loopover-miner/lib/chat-discover-attempt-actions.js — the JSDoc-style header comment is unusually long (24 lines) for a file this size; a shorter comment plus a link to the sibling files' rationale would be more maintainable if this pattern is repeated for future action families.
  • Consider factoring the repeated 'reject unknown keys' + 'per-key type check' loop pattern shared across isDiscoverChatParams and isAttemptChatParams (and likely the sibling governor/portfolio validators) into one small utility to keep future action families DRY.
  • If the claim that Chat action-dispatch: discover/attempt (new HTTP routes mirroring vite-governor-api.ts) #6522 already shipped deliverable-1 routes is central to closing out issue Miner dashboard chat: discover/attempt action-dispatch #6837, it'd strengthen the PR to link the specific commit/PR reference directly in code comments rather than only in the PR description.

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 #6837
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: 163 registered-repo PR(s), 99 merged, 30 issue(s).
Contributor context ✅ Confirmed Gittensor contributor luciferlive112116; Gittensor profile; 163 PR(s), 30 issue(s).
Improvement ✅ Minor risk: clean · value: minor · LLM: moderate
Linked issue satisfaction

Partially addressed
The PR delivers the chat-wiring and test-coverage deliverables (registering discover/attempt with validators, and tests including a gate-deny regression test), and makes a well-argued case that the 'new API routes' deliverable is stale because #6522 already shipped /api/discover and /api/attempt. However, it deliberately does not re-verify or re-gate at the chat-action layer itself, instead relyin

Review context
  • Author: luciferlive112116
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Python, JavaScript, MDX, Rust, TypeScript
  • Official Gittensor activity: 163 PR(s), 30 issue(s).
  • Related work: Titles/paths share 9 meaningful terms. (issue #6836, issue #6837)
  • Related work: Titles/paths share 9 meaningful terms. (issue #6837, issue #6839)
  • Related work: Titles/paths share 7 meaningful terms. (issue #6837, issue #6833)
  • 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
Contributor

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 a4c76a6 into JSONbored:main Jul 17, 2026
16 checks passed
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.

Miner dashboard chat: discover/attempt action-dispatch

1 participant