@substrat-run/kernel 0.139.0 → 0.140.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.
Files changed (140) hide show
  1. package/dist/admin-log-ddl.d.ts +21 -0
  2. package/dist/admin-log-ddl.d.ts.map +1 -0
  3. package/dist/admin-log-ddl.js +32 -0
  4. package/dist/admin-log-ddl.js.map +1 -0
  5. package/dist/attachment-extractor.d.ts +12 -1
  6. package/dist/attachment-extractor.d.ts.map +1 -1
  7. package/dist/attachment-extractor.js +10 -5
  8. package/dist/attachment-extractor.js.map +1 -1
  9. package/dist/audit-outcome.d.ts +149 -0
  10. package/dist/audit-outcome.d.ts.map +1 -0
  11. package/dist/audit-outcome.js +233 -0
  12. package/dist/audit-outcome.js.map +1 -0
  13. package/dist/connect-links.d.ts +91 -0
  14. package/dist/connect-links.d.ts.map +1 -0
  15. package/dist/connect-links.js +189 -0
  16. package/dist/connect-links.js.map +1 -0
  17. package/dist/connect-state.d.ts +12 -3
  18. package/dist/connect-state.d.ts.map +1 -1
  19. package/dist/connect-state.js +8 -3
  20. package/dist/connect-state.js.map +1 -1
  21. package/dist/derived-object.d.ts +14 -0
  22. package/dist/derived-object.d.ts.map +1 -0
  23. package/dist/derived-object.js +2 -0
  24. package/dist/derived-object.js.map +1 -0
  25. package/dist/derived-objects.d.ts +108 -0
  26. package/dist/derived-objects.d.ts.map +1 -0
  27. package/dist/derived-objects.js +199 -0
  28. package/dist/derived-objects.js.map +1 -0
  29. package/dist/email-intent.d.ts +56 -0
  30. package/dist/email-intent.d.ts.map +1 -0
  31. package/dist/email-intent.js +71 -0
  32. package/dist/email-intent.js.map +1 -0
  33. package/dist/entity-edges.d.ts +6 -1
  34. package/dist/entity-edges.d.ts.map +1 -1
  35. package/dist/entity-edges.js +13 -0
  36. package/dist/entity-edges.js.map +1 -1
  37. package/dist/entity-grant-shape.d.ts +94 -0
  38. package/dist/entity-grant-shape.d.ts.map +1 -0
  39. package/dist/entity-grant-shape.js +329 -0
  40. package/dist/entity-grant-shape.js.map +1 -0
  41. package/dist/entity-grant.d.ts +45 -0
  42. package/dist/entity-grant.d.ts.map +1 -0
  43. package/dist/entity-grant.js +71 -0
  44. package/dist/entity-grant.js.map +1 -0
  45. package/dist/entity-state-reads.d.ts +4 -7
  46. package/dist/entity-state-reads.d.ts.map +1 -1
  47. package/dist/entity-state-reads.js +13 -57
  48. package/dist/entity-state-reads.js.map +1 -1
  49. package/dist/entity-state.d.ts +37 -10
  50. package/dist/entity-state.d.ts.map +1 -1
  51. package/dist/entity-state.js +80 -69
  52. package/dist/entity-state.js.map +1 -1
  53. package/dist/entity-trash.d.ts +245 -0
  54. package/dist/entity-trash.d.ts.map +1 -0
  55. package/dist/entity-trash.js +380 -0
  56. package/dist/entity-trash.js.map +1 -0
  57. package/dist/grant-scoped-read.d.ts +41 -0
  58. package/dist/grant-scoped-read.d.ts.map +1 -0
  59. package/dist/grant-scoped-read.js +100 -0
  60. package/dist/grant-scoped-read.js.map +1 -0
  61. package/dist/index.d.ts +31 -5
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +20 -4
  64. package/dist/index.js.map +1 -1
  65. package/dist/kernel-outbox.d.ts +14 -0
  66. package/dist/kernel-outbox.d.ts.map +1 -0
  67. package/dist/kernel-outbox.js +37 -0
  68. package/dist/kernel-outbox.js.map +1 -0
  69. package/dist/list-index.d.ts +11 -2
  70. package/dist/list-index.d.ts.map +1 -1
  71. package/dist/list-index.js +29 -21
  72. package/dist/list-index.js.map +1 -1
  73. package/dist/mail-sender.d.ts +78 -0
  74. package/dist/mail-sender.d.ts.map +1 -0
  75. package/dist/mail-sender.js +2 -0
  76. package/dist/mail-sender.js.map +1 -0
  77. package/dist/membership-executor.d.ts +0 -52
  78. package/dist/membership-executor.d.ts.map +1 -1
  79. package/dist/membership-executor.js +19 -59
  80. package/dist/membership-executor.js.map +1 -1
  81. package/dist/migration-digest.d.ts +161 -0
  82. package/dist/migration-digest.d.ts.map +1 -0
  83. package/dist/migration-digest.js +237 -0
  84. package/dist/migration-digest.js.map +1 -0
  85. package/dist/module-erasure.d.ts +156 -0
  86. package/dist/module-erasure.d.ts.map +1 -0
  87. package/dist/module-erasure.js +440 -0
  88. package/dist/module-erasure.js.map +1 -0
  89. package/dist/peer.d.ts +9 -1
  90. package/dist/peer.d.ts.map +1 -1
  91. package/dist/peer.js +29 -0
  92. package/dist/peer.js.map +1 -1
  93. package/dist/permission-checker.d.ts +6 -0
  94. package/dist/permission-checker.d.ts.map +1 -1
  95. package/dist/permission-checker.js.map +1 -1
  96. package/dist/permission-eval.d.ts +10 -1
  97. package/dist/permission-eval.d.ts.map +1 -1
  98. package/dist/permission-eval.js +51 -2
  99. package/dist/permission-eval.js.map +1 -1
  100. package/dist/platform-sweep.d.ts +1 -1
  101. package/dist/platform-sweep.d.ts.map +1 -1
  102. package/dist/platform-sweep.js +5 -0
  103. package/dist/platform-sweep.js.map +1 -1
  104. package/dist/scope-host.d.ts +301 -22
  105. package/dist/scope-host.d.ts.map +1 -1
  106. package/dist/scope-host.js +72 -5
  107. package/dist/scope-host.js.map +1 -1
  108. package/dist/search-index.d.ts +8 -0
  109. package/dist/search-index.d.ts.map +1 -1
  110. package/dist/search-index.js +51 -21
  111. package/dist/search-index.js.map +1 -1
  112. package/dist/spine-guard.d.ts +7 -0
  113. package/dist/spine-guard.d.ts.map +1 -1
  114. package/dist/spine-guard.js +54 -6
  115. package/dist/spine-guard.js.map +1 -1
  116. package/dist/spine-restore.d.ts.map +1 -1
  117. package/dist/spine-restore.js +5 -0
  118. package/dist/spine-restore.js.map +1 -1
  119. package/dist/sql-statements.d.ts +71 -0
  120. package/dist/sql-statements.d.ts.map +1 -0
  121. package/dist/sql-statements.js +191 -0
  122. package/dist/sql-statements.js.map +1 -0
  123. package/dist/subject-redaction.d.ts +9 -1
  124. package/dist/subject-redaction.d.ts.map +1 -1
  125. package/dist/subject-redaction.js.map +1 -1
  126. package/dist/system-switch-record.d.ts +3 -0
  127. package/dist/system-switch-record.d.ts.map +1 -1
  128. package/dist/system-switch-record.js +2 -0
  129. package/dist/system-switch-record.js.map +1 -1
  130. package/dist/table-ownership.d.ts +103 -0
  131. package/dist/table-ownership.d.ts.map +1 -0
  132. package/dist/table-ownership.js +285 -0
  133. package/dist/table-ownership.js.map +1 -0
  134. package/dist/timeline.d.ts +4 -4
  135. package/dist/timeline.js +4 -4
  136. package/dist/visible-continuation.d.ts +38 -0
  137. package/dist/visible-continuation.d.ts.map +1 -0
  138. package/dist/visible-continuation.js +162 -0
  139. package/dist/visible-continuation.js.map +1 -0
  140. package/package.json +2 -2
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Every index on the directory's `_substrat_admin_log`, as ONE script both adapters build from
3
+ * (#2064). The table is created by each adapter's directory schema, and it is REBUILT on a
4
+ * legacy directory (K-23's `tenant_id` made nullable, `ensureAdminLogTenantNullable`). A
5
+ * rebuild drops every index on the table it replaces, so this script runs twice: in the schema,
6
+ * and again inside the rebuild's own transaction, after the rename. An index added to the log
7
+ * goes here, never into one adapter's DDL, or the next legacy rebuild drops it silently.
8
+ *
9
+ * - The first five are the console's read-path indexes (control-plane.md §4.5). The log is
10
+ * append-only and only grows, so every filter it offers needs one, and the trailing id
11
+ * makes each a covering index for the ORDER BY.
12
+ * - `_substrat_admin_log_operation` (#2064) finds an audited change's rows by operation id
13
+ * rather than by scanning the log. It is partial, so rows that pair nothing cost nothing.
14
+ *
15
+ * A literal with no comments and no interpolation, because `lint:spine-ddl` inlines it as
16
+ * written and the hosted DDL is split on semicolons.
17
+ */
18
+ export declare const ADMIN_LOG_INDEXES_SQL = "\n CREATE INDEX IF NOT EXISTS _substrat_admin_log_tenant ON _substrat_admin_log (tenant_id, id);\n CREATE INDEX IF NOT EXISTS _substrat_admin_log_scope ON _substrat_admin_log (scope_id, id);\n CREATE INDEX IF NOT EXISTS _substrat_admin_log_actor ON _substrat_admin_log (actor, id);\n CREATE INDEX IF NOT EXISTS _substrat_admin_log_action ON _substrat_admin_log (action, id);\n CREATE INDEX IF NOT EXISTS _substrat_admin_log_at ON _substrat_admin_log (at);\n CREATE INDEX IF NOT EXISTS _substrat_admin_log_operation\n ON _substrat_admin_log (json_extract(after, '$.operationId'))\n WHERE json_extract(after, '$.operationId') IS NOT NULL;\n";
19
+ /** `ADMIN_LOG_INDEXES_SQL` one statement at a time, for a host that executes them singly. */
20
+ export declare const ADMIN_LOG_INDEX_DDL: readonly string[];
21
+ //# sourceMappingURL=admin-log-ddl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-log-ddl.d.ts","sourceRoot":"","sources":["../src/admin-log-ddl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,qBAAqB,+oBASjC,CAAC;AAEF,6FAA6F;AAC7F,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAEP,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Every index on the directory's `_substrat_admin_log`, as ONE script both adapters build from
3
+ * (#2064). The table is created by each adapter's directory schema, and it is REBUILT on a
4
+ * legacy directory (K-23's `tenant_id` made nullable, `ensureAdminLogTenantNullable`). A
5
+ * rebuild drops every index on the table it replaces, so this script runs twice: in the schema,
6
+ * and again inside the rebuild's own transaction, after the rename. An index added to the log
7
+ * goes here, never into one adapter's DDL, or the next legacy rebuild drops it silently.
8
+ *
9
+ * - The first five are the console's read-path indexes (control-plane.md §4.5). The log is
10
+ * append-only and only grows, so every filter it offers needs one, and the trailing id
11
+ * makes each a covering index for the ORDER BY.
12
+ * - `_substrat_admin_log_operation` (#2064) finds an audited change's rows by operation id
13
+ * rather than by scanning the log. It is partial, so rows that pair nothing cost nothing.
14
+ *
15
+ * A literal with no comments and no interpolation, because `lint:spine-ddl` inlines it as
16
+ * written and the hosted DDL is split on semicolons.
17
+ */
18
+ export const ADMIN_LOG_INDEXES_SQL = `
19
+ CREATE INDEX IF NOT EXISTS _substrat_admin_log_tenant ON _substrat_admin_log (tenant_id, id);
20
+ CREATE INDEX IF NOT EXISTS _substrat_admin_log_scope ON _substrat_admin_log (scope_id, id);
21
+ CREATE INDEX IF NOT EXISTS _substrat_admin_log_actor ON _substrat_admin_log (actor, id);
22
+ CREATE INDEX IF NOT EXISTS _substrat_admin_log_action ON _substrat_admin_log (action, id);
23
+ CREATE INDEX IF NOT EXISTS _substrat_admin_log_at ON _substrat_admin_log (at);
24
+ CREATE INDEX IF NOT EXISTS _substrat_admin_log_operation
25
+ ON _substrat_admin_log (json_extract(after, '$.operationId'))
26
+ WHERE json_extract(after, '$.operationId') IS NOT NULL;
27
+ `;
28
+ /** `ADMIN_LOG_INDEXES_SQL` one statement at a time, for a host that executes them singly. */
29
+ export const ADMIN_LOG_INDEX_DDL = ADMIN_LOG_INDEXES_SQL.split(';')
30
+ .map((statement) => statement.trim())
31
+ .filter((statement) => statement !== '');
32
+ //# sourceMappingURL=admin-log-ddl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-log-ddl.js","sourceRoot":"","sources":["../src/admin-log-ddl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;CASpC,CAAC;AAEF,6FAA6F;AAC7F,MAAM,CAAC,MAAM,mBAAmB,GAAsB,qBAAqB,CAAC,KAAK,CAAC,GAAG,CAAC;KACnF,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;KACpC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC"}
@@ -183,6 +183,17 @@ export declare function truncateUtf8(text: string, maxBytes: number): {
183
183
  * or an HTML file's indentation would spend the per-attachment budget on nothing.
184
184
  */
185
185
  export declare function normalizeExtractedText(text: string): string;
186
+ /**
187
+ * The timers the time budget runs on: the deadline, and the turn owed to it after a
188
+ * synchronous extractor returns. Both go through the same pair, because the guarantee is an
189
+ * ORDER between them — the deadline, if it passed, runs first. The runtime's own by default; a
190
+ * caller that passes others (a test, on a clock it moves itself) moves both together, so the
191
+ * outcome is decided by that clock rather than by how busy the machine is (#2085).
192
+ */
193
+ export interface ExtractionTimers {
194
+ setTimeout(fn: () => void, ms: number): unknown;
195
+ clearTimeout(handle: unknown): void;
196
+ }
186
197
  /**
187
198
  * Run one extractor and turn whatever it does into an outcome the kernel can record: the
188
199
  * time budget, the throw, the shape and the output cap, all judged here, after it returns.
@@ -192,5 +203,5 @@ export declare function runAttachmentExtractor(extractor: AttachmentExtractor, i
192
203
  body: Uint8Array;
193
204
  contentType: string;
194
205
  filename: string;
195
- }, bounds?: AttachmentTextBounds): Promise<ExtractionOutcome>;
206
+ }, bounds?: AttachmentTextBounds, timers?: ExtractionTimers): Promise<ExtractionOutcome>;
196
207
  //# sourceMappingURL=attachment-extractor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"attachment-extractor.d.ts","sourceRoot":"","sources":["../src/attachment-extractor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"attachment-extractor.d.ts","sourceRoot":"","sources":["../src/attachment-extractor.ts"],"names":[],"mappings":"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"}
@@ -193,7 +193,12 @@ export function normalizeExtractedText(text) {
193
193
  * order of when they are due, so this one cannot run before a deadline that has already
194
194
  * passed, whichever phase of the loop the extractor returned in. It runs once per extraction.
195
195
  */
196
- const nextTurn = () => new Promise((resolve) => setTimeout(resolve, 0));
196
+ const nextTurn = (timers) => new Promise((resolve) => timers.setTimeout(resolve, 0));
197
+ /** The runtime's timers, called bare — workerd throws `Illegal invocation` on `obj.setTimeout(…)`. */
198
+ const RUNTIME_TIMERS = {
199
+ setTimeout: (fn, ms) => setTimeout(fn, ms),
200
+ clearTimeout: (handle) => clearTimeout(handle),
201
+ };
197
202
  const TIMED_OUT = Symbol('timed out');
198
203
  /** A recorded reason is short: an extractor's `failed` is cut, never trusted to be. */
199
204
  const DETAIL_MAX = 500;
@@ -202,7 +207,7 @@ const DETAIL_MAX = 500;
202
207
  * time budget, the throw, the shape and the output cap, all judged here, after it returns.
203
208
  * See this file's header for what the budget can and cannot stop.
204
209
  */
205
- export async function runAttachmentExtractor(extractor, input, bounds = DEFAULT_ATTACHMENT_TEXT_BOUNDS) {
210
+ export async function runAttachmentExtractor(extractor, input, bounds = DEFAULT_ATTACHMENT_TEXT_BOUNDS, timers = RUNTIME_TIMERS) {
206
211
  const failed = (detail) => ({
207
212
  status: 'failed',
208
213
  extractor: extractor.name,
@@ -212,7 +217,7 @@ export async function runAttachmentExtractor(extractor, input, bounds = DEFAULT_
212
217
  const controller = new AbortController();
213
218
  let timedOut = false;
214
219
  let onTimeout = () => { };
215
- const timer = setTimeout(() => {
220
+ const timer = timers.setTimeout(() => {
216
221
  timedOut = true;
217
222
  controller.abort();
218
223
  onTimeout(TIMED_OUT);
@@ -235,8 +240,8 @@ export async function runAttachmentExtractor(extractor, input, bounds = DEFAULT_
235
240
  // A SYNCHRONOUS extractor returns before its timer can run, however long it took. Give the
236
241
  // timer the turn it was owed: if the deadline passed meanwhile, the answer is discarded.
237
242
  if (!timedOut)
238
- await nextTurn();
239
- clearTimeout(timer);
243
+ await nextTurn(timers);
244
+ timers.clearTimeout(timer);
240
245
  if (timedOut || result === TIMED_OUT)
241
246
  return timeout;
242
247
  if (didThrow) {
@@ -1 +1 @@
1
- {"version":3,"file":"attachment-extractor.js","sourceRoot":"","sources":["../src/attachment-extractor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"attachment-extractor.js","sourceRoot":"","sources":["../src/attachment-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,149 @@
1
+ import type { OpsFailureInput } from './scope-host.js';
2
+ /**
3
+ * The admin actions written intent-then-outcome, which a settle closes: the two the control plane
4
+ * writes around a vertical call, (#2089) the schedule and peer kill switches, which each adapter
5
+ * writes around the scope's move, and (#2114) the replay lever, written the same way around the
6
+ * watermark's move. A lever row written before #2114 carries only `replayId`, no `operationId`,
7
+ * so every reader passes it over as it passes over any row without one.
8
+ */
9
+ export declare const AUDITED_CHANGE_ACTIONS: readonly ["transferOwner", "manageScopeMember", "setPeerBinding", "revokeFromSystem", "restoreToSystem", "revokeFromPeer", "restoreToPeer", "moveImportCursor"];
10
+ export type AuditedChangeAction = (typeof AUDITED_CHANGE_ACTIONS)[number];
11
+ /** The structured line an outcome row that could not be written leaves, keyed so a log search finds every one. */
12
+ export declare const UNRECORDED_OUTCOME_LOG = "audit-outcome-unrecorded";
13
+ /** Where an unwritten outcome is reported: the host's error log (the kernel has none of its own). */
14
+ export type AuditLogError = (message: string, fields: Record<string, unknown>) => void;
15
+ /**
16
+ * Write one outcome row of an audited change (#2064, #2089 for the kill switches), never
17
+ * swallowing its failure. Answers null when the row landed. When it did not, the failure is
18
+ * logged as `UNRECORDED_OUTCOME_LOG` with the flow, the operation id and the phase, and its
19
+ * message is the answer, for the caller to surface: a `refused`/`failed` caller still answers
20
+ * with its own error (so a refusal never reads as retryable), and an `applied` caller answers
21
+ * success with `auditWarningOf`. The intent left without an outcome is closed as `unknown` by
22
+ * the control plane's scheduled settle either way.
23
+ */
24
+ export declare function recordAuditOutcome(write: () => unknown, line: {
25
+ flow: string;
26
+ operationId: string;
27
+ phase: string;
28
+ }, logError: AuditLogError): Promise<string | null>;
29
+ /** The `auditWarning` a change that went through answers when its `applied` row could not be written. */
30
+ export declare const auditWarningOf: (what: string, unrecorded: string) => string;
31
+ /** The intent a settle reads by id, inside its transaction. */
32
+ export declare const SETTLE_INTENT_SQL = "SELECT id, action, tenant_id, scope_id, vertical, after FROM _substrat_admin_log WHERE id = ?";
33
+ /**
34
+ * Both statements below write `+action`, so the action column cannot drive an index choice: an
35
+ * operation's few rows are reached through `_substrat_admin_log_operation` (the kernel's
36
+ * admin-log index list), never by walking every row of an action. A planner left to choose takes
37
+ * `(action, id)`, which reads the whole history of the action.
38
+ */
39
+ /**
40
+ * Whether the operation already has an outcome: a non-intent row of the SAME operation, its whole
41
+ * identity compared column by column. The operation id reaches `_substrat_admin_log_operation`.
42
+ * The action, tenant and scope are compared with `IS`, so a null tenant or scope matches only
43
+ * null and never acts as a wildcard, and written `+column` so that the operation id is the only
44
+ * index the statement can use: left to choose, the planner took `(action, id)` once, and
45
+ * `(tenant_id, id)` or `(scope_id, id)` would read as much. No
46
+ * value is serialized to compare, so nothing depends on two encoders agreeing. Never by row
47
+ * order: the intent, a real outcome and a settle's `unknown` are stamped by different writers
48
+ * whose ids and clocks need not agree.
49
+ */
50
+ export declare const SETTLE_OUTCOME_SQL = "SELECT 1 AS present FROM _substrat_admin_log\n WHERE json_extract(after, '$.operationId') = ?\n AND json_extract(after, '$.operationId') IS NOT NULL\n AND +action IS ?\n AND +tenant_id IS ?\n AND +scope_id IS ?\n AND json_extract(after, '$.phase') <> 'intent'\n LIMIT 1";
51
+ /** `SETTLE_OUTCOME_SQL`'s parameters for one operation, every part of its identity in order. */
52
+ export declare const settleOutcomeParamsOf: (operation: AuditedOperationRef) => [string, string, string | null, string | null];
53
+ /** How many operation ids one batched read binds: well under a Durable Object's 100 parameters. */
54
+ export declare const AUDITED_OPERATIONS_BATCH = 50;
55
+ /**
56
+ * Every row of the given operations, by the operation-id index. One statement per batch of
57
+ * `AUDITED_OPERATIONS_BATCH` ids. The caller narrows the rows to the action, tenant and scope it
58
+ * asked about.
59
+ */
60
+ export declare function auditedOperationsSql(count: number): string;
61
+ /** One row as `auditedOperationsSql` reads it. */
62
+ export interface AuditedOperationSqlRow {
63
+ id: string;
64
+ action: string;
65
+ tenant_id: string | null;
66
+ scope_id: string | null;
67
+ operation_id: string;
68
+ phase: string | null;
69
+ }
70
+ /** One row of an audited operation, as `HostAdmin.auditedOperations` answers it. */
71
+ export interface AuditedOperationRow {
72
+ id: string;
73
+ action: string;
74
+ tenantId: string | null;
75
+ scopeId: string | null;
76
+ operationId: string;
77
+ phase: string | null;
78
+ }
79
+ /** The operations a reader asks about: an operation is its action, its id and its scope. */
80
+ export interface AuditedOperationRef {
81
+ action: string;
82
+ operationId: string;
83
+ tenantId: string | null;
84
+ scopeId: string | null;
85
+ }
86
+ /**
87
+ * Run `auditedOperationsSql` over `refs` in batches through `all`, and keep only the rows of
88
+ * the exact operations asked about. An operation id from another action or scope is not one.
89
+ */
90
+ export declare function readAuditedOperations(all: (sql: string, params: string[]) => AuditedOperationSqlRow[], refs: readonly AuditedOperationRef[]): AuditedOperationRow[];
91
+ /**
92
+ * An audited operation's identity: its action, its operation id AND the tenant and scope it was
93
+ * made in. The one key every grouping, lookup and resolution uses, built only here. An id alone
94
+ * is not an operation: the same id in two scopes is two operations, never a conflict.
95
+ */
96
+ export type OperationKey = string & {
97
+ readonly __operationKey: unique symbol;
98
+ };
99
+ export declare const operationKeyOf: (r: AuditedOperationRef) => OperationKey;
100
+ /** One row as `SETTLE_INTENT_SQL` reads it. */
101
+ export interface SettleIntentRow {
102
+ id: string;
103
+ action: string;
104
+ tenant_id: string | null;
105
+ scope_id: string | null;
106
+ vertical: string | null;
107
+ after: string | null;
108
+ }
109
+ /** What a settle writes: the admin row's target and payload, and the ops-failure row. */
110
+ export interface UnknownOutcome {
111
+ action: AuditedChangeAction;
112
+ operationId: string;
113
+ /** The operation the intent belongs to, the settle check's whole key. */
114
+ operation: AuditedOperationRef;
115
+ target: {
116
+ tenantId: string | null;
117
+ scopeId: string | null;
118
+ vertical: string | null;
119
+ };
120
+ after: Record<string, unknown>;
121
+ failure: Omit<OpsFailureInput, 'actor'>;
122
+ }
123
+ /**
124
+ * The `unknown` outcome for one intent row: the intent's own fields with `phase: 'unknown'` and
125
+ * `error` saying why, parsed by the same schema the flow writes its rows with. Throws `not_found`
126
+ * when the row is absent, or is not the intent of an audited change.
127
+ */
128
+ export declare function unknownOutcomeOf(row: SettleIntentRow | undefined, intentId: string, error: string): UnknownOutcome;
129
+ /** The phases an audited change's rows carry. */
130
+ export type AuditedPhase = 'intent' | 'applied' | 'refused' | 'failed' | 'unknown';
131
+ /** Where an operation stands, by priority over its rows (see the module header). */
132
+ export interface EffectiveOutcome {
133
+ /** `conflicting`: more than one real outcome row, which the audit must never hold. */
134
+ outcome: 'applied' | 'refused' | 'failed' | 'unknown' | 'conflicting';
135
+ /** The real outcome phases found, in no particular order: one, or several when conflicting. */
136
+ real: string[];
137
+ }
138
+ /**
139
+ * Each audited operation's effective outcome among `rows`, keyed by `operationKeyOf`. A real
140
+ * outcome beats `unknown` regardless of which was written first. Two or more real outcome rows
141
+ * are `conflicting`. An operation with only an intent has no entry, so it is pending. Row ids
142
+ * and timestamps decide nothing.
143
+ */
144
+ export declare function effectiveOutcomes(rows: readonly (AuditedOperationRef & {
145
+ phase: string | null;
146
+ })[]): Map<OperationKey, EffectiveOutcome>;
147
+ /** Whether a row is an outcome its operation's effective outcome replaced: an `unknown` beaten by a real one. */
148
+ export declare function isSupersededOutcome(phase: string | null, effective: EffectiveOutcome | undefined): boolean;
149
+ //# sourceMappingURL=audit-outcome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-outcome.d.ts","sourceRoot":"","sources":["../src/audit-outcome.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,233 @@
1
+ /**
2
+ * Closing an audited change whose outcome was never written (#2064), shared by both adapters.
3
+ *
4
+ * The owner hand-over (#1665) and dashboard member management (#1150) audit a change made in the
5
+ * vertical's own deployment in two rows paired by `operationId`: an `intent`, then `applied`,
6
+ * `refused` or `failed`. The schedule and peer kill switches (#1666, #1706; #2089) audit the
7
+ * scope's move the same way, from inside each adapter, and so does the replay lever
8
+ * (`moveImportCursor`, #2114), whose rows carry its `replayId` as their `operationId`. The two
9
+ * stores are separate, so an intent can be left with no outcome: its outcome write failed (`recordAuditOutcome` logs it), or the
10
+ * request died between the two. The control plane's scheduled
11
+ * pass finds such an intent and asks the host to settle it through
12
+ * `HostAdmin.settleUnrecordedOutcome`.
13
+ *
14
+ * **The settle is one transaction, and it claims the outcome only if none exists.** It reads
15
+ * the intent by id, checks there is no outcome row for the operation, then writes the `unknown`
16
+ * row and the ops-failure row that brings it to the staff digest. Two passes that race settle
17
+ * once. An outcome that lands before the settle runs wins, and the settle writes nothing.
18
+ * Because the ops-failure row is written in the same unit, an `unknown` row cannot exist without
19
+ * the digest hearing of it.
20
+ *
21
+ * **A real outcome supersedes `unknown`, by priority, not by order.** The log is append-only, so
22
+ * a real outcome that lands after the settle is still recorded. Every reader resolves an
23
+ * operation by `effectiveOutcomes`: a real outcome (`applied`, `refused`, `failed`) beats
24
+ * `unknown` whichever row was written first, since the two writers' ids and clocks need not
25
+ * agree. Two real outcomes for one operation break the audit's invariant, so they resolve to
26
+ * `conflicting`, which is reported and never guessed past. The control plane bounds the vertical call well inside the
27
+ * settle's grace window, so a live request cannot normally be overtaken this way. The rule is
28
+ * stated for the case where one is.
29
+ */
30
+ import { AUDIT_ERROR_MAX, auditOperationId, memberChangeAudit, ownerTransferAudit, peerBindingAudit, substratError } from '@substrat-run/contracts';
31
+ import { SWITCH_ACTIONS } from './system-switch-record.js';
32
+ /**
33
+ * The admin actions written intent-then-outcome, which a settle closes: the two the control plane
34
+ * writes around a vertical call, (#2089) the schedule and peer kill switches, which each adapter
35
+ * writes around the scope's move, and (#2114) the replay lever, written the same way around the
36
+ * watermark's move. A lever row written before #2114 carries only `replayId`, no `operationId`,
37
+ * so every reader passes it over as it passes over any row without one.
38
+ */
39
+ export const AUDITED_CHANGE_ACTIONS = [
40
+ 'transferOwner',
41
+ 'manageScopeMember',
42
+ 'setPeerBinding',
43
+ ...SWITCH_ACTIONS,
44
+ 'moveImportCursor',
45
+ ];
46
+ /** The structured line an outcome row that could not be written leaves, keyed so a log search finds every one. */
47
+ export const UNRECORDED_OUTCOME_LOG = 'audit-outcome-unrecorded';
48
+ /**
49
+ * Write one outcome row of an audited change (#2064, #2089 for the kill switches), never
50
+ * swallowing its failure. Answers null when the row landed. When it did not, the failure is
51
+ * logged as `UNRECORDED_OUTCOME_LOG` with the flow, the operation id and the phase, and its
52
+ * message is the answer, for the caller to surface: a `refused`/`failed` caller still answers
53
+ * with its own error (so a refusal never reads as retryable), and an `applied` caller answers
54
+ * success with `auditWarningOf`. The intent left without an outcome is closed as `unknown` by
55
+ * the control plane's scheduled settle either way.
56
+ */
57
+ export async function recordAuditOutcome(write, line, logError) {
58
+ try {
59
+ await write();
60
+ return null;
61
+ }
62
+ catch (auditError) {
63
+ const message = auditError instanceof Error ? auditError.message : String(auditError);
64
+ try {
65
+ logError(UNRECORDED_OUTCOME_LOG, { ...line, auditError: message });
66
+ }
67
+ catch {
68
+ // Reporting an unwritten row must not replace the operation’s own error or warning.
69
+ }
70
+ return message;
71
+ }
72
+ }
73
+ /** The `auditWarning` a change that went through answers when its `applied` row could not be written. */
74
+ export const auditWarningOf = (what, unrecorded) => `${what} completed, but its outcome could not be written to the admin log: ${unrecorded}`;
75
+ /** The intent a settle reads by id, inside its transaction. */
76
+ export const SETTLE_INTENT_SQL = 'SELECT id, action, tenant_id, scope_id, vertical, after FROM _substrat_admin_log WHERE id = ?';
77
+ /**
78
+ * Both statements below write `+action`, so the action column cannot drive an index choice: an
79
+ * operation's few rows are reached through `_substrat_admin_log_operation` (the kernel's
80
+ * admin-log index list), never by walking every row of an action. A planner left to choose takes
81
+ * `(action, id)`, which reads the whole history of the action.
82
+ */
83
+ /**
84
+ * Whether the operation already has an outcome: a non-intent row of the SAME operation, its whole
85
+ * identity compared column by column. The operation id reaches `_substrat_admin_log_operation`.
86
+ * The action, tenant and scope are compared with `IS`, so a null tenant or scope matches only
87
+ * null and never acts as a wildcard, and written `+column` so that the operation id is the only
88
+ * index the statement can use: left to choose, the planner took `(action, id)` once, and
89
+ * `(tenant_id, id)` or `(scope_id, id)` would read as much. No
90
+ * value is serialized to compare, so nothing depends on two encoders agreeing. Never by row
91
+ * order: the intent, a real outcome and a settle's `unknown` are stamped by different writers
92
+ * whose ids and clocks need not agree.
93
+ */
94
+ export const SETTLE_OUTCOME_SQL = `SELECT 1 AS present FROM _substrat_admin_log
95
+ WHERE json_extract(after, '$.operationId') = ?
96
+ AND json_extract(after, '$.operationId') IS NOT NULL
97
+ AND +action IS ?
98
+ AND +tenant_id IS ?
99
+ AND +scope_id IS ?
100
+ AND json_extract(after, '$.phase') <> 'intent'
101
+ LIMIT 1`;
102
+ /** `SETTLE_OUTCOME_SQL`'s parameters for one operation, every part of its identity in order. */
103
+ export const settleOutcomeParamsOf = (operation) => [
104
+ operation.operationId,
105
+ operation.action,
106
+ operation.tenantId,
107
+ operation.scopeId,
108
+ ];
109
+ /** How many operation ids one batched read binds: well under a Durable Object's 100 parameters. */
110
+ export const AUDITED_OPERATIONS_BATCH = 50;
111
+ /**
112
+ * Every row of the given operations, by the operation-id index. One statement per batch of
113
+ * `AUDITED_OPERATIONS_BATCH` ids. The caller narrows the rows to the action, tenant and scope it
114
+ * asked about.
115
+ */
116
+ export function auditedOperationsSql(count) {
117
+ return `SELECT id, action, tenant_id, scope_id,
118
+ json_extract(after, '$.operationId') AS operation_id, json_extract(after, '$.phase') AS phase
119
+ FROM _substrat_admin_log
120
+ WHERE json_extract(after, '$.operationId') IN (${Array.from({ length: count }, () => '?').join(', ')})
121
+ AND json_extract(after, '$.operationId') IS NOT NULL
122
+ AND +action IN (${AUDITED_CHANGE_ACTIONS.map((a) => `'${a}'`).join(', ')})`;
123
+ }
124
+ /**
125
+ * Run `auditedOperationsSql` over `refs` in batches through `all`, and keep only the rows of
126
+ * the exact operations asked about. An operation id from another action or scope is not one.
127
+ */
128
+ export function readAuditedOperations(all, refs) {
129
+ const wanted = new Set(refs.map(operationKeyOf));
130
+ const ids = [...new Set(refs.map((r) => r.operationId))];
131
+ const rows = [];
132
+ for (let i = 0; i < ids.length; i += AUDITED_OPERATIONS_BATCH) {
133
+ const batch = ids.slice(i, i + AUDITED_OPERATIONS_BATCH);
134
+ for (const r of all(auditedOperationsSql(batch.length), batch)) {
135
+ const row = { id: r.id, action: r.action, tenantId: r.tenant_id, scopeId: r.scope_id, operationId: r.operation_id, phase: r.phase };
136
+ if (wanted.has(operationKeyOf(row)))
137
+ rows.push(row);
138
+ }
139
+ }
140
+ return rows;
141
+ }
142
+ export const operationKeyOf = (r) => JSON.stringify([r.action, r.operationId, r.tenantId, r.scopeId]);
143
+ const isAudited = (action) => AUDITED_CHANGE_ACTIONS.includes(action);
144
+ const isSwitch = (action) => SWITCH_ACTIONS.includes(action);
145
+ /** The actions whose rows have no schema of their own, so an `unknown` row is the intent's fields. */
146
+ const copiesIntent = (action) => isSwitch(action) || action === 'moveImportCursor';
147
+ /**
148
+ * The `unknown` row of a kill switch's operation (#2089), or of the replay lever's (#2114): the
149
+ * intent's own fields (its subject, position and reason) with `phase: 'unknown'` and the error.
150
+ * Neither has a row schema of its own: each adapter writes the switch's rows from
151
+ * `switchAuditSubject` and the lever's from its move, and the history readers count only
152
+ * `applied` rows, so an `unknown` row moves no position.
153
+ */
154
+ const intentUnknownOf = (after, error) => ({
155
+ ...after,
156
+ phase: 'unknown',
157
+ error: error.slice(0, AUDIT_ERROR_MAX),
158
+ });
159
+ /**
160
+ * The `unknown` outcome for one intent row: the intent's own fields with `phase: 'unknown'` and
161
+ * `error` saying why, parsed by the same schema the flow writes its rows with. Throws `not_found`
162
+ * when the row is absent, or is not the intent of an audited change.
163
+ */
164
+ export function unknownOutcomeOf(row, intentId, error) {
165
+ const after = row?.after ? JSON.parse(row.after) : null;
166
+ if (!row || !isAudited(row.action) || after?.phase !== 'intent' || !auditOperationId.safeParse(after.operationId).success) {
167
+ throw substratError('not_found', `no audited-change intent ${intentId} to settle`);
168
+ }
169
+ const parsed = copiesIntent(row.action) ? intentUnknownOf(after, error) : auditedUnknownOf(row, after, error);
170
+ const operationId = after.operationId;
171
+ return {
172
+ action: row.action,
173
+ operationId,
174
+ operation: { action: row.action, operationId, tenantId: row.tenant_id, scopeId: row.scope_id },
175
+ target: { tenantId: row.tenant_id, scopeId: row.scope_id, vertical: row.vertical },
176
+ after: parsed,
177
+ failure: {
178
+ operation: `audit.${row.action}`,
179
+ stage: 'outcome-unknown',
180
+ tenantId: row.tenant_id,
181
+ scopeId: row.scope_id,
182
+ vertical: row.vertical,
183
+ // The operation id is the row's handle: the digest reads the admin log by it, to drop an
184
+ // `unknown` that a real outcome has since superseded.
185
+ reference: operationId,
186
+ message: `operation ${operationId}: ${error}`,
187
+ },
188
+ };
189
+ }
190
+ /** A control-plane flow's `unknown` row, parsed by the same schema the flow writes its rows with. */
191
+ function auditedUnknownOf(row, after, error) {
192
+ const entry = { ...after, tenantId: row.tenant_id, scopeId: row.scope_id, phase: 'unknown', error };
193
+ const { tenantId: _t, scopeId: _s, ...parsed } = row.action === 'transferOwner' ? ownerTransferAudit.parse(entry)
194
+ : row.action === 'manageScopeMember' ? memberChangeAudit.parse(entry)
195
+ : peerBindingAudit.parse(entry);
196
+ return parsed;
197
+ }
198
+ const REAL_OUTCOMES = new Set(['applied', 'refused', 'failed']);
199
+ /**
200
+ * Each audited operation's effective outcome among `rows`, keyed by `operationKeyOf`. A real
201
+ * outcome beats `unknown` regardless of which was written first. Two or more real outcome rows
202
+ * are `conflicting`. An operation with only an intent has no entry, so it is pending. Row ids
203
+ * and timestamps decide nothing.
204
+ */
205
+ export function effectiveOutcomes(rows) {
206
+ const seen = new Map();
207
+ for (const row of rows) {
208
+ if (!isAudited(row.action) || row.phase === null || row.phase === 'intent')
209
+ continue;
210
+ const key = operationKeyOf(row);
211
+ const entry = seen.get(key) ?? { real: [], unknown: false };
212
+ if (REAL_OUTCOMES.has(row.phase))
213
+ entry.real.push(row.phase);
214
+ else if (row.phase === 'unknown')
215
+ entry.unknown = true;
216
+ seen.set(key, entry);
217
+ }
218
+ const out = new Map();
219
+ for (const [key, { real, unknown }] of seen) {
220
+ if (real.length > 1)
221
+ out.set(key, { outcome: 'conflicting', real });
222
+ else if (real.length === 1)
223
+ out.set(key, { outcome: real[0], real });
224
+ else if (unknown)
225
+ out.set(key, { outcome: 'unknown', real });
226
+ }
227
+ return out;
228
+ }
229
+ /** Whether a row is an outcome its operation's effective outcome replaced: an `unknown` beaten by a real one. */
230
+ export function isSupersededOutcome(phase, effective) {
231
+ return phase === 'unknown' && effective !== undefined && effective.real.length > 0;
232
+ }
233
+ //# sourceMappingURL=audit-outcome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-outcome.js","sourceRoot":"","sources":["../src/audit-outcome.ts"],"names":[],"mappings":"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"}