Skip to content

Commit 23df2c8

Browse files
committed
Merge remote-tracking branch 'origin/main' into claude/issue-21829-predicate-write-matches-readable-rows
2 parents 17ed50b + 67c544c commit 23df2c8

31 files changed

Lines changed: 1109 additions & 187 deletions
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
'@objectstack/plugin-security': patch
3+
---
4+
5+
A data-door edit of a permission set saved into a writable runtime package updates that set's stored definition instead of forking it
6+
7+
Clause-②: no
8+
9+
Setup saves a permission set through the data door (`PATCH /api/v1/data/sys_permission_set/:id`), which redirects the edit into the metadata store. A stored definition row is keyed by its package as well as its name, and the redirected save named no package. For a set saved into a writable runtime package (`PUT /api/v1/meta/permission/:name?package=<id>`), whose only stored row is bound to that package, the save therefore created a second, package-less row carrying the edit and left the package's row untouched: two active definitions for one name, with the package's copy no longer receiving the organization's edits. The save now goes into the package the edited row is bound to, read from that row through the metadata door's own item read, so the edit lands on the set's one row and the row stays in its package.
10+
11+
Unchanged: a set with no package binding still saves with none, and a set a code package ships is still refused with `403 NOT_OVERRIDABLE` before anything is read or written. The edit answers `200` as before; no error code, route or field moves.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
'@objectstack/service-datasource': minor
3+
---
4+
5+
fix(service-datasource)!: on `objectstack start`, external validation and the boot gate compare every federated object
6+
7+
**BREAKING (narrowing)** — on `objectstack start` a deployment with real schema drift on a
8+
federated object can now refuse to boot, as its `external.validation.onMismatch` setting
9+
declares.
10+
11+
The federation service (`ExternalDatasourceServicePlugin`) read the `metadata` service once,
12+
in its `init()`, and kept the answer. `objectstack start` composes no metadata plugin: its
13+
`metadata` service is the kernel's in-memory fallback, which the kernel registers after every
14+
plugin's `init()`, just before the start phase. So on `start` the federation service kept "no
15+
metadata service" for the life of the process, and every read behind it answered as if the
16+
deployment declared nothing. It now asks for the `metadata` service each time it reads it, so
17+
`start` sees what `objectstack dev` always saw.
18+
19+
| on `objectstack start` | before | now |
20+
| --- | --- | --- |
21+
| the boot gate (ADR-0015 §5.2) | logged "all federated objects match their remote schema" with `objects: 0`, having compared nothing, so no `onMismatch` policy ever applied | compares every federated object and applies each datasource's `onMismatch` to every measured mismatch |
22+
| `POST /api/v1/datasources/:name/external/validate` | `ok: true` with no rows | one row per federated object bound to the datasource, with its diffs |
23+
| `POST /api/v1/datasources/:name/external/refresh-catalog` | answered the snapshot, never stored it | also stores it as the datasource's `external_catalog` record |
24+
| `GET /api/v1/datasources/:name/external/tables` | ignored the datasource's `external.allowedSchemas` | leaves out a table whose schema is outside them |
25+
| draft and import names | never resolved a package namespace: drafts were unprefixed, and an import's explicit `name` was never held to the ADR-0028 prefix rule | resolve the namespace of the datasource's package when the datasource carries package provenance; an import whose explicit `name` lacks that prefix is refused `400 EXTERNAL_IMPORT_ERROR` |
26+
27+
**What to do if a `start` deployment now refuses to boot.** Under `onMismatch: 'fail'` (the
28+
default) the boot stops with `ExternalSchemaMismatchError`, naming the object, the datasource
29+
and each drifted column. Either fix the drift (align the object's fields, its
30+
`external.columnMap` or `external.ignoreColumns`, or the remote table) or set
31+
`external.validation.onMismatch: 'warn'` on that datasource, which boots and logs the drift
32+
instead. To see the drift before deploying, call
33+
`POST /api/v1/datasources/:name/external/validate` on `objectstack dev`, which already
34+
compared. A remote that cannot be reached still never stops the boot. An import refused for
35+
its name takes a `name` carrying the datasource package's namespace prefix.
36+
37+
**Unchanged.** `objectstack dev`, and every composition that registers a metadata plugin before
38+
the federation service, answers exactly as before: measured on the showcase, every federation
39+
door and the boot gate gave the same answers before and after. What validation judges, what
40+
each `onMismatch` value does, and the boot gate's skip for a datasource that sets
41+
`external.validation.checkOnBoot: false` are unchanged.
42+
43+
Clause-②: no (narrowing)
44+
45+
<!-- adr-0087: not-required (no-migration-prescription) No authorable key, spelling, export, config field or stored shape is removed or renamed, and no stored row is read or rewritten: on a composition with no metadata plugin the federation service now reads the metadata service it always declared it reads, so the boot gate and the federation doors judge the objects and datasources the deployment already declares. The handling above is an operator choice between two settings that already exist, not a FROM to TO mapping that objectstack migrate meta could apply. The other categories are closed on facts: the package publishes (not unpublished); no ADR-0087 id covers when a plugin resolves a service (not registered / already-registered); and the change is runtime behaviour, not a declaration (not runtime-interface-only / type-surface-only). -->

0 commit comments

Comments
 (0)