@vectros-ai/cli 0.25.0 → 0.27.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.
- package/AUTHORING.md +109 -18
- package/CHANGELOG.md +78 -0
- package/README.md +90 -22
- package/dist/cli.js +2593 -552
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +2592 -551
- package/dist/cli.mjs.map +1 -1
- package/package.json +5 -5
package/AUTHORING.md
CHANGED
|
@@ -8,7 +8,7 @@ ready-to-use data model + a narrow `ssk_*` scoped key — no root key, no manual
|
|
|
8
8
|
admin steps. `vectros blueprint apply <file> --tenant test|live` applies the same
|
|
9
9
|
blueprint WITHOUT minting a key, for re-applying a change from CI.
|
|
10
10
|
|
|
11
|
-
This guide is the authoring loop. Everything here except `bootstrap` and `blueprint apply` is
|
|
11
|
+
This guide is the authoring loop. Everything here except `blueprint-test`, `bootstrap` and `blueprint apply` is
|
|
12
12
|
**creds-free and offline** — you can iterate on a blueprint with no account.
|
|
13
13
|
|
|
14
14
|
> The examples use the bare `vectros` binary — install it once with
|
|
@@ -22,7 +22,7 @@ vectros blueprint init my-thing # 1. scaffold a starter
|
|
|
22
22
|
# …edit ./my-thing.blueprint.yaml…
|
|
23
23
|
vectros blueprint validate ./my-thing.blueprint.yaml # 2. structural + scope-gate + lint (offline)
|
|
24
24
|
vectros blueprint plan ./my-thing.blueprint.yaml # 3. preview what it provisions (offline)
|
|
25
|
-
vectros blueprint-test ./my-thing.blueprint.yaml --
|
|
25
|
+
vectros blueprint-test ./my-thing.blueprint.yaml --tenant test # 4. prove it live (creds; auto-teardown)
|
|
26
26
|
vectros bootstrap --blueprint ./my-thing.blueprint.yaml # 5. apply for real + mint a key (needs a bridge token)
|
|
27
27
|
vectros blueprint apply ./my-thing.blueprint.yaml --tenant test # 5'. apply for real, no key (CI: add --yes --confirm-existing-principal)
|
|
28
28
|
```
|
|
@@ -50,7 +50,7 @@ A name must be 2–50 chars: a lowercase letter, then lowercase letters / digits
|
|
|
50
50
|
`validate` runs three layers and exits non-zero on any failure:
|
|
51
51
|
|
|
52
52
|
1. **Structural** — the file parses against the blueprint schema (readable
|
|
53
|
-
`path: message` errors, e.g. `schemas[0].fields[1]:
|
|
53
|
+
`path: message` errors, e.g. `schemas[0].fields[1].fieldType: Invalid input: expected string, received undefined`).
|
|
54
54
|
2. **Scope + capability gates** — the requested `allowedActions` are data-plane
|
|
55
55
|
only. This is the trust boundary: `keys`/`users`/`admin`/`app-contexts`/
|
|
56
56
|
`namespaces` and the `*` wildcard are **hard-rejected, no override**.
|
|
@@ -97,12 +97,14 @@ A name must be 2–50 chars: a lowercase letter, then lowercase letters / digits
|
|
|
97
97
|
|
|
98
98
|
```
|
|
99
99
|
Plan for blueprint 'my-thing' (v1.0.0) → context 'mcp':
|
|
100
|
-
|
|
101
|
-
+ context 'mcp' (MCP — my-thing)
|
|
100
|
+
...
|
|
102
101
|
+ principal 'my-thing-sp' (SERVICE)
|
|
102
|
+
+ context 'mcp' (MCP — my-thing)
|
|
103
|
+
+ schema 'thing' (1 field, HYBRID) lookup: [title]
|
|
103
104
|
+ profile scopes [records:r, records:c, records:u, search:r, schemas:r] (data-plane ✓)
|
|
104
105
|
+ key my-thing-<machine> (mint 1 scoped ssk_*)
|
|
105
|
-
+ seed 1 record
|
|
106
|
+
+ seed 1 record
|
|
107
|
+
6 step(s). This is a preview — nothing was minted.
|
|
106
108
|
```
|
|
107
109
|
|
|
108
110
|
**A blueprint whose `accessProfile` composes roles (`roleIds:`) previews every
|
|
@@ -111,9 +113,10 @@ sharing an action set can still carry different `dataScope`:
|
|
|
111
113
|
|
|
112
114
|
```
|
|
113
115
|
Plan for blueprint 'my-thing' (v1.0.0) → context 'mcp':
|
|
114
|
-
|
|
115
|
-
+ context 'mcp' (MCP — my-thing)
|
|
116
|
+
...
|
|
116
117
|
+ principal 'my-thing-sp' (SERVICE)
|
|
118
|
+
+ context 'mcp' (MCP — my-thing)
|
|
119
|
+
+ schema 'thing' (1 field, HYBRID) lookup: [title]
|
|
117
120
|
+ role 'case-handler' (1 clause, actions [records:cru])
|
|
118
121
|
clause 1: actions [records:cru], dataScope: scope:org=[${{ self.scope.org }}]
|
|
119
122
|
+ role 'hr-admin' (1 clause, actions [records:r])
|
|
@@ -121,7 +124,8 @@ sharing an action set can still carry different `dataScope`:
|
|
|
121
124
|
assumable: scope:org=[org_engineering, org_sales]
|
|
122
125
|
+ profile via role(s) [case-handler, hr-admin] (composed — each role's own clauses, concatenated in order)
|
|
123
126
|
+ key my-thing-<machine> (mint 1 scoped ssk_*)
|
|
124
|
-
+ seed 1 record
|
|
127
|
+
+ seed 1 record
|
|
128
|
+
8 step(s). This is a preview — nothing was minted.
|
|
125
129
|
```
|
|
126
130
|
|
|
127
131
|
A role's `assumable` line only appears when the blueprint's top-level
|
|
@@ -164,16 +168,17 @@ everything it created:
|
|
|
164
168
|
|
|
165
169
|
```
|
|
166
170
|
vectros login # sign in once (or pass --token)
|
|
167
|
-
vectros blueprint-test ./my-thing.blueprint.yaml --
|
|
171
|
+
vectros blueprint-test ./my-thing.blueprint.yaml --tenant test
|
|
168
172
|
vectros blueprint-test task-management --keep # leave the graph in place to inspect it
|
|
169
173
|
```
|
|
170
174
|
|
|
171
175
|
Teardown is the default and runs even if an assertion fails. It is **created-only** — a pre-apply
|
|
172
176
|
snapshot means it never deletes a schema or AccessProfile that already existed, so it's safe to point at
|
|
173
|
-
a
|
|
174
|
-
`0` = applied + every assertion passed; `1` = an assertion failed or
|
|
175
|
-
or the blueprint asked for control-plane scope (the same gate `validate` enforces)
|
|
176
|
-
ship a blueprint — it catches an unusable or mis-scoped credential
|
|
177
|
+
a tenant other people use. (It does **not** delete the app-context: that's idempotent and reused.) Exit
|
|
178
|
+
`0` = applied + every assertion passed; `1` = an assertion failed, apply errored, or an agent the run created could not be retired or purged; `130`/`143` = stopped by SIGINT (^C) / SIGTERM; `2` = no credential,
|
|
179
|
+
or the blueprint asked for control-plane scope (the same gate `validate` enforces), or an agent name is too long
|
|
180
|
+
to take the run's suffix. Run this before you ship a blueprint — it catches an unusable or mis-scoped credential
|
|
181
|
+
that the offline checks can't. A blueprint that declares `agents:` runs under agent names of its own: see *Agents*.
|
|
177
182
|
|
|
178
183
|
## The format, field by field
|
|
179
184
|
|
|
@@ -226,7 +231,7 @@ accessProfile:
|
|
|
226
231
|
# A SEPARATE gated dimension from allowedActions — named platform effects a
|
|
227
232
|
# resource:ops verb can't express (e.g. creating/removing an identity in
|
|
228
233
|
# your tenant). 'member-lifecycle' and 'delegate-principal-stamp' are
|
|
229
|
-
# admitted
|
|
234
|
+
# admitted; every other name is hard-rejected, same posture as the
|
|
230
235
|
# scope gate. See "Capabilities" below.
|
|
231
236
|
#
|
|
232
237
|
# Instead of allowedActions (+ optional dataScope/capabilities), accessProfile
|
|
@@ -367,6 +372,16 @@ identities:
|
|
|
367
372
|
YAML or JSON are both accepted (chosen by extension). The bundled library is
|
|
368
373
|
authored in TypeScript; YAML is the authoring affordance for your own.
|
|
369
374
|
|
|
375
|
+
### Inputs — values you supply when you install
|
|
376
|
+
|
|
377
|
+
A blueprint can declare a top-level `inputs:` block (each input has a `type` of `string`, `number` or `boolean`, and may
|
|
378
|
+
have `required`, `default` and `description`) and use the values in any string with `${{ inputs.<name> }}`. The built-ins
|
|
379
|
+
`${{ vectros.context }}` and `${{ vectros.suffix }}` are the blueprint's literal `contextId` and a short stable token derived
|
|
380
|
+
from it. Supply values to `validate`, `plan` and `apply` with `--set name=value` (repeatable) or `--values <file>` (a YAML or
|
|
381
|
+
JSON map); `--set` wins over `--values`, which wins over the declared `default`. An unknown input, a missing value with no
|
|
382
|
+
default, or a value of the wrong type stops the command before any request is sent. Write `$${{` for a literal `${{`. The
|
|
383
|
+
`@vectros-ai/blueprints` README describes the block in full.
|
|
384
|
+
|
|
370
385
|
### Choosing lookup indexes — a permanent decision
|
|
371
386
|
|
|
372
387
|
`lookupFields` are how you reach records *directly* — by exact value, by an
|
|
@@ -424,7 +439,6 @@ each tell you "records with this status" or "records with this area", but never
|
|
|
424
439
|
|
|
425
440
|
```yaml
|
|
426
441
|
lookupFields:
|
|
427
|
-
- externalId
|
|
428
442
|
- { fieldNames: [status, area], sortBy: createdAt, allowOverflow: true }
|
|
429
443
|
```
|
|
430
444
|
|
|
@@ -562,10 +576,82 @@ Full field grammar, including the byte caps on `source` and
|
|
|
562
576
|
`declaredInputContract` and the `manifest` verb vocabulary:
|
|
563
577
|
[`@vectros-ai/blueprints`](https://www.npmjs.com/package/@vectros-ai/blueprints).
|
|
564
578
|
|
|
579
|
+
### Agents — stored model definitions
|
|
580
|
+
|
|
581
|
+
A blueprint can declare the agents it needs. The block needs `formatVersion: 2`, so a CLI that predates the
|
|
582
|
+
format refuses the file instead of misreading it.
|
|
583
|
+
|
|
584
|
+
```yaml
|
|
585
|
+
formatVersion: 2
|
|
586
|
+
agents:
|
|
587
|
+
intake-triage: # the key is the agent's name: 1-64 letters, digits, '_' and '-'
|
|
588
|
+
description: Summarises a new intake record and flags missing fields.
|
|
589
|
+
model: claude-sonnet-5-5
|
|
590
|
+
system: You triage intake records. Be concise.
|
|
591
|
+
tools:
|
|
592
|
+
- { name: records_get }
|
|
593
|
+
- { name: records_create, allowWrites: true } # a tool that changes data needs allowWrites ...
|
|
594
|
+
limits: { maxToolCalls: 10, maxWrites: 2 } # ... and limits.maxWrites of at least 1
|
|
595
|
+
budget: { maxInferenceCents: 100 }
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
`apply` and `bootstrap` create each agent in the blueprint's context, after the roles, scripts and triggers and
|
|
599
|
+
before any key is minted, and `plan` lists one step per agent. The write is convergent, and the platform does the
|
|
600
|
+
comparing: a new name is created at version 1, an identical definition writes nothing, and a changed definition
|
|
601
|
+
becomes the next version. Nothing is edited in place, so every earlier version stays readable. The apply summary
|
|
602
|
+
names what it did to each agent (`created at version 1`, `unchanged at version 2`, `version 2 -> 3`, or `adopted`).
|
|
603
|
+
|
|
604
|
+
- **The applying credential needs `agents:c`**, and `agents:u` and `agents:r` as well whenever the agent already exists, even
|
|
605
|
+
when its definition is unchanged (the platform checks `u` before it compares, and without `r` it cannot show the existing agent
|
|
606
|
+
and answers that the name is in use). A re-apply with only `agents:c` is refused, and the error says which scopes are missing.
|
|
607
|
+
A principal without them gets a `403`, and the apply stops with an error that names the scope and the context.
|
|
608
|
+
Agents are written before the key, so a refused apply mints none. This is a grant on the credential that applies
|
|
609
|
+
the blueprint, not something to put in the blueprint's `accessProfile`: `agents` is a control-plane resource, so
|
|
610
|
+
the scope gate refuses it there.
|
|
611
|
+
- **Each agent is marked as this blueprint's.** Another blueprint's agent of the same name is refused, not rewritten, so two
|
|
612
|
+
blueprints cannot declare one name, and renaming a blueprint that already created agents strands them: the new name is
|
|
613
|
+
refused for them. The mark is set once and cannot change. It is the blueprint's own `name`, which the file declares
|
|
614
|
+
for itself (the same trust as for scripts and triggers): any file that declares `name: X` rewrites the agents marked
|
|
615
|
+
`X`, so the adoption flag below guards unmarked agents only.
|
|
616
|
+
- **An agent made by hand under the same name is refused unless you pass `--allow-agent-adoption`** (to `apply` or `bootstrap`; a
|
|
617
|
+
flag only the operator can give, never something the blueprint declares). Adopting marks it as this blueprint's and writes the
|
|
618
|
+
declared definition as its next version if that differs, so every run that uses the agent's latest version changes; earlier
|
|
619
|
+
versions stay readable. Nothing is written to a refused agent. Once adopted it is an ordinary managed agent and later applies
|
|
620
|
+
need no flag. This is how you bring agents you created by hand under a blueprint. It is checked per agent as the agents are
|
|
621
|
+
written, partway through the apply, so what an earlier agent or section already wrote stays.
|
|
622
|
+
- **Hand edits to a managed agent do not last.** A version written with `vectros agents version` (or the API) on an agent a
|
|
623
|
+
blueprint declares is replaced by the declared definition at the next apply, as another version. Change the blueprint.
|
|
624
|
+
- **A retired agent that the blueprint still declares fails the apply** (`409`), after the sections before it are written. Restore it
|
|
625
|
+
with `vectros agents version <id> --restore --file <definition>`, or remove the entry; a purged agent cannot be restored.
|
|
626
|
+
- **Removing an entry deletes nothing.** The agent stays stored and runnable. Retire it deliberately through the
|
|
627
|
+
API (`DELETE /v1/agents/{id}`); a retired agent keeps its name, so the same name cannot be created again.
|
|
628
|
+
- **`blueprint-test` runs a blueprint that declares agents, under names of their own.** A retired or purged agent keeps
|
|
629
|
+
its name for good, so the test applies a copy of your blueprint whose agent names carry a suffix unique to the run
|
|
630
|
+
(`triage` becomes `triage-t1a2b3c4d`; the report lists each), then retires and purges exactly the agents it created,
|
|
631
|
+
even when an assertion failed. Agents that exist under your declared names are never touched, and the file you wrote is
|
|
632
|
+
not changed. Because the suffix takes 10 characters, a name can be at most 54 characters long here (exit `2`, before any
|
|
633
|
+
write). The credential needs `agents:d` as well as the scopes an apply needs; if a retire is refused the agent stays active, the report names the API call that retires it, and the run exits
|
|
634
|
+
`1` (a teardown failure on any other resource is still reported without changing the exit code). **^C, SIGINT and SIGTERM.** Once the apply has begun, only the agent step has a stop point (a signal during context provisioning or the snapshot ends the run before the apply starts). After the first signal the run writes no further agents and skips
|
|
635
|
+
the assertions if they have not begun, but the rest of the apply still runs to its end (schemas, roles, the profile, the scoped-key mint,
|
|
636
|
+
seed records, the index poll), so a request in progress or a long seed delays the stop. Then the same teardown as after a failed run
|
|
637
|
+
removes what the apply's result lists (never the context, the service principal or namespaces), the report is printed, and the exit
|
|
638
|
+
code is `130` (SIGINT) or `143` (SIGTERM); a run stopped this way never passes, and these codes win over `1` (the report still names
|
|
639
|
+
an agent that could not be removed). A step that never answers holds the run until you send the signal again. That second signal starts no
|
|
640
|
+
teardown: it prints the id of each agent this run created with the calls that retire and erase it, names a create that was sent and never
|
|
641
|
+
answered, notes that other things the run wrote are not listed, and leaves at once. With `--keep` nothing is torn down. A process manager that
|
|
642
|
+
follows SIGTERM with SIGKILL after a grace period ends the process wherever it is, and SIGKILL cannot be handled: what was written so far
|
|
643
|
+
stays. A create of a tracked agent is sent with no client retries, so a single 429 or 5xx fails that create (the run reports it and tears
|
|
644
|
+
down) instead of being retried; a create that may have gone through is searched for by name. Each run leaves one purged row per declared agent (the name stays reserved), which
|
|
645
|
+
`agents list --include-retired` shows. With `--keep` the agents stay, under their run names.
|
|
646
|
+
- `authority` is `CALLER` (the default and the only value the platform accepts): a run calls tools with the identity
|
|
647
|
+
and permissions of whoever starts it, further limited by the tool whitelist.
|
|
648
|
+
|
|
649
|
+
The same API is available directly as `vectros agents list|get|create|version`; see the README.
|
|
650
|
+
|
|
565
651
|
### The scope gate — what you can and can't request
|
|
566
652
|
|
|
567
653
|
The gate allows only **data-plane** resources:
|
|
568
|
-
`records`, `schemas`, `search`, `documents`, `folders`, `inference`, `entities`
|
|
654
|
+
`records`, `schemas`, `search`, `documents`, `folders`, `inference`, `entities`, `runs`
|
|
569
655
|
(per-namespace identity-entity CRUD — `org`/`client`/any namespace you
|
|
570
656
|
registered — ownership-gated the same way as `records`; it grants no
|
|
571
657
|
authority over the namespace *registry* itself, which stays root-key-only).
|
|
@@ -605,7 +691,7 @@ An `accessProfile` or role clause may also declare `capabilities: [...]` —
|
|
|
605
691
|
named platform effects (like creating or removing an identity in your tenant)
|
|
606
692
|
that a `resource:ops` scope token can't express. This rides its own field,
|
|
607
693
|
separate from `allowedActions`, and has its own allowlist: **`member-lifecycle`
|
|
608
|
-
and `delegate-principal-stamp` are admitted
|
|
694
|
+
and `delegate-principal-stamp` are admitted.** Every other capability
|
|
609
695
|
name — including ones the platform's own registry recognizes — is refused,
|
|
610
696
|
the same fail-closed, deliberately-narrow posture as the scope gate above. `validate`,
|
|
611
697
|
`plan`, `blueprint-test` and `bootstrap` all report a rejected capability the
|
|
@@ -693,6 +779,11 @@ stays, because there is no second, principal-shaped factor to safely gate a
|
|
|
693
779
|
DELETE the way a trigger row's provenance marker does. Remove one deliberately
|
|
694
780
|
with `vectros scripts delete`.
|
|
695
781
|
|
|
782
|
+
**A FOURTH qualification, and here the platform does the comparing: an `agents:` entry is idempotent server-side,
|
|
783
|
+
and a change adds a version.** For an agent that exists, the loader first makes a plain create call to see the agent's mark and
|
|
784
|
+
version, then an upsert, which compares the declared definition with the stored latest (after defaults are filled in) and writes
|
|
785
|
+
nothing when they are identical. The two versions give the exact outcome. See *Agents*, including `--allow-agent-adoption`.
|
|
786
|
+
|
|
696
787
|
## Distribution
|
|
697
788
|
|
|
698
789
|
- **Bundled** — reviewed, versioned blueprints shipped in the library
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,84 @@
|
|
|
3
3
|
All notable changes to `@vectros-ai/cli` are documented here.
|
|
4
4
|
This project adheres to [Semantic Versioning](https://semver.org).
|
|
5
5
|
|
|
6
|
+
## 0.27.0 — 2026-11-07
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- **`vectros blueprint apply` and `bootstrap` create the agents of a blueprint's `agents` section** (it needs `formatVersion: 2`), after the
|
|
11
|
+
roles, scripts and triggers and before any key is minted. `blueprint plan` lists one step per agent (model, tools, limits, budget,
|
|
12
|
+
prompt size). A new name is created at version 1, an unchanged definition writes nothing, a changed one becomes a new version; the
|
|
13
|
+
summary says which (`created at version 1`, `unchanged at version 2`, `version 2 -> 3`).
|
|
14
|
+
- **Agents are marked as the blueprint's own.** Another blueprint's agent of the same name is refused, and an agent made by hand is
|
|
15
|
+
refused unless you pass `--allow-agent-adoption` (adopting it writes the declared definition as a new version, which changes every
|
|
16
|
+
run that uses the latest version). Removing an entry from the blueprint deletes nothing.
|
|
17
|
+
- **Scopes:** the applying credential needs `agents:c`, and `agents:u` and `agents:r` as well when the agent already exists, even if
|
|
18
|
+
its definition is unchanged. On a `403` the apply stops, names the agent, scope and context, and mints no key.
|
|
19
|
+
- **`vectros agents list|get|create|version`.** `--context` is required and `--tenant test|live` is accepted. `create` takes a name
|
|
20
|
+
(1 to 64 letters, digits, `_` or `-`) and a JSON or YAML definition file. `version` takes the agent's id and a file, writes a new
|
|
21
|
+
version as a full replacement, and takes `--expected-version` (refuse the write if someone else got there first) and `--restore`
|
|
22
|
+
(bring a retired agent back). `list` takes `--include-retired`; `get` takes the id and `--at-version`. There is no `delete` verb:
|
|
23
|
+
retire an agent through the API.
|
|
24
|
+
- **A blueprint can grant `runs:c` and `runs:r`.** A trigger cannot be granted `runs`, directly or through a role.
|
|
25
|
+
- **`blueprint validate` and `plan` warn about a schema field named `externalId`, `partnerUserId`, `scopes` or `userId`** (the platform
|
|
26
|
+
reserves them; exit `0`); a lookup field with one of those names is an error (exit `2`).
|
|
27
|
+
- **A blueprint's names, labels and descriptions with more invisible characters are refused.**
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- **`vectros --version` reports SDK 0.49.0.**
|
|
32
|
+
- **`apply` and `bootstrap` ask before reusing a trigger's service principal that this blueprint did not mark:** a prompt, or
|
|
33
|
+
`--confirm-existing-principal` in a pipeline (exit `3` without it, before anything is written). Principals from earlier releases
|
|
34
|
+
carry no mark, so the first re-apply of a blueprint with triggers needs the confirmation once per trigger; marking needs `users:u`.
|
|
35
|
+
- **`vectros blueprint-test` runs a blueprint with agents.** Agent names get a per-run suffix (a declared name over 54 characters exits
|
|
36
|
+
`2`), the test retires and purges only the agents it created, and the credential needs `agents:d`. `^C` or SIGTERM during the run
|
|
37
|
+
tears down what the apply listed and exits `130` or `143`. Each run leaves one purged row per agent, and `--keep` leaves the agents.
|
|
38
|
+
- **Text from blueprint files, agent definitions and the platform reaches the terminal without control, invisible or bidirectional
|
|
39
|
+
characters,** cut at 200 lines or 20,000 characters (`[truncated]`). YAML parser warnings are no longer printed.
|
|
40
|
+
- **Blueprint validation runs on zod 4.** An integer beyond JavaScript's safe-integer range and `Infinity` are refused, a string length
|
|
41
|
+
counts characters, and a wrong-typed value stops the checks that depend on it. zod's own messages are reworded (a missing field reads
|
|
42
|
+
`Invalid input: expected string, received undefined`): match on the field path, not on the text.
|
|
43
|
+
|
|
44
|
+
## 0.26.0 — 2026-10-25
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
|
|
48
|
+
- **`vectros whoami --tenant test|live`** shows the session for that tenant (default `live`). The output gains a `tenant type`
|
|
49
|
+
line and `--json` gains `tenantType`. The test tenant shows your own user id there, which needs platform 0.47.0 or later and
|
|
50
|
+
shows `—` on an earlier platform. Any other value stops with a usage error (exit 2).
|
|
51
|
+
- **`vectros access list --principal` prints a note on standard error naming the context it searched.** The command searches
|
|
52
|
+
the `default` context, and depending on the caller the platform may not look beyond it, so an empty result means none in
|
|
53
|
+
`default`; the note gives the `vectros access get --principal … --context <c>` command to check another. Standard output
|
|
54
|
+
and `--json` are unchanged. A `2>&1 | jq` pipeline fails on the note; redirect standard error instead.
|
|
55
|
+
|
|
56
|
+
### Fixed
|
|
57
|
+
|
|
58
|
+
- **A blueprint file whose trigger `dataScope` uses `${{ input.userId }}` or `${{ input.scope.<namespace> }}` loads in
|
|
59
|
+
`validate`, `plan`, `apply` and `bootstrap`.** The platform resolves these placeholders against the record that fires the
|
|
60
|
+
trigger.
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
|
|
64
|
+
- **`vectros --version` reports SDK 0.48.0.**
|
|
65
|
+
- **`vectros blueprint apply` stops with the platform's message when another request changes the same item at the same
|
|
66
|
+
moment.** When apply updates a schema, role or trigger rule, the platform answers `409` (`VERSION_CONFLICT`) instead of
|
|
67
|
+
overwriting the other change. Run apply again once the other change has finished.
|
|
68
|
+
- **`vectros provider-config create` and `update` stop with the platform's `503` when it cannot store the provider key.**
|
|
69
|
+
Nothing is saved; run the command again shortly.
|
|
70
|
+
- **The bundled `@vectros-ai/blueprints` is 0.20.3, and the package description covers the whole command set.**
|
|
71
|
+
- **The comments in the shipped code describe the code as it is today.** Behaviour is unchanged, except for the text of the
|
|
72
|
+
error for a missing Cognito client id.
|
|
73
|
+
|
|
74
|
+
### Documentation
|
|
75
|
+
|
|
76
|
+
- **The README documents `vectros login`, `logout`, `whoami` and `switch`, and `vectros keyring prune --dry-run`.**
|
|
77
|
+
- **The README says `vectros blueprint-test` exits `1` for a blueprint that cannot be read, and that
|
|
78
|
+
`vectros provider-config create` and `update` stop with the platform's `503` when it cannot store the provider key.**
|
|
79
|
+
- **The authoring guide describes the `inputs:` block of a blueprint: its types, `required` and `default`, `--set` and
|
|
80
|
+
`--values`, and the `vectros.context` and `vectros.suffix` built-ins.**
|
|
81
|
+
- **The authoring guide shows an abbreviated `plan` output, with the steps in the order they run and the closing step count, and
|
|
82
|
+
uses `--tenant test` for `blueprint-test`.**
|
|
83
|
+
|
|
6
84
|
## 0.25.0 — 2026-10-12
|
|
7
85
|
|
|
8
86
|
### Breaking changes
|
package/README.md
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
The Vectros provisioning CLI — the `vectros` binary:
|
|
7
7
|
|
|
8
|
+
- **`vectros login`** / **`logout`** / **`whoami`** — sign in through your browser (`--no-browser` prints the URL instead, for headless machines), clear the stored session, and show the signed-in session for a tenant (`--tenant test|live`, default `live`; `--json`).
|
|
9
|
+
- **`vectros switch <alias>`** — shortcut for `keyring use`.
|
|
8
10
|
- **`vectros bootstrap`** — provision a least-privilege MCP credential (+ optional blueprint).
|
|
9
11
|
- **`vectros blueprint`** — author + inspect blueprints (`init` / `validate` / `plan` / `list`, creds-free), and
|
|
10
12
|
**`apply`** one into a tenant without minting a key (for CI).
|
|
@@ -18,6 +20,7 @@ The Vectros provisioning CLI — the `vectros` binary:
|
|
|
18
20
|
- **`vectros role`** — define reusable, context-scoped access rules.
|
|
19
21
|
- **`vectros scripts`** — push, list, inspect, and delete the versioned script source a trigger
|
|
20
22
|
fires, or your own app executes directly.
|
|
23
|
+
- **`vectros agents`** — list, inspect, create, and version stored agents (a model, a system prompt, and a tool whitelist).
|
|
21
24
|
- **`vectros assume`** — switch identity namespace values on your own token, per a role's `assumable` grant.
|
|
22
25
|
- **`vectros access`** — bind principals to contexts, and inspect what a binding grants.
|
|
23
26
|
- **`vectros key`** — issue, list, revoke, and rotate scoped API keys (`ssk_*`).
|
|
@@ -76,7 +79,8 @@ On a machine with no local record of a prior mint (e.g. an ephemeral CI
|
|
|
76
79
|
container re-running `--yes` for the first time) against a blueprint whose
|
|
77
80
|
service principal already exists in the tenant, `--yes` alone isn't enough —
|
|
78
81
|
add `--confirm-existing-principal` to make that expected case explicit and
|
|
79
|
-
non-interactive; see AUTHORING.md's "idempotency contract" for why.
|
|
82
|
+
non-interactive; see AUTHORING.md's "idempotency contract" for why. The same flag covers a trigger's service principal
|
|
83
|
+
that already exists without this blueprint's mark (see the `apply` section below). For a CI re-apply that has no use for the
|
|
80
84
|
key, `vectros blueprint apply` (below) is the better fit.
|
|
81
85
|
|
|
82
86
|
**An issuer that needs verification.** A blueprint's `issuers` entry registered without `restrictedToDomain` starts
|
|
@@ -140,7 +144,7 @@ vectros blueprint apply ./my-thing.blueprint.yaml --tenant live --yes --confirm-
|
|
|
140
144
|
|
|
141
145
|
`apply` runs the same pipeline as `vectros bootstrap` (the same credential, the same scope and capability gates,
|
|
142
146
|
the same loader) with the key step switched off: the context, its service principal and access profile, schemas,
|
|
143
|
-
roles, issuers, triggers and
|
|
147
|
+
roles, issuers, triggers, scripts and agents are created or reconciled (and, only if you pass `--seed`, the blueprint's sample
|
|
144
148
|
seed records are written), but **no scoped key is minted,
|
|
145
149
|
nothing is written to a keyring, and no MCP client config is touched**. (Short-lived bootstrap tokens are minted
|
|
146
150
|
to call the platform, as with `bootstrap`; none is a scoped key.) That is what makes it fit for re-applying
|
|
@@ -164,11 +168,18 @@ run. Use `bootstrap` when you also want the credential.
|
|
|
164
168
|
place, as `bootstrap` does.)
|
|
165
169
|
- **An existing service principal needs `--confirm-existing-principal`** (with `--yes`, or with no terminal),
|
|
166
170
|
which is every apply once the principal exists, on any machine: `apply` never reads a local key record, so a
|
|
167
|
-
machine that ran `bootstrap` is not exempt. It lets `apply` rewrite that principal's access profile
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
171
|
+
machine that ran `bootstrap` is not exempt. It lets `apply` rewrite that principal's access profile. The same flag
|
|
172
|
+
covers a trigger's service principal that already exists and that this blueprint did not mark. A principal created
|
|
173
|
+
for a trigger is marked with the blueprint's name (a `provisionedBy` key on the principal), so the confirmation
|
|
174
|
+
is asked only for one that has no mark (an earlier release made it, or someone made it by hand) or carries another
|
|
175
|
+
blueprint's: the first confirmation marks it as this blueprint's (an overwrite that needs the `users:u` scope in the
|
|
176
|
+
blueprint's context and is skipped when the principal's payload reads back masked; if the run does not write it, it says
|
|
177
|
+
why and the next run asks again), and with no
|
|
178
|
+
terminal and no flag the run stops before it writes a schema, role, profile, trigger, key or seed record. The mark is advisory, a guard against
|
|
179
|
+
an accidental name collision or a pre-created principal; it does not stop someone who can create principals and
|
|
180
|
+
copies the format. In a pipeline this flag is standing consent: it also waves through a blueprint whose
|
|
181
|
+
`servicePrincipal.externalId` or trigger name collides with an unrelated identity, so keep the blueprint's source
|
|
182
|
+
reviewed. Every run that proceeds prints which principal it reused (id, external id, created time) and why.
|
|
172
183
|
- **Sample seed records are opt-in: `apply` writes none unless you pass `--seed`,** in either tenant, and never asks.
|
|
173
184
|
This is the opposite of `bootstrap` (which seeds unless `--no-seed`) on purpose: a blueprint's seeds are
|
|
174
185
|
illustrative, not real data, and a re-apply from a pipeline must not write them by omission. When the blueprint
|
|
@@ -184,13 +195,13 @@ run. Use `bootstrap` when you also want the credential.
|
|
|
184
195
|
but `--require-verified-issuers` was given and an issuer is pending verification.
|
|
185
196
|
|
|
186
197
|
Flags it shares with `bootstrap` (`--set`, `--values`, `--allow-tenant-wide-namespaces`,
|
|
187
|
-
`--allow-script-adoption`, `--require-verified-issuers`, `--token`, `--base-url`) behave the same. `--tenant`,
|
|
198
|
+
`--allow-script-adoption`, `--allow-agent-adoption`, `--require-verified-issuers`, `--token`, `--base-url`) behave the same. `--tenant`,
|
|
188
199
|
`--yes` and `--confirm-existing-principal` are shared but behave as described above (`--tenant` is required here,
|
|
189
200
|
`--yes` is required without a terminal, and the principal flag applies to every re-apply). The flags that concern a
|
|
190
201
|
key or your MCP client (`--rotate`, `--client`, `--no-merge`, `--activate`, `--no-activate`, `--use-scoped-token`,
|
|
191
202
|
`--test`) belong to `bootstrap` and are refused with a pointer; the blueprint is an argument, not `--blueprint`, and
|
|
192
|
-
there is no `--blank`. A script pushed onto an existing hand-authored name (`--allow-script-adoption`)
|
|
193
|
-
|
|
203
|
+
there is no `--blank`. A script pushed onto an existing hand-authored name (`--allow-script-adoption`) and an agent
|
|
204
|
+
that exists with no blueprint mark (`--allow-agent-adoption`) are checked when they are written, partway through, not up front. `vectros blueprint apply --help` lists everything.
|
|
194
205
|
|
|
195
206
|
## `vectros blueprint-test` — verify it actually provisions (creds-required)
|
|
196
207
|
|
|
@@ -210,10 +221,17 @@ vectros blueprint-test ./my-thing.blueprint.yaml --tenant test
|
|
|
210
221
|
vectros blueprint-test task-management --keep
|
|
211
222
|
```
|
|
212
223
|
|
|
213
|
-
Exit `0` = applied and every assertion passed; `1` = an assertion failed
|
|
214
|
-
errored; `2` = no credential, or the scope gate or the capability gate refused the blueprint
|
|
224
|
+
Exit `0` = applied and every assertion passed; `1` = an assertion failed, apply
|
|
225
|
+
errored, the blueprint could not be read, or an agent the run created could not be retired or purged (the one teardown failure that changes the result); `130` = stopped by SIGINT (^C) and `143` = by SIGTERM, after the rest of the apply finishes (no further agents are written; a key mint and seed records still run) and the teardown it still runs (a second signal leaves at once and names the agents that may still be active); `2` = no credential, or the scope gate or the capability gate refused the blueprint,
|
|
226
|
+
or an agent name is too long to take the run's suffix.
|
|
215
227
|
The app-context is intentionally **not** deleted (it's idempotent and reused).
|
|
216
228
|
|
|
229
|
+
A blueprint that declares `agents` (see [`vectros agents`](#vectros-agents--stored-versioned-agent-definitions)) runs too. Because a retired or purged agent keeps its name for good, the
|
|
230
|
+
test applies a copy of your blueprint whose agent names carry a suffix unique to the run (`triage` runs as `triage-t1a2b3c4d`; the report
|
|
231
|
+
lists each), then retires and purges exactly the agents it created, even when an assertion failed. Agents that exist under your declared names
|
|
232
|
+
are never touched. A name can be at most 54 characters long here, and the credential needs `agents:d` as well as the scopes an apply needs.
|
|
233
|
+
Each run leaves one purged row per declared agent behind, because a name stays reserved; `vectros agents list --include-retired` shows them.
|
|
234
|
+
|
|
217
235
|
## `vectros context` — app contexts
|
|
218
236
|
|
|
219
237
|
A context is the namespace all data (records, documents, schemas, roles, access
|
|
@@ -317,13 +335,14 @@ config up itself is refused by the platform with a `400` for anything but `--bil
|
|
|
317
335
|
`byo-model-inference:customer-key` waiver type, and a plain `https://` endpoint on port 443 (no credentials,
|
|
318
336
|
query or fragment). On `update`, only a **change** to one of those is refused; a value the config already
|
|
319
337
|
holds is accepted. Changing an endpoint's host needs the key again (`--api-key-secret-file`). The key must
|
|
320
|
-
be printable ASCII, at most 4096 characters. A tenant holds at most 25 provider configs.
|
|
338
|
+
be printable ASCII, at most 4096 characters. A tenant holds at most 25 provider configs. If the platform cannot store the key it answers `503`, nothing is saved, and the command stops with that message; run it again shortly.
|
|
321
339
|
|
|
322
340
|
The CLI does not sign the risk waiver: an account owner signs it in the developer portal, under **Model
|
|
323
341
|
Providers**, for each environment (live or test). A config is usable only while that waiver is in force for
|
|
324
|
-
your account. It is not in force when it is neither signed nor granted to your account, when it
|
|
325
|
-
|
|
326
|
-
|
|
342
|
+
your account. It is not in force when it is neither signed nor granted to your account, when it has been revoked,
|
|
343
|
+
or when Vectros has required a newer version than the one your owner signed (a waiver Vectros granted to your tenant
|
|
344
|
+
without a signature ends then too). A new published version of the waiver changes nothing by itself: the version your owner signed stays in force
|
|
345
|
+
until Vectros requires a newer one, and account owners are told in advance of the date. The portal shows which of these
|
|
327
346
|
applies. An account that has accepted the Business Associate Agreement with Vectros in the developer portal needs one more thing before a call can
|
|
328
347
|
use a config: an account owner attests that config in the developer portal (Model Providers). Until then the
|
|
329
348
|
platform refuses the call with a `403` that says it needs a BAA-holder attestation. The CLI does not attest
|
|
@@ -506,6 +525,42 @@ A blueprint can ship a script instead of pushing one — see `scripts:` in
|
|
|
506
525
|
convergent (an unchanged source pushes nothing) and never deletes: removing a `scripts:` entry
|
|
507
526
|
leaves every version in place, which is why this command group exists to remove one deliberately.
|
|
508
527
|
|
|
528
|
+
## `vectros agents` — stored, versioned agent definitions
|
|
529
|
+
|
|
530
|
+
A stored agent is a named definition of a model, a system prompt, a tool whitelist, per-run limits and a
|
|
531
|
+
spending cap, kept in an app context. Every change writes a new immutable version and the agent always
|
|
532
|
+
points at its newest one; nothing is edited in place. These verbs and a blueprint's `agents:` section
|
|
533
|
+
write through the same API, so use them for an agent no blueprint manages and to read what an apply stored.
|
|
534
|
+
|
|
535
|
+
```bash
|
|
536
|
+
vectros agents create intake-triage --context my-app --file ./intake-triage.yaml
|
|
537
|
+
vectros agents list --context my-app # each agent at its newest version
|
|
538
|
+
vectros agents list --context my-app --include-retired
|
|
539
|
+
vectros agents get 3b1c9f2e7a5d… --context my-app # newest version, with its prompt
|
|
540
|
+
vectros agents get 3b1c9f2e7a5d… --context my-app --at-version 1 # an earlier version
|
|
541
|
+
vectros agents version 3b1c9f2e7a5d… --context my-app --file ./intake-triage.yaml --expected-version 1
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
The definition file is JSON, or YAML for a `.yaml`/`.yml` file, with the fields of a blueprint's `agents` entry:
|
|
545
|
+
`model` (required), `description`, `authority`, `system`, `tools` (`{ name, allowWrites? }`), `limits` and `budget`.
|
|
546
|
+
A key outside that list is refused before anything is sent, because the platform would drop it and store the agent
|
|
547
|
+
without what you meant it to have.
|
|
548
|
+
|
|
549
|
+
| Subcommand | Flags | Notes |
|
|
550
|
+
|---|---|---|
|
|
551
|
+
| `create` | the agent name; `--context <c>`, `--file <path>` (both required); `--tenant <test\|live>` | Stores version 1. If the name already exists the stored agent is returned **untouched** and nothing is written; the output says so. A retired or purged name is refused (`409`) because the name stays reserved. |
|
|
552
|
+
| `version` | the agent id; `--context <c>`, `--file <path>` (both required); `--expected-version <n>`, `--restore`, `--tenant <test\|live>` | Writes the next version. A **full replacement**: a field the file leaves out takes its default, nothing is carried over from the version before. `--expected-version` refuses the write (`409`) if the agent has a newer version than the one you read. `--restore` brings a **retired** agent back, with the file as its next version; a purged agent cannot be restored. |
|
|
553
|
+
| `list` | `--context <c>` (required); `--include-retired`, `--tenant <test\|live>` | Each agent at its newest version, newest first. Retired agents are left out unless asked for. |
|
|
554
|
+
| `get` | the agent id; `--context <c>` (required); `--at-version <n>`, `--tenant <test\|live>` | One agent, with its prompt and write-enabled tools marked. Ids are opaque: copy them from `agents list`. |
|
|
555
|
+
|
|
556
|
+
`--context` is required on all four, because an agent belongs to one app context. `create` needs the
|
|
557
|
+
`agents:c` scope on the credential, `version` needs `agents:u`, and `get` needs `agents:r`; `list` needs `agents:r` too, or `runs:c`, which lists each agent's name, version and status without its definition. A `403` names the scope. (A credential that
|
|
558
|
+
can create but not read gets "the name is already in use" for a name that exists; the output says why.)
|
|
559
|
+
There is no `delete`: retiring an agent keeps its name reserved, so it stays a deliberate call to the API.
|
|
560
|
+
|
|
561
|
+
A blueprint can declare agents instead; see *Agents* in [`AUTHORING.md`](./AUTHORING.md). To bring agents you created by hand
|
|
562
|
+
under a blueprint, apply it once with `--allow-agent-adoption`.
|
|
563
|
+
|
|
509
564
|
## `vectros assume` — switch identity namespace values on your own token
|
|
510
565
|
|
|
511
566
|
Re-mints your own verb token with one or more `identity.<namespace>` values
|
|
@@ -541,12 +596,24 @@ vectros access grant --principal me --context my-app --role editor
|
|
|
541
596
|
vectros access grant --principal usr_<id> --context my-app --actions records:r,search:r \
|
|
542
597
|
--scope org:<orgId>
|
|
543
598
|
vectros access list --context my-app # who's in this context
|
|
544
|
-
vectros access list --principal me # which contexts I'm bound to
|
|
599
|
+
vectros access list --principal me # which contexts I'm bound to (see the note below)
|
|
545
600
|
vectros access get --principal me --context my-app
|
|
546
601
|
vectros access explain --principal me --context my-app
|
|
547
602
|
vectros access revoke --principal usr_<id> --context my-app
|
|
548
603
|
```
|
|
549
604
|
|
|
605
|
+
`access list --principal` searches one context, `default`, because the command's token is pinned to it:
|
|
606
|
+
depending on the caller the platform may not look beyond that context, so a grant you hold in another
|
|
607
|
+
context can be missing from the list, and an empty list means no grant in `default`, not no grants
|
|
608
|
+
anywhere. The command says so on standard error, so `--json` output on standard output stays a bare array,
|
|
609
|
+
and it drops the line when a row from another context shows the lookup did span contexts. To see a grant
|
|
610
|
+
in a specific context, run `vectros access get --principal me --context <context-id>` (add `--tenant test`
|
|
611
|
+
for the test tenant), or `vectros access list --context <context-id>` for everyone in it.
|
|
612
|
+
|
|
613
|
+
The line is also written with `--json`, and there is no switch to turn it off. A script that merges standard
|
|
614
|
+
error into standard output (`2>&1`) will see one extra line and a `2>&1 | jq` pipeline will fail on it;
|
|
615
|
+
redirect standard error (`2>/dev/null`) to drop it.
|
|
616
|
+
|
|
550
617
|
`--principal` accepts `usr_<userId>`, `key_<keyId>`, or the alias `me` (your
|
|
551
618
|
own signed-in user, resolved from your login) — every `access` subcommand
|
|
552
619
|
shares this grammar. In the **test tenant** your principal has a different id from your live user, so `me` resolves it per tenant: add `--tenant test` and it still works, e.g. `vectros access grant --principal me --context <context-id> --role <role> --tenant test`. This needs platform 0.47.0 or later; on an earlier platform the command typically stops and points you to `vectros identity list-all --tenant test` (an owner login), which shows the id to pass as `--principal usr_<id>`.
|
|
@@ -612,7 +679,7 @@ is optional and stripped if present) — narrower than `access`'s grammar: there
|
|
|
612
679
|
is no `me` alias on any `key` subcommand, and a key never authenticates as a
|
|
613
680
|
`key_*` principal. Look your own id up first with `vectros identity list
|
|
614
681
|
--type user` (or `vectros whoami`; both show your live tenant, and for the test tenant
|
|
615
|
-
use `vectros identity list-all --tenant test`), or grant/issue via `vectros join`, which
|
|
682
|
+
use `vectros whoami --tenant test` or `vectros identity list-all --tenant test`), or grant/issue via `vectros join`, which
|
|
616
683
|
does resolve `--as me`.
|
|
617
684
|
|
|
618
685
|
A minted secret has exactly two destinations, and the flags for choosing one
|
|
@@ -630,7 +697,7 @@ are shared by `issue` and `rotate`:
|
|
|
630
697
|
| `issue` | `--principal <p>`, `--context <c>` (required); `--name <n>` (default `default`), `--label <l>`, `--tenant test\|live`, destination flags above | Idempotent on `(tenant, context, principal, name)` — re-issuing an existing tuple returns the key **without** the secret (never re-disclosed); the CLI detects that and points you at `rotate`. |
|
|
631
698
|
| `list` | `--principal <p>`, `--context <c>`, `--tenant test\|live` **or** `--all-contexts` (owner-only; spans both tenants, not combinable with `--tenant`) | **The default lists only ONE context's keys** (the token's context — `default`, or `--context`), not your whole account — easy to miss since the active-key limit is tenant-wide across all contexts. `--all-contexts` is the true account-wide view. |
|
|
632
699
|
| `get <keyId>` | `--context <c>`, `--tenant test\|live` | `--context` pins the verb token to the key's context — omit it for a key bound to a non-default context (e.g. one `bootstrap` minted) and the lookup 404s. |
|
|
633
|
-
| `revoke <keyId>` | `--context <c>`, `--tenant test\|live` | Soft-delete;
|
|
700
|
+
| `revoke <keyId>` | `--context <c>`, `--tenant test\|live` | Soft-delete; it takes about 5 minutes to take effect. Same `--context` pinning caveat as `get`. |
|
|
634
701
|
| `rotate` | `--principal <p>`, `--context <c>` (required); `--name <n>`, `--force-new`, `--tenant test\|live`, destination flags above | Revokes the matching active key (by the exact `(context, principal, name)` tuple), then mints a fresh one — there is no dedicated rotate endpoint. **Default-name guard:** if no key is currently active under `--name` (default `default`) but the principal/context has *other* active keys, `rotate` refuses rather than silently minting an unrelated second key — pass the right `--name` or `--force-new` to proceed anyway. |
|
|
635
702
|
|
|
636
703
|
`issue`/`rotate` have no `--json` (use `--format json` instead); `list`/`get`
|
|
@@ -652,6 +719,7 @@ vectros keyring show # the active entry's fields + its key
|
|
|
652
719
|
vectros keyring show --format raw # JUST the secret, for scripts (see below)
|
|
653
720
|
vectros keyring doctor # is the keyring healthy? which keys are live?
|
|
654
721
|
vectros keyring prune # drop entries whose stored secret is gone
|
|
722
|
+
vectros keyring prune --dry-run # report what would be removed, remove nothing
|
|
655
723
|
vectros keyring remove <alias> # drop one entry + its secret
|
|
656
724
|
```
|
|
657
725
|
|
|
@@ -714,8 +782,8 @@ Blueprints are **untrusted input** (agent- or community-authored) and the
|
|
|
714
782
|
CLI runs under an elevated ephemeral bridge token. So the trust boundary is
|
|
715
783
|
**this binary, not the blueprint**: a hardcoded **scope gate** bounds every
|
|
716
784
|
mint to a data-plane allowlist (`records` / `schemas` / `search` / `documents`
|
|
717
|
-
/ `folders` / `inference` / `entities`). Most control-plane scope (keys /
|
|
718
|
-
app-contexts / users / billing / admin / namespaces / triggers) or a
|
|
785
|
+
/ `folders` / `inference` / `entities` / `runs`). Most control-plane scope (keys /
|
|
786
|
+
app-contexts / users / billing / admin / namespaces / triggers / agents) or a
|
|
719
787
|
`*` wildcard **hard-rejects** — the CLI mints nothing and exits non-zero. There is
|
|
720
788
|
intentionally **no override flag**.
|
|
721
789
|
|
|
@@ -754,7 +822,7 @@ A blueprint's `accessProfile` and role clauses may also declare
|
|
|
754
822
|
identity in your tenant) that reach across a partition boundary in a way no
|
|
755
823
|
`resource:ops` verb can express. This rides a field entirely separate from
|
|
756
824
|
`allowedActions`, and it has its own allowlist: **`member-lifecycle` and
|
|
757
|
-
`delegate-principal-stamp` are admitted
|
|
825
|
+
`delegate-principal-stamp` are admitted.** Every other capability name —
|
|
758
826
|
including ones the platform's own registry recognizes — is refused, the same
|
|
759
827
|
fail-closed, deliberately-widen posture as the scope gate above. `vectros blueprint validate`/`plan` and
|
|
760
828
|
`bootstrap` all report a rejected capability the same way they report a
|