feat(rails): pause on user input + sends gate for approval - #87
Conversation
Closes the documented-but-unwired defense (SAFETY_REVIEW 'any user touch pauses'): a watchdog shared by the vision and AX hosts pauses the guard on human input. Synthetic suppression has one owner - the actuation adapter brackets every action in a tracker (in-flight + parked cursor), so the rail's own output never reads as a takeover, and neither do clicks on our own overlay (or resuming would instantly re-pause). Detection: uiohook-napi (new OPTIONAL native addon, same load-by-variable pattern as nut-js) for mouse + keyboard; a dependency-free cursor-poll fallback covers mouse when the addon is absent. 15 tests over the decision rule and the poll path; the hook path is owned by the real-machine pass like actuation itself. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The approval policy diverged from the safety story: mail_send and messages_send ran with no human in the loop while every doc and the model-facing prompts promised gating. One rule now, in needsApproval: computer-use rails AND send action types gate; web_task stays unprompted (it acts in Off Grid's own watched pane); undoable mutations keep the auto-run + Undo tier. The pro auto-approve toggle is scoped to computer use only - sends ask every time. Model hints and SAFETY_REVIEW updated to say exactly this. Tests: the policy matrix + sends parking (even in auto mode) + resolve round-trips. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing |
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
… left behind
The planning pass (shouldPlan -> planTask) was consuming every tools-loop
test's first scripted turn - the fake llama now answers PLAN_SCHEMA
requests out-of-band with an empty plan (recorded separately as
plannerRequests), so tests drive the reactive loop they script. The
gate-seam journey's fixture becomes a SEND ('email') - under the current
policy only sends and computer-use gate, so that is the type that parks.
Both files were red on feat/windows-parity already (db suite is
non-blocking on push and the branch never ran CI); 29/29 now pass.
fresh-setup-first-use still fails on the base branch (pre-existing,
'LLM Service not ready' after relaunch) - tracked separately.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
The orchestrator's plan-executor imported ToolCall/UnifiedSource from the big tools.ts, which imports the executor back - a no-circular violation the dependency-boundaries gate rejects. Move the two shared leaf types to tools/tool-types.ts (imported by both, importing nothing back); tools.ts re-exports them so external importers are unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|



What this does
Two production-readiness fixes for the rails, both verified by hand on a live dev build (2026-08-27):
1. Pause when the user touches the machine - the documented defense, now wired. SAFETY_REVIEW promised "any user touch pauses the supervised run"; only the overlay's Pause button actually did. Now a watchdog shared by the vision and AX hosts pauses the guard on any human mouse/keyboard input. Telling human input from the rail's own output has one owner: the actuation adapter brackets every synthetic action (in-flight + parked cursor) in a tracker the watchdog consults - so the rail never pauses itself, and clicks on our own overlay (Resume) never re-pause. Detection is uiohook-napi (new OPTIONAL native addon, loaded by-variable like nut-js) for mouse + keyboard, with a dependency-free cursor-poll fallback for mouse. Esc remains the kill switch either way.
2. Sends gate for approval alongside computer_task. The shipped policy had drifted: mail_send / messages_send ran with no human in the loop while the safety review and the model-facing prompts promised gating. One rule now (gate-host
needsApproval): computer-use rails AND send action types gate; web_task stays unprompted (it acts inside Off Grid's own watched pane and hands back at sign-in/payment); undoable mutations (calendar, reminders) keep the auto-run + Undo tier. The pro auto-approve toggle is scoped to computer use only - sends ask every time. Model hints and SAFETY_REVIEW now state exactly this policy.Verification
🤖 Generated with Claude Code