> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agentfacets.io/llms.txt
> Use this file to discover all available pages before exploring further.

# facet publish

> Verify and upload a built facet

## Usage

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
facet publish            # publish the facet in the current directory
facet publish ./cowsay   # publish the facet in ./cowsay
```

Reads the built `.facet` archive from `dist/`, verifies it against the facet artifact specification, and uploads it to the registry. The directory argument is optional and defaults to the current working directory, consistent with `facet build`, `facet edit`, and `facet create`. Publish is a verify-and-ship step, not a build -- `facet build` is the sole producer of the `.facet` archive.

## Exit codes

| Code | Meaning                                                                                                       |
| ---- | ------------------------------------------------------------------------------------------------------------- |
| `0`  | Publish succeeded (201 published or 202 queued).                                                              |
| `1`  | Failed (no credential, invalid manifest, verification failure, no artifact in non-TTY, registry error, etc.). |

## What it does

<Steps>
  <Step title="Resolve directory">
    Defaults to the current working directory. The directory must contain a `facet.json`.
  </Step>

  <Step title="Resolve credential">
    Checks `FACET_TOKEN` environment variable first, then the credentials file at `$FACET_DIR/credentials` (default `~/.facet/credentials`). Fails before any further work if no credential is found.
  </Step>

  <Step title="Validate manifest">
    Loads and validates the source-tree `facet.json` against the schema.
  </Step>

  <Step title="Discover dist/ artifact">
    Finds the `.facet` file in `dist/`. If `dist/` contains multiple `.facet` files, publish fails -- run `facet build` to prune `dist/` or remove the extras manually.
  </Step>

  <Step title="Drift detection">
    Compares the built artifact's embedded manifest against the current source-tree `facet.json`. See [Drift detection](#drift-detection) below.
  </Step>

  <Step title="Re-verify archive">
    Runs full archive verification: integrity hash, per-asset hashes, embedded manifest, and content rules. The archive is verified immediately before upload regardless of whether earlier steps already verified it.
  </Step>

  <Step title="Upload">
    POSTs the verified bytes to the registry. The `name` and `version` used to address the upload come from the verified artifact's embedded manifest, not from a separate parse of the source-tree `facet.json`.
  </Step>
</Steps>

## Credential resolution

The publish token comes from `FACET_TOKEN` or the credentials file written by [`facet login`](/cli/login) — see that page for precedence and the file format. If no token is found, publish fails before any verification or registry round-trip.

## Drift detection

Publish compares the built artifact's embedded manifest against the current source tree and handles a missing artifact, content drift, and identity drift — each with defined interactive and non-interactive behavior. The decision semantics are specified in the [Publish specification](/specification/publish#when-the-built-artifact-is-missing); the prompts you see in a terminal are below.

## Interactive prompts

In an interactive terminal, each scenario gets its own prompt. In a non-interactive context (CI, piped stdin) the CLI never prompts: a missing artifact fails with "no built artifact; run `facet build` first", and both drift classes warn on standard error and upload the existing artifact unchanged. Pipelines that want a strict rebuild-from-source run `facet build && facet publish` as two commands.

**Missing artifact** — when `dist/` is empty, the CLI offers to build the current source. On acceptance it runs the build pipeline in the same view `facet build` uses, then verifies and uploads the freshly built artifact. On decline it reports that there is nothing to publish and exits non-zero — the registry is never contacted.

**Content drift** — a two-option prompt: rebuild and publish the new artifact, or publish the existing artifact unchanged.

**Identity drift** — a three-option prompt:

* **Build & publish the current source.** Run the build pipeline against the source's current name and version, verify, and upload.
* **Publish the existing artifact as-is.** Upload the older artifact under its own embedded `(name, version)`. If that identity is already published, the upload fails with the registry's verbatim immutability message — that 409 is the signal that the source needs a version bump (or that the older version was already published).
* **Cancel.** Exit non-zero without contacting the registry.

<Note>
  The second option exists because there are real workflows where it succeeds: a user who built `v0.1.0` on machine A, copied the `.facet` to machine B, then started editing `facet.json` for the next version, and now wants to publish what they actually built before continuing.
</Note>

## Publish outcomes

| HTTP status | CLI exit | Meaning                                                                                                               |
| ----------- | -------- | --------------------------------------------------------------------------------------------------------------------- |
| `201`       | `0`      | Published immediately.                                                                                                |
| `202`       | `0`      | Queued for review. The CLI reports that the submission was accepted and surfaces the registry's guidance.             |
| `409`       | `1`      | Version already exists. The registry enforces immutability -- a version cannot be republished with different content. |

<Note>
  Registry errors are rendered verbatim, as the [Publish specification](/specification/publish#authentication) requires.
</Note>

## See also

* [`facet build`](/cli/authoring/build) -- produce the `.facet` archive that publish uploads.
* [`facet login`](/cli/login) -- sign in to the registry.
* [`facet whoami`](/cli/whoami) -- verify the signed-in identity.
* [Publish specification](/specification/publish) -- the normative publish requirements.
