@byollm/protocol 0.1.0-alpha.53 → 0.1.0-alpha.55
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 +110 -2
- package/dist/index.js +203 -100
- 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.55`) — 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.55` 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
|
@@ -1029,7 +1029,17 @@ declare function publicIdentityOf(keys: StoredKeys): PublicIdentity;
|
|
|
1029
1029
|
*/
|
|
1030
1030
|
declare function verifyPublicIdentity(identity: PublicIdentity): boolean;
|
|
1031
1031
|
/** Sign arbitrary bytes with an identity key. */
|
|
1032
|
-
|
|
1032
|
+
/**
|
|
1033
|
+
* Sign bytes with an identity key.
|
|
1034
|
+
*
|
|
1035
|
+
* Takes only the private half it uses. A signer that demanded a whole
|
|
1036
|
+
* {@link StoredKeys} would make every caller hold an encryption keypair for a
|
|
1037
|
+
* job that has no encryption in it — and the control plane, which signs
|
|
1038
|
+
* rosters and opens nothing, would be generating and storing secret material
|
|
1039
|
+
* it can never need. Every existing caller passes a full `StoredKeys`, which
|
|
1040
|
+
* satisfies this.
|
|
1041
|
+
*/
|
|
1042
|
+
declare function signWith(keys: Pick<StoredKeys, "identityPrivate">, data: Uint8Array): string;
|
|
1033
1043
|
/** Verify bytes against a raw Ed25519 public key. */
|
|
1034
1044
|
declare function verifyWith(identityPublic: string, data: Uint8Array, signature: string): boolean;
|
|
1035
1045
|
/**
|
|
@@ -1286,6 +1296,97 @@ declare function verifyRequest(input: {
|
|
|
1286
1296
|
maxSkewMs?: number;
|
|
1287
1297
|
}): SignatureFailure | null;
|
|
1288
1298
|
|
|
1299
|
+
/**
|
|
1300
|
+
* The roster a daemon holds, and how it knows the roster is real.
|
|
1301
|
+
*
|
|
1302
|
+
* byollm_001 Amendment G, RATIFIED 2026-08-25. A `team` job is admitted by a
|
|
1303
|
+
* list **this device holds**, signed by the owner's control plane and verified
|
|
1304
|
+
* against a key pinned at pairing — never by an assertion from the party
|
|
1305
|
+
* routing the job, per-job or in bulk.
|
|
1306
|
+
*
|
|
1307
|
+
* The relay's power over this is exactly denial: it can withhold a roster as
|
|
1308
|
+
* it can withhold a job, and it can forge neither. That is what lets the hub
|
|
1309
|
+
* go on reading and filtering rosters for its own routing without being
|
|
1310
|
+
* trusted for admission — non-authorship, not blindness.
|
|
1311
|
+
*/
|
|
1312
|
+
/**
|
|
1313
|
+
* How old a held roster may be before a device stops honouring it.
|
|
1314
|
+
*
|
|
1315
|
+
* One hour, and the shortest constant in this protocol on purpose: every other
|
|
1316
|
+
* one bounds how long a *thing* stays valid, and this one alone bounds how
|
|
1317
|
+
* long a *person* keeps access after the owner has said no.
|
|
1318
|
+
*
|
|
1319
|
+
* A failure bound, not a sync interval. A daemon refreshes on every heartbeat
|
|
1320
|
+
* and a removal propagates in seconds; the hour is what a device gets when
|
|
1321
|
+
* that conversation stops working — enough that a closed laptop or a flaky
|
|
1322
|
+
* café network does not narrow a working device, and not so much that a
|
|
1323
|
+
* removed teammate outlives the owner's patience.
|
|
1324
|
+
*/
|
|
1325
|
+
declare const ROSTER_MAX_AGE_MS: number;
|
|
1326
|
+
/**
|
|
1327
|
+
* The domain separator, and why a roster gets its own.
|
|
1328
|
+
*
|
|
1329
|
+
* Every signature in this system says what kind of statement it is before it
|
|
1330
|
+
* says anything else. Without that, bytes signed for one purpose verify for
|
|
1331
|
+
* another: a roster document and a request body are both "some bytes this key
|
|
1332
|
+
* signed", and a scheme that could not tell them apart would let a captured
|
|
1333
|
+
* roster be replayed as a request — or worse, let a control plane that signs
|
|
1334
|
+
* one thing be held to have signed the other.
|
|
1335
|
+
*/
|
|
1336
|
+
declare const ROSTER_CONTEXT = "byollm/v1/roster";
|
|
1337
|
+
declare const SignedRoster: z.ZodObject<{
|
|
1338
|
+
owner: z.ZodString;
|
|
1339
|
+
members: z.ZodArray<z.ZodString>;
|
|
1340
|
+
issuedAt: z.ZodNumber;
|
|
1341
|
+
signature: z.ZodString;
|
|
1342
|
+
}, z.core.$strict>;
|
|
1343
|
+
type SignedRoster = z.infer<typeof SignedRoster>;
|
|
1344
|
+
/**
|
|
1345
|
+
* The exact bytes both sides sign and verify.
|
|
1346
|
+
*
|
|
1347
|
+
* Every field that decides what the roster *means* is in here. Leave one out
|
|
1348
|
+
* and it becomes something an intermediary can change without breaking the
|
|
1349
|
+
* signature — `owner` most of all: a roster whose owner was not signed over
|
|
1350
|
+
* could be lifted from one account and delivered to another's devices, and
|
|
1351
|
+
* every signature check would pass.
|
|
1352
|
+
*
|
|
1353
|
+
* Members are joined with NUL, which cannot appear in an id, so no arrangement
|
|
1354
|
+
* of member names can imitate a different membership. Joining on a comma would
|
|
1355
|
+
* let `["a,b"]` and `["a","b"]` sign identically.
|
|
1356
|
+
*/
|
|
1357
|
+
declare function rosterStatement(input: {
|
|
1358
|
+
owner: string;
|
|
1359
|
+
members: readonly string[];
|
|
1360
|
+
issuedAt: number;
|
|
1361
|
+
}): Uint8Array;
|
|
1362
|
+
/** Sign a roster with the control plane's own key. */
|
|
1363
|
+
declare function signRoster(keys: Pick<StoredKeys, "identityPrivate">, input: {
|
|
1364
|
+
owner: string;
|
|
1365
|
+
members: readonly string[];
|
|
1366
|
+
issuedAt: number;
|
|
1367
|
+
}): SignedRoster;
|
|
1368
|
+
/** Why a roster was refused. Typed for logs; never returned to a caller. */
|
|
1369
|
+
type RosterRefusal = "bad-signature" | "wrong-owner" | "stale" | "from-the-future";
|
|
1370
|
+
/**
|
|
1371
|
+
* Is this roster one this device may admit people from, right now?
|
|
1372
|
+
*
|
|
1373
|
+
* `owner` is passed in rather than read out of the document, for the reason
|
|
1374
|
+
* {@link verifyLink} takes its successor as an argument: a verifier that
|
|
1375
|
+
* recovered the owner from the signed bytes would accept a genuine roster
|
|
1376
|
+
* belonging to somebody else, and every check would pass.
|
|
1377
|
+
*
|
|
1378
|
+
* Age is checked in **both** directions. A clock far ahead is as much a
|
|
1379
|
+
* problem as one behind: an `issuedAt` in the future would extend a roster's
|
|
1380
|
+
* life past the bound, which is the whole thing being enforced.
|
|
1381
|
+
*/
|
|
1382
|
+
declare function verifyRoster(input: {
|
|
1383
|
+
roster: SignedRoster;
|
|
1384
|
+
owner: string;
|
|
1385
|
+
controlPlanePublic: string;
|
|
1386
|
+
now: number;
|
|
1387
|
+
maxAgeMs?: number;
|
|
1388
|
+
}): RosterRefusal | null;
|
|
1389
|
+
|
|
1289
1390
|
/**
|
|
1290
1391
|
* Rotation — byollm_009 Amendment C.
|
|
1291
1392
|
*
|
|
@@ -1850,6 +1951,7 @@ declare const PairPollResponse: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
1850
1951
|
encryption: z.ZodString;
|
|
1851
1952
|
encryptionSig: z.ZodString;
|
|
1852
1953
|
}, z.core.$strict>>;
|
|
1954
|
+
controlPlanePublic: z.ZodOptional<z.ZodString>;
|
|
1853
1955
|
}, z.core.$strict>], "status">;
|
|
1854
1956
|
type PairPollResponse = z.infer<typeof PairPollResponse>;
|
|
1855
1957
|
declare const PairRequest: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
@@ -2082,6 +2184,12 @@ declare const HeartbeatResponse: z.ZodObject<{
|
|
|
2082
2184
|
}, z.core.$strict>>;
|
|
2083
2185
|
serverTime: z.ZodNumber;
|
|
2084
2186
|
awaitingConsent: z.ZodArray<z.ZodString>;
|
|
2187
|
+
roster: z.ZodOptional<z.ZodObject<{
|
|
2188
|
+
owner: z.ZodString;
|
|
2189
|
+
members: z.ZodArray<z.ZodString>;
|
|
2190
|
+
issuedAt: z.ZodNumber;
|
|
2191
|
+
signature: z.ZodString;
|
|
2192
|
+
}, z.core.$strict>>;
|
|
2085
2193
|
}, z.core.$strict>;
|
|
2086
2194
|
type HeartbeatResponse = z.infer<typeof HeartbeatResponse>;
|
|
2087
2195
|
/**
|
|
@@ -2217,4 +2325,4 @@ declare const FetchResponse: z.ZodObject<{
|
|
|
2217
2325
|
}, z.core.$strict>;
|
|
2218
2326
|
type FetchResponse = z.infer<typeof FetchResponse>;
|
|
2219
2327
|
|
|
2220
|
-
export { AUDIENCES, Audience, BACKENDS, BACKEND_IDS, BackendClass, BackendCost, type BackendDescriptor, type BackendId, BackendIdSchema, 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, GeneratePayload, 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, 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, REFUSAL_MESSAGES, RETIREMENT_WINDOW_MS, RefusalReason, ReleaseRequest, ReleaseResponse, RequestSignature, ResultDisposition, ResultProvenance, ResultRequest, ResultResponse, RunMetadata, SIZE_CLASS_LIMITS, SUCCESSION_CONTEXT, SUPPORTED_PROTOCOL_VERSIONS, SealedEnvelope, SealedOutcome, type SignatureFailure, 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, isBackendId, isCloudTaggedModel, isJobKind, isLocalHost, isTerminal, keyId, kindsOf, matchAudience, mustsVerifiedBy, open, payloadTextLength, provenanceFor, publicIdentityOf, resolveCost, seal, signRequest, signSiteRequest, signSuccession, signWith, sizeClassCeiling, sizeClassOf, successionStatement, verifyLink, verifyPublicIdentity, verifyRequest, verifySiteRequest, verifyWith, walkSuccession };
|
|
2328
|
+
export { AUDIENCES, Audience, BACKENDS, BACKEND_IDS, BackendClass, BackendCost, type BackendDescriptor, type BackendId, BackendIdSchema, 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, GeneratePayload, 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, 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, REFUSAL_MESSAGES, RETIREMENT_WINDOW_MS, ROSTER_CONTEXT, ROSTER_MAX_AGE_MS, RefusalReason, ReleaseRequest, ReleaseResponse, RequestSignature, ResultDisposition, ResultProvenance, ResultRequest, ResultResponse, type RosterRefusal, RunMetadata, SIZE_CLASS_LIMITS, SUCCESSION_CONTEXT, SUPPORTED_PROTOCOL_VERSIONS, SealedEnvelope, SealedOutcome, type SignatureFailure, SignedRoster, 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, isBackendId, isCloudTaggedModel, isJobKind, isLocalHost, isTerminal, keyId, kindsOf, matchAudience, mustsVerifiedBy, open, payloadTextLength, provenanceFor, publicIdentityOf, resolveCost, rosterStatement, seal, signRequest, signRoster, signSiteRequest, signSuccession, signWith, sizeClassCeiling, sizeClassOf, successionStatement, verifyLink, verifyPublicIdentity, verifyRequest, verifyRoster, verifySiteRequest, verifyWith, walkSuccession };
|