Skip to content

Commit 393da1d

Browse files
committed
docs(spec): regenerate the protocol reference for the lock description; add the changeset
Claude-Session: https://claude.ai/code/session_016tKoy8NJa35Yih1FdzrVmn Co-authored-by: Claude <noreply@anthropic.com>
1 parent 01c2c45 commit 393da1d

2 files changed

Lines changed: 25 additions & 1 deletion

File tree

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
'@objectstack/metadata-protocol': patch
3+
'@objectstack/spec': patch
4+
---
5+
6+
The metadata reads' `lock` / `editable` / `deletable` now say what the write doors do with a packaged item
7+
8+
Clause-②: no
9+
10+
Both metadata reads publish the ADR-0010 protection envelope beside the item: `GET /api/v1/meta/:type/:name/layers` (and its deprecated `?layers=true` spelling), and the by-name read `GET /api/v1/meta/:type/:name` where it resolves the envelope. The envelope was resolved from the item's own `_lock` alone, so it ignored the other refusal the write doors apply: an item a code package ships, on a type with no per-org overlay channel, is locked against in-place edits.
11+
12+
**Before.** A packaged flow, action, object, hook, seed, mapping, datasource, external catalog, doc, picklist, field, job, api, capability or agent with no `_lock` read `lock: 'none'`, `editable: true` and `deletable: true`. A packaged page, app, dataset, book, permission set, position, tool or skill read the same. Yet `PUT` refused each of them with `403 NOT_OVERRIDABLE` (or `403 ITEM_LOCKED` when the write names the read-only package), and the removal of the first group was refused too.
13+
14+
**After.** Each read reports what its doors answer:
15+
16+
- The first group reads `lock: 'full'`, `editable: false` and `deletable: false`.
17+
- The second group reads `lock: 'no-overlay'`, `editable: false` and `deletable: true`. Removing a leftover overlay row of these types is allowed: that is the repair path for overlays written before their per-org channel was withdrawn.
18+
- Items of the overlay types (`view`, `dashboard`, `report`, `translation`, `email_template`) are unchanged. So are items no package ships, such as an organization's own flows and actions, and every item while the `OS_METADATA_WRITABLE` operator hatch opens its type.
19+
20+
An item's own `_lock` still applies on top: the two refusals join, and neither replaces the other. `lockReason`, `lockSource` and `lockDocsUrl` are still present only when the item declares them. `provenance` and `packageId` already name the package.
21+
22+
The verdict is the one the write doors already share, read rather than re-derived, so the read moves whenever a door moves. The `lock` field's description in `@objectstack/spec` now names both refusals it reports. No key, type or accepted value changes.
23+
24+
**What to do.** Nothing, unless a client gated an edit or delete affordance on `editable` / `deletable`: it now hides that affordance for packaged items the server refuses, instead of offering a write that answers 403. The refusal itself names the sanctioned route for each type: for a packaged flow, clone it under a new name or switch it off; for a packaged action, switch it off.

‎content/docs/references/api/protocol.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1344,7 +1344,7 @@ Enable package response
13441344
| **name** | `string` | ✅ | Item name |
13451345
| **item** | `any` | ✅ | Metadata item definition |
13461346
| **sortability** | `{ fields: Record<string, object> }` | optional | Per-column sortability projection — present exactly when `type` is `object`, on every serving branch. Computed at serve time from the served document via the spec's own storage predicates; consumers render sort affordances from this signal and never re-derive it from field `type`. See `ObjectSortabilitySchema` for the closed category set. |
1347-
| **lock** | `Enum<'none' \| 'no-overlay' \| 'no-delete' \| 'full'>` | optional | Resolved lock verdict for this item (ADR-0010 §3.3). `none` means unlocked; `no-overlay` / `no-delete` / `full` refuse the corresponding write with 403 `ITEM_LOCKED`. Resolved from the document's `_lock`, with the packaged artifact winning over any org overlay. |
1347+
| **lock** | `Enum<'none' \| 'no-overlay' \| 'no-delete' \| 'full'>` | optional | Resolved lock verdict for this item (ADR-0010 §3.3). `none` means unlocked; `no-overlay` / `no-delete` / `full` mean the write doors refuse the corresponding write with 403. Joins two refusals: the document's own `_lock` (`ITEM_LOCKED`; the packaged artifact wins over any org overlay), and the locked packaged base — an item a code package ships, on a type with no per-org overlay channel (`NOT_OVERRIDABLE`, or `ITEM_LOCKED` when the write names the read-only package). |
13481348
| **lockReason** | `string` | optional | Human-readable explanation shown next to a refused write. Present only when the resolved item declares `_lockReason`. |
13491349
| **lockSource** | `Enum<'artifact' \| 'package' \| 'env-forced'>` | optional | Which layer asserted the lock. Present only when the resolved item declares `_lockSource`. |
13501350
| **lockDocsUrl** | `string` | optional | Documentation link surfaced beside `lockReason`. Present only when the resolved item declares `_lockDocsUrl`. |

0 commit comments

Comments
 (0)