Drive the container config phase from Python - #52
Open
CrypticSwarm wants to merge 2 commits into
Open
Conversation
A Context record carries what one config run knows (home, destination, the three layer sources, the tong MCP fragment), and three spec hooks slot into the phase around the tong-MCP merge: build_config before it, finalize_config after it, publish_config last. Defaults are no-ops. - Codex fills build_config (rebuild config.toml key-wise from the layers) and publish_config (truncate-and-copy into its persistent home) because its config is excluded from the whole-file overlay. - Claude fills finalize_config: the settings file its exec is handed is derived from the image defaults plus the layers on every run. - The split exists because codex's build must precede the MCP merge while claude's settings build must follow it.
swarmforge.harness.init now owns the config phase the entrypoint ran as
shell: the repo -> user -> org layer merge (tar overlay with the same
exclude flags, same-inode skip via st_dev/st_ino), the key-wise merges
of each spec's keyed files, the tong-MCP merge dispatched by the spec's
mcp_merge value, and the build/finalize/publish config hooks around it.
The entrypoint invokes it as
`python3 -P -m swarmforge.harness.init "${AGENT_BIN}" "${ANVIL_HOME}"`
and keeps only the root-shell work: users, assets, agents, state links,
chown, exec.
The guarantees the deleted shell functions carried move from text
assertions over entrypoint.sh to behavior tests that run the driver over
staged layer trees: precedence, keyed merges, per-harness excludes, the
same-directory layer skip, reset semantics, empty layer variables, MCP
merge shapes, codex's rebuild-and-publish, claude's settings stack, hook
ordering, and the spec-to-entrypoint path agreements.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The entrypoint's config phase — layer merges, keyed files, harness-specific config builds, and the tong MCP merge — was a couple hundred lines of shell branching on
AGENT_BIN. It now runs aspython3 -P -m swarmforge.harness.init, driven by the harness specs: repo→user→org merge order with the same tar invocations, the same-inode skip for bind-mounted layers, per-harness excludes and keyed merges, then abuild_confighook, the MCP merge selected by the spec, afinalize_confighook, and apublish_confighook. Codex's off-home config rebuild and copy-back become itsbuild_config/publish_config; claude's settings build becomes itsfinalize_config— the split exists because codex must run before the MCP merge and claude after it.The replaced shell functions are deleted, and every text assertion over them is replaced by a behavior test in the same commit: tmpdir layer stagings covering precedence, conflicting keys, excludes, keyed merges, and the bind-mount-same-dir skip, parameterized per harness. The driver's output trees are byte-identical to the shell's across all four harnesses and the reset, tong, no-dest, and aliased-layer variants.