Skip to content

fix: 1.2.1 follow-ups — /ss quoting (#43), channel-relay uid (#48), attach exit-5 (#47) - #53

Merged
rappdw merged 1 commit into
mainfrom
fix/1.2.1-ss-channels-attach
Jul 17, 2026
Merged

fix: 1.2.1 follow-ups — /ss quoting (#43), channel-relay uid (#48), attach exit-5 (#47)#53
rappdw merged 1 commit into
mainfrom
fix/1.2.1-ss-channels-attach

Conversation

@rappdw

@rappdw rappdw commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Three bugs surfaced exercising 1.2.0 in real daemon / sandy-ui use.

#43 — /ss quoting

The generated /ss commands spliced $ARGUMENTS (claude) and {{args}} (gemini) directly into the !`…` / !{ } shell-exec line, so a quoted request like /ss 2 "what's this?" broke the shell parse (and was a latent injection vector). The shell line now runs a fixed sandy-ss-paths 5 with zero user text; the count is handled in model prose (read the first N of the newest 5, default 1). codex SKILL.md was already prose-only — unchanged.

#48 — channel-relay uid

The host-side relay execs tmux has-session / send-keys via docker exec without -u "$(id -u)". docker exec defaults to the image user (root — sandy sets no USER), but the in-container tmux server runs as the gosu-dropped host uid, so its socket is at /tmp/tmux-<uid>/. Root can't see it → the gemini/codex/opencode host-side Telegram/Discord relay silently never delivered. Same class as the daemon-probe -u fixes. Claude channels (in-container plugin) were unaffected.

#47 — attach exit-5 (completes the exit-5 half; zombie half shipped in 5048899)

Post-attach, a container-still-up-but-session-gone state (the agent exited while a client was attached and the supervisor watch-loop is mid-teardown) was misclassified as "attach failed" (exit 5). It's a normal session-end → now exit 0, so sandy-ui stops sticky-reconnecting a dying session. A one-shot re-probe absorbs a transient docker exec hiccup before the 0 verdict. Exit 5 is now reserved for a failure to establish the attach.

Tests / docs

  • run-tests.sh §45j (no user-arg splice in the /ss shell lines) + new §46 (channel-relay execs are uid-scoped, no bare-root exec remains).
  • SPECIFICATION.md relay-inject example shows -u + why; CLAUDE.md DEC-C clarifies post-attach exit-5 is establishment-only.
  • templates/user-setup.sh.tmpl regenerated (no drift).

Closes #43
Closes #48
Closes #47

🤖 Generated with Claude Code

…ttach exit-5 (#47)

Three bugs surfaced exercising 1.2.0 in real daemon/sandy-ui use.

#43 /ss quoting — the generated /ss commands spliced $ARGUMENTS (claude) and
{{args}} (gemini) directly into the `!`…`` / `!{ }` shell-exec line, so a
quoted request (`/ss 2 "what's this?"`) broke the shell parse and was a latent
injection vector. The shell line now runs a FIXED `sandy-ss-paths 5` with no
user text; the count is handled in model prose (read the first N of the newest
5, default 1). codex SKILL.md was already prose-only — unchanged.

#48 channel-relay uid — the host-side relay execs `tmux has-session`/`send-keys`
via `docker exec` WITHOUT `-u "$(id -u)"`. docker exec defaults to the image
user (root — sandy sets no USER), but the in-container tmux server runs as the
gosu-dropped host uid, so its socket is at /tmp/tmux-<uid>/. Root can't see it,
so the gemini/codex/opencode host-side Telegram/Discord relay silently never
delivered. Same class as the daemon-probe -u fixes. Claude channels use an
in-container plugin and were unaffected.

#47 attach exit-5 (completes the exit-5 half; the zombie half shipped in
5048899) — post-attach, a container-still-up-but-session-gone state (the agent
exited while a client was attached and the supervisor watch-loop is mid-
teardown) was misclassified as "attach failed" (exit 5). It's a normal
session-end → now exit 0, so sandy-ui stops sticky-reconnecting a dying
session. A one-shot re-probe absorbs a transient docker-exec hiccup before the
0 verdict. Exit 5 is now reserved for a failure to *establish* the attach.

Regression guards: run-tests.sh §45j (no user-arg splice in the /ss shell
lines) + new §46 (channel-relay execs are uid-scoped, no bare-root exec
remains). Docs synced: SPECIFICATION relay-inject example shows -u and why;
CLAUDE.md DEC-C clarifies post-attach exit-5 is establishment-only.
templates/user-setup.sh.tmpl regenerated (no drift).

Closes #43
Closes #48
Closes #47

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@rappdw
rappdw merged commit 5567cbf into main Jul 17, 2026
2 checks passed
@rappdw
rappdw deleted the fix/1.2.1-ss-channels-attach branch July 17, 2026 01:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant