Skip to main content

Package lifecycle

This guide covers how to develop, test, release, and run package versions in a group. Each device chooses which version to run; the group shares version records and defaults, but dev work does not automatically switch everyone else.

For the underlying design rationale and remaining roadmap items, see Package lifecycle design.

Overview​

Packages move through three promotion levels:

dev ──▶ beta ──▶ stable
PhaseHow it is createdSyncs to the group?Auto-activates on other devices?
devAutomatically when code is loaded from diskYes (version records sync)Never — unless a device explicitly opts in
betaPromote in the package Versions UIYesOnly on devices following stable,beta or *
stablePromote in the package Versions UIYesOn devices using the default follow policy (stable)

The platform assigns versionTag (dev / beta / stable). Do not set it in an isolated manifest, definePackage(), or contract definitions.

Metadata vs bundle bytes: PackageVersions (and related Files records) sync as group data. As soon as a version record arrives, this device also downloads that version’s package, routes, and UI bundles into the local chunk cache so later activation or UI load does not wait on a peer. A downloaded version is not automatically activated. The device waits until the current sync has applied every page and saved its watermark, then evaluates the final package state once using its pin, follow, and device-override rules. An incompatible bundle can fail to load without blocking metadata sync or preventing a newer version from arriving. If a peer cannot provide a bundle yet, metadata sync still succeeds and the missing chunks retry when another peer becomes available.

Group defaults vs this device​

Two layers work together:

LayerWhere it livesPurpose
Group settingsIPackage record (synced)activePackageVersionId, versionFollowRange, followVersionTags for devices that follow the group
Device preferencesgroupDeviceVar per package (packagePrefs_${packageId})Local active version, pin state, and optional per-device follow overrides

By default, a device follows the group settings. Turning on Override on this device in Package Info makes the auto-update range and release channel local to that device.

Activation scope depends on the version and override state:

  • Activating a non-dev version with device override off updates the group active version.
  • Activating a non-dev version with device override on updates only this device.
  • Activating a dev version updates only this device, even when override is off.
  • Promoting the version this device is already running to a tag the group follows (default stable) advances the group active version under the same admin / override / not-pinned rules as Activate.
  • Automatic non-dev upgrades advance the group active version only when the device is following group settings and the current user is a group Admin or higher. Otherwise the upgrade remains local to the device.

Day-to-day development​

  1. Edit your package on disk (local path in Package settings).
  2. Reload or restart the app (or use your usual dev workflow). The installer creates or updates a dev package version from the bundle on disk.
  3. Dev versions sync to the group as PackageVersions records, and other devices download those version files immediately, but they do not auto-switch to dev.
  4. Open Packages → your package → Versions to see versions, hashes, and tags. Use Activate on a dev version to run it on this device without changing the group active version.

App icons in the apps list come from appNavs on the active PackageVersion (copied from the isolated manifest or legacy package definition when bundles are installed). Startup sync always persists appNavs onto new versions, including when the group is currently on a stable build.

Routes and UI bundles reload when you change the active version on this device (no full page refresh required).

Releasing to the group​

  1. In Versions, use Promote on a dev version: dev → beta or dev → stable (or beta → stable).
  2. Promotion updates the version’s versionTag, refreshes packageAuthorSignature when a package signing key is available (and clears a stale signature if not), and appends to the version’s signed history audit trail. Editing the semver on a version row does the same for the signature.
  3. If you promote the version this device is already running, and the new tag matches the group’s follow policy (default: stable; beta only when the group follows beta), the group activePackageVersionId advances automatically (admin, device follow override off, group not pinned) — same rules as Activate. Otherwise use Activate on the promoted beta/stable release; devices following the group pick it up on their next resolve/sync.

Today: promotion and activation are done in the package Versions UI.

Planned: promote-package-version and set-active-package-version tools for CI and AI assistants (same behavior as the UI, single code path). See Package lifecycle design.

Signed publish artifacts (local)​

Use the system tool publish-package to build distributable files on disk after you have a signing key and built bundles:

peers tools run publish-package '{"name":"Groceries","versionTag":"beta"}'

This writes (by default under <packageLocalPath>/dist/publish/):

  • A signed .peers-pkg.tar.gz containing the three bundles plus metadata
  • A latest-<tag>.json pointer with version, hashes, and author signature

Verification expectations before you trust an artifact:

  • Bundle file hashes in the pointer/payload match the files inside the tarball
  • packageAuthorSignature verifies against Packages.publishPublicKey
  • Semver in the pointer is what you intend to publish (remote auto-activation requires a newer semver than the installed follow candidate)

Upload / hosting is a separate step. publish-package does not push to S3 or your updateUrl. Point Packages.updateUrl at a host only after you have uploaded the tarball and pointer yourself (or via your release tooling).

Permissions​

ActionTypical role
Create / update dev versions (disk reload)Writer
Promote to beta or stableAdmin
Activate beta/stable for the groupAdmin
Activate dev or use device overrideLocal device choice
Pin a deviceLocal device choice

Personal space (no group) bypasses group role checks for your own packages.

Package Info Settings​

On the package Info tab, Auto-update range and Following edit group settings by default. Enable Override on this device to make those controls local to the current device.

  • Update URL — base URL where admin devices check for new signed releases (<updateUrl>/latest-<tag>.json). Edit on the Info tab and save with Save Changes. See Package lifecycle design for publishing and upload details.
  • Auto-update range - pinned (no auto-updates), patch, minor, or latest.
  • Following - stable or stable,beta.
  • Override on this device - when enabled, auto-upgrades and manual beta/stable activations affect only this device.

Pinned devices keep their active version even when new stable or beta versions sync in.

Multi-device testing​

To test with other devices before a stable release:

  1. Promote your build to beta in Versions.
  2. On each tester device, set Follow version tags to stable,beta (or *) if you want automatic beta upgrades, or Activate the beta version manually.
  3. Dev versions remain available for manual activation on any device but never auto-activate elsewhere.

Contracts and stable releases​

Contract maturity is tied to package promotion. New contract shapes can evolve freely in dev builds. The platform is designed to finalize contracts (remove dev tag, freeze shape) when a package version is promoted to stable.

If you need to extend a frozen contract after stable, increment the contract version and use alsoImplements so providers remain compatible with older consumers. See Package contracts.