2026-09-27 — SetCallback got a real IPC file, an API, and a UI
Resumed session frosty_sagan (worktree picobot-botnewcallbackipc) with a fully
researched plan and three of four build steps done. Finished the whole chain today.
What shipped
| Repo | Commit | What |
|---|---|---|
| clang | a2c49fa | libsxutil/sx_callbacks.h (header-only load/save/tick), agent persists to callbacks.json, TUI + DLL tick wiring, DLL monotonic→wall-clock fix |
| scorpiox-bot-api | 082ede2 | /callbacks GET/POST/PUT/DELETE + /callbacks_sse, rev-bump protocol |
| scorpiox-bot-web | 2bd1ef3 | chat popover (chat_callbacks.h), callbacks.c + callbacks_sse.c wrappers, 4-place registration |
| scorpiox-picobot-client | 32d12af | picobot_get_callbacks/set_callback/cancel_callback + picobot_set_password, scorpiox_io PUT/DELETE |
| picobot skills | 4ddb151b | bot-architecture §4.11, node-api route rows, live-json test §12 |
Release: release-bot all all → SUCCESS (linux + windows zips on dist, 14:53–14:54).
.3 and .6 bot-api pulled, rebuilt, restarted. Prod verified: :8150/callbacks 200,
:8155/chat 200, SSE stream pushes event: callbacks on every write.
How the live-fire E2E went
I POSTed two callbacks to the live picobot session (30s×3 "alpha", 120s×∞ "beta").
The file appeared instantly with correct epoch-ms fire_at_ms, rev 1→2.
The slots fired overdue in the file's eyes — but the running TUI still runs the
old binary (built 20:48, feature commit is 21:2x), so nothing fired and the
agent never adopted the edits. Expected: sessions pick up the feature only when
restarted on the new build. I rebuilt sx + scorpiox-agent on .100 and copied
them into /usr/local/bin (build outputs: build/bin/sx, build/scorpiox/scorpiox-agent).
Things I learned (worth remembering)
- cpp macro line continuations: a
#define X \block where any line lacks the
trailing \ compiles as a string-literal collision error at the next line —
42 missing continuations in chat_callbacks.h produced one misleading error.
- Make "Nothing to be done" lies: the client lib
Makefiledeps didn't include
all edited files — touch + rebuild, or delete the target.
- **
--flagoption parsing bug pattern**:cmd_start = i + 2; break;exits the
option loop after the FIRST flag, so --host X --pwd Y → --pwd becomes the
command. Fix: consume the value with i++ and only break on the first
non-option token.
- Hub edge auth:
:8155(SERVER_JWT_PROTECT=/) rejects?pwd=— only the JWT
cookie passes. Password (?pwd=/X-Bot-Password) works on node APIs (:8150,
.3:8151, .6:8152) with the default password (stored in AGENTS.md). The client lib
therefore defaults to bot.scorpiox.net for JWT users; tests ran against :8150
with --pwd <default>.
- Agent adoption protocol: external writers bump
rev; the agent's poll-only
sync (persist=false) copies the file wholesale when rev moved. Own writes use
max(file_rev, local_rev)+1. Same file, two directions, no locks — atomic renames
make it safe at human edit rates.
- Old-binary restarts are the deployment unit for TUI features: bot-api/web
redeploys are instant (systemd restart), but the 5 long-running scorpiox TUI
sessions keep the binary they started with. /usr/local/bin/scorpiox is bind-mounted
read-only into running containers (/opt/host-bin), so even copying the new binary
doesn't affect live processes.
Left open (user decision needed)
Restart the 5 picobot-family TUI sessions (mine, main picobot, 3 worktree agents) to
load the new binary so web/API-set callbacks actually fire into live sessions. The
two test slots I created were cleaned up (rev 7, all slots inactive).