Tag filtering and skill dependencies
Two features decide which skills a project receives, and they interact, so this page covers both. The How sync works states the basic rule of each; here is the full reference.
Tag filtering
The rule: a vendor skill ships only when every tag in its boost-tags is among the project's withTags() (skillTags ⊆ projectTags). An untagged skill always ships, so the feature is inert until skills and projects opt in.
One exception: a tag-dropped skill that a shipping skill declares in its boost-requires is pulled back in. See Rescue below.
withExcludedSkills() drops a specific vendor/package:skill-name regardless of tags.
Guidelines filter the same way
Vendor guidelines are tagged either by metadata.boost-tags or a sidecar resources/boost/guidelines/.boost-tags.yaml manifest. The sidecar exists for guidelines that must stay frontmatter-free to remain readable by laravel/boost. withExcludedGuidelines(['acme/pack:unwanted-guideline']) is the guideline-side deny-list.
The tag vocabulary is open
The Tag enum is a convenience, not a closed set; any string is a valid tag.
vendor/bin/boost tagslists every tag installed skills and guidelines declare, which of them yourwithTags()filters out, and what to add to receive them.boost install's interactive picker offers the same choices.- When sync drops tagged skills because
withTags()is empty, it prints a one-line nudge pointing atboost tags.
WARNING
Adding a tag to an already-shipped skill is consumer-breaking: every project that hasn't declared that tag loses the skill. Treat it as a breaking change.
Tracing what shipped and why
boost where traces where every resolved skill, guideline, and command comes from (host / vendor / remote), with host-override shadowing annotated inline. boost where --diff=<name> prints a unified diff between a host override and the vendor copy it shadows.
Skill dependencies
The rule: whenever a skill ships, every name in its boost-requires ships too.
---
name: interview
description: Requirements-gathering flow that hands off to write-spec.
metadata:
boost-requires: "write-spec"
---Rescue
A dependency that tag filtering would have dropped is rescued: the author's "this skill is broken without it" outranks topic scoping, so it ships anyway. Sync reports every rescue as an INFO diagnostic, and rescue is transitive, so a rescued skill's own requires ship as well.
The details
- Bare names, not
vendor/package:keys. Dependencies bind to the name: a host.ai/skills/override of the dep satisfies it, and any provider can. withExcludedSkills()wins. An exclude removes that provider's copy from consideration; if no other provider holds the name, sync warns and the dependent ships degraded. Rescue never overrides an explicit deny.- Missing deps warn, never fail. A require naming a skill that exists nowhere is a sync warning +
boost doctorfinding, not an error. - Cycles are legal.
a ⇄ bco-ships. - Malformed
boost-requires(not a string) warns at sync and is an error inboost validate --strict. Unlikeboost-tags, it does not fail closed, because requires gate completeness, not scoping.
Authoring guidance
Declare only hard hand-offs, meaning flows that invoke the other skill. Conditional references ("where the project has quality-check skills synced, delegate to them") and routing notes ("NOT for X, use Y") must stay undeclared, or rescue drags unrelated tooling into projects that scoped it out via tags. boost validate -v flags requires that cross a tag boundary, so the choice stays deliberate.