@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/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 z8 } from "zod";
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 = z8.object({
1374
+ var Capability = z9.object({
1304
1375
  kind: JobKind,
1305
1376
  backendId: BackendIdSchema,
1306
1377
  backendClass: BackendClass,
1307
- model: z8.string().min(1),
1378
+ model: z9.string().min(1),
1308
1379
  offerScope: OfferScope
1309
1380
  }).strict();
1310
- var CapabilityMatrix = z8.array(Capability);
1311
- var PairStartRequest = z8.object({
1312
- protocolVersion: z8.literal(PROTOCOL_VERSION),
1313
- action: z8.literal("start"),
1314
- daemon: z8.object({
1315
- version: z8.string().min(1),
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: z8.string().min(1).max(120),
1318
- platform: z8.enum(["darwin", "linux", "win32"])
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 = z8.object({
1401
+ var PairStartResponse = z9.object({
1331
1402
  /** Secret the daemon polls with. Never shown to the user. */
1332
- deviceCode: z8.string().min(20),
1403
+ deviceCode: z9.string().min(20),
1333
1404
  /** Short code the user reads and confirms in the browser. */
1334
- userCode: z8.string().min(4).max(16),
1405
+ userCode: z9.string().min(4).max(16),
1335
1406
  /** Where the user approves. Must be on the server's own origin. */
1336
- verificationUrl: z8.url(),
1407
+ verificationUrl: z9.url(),
1337
1408
  /** Epoch ms after which the code is dead ({@link MUSTS.PAIR_CODE_EXPIRES}). */
1338
- expiresAt: z8.number().int().positive(),
1409
+ expiresAt: z9.number().int().positive(),
1339
1410
  /** How often the daemon may poll. */
1340
- pollIntervalMs: z8.number().int().min(500).max(6e4)
1411
+ pollIntervalMs: z9.number().int().min(500).max(6e4)
1341
1412
  }).strict();
1342
- var PairPollRequest = z8.object({
1343
- protocolVersion: z8.literal(PROTOCOL_VERSION),
1344
- action: z8.literal("poll"),
1345
- deviceCode: z8.string().min(20)
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 = z8.discriminatedUnion("status", [
1348
- z8.object({ status: z8.literal("pending") }).strict(),
1349
- z8.object({ status: z8.literal("denied") }).strict(),
1350
- z8.object({ status: z8.literal("expired") }).strict(),
1351
- z8.object({
1352
- status: z8.literal("approved"),
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: z8.string().min(1),
1440
+ runnerId: z9.string().min(1),
1370
1441
  /** The app's id for the approving user — this daemon's owner forever. */
1371
- owner: z8.string().min(1),
1442
+ owner: z9.string().min(1),
1372
1443
  /** Display name for the trust UI, if the app offers one. */
1373
- ownerLabel: z8.string().optional(),
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: z8.record(z8.string().min(1), PublicIdentity)
1463
+ sites: z9.record(z9.string().min(1), PublicIdentity)
1393
1464
  }).strict()
1394
1465
  ]);
1395
- var PairRequest = z8.discriminatedUnion("action", [
1466
+ var PairRequest = z9.discriminatedUnion("action", [
1396
1467
  PairStartRequest,
1397
1468
  PairPollRequest
1398
1469
  ]);
1399
- var ClaimRequest = z8.object({
1400
- protocolVersion: z8.literal(PROTOCOL_VERSION),
1401
- runnerId: z8.string().min(1),
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: z8.number().int().min(1).max(64)
1476
+ max: z9.number().int().min(1).max(64)
1406
1477
  }).strict();
1407
- var ClaimResponse = z8.object({
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: z8.array(ClaimedStub),
1483
+ jobs: z9.array(ClaimedStub),
1413
1484
  /** Lease duration granted, so the daemon knows its renewal deadline. */
1414
- leaseMs: z8.number().int().positive()
1485
+ leaseMs: z9.number().int().positive()
1415
1486
  }).strict();
1416
- var HeartbeatRequest = z8.object({
1417
- protocolVersion: z8.literal(PROTOCOL_VERSION),
1418
- runnerId: z8.string().min(1),
1419
- daemonVersion: z8.string().min(1),
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: z8.array(
1428
- z8.object({ jobId: z8.string().min(1), leaseId: z8.string().min(1) })
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: z8.boolean()
1502
+ paused: z9.boolean()
1432
1503
  }).strict();
1433
- var HeartbeatResponse = z8.object({
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: z8.record(z8.string().min(1), PublicIdentity),
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: z8.array(
1463
- z8.object({ jobId: z8.string().min(1), leaseId: z8.string().min(1) }).strict()
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: z8.array(
1494
- z8.object({ jobId: z8.string().min(1), leaseId: z8.string().min(1) }).strict()
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: z8.number().int().positive(),
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: z8.array(z8.string().min(1))
1616
+ awaitingConsent: z9.array(z9.string().min(1))
1513
1617
  }).strict();
1514
- var ResultDisposition = z8.enum(["ok", "error", "canceled"]);
1515
- var ResultRequest = z8.object({
1516
- protocolVersion: z8.literal(PROTOCOL_VERSION),
1517
- runnerId: z8.string().min(1),
1518
- jobId: z8.string().min(1),
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: z8.string().min(1),
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 = z8.object({
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: z8.boolean(),
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: z8.boolean().optional(),
1696
+ duplicate: z9.boolean().optional(),
1593
1697
  /** The job's state after this submission. */
1594
- state: z8.string().min(1)
1698
+ state: z9.string().min(1)
1595
1699
  }).strict();
1596
- var ReleaseRequest = z8.object({
1597
- protocolVersion: z8.literal(PROTOCOL_VERSION),
1598
- runnerId: z8.string().min(1),
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: z8.array(
1607
- z8.object({ jobId: z8.string().min(1), leaseId: z8.string().min(1) })
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: z8.enum(["shutdown", "pause", "revoked", "backend-down", "refused"])
1722
+ reason: z9.enum(["shutdown", "pause", "revoked", "backend-down", "refused"])
1619
1723
  }).strict();
1620
- var ReleaseResponse = z8.object({
1621
- released: z8.array(z8.string().min(1))
1724
+ var ReleaseResponse = z9.object({
1725
+ released: z9.array(z9.string().min(1))
1622
1726
  }).strict();
1623
- var WireErrorCode = z8.enum([
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 = z8.object({
1777
+ var WireError = z9.object({
1674
1778
  error: WireErrorCode,
1675
- message: z8.string().min(1),
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: z8.array(z8.string().min(1)).optional(),
1690
- minimum: z8.string().min(1).optional(),
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: z8.number().int().nonnegative().optional(),
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: z8.number().int().positive().optional(),
1703
- maxSkewMs: z8.number().int().positive().optional()
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 = z8.object({
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: z8.literal(PROTOCOL_VERSION),
1762
- runnerId: z8.string().min(1),
1763
- jobId: z8.string().min(1),
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: z8.string().min(1)
1875
+ leaseId: z9.string().min(1)
1772
1876
  }).strict();
1773
- var FetchResponse = z8.object({
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