facet install.
Ordering
An install MUST resolve and verify the complete desired set, and MUST compose one plan over all of it, before writing anything. Composing globally is what makes collision detection possible: two facets claiming one name cannot be detected once the first is already on disk. See Materialization. Project state MUST NOT be written unless every check passes. A failure before the first write leaves the project byte-identical. From the first write onward, an implementation MUST record enough state to restore every file it changes. A failure MUST then restore text assets, native configuration documents, and project state to their exact prior bytes, except where a path was changed by something else after this operation wrote it, or cannot be read or written back. Such a path MUST be left as it stands rather than overwritten, and every path an implementation could not return to its prior bytes MUST be reported.Resolve
Whether the lockfile is trusted for version resolution depends on how an entry was requested, not on a flag.- Implicit request. A non-exact specifier in an addition, such as a bare name,
1.*, orlatest, MUST resolve to the newest matching version even when the lockfile already satisfies it. The user asked for that range now. - Explicit request. An exact specifier, and any reproduction of an already-declared facet, MUST reuse a satisfying lockfile entry. Only an absent or stale entry triggers resolution.
- Reviewed update. A version chosen during an update’s read-only discovery MUST be installed as reviewed. Resolution MUST NOT be repeated at write time, so a release published in between cannot silently change what is installed.
Verification
Verification obligations are defined in the Integrity Model. An install MUST apply them:- Cached content MUST be re-verified on every use, and content that fails MUST NOT be materialized.
- When the lockfile pins a version, the verified integrity MUST equal the locked integrity. A mismatch MUST fail.
- When a lockfile entry is created or replaced, the integrity MUST be confirmed against the registry’s published fingerprint. An unreachable registry MUST fail rather than record an unconfirmed entry.
- A git source MUST verify its built content against the locked integrity, which is what detects a moved tag.
- Failures MUST be reported under distinct checks, so a frozen local-source failure is never reported as a git failure.
Composition
The desired set is computed by the deterministic planner defined in Materialization. Text assets and MCP servers are planned in separate identity spaces. A collision MUST NOT be resolved by choosing a winner or inventing a name. An implementation MUST either collect the user’s decision, recorded as durable intent infacets.json, or report every claimant and stop.
MCP configuration
A new or changed MCP server declaration MUST be approved before it is materialized.- Approval MUST be keyed by the effective server name and the declaration’s canonical content, so an unchanged declaration does not ask again and any change to what would launch or connect does.
- Interactive consumers MUST be shown the exact command, arguments, and environment assignments, or the exact URL, before anything is written. Non-interactive consumers MUST require an explicit opt-in.
- Approval MUST be recorded only by a fully successful operation. A declined, failed, or rolled back run MUST bank nothing.
- Approval MUST be machine-local. It MUST NOT be stored in version-controlled project state, because a committed file must not be able to claim that another machine consented to running something.
Ownership
Two rules govern every kind of state.- Desired state authorizes writes. Every desired identity is reconciled. When what is already present matches byte for byte, the write MAY be skipped, and the identity is still recorded as owned.
- Recorded ownership authorizes deletion. Only an identity this machine recorded materializing may be deleted. A lockfile entry alone is not evidence, because a lockfile is shared state that can arrive from a teammate.
Untracked destinations
A desired identity already occupied by state this machine does not own MUST be disclosed before it is adopted or replaced. Equivalent state MUST be adopted without rewriting it. Divergent state MAY be replaced once the user continues. State at an identity the desired set does not name MUST NOT be inspected or modified.Manifest write policy
The value written tofacets.json depends on the specifier shape, and is applied only as part of the final write.
An update decides its manifest value from the choice the user reviewed. Taking a facet’s range target never rewrites the specifier, and the authored string is preserved rather than re-rendered. Taking the latest release widens the specifier by the smallest edit that admits it:
Materialization overrides are carried across a version change untouched. An override naming something the new version no longer contains is pruned and reported.
Comments in
facets.json MUST survive a write.
Transactional tri-write
On success, a non-frozen install MUST write the project manifest, the lockfile, and the machine-local ownership record together. A failure anywhere MUST leave all three exactly as they were, and MUST restore every text asset and every native configuration document the operation touched, under the restoration rule in Ordering.Frozen lockfile
Frozen mode treats the lockfile as authoritative for what to reproduce. It is not authority to delete: that stays with the machine-local record. Only a reproduction can run frozen. An addition, removal, or update has no frozen form. Frozen mode MUST NOT prompt, for a collision or for approval, though it MAY use approval supplied in advance. These gates MUST run before any network access, so a frozen install can refuse without fetching anything:1
Coverage
Every manifest facet MUST have a satisfying lockfile entry, the lockfile MUST NOT pin anything the manifest dropped, and git and local sources MUST match their locked provenance.
2
Format capability
A lockfile version with no field for a text-asset disposition MUST fail when the manifest declares one, rather than ignore the intent. A server disposition never triggers this, because no lockfile version records server intent.
3
Plan over the locked set
The planner runs against the lockfile’s recorded text assets, so a collision or invalid alias in recorded state is reported before anything is downloaded.
4
Stale intent
An override naming a text asset the locked version does not contain, or a server the pinned facet does not declare, is blocking drift. Frozen mode reports it without removing it.
5
Intent against recorded disposition
For every locked text asset, what the manifest asks for MUST equal what the lockfile records. Editing an alias without a normal install is drift, exactly like editing a version.
Version axes
The archivefacetVersion, the project manifest version, and the lockfile version are independent axes. Each is classified by exact match against a supported set, never by numeric ordering, so an unrecognized version is refused rather than guessed at.
An implementation that also supports adapters carries its own adapter SDK API axis on top of these.
An archive whose facetVersion is unsupported MUST fail with the observed and supported versions, so a consumer can be told what to upgrade.
Boundaries
- Text is never fetched or assembled at install time. Everything installed comes from the verified archive.
- Skill companion files materialize with their skill. Every other supplementary file ships in the archive and MUST NOT be written to disk.
- Materializing a declaration MUST NOT install, launch, probe, or authenticate to an MCP server, and MUST NOT store credentials.
- An installer MUST NOT modify user-wide or system-wide tool configuration.