Skip to content
This repository was archived by the owner on Jul 24, 2026. It is now read-only.

launch: bake --root <net> into the ding command line (durable ST_ROOT fix) [HOLD for smalltalk#85] - #43

Merged
myobie merged 1 commit into
mainfrom
ding-root-flag
Jul 13, 2026
Merged

launch: bake --root <net> into the ding command line (durable ST_ROOT fix) [HOLD for smalltalk#85]#43
myobie merged 1 commit into
mainfrom
ding-root-flag

Conversation

@myobie

@myobie myobie commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

What

dingCommand() gains an optional network root and, when set, bakes it into the ding command line:

st ding <target> --identity <id> --root <net>

using smalltalk's new --root flag (compoundingtech/smalltalk#85). writePtyToml passes spec.networkRoot through. ST_ROOT still goes in the session env too (belt-and-suspenders).

Why — the durable half of the fleet ST_ROOT fix

A ding launched with ST_ROOT unset defaults to st's install root (~/.local/state/smalltalk), not the convoy network root — it then watches the wrong inbox. That was the root cause of the fleet phantom-poke loops and the real-delivery desync (agents effectively poll-only). Audit found 15 of 21 running dings with ST_ROOT unset.

writePtyToml already wrote ST_ROOT into the ding session env — but a pty restart replays the stored command and can drop the env for pre-fix daemons. Putting --root in the command line makes it restart-proof: the root travels with the exact command pty replays. This is convoy's half; smalltalk#85 is the flag itself.

Scope / safety

  • No-root specs are unchanged (no flag emitted; falls back to env / st default) — no regression for non-networked agents.
  • --root lands on the ding command only, never the harness (exec claude) command (asserted).
  • tsc clean, 147 tests green (adds dingCommand --root + writePtyToml networkRoot coverage).

⚠️ HOLD — do not merge yet

Merge only after smalltalk#85 (st ding --root) is in main AND the box's st binary carries it. Emitting --root against an older st would fail on an unknown flag. smalltalk is pinging me the moment #85 lands; this PR then merges alongside the fleet ding re-launch (awaiting cos's go for the 13 remaining unset-root daemons).

… fix)

dingCommand() now takes an optional network root and, when set, emits
  st ding <target> --identity <id> --root <net>
(smalltalk #85's new flag) instead of relying on ST_ROOT in the session
env alone. writePtyToml passes spec.networkRoot through.

Why: a ding launched with ST_ROOT unset defaults to st's install root
(~/.local/state/smalltalk), not the convoy network root -- it then watches
the wrong inbox, causing the fleet phantom-poke loops + non-delivery. The
env carried ST_ROOT, but a pty-restart replays the STORED command and could
drop the env for pre-fix daemons. Putting --root in the command line makes
it restart-proof: the root travels with the command pty replays. ST_ROOT
stays in env too (belt-and-suspenders).

No-root specs are unchanged (no flag; falls back to env/default). tsc clean,
147 tests green (adds dingCommand --root + writePtyToml networkRoot coverage).

HOLD: do NOT merge until smalltalk #85 (st ding --root) is in main AND the
box's st binary carries it -- emitting --root against an older st would fail
on an unknown flag. Pairs with the fleet ding re-launch (cos's go).
@myobie
myobie merged commit a4cb8b5 into main Jul 13, 2026
@myobie
myobie deleted the ding-root-flag branch July 13, 2026 04:18
myobie added a commit that referenced this pull request Jul 13, 2026
… respawn (#45)

convoy#43 fixed writePtyToml so NEW agents get --root in the ding command, but
the existing agents' on-disk pty.tomls are still pre-#43: the ding command has
no --root and the root lives only in [sessions.ding.env]. convoy up respawns via
pty restart = stored metadata (no env), so a convoy reload / cold up re-materializes
an env-only ding that drops ST_ROOT on its next restart -- the original bug returns.

regenerateDingRoot(dir) surgically rewrites ONLY the [sessions.ding] command to
carry --root <net> (via dingCommand), idempotently, leaving [sessions.claude] --
the role boot prompt + --resume uuid, which are NOT structurally recoverable from
the pty.toml -- VERBATIM. cmdReload runs it before re-materializing so the fresh
spawn + every future cold-up gets a durable ding. New --write-only flag heals the
pty.toml WITHOUT kill/respawn, so the already-durable running fleet's files heal
with zero disruption. --dry-run previews the heal.

tsc clean, 151 tests green (adds regenerateDingRoot heal/idempotent/dryRun/no-ding).

Follow-up (v2, documented): embed the AgentSpec as a [convoy.spec] table so reload
can FULLY regenerate (role/persona/resume) + auto-pick-up any future writePtyToml
fix. v1 scopes to the ding block to avoid guessing role / stripping --resume.
myobie added a commit that referenced this pull request Jul 21, 2026
…g`) (#99)

Adds a `ding` field to <net>/convoy.toml letting a network choose its ding
sidecar: "node" (smalltalk's `st ding`, the default — unset → node, so every
existing user is unchanged) or "rust" (compoundingtech/ding — full st-ding
parity, ~0% CPU). Both take IDENTICAL args, so the selector swaps ONLY the
binary prefix; --identity/--root and the whole flag surface are untouched.

- network-config.ts: DingService type + `ding` field, read/write + validation.
- launch.ts: dingBin()/dingCommand(service) — writePtyToml reads the net's
  choice and bakes the right ding binary into each agent's pty.toml. The
  pre-#43 ding-heal path stays node-only (it only ever matches `st ding` tomls;
  a rust ding is new and already carries --root, so heal skips it).
- convoy init --ding node|rust records the choice (mirrors --megarepo), also
  surfaced in the command table (completions + flag allow-list).

Coordinated with ding-rust-claude: the rust `ding` is a confirmed drop-in
(same positional session-id, same --identity/--root, zero new required config).


Claude-Session: https://claude.ai/code/session_01MCzqQKSpPiNX2ketyubByS

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant