facet build produces the canonical .facet archive from the author’s source tree and writes it to dist/<name>-<version>.facet. This is the artifact of record: the bytes facet publish will later verify and upload. There is a single source of truth for what a .facet is: the two-layer archive format, whose content-hash contract is described in the Integrity Model.
Steps
-
Parse and validate the manifest. Read the facet manifest (
facet.json) and validate it against the manifest schema. Invalid manifests MUST be rejected with a descriptive error. The manifest’snameMUST be a valid facet identity; theversionMUST be a semver string; at least one text asset MUST be declared. -
Resolve prompts. Read each declared asset file from its conventional path:
skills/<name>/SKILL.mdfor skills,agents/<name>.mdfor agents,commands/<name>.mdfor commands. Missing files are build errors. YAML front matter in content files is permitted and MUST be preserved verbatim in the archive — the manifest’sname,description, and any per-adapter extras are merged on top of the author’s front matter at install time. -
Validate content. A declared asset MUST NOT be empty (zero bytes or whitespace only). Two assets within the same type MUST NOT share a name. Compact
facets[]entries MUST match thename@versionshape. -
Validate adapter metadata. For each asset with an
adaptersblock, validate the adapter-specific metadata against each installed adapter’s schema. Unknown adapters SHOULD produce a warning. Invalid metadata for an installed adapter MUST be a build error. -
Assemble the archive. Compute per-asset SHA-256 hashes. Assemble the deterministic inner tar. Compute the integrity hash over the uncompressed inner tar. Gzip the inner tar (
archive.tar.gz). Assemble the outer tar containingbuild-manifest.json(recording the integrity hash and the per-asset hash map) plus the gzipped inner archive. Write the result todist/<name>-<version>.facet. The layout, determinism rules, and hash domains are specified in Facet Archive.
facet build purges dist/ before writing, so the directory contains exactly one .facet after a successful build: the archive for the current source’s name and version. For a scoped facet identity, the name’s / renders as a nested path under dist/ — @acme/cowsay at 1.0.0 is written to dist/@acme/cowsay-1.0.0.facet, with parent directories created as required.
Boundaries
Building never contacts the registry and never mutates the manifest. What happens to the built artifact next — verification, upload, drift handling — is defined in Publish. Command usage and flags are documented atfacet build.