Kai Ase Siren
Skip to content

agent-compose features

Inventory of what ships today.

The roster is mounted, not embedded

The binary carries no roster. It resolves one from AGENT_COMPOSE_ROSTER, then ~/.agent-compose/roster, then the seed a package manager installed beside it, and names every path it tried when none resolves. brew and scoop install that seed, so a roster change needs no rebuild and an upgrade never overwrites an edited roster in the state directory (#336). The release also ships the composed bundle set, addressed <role>-<tier>-<delivery>, because housecast composes at build time and never runs on a user's machine (#412). A root marked as an overlay adds to the roster under it, and a role can derives: a parent, declaring only its deltas.

Composition moved to housecast

The roster language, the composition engine, and the eval board runner live in coilyco-flight-deck/housecast as of #337. This repository consumes housecast from Forgejo through [tool.uv.sources], pinned by tag, and keeps checks/ to prove the Go engine still composes identical bundles until #339 deletes it.

Where composition lives is a public boundary, which is why it is recorded here rather than only in the issue.

Composition engine

  • agent-compose compose turns a KDL request into an immutable bundle.
  • roster:core describes 13 seats and 11 personalities, three archived on 2026-09-15: refused by the resolver, keeping their charter, art and edges. Each seat melds two traits, and every boundary reaches all ten, exactly one as owner. Role briefings own each charter.
  • External person packages and local personality libraries replace the default. Their manifests and fragments are authored as YAML or KDL, and a package may hold both while it converts (#335).
  • personality-library "roster:core" lets an external package bind the embedded core personalities by slug instead of vendoring their bodies. Roles, seats, and identity stay package-exclusive.
  • .agents/roles.kdl owns skill-provider repos, skills, and repository policy.
  • Three model tiers declare Core role deployment compatibility without changing selected context.
  • Materialization promotes admitted COMPOSED.md to native SKILL.md.
  • Resolver traces provider and content outcomes with budgets.
  • boundary-omit drops a defer-side boundary whose owning seat the deployment does not have, and refuses a scoped grant. See boundary omission.
  • Atomic materialization verifies staged and reused bundles.
  • Canonical skills use identity cards and compiled fallback. Role bodies cap at 1200 words, role boundaries at 200 words per side.
  • Role adjacency names each role's two likeliest absorptions.
  • Attribute acts give every role, personality, and boundary side three named things to run. The identity card renders them, and a boundary's acts follow the side the seat holds rather than the owner's.

Load-point projection

  • agent-compose project places verified bundles at repo or container-home load points from a layout table AGENT_COMPOSE_LAYOUTS replaces.
  • Sidecar ownership protects foreign files and restores prior owned state.

Launch-time refresh

  • Launch adds color, an Enter gate, and a Codex intro.
  • A Claude launch passes identity flags, not files, guards bare kubectl and helm by role, and exports seat-labelled token metrics. Every native harness narrows MCP servers to the role. A failed startup step degrades a launch if it shapes behavior and refuses it if it bounds reach.
  • Refresh uses validated fallback unless external-only forbids it.
  • launch starts a second seat from inside a session, one hop deep and never over the caller's own load points.

Inspection

  • config validate strictly checks staged host configuration without writes.
  • agent-compose describe renders a collapsible decision tree. --why follows one item from consideration to outcome.
  • agent-compose diff reports semantic changes. verify checks entry points, delivery, traces, and selected identities.
  • Catalogues and export provide inspection, reproducible archives, and logical content diff.
  • compose renders the role metadata and the identity texture. --explain adds the briefing, the credits, the expressions, and the decisions.
  • Evaluation derives the board from the roster, runs it with evalkit, and grades it by hand with housecast grade. No mechanical scorer anywhere in the loop.
  • V2 migration maps v1 roles without aliases.
  • TTY colors use canonical identity and pass an OKLab legibility gate. Redirects and NO_COLOR stay plain.

Identity surfaces

  • Identity primitives give every personality a species, a color_word, an emblem name list, a motif, a geometry, and a prose body. A seat's creature is derived from its meld rather than authored, so two seats sharing a personality share an animal.
  • Identity renderers cover the palette, overlays, the acompose statusline row, --subagent rows, and the short id. whoami prints it. The overlay carries a separation-solved window background beside the accent, so a renderer no longer tints its own.
  • native-ui emits per-role Claude Code themes.

Roster artifact and cascade

  • agent-compose roster --out <dir> renders lazy-loaded role and personality skills plus native adaptation.
  • Bare convergence emits deterministic person.json.
  • cascade emits harness doctrine and the role/residency repository-plan.yaml with sealed provenance.
  • bundle materialize returns a verified role/harness bundle with provenance.
  • Bare acompose converges hosts. --reapply forces the layout, --verbose traces source => destination, -- <command> refreshes then execs, and Ward smoke proves idempotence.
  • appendix composes inline or file tail blocks, optionally scoped to named roles.
  • source_delivery emits a source as an @path import rather than inlining it, so a source the repository cascade also delivers is loaded once; a missing target fails convergence rather than shipping a pointer to nothing.
  • Local skill catalogues consume AOS roots, each addressed by a forge-qualified source that travels with the root, so a bare owner/repo real on two forges fails rather than picking one, and one name meaning two different skills stops the converge naming both. An entry marked private keeps its content and loses its identity, so a private focus reaches a public lane without the image learning it exists. An org grant admits a whole owner from the compiled set, open to repositories added later and bounded only by its selectors, and skill_requests reaches one skill by address, failing the converge by name when it resolves to nothing.
  • Release publishes unreleased deltas under a hold, with roll-forward recovery.
  • A bundle carries a voice profile merging a skill's rules with the seat's avoid banks, so a Refuse reaches a checker.

See also