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

convoy: per-network ding-service selector (node st ding | rust ding) - #99

Merged
myobie merged 1 commit into
mainfrom
ding-service-choice
Jul 21, 2026
Merged

convoy: per-network ding-service selector (node st ding | rust ding)#99
myobie merged 1 commit into
mainfrom
ding-service-choice

Conversation

@myobie

@myobie myobie commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

What

Adds a per-network ding-service selector so a convoy network chooses which ding sidecar runs — node (smalltalk's st ding, the default) or rust (compoundingtech/ding: full st ding parity, ~0% CPU).

Unset → node, so every existing user is unchanged. Our network (Mac + hetz) sets ding = "rust".

How

The rust ding is a confirmed drop-in (coordinated with ding-rust-claude): same positional <session-id>, same --identity/--root, zero new required config. So the selector swaps only the binary prefix (st dingding); the args are byte-identical.

  • network-config.tsDingService type + ding field on NetworkConfig, read/write + validation (a garbage value falls back to the node default).
  • launch.tsdingBin() / dingCommand(service); writePtyToml reads the network's choice from <net>/convoy.toml and bakes the right ding binary into each agent's pty.toml. The pre-launch: bake --root <net> into the ding command line (durable ST_ROOT fix) [HOLD for smalltalk#85] #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); surfaced in the command table (completions + flag allow-list).

Verification

  • typecheck clean; 531 tests pass (+3 new: network-config round-trip/validation, dingCommand service param, writePtyToml convoy.toml → baked-binary).
  • Against the live rust ding on hetz: usage: ding <pty-session> [--identity ID] [--root PATH] — accepts the exact generated invocation (--root even aliases --st-root, --identity defaults to $ST_AGENT). Confirmed drop-in.
  • convoy init --ding bananainvalid --ding "banana" (want: node | rust); convoy --help shows the flag.

Follow-ups (not in this PR)

  • Setting ding = "rust" on our existing net's convoy.toml (ops).
  • Health upgrade: the rust ding exposes a health-file / ding <session> --health-check signal that catches wedged dings (live pid, stuck loop) that kill -0 can't see — a future upgrade to dingHealthPlan, to pair with ding-rust-claude.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MCzqQKSpPiNX2ketyubByS

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).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MCzqQKSpPiNX2ketyubByS
@myobie
myobie merged commit ae77ec8 into main Jul 21, 2026
1 check passed
@myobie
myobie deleted the ding-service-choice branch July 21, 2026 11:09
myobie added a commit that referenced this pull request Jul 21, 2026
…ml (#104)

Adds an `env` field to <net>/convoy.toml: a string->string map merged into EVERY
agent's derived pty.toml session env at render — BOTH the harness and the ding
session — UNDER the derived wiring (ST_AGENT/ST_ROOT/PTY_ROOT always win, so a
network key can't repoint the agent at another bus). A per-agent `env` still
overrides a network default. Unset -> no network env.

This is the fleet-wide runtime-knob seam: e.g. PTY_REAP_ON_EXIT=false to preserve
finished sessions network-wide (the pty daemon reads it from its OWN env, so it
must go on both sessions). Pairs with the ding selector (#99) so ONE re-render
bakes both ding=rust and PTY_REAP_ON_EXIT=false.

- network-config.ts: env field + isEnvMap validation (a non-string-map is dropped
  whole, never a half-valid launch env), read + write.
- launch.ts: precedence networkEnv < spec.env < derived wiring, on both sessions.
- +2 tests: round-trip/validation; both-sessions + derived-wins + per-agent-override.


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