Conversation
Replace the auto-allow stub in delegate.rs that silently approved every RequestUserInput with proper user prompting infrastructure. Changes: - Remove token-generator-specific Response/Context types from runtime - Route RequestUserInput through the executor loop (same pattern as GET/PUT/UPDATE contract requests) - Add UserInputPrompter trait with SubprocessPrompter (production), AutoApprovePrompter (testing), and AutoDenyPrompter (headless) - Add `freenet prompt` subcommand that shows native OS dialogs: zenity/kdialog on Linux, osascript on macOS, PowerShell on Windows, with terminal fallback - 60s timeout auto-denies to prevent indefinite blocking The delegate's own WASM code handles context updates via UserResponse (already implemented at delegate.rs:541). The runtime no longer touches delegate-specific types. Closes #1499 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rule Review: Minor style issues only — no blockersRules checked: WarningsNone. Info
Rule review against |
- Rename atty_is_terminal to stdin_is_terminal (clearer, no atty crate involved) - Replace match-with-empty-arm with simpler if-expression for zenity exit code - Remove misleading comments (Windows dialog, kdialog menu support) - Document why terminal_prompt ignores timeout_secs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Security: prevent command injection in osascript (pipe message via stdin instead of string interpolation) and PowerShell (read from temp JSON file instead of inline interpolation). Add input sanitization (length limits, control char stripping) for all platforms. - Fix zenity extra-button logic: check stdout for button text BEFORE falling back to Cancel interpretation on exit code 1. - Send denial response to delegate: on timeout/dismiss, send an empty ClientResponse via UserResponse so the delegate knows the request was denied rather than silently dropping it. - Fix parse_message: try JSON deserialization first to unwrap quotes/escapes from NotificationMessage bytes before falling back to raw UTF-8. - Add 6 new tests: parse_message JSON/raw/quotes, parse_button_labels invalid UTF-8, auto_approve/deny with 3+ responses. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add 8 tests for sanitize_message/sanitize_label: normal text, newline preservation, control char stripping, truncation at limits, empty strings - Rename misleading test_parse_message_invalid_utf8_fallback to test_parse_message_json_with_quotes (test body doesn't exercise invalid UTF-8 path) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ack The The info items (AutoDenyPrompter doc comment, constant rationale) are addressed in the latest commit. [AI-assisted - Claude] |
- Document why MAX_MESSAGE_LEN=2048, MAX_LABEL_LEN=64, MAX_LABELS=10 - Add doc comment explaining AutoDenyPrompter's intended use case Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Problem
RequestUserInputwas stubbed atdelegate.rs:348-360-- every request was auto-approved by fabricating aResponse::Allowedusing token-generator-specific types hardcoded into the runtime. This meant any web page could silently trigger delegate operations (like ghostkey signing) without user consent.Approach
Replace the stub with proper user prompting infrastructure that follows the existing contract request pattern:
RequestUserInputnow flows throughprocess_outbound()to the executor loop, just likeGetContractRequest/PutContractRequestSubprocessPrompter(production): spawnsfreenet promptas a child processAutoApprovePrompter(testing): returns first response immediatelyAutoDenyPrompter(headless): always deniesfreenet promptsubcommand: Native OS dialogs via zenity/kdialog (Linux), osascript (macOS), PowerShell (Windows), with terminal fallback. Returns selected button index on stdout.The delegate's own WASM code handles context updates via
InboundDelegateMsg::UserResponse(already implemented at delegate.rs:541). The runtime no longer touches delegate-specific types.Key design decisions
RequestUserInputis intercepted and fulfilled inhandle_delegate_with_contract_requests(), following the exact same pattern as contract requests (GET/PUT/UPDATE/SUBSCRIBE).Testing
UserInputPrompterimplementationscargo fmtandcargo clippycleanCloses #1499
[AI-assisted - Claude]