@xemahq/xema 0.29.1 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +60 -389
  2. package/dist/commands/edition.js +3 -3
  3. package/dist/commands/edition.js.map +1 -1
  4. package/dist/edition/verify-image-evidence.bundle.mjs +8715 -807
  5. package/dist/edition/verify-image-evidence.bundle.provenance.json +873 -405
  6. package/edition/README.md +53 -273
  7. package/edition/adapter-bundled-versions.mjs +107 -0
  8. package/edition/adapter-host-versions.mjs +41 -0
  9. package/edition/authorization-base.mjs +18 -9
  10. package/edition/build-runtime-image-source-index.mjs +77 -4
  11. package/edition/catalogue.mjs +15 -12
  12. package/edition/customer-definition.mjs +3 -20
  13. package/edition/develop-customer-edition.mjs +2 -2
  14. package/edition/develop-edition-resolve.mjs +10 -2
  15. package/edition/develop-edition.mjs +56 -62
  16. package/edition/develop-freeze.mjs +14 -3
  17. package/edition/dist-check.mjs +1 -0
  18. package/edition/distribution-evidence-set.mjs +32 -5
  19. package/edition/edition-channel.mjs +15 -1
  20. package/edition/edition-locks.mjs +16 -6
  21. package/edition/edition-protocol.mjs +30 -8
  22. package/edition/edition-workspace.mjs +8 -0
  23. package/edition/image-evidence.mjs +133 -25
  24. package/edition/kernel-package.mjs +193 -0
  25. package/edition/lib.mjs +73 -1
  26. package/edition/oci-evidence-verbs.mjs +2 -2
  27. package/edition/plan-image-evidence-refresh.mjs +2 -2
  28. package/edition/produce-distribution-completeness-evidence.mjs +5 -0
  29. package/edition/produce-image-delivery-entitlement-evidence.mjs +11 -1
  30. package/edition/release-catalogue.mjs +10 -3
  31. package/edition/resolve-chart-set.mjs +1 -1
  32. package/edition/resolve-customer-edition.mjs +29 -33
  33. package/edition/resolve-distribution.mjs +5 -1
  34. package/edition/resolve-edition.mjs +3 -2
  35. package/edition/seal-image-digests.mjs +16 -4
  36. package/edition/trust-policy-arming-verb.mjs +2 -10
  37. package/edition/verify-image-evidence.mjs +1 -0
  38. package/examples/README.md +3 -2
  39. package/package.json +3 -3
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  <path d="M26 12 L41 21 L41 39 L26 48 L11 39 L11 21 Z" fill="#8B5CF6"/>
7
7
  </g>
8
8
  <text x="92" y="52" font-family="ui-monospace,SFMono-Regular,Menlo,monospace" font-size="22" fill="#F8FAFC" font-weight="700">@xemahq/xema</text>
9
- <text x="92" y="80" font-family="ui-sans-serif,system-ui,sans-serif" font-size="15" fill="#94A3B8">The Xema OS command-line interface</text>
9
+ <text x="92" y="80" font-family="ui-sans-serif,system-ui,sans-serif" font-size="15" fill="#94A3B8">Command-line interface for Xema</text>
10
10
  <text x="652" y="105" text-anchor="end" font-family="ui-sans-serif,system-ui,sans-serif" font-size="12" fill="#475569">xema.dev</text>
11
11
  </svg>
12
12
  </p>
@@ -24,21 +24,18 @@
24
24
 
25
25
  # @xemahq/xema
26
26
 
27
- > The Xema OS command-line interface
27
+ > Command-line interface for Xema
28
28
 
29
29
  ## Overview
30
30
 
31
- The single global binary for Xema. Install it once to **launch the whole
32
- platform with one command**, author and ship biomes, and invoke capabilities
33
- from your terminal.
31
+ The `xema` command launches a Xema installation locally or on Kubernetes, authors and publishes biomes, invokes capabilities, and manages declarative stacks against a running control plane. It resolves an edition's distribution lock into a service roster and runs it on the substrate you choose.
34
32
 
35
- `xema up` resolves the platform's distribution lock into an effective service
36
- roster, brings up the backing infrastructure you don't already run, and
37
- supervises every service to readiness — over a **container** substrate
38
- (customers) or a **native** substrate (contributors). It is a thin bring-up
39
- coordinator: it resolves topology and sequences startup, delegating process
40
- lifecycle (restart, health, resource limits) to the substrate beneath it
41
- (Docker/Podman, or your own infra). It never becomes a second orchestrator.
33
+ ## When to use it
34
+
35
+ - Run a Xema installation on your machine or on Kubernetes (`up`, `dev`, `installation`).
36
+ - Author, publish and install biomes (`biome`).
37
+ - Drive a running platform: `login`, `run`, `plan`, `apply`, `export`, `import`, `status`, `logs`.
38
+ - Resolve, seal and check editions (`edition`; see [`edition/README.md`](edition/README.md)).
42
39
 
43
40
  ## Installation
44
41
 
@@ -46,409 +43,83 @@ lifecycle (restart, health, resource limits) to the substrate beneath it
46
43
  npm i -g @xemahq/xema
47
44
  ```
48
45
 
49
- ### Client mode vs developer mode
50
-
51
- A fresh install starts in **client mode**, for people who USE a Xema deployment:
52
- `login`, `apply`, `plan`, `run`, `shell`, `objects`, `status`, `logs`.
53
-
54
- The commands that stand a platform up locally — **`up`, `dev`, `serve`**, which
55
- the rest of this document is largely about — are the platform contributor's inner
56
- loop. They are fully functional in client mode but **hidden from `xema --help`**,
57
- so following the sections below without turning developer mode on gives you
58
- working commands that `--help` never mentions:
46
+ A fresh install is in client mode. `up`, `dev` and `serve` still work but are hidden from `xema --help` until you turn developer mode on:
59
47
 
60
48
  ```bash
61
49
  xema config set dev on # or: export XEMA_DEV=1
62
50
  ```
63
51
 
64
- `xema --help` states this in both modes, and `xema config get` explains which
65
- input decided it.
66
-
67
- ## Scaffold a config — `xema init`
68
-
69
- Generate a `xema.config.yaml` tailored to your scenario. Run it with no flags for
70
- a short interactive wizard, or `--preset` / `--yes` for scripted use:
52
+ ## Usage
71
53
 
72
54
  ```bash
73
- xema init # interactive wizard
74
- xema init --preset local-container --yes # full local stack in containers
75
- xema init --preset byo-infra # bring-your-own Postgres/Keycloak/object-store
76
- xema init --preset appliance # Kubernetes via Helm
77
- # --edition <id> picks a distribution edition (offered from xema-distributions);
78
- # --web enables the host shell; --output <path>; --force to overwrite.
55
+ xema init --preset local-container --yes # write xema.config.yaml
56
+ xema up # boot infra and services
57
+ xema status # workloads and health
58
+ xema logs <service> -f # stream one workload's logs
59
+ xema down # stop (add --purge to delete data volumes)
79
60
  ```
80
61
 
81
- The wizard walks you through:
82
-
83
- - **scenario** (containers / BYO-infra / appliance),
84
- - **edition** — which biomes make up the platform (`oss`, `core`, … described inline),
85
- - **infrastructure, per service** — for each of Postgres / Redis / Keycloak /
86
- object-store / etcd / search / Temporal, choose **auto** (xema launches it) or
87
- **external** (paste your connection URL), and each external URL is
88
- **connection-tested** (reachability),
89
- - **your own biomes** — add git repo(s) as sources (composed with the edition at
90
- launch).
91
-
92
- Every generated config is validated against the schema before it's written, so it
93
- can never be one `xema up` would reject.
94
-
95
- ## Launch the platform
96
-
97
- ```bash
98
- xema up # boot the backend (infra + services) as one supervised process
99
- xema up --web # also start the host-shell frontend
100
- xema up --all # everything, including the frontend
101
- xema up --detach # leave container workloads running and return
102
- xema down # stop everything (xema down --purge also deletes data volumes)
103
- xema status # show launcher-owned workloads + health
104
- xema logs <service> -f # stream a launcher-owned workload's logs
105
- ```
106
-
107
- Every verb works against the configured substrate — one verb set, pluggable
108
- target. `xema logs` streams from a launcher-owned container (`docker logs`) on
109
- the container substrate, from the owned release's Deployment
110
- (`kubectl logs deploy/<service>`) on the helm substrate, and on native points
111
- at the foreground `xema up` / `xema dev` console (that is where native
112
- services log).
62
+ | Command | Purpose |
63
+ | --- | --- |
64
+ | `xema init [--preset <name>] [--edition <id>] [--web] [--output <path>] [--yes] [--force]` | Scaffold `xema.config.yaml`; interactive without flags. |
65
+ | `xema up [--web] [--all] [--only <services>] [--detach] [--dry-run] [--edition <id>] [--config <path>]` | Boot the configured substrate. |
66
+ | `xema dev [services...] [--watch] [--web] [--dry-run]` | Native boot from source; a service list boots only those plus their prerequisites. |
67
+ | `xema serve --substrate single-instance\|cluster\|appliance` | Boot as separate processes. |
68
+ | `xema doctor [--infra] [--sources]` | Check the environment, backing services and biome sources (token presence only). |
69
+ | `xema biome scaffold\|install\|publish\|lint\|search\|list\|info\|remove` | Author and manage biomes. |
70
+ | `xema run <capability> [--input <json>]` | Invoke a capability. |
71
+ | `xema plan\|apply\|export\|import -f xema.yaml` | Declarative stacks (`--stack`, `--auto-approve` on apply). |
72
+ | `xema installation init\|validate\|plan\|apply\|verify\|status\|support-bundle` | Manage a `XemaInstallation` (`xema.installation.yaml`). |
73
+ | `xema login`, `logout`, `whoami` | Authenticate against a platform. |
113
74
 
114
- The launcher and automation use the same compiled desired state — one
115
- `XemaInstallation` document — and the target kind decides who executes it.
75
+ `xema <command> --help` lists every option.
116
76
 
117
- ### Installing on Kubernetes — the boring path
77
+ ### Kubernetes
118
78
 
119
79
  ```bash
120
- export XEMA_DEPLOYMENT_ENGINE=/path/to/xema-deploy/scripts/engine/cli.mjs # the ONE deployment engine
80
+ export XEMA_DEPLOYMENT_ENGINE=/path/to/xema-deploy/scripts/engine/cli.mjs
121
81
  xema installation init --profile single-node-production \
122
82
  --target customer-kubernetes --context <kubectl-context> --kubeconfig ./kubeconfig \
123
- --name acme-prod --edition oss
124
- # …fill in xema.installation.yaml: namespace, domains, external infrastructure…
125
- xema installation validate --file xema.installation.yaml # providers, then the deployment root
126
- xema installation plan --file xema.installation.yaml # what apply would change
127
- xema installation apply --file xema.installation.yaml # reconcile, wave by wave
128
- xema installation verify --file xema.installation.yaml # every release present and converged
129
- ```
130
-
131
- On a `customer-kubernetes` or `single-node-kubernetes` target every verb
132
- PROJECTS the installation into a deployment root — `deployment.yaml`,
133
- `infra.yaml`, `secret-inputs.yaml`, `values.yaml` and the edition's two lock
134
- files, under `~/.xema/installations/<name>/deployment/` or beside the
135
- installation file when that directory already holds a `deployment.yaml` —
136
- and runs `xema-deployment-engine` over it. The CLI never renders a chart,
137
- ranks a wave or reads a lock; the engine does. A declaration the root cannot
138
- carry is refused by name rather than dropped, and nothing in the root is ever a
139
- secret value.
140
-
141
- #### Getting the deployment engine
142
-
143
- `XEMA_DEPLOYMENT_ENGINE` resolves the engine, and it takes either the
144
- `xema-deployment-engine` bin itself or a package root whose `package.json`
145
- declares that bin.
146
-
147
- **Today it is the bin.** The engine ships as `scripts/engine/cli.mjs` in the
148
- `xema-dev/xema-deploy` repository — the checkout an operator running a managed
149
- Xema deployment already has — so point the variable at that file:
150
-
151
- ```bash
152
- export XEMA_DEPLOYMENT_ENGINE="$HOME/xema-deploy/scripts/engine/cli.mjs"
153
- xema-deployment-engine() { node "$XEMA_DEPLOYMENT_ENGINE" "$@"; } # optional, for running it by hand
83
+ --name my-install --edition oss
84
+ xema installation validate --file xema.installation.yaml
85
+ xema installation plan --file xema.installation.yaml
86
+ xema installation apply --file xema.installation.yaml
87
+ xema installation verify --file xema.installation.yaml
154
88
  ```
155
89
 
156
- Two things this README asserted until 2026-09-21 and should not have. There is
157
- no package to fetch: the name `@xemahq/deployment-engine` is served by no
158
- registry, so the `npm i -g` that used to open this section answered 404. And
159
- the package-root form does not reach a `xema-deploy` checkout either, because
160
- `scripts/engine/` carries no `package.json` — pointing the variable at the
161
- directory refuses with *"is a directory without a package.json"*. Point it at
162
- the file. The package-root form stays supported for the day the engine is
163
- published under a name of its own.
164
-
165
- Point it at the file *inside the checkout*, not at a copy of it: `cli.mjs`
166
- imports `../lib/*.mjs` from `scripts/lib/`, so the surrounding tree is part of
167
- the engine.
90
+ The CLI projects the installation into a deployment root and runs the deployment engine over it; without `XEMA_DEPLOYMENT_ENGINE` every Kubernetes verb refuses. Last-applied state is kept under `~/.xema/installations/<name>/`.
168
91
 
169
- Unset it and every Kubernetes verb refuses by name, with that same remedy,
170
- before anything is projected or spawned.
171
-
172
- ### Installing on this machine
92
+ ### Biomes
173
93
 
174
94
  ```bash
175
- xema installation plan # deterministic redacted change plan
176
- xema installation apply --detach # reconcile through the same launcher as `xema up`
177
- xema installation status # desired vs applied vs observed drift
178
- xema installation support-bundle # redacted JSON + SHA-256 integrity manifest
179
- ```
180
-
181
- Destructive transitions are refused unless explicitly reviewed and authorized
182
- with `--allow-destructive`; rejected identity/schema transitions and the
183
- profiles without a renderer (`business-ha`, `enterprise-regulated`,
184
- `hosted-cell`) remain fail-fast. Last-applied state is atomically stored
185
- under `~/.xema/installations/<installation-id>/`, while secret values are
186
- resolved before source or deployment side effects and are never persisted in
187
- plans or support bundles.
188
-
189
- ### Topology — `xema.config.yaml`
190
-
191
- The launcher reads an optional `xema.config.yaml` (or `~/.xema/config.yaml`)
192
- declaring **which infrastructure you own** and **what to run**. Every backing
193
- component is `managed` (the launcher starts it), `external` (you already run it —
194
- provide the URL), or `disabled`:
195
-
196
- ```yaml
197
- edition: oss
198
- infra:
199
- postgres:
200
- {
201
- mode: external,
202
- url: postgresql://xema@db.corp:5432,
203
- secretRef: postgres-password,
204
- }
205
- redis: { mode: managed }
206
- etcd: { mode: managed }
207
- keycloak: { mode: external, url: https://sso.corp/realms/xema, realm: xema }
208
- objectStore: { mode: external, url: https://s3.corp }
209
- search: { mode: managed }
210
- temporal: { mode: managed }
211
- secrets:
212
- postgres-password: { from: env, env: XEMA_POSTGRES_PASSWORD }
213
- app:
214
- substrate: container # container | native
215
- include: [all] # all | default | minimal | <tier> | [service ...]
216
- features: [] # curated capability bundles
217
- web: { enabled: true }
95
+ xema biome install <biomeId> --project <projectId> # or --org for in-process biomes
218
96
  ```
219
97
 
220
- - **`container`** (recommended): pulls content-addressed service images
221
- (`imageRef:contentHash`) and runs them on a shared network, after bringing up
222
- and bootstrapping managed infra — works without a monorepo checkout.
223
- - **`native`**: runs services as host processes against a built monorepo (the
224
- contributor inner loop). Equivalent: `xema serve --substrate single-instance`.
225
- - **`helm`**: deploys to Kubernetes via `helm upgrade --install` (the appliance /
226
- cluster target). Equivalent: `xema serve --substrate appliance`. `xema
227
- status` lists the installation's releases, `xema logs` streams them through
228
- `kubectl` (or the `k3s kubectl` applet a k3s appliance ships), and `xema
229
- down` uninstalls exactly the releases this installation owns.
98
+ Target and auth come from `--endpoint` / `--token` or `XEMA_ENDPOINT` / `XEMA_TOKEN`. Use `--install-config <file.json>` for install config and `--version <semver>` to pin.
230
99
 
231
- `xema up` fails fast on a missing required secret, an unreachable `external`
232
- dependency, or a disabled-but-mandatory infra component — never a silent
233
- degradation.
100
+ ## Configuration
234
101
 
235
- Managed local PostgreSQL and object-store credentials are generated uniquely
236
- per installation and retained under
237
- `~/.xema/installations/<installation-id>/managed-local-credentials.json` with
238
- directory mode `0700` and file mode `0600`. Repeated and concurrent launches
239
- reuse the same credentials; values are not written to config or command
240
- arguments. `xema down` preserves them with the data volumes, while
241
- `xema down --purge` removes both. A named volume created by an older CLI with
242
- fixed development credentials fails fast and requires that explicit purge
243
- before its first launch with credential custody.
102
+ `xema.config.yaml` is read from `--config <path>`, then `./xema.config.yaml`, then `~/.xema/config.yaml`, then built-in defaults. See [`xema.config.example.yaml`](xema.config.example.yaml) and [`examples/`](examples/README.md).
244
103
 
245
- External PostgreSQL credentials are never defaulted or persisted in the
246
- endpoint URL. Put the username in the URL and source the password through
247
- `secretRef`. A referenced secret must be declared under
248
- `secrets` and resolve from `env`, `file`, or an interactive masked `prompt`
249
- before Xema creates any deployment resources.
250
-
251
- Secret names that are valid environment-variable names are intentionally
252
- injected into every native/container service in the launch. Use a non-environment
253
- name such as `postgres-password` for launcher-only `secretRef` values. File
254
- sources must be regular, non-symlink files with no group/other permissions
255
- (`0600` or stricter); relative paths resolve from the directory containing
256
- `xema.config.yaml`. The Helm substrate does not accept launcher-resolved
257
- secrets: configure Kubernetes Secrets through each service chart instead.
258
-
259
- ### Credential custody — the local OpenBao
260
-
261
- The credential broker (`credential-broker-api`) refuses to boot without a
262
- deployment-selected custody provider. On the container and native substrates
263
- `xema up` therefore runs its own single-node OpenBao (`xema-openbao`, the
264
- official `openbao/openbao` image pinned by digest, integrated raft storage on the
265
- `xema-openbao-data` volume, published on `127.0.0.1:8200` only) whenever the
266
- roster contains the broker. On the first launch the CLI initialises it with a
267
- single unseal share and stores the unseal key and root token, encrypted, in
268
- `~/.xema/installations/<installation-id>/openbao-custody.json` (directory
269
- `0700`, file `0600`); they are never printed. Every later launch only unseals
270
- from the stored key, so `xema up` is idempotent. The CLI mounts a KV v2 engine
271
- at `xema-local`, writes a policy limited to `xema-local/{data,metadata}/xema/*`,
272
- and mints a scoped (non-root) token for the broker on each launch. The broker
273
- alone receives:
274
-
275
- | Variable | Value |
104
+ | Key | Values |
276
105
  | --- | --- |
277
- | `CUSTODY_PROVIDER_REF` | `openbao` |
278
- | `OPENBAO_ADDRESS` | `http://xema-openbao:8200` (container) or `http://127.0.0.1:8200` (native) |
279
- | `OPENBAO_AUTH_METHOD` | `token` |
280
- | `OPENBAO_TOKEN` | the scoped broker token |
281
- | `OPENBAO_MOUNT_PATH` | `xema-local` |
282
-
283
- `xema down` keeps the vault and its keys; `xema down --purge` removes both
284
- together. A vault whose keys are missing (or keys whose vault is gone) is
285
- reported with that instruction rather than re-initialised. The Helm substrate
286
- does not start a vault: the chart selects the provider.
287
-
288
- `xema dev` does not start a vault. It expects an OpenBao on `127.0.0.1:8200`
289
- (pre-flight checks the port) and an `OPENBAO_TOKEN` in your environment; it
290
- defaults the rest of the contract above.
291
-
292
- ### Realtime dev
293
-
294
- Xema always runs the `distributed` model: every service is its own process and
295
- peers discover each other through the KernelState adapter over etcd (native forks
296
- one child per service; container/helm run one workload each).
297
-
298
- For development, see code changes live — the composition restarts when service
299
- output changes (pair with each service's own `tsc -w` / `turbo watch`):
300
-
301
- ```bash
302
- xema dev --watch # boot from source; restart on any .ts change
303
- ```
304
-
305
- ### Launch one service (or a subset)
306
-
307
- Boot just the services you're working on — their hard prerequisites
308
- (`identity-api`, the foundational services) are pulled in automatically, so a
309
- lone service still boots a correct graph:
310
-
311
- ```bash
312
- xema dev agent-session-api memory-api # native: just these two (+ prerequisites)
313
- xema up --only app-platform-api # container: one service (+ prerequisites)
314
- xema serve --substrate cluster --only audit-log-api
315
- ```
316
-
317
- ### Biome sources — pull biomes from many origins
318
-
319
- A deployment's biomes can come from the first-party distribution, a cultivars
320
- edition, **a client's own private git repo or registry**, or a third party —
321
- each with its own auth — declared in a `sources:` block:
322
-
323
- ```yaml
324
- sources:
325
- - name: workspace # local working tree (monorepo): always wins
326
- kind: workspace
327
- - name: cultivars # a pinned edition lock
328
- kind: distribution
329
- edition: cultivars
330
- - name: acme # a client's OWN biome git repo (private)
331
- kind: git
332
- url: https://github.com/acme/xema-biomes.git
333
- ref: v2.1.0
334
- authTokenEnv: GIT_TOKEN_ACME # env-var NAME, never the secret
335
- ```
336
-
337
- Precedence: **`workspace` > other sources (declared order) > base distribution**.
338
- In a monorepo checkout the workspace source always wins, so `xema dev` runs your
339
- local edits with **no publish** and **no token** required. Tokens for private
340
- sources are referenced by env-var _name_ (the `biome-fetcher` convention) and
341
- resolved from the environment or a git-ignored `~/.xema/credentials.env` — never
342
- inlined in config. `npm`/`oci` sources are install-time (the `xema biome install`
343
- path); `workspace`/`distribution`/`git` boot directly from `xema up`/`dev`.
344
-
345
- Check every source + token before launching:
346
-
347
- ```bash
348
- xema doctor --sources # per source: target, launch-vs-install, token present? (redacted)
349
- ```
350
-
351
- A full example lives at [`examples/06-biome-sources.yaml`](examples/06-biome-sources.yaml).
352
-
353
- ### The standard biome structure (one shape, open features)
354
-
355
- Sources discover biomes by walking for `xema-biome.json` — a repo may hold ONE
356
- biome at its root or MANY nested; both are valid layouts of the **same
357
- standard**. A biome is a directory with a manifest at its root; its services
358
- live at the manifest-declared `ships.apis[].path` (convention `./api/<name>`).
359
- What a biome _does_ (services, skills, capabilities, agents) is wholly open —
360
- only the bundle _shape_ is standardized, so every author builds the same way and
361
- any source resolves the same way.
362
-
363
- ## Resolve and check an edition — `xema edition`
364
-
365
- ```bash
366
- xema edition resolve <id> [--check] # the release lock set (distribution, authorization, chart-set, images)
367
- xema edition seal <id> # seal the image digests
368
- xema edition develop <subcommand> ... # develop editions: resolve a snapshot into the edition artifact files
369
- xema edition artifact <id> --channel release --registry <ns> --coordinate <tag> --engine-image <repo>@sha256:<digest> --out <dir>
370
- # the release edition artifact files, from the committed sealed locks
371
- xema edition index biome|platform-service|runtime-image-source [--check]
372
- xema edition check # the committed locks and indices are current
373
- xema edition why <id> <biome> # why a biome is in an edition
374
- xema edition verify-platforms <id> # the registry serves every required platform
375
- xema edition checkout-sources # check out the sources the image index pins
376
- ```
377
-
378
- Every verb takes the six roots (`--data-root`, `--editions-root`, `--sources-root`, `--kernel`,
379
- `--deploy-root`, `--cache-dir`); see `edition/README.md` for which verb needs which.
380
-
381
- ### The edition protocol — what ties this CLI to a kernel
382
-
383
- The CLI is coupled to the kernel's **edition protocol**, not to the whole kernel package.
384
- `@xemahq/contracts` exports the protocol's identity as data
385
- (`@xemahq/contracts/edition-protocol/edition-protocol.json`): a version and a content digest over
386
- the exact bytes of every kernel source file the protocol's entry subpaths load at runtime (the
387
- schemas and every refinement, parser, resolver and composer behind them), derived from the
388
- kernel's import graph. This CLI declares the protocol versions it supports, each pinned to one
389
- digest, and vendors each supported contract (the identity, the entry subpaths and the source
390
- paths); it loads no kernel subpath outside those entry subpaths. `xema edition check` and every
391
- other verb compare only that identity with the `--kernel` they are given, and refuse any other,
392
- naming the versions this CLI supports and the version the kernel declares.
393
-
394
- The digest is a CONSERVATIVE, deterministic stand-in for protocol semantics. Any change to
395
- accepted or refused edition semantics MUST change it; a behaviour-preserving refactor MAY change
396
- it too, and the cost is a repin, which is accepted. Semantic equivalence isn't computable, so it
397
- is never detected.
398
-
399
- A kernel change outside the protocol's source files keeps the identity, so it needs no CLI
400
- release. An edition protocol change needs a CLI that supports it, so the order is: **the CLI
401
- release that supports the new protocol goes first, then the data root repins its kernel
402
- authority** to a kernel that speaks it.
403
-
404
- ## Author biomes & run capabilities
405
-
406
- ```bash
407
- xema dev # lock-driven native dev boot (contributors)
408
- xema biome scaffold <name> # author a new biome
409
- xema biome publish <path> # ship a biome
410
- xema run <capability> # invoke a capability by name
411
- xema doctor # diagnose your environment
412
- ```
413
-
414
- Install a catalog biome into a running platform (by id — the biome's bundle
415
- source is resolved server-side from its registered manifest; npm/OCI biomes
416
- require a project):
417
-
418
- ```bash
419
- xema biome install <biomeId> --project <projectId> # npm/OCI + any catalog biome
420
- xema biome install <biomeId> --org # in-process / kernel biomes only
421
- # target + auth: --endpoint/--token or env XEMA_ENDPOINT / XEMA_TOKEN
422
- # --config <file.json> for install config, --version <semver> to pin
423
- ```
424
-
425
- The CLI never sends a registry token: a private source's `authTokenEnv` is read
426
- by `biome-fetcher-api` in the platform's own environment, so the token lives on
427
- the cluster, not in the install call.
428
-
429
- ## Xema-as-Code — declarative stacks
430
-
431
- Drive a running control plane from a `xema.yaml` manifest (orgs, roles,
432
- deliverable-specs, biome-installs, …) — plan/apply/export/import, GitOps-style:
433
-
434
- ```bash
435
- xema plan -f xema.yaml # preview the change set (read-only)
436
- xema apply -f xema.yaml # apply it (--auto-approve to skip the prompt)
437
- xema export --stack <name> -o xema.yaml # snapshot a live stack to a manifest
438
- xema import -f xema.yaml # adopt existing resources into a stack
439
- # target + auth: --endpoint/--token or env XEMA_ENDPOINT / XEMA_TOKEN
440
- ```
441
-
442
- ## Diagnose
443
-
444
- ```bash
445
- xema doctor # node version + ~/.xema/ + dev KernelState
446
- xema doctor --infra # also TCP-probe Postgres / Redis / event-hub-api
447
- xema doctor --sources # list biome sources + per-source token presence (redacted)
448
- ```
106
+ | `edition` | Distribution edition id (default `oss`). |
107
+ | `infra.<component>.mode` | `managed`, `external` (with `url`, optional `secretRef`) or `disabled`. Components: `postgres`, `redis`, `etcd`, `keycloak`, `objectStore`, `fga`, `git`, `temporal`. |
108
+ | `app.substrate` | `container`, `native` or `helm`. |
109
+ | `app.include` / `app.exclude` | `default`, `all`, tier names or service names / service names to drop. |
110
+ | `app.features` | Curated capability bundles. |
111
+ | `app.web.enabled` | Start the host-shell frontend. |
112
+ | `secrets.<name>` | `{ from: env \| file \| prompt }`; files must be mode `0600` or stricter. |
113
+ | `sources[]` | Biome sources: `kind: workspace \| distribution \| git`, with `authTokenEnv` naming an environment variable (never the token). |
114
+
115
+ | Environment | Purpose |
116
+ | --- | --- |
117
+ | `XEMA_DEV` | Developer mode on or off. |
118
+ | `XEMA_ENDPOINT`, `XEMA_TOKEN` | Platform API and bearer token for client commands. |
119
+ | `XEMA_DEPLOYMENT_ENGINE` | Deployment engine bin for Kubernetes installations. |
120
+ | `XEMA_NAMESPACE` | Kubernetes namespace (default `xema`). |
121
+ | `XEMA_MANAGED_LOCAL_KEY_PROVIDER`, `XEMA_MANAGED_LOCAL_RECOVERY_KEY` | Managed-local secret custody on headless hosts. |
449
122
 
450
123
  ## License
451
124
 
452
- Apache-2.0 &copy; Neuralchowder Inc. — [xema.dev](https://xema.dev). `@xemahq/xema`
453
- is the open developer/operator tool tier (like the Xema SDKs), distributed under
454
- the Apache License 2.0. See [LICENSE](../../LICENSE) / [NOTICE](../../NOTICE).
125
+ Apache-2.0 &copy; Xema &mdash; [xema.dev](https://xema.dev)
@@ -7,7 +7,7 @@ const verb_map_1 = require("../runtime/edition/verb-map");
7
7
  const VERB_SUMMARY = {
8
8
  [verb_map_1.EditionVerb.Resolve]: 'Resolve the whole release lock set of an edition: xema edition resolve <id> [--check]; or a customer edition against the catalogue pinned in catalogue.pin.json beside the definition: xema edition resolve --definition <file> --channel <release|develop> --out <dir> [--source-image <source>=<registry>/<prefix>]...',
9
9
  [verb_map_1.EditionVerb.Seal]: 'Seal the image digests of an edition: xema edition seal <id> [--definition <file>] (a customer edition seals against the release catalogue pinned in catalogue.pin.json beside the definition)',
10
- [verb_map_1.EditionVerb.Develop]: 'Resolve a develop edition snapshot: xema edition develop <resolve|target|freeze-graph|freeze-sources|check-existing|check-overrides> ...; or a customer develop edition (catalogue pinned in catalogue.pin.json beside the definition): xema edition develop <resolve|target|check-existing|freeze-sources|kernel-commit> --definition <file> ... (resolve: --pins <file> --out <dir> --registry <root> --engine-image <repo>@sha256:<digest> [--source-image <source>=<registry>/<prefix>]...; kernel-commit prints the contract authority source commit of the catalogue)',
10
+ [verb_map_1.EditionVerb.Develop]: 'Resolve a develop edition snapshot: xema edition develop <resolve|target|freeze-graph|freeze-sources|check-existing|check-overrides> ...; or a customer develop edition (catalogue pinned in catalogue.pin.json beside the definition): xema edition develop <resolve|target|check-existing|freeze-sources> --definition <file> ... (resolve: --pins <file> --out <dir> --registry <root> --engine-image <repo>@sha256:<digest> [--source-image <source>=<registry>/<prefix>]...)',
11
11
  [verb_map_1.EditionVerb.Artifact]: 'Write the OCI artifact files of a release edition from the committed sealed locks: xema edition artifact <id> --channel release --registry <root> --coordinate <tag> --engine-image <repo>@sha256:<digest> --out <dir>',
12
12
  [verb_map_1.EditionVerb.Catalogue]: 'Write the catalogue.json of a release offering from its committed sealed locks: xema edition catalogue <id> --out <dir>',
13
13
  [verb_map_1.EditionVerb.Index]: `Rebuild a catalogue index: xema edition index <${Object.values(verb_map_1.EditionIndexKind).join('|')}> [--check]; xema edition index runtime-image-source --repin-contract-authority --kernel-commit <40-hex> replaces only the contract authority of the committed index with the kernel checkout's at the stated commit (its HEAD must equal it)`,
@@ -19,8 +19,8 @@ const VERB_SUMMARY = {
19
19
  [verb_map_1.EditionVerb.VerifyEvidence]: 'Verify the signed image evidence of an edition with the pinned verifier bundle: xema edition verify-evidence <id> --evidence-root <dir> --descriptor <path> --state <path> --cosign <path> --git <path> [--json] --data-root <dir> --editions-root <dir> --kernel <dir>',
20
20
  [verb_map_1.EditionVerb.Evidence]: `Build, accept and plan image evidence (never signs): xema edition evidence <${Object.values(verb_map_1.EditionEvidenceKind).join('|')}> …`,
21
21
  [verb_map_1.EditionVerb.List]: 'Print the offering ids of an editions root as JSON: xema edition list --editions-root <dir>',
22
- [verb_map_1.EditionVerb.Locks]: 'Print the validated locks of an edition as JSON: xema edition locks <id> --data-root <dir> --editions-root <dir> --kernel <dir>',
23
- [verb_map_1.EditionVerb.ChartSet]: `Pin the chart set of the editions to the charts the registry serves: xema edition chart-set <${Object.values(verb_map_1.EditionChartSetOperation).join('|')}> [--check] --data-root <dir> --editions-root <dir> --deploy-root <dir> --kernel <dir>; source-commit prints the commit each publisher closed its locked set at (--data-root, --kernel)`,
22
+ [verb_map_1.EditionVerb.Locks]: 'Print the validated locks of an edition as JSON: xema edition locks <id> --channel <release|develop> --data-root <dir> --editions-root <dir> --kernel <dir>',
23
+ [verb_map_1.EditionVerb.ChartSet]: `Pin the chart set of the editions to the charts the registry serves: xema edition chart-set <${Object.values(verb_map_1.EditionChartSetOperation).join('|')}> [--check] --data-root <dir> --editions-root <dir> --kernel <dir>; source-commit prints the commit each publisher closed its locked set at (--data-root, --kernel)`,
24
24
  [verb_map_1.EditionVerb.BiomeManifests]: 'Print the pinned xema-biome.json of every biome of an edition as JSON: xema edition biome-manifests <id> --json --data-root <dir> --editions-root <dir> --sources-root <dir> --kernel <dir>',
25
25
  [verb_map_1.EditionVerb.Arming]: 'Print whether the data root evidence trust policy is armed on one channel as one JSON line, exiting 0 only when armed: xema edition arming --channel <release|develop> --data-root <dir> --kernel <dir>',
26
26
  [verb_map_1.EditionVerb.SourceClosure]: 'Print the source tree hash and workspace closure of a source directory at a commit as JSON: xema edition source-closure --repo <repo> --path <dir> --commit <sha> --sources-root <dir> --kernel <dir>',
@@ -1 +1 @@
1
- {"version":3,"file":"edition.js","sourceRoot":"","sources":["../../src/commands/edition.ts"],"names":[],"mappings":";;AAyCA,0CAiBC;AA1DD,kDAA8D;AAC9D,4DAA8D;AAC9D,0DAA2H;AAW3H,MAAM,YAAY,GAA0C;IAC1D,CAAC,sBAAW,CAAC,OAAO,CAAC,EACnB,0TAA0T;IAC5T,CAAC,sBAAW,CAAC,IAAI,CAAC,EAAE,gMAAgM;IACpN,CAAC,sBAAW,CAAC,OAAO,CAAC,EAAE,6iBAA6iB;IACpkB,CAAC,sBAAW,CAAC,QAAQ,CAAC,EACpB,wNAAwN;IAC1N,CAAC,sBAAW,CAAC,SAAS,CAAC,EAAE,yHAAyH;IAClJ,CAAC,sBAAW,CAAC,KAAK,CAAC,EAAE,kDAAkD,MAAM,CAAC,MAAM,CAAC,2BAAgB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,+OAA+O;IAC/V,CAAC,sBAAW,CAAC,KAAK,CAAC,EAAE,yDAAyD;IAC9E,CAAC,sBAAW,CAAC,GAAG,CAAC,EAAE,qEAAqE;IACxF,CAAC,sBAAW,CAAC,eAAe,CAAC,EAAE,qGAAqG;IACpI,CAAC,sBAAW,CAAC,eAAe,CAAC,EAAE,wEAAwE;IACvG,CAAC,sBAAW,CAAC,kBAAkB,CAAC,EAAE,mIAAmI;IACrK,CAAC,sBAAW,CAAC,cAAc,CAAC,EAC1B,yQAAyQ;IAC3Q,CAAC,sBAAW,CAAC,QAAQ,CAAC,EAAE,+EAA+E,MAAM,CAAC,MAAM,CAAC,8BAAmB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK;IACxJ,CAAC,sBAAW,CAAC,IAAI,CAAC,EAAE,6FAA6F;IACjH,CAAC,sBAAW,CAAC,KAAK,CAAC,EAAE,iIAAiI;IACtJ,CAAC,sBAAW,CAAC,QAAQ,CAAC,EAAE,gGAAgG,MAAM,CAAC,MAAM,CAAC,mCAAwB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,yLAAyL;IAClW,CAAC,sBAAW,CAAC,cAAc,CAAC,EAC1B,6LAA6L;IAC/L,CAAC,sBAAW,CAAC,MAAM,CAAC,EAClB,yMAAyM;IAC3M,CAAC,sBAAW,CAAC,aAAa,CAAC,EACzB,uMAAuM;CAC1M,CAAC;AAEF,SAAgB,eAAe,CAAC,OAAgB;IAC9C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;IACvF,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,sBAAW,CAAC,EAAE,CAAC;QAC9C,OAAO;aACJ,OAAO,CAAC,IAAI,CAAC;aACb,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;aAC/B,QAAQ,CAAC,WAAW,EAAE,0DAA0D,CAAC;aACjF,kBAAkB,EAAE;aACpB,MAAM,CAAC,CAAC,IAAc,EAAE,EAAE;YACzB,IAAI,CAAC;gBACH,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAA,0BAAc,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBAChD,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAA,qBAAQ,EAAC,4BAAe,CAAC,YAAY,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACjG,CAAC;QACH,CAAC,CAAC,CAAC;IACP,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"edition.js","sourceRoot":"","sources":["../../src/commands/edition.ts"],"names":[],"mappings":";;AAyCA,0CAiBC;AA1DD,kDAA8D;AAC9D,4DAA8D;AAC9D,0DAA2H;AAW3H,MAAM,YAAY,GAA0C;IAC1D,CAAC,sBAAW,CAAC,OAAO,CAAC,EACnB,0TAA0T;IAC5T,CAAC,sBAAW,CAAC,IAAI,CAAC,EAAE,gMAAgM;IACpN,CAAC,sBAAW,CAAC,OAAO,CAAC,EAAE,mdAAmd;IAC1e,CAAC,sBAAW,CAAC,QAAQ,CAAC,EACpB,wNAAwN;IAC1N,CAAC,sBAAW,CAAC,SAAS,CAAC,EAAE,yHAAyH;IAClJ,CAAC,sBAAW,CAAC,KAAK,CAAC,EAAE,kDAAkD,MAAM,CAAC,MAAM,CAAC,2BAAgB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,+OAA+O;IAC/V,CAAC,sBAAW,CAAC,KAAK,CAAC,EAAE,yDAAyD;IAC9E,CAAC,sBAAW,CAAC,GAAG,CAAC,EAAE,qEAAqE;IACxF,CAAC,sBAAW,CAAC,eAAe,CAAC,EAAE,qGAAqG;IACpI,CAAC,sBAAW,CAAC,eAAe,CAAC,EAAE,wEAAwE;IACvG,CAAC,sBAAW,CAAC,kBAAkB,CAAC,EAAE,mIAAmI;IACrK,CAAC,sBAAW,CAAC,cAAc,CAAC,EAC1B,yQAAyQ;IAC3Q,CAAC,sBAAW,CAAC,QAAQ,CAAC,EAAE,+EAA+E,MAAM,CAAC,MAAM,CAAC,8BAAmB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK;IACxJ,CAAC,sBAAW,CAAC,IAAI,CAAC,EAAE,6FAA6F;IACjH,CAAC,sBAAW,CAAC,KAAK,CAAC,EAAE,6JAA6J;IAClL,CAAC,sBAAW,CAAC,QAAQ,CAAC,EAAE,gGAAgG,MAAM,CAAC,MAAM,CAAC,mCAAwB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,qKAAqK;IAC9U,CAAC,sBAAW,CAAC,cAAc,CAAC,EAC1B,6LAA6L;IAC/L,CAAC,sBAAW,CAAC,MAAM,CAAC,EAClB,yMAAyM;IAC3M,CAAC,sBAAW,CAAC,aAAa,CAAC,EACzB,uMAAuM;CAC1M,CAAC;AAEF,SAAgB,eAAe,CAAC,OAAgB;IAC9C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;IACvF,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,sBAAW,CAAC,EAAE,CAAC;QAC9C,OAAO;aACJ,OAAO,CAAC,IAAI,CAAC;aACb,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;aAC/B,QAAQ,CAAC,WAAW,EAAE,0DAA0D,CAAC;aACjF,kBAAkB,EAAE;aACpB,MAAM,CAAC,CAAC,IAAc,EAAE,EAAE;YACzB,IAAI,CAAC;gBACH,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAA,0BAAc,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBAChD,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAA,qBAAQ,EAAC,4BAAe,CAAC,YAAY,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACjG,CAAC;QACH,CAAC,CAAC,CAAC;IACP,CAAC;AACH,CAAC"}