@ornncompute/cli 0.2.24 → 1.0.25

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 (85) hide show
  1. package/README.md +298 -426
  2. package/package.json +12 -6
  3. package/src/admin-capacity-reservations.mjs +280 -0
  4. package/src/admin-command-handlers.mjs +57 -0
  5. package/src/admin-enrollment.mjs +680 -0
  6. package/src/admin-mutations.mjs +187 -0
  7. package/src/admin-node-diagnostics.mjs +412 -0
  8. package/src/admin-node-lifecycle.mjs +908 -0
  9. package/src/admin-shell.mjs +322 -0
  10. package/src/api-client.mjs +81 -28
  11. package/src/atomic-output.mjs +112 -0
  12. package/src/auth-store.mjs +182 -11
  13. package/src/capability-catalog.mjs +7 -0
  14. package/src/catalog-shell.mjs +1350 -0
  15. package/src/cli.mjs +123 -10266
  16. package/src/connect-mode-handlers.mjs +170 -0
  17. package/src/device-auth.mjs +178 -61
  18. package/src/evidence-commands.mjs +1340 -0
  19. package/src/external-bucket-commands.mjs +1374 -0
  20. package/src/interaction-runtime.mjs +310 -0
  21. package/src/kubernetes-commands.mjs +2229 -0
  22. package/src/launch-mode-handlers.mjs +119 -0
  23. package/src/machine-reference.mjs +277 -0
  24. package/src/mount-commands.mjs +1146 -0
  25. package/src/session-commands.mjs +565 -0
  26. package/src/slurm-commands.mjs +263 -0
  27. package/src/startup.mjs +34 -11
  28. package/src/storage-commands.mjs +1144 -0
  29. package/src/update.mjs +172 -24
  30. package/src/vm-commands.mjs +4273 -0
  31. package/src/vpn-secret-output.mjs +150 -0
  32. package/src/wait-runtime.mjs +231 -0
  33. package/vendor/capabilities/capabilities/admin-capacity-reservations.js +126 -0
  34. package/vendor/capabilities/capabilities/admin-enrollment.js +321 -0
  35. package/vendor/capabilities/capabilities/admin-node-diagnostics.js +88 -0
  36. package/vendor/capabilities/capabilities/admin-nodes-lifecycle.js +235 -0
  37. package/vendor/capabilities/capabilities/admin.js +89 -0
  38. package/vendor/capabilities/capabilities/capacity-offers.js +368 -0
  39. package/vendor/capabilities/capabilities/cli.js +156 -0
  40. package/vendor/capabilities/capabilities/clusters.js +150 -1
  41. package/vendor/capabilities/capabilities/compute.js +522 -0
  42. package/vendor/capabilities/capabilities/evidence.js +145 -0
  43. package/vendor/capabilities/capabilities/external-buckets.js +191 -0
  44. package/vendor/capabilities/capabilities/fleet.js +21 -5
  45. package/vendor/capabilities/capabilities/identity.js +114 -3
  46. package/vendor/capabilities/capabilities/listings.js +14 -8
  47. package/vendor/capabilities/capabilities/mounts.js +176 -0
  48. package/vendor/capabilities/capabilities/networks.js +1257 -0
  49. package/vendor/capabilities/capabilities/observability.js +38 -8
  50. package/vendor/capabilities/capabilities/tokens.js +20 -8
  51. package/vendor/capabilities/capabilities/volumes.js +178 -0
  52. package/vendor/capabilities/capability.js +19 -13
  53. package/vendor/capabilities/cli-catalog.js +65 -0
  54. package/vendor/capabilities/cli-migrations.js +288 -0
  55. package/vendor/capabilities/cli.js +7 -0
  56. package/vendor/capabilities/software-catalog.js +36 -0
  57. package/vendor/capabilities/spec-catalog.js +2 -2
  58. package/src/catalog-dispatch.mjs +0 -605
  59. package/src/color.mjs +0 -71
  60. package/vendor/capabilities/capabilities/clusters.d.ts +0 -2
  61. package/vendor/capabilities/capabilities/fleet.d.ts +0 -8
  62. package/vendor/capabilities/capabilities/identity.d.ts +0 -3
  63. package/vendor/capabilities/capabilities/listings.d.ts +0 -51
  64. package/vendor/capabilities/capabilities/observability.d.ts +0 -5
  65. package/vendor/capabilities/capabilities/staff-access.d.ts +0 -29
  66. package/vendor/capabilities/capabilities/staff-access.js +0 -278
  67. package/vendor/capabilities/capabilities/staff-commerce.d.ts +0 -160
  68. package/vendor/capabilities/capabilities/staff-commerce.js +0 -689
  69. package/vendor/capabilities/capabilities/staff-fleet.d.ts +0 -140
  70. package/vendor/capabilities/capabilities/staff-fleet.js +0 -538
  71. package/vendor/capabilities/capabilities/staff-gtm.d.ts +0 -142
  72. package/vendor/capabilities/capabilities/staff-gtm.js +0 -521
  73. package/vendor/capabilities/capabilities/staff-shared.d.ts +0 -47
  74. package/vendor/capabilities/capabilities/staff-shared.js +0 -98
  75. package/vendor/capabilities/capabilities/tokens.d.ts +0 -10
  76. package/vendor/capabilities/capabilities/users.d.ts +0 -2
  77. package/vendor/capabilities/capability.d.ts +0 -93
  78. package/vendor/capabilities/catalog.d.ts +0 -3
  79. package/vendor/capabilities/catalog.js +0 -26
  80. package/vendor/capabilities/index.d.ts +0 -16
  81. package/vendor/capabilities/index.js +0 -16
  82. package/vendor/capabilities/names.d.ts +0 -6
  83. package/vendor/capabilities/role.d.ts +0 -6
  84. package/vendor/capabilities/role.js +0 -17
  85. package/vendor/capabilities/spec-catalog.d.ts +0 -78
package/README.md CHANGED
@@ -1,453 +1,325 @@
1
1
  # Ornn CLI
2
2
 
3
- Command-line access for Ornn compute workflows: browse Listings, buy capacity,
4
- bid in Exchange, manage GPU reservations, launch VM or Bare Metal machines,
5
- create Kubernetes or Slurm clusters, manage private networks and storage
6
- volumes, attach SSH keys, SSH into launched machines, watch machine health
7
- metrics, and view billing readouts.
3
+ `@ornncompute/cli` installs the `ornn` command. The CLI is a catalog-backed
4
+ client for customer compute journeys and the explicit staff namespace. It
5
+ sends browser and CLI traffic only through the API gateway.
8
6
 
9
- For the end-user install, browser-login, command, and troubleshooting guide, see
10
- the [`docs/cli.md`](../../docs/cli.md) guide.
7
+ For the customer install and usage guide, see [`docs/cli.md`](../../docs/cli.md).
8
+ The shared capability catalog in `packages/capabilities` is the authority for
9
+ command identity, role visibility, input schemas, help, and resource discovery.
10
+ The CLI imports `@ornn/capabilities/cli`; packaging includes only that entrypoint's
11
+ dependencies, excluding staff bidding and CRM handlers.
11
12
 
12
- ## 0.2.24 storage compatibility update
13
+ For GCS imports, start with the [source-bucket permissions and version-specific CLI guide](https://docs.ornn.com/cli#gcs-imports-and-storage-transfer-service).
14
+ It documents Ornn's Storage Transfer service agent, the required `gcloud` IAM
15
+ grants, and the current CLI 1.x GCS verification limitation. Scoped
16
+ `ornn help external-buckets connect`, `verify`, and `import` help links to the
17
+ same guide.
13
18
 
14
- Version 0.2.24 restores file uploads against the current Ornn API, including
15
- completion and cancellation. Run `ornn update`, then use the existing command:
19
+ ## Install and sign in
20
+
21
+ Node.js 20 or newer is required.
16
22
 
17
23
  ```bash
18
- ornn storage files upload <drive-id> ./data.json --destination datasets/data.json
24
+ npm install -g @ornncompute/cli
25
+ ornn login
26
+ ornn context
27
+ ```
28
+
29
+ `ornn login` uses the browser device flow. Login links must use HTTP(S) on the configured authentication origin. Use `--no-browser` when the CLI must
30
+ print the URL instead of opening it. Session and endpoint configuration remains
31
+ in `~/.config/ornn`; the gateway re-derives organization and role scope from the
32
+ bearer on every request.
33
+
34
+ ## Command map
35
+
36
+ The three primary customer journeys are:
37
+
38
+ ```text
39
+ ornn launch # launch VM, Bare Metal, Kubernetes, or Slurm
40
+ ornn connect # derive SSH, kubeconfig, or Slurm-native access
41
+ ornn check # lifecycle, health, reachability, metrics, and logs
42
+ ```
43
+
44
+ Session and platform commands are:
45
+
46
+ ```text
47
+ ornn login
48
+ ornn context
49
+ ornn logout
50
+ ornn status
51
+ ornn version
52
+ ornn update [--major]
53
+ ornn completion <bash|fish|zsh> --format human
54
+ ornn resources
55
+ ```
56
+
57
+ Advanced customer resources are registered under one noun and one verb:
58
+
59
+ ```text
60
+ capacity-offers list | forecast | show
61
+ machines list | show | wait | switch | reboot | reset | metrics | logs
62
+ clusters list | show | wait | eligible-machines | add-node | remove-node | teardown | metrics | logs
63
+ ssh-keys list | add | delete
64
+ ssh-keys assignments list | assign | sync | status
65
+ private-networks list | show | create | update | delete
66
+ vpn-connections list | configure | disconnect
67
+ volumes list | show | create | refresh | clear | delete
68
+ volumes files list | upload | download | delete
69
+ volumes folders delete
70
+ volume-mounts candidates | show | attach | wait | detach
71
+ external-buckets list | show | connect | update-credentials | verify | import | disconnect
72
+ filesystems deploy | show | wait | delete
19
73
  ```
20
74
 
21
- Uploads update the Ornn-managed volume. Connected external source buckets are
22
- not modified.
75
+ Listing discovery is read-only: list, inspect, and forecast capacity, including
76
+ advertised prices. Purchases, bids, payments, resale, billing, and commercial
77
+ reservation management use the web app. Launch consumes already allocated
78
+ capacity; internal reservation lookups remain necessary for access and ownership.
79
+
80
+ Only admins can create listings or reservations through
81
+ `ornn admin capacity-offers create` and `ornn admin reservations create`.
82
+ The CLI and gateway both enforce the admin role before mutation. Both commands
83
+ retain explicit commercial-term validation and default-no human confirmation.
84
+
85
+ All staff discovery and execution starts at `ornn admin`. A fresh staff preflight
86
+ runs before the catalog is shown. The seven roots are:
87
+
88
+ ```text
89
+ ornn admin users
90
+ ornn admin operators
91
+ ornn admin facilities
92
+ ornn admin nodes
93
+ ornn admin enrollment-tokens
94
+ ornn admin capacity-offers
95
+ ornn admin reservations
96
+ ```
97
+
98
+ Every `ornn admin` command, read or mutation, requires an admin session.
99
+ `ornn admin nodes enroll` takes optional `--filter COMPARTMENT_IDS`
100
+ (omit to run every compartment step); the retired `--mode` flag is gone. The
101
+ gateway, not CLI metadata, authoritatively enforces the admin role.
23
102
 
24
- ## Install
103
+ Token revocation looks up the token by ID, including tokens outside the newest
104
+ 500-row list. Creation-time checks and safe retries still apply.
105
+
106
+ ## Catalog-generated discovery
25
107
 
26
108
  ```bash
27
- curl -fsSL https://compute.ornn.com/cli/install | sh
109
+ ornn
110
+ ornn help
111
+ ornn help machines
112
+ ornn machines --help
113
+ ornn help machines reset
114
+ ornn resources --format json
115
+ ornn completion bash --format human > ~/.local/share/bash-completion/completions/ornn
116
+ ornn admin
28
117
  ```
29
118
 
30
- The installer requires Node.js 20 or newer and npm. It installs `@ornncompute/cli`
31
- globally, exposes the `ornn` binary, adds the npm global bin directory to the
32
- user's shell profile when needed, and records the web browser handoff as
33
- `authBaseUrl` plus the API gateway as `apiBaseUrl` in
34
- `~/.config/ornn/config.json`. The
35
- installer prints a short Ornn Compute welcome banner and next steps; set
36
- `ORNN_INSTALL_BANNER=0` to skip it or `ORNN_INSTALL_ANIMATION=0` to keep it
37
- static.
38
-
39
- `ornn whoami`, `ornn logout`, and `ornn status` call the API gateway's
40
- `/v1/cli/session` and `/v1/cli/status` contracts. The gateway resolves the CLI
41
- bearer itself; it never trusts caller-supplied identity or authorization-admin
42
- headers. Logout asks the gateway to revoke the remote credential, then always
43
- clears the local bearer. If revocation cannot be confirmed, the CLI reports
44
- that the remote credential may remain active. Updated legacy installs that
45
- saved only a deployed web/auth
46
- origin map that known Ornn origin to its API gateway automatically; custom and
47
- localhost combined endpoints are left unchanged.
48
-
49
- ## First machine
119
+ Root help, scoped help, suggestions, and the advanced-resource index are
120
+ rendered from the same catalog bindings used for dispatch. Customer discovery
121
+ never contains admin children. There is no second parser or command registry.
122
+
123
+ ## Interaction contract
124
+
125
+ An eligible human context requires TTY stdin and TTY stdout and no JSON/NDJSON
126
+ format. Human commands may guide selection, render a normalized review, and ask
127
+ default-no `[y/N]` consent. Empty input, EOF, and refusal submit nothing.
128
+
129
+ Automation supplies complete semantic inputs and an explicit format:
50
130
 
51
131
  ```bash
52
- ornn login
53
- ornn listings forecast
54
- ornn buy <listing-id>
55
- # Complete checkout in the browser, then:
56
- ornn gpus list
57
- ornn nodes launch --interactive --wait
58
- ornn nodes list
59
- ornn ssh <machine-hostname>
132
+ ornn status --format json
133
+ ornn machines list --limit 100 --format ndjson
134
+ ornn launch RESERVATION_ID --mode vm --yes \
135
+ --idempotency-key caller-stable-key --format json
60
136
  ```
61
137
 
62
- Use `ornn exchange create --interactive` instead of `ornn buy` to place a bid.
63
- Guided creation is explicit and TTY-only; flag-based commands remain canonical
64
- for scripts.
138
+ Redirected commands require `--format human`, `--format json`, or
139
+ `--format ndjson`. The retired `--json` alias is rejected. Machine mode never
140
+ prompts or launches a browser. Inputs missing for a safe decision fail before
141
+ network, browser, or process I/O.
142
+
143
+ Global interaction modifiers are `--format`, `--guided`, `--yes`, `--wait`,
144
+ `--no-wait`, `--timeout`, `--no-browser`, `--overwrite`, and
145
+ `--idempotency-key`. Mutations that create or increase spend, erase data, tear
146
+ down resources, or reduce access require consent. Machine retries require a
147
+ caller-stable idempotency key and reconcile against durable owner state.
148
+
149
+ Permanent deletion and teardown requests never fire without consent. Private
150
+ networks, detached volumes, filesystem deployments, and Kubernetes or Slurm
151
+ clusters accept `--yes` for automation or ask an eligible human for default-no
152
+ confirmation. Clearing a volume or deleting nested content is live-terminal
153
+ only and always asks, even when `--yes` is present.
154
+
155
+ List commands use bounded `--limit` values and opaque `--cursor` values. Waits
156
+ poll only retryable transitional states, honor the caller deadline and
157
+ cancellation, and return the last observed state on timeout. Durable Bare Metal
158
+ workspace flows persist local recovery pointers for `launch --resume`.
159
+ Browser handoff is limited to login and organization authorization. Secret
160
+ bytes are written only by an explicit export command.
161
+
162
+ Human waits report throttled progress on stderr; NDJSON waits emit versioned
163
+ progress records, and JSON stays a single terminal envelope.
164
+
165
+ Eligible human output uses color when the output stream supports it.
166
+ `NO_COLOR` (including an empty value), `FORCE_COLOR`, and the global
167
+ `--no-color` flag are respected. JSON and NDJSON never contain ANSI escapes.
168
+
169
+ Exact unique machine hostnames are accepted anywhere a machine reference is
170
+ advertised, including JSON and NDJSON. The CLI resolves them through the
171
+ bounded owned-machine list and sends only the canonical machine ID to the
172
+ machine owner route. Bare `connect` discovers VM, Bare Metal,
173
+ Kubernetes, and Slurm targets before making one safe-fact choice across the
174
+ combined set. `connect --print` renders a native direct-access command; raw
175
+ secret `--print` rejects every explicit `--format`. Direct human `connect`
176
+ announces the native command and explains that Ctrl-C ends only local SSH while
177
+ the remote machine keeps running before it starts the session. Human metrics
178
+ and logs output includes returned sample rows, not only source availability.
179
+
180
+ ## Machine output and exit status
181
+
182
+ JSON and NDJSON use schema `ornn.cli/v1`. A terminal record contains:
183
+
184
+ ```json
185
+ {
186
+ "schema": "ornn.cli/v1",
187
+ "type": "result",
188
+ "command": "machines show",
189
+ "outcome": { "class": "ready", "phase": "ready" },
190
+ "data": {},
191
+ "action": null,
192
+ "page": null,
193
+ "errors": [],
194
+ "resume": null
195
+ }
196
+ ```
65
197
 
66
- ## Commands
198
+ NDJSON emits zero or more progress records and exactly one terminal result or
199
+ error record. Progress is additive and contains no secret or supplier identity.
200
+
201
+ | Exit | Meaning |
202
+ | ---: | ------------------------------------------------- |
203
+ | 0 | Requested terminal goal reached |
204
+ | 1 | Failed, declined, or terminal negative outcome |
205
+ | 2 | Usage or validation error |
206
+ | 3 | Durable external action is required |
207
+ | 4 | Useful partial result with explicit source errors |
208
+ | 5 | Authentication or authorization failure |
209
+ | 6 | Service unavailable or retryable owner failure |
210
+ | 124 | Deadline expired; last observed state returned |
211
+ | 130 | Interrupted |
212
+
213
+ ## Migrating to vNext
214
+
215
+ vNext is a clean cutover. Retired forms are never aliases: each fails before I/O
216
+ with one replacement and <https://docs.ornn.com/cli#migrating-to-vnext>.
217
+
218
+ | Retired form | Replacement |
219
+ | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
220
+ | `ornn account`, `ornn whoami` | `ornn context` |
221
+ | `ornn catalog search`, `gpu-types`, `availability *`, `listing *`, `listings` read leaves | matching `ornn capacity-offers` leaf |
222
+ | `ornn listings create` | `ornn admin capacity-offers create` |
223
+ | `ornn buy` | Use the Ornn web app. |
224
+ | `ornn bid create`, `exchange create` | Use the Ornn web app. |
225
+ | `ornn bid` or `exchange` list, show, update, withdraw | Use the Ornn web app. |
226
+ | `ornn gpu` or `gpus` list, show | Use the Ornn web app. |
227
+ | `ornn gpu` or `gpus` checkout, `reservations checkout` | Use the Ornn web app. |
228
+ | `ornn nodes launch` | `ornn launch` |
229
+ | `ornn nodes` list, show, wait, switch, reboot, hard-reset | matching `ornn machines` leaf; reset needs erase flag |
230
+ | `ornn ssh`, `nodes ssh-command` | `ornn connect` |
231
+ | `ornn metrics`, `telemetry`, `logs` | `ornn check`, `machines metrics`, or `machines logs` |
232
+ | `ornn clusters create`, `kubernetes launch`, `slurm launch` | `ornn launch --mode kubernetes` or `ornn launch --mode slurm` |
233
+ | Kubernetes or Slurm status, credentials, SSH, teardown | `ornn clusters show`, `connect`, or `clusters teardown` |
234
+ | `ornn network *`, `networks *` | `ornn private-networks <verb>` |
235
+ | `ornn access *`, `keys` | exact `ornn machines` or `ornn ssh-keys` leaf printed |
236
+ | `ornn storage volumes *` | `ornn volumes <verb>` |
237
+ | `ornn storage files *` | `ornn volumes files <verb>` |
238
+ | `ornn storage buckets *` | `ornn external-buckets <verb>` |
239
+ | Storage targets, deploy, status, detach, filesystem | exact `ornn volume-mounts` or `ornn filesystems` leaf printed |
240
+ | `ornn billing` | Use the Ornn web app. |
241
+ | customer-root `operator(s)`, `facilities`, `tokens`, `users`, `node`, or staff `reservations *` | exact `ornn admin ...` command printed by the error |
242
+ | `ornn api`, `commerce`, `orchestrator`, `cache purge` | `ornn resources`; no generic replacement exists |
243
+ | `--json` | `--format json` |
244
+ | `--interactive` | `--guided` |
245
+
246
+ Changed behavior is intentional: waits are deadline-bound, consent is semantic
247
+ and default-no, pagination is bounded and cursor-based, machine output is always
248
+ enveloped, and exit statuses are semantic. Old help, completion entries,
249
+ fixtures, staff roots, and owner-route spellings are not shipped.
250
+
251
+ `0.2.10` is the configured final legacy release (`legacyVersion`, dated
252
+ `2026-09-04T00:00:00Z`). The configured vNext artifact is `@ornncompute/cli`
253
+ at the version in `packages/config/cli-release.json` `vnextVersion`, on the
254
+ same binary and Node 20 minimum; `minimumVersion` for legacy tombstones
255
+ remains `1.0.0`. Publication is allowed as soon as release validation and
256
+ approvals pass; npm `latest` selects the approved production release. The
257
+ legacy support schedule remains anchored to `2026-10-05T00:00:00Z`, after
258
+ the required 30-day migration-notice interval. That date does not block npm
259
+ publication.
260
+
261
+ `ornn update` stays within the installed major. Crossing into vNext requires
262
+ `ornn update --major`. Through day 90 (ending immediately before
263
+ `2027-01-04T00:00:00Z`), rollback is available by reinstalling the pinned final
264
+ legacy package:
67
265
 
68
266
  ```bash
69
- ornn help [command]
70
- ornn login [--auth-base <url>] [--no-browser] [--timeout <seconds>]
71
- ornn update
72
- ornn whoami [--json]
73
- ornn status [--json]
74
- ornn listings list [--gpu-type <type>] [--facility <name>] [--json]
75
- ornn listings forecast [--limit <1-500>] [--cursor <opaque>] [--json]
76
- ornn listings show <listing-id> [--open] [--json]
77
- ornn listings create [--gpu-type <type>] [--node-count <n>] [--yes] [--json]
78
- ornn buy <listing-id> [--no-open] [--json]
79
- ornn exchange create <listing-id> --node-count <n> [--min-node-count <n>] --start-date <yyyy-mm-dd> --end-date <yyyy-mm-dd> --price <usd> [--no-open] [--json]
80
- ornn exchange create [<listing-id>] --interactive [--node-count <n>] [--min-node-count <n>] [--start-date <yyyy-mm-dd>] [--end-date <yyyy-mm-dd>] [--price <usd>] [--no-open]
81
- ornn exchange list [--limit <1-500>] [--cursor <cursor>] [--json]
82
- ornn exchange show <exchange-id> [--open] [--json]
83
- ornn exchange update <exchange-id> --node-count <n> --min-node-count <n> --start-date <yyyy-mm-dd> --end-date <yyyy-mm-dd> --price <usd>
84
- ornn exchange withdraw <exchange-id>
85
-
86
- Bid create/update prefer `--node-count` and `--min-node-count`. Legacy
87
- `--gpu-count` and `--min-gpu-count` remain available; they convert using the
88
- listing's GPUs per node before the gateway translates the request to the
89
- Commerce bid contract.
90
-
91
- ornn gpus list [--status <status>] [--limit <1-500>] [--cursor <cursor>] [--json]
92
- ornn gpus show <gpu-id> [--open] [--json]
93
- ornn gpus checkout <gpu-id> [--no-open] [--json]
94
- ornn nodes list [--json]
95
- ornn nodes show <node-id-or-hostname> [--json]
96
- ornn nodes launch <reservation-id> --key <path|id|label> [--mode bare-metal|vm] [--username <name>] [--network public|private] [--storage-load-drive-id <id>] [--storage-save-drive-id <id>] [--wait] [--json]
97
- ornn nodes launch [<reservation-id>] --interactive [--key <path|id|label>] [--mode bare-metal|vm] [--username <name>] [--network public|private] [--storage-load-drive-id <id>] [--storage-save-drive-id <id>] [--wait]
98
- ornn nodes switch <reservation-id> --network public|private --key <path|id|label> [--mode bare-metal|vm] [--username <name>] [--wait] [--json]
99
- ornn nodes wait <node-or-reservation-id-or-hostname> [--timeout <seconds>] [--json]
100
- ornn nodes reboot <node-id> [--json]
101
- ornn nodes hard-reset <node-id> [--json]
102
- ornn nodes ssh-command <node-or-reservation-id-or-hostname> [--json]
103
- ornn nodes keys attach <node-id> --key <path|id|label> [--json]
104
- ornn nodes keys list <node-id> [--json]
105
- ornn node health <node-id> [--json]
106
- ornn node diagnose <node-id> [--json]
107
- ornn node list [--operator <id-or-slug>] [--facility <id>] [--email <email>] [--json]
108
- ornn node reboot <node-id> [--json]
109
- ornn node hard-reset <node-id> [--json]
110
- ornn node off-grid <node-id> [--reason <text>] [--yes] [--json]
111
- ornn node on-grid <node-id> [--yes] [--json]
112
- ornn node exec <node-id> --command <shell> --timeout-seconds <n> [--json]
113
- ornn node terminate <node-id> [--reason <text>] [--force] [--yes] [--json]
114
- ornn node admin-key <node-id> [--generate] [--json]
115
- ornn reservations commerce list --tenant <email-or-id> [--listing <listing-id>] [--json]
116
- ornn reservations commerce create --tenant <email> --listing <listing-id> [--node-count <n>] [--node <node-id>] [--start-at <timestamp>] [--end-at <timestamp>] [--price-per-gpu-hour <rate>] [--json]
117
- ornn reservations deploy <node-id> --target-tenant <id> --commerce-reservation <id> [--target-user <id>] [--network public|private] [--json]
118
- ornn ssh <node-or-reservation-id-or-hostname> [--print] [--identity-file <path>] [--user <name>] [--json]
119
- ornn metrics nodes [--json]
120
- ornn metrics node <node-id-or-hostname> [--json]
121
- ornn metrics history <node-id-or-hostname> [--start <iso>] [--end <iso>] [--max-points <n>] [--json]
122
- ornn metrics watch <node-id-or-hostname> [--interval <seconds>] [--count <n>] [--timeout <seconds>] [--json]
123
- ornn clusters list [--json]
124
- ornn clusters reservations [--json]
125
- ornn clusters eligible-nodes <reservation-id> [--type kubernetes|slurm] [--network public|private] [--json]
126
- ornn clusters create <reservation-id> --type kubernetes|slurm [--network public|private] [--node <node-id>] [--node-count <n>] [--wait] [--json]
127
- ornn clusters create [<reservation-id>] --interactive [--type kubernetes|slurm] [--network public|private] [--node <node-id>] [--node-count <n>] [--wait]
128
- ornn clusters show <reservation-id> [--type kubernetes|slurm] [--json]
129
- ornn clusters wait <reservation-id> [--type kubernetes|slurm] [--timeout <seconds>] [--json]
130
- ornn clusters credentials <reservation-id> [--type kubernetes|slurm] [--json]
131
- ornn clusters kubeconfig <reservation-id> [--output <path>] [--json]
132
- ornn clusters ssh-command <reservation-id> [--identity-file <path>] [--user <name>] [--json]
133
- ornn clusters ssh <reservation-id> [--print] [--identity-file <path>] [--user <name>] [--json]
134
- ornn clusters add-node <reservation-id> --node <node-id> [--json]
135
- ornn clusters remove-node <reservation-id> --node <node-id> [--json]
136
- ornn clusters teardown <reservation-id> [--yes] [--type kubernetes|slurm] [--json]
137
- ornn slurm launch <reservation-id> [--network public|private] [--node <node-id>] [--node-count <n>] [--wait] [--wait-timeout <seconds>] [--json]
138
- ornn slurm teardown <reservation-id> [--yes] [--json]
139
- ornn slurm status <reservation-id> [--json]
140
- ornn slurm credentials <reservation-id> [--json]
141
- ornn slurm ssh <reservation-id> [--print] [--identity-file <path>] [--user <name>] [--json]
142
- ornn kubernetes launch <reservation-id> [--network public|private] [--node <node-id>] [--node-count <n>] [--wait] [--wait-timeout <seconds>] [--json]
143
- ornn kubernetes teardown <reservation-id> [--yes] [--json]
144
- ornn kubernetes status <reservation-id> [--json]
145
- ornn kubernetes credentials <reservation-id> [--json]
146
- ornn kubernetes kubeconfig <reservation-id> [--output <path>] [--json]
147
- ornn networks list [--json]
148
- ornn networks show <network-id> [--json]
149
- ornn networks create --name <name> [--cidr <cidr>] [--description <text>] [--json]
150
- ornn networks update <network-id> [--name <name>] [--description <text>] [--clear-description] [--json]
151
- ornn networks delete <network-id> [--yes] [--json]
152
- ornn storage volumes list [--json]
153
- ornn storage volumes show <drive-id> [--json]
154
- ornn storage volumes create --name <name> [--source <drive-id>] [--json]
155
- ornn storage volumes refresh <drive-id> [--json]
156
- ornn storage volumes clear <drive-id> [--yes] [--json]
157
- ornn storage volumes delete <drive-id> [--yes] [--json]
158
- ornn storage files ls <drive-id> [--prefix <path>] [--json]
159
- ornn storage files upload <drive-id> <local-file> [--destination <path>] [--content-type <type>] [--json]
160
- ornn storage files download <drive-id> <remote-path> [--output <path>] [--json]
161
- ornn storage targets [--json]
162
- ornn storage deploy <drive-id> --reservation <reservation-id> [--all-nodes] [--read-only|--read-write] [--json]
163
- ornn storage status --reservation <reservation-id> [--watch] [--interval <seconds>] [--timeout <seconds>] [--json]
164
- ornn storage detach --reservation <reservation-id> [--json]
165
- ornn storage buckets list [--json]
166
- ornn storage buckets show <drive-id> [--json]
167
- ornn storage buckets connect gcs|s3|r2 --bucket <bucket>|--url <url> [--name <name>] [--prefix <prefix>] [--region <region>] [--account-id <id>|--endpoint-url <url>] [--access-key-id <id> --secret-access-key-file <path>] [--read-only|--read-write] [--verify] [--json]
168
- ornn storage buckets update-credentials <drive-id> --access-key-id <id> --secret-access-key-file <path> [--json]
169
- ornn storage buckets verify <drive-id> [--json]
170
- ornn storage buckets disconnect <drive-id> [--json]
171
- ornn storage filesystem deploy --reservation <reservation-id> [--performance-tier <tier>] [--capacity-gib <gib>] [--json]
172
- ornn storage filesystem status --reservation <reservation-id> [--json]
173
- ornn storage filesystem delete --reservation <reservation-id> [--yes] [--json]
174
- ornn telemetry latest <node-id> [--span 15m] [--start <iso>] [--end <iso>] [--max-points <n>] [--json]
175
- ornn telemetry tail <node-id> [--duration <seconds>] [--json]
176
- ornn logs latest <node-id> [--stream kernel] [--count <n>] [--before <iso>] [--cursor <token>] [--json]
177
- ornn logs tail <node-id> [--stream kernel] [--duration <seconds>] [--json]
178
- ornn users query [--name <name>] [--email <email>] [--organization <name>] [--max <n>]
179
- ornn keys list [--json]
180
- ornn keys add [<public-key-file>] --label <label> [--public-key <key>] [--json]
181
- ornn keys delete <key-id> [--json]
182
- ornn access show <reservation-id> [--json]
183
- ornn access activate <reservation-id> --key <path|id|label> [--mode bare-metal|vm] [--username <name>] [--network public|private] [--storage-load-drive-id <id>] [--storage-save-drive-id <id>] [--wait] [--no-open] [--json]
184
- ornn access switch <reservation-id> --network public|private --key <path|id|label> [--mode bare-metal|vm] [--username <name>] [--wait] [--json]
185
- ornn access push-keys <reservation-id> --ssh-key-id <id> [--json]
186
- ornn access keys list <reservation-id> [--json]
187
- ornn access keys add <reservation-id> --public-key <key> --label <label> [--json]
188
- ornn access keys add <reservation-id> --public-key-file <path> --label <label> [--json]
189
- ornn access keys push <reservation-id> --ssh-key-id <id> [--json]
190
- ornn access keys status <reservation-id> [--json]
191
- ornn ssh-keys list [--json]
192
- ornn ssh-keys add --public-key <key> --label <label> [--json]
193
- ornn ssh-keys add --public-key-file <path> --label <label> [--json]
194
- ornn ssh-keys delete <key-id> [--json]
195
- ornn billing summary [--json]
196
- ornn billing invoices [--limit <1-500>] [--cursor <opaque>] [--json]
197
- ornn billing showback --start <yyyy-mm-dd> --end <yyyy-mm-dd> [--json]
198
- ornn billing open [--no-open] [--json]
199
- ornn api <get|post|patch|put|delete> <allowlisted-path> [--data <json>] [--raw]
200
- ornn logout
267
+ npm install -g @ornncompute/cli@0.2.10
201
268
  ```
202
269
 
203
- `ornn access keys add` is safe before or after launch. When the reservation has
204
- active VM or Bare Metal machines, adding the key automatically queues the
205
- current user's complete reservation key set on those machines. Use
206
- `ornn access keys push` to explicitly re-sync keys that are already attached.
207
-
208
- `ornn storage status` prints reconciled object and byte progress once the
209
- managed transfer has reported progress, plus the number of target nodes that
210
- have acknowledged the mount. Internal placement bucket details are not shown.
211
- AWS S3 and external GCS sources use the managed transfer path. Cloudflare R2
212
- buckets can be connected and verified, but deployment support is coming soon.
213
- The mount path is always `/home/tenant/volume`; node agents resolve `tenant` to the
214
- machine's real Linux user at mount time.
215
-
216
- `ornn storage status --watch` polls the same status endpoint on an interval
217
- (10 seconds by default) instead of returning after a single check, re-printing
218
- the human summary on each poll. It exits 0 once the attachment is attached and
219
- every scoped node has mounted, exits 1 with an error on stderr if the
220
- attachment detaches before that happens, and exits 1 with a timeout message on
221
- stderr after 1800 seconds (or the value passed to `--timeout`) without
222
- success. Use `--interval <seconds>` to change the poll cadence. `--interval`
223
- and `--timeout` require `--watch`. Combined with `--json`, only a single JSON
224
- payload is printed, at the end, instead of a stream of per-poll output.
225
-
226
- `ornn storage detach` detaches the drive from the reservation's storage
227
- attachment. Detach is origin-aware: if your reservation individually joined a
228
- drive that another reservation already had attached, detach releases only
229
- your reservation's own mount and leaves the rest of the attachment alone. If
230
- your reservation started the attachment, or it is the last member still
231
- joined, detach flushes and unmounts every node before releasing the whole
232
- attachment. A node that fails to unmount is left in a retryable state with
233
- the reported error; run `ornn storage detach` again with the same
234
- `--reservation` to retry it. A reservation that detached from a shared drive
235
- can rejoin it later by running `ornn storage deploy` again. Mounted state is
236
- tracked per node, not by attachment membership, so `ornn storage status`
237
- can show one node as unmounted while the rest of the attachment
238
- stays mounted.
239
-
240
- `ornn storage files upload` adds a file to the drive's current colocated copy.
241
- You can upload while a direct FUSE mount is active; every mounted node sees the
242
- file on its next lookup without a remount. A direct FUSE drive attaches to one
243
- reservation by default; pass `--all-nodes` on `ornn storage deploy` to fan the
244
- same mount out across every compatible node in the node group. Avoid writing
245
- the same file path concurrently from multiple nodes because object storage is
246
- not a POSIX shared filesystem.
247
-
248
- `ornn storage files download` streams a single object from the drive straight
249
- to disk. Pass `--output <path>` to control where it's written; without it, the
250
- file is saved under the remote path's basename in the current directory.
251
-
252
- For a connected bucket, deploy once before uploading. The first deploy imports
253
- the source into an Ornn-managed colocated working copy. That copy remains the
254
- drive's durable data when you unmount, detach, or mount it elsewhere. Ornn
255
- does not write changes back to the original connected bucket.
256
-
257
- UI aliases are first-class in the CLI: `listings` maps to the older
258
- `availability` command, `exchange` maps to `bid`, `gpus` maps to
259
- `reservations`. The older command names remain available for scripts.
260
- Bid and reservation list commands return a bounded page (500 rows by default);
261
- use `--limit`, `--json`, and the response's opaque `next_cursor` to traverse
262
- older history. Replay that cursor exactly; it is not an item ID. `show` and `checkout`
263
- use exact tenant-owned item lookups, so they are not limited to the current page.
264
-
265
- `listings forecast` is a Commerce-owned view of the next 48 one-hour
266
- availability windows. It includes capacity that is unavailable now but frees
267
- up during the horizon. The CLI makes one gateway request; it does not probe
268
- each hour independently.
269
-
270
- `exchange create`, `nodes launch`, and `clusters create` accept
271
- `--interactive`. Supplied flags prefill the guided answers. The mode requires
272
- TTY stdin and stdout, rejects `--json`, prints the complete request, and
273
- submits only after an explicit default-no confirmation.
274
-
275
- Machine UUIDs remain canonical. `ornn ssh`, `nodes show`, `nodes wait`, and
276
- tenant metrics also accept a case-insensitive exact hostname when it uniquely
277
- matches one active machine; ambiguous hostnames fail and print the matching
278
- full IDs.
279
-
280
- ## Operator commands
281
-
282
- The `ornn node` commands are for Ornn operators and reviewers, not tenants. They
283
- wrap internal-reviewer-gated endpoints. Run `ornn login` as an
284
- internal-allowed staff user. The CLI calls `/v1/cli/operator/*`; the gateway
285
- resolves the user bearer and applies staff authorization without downloading a
286
- review or service secret to the laptop. There is no direct-service break-glass
287
- path.
288
-
289
- - `ornn node health <node-id>` shows launch readiness (ready/blocked plus
290
- reasons), passive fault reasons, and the last validation status.
291
- - `ornn node diagnose <node-id>` queues a manual node validation test.
292
- - `ornn node list [--operator <id-or-slug>] [--facility <id>] [--email <email>]` lists GPU nodes.
293
- Orchestrator applies facility id and an operator UUID. Non-UUID `--operator`
294
- slugs and `--email` are forwarded today and do not filter the fleet.
295
- - `ornn node reboot <node-id>` queues an OS reboot of the node's resolved
296
- instance (its host for bare-metal, its VM for a virtual-machine instance id;
297
- storage and SSH keys preserved).
298
- - `ornn node hard-reset <node-id>` wipes tenant storage/users and reboots, then
299
- re-pushes the tenant's keys on reconnect. The tenant keeps ownership of the
300
- instance.
301
- - `ornn node off-grid <node-id> [--reason <text>] [--yes]` takes a node off-grid
302
- (remove Ornn agent management, leave the host powered on). Asks y/N unless `--yes`.
303
- - `ornn node on-grid <node-id> [--yes]` re-enrolls an off-grid host: orchestrator
304
- SSHs with the stored admin key and re-runs the installer. Asks y/N unless `--yes`.
305
- - `ornn node exec <node-id> --command <shell> --timeout-seconds <n>` runs
306
- one unrestricted command over orchestrator SSH with the stored admin key. Not
307
- an interactive shell (`ornn ssh`). Runs immediately; no y/N.
308
- - `ornn node terminate <node-id> [--reason <text>] [--force] [--yes]` best-effort
309
- cleans the host, removes the Ornn agent, and hard-deletes the node record.
310
- It does not return the host to a tenant. Asks y/N unless `--yes`. There is no
311
- `deenroll` verb; use terminate.
312
- - `ornn node admin-key <node-id> [--generate]` prints the Ornn admin SSH keypair
313
- for the node (including the private key) so an operator can SSH into the host.
314
- `--generate` always mints a new pair, stores it, and installs the public key
315
- on the live host. Treat the output as a secret.
316
-
317
- The operator resource commands share the same reviewer auth:
318
-
319
- - `ornn operator list [--json]` lists operators from the capabilities
320
- catalog (staff). Distinct from `ornn operators list`.
321
- - `ornn operators list` lists enrolled provisioning operators
322
- (`GET /provisioning/operators`).
323
- - `ornn facilities list [--operator <id-or-slug>]` lists facilities, optionally
324
- filtered to one operator.
325
- - `ornn tokens list` lists enrollment tokens.
326
- - `ornn tokens create --operator <id> [--facility <id>]
327
- [--expires-in <seconds>] [--ip <addr>] [--host <ip>]
328
- [--identity-file <path>] [--yes]` mints an enrollment token and prints a
329
- `curl … | sudo bash` install command. With `--host` and `--identity-file`,
330
- orchestrator SSHs and runs that curl (same as Bulk Enroll). Asks y/N unless `--yes`.
331
- - `ornn tokens revoke <token-id>` revokes an enrollment token.
332
-
333
- Staff Commerce reservations are listing-backed, not fleet-backed:
334
-
335
- - `reservations commerce create --tenant <email> --listing <listing-id>
336
- [--node-count <n>] [--node <node-id>]` creates and activates the tenant's
337
- Commerce reservation. Node count defaults to the listing capacity; start,
338
- end, and hourly rate default from the listing. Optional `--node` values pin
339
- specific catalog ids. Start and end overrides must remain inside the
340
- listing's allowed window; the hourly rate can also be overridden explicitly.
341
- - `reservations commerce list --tenant <email-or-id> [--listing <listing-id>]`
342
- lists active reservations in their live window, optionally filtered to one
343
- listing.
344
-
345
- Reservation lifecycle verbs also run under the operator surface:
346
-
347
- - `ornn reservations commerce create|list` creates or discovers a validated
348
- Commerce reservation from a listing. These actions require a staff
349
- `ornn login` session; the gateway `/v1/cli/operator/*` allowlist enforces
350
- staff authorization — there is no review-secret break-glass that bypasses
351
- that gate.
352
- - `ornn reservations transfer <reservation-id> --target-tenant <id>
353
- [--target-user <id>] [--node <id>] [--strategy reject|park] [--confirm]`
354
- transfers a reservation to another tenant.
355
- - `ornn reservations deploy <node-id> --target-tenant <id>
356
- --commerce-reservation <id> [--target-user <id>] [--network public|private]`
357
- deploys one node only after the gateway operator contract verifies that the
358
- live tenant-owned Commerce reservation and listing match that node.
359
-
360
- The tenant `ornn reservations list|show|checkout` verbs use the tenant CLI
361
- login and `/v1/cli/compute` gateway contract. Staff Commerce actions use the
362
- gateway operator contract; `transfer|deploy` retain the operator path above.
363
-
364
- Staff happy path:
365
-
366
- - `ORNN_AUTH_BASE_URL` — web/browser handoff origin
367
- - `ORNN_API_BASE_URL` — API gateway origin
368
- - `ornn login` as a user allowed by `INTERNAL_ALLOWED_*` on that environment
369
-
370
- Optional installer gateway base for `ornn tokens create` install one-liners:
371
-
372
- - `ORNN_INSTALLER_URL` - base serving `enrollment/install` (for deployed
373
- gateways, `https://<gateway>/v1/orchestrator`), falling back to
374
- `NEXT_PUBLIC_INSTALLER_URL`. Unset prints the token without an install command.
375
-
376
- Without a staff login session, operator commands fail with a clear error before
377
- making a network request.
378
-
379
- Commands print concise human-readable output by default. Customer list
380
- commands use aligned tables when stdout is a TTY and retain their existing
381
- line-oriented shape when piped or redirected. Use `--json` on
382
- read/show/list commands and transaction handoffs for the supported structured
383
- stdout contract. JSON never contains tables, progress, next-step hints, color,
384
- or ANSI sequences. Errors and login/browser progress go to stderr. Under
385
- `--json` an error is written to stderr as one object, `{"error": "<message>",
386
- "status": <http-status>}` (`status` only when the API supplied one); stdout
387
- stays empty and the exit code is unchanged.
388
-
389
- `ornn login` opens a browser to the Ornn auth origin, lets the user sign in
390
- with the normal web account flow, and then completes automatically in the
391
- terminal once the browser session approves the CLI device request. If the CLI
392
- cannot open a browser, copy the printed URL into any browser and sign in there;
393
- the terminal keeps polling until the login is approved or expires.
394
-
395
- Run `ornn --help` for the full command list and `ornn api` for the
396
- allowlisted gateway API escape hatch.
397
-
398
- WireGuard client configs use the current tenant-scoped `/nodes` routes:
270
+ Both directions reuse valid `auth.json`, `config.json`, and
271
+ `update-check.json`. `selectedOrganizationId` is an untrusted hint; the gateway
272
+ revalidates membership. Neither direction rewrites credentials or configured
273
+ endpoints. Rollback is unsupported from day 91. From day 91 through day 180,
274
+ legacy compatibility calls return a non-forwarding `426 Upgrade Required`
275
+ tombstone with `cli_version_unsupported`, minimum version `1.0.0`, and the
276
+ migration URL. The legacy route surface is absent from day 181
277
+ (`2027-04-04T00:00:00Z`).
278
+
279
+ `ornn --version` and `ornn -v` print the semantic package version. `ornn
280
+ version` also reports machine schema and update channel.
281
+
282
+ ## Development
283
+
284
+ The exported `run(argv, io)` seam accepts injected streams, fetch, browser,
285
+ process, clock, sleep, and cancellation dependencies. The packaged binary uses
286
+ the same seam. Capability code preserves existing MCP and Slack identities;
287
+ only canonical `cli.vnext` bindings are dispatchable by the CLI.
288
+
289
+ ### Packaged journey and release evidence
290
+
291
+ The permanent package gate vendors the capability catalog, creates one npm
292
+ archive, installs that exact archive under a clean temporary prefix, and tests
293
+ only its installed `ornn` entrypoint against a deterministic loopback gateway:
399
294
 
400
295
  ```bash
401
- ornn api get /nodes/reservations/<reservation-id>/vpn/peers --raw
402
- ornn api post /nodes/reservations/<reservation-id>/vpn/peers \
403
- --data '{"public_key":"<wireguard-public-key>","label":"Laptop"}' --raw
404
- ornn api delete /nodes/reservations/<reservation-id>/vpn/peers/<peer-id> --raw
296
+ rm -rf /tmp/ornn-vnext-artifacts
297
+ mkdir -p /tmp/ornn-vnext-artifacts
298
+ npm run acceptance:packaged --workspace @ornncompute/cli -- \
299
+ --artifact-dir /tmp/ornn-vnext-artifacts \
300
+ --evidence /tmp/ornn-vnext-packaged-gate.json
405
301
  ```
406
302
 
407
- The legacy `/standalone-vms/*` prefix is not exposed through the gateway
408
- `/v1/cli/*` allowlist.
409
- Deleting a peer is the supported way to replace its key; switching a node
410
- between Public and Private VPN preserves the peer.
411
-
412
- ## Updating
413
-
414
- Interactive global installations check for new releases in the background,
415
- using a daily interval. When a newer release has been discovered, Ornn
416
- installs it before your next eligible command and then runs that command
417
- with the updated CLI. The first check has a one-day grace period.
418
-
419
- Automatic updates are skipped in CI, with redirected input or output,
420
- for machine-readable output, and for help or version commands. Project
421
- dependencies, development checkouts, and package-runner invocations do
422
- not update automatically. Run `ornn update` to check and update immediately.
423
-
424
- If an installation fails, Ornn continues only when it can verify that
425
- the remaining CLI loads successfully. Otherwise it prints reinstall
426
- instructions. If another update is running, retry after it finishes.
427
-
428
- Updates publish an initialized `update-install-*.lock` directory in the Ornn
429
- config directory. Its unique owner file prevents competing processes from
430
- removing a replacement lock during recovery or release. Directory locks from
431
- processes that exit before installation are reclaimed on the next update
432
- attempt; live or inaccessible PIDs and malformed metadata remain locked. Legacy regular-file locks require
433
- manual cleanup after confirming that no updater is running: deleting them
434
- automatically could remove a live lock created by an older CLI. PID reuse can
435
- also require manual cleanup. An installation marker keeps the lock held if the
436
- CLI is killed during installation, because its package installer may still be
437
- running. Confirm that installer has stopped before removing the lock. Repeated
438
- Ctrl+C or SIGTERM releases the lock after installer teardown. An interrupted
439
- package installation may still require reinstalling the CLI if the package
440
- manager has already removed the previous version.
441
-
442
- On POSIX, SIGHUP and SIGQUIT are forwarded to the package installer so it can
443
- exit before the update lock is released.
444
-
445
- ## Deployment
446
-
447
- `deploy-cli-pipeline.yml` publishes `@ornncompute/cli` from `main`. Staging
448
- publishes the package.json version to the npm `next` dist-tag; production then
449
- promotes that same version to `latest`. Manual rolls use
450
- `deploy-cli-service.yml`. Runtime changes under `apps/cli` or
451
- `packages/capabilities` must bump `apps/cli/package.json` so npm receives a
452
- new release. Re-running the pipeline is idempotent when that version is
453
- already published.
303
+ The real gateway smoke and unassisted participant pass are separate release
304
+ evidence; the deterministic fixture must never be presented as either one.
305
+ The participant recorder installs the retained archive itself and owns the
306
+ interactive shell used for the journey, with that installation first in
307
+ `PATH`; it does not attest a session run in another terminal.
308
+ Production and shared staging are refused by the smoke runner. See
309
+ [`docs/packaged-vnext-release-gate.md`](docs/packaged-vnext-release-gate.md) for
310
+ the non-production inputs, redacted evidence schemas, participant checklist,
311
+ pass criteria, and exact commands.
312
+
313
+ Private networks and VPN peers belong to the selected organization. There is no
314
+ per-reservation network attachment step. Durable Bare Metal workspaces use
315
+ `--network shared --volume <volume-id> --mount-access read-only|read-write`;
316
+ private Kubernetes and Slurm launches continue to use `--network private`.
317
+
318
+ ### Storage list pages
319
+
320
+ Ornn CLI 1.0.22 and later request storage lists one page at a time.
321
+ `ornn volumes list` and `ornn external-buckets list` accept `--limit 1` through
322
+ `--limit 100` (default 25), ordered by last updated. Pass the returned
323
+ `page.next_cursor` to `--cursor` for the next page; null means the end.
324
+ Refresh from the first page after changes. Older CLI versions receive an
325
+ upgrade error for storage lists. File-list pagination is unchanged.