Expand description
Host integration asset rendering and merge behavior.
Lifeloop owns the file shape, merge safety, and status reporting for
lifecycle integration assets installed into harness host directories
(.claude/, .codex/, .hermes/, .openclaw/). The host apply
and host inspect compatibility commands route here.
§Boundary (issue #4)
This module owns:
- rendering source/applied asset content as in-memory data,
- additive-merge logic that preserves user-owned entries,
- asset status reporting (
Present/Missing/Drifted/InvalidMode/NotApplicable), - supported-mode rules for each adapter.
This module does not own:
- the hook protocol command strings themselves (those are issue #3 — the strings appear here only as opaque compatibility labels that the merge logic must recognize so it can scrub stale entries);
- the full adapter manifest registry (issue #6);
- lifecycle routing (issue #7);
- telemetry parsing (issue #5);
- filesystem IO. Callers handle reads, writes, mode bits, and atomic
replace. This module is pure: it operates on
serde_json::Value, strings, and byte slices.
§CCD compatibility
The command-prefix constants and legacy recognizer patterns
(CCD_COMPAT_*) are CCD compatibility labels — Lifeloop’s first
client wires its own binary into harness hooks via these prefixes.
They are not core Lifeloop semantics: a future non-CCD client
gets its own profile in the same shape. Keeping them in one place
makes the compat surface auditable.
§Lifecycle integration profiles (issue #26)
LifecycleProfile generalizes the CCD-shaped command-prefix /
managed-event surface into a per-client-profile struct. The free
functions exported from this module keep their CCD-compat default
behavior (they delegate to CCD_COMPAT_PROFILE); paired
*_with_profile variants accept any profile so a future non-CCD
client shape can render and merge its own lifecycle hook assets
without editing core merge logic. This is the bridge contemplated by
docs/release-gates.md for the CCD slimdown
(dusk-network/ccd#723) — the slimdown lands by switching active
installs from CCD_COMPAT_PROFILE to another profile, not by
rewriting the renderer.
Structs§
- Lifecycle
Profile - Per-client-profile data driving lifecycle integration asset rendering and merge.
- Merged
File - Outcome of merging managed entries into an existing settings/hooks
file.
existingis the prior file content (Noneif the file did not exist);renderedis the merged content the caller should write. - Rendered
Asset - One file Lifeloop renders for a host adapter.
relative_pathis relative to the repository root the caller is rendering into.modeis a Unix permission bitmask when present; callers on non-Unix targets may ignore it, but cross-checking is still meaningful for status reporting.
Enums§
- Asset
Status - Status of an installed asset relative to the rendered template.
- File
Action - Action taken for one asset during apply.
- Host
Adapter - Host adapters Lifeloop ships asset rendering and merge support for.
- Host
Asset Error - Errors returned by merge or render entry points. Callers convert as needed; the variants are pinned so downstream tests can match.
- Integration
Mode - Integration modes supported by host asset rendering.
Constants§
- CCD_
COMPAT_ CLAUDE_ COMMAND_ PREFIX - Command prefix Lifeloop renders into
.claude/settings.jsonfor CCD-managed hook entries. Equal toCCD_COMPAT_PROFILE.claude_command_prefix. - CCD_
COMPAT_ CODEX_ COMMAND_ PREFIX - Command prefix Lifeloop renders into
.codex/hooks.jsonfor CCD-managed hook entries. Equal toCCD_COMPAT_PROFILE.codex_command_prefix. - CCD_
COMPAT_ PROFILE - CCD compatibility profile: the harness invokes
${CCD_BIN:-ccd} host-hook ...and CCD acts as the broker that calls back into Lifeloop. This is Lifeloop’s first client and its current production install shape. - CLAUDE_
SOURCE_ SETTINGS - CLAUDE_
TARGET_ SETTINGS - CODEX_
SOURCE_ CONFIG - CODEX_
SOURCE_ HOOKS - CODEX_
SOURCE_ LAUNCHER - CODEX_
SOURCE_ README - CODEX_
TARGET_ CONFIG - CODEX_
TARGET_ HOOKS - CODEX_
TARGET_ LAUNCHER - HERMES_
SOURCE_ ADAPTER - HERMES_
TARGET_ ADAPTER - OPENCLAW_
SOURCE_ ADAPTER - OPENCLAW_
TARGET_ ADAPTER
Functions§
- aggregate_
status - Combine per-asset statuses into a single bundle status.
DrifteddominatesMissingdominatesPresent; an empty input isNotApplicable. - asset_
status - Compute status for one rendered asset by dispatching to the appropriate per-path comparison. Falls back to byte-equal comparison for any path that doesn’t match a merge-aware target.
- byte_
equal_ asset_ status - Status of an installed asset that uses byte-equal comparison (every asset except the merge-aware Claude settings, Codex hooks, and Codex config files).
- ccd_
compat_ claude_ command - Render a CCD-compat
.claude/settings.jsonhook command forhook_arg. - claude_
settings_ status - Status of
.claude/settings.jsonagainst the rendered template for the defaultCCD_COMPAT_PROFILE.existingis the file body (Nonemeans missing). The merge is re-run and compared byte-for-byte to detect drift. - claude_
settings_ status_ with_ profile - Status of
.claude/settings.jsonagainst the rendered template forprofile. - codex_
config_ status - Status of
.codex/config.toml. ReturnsPresentonly when the[features].hooks = trueflag is set; the rest of the file is ignored because users are free to add their own config. - codex_
hooks_ contain_ managed_ lifecycle - True when
hooks_docalready contains the full CCD-managed Codex lifecycle hook set (defaultCCD_COMPAT_PROFILE). Used by status reporting to detect “Codex hooks installed externally” vs. “needs apply”. - codex_
hooks_ contain_ managed_ lifecycle_ with_ profile - True when
hooks_docalready contains the full set ofprofile’s managed Codex lifecycle hooks. - codex_
hooks_ feature_ is_ enabled - True when the parsed TOML enables
[features].hooks. - codex_
hooks_ status - Status of
.codex/hooks.jsonagainst the rendered template for the defaultCCD_COMPAT_PROFILE. - codex_
hooks_ status_ with_ profile - Status of
.codex/hooks.jsonagainst the rendered template forprofile. - combine_
actions - Combine
currentwithnextso a multi-file apply reports the strongest action seen.UpdateddominatesInstalleddominatesAlreadyPresent. - merge_
claude_ settings - Additive merge of CCD-managed lifecycle hooks into a Claude
settings.jsonvalue, using the defaultCCD_COMPAT_PROFILE. - merge_
claude_ settings_ text - Merge an existing serialized
.claude/settings.jsonbody into the CCD-managed shape (defaultCCD_COMPAT_PROFILE). Seemerge_claude_settings_text_with_profilefor the contract. - merge_
claude_ settings_ text_ with_ profile - Merge an existing serialized
.claude/settings.jsonbody intoprofile’s managed shape. Returns: - merge_
claude_ settings_ with_ profile - Additive merge of
profile’s managed lifecycle hooks into a Claudesettings.jsonvalue. - merge_
codex_ config_ text - Merge
[features].hooks = trueinto an existing Codexconfig.toml, preserving every other key. - merge_
codex_ hooks - Additive merge of CCD-managed lifecycle hooks into a Codex
hooks.jsonvalue (defaultCCD_COMPAT_PROFILE). Seemerge_codex_hooks_with_profilefor the algorithm. - merge_
codex_ hooks_ text - Merge an existing serialized
.codex/hooks.jsonbody using the defaultCCD_COMPAT_PROFILE. Seemerge_codex_hooks_text_with_profilefor the contract. - merge_
codex_ hooks_ text_ with_ profile - Merge an existing serialized
.codex/hooks.jsonbody usingprofile. ReturnsOk(None)when the existing body is invalid JSON or has an incompatible top-level shape;_forceis reserved for symmetry withmerge_claude_settings_text_with_profileand currently behaves the same regardless of value (the previous CCD implementation never branched on it). - merge_
codex_ hooks_ with_ profile - Additive merge of
profile’s managed lifecycle hooks into a Codexhooks.jsonvalue. Seemerge_claude_settings_with_profilefor the algorithm; the only differences are the managed event table and the per-entrytimeout/statusMessagefields Codex carries. - render_
applied_ assets - Assets to apply into the host’s runtime directories (
.claude/,.codex/,.hermes/,.openclaw/) using the defaultCCD_COMPAT_PROFILE. Empty when the (host, mode) pair has no installable files (e.g. Codex manual-skill mode is scaffold-only). - render_
applied_ assets_ with_ profile - Assets to apply into the host’s runtime directories rendered with
profile’s command prefixes and managed event tables. - render_
required_ source_ assets - Subset of
render_source_assetsrequired for the given mode. Modes that pin only a few of a host’s source files (Codex manual-skill, launcher-wrapper) trim the list so absent files don’t trigger spurious “missing scaffold” errors. - render_
source_ assets - Full set of source-tree assets for a host using the default
CCD_COMPAT_PROFILE. These are the templates that land under.ccd-hosts/<host>/. - render_
source_ assets_ with_ profile - Full set of source-tree assets for a host rendered with
profile’s command prefixes and managed event tables. Seerender_applied_assets_with_profilefor the per-profile vs. per-host scope split. - supported_
modes - Modes the adapter accepts, in declaration order, for diagnostic messaging. Order is informational.
- supports_
mode - Whether
hostsupports the requested install mode. Gatesapplyso a caller can refuse before mutating files.