4.1 KiB
SPIKE: crush server (v0.87.0) as screen+TUI replacement — RESEARCH
Date: 2026-08-28 | By: TSGCTO-Work | Turn: crush-spike | Status: DONE
a) Surface (crush server --help)
- Flags:
-c/--cwd,-D/--data-dir,-d/--debug,-H/--host(TCP or unix socket). - Default socket:
unix:///tmp/crush-<uid>.sock→ here/tmp/crush-1005.sock(uid 1005 confirmed). - Protocol: Go
net/httpmux speaking HTTP/1.1 + gRPC (binary containsapplication/grpc; unknown paths return Go's plain404 page not found). Not REST — probed/healthz /health /v1/sessions /grpc.health.v1.Health/Checkand connect-style paths: all 404. It exposes the crush client RPC API only.
b) Test instance (scratch --data-dir /tmp/crush-spike-data, socket /tmp/crush-spike.sock)
What it exposes / does:
- Serves the client API:
crush -H unix://... run|session ...all work through it. - Persists sessions to SQLite
crush.db+logs/crush.loginside--data-dir. - No dashboard, no REST, no health endpoint. stdout log empty even with
-d. - Socket created 0755 in world-writable /tmp (any local uid can connect).
c) Non-interactive client via -H unix://...
Yes, fully. Evidence:
crush -H unix://... --data-dir <scratch> run "Reply with exactly: SPIKE-OK"→ repliedSPIKE-OK, exit 0; real model turn (glm-5.2/zai, 11k tok) recorded.session last --json,session list/new/delete/rename/showall functional.- Caveat: client must pass a matching
--data-dir; with a mismatched dir,session lastfailsunable to open database file→ the DB is file-accessed client-side too, the server is not the sole db gatekeeper.
d) Server-side session liveness (no per-client pty)?
No. Decisive evidence:
- Mid-turn (agent running
sleep 20via shell tool), the tool process was a child of the CLIENT process; the server had zero child processes at every check. - Agent loop (
app.RunNonInteractive,sessionAgent.Runper data-dir log) executes in the client binary.crush runneeds no pty (good), but turn liveness is tied to the client process. - Killing the client kills the work; the server adopts nothing. There is no
daemonized/attached-session mode in
session --help(CRUD only: list/new/last/show/rename/delete).
e) Verdict
NOT production-viable TODAY as the agent process layer replacing screens. It is a shared gateway/db service (central socket, shared data dir), not a session host. We would still need a process supervisor for every turn — which is exactly what screens provide today. Adopting it adds risk without removing the supervision requirement.
Risks if adopted:
- Auth: none observed. 0755 socket at predictable
/tmp/crush-<uid>.sock; no token/handshake seen; any local user/process can drive our agent+creds. TCP mode would be strictly worse. - SPOF: one server crash takes out every connected client mid-turn.
- Resource/locking: single SQLite
crush.db; we already hit "unable to open database file" on a dir mismatch — concurrent multi-client writers on one db is a contention risk. - Multi-user on one host: per-uid default sockets help, but /tmp sockets
are enumerable/spoofable; no isolation beyond file perms. Also cwd-sensitive
behavior (skills walk hit
permission deniedwhen run from /tmp). - Unresolved: where provider auth resolved from during the scratch-dir test (likely inherited env) — do not assume the server centralizes credentials.
Migration sketch
Not viable → no migration. Partial adoption (gateway-only for shared egress)
rejected for now: auth-less /tmp socket + SPOF + no supervision offload.
Keep dispatch v2 (screen + crush run --session) as the process layer.
Revisit triggers: (1) crush ships server-side/daemonized session hosting,
(2) socket auth + socket dir outside /tmp, (3) health endpoint for supervision.
Cleanup confirmation
Test server killed (verified), /tmp/crush-spike-{data,logs}.sock removed
(ls /tmp/crush-spike* → No such file). Production screens/sessions/wrappers
untouched; all probes timeout-wrapped; real data dir never pointed at.