Nostrautica docs

Versioning and Release Policy

Nostrautica keeps independent package versions bound together at deploy time by a release manifest (audit §13.9, Option B). Package versions carry semantic meaning per package; the manifest is what ties one deployed set of artifacts to a single product release.

The versions and how they bump

Field Source Bump when
Product release package.json (root) version + the git tag/SHA Any deploy — it labels the release, not any one package.
@nostrautica/app packages/app/package.json The PWA changes (UI, client logic, service worker). Also the SW-precache input.
@nostrautica/protocol packages/protocol/package.json The shared protocol package API (types/schemas/helpers) changes.
@nostrautica/coordinator packages/coordinator/package.json The coordinator package API/behavior changes.
Wire protocol v PROTOCOL_VERSION in packages/protocol/src/schemas.ts The on-the-wire payload contract changes. This is deliberately separate: package versions can move without a wire change, and a wire change is a compatibility event for every peer. Currently 2.
Store schema SCHEMA_VERSION in packages/coordinator/src/store/db.ts The coordinator's durable SQLite shape changes in a way a downgrade can't tolerate (drives the open-time and backup/restore downgrade guards). Bumped at every downgrade-incompatible boundary via a numbered migration (see below). Currently 2.

Do not infer compatibility from equal or unequal package versions. Compatibility is defined by the wire protocol version (and the protocol registry, docs/PROTOCOL-REGISTRY.md) and by the specific tested release commit — never by a package number.

Store schema migrations (SCHEMA_VERSION)

The coordinator's SQLite schema uses a numbered, ordered migration model (audit O3). It has two parts:

The open path refuses a database whose user_version is greater than the binary's SCHEMA_VERSION (a database written by a newer coordinator), with a clear operator message to upgrade the coordinator first. From v2 onward the same refusal applies at Store open and at backup verify/restore (schemaTooNew) — an older binary can no longer silently open or restore a database a newer binary has migrated. The residual risk that a pre-remediation (pre-v2) binary rewrites the marker back to 1 is inherent to those old binaries and unfixable from here; the operational rule is simply do not run superseded binaries against a migrated database — take the pre-upgrade backup (operator guide §7) so a rollback restores a schema the old binary accepts.

The release manifest

scripts/release-manifest.mjs computes a JSON manifest at build time:

{
  "releaseId": "<git describe --tags --always --dirty, or v<root pkg>>",
  "gitSha": "<full commit sha>",
  "appVersion": "…", "protocolVersion": "…", "coordinatorVersion": "…",
  "wireProtocolVersion": 2,
  "basePath": "/app",
  "buildTimestamp": "<git commit time ISO, or build time>"
}

NOSTRAUTICA_RELEASE_ID overrides the computed id — set it in the coordinator's service environment on a host that runs from rsync'd source without .git, so the logged/announced id is the real release rather than the v<pkg> fallback. NOSTRAUTICA_BUILD_TIMESTAMP similarly pins the timestamp.

Reproducible service-worker revision

The PWA's service-worker precache revision for the shell is releaseManifest.releaseId (a git identity), not Date.now(). The same commit + BASE_PATH therefore builds the same revision — a rebuild no longer looks like a new release — while every real release changes it, which is what drives the auto-update + refresh mechanism.

Where to find the deployed revision

For a release record, capture the git commit/tag, the release manifest (from either diagnostic surface), the deployed app URL, and the coordinator revision together.