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 6038ff6
Browse filesBrowse the repository at this point in the historyBrowse files
perf(core): an authenticated request resolves its grants in one round fewer, and a write to an unrelated object no longer retires the localization cache
6
+
7
+
Clause-②: no (no accept set, served body or authz answer moves: fewer queries and rounds for the same answer; owes the seat's review of record before the queue, at `CONTRACT_REVIEW_TIER` by the seat's choice, since it changes when authz and localization caches are trusted)
8
+
9
+
-**The Default Organization read and the activation-ledger read are one wave.**`resolveUserAuthzGrants` read `sys_organization` (by slug) and then `sys_metadata_activation`, each awaited after the other. Both depend only on the first wave of reads, so they now run together. While the organization read is still open, the ledger is asked about every permission-set name that may apply. In one case that adds the name `admin_full_access` to the ledger's `name IN` list: an organization-owned `admin_full_access` grant that turns out not to anchor platform standing. The envelope is unchanged in every case: positions, permissions, `org_user_ids`, `accessible_org_ids` and posture. The organization read's filter is unchanged, and so are the organization-less grant readings.
10
+
-**The localization success cache is retired only by a write that can change its answer.** That is a write to `sys_setting` or `sys_platform_setting`, observed after it settles by an engine middleware. A non-`write` epoch reason (a peer node's `remote` hint, `metadata`, `manual`), a `localization` settings change or `OS_LOCALIZATION_CACHE_TTL_MS` also retires it. Before, any engine write to any object retired it, so on an idle boot the outbox pollers' claim updates made warm requests read the settings again. A success is cached only on an engine that has both the write epoch and `registerMiddleware`. With `OS_LOCALIZATION_CACHE_TTL_MS=0`, nothing is registered on the engine. The failure memo for a missing `sys_setting` table is unchanged: it is retired only by its TTL.
perf(metadata-protocol): the served by-name read takes its stored rows from the overlay cache, and only a `sys_metadata` write retires that cache
6
+
7
+
Clause-②: no (no accept set, served body or authz answer moves: fewer queries and rounds for the same answer; owes the seat's review of record before the queue, at `CONTRACT_REVIEW_TIER` by the seat's choice, since it changes when authz and localization caches are trusted)
8
+
9
+
-**`getMetaItem` reads the item's active `sys_metadata` rows through the overlay cache.** The list read already used that cache. The REST API-exposure gate reads the object by name on every `/data` request, and that read was its one uncached `sys_metadata` round trip. The cached value is the raw row set. Parsing, merging and registry hydration still run on every call, hit or miss. Only the served face reads through the cache. The protocol's own authoring checks, such as the destructive-change check before an object save, still read the store on every call.
10
+
-**Only a write to `sys_metadata` retires the cache.** The write is observed by an engine middleware after it settles. Every non-`write` epoch reason also retires it, including the metadata cluster bridge's `remote` bump, and `OS_METADATA_OVERLAY_CACHE_TTL_MS` still bounds it. Before, any engine write to any object retired it. A row set is cached only on an engine that has both the write epoch and `registerMiddleware`. With the TTL set to `0`, nothing is registered on the engine.
`record:related_list`'s `parentDataSource` is described as rendered
6
+
7
+
Clause-②: no (describe and TSDoc text only: `RecordRelatedListProps` accepts exactly what it accepted before, and every refusal keeps its issue `code` and `path`)
8
+
9
+
- The `parentDataSource` describe no longer opens with `[PLANNED — not yet rendered]`. The console renders the key: a related list reads its parent record from the binding, the first row by its `sort`, and draws a notice in its place when no row answers, never an empty list. Without the key, the record page's record is the parent, as before. The rest of the describe is unchanged.
10
+
- The key's TSDoc names the console's read points in place of the planned note, and no longer calls the `api` data source unrendered.
fix(objectql): a bound action named like an action its target object already lists, with a different declaration, is reported at boot naming both packages; `registerAction` reports replacing another owner's handler
6
+
7
+
Clause-②: no (a warning only: no accept set narrows, no door answer moves, and no published surface gains a key; owes the seat's review of record before the queue)
8
+
9
+
-**The listing.** A top-level action bound by `objectName` to an object that already lists an action of the same name is still not attached: the object keeps serving its own declaration, as the action router does. When the two declarations differ, the boot now warns once per pair, at `kernel:ready`, naming the object, the action, the package whose declaration is served and the package whose declaration is not listed. Two packages binding different declarations of one name to a third package's object are reported the same way (the first one attached is served).
10
+
-**Not a collision.** One declaration carried twice is compared without its provenance stamps (`_packageId`, `_provenance`, the `_lock` envelope, `protection`) and without `objectName`, and is not reported: a same-stack bound action merged onto its object, or the same declaration shipped by two packages.
11
+
-**Later artifacts.** An artifact registered after the boot (a marketplace install, a ledger rehydrate) is judged once it has registered, for the pairs naming one of its packages; a pair the boot already reported is not reported again.
12
+
-**The handler.**`ObjectQL.registerAction` keys handlers by `OBJECT:ACTION`. A registration under a key another owner holds still replaces it (the last registration runs), and now warns, naming both owners: the action door runs the new owner's handler whichever declaration the object lists, and withdrawing that owner leaves the action with no handler. The same owner re-registering is silent, and so is the authored-action resync, which tears its set down first. A registration with no package is its own owner.
13
+
-**Unchanged.** Nothing is refused and no boot fails on it; the served `actions`, the router's precedence and which handler runs are as before. Measured on stock CRM, showcase and todo boots: no new warning.
14
+
-**Fix.** Rename one of the two actions, or drop the duplicate declaration.
Copy file name to clipboardExpand all lines: content/docs/deployment/environment-variables.mdx
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -375,8 +375,8 @@ the hosted ObjectOS Cloud control plane.
375
375
|`OS_SANDBOX_HOOK_TIMEOUT_MS`| number |`250`| Default **CPU-time** budget for a sandboxed **hook** body (QuickJS, ADR-0102): how much *VM-active* time a body may burn — idle host-await time and a nested hook's own run are NOT charged. A loaded/slow host rarely needs to raise this now (it is not wall-clock), but the knob remains. Only a positive integer is honored; unset / non-numeric / non-positive keeps the 250ms default. A hook body's own declared `timeoutMs` still wins over this. |
376
376
|`OS_SANDBOX_ACTION_TIMEOUT_MS`| number |`5000`| Default **CPU-time** budget for a sandboxed **action** body (QuickJS). Same resolution rules as the hook variant above (positive integer only; an action body's own `timeoutMs` still wins). |
377
377
|`OS_SANDBOX_WALL_CEILING_MS`| number |`30000`| Wall-clock ceiling (ADR-0102) — the backstop that cuts a hook/action body stuck on a host call that never settles (which burns no CPU, so the CPU budget alone would never fire). The effective ceiling is `max(this, cpuBudget)`, so it can never cut a body still inside its CPU budget. Positive integer only; unset keeps 30s. |
378
-
| `OS_LOCALIZATION_CACHE_TTL_MS` | number | `30000` | Staleness bound, in milliseconds, for the cross-request cache of a workspace's reference localization (`timezone` / `locale` / `currency`, read from `sys_setting`) — leg C of #11633. `0` means **off**, a real path that restores the uncached query pattern exactly. Unlike `OS_AUTHZ_GRANTS_CACHE_TTL_MS` (which is off by default) this one ships **on**, because its invalidation is synchronous and in-process rather than TTL-bound: a `localization` settings change and any engine write both retire a cached answer immediately, so the TTL only bounds what neither seam can see — a write made on another replica with no cluster bridge attached at all: neither the `metadata.mutated` channel's receipt path (`applyRemoteMetadataMutation` calls `bumpWriteEpoch`, #13609) nor the `authz.invalidated` bridge, both of which bump this same epoch when attached. ⚠️ A malformed value reads as `0` (off), the opposite arm from the grants variable and deliberately so: there `0` is also the default, whereas here folding `3OOO` (letter O) into the default would hand you a **longer** window than the one you were setting. Deployment config only — never a settings row, because `sys_setting` is the table this cache caches. |
379
-
| `OS_METADATA_OVERLAY_CACHE_TTL_MS` | number | `30000` | Staleness bound, in milliseconds, for the cross-request cache of the `sys_metadata` overlay read inside `getMetaItems` — leg D of #11633. `0` means **off**, a real path that restores the uncached query pattern exactly. Ships **on**, for the same reason as `OS_LOCALIZATION_CACHE_TTL_MS`: invalidation is synchronous and in-process, because every `sys_metadata` write goes through the engine and so advances the write epoch that retires the entry before the next read. What is cached is the overlay ROW SET only — never the merged answer — so the SchemaRegistry, the MetadataService and the artifact table are re-consulted on every call, cached or not, and the read-side registry hydration keeps running on a cache hit. The TTL therefore bounds one thing: a write made on **another replica** with no cluster bridge attached at all — neither the `metadata.mutated` channel's own receipt path (`applyRemoteMetadataMutation` calls `bumpWriteEpoch` right after registry convergence, #13609) nor the `authz.invalidated` bridge, either of which retires this entry the moment it is attached and fires. ⚠️ A malformed value reads as `0` (off) — same arm and same reason as `OS_LOCALIZATION_CACHE_TTL_MS`. Deployment config only, never a settings row. |
378
+
| `OS_LOCALIZATION_CACHE_TTL_MS` | number | `30000` | Staleness bound, in milliseconds, for the cross-request cache of a workspace's reference localization (`timezone` / `locale` / `currency`, read from `sys_setting`) — leg C of #11633. `0` means **off**, a real path that restores the uncached query pattern exactly. Unlike `OS_AUTHZ_GRANTS_CACHE_TTL_MS` (which is off by default) this one ships **on**, because its invalidation is synchronous and in-process rather than TTL-bound: a `localization` settings change, a write to `sys_setting` or `sys_platform_setting` (the tables the answer is read from), and a non-`write` bump of the engine write epoch each retire a cached answer immediately. A write to any other object does not. So the TTL only bounds what none of these seams can see — a write made on another replica with no cluster bridge attached at all: neither the `metadata.mutated` channel's receipt path (`applyRemoteMetadataMutation` calls `bumpWriteEpoch`, #13609) nor the `authz.invalidated` bridge, both of which bump this same epoch when attached. ⚠️ A malformed value reads as `0` (off), the opposite arm from the grants variable and deliberately so: there `0` is also the default, whereas here folding `3OOO` (letter O) into the default would hand you a **longer** window than the one you were setting. Deployment config only — never a settings row, because `sys_setting` is the table this cache caches. |
379
+
| `OS_METADATA_OVERLAY_CACHE_TTL_MS` | number | `30000` | Staleness bound, in milliseconds, for the cross-request cache of the `sys_metadata` overlay rows read inside `getMetaItems` (the list read) and `getMetaItem` (the served by-name read the REST API-exposure gate makes on every `/data` request) — leg D of #11633. `0` means **off**, a real path that restores the uncached query pattern exactly. Ships **on**, for the same reason as `OS_LOCALIZATION_CACHE_TTL_MS`: invalidation is synchronous and in-process, because every `sys_metadata` write goes through the engine, whose middleware retires the entry when the write's statement completes, before the next read. Outside a transaction that is the commit. Inside an engine transaction it is earlier than the commit: a read that lands between the statement and the commit can keep the pre-commit rows until the next `sys_metadata` write or the TTL. A write to any other object does not retire it; a non-`write` bump of the engine write epoch retires it wholesale. What is cached is the overlay ROW SET only — never the merged answer — so the SchemaRegistry, the MetadataService and the artifact table are re-consulted on every call, cached or not, and the read-side registry hydration keeps running on a cache hit. The TTL therefore bounds one thing: a write made on **another replica** with no cluster bridge attached at all — neither the `metadata.mutated` channel's own receipt path (`applyRemoteMetadataMutation` calls `bumpWriteEpoch` right after registry convergence, #13609) nor the `authz.invalidated` bridge, either of which retires this entry the moment it is attached and fires. ⚠️ A malformed value reads as `0` (off) — same arm and same reason as `OS_LOCALIZATION_CACHE_TTL_MS`. Deployment config only, never a settings row. |
380
380
|`OS_INLINE_SEED_BUDGET_MS`| number |`8000`| Time budget for synchronous seed execution at boot before deferring to a worker. |
381
381
|`OS_TENANT_AUDIT`| flag |`1`| Set to `0` to silence the tenant-isolation audit warnings emitted by the SQL driver. |
0 commit comments