feat(issue-fix): continuous LoopX-driven issue repair with MiniApp surface - #2006
Open
xielixing wants to merge 40 commits into
Open
feat(issue-fix): continuous LoopX-driven issue repair with MiniApp surface#2006xielixing wants to merge 40 commits into
xielixing wants to merge 40 commits into
Conversation
Adds a probe-gated bridge to the external `loopx` CLI's issue-fix capability,
which supplies a deterministic decision skeleton (which route to take for an
issue, how a PR's lifecycle projects forward) while performing no writes of its
own. BitFun keeps every side effect and supplies every piece of evidence.
Behind a non-default `loopx-issue-fix` feature, deliberately outside
`product-full` until the chain is verified against a real repository.
Two behaviors were found by testing against the real CLI rather than assumed:
- LoopX reports domain refusals as `{"ok": false, "error": ...}` on stdout *and*
exits nonzero. Parsing stdout before checking the exit status keeps the
structured reason instead of reporting a bare exit code.
- `--validation-label` is required for the `fix_pr` route. Without a named
validation surface LoopX downgrades to `triage_only` even when the context is
grounded, the issue reproduces, and the scope is bounded.
Sets `PYTHONUTF8=1` on every invocation: LoopX's 123 subprocess call sites pass
`text=True` without `encoding=`, so on a non-UTF-8 locale it decodes `gh` output
as the local codepage and dies. The env var fixes all of them at once and needs
no patch to LoopX.
Contract tests drive the real CLI and skip cleanly when it is absent, matching
the runtime probe gate.
Co-Authored-By: Claude <noreply@anthropic.com>
Adds `list_issues`, closing the one real backend gap for automatic issue fixing: the service could fetch a single issue by id but had no way to discover which issues exist. Five `list_pull_requests` implementations already existed; issues had no equivalent. Returns a new lightweight `ReviewPlatformIssueSummary` rather than the existing `ReviewPlatformIssueEvidence`, which carries a full body and every comment — enumerating a hundred issues must not pull all of that. Provider differences handled: - GitHub returns pull requests inline from its issues endpoint, marked only by a `pull_request` member, so they are filtered out. Continuation is inferred from a full page because `gh` surfaces no Link headers here; the check runs before PR filtering, since a page of only PRs can still be followed by issues. - GitLab addresses issues by project-scoped `iid`, not the global `id`, and has no "all" state literal — the filter is omitted entirely instead of sent empty. Continuation comes from its `x-next-page` header. Takes a request struct because the sibling `issue` method already sits at clippy's argument limit. Covered by mocked-HTTP tests for the GitLab path and an ignored test that drives the real `gh` CLI for GitHub, which mocks cannot reach. Co-Authored-By: Claude <noreply@anthropic.com>
Adds `RepositoryContextBuilder`, the evidence half of the integration. LoopX holds no code-reading ability and refuses to guess, so the quality of its route decisions depends entirely on what BitFun reports here. Every constraint LoopX's validator enforces is enforced at construction time instead, because a rejected payload costs a whole subprocess round trip: source-id shape and uniqueness, reference length, summary length measured after whitespace collapsing, the 16-source cap, advisory-only trust for memory and expert sources, and a pinned revision whenever a source claims current freshness. References must be repository-relative — an absolute local path would leak the operator's filesystem layout into a payload that can reach a public issue thread. `context_status` and `ungrounded_required_aspects` mirror LoopX's grounding rules locally, so a caller can decide what else to read without paying for a subprocess call. A contract test compares the prediction against the real CLI aspect by aspect, which is what would catch the two drifting apart. That comparison corrected a mistaken assumption of mine. I had assumed a partial context caps the route at `triage_only`; it does not. Two contract tests now pin the real behavior: a grounded context without `--validation-label` yields `triage_only`, while a merely partial context *with* the label yields `fix_pr`. LoopX distinguishes "which test files did you read" from "how will you check this fix", and only the latter gates opening a PR. Comments and the design doc that stated otherwise are corrected. Moves the module into a directory to hold the new submodule. Co-Authored-By: Claude <noreply@anthropic.com>
Runs one issue through feasibility → branch → PR lifecycle behind typed outcomes. The value is in the typing: LoopX's decisive fields sit at non-obvious paths, and reading them wrong is the failure mode that turns a refusal into an approval. Two paths were corrected by testing against the real CLI rather than assumed: `state` lives under `observation`, and `state_bucket` under `grouped_monitor_projection` — neither is top level, though the markdown rendering shows them flattened. A unit test asserting the wrong shape would have looked fine, so the mocked packets now match verified reality. Unrecognized routes and lifecycle decisions are errors, never defaults. Silently mapping an unknown value onto something permissive could open a pull request LoopX had declined. Optional evidence still degrades to empty, since guessing there is harmless. `plan_issue` skips branch preparation entirely on a non-fix route. Under `ExecutionMode::Execute` that would otherwise create a branch LoopX just refused to justify, so the skip is a safety property. `may_open_pull_request` requires the fix route, a ready review packet, and passing validation together. The feature ships with no runtime kill switch, so this gate lives on the action itself rather than relying on a disabled toggle. Co-Authored-By: Claude <noreply@anthropic.com>
Adds `review_platform_list_issues` across the three layers the existing `review_platform_get_issue` already spans: core facade wrapper, Tauri command, and typed frontend binding. The command takes an owned DTO because `ReviewPlatformListIssuesRequest` borrows its strings and cannot be deserialized directly. Co-Authored-By: Claude <noreply@anthropic.com>
Opens from a chat-header button into a right-panel tab: issue list on the left, selected issue's detail on the right. Follows the pull-requests button and `createReviewPlatformTab` for how the tab opens. Row state lives in `issueFixRunState` as pure functions, so the mapping from LoopX's decisions onto what a user sees is testable without rendering. The mapping that matters: a `user_gate` renders as blocked, never as done, and `nextIssueToRun` returns null while any row is blocked. Advancing past a gate would defeat the gate — that is the one behavior LoopX raises it for. Reason codes are shown verbatim rather than paraphrased, so a declined fix explains itself in LoopX's own vocabulary. The panel resolves `owner/repo`, host, and platform from the workspace's selected remote, since the header only knows the local checkout path. Platform is threaded through rather than hardcoded, so GitLab works too. The error status key is `stopped`, not `failed`: the i18n audit tracks `statuses.failed` as a shared term with a governance budget, and adding a 43rd duplicate would have needed that budget raised. Renaming was the honest fix rather than moving the baseline. Co-Authored-By: Claude <noreply@anthropic.com>
Multi-issue runs need continuation, budgets, and human gates. BitFun already owns all three in `thread_goal`, so this bridge adds none of its own — it only translates. That is also why nothing here reaches for a scheduler or quota: LoopX's issue-fix capability contributes neither, and its 35 modules import neither. The mapping that carries weight is `user_gate` → `Blocked`. `plan_serial_run` additionally returns no next issue while a gate is open, since handing one back would invite a caller to step over the gate rather than resolve it. `Blocked` stays resumable, so answering the question picks the run back up instead of stranding it. `is_resumable` duplicates the agent-runtime predicate rather than pulling in that crate for four lines. The test enumerates every `ThreadGoalStatus` variant, so a new one has to be classified deliberately instead of silently defaulting to non-resumable. Note on clippy: adding the runtime-ports dependency brings one pre-existing warning from that crate into this feature's build. It is not new code of mine. Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Closes the gap my earlier summary glossed over: the panel could list and select issues, but nothing connected it to the orchestrator, so no fix action was reachable. A Start button now walks the selected issues serially through `feasibility`, driving the row states that were already implemented and tested. Planning only, verified rather than asserted: `ExecutionMode::Execute` has zero production callers, and the Tauri surface mentions execute exactly once — in the comment saying it has none. Nothing reachable from the UI can create a branch, run a command, or open a pull request. The run loop tracks state in a local variable rather than reading React state back each iteration, which would lag a render behind and could re-run an issue. It stops as soon as `nextIssueToRun` returns null, so an open gate halts the run instead of being stepped over. No repository context is generated yet, because nothing in BitFun generates one. LoopX therefore reports `not_provided` and declines to open a pull request. That is the honest current state, and its reason codes name exactly which evidence is missing — better than asserting a validation surface nobody checked. `loopx-issue-fix` is enabled for the desktop crate only, leaving `product-full` untouched so release builds of other consumers are unaffected. Co-Authored-By: Claude <noreply@anthropic.com>
…tion spawning - Add loopx-issue-fix to the services-integrations product-full feature group after real-repo validation against GCWing/BitFun GCWing#1849 - Register the feature and its optional dependency owners in the core boundary rules so the product-full assembly stays explicit - Wrap caller-declared validation commands with cmd /c on Windows: LoopX spawns them with subprocess.run(argv) and no shell, so .cmd shims such as pnpm fail with WinError 2 - Fix a pre-existing lib-test compile gap in plugin_source tests - Record the real-repo verification and the Windows defect in the integration design doc
The start button used to only project LoopX routes; a fix_pr route had no execution path, so no model was ever called. Wire the missing half: - New issue_fix_execute Tauri command: feasibility gate, then submit the fix task as a dialog turn to the session's agent loop (same scheduling path as a manual message, so the model's streaming output appears in the chat transcript) - Empty agent_type lets the coordinator resolve the session's own mode instead of overriding it - Panel: plan first, then submit fix_pr issues to the agent; non-fix routes record their reason codes and move on - Declare remote-workspace policies for all issue_fix commands and the pre-existing review_platform_list_issues gap - Document the execution model in the integration design doc
Author
|
Follow-up repair for the Issue-Fix gate/cancellation lifecycle:
Validation:
|
…host loop Replace the thread-goal bridge with a Kernel-owned autonomous loop: selected issues become LoopX intake todos, and BitFun's persistent cron service wakes one agent session every 10 minutes with an English host preamble plus the LoopX `heartbeat-prompt --compact` contract (thin mode depends on skill packs absent from BitFun sessions). - Project user gates from `todo list` instead of the quota preview, which is compacted to two entries; issue-linked gates win, unlinked gates still surface so an open gate can never stall the loop invisibly. - Add issue_fix_stop_autonomous (kill switch that also sweeps orphaned or duplicate jobs and survives a broken registry) and a quota-free issue_fix_autonomous_poll for the panel's 30s poll loop, since `quota should-run` appends a rollout event per call. - Serialize start/stop/answer-wake on HOST_LOOP_LOCK, self-heal duplicate cron jobs, refresh the heartbeat prompt snapshot at every gate answer, and surface host-loop failures (lastError/consecutiveFailures) in the UI. - Guard every panel state write with a monotonic ticket, pause polling during mutations, add a Stop button, re-project after failed gate answers, and collapse scheduled heartbeat turns into an expandable chip. - Prune ~60 dead issue-fix locale keys; keep en-US/zh-CN/zh-TW in parity. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
xielixing
force-pushed
the
codex/bitfun-loopx-issue-fix-repair
branch
from
August 4, 2026 11:53
bc5dc05 to
276583f
Compare
# Conflicts: # scripts/core-boundaries/rules/feature-rules.mjs # src/apps/desktop/Cargo.toml # src/crates/services/services-integrations/Cargo.toml # src/web-ui/src/app/components/NavPanel/sections/workspaces/WorkspaceItem.tsx # src/web-ui/src/flow_chat/components/modern/FlowChatHeader.tsx # src/web-ui/src/flow_chat/components/modern/UserMessageItem.tsx # src/web-ui/src/flow_chat/tool-cards/AskUserQuestionCard.tsx
During the first overnight full-batch run the agent hit cargo lock contention in a worktree, ran Stop-Process -Force against "stale cargo processes", and terminated the BitFun app hosting it (twice). The host preamble now carries a hard rule: never force-kill processes not started in the current turn; on lock contention wait, use a worktree-local CARGO_TARGET_DIR, or record a blocker todo. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
GitHub's /repos/{o}/{r}/issues endpoint interleaves pull requests with
issues, and the client-side PR filter ran after taking one page — so once
the continuous Issue-Fix loop opened 19 PRs, the first page starved down
to a handful of issues and the panel showed a truncated queue with a zero
count. /search/issues with is:issue filters server-side, reports an exact
total_count, and keeps newest-first ordering explicitly.
Verified by the live github_issue_page_enumerates_a_public_repository
test (network + authenticated gh).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…block The heartbeat agent surfaces review/merge requests and authority gates as LoopX user todos, but the panel only rendered the single active gate card — merge-PR actions were visible only inside chat NOTIFY summaries. The panel now lists every open user_gate/user_action todo in a read-only "pending your action" block with provider jump links. No mutation surface is offered: gates answer through the existing question card, review/merge actions resolve on the provider side and close via the Kernel's monitors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The heartbeat agent wrote user-lane todo text free-form, so the pending
block ranged from terse ("Authorize merge of PR GCWing#2039") to a full drafted
comment pasted inline. The host preamble now prescribes one compact line:
action + PR/issue ref + which issue it serves + the state justifying it,
with long material routed to --note/--evidence. Display side: the primary
URL moves to the jump icon instead of repeating inline, and rows clamp to
two lines.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Gates and review requests were only visible inside the Issue-Fix panel (and chat NOTIFY text), so users working elsewhere missed them. The panel now raises app-level notification cards through the existing notification system when a new gate or user_action todo appears: warning card for gates, info cards for actions (digested into one card when a beat produces more than three), each with an "Open panel" action. The first projection seeds silently so pre-existing items do not re-toast on mount. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The continuous Issue-Fix host must work against any repository, but the hardening rules named BitFun's own toolchain (node/vite, pnpm, cargo, CARGO_TARGET_DIR). Restate them generically — never kill processes not started this turn, keep build outputs inside the worktree, remove the worktree and its caches at terminal closeout, one sibling worktrees folder per repository — and route repository-specific policy where LoopX says it belongs: the goal's active state and registry, read and written by the agent, never baked into the automation prompt. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Three afternoon PRs ballooned to ~8.8k added lines because the agent branched its fix worktrees from the host checkout's HEAD, which sat on the in-flight feature branch; the whole feature diff rode along into each PR. The preamble now requires basing every fix branch on origin/<default> after a fetch, never on the host checkout's current branch. The three contaminated branches were rebased onto origin/main and force-pushed (PRs GCWing#2058/GCWing#2059/GCWing#2060 now carry only their own fix). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
It described the abandoned plan/execute + thread-goal design; the implemented architecture (heartbeat host loop, kernel-owned state, panel projection) diverged from it entirely. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…enter Reuse BitFun's built-in notification system as the single carrier for user-lane work instead of inventing a VS Code-style popup: new gates and review requests toast briefly and land in the center history (bell icon, unread badge, scrollable, searchable); items resolved on the provider side are marked read automatically; on first load existing todos seed the history silently via the new silent-notification actions support. Toast bodies use a compact two-line presentation — the action, then the state/reason that justifies it — derived from the todo text. A header chip on the panel shows the pending count and opens the center. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Drop the in-panel pending block — with the notification center as the
carrier it was a duplicate list; the panel keeps only a compact count
chip that opens the center. Toast/center entries now render a localized
first line stating what happened and what is asked ("Issue GCWing#1980 fixed —
review and merge PR GCWing#2038") by classifying the todo into merge-PR /
close-issue / post-comment shapes, with the agent's state/reason as the
second line; unrecognized shapes fall back to the compact free-form
text.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The state/reason tail is the user's only view of why an action is requested; cutting it at 96 chars produced dangling '…' text. Keep the full context and let the notification center's existing two-line clamp + expand-on-click handle display; only the action line stays bounded. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Issue-Fix entry lived only as a small wrench icon in the chat header's top-right cluster — easy to miss for the feature's primary audience. Add a wrench button to the workspace strip directly above the input box (next to usage/goal), where the user's attention already rests, opening the same Issue-Fix tab. The header icon stays for consistency with the PR-review entry. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Remove the duplicate header wrench now that the strip button above the input box is the primary entry; regenerate i18n contracts so the new chatInput.issueFix keys resolve instead of rendering raw key paths. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Continuous issue fixing is GitHub-only today: issue enumeration hits the GitHub API, the agent gathers evidence through gh, and LoopX's PR-lifecycle monitors are GitHub-shaped. The panel previously defaulted unknown remotes to github.com and fired broken requests. Now the remote probe has an explicit pending/none state, non-GitHub hosts render a clear unsupported notice naming the detected host instead of a broken list, and no GitHub calls are made for them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
On Windows the borderless main window sometimes maximizes to the FULL monitor instead of the work area (double-click drag-region maximize racing a DPI change, or an external ShowWindow(SW_MAXIMIZE)), hiding the app's bottom edge — nav footer, notification bell, composer strip — behind the taskbar. Tao's WM_NCCALCSIZE clamp misses these paths, so watch Resized events on the main window and, when maximized with a client rect taller than the monitor work area, SetWindowPos it back to the work area. Verified with an external SW_MAXIMIZE: client height now lands exactly on the work area (1392 vs the previous 1440 overflow) and restore/re-maximize cycles stay stable. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The notification card's Open panel action dispatched AGENT_CREATE_TAB unconditionally, but the agent content canvas only listens while the session scene is mounted — from the welcome or any other scene the event fired into the void and the click did nothing. Route agent-canvas tab delivery (issue-fix and review-platform alike) through a shared helper that activates the session scene first and, when the scene was just opened, hands the tab through the pending-tab queue the canvas drains after mount. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The first clamp only handled the maximized case, but once the overflow bug had happened the window-state plugin persisted the taskbar-covering size, so every later restore reproduced the hidden bottom edge without being maximized. Handle both branches in the Resized watcher: maximized windows re-clamp to the work area, restored windows taller or wider than the work area shrink to fit and stay inside, which also self-heals the bad persisted geometry on the next save. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts: # scripts/core-boundaries/rules/feature-rules.mjs
Packaged BitFun users should not need a Python toolchain to use continuous Issue-Fix. Following the flashgrep precedent: - prepare-loopx-resource.mjs builds a single-file loopx binary with PyInstaller (LoopX has zero runtime deps) into resources/loopx/; desktop-tauri-build bundles it when present. The sidecar is optional — builds without it keep working and fall back to LOOPX_BIN / PATH. - The desktop host resolves the bundled sidecar at startup and points LOOPX_BIN at it unless the user already set it, so probe order is developer override -> shipped sidecar -> PATH, and the LoopX version shipping with each BitFun release pins the CLI contract the integration was validated against. - issue_fix_probe now reports the full runtime readiness (loopx source, gh installed, gh authenticated); the panel shows targeted guidance for whichever tier is missing instead of one generic banner. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
xielixing
force-pushed
the
codex/bitfun-loopx-issue-fix-repair
branch
from
August 6, 2026 09:09
669e799 to
84d4aaa
Compare
A fresh user's repository has no .loopx control plane, which previously surfaced as a raw "Failed to read LoopX Issue-Fix state" error banner the moment the panel opened. Pre-bootstrap is a normal state, not an error: status/poll now return null for unconnected repositories, the header says "not connected yet - select issues and press Start", and the Start command runs loopx bootstrap (BitFun's continuous-repair objective, controller role) plus register-agent bitfun-cron before writing the first intake todos. Verified end to end on a fresh git repo with the PyInstaller sidecar: bootstrap, register, intake, todo projection, and compact heartbeat generation all succeed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
xielixing
force-pushed
the
codex/bitfun-loopx-issue-fix-repair
branch
from
August 6, 2026 09:09
84d4aaa to
3e9cc4a
Compare
Deleting a chat session cascades into delete_jobs_for_session, which silently kills any scheduled work bound to it — including the continuous Issue-Fix heartbeat. Users cleaning up their sidebar had no way to know a session was load-bearing. The delete action now checks the cron service for enabled jobs on that session and, when found, explains the consequence (job stops; progress lives outside the session and Start resumes it) before proceeding. Plain sessions delete exactly as before, and a failed job lookup never blocks deletion. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replaces the deleted pre-implementation design doc with one describing the shipped architecture: host/kernel division, decoupling contract, state ownership, heartbeat design with the incident provenance of each preamble rule, CLI write semantics, distribution/readiness tiers, interaction invariants, and known deviations with upstream items. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rding guide Three gaps in the architecture doc surfaced in review: how the LoopX dependency is obtained and built (three-tier resolution, sidecar build steps, smoke checks, per-platform caveats), what happens and what to do when each prerequisite is missing (loopx / gh install / gh auth / pre-bootstrap / non-GitHub host, with the user-facing behavior and the developer remedy side by side), and how to onboard further LoopX capabilities — a layer-reuse table over the existing bridge, sidecar, identity, projection, heartbeat and UI assets, plus a six-step checklist distilled from the issue-fix lessons (verify write semantics before polling, define the intake shape, mandate gate linkage, keep the preamble repository-agnostic, finish with a clean-machine E2E). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…work
The agent misfiled provider-side reminders ("Merge PR #N") as
user_gate todos, flooding the panel's blocking decision card with items
that need no authorization — merging is the user's own GitHub action,
observed and closed out by the lifecycle monitor. Two-sided fix:
- The preamble now picks the task class by WHO performs the action:
user_gate exclusively requests authorization for something the AGENT
will do; provider-side work the user completes themselves is
user_action, never a gate.
- project_user_question keeps the decision card only for gates that
actually stall agent work — blocks_agent set, global_gate, or an
authorization request (conservative verb check) — so legacy
misclassified reminders degrade to the ambient pending lane instead
of impersonating urgent decisions.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The chat stop button cancels one turn, but when that turn came from a scheduled job (the continuous Issue-Fix heartbeat), one-turn cancel is rarely the intent — the next beat re-injects the same prompt within the interval, which reads as "it would not stop". Instead of overloading the stop button with a destructive side effect, cancelling a turn that belongs to an enabled scheduled job now raises a notification offering one-click "Stop the schedule" (15s window). Disabling only stops host scheduling; kernel-side progress is untouched and the Issue-Fix panel's Start resumes it. Jobs are snapshotted before the cancel lands because the cron subscriber clears activeTurnId on DialogTurnCancelled. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sessions hosting the continuous Issue-Fix heartbeat looked identical to ordinary code chats in the sidebar — users could not tell load-bearing sessions apart before renaming or deleting them. Rows whose session is bound to an enabled session-targeted cron job now render a wrench icon (matching the Issue-Fix entry point) with a tooltip line naming the role. Membership comes from one listJobs snapshot refreshed every 60s; rendering stays a pure Set lookup. The unread/running indicators are unchanged — green dot still means an unseen completed run, the spinner still means a turn in flight. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Reframe continuous Issue-Fix as a MiniApp while keeping every native capability. Three layers: - Bridge: new issueFix.* namespace (probe/listIssues/status/poll/start/ stop/answer) routing to the native issue_fix_* commands, gated on agent+cron permissions; cron.* restored (listJobs/updateJob) for schedule inspection. CronPermissions re-added to the manifest types. - Hidden heartbeat host: issue_fix_start_autonomous accepts hiddenHost, creating/reusing a backend-owned hidden session invisible in the sidebar — the MiniApp owns the whole experience while scheduling stays host-side, so the repair loop survives the MiniApp being closed. MiniApp starts always use hidden mode; the native panel keeps its visible-session mode during the transition. - builtin-loopx-issue-fix MiniApp: issue selection, start/stop, blocking gate card, pending user-lane todos, activity log — porting the panel's interaction rules (monotonic ticket guard, zero-write polling, pause during mutations, GitHub-only notice, readiness guidance). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Continuous Issue-Fix: select a repository's open GitHub issues and let a LoopX-driven agent repair them continuously — isolated worktree per issue, failure-before/pass-after validation, PR publication, and lifecycle monitoring through merge — with every human-authority decision (publishing, closing issues, posting comments) surfaced as an explicit gate.
The product surface is a self-contained builtin MiniApp (
builtin-loopx-issue-fix); the capability layer is native:services-integrations/loopx_issue_fix): JSON subprocess bridge, kernel-owned state projection (todo listfor polling — zero-write;quota should-runonly on demand since it appends a rollout event per call), typed gate answers, first-use bootstrap (loopx bootstrap+ agent-lane registration).loopx heartbeat-prompt --compactcontract every 10 minutes into a backend-owned hidden session (invisible in the sidebar). Scheduling is host-owned: closing the MiniApp does not stop the loop; restarts resume from kernel state. Start/stop/answer serialize on a host-loop lock; duplicate/orphan jobs self-heal.scripts/prepare-loopx-resource.mjs --build) resolved as LOOPX_BIN override → bundled sidecar → PATH, pinning the validated CLI contract per release. Three-tier readiness probe (loopx / gh installed / gh authenticated) with targeted guidance.issueFix.*namespace (probe/listIssues/status/poll/start/stop/answer) gated on agent+cron permissions;cron.*restored for schedule inspection.Product scope: GitHub-only for now; other hosts get an explicit unsupported notice. The interim native panel is retained during MiniApp validation and will be retired in a follow-up.
Type and Areas
Type: Feature, UI/UX, fix, docs, tests
Areas: Rust services integration, desktop/Tauri, MiniApp runtime, web UI, build scripts, LoopX integration
Motivation / Impact
Manual issue triage and repair does not scale. This PR turns it into a supervised continuous loop: LoopX's State Kernel owns goals/todos/gates/monitors as the single source of truth, BitFun supplies execution (agent sessions), scheduling (cron heartbeat), and the human-authority surface. A two-night live run on this repository produced 26 validated PRs with per-issue isolation, spending ~1.5% of the quota budget; crashes and restarts resumed cleanly from kernel state.
Architecture record:
docs/architecture/loopx-issue-fix-integration.md(division of labor, decoupling contract, CLI write semantics, build/prerequisite handbook, capability onboarding guide).Verification
cargo test -p bitfun-services-integrations --features loopx-issue-fix(150 tests),cargo check -p bitfun-desktopcleantsc --noEmitclean; vitest suites for the issue-fix panel, run-state projection, notification center, NavPanel, flow-chat (1400+ tests)AI-assisted: yes (fully tested as above).
🤖 Generated with Claude Code