Skip to content

Split the tongs launcher core into one module per concern - #38

Merged
CrypticSwarm merged 4 commits into
masterfrom
tongs-core-into-modules
Aug 6, 2026
Merged

Split the tongs launcher core into one module per concern#38
CrypticSwarm merged 4 commits into
masterfrom
tongs-core-into-modules

Conversation

@CrypticSwarm

Copy link
Copy Markdown
Owner

swarmforge/tongs.py had reached 1800 lines and roughly eighty top-level functions spanning eight concerns, kept apart only by comment banners. Those banners were already a table of contents, so each becomes its own module under swarmforge/tongs/:

module what it owns
model the vocabulary of a definition, and readiness resolution
discovery reading the layer directories and merging by name
validate schema validation
secrets secret references, the provider table, FIFO delivery
mounts the mounts: magic words and their docker bind specs
mcp what each interface: contributes to the anvil
network per-session network planning
approvals config hash, privilege summary, approval keying
argv docker names, and the run argv for a tong and for the anvil
cli the validate/discover diagnostic commands

__init__.py re-exports the whole public surface, so swarmforge.anvil, bin/tongs, and the tests import exactly the names they did before — no call site churns in this PR. __main__.py keeps python3 -m swarmforge.tongs working.

This is a move, not a change

Every top-level name keeps its body byte for byte. Verified by parsing the old module and the ten new ones and comparing each definition's source segment: 112 of 112 identical, none missing, none added, none duplicated across modules. The new text is the module headers, the package docstring, and one comment on _is_int.

Four helpers follow their subject rather than their old banner: _is_int and the readiness resolvers join the schema vocabulary in model (the leaf every other module imports), _has_socket_mount joins the mount words it reads, and _is_network_facing joins the interface kinds it dispatches on — which is what keeps argv from importing network for a one-line predicate. The import graph is acyclic with model at the leaf.

Also checked: the CLI prints byte-identical stdout, stderr, and exit codes for validate, discover, and its usage error; importing the package has no observable effect beyond defining names; no dependency was added, and the modules import nothing outside the standard library and swarmforge.yamlite.

The one thing the split broke, and the fix

Splitting a module means from .secrets import SECRET_FIFO_TARGET copies the binding, so a constant that had one home now has several. tests/test_tongs.py redirects that path at a file it knows is missing and asserts the secret wrapper aborts rather than exec'ing the tong's real entrypoint with no secret environment. Redirecting the re-exported copy left the real /run/swarmforge/secret-env baked into the script, so the test kept passing for the wrong reason — and would have hung had that path existed as a FIFO with no writer.

The redirect now lands on swarmforge.tongs.secrets. With the path made readable the wrapper execs the target again, which is what makes the failure case worth asserting. The package docstring records the rule so the next test does not repeat it.

Rounding it out: pyproject.toml lists subpackages explicitly and would have silently omitted the new one.

Testing

python3 -m unittest discover -s tests -p 'test_*.py' — 495 tests, OK, unchanged from before the split. The passthrough tests (tests/test_run_anvil.py, which spawn the real launcher and assert byte-identical forwarding when no tongs are discovered) and the launch-path tests (tests/test_run_agent_container.py, which drive the real make recipes with docker stubbed) are green and untouched.

`swarmforge/tongs.py` had reached 1800 lines and eight concerns kept apart
only by comment banners. Those banners were already a table of contents, so
each becomes a module under `swarmforge/tongs/`: `model`, `discovery`,
`validate`, `secrets`, `mounts`, `mcp`, `network`, `approvals`, `argv`, and
the diagnostic `cli`.

Nothing crosses a seam it did not already sit behind. Every top-level name
keeps its body byte for byte; the new text is the module headers, the package
docstring, and one comment on `_is_int`.

Four helpers follow their subject rather than their old banner. `_is_int` and
the readiness resolvers join the schema vocabulary in `model`, the leaf module
every other one imports. `_has_socket_mount` joins the mount words it reads.
`_is_network_facing` joins the interface kinds it dispatches on, which is what
keeps `argv` from importing `network` for a one-line predicate. The
environment-variable naming folds into `mcp`, beside the interface wiring that
is its only caller.

`__init__.py` re-exports the whole public surface, so `swarmforge.anvil`,
`bin/tongs`, and the tests import exactly the names they did before, and
`__main__.py` keeps `python3 -m swarmforge.tongs` working. The CLI prints
byte-identical output for `validate`, `discover`, and its usage error.
Splitting the core into modules gave `SECRET_FIFO_TARGET` two bindings: the
one `secret_inject_argv` reads, and the copy the package re-exports. This
test redirects that path to a file it knows is missing and asserts the
wrapper aborts instead of exec'ing the tong's real entrypoint with no secret
environment. Redirecting the re-export left the real `/run/swarmforge/
secret-env` baked into the script, so the test passed only because that path
happens not to exist on a test host -- and would have hung had it existed as
a FIFO with no writer.

Point the redirect at `swarmforge.tongs.secrets` instead. With the path made
readable the wrapper now execs the target again, which is what makes the
failure case worth asserting.
The explicit package list is what makes imports resolve for editors, type
checkers and linters; a subpackage missing from it is invisible to them.
The test asserted only that the wrapper exited non-zero with no output.
Both hold when the redirect never reaches the script and the wrapper
reads the real `/run/swarmforge/secret-env`, which is absent on a test
host -- the exact failure mode redirecting the package re-export
produces, and the one the previous commit fixed. So the test could not
detect a reintroduction of the bug it exists to prevent.

Assert the temp path actually appears in the generated script. Reverting
the redirect to `tongs.SECRET_FIFO_TARGET` now fails the test instead of
passing it, which is what pins the fail-closed guarantee that a tong
never execs its target without its secret environment.
@CrypticSwarm
CrypticSwarm merged commit 82bd7a5 into master Aug 6, 2026
3 checks passed
@CrypticSwarm
CrypticSwarm deleted the tongs-core-into-modules branch August 6, 2026 03:09
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