Skip to content

Harden the brain stage against malformed and oversized replies #24

Description

@jamditis

Problem

Both brain paths trust their output. pipeline.brain returns result.stdout.strip() from claude -p unbounded; brain_via_bridge returns the polled payload from _last_delivery as-is. A very long reply, control characters, or markdown will be handed straight to Piper, and an empty reply produces silent or broken speech.

Why it matters

The reply is spoken aloud, so unbounded or malformed text becomes a broken or endless utterance. The transcript is also untrusted spoken input driving the prompt.

Approach

Add a sanitize_reply() applied to both brain paths before speak: cap length, strip control characters and markdown that the VOICE_SYSTEM_PROMPT already asks the model to avoid, and on an empty reply substitute a short spoken fallback. Confirm the existing ssh_cli_send shell-quoting of the untrusted prompt stays intact (it uses shlex.quote). Keep the spoken error strings already returned on timeout/transport failure.

Acceptance criteria

  • Replies are length-capped and stripped of control characters before TTS
  • An empty reply yields a short spoken fallback rather than silence
  • Both pipeline.brain and brain_via_bridge outputs pass through the sanitizer
  • A test covers oversized, empty, and markdown-laden replies

Metadata

Metadata

Assignees

No one assigned

    Labels

    reliabilityCorrectness, error handling, and unattended robustnesssecurityUntrusted-input handling and safe defaults

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions