Skip to content

Commit cadfe0b

Browse files
hotlongclaude
andcommitted
fix(spec): record the runtime uninstall door's TENANT_SCOPE_REQUIRED stamp as a provenance waiver
The DELETE /packages/:id door now answers deletePackage's organization-scope refusal itself, before the registry is touched, with the code the protocol registers. The door mirrors the producer; it is not a second emitter, so the row stays under @objectstack/metadata-protocol and the stamp is waived. Claude-Session: https://claude.ai/code/session_local_1d2a197c-c20e-4e90-9be8-413d4d432289 Co-authored-by: Claude <noreply@anthropic.com>
1 parent 32da13c commit cadfe0b

2 files changed

Lines changed: 15 additions & 0 deletions

File tree

‎.changeset/20492-uninstall-refuse-before-mutate.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
22
'@objectstack/runtime': patch
3+
'@objectstack/spec': patch
34
---
45

56
fix(runtime): `DELETE /packages/:id` refuses an uninstall that names no organization before it touches the running registry (#20492)
@@ -11,3 +12,5 @@ A caller holding `manage_metadata` with no active organization — a member remo
1112
The door now asks the persisted delete's organization-scope question first, from the same organization value it hands `deletePackage`, and only when a persisted delete will run. The same refusal (`400 TENANT_SCOPE_REQUIRED`) now arrives before anything changes: the package stays served, listed and registered, and its stored rows are untouched. The refusal's message names what an HTTP caller can do, which is to select an organization they are a member of and retry.
1213

1314
- **Unchanged:** a caller acting in an organization uninstalls exactly as before. A read-only package is still refused `422 WRITABLE_PACKAGE_REQUIRED` first. A host with no persisted delete (no `deletePackage` on its `protocol` service) still uninstalls from the registry alone, because there is no refusal to mirror there. The protocol keeps its own refusal as a second line.
15+
16+
- **`@objectstack/spec`:** `PROVENANCE_WAIVERS` (the error-code ledger) gains one entry: `@objectstack/runtime` stamps `TENANT_SCOPE_REQUIRED`, which stays registered under `@objectstack/metadata-protocol`. The door mirrors `deletePackage`'s refusal and does not emit a second vocabulary. The registered code union and `ErrorCode` are unchanged.

‎packages/spec/src/api/error-code-ledger.zod.ts‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1762,4 +1762,16 @@ export const PROVENANCE_WAIVERS: readonly ProvenanceWaiver[] = [
17621762
'constructor there is one stamp site, and rows for packages that stamp nothing ' +
17631763
'would be the dead weight this file\'s gate refuses.',
17641764
},
1765+
{
1766+
package: '@objectstack/runtime',
1767+
code: 'TENANT_SCOPE_REQUIRED',
1768+
registeredUnder: '@objectstack/metadata-protocol',
1769+
reason: 'The door mirrors the producer\'s refusal; it is not a second emitter. ' +
1770+
'`DELETE /packages/:id` (domains/packages.ts, `requireUninstallOrganizationScope`) asks ' +
1771+
'`deletePackage`\'s organization-scope question BEFORE `registry.uninstallPackage`, and ' +
1772+
'answers with the code `deletePackage` refuses with (#7780), so a refused uninstall ' +
1773+
'changes nothing (#20492). The door never sends `allTenants`, so its condition is exactly ' +
1774+
'the producer\'s "no organization"; the protocol keeps its own refusal as the second line ' +
1775+
'and stays the registered emitter.',
1776+
},
17651777
];

0 commit comments

Comments
 (0)