feat(schema): let a role narrow the skills it receives from a mounted provider (#297) #298
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!298
Loading…
Reference in a new issue
No description provided.
Delete branch "aos/claude/gh297-binding-skill-selector"
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 #297.
Shape
use-provideranduse-repositorynow acceptskillchildren, reusingparseSkillSelectorChildrenso the child syntax is identical to the definition form.How the semantics are enforced
SelectOrdinarySkillstakes the definition selector and the binding selector and applies them as two passes, the binding running over what the definition already admitted. Every semantic the issue asked for falls out of that ordering rather than needing a new rule:Selectalready rejects.Selectcall per pass, so the existing overlap rule applies per selector.Glob-to-glob intersection is never computed symbolically. Ordering does the work.
Threading
The selector rides
ProviderUseandRepositoryUse, intorepositoryplan.Selection.BindingSkills(binding_skills, omitempty), throughcompose.RootSourceintoSelectOrdinarySkills. Residency clears it, because a role-union entry must not report one role's narrowing as a property of the repository.One thing worth flagging
repositoryplan.Marshalhand-builds its YAML node tree andLoadvalidates against a closed key set, so adding the struct tag was not enough on its own - the field serialized as nothing. The schema unit tests all passed while the plan silently dropped the selector. The cascade end-to-end test is what caught it, which is why that test is in here rather than just the unit ones.Tests
All six the issue suggested, plus parse-level and
use-providercoverage:repository-plan.yamlfor the narrowing role, is absent for the unbound role, and is absent from residencygo build ./...,go vet ./...,go test ./...,gofmt -l, andpre-commit run --all-filesall pass. The existing suite passing unchanged is the evidence for requirement 6 at bundle level.Not changed
globalandresident-onlystill reject children. They are repository policy rather than role bindings, and the issue is about what one role receives.No
docs/FEATURES.mdentry. This extends the expressiveness of the existing.agents/roles.kdlline rather than adding a capability, so per the FEATURES rule the detail went todocs/kdl-contracts.mdinstead. Easy to overrule if you read it the other way.A skill selector could only sit on a provider or repository definition, so every role mounting a path received an identical set. Declaring the path twice with different selectors was closed in both directions, leaving all-or-nothing as the only choice. For a repository holding third-party identity and NDA-bound material next to publishable material, nothing was the safe answer, and the role that needed the publishable quarter worked from a weaker secondary source. Accept skill children on the use-provider and use-repository bindings: role "creator" { use-repository lore { skill "lore-self-*" } } The binding runs as a second selector pass over what the definition already admitted, so intersection, non-widening, unmatched-pattern, and overlap semantics all fall out of the existing skillselector rather than needing new rules. A pattern reaching past the definition matches nothing in the narrowed catalogue and fails with the existing message. An omitted binding is nil and returns before touching the source, so current bundles are unchanged. The selector travels on ProviderUse and RepositoryUse, into the repository plan as binding_skills, and through RootSource into compose. Residency drops it, because a role-union entry must not carry one role's narrowing. Note that repositoryplan.Marshal hand-builds its YAML node tree and its loader validates against a closed key set, so the struct tag alone was not enough. The cascade test is what caught that, not the schema unit tests. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: Kai Siren <coilysiren@gmail.com> Co-authored-by: Claude <noreply@anthropic.com>