
# App Metadata

Three scalar root properties identify your application: `name`, `version`, and `description`. Only `name` is required. Together they anchor Sovrium's immutable version ledger and its schema-drift detection.

```yaml
name: '@acme/crm'
version: 2.1.0
description: 'A CRM workspace for managing contacts, deals, and tasks.'
```

## `name`

The app name follows npm package naming conventions. It is lowercase, URL-safe, and the only required property in the entire schema.

| Constraint | Description                                                                                                   |
| ---------- | ------------------------------------------------------------------------------------------------------------- |
| Pattern    | `^(?:@[a-z0-9-~][a-z0-9-._~]*/)?[a-z0-9-~][a-z0-9-._~]*$` — lowercase letters, digits, hyphens, dots, tildes. |
| Length     | 1–214 characters (including the `@scope/` prefix if scoped).                                                  |
| Leading    | Cannot start with a dot or underscore; no leading/trailing spaces.                                            |
| Scoped     | npm-style scoped names are allowed: `@scope/name` (e.g. `@acme/dashboard`).                                   |

```yaml
# Valid names
name: my-app
name: task-tracker-v2
name: '@acme/dashboard'
```

## `version`

A Semantic Versioning 2.0.0 string ([semver.org](https://semver.org)). Optional, but recommended — when present it feeds the version ledger described below.

| Rule           | Description                                                                   |
| -------------- | ----------------------------------------------------------------------------- |
| Format         | `MAJOR.MINOR.PATCH` (e.g. `1.0.0`). Each component is a non-negative integer. |
| No leading 0   | `01.0.0` is rejected — version components must not have leading zeros.        |
| Pre-release    | Optional hyphen suffix: `1.0.0-alpha`, `1.0.0-beta.1`, `2.0.0-rc.1`.          |
| Build metadata | Optional plus suffix: `1.0.0+build.123`, `1.0.0-alpha+001`.                   |

```yaml
version: 1.0.0 # Stable release
version: 2.0.0-beta.1 # Pre-release
version: 1.0.0+build.42 # Build metadata
```

## `description`

A single-line description shown in the admin UI and metadata.

| Constraint | Description                                               |
| ---------- | --------------------------------------------------------- |
| Format     | Single line only — line breaks (`\n`, `\r`) are rejected. |
| Max length | 2000 characters.                                          |
| Unicode    | Full Unicode support including emojis.                    |

```yaml
description: 'Full-featured e-commerce platform with cart, checkout & payment processing'
```

## Version history

Every Sovrium app keeps an **immutable version ledger** — an append-only audit log of schema snapshots. Each successful publish appends one row containing the encoded schema snapshot, a SHA-256 checksum of that snapshot, and the `source` that produced it. Restoring an older version copies its snapshot into a _new_ row; history is never mutated.

### The four transports

A schema change can arrive through one of four transports. Each transition appends exactly one ledger row, and the `source` column records which transport produced it.

| Transport       | `source` value | How a change arrives                                                               |
| --------------- | -------------- | ---------------------------------------------------------------------------------- |
| **Config file** | `config-file`  | `sovrium start app.yaml` at boot, or `sovrium reload` for a running server.        |
| **Env var**     | `env`          | The `APP_SCHEMA` environment variable (inline JSON/YAML or a remote URL snapshot). |
| **Admin API**   | `api`          | The admin HTTP API (`POST /api/admin/schema/draft/publish`).                       |
| **MCP**         | `mcp`          | An MCP schema-edit tool (`{app}_schema_draft_publish`).                            |

A fifth `source`, `restore`, marks rows created by restoring an earlier version. Checksums are self-contained (each row hashes its own snapshot, not a parent), which is what makes pruning interior rows safe.

## Schema drift detection

Because the live schema can be edited at runtime (via the admin API or MCP) while a `config-file` still sits on disk, the live app can **drift** away from its source file. Sovrium computes a drift posture from the ledger and exposes it so tooling can warn before overwriting work.

| Drift status        | Meaning                                                                                                                 |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `in-sync`           | The active version came from a `config-file`/`env` transport — the running app matches its source.                      |
| `drifted-from-file` | The active version came from `api`/`mcp`/`restore` — the live app was edited at runtime and no longer matches the file. |
| `file-ahead`        | The on-disk file's normalized checksum changed — the source file is now ahead of the live app.                          |

:::callout
**`sovrium reload` respects drift.** Reloading a `config-file`-launched server first probes the live drift status. If the live app has `drifted-from-file`, the reload is refused unless you pass `--force` — preventing an accidental overwrite of runtime edits with stale file contents.
:::

## Draft staleness

Runtime editing happens against a **mutable draft** — a single working copy branched from the active version. The draft records the `baseVersion` it branched from, which doubles as both an optimistic-concurrency token on publish and a **staleness anchor**.

A draft becomes **stale** whenever `draft.baseVersion` no longer equals the active version number. This occurs when another admin publishes, or when a `config-file`/`env` reload moves the base underneath an open draft.

| Operation on a stale draft | Allowed?                                |
| -------------------------- | --------------------------------------- |
| Preview / validate / edit  | Yes                                     |
| Publish                    | No — blocked until the draft is rebased |

To clear staleness, **rebase** the draft: re-point its `baseVersion` to the active version, leaving the draft contents untouched. There is no field-level merge — the next publish is a whole-snapshot, last-writer-wins operation, consistent with Sovrium's snapshot-atomic schema system.

## Next steps

- [Schema Overview](/en/docs/overview) — all root properties at a glance.
- [Configuration Files](/en/docs/configuration-files) — how `config-file` and `env` transports load your app.
- [CLI Reference](/en/docs/cli) — `sovrium reload` and drift handling.
