Skip to content

Add the pure launch toolkit for sidecar tongs#11

Merged
CrypticSwarm merged 4 commits into
masterfrom
tongs-phase-7a-pure-toolkit
Jun 18, 2026
Merged

Add the pure launch toolkit for sidecar tongs#11
CrypticSwarm merged 4 commits into
masterfrom
tongs-phase-7a-pure-toolkit

Conversation

@CrypticSwarm

Copy link
Copy Markdown
Owner

Summary

Adds the pure, side-effect-free helpers the launcher will use to start
sidecar containers ("tongs") and to let an anvil reach them. Everything here
returns plain values or argv lists and runs no docker, so the exact behavior
is unit-tested in isolation; the side-effectful execution lands in a later
change. Nothing here is called from a launch path yet, so this is inert for
existing repos: with no tong definitions discovered, the anvil still launches
exactly as it does today.

What's included

  • Readiness resolution. parse_duration turns 30s/500ms/2m (or
    bare-number seconds) into float seconds and rejects a typo or a non-positive
    deadline up front; readiness_settings resolves a tong's readiness: block
    to a (mode, command, timeout) triple, defaulting to a TCP probe for the
    network-facing kinds.

  • Docker argv builders. tong_run_argv assembles the docker run -d
    command for one tong: a detached container under a chosen name, joined to a
    network under a --network-alias (only for network-facing tongs), stamped
    with name and config-hash labels, with env as sorted -e, secret tmpfs
    mounts, opt-in workspace/docker-socket mounts, and resource flags before
    the image. inject_anvil_argv rewrites the anvil's own docker-run argv to
    join the tong network and carry injected options without mutating the input,
    and returns it unchanged when there is nothing to inject -- so a zero-tong
    launch stays byte-identical to the direct docker run.

  • Naming and collision helpers. A stable, session-independent name for a
    shared tong and a unique per-session name for a session tong (both
    collision-safe for degenerate inputs); alias_collisions flags any canonical
    DNS alias claimed by more than one tong.

  • Up-front validation. validate_tong now also checks the readiness,
    mount, network, and resource fields these helpers consume, so a malformed
    definition fails validation with a clear message instead of raising during a
    launch.

All helpers are covered by unit tests run the same way as the existing
scripts/test_*.py suites.

A tong's readiness: block says how the launcher decides the sidecar is up
before gating the anvil on it. Add parse_duration and readiness_settings
so that declaration resolves to plain values -- a (mode, command,
timeout_s) triple -- that the live launcher can probe against later. tcp
is the implicit default for the network-facing kinds (mcp/port); a
portless kind (volume/none) falls back to none, since there is no port to
dial. parse_duration accepts 30s/500ms/2m/1h and bare-number seconds, and
raises on a typo so a bad readiness timeout stops the launch rather than
silently falling back to a default.

Validate the readiness fields the launcher will consume up front: reject a
tcp probe on a portless kind (it could never become ready), and reject a
malformed readiness.timeout or readiness.command so the error is a clean
validation message rather than an uncaught exception mid-launch.

Pure helpers with no live call site; the empty-discovery launch path is
unchanged.
Turn a validated tong definition into the concrete `docker run -d` argv
that starts its container, and rewrite the anvil's own docker-run argv so
it can reach the discovered tongs. The builders are pure -- they return
argv lists and run no docker -- so the exact flags are unit-tested while
the side-effectful execution stays in the launcher.

tong_run_argv detaches the container under a caller-chosen name, joins it
to a network under a `--network-alias` (only for the network-facing kinds;
volume/none tongs need no DNS name), stamps the tong-name and config-hash
labels a later launch reads to detect a stale shared container, passes env
as sorted `-e`, mounts secret tmpfs dirs, and appends mounts and resources
before the image. mounts: are opt-in magic words -- `workspace` and
`docker-socket`, never a raw host path -- resolved to `-v` specs;
resources.memory maps to `--memory`. shared/session container-name helpers
give shared tongs a stable session-independent name and session tongs a
per-session name carrying the session handle.

inject_anvil_argv splices the network, pre-image `-e`/`-v` options, and
post-image harness flags into the anvil argv without mutating it; with no
arguments it returns the argv unchanged, so a zero-tong launch stays
byte-identical to the direct docker run. The `--network` lookup and rewrite
scan only the docker options before the image, so a same-named harness
argument after the image is never read or rewritten.

Validate the mount words, network entries, and resources block up front so
a malformed entry fails validation rather than raising mid-launch. Pure
helpers with no live call site.
Two tongs on one network cannot share a DNS alias without nondeterministic
resolution. alias_collisions groups the network-facing tongs by their
canonical alias and returns the aliases more than one tong resolves to, so
the live launcher can refuse such a set and the planning functions can keep
the first and warn. Only mcp/port tongs register a `--network-alias`, so
volume/none tongs are skipped -- they never claim a DNS name and so cannot
collide, matching how the network plan and the run argv assign aliases. The
canonical alias is interface.name for an mcp tong and the tong name
otherwise, so an mcp name can collide with another network-facing tong's
name -- the check covers that case too.

Pure helper with no live call site.
Two edge cases in the launch toolkit would have slipped a bad value
through to the launcher instead of failing early:

A bare negative or zero readiness.timeout bypassed the (sign-less)
duration regex via parse_duration's numeric path and resolved to a
non-positive deadline -- one that gives the readiness probe no time to
succeed, so the tong would never report ready and the launch would fail
for a reason far from the typo. Reject a non-positive duration with a clear
error, matching how the string forms are already refused.

A tong name that sanitizes to empty made session_container_name emit a
trailing-dash "<session>-tong-" name; two such tongs would collide on one
container name. Fall back to "<session>-tong" the way shared_container_name
already drops to its bare prefix.
@CrypticSwarm CrypticSwarm merged commit 40e55cc into master Jun 18, 2026
1 check passed
@CrypticSwarm CrypticSwarm deleted the tongs-phase-7a-pure-toolkit branch June 18, 2026 01:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant