⚠️ Definition of Done: this issue must be completed in full, in a single PR. Do not split this
work across multiple PRs, and do not defer any Deliverable below to a follow-up issue. A PR that
satisfies only some of the Deliverables, stubs a required test, or leaves a checkbox
partially-done does NOT resolve this issue and will be closed.
Context
apps/loopover-miner-ui/src/lib/chat-governor-actions.ts's header claims full parity with the
Ledgers UI ("the same functions the Ledgers buttons call"), and chat-governor-action-copy.ts
claims to mirror GovernorControlSection (ledgers.tsx:258) "verbatim." But no chat message can
actually reach either:
apps/loopover-miner-ui/src/components/chat/conversation.tsx:11-17,86-113's handleSubmit only
calls resolvePortfolioQueueChatAction(text) (the portfolio-queue resolver). There is no
equivalent governor-intent resolver import or check, so any user text falls straight through to
the generic streamChatImpl read-only assistant.
runGovernorChatAction (chat-governor-actions.ts:58) has zero non-test callers, apart from
registerGovernorChatActions() (line 38), which is only called once at Vite dev-server start
(vite-chat-governor-actions.ts) to register the handler into the server-side registry — it never
calls runGovernorChatAction itself.
GovernorChatActionResult (governor-action-result.tsx:10) is never imported outside its own test
file — nothing in message-bubble.tsx/message-list.tsx/conversation.tsx renders it.
- No
resolveGovernorChatAction-style text resolver exists anywhere in the repo (confirmed by
repo-wide grep) — unlike the sibling portfolio-queue feature, which has a working
chat-portfolio-queue-resolve.ts plus real conversation.tsx wiring.
Contrast with chat-discover-attempt-actions.ts:6-8, whose header comment explicitly discloses
"there is no runner/unwrap surface here yet ... intentionally left to a follow-up" — the governor
module's header makes no such disclosure and instead claims completed parity.
Consequence: an operator typing "pause the governor" (or any governor-intent text) into the
miner-ui chat rail is silently answered by the generic streaming assistant instead of triggering the
real pause/resume action. The dispatch wrapper, result-renderer, and copy-formatter for this feature
are all fully unit-tested in isolation, but dead in the actual product surface.
Requirements
- Add a
resolveGovernorChatAction-style text resolver, mirroring
chat-portfolio-queue-resolve.ts's existing pattern (intent detection from free text, mapping to a
structured governor pause/resume action).
- Wire that resolver into
conversation.tsx's handleSubmit, alongside the existing
resolvePortfolioQueueChatAction call, so governor-intent text actually reaches
runGovernorChatAction.
- Render
GovernorChatActionResult in the message stream when a governor chat action resolves,
mirroring how the portfolio-queue result is already rendered.
Deliverables
All four Deliverables are required in the same PR.
Test Coverage Requirements
apps/** is excluded from codecov/patch gating, but apps/loopover-miner-ui's own local vitest
coverage thresholds (85% branches/statements/lines, 75% functions, enforced in CI) apply. The new
end-to-end-style test must exercise the full chat-to-dispatch path, not just the already-covered
isolated helper functions.
Expected Outcome
A user can actually pause/resume the governor from the miner-ui chat rail by typing free-form
intent text, matching what this feature's own module headers already claim is implemented.
Links & Resources
apps/loopover-miner-ui/src/components/chat/conversation.tsx:11-17,86-113 (handleSubmit, where
the resolver needs wiring)
apps/loopover-miner-ui/src/lib/chat-governor-actions.ts (runGovernorChatAction,
registerGovernorChatActions)
apps/loopover-miner-ui/src/components/chat/governor-action-result.tsx (GovernorChatActionResult,
never rendered)
apps/loopover-miner-ui/src/lib/chat-portfolio-queue-resolve.ts (the working sibling pattern to
mirror)
- Contrast:
chat-discover-attempt-actions.ts:6-8 (a similar feature that honestly discloses its own
incomplete wiring, unlike this one)
Context
apps/loopover-miner-ui/src/lib/chat-governor-actions.ts's header claims full parity with theLedgers UI ("the same functions the Ledgers buttons call"), and
chat-governor-action-copy.tsclaims to mirror
GovernorControlSection(ledgers.tsx:258) "verbatim." But no chat message canactually reach either:
apps/loopover-miner-ui/src/components/chat/conversation.tsx:11-17,86-113'shandleSubmitonlycalls
resolvePortfolioQueueChatAction(text)(the portfolio-queue resolver). There is noequivalent governor-intent resolver import or check, so any user text falls straight through to
the generic
streamChatImplread-only assistant.runGovernorChatAction(chat-governor-actions.ts:58) has zero non-test callers, apart fromregisterGovernorChatActions()(line 38), which is only called once at Vite dev-server start(
vite-chat-governor-actions.ts) to register the handler into the server-side registry — it nevercalls
runGovernorChatActionitself.GovernorChatActionResult(governor-action-result.tsx:10) is never imported outside its own testfile — nothing in
message-bubble.tsx/message-list.tsx/conversation.tsxrenders it.resolveGovernorChatAction-style text resolver exists anywhere in the repo (confirmed byrepo-wide grep) — unlike the sibling portfolio-queue feature, which has a working
chat-portfolio-queue-resolve.tsplus realconversation.tsxwiring.Contrast with
chat-discover-attempt-actions.ts:6-8, whose header comment explicitly discloses"there is no runner/unwrap surface here yet ... intentionally left to a follow-up" — the governor
module's header makes no such disclosure and instead claims completed parity.
Consequence: an operator typing "pause the governor" (or any governor-intent text) into the
miner-ui chat rail is silently answered by the generic streaming assistant instead of triggering the
real pause/resume action. The dispatch wrapper, result-renderer, and copy-formatter for this feature
are all fully unit-tested in isolation, but dead in the actual product surface.
Requirements
resolveGovernorChatAction-style text resolver, mirroringchat-portfolio-queue-resolve.ts's existing pattern (intent detection from free text, mapping to astructured governor pause/resume action).
conversation.tsx'shandleSubmit, alongside the existingresolvePortfolioQueueChatActioncall, so governor-intent text actually reachesrunGovernorChatAction.GovernorChatActionResultin the message stream when a governor chat action resolves,mirroring how the portfolio-queue result is already rendered.
Deliverables
to the structured action
runGovernorChatActionexpects.conversation.tsx'shandleSubmitcalls the new resolver and, on a match, dispatches torunGovernorChatActioninstead of falling through to the generic assistant.GovernorChatActionResultis rendered in the message stream when a governor chat actionresolves.
in isolation) types a governor-intent message (e.g. "pause the governor") into
ChatConversationand asserts the pause action actually fires andGovernorChatActionResult'scopy appears in the message list.
All four Deliverables are required in the same PR.
Test Coverage Requirements
apps/**is excluded fromcodecov/patchgating, butapps/loopover-miner-ui's own local vitestcoverage thresholds (85% branches/statements/lines, 75% functions, enforced in CI) apply. The new
end-to-end-style test must exercise the full chat-to-dispatch path, not just the already-covered
isolated helper functions.
Expected Outcome
A user can actually pause/resume the governor from the miner-ui chat rail by typing free-form
intent text, matching what this feature's own module headers already claim is implemented.
Links & Resources
apps/loopover-miner-ui/src/components/chat/conversation.tsx:11-17,86-113(handleSubmit, wherethe resolver needs wiring)
apps/loopover-miner-ui/src/lib/chat-governor-actions.ts(runGovernorChatAction,registerGovernorChatActions)apps/loopover-miner-ui/src/components/chat/governor-action-result.tsx(GovernorChatActionResult,never rendered)
apps/loopover-miner-ui/src/lib/chat-portfolio-queue-resolve.ts(the working sibling pattern tomirror)
chat-discover-attempt-actions.ts:6-8(a similar feature that honestly discloses its ownincomplete wiring, unlike this one)