---
name: owl-send-not-legacy-spt-send
description: inter-agent messaging must use $OWL send; spt send is the new spt-core binary but no live perches run on it yet (bounces NO_PERCH)
metadata: 
  node_type: memory
  type: feedback
  originSessionId: 54192bb2-27e5-4385-b119-3cc0db6e0700
---

For agent-to-agent messaging on this rig, use **`$OWL send <target>`** — NOT `spt send <target>`.

The naming is counter-intuitive: **`spt send` is the NEW spt-core binary** (the system being built in this repo), and **`$OWL` is the LEGACY system**. Everyone's active perch currently runs on the **legacy** version because the new spt-core messaging isn't stable enough yet. So `spt send <target>` talks to the new system — which has no live perches — and returns `NO_PERCH:<target> is not listening`, while `$OWL send` reaches the perch that's actually live on legacy.

**Why:** observed 2026-06-08 — doyle tried `printf '%s' "…" | spt send todlando` to coordinate a release hand-off; it bounced `NO_PERCH`. Not because todlando was offline and not because spt is "stale" — because the live perches run on legacy ($OWL) while `spt send` drives the not-yet-deployed new path. User confirmed.

**How to apply:** always `$OWL send` / `$OWL ring` / `$OWL send --reply-to` for messaging until perches migrate to the new spt-core binary. If `$OWL` is unset, restart the session so the SessionStart hook re-injects it. Also: don't pipe a send through `tail` and read `$?` — the pipe masks the real exit (doyle's `SENT=$?` read 0 despite the bounce); use `${PIPESTATUS[0]}`.

**CRITICAL invocation (2026-06-13): `owl send <TARGET> [FROM]` reads the MESSAGE BODY FROM STDIN — there is NO body positional/flag.** Passing the body as an argument (`& $OWL send doyle "my message"`) makes "my message" the FROM arg and then **blocks forever waiting on stdin** — the send never finishes (user confirmed: "sending that way is broken, never finishes"; run_in_background tasks hung with empty output). CORRECT: pipe the body in, body NOT an arg — PowerShell `$body | & $env:OWL send doyle todlando` (TARGET=doyle, optional FROM=todlando). Success prints `➜ SENT:doyle`, exit 0. Use a here-string `@'...'@` for multi-line bodies. Run FOREGROUND with a timeout — do NOT background it.

**GOTCHA (2026-06-23, bash tool): backticks in a double-quoted send body get COMMAND-SUBSTITUTED by bash before the pipe.** `printf '%s' "...resolve_idle_file...spool_deferred..." | $OWL send doyle` ran the backtick-wrapped words as commands (`spool_deferred: command not found`) → doyle got a garbled body. FIX: use a single-quoted **heredoc** for the body — `cat <<'EOF' | "$OWL" send doyle` … `EOF` (the quoted `'EOF'` delimiter disables ALL expansion incl backticks/`$`). Or strip backticks/`$`. Don't put markdown backticks in a double-quoted bash send.

Related: [[spt-daemon-is-live-infra]] (owl.exe plugin = live listener; spt.exe = dev/test artifact).
