You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit a832564
Browse filesBrowse the repository at this point in the historyBrowse files
REST no longer reads a FAILED authorization-input lookup as "this check does not apply" — the tenancy-posture and ADR-0069 auth-gate seams in `computeExecCtx` fail closed
6
+
7
+
Two seams inside `RestServer.computeExecCtx` absorbed a FAILURE into the same `undefined` an
8
+
ABSENT wiring produces, and both feed authorization inputs. Unlike the sibling repairs in this
9
+
family — where an unknown was answered as a REFUSAL — these two pointed the other way: a failure
10
+
read as *permissive*, so a refusal was SKIPPED rather than produced. Driven on a real
11
+
`ObjectKernel`, each fault beside a positive control that is the same fixture with the one fault
Copy file name to clipboardExpand all lines: content/docs/permissions/system-context.mdx
+5-5Lines changed: 5 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -64,7 +64,7 @@ not on any flag.
64
64
## How the flag is set
65
65
66
66
`isSystem` is **server-constructed and never client-supplied**. Inbound HTTP
67
-
cannot set it (`packages/rest/src/rest-server.ts:1520`, `:1549`), and neither
67
+
cannot set it (`packages/rest/src/rest-server.ts:1524`, `:1553`), and neither
68
68
can an action body (`packages/runtime/src/domains/actions.ts:404`). It is
69
69
written by internal callers only, as an option on the engine call:
70
70
@@ -103,7 +103,7 @@ that silently does not happen.
103
103
| 14 | MCP stdio bridge skips the object API-exposure gate | mcp | Get: the bridge reaches objects whose `apiEnabled` / `apiMethods` would refuse an external caller |`stdio-data-bridge.ts:246`|
104
104
| 15 |**Read-audit rows are not written**| plugin-audit | Lose: the "a person opened this record" trail. `sudo()` keeps the caller's `userId`, so this flag is the only thing separating a human read from a platform one |`read-audit.ts:556`|
105
105
| 16 | Approval snapshot payload redaction skipped | plugin-approvals | Get: the whole snapshot on `find` / `findOne` — the audit/replay channel. Lose: field-visibility redaction over approval payloads |`payload-redaction-middleware.ts:115`|
106
-
| 17 | REST anonymous-deny seam satisfied | rest | Get: `enforceAuth` passes with no `userId`. Not reachable from the wire — `isSystem` is never set on an inbound request |`rest-server.ts:1552`|
106
+
| 17 | REST anonymous-deny seam satisfied | rest | Get: `enforceAuth` passes with no `userId`. Not reachable from the wire — `isSystem` is never set on an inbound request |`rest-server.ts:1556`|
107
107
108
108
### 2. Write pipeline and data integrity
109
109
@@ -158,7 +158,7 @@ The largest single consumer — **17 of the 106 sites**.
158
158
|:--|:---|:---|:---|:---|
159
159
| 48 | Object API-exposure gate bypassed (`apiEnabled` / `apiMethods`) | runtime | Get: internal self-writes ignore exposure declarations — these govern **external** exposure, not engine self-writes |`action-execution.ts:138`|
| 50 |`manage_metadata` bypassed on metadata writes | runtime, rest | Get: schema writes without the capability |`domains/meta.ts:471`, `:874`, `rest-server.ts:4789`, `:6203`, `:6451`, `:6882`, `:7075`|
161
+
| 50 |`manage_metadata` bypassed on metadata writes | runtime, rest | Get: schema writes without the capability |`domains/meta.ts:471`, `:874`, `rest-server.ts:4888`, `:6302`, `:6550`, `:6981`, `:7174`|
162
162
| 51 | The shared metadata-write verdict itself returns `allowed`| metadata-core | Get: the one function all of row 50's doors consult answers yes before any capability is examined |`meta-write-capability.ts:134`|
163
163
| 52 | Anonymous-deny seam satisfied on the domain dispatchers and the package/federation routes | runtime, rest | Get: passes with no `userId`|`domains/actions.ts:411`, `domains/ai.ts:60`, `domains/automation.ts:989`, `domains/meta.ts:232`, `domains/security.ts:78`, `domains/packages.ts:326`, `external-datasource-routes.ts:302`, `package-routes.ts:97`|
164
164
| 53 | MCP principal check satisfied | runtime | Get: MCP surface reachable with no user |`domains/mcp.ts:61`|
@@ -199,7 +199,7 @@ assuming `isSystem` covers it is a documented source of bugs.
199
199
| "It preserves a supplied `updated_at` / `updated_by`" |**No.** That is `preserveAudit`, a separate opt-in — and an UPDATE-path exemption only |`field.zod.ts:1580` (#3493 / #6640) |
200
200
| "It stamps `created_by`" |**No.** Audit stamping reads `userId` from the context. A user-less system write stamps nothing — that is today's behaviour, not an error |`runtime-identity.ts:280`–`281`|
201
201
| "It bypasses every guard" |**No.** The last-admin guard applies to **every** context, `isSystem` included — the deprovision path that actually locks an org out is the system one |`last-admin-guard.ts:299`|
202
-
| "A client can request it" |**No.** Never settable from inbound HTTP or from an action body |`rest-server.ts:1520`, `:1549`; `domains/actions.ts:404`|
202
+
| "A client can request it" |**No.** Never settable from inbound HTTP or from an action body |`rest-server.ts:1524`, `:1553`; `domains/actions.ts:404`|
203
203
204
204
---
205
205
@@ -253,7 +253,7 @@ should recognise it instead of re-deriving it.
253
253
rule-materialised grant that the next reconcile silently restores.
254
254
255
255
5.**`applySystemFields` does not read this flag.** It is named as if it did.
256
-
`packages/objectql/src/registry.ts:464` is **schema-side column
256
+
`packages/objectql/src/registry.ts:475` is **schema-side column
257
257
provisioning** — which columns an object carries — and consumes
258
258
`ExecutionContext.isSystem` zero times. The write-time ownership behaviour
259
259
people attribute to it is row 2, in `plugin-security`.
Copy file name to clipboardExpand all lines: docs/adr/0005-metadata-customization-overlay.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,7 +3,7 @@
3
3
> **v5.0 update (2026):** Throughout this document, the term *project* has been renamed to *environment* (no aliases; CLI flags, URL paths, schemas, env vars all hard-renamed). See [ADR-0006 v4 — the v5.0 rename and its no-alias decision](./0006-project-environment-split.v4.md#the-v50-rename-and-its-no-alias-decision) for the rationale. The body below is preserved verbatim for historical context.
4
4
5
5
6
-
**Status**: Accepted (2026-05-16) · **Amended** (2026-05-22, see "Amendment: post-ADR-0006 v4 scope") · **Amended** (2026-04-13, branch concept removed — see [ADR-0008 §0](./0008-metadata-repository-and-change-log.md#0-2026-04-13-amendment--drop-project-and-branch-from-metaref)) · **Amended** (2026-08-09, #6825 — the Phase-1 overlay-index migration is deleted; see "Amendment (2026-08-09, #6825): overlay-index delivery after the Phase-1 migration was deleted")
6
+
**Status**: Accepted (2026-05-16) · **Amended** (2026-05-22, see "Amendment: post-ADR-0006 v4 scope") · **Amended** (2026-04-13, branch concept removed — see [ADR-0008 §0](./0008-metadata-repository-and-change-log.md#0-2026-04-13-amendment--drop-project-and-branch-from-metaref)) · **Amended** (2026-08-09, #6825 — the Phase-1 overlay-index migration is deleted; see "Amendment (2026-08-09, #6825): overlay-index delivery after the Phase-1 migration was deleted") · **Amended** (2026-09-04, [ADR-0131](./0131-total-organization-ownership-no-null-organization-id.md) D6 — the per-organization overlay axis is **retired for now**: `sys_metadata` carries no organization column, org-scoped writes of the five tier-A types are refused, and the environment layer is the whole ledger; the environment → code layered resolution and the "no overlay row = the registry" reading are unchanged)
**Amended by**: [ADR-0006 v4](./0006-project-environment-split.v4.md) (drops `sys_project` entirely), [ADR-0008](./0008-metadata-repository-and-change-log.md) (re-expresses overlay as `LayeredRepository`; subsequently drops `project`/`branch` from `MetaRef`), [ADR-0029 D9](./0029-kernel-object-ownership-and-platform-objects-decomposition.md#amendment-2026-08-09-6853-a-tenant-overlay-of-an-object-is-its-own-contributor-layer-not-a-second-own) (for `object` only: the overlay is a registry contributor LAYER over the packaged owner, resolved as `base = overlay ?? own`, instead of a destructive in-place overwrite)
**Status**: Accepted · Implemented Phases 1–4 (2026-05-30) · Phase 5 (Studio designer) deferred · **Amended** (2026-09-04, [ADR-0131](./0131-total-organization-ownership-no-null-organization-id.md) D13 — §3.4's `sys_view_definition` store and §3.6's objectui repointing are **retired as inert**: verified on 2026-09-04 that no framework writer or reader of its rows exists, that `objectui` never referenced the object in its history (its runtime-view CRUD writes the ADR-0005 `view` overlay via `client.meta.saveItem`), and that a per-user view scope is a parked v18 direction. Runtime-authored views are environment metadata; §3.5's `GET /meta/view?object=` filter stands)
4
4
**Deciders**: ObjectStack Protocol Architects
5
5
**Builds on**: [ADR-0003](./0003-package-as-first-class-citizen.md) (package as first-class citizen), [ADR-0005](./0005-metadata-customization-overlay.md) (one Zod source per type, org overlay), [ADR-0010](./0010-metadata-protection-model.md) (L1/L2/L3 protection)
0 commit comments