Skip to content

Install agents and assets from the container driver - #53

Open
CrypticSwarm wants to merge 3 commits into
harness-container-initfrom
harness-container-assets
Open

Install agents and assets from the container driver#53
CrypticSwarm wants to merge 3 commits into
harness-container-initfrom
harness-container-assets

Conversation

@CrypticSwarm

Copy link
Copy Markdown
Owner

Agent translation and the skills/commands installs were the entrypoint's remaining big case blocks. The container driver now owns both: the translator runs with the harness's emitter into its declared agents destination, then finalize_agents — codex registers the emitted agents in ~/.codex/config.toml — and asset layers install in the canonical order (dotagents user, org, shared, workspace) with per-entry replacement, through an install_assets hook. The default hook copies skills then commands; codex's override translates commands to skills before the skills copy, per layer, as the shell did. Grok's waived agents destination skips translation exactly as before.

The replaced shell is deleted with its text assertions ported to behavior tests in the same commits. Output trees — paths, modes, symlink targets, content — are byte-identical to the pre-change shell across full, sparse, empty, and collision layer stagings for all four harnesses.

The driver now runs unified agent translation right after the config
phase, dispatching through the registered spec: the destination comes
from the spec's agents_dest ({home}/{config} placeholders resolved
against the run), the four asset sources are the same for every
harness, and grok's Waiver skips the phase on record instead of
falling through a case arm. Codex's finalize hook gains the home the
driver hands it and merges the emitted registrations into the
published ~/.codex/config.toml, replacing the separate registration
step; a bare CLI run of the translator still has no home and leaves
the published config alone.

The replaced entrypoint shell (prepare_unified_agents,
register_codex_agents, CODEX_CONFIG_FILE) is deleted, and the text
assertions over it become behavior tests: tests/test_harness_agents.py
stages source trees and reads what landed -- per-harness destinations,
source precedence, the opencode fallback destination, the grok
waiver, both degrade-to-warning paths, and the registration meeting
the published config that publish_config wrote.
The driver's third root phase installs skills and commands into each
harness's native locations, one install_assets hook call per source
layer -- dotagents user, org, shared assets, then the workspace
overlay -- with the destinations resolved from the spec's
skills_dest/commands_dest. The default hook copies with per-entry
replacement (top-level dot entries skipped, symlinks recreated,
wholesale replacement of whatever stands at the destination name);
codex overrides it to translate the layer's portable commands into
skill packages before the skills copy, so a layer's own skill package
outranks its same-named command while later layers still replace
earlier ones. A failed codex translation degrades to a warning; a
failed copy stops the container.

The replaced entrypoint shell (copy_dir_entries,
translate_codex_commands, copy_shared_assets) is deleted, and the
text assertions over it become behavior tests:
tests/test_harness_assets.py stages layer trees and reads what landed
-- layer precedence, wholesale replacement, entry selection, absent
layers, per-harness destinations, the codex translate-then-copy
ordering, and recorded whole-tree installs for claude and codex.
The phase-order tests mock every driver phase they are not asserting,
so they no longer run the real asset install against claude's pinned
live config destination from inside the suite. New tests pin the
guarantees the code already made without a witness: a failed copy
propagates out of the phase (and is not taken for a translation
failure on the codex path), a destination symlink to a live directory
is severed rather than followed, and a registration the published
codex config already carries outranks the generated one.

The merge_toml import moves inside the registration's try, so a
python without tomllib fails the registration with its own warning
instead of the translation's. Docstrings that named the entrypoint as
the actor -- the command-translation shim, the Context and
HarnessSpec contracts -- now name the driver.
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