feat(request): let a deployment omit a boundary it has no seat for #310
No reviewers
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!310
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/boundary-omit"
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?
Closes #304, and implements the knob that issue specified.
Why
docs/ownership.mdis explicit that a boundary is a relationship: "Every boundary names the role holding the other side with a requiredowner. The owner is a relationship, not authority." The defer side is therefore routing - hand this toops.A deployment where
opsis not a seat has nowhere to route. The rule reads as a stop rather than a handoff, and the agent defers work nobody will pick up. A single-agent deployment hits this on every boundary its role defers:engineerdefers two, toopsand toexec, and gets neither.The reporting case is the
sirens-dowellane, the only agent in its guild. It currently ships a local skill saying the composed boundary "does not reach these verbs" and "this file wins", which is a workaround in prose for something that should not have composed.The knob
The boundary leaves the composed set completely: no body in the bundle, no name on the identity card, no manifest entry. That completeness is the point. Naming a boundary whose body is absent is worse than either state, because the card then describes doctrine the agent cannot read, which is the failure sirens-echo#859 was about.
Three refusals, all from #304's own list:
validateBoundaryOwnersalready refuses to let one role sit on both sides; this keeps it from being reachable the other way round.The decision trace records each omission as an excluded profile decision, per #304's requirement that the review surface keep telling the truth.
Two paths, not one
Worth flagging for review, because I got it wrong first. The boundary body reaches a bundle through two routes:
Resolve, which buildsres.Skills.person.Sourceattaches each role's active boundaries tosrc.RoleSkills[role], and a catch-all loop admits anything an admitted source offers.Filtering only the first left the manifest, card, and trace all correct while the bundle still shipped both
SKILL.mdfiles - the worst possible outcome, since every review surface would have said they were gone.TestBoundaryOmitLeavesNoTraceInTheBundlecaught it, and that failure is why the test globs the tree rather than trusting the manifest.What is not in scope
I considered deriving the omission from a declared seat set (
roster-seats "engineer") rather than listing boundaries, and wrote it up on #304. It generalises better and needs no per-deployment list. I built the explicit form instead: this issue specified it, it is more auditable at review time, and it is the smaller change. The derived form can sit on top later without changing this grammar.Also unchanged:
roster.gostill renders every role's full boundary set into the roster projection, because that describes the roster rather than one deployment.Verification
go test ./...,go vet ./..., andpre-commit run --all-filesall green.End to end through the CLI, on the new
boundary-omit.kdlcontract fixture:RenderRoleIdentityCardgains the composed boundary list as a parameter rather than deriving it from the role, so the bundle card and the roster card can differ truthfully. Two callers and one test updated.