Profile launch home
agentihooks init-agent --profile NAME renders the profile once, records the rendered home in the launch report, and starts the session on exactly that home. The launcher it writes runs agentihooks select-profile NAME --home=<home>, which checks the recorded home and mounts it without rendering again. A change to the editable package between prepare and launch, such as a pull of dev into the primary checkout, or a launcher running from another checkout than the one that prepared the launch, no longer moves the session to a different home, so the binding canary validates the home the launch recorded.
Launch sequence
- Prepare.
init-agentrenders the profile for the chosen harness, with its--overlayand--bundle-revisionchoices, into~/.agentihooks/profiles/.homes/<profile>/<key>/<harness>and setsCLAUDE_CONFIG_DIR(Claude) orCODEX_HOME(Codex) to it. It always renders here: anAGENTIHOOKS_RECORDED_PROFILE_HOMEinherited from its caller is dropped first. - Record. It writes a pending launch report (
AGENTIHOOKS_PROFILE_REPORT) holding the profile, the harness and the rendered binding of that home: home path, persona digest, source manifest digest and canary. -
Launch. The launcher script runs, after the terminal or herdr pane opens:
agentihooks select-profile NAME \ [--overlay=<overlay> ...] [--bundle-revision=<commit>] \ --home=<recorded home> --agent claude|codex -- <harness arguments>Fresh launches,
--resumeand--handoffall take this command. - Mount.
select-profilesees--homeand skips the render. It inspects the home, then exports it asCLAUDE_CONFIG_DIRorCODEX_HOMEand startsagentihooks claudeoragentihooks codex. - Validate. The session’s opening prompt asks it to run the binding canary command from its mounted instructions. That writes
validatedto the launch report, andinit-agentprintsprofile_validation=validatedandprofile_binding=<json>, whosehomeis the recorded home.
What the home check requires
select-profile --home passes the home to the same inspection the launch report used. The home is refused unless all of these hold:
| Check | Refusal |
|---|---|
| The directory exists | missing profile home: <home> |
.profile-binding.json in the home is readable JSON | missing or invalid rendered profile evidence: <error> |
Its profile, harness and resolved home match the request | profile mismatch in rendered binding |
The persona file (CLAUDE.md or AGENTS.md) still has the rendered digest | mounted persona changed since render |
<harness>.sources.json beside the home still has the rendered digest | rendered source manifest changed |
A swarm Codex launch (AGENTIHOOKS_SWARM set) is also refused when the home resolves to the operator’s own Codex home: swarm codex profile resolves to the operator Codex home.
On a refusal select-profile prints agentihooks select-profile: <reason> to stderr, exits 2, and, when AGENTIHOOKS_PROFILE_REPORT is set, marks the pending report failed with the reason profile selection failed: <reason>. init-agent then reports the launch failed rather than waiting for the route timeout.
Using select-profile directly
Without --home, select-profile renders the profile itself and mounts the current home for that profile and overlays, as before. Pass --home to pin a run to a home rendered earlier. --dry-run prints the environment and the harness command without starting it:
$ agentihooks select-profile documentation \
--home=$HOME/.agentihooks/profiles/.homes/documentation/<key>/claude \
--agent claude --dry-run -- --model opus
AGENTIHOOKS_PROFILE=documentation
AGENTIHOOKS_BASE_CHANNELS=brain,amygdala
AGENTIHOOKS_OVERLAYS=
AGENTIHOOKS_BUNDLE_REVISION=
CLAUDE_CONFIG_DIR=/home/<user>/.agentihooks/profiles/.homes/documentation/<key>/claude
argv=agentihooks claude --model opus --effort medium
The same home given with another profile name is refused:
$ agentihooks select-profile engineer --home=<documentation home> --agent claude --dry-run
agentihooks select-profile: profile mismatch in rendered binding
$ echo $?
2
--home maps to AGENTIHOOKS_RECORDED_PROFILE_HOME inside the selector. The variable is internal: neither init-agent nor select-profile reads it from the caller’s environment, so only an explicit --home skips the render.
Limits
- The Codex app-server transport (
--codex-transport app_server) launchesscripts.codex_session serve, which still renders inside its server process; it does not take the recorded home. - A home whose persona or source manifest is rewritten after the launch was recorded is refused, not re-rendered. Launch again to render a fresh home.
Troubleshooting
| Symptom | Cause and fix |
|---|---|
profile mismatch in rendered binding | The recorded home belongs to another profile or harness, or was moved. Launch again with the intended --profile and --agent. |
mounted persona changed since render or rendered source manifest changed | Files in the home changed after init-agent recorded it. Launch again to render and record a fresh home. |
missing profile home | The home was removed between prepare and launch. Launch again. |
mounted profile canary did not validate before timeout | The session started but never ran the canary command. Check the session pane; the home it mounted is in its CLAUDE_CONFIG_DIR or CODEX_HOME. |
See agentihooks init-agent and agentihooks select-profile for the full flag lists.