@byollm/protocol 0.1.0-alpha.58 → 0.1.0-alpha.59
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 +40 -27
- package/dist/index.js +51 -17
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
> [!WARNING]
|
|
2
|
-
> **Alpha (`0.1.0-alpha.
|
|
2
|
+
> **Alpha (`0.1.0-alpha.59`) — under active development. Don't use this yet.**
|
|
3
3
|
>
|
|
4
4
|
> Install it deliberately: `npm install @byollm/protocol@alpha`.
|
|
5
5
|
>
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
> packages published and `@byollm/server` did not: a Sigstore
|
|
84
84
|
> transparency-log 409 on its provenance attestation. The workflow's
|
|
85
85
|
> "already published" guard correctly refuses to resume a partial publish,
|
|
86
|
-
> so `0.1.0-alpha.
|
|
86
|
+
> so `0.1.0-alpha.59` is that release, whole.
|
|
87
87
|
>
|
|
88
88
|
> If you run the Supabase adapter, `alpha.21` needs
|
|
89
89
|
> `20260819010000_completed_by_lease_id.sql`: alpha.19 shipped §3.6's
|
package/dist/index.d.ts
CHANGED
|
@@ -477,7 +477,7 @@ declare const ChatMessage: z.ZodObject<{
|
|
|
477
477
|
assistant: "assistant";
|
|
478
478
|
}>;
|
|
479
479
|
content: z.ZodString;
|
|
480
|
-
}, z.core.$
|
|
480
|
+
}, z.core.$strict>;
|
|
481
481
|
type ChatMessage = z.infer<typeof ChatMessage>;
|
|
482
482
|
/**
|
|
483
483
|
* Payload for `llm.generate`.
|
|
@@ -504,7 +504,7 @@ declare const ChatPayload: z.ZodObject<{
|
|
|
504
504
|
assistant: "assistant";
|
|
505
505
|
}>;
|
|
506
506
|
content: z.ZodString;
|
|
507
|
-
}, z.core.$
|
|
507
|
+
}, z.core.$strict>>;
|
|
508
508
|
system: z.ZodOptional<z.ZodString>;
|
|
509
509
|
}, z.core.$strict>;
|
|
510
510
|
type ChatPayload = z.infer<typeof ChatPayload>;
|
|
@@ -531,7 +531,7 @@ declare const KindedPayload: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
531
531
|
prompt: z.ZodString;
|
|
532
532
|
system: z.ZodOptional<z.ZodString>;
|
|
533
533
|
}, z.core.$strict>;
|
|
534
|
-
}, z.core.$
|
|
534
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
535
535
|
kind: z.ZodLiteral<"llm.chat">;
|
|
536
536
|
payload: z.ZodObject<{
|
|
537
537
|
messages: z.ZodArray<z.ZodObject<{
|
|
@@ -541,10 +541,10 @@ declare const KindedPayload: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
541
541
|
assistant: "assistant";
|
|
542
542
|
}>;
|
|
543
543
|
content: z.ZodString;
|
|
544
|
-
}, z.core.$
|
|
544
|
+
}, z.core.$strict>>;
|
|
545
545
|
system: z.ZodOptional<z.ZodString>;
|
|
546
546
|
}, z.core.$strict>;
|
|
547
|
-
}, z.core.$
|
|
547
|
+
}, z.core.$strict>], "kind">;
|
|
548
548
|
type KindedPayload = z.infer<typeof KindedPayload>;
|
|
549
549
|
/** The payload type for a given kind. */
|
|
550
550
|
type PayloadFor<K extends JobKind> = K extends "llm.generate" ? GeneratePayload : ChatPayload;
|
|
@@ -591,7 +591,7 @@ declare const Lease: z.ZodObject<{
|
|
|
591
591
|
id: z.ZodString;
|
|
592
592
|
runnerId: z.ZodString;
|
|
593
593
|
expiresAt: z.ZodNumber;
|
|
594
|
-
}, z.core.$
|
|
594
|
+
}, z.core.$strict>;
|
|
595
595
|
type Lease = z.infer<typeof Lease>;
|
|
596
596
|
/** Payload union as it appears on a job record. */
|
|
597
597
|
declare const JobPayload: z.ZodUnion<readonly [z.ZodObject<{
|
|
@@ -605,7 +605,7 @@ declare const JobPayload: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
605
605
|
assistant: "assistant";
|
|
606
606
|
}>;
|
|
607
607
|
content: z.ZodString;
|
|
608
|
-
}, z.core.$
|
|
608
|
+
}, z.core.$strict>>;
|
|
609
609
|
system: z.ZodOptional<z.ZodString>;
|
|
610
610
|
}, z.core.$strict>]>;
|
|
611
611
|
type JobPayload = z.infer<typeof JobPayload>;
|
|
@@ -634,7 +634,7 @@ declare const ClaimedJob: z.ZodObject<{
|
|
|
634
634
|
assistant: "assistant";
|
|
635
635
|
}>;
|
|
636
636
|
content: z.ZodString;
|
|
637
|
-
}, z.core.$
|
|
637
|
+
}, z.core.$strict>>;
|
|
638
638
|
system: z.ZodOptional<z.ZodString>;
|
|
639
639
|
}, z.core.$strict>]>;
|
|
640
640
|
audience: z.ZodEnum<{
|
|
@@ -648,7 +648,7 @@ declare const ClaimedJob: z.ZodObject<{
|
|
|
648
648
|
id: z.ZodString;
|
|
649
649
|
runnerId: z.ZodString;
|
|
650
650
|
expiresAt: z.ZodNumber;
|
|
651
|
-
}, z.core.$
|
|
651
|
+
}, z.core.$strict>;
|
|
652
652
|
}, z.core.$strict>;
|
|
653
653
|
type ClaimedJob = z.infer<typeof ClaimedJob>;
|
|
654
654
|
/**
|
|
@@ -979,11 +979,11 @@ declare const ClaimedStub: z.ZodObject<{
|
|
|
979
979
|
id: z.ZodString;
|
|
980
980
|
runnerId: z.ZodString;
|
|
981
981
|
expiresAt: z.ZodNumber;
|
|
982
|
-
}, z.core.$
|
|
982
|
+
}, z.core.$strict>;
|
|
983
983
|
grant: z.ZodOptional<z.ZodObject<{
|
|
984
984
|
grantId: z.ZodString;
|
|
985
985
|
jobId: z.ZodString;
|
|
986
|
-
|
|
986
|
+
site: z.ZodString;
|
|
987
987
|
user: z.ZodString;
|
|
988
988
|
owner: z.ZodString;
|
|
989
989
|
purpose: z.ZodString;
|
|
@@ -1378,13 +1378,6 @@ declare const Purpose: z.ZodObject<{
|
|
|
1378
1378
|
}>>;
|
|
1379
1379
|
}, z.core.$strict>;
|
|
1380
1380
|
type Purpose = z.infer<typeof Purpose>;
|
|
1381
|
-
/**
|
|
1382
|
-
* Everything a site needs, by purpose key.
|
|
1383
|
-
*
|
|
1384
|
-
* At least one purpose: a site that declares none is a site that can enqueue
|
|
1385
|
-
* nothing, and accepting it would mean the first refusal a person saw came
|
|
1386
|
-
* from a job rather than from registration.
|
|
1387
|
-
*/
|
|
1388
1381
|
declare const Manifest: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
1389
1382
|
label: z.ZodString;
|
|
1390
1383
|
description: z.ZodOptional<z.ZodString>;
|
|
@@ -1509,7 +1502,7 @@ declare const GRANT_CONTEXT = "byollm/v1/grant";
|
|
|
1509
1502
|
declare const SignedGrant: z.ZodObject<{
|
|
1510
1503
|
grantId: z.ZodString;
|
|
1511
1504
|
jobId: z.ZodString;
|
|
1512
|
-
|
|
1505
|
+
site: z.ZodString;
|
|
1513
1506
|
user: z.ZodString;
|
|
1514
1507
|
owner: z.ZodString;
|
|
1515
1508
|
purpose: z.ZodString;
|
|
@@ -1575,10 +1568,14 @@ type GrantRefusal =
|
|
|
1575
1568
|
/** Older than {@link GRANT_MAX_AGE_MS}. */
|
|
1576
1569
|
| "expired"
|
|
1577
1570
|
/**
|
|
1578
|
-
* Issued in the future.
|
|
1571
|
+
* Issued further in the future than clock drift explains.
|
|
1579
1572
|
*
|
|
1580
1573
|
* Checked, and not as pedantry: an `issuedAt` ahead of now extends a
|
|
1581
1574
|
* grant's life past the bound, which is the whole thing being enforced.
|
|
1575
|
+
*
|
|
1576
|
+
* Tolerant by {@link CLOCK_SKEW_WARN_MS}, because it was tolerant by
|
|
1577
|
+
* nothing and that made ordinary drift a total outage — see
|
|
1578
|
+
* {@link verifyGrant}.
|
|
1582
1579
|
*/
|
|
1583
1580
|
| "from-the-future";
|
|
1584
1581
|
/**
|
|
@@ -2061,6 +2058,22 @@ declare const WithheldKind: z.ZodObject<{
|
|
|
2061
2058
|
}, z.core.$strict>>;
|
|
2062
2059
|
}, z.core.$strict>;
|
|
2063
2060
|
type WithheldKind = z.infer<typeof WithheldKind>;
|
|
2061
|
+
/**
|
|
2062
|
+
* One grant, named by both halves — V1-3.
|
|
2063
|
+
*
|
|
2064
|
+
* A job id is chosen per site, so the lease id is the unique thing an upstream
|
|
2065
|
+
* and a daemon can both point at. Anywhere a request says "this piece of work,
|
|
2066
|
+
* held by me", it says it with both.
|
|
2067
|
+
*
|
|
2068
|
+
* Declared once because it was written out twice — `activeLeases` and
|
|
2069
|
+
* `ReleaseRequest.leases` — and both needed the same `.strict()` added. Two
|
|
2070
|
+
* copies of a shape are two places to forget it.
|
|
2071
|
+
*/
|
|
2072
|
+
declare const GrantRef: z.ZodObject<{
|
|
2073
|
+
jobId: z.ZodString;
|
|
2074
|
+
leaseId: z.ZodString;
|
|
2075
|
+
}, z.core.$strict>;
|
|
2076
|
+
type GrantRef = z.infer<typeof GrantRef>;
|
|
2064
2077
|
/**
|
|
2065
2078
|
* Pairing is a device-code exchange, not a pasted secret
|
|
2066
2079
|
* ({@link MUSTS.PAIR_INTERACTIVE}). The daemon starts a pairing, shows the
|
|
@@ -2079,7 +2092,7 @@ declare const PairStartRequest: z.ZodObject<{
|
|
|
2079
2092
|
linux: "linux";
|
|
2080
2093
|
win32: "win32";
|
|
2081
2094
|
}>;
|
|
2082
|
-
}, z.core.$
|
|
2095
|
+
}, z.core.$strict>;
|
|
2083
2096
|
device: z.ZodObject<{
|
|
2084
2097
|
identity: z.ZodString;
|
|
2085
2098
|
encryption: z.ZodString;
|
|
@@ -2168,7 +2181,7 @@ declare const PairRequest: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
2168
2181
|
linux: "linux";
|
|
2169
2182
|
win32: "win32";
|
|
2170
2183
|
}>;
|
|
2171
|
-
}, z.core.$
|
|
2184
|
+
}, z.core.$strict>;
|
|
2172
2185
|
device: z.ZodObject<{
|
|
2173
2186
|
identity: z.ZodString;
|
|
2174
2187
|
encryption: z.ZodString;
|
|
@@ -2286,11 +2299,11 @@ declare const ClaimResponse: z.ZodObject<{
|
|
|
2286
2299
|
id: z.ZodString;
|
|
2287
2300
|
runnerId: z.ZodString;
|
|
2288
2301
|
expiresAt: z.ZodNumber;
|
|
2289
|
-
}, z.core.$
|
|
2302
|
+
}, z.core.$strict>;
|
|
2290
2303
|
grant: z.ZodOptional<z.ZodObject<{
|
|
2291
2304
|
grantId: z.ZodString;
|
|
2292
2305
|
jobId: z.ZodString;
|
|
2293
|
-
|
|
2306
|
+
site: z.ZodString;
|
|
2294
2307
|
user: z.ZodString;
|
|
2295
2308
|
owner: z.ZodString;
|
|
2296
2309
|
purpose: z.ZodString;
|
|
@@ -2360,7 +2373,7 @@ declare const HeartbeatRequest: z.ZodObject<{
|
|
|
2360
2373
|
activeLeases: z.ZodArray<z.ZodObject<{
|
|
2361
2374
|
jobId: z.ZodString;
|
|
2362
2375
|
leaseId: z.ZodString;
|
|
2363
|
-
}, z.core.$
|
|
2376
|
+
}, z.core.$strict>>;
|
|
2364
2377
|
paused: z.ZodBoolean;
|
|
2365
2378
|
}, z.core.$strict>;
|
|
2366
2379
|
type HeartbeatRequest = z.infer<typeof HeartbeatRequest>;
|
|
@@ -2445,7 +2458,7 @@ declare const ReleaseRequest: z.ZodObject<{
|
|
|
2445
2458
|
leases: z.ZodArray<z.ZodObject<{
|
|
2446
2459
|
jobId: z.ZodString;
|
|
2447
2460
|
leaseId: z.ZodString;
|
|
2448
|
-
}, z.core.$
|
|
2461
|
+
}, z.core.$strict>>;
|
|
2449
2462
|
reason: z.ZodEnum<{
|
|
2450
2463
|
refused: "refused";
|
|
2451
2464
|
shutdown: "shutdown";
|
|
@@ -2526,4 +2539,4 @@ declare const FetchResponse: z.ZodObject<{
|
|
|
2526
2539
|
}, z.core.$strict>;
|
|
2527
2540
|
type FetchResponse = z.infer<typeof FetchResponse>;
|
|
2528
2541
|
|
|
2529
|
-
export { AUDIENCES, Audience, BACKENDS, BACKEND_IDS, BackendClass, BackendCost, type BackendDescriptor, type BackendId, BackendIdSchema, CLOCK_ATTRIBUTION_MS, CLOCK_SKEW_WARN_MS, Capability, CapabilityMatrix, ChatMessage, ChatPayload, ClaimRequest, ClaimResponse, ClaimedJob, ClaimedStub, DeliveredResult, ENCRYPTION_KEY_CONTEXT, ENDPOINTS, ENVELOPE_MAX_AGE_MS, ERROR_STATUS, type Endpoint, type EnvelopeContext, EnvelopeDirection, type EnvelopeFailure, FetchRequest, FetchResponse, GRANT_CONTEXT, GRANT_MAX_AGE_MS, GRANT_SIGNED_FIELDS, GeneratePayload, type GrantClaims, type GrantRefusal, HeartbeatRequest, HeartbeatResponse, JOB_KINDS, JobKind, JobOutcome, JobPayload, JobRefused, JobResultCanceled, JobResultError, JobResultOk, JobState, JobStub, KindedPayload, Lease, MAX_CLOCK_SKEW_MS, MAX_SUCCESSION_CHAIN, MIN_PROTOCOL_VERSION, MUSTS, MUST_IDS, Manifest, type MatchDaemon, type MatchJob, MatchRefusal, type MatchResult, type Must, type MustEnforcer, type MustId, type MustVerification, type MustVerifiedBy, OFFER_SCOPES, OfferScope, type OpenResult, PAYLOAD_LIMITS, PROTOCOL_PREFIX, PROTOCOL_VERSION, PairPollRequest, PairPollResponse, PairRequest, PairStartRequest, PairStartResponse, type PayloadFor, PublicIdentity, Purpose, REFUSAL_MESSAGES, RESERVED_PURPOSE, RETIREMENT_WINDOW_MS, RefusalReason, ReleaseRequest, ReleaseResponse, RequestSignature, ResultDisposition, ResultProvenance, ResultRequest, ResultResponse, RunMetadata, SIZE_CLASS_LIMITS, SUCCESSION_CONTEXT, SUPPORTED_PROTOCOL_VERSIONS, SealedEnvelope, SealedOutcome, type SignatureFailure, SignedGrant, SizeClass, type SpendConsent, StoredKeys, Succession, type SuccessionFailure, type SuccessionWalk, TERMINAL_STATES, type VersionRefusal, WireError, WireErrorCode, WithheldKind, backendDescriptor, backendName, canTransition, canonicalRequest, checkProtocolVersion, classifyCost, cryptoReady, declaredVersion, effectiveOfferScope, fingerprint, generateKeys, grantStatement, isBackendId, isCloudTaggedModel, isJobKind, isLocalHost, isTerminal, keyId, kindsOf, matchAudience, mustsVerifiedBy, open, payloadTextLength, provenanceFor, publicIdentityOf, resolveCost, seal, signGrant, signRequest, signSiteRequest, signSuccession, signWith, singlePurposeManifest, sizeClassCeiling, sizeClassOf, successionStatement, verifyGrant, verifyLink, verifyPublicIdentity, verifyRequest, verifySiteRequest, verifyWith, walkSuccession };
|
|
2542
|
+
export { AUDIENCES, Audience, BACKENDS, BACKEND_IDS, BackendClass, BackendCost, type BackendDescriptor, type BackendId, BackendIdSchema, CLOCK_ATTRIBUTION_MS, CLOCK_SKEW_WARN_MS, Capability, CapabilityMatrix, ChatMessage, ChatPayload, ClaimRequest, ClaimResponse, ClaimedJob, ClaimedStub, DeliveredResult, ENCRYPTION_KEY_CONTEXT, ENDPOINTS, ENVELOPE_MAX_AGE_MS, ERROR_STATUS, type Endpoint, type EnvelopeContext, EnvelopeDirection, type EnvelopeFailure, FetchRequest, FetchResponse, GRANT_CONTEXT, GRANT_MAX_AGE_MS, GRANT_SIGNED_FIELDS, GeneratePayload, type GrantClaims, GrantRef, type GrantRefusal, HeartbeatRequest, HeartbeatResponse, JOB_KINDS, JobKind, JobOutcome, JobPayload, JobRefused, JobResultCanceled, JobResultError, JobResultOk, JobState, JobStub, KindedPayload, Lease, MAX_CLOCK_SKEW_MS, MAX_SUCCESSION_CHAIN, MIN_PROTOCOL_VERSION, MUSTS, MUST_IDS, Manifest, type MatchDaemon, type MatchJob, MatchRefusal, type MatchResult, type Must, type MustEnforcer, type MustId, type MustVerification, type MustVerifiedBy, OFFER_SCOPES, OfferScope, type OpenResult, PAYLOAD_LIMITS, PROTOCOL_PREFIX, PROTOCOL_VERSION, PairPollRequest, PairPollResponse, PairRequest, PairStartRequest, PairStartResponse, type PayloadFor, PublicIdentity, Purpose, REFUSAL_MESSAGES, RESERVED_PURPOSE, RETIREMENT_WINDOW_MS, RefusalReason, ReleaseRequest, ReleaseResponse, RequestSignature, ResultDisposition, ResultProvenance, ResultRequest, ResultResponse, RunMetadata, SIZE_CLASS_LIMITS, SUCCESSION_CONTEXT, SUPPORTED_PROTOCOL_VERSIONS, SealedEnvelope, SealedOutcome, type SignatureFailure, SignedGrant, SizeClass, type SpendConsent, StoredKeys, Succession, type SuccessionFailure, type SuccessionWalk, TERMINAL_STATES, type VersionRefusal, WireError, WireErrorCode, WithheldKind, backendDescriptor, backendName, canTransition, canonicalRequest, checkProtocolVersion, classifyCost, cryptoReady, declaredVersion, effectiveOfferScope, fingerprint, generateKeys, grantStatement, isBackendId, isCloudTaggedModel, isJobKind, isLocalHost, isTerminal, keyId, kindsOf, matchAudience, mustsVerifiedBy, open, payloadTextLength, provenanceFor, publicIdentityOf, resolveCost, seal, signGrant, signRequest, signSiteRequest, signSuccession, signWith, singlePurposeManifest, sizeClassCeiling, sizeClassOf, successionStatement, verifyGrant, verifyLink, verifyPublicIdentity, verifyRequest, verifySiteRequest, verifyWith, walkSuccession };
|
package/dist/index.js
CHANGED
|
@@ -348,7 +348,7 @@ var PAYLOAD_LIMITS = Object.freeze({
|
|
|
348
348
|
var ChatMessage = z3.object({
|
|
349
349
|
role: z3.enum(["system", "user", "assistant"]),
|
|
350
350
|
content: z3.string().max(PAYLOAD_LIMITS.maxTextChars)
|
|
351
|
-
});
|
|
351
|
+
}).strict();
|
|
352
352
|
var GeneratePayload = z3.object({
|
|
353
353
|
prompt: z3.string().min(1).max(PAYLOAD_LIMITS.maxTextChars),
|
|
354
354
|
system: z3.string().max(PAYLOAD_LIMITS.maxTextChars).optional()
|
|
@@ -370,8 +370,11 @@ var ChatPayload = z3.object({
|
|
|
370
370
|
var JobKind = z3.enum(["llm.generate", "llm.chat"]);
|
|
371
371
|
var JOB_KINDS = Object.freeze(JobKind.options);
|
|
372
372
|
var KindedPayload = z3.discriminatedUnion("kind", [
|
|
373
|
-
|
|
374
|
-
|
|
373
|
+
// Strict on the wrappers too. A union member that strips is a door beside
|
|
374
|
+
// the one that is locked: the payloads inside are strict, and an extra key
|
|
375
|
+
// on the envelope vanished just as quietly.
|
|
376
|
+
z3.object({ kind: z3.literal("llm.generate"), payload: GeneratePayload }).strict(),
|
|
377
|
+
z3.object({ kind: z3.literal("llm.chat"), payload: ChatPayload }).strict()
|
|
375
378
|
]);
|
|
376
379
|
function isJobKind(value) {
|
|
377
380
|
return JOB_KINDS.includes(value);
|
|
@@ -542,8 +545,29 @@ var SignedGrant = z5.object({
|
|
|
542
545
|
* attack, and this field is why it fails.
|
|
543
546
|
*/
|
|
544
547
|
jobId: z5.string().min(1),
|
|
545
|
-
/**
|
|
546
|
-
|
|
548
|
+
/**
|
|
549
|
+
* The site the work came from, **as a key id** — byollm-review 2026-08-27.
|
|
550
|
+
*
|
|
551
|
+
* This was `siteId`, holding the site's id in the control plane's
|
|
552
|
+
* namespace, and it was signed by the engine and read by nobody. A signed
|
|
553
|
+
* field nobody checks is not a weak guarantee, it is the appearance of
|
|
554
|
+
* one: the design says "the grant carries the site", and nothing anywhere
|
|
555
|
+
* compared it to anything.
|
|
556
|
+
*
|
|
557
|
+
* It could not be compared. Job ids are chosen per site, so a grant
|
|
558
|
+
* authored for (site A, `job_1`) satisfied every device check against a
|
|
559
|
+
* stub naming (site B, `job_1`) — but the device holds sites only by the
|
|
560
|
+
* key ids it pinned, and had no way to relate a control-plane uuid to
|
|
561
|
+
* one. Checking the field would have meant a lookup through the party the
|
|
562
|
+
* grant exists to distrust.
|
|
563
|
+
*
|
|
564
|
+
* So the namespace changes to the one the device already has, and the
|
|
565
|
+
* name changes with it: this is the same value as {@link JobStub.site},
|
|
566
|
+
* compared directly, no lookup and nothing to believe. The control-plane
|
|
567
|
+
* id is not carried alongside — it had no reader, and keeping an
|
|
568
|
+
* unchecked field beside a checked one is how this hole was dug.
|
|
569
|
+
*/
|
|
570
|
+
site: z5.string().min(1),
|
|
547
571
|
/** Whose job it is — the person the site enqueued for. */
|
|
548
572
|
user: z5.string().min(1),
|
|
549
573
|
/**
|
|
@@ -593,7 +617,7 @@ function verifyGrant(input) {
|
|
|
593
617
|
if (grant.owner !== input.owner) return "wrong-owner";
|
|
594
618
|
if (grant.jobId !== input.jobId) return "wrong-job";
|
|
595
619
|
const age = now - grant.issuedAt;
|
|
596
|
-
if (age <
|
|
620
|
+
if (age < -CLOCK_SKEW_WARN_MS) return "from-the-future";
|
|
597
621
|
if (age > (input.maxAgeMs ?? GRANT_MAX_AGE_MS)) return "expired";
|
|
598
622
|
return verifyWith(
|
|
599
623
|
input.controlPlanePublic,
|
|
@@ -655,7 +679,7 @@ var Lease = z6.object({
|
|
|
655
679
|
runnerId: z6.string().min(1),
|
|
656
680
|
/** Epoch milliseconds after which the claim is void. */
|
|
657
681
|
expiresAt: z6.number().int().positive()
|
|
658
|
-
});
|
|
682
|
+
}).strict();
|
|
659
683
|
var JobPayload = z6.union([GeneratePayload, ChatPayload]);
|
|
660
684
|
var ClaimedJob = z6.object({
|
|
661
685
|
id: z6.string().min(1),
|
|
@@ -1113,6 +1137,13 @@ function verifyRequest(input) {
|
|
|
1113
1137
|
// src/manifest.ts
|
|
1114
1138
|
import { z as z9 } from "zod";
|
|
1115
1139
|
var RESERVED_PURPOSE = "default";
|
|
1140
|
+
var RENDERABLE = /^[^\p{Cc}\p{Cf}\p{Cs}\p{Co}]+$/u;
|
|
1141
|
+
var renderable = (max, what) => z9.string().min(1).max(max).regex(
|
|
1142
|
+
RENDERABLE,
|
|
1143
|
+
`a ${what} is text a person reads \u2014 no control characters, direction overrides or zero-width padding`
|
|
1144
|
+
).refine((value) => value.trim() !== "", {
|
|
1145
|
+
message: `a ${what} cannot be blank`
|
|
1146
|
+
});
|
|
1116
1147
|
var PurposeKey = z9.string().regex(
|
|
1117
1148
|
/^[a-z0-9][a-z0-9-]*$/,
|
|
1118
1149
|
"a purpose key is a lowercase slug \u2014 letters, digits and hyphens"
|
|
@@ -1125,9 +1156,9 @@ var Purpose = z9.object({
|
|
|
1125
1156
|
* compromise between machines and this is not. "Writing Assistant" is
|
|
1126
1157
|
* what somebody understands; `writing-assistant` is what travels.
|
|
1127
1158
|
*/
|
|
1128
|
-
label:
|
|
1159
|
+
label: renderable(80, "label"),
|
|
1129
1160
|
/** One line of context for the consent screen. Optional. */
|
|
1130
|
-
description:
|
|
1161
|
+
description: renderable(280, "description").optional(),
|
|
1131
1162
|
/**
|
|
1132
1163
|
* The kinds this purpose uses.
|
|
1133
1164
|
*
|
|
@@ -1135,10 +1166,15 @@ var Purpose = z9.object({
|
|
|
1135
1166
|
* person can send this purpose's chat to one service and its generation
|
|
1136
1167
|
* to another. Listing a kind here is what makes that slot appear.
|
|
1137
1168
|
*/
|
|
1138
|
-
kinds: z9.array(JobKind).min(1)
|
|
1169
|
+
kinds: z9.array(JobKind).min(1).max(JOB_KINDS.length).refine((kinds) => new Set(kinds).size === kinds.length, {
|
|
1170
|
+
message: "a purpose lists each kind once"
|
|
1171
|
+
})
|
|
1139
1172
|
}).strict();
|
|
1173
|
+
var MAX_PURPOSES = 32;
|
|
1140
1174
|
var Manifest = z9.record(PurposeKey, Purpose).refine((manifest) => Object.keys(manifest).length > 0, {
|
|
1141
1175
|
message: "a manifest declares at least one purpose"
|
|
1176
|
+
}).refine((manifest) => Object.keys(manifest).length <= MAX_PURPOSES, {
|
|
1177
|
+
message: `a manifest declares at most ${String(MAX_PURPOSES)} purposes \u2014 a consent screen is a set of questions somebody answers one at a time`
|
|
1142
1178
|
}).refine((manifest) => !(RESERVED_PURPOSE in manifest), {
|
|
1143
1179
|
message: `"${RESERVED_PURPOSE}" is reserved for a site that declares no purposes of its own \u2014 give this one a name from your own vocabulary`
|
|
1144
1180
|
});
|
|
@@ -1716,6 +1752,7 @@ var WithheldKind = z11.object({
|
|
|
1716
1752
|
z11.object({ service: z11.string().min(1), offer: OfferScope }).strict()
|
|
1717
1753
|
).min(2)
|
|
1718
1754
|
}).strict();
|
|
1755
|
+
var GrantRef = z11.object({ jobId: z11.string().min(1), leaseId: z11.string().min(1) }).strict();
|
|
1719
1756
|
var PairStartRequest = z11.object({
|
|
1720
1757
|
protocolVersion: z11.literal(PROTOCOL_VERSION),
|
|
1721
1758
|
action: z11.literal("start"),
|
|
@@ -1724,7 +1761,7 @@ var PairStartRequest = z11.object({
|
|
|
1724
1761
|
/** Shown in the app's runner list so a user can tell their machines apart. */
|
|
1725
1762
|
label: z11.string().min(1).max(120),
|
|
1726
1763
|
platform: z11.enum(["darwin", "linux", "win32"])
|
|
1727
|
-
}),
|
|
1764
|
+
}).strict(),
|
|
1728
1765
|
/**
|
|
1729
1766
|
* This machine's public keys (byollm_009 §5).
|
|
1730
1767
|
*
|
|
@@ -1861,9 +1898,7 @@ var HeartbeatRequest = z11.object({
|
|
|
1861
1898
|
* Lease ids rather than job ids, so a replayed heartbeat cannot renew a
|
|
1862
1899
|
* grant the runner no longer holds — see {@link Lease.id}.
|
|
1863
1900
|
*/
|
|
1864
|
-
activeLeases: z11.array(
|
|
1865
|
-
z11.object({ jobId: z11.string().min(1), leaseId: z11.string().min(1) })
|
|
1866
|
-
),
|
|
1901
|
+
activeLeases: z11.array(GrantRef),
|
|
1867
1902
|
/** True while the owner has the daemon paused; the server stops offering work. */
|
|
1868
1903
|
paused: z11.boolean()
|
|
1869
1904
|
}).strict();
|
|
@@ -2073,9 +2108,7 @@ var ReleaseRequest = z11.object({
|
|
|
2073
2108
|
* moment it arrives, which for a replayed request is not the lease the
|
|
2074
2109
|
* daemon meant. See {@link Lease.id}.
|
|
2075
2110
|
*/
|
|
2076
|
-
leases: z11.array(
|
|
2077
|
-
z11.object({ jobId: z11.string().min(1), leaseId: z11.string().min(1) })
|
|
2078
|
-
),
|
|
2111
|
+
leases: z11.array(GrantRef),
|
|
2079
2112
|
/**
|
|
2080
2113
|
* Why, so the app's runner list can say something true.
|
|
2081
2114
|
*
|
|
@@ -2281,6 +2314,7 @@ export {
|
|
|
2281
2314
|
GRANT_MAX_AGE_MS,
|
|
2282
2315
|
GRANT_SIGNED_FIELDS,
|
|
2283
2316
|
GeneratePayload,
|
|
2317
|
+
GrantRef,
|
|
2284
2318
|
HeartbeatRequest,
|
|
2285
2319
|
HeartbeatResponse,
|
|
2286
2320
|
JOB_KINDS,
|