@openengio/cli 0.27.1 → 0.33.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openengio/cli",
3
- "version": "0.27.1",
3
+ "version": "0.33.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "engines": {
@@ -79,7 +79,7 @@ differences:
79
79
 
80
80
  | json-render teaches | here | why |
81
81
  |---|---|---|
82
- | props naming a project, ref, organisation, namespace, object, type version, URL or path | refused, always | a view never chooses its own scope: the host derives the page's project and ref from its address, so a view cannot read or link outside it |
82
+ | props naming a project, branch or baseline, organisation, namespace, object, type version, URL or path | refused, always | a view never chooses its own scope: the host derives the page's project and branch or baseline from its address, so a view cannot read or link outside it |
83
83
  | `className`, `style`, `html`, `color` | refused, always | a visual choice is a design-token name, such as a Badge's `tone`, so every view keeps the platform's look and carries no raw HTML |
84
84
  | defining your own catalog and components | not possible | a view is display data, not a capability: the web renders only the catalogue's components |
85
85
  | fetching data from json-render | not possible | data enters only through a `Query` element, which the host scopes |
@@ -88,6 +88,14 @@ Check: the model's convention is written down, and every edge follows it.
88
88
  Check: each type's default tree is the one the person expects; a type with views has its main tree as
89
89
  the first view.
90
90
 
91
+ The `relationships` array is the ordered list of natural parent edge types: the first declared edge
92
+ that supplies a parent places an object in the default tree. Climbing farther uses each ancestor
93
+ type's own declaration. A `structureDeclaration.views` entry is a navigation tree; declaring views
94
+ replaces the relationship picker with those views, so include the usual tree first. A two-step view
95
+ can pass through a shared intermediate object, omit it from the tree, and show its properties as
96
+ decoration. A traceability edge with a `parentEnd` can give one object several parents; the object
97
+ then appears once at each placement, and its ancestry depends on the selected tree.
98
+
91
99
  ## 5. The rail and the page
92
100
 
93
101
  - The organisation holds one list of rail groups, in the order the rail draws them; it is sent whole
@@ -96,7 +104,13 @@ the first view.
96
104
  `rail` is listed under "More types": leave it off for a type that is the detail of another, not a
97
105
  destination.
98
106
  - `presentationBindings.title` names the property that titles the object in tables, trees and the graph view.
99
- `presentationBindings.typeIcon` is a Material Symbols glyph name.
107
+ `presentationBindings.typeIcon` is a Material Symbols glyph name. A new object type needs one, and so does
108
+ every later version of a type whose current version has one; publication refuses it otherwise
109
+ (`missing-type-icon`). Before choosing, read the organisation's existing type icons (`openeng types export`)
110
+ and pick a glyph that is relevant to the type and distinct from theirs.
111
+ `presentationBindings.propertyLabels` maps a property key to a display label of at most 80 characters,
112
+ and `presentationBindings.propertyOrder` lists property keys in display order, each once. Both name
113
+ only properties the version defines.
100
114
  - An **object view** (`presentationBindings.views.object`, root `ObjectBody`) lays out the object's
101
115
  drawer; an **App view** (`.app`, root `AppBody`) lays out the type's page. Only components the view
102
116
  catalogue admits may appear, each with the props it takes.
@@ -135,6 +149,12 @@ for a lifecycle state. A wrong edge is replaced by a new edge type key and a rec
135
149
  - An update is a compare-and-set per property: `{"<property>": {"from": {"value": <what it holds now>}, "to":
136
150
  {"value": <the new value>}}}`; `{"absent": true}` stands for no value on either side. A `from` that no
137
151
  longer matches is refused, so read the object first.
152
+ - A `datetime` property takes an RFC 3339 date-time with an explicit offset and zero to three fraction digits
153
+ (`2026-10-19T22:30:00+01:00`); a value with no offset, an impossible date or time, or four or more
154
+ fraction digits is refused, never truncated. It is stored as `YYYY-MM-DDTHH:MM:SS.sssZ`, the same
155
+ instant in UTC, and a `from` naming the stored instant in another offset still matches. A calendar
156
+ date is its midnight in UTC; there is no date kind. A type that declares `datetime` is schema
157
+ language version `2` or later, and a type's version never decreases.
138
158
 
139
159
  ## Property kinds
140
160
 
@@ -194,8 +214,65 @@ An enum's `members` is a list of strings or finite numbers. A published member c
194
214
  {"kind": "object", "properties": {"name": {"kind": "string"}}, "required": ["name"]}
195
215
  ```
196
216
 
217
+ ### datetime
218
+
219
+ An instant, under schema language version `2`.
220
+
221
+ ```json
222
+ {"kind": "datetime"}
223
+ ```
224
+
225
+ ### attachment
226
+
227
+ A file descriptor on a top-level object property, under schema language version `3`. The kind is
228
+ refused inside object or array properties and in edge and verb schemas. `accept` lists admitted
229
+ classes: adding a class is compatible; removing one or changing the property's kind is refused.
230
+ The accepted classes are `image` (`.png`, `.jpg`, `.jpeg`, `.webp`, `.gif`), `pdf` (`.pdf`),
231
+ `step` (`.step`, `.stp`), `mesh` (`.stl`) and `text` (`.txt`, `.md`, `.csv`, `.json`, `.yaml`,
232
+ `.yml`, `.toml`, `.ini`, `.log`, `.xml`, `.ts`, `.tsx`, `.js`, `.py`, `.c`, `.h`, `.cpp`, `.hpp`,
233
+ `.rs`, `.go`, `.java`, `.m`, `.sql`, `.sh`). The maximum file body is 26,214,400 bytes (25 MiB).
234
+ Use `openeng attachment add <object> <property> <file> --project <id> --ref <ref>` to attach a
235
+ file, `openeng attachment list <object> --project <id> --ref <ref>` to list attachment properties,
236
+ and `openeng attachment get <object> <property> [--out <path>] --project <id> --ref <ref>` to save
237
+ one property's bytes.
238
+
239
+ ```json
240
+ {
241
+ "typeCategory": "object",
242
+ "typeKey": "drawing_record",
243
+ "version": 1,
244
+ "displayName": "Drawing record",
245
+ "description": null,
246
+ "schemaLanguageVersion": "3",
247
+ "propertyDefinitions": {
248
+ "drawing": {"kind": "attachment", "accept": ["image", "pdf", "step", "mesh", "text"]}
249
+ },
250
+ "requiredPropertyKeys": []
251
+ }
252
+ ```
253
+
197
254
  ## 9. Examples
198
255
 
256
+ These are small type documents to adapt and validate in a change set before accepting it.
257
+
258
+ ### Example: object type
259
+
260
+ ```json
261
+ {"typeCategory":"object","typeKey":"task","version":1,"displayName":"Task","description":null,"schemaLanguageVersion":"1","propertyDefinitions":{"name":{"kind":"string"}},"requiredPropertyKeys":["name"],"presentationBindings":{"title":"name","typeIcon":"task"}}
262
+ ```
263
+
264
+ ### Example: edge type
265
+
266
+ ```json
267
+ {"typeCategory":"edge","typeKey":"depends-on","version":1,"displayName":"Depends on","sourceObjectType":"task","targetObjectType":"task","kind":"traceability","subjectEnd":"source","parentEnd":"source","sourceLabel":"depends on","targetLabel":"is depended on by","schemaLanguageVersion":"1","propertyDefinitions":{},"requiredPropertyKeys":[],"readRule":"both-endpoints","writeRule":"both-endpoints"}
268
+ ```
269
+
270
+ ### Example: template verb with its result contract
271
+
272
+ ```json
273
+ {"typeCategory":"verb","typeKey":"create-task","version":1,"displayName":"Create task","description":null,"allowedSubjectTypes":"none","inputSchema":{"kind":"object","properties":{"name":{"kind":"string"}},"required":["name"]},"resultSchema":{"kind":"null"},"schemaLanguageVersion":"1","template":{"operations":[{"kind":"create-object","typeKey":"task","properties":{"name":{"slot":"input","key":"name"}}}]}}
274
+ ```
275
+
199
276
  A minimal object type and a structural edge, every key at version 1:
200
277
 
201
278
  ```json
@@ -44,7 +44,7 @@ out of every story.
44
44
  - [ ] C2. One data model, two ways of working: a CRUD app or a branch-first engineering workflow
45
45
  Checklist: Switch one project between direct edits on `main` and branch-only edits.
46
46
  Features shown: Objects; Branches; Branch diff and changed-object accents; Proposals; Roles and
47
- membership; Ref rules.
47
+ membership; Branch rules.
48
48
 
49
49
  - [ ] C3. Follow one question across every tool
50
50
  Checklist: Answer one question that crosses requirements, parts and tests.
@@ -57,13 +57,15 @@ out of every story.
57
57
  subscribers; Delete preview; Branch history and the audit trail.
58
58
 
59
59
  - [ ] C5. An agent does the work, a person makes the call
60
- Checklist: Have the in-product agent make a change that a person approves and merges.
60
+ Checklist: Explain that the organisation's agent model is chosen in the web app under Admin,
61
+ Agent model; open or link that page. Have the in-product agent make a change that a person
62
+ approves and merges.
61
63
  Features shown: Branches; Branch diff and changed-object accents; Proposals; Branch history and
62
64
  the audit trail; Object agent; Agent model per organisation; Agent ceiling.
63
65
 
64
66
  - [ ] C6. Freeze what shipped, keep building what comes next
65
67
  Checklist: Freeze a released part and keep a read-only release baseline.
66
- Features shown: Types and the ontology; Objects; Relationships; Organisation refs; Instance
68
+ Features shown: Types and the ontology; Objects; Relationships; Organisation branches and baselines; Instance
67
69
  locks; Type rules.
68
70
 
69
71
  - [ ] C7. Your CAD system stays the source of truth
@@ -99,11 +101,14 @@ cares about; do not explain a primitive in isolation.
99
101
  `objects-sdk mutateBatch`, then show the rail, table and object card with `link type`.
100
102
  - C2: edit on main, add a merge-only rule, show the same edit refused `protected`, then branch,
101
103
  edit, compare and submit a proposal. The person merges; remove the rule and show direct edits.
102
- - C3: narrow with `objects-sdk readStructure`, show `link explore`, and answer a question
104
+ - C3: narrow with `objects-sdk readStructure`, show `link explore --object <id>` for the selected
105
+ object, and answer a question
103
106
  across requirements, parts and tests with `queryObjects`, `findPaths` and `aggregateObjects`.
104
107
  - C4: open a record's history, comment and subscribe; use `objects-sdk previewDelete` before
105
108
  any deletion, and read branch history and `admin-sdk listAudit`.
106
- - C5: show the organisation's agent model and project's `ceiling show`. The person uses
109
+ - C5: explain that the organisation's agent model is chosen in the web app under **Admin**, **Agent model**.
110
+ Run `openeng link organisation-page agent-model` and open or share the returned link. The CLI
111
+ has no read of the selected model; do not claim to have read it. Show the project's `ceiling show`. The person uses
107
112
  "Open agent", approves its plan, inspects the branch diff, submits and merges. Read the audit
108
113
  naming the person and run; show the agent refused on protected main.
109
114
  - C6: use `locks set --lock frozen` on a released part, show an edit refused, create its successor
@@ -118,7 +123,7 @@ cares about; do not explain a primitive in isolation.
118
123
 
119
124
  At each step, say what comes next and why, make the smallest useful change (one atomic batch
120
125
  for related writes), validate before publishing, and read the result in the intended organisation,
121
- project and ref. Give a link from `openeng link`, say what they should see, and leave time to see it.
126
+ project and branch or baseline. Give a link from `openeng link`, say what they should see, and leave time to see it.
122
127
  Invite an action that matters, then check its result with a read. Keep accepted, validated,
123
128
  published and seen in the app distinct. Drive through the CLI; the person operates the app.
124
129
 
@@ -2,7 +2,7 @@
2
2
  name: openeng
3
3
  description: >-
4
4
  Use when you need to work with an OpenEngineering platform through its command line, `openeng`.
5
- Signing in, listing projects and types, editing object types, writing objects on an agreed ref
5
+ Signing in, listing projects and types, editing object types, writing objects on an agreed branch
6
6
  and submitting branches for review.
7
7
  ---
8
8
 
@@ -14,11 +14,27 @@ description: >-
14
14
  npm install -g @openengio/cli
15
15
  ```
16
16
 
17
+ Set `OPENENG_NO_UPDATE_CHECK=1` to disable the daily npm update check and standard-error notice; `CI`, help and `--version` also skip it.
18
+
17
19
  This skill gives the commands and their order. It gives no input shapes, because the commands print
18
20
  their own. Before you send a generated command (`objects-sdk`, `branches-sdk` and the other
19
21
  `<module> <method>` commands), run `openeng help <module> <method>`. It prints the fields, the kinds a
20
22
  field may take, the selector keys and one example input, and needs no sign-in.
21
23
 
24
+ ## Explain each step
25
+
26
+ When guiding a person, say what you intend to learn or change, give the command, then report what it
27
+ answered and what follows. When the step has a GUI page, include the address from `openeng link` at
28
+ that step; do not construct a page address yourself. For example:
29
+
30
+ 1. Intent: identify the project and its namespace. Run `openeng projects list --json`; report the
31
+ project id and namespace it returned.
32
+ 2. Intent: show the project in the web app. Run `openeng link project --project <id> --ref main`
33
+ and give the returned address with what the page should show.
34
+ 3. Intent: inspect one object in the chosen branch. Run the relevant read command and report its
35
+ result; when the person needs its page, run `openeng link object <object-id> --project <id>
36
+ --ref <ref>` and give that returned address.
37
+
22
38
  ## Read the topic for your task
23
39
 
24
40
  - A person new to OpenEngineering who wants a tour, or has just signed in with no task of their own: `openeng skill demo`.
@@ -29,6 +45,15 @@ field may take, the selector keys and one example input, and needs no sign-in.
29
45
  - A domain model: `openeng skill playbook engineering-requirements`,
30
46
  `openeng skill playbook product-lifecycle`, or `openeng skill playbook project-management`.
31
47
 
48
+ ## Attachments
49
+
50
+ For a top-level object property declared with kind `attachment`, use
51
+ `openeng attachment add <object> <property> <file> --project <id> --ref <ref>` to stage a file and
52
+ save its descriptor, `openeng attachment list <object> --project <id> --ref <ref>` to read its
53
+ attachment properties, and `openeng attachment get <object> <property> [--out <path>]` with the
54
+ project and ref flags to download it. The `get` command uses the descriptor's file name when `--out`
55
+ is omitted. The accepted classes and file-size limit are in `openeng skill conventions`.
56
+
32
57
  ## Rules that hold for every command
33
58
 
34
59
  - Add `--json` when you read the answer yourself. It prints one JSON value on standard output.
@@ -91,9 +116,9 @@ For a generic open-cycle gas turbine demonstration project, run `openeng demo se
91
116
  `{"organisation": {"id", "name"}, "project"?, "ref"?}`. An object value normally gains a `scope` key.
92
117
  A value that is an array or null, such as the list from `openeng projects list`, comes wrapped as
93
118
  `{"scope": {...}, "value": <the original value>}`. Rules command successes always use this wrapper
94
- to preserve the rule's own `scope` field. Organisation-ref, lock, ceiling and schema-update
119
+ to preserve the rule's own `scope` field. Organisation branch or baseline, lock, ceiling and schema-update
95
120
  successes also always use `{ scope, value }`. A command with no scope carries no `scope` field.
96
- - A `not-found` in an organisation is often a project or a ref that belongs to another one. The
121
+ - A `not-found` in an organisation is often a project or a branch or baseline that belongs to another one. The
97
122
  command prints "not found in organisation <name>: check that you are attached to the correct
98
123
  organisation (openeng org current)". Run `openeng org current`; if it names the wrong organisation,
99
124
  `openeng org list` and `openeng org attach <id>`.
@@ -111,6 +136,8 @@ to understand each part, then design the model with the person before you draft
111
136
  it writes them as one JSON object keyed by type key, each at the next version, ready to send
112
137
  with revise. If it has no published types, create `draft.json` from the `changes` map in the
113
138
  example input printed by `openeng help ontology-sdk reviseChangeSet`.
139
+ A new object type needs `presentationBindings.typeIcon`; read the existing types' icons in the
140
+ export and choose a relevant glyph that no other type uses.
114
141
  2. Make `draft.json` hold only the types you change: delete every other key, and keep each type you
115
142
  keep whole, as the export wrote it. Accepting a type you did not change publishes an identical
116
143
  new version of it.
@@ -121,12 +148,28 @@ to understand each part, then design the model with the person before you draft
121
148
  5. `openeng types draft validate --change-set <id> --revision <revision>` must report no violations.
122
149
  It exits 0 when there are no violations, and exits 4 with the violations on standard output
123
150
  otherwise; then edit the file and revise again.
151
+ To try a sample instance against a type in the draft before you accept it, write the sample as a
152
+ JSON object of raw property values and run `openeng types draft try --type <type key> --sample
153
+ sample.json`. It reads the open change set and writes nothing, and checks the sample the way a
154
+ write does: it exits 0 when the sample fits and exits 4 with each violation's path and rule
155
+ otherwise. Add `--change-set <id>` to name the change set instead of using the open one.
124
156
  6. `openeng types draft show --change-set <id> --project <project id>` shows what changes against the
125
157
  published types, per type and per field. Check that it is exactly the change you meant.
126
158
  7. `openeng types draft accept --change-set <id> --revision <revision>` publishes it. The new version
127
159
  is now the published one: from here on, take a type's version for data writes from
128
160
  `openeng types list`.
129
161
 
162
+ Property kinds are `null`, `boolean`, `string`, `number`, `integer`, `person`, `enum`, `array`,
163
+ `object`, `datetime` and `attachment`. Use `datetime` for an instant. A value is an RFC 3339 date-time
164
+ with an explicit offset and zero to three fraction digits, such as `2026-10-19T22:30:00+01:00` or
165
+ `2026-10-19T21:30:00Z`; a value with no offset, an impossible date or time, or four or more fraction
166
+ digits is refused. The platform stores it as `YYYY-MM-DDTHH:MM:SS.sssZ`, the same instant in UTC.
167
+ A calendar date is midnight UTC; there is no date kind. A type declaring `datetime` needs language
168
+ version `2` or later. An `attachment` is a top-level object property under version `3`, with a
169
+ non-empty `accept` listing classes such as `image` and `pdf`; it is refused inside an object or
170
+ array property and in an edge or verb schema. See the named property example in
171
+ `openeng skill conventions`. Never lower a published type's language version when revising it.
172
+
130
173
  To abandon a draft, `openeng types draft discard --change-set <id>`.
131
174
 
132
175
  `presentationBindings.typeIcon` is a Material Symbols Rounded name from the installed
@@ -141,29 +184,35 @@ watchers are admitted; the publication validator decides whether a declaration i
141
184
 
142
185
  ## 3. Write data
143
186
 
144
- Write on the ref agreed with the person and within their authority. That may be `main` when
187
+ Write on the branch agreed with the person and within their authority. That may be `main` when
145
188
  the applicable protections permit the write; an approved agent plan may also name an unprotected
146
- project's `main`. Use a branch and review when a rule protects the ref or the person asks for it.
189
+ project's `main`. Use a branch and review when a rule protects the branch or the person asks for it.
147
190
 
148
191
  1. `openeng help objects-sdk mutate` and `openeng help branches-sdk createBranch` for the fields, the
149
192
  selector keys and an example each.
150
193
  2. When a branch is needed, `openeng branches-sdk createBranch` makes one in the project. It
151
- answers the branch's ref, written `<project id>/<name>`.
152
- 3. `openeng objects-sdk mutate` creates, changes or deletes an object or an edge on that ref. A ref in
194
+ answers the branch's full name, written `<project id>/<name>`.
195
+ 3. `openeng objects-sdk mutate` creates, changes or deletes an object or an edge on that branch. The `ref` field in
153
196
  a selector takes one of three forms: the organisation trunk is the bare `main`; a project
154
- branch is its whole ref, `<project id>/<name>`; an organisation ref is its bare name.
155
- The server derives the organisation from the token. Use the agreed ref for writes and read
156
- back from that same ref with
197
+ branch is its full name, `<project id>/<name>`; an organisation branch or baseline is its bare name.
198
+ `--ref` takes a branch (`main` or `<projectId>/<branch>`) or a baseline for commands that admit organisation names.
199
+ The server derives the organisation from the token. Use the agreed branch for writes and read
200
+ back from that same branch with
157
201
  `openeng objects-sdk readObject` and `openeng objects-sdk queryObjects`.
158
202
  4. Read back what you wrote: `openeng objects-sdk readObject` for one object, or
159
- `openeng objects-sdk queryObjects` for a list. Use the type key and version the project's
203
+ `openeng objects-sdk queryObjects` for a list. Use `openeng objects-sdk queryRows` when you need
204
+ selected row cells, a count or grouped values; it answers these in one call instead of paging
205
+ `queryObjects` to count locally. Use the type key and version the project's
160
206
  `openeng types list` showed. For an object's edges use `openeng objects-sdk queryGraph`;
161
207
  for paths use `openeng objects-sdk findPaths`. Confirm relationships through the CLI;
162
208
  do not hand the check to the web app.
163
209
  5. `openeng objects-sdk executeVerb` runs a verb a type defines. `openeng objects-sdk discoverVerbs` lists
164
210
  the verbs available.
165
211
  6. When using a branch for review, `openeng branches-sdk submitProposal` sends it for review. It
166
- names the branch by its `name` alone, the part of the ref after the slash.
212
+ names the branch by its `name` alone, the part of the full branch name after the slash.
213
+
214
+ If a verb name is unknown, use `openeng objects-sdk discoverVerbs` for the object and choose a
215
+ listed verb; do not guess a verb key.
167
216
 
168
217
  If a command is refused, the refusal names the field and its allowed kinds. Run
169
218
  `openeng help <module> <method>` again and compare.
@@ -181,11 +230,35 @@ openeng objects-sdk queryGraph --host https://api.openeng.io --selector '{"proje
181
230
  Check the returned hops against the relationships you wrote. Use `findPaths` for paths across
182
231
  several objects; read its help before supplying input.
183
232
 
184
- ## Project ref rules
233
+ ### Review object and relationship changes
234
+
235
+ Run `openeng help branches-sdk diffBranches` for a live branch comparison, or
236
+ `openeng help branches-sdk readBranchDiff` for a submitted proposal's reviewed comparison.
237
+ Read both the object collection (`changes` for a live diff, `objects` for a proposal) and
238
+ `edges`. One page holds at most 200 changes total; follow its cursor until it is null before
239
+ describing the whole change. An edge's source and target carry object and project identifiers,
240
+ plus the edge's own properties before and after. An unreadable endpoint's identifiers do not
241
+ grant access to its title, type or properties. A cursor from an older client is refused;
242
+ start the comparison again with no cursor.
243
+
244
+ ## Project branch rules
245
+
246
+ `openeng branches-sdk disposeRef` is a writer's cleanup of a branch with no pending proposal.
185
247
 
186
- A project rule may protect `main` or refs under that project's identifier. A matching
248
+ ### Resolve a merge conflict
249
+
250
+ When merge answers `merge-conflict`, read the conflicts with
251
+ `openeng branches-sdk readMergeConflicts --selector '{"projectId":"<project-id>"}'
252
+ --input '{"name":"<source-branch-name>"}'`. The `name` is the source branch's name. For each
253
+ field, `base` is its value before either side changed it, `ours` is `main`, and `theirs` is the
254
+ source branch's value. A value may be absent on a side. The read always compares the source with
255
+ `main`, even if the merge targeted another branch, so it does not report conflicts from a merge
256
+ whose target was not `main`. Reconcile the changes on the source branch, then submit a new merge
257
+ with the reviewed head; reading conflicts makes no changes.
258
+
259
+ A project rule may protect `main` or branches under that project's identifier. A matching
187
260
  `merge-only` rule requires changes through a branch and merge. A `locked-rows-only` rule binds
188
- merge-only row locks on the matching ref while leaving unlocked rows direct.
261
+ merge-only row locks on the matching branch while leaving unlocked rows direct.
189
262
 
190
263
  Rule management is the person's workflow: they must hold `administer projects` on the project
191
264
  and run these commands themselves. Never add or remove rules on their behalf, including to
@@ -199,11 +272,11 @@ get past a refusal.
199
272
  3. To lift one rule, the person runs `openeng rules remove --project <id> --rule-id <id>` with
200
273
  the identifier from the list. An absent identifier or one from another project answers
201
274
  `not-found`. Removal is audited, as is addition, and takes effect on the next request.
202
- Other matching rules and row locks may still protect the ref's rows.
275
+ Other matching rules and row locks may still protect that branch's rows.
203
276
 
204
- ## Organisation rules, refs, locks and agent ceilings
277
+ ## Organisation rules, branches and baselines, locks and agent ceilings
205
278
 
206
- These protections are managed by the person. Never change rules, refs or locks yourself,
279
+ These protections are managed by the person. Never change rules, branches, baselines or locks yourself,
207
280
  including to get past a refusal. Read their current state and ask the person to make a change.
208
281
  Each command's `--help` names the person's capability. A `not-permitted` refusal carries no
209
282
  capability; read the help line before asking the person to seek permission.
@@ -215,8 +288,8 @@ capability; read the help line before asking the person to seek permission.
215
288
  `openeng rules list --organisation` reads the rules;
216
289
  `openeng rules remove --organisation --rule-id <id>` removes one by its identifier.
217
290
  Adding or removing needs `administer projects` in the attached organisation; listing needs `read`.
218
- - `openeng org-refs list` reads organisation refs and their read-only state. The person creates
219
- one with `openeng org-refs create --name <name> [--read-only]`, marks it read-only with
291
+ - `openeng org-refs list` reads organisation branches and baselines with their read-only state. The person creates
292
+ a branch with `openeng org-refs create --name <name>` or a baseline by adding `--read-only`. A branch becomes a baseline with
220
293
  `openeng org-refs mark-read-only --name <name>`, or deletes a writable one with
221
294
  `openeng org-refs delete --name <name>`. Names are single segments, such as `release-v1`.
222
295
  Creating, deleting and marking need `administer projects` in the attached organisation;
@@ -224,8 +297,8 @@ capability; read the help line before asking the person to seek permission.
224
297
  - The person sets or lifts an object's lock with
225
298
  `openeng locks set --project <id> --ref <ref> --object <objectId> --lock <none|merge-only|frozen>`.
226
299
  `none` lifts it. The lock also applies to its existing structural child edges in the selected
227
- project. New children on a live ref are not thereby frozen. Use a read-only organisation ref
228
- for a fixed baseline. This needs `lock objects` on the selected project.
300
+ project. New children on a writable branch are not thereby frozen. Use a baseline
301
+ to preserve a fixed snapshot. This needs `lock objects` on the selected project.
229
302
  - `openeng ceiling show --project <id>` reads the maximum agent role. The person sets it with
230
303
  `openeng ceiling set --project <id> --ceiling <contributor|maintainer>`.
231
304
  Showing needs `read`; setting needs `administer projects` on the selected project.
@@ -234,50 +307,75 @@ capability; read the help line before asking the person to seek permission.
234
307
 
235
308
  When a command returns one of these rules, follow its action and do not repeat the same request:
236
309
 
237
- - `immutable`: the type forbids changing or deleting the record on every ref. Leave it unchanged.
310
+ - `immutable`: the type forbids changing or deleting the record on every branch or baseline. Leave it unchanged.
238
311
  - `owned`: a connected system alone writes the record. Ask that system to make the change.
239
312
  - `frozen`: someone with the lock capability must lift the lock. Ask that person; do not try a
240
- different ref.
313
+ different branch or baseline.
241
314
  - `protected`: a rule allows the record to change only through a merge from a branch. Make the
242
315
  change on a branch and merge it.
243
- - `not-a-ref-head`: the commit is not the head of a ref you can use. Read the usable refs and
244
- choose one of their heads; the refusal does not identify which commit or ref was involved.
245
- - `branch-needs-schema-update`: the ref's schema must be updated before writing. The
316
+ - `stale-source`: read a branch you can use and merge its current head. Optional merge `name`
317
+ requires that bound branch's current head to equal `sourceHash`; it never selects a proposal.
318
+ A successful merge into main closes every pending proposal in the project at that reviewed hash.
319
+ - `not-a-ref-head`: the branch has new commits since the review began. Reload the proposal to
320
+ review its latest commit; the refusal does not identify the branch or its newer head.
321
+ - `branch-needs-schema-update`: the branch's schema must be updated before writing. The
246
322
  person can run `openeng schema-update request --ref <ref>` to record a request, then
247
323
  `openeng schema-update show --ref <ref>` to read its state or `no request`. Stop writing while
248
- the ref needs an update; recording a request does not execute the update. Requesting needs
249
- `write ref` on the branch's home project, or `administer projects` for an organisation ref;
324
+ the branch needs an update; recording a request does not execute the update. Requesting needs
325
+ `write ref` on the branch's home project, or `administer projects` for an organisation branch or baseline;
250
326
  showing reads only the requester's records in the token organisation and needs no project read
251
327
  access. A branch whose name contains `/` cannot request or show a schema update today.
252
328
  - `organisation-not-ready`: the organisation's trunk is not ready. Try again shortly.
253
- - `read-only-ref`: nothing can be written or merged into this ref. Choose a writable ref.
329
+ - `read-only-ref`: nothing can be written or merged into this branch or baseline. Choose a writable branch.
254
330
 
255
331
  ## 4. Link to a page
256
332
 
257
333
  To give the person a page, run `openeng link` and hand them the address it prints; never write a path
258
- or an address yourself. `openeng link <kind> --project <id> --ref <ref>` takes `explore`, `branch-diff`
334
+ or an address yourself. `openeng link <kind> --project <id> --ref <ref>` takes `branch-diff`
259
335
  or `project`; `openeng link <kind> <identifier> --project <id> --ref <ref>` takes `object`, `type`, `proposal` or
260
336
  `app` (the app's first page); `openeng link app-page <appKey> <pageKey> --project <id> --ref <ref>` takes
261
337
  one page of an app; `openeng link app-draft <appKey> --ref <ref>` takes the app's draft screen and no
262
- project. `openeng link ontology --ref <ref>` and `openeng link change-set --ref <ref>` take a ref and no
338
+ project. `openeng link ontology --ref <ref>` and `openeng link change-set --ref <ref>` take a branch and no
263
339
  project, and `openeng link organisation-page <page>` takes neither flag. The organisation is the one
264
340
  your session is attached to.
265
341
 
342
+ | kind | destination |
343
+ |---|---|
344
+ | `object <id>` | The object's type page with the object open; the type comes from its read. |
345
+ | `type <key>` | The type's page. |
346
+ | `explore` | Explore with exactly one `--object <id>` or `--object-set <id>` seed. |
347
+ | `branch-diff` | The branch comparison page. |
348
+ | `project` | The project page. |
349
+ | `proposal <id>` | The proposal review page. |
350
+ | `ontology` | The organisation's Types workspace. |
351
+ | `change-set` | The organisation's Change set workspace. |
352
+ | `app <key>` | The published app's first page. |
353
+ | `app-page <appKey> <pageKey>` | The named page of a published app. |
354
+ | `app-draft <key>` | The app's draft screen in the Types workspace. |
355
+ | `organisation-page <page>` | The named organisation administration page or settings. |
356
+
357
+ Only `explore` opens Explore. Use `openeng link explore --project <id> --ref <ref>` with exactly
358
+ one of `--object <id>` or `--object-set <id>`; neither or both refuse before a host call.
359
+ The seed flags are only for `explore`. `link object <id>` opens the type page with that object,
360
+ using the type key from the object read. Explore also reads its selected object or saved set first.
361
+
266
362
  ### Save an object set and link to its canvas
267
363
 
268
364
  1. Run `openeng help objects-sdk createObjectSet` and `openeng help objects-sdk readObjectSet`.
269
365
  2. Query the objects you need with `openeng objects-sdk queryObjects --json`. Keep each object's
270
366
  project with its identifier; one set may contain objects of several projects in your organisation.
367
+ To combine two selections on the same ref, send `{ "kind": "set", "op": "difference", "left": { "kind": "objects", "typeKey": "..." }, "right": { "kind": "objects", "typeKey": "..." }, "limit": 100, "continuation": null }`. `op` may be `union`, `intersection` or `difference`. Each operand may have its own `projects`, `filters` and `steps`; operands cannot be nested set operations.
368
+ `aggregateObjects` also accepts `operation: "average"` with one numeric `property`; the result includes its mean and the count averaged, and omits the mean when that count is zero.
271
369
  3. Call `openeng objects-sdk createObjectSet` with a name and the selected addresses, following its
272
370
  help. Keep the returned set identifier and revision. Retrying with the same idempotency key
273
371
  returns that original answer.
274
372
  4. Run `openeng link explore --project <page project> --ref <ref> --object-set <set id>` and give the
275
373
  person the address it prints. It reads the set first; a refused read prints no link. The set
276
- stores no ref, so the link's ref chooses which version of its objects opens.
374
+ stores no branch or baseline, so the link's branch chooses which version of its objects opens.
277
375
 
278
376
  Every kind with `--ref`, including `ontology` and `change-set`, takes `main` or
279
- `<projectId>/<branch>`, the ref the platform returns. A bare branch name or change-set id is
280
- refused by `openeng link`. Before printing, the command reads the ref and the page's own subject;
377
+ `<projectId>/<branch>`, the branch name the platform returns. Baseline names are not accepted by `openeng link`. A bare branch name or change-set id is
378
+ refused by `openeng link`. Before printing, the command reads the branch and the page's own subject;
281
379
  a subject it cannot find is a refusal with a reason and no printed address.
282
380
 
283
381
  An **App** is an organisation entity with its own pages and drafts, linked by `openeng link app`.
@@ -350,3 +448,47 @@ Refusals you will meet, with what each means and what to do:
350
448
  - `change-set-open`: the organisation already has an open change set, so drafting the types
351
449
  stopped. Read it with `openeng types draft current` and continue with it; the connection exists, and
352
450
  `openeng connector draft-types <connection>` drafts once that change set is settled.
451
+
452
+ ## Inviting a person
453
+
454
+ Run `openeng help admin-sdk createInvitation` before inviting. The request takes `email`, an
455
+ organisation `roleKey`, and optional `projectRoles`: up to 50 `{ projectId, roleKey }` entries,
456
+ one per project in the attached organisation. The inviter must administer members on the
457
+ organisation and each project, and may offer no role above their own there. Send no organisation
458
+ field; the server derives it. Deliver the returned link to the person.
459
+
460
+ `openeng admin-sdk listInvitations --input '{}' --json` lists pending invitations and their
461
+ project roles. Re-issuing keeps the roles; revoking removes the invitation from that list.
462
+ Acceptance skips and audits a project role when the project ended, the person already holds an
463
+ equal or higher project role, or the inviter lost the required standing. Sign-in continues.
464
+
465
+ Membership roles are `owner`, `maintainer`, `contributor` and `reader`. They grant, respectively:
466
+
467
+ - `owner`: administer members, projects and service identities; write trunk, branches and protected
468
+ rows; merge; and read.
469
+ - `maintainer`: write trunk, branches and protected rows; merge; and read.
470
+ - `contributor`: write branches and read. For example, a project contributor may edit on a branch
471
+ and read the project, but does not gain merge or trunk-write permission.
472
+ - `reader`: read.
473
+
474
+ A membership can be scoped to an organisation or a project. An organisation role supplies its
475
+ capabilities in each project of that organisation too; a project role applies to its named project.
476
+ For a project-specific exception, grant the role on that project rather than assuming a membership
477
+ in one project applies to another.
478
+
479
+ An unknown role on an invitation or membership grant answers `unknown-role` with `roleKeys`, the
480
+ deployment's role keys. Choose one of those keys. A known role above your own answers
481
+ `above-caller-role`.
482
+
483
+ ## Recover an interrupted operation
484
+
485
+ `openeng objects-sdk recover` checks the record of a mutation or verb whose result was unknown. Give
486
+ the same project and ref, and the original correlation id:
487
+
488
+ ```sh
489
+ openeng objects-sdk recover --selector '{"projectId":"<project-id>","ref":"<project-id>/<branch>"}' --input '{"correlationId":"<correlation-id>"}' --json
490
+ ```
491
+
492
+ Recovery can report a committed change and its hash, and finish the recovery record. It never sends
493
+ the original mutation again. If the saved evidence still cannot establish an outcome, it returns
494
+ `unknown`; it cannot undo a successful write, restore a deleted object, or retry a failed operation.
@@ -112,4 +112,4 @@ reached through a part or a plant.
112
112
  a structure by it.
113
113
  - **Mass change** of many lines, and a **cost roll-up** across a structure: a count per question is a query, a
114
114
  roll-up is not built.
115
- - **CAD geometry**: an object view can show an STL property (`STLViewer`); there is no live CAD link.
115
+ - **CAD geometry**: an object view can show an STL attachment (`STLViewer`); there is no live CAD link.