@substrat-run/control-plane-api 0.160.0 → 0.161.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.
@@ -0,0 +1,339 @@
1
+ /**
2
+ * The fleet walk (RFC wire-signing follow-on 4): bring every deployed script's key lists, audience
3
+ * and state to what the control plane gives now, so that a key listed, rotated, dropped or withdrawn
4
+ * reaches every script, not only the ones an upload happens to reach. A vertical's serving script is
5
+ * uploaded again at each promote, but a version's own script (its archive script, which a preview is
6
+ * routed to) is uploaded once, at its push, and nothing else ever rewrites it.
7
+ *
8
+ * A person runs it, a pass at a time, and it reports before it changes anything:
9
+ *
10
+ * - **Dry run by default.** Without `apply` a pass only reads: the settings write is unreachable, no
11
+ * operational failure is filed and no hold is released.
12
+ * - **Bounded and resumable.** A pass walks at most `limit` scripts in a fixed order (verticals by
13
+ * slug; each one's serving script, then its versions' scripts by id) and answers the cursor the next
14
+ * pass starts from, `null` when the fleet is done. A vertical deleted since it was listed, or named by
15
+ * a saved cursor, is passed over.
16
+ * - **Only scripts it can attribute.** The inventory is the registry's: a vertical's serving script and
17
+ * each of its versions' scripts. A script the registry does not name is never touched, nor is one
18
+ * whose name is the platform's own.
19
+ * - **No call it does not need.** A script whose record already says it was given what the settings give
20
+ * now is not read. A script with no record, which the settings give nothing, is not read either: in an
21
+ * environment where the rollout was never set, a pass makes no call to the runtime at all. A
22
+ * **confirming** pass (`confirm`) reads every recorded script instead, trusting no record; a held
23
+ * script, and one with no record that nothing is given or that is skipped, it leaves unread as well.
24
+ * - **Only a script that verifies is given lists by it.** A script with no record is read back first, on
25
+ * every pass that reaches it (no verdict is kept between passes: pushing it again gives it a record);
26
+ * one that runs without the platform's entry is skipped (`no-entry`), never recorded as verifying.
27
+ * - **One script's failure is that script's.** It is reported, recorded as an operational failure by
28
+ * reason, and the pass goes on.
29
+ * - **A script it cannot vouch for is held.** When the read after an update differs, or the serve moved
30
+ * under it, the script's record is marked held, with the binding names that differed, and later passes
31
+ * leave it alone until a person names it in `release`, or an upload of it writes a fresh record.
32
+ *
33
+ * Each script it changes writes its capability record and that record's admin row in one directory
34
+ * transaction (`recordWireAuth`), and each pass writes one `walkWireAuth` row. The settings write is
35
+ * `wire-settings.ts`. Do not run the walk while a push or promote of the same vertical is in flight,
36
+ * and end with a confirming pass.
37
+ */
38
+ import { errorCodeOf, instant, LIST_PAGE_MAX, PLATFORM_SCRIPT_NAMES, storedDeployManifest, verticalSlug as verticalSlugSchema, WALK_HOLD_BINDINGS_MAX, } from '@substrat-run/contracts';
39
+ import { PLATFORM_ENTRY_MODULE } from './platform-entry.js';
40
+ import { applyWireSettings, CONCURRENT_RETRIES } from './wire-settings.js';
41
+ import { wireEntryOf, wireUploadGiven } from './wire-upload.js';
42
+ /** A pass walks this many scripts when it names no limit. */
43
+ export const WIRE_WALK_LIMIT_DEFAULT = 25;
44
+ /** A pass walks at most this many scripts. */
45
+ export const WIRE_WALK_LIMIT_MAX = 50;
46
+ /** A pass releases at most this many held scripts. */
47
+ export const WIRE_WALK_RELEASE_MAX = 50;
48
+ const PAGE = 50;
49
+ const GONE = Symbol('gone');
50
+ /** The cursor's position inside a vertical just after its serving script: nothing after the `|`. */
51
+ const AFTER_SERVING = '';
52
+ /**
53
+ * A cursor as a pass answers it, or `null` for one that is not one. Opaque to a caller. A slug never
54
+ * holds a `|`, so the first one ends it, and everything after it is the position.
55
+ */
56
+ export function parseWireWalkCursor(text) {
57
+ const at = text.indexOf('|');
58
+ if (at <= 0)
59
+ return null;
60
+ const vertical = text.slice(0, at);
61
+ if (!verticalSlugSchema.safeParse(vertical).success)
62
+ return null;
63
+ return { vertical, after: text.slice(at + 1) };
64
+ }
65
+ const cursorText = (vertical, after) => `${vertical}|${after}`;
66
+ /** The registry's scripts in walk order, from `from` on: each vertical's serving script, then its versions' scripts. */
67
+ async function* inventory(admin, actor, from) {
68
+ /** A directory read of one vertical, or `gone` when the vertical no longer exists (deleted since it was listed, or named by a saved cursor). */
69
+ const ofVertical = async (read) => {
70
+ try {
71
+ return await read();
72
+ }
73
+ catch (error) {
74
+ if (errorCodeOf(error) === 'not_found')
75
+ return GONE;
76
+ throw error;
77
+ }
78
+ };
79
+ async function* scriptsOf(vertical, after) {
80
+ const serving = await ofVertical(() => admin.verticalServing(actor, vertical));
81
+ if (serving === GONE)
82
+ return;
83
+ const servingRef = serving && !PLATFORM_SCRIPT_NAMES.has(serving.ref) ? serving.ref : null;
84
+ if (after === null && servingRef !== null) {
85
+ yield { vertical, deploymentRef: servingRef, versionId: serving.versionId, kind: 'serving', cursor: cursorText(vertical, AFTER_SERVING) };
86
+ }
87
+ let cursor = after !== null && after !== AFTER_SERVING ? after : undefined;
88
+ for (;;) {
89
+ const versions = await ofVertical(() => admin.listVersions(actor, vertical, { limit: PAGE, ...(cursor ? { cursor } : {}) }));
90
+ if (versions === GONE)
91
+ return;
92
+ for (const v of versions) {
93
+ const ref = v.deploymentRef;
94
+ if (ref === null || ref === servingRef || PLATFORM_SCRIPT_NAMES.has(ref))
95
+ continue;
96
+ yield { vertical, deploymentRef: ref, versionId: v.id, kind: 'version', cursor: cursorText(vertical, v.id) };
97
+ }
98
+ if (versions.length < PAGE)
99
+ return;
100
+ cursor = versions.at(-1).id;
101
+ }
102
+ }
103
+ let slugCursor;
104
+ if (from) {
105
+ yield* scriptsOf(from.vertical, from.after);
106
+ slugCursor = from.vertical;
107
+ }
108
+ for (;;) {
109
+ const verticals = await admin.listVerticals(actor, { limit: PAGE, ...(slugCursor ? { cursor: slugCursor } : {}) });
110
+ for (const v of verticals)
111
+ yield* scriptsOf(v.slug, null);
112
+ if (verticals.length < PAGE)
113
+ return;
114
+ slugCursor = verticals.at(-1).slug;
115
+ }
116
+ }
117
+ /** Whether a record already holds what a given record says, in what a script carries: the state, the audience and the key ids. */
118
+ function carriesAlready(stored, given) {
119
+ const same = (a, b) => a.length === b.length && a.every((x, i) => x === b[i]);
120
+ return (stored.state === given.state &&
121
+ stored.audience === given.audience &&
122
+ same(stored.routerKids, given.routerKids) &&
123
+ same(stored.platformKids, given.platformKids));
124
+ }
125
+ /** Run one pass. Never throws for one script's failure; throws only for a directory read that fails. */
126
+ export async function runWireWalk(deps, input) {
127
+ const { admin, actor, settings, api } = deps;
128
+ const now = deps.now ?? (() => new Date());
129
+ const release = new Set(input.apply ? input.release : []);
130
+ const recordsBy = async (vertical) => {
131
+ const held = new Map();
132
+ let cursor;
133
+ for (;;) {
134
+ const page = await admin.listWireAuth(actor, { reach: { fleet: true }, verticalSlug: vertical, limit: LIST_PAGE_MAX, ...(cursor ? { cursor } : {}) });
135
+ for (const r of page)
136
+ held.set(r.deploymentRef, r);
137
+ if (page.length < LIST_PAGE_MAX)
138
+ return held;
139
+ cursor = page.at(-1).deploymentRef;
140
+ }
141
+ };
142
+ const records = new Map();
143
+ const recordsOf = async (vertical) => {
144
+ let held = records.get(vertical);
145
+ if (held)
146
+ return held;
147
+ held = await recordsBy(vertical);
148
+ records.clear(); // one vertical at a time: the walk moves through them in order
149
+ records.set(vertical, held);
150
+ return held;
151
+ };
152
+ const record = (script, rec, versionId = script.versionId) => admin.recordWireAuth(actor, { deploymentRef: script.deploymentRef, verticalSlug: script.vertical, versionId, record: rec, recordedAt: now().toISOString() });
153
+ /**
154
+ * Whether the script carries the platform's entry, which holds the verifier, read back from the
155
+ * script itself: its modules must hold the entry module, and its own bundle must be one the entry
156
+ * wraps. `no-manifest` when it cannot be told; `no-entry` when the script runs without one.
157
+ */
158
+ const entryOf = async (script) => {
159
+ if (!deps.fetchModules || script.versionId === null)
160
+ return 'no-manifest';
161
+ const manifestJson = await admin.versionManifest(actor, script.vertical, script.versionId);
162
+ if (!manifestJson)
163
+ return 'no-manifest';
164
+ const manifest = storedDeployManifest.parse(JSON.parse(manifestJson));
165
+ const modules = await deps.fetchModules(script.deploymentRef);
166
+ if (!modules.some((m) => m.name === PLATFORM_ENTRY_MODULE))
167
+ return 'no-entry';
168
+ const entry = wireEntryOf({ entry: manifest.entry, modules });
169
+ return entry.envelope === null ? 'no-entry' : entry;
170
+ };
171
+ const walkOne = async (script) => {
172
+ const stored = (await recordsOf(script.vertical)).get(script.deploymentRef);
173
+ const wasHeld = stored?.record.walkHold !== undefined;
174
+ const base = { deploymentRef: script.deploymentRef, vertical: script.vertical, versionId: script.versionId, kind: script.kind };
175
+ if (wasHeld && !release.has(script.deploymentRef))
176
+ return { ...base, action: 'held' };
177
+ /** A failure: reported, and recorded as an operational failure when the pass applies (a dry run attempts nothing). */
178
+ const failed = (reason, message, extra = {}) => {
179
+ if (input.apply) {
180
+ deps.fail({ vertical: script.vertical, version: script.versionId, stage: reason, message: `the wire walk did not bring '${script.deploymentRef}' current: ${message}` });
181
+ }
182
+ return { ...base, action: 'failed', reason, ...extra };
183
+ };
184
+ /**
185
+ * Mark the script held: a script the walk wrote and could not confirm is never left without one.
186
+ * It holds the record as it stands now, read again (an upload's record written during the pass
187
+ * included, which the hold keeps and marks), or, with none, a record that claims no lists
188
+ * (`unverified`). It keeps the first `WALK_HOLD_BINDINGS_MAX` binding names and counts the rest.
189
+ * A write that fails is tried once more; answers whether the hold was written, and the failure the
190
+ * walk reports says so when it was not.
191
+ */
192
+ const hold = async (entry, reason, bindings) => {
193
+ const once = async () => {
194
+ const latest = (await recordsBy(script.vertical)).get(script.deploymentRef);
195
+ const known = latest
196
+ ? (({ walkHold: _previous, ...rest }) => rest)(latest.record)
197
+ : { ...entry, state: 'legacy-only', audience: null, routerKids: [], platformKids: [], withheld: 'unverified' };
198
+ const kept = bindings.slice(0, WALK_HOLD_BINDINGS_MAX);
199
+ const more = bindings.length - kept.length;
200
+ const walkHold = { reason, bindings: [...kept], ...(more > 0 ? { more } : {}), at: instant.parse(now().toISOString()) };
201
+ // Under the version the record it marks names: an upload's record keeps its upload's version.
202
+ await record(script, { ...known, walkHold }, latest ? latest.versionId : script.versionId);
203
+ };
204
+ for (let attempt = 0; attempt < 2; attempt++) {
205
+ try {
206
+ await once();
207
+ return true;
208
+ }
209
+ catch {
210
+ // Tried once more, then reported.
211
+ }
212
+ }
213
+ return false;
214
+ };
215
+ /** Binding names for a person to read: the first `WALK_HOLD_BINDINGS_MAX`, and how many more. */
216
+ const named = (bindings) => bindings.length > WALK_HOLD_BINDINGS_MAX
217
+ ? `${bindings.slice(0, WALK_HOLD_BINDINGS_MAX).join(', ')} and ${bindings.length - WALK_HOLD_BINDINGS_MAX} more`
218
+ : bindings.join(', ');
219
+ const holdNote = (held) => (held ? 'held until a person looks' : 'and the hold itself could not be written: look at it now');
220
+ try {
221
+ let entry = stored ? { envelope: stored.record.envelope, entrySkipped: stored.record.entrySkipped } : null;
222
+ if (!entry) {
223
+ // No record: an upload from before records existed, or one whose record was not written. The
224
+ // settings decide whether it needs reading at all; whether it carries the entry needs its bundle.
225
+ const probe = await wireUploadGiven(settings, { vertical: script.vertical, deploymentRef: script.deploymentRef, entry: { envelope: 1, entrySkipped: null } });
226
+ if (probe.bindings.length === 0)
227
+ return { ...base, action: 'unrecorded' };
228
+ const read = await entryOf(script);
229
+ if (read === 'no-manifest')
230
+ return failed('entry-unknown', 'no record, and no stored manifest to read its entry from: upload it again');
231
+ // It runs without the platform's entry, so nothing in it verifies: it is not given lists, nor
232
+ // recorded as verifying. Pushing it again wraps it.
233
+ if (read === 'no-entry')
234
+ return { ...base, action: 'skipped', reason: 'no-entry' };
235
+ entry = read;
236
+ }
237
+ const given = await wireUploadGiven(settings, { vertical: script.vertical, deploymentRef: script.deploymentRef, entry });
238
+ // Refused settings give nothing, and nothing is not a withdrawal to write: the route refuses such a
239
+ // pass before it starts, and a script never acts on one here either.
240
+ // The route refuses a pass under refused settings before it starts, so what is refused here is
241
+ // this script alone (its name is not one the lists can be given as an audience).
242
+ if (given.refusal !== null)
243
+ return failed('settings-refused', `the lists are refused for this script (${given.refusal}): nothing was written`);
244
+ if (!input.confirm && stored && !stored.record.walkHold && carriesAlready(stored.record, given.record))
245
+ return { ...base, action: 'current' };
246
+ let outcome;
247
+ try {
248
+ outcome = await applyWireSettings(api, script.deploymentRef, given.bindings.map((b) => ({ name: b.name, text: b.text })), {
249
+ apply: input.apply,
250
+ ...(script.kind === 'serving' && script.versionId !== null
251
+ ? {
252
+ servedVersion: script.versionId,
253
+ servedVersionAfter: async () => (await admin.verticalServing(actor, script.vertical))?.versionId ?? null,
254
+ }
255
+ : {}),
256
+ });
257
+ }
258
+ catch (error) {
259
+ // The settings API's own messages name the script and a status, never a value.
260
+ return failed('settings', error instanceof Error ? error.message : 'the settings call failed');
261
+ }
262
+ switch (outcome.outcome) {
263
+ case 'would-change':
264
+ return { ...base, action: 'would-change', changes: outcome.changes };
265
+ case 'unchanged':
266
+ case 'updated': {
267
+ if (input.apply) {
268
+ try {
269
+ await record(script, given.record);
270
+ }
271
+ catch {
272
+ return failed('record', 'its settings are current, but its record was not written');
273
+ }
274
+ }
275
+ return outcome.outcome === 'updated' ? { ...base, action: 'updated', changes: outcome.changes } : { ...base, action: 'unchanged' };
276
+ }
277
+ case 'concurrent-change':
278
+ return failed('concurrent-change', `its bindings changed between reads ${CONCURRENT_RETRIES} times; nothing was written`);
279
+ case 'serve-in-flight': {
280
+ if (!outcome.written)
281
+ return failed('serve-in-flight', 'it does not run the version the directory says it serves; nothing was written: promote again, then walk');
282
+ const held = await hold(entry, 'serve-in-flight', []);
283
+ return failed('serve-in-flight', `the served version moved while it was updated, ${holdNote(held)}; ${held ? 'promote again, then release it' : 'promote again'}`, held ? { held: true } : {});
284
+ }
285
+ case 'verify': {
286
+ const held = await hold(entry, 'verify', outcome.bindings);
287
+ return failed('verify', `after its update, these bindings read differently: ${named(outcome.bindings)}; ${holdNote(held)}`, {
288
+ bindings: outcome.bindings.slice(0, WALK_HOLD_BINDINGS_MAX),
289
+ ...(outcome.bindings.length > WALK_HOLD_BINDINGS_MAX ? { more: outcome.bindings.length - WALK_HOLD_BINDINGS_MAX } : {}),
290
+ ...(held ? { held: true } : {}),
291
+ });
292
+ }
293
+ }
294
+ }
295
+ catch {
296
+ // A read for this one script (its stored manifest, its modules) failed. Its text is not echoed:
297
+ // nothing here vouches that it carries no value.
298
+ return failed('entry-unknown', 'its stored manifest or its modules could not be read');
299
+ }
300
+ };
301
+ /**
302
+ * One script, and whether a person's release of it took: only a script that was held and came out
303
+ * current (its fresh record, with no hold, written) is `released`; one that failed again stays held.
304
+ */
305
+ const walkReleasing = async (script) => {
306
+ const result = await walkOne(script);
307
+ const wasHeld = (await recordsOf(script.vertical)).get(script.deploymentRef)?.record.walkHold !== undefined;
308
+ const current = result.action === 'updated' || result.action === 'unchanged';
309
+ return wasHeld && release.has(script.deploymentRef) && current ? { ...result, released: true } : result;
310
+ };
311
+ const scripts = input.sink ?? [];
312
+ let next = null;
313
+ const fleet = inventory(admin, actor, input.cursor);
314
+ try {
315
+ let step = await fleet.next();
316
+ while (!step.done) {
317
+ const script = step.value;
318
+ scripts.push(await walkReleasing(script));
319
+ if (scripts.length >= input.limit) {
320
+ // Looked one ahead, so the pass that ends on the fleet's last script answers `null`. A look
321
+ // that fails does not undo a pass that is done: the next one starts after its last script.
322
+ try {
323
+ step = await fleet.next();
324
+ next = step.done ? null : script.cursor;
325
+ }
326
+ catch {
327
+ next = script.cursor;
328
+ }
329
+ break;
330
+ }
331
+ step = await fleet.next();
332
+ }
333
+ }
334
+ finally {
335
+ await fleet.return(undefined).catch(() => undefined);
336
+ }
337
+ return { apply: input.apply, from: input.cursor ? cursorText(input.cursor.vertical, input.cursor.after) : null, next, scripts };
338
+ }
339
+ //# sourceMappingURL=wire-walk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire-walk.js","sourceRoot":"","sources":["../src/wire-walk.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@substrat-run/control-plane-api",
3
- "version": "0.160.0",
3
+ "version": "0.161.0",
4
4
  "description": "HTTP surface over HostAdmin — the audited control-plane transport (control-plane.md §4.5)",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {
@@ -27,10 +27,10 @@
27
27
  ],
28
28
  "dependencies": {
29
29
  "hono": "^4.13.13",
30
- "@substrat-run/contracts": "^0.160.0",
31
- "@substrat-run/control-plane-client": "^0.3.11",
32
- "@substrat-run/psl": "^0.2.5",
33
- "@substrat-run/kernel": "^0.160.0"
30
+ "@substrat-run/contracts": "^0.161.0",
31
+ "@substrat-run/control-plane-client": "^0.3.12",
32
+ "@substrat-run/kernel": "^0.161.0",
33
+ "@substrat-run/psl": "^0.2.5"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@hono/node-server": "^1.13.0",
@@ -43,10 +43,10 @@
43
43
  "tsx": "^4.19.0",
44
44
  "typescript": "^7.0.0",
45
45
  "vitest": "^5.0.5",
46
- "@substrat-run/adapter-sqlite": "^0.160.0",
47
- "@substrat-run/connector-fortnox": "^0.4.62",
48
- "@substrat-run/vertical-host": "^0.160.0",
49
- "@substrat-run/connector-planima": "^0.2.57"
46
+ "@substrat-run/adapter-sqlite": "^0.161.0",
47
+ "@substrat-run/connector-planima": "^0.2.58",
48
+ "@substrat-run/connector-fortnox": "^0.4.63",
49
+ "@substrat-run/vertical-host": "^0.161.0"
50
50
  },
51
51
  "publishConfig": {
52
52
  "access": "public"