No way to compose a role without its boundaries, and a deployment that owns its own live surface needs one #304
Labels
No labels
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
coherence-core
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
qa-fixture
role/ai
role/creator
role/design
role/director
role/engineer
role/exec
role/human
role/ops
role/qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-flight-deck/agent-compose#304
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found while staging the
sirens-dowellane for the 2026-08-19 Temporal session. Read-only investigation of this repository, nothing changed here.What is true today
A role's boundaries come from two places and neither is overridable at compose time:
role.kdl's ownboundarynode, read intorole.Boundaries.RoleActiveBoundaries(internal/person/person.go:1217).ParseRequest(internal/schema/schema.go:225) accepts exactly nine keys:person-policy,person-source,role,delivery,model-tier,personality-library,source,identity, and the legacydensitywhich is rejected outright. None of them touches boundaries.So the only ways to get a boundary-free bundle are to edit the role's
role.kdlin the roster, which changes that role everywhere, or to add a near-duplicate role that exists only to omit a boundary.Why that is a real gap
boundary-modify-live-systemencodes "DevOps changes running systems, other roles observe and hand the action over." That is correct whenever a DevOps seat exists.It is wrong for a deployment that is the operator of its own surface. The concrete case: a lane whose entire granted tool surface is a small guarded MCP over its own content, with no operator standing behind it. There, the boundary instructs the agent to hand off the only work it was deployed to do, to nobody. The deferral protects nothing and costs the whole function.
This is not "remove safety." The boundary is a statement about which seat owns an action, and a deployment where that seat does not exist needs to say so at compose time rather than by forking the role.
Shape worth considering
A request-level node, so the roster stays the single description of the role and the deployment states its own situation:
Constraints worth building in rather than bolting on later:
What was done instead, for the immediate need
The lane names the precedence in its own local skill root, which lands after
<composed-identity>in the sirens-echo prompt and is the patterncomposedVoicePolicyalready sets for voice. That works and it shipped, but it leaves the boundary prose in the bundle and relies on a later instruction to override it, which is strictly weaker than not composing it.Recorded in coilyco-gaming/sirens-echo#956.
Not built here because the change reaches this repository, sirens-echo's bake, an image publish, and a rollout, roughly 19 hours before a live recording. The knob is the right fix on any other day.
Adding to this rather than opening a second issue. I filed #309 before finding this one and am closing it as a duplicate; the part of it worth keeping is below.
The ask got broader tonight
Kai, on the Dowel lane: "dowel really shouldn't be loading any boundaries. at all." Not
modify-live-systemspecifically. The whole set.That is consistent with what this issue found and slightly larger than the knob it proposes. Dowel runs
engineer, which defers two:Both name an absent seat.
seek-external-validationhands toexec, and there is noexecon that lane either, so the second one is dead for the same reason as the first. Aboundary-omitlist answers it, but it answers it by making the deployment restate per boundary something it already knows once.An alternative shape: derive it from who is present
docs/ownership.mdis explicit that this is a relationship:validateBoundaryOwnersenforces both halves of that at load. So the defer side is routing - "hand this toops". A deployment with noopsseat is not a deployment that wants an exception; it is one where the relationship has a single participant and the rule has nothing to say.So instead of listing omissions, the request could state the roster and let composition evaluate the
ownerlink it currently assumes:A defer-side boundary whose owner is not in
roster-seatsdoes not compose. Owned boundaries are untouched, which preserves the constraint this issue already flags - an owner losing its own boundary stays impossible rather than merely discouraged, because nothing in the mechanism can produce it.It also degrades correctly at sizes neither of us has a case for yet: a two-seat deployment with
engineerandopskeepsmodify-live-systemand dropsseek-external-validation, with no per-deployment list to maintain.The honest trade is that
boundary-omitis more auditable. It says what was dropped, in one place, in the request.roster-seatssays what exists and leaves the drop to be computed, which is exactly the kind of thing that is harder to review. This issue's requirement that the omission appear in the rendered identity card and the compose review artifact matters more under my shape than under yours, not less.Two supporting facts
role-creatorships with no declaredboundarynode. So neither shape needs a new capability in the role model; both are compose-time questions about an existing one.roster:coreeager, so boundary bodies are now at full weight in every prompt rather than named on the card and fetched on demand. That sharpens this rather than causing it - the prose was always composed - but it is worth knowing when weighing the work.Still not before the recording
Agreed with this issue's closing note, and the window is shorter now. Filed for after.