Bake a bundle for every roster role, and make roles.kdl purely additive #149

Closed
opened 2026-08-12 11:20:39 +00:00 by coilyco-ops · 0 comments
Member

Carved out of #98. Kai's decision, 2026-08-12:

the behavior for roles should be that the kdl file is purely additive - if a role exists in acompose at all then sirens deep can use it

Current behavior

scripts/stage-compose-sources.sh enumerates roles by grepping agent/compose/roles.kdl:

roles=$(grep -oE '^[[:space:]]*role[[:space:]]+"[^"]+"' "$compose_dir/roles.kdl" | ...)

That file declares one role, creator. So the image bakes exactly one bundle, and resolveBundlePath requires manifest.json under the role slug. SIRENS_DEEP_ROLE=director, the worked example in #98, fails startup:

no composed bundle for role "director" under /app/agent/bundles

The outcome #98 asks for is a role "flippable between roles by changing one string in the deploy repository", and its design section says the build "bakes all eight". Today there is nothing to flip to.

The file is also self-contradictory about this. Its own comment already states the intended behavior:

A role with no entry composes the roster identity alone, which is a valid, deliberately bare agent.

That is only true if a role with no entry is still baked, which is not what the loop does.

Intended behavior

roles.kdl adds composed skills to roles. It does not decide which roles exist.

The roster is the authority. agent-compose roster writes person.json, whose role_order currently carries eight: engineer, director, qa, ops, design, strats, creator, ai. Every one of those gets a bundle. A role named in roles.kdl additionally gets its allowlisted skills. A role absent from roles.kdl composes the roster identity alone, exactly as that comment already promises.

A role added to agent-compose later is then available to Sirens Deep on the next image build with no change to this repository.

Notes

  • The allowlist keeps doing its real job, which is bounding which skills a role may pull. The denied set and the private-repository check in composepolicy.go are unaffected, and #98's requirement that widening the surface is a reviewed act still holds.
  • Baking eight bundles instead of one costs build time in the compose stage. Each is a small tree of markdown, and the stage already clones the catalogue once for all of them.
  • defaultComposedRole stays creator, so a deployment that sets nothing is unchanged.

Complete when

  • The build bakes one verified bundle per roster role, not per roles.kdl entry.
  • SIRENS_DEEP_ROLE=director starts and renders the director identity, with no rebuild and no change to roles.kdl.
  • A role with no roles.kdl entry still produces a valid bundle carrying the roster identity.
  • roles.kdl says what it now does, and the compose page agrees.
Carved out of #98. Kai's decision, 2026-08-12: > the behavior for roles should be that the kdl file is purely additive - if a role exists in acompose at all then sirens deep can use it ## Current behavior `scripts/stage-compose-sources.sh` enumerates roles by grepping `agent/compose/roles.kdl`: ```sh roles=$(grep -oE '^[[:space:]]*role[[:space:]]+"[^"]+"' "$compose_dir/roles.kdl" | ...) ``` That file declares one role, `creator`. So the image bakes exactly one bundle, and `resolveBundlePath` requires `manifest.json` under the role slug. `SIRENS_DEEP_ROLE=director`, the worked example in #98, fails startup: ``` no composed bundle for role "director" under /app/agent/bundles ``` The outcome #98 asks for is a role "flippable between roles by changing one string in the deploy repository", and its design section says the build "bakes all eight". Today there is nothing to flip to. The file is also self-contradictory about this. Its own comment already states the intended behavior: > A role with no entry composes the roster identity alone, which is a valid, deliberately bare agent. That is only true if a role with no entry is still baked, which is not what the loop does. ## Intended behavior `roles.kdl` adds composed skills to roles. It does not decide which roles exist. The roster is the authority. `agent-compose roster` writes `person.json`, whose `role_order` currently carries eight: `engineer`, `director`, `qa`, `ops`, `design`, `strats`, `creator`, `ai`. Every one of those gets a bundle. A role named in `roles.kdl` additionally gets its allowlisted skills. A role absent from `roles.kdl` composes the roster identity alone, exactly as that comment already promises. A role added to agent-compose later is then available to Sirens Deep on the next image build with no change to this repository. ## Notes * The allowlist keeps doing its real job, which is bounding *which skills* a role may pull. The denied set and the private-repository check in `composepolicy.go` are unaffected, and #98's requirement that widening the surface is a reviewed act still holds. * Baking eight bundles instead of one costs build time in the compose stage. Each is a small tree of markdown, and the stage already clones the catalogue once for all of them. * `defaultComposedRole` stays `creator`, so a deployment that sets nothing is unchanged. ## Complete when * The build bakes one verified bundle per roster role, not per `roles.kdl` entry. * `SIRENS_DEEP_ROLE=director` starts and renders the director identity, with no rebuild and no change to `roles.kdl`. * A role with no `roles.kdl` entry still produces a valid bundle carrying the roster identity. * `roles.kdl` says what it now does, and the compose page agrees.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-gaming/sirens-echo#149
No description provided.