Materialization decides names, never content. Every archive path, every integrity hash, and every field of a declaration is fixed by its publisher and unaffected by anything on this page.
Two identities
fixed by the publisher
The name declared in
facet.json. It fixes a text asset’s canonical archive paths, and therefore every integrity value recorded for it. It is what the lockfile stores. Aliasing and omission never change it.chosen by the project
The name the contribution is materialized under. It equals the authored name unless the project aliased it.
name written into a materialized asset is the effective name, and description stays as the publisher wrote it.
MCP servers have the same two identities. The authored name keys the project’s override and the ownership record; the effective name is the key written into the tool’s document. The declaration body is name-independent, so renaming a server never changes what it launches or connects to.
Dispositions
A project resolves each authored contribution to exactly one outcome.the default
Materialize under the publisher’s name. Expressed by recording nothing: the absence of an override is the authored disposition. An explicit
authored override MUST be rejected, so one state has one spelling.{ kind: 'aliased', as }
Materialize under a different effective name.
as is required and MUST satisfy the single-segment asset-name grammar. An invalid alias MUST be rejected rather than normalized, because silently rewriting a chosen name would make the result unpredictable.{ kind: 'omitted' }
Do not materialize this contribution or any file it owns. An omitted text asset is still resolved, verified, and recorded in the lockfile. It simply never reaches an adapter, and is never approved or owned.
- A project override admits only
aliasedandomitted, becauseauthoredis the absence of one. - A materialized disposition admits only
authoredandaliased, because an omitted contribution was never materialized.
Recording intent
Dispositions live infacets.json, keyed by contribution kind and then by authored name:
facets.json
Namespaces
Two contributions may share a name across namespaces, never within one.- Skills and commands share one namespace, because they materialize into a single flat surface in the tools facets target.
- Agents occupy their own namespace.
deploy and a command deploy collide, while an agent deploy coexists with both.
MCP servers are not a text asset type. They occupy a separate configuration identity space, keyed by effective server name at project scope, so a server deploy coexists with every text asset named deploy and can only collide with another server.
Collisions
Two text assets collide when their collision keys are equal:- It uses the effective name, so aliasing can both cause and cure a collision.
- It folds text asset type into its namespace, giving the rule above.
- It folds the name portably: Unicode NFC, then Unicode lowercasing. Lowercasing is not ASCII-only, so
Äandäcollide, but it is deliberately not full Unicode case folding, soßandSSdo not fold together. Two names differing only by case or normalization collide rather than silently overwriting each other on a case-insensitive volume.
(scope, type, effective name), using the verbatim name: a skill deploy and a command deploy are two different files even though they may not legally coexist.
Server collisions
Servers collide by project scope and portable effective server name, in the same pass as text assets, with one rule that has no text-asset counterpart:- Identical declarations compose. When two facets claim one effective name with declarations whose canonical fingerprints are equal, they agree. One configuration is produced and both facets are retained as claimants.
- Different declarations collide. Differing fingerprints describe materially different behavior at one key, so they form a collision group naming every claimant.
Planning rules
Planning is a single pass, not a fixed-point resolver. Overrides are applied once against authored identity, then the resulting effective set is checked once. Text assets and servers share one planning primitive, so every rule below holds in both identity spaces.- Alias swaps are legal. If
Aaliases toBandBaliases toA, both land, because neither observes the other’s result. - Duplicate alias targets fail. Two contributions aliased to one name collide like any other pair.
- A name freed by an omission is available.
- Order does not matter. The result never depends on declaration order.
Stale overrides
An override naming a contribution the resolved version no longer contains is stale, usually because a publisher renamed or dropped it. A stale override is reported rather than fatal. Because intent is durable, it survives a failed operation and is pruned only by a successful install, which reports what it dropped. Under a frozen install the same condition is blocking drift instead, and the override is not removed.What aliasing does not change
Everything below is anchored to the authored name and is byte-identical whether or not a contribution is aliased:- Canonical archive paths, and therefore the per-entry hashes.
- The facet’s canonical fingerprint.
- The lockfile’s
nameandfilesrecords. - The text asset’s content and its
description.