REPL audit: close eleven engineering gaps, safe-mode Extended-bucket fix, tmux driver skill - #96
Merged
Merged
Conversation
added 7 commits
September 6, 2026 18:44
- Crash: legacy-key migration dereferenced a null UserConfig when ~/.fuseraft/config was missing but an old .key file survived. - Turn-index corruption: mutation/critic/todo correction turns recursed into ExecuteAsync before the outer turn's own bookkeeping ran, inflating ctx.TurnIndex and mislabeling TurnEnd/message_end events. Corrections now run after the turn they follow has fully closed out. - Silent memory loss: LastExtractedTurnIndex wasn't reset by /clear, /rewind, or /compact, so exit-time memory extraction could compare against a stale index and skip a whole post-reset conversation. - Safe-mode desync: /tools enable on a Shell/Git/Http category left SafeMode=true while the category was actually back on, so a later /safe-mode on would no-op instead of re-disabling it. - JSON-mode contract break: /execute's critic-review branch wrote raw ANSI to stdout unconditionally; now gated on JsonMode, with the rejection reason carried in the StepHalted event payload instead. - /tools restrict silently blocked 100% of a plugin's tools when given a tag that plugin doesn't use (e.g. "Http write"); now warns. - /assist never recorded token usage, unlike /explore, /delegate, and /locate; DiagnoseAsync now returns usage like its siblings. - /compact didn't reset PrevCtxEstimate, so the next /context showed a confusing negative delta against pre-compaction usage. - A plan with duplicate step numbers silently dropped a step with no warning; now flagged at plan-capture time. - Removed a dead, no-op reflection pass left over from a refactor. - /mcp add split stdio arguments on bare spaces with no quoting, breaking any argument containing a space; added a quote-aware split.
compact_context/get_context_status are load-bearing for the main agent's own context-budget self-management, so they stay default-on. current/list/read_event_log/read_log let the model read a *different* session's full event log by ID/prefix match — real cross-session data exposure with no turn-to-turn value for the primary loop — so they're withheld from the default set and handed only to /assist's diagnose loop, which previously ran with no tools at all.
The main agent's system prompt told it to use repl_session_* tools to inspect session metadata, list past sessions, or read log files — but the prior ReplSessionPlugin split withheld exactly those tools from the default set, leaving only compact_context/get_context_status. Point the prompt at the two tools it actually still has.
Judge a third thing alongside correctness/completeness: whether the response is right-sized for what the user actually asked for, not just the plan step's own (possibly drifted) description. Threads the original /plan <task> text through as ctx.CurrentPlanRequest so step reviews have the real ask to compare against, not a paraphrase. Live-tested against grok-4-1-fast-reasoning: an over-scoped response (unrequested extra files, unrelated git commits) is reliably rejected citing the added scope. The first rubric wording also flagged a plain write-then-verify (write_file + read_file) as scope creep, which would have fought the main agent's own required post-write verification step — added an explicit carve-out so confirmation actions aren't penalized. Re-verified 3x after the fix: control approves, over-scope still rejects.
/safe-mode on only disabled the Shell/Git/Http category-key buckets, so once --plugins Extended was enabled, tools like git_push, git_reset, and shell_run_background lived under the separate "Extended" bucket and stayed callable through safe mode. Add ReplSessionContext.PassesSafeMode(toolName), which blocks a tool by its owning plugin (PluginCapabilityMap.GetPlugin) rather than by which category dictionary key holds it - the same reach /tools restrict already had. Combined with the existing capability-restriction check via a new IsToolAllowed. This also means safe-mode never touches CapabilityRestrictions, so a prior /tools restrict on Shell/Git/Http now survives /safe-mode on/off untouched instead of needing a save/restore dance. FileSystem-owned Extended tools (delete_file, copy_file, etc.) are left alone - safe-mode has never claimed to touch FileSystem.
Captures the tmux workflow for driving fuseraft repl interactively from outside - injecting single/multi-line input, polling for the idle prompt instead of blind-sleeping, capturing pane output, and verifying results independently rather than trusting the agent's own summary. Written up after using this exact procedure to have a live REPL session fix the /safe-mode Extended-bucket gap.
Was missing from the "Shipped skills" list added alongside the skill itself in 9e0dbe5.
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
ReplSessionPluginbetween the default REPL tool set and/assist's diagnostic setrepl_session_*claim in the system prompt left over from that split/plan <task>text/safe-modeExtended-bucket gap: Shell/Git/Http tools living in theExtendedcategory (e.g.git_push,shell_run_background) now get blocked by owning plugin regardless of which bucket holds them, without disturbing any prior/tools restrictrepl-tmux-driverskill capturing the tmux workflow used to live-test REPL changes against a real modelTest plan
./build.sh --target=Buildclean./build.sh --target=Test— 1022/1022 passing--plugins Extended:/toolsbefore/after/safe-mode onconfirms Extended-bucketgit_push/git_reset/shell_run_backgroundflip to blocked while FileSystem-owned Extended tools stay activerepl-tmux-driverskill loads cleanly in a REPL session (fuseraft skills validatepasses; skill count increments with no load error)