Route every orchestrator code-execution path through the AI safety
classifier, closing the gap where session_execute_command, submitted
send_text, create_file, and TUI keystrokes dispatched to the PTY on a
one-time workgroup claim with no per-action classification.
Classifier and prompt hardening (AutoModeClassifier / TUISafetyPrompt):
- Untrusted-content trust rules: only a direct user turn authorizes a
risky action; agent prose is never projected into the transcript.
- Prompt-injection defenses: fence the untrusted screen with a random
sentinel, neutralize block/thinking/reason and transcript delimiters,
collapse every line-break scalar so a payload cannot forge a row or a
role turn, and a fail-closed any-yes parse against injected verdicts.
- Transcript count/size caps that keep the newest turn and the most
recent user turn, truncating middles rather than dropping intent.
- Recent chat history seeded into both the orchestrator and the
session-bound safety checks so intent is visible.
Screen-aware TUI keystroke classification with an offline eval harness,
scorer, and fixtures captured from real terminal programs.
Whole-line reconstruction plus a lag-free per-session accumulator so a
command split across back-to-back sends, spliced mid-line, or staged
across calls is classified as one line rather than dodging the gate.
TerminalHardRules is now a tokenized blocklist, not an allowlist: it
never permits and never hard-denies. It tokenizes each command (argv,
flags, target) and surfaces only a narrow set for one-tap approval
(catastrophic rm/chmod/chown/dd/mkfs/find at root or a device, carriage
returns, unbalanced quotes, pipe-to-shell, obscure zsh builtins,
terminal escapes); everything else defers to the LLM, which reads it in
full and judges it against what the user asked for. This mirrors Claude
Code's auto mode and removes the read-only allowlist that let an
autonomous agent cat secrets or trigger a poisoned pager unchecked.
Wire needsManualApproval and deny through the existing awaitPermission
bubble ("Run this command?") so a flagged command is offered for one-tap
approval instead of dead-ending as a text message to the model.