Skip to content

REPL audit: close eleven engineering gaps, safe-mode Extended-bucket fix, tmux driver skill - #96

Merged
fuseraft merged 7 commits into
mainfrom
fix/repl-audit-2026-09-06
Sep 7, 2026
Merged

REPL audit: close eleven engineering gaps, safe-mode Extended-bucket fix, tmux driver skill#96
fuseraft merged 7 commits into
mainfrom
fix/repl-audit-2026-09-06

Conversation

@fuseraft

@fuseraft fuseraft commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Summary

  • Closes eleven engineering gaps found in a REPL audit pass (crash on null config, turn-index corruption, silent memory-extraction skip, /safe-mode desync, JSON-mode stdout break, /tools restrict tag validation, /assist usage tracking, /compact context-estimate reset, duplicate plan-step warning, dead code, /mcp add argument quoting)
  • Splits ReplSessionPlugin between the default REPL tool set and /assist's diagnostic set
  • Fixes a stale repl_session_* claim in the system prompt left over from that split
  • Adds a scope axis to the adversarial-mode critic review, judging against the real /plan <task> text
  • Closes the /safe-mode Extended-bucket gap: Shell/Git/Http tools living in the Extended category (e.g. git_push, shell_run_background) now get blocked by owning plugin regardless of which bucket holds them, without disturbing any prior /tools restrict
  • Adds a repl-tmux-driver skill capturing the tmux workflow used to live-test REPL changes against a real model

Test plan

  • ./build.sh --target=Build clean
  • ./build.sh --target=Test — 1022/1022 passing
  • Live-verified the safe-mode fix against a real grok-4.5 REPL session with --plugins Extended: /tools before/after /safe-mode on confirms Extended-bucket git_push/git_reset/shell_run_background flip to blocked while FileSystem-owned Extended tools stay active
  • Live-verified the repl-tmux-driver skill loads cleanly in a REPL session (fuseraft skills validate passes; skill count increments with no load error)

Scott Stauffer 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.
@fuseraft
fuseraft merged commit 374d2c5 into main Sep 7, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant