A role cannot narrow the skills it receives from a mounted provider #297
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#297
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?
The gap
A skill selector can only be declared on a provider or repository definition, never on the binding that attaches it to a role. So every role mounting a given path receives an identical skill set, and there is no way to give one role a subset of what another role gets.
Evidence
Read at
9039e92.The bindings carry no selector.
internal/schema/schema.go:ProviderUseis the same shape plusRequired bool. The parse sites confirm it:use-providerrejects children outright withuse-provider accepts no children, anduse-repositoryrejects anything past the id withuse-repository accepts only one argument.The selectors live on the definitions.
RepositoryDefinitionandProviderDefinitionboth carrySkills []string, parsed byparseSkillSelectorChildren. A definition's selector therefore applies uniformly to every role that mounts it.Declaring the same path twice is closed in both directions.
pathsis a single map shared across therepositoriesandprovidersblocks:repository declaration %q duplicates path %q already named by %sproviders %q and %q name the same repository path %qSo the obvious workaround, two declarations on one path with different selectors, fails whichever pair of node types you try.
Why it matters
The consumer is a private context repository with 64 entries mounted by one role. A second role needs roughly a quarter of them, and the excluded three quarters include third-party identity and NDA-bound material that must not reach that role, because it is the role that drafts outward-facing text. Today the only options are all 64 or nothing, and "nothing" is the safe answer, which means the role works from a less accurate secondary source instead.
Consumer detail:
coilyco-bridge/agentic-os-kai#881.Proposed shape
Accept a skill selector on the binding:
Reusing
parseSkillSelectorChildrenkeeps the child syntax identical to the definition form.Semantics worth deciding explicitly
Validaterejects an explicitly empty selector withskills selector is empty; omit skills to admit the whole provider.Selectalready errors when a pattern matches nothing. A binding pattern that matches nothing after intersecting is a real authoring mistake and should say so.Selectrejects patterns that both admit one skill, withoverlap on skill %q. That should hold within a binding's own selector.Suggested tests
Note on the workaround already applied
The consumer renamed all 64 entries onto seven non-overlapping category segments so the eventual allowlist is two globs rather than a long exact-name list. That was needed regardless, because the unmatched-pattern and overlap rules make a long exact-name selector brittle against any rename. It does not substitute for this change, it only makes the selector expressible once the change lands.