@substrat-run/adapter-cloudflare 0.158.0 → 0.160.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/control-plane-do.d.ts +91 -24
- package/dist/control-plane-do.d.ts.map +1 -1
- package/dist/control-plane-do.js +223 -87
- package/dist/control-plane-do.js.map +1 -1
- package/dist/host.d.ts +818 -6
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +336 -103
- package/dist/host.js.map +1 -1
- package/dist/platform-sweeper-do.d.ts +3 -2
- package/dist/platform-sweeper-do.d.ts.map +1 -1
- package/dist/platform-sweeper-do.js +3 -2
- package/dist/platform-sweeper-do.js.map +1 -1
- package/dist/r2.d.ts +7 -1
- package/dist/r2.d.ts.map +1 -1
- package/dist/r2.js +20 -2
- package/dist/r2.js.map +1 -1
- package/dist/scope-do.d.ts.map +1 -1
- package/dist/scope-do.js +130 -40
- package/dist/scope-do.js.map +1 -1
- package/dist/scope-sweeper-do.d.ts +4 -2
- package/dist/scope-sweeper-do.d.ts.map +1 -1
- package/dist/scope-sweeper-do.js +7 -1
- package/dist/scope-sweeper-do.js.map +1 -1
- package/package.json +9 -9
|
@@ -87,8 +87,9 @@ export interface PlatformSweeperDo {
|
|
|
87
87
|
* sweep: (env) =>
|
|
88
88
|
* runPlatformSweep(hostFor(env), {
|
|
89
89
|
* actor: SWEEP_ACTOR,
|
|
90
|
-
* //
|
|
91
|
-
*
|
|
90
|
+
* // the kernel's: called on its global (workerd refuses another receiver), and a sized
|
|
91
|
+
* // stream body is sent at its length rather than as "[object Object]" (#2498)
|
|
92
|
+
* fetch: globalFetch,
|
|
92
93
|
* sweepers: { scrive: sweepScriveReconciliations },
|
|
93
94
|
* }),
|
|
94
95
|
* });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-sweeper-do.d.ts","sourceRoot":"","sources":["../src/platform-sweeper-do.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEhE;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD,2EAA2E;AAC3E,MAAM,MAAM,oBAAoB,GAAG,mBAAmB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,MAAM,WAAW,uBAAuB,CAAC,GAAG;IAC1C;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;;;OASG;IACH,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC9C,kFAAkF;IAClF,MAAM,CAAC,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC;CACxD;AAED,+EAA+E;AAC/E,MAAM,WAAW,iBAAiB;IAChC,2EAA2E;IAC3E,WAAW,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5D,gEAAgE;IAChE,QAAQ,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAAC;CAC3C;AAED
|
|
1
|
+
{"version":3,"file":"platform-sweeper-do.d.ts","sourceRoot":"","sources":["../src/platform-sweeper-do.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEhE;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD,2EAA2E;AAC3E,MAAM,MAAM,oBAAoB,GAAG,mBAAmB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,MAAM,WAAW,uBAAuB,CAAC,GAAG;IAC1C;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;;;OASG;IACH,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC9C,kFAAkF;IAClF,MAAM,CAAC,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC;CACxD;AAED,+EAA+E;AAC/E,MAAM,WAAW,iBAAiB;IAChC,2EAA2E;IAC3E,WAAW,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5D,gEAAgE;IAChE,QAAQ,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAAC;CAC3C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EACzC,MAAM,EAAE,uBAAuB,CAAC,GAAG,CAAC,GACnC,KAAK,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG,KAAK,aAAa,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAqDnF"}
|
|
@@ -50,8 +50,9 @@ export const PLATFORM_SWEEPER_NAME = 'platform-sweeper';
|
|
|
50
50
|
* sweep: (env) =>
|
|
51
51
|
* runPlatformSweep(hostFor(env), {
|
|
52
52
|
* actor: SWEEP_ACTOR,
|
|
53
|
-
* //
|
|
54
|
-
*
|
|
53
|
+
* // the kernel's: called on its global (workerd refuses another receiver), and a sized
|
|
54
|
+
* // stream body is sent at its length rather than as "[object Object]" (#2498)
|
|
55
|
+
* fetch: globalFetch,
|
|
55
56
|
* sweepers: { scrive: sweepScriveReconciliations },
|
|
56
57
|
* }),
|
|
57
58
|
* });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-sweeper-do.js","sourceRoot":"","sources":["../src/platform-sweeper-do.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AAoCxD
|
|
1
|
+
{"version":3,"file":"platform-sweeper-do.js","sourceRoot":"","sources":["../src/platform-sweeper-do.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AAoCxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,MAAM,UAAU,uBAAuB,CACrC,MAAoC;IAEpC,OAAO,MAAM,iBAAkB,SAAQ,aAAkB;QACvD,mEAAmE;QACnE,KAAK,GAAyC,IAAI,CAAC;QAEnD;;;WAGG;QACH,KAAK,CAAC,WAAW;YACf,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YACnD,IAAI,QAAQ,KAAK,IAAI;gBAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;YAClE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC;YAC/C,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACzC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAClC,CAAC;QAED;;;;WAIG;QACH,KAAK,CAAC,QAAQ;YACZ,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;QACrB,CAAC;QAED,yEAAyE;QACzE,KAAK,CAAC,KAAK;YACT,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACpB,CAAC;QAED,KAAK,CAAC,IAAI;YACR,IAAI,IAAI,CAAC,KAAK;gBAAE,OAAO,IAAI,CAAC,KAAK,CAAC;YAClC,IAAI,CAAC,KAAK,GAAG,CAAC,KAAK,IAAmC,EAAE;gBACtD,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBAC5C,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;oBAClC,OAAO,MAAM,CAAC;gBAChB,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,OAAO,GAAG,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC5E,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;oBACnC,OAAO,OAAO,CAAC;gBACjB,CAAC;YACH,CAAC,CAAC,EAAE,CAAC;YACL,IAAI,CAAC;gBACH,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC;YAC1B,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;gBAClB,yEAAyE;gBACzE,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/r2.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type FetchLike, type TenantBlobStore } from '@substrat-run/kernel';
|
|
1
|
+
import { type FetchLike, type IncrementalSha256, type TenantBlobStore } from '@substrat-run/kernel';
|
|
2
2
|
/**
|
|
3
3
|
* The live R2 side of per-tenant blob stores (#473): a minimal client over Cloudflare's
|
|
4
4
|
* R2 REST API — create and delete buckets. Pure web-standard `fetch`, injected for tests,
|
|
@@ -40,6 +40,12 @@ export interface R2BlobStoresOptions {
|
|
|
40
40
|
*/
|
|
41
41
|
export declare function blobStoreBucketName(tenantId: string, vertical: string, binding: string): Promise<string>;
|
|
42
42
|
export declare function createR2BlobStores(opts: R2BlobStoresOptions): R2BlobStores;
|
|
43
|
+
/**
|
|
44
|
+
* workerd's running SHA-256 (#2498): `crypto.DigestStream`, fed chunk by chunk as a streamed
|
|
45
|
+
* upload passes, so its sha256 is known when the last byte lands without the body ever being
|
|
46
|
+
* held. The kernel's `putAttachmentBytes` takes it.
|
|
47
|
+
*/
|
|
48
|
+
export declare function workerdSha256(): IncrementalSha256;
|
|
43
49
|
/**
|
|
44
50
|
* The WORKER-side open (#473): wrap the tenant's real `r2_bucket` binding — looked up as
|
|
45
51
|
* `env[blobStoreBindingName(binding, tenantId)]` — in the kernel's `TenantBlobStore`
|
package/dist/r2.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"r2.d.ts","sourceRoot":"","sources":["../src/r2.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"r2.d.ts","sourceRoot":"","sources":["../src/r2.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACtC,8EAA8E;IAC9E,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,0FAA0F;IAC1F,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAaD;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAYjB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,mBAAmB,GAAG,YAAY,CA2D1E;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,iBAAiB,CAUjD;AAsBD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,eAAe,CA6BlE"}
|
package/dist/r2.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { globalFetch } from '@substrat-run/kernel';
|
|
1
|
+
import { globalFetch, isSizedByteStream, knownLengthStream, } from '@substrat-run/kernel';
|
|
2
2
|
/** Bound an untrusted upstream body for an error message, marking the cut (#307). */
|
|
3
3
|
function bounded(body, max = 2000) {
|
|
4
4
|
return body.length <= max ? body : `${body.slice(0, max)} … [truncated, ${body.length - max} chars omitted]`;
|
|
@@ -84,6 +84,22 @@ export function createR2BlobStores(opts) {
|
|
|
84
84
|
},
|
|
85
85
|
};
|
|
86
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* workerd's running SHA-256 (#2498): `crypto.DigestStream`, fed chunk by chunk as a streamed
|
|
89
|
+
* upload passes, so its sha256 is known when the last byte lands without the body ever being
|
|
90
|
+
* held. The kernel's `putAttachmentBytes` takes it.
|
|
91
|
+
*/
|
|
92
|
+
export function workerdSha256() {
|
|
93
|
+
const digest = new crypto.DigestStream('SHA-256');
|
|
94
|
+
const writer = digest.getWriter();
|
|
95
|
+
return {
|
|
96
|
+
update: (chunk) => writer.write(chunk),
|
|
97
|
+
hex: async () => {
|
|
98
|
+
await writer.close();
|
|
99
|
+
return [...new Uint8Array(await digest.digest)].map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
87
103
|
/**
|
|
88
104
|
* The WORKER-side open (#473): wrap the tenant's real `r2_bucket` binding — looked up as
|
|
89
105
|
* `env[blobStoreBindingName(binding, tenantId)]` — in the kernel's `TenantBlobStore`
|
|
@@ -94,7 +110,9 @@ export function r2TenantBlobStore(bucket) {
|
|
|
94
110
|
const r2 = bucket;
|
|
95
111
|
return {
|
|
96
112
|
put: async (key, body, opts) => {
|
|
97
|
-
|
|
113
|
+
// #2498: a stream goes in as it is read, at the length it declared.
|
|
114
|
+
const value = isSizedByteStream(body) ? knownLengthStream(body) : body;
|
|
115
|
+
await r2.put(key, value, opts?.contentType ? { httpMetadata: { contentType: opts.contentType } } : undefined);
|
|
98
116
|
},
|
|
99
117
|
get: async (key) => {
|
|
100
118
|
const obj = await r2.get(key);
|
package/dist/r2.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"r2.js","sourceRoot":"","sources":["../src/r2.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"r2.js","sourceRoot":"","sources":["../src/r2.ts"],"names":[],"mappings":"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"}
|
package/dist/scope-do.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope-do.d.ts","sourceRoot":"","sources":["../src/scope-do.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAgEnD,OAAO,
|
|
1
|
+
{"version":3,"file":"scope-do.d.ts","sourceRoot":"","sources":["../src/scope-do.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAgEnD,OAAO,EA0DL,KAAK,mBAAmB,EASxB,KAAK,SAAS,EAsBd,KAAK,kBAAkB,EAEvB,KAAK,gBAAgB,EAmHtB,MAAM,sBAAsB,CAAC;AAoD9B,OAAO,EAAW,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAGtD,OAAO,EAwBL,kBAAkB,EAiFnB,MAAM,sBAAsB,CAAC;AA2B9B;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,UAAU;IACzB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,sBAAsB,CAAC;IACvC;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC;AAoFD,oFAAoF;AACpF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;AA2rB5E;;;GAGG;AACH,MAAM,MAAM,yBAAyB,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;AAmBtD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,SAAS,CAOxD;AAED,gHAAgH;AAChH,OAAO,EAAE,kBAAkB,EAAE,CAAC;AA2B9B,wBAAgB,aAAa,CAC3B,OAAO,EAAE,kBAAkB,EAAE,EAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AACzD;;;;GAIG;AACH,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,mBAAmB,CAAA;CAAO,GAClD,KAAK,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,UAAU,KAAK,aAAa,CAAC,UAAU,CAAC,CAuuP7E"}
|
package/dist/scope-do.js
CHANGED
|
@@ -2,12 +2,12 @@ import { REWIND_REFUSED } from './rewind-refusal.js';
|
|
|
2
2
|
import { SYSTEM_DOOR_MOVED } from './system-door.js';
|
|
3
3
|
import { DurableObject } from 'cloudflare:workers';
|
|
4
4
|
import { ATTACHMENT_ADDED, ATTACHMENT_REMOVED, attachmentRecord, domainEvent, domainEventInput, eventId, instant, objectRef, entityObjectRef, assertModuleEmittableType, assertKernelAuthoredType, toWireFailure, grantRefFromProof, principalId, principalBecomeCapabilityInput, scopeId as scopeIdOf, tenantId as tenantIdOf, platformRequestInput, platformRequestId, MAX_PENDING_PLATFORM_REQUESTS, MAX_PENDING_SWEEP_RUNS, SWEEP_RUNS_KIND, SCOPE_DUMP_PAGE_MAX_BYTES, SCOPE_TABLE_PAGE_MAX, SCOPE_QUERY_ROW_MAX, listLimitOf, pageOf, countedPageOf, requestFingerprint, substratError, errorCodeOf, assertReplayableDump, REDRAIN_BATCH, } from '@substrat-run/contracts';
|
|
5
|
-
import { ulid, DO_SQL_LIMITS, unknownRoleError, createUlid, assertAllowed, ConnectionSealingKeyUnavailableError, noSealingKeyMessage, sealTo, assertReadOnlyQuery, entitlementDenial, platformRequestHistoryQuery, platformRequestOf, PLATFORM_REQUEST_COLUMNS, PLATFORM_REQUEST_REDACTION_SQL, platformRequestRedactionParams, platformRequestRedactionQuery, intentPayloadCarriesSubject, redactSubjectJobRuns, eraseSubjectFromModules, moduleErasurePlan, redactSubjectScopeText, assertRowLimit, assertRowOffset, JOB_RUN_PATCH_SQL, JOB_RUN_CLAIM_SQL, JOB_RUN_RENEW_SQL, JOB_RUN_BEGIN_SQL, JOB_RUN_MISS_SQL, JOB_RUN_MISS_SETTLE_SQL, admissionMissOutcome, JOB_LEASE_EXPIRED_NOTE, JOB_STEP_RECORD_SQL, DELIVERY_ERROR_REDACTION_SQL, REDACTED_DELIVERY_NOTE, seatScopeTuple, delegatedRevokeSql, writeExplicitTupleIn, grantEntityShapeIn, topUpEntityGrantShapes, applyScopeRoleChange, changeScopeRole, revokeScopeRoles, scopeRoleHolders, assertModuleDeclared, noteReservedKeys, reservedGrantRefusal, reservedRoleRefusal, reservedShapeRefusal, effectiveRoleGrantQuery, switchRecordedOff, switchSystemSchedules, peerGrantsStatus, systemGrantsStatus, systemScheduleState, systemSwitchedOff, denialListQuery, refusalListQuery, mapRefusalRow, denialSummaryQuery, denialTotalsQuery, DENIAL_WINDOW_QUERY, mapDenialRow, mapDenialSummaryBuckets, PermissionDenied, assertImpersonationWrites, assertModuleEnqueueableKind, impersonationStampOf, createAtomic, NotSearchable, isSearchIndexTable, searchIndexPlans, NotListable, listIndexPlans, moduleMigrations, MIGRATION_DIGEST_FENCE_DDL, MIGRATION_DIGEST_MARK_LEGACY, assertJournalDumpCoherent, assertMigrationSql, migrationDivergence, migrationFailedError, migrationSetDivergence, migrationSteps, planMigrations, listQuery, cursorOf, searchLimit, searchMatchExpression, searchQuery, ATTACHMENT_TEXT_DDL, ATTACHMENT_CONDEMNED_DDL, ATTACHMENT_SWEEP_LICENCE_DDL, ATTACHMENT_SWEEP_LICENCE_TABLE, clearOrphanSweepLicence, condemnLicensedOrphanAttachments, consumeOrphanSweepLicence, licensedOrphanIds, recordOrphanSweepLicence, refuseUnlicensedOrphanSweep, refuseCondemnedAttachment, refuseCondemnedInDump, rowlessAttachmentIds, attachmentRecordOfRow, enqueueAttachmentText, reconcileAttachmentText, queueAttachmentTextBackfill, startAttachmentTextBackfill, recordAttachmentText, searchAttachments, IDEMPOTENCY_DDL, REFUSALS_TABLE_DDL, REFUSALS_INDEX, refusalInsert, refusalOf, markGuardRefusal, REFUSALS_REBUILD, refusalsAdmitGuards, assertIdempotencyKey, assertPermissionKey, idempotencyLookupQuery, idempotencyPruneStatement, idempotencyRecordStatement, idempotencyOptedOutMessage, replayFor, entityVersionQuery, entityVersionOf, assertIfMatch, OUTBOX_ENTITY_INDEX, SCHEDULE_STATE_DDL, SCHEDULE_STATE_REBUILD, scheduleStateHasKind, VERTICAL_EVENTS_DDL, EXPORT_HOPS_SQL, emptyImportResult, IMPORT_CURSORS_SQL, IMPORT_CURSOR_OF_SQL, OUTBOX_MARK_SQL, exportedSinceQuery, emittedSinceQuery, emittedReportOf, EMITTED_REPORT_CAP, IMPORT_CURSOR_ADVANCE_SQL, IMPORT_RECORD_SQL, moveImportCursor, CrossVerticalRegistry, exportReadPlan, exportReadQuery, planExportBatch, withheldNote, JOB_RUN_DDL, JOB_RUN_DUE_AT, jobRunListLimit, SYSTEM_DOOR_WAIT, ancestorsWithin, } from '@substrat-run/kernel';
|
|
5
|
+
import { ulid, DO_SQL_LIMITS, unknownRoleError, createUlid, assertAllowed, ConnectionSealingKeyUnavailableError, noSealingKeyMessage, sealTo, assertReadOnlyQuery, entitlementDenial, platformRequestHistoryQuery, platformRequestOf, PLATFORM_REQUEST_COLUMNS, PLATFORM_REQUEST_REDACTION_SQL, platformRequestRedactionParams, platformRequestRedactionQuery, intentPayloadCarriesSubject, redactSubjectJobRuns, eraseSubjectFromModules, moduleErasurePlan, redactSubjectScopeText, assertRowLimit, assertRowOffset, JOB_RUN_PATCH_SQL, JOB_RUN_CLAIM_SQL, JOB_RUN_RENEW_SQL, JOB_RUN_BEGIN_SQL, JOB_RUN_MISS_SQL, JOB_RUN_MISS_SETTLE_SQL, admissionMissOutcome, JOB_LEASE_EXPIRED_NOTE, JOB_STEP_RECORD_SQL, DELIVERY_ERROR_REDACTION_SQL, REDACTED_DELIVERY_NOTE, seatScopeTuple, delegatedRevokeSql, writeExplicitTupleIn, grantEntityShapeIn, topUpEntityGrantShapes, applyScopeRoleChange, changeScopeRole, revokeScopeRoles, scopeRoleHolders, assertModuleDeclared, noteDeclaredKeys, noteReservedKeys, SCOPE_SEATED_ROLES_SQL, reservedGrantRefusal, reservedRoleRefusal, reservedShapeRefusal, effectiveRoleGrantQuery, switchRecordedOff, switchSystemSchedules, peerGrantsStatus, systemGrantsStatus, systemScheduleState, systemSwitchedOff, denialListQuery, refusalListQuery, mapRefusalRow, denialSummaryQuery, denialTotalsQuery, DENIAL_WINDOW_QUERY, mapDenialRow, mapDenialSummaryBuckets, PermissionDenied, assertImpersonationWrites, assertModuleEnqueueableKind, impersonationStampOf, createAtomic, NotSearchable, isSearchIndexTable, searchIndexPlans, NotListable, listIndexPlans, moduleMigrations, MIGRATION_DIGEST_FENCE_DDL, MIGRATION_DIGEST_MARK_LEGACY, assertJournalDumpCoherent, assertMigrationSql, migrationDivergence, migrationFailedError, migrationSetDivergence, migrationSteps, planMigrations, listQuery, cursorOf, searchLimit, searchMatchExpression, searchQuery, ATTACHMENT_TEXT_DDL, ATTACHMENT_BYTES_SQL, ATTACHMENT_CONDEMNED_DDL, ATTACHMENT_SWEEP_LICENCE_DDL, ATTACHMENT_SWEEP_LICENCE_TABLE, clearOrphanSweepLicence, condemnLicensedOrphanAttachments, consumeOrphanSweepLicence, licensedOrphanIds, recordOrphanSweepLicence, refuseUnlicensedOrphanSweep, refuseCondemnedAttachment, refuseCondemnedInDump, rowlessAttachmentIds, attachmentRecordOfRow, enqueueAttachmentText, reconcileAttachmentText, queueAttachmentTextBackfill, startAttachmentTextBackfill, recordAttachmentText, searchAttachments, IDEMPOTENCY_DDL, REFUSALS_TABLE_DDL, REFUSALS_INDEX, refusalInsert, refusalOf, markGuardRefusal, REFUSALS_REBUILD, refusalsAdmitGuards, assertIdempotencyKey, assertPermissionKey, idempotencyLookupQuery, idempotencyPruneStatement, idempotencyRecordStatement, idempotencyOptedOutMessage, replayFor, entityVersionQuery, entityVersionOf, assertIfMatch, OUTBOX_ENTITY_INDEX, SCHEDULE_STATE_DDL, SCHEDULE_STATE_REBUILD, scheduleStateHasKind, VERTICAL_EVENTS_DDL, EXPORT_HOPS_SQL, emptyImportResult, IMPORT_CURSORS_SQL, IMPORT_CURSOR_OF_SQL, OUTBOX_MARK_SQL, exportedSinceQuery, emittedSinceQuery, emittedReportOf, EMITTED_REPORT_CAP, IMPORT_CURSOR_ADVANCE_SQL, IMPORT_RECORD_SQL, moveImportCursor, CrossVerticalRegistry, exportReadPlan, exportReadQuery, planExportBatch, withheldNote, JOB_RUN_DDL, JOB_RUN_DUE_AT, jobRunListLimit, SYSTEM_DOOR_WAIT, ancestorsWithin, } from '@substrat-run/kernel';
|
|
6
6
|
import { isUpgradeRequest, readSubscription, LIVE_DECIDE_ATTEMPTS, LIVE_FANOUT_LIMIT, LIVE_PRINCIPAL_HEADER, LIVE_SCOPE_HEADER, LIVE_SUBSCRIBE_PATH, LIVE_TENANT_HEADER, LIVE_WITHIN_HEADER, LIVE_EXPIRES_HEADER, LIVE_CLOSE, LIVE_SOCKETS_PER_PRINCIPAL, decodeLiveWithin, liveInstant, liveRefusal, liveRefusalStatus, } from './live-reads.js';
|
|
7
7
|
import { replyOf } from './do-reply.js';
|
|
8
8
|
import { OperationQueue } from './serialization.js';
|
|
9
9
|
import { assertNoWorkerdStorage, doScopedSql, doBuiltColumnsOf, doRedactionSql, doSpineSql } from './sql.js';
|
|
10
|
-
import { actorOf, admitPeer, boundToPeerDeclarations, collectPeers, switchPeer, peerSubjectRef, subjectGrantState, assertNoSecret, CAPABILITY_DDL, UPLOAD_LINK_DDL, createAttachmentVerbs, inspectUploadLink, redeemUploadLinkInTransaction, COPY_ORIGIN_DDL, ENTITY_STATE_MOVES_DDL, SWITCH_FENCES_DDL, TABLE_OWNERS_DDL, assertMigrationLeavesLedgerAlone, recordOwnershipSteps, runMigrationStatements, splitSqlStatements, executableSqlStatements, blankSqlComments, CAPABILITY_EXCHANGE_OPERATION, CAPABILITY_BECOME_MINT_OPERATION, becomeMintCheck, mintBecomeCapabilityAsPrincipal, revokeBecomeCapabilityAsPrincipal, readBecomeLinkStates, ENTITY_UNBIND_OPERATION, allowedFor, unbindEntityHolderBounded, capabilityAttachmentWriteRefused, createCapabilityVerbs, createEntityEdgeVerbs, createEntityStateVerbs, createTrashedReads, CONTINUATION_POSITION_CAP, visibleContinuation, searchStateWhere, uncheckedView, addStatePlans, addUpdatedStampPlans, watchUpdatedStamps, assertNoCallerPurge, isUnreachableParent, PURGE_BATCH, heldPurgePass, lifecycleRefusal, purgeHeldBy, purgeDueOf, purgeOnlyKeysOf, runPurgePass, refuseTrashedTarget, assertBoundOperations, checkHeldOperationsOf, countChecks, noteUncheckedCompletion, registerTrashTargets, withheldKeysFor, statefulTablesOf, afterMigration, afterRuntimeDdl, derivesAnything, repairDerivedObjects, StateColumnLost, exchangeCapability, guardSecrets, mintBecomeCapability, redactSecrets, redactSecretText, moduleLog, asyncInvocationId, asyncLinePass, resolveCapabilitySession, revokeCapabilityAsPlatform, readCapabilityPage, domainEventOf, facetEvents, readDeadLetters, readLifecycleFlow, readOperationSeries, readHistory, readInvocation, readUndrainedOutbox, walkEventCause, walkEventEffects, } from '@substrat-run/kernel';
|
|
10
|
+
import { actorOf, admitPeer, boundToPeerDeclarations, collectPeers, switchPeer, peerSubjectRef, subjectGrantState, assertNoSecret, CAPABILITY_DDL, UPLOAD_LINK_DDL, createAttachmentVerbs, inspectUploadLink, redeemUploadLinkInTransaction, COPY_ORIGIN_DDL, ENTITY_STATE_MOVES_DDL, SWITCH_FENCES_DDL, TABLE_OWNERS_DDL, assertMigrationLeavesLedgerAlone, recordOwnershipSteps, runMigrationStatements, splitSqlStatements, executableSqlStatements, blankSqlComments, CAPABILITY_EXCHANGE_OPERATION, CAPABILITY_BECOME_MINT_OPERATION, becomeMintCheck, mintBecomeCapabilityAsPrincipal, revokeBecomeCapabilityAsPrincipal, readBecomeLinkStates, ENTITY_UNBIND_OPERATION, allowedFor, unbindEntityHolderBounded, capabilityAttachmentWriteRefused, createCapabilityVerbs, createEntityEdgeVerbs, createEntityStateVerbs, createTrashedReads, CONTINUATION_POSITION_CAP, visibleContinuation, searchStateWhere, uncheckedView, addStatePlans, addUpdatedStampPlans, watchUpdatedStamps, assertNoCallerPurge, isUnreachableParent, PURGE_BATCH, heldPurgePass, lifecycleRefusal, purgeHeldBy, assertPlatformRequestRoom, purgeDueOf, purgeOnlyKeysOf, runPurgePass, refuseTrashedTarget, assertBoundOperations, checkHeldOperationsOf, countChecks, noteUncheckedCompletion, registerTrashTargets, withheldKeysFor, statefulTablesOf, afterMigration, afterRuntimeDdl, derivesAnything, repairDerivedObjects, StateColumnLost, exchangeCapability, guardSecrets, mintBecomeCapability, redactSecrets, redactSecretText, moduleLog, asyncInvocationId, asyncLinePass, resolveCapabilitySession, revokeCapabilityAsPlatform, readCapabilityPage, domainEventOf, facetEvents, readDeadLetters, readLifecycleFlow, readOperationSeries, readHistory, readInvocation, readUndrainedOutbox, walkEventCause, walkEventEffects, } from '@substrat-run/kernel';
|
|
11
11
|
import { COPY_RESTORE_FENCE_LAPSED, copyRestoreFenceLapsed, orphanSweepVersionRefusal } from '@substrat-run/kernel';
|
|
12
12
|
import { createDoTupleChecker, createLocalControlPlaneReader, scopeTupleReader } from './checker.js';
|
|
13
13
|
import { settlePlatformRequestIn } from '@substrat-run/kernel';
|
|
@@ -762,8 +762,11 @@ options = {}) {
|
|
|
762
762
|
assertModuleDeclared(options.permissions, registration.manifest.id);
|
|
763
763
|
// What the declared surface reserves holds in every instance too, whatever registers under its ids.
|
|
764
764
|
const declaredReserved = new Set();
|
|
765
|
-
|
|
765
|
+
const declaredListed = new Set();
|
|
766
|
+
for (const m of options.permissions?.modules ?? []) {
|
|
766
767
|
noteReservedKeys(declaredReserved, m.manifest);
|
|
768
|
+
noteDeclaredKeys(declaredListed, m.manifest);
|
|
769
|
+
}
|
|
767
770
|
return class ScopeDO extends DurableObject {
|
|
768
771
|
sql;
|
|
769
772
|
continuationOrder = 0;
|
|
@@ -825,6 +828,8 @@ options = {}) {
|
|
|
825
828
|
* `holder: 'system'` — the role and grant doors' refusals read it.
|
|
826
829
|
*/
|
|
827
830
|
reservedKeys = new Set(declaredReserved);
|
|
831
|
+
/** #2447: every key those modules declare, marked or not — a role definition projected here reads it. */
|
|
832
|
+
declaredKeys = new Set(declaredListed);
|
|
828
833
|
/** #1705: what this deployment exports to other verticals and imports from them. */
|
|
829
834
|
crossVertical = new CrossVerticalRegistry();
|
|
830
835
|
/**
|
|
@@ -1004,6 +1009,7 @@ options = {}) {
|
|
|
1004
1009
|
})),
|
|
1005
1010
|
});
|
|
1006
1011
|
noteReservedKeys(this.reservedKeys, manifest);
|
|
1012
|
+
noteDeclaredKeys(this.declaredKeys, manifest);
|
|
1007
1013
|
if (erasure)
|
|
1008
1014
|
this.erasurePlans.push(erasure);
|
|
1009
1015
|
for (const [name, handler] of Object.entries(registration.predicates ?? {})) {
|
|
@@ -1198,6 +1204,14 @@ options = {}) {
|
|
|
1198
1204
|
databaseSize() {
|
|
1199
1205
|
return this.sql.databaseSize;
|
|
1200
1206
|
}
|
|
1207
|
+
/**
|
|
1208
|
+
* This scope's attachment bytes (#2501): what its attachment rows sum to
|
|
1209
|
+
* (`ATTACHMENT_BYTES_SQL`). Read without migrating, as `databaseSize` is. The constructor lays
|
|
1210
|
+
* the spine, so the table is always there, and a copy wiped of its rows reads 0.
|
|
1211
|
+
*/
|
|
1212
|
+
attachmentBytes() {
|
|
1213
|
+
return this.sql.exec(ATTACHMENT_BYTES_SQL).toArray()[0].bytes;
|
|
1214
|
+
}
|
|
1201
1215
|
/**
|
|
1202
1216
|
* The PITR bookmarks this scope recorded before migration passes (#286),
|
|
1203
1217
|
* newest first — what a backout UI offers as rewind points. Rows taken after
|
|
@@ -1209,11 +1223,21 @@ options = {}) {
|
|
|
1209
1223
|
* written since this table shipped and selected by nobody — the frontier
|
|
1210
1224
|
* readers want `(module_id, version)` only — so "when did this scope's
|
|
1211
1225
|
* schema change" had no answer. A pre-column row reads null, a fact.
|
|
1226
|
+
*
|
|
1227
|
+
* Every row, never a page (#2553): the caller treats the list as the scope's whole
|
|
1228
|
+
* migration history, and a cap truncated it silently once a scope passed 100 rows.
|
|
1229
|
+
* A row is a few short columns (~150 B on the wire) and every row is an authored
|
|
1230
|
+
* migration a push shipped, so the set is bounded by authored migrations × pushes:
|
|
1231
|
+
* hundreds of rows, tens of KB, far under the RPC and response limits.
|
|
1232
|
+
*
|
|
1233
|
+
* `rowid DESC` breaks a tie: each migration reads its own clock, so neighbours can
|
|
1234
|
+
* share a millisecond, and the rowid is the order they were written in. `module_id,
|
|
1235
|
+
* version` ascending would read those oldest-first.
|
|
1212
1236
|
*/
|
|
1213
|
-
appliedMigrations(
|
|
1237
|
+
appliedMigrations() {
|
|
1214
1238
|
return this.sql
|
|
1215
1239
|
.exec(`SELECT module_id, version, applied_at, duration_ms, rows_changed FROM _substrat_migrations
|
|
1216
|
-
ORDER BY applied_at DESC,
|
|
1240
|
+
ORDER BY applied_at DESC, rowid DESC`)
|
|
1217
1241
|
.toArray()
|
|
1218
1242
|
.map((r) => ({
|
|
1219
1243
|
moduleId: r.module_id,
|
|
@@ -1348,6 +1372,34 @@ options = {}) {
|
|
|
1348
1372
|
const { verdict } = this.tenantVerdict(tenantId);
|
|
1349
1373
|
return verdict === 'recorded' || verdict === 'inferred';
|
|
1350
1374
|
}
|
|
1375
|
+
/**
|
|
1376
|
+
* #2541: this scope's database size, or null when the deployment does not hold it. The held
|
|
1377
|
+
* check and the read are ONE call: a reap or wipe cannot land between them, so a scope that
|
|
1378
|
+
* stopped being held is answered "not held", never with a number.
|
|
1379
|
+
*/
|
|
1380
|
+
async databaseSizeIfHeld() {
|
|
1381
|
+
return (await this.holdsScope()) ? this.databaseSize() : null;
|
|
1382
|
+
}
|
|
1383
|
+
/** #2541: this scope's attachment bytes, or null when the deployment does not hold it; one call, as the size is. */
|
|
1384
|
+
async attachmentBytesIfHeld() {
|
|
1385
|
+
return (await this.holdsScope()) ? this.attachmentBytes() : null;
|
|
1386
|
+
}
|
|
1387
|
+
/**
|
|
1388
|
+
* #2541: whether this object is a scope the deployment holds, asked by a read that names only a
|
|
1389
|
+
* scope id. False for a DO nothing provisioned or loaded here (never provisioned), for a reaped
|
|
1390
|
+
* scope's name addressed again (its tombstone), and for a copy a carry wiped, whose rows went
|
|
1391
|
+
* with the wipe. Held otherwise: a provision receipt or role rows, or state (`holdsData`). Read
|
|
1392
|
+
* without migrating, so a refusal leaves the DO as it found it.
|
|
1393
|
+
*/
|
|
1394
|
+
async holdsScope() {
|
|
1395
|
+
if (this.carriedAwayCopy || (await this.isReaped()))
|
|
1396
|
+
return false;
|
|
1397
|
+
return this.provisionedFor() !== null || this.holdsRoles() || this.holdsData();
|
|
1398
|
+
}
|
|
1399
|
+
/** Whether the scope holds any role row, of whichever tenant; read without migrating. */
|
|
1400
|
+
holdsRoles() {
|
|
1401
|
+
return this.hasTable('_substrat_roles') && this.sql.exec('SELECT 1 FROM _substrat_roles LIMIT 1').toArray().length > 0;
|
|
1402
|
+
}
|
|
1351
1403
|
/**
|
|
1352
1404
|
* #2016: what one door into this scope needs from its storage on a CP-less host, in ONE call —
|
|
1353
1405
|
* how `tenantId` reads against the scope (`tenantVerdict`), and the lifecycle the platform
|
|
@@ -3170,6 +3222,29 @@ options = {}) {
|
|
|
3170
3222
|
return parsed;
|
|
3171
3223
|
});
|
|
3172
3224
|
}
|
|
3225
|
+
/**
|
|
3226
|
+
* The upload's write gate and nothing else (#2516): asked by the host before a streamed body is
|
|
3227
|
+
* read, so a connection that may not write costs no object. Checked and recorded exactly as
|
|
3228
|
+
* `addAttachment` does, which still checks again when the row is written.
|
|
3229
|
+
*/
|
|
3230
|
+
async checkAttachmentWrite(entity, principal, tenantId, scopeId, connectionId) {
|
|
3231
|
+
await this.ensureMigrations();
|
|
3232
|
+
const gate = this.attachmentGate(entity.entityType);
|
|
3233
|
+
try {
|
|
3234
|
+
const ctx = this.operationContext(principal, tenantId, scopeId, undefined, connectionId, undefined, undefined, undefined, 'attachments.upload');
|
|
3235
|
+
assertAllowed(await ctx.check(gate.write, entity));
|
|
3236
|
+
}
|
|
3237
|
+
catch (err) {
|
|
3238
|
+
if (err instanceof PermissionDenied) {
|
|
3239
|
+
this.recordDenial(attachSubject(principal, connectionId), tenantId, 'attachments.upload', err, null);
|
|
3240
|
+
}
|
|
3241
|
+
throw err;
|
|
3242
|
+
}
|
|
3243
|
+
return null;
|
|
3244
|
+
}
|
|
3245
|
+
attachmentCheckWriteReply(...args) {
|
|
3246
|
+
return replyOf(() => this.checkAttachmentWrite(...args));
|
|
3247
|
+
}
|
|
3173
3248
|
/** Records for one entity, newest first — read gate first. */
|
|
3174
3249
|
async listAttachments(entity, principal, tenantId, scopeId, connectionId) {
|
|
3175
3250
|
await this.ensureMigrations();
|
|
@@ -3664,10 +3739,15 @@ options = {}) {
|
|
|
3664
3739
|
/**
|
|
3665
3740
|
* #2430: why `roleKey` may not be conferred through `door` here, or null — the tenant's role as
|
|
3666
3741
|
* the checker expands it (`controlPlaneReader`), against the keys this class's modules reserve.
|
|
3667
|
-
* A role the tenant does not define is left to the door's own answer for it.
|
|
3742
|
+
* A role the tenant does not define is left to the door's own answer for it. A person's door reads
|
|
3743
|
+
* the role even when this class reserves nothing (#2447): a role stored `holder: 'system'` is
|
|
3744
|
+
* never a person's, whatever this class knows. Accepted cost: on a class that reserves nothing, an
|
|
3745
|
+
* invite, a role change and a `canAssign` read the role here and again for the bound, which on a
|
|
3746
|
+
* scope still reading the shared directory is one more ControlPlaneDO round trip per call. These
|
|
3747
|
+
* doors are a person acting, not a hot path, so one read is not threaded through both.
|
|
3668
3748
|
*/
|
|
3669
3749
|
async reservedRoleRefusalFor(tenantId, roleKey, door) {
|
|
3670
|
-
if (this.reservedKeys.size === 0)
|
|
3750
|
+
if (door === 'platform' && this.reservedKeys.size === 0)
|
|
3671
3751
|
return null;
|
|
3672
3752
|
const role = await this.controlPlaneReader().getRole(tenantId, roleKey);
|
|
3673
3753
|
return role ? reservedRoleRefusal(role, this.reservedKeys, door) : null;
|
|
@@ -3686,7 +3766,7 @@ options = {}) {
|
|
|
3686
3766
|
* door cannot know, so it refuses.
|
|
3687
3767
|
*/
|
|
3688
3768
|
async reservedRoleRefusalHere(roleKey, door) {
|
|
3689
|
-
if (this.reservedKeys.size === 0)
|
|
3769
|
+
if (door === 'platform' && this.reservedKeys.size === 0)
|
|
3690
3770
|
return null;
|
|
3691
3771
|
const tenantId = this.provisionedFor();
|
|
3692
3772
|
if (tenantId)
|
|
@@ -3699,7 +3779,8 @@ options = {}) {
|
|
|
3699
3779
|
if (refusal)
|
|
3700
3780
|
return refusal;
|
|
3701
3781
|
}
|
|
3702
|
-
|
|
3782
|
+
// A class that reserves nothing has nothing to rule out here, at either door (#2447 keeps that).
|
|
3783
|
+
if (tenants.length === 0 && this.reservedKeys.size > 0 && this.permissionSourceIsRemote()) {
|
|
3703
3784
|
return (`role '${roleKey}' cannot be judged here: this scope has no provisioning receipt and no projected role, and its ` +
|
|
3704
3785
|
"checks read roles from the control plane, so which tenant's definition a check expands is unknown and a key " +
|
|
3705
3786
|
'reserved to a system principal cannot be ruled out. Provision the scope first.');
|
|
@@ -3714,6 +3795,27 @@ options = {}) {
|
|
|
3714
3795
|
async reservedShapeRefusalFor(shapes) {
|
|
3715
3796
|
return reservedShapeRefusal(shapes, this.reservedKeys);
|
|
3716
3797
|
}
|
|
3798
|
+
/**
|
|
3799
|
+
* #2447: the tenant's roles as this scope stores them, and the role keys anyone but a system
|
|
3800
|
+
* principal holds a live scope-level seat in here — what a role
|
|
3801
|
+
* set defined on this scope, or a role definition fanned out to it, is judged against.
|
|
3802
|
+
*/
|
|
3803
|
+
async roleStateHere(tenantId) {
|
|
3804
|
+
// Spine tables only (built in the constructor), so no module migration runs ahead of a provision's.
|
|
3805
|
+
const now = new Date().toISOString();
|
|
3806
|
+
const roles = this.hasTable('_substrat_roles')
|
|
3807
|
+
? this.sql.exec('SELECT role_key, permissions, holder FROM _substrat_roles WHERE tenant_id = ? AND revoked_at IS NULL', tenantId).toArray().map((r) => ({ key: r.role_key, permissions: JSON.parse(r.permissions), ...(r.holder ? { holder: r.holder } : {}) }))
|
|
3808
|
+
: [];
|
|
3809
|
+
// Scope-level seats only. The tenant-level ones are the directory's (the ControlPlaneDO reads
|
|
3810
|
+
// them in its own unit), and this scope's projected copy can be stale: a fan-out skips an
|
|
3811
|
+
// archived scope, and a CP-less projection carries none.
|
|
3812
|
+
const seated = new Set(this.sql.exec(SCOPE_SEATED_ROLES_SQL, now).toArray().map((r) => r.role_key));
|
|
3813
|
+
return { roles, seated: [...seated] };
|
|
3814
|
+
}
|
|
3815
|
+
/** #2447: what this class's modules reserve and declare — a coordinator judging a role definition joins its own. */
|
|
3816
|
+
async reservationHere() {
|
|
3817
|
+
return { reserved: [...this.reservedKeys], declared: [...this.declaredKeys] };
|
|
3818
|
+
}
|
|
3717
3819
|
/** #2430: which of `permissions` this class's modules reserve to a system principal. */
|
|
3718
3820
|
async reservedAmong(permissions) {
|
|
3719
3821
|
return permissions.filter((p) => this.reservedKeys.has(p));
|
|
@@ -4100,7 +4202,12 @@ options = {}) {
|
|
|
4100
4202
|
* positional-RPC reason `recordExecutorAttempt` gives; a coordinator without it gets a fresh
|
|
4101
4203
|
* id per purge, as before.
|
|
4102
4204
|
*/
|
|
4103
|
-
runInvocationId
|
|
4205
|
+
runInvocationId,
|
|
4206
|
+
/**
|
|
4207
|
+
* #2517: platform requests the purge runs earlier in the same tick enqueued. LAST and optional
|
|
4208
|
+
* for the same reason; absent means none, so a refused head is a failure as before.
|
|
4209
|
+
*/
|
|
4210
|
+
earlierPurgeRequests) {
|
|
4104
4211
|
await this.ensureMigrations();
|
|
4105
4212
|
const schedule = this.purgeSchedules.get(operation);
|
|
4106
4213
|
if (!schedule)
|
|
@@ -4120,9 +4227,14 @@ options = {}) {
|
|
|
4120
4227
|
if (held !== null)
|
|
4121
4228
|
return heldPurgePass(held);
|
|
4122
4229
|
const due = purgeDueOf(doSpineSql(this.sql), this.statePlans, this.operationTarget, operation, schedule.entityType, new Date().toISOString(), PURGE_BATCH);
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4230
|
+
// #2440: what each committed purge enqueued, from the same envelope an ordinary invoke's
|
|
4231
|
+
// caller reads. A purge that threw rolled back, and its intents with it.
|
|
4232
|
+
let platformRequests = 0;
|
|
4233
|
+
const pass = await runPurgePass(operation, due, async (entityId) => {
|
|
4234
|
+
const envelope = await this.#invokeOrThrow(operation, { [due.idFrom]: entityId }, schedule.moduleId, tenantId, scopeId, undefined, undefined, schedule.moduleId, { invocationId: runInvocationId ?? ulid() }, undefined, undefined, undefined, systemDoorInstance, true);
|
|
4235
|
+
platformRequests += envelope.platformRequests;
|
|
4236
|
+
}, (write) => write(doSpineSql(this.sql)), earlierPurgeRequests ?? 0);
|
|
4237
|
+
return platformRequests > 0 ? { ...pass, platformRequests } : pass;
|
|
4126
4238
|
}
|
|
4127
4239
|
/**
|
|
4128
4240
|
* #119: the purge gate's facts (`PurgeGateFacts`), from this scope's own storage: the module's
|
|
@@ -4911,9 +5023,7 @@ options = {}) {
|
|
|
4911
5023
|
const pending = Number(this.sql
|
|
4912
5024
|
.exec(`SELECT COUNT(*) AS c FROM _substrat_platform_requests WHERE status = 'pending'`)
|
|
4913
5025
|
.toArray()[0].c);
|
|
4914
|
-
|
|
4915
|
-
throw new Error(`too many pending platform requests (${pending}); the delivery retries once some have drained`);
|
|
4916
|
-
}
|
|
5026
|
+
assertPlatformRequestRoom(pending, 'the delivery retries once some have drained');
|
|
4917
5027
|
const id = platformRequestId.parse(ulid());
|
|
4918
5028
|
// K-42: the intent inherits the SOURCE EVENT's stamp rather than being written
|
|
4919
5029
|
// unstamped. Nobody is impersonating at this moment — the drain runs long after
|
|
@@ -6551,9 +6661,7 @@ options = {}) {
|
|
|
6551
6661
|
const pending = Number(sql
|
|
6552
6662
|
.exec(`SELECT COUNT(*) AS c FROM _substrat_platform_requests WHERE status = 'pending'`)
|
|
6553
6663
|
.toArray()[0].c);
|
|
6554
|
-
|
|
6555
|
-
throw new Error(`too many pending platform requests (${pending}); retry once some have drained`);
|
|
6556
|
-
}
|
|
6664
|
+
assertPlatformRequestRoom(pending);
|
|
6557
6665
|
const id = platformRequestId.parse(ulid());
|
|
6558
6666
|
const requestedBy = systemActor ?? derivedActor;
|
|
6559
6667
|
sql.exec(`INSERT INTO _substrat_platform_requests
|
|
@@ -6838,27 +6946,9 @@ options = {}) {
|
|
|
6838
6946
|
// The write side of the local reader: the coordinator fans role/tuple changes
|
|
6839
6947
|
// into a scope's own storage (Phase 2), then flips the source to 'local'. Public
|
|
6840
6948
|
// RPC methods so `CloudflareScopeHost` (and the projection sweep) can call them.
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
|
|
6844
|
-
this.sql.exec(`INSERT OR REPLACE INTO _substrat_roles (tenant_id, role_key, permissions, source, holder, revoked_at)
|
|
6845
|
-
VALUES (?, ?, ?, ?, ?, NULL)`, tenantId, role.key, JSON.stringify(role.permissions), role.source, role.holder ?? null);
|
|
6846
|
-
});
|
|
6847
|
-
}
|
|
6848
|
-
/** Tombstone a projected role — it stops granting but stays as evidence (K-21). */
|
|
6849
|
-
async revokeProjectedRole(tenantId, key, revokedAt) {
|
|
6850
|
-
await this.queue.enqueue(() => {
|
|
6851
|
-
this.sql.exec(`UPDATE _substrat_roles SET revoked_at = ? WHERE tenant_id = ? AND role_key = ?`, revokedAt, tenantId, key);
|
|
6852
|
-
});
|
|
6853
|
-
}
|
|
6854
|
-
/** Project (upsert) a tenant-level tuple into this scope. `revokedAt` tombstones it. */
|
|
6855
|
-
async projectTenantTuple(tenantId, subject, relation, object, expiresAt, revokedAt = null) {
|
|
6856
|
-
await this.queue.enqueue(() => {
|
|
6857
|
-
this.sql.exec(`INSERT OR REPLACE INTO _substrat_tenant_tuples
|
|
6858
|
-
(tenant_id, subject, relation, object, expires_at, revoked_at)
|
|
6859
|
-
VALUES (?, ?, ?, ?, ?, ?)`, tenantId, subject, relation, object, expiresAt, revokedAt);
|
|
6860
|
-
});
|
|
6861
|
-
}
|
|
6949
|
+
// #2531: no per-row role or tenant-tuple projection RPC. Every projected row arrives through
|
|
6950
|
+
// `applyProjection`, whose callers judge what they project (or fan out definitions already
|
|
6951
|
+
// judged), so no RPC writes a role row unjudged.
|
|
6862
6952
|
/** Flip which reader the checker uses. 'local' makes projections authoritative. */
|
|
6863
6953
|
async setPermissionSource(source) {
|
|
6864
6954
|
await this.queue.enqueue(() => {
|