@byollm/protocol 0.1.0-alpha.31 → 0.1.0-alpha.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/index.d.ts +116 -1
- package/dist/index.js +200 -88
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -855,6 +855,65 @@ function verifyRequest(input) {
|
|
|
855
855
|
return ok ? null : "bad-signature";
|
|
856
856
|
}
|
|
857
857
|
|
|
858
|
+
// src/succession.ts
|
|
859
|
+
import { z as z8 } from "zod";
|
|
860
|
+
var SUCCESSION_CONTEXT = "byollm/v1/site-succession";
|
|
861
|
+
var RETIREMENT_WINDOW_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
862
|
+
var MAX_SUCCESSION_CHAIN = 64;
|
|
863
|
+
var Succession = z8.object({
|
|
864
|
+
/**
|
|
865
|
+
* The predecessor's public identity — K1, in full.
|
|
866
|
+
*
|
|
867
|
+
* The whole identity rather than the key id, because a daemon meeting a
|
|
868
|
+
* chain it has not seen before has to *verify* each link, and a key id is
|
|
869
|
+
* a fingerprint: enough to compare, never enough to check a signature.
|
|
870
|
+
*/
|
|
871
|
+
identity: PublicIdentity,
|
|
872
|
+
/** K1's signature over the statement naming K1 and its successor. */
|
|
873
|
+
signature: z8.string().min(1)
|
|
874
|
+
}).strict();
|
|
875
|
+
function successionStatement(fromKeyId, toKeyId) {
|
|
876
|
+
return Buffer.from(`${SUCCESSION_CONTEXT}:${fromKeyId}:${toKeyId}`);
|
|
877
|
+
}
|
|
878
|
+
function signSuccession(previous, next) {
|
|
879
|
+
return {
|
|
880
|
+
identity: {
|
|
881
|
+
identity: previous.identityPublic,
|
|
882
|
+
encryption: previous.encryptionPublic,
|
|
883
|
+
encryptionSig: previous.encryptionSig
|
|
884
|
+
},
|
|
885
|
+
signature: signWith(
|
|
886
|
+
previous,
|
|
887
|
+
successionStatement(keyId(previous.identityPublic), keyId(next.identity))
|
|
888
|
+
)
|
|
889
|
+
};
|
|
890
|
+
}
|
|
891
|
+
function verifyLink(link, toKeyId) {
|
|
892
|
+
if (!verifyPublicIdentity(link.identity)) return false;
|
|
893
|
+
return verifyWith(
|
|
894
|
+
link.identity.identity,
|
|
895
|
+
successionStatement(keyId(link.identity.identity), toKeyId),
|
|
896
|
+
link.signature
|
|
897
|
+
);
|
|
898
|
+
}
|
|
899
|
+
function walkSuccession(input) {
|
|
900
|
+
const { current, chain, approved } = input;
|
|
901
|
+
if (chain.length === 0) return { path: [current], failure: "no-chain" };
|
|
902
|
+
if (chain.length > MAX_SUCCESSION_CHAIN)
|
|
903
|
+
return { path: [current], failure: "too-long" };
|
|
904
|
+
const steps = [...chain].reverse();
|
|
905
|
+
const path = [current];
|
|
906
|
+
let succeeding = current;
|
|
907
|
+
for (const link of steps) {
|
|
908
|
+
if (!verifyLink(link, succeeding)) return { path, failure: "broken-link" };
|
|
909
|
+
const previous = keyId(link.identity.identity);
|
|
910
|
+
path.unshift(previous);
|
|
911
|
+
if (approved(previous)) return { path, from: previous };
|
|
912
|
+
succeeding = previous;
|
|
913
|
+
}
|
|
914
|
+
return { path, failure: "unknown-origin" };
|
|
915
|
+
}
|
|
916
|
+
|
|
858
917
|
// src/musts.ts
|
|
859
918
|
function kindsOf(must2) {
|
|
860
919
|
return typeof must2.verifiedBy === "string" ? [must2.verifiedBy] : must2.verifiedBy;
|
|
@@ -918,8 +977,20 @@ var MUSTS = Object.freeze({
|
|
|
918
977
|
// upstream sends and which the fence above does not see. That was the
|
|
919
978
|
// bypass: the pin was deleted with the id, so the comparison had nothing
|
|
920
979
|
// to compare against and the substitution arrived as a stranger.
|
|
980
|
+
// **Not `conformance`, and that is a live gap rather than a judgement.**
|
|
981
|
+
// Amendment C's succession clause is a rule about two implementations
|
|
982
|
+
// agreeing, which is what a conformance check is for — but rotating a
|
|
983
|
+
// site's key is not something `ConformanceTarget` can express, and adding
|
|
984
|
+
// an optional hook that most targets omit would produce a check reporting
|
|
985
|
+
// success for a reason unrelated to the property it claims. That is this
|
|
986
|
+
// project's most-repeated bug, and it is not worth reintroducing for a
|
|
987
|
+
// stronger-sounding word in a table. The rotation path is verified by
|
|
988
|
+
// `site-rotation.test.ts` (both directions, against the shipped runner)
|
|
989
|
+
// and `relay/test/rotation.test.ts` (both planes, against the reference
|
|
990
|
+
// relay); the missing piece is a second *independent* implementation to
|
|
991
|
+
// check them against, and there is not one yet.
|
|
921
992
|
verifiedBy: ["construction", "adversarial"],
|
|
922
|
-
source: "byollm_009 \xA7B.2"
|
|
993
|
+
source: "byollm_009 \xA7B.2, Amendment C"
|
|
923
994
|
}),
|
|
924
995
|
KEYS_EXCHANGED_AT_CONSENT: must({
|
|
925
996
|
id: "KEYS_EXCHANGED_AT_CONSENT",
|
|
@@ -1257,7 +1328,7 @@ function mustsVerifiedBy(kind) {
|
|
|
1257
1328
|
}
|
|
1258
1329
|
|
|
1259
1330
|
// src/wire.ts
|
|
1260
|
-
import { z as
|
|
1331
|
+
import { z as z9 } from "zod";
|
|
1261
1332
|
var PROTOCOL_VERSION = "0";
|
|
1262
1333
|
var SUPPORTED_PROTOCOL_VERSIONS = Object.freeze([
|
|
1263
1334
|
PROTOCOL_VERSION
|
|
@@ -1300,22 +1371,22 @@ var ENDPOINTS = Object.freeze([
|
|
|
1300
1371
|
"result",
|
|
1301
1372
|
"release"
|
|
1302
1373
|
]);
|
|
1303
|
-
var Capability =
|
|
1374
|
+
var Capability = z9.object({
|
|
1304
1375
|
kind: JobKind,
|
|
1305
1376
|
backendId: BackendIdSchema,
|
|
1306
1377
|
backendClass: BackendClass,
|
|
1307
|
-
model:
|
|
1378
|
+
model: z9.string().min(1),
|
|
1308
1379
|
offerScope: OfferScope
|
|
1309
1380
|
}).strict();
|
|
1310
|
-
var CapabilityMatrix =
|
|
1311
|
-
var PairStartRequest =
|
|
1312
|
-
protocolVersion:
|
|
1313
|
-
action:
|
|
1314
|
-
daemon:
|
|
1315
|
-
version:
|
|
1381
|
+
var CapabilityMatrix = z9.array(Capability);
|
|
1382
|
+
var PairStartRequest = z9.object({
|
|
1383
|
+
protocolVersion: z9.literal(PROTOCOL_VERSION),
|
|
1384
|
+
action: z9.literal("start"),
|
|
1385
|
+
daemon: z9.object({
|
|
1386
|
+
version: z9.string().min(1),
|
|
1316
1387
|
/** Shown in the app's runner list so a user can tell their machines apart. */
|
|
1317
|
-
label:
|
|
1318
|
-
platform:
|
|
1388
|
+
label: z9.string().min(1).max(120),
|
|
1389
|
+
platform: z9.enum(["darwin", "linux", "win32"])
|
|
1319
1390
|
}),
|
|
1320
1391
|
/**
|
|
1321
1392
|
* This machine's public keys (byollm_009 §5).
|
|
@@ -1327,29 +1398,29 @@ var PairStartRequest = z8.object({
|
|
|
1327
1398
|
device: PublicIdentity,
|
|
1328
1399
|
capabilities: CapabilityMatrix
|
|
1329
1400
|
}).strict();
|
|
1330
|
-
var PairStartResponse =
|
|
1401
|
+
var PairStartResponse = z9.object({
|
|
1331
1402
|
/** Secret the daemon polls with. Never shown to the user. */
|
|
1332
|
-
deviceCode:
|
|
1403
|
+
deviceCode: z9.string().min(20),
|
|
1333
1404
|
/** Short code the user reads and confirms in the browser. */
|
|
1334
|
-
userCode:
|
|
1405
|
+
userCode: z9.string().min(4).max(16),
|
|
1335
1406
|
/** Where the user approves. Must be on the server's own origin. */
|
|
1336
|
-
verificationUrl:
|
|
1407
|
+
verificationUrl: z9.url(),
|
|
1337
1408
|
/** Epoch ms after which the code is dead ({@link MUSTS.PAIR_CODE_EXPIRES}). */
|
|
1338
|
-
expiresAt:
|
|
1409
|
+
expiresAt: z9.number().int().positive(),
|
|
1339
1410
|
/** How often the daemon may poll. */
|
|
1340
|
-
pollIntervalMs:
|
|
1411
|
+
pollIntervalMs: z9.number().int().min(500).max(6e4)
|
|
1341
1412
|
}).strict();
|
|
1342
|
-
var PairPollRequest =
|
|
1343
|
-
protocolVersion:
|
|
1344
|
-
action:
|
|
1345
|
-
deviceCode:
|
|
1413
|
+
var PairPollRequest = z9.object({
|
|
1414
|
+
protocolVersion: z9.literal(PROTOCOL_VERSION),
|
|
1415
|
+
action: z9.literal("poll"),
|
|
1416
|
+
deviceCode: z9.string().min(20)
|
|
1346
1417
|
}).strict();
|
|
1347
|
-
var PairPollResponse =
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
status:
|
|
1418
|
+
var PairPollResponse = z9.discriminatedUnion("status", [
|
|
1419
|
+
z9.object({ status: z9.literal("pending") }).strict(),
|
|
1420
|
+
z9.object({ status: z9.literal("denied") }).strict(),
|
|
1421
|
+
z9.object({ status: z9.literal("expired") }).strict(),
|
|
1422
|
+
z9.object({
|
|
1423
|
+
status: z9.literal("approved"),
|
|
1353
1424
|
// `runnerToken` is gone — cloud_008 §2.4, finding 37.
|
|
1354
1425
|
//
|
|
1355
1426
|
// It was minted here, hashed into `RunnerRecord.tokenHash`, written to
|
|
@@ -1366,11 +1437,11 @@ var PairPollResponse = z8.discriminatedUnion("status", [
|
|
|
1366
1437
|
// `REQUESTS_SIGNED_NOT_BEARER` was already the rule and was already
|
|
1367
1438
|
// enforced — every authenticated call is signed by the device's pinned
|
|
1368
1439
|
// identity key. This removes the thing the MUST is named after.
|
|
1369
|
-
runnerId:
|
|
1440
|
+
runnerId: z9.string().min(1),
|
|
1370
1441
|
/** The app's id for the approving user — this daemon's owner forever. */
|
|
1371
|
-
owner:
|
|
1442
|
+
owner: z9.string().min(1),
|
|
1372
1443
|
/** Display name for the trust UI, if the app offers one. */
|
|
1373
|
-
ownerLabel:
|
|
1444
|
+
ownerLabel: z9.string().optional(),
|
|
1374
1445
|
/**
|
|
1375
1446
|
* The sites this pairing covers, for the daemon to pin (byollm_009 §5),
|
|
1376
1447
|
* keyed by each site's identity key id — cloud_009 §5.
|
|
@@ -1389,34 +1460,34 @@ var PairPollResponse = z8.discriminatedUnion("status", [
|
|
|
1389
1460
|
* runner's lookup is a map read rather than a join across two
|
|
1390
1461
|
* namespaces.
|
|
1391
1462
|
*/
|
|
1392
|
-
sites:
|
|
1463
|
+
sites: z9.record(z9.string().min(1), PublicIdentity)
|
|
1393
1464
|
}).strict()
|
|
1394
1465
|
]);
|
|
1395
|
-
var PairRequest =
|
|
1466
|
+
var PairRequest = z9.discriminatedUnion("action", [
|
|
1396
1467
|
PairStartRequest,
|
|
1397
1468
|
PairPollRequest
|
|
1398
1469
|
]);
|
|
1399
|
-
var ClaimRequest =
|
|
1400
|
-
protocolVersion:
|
|
1401
|
-
runnerId:
|
|
1470
|
+
var ClaimRequest = z9.object({
|
|
1471
|
+
protocolVersion: z9.literal(PROTOCOL_VERSION),
|
|
1472
|
+
runnerId: z9.string().min(1),
|
|
1402
1473
|
/** Re-sent on every claim so a server never matches against a stale matrix. */
|
|
1403
1474
|
capabilities: CapabilityMatrix,
|
|
1404
1475
|
/** Upper bound on jobs to return; the server may return fewer. */
|
|
1405
|
-
max:
|
|
1476
|
+
max: z9.number().int().min(1).max(64)
|
|
1406
1477
|
}).strict();
|
|
1407
|
-
var ClaimResponse =
|
|
1478
|
+
var ClaimResponse = z9.object({
|
|
1408
1479
|
/**
|
|
1409
1480
|
* Stubs, not jobs. The payload arrives from `fetch`, sealed to whichever
|
|
1410
1481
|
* device claimed — see {@link JobStub} for the exhaustive metadata list.
|
|
1411
1482
|
*/
|
|
1412
|
-
jobs:
|
|
1483
|
+
jobs: z9.array(ClaimedStub),
|
|
1413
1484
|
/** Lease duration granted, so the daemon knows its renewal deadline. */
|
|
1414
|
-
leaseMs:
|
|
1485
|
+
leaseMs: z9.number().int().positive()
|
|
1415
1486
|
}).strict();
|
|
1416
|
-
var HeartbeatRequest =
|
|
1417
|
-
protocolVersion:
|
|
1418
|
-
runnerId:
|
|
1419
|
-
daemonVersion:
|
|
1487
|
+
var HeartbeatRequest = z9.object({
|
|
1488
|
+
protocolVersion: z9.literal(PROTOCOL_VERSION),
|
|
1489
|
+
runnerId: z9.string().min(1),
|
|
1490
|
+
daemonVersion: z9.string().min(1),
|
|
1420
1491
|
capabilities: CapabilityMatrix,
|
|
1421
1492
|
/**
|
|
1422
1493
|
* Leases this daemon believes it holds; the server renews exactly these.
|
|
@@ -1424,13 +1495,13 @@ var HeartbeatRequest = z8.object({
|
|
|
1424
1495
|
* Lease ids rather than job ids, so a replayed heartbeat cannot renew a
|
|
1425
1496
|
* grant the runner no longer holds — see {@link Lease.id}.
|
|
1426
1497
|
*/
|
|
1427
|
-
activeLeases:
|
|
1428
|
-
|
|
1498
|
+
activeLeases: z9.array(
|
|
1499
|
+
z9.object({ jobId: z9.string().min(1), leaseId: z9.string().min(1) })
|
|
1429
1500
|
),
|
|
1430
1501
|
/** True while the owner has the daemon paused; the server stops offering work. */
|
|
1431
|
-
paused:
|
|
1502
|
+
paused: z9.boolean()
|
|
1432
1503
|
}).strict();
|
|
1433
|
-
var HeartbeatResponse =
|
|
1504
|
+
var HeartbeatResponse = z9.object({
|
|
1434
1505
|
/**
|
|
1435
1506
|
* The sites this daemon may serve, right now — cloud_008 finding 59.
|
|
1436
1507
|
*
|
|
@@ -1448,7 +1519,40 @@ var HeartbeatResponse = z8.object({
|
|
|
1448
1519
|
* rather than being told a second time — two fields for one fact is how
|
|
1449
1520
|
* they drift.
|
|
1450
1521
|
*/
|
|
1451
|
-
sites:
|
|
1522
|
+
sites: z9.record(z9.string().min(1), PublicIdentity),
|
|
1523
|
+
/**
|
|
1524
|
+
* How a site's current key traces back to one this daemon already holds —
|
|
1525
|
+
* byollm_009 Amendment C.
|
|
1526
|
+
*
|
|
1527
|
+
* Keyed by the same id as `sites`, and **additive on purpose**: `sites`
|
|
1528
|
+
* remains the one statement of which key is current, and this says only
|
|
1529
|
+
* how that key got there. Two fields for one fact is how they drift; this
|
|
1530
|
+
* is two facts, and the second is evidence about the first.
|
|
1531
|
+
*
|
|
1532
|
+
* Optional because a site that has never rotated has no chain, which is
|
|
1533
|
+
* every site today. A daemon that receives one for an id it already holds
|
|
1534
|
+
* ignores it: the pin it has is the pin it approved.
|
|
1535
|
+
*
|
|
1536
|
+
* §12 carries what this adds to the metadata surface — a site's rotation
|
|
1537
|
+
* history is public by construction, because a daemon that cannot read it
|
|
1538
|
+
* cannot verify it.
|
|
1539
|
+
*/
|
|
1540
|
+
successions: z9.record(
|
|
1541
|
+
z9.string().min(1),
|
|
1542
|
+
z9.object({
|
|
1543
|
+
/** Oldest last, as the projection carries it. */
|
|
1544
|
+
succeeds: z9.array(Succession).max(MAX_SUCCESSION_CHAIN),
|
|
1545
|
+
/**
|
|
1546
|
+
* Until when the superseded key may still sign work — epoch ms.
|
|
1547
|
+
*
|
|
1548
|
+
* The daemon holds its own clock against this, for the reason it
|
|
1549
|
+
* holds its own allowlist: a projection that could extend the
|
|
1550
|
+
* window indefinitely would be a two-key site forever, decided by
|
|
1551
|
+
* the party this design does not trust.
|
|
1552
|
+
*/
|
|
1553
|
+
retiringUntil: z9.number().int().positive().optional()
|
|
1554
|
+
}).strict()
|
|
1555
|
+
).optional(),
|
|
1452
1556
|
/**
|
|
1453
1557
|
* Per-job cancel (byollm_001 Rev 1 §C). The daemon aborts these jobs'
|
|
1454
1558
|
* in-flight backend calls and reports them `canceled`.
|
|
@@ -1459,8 +1563,8 @@ var HeartbeatResponse = z8.object({
|
|
|
1459
1563
|
* is the unique grant and the daemon already keys its work by it; this is
|
|
1460
1564
|
* the same shape `activeLeases` sends in the other direction.
|
|
1461
1565
|
*/
|
|
1462
|
-
cancel:
|
|
1463
|
-
|
|
1566
|
+
cancel: z9.array(
|
|
1567
|
+
z9.object({ jobId: z9.string().min(1), leaseId: z9.string().min(1) }).strict()
|
|
1464
1568
|
),
|
|
1465
1569
|
// `leases` is deliberately absent — cloud_008 §1.4b, finding 16.
|
|
1466
1570
|
//
|
|
@@ -1490,11 +1594,11 @@ var HeartbeatResponse = z8.object({
|
|
|
1490
1594
|
* ambiguous across sites, and "the lease you no longer hold" is exactly
|
|
1491
1595
|
* what this field means anyway.
|
|
1492
1596
|
*/
|
|
1493
|
-
lost:
|
|
1494
|
-
|
|
1597
|
+
lost: z9.array(
|
|
1598
|
+
z9.object({ jobId: z9.string().min(1), leaseId: z9.string().min(1) }).strict()
|
|
1495
1599
|
),
|
|
1496
1600
|
/** Server clock, so a daemon with a skewed clock still honors leases. */
|
|
1497
|
-
serverTime:
|
|
1601
|
+
serverTime: z9.number().int().positive(),
|
|
1498
1602
|
/**
|
|
1499
1603
|
* Sites whose disclosure the user must read again before work moves —
|
|
1500
1604
|
* cloud_008 finding 48, named rather than counted.
|
|
@@ -1509,13 +1613,13 @@ var HeartbeatResponse = z8.object({
|
|
|
1509
1613
|
* operator stopped it" — one word with two subjects on two halves of one
|
|
1510
1614
|
* exchange is a confusion nobody untangles from a log.
|
|
1511
1615
|
*/
|
|
1512
|
-
awaitingConsent:
|
|
1616
|
+
awaitingConsent: z9.array(z9.string().min(1))
|
|
1513
1617
|
}).strict();
|
|
1514
|
-
var ResultDisposition =
|
|
1515
|
-
var ResultRequest =
|
|
1516
|
-
protocolVersion:
|
|
1517
|
-
runnerId:
|
|
1518
|
-
jobId:
|
|
1618
|
+
var ResultDisposition = z9.enum(["ok", "error", "canceled"]);
|
|
1619
|
+
var ResultRequest = z9.object({
|
|
1620
|
+
protocolVersion: z9.literal(PROTOCOL_VERSION),
|
|
1621
|
+
runnerId: z9.string().min(1),
|
|
1622
|
+
jobId: z9.string().min(1),
|
|
1519
1623
|
/**
|
|
1520
1624
|
* The grant this result was produced under — cloud_008 §1.4a.
|
|
1521
1625
|
*
|
|
@@ -1538,7 +1642,7 @@ var ResultRequest = z8.object({
|
|
|
1538
1642
|
* learned once already, when a replayed release yanked a later grant, and
|
|
1539
1643
|
* it applies here for the same reason.
|
|
1540
1644
|
*/
|
|
1541
|
-
leaseId:
|
|
1645
|
+
leaseId: z9.string().min(1),
|
|
1542
1646
|
/**
|
|
1543
1647
|
* The outcome, sealed to the site and signed by the device.
|
|
1544
1648
|
*
|
|
@@ -1570,12 +1674,12 @@ var ResultRequest = z8.object({
|
|
|
1570
1674
|
// on it, so it is a class a routing party consumes. Nobody between the
|
|
1571
1675
|
// two ends consumes these.
|
|
1572
1676
|
}).strict();
|
|
1573
|
-
var ResultResponse =
|
|
1677
|
+
var ResultResponse = z9.object({
|
|
1574
1678
|
/**
|
|
1575
1679
|
* False when this submission wrote nothing — the daemon should discard,
|
|
1576
1680
|
* not retry ({@link MUSTS.RESULT_IDEMPOTENT}).
|
|
1577
1681
|
*/
|
|
1578
|
-
accepted:
|
|
1682
|
+
accepted: z9.boolean(),
|
|
1579
1683
|
/**
|
|
1580
1684
|
* True when this device had already recorded this job's result.
|
|
1581
1685
|
*
|
|
@@ -1589,13 +1693,13 @@ var ResultResponse = z8.object({
|
|
|
1589
1693
|
* the same refusal it would get for a job that is *not* terminal, so a job
|
|
1590
1694
|
* id cannot be used as a terminality probe.
|
|
1591
1695
|
*/
|
|
1592
|
-
duplicate:
|
|
1696
|
+
duplicate: z9.boolean().optional(),
|
|
1593
1697
|
/** The job's state after this submission. */
|
|
1594
|
-
state:
|
|
1698
|
+
state: z9.string().min(1)
|
|
1595
1699
|
}).strict();
|
|
1596
|
-
var ReleaseRequest =
|
|
1597
|
-
protocolVersion:
|
|
1598
|
-
runnerId:
|
|
1700
|
+
var ReleaseRequest = z9.object({
|
|
1701
|
+
protocolVersion: z9.literal(PROTOCOL_VERSION),
|
|
1702
|
+
runnerId: z9.string().min(1),
|
|
1599
1703
|
/**
|
|
1600
1704
|
* Which leases to release — the grant, not just the job.
|
|
1601
1705
|
*
|
|
@@ -1603,8 +1707,8 @@ var ReleaseRequest = z8.object({
|
|
|
1603
1707
|
* moment it arrives, which for a replayed request is not the lease the
|
|
1604
1708
|
* daemon meant. See {@link Lease.id}.
|
|
1605
1709
|
*/
|
|
1606
|
-
leases:
|
|
1607
|
-
|
|
1710
|
+
leases: z9.array(
|
|
1711
|
+
z9.object({ jobId: z9.string().min(1), leaseId: z9.string().min(1) })
|
|
1608
1712
|
),
|
|
1609
1713
|
/**
|
|
1610
1714
|
* Why, so the app's runner list can say something true.
|
|
@@ -1615,12 +1719,12 @@ var ReleaseRequest = z8.object({
|
|
|
1615
1719
|
* stop offering that job to that runner, or the pair would spin between
|
|
1616
1720
|
* claim and release forever.
|
|
1617
1721
|
*/
|
|
1618
|
-
reason:
|
|
1722
|
+
reason: z9.enum(["shutdown", "pause", "revoked", "backend-down", "refused"])
|
|
1619
1723
|
}).strict();
|
|
1620
|
-
var ReleaseResponse =
|
|
1621
|
-
released:
|
|
1724
|
+
var ReleaseResponse = z9.object({
|
|
1725
|
+
released: z9.array(z9.string().min(1))
|
|
1622
1726
|
}).strict();
|
|
1623
|
-
var WireErrorCode =
|
|
1727
|
+
var WireErrorCode = z9.enum([
|
|
1624
1728
|
"bad-request",
|
|
1625
1729
|
"unsupported-protocol-version",
|
|
1626
1730
|
// "We do not know who you are." Exactly 401, and only that — cloud_008
|
|
@@ -1670,9 +1774,9 @@ var WireErrorCode = z8.enum([
|
|
|
1670
1774
|
"rate-limited",
|
|
1671
1775
|
"server-error"
|
|
1672
1776
|
]);
|
|
1673
|
-
var WireError =
|
|
1777
|
+
var WireError = z9.object({
|
|
1674
1778
|
error: WireErrorCode,
|
|
1675
|
-
message:
|
|
1779
|
+
message: z9.string().min(1),
|
|
1676
1780
|
/**
|
|
1677
1781
|
* What this server speaks, on `unsupported-protocol-version` — §B.4.
|
|
1678
1782
|
*
|
|
@@ -1686,10 +1790,10 @@ var WireError = z8.object({
|
|
|
1686
1790
|
* Modelled the way `clock-skew`'s two fields already are — code-specific
|
|
1687
1791
|
* extras, refused on any other code by the refinement below.
|
|
1688
1792
|
*/
|
|
1689
|
-
supported:
|
|
1690
|
-
minimum:
|
|
1793
|
+
supported: z9.array(z9.string().min(1)).optional(),
|
|
1794
|
+
minimum: z9.string().min(1).optional(),
|
|
1691
1795
|
/** Seconds; mirrors Retry-After for `rate-limited` and `server-error`. */
|
|
1692
|
-
retryAfter:
|
|
1796
|
+
retryAfter: z9.number().int().nonnegative().optional(),
|
|
1693
1797
|
/**
|
|
1694
1798
|
* The server's clock, and the window it allows. `clock-skew` only.
|
|
1695
1799
|
*
|
|
@@ -1699,8 +1803,8 @@ var WireError = z8.object({
|
|
|
1699
1803
|
* heartbeat response returns the same value, and so does every `Date`
|
|
1700
1804
|
* header.
|
|
1701
1805
|
*/
|
|
1702
|
-
serverTime:
|
|
1703
|
-
maxSkewMs:
|
|
1806
|
+
serverTime: z9.number().int().positive().optional(),
|
|
1807
|
+
maxSkewMs: z9.number().int().positive().optional()
|
|
1704
1808
|
}).strict().superRefine((error, ctx) => {
|
|
1705
1809
|
const skew = error.error === "clock-skew";
|
|
1706
1810
|
const carried = error.serverTime !== void 0 || error.maxSkewMs !== void 0;
|
|
@@ -1751,16 +1855,16 @@ var ERROR_STATUS = Object.freeze({
|
|
|
1751
1855
|
"rate-limited": 429,
|
|
1752
1856
|
"server-error": 500
|
|
1753
1857
|
});
|
|
1754
|
-
var FetchRequest =
|
|
1858
|
+
var FetchRequest = z9.object({
|
|
1755
1859
|
// `literal`, like every other request — V1-17. This one said
|
|
1756
1860
|
// `string().min(1)`, so a daemon speaking a version this server does not
|
|
1757
1861
|
// know got past the handshake on the one endpoint that hands over a
|
|
1758
1862
|
// sealed payload. The version check exists so that a mismatch is a named
|
|
1759
1863
|
// refusal rather than a schema failure three fields later; here it was
|
|
1760
1864
|
// neither.
|
|
1761
|
-
protocolVersion:
|
|
1762
|
-
runnerId:
|
|
1763
|
-
jobId:
|
|
1865
|
+
protocolVersion: z9.literal(PROTOCOL_VERSION),
|
|
1866
|
+
runnerId: z9.string().min(1),
|
|
1867
|
+
jobId: z9.string().min(1),
|
|
1764
1868
|
/**
|
|
1765
1869
|
* The grant this daemon holds.
|
|
1766
1870
|
*
|
|
@@ -1768,9 +1872,9 @@ var FetchRequest = z8.object({
|
|
|
1768
1872
|
* only the job would be answerable for whatever lease exists when it
|
|
1769
1873
|
* arrives ({@link Lease.id}).
|
|
1770
1874
|
*/
|
|
1771
|
-
leaseId:
|
|
1875
|
+
leaseId: z9.string().min(1)
|
|
1772
1876
|
}).strict();
|
|
1773
|
-
var FetchResponse =
|
|
1877
|
+
var FetchResponse = z9.object({
|
|
1774
1878
|
/**
|
|
1775
1879
|
* The work, sealed to the device that claimed it — byollm_009 §6.
|
|
1776
1880
|
*
|
|
@@ -1820,6 +1924,7 @@ export {
|
|
|
1820
1924
|
KindedPayload,
|
|
1821
1925
|
Lease,
|
|
1822
1926
|
MAX_CLOCK_SKEW_MS,
|
|
1927
|
+
MAX_SUCCESSION_CHAIN,
|
|
1823
1928
|
MIN_PROTOCOL_VERSION,
|
|
1824
1929
|
MUSTS,
|
|
1825
1930
|
MUST_IDS,
|
|
@@ -1836,6 +1941,7 @@ export {
|
|
|
1836
1941
|
PairStartResponse,
|
|
1837
1942
|
PublicIdentity,
|
|
1838
1943
|
REFUSAL_MESSAGES,
|
|
1944
|
+
RETIREMENT_WINDOW_MS,
|
|
1839
1945
|
ReleaseRequest,
|
|
1840
1946
|
ReleaseResponse,
|
|
1841
1947
|
RequestSignature,
|
|
@@ -1845,11 +1951,13 @@ export {
|
|
|
1845
1951
|
ResultResponse,
|
|
1846
1952
|
RunMetadata,
|
|
1847
1953
|
SIZE_CLASS_LIMITS,
|
|
1954
|
+
SUCCESSION_CONTEXT,
|
|
1848
1955
|
SUPPORTED_PROTOCOL_VERSIONS,
|
|
1849
1956
|
SealedEnvelope,
|
|
1850
1957
|
SealedOutcome,
|
|
1851
1958
|
SizeClass,
|
|
1852
1959
|
StoredKeys,
|
|
1960
|
+
Succession,
|
|
1853
1961
|
TERMINAL_STATES,
|
|
1854
1962
|
WireError,
|
|
1855
1963
|
WireErrorCode,
|
|
@@ -1878,12 +1986,16 @@ export {
|
|
|
1878
1986
|
seal,
|
|
1879
1987
|
signRequest,
|
|
1880
1988
|
signSiteRequest,
|
|
1989
|
+
signSuccession,
|
|
1881
1990
|
signWith,
|
|
1882
1991
|
sizeClassCeiling,
|
|
1883
1992
|
sizeClassOf,
|
|
1993
|
+
successionStatement,
|
|
1994
|
+
verifyLink,
|
|
1884
1995
|
verifyPublicIdentity,
|
|
1885
1996
|
verifyRequest,
|
|
1886
1997
|
verifySiteRequest,
|
|
1887
|
-
verifyWith
|
|
1998
|
+
verifyWith,
|
|
1999
|
+
walkSuccession
|
|
1888
2000
|
};
|
|
1889
2001
|
//# sourceMappingURL=index.js.map
|