@substrat-run/kernel 0.147.0 → 0.149.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 (108) hide show
  1. package/dist/attachment-sweep.d.ts +208 -0
  2. package/dist/attachment-sweep.d.ts.map +1 -0
  3. package/dist/attachment-sweep.js +318 -0
  4. package/dist/attachment-sweep.js.map +1 -0
  5. package/dist/audit-outcome.d.ts +1 -1
  6. package/dist/audit-outcome.d.ts.map +1 -1
  7. package/dist/audit-outcome.js +4 -2
  8. package/dist/audit-outcome.js.map +1 -1
  9. package/dist/export-break.d.ts +137 -0
  10. package/dist/export-break.d.ts.map +1 -0
  11. package/dist/export-break.js +219 -0
  12. package/dist/export-break.js.map +1 -0
  13. package/dist/index.d.ts +24 -10
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +16 -7
  16. package/dist/index.js.map +1 -1
  17. package/dist/install-receipts.d.ts +116 -0
  18. package/dist/install-receipts.d.ts.map +1 -0
  19. package/dist/install-receipts.js +162 -0
  20. package/dist/install-receipts.js.map +1 -0
  21. package/dist/invocation-line.d.ts +85 -0
  22. package/dist/invocation-line.d.ts.map +1 -1
  23. package/dist/invocation-line.js +43 -0
  24. package/dist/invocation-line.js.map +1 -1
  25. package/dist/map-bounded.d.ts +8 -0
  26. package/dist/map-bounded.d.ts.map +1 -0
  27. package/dist/map-bounded.js +16 -0
  28. package/dist/map-bounded.js.map +1 -0
  29. package/dist/migration-digest.d.ts +56 -0
  30. package/dist/migration-digest.d.ts.map +1 -1
  31. package/dist/migration-digest.js +92 -0
  32. package/dist/migration-digest.js.map +1 -1
  33. package/dist/migration-fence.d.ts +14 -0
  34. package/dist/migration-fence.d.ts.map +1 -0
  35. package/dist/migration-fence.js +515 -0
  36. package/dist/migration-fence.js.map +1 -0
  37. package/dist/migration-replay.d.ts +52 -0
  38. package/dist/migration-replay.d.ts.map +1 -0
  39. package/dist/migration-replay.js +140 -0
  40. package/dist/migration-replay.js.map +1 -0
  41. package/dist/module-migrations.d.ts +3 -3
  42. package/dist/module-migrations.js +3 -3
  43. package/dist/peer.d.ts +32 -2
  44. package/dist/peer.d.ts.map +1 -1
  45. package/dist/peer.js +100 -4
  46. package/dist/peer.js.map +1 -1
  47. package/dist/permission-eval.d.ts +8 -0
  48. package/dist/permission-eval.d.ts.map +1 -1
  49. package/dist/permission-eval.js +14 -0
  50. package/dist/permission-eval.js.map +1 -1
  51. package/dist/platform-sweep.d.ts +114 -361
  52. package/dist/platform-sweep.d.ts.map +1 -1
  53. package/dist/platform-sweep.js +134 -561
  54. package/dist/platform-sweep.js.map +1 -1
  55. package/dist/promote-review.d.ts +125 -0
  56. package/dist/promote-review.d.ts.map +1 -0
  57. package/dist/promote-review.js +181 -0
  58. package/dist/promote-review.js.map +1 -0
  59. package/dist/schedule-state.d.ts +91 -0
  60. package/dist/schedule-state.d.ts.map +1 -0
  61. package/dist/schedule-state.js +118 -0
  62. package/dist/schedule-state.js.map +1 -0
  63. package/dist/scope-copy-ledger.d.ts +29 -0
  64. package/dist/scope-copy-ledger.d.ts.map +1 -1
  65. package/dist/scope-copy-ledger.js +23 -0
  66. package/dist/scope-copy-ledger.js.map +1 -1
  67. package/dist/scope-copy.d.ts.map +1 -1
  68. package/dist/scope-copy.js +3 -2
  69. package/dist/scope-copy.js.map +1 -1
  70. package/dist/scope-host.d.ts +303 -11
  71. package/dist/scope-host.d.ts.map +1 -1
  72. package/dist/scope-host.js.map +1 -1
  73. package/dist/scope-identity.d.ts +68 -0
  74. package/dist/scope-identity.d.ts.map +1 -0
  75. package/dist/scope-identity.js +75 -0
  76. package/dist/scope-identity.js.map +1 -0
  77. package/dist/scope-store.d.ts +9 -6
  78. package/dist/scope-store.d.ts.map +1 -1
  79. package/dist/scope-store.js.map +1 -1
  80. package/dist/spine-restore.d.ts +2 -0
  81. package/dist/spine-restore.d.ts.map +1 -1
  82. package/dist/spine-restore.js +6 -1
  83. package/dist/spine-restore.js.map +1 -1
  84. package/dist/store-driver-releases.d.ts +306 -0
  85. package/dist/store-driver-releases.d.ts.map +1 -0
  86. package/dist/store-driver-releases.js +581 -0
  87. package/dist/store-driver-releases.js.map +1 -0
  88. package/dist/table-ownership.d.ts +5 -2
  89. package/dist/table-ownership.d.ts.map +1 -1
  90. package/dist/table-ownership.js +19 -10
  91. package/dist/table-ownership.js.map +1 -1
  92. package/dist/testing.d.ts +2 -0
  93. package/dist/testing.d.ts.map +1 -1
  94. package/dist/testing.js +2 -0
  95. package/dist/testing.js.map +1 -1
  96. package/dist/upload-link.d.ts +142 -0
  97. package/dist/upload-link.d.ts.map +1 -0
  98. package/dist/upload-link.js +441 -0
  99. package/dist/upload-link.js.map +1 -0
  100. package/dist/version-migrations.d.ts +63 -1
  101. package/dist/version-migrations.d.ts.map +1 -1
  102. package/dist/version-migrations.js +174 -8
  103. package/dist/version-migrations.js.map +1 -1
  104. package/dist/vertical-scope-stores.d.ts +43 -0
  105. package/dist/vertical-scope-stores.d.ts.map +1 -0
  106. package/dist/vertical-scope-stores.js +195 -0
  107. package/dist/vertical-scope-stores.js.map +1 -0
  108. package/package.json +2 -2
@@ -0,0 +1,181 @@
1
+ /**
2
+ * The promote review's binding (#2333), shared by both adapters and the control plane's
3
+ * migrations read.
4
+ *
5
+ * A promote review is computed from the version being promoted over the channel's CURRENT
6
+ * version. The acknowledgement a person gives after reading it used to be a bare flag, so a
7
+ * concurrent promote between showing the review and acknowledging it changed the base, and the
8
+ * person acknowledged a diff that was no longer the one applied. The review now hands out a
9
+ * binding — the base it was computed against, and a digest of the stored rows it was computed
10
+ * from — and the promote refuses unless both still hold.
11
+ *
12
+ * The digest is the server's, over the server's stored rows, on both ends: the migrations read
13
+ * computes it beside the diff it shows, and the promote recomputes it. What a client sends is
14
+ * only compared with it, never read as the diff (the same rule the push digests keep: nothing
15
+ * re-derives a review from a client's digest).
16
+ */
17
+ import { PROMOTE_REVIEW_REASONS, REBIND_REVIEW_REASONS, reviewLine, substratError, errorCodeOf, } from '@substrat-run/contracts';
18
+ /** A declaration record as sorted pairs, so key order never moves the digest. */
19
+ const pairs = (r) => Object.entries(r ?? {}).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
20
+ /**
21
+ * Exactly what a review shows, and nothing else: each side's id, its two pushed digests (the
22
+ * gate's own comparison) and its stored migrations with their declared moves and discards. A
23
+ * version's admission, origin, label or deployment are left out, so changing them never turns a
24
+ * current review stale.
25
+ */
26
+ const sideOf = (v) => v === null
27
+ ? null
28
+ : [
29
+ v.id,
30
+ v.permissionDigest,
31
+ v.migrationDigest,
32
+ v.migrations === null
33
+ ? null
34
+ : v.migrations.map((m) => [m.moduleId, m.version, m.sql, pairs(m.moves), pairs(m.discards)]),
35
+ ];
36
+ /** Lowercase hex SHA-256 of a value's JSON. */
37
+ async function digestOf(value) {
38
+ const hash = new Uint8Array(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(JSON.stringify(value))));
39
+ return Array.from(hash, (b) => b.toString(16).padStart(2, '0')).join('');
40
+ }
41
+ /** The digest of a review of `incoming` over `base` (null: nothing serves). Lowercase hex SHA-256. */
42
+ export async function promoteReviewDigest(base, incoming) {
43
+ return digestOf(['promote-review/1', sideOf(base), sideOf(incoming)]);
44
+ }
45
+ /**
46
+ * The digest of a rebind review (#2347): the target lineage's serving version over the version
47
+ * the scope is bound to (null: bound to none). Each side names its lineage too, since the two are
48
+ * different verticals. Its own tag, so a promote's binding is never accepted as a rebind's, nor
49
+ * the reverse: the two answer different questions over what can be the same two rows.
50
+ */
51
+ export async function rebindReviewDigest(base, target) {
52
+ return digestOf([
53
+ 'rebind-review/1',
54
+ base === null ? null : [base.vertical, sideOf(base.version)],
55
+ [target.vertical, sideOf(target.version)],
56
+ ]);
57
+ }
58
+ /**
59
+ * Where the unbound refusal sends a person, by what the release does rather than its number: the
60
+ * number is the release tooling's to assign, and a version named here before it is cut can name
61
+ * one that does not carry `--review`.
62
+ */
63
+ const PROMOTE_REVIEW_DOCS = 'https://substrat.net/guide/deploying#acknowledgement-answers-one-review';
64
+ /**
65
+ * The refusal for a promote that lost a race (#2333): the channel moved to another version after
66
+ * this promote's gates and review binding were judged against it. Its acknowledgements answered a
67
+ * diff that is no longer the one it would apply, so it is refused as stale whether bound or not.
68
+ */
69
+ export function promoteRaceRefusal(channel) {
70
+ return substratError('precondition_failed', `the promote review is stale: ${reviewLine(channel)} moved to another version while this promote was being ` +
71
+ 'judged. Read the review again and acknowledge what it shows now', { reason: PROMOTE_REVIEW_REASONS.stale });
72
+ }
73
+ /** Whether a throw is one of the refusals below, and which. */
74
+ export function promoteReviewRefusalOf(err) {
75
+ if (errorCodeOf(err) !== 'precondition_failed')
76
+ return null;
77
+ const reason = err.extensions?.reason;
78
+ return reason === PROMOTE_REVIEW_REASONS.stale ? 'stale' : reason === PROMOTE_REVIEW_REASONS.unbound ? 'unbound' : null;
79
+ }
80
+ /**
81
+ * The promote gate's binding check. `baseId` is what the channel points at now (null: nothing).
82
+ * `read` loads both sides' stored rows, and is only called when a binding was sent.
83
+ *
84
+ * - A binding is always checked, whatever it acknowledges: the base it names must be the
85
+ * channel's, and the digest must be the one the stored rows give now.
86
+ * - Without one, a `migrationChange` the gate is about to consume is refused: that is the
87
+ * acknowledgement that lets a migration — and any data loss it declares — reach live data.
88
+ * A permission-only acknowledgement without one is still honoured (an older client's).
89
+ *
90
+ * The refusals carry neither the current base's digest nor anything to retry with: a client
91
+ * that wants to proceed reads the review again, and reading is what shows its person the diff
92
+ * that would now apply.
93
+ */
94
+ export async function assertPromoteReviewCurrent(opts) {
95
+ const review = opts.ack.review;
96
+ if (review === undefined) {
97
+ if (opts.migrationsChange && opts.ack.migrationChange) {
98
+ throw substratError('precondition_failed', `acknowledging a migration change needs the review it answers: send acknowledge.review (the base and ` +
99
+ `digest the migrations read returned beside the diff that was shown). From the command line, upgrade ` +
100
+ `to a CLI release whose 'substrat promote' supports --review, and run it without --ack-migrations: it ` +
101
+ `prints the migrations and the --review token to acknowledge them with (${PROMOTE_REVIEW_DOCS})`, { reason: PROMOTE_REVIEW_REASONS.unbound });
102
+ }
103
+ return;
104
+ }
105
+ if (review.base !== opts.baseId) {
106
+ throw substratError('precondition_failed',
107
+ // The ids are a publisher's text (#2322): every control, format and bidi character made visible.
108
+ `the promote review is stale: it was read against ${review.base === null ? 'no serving version' : `version ${reviewLine(review.base)}`}, ` +
109
+ `and ${opts.channel} now points at ${opts.baseId === null ? 'none' : `version ${reviewLine(opts.baseId)}`}. ` +
110
+ 'Read the review again and acknowledge what it shows now', { reason: PROMOTE_REVIEW_REASONS.stale });
111
+ }
112
+ const { base, incoming } = await opts.read();
113
+ if ((await promoteReviewDigest(base, incoming)) !== review.digest) {
114
+ throw substratError('precondition_failed', 'the promote review is stale: the stored versions it was computed from no longer give the digest it was ' +
115
+ 'acknowledged with. Read the review again and acknowledge what it shows now', { reason: PROMOTE_REVIEW_REASONS.stale });
116
+ }
117
+ }
118
+ /** Where the unbound rebind refusal sends a person; by what the release does, as `PROMOTE_REVIEW_DOCS`. */
119
+ const REBIND_REVIEW_DOCS = 'https://substrat.net/guide/deploying#a-rebind-answers-one-review';
120
+ const rebindStale = (why) => substratError('precondition_failed', `the rebind review is stale: ${why}. Read the review again and acknowledge what it shows now`, {
121
+ reason: REBIND_REVIEW_REASONS.stale,
122
+ });
123
+ /**
124
+ * The refusal for a rebind that lost a race (#2347): the scope's bound version, or the target's
125
+ * serving version, moved after the rebind's gate and review binding were judged against them, so
126
+ * its acknowledgement answered a diff that is no longer the one it would apply.
127
+ */
128
+ export function rebindRaceRefusal(target) {
129
+ return rebindStale(`the scope's bound version or what ${reviewLine(target)} serves moved while this rebind was being judged`);
130
+ }
131
+ /** Whether a throw is one of the rebind review refusals, and which. */
132
+ export function rebindReviewRefusalOf(err) {
133
+ if (errorCodeOf(err) !== 'precondition_failed')
134
+ return null;
135
+ const reason = err.extensions?.reason;
136
+ return reason === REBIND_REVIEW_REASONS.stale ? 'stale' : reason === REBIND_REVIEW_REASONS.unbound ? 'unbound' : null;
137
+ }
138
+ /**
139
+ * The rebind gate's binding check (#2347), `assertPromoteReviewCurrent`'s rule for a scope
140
+ * moving onto another lineage. `baseId` is the version the scope is bound to now (null: none),
141
+ * `target` the lineage it moves onto. `read` loads both sides' stored rows, and is only called
142
+ * when a binding was sent.
143
+ *
144
+ * - A binding is always checked: its base must be the scope's bound version, and its digest the
145
+ * one the stored rows of both sides give now. The target's serving version is inside the
146
+ * digest, so a promote on either lineage since the review was read turns it stale.
147
+ * - Without one, an `ackMigrations` the gate is about to consume (the digests differ) is refused.
148
+ *
149
+ * Neither refusal hands back the current digest: the client reads the review again.
150
+ */
151
+ export async function assertRebindReviewCurrent(opts) {
152
+ const review = opts.review;
153
+ if (review === undefined) {
154
+ if (opts.migrationsChange && opts.ackMigrations) {
155
+ throw substratError('precondition_failed', `acknowledging the migrations of a rebind needs the review it answers: send acknowledge.review (the base and ` +
156
+ `digest the rebind-review read returned beside the diff that was shown). From the command line, upgrade ` +
157
+ `to a CLI release whose 'substrat scope rebind' supports --review, and run it without --ack-migrations: it ` +
158
+ `prints the migrations and the --review token to acknowledge them with (${REBIND_REVIEW_DOCS})`, { reason: REBIND_REVIEW_REASONS.unbound });
159
+ }
160
+ return;
161
+ }
162
+ if (review.base !== opts.baseId) {
163
+ throw rebindStale(
164
+ // The ids are a publisher's text (#2322): every control, format and bidi character made visible.
165
+ `it was read against ${review.base === null ? 'no bound version' : `version ${reviewLine(review.base)}`}, ` +
166
+ `and the scope is now bound to ${opts.baseId === null ? 'none' : `version ${reviewLine(opts.baseId)}`}`);
167
+ }
168
+ const { base, baseVertical, target } = await opts.read();
169
+ const digest = await rebindReviewDigest(base && baseVertical !== null ? { vertical: baseVertical, version: base } : null, { vertical: opts.target, version: target });
170
+ if (digest !== review.digest) {
171
+ throw rebindStale(`the stored versions it was computed from, the target's serving version among them, no longer give the ` +
172
+ 'digest it was acknowledged with');
173
+ }
174
+ }
175
+ /** The serving row a rebind was judged against, as a `verticals` WHERE. Params: `servesNowParams`. */
176
+ export const SERVES_NOW_CONDITION = 'slug = ? AND serving_ref IS ? AND serving_version_id IS ?';
177
+ /** Appended to a rebind's `UPDATE scopes … WHERE`, so the route and pointer move only onto what was judged. */
178
+ export const SERVES_NOW_PREDICATE = `
179
+ AND EXISTS (SELECT 1 FROM verticals WHERE ${SERVES_NOW_CONDITION})`;
180
+ export const servesNowParams = (e) => [e.vertical, e.ref, e.versionId];
181
+ //# sourceMappingURL=promote-review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promote-review.js","sourceRoot":"","sources":["../src/promote-review.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * The platform sweep's per-scope scheduling state (#383, #1288): the
3
+ * `_substrat_schedule_state` DDL both adapters build, its rebuild, and the report of
4
+ * the recurring-schedule phase. Split out of `platform-sweep.ts` (#1978) so an adapter
5
+ * and a restore read it without the fleet sweep.
6
+ */
7
+ /**
8
+ * Which family a `_substrat_schedule_state` row belongs to (#1288) — the two of
9
+ * `sweepRunKind`'s three names that a SCOPE can hold gating state for. (`connector`
10
+ * is the third and is deliberately absent: a connection is swept host-wide and its
11
+ * state lives nowhere in a scope.)
12
+ */
13
+ export type ScheduleStateKind = 'schedule' | 'freshness';
14
+ /**
15
+ * The platform sweep's per-scope gating state (#383), as both adapters build it.
16
+ *
17
+ * Shared rather than spelled twice because `lint:spine-ddl` can compare the copies
18
+ * only where they are DDL a `KERNEL_DDL` executes — and this table is also rebuilt
19
+ * by `SCHEDULE_STATE_REBUILD` below, on a store that predates the key. One
20
+ * definition is what keeps the rebuilt shape and the created shape the same shape;
21
+ * the gate then holds each adapter to including it.
22
+ */
23
+ export declare const SCHEDULE_STATE_DDL = "\n CREATE TABLE IF NOT EXISTS _substrat_schedule_state (\n -- #1288: WHICH of the two families this row belongs to, named with the same two\n -- words _substrat_sweep_runs already records its entries under:\n -- * 'schedule' -- keyed by the operation (module/verb). last_run_at and\n -- last_status are when that operation RAN here and how it ended.\n -- * 'freshness' -- keyed freshness:<eventType> (#1232). last_run_at and\n -- last_status are when the evaluator last RECORDED a verdict for that event\n -- type and what it was. Nothing ran; the row gates what the sweep records.\n kind TEXT NOT NULL,\n schedule_op TEXT NOT NULL,\n last_run_at TEXT,\n last_status TEXT,\n -- #1525: the invocation this row's last run happened in, or null. Null is a fact\n -- here, not a gap: a 'freshness' row never invokes anything (the evaluator only\n -- records a verdict), a 'schedule' row a pass SKIPPED carries no fresh call to\n -- attribute and keeps whatever it already held, and a row written before this\n -- column existed predates the possibility. Only a due schedule's own invoke\n -- mints one and writes it here, in the same call that stamps it onto whatever\n -- the operation emits \u2014 see runDueSchedules in each adapter.\n invocation_id TEXT,\n -- #2096: a purge horizon's lap in progress (entity-trash.ts, PurgeLap) -- where its\n -- next pass resumes in the bin, and how many purges failed earlier in the lap. Only a\n -- 'schedule' row of a purge schedule holds one, and only mid-lap: NULL is the start\n -- of a lap, which is also the honest reading of every row written before the column.\n purge_cursor TEXT,\n -- The key LEADS with kind, and that is the point of #1288 rather than a tidy-up.\n -- Until it did, the two families were told apart by the spelling of one column:\n -- a freshness key could never LOOK like an operation (an event type has passed\n -- contracts' eventType regex -- lowercase ns.verb, no colon, no slash), but the\n -- other direction was convention only, because scheduleSpec.operation is\n -- z.string().min(1). A module declaring a schedule literally named\n -- \"freshness:orders.placed\" shared the evaluator's row and nothing refused it:\n -- each write clobbered the other's verdict, and the sweep read back whichever\n -- ran last. With kind in the key those are two rows that cannot meet.\n PRIMARY KEY (kind, schedule_op)\n );\n";
24
+ /**
25
+ * The `kind` a pre-#1288 row belongs to, derived from its `schedule_op` — the backfill's one
26
+ * rule, shared by `SCHEDULE_STATE_REBUILD` below and by a restore of a dump taken before the
27
+ * column (`spineRowsInsert`, #1883), so the two cannot file the same row differently.
28
+ */
29
+ export declare const SCHEDULE_STATE_KIND_OF_OP = "CASE WHEN substr(schedule_op, 1, 10) = 'freshness:' THEN 'freshness' ELSE 'schedule' END";
30
+ /**
31
+ * `_substrat_schedule_state`, rebuilt with its #1288 key on a store created before
32
+ * it. Create-copy-drop-rename, because `kind` joins the PRIMARY KEY and SQLite
33
+ * cannot widen a key in place — the same shape the directory's `ensureIdentityKey`
34
+ * uses, and detected the same way (from `sqlite_master.sql`, which DO SQLite serves
35
+ * and `PRAGMA` does not, so both adapters migrate by one strategy).
36
+ *
37
+ * The new table is `SCHEDULE_STATE_DDL` under a temporary name, so the rebuilt shape
38
+ * cannot drift from the created one.
39
+ *
40
+ * The backfill derives `kind` from the `freshness:` prefix because that prefix IS how
41
+ * the two families were told apart until now: every row the evaluator ever wrote
42
+ * carries it, and no operation name in existence does. `substr(...) = 'freshness:'`
43
+ * rather than `LIKE`, which is case-insensitive over ASCII in SQLite and would file a
44
+ * schedule named `FRESHNESS:x` under the evaluator.
45
+ *
46
+ * Keys are copied VERBATIM, prefix included. What changes is which rows can coexist,
47
+ * not what any row says — so a deployment rolled back to code that looks a freshness
48
+ * key up under its old name still finds it.
49
+ *
50
+ * **Run these inside the adapter's transaction API**, which is what both callers do —
51
+ * `db.transaction` on the pure side, `ctx.storage.transactionSync` on the DO side.
52
+ * Un-wrapped, a stop between the CREATE and the DROP leaves the scratch table behind
53
+ * and the NEXT wake dies on `table _substrat_schedule_state_new already exists`, which
54
+ * is a scope that cannot open; a stop between the DROP and the RENAME is worse and
55
+ * quieter, because the next wake's `CREATE TABLE IF NOT EXISTS` puts an EMPTY table
56
+ * of the new shape in place, the detection below then reads it as already migrated,
57
+ * and every copied row stays orphaned in the scratch table. Atomically, neither state
58
+ * is reachable — which is why there is no recovery path here to go with them.
59
+ *
60
+ * The leading `DROP TABLE IF EXISTS` is belt to that braces, not the fix: it costs one
61
+ * statement and makes the rebuild idempotent against a scratch table left by anything
62
+ * below the transaction (a torn copy of the file). A restore cannot carry one in: since
63
+ * #1883 it refuses a spine table the kernel does not build.
64
+ *
65
+ * A restore never reaches this rebuild either: it builds the table from the current DDL and
66
+ * derives `kind` for a legacy dump's rows with `SCHEDULE_STATE_KIND_OF_OP`. This runs only
67
+ * for a store that already holds the old table when it wakes.
68
+ */
69
+ export declare const SCHEDULE_STATE_REBUILD: string;
70
+ /**
71
+ * Whether a store's `_substrat_schedule_state` already carries the #1288 key, read
72
+ * off the `sql` column of `sqlite_master`. `false` means the rebuild is due.
73
+ */
74
+ export declare function scheduleStateHasKind(tableSql: string): boolean;
75
+ /**
76
+ * What the recurring-schedule phase did in one pass (#383), summed across every
77
+ * module's live scopes. `null` on `PlatformSweepReport` means the phase was
78
+ * disabled or the host predates it — distinct from a report of all zeros, which is
79
+ * "ran, nothing was due."
80
+ */
81
+ export interface ScheduleSweepReport {
82
+ /** Scopes `runDueSchedules` ran on (had ≥1 declared schedule). */
83
+ scopes: number;
84
+ /** Due schedules whose operation ran successfully. */
85
+ fired: number;
86
+ /** Schedules skipped this pass — still inside their cadence window. */
87
+ skipped: number;
88
+ /** Due schedules whose operation failed — recorded, stepped over. */
89
+ failed: number;
90
+ }
91
+ //# sourceMappingURL=schedule-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule-state.d.ts","sourceRoot":"","sources":["../src/schedule-state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,WAAW,CAAC;AAEzD;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,48EAqC9B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,6FACsD,CAAC;AAE7F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,eAAO,MAAM,sBAAsB,QAclC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * The platform sweep's per-scope scheduling state (#383, #1288): the
3
+ * `_substrat_schedule_state` DDL both adapters build, its rebuild, and the report of
4
+ * the recurring-schedule phase. Split out of `platform-sweep.ts` (#1978) so an adapter
5
+ * and a restore read it without the fleet sweep.
6
+ */
7
+ /**
8
+ * The platform sweep's per-scope gating state (#383), as both adapters build it.
9
+ *
10
+ * Shared rather than spelled twice because `lint:spine-ddl` can compare the copies
11
+ * only where they are DDL a `KERNEL_DDL` executes — and this table is also rebuilt
12
+ * by `SCHEDULE_STATE_REBUILD` below, on a store that predates the key. One
13
+ * definition is what keeps the rebuilt shape and the created shape the same shape;
14
+ * the gate then holds each adapter to including it.
15
+ */
16
+ export const SCHEDULE_STATE_DDL = `
17
+ CREATE TABLE IF NOT EXISTS _substrat_schedule_state (
18
+ -- #1288: WHICH of the two families this row belongs to, named with the same two
19
+ -- words _substrat_sweep_runs already records its entries under:
20
+ -- * 'schedule' -- keyed by the operation (module/verb). last_run_at and
21
+ -- last_status are when that operation RAN here and how it ended.
22
+ -- * 'freshness' -- keyed freshness:<eventType> (#1232). last_run_at and
23
+ -- last_status are when the evaluator last RECORDED a verdict for that event
24
+ -- type and what it was. Nothing ran; the row gates what the sweep records.
25
+ kind TEXT NOT NULL,
26
+ schedule_op TEXT NOT NULL,
27
+ last_run_at TEXT,
28
+ last_status TEXT,
29
+ -- #1525: the invocation this row's last run happened in, or null. Null is a fact
30
+ -- here, not a gap: a 'freshness' row never invokes anything (the evaluator only
31
+ -- records a verdict), a 'schedule' row a pass SKIPPED carries no fresh call to
32
+ -- attribute and keeps whatever it already held, and a row written before this
33
+ -- column existed predates the possibility. Only a due schedule's own invoke
34
+ -- mints one and writes it here, in the same call that stamps it onto whatever
35
+ -- the operation emits — see runDueSchedules in each adapter.
36
+ invocation_id TEXT,
37
+ -- #2096: a purge horizon's lap in progress (entity-trash.ts, PurgeLap) -- where its
38
+ -- next pass resumes in the bin, and how many purges failed earlier in the lap. Only a
39
+ -- 'schedule' row of a purge schedule holds one, and only mid-lap: NULL is the start
40
+ -- of a lap, which is also the honest reading of every row written before the column.
41
+ purge_cursor TEXT,
42
+ -- The key LEADS with kind, and that is the point of #1288 rather than a tidy-up.
43
+ -- Until it did, the two families were told apart by the spelling of one column:
44
+ -- a freshness key could never LOOK like an operation (an event type has passed
45
+ -- contracts' eventType regex -- lowercase ns.verb, no colon, no slash), but the
46
+ -- other direction was convention only, because scheduleSpec.operation is
47
+ -- z.string().min(1). A module declaring a schedule literally named
48
+ -- "freshness:orders.placed" shared the evaluator's row and nothing refused it:
49
+ -- each write clobbered the other's verdict, and the sweep read back whichever
50
+ -- ran last. With kind in the key those are two rows that cannot meet.
51
+ PRIMARY KEY (kind, schedule_op)
52
+ );
53
+ `;
54
+ /**
55
+ * The `kind` a pre-#1288 row belongs to, derived from its `schedule_op` — the backfill's one
56
+ * rule, shared by `SCHEDULE_STATE_REBUILD` below and by a restore of a dump taken before the
57
+ * column (`spineRowsInsert`, #1883), so the two cannot file the same row differently.
58
+ */
59
+ export const SCHEDULE_STATE_KIND_OF_OP = "CASE WHEN substr(schedule_op, 1, 10) = 'freshness:' THEN 'freshness' ELSE 'schedule' END";
60
+ /**
61
+ * `_substrat_schedule_state`, rebuilt with its #1288 key on a store created before
62
+ * it. Create-copy-drop-rename, because `kind` joins the PRIMARY KEY and SQLite
63
+ * cannot widen a key in place — the same shape the directory's `ensureIdentityKey`
64
+ * uses, and detected the same way (from `sqlite_master.sql`, which DO SQLite serves
65
+ * and `PRAGMA` does not, so both adapters migrate by one strategy).
66
+ *
67
+ * The new table is `SCHEDULE_STATE_DDL` under a temporary name, so the rebuilt shape
68
+ * cannot drift from the created one.
69
+ *
70
+ * The backfill derives `kind` from the `freshness:` prefix because that prefix IS how
71
+ * the two families were told apart until now: every row the evaluator ever wrote
72
+ * carries it, and no operation name in existence does. `substr(...) = 'freshness:'`
73
+ * rather than `LIKE`, which is case-insensitive over ASCII in SQLite and would file a
74
+ * schedule named `FRESHNESS:x` under the evaluator.
75
+ *
76
+ * Keys are copied VERBATIM, prefix included. What changes is which rows can coexist,
77
+ * not what any row says — so a deployment rolled back to code that looks a freshness
78
+ * key up under its old name still finds it.
79
+ *
80
+ * **Run these inside the adapter's transaction API**, which is what both callers do —
81
+ * `db.transaction` on the pure side, `ctx.storage.transactionSync` on the DO side.
82
+ * Un-wrapped, a stop between the CREATE and the DROP leaves the scratch table behind
83
+ * and the NEXT wake dies on `table _substrat_schedule_state_new already exists`, which
84
+ * is a scope that cannot open; a stop between the DROP and the RENAME is worse and
85
+ * quieter, because the next wake's `CREATE TABLE IF NOT EXISTS` puts an EMPTY table
86
+ * of the new shape in place, the detection below then reads it as already migrated,
87
+ * and every copied row stays orphaned in the scratch table. Atomically, neither state
88
+ * is reachable — which is why there is no recovery path here to go with them.
89
+ *
90
+ * The leading `DROP TABLE IF EXISTS` is belt to that braces, not the fix: it costs one
91
+ * statement and makes the rebuild idempotent against a scratch table left by anything
92
+ * below the transaction (a torn copy of the file). A restore cannot carry one in: since
93
+ * #1883 it refuses a spine table the kernel does not build.
94
+ *
95
+ * A restore never reaches this rebuild either: it builds the table from the current DDL and
96
+ * derives `kind` for a legacy dump's rows with `SCHEDULE_STATE_KIND_OF_OP`. This runs only
97
+ * for a store that already holds the old table when it wakes.
98
+ */
99
+ export const SCHEDULE_STATE_REBUILD = `
100
+ DROP TABLE IF EXISTS _substrat_schedule_state_new;
101
+ ${SCHEDULE_STATE_DDL.replace('CREATE TABLE IF NOT EXISTS _substrat_schedule_state', 'CREATE TABLE _substrat_schedule_state_new')}
102
+ -- #1525: invocation_id is not in this column list, deliberately — this rebuild runs
103
+ -- only on a pre-#1288 table, which predates invocation_id too, so there is nothing
104
+ -- to copy. The new table's default (NULL) is the honest answer for every such row.
105
+ INSERT INTO _substrat_schedule_state_new (kind, schedule_op, last_run_at, last_status)
106
+ SELECT ${SCHEDULE_STATE_KIND_OF_OP}, schedule_op, last_run_at, last_status
107
+ FROM _substrat_schedule_state;
108
+ DROP TABLE _substrat_schedule_state;
109
+ ALTER TABLE _substrat_schedule_state_new RENAME TO _substrat_schedule_state;
110
+ `;
111
+ /**
112
+ * Whether a store's `_substrat_schedule_state` already carries the #1288 key, read
113
+ * off the `sql` column of `sqlite_master`. `false` means the rebuild is due.
114
+ */
115
+ export function scheduleStateHasKind(tableSql) {
116
+ return tableSql.includes('PRIMARY KEY (kind, schedule_op)');
117
+ }
118
+ //# sourceMappingURL=schedule-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule-state.js","sourceRoot":"","sources":["../src/schedule-state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCjC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GACpC,0FAA0F,CAAC;AAE7F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;;IAElC,kBAAkB,CAAC,OAAO,CAC1B,qDAAqD,EACrD,2CAA2C,CAC5C;;;;;aAKU,yBAAyB;;;;CAIrC,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAgB;IACnD,OAAO,QAAQ,CAAC,QAAQ,CAAC,iCAAiC,CAAC,CAAC;AAC9D,CAAC"}
@@ -76,6 +76,35 @@ export interface ErasureEpochStamp {
76
76
  erasureEpoch: number;
77
77
  path: 'orchestrated' | 'direct';
78
78
  }
79
+ /**
80
+ * What a subject erasure read before it erased anything, and requires to still hold when it
81
+ * destroys the key (#1722, #2285). A bind, a promote, a rollback or a serving re-upload that
82
+ * landed in between would run a version whose stores the erasure may not have reached (L19).
83
+ */
84
+ export interface SubjectErasureFence {
85
+ versionId: string | null;
86
+ servingRef: string | null;
87
+ epoch: number;
88
+ copyCount: number;
89
+ /**
90
+ * The vertical's serving pointer as the erasure read it, for a scope with a serving pin: the
91
+ * claim requires the vertical to hold exactly this pair, whether or not the scope was on it,
92
+ * so a pointer that moves onto (or off) the scope's script is seen. `null` is no pointer.
93
+ * Omitted, the pointer is not fenced: a scope with no pin does not run the pointer's version.
94
+ */
95
+ servingPointer?: {
96
+ ref: string;
97
+ versionId: string;
98
+ } | null;
99
+ }
100
+ /**
101
+ * The erasure claim (#1722, #2285): moves the erasure epoch, which every bind compares, only while
102
+ * the scope still holds what the erasure read. Taken on both arms, the orchestrated finalize and the
103
+ * direct shred, before the key goes. Params: `subjectErasureClaimParams`.
104
+ */
105
+ export declare const SUBJECT_ERASURE_CLAIM_SQL = "\n UPDATE scopes SET erasure_epoch = COALESCE(erasure_epoch, 0) + 1\n WHERE tenant_id = ? AND scope_id = ? AND vertical_version_id IS ?\n AND serving_ref IS ? AND COALESCE(erasure_epoch, 0) = ?\n AND NOT EXISTS (SELECT 1 FROM scope_script_copies AS copy\n WHERE copy.tenant_id = scopes.tenant_id AND copy.scope_id = scopes.scope_id\n AND copy.state = 'pending')\n AND (SELECT COUNT(*) FROM scope_script_copies AS copy\n WHERE copy.tenant_id = scopes.tenant_id AND copy.scope_id = scopes.scope_id) = ?\n AND (? = 0 OR EXISTS (SELECT 1 FROM verticals\n WHERE verticals.slug = scopes.vertical\n AND verticals.serving_ref IS ? AND verticals.serving_version_id IS ?))";
106
+ /** `SUBJECT_ERASURE_CLAIM_SQL`'s parameters, in order. */
107
+ export declare const subjectErasureClaimParams: (tenantId: string, scopeId: string, fence: SubjectErasureFence) => (string | number | null)[];
79
108
  /** `COPY_BACKFILL_SCOPE_SQL`'s row. */
80
109
  export interface CopyBackfillScopeRow {
81
110
  reap_claimed_at: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"scope-copy-ledger.d.ts","sourceRoot":"","sources":["../src/scope-copy-ledger.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElF;;;;;;;;;;;;;;;;;GAiBG;AAEH,8FAA8F;AAC9F,eAAO,MAAM,wBAAwB,4cAM0B,CAAC;AAEhE,eAAO,MAAM,kBAAkB,YAAa,yBAAyB,OAAO,MAAM,KAAG,MAAM,EACpD,CAAC;AAExC;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,kWAM2C,CAAC;AAE9E,eAAO,MAAM,qBAAqB,YACvB,yBAAyB,YAAY,MAAM,WAAW,MAAM,OAAO,MAAM,KACjF,CAAC,MAAM,GAAG,IAAI,CAAC,EAGjB,CAAC;AAEF,uGAAuG;AACvG,eAAO,MAAM,gBAAgB,oOAG4C,CAAC;AAE1E,iGAAiG;AACjG,eAAO,MAAM,cAAc,4NAG6C,CAAC;AAEzE,8FAA8F;AAC9F,eAAO,MAAM,gBAAgB,kBAAkB,CAAC;AAEhD;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,4bAK6E,CAAC;AAE5G,eAAO,MAAM,kBAAkB,aAAc,MAAM,WAAW,MAAM,aAAa,MAAM,KAAG,MAAM,EACnC,CAAC;AAE9D,sGAAsG;AACtG,MAAM,MAAM,uBAAuB,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;AAEtF;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,sgBAMJ,CAAC;AAErC;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,yHACoF,CAAC;AAEzH;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAAG,YAAY,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,cAAc,GAAG,QAAQ,CAAA;CAAE;AAE5F,uCAAuC;AACvC,MAAM,WAAW,oBAAoB;IAAG,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE;AAE/F,sGAAsG;AACtG,eAAO,MAAM,mBAAmB,UAAW,oBAAoB,GAAG,SAAS,KAAG,uBACA,CAAC;AAE/E;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAKD,gGAAgG;AAChG,eAAO,MAAM,gBAAgB,WACnB,MAAM,cAAc,MAAM,WAAW,MAAM,gBAAgB,MAAM,KACxE,gBAID,CAAC;AAEH,iFAAiF;AACjF,eAAO,MAAM,sBAAsB,UAAW,gBAAgB,OAAO,MAAM,KAAG,OAA2C,CAAC;AAE1H,6EAA6E;AAC7E,eAAO,MAAM,yBAAyB,iFAAiF,CAAC;AAExH,6CAA6C;AAC7C,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wFAAwF;AACxF,eAAO,MAAM,yBAAyB,6FACsD,CAAC;AAE7F,eAAO,MAAM,iBAAiB,MAAO,kBAAkB,KAAG,eAUxD,CAAC"}
1
+ {"version":3,"file":"scope-copy-ledger.d.ts","sourceRoot":"","sources":["../src/scope-copy-ledger.ts"],"names":[],"mappings":"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"}
@@ -95,6 +95,29 @@ export const COPY_BACKFILL_SUPERSEDE_SQL = `
95
95
  * audit rows landed in. Params: tenantId, scopeId.
96
96
  */
97
97
  export const COPY_BACKFILL_SCOPE_SQL = 'SELECT reap_claimed_at, COALESCE(erasure_epoch, 0) AS erasure_epoch FROM scopes WHERE tenant_id = ? AND scope_id = ?';
98
+ /**
99
+ * The erasure claim (#1722, #2285): moves the erasure epoch, which every bind compares, only while
100
+ * the scope still holds what the erasure read. Taken on both arms, the orchestrated finalize and the
101
+ * direct shred, before the key goes. Params: `subjectErasureClaimParams`.
102
+ */
103
+ export const SUBJECT_ERASURE_CLAIM_SQL = `
104
+ UPDATE scopes SET erasure_epoch = COALESCE(erasure_epoch, 0) + 1
105
+ WHERE tenant_id = ? AND scope_id = ? AND vertical_version_id IS ?
106
+ AND serving_ref IS ? AND COALESCE(erasure_epoch, 0) = ?
107
+ AND NOT EXISTS (SELECT 1 FROM scope_script_copies AS copy
108
+ WHERE copy.tenant_id = scopes.tenant_id AND copy.scope_id = scopes.scope_id
109
+ AND copy.state = 'pending')
110
+ AND (SELECT COUNT(*) FROM scope_script_copies AS copy
111
+ WHERE copy.tenant_id = scopes.tenant_id AND copy.scope_id = scopes.scope_id) = ?
112
+ AND (? = 0 OR EXISTS (SELECT 1 FROM verticals
113
+ WHERE verticals.slug = scopes.vertical
114
+ AND verticals.serving_ref IS ? AND verticals.serving_version_id IS ?))`;
115
+ /** `SUBJECT_ERASURE_CLAIM_SQL`'s parameters, in order. */
116
+ export const subjectErasureClaimParams = (tenantId, scopeId, fence) => [
117
+ tenantId, scopeId, fence.versionId, fence.servingRef, fence.epoch, fence.copyCount,
118
+ fence.servingPointer === undefined ? 0 : 1,
119
+ fence.servingPointer?.ref ?? null, fence.servingPointer?.versionId ?? null,
120
+ ];
98
121
  /** Read the outcome of a backfill insert that wrote nothing, from `COPY_BACKFILL_SCOPE_SQL`'s row. */
99
122
  export const copyBackfillRefusal = (scope) => !scope ? 'missing' : scope.reap_claimed_at !== null ? 'reaping' : 'ledgered';
100
123
  /** How far inside the lease a restore must commit: five minutes, or a quarter of a short lease. */
@@ -1 +1 @@
1
- {"version":3,"file":"scope-copy-ledger.js","sourceRoot":"","sources":["../src/scope-copy-ledger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scope-copy-ledger.js","sourceRoot":"","sources":["../src/scope-copy-ledger.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"scope-copy.d.ts","sourceRoot":"","sources":["../src/scope-copy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,UAAU,gBAAiB,MAAM,GAAG,SAAS,iBAAiB,MAAM,GAAG,SAAS,KAAG,OACpC,CAAC;AAK7D;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,EACtF,MAAM,EAAE,CAAC,EAAE,EACX,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,aAAa,EAAE,MAAM,GAAG,SAAS,GAChC,CAAC,EAAE,CAGL;AAcD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,eAAe,8cAW3B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,sBAAiB,MACqD,CAAC;AAE/F;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,SAAS,EACd,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,GAAG,EAAE,MAAM,GACV,IAAI,CAiDN;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAInE;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,QAEa,CAAC;AAE/C;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAIpE;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW,0FAA0F,CAAC"}
1
+ {"version":3,"file":"scope-copy.d.ts","sourceRoot":"","sources":["../src/scope-copy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,UAAU,gBAAiB,MAAM,GAAG,SAAS,iBAAiB,MAAM,GAAG,SAAS,KAAG,OACpC,CAAC;AAK7D;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,EACtF,MAAM,EAAE,CAAC,EAAE,EACX,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,aAAa,EAAE,MAAM,GAAG,SAAS,GAChC,CAAC,EAAE,CAGL;AAcD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,eAAe,8cAW3B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,sBAAiB,MACqD,CAAC;AAE/F;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,SAAS,EACd,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,GAAG,EAAE,MAAM,GACV,IAAI,CAiDN;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAInE;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,QAEa,CAAC;AAE/C;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAIpE;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW,0FAA0F,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { CAPABILITY_TABLE_NAMES } from './capability.js';
2
+ import { UPLOAD_LINK_TABLE_NAMES } from './upload-link.js';
2
3
  /**
3
4
  * What a dump leaves behind when it lands in a scope other than the one it was captured from
4
5
  * (#1686). One definition for both adapters' loaders, so the DO and the pure host agree.
@@ -33,8 +34,8 @@ import { CAPABILITY_TABLE_NAMES } from './capability.js';
33
34
  * consumer's position, so a copy's cursor acknowledges nothing at the source either.
34
35
  */
35
36
  export const isCopyLoad = (destScopeId, sourceScopeId) => destScopeId === undefined || sourceScopeId !== destScopeId;
36
- /** The capability tables, as `capabilitiesForLoad` matches a dump's (lowercased) names. */
37
- const CAPABILITY_TABLES = new Set(CAPABILITY_TABLE_NAMES);
37
+ /** The capability tables — and the upload-link table, a bearer link of the same kind — as `capabilitiesForLoad` matches a dump's (lowercased) names. */
38
+ const CAPABILITY_TABLES = new Set([...CAPABILITY_TABLE_NAMES, ...UPLOAD_LINK_TABLE_NAMES]);
38
39
  /**
39
40
  * A dump's tables as a load into `destScopeId` takes them: **capability rows never cross a scope
40
41
  * id.** A copy loads both capability tables empty, so a live link share opens the scope it was
@@ -1 +1 @@
1
- {"version":3,"file":"scope-copy.js","sourceRoot":"","sources":["../src/scope-copy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scope-copy.js","sourceRoot":"","sources":["../src/scope-copy.ts"],"names":[],"mappings":"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"}