@byollm/protocol 0.1.0-alpha.98 → 0.1.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.
- package/README.md +8 -15
- package/dist/{chunk-W7Q7DKQ6.js → chunk-J3HTAGMX.js} +18 -2
- package/dist/chunk-J3HTAGMX.js.map +1 -0
- package/dist/index.d.ts +224 -52
- package/dist/index.js +98 -15
- package/dist/index.js.map +1 -1
- package/dist/{portable-D2mu8USa.d.ts → portable-C6rfiCXi.d.ts} +35 -1
- package/dist/portable.d.ts +1 -1
- package/dist/portable.js +7 -1
- package/package.json +2 -2
- package/dist/chunk-W7Q7DKQ6.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
> [!WARNING]
|
|
2
|
-
> **Alpha (`0.1.0-alpha.98`) — under active development. Don't use this yet.**
|
|
3
|
-
>
|
|
4
|
-
> Install it deliberately: `npm install @byollm/protocol@alpha`.
|
|
5
|
-
>
|
|
6
|
-
> The protocol is v0 and **will** change without a deprecation path, this has
|
|
7
|
-
> never run outside its own test suite, and nothing here has production miles.
|
|
8
|
-
> Read it, take the ideas, tell us what's wrong — but don't put it in front of
|
|
9
|
-
> your users.
|
|
10
|
-
>
|
|
11
|
-
> npm assigns `latest` on a first publish and won't let it be removed, so a
|
|
12
|
-
> bare install resolves here too. This notice is the only guard — deliberately
|
|
13
|
-
> not an npm deprecation, which would read as *abandoned* rather than *early*.
|
|
14
|
-
> Ask for `@alpha` explicitly so your lockfile records that you meant to.>
|
|
15
1
|
> **`alpha.15` is a breaking wire change, and it breaks daemons and relays —
|
|
16
2
|
> not app authors.** If you call `app.enqueue(...)` and read results, nothing
|
|
17
3
|
> in your code changes. If you run a daemon or an upstream, every package must
|
|
@@ -183,7 +169,7 @@ to know which one happened.
|
|
|
183
169
|
|
|
184
170
|
## Normative spec
|
|
185
171
|
|
|
186
|
-
[`docs/protocol.md`](
|
|
172
|
+
[`docs/protocol.md`](https://github.com/oftomorrowinc/byollm/blob/main/docs/protocol.md). Every MUST there carries a
|
|
187
173
|
conformance id that appears in this package's `MUSTS` registry.
|
|
188
174
|
|
|
189
175
|
MIT
|
|
@@ -200,4 +186,11 @@ Six packages, and they are only interesting together:
|
|
|
200
186
|
- [`@byollm/control-plane`](https://www.npmjs.com/package/@byollm/control-plane) — who may ask whom, and the policy store behind it
|
|
201
187
|
- [`@byollm/conformance`](https://www.npmjs.com/package/@byollm/conformance) — the kit that proves an implementation is one — including a posture audit that holds nothing but a URL
|
|
202
188
|
|
|
189
|
+
### Where the rest lives
|
|
190
|
+
|
|
191
|
+
- [GitHub](https://github.com/oftomorrowinc/byollm) — the source, and where issues go
|
|
192
|
+
- [byo-llm.com](https://byo-llm.com) — what this is, and why
|
|
193
|
+
- [byollm.cloud](https://byollm.cloud) — the hosted relay — devices, consent and billing
|
|
194
|
+
- [docs.byollm.cloud](https://docs.byollm.cloud) — integrating a site, end to end
|
|
195
|
+
|
|
203
196
|
<!-- family:end -->
|
|
@@ -96,7 +96,20 @@ function decodeEnvelopeInner(text) {
|
|
|
96
96
|
import { z as z2 } from "zod";
|
|
97
97
|
var CONSOLE_FRAME_VERSION = "byollm/v1/console";
|
|
98
98
|
var CONSOLE_MAX_DATA_BYTES = 64 * 1024;
|
|
99
|
-
|
|
99
|
+
function encodeConsoleData(bytes) {
|
|
100
|
+
return toBase64Url(bytes);
|
|
101
|
+
}
|
|
102
|
+
function decodeConsoleData(text) {
|
|
103
|
+
const padding = /(={0,2})$/.exec(text)?.[1]?.length ?? 0;
|
|
104
|
+
const body = text.slice(0, text.length - padding);
|
|
105
|
+
return fromBase64Url(body.replace(/\+/g, "-").replace(/\//g, "_"));
|
|
106
|
+
}
|
|
107
|
+
function consoleDataBytes(data2) {
|
|
108
|
+
return decodeConsoleData(data2) ?? new Uint8Array();
|
|
109
|
+
}
|
|
110
|
+
var data = z2.string().max(Math.ceil(CONSOLE_MAX_DATA_BYTES * 4 / 3) + 4).refine((text) => decodeConsoleData(text) !== void 0, {
|
|
111
|
+
message: "not base64"
|
|
112
|
+
});
|
|
100
113
|
var cols = z2.number().int().min(1).max(1e4);
|
|
101
114
|
var rows = z2.number().int().min(1).max(1e4);
|
|
102
115
|
var seq = z2.number().int().positive();
|
|
@@ -214,6 +227,9 @@ export {
|
|
|
214
227
|
decodeEnvelopeInner,
|
|
215
228
|
CONSOLE_FRAME_VERSION,
|
|
216
229
|
CONSOLE_MAX_DATA_BYTES,
|
|
230
|
+
encodeConsoleData,
|
|
231
|
+
decodeConsoleData,
|
|
232
|
+
consoleDataBytes,
|
|
217
233
|
ConsoleHello,
|
|
218
234
|
ConsoleStdin,
|
|
219
235
|
ConsoleStdout,
|
|
@@ -223,4 +239,4 @@ export {
|
|
|
223
239
|
consoleEnvelope,
|
|
224
240
|
consoleOrder
|
|
225
241
|
};
|
|
226
|
-
//# sourceMappingURL=chunk-
|
|
242
|
+
//# sourceMappingURL=chunk-J3HTAGMX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/public-identity.ts","../src/envelope-format.ts","../src/console.ts"],"sourcesContent":["import { z } from \"zod\";\n\n/**\n * A party's public keys, as they travel — extracted from `keys.ts` for B018c.\n *\n * ## Why it lives on its own\n *\n * The browser end of a console session needs this SCHEMA at runtime, and\n * `keys.ts` is irreducibly node-only: `generateKeyPairSync`,\n * `createPrivateKey`, `createHash`. So every route to the console types\n * dragged the node world into a bundle meant for a tab.\n *\n * Nothing about the shape changed. `keys.ts` re-exports it, so every existing\n * import still resolves and the wire is untouched — this is a file move, and\n * the tests that were passing before it are the proof.\n *\n * Pure zod: no crypto, no node, nothing to make unportable later.\n */\nexport const PublicIdentity = z\n .object({\n /** Raw Ed25519 public key. The pinned one. */\n identity: z.string().min(1),\n /** Raw X25519 public key, for sealing to this party. */\n encryption: z.string().min(1),\n /**\n * Ed25519 signature over the encryption key, by the identity key.\n *\n * This is what stops an upstream substituting an encryption key of its\n * own while relaying a genuine identity: the receiver pins the identity\n * and refuses any encryption key not signed by it.\n */\n encryptionSig: z.string().min(1),\n })\n .strict();\nexport type PublicIdentity = z.infer<typeof PublicIdentity>;\n","/**\n * The envelope's FORMAT, with no primitives and no platform — B018c step 3.\n *\n * ## Why this file exists\n *\n * The browser is one of the two ends a console stream is encrypted between,\n * and it cannot run `envelope.ts`: the sealing is WASM and portable, but the\n * inner signature goes through `node:crypto`'s Ed25519. So the browser needs\n * its own primitives.\n *\n * What it must NOT have is its own *format*. Two implementations of \"which\n * bytes get signed\" is the defect class this codebase spends most of its\n * checks on, and here the two copies would diverge silently — a mismatched\n * signature is indistinguishable from an attack, so the first symptom would\n * be a console that refuses to open and a log line saying `bad-signature`.\n *\n * Everything here is therefore pure: no `node:` imports, no `Buffer`, no\n * `btoa`. `envelope-is-portable.test.ts` asserts that mechanically, because\n * \"somebody will import Buffer for convenience one day\" is a prediction, and\n * this project's rule is that a prediction ships with the test that catches it.\n *\n * ## Why base64url is written out by hand\n *\n * `Buffer` is Node's and `btoa` takes a binary string, so neither is both\n * portable and pleasant. Twenty lines of table lookup is: it agrees with\n * `Buffer` on every byte value, which the test proves rather than assumes.\n */\n\nconst ALPHABET =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n/** Indexed as an array so the compiler knows every lookup lands. */\nconst CHARS: readonly string[] = ALPHABET.split(\"\");\n\n/** Reverse table, built once. 255 marks \"not a base64url character\". */\nconst VALUES = /* @__PURE__ */ (() => {\n const table = new Uint8Array(128).fill(255);\n for (let at = 0; at < ALPHABET.length; at += 1) {\n table[ALPHABET.charCodeAt(at)] = at;\n }\n return table;\n})();\n\n/** Unpadded base64url, the encoding every key and signature on this wire uses. */\nexport function toBase64Url(bytes: Uint8Array): string {\n let out = \"\";\n for (let at = 0; at < bytes.length; at += 3) {\n const a = bytes[at] ?? 0;\n const b = bytes[at + 1];\n const c = bytes[at + 2];\n const word = (a << 16) | ((b ?? 0) << 8) | (c ?? 0);\n out += CHARS[(word >> 18) & 63] ?? \"\";\n out += CHARS[(word >> 12) & 63] ?? \"\";\n if (b !== undefined) out += CHARS[(word >> 6) & 63] ?? \"\";\n if (c !== undefined) out += CHARS[word & 63] ?? \"\";\n }\n return out;\n}\n\n/** The inverse. Returns undefined rather than throwing — this parses input. */\nexport function fromBase64Url(text: string): Uint8Array | undefined {\n const length = text.length;\n // 1 leftover character cannot encode any whole byte.\n if (length % 4 === 1) return undefined;\n const bytes = new Uint8Array(Math.floor((length * 3) / 4));\n let written = 0;\n let word = 0;\n let bits = 0;\n for (let at = 0; at < length; at += 1) {\n const code = text.charCodeAt(at);\n const value = code < 128 ? VALUES[code] : 255;\n if (value === undefined || value === 255) return undefined;\n word = (word << 6) | value;\n bits += 6;\n if (bits >= 8) {\n bits -= 8;\n bytes[written] = (word >> bits) & 0xff;\n written += 1;\n }\n }\n return bytes.subarray(0, written);\n}\n\n/** Domain tag for the bytes an envelope's signature covers. */\nexport const ENVELOPE_BODY_VERSION = \"byollm/v1/envelope\";\n\n/** What an envelope's signature is over — the fields, in this order. */\nexport interface EnvelopeBodyContext {\n readonly jobId: string;\n readonly senderKeyId: string;\n readonly recipientKeyId: string;\n readonly deadlineAt: number;\n readonly direction: string;\n}\n\n/**\n * The exact bytes an envelope's signature covers.\n *\n * **Field order is part of the format**, because `JSON.stringify` emits keys\n * in insertion order and the verifier hashes bytes, not meaning. Reordering\n * these lines is a wire change that no type would catch and every signature\n * would fail — which is why they are written out rather than spread from an\n * object somebody could reshape.\n */\nexport function envelopeSignedBody(\n context: EnvelopeBodyContext,\n plaintext: string,\n): Uint8Array {\n return new TextEncoder().encode(\n JSON.stringify({\n v: ENVELOPE_BODY_VERSION,\n jobId: context.jobId,\n senderKeyId: context.senderKeyId,\n recipientKeyId: context.recipientKeyId,\n deadlineAt: context.deadlineAt,\n direction: context.direction,\n plaintext,\n }),\n );\n}\n\n/** The signed body and its signature, as they travel inside the sealed box. */\nexport function encodeEnvelopeInner(\n body: Uint8Array,\n signature: string,\n): string {\n return JSON.stringify({ body: toBase64Url(body), signature });\n}\n\nexport interface EnvelopeInner {\n readonly body: Uint8Array;\n readonly signature: string;\n}\n\n/**\n * Read the inner object back.\n *\n * Returns undefined for anything malformed rather than throwing, because\n * every byte reaching this has come out of a decryption and is therefore\n * input — `malformed` is one of the outcomes `open()` already distinguishes.\n */\nexport function decodeEnvelopeInner(text: string): EnvelopeInner | undefined {\n let parsed: { body?: unknown; signature?: unknown };\n try {\n parsed = JSON.parse(text) as { body?: unknown; signature?: unknown };\n } catch {\n return undefined;\n }\n if (typeof parsed.body !== \"string\" || typeof parsed.signature !== \"string\") {\n return undefined;\n }\n const body = fromBase64Url(parsed.body);\n if (body === undefined) return undefined;\n return { body, signature: parsed.signature };\n}\n","import { z } from \"zod\";\nimport { fromBase64Url, toBase64Url } from \"./envelope-format.js\";\nimport { PublicIdentity } from \"./public-identity.js\";\nimport type { EnvelopeContext } from \"./envelope.js\";\n\n/**\n * The terminal stream a hosted box's console runs over — byollm_018 §\"Console\n * redesign: brokered E2E replaces SSH-first (RULED, Todd 2026-09-03)\".\n *\n * The ruling's item 3 is the whole reason this file exists: *\"The terminal\n * stream is E2E encrypted browser↔agent with the sealed-channel pattern jobs\n * use; the hub routes ciphertext.\"* So the bytes are carried by\n * {@link seal}/{@link open} exactly as a job's payload is, and what is defined\n * here is the thing a sealed envelope does not carry: **what a frame means,\n * and where it sits in the stream.**\n *\n * ## Why an ordering rule is protocol and not an implementation detail\n *\n * Sealing makes the hub unable to READ the stream. It does nothing to make\n * the hub unable to reshape it. A router that holds ciphertext can drop a\n * frame, deliver two out of order, or send the same frame twice, and every\n * envelope still opens, still verifies against the pinned identity, and still\n * looks perfect to the receiver — because each envelope is authenticated on\n * its own and says nothing about the ones around it.\n *\n * On a terminal that is not a theoretical loss of tidiness. A dropped\n * keystroke is a different command; two frames swapped is a different command;\n * a replayed frame is a command run twice. The console carries vendor\n * sign-in flows (byollm_018 item 5), so \"a different command\" can mean an auth\n * code going somewhere it was not typed.\n *\n * Hence {@link consoleOrder}: a sequence inside the ciphertext, checked by\n * both ends. Inside, because a counter the hub could see is a counter the hub\n * could rewrite.\n *\n * ## One definition, both ends, and there are three ends\n *\n * The browser, the box's agent, and the hub broker all handle these frames,\n * and the first two must agree byte for byte or the stream silently corrupts.\n * The hub must NOT be able to agree — it only ever sees the sealed envelope.\n * This module is the single definition the two real ends share; neither\n * retypes it.\n *\n * ## The pinned box key is the PAIRING key (CCB's call, 09-16)\n *\n * The ruling says \"box key pinned at first session\", and the backlog left one\n * delta open: whether the identity the owner already approved at pairing can\n * serve as that pinned key. It can, and it should, for three reasons.\n *\n * 1. **The pairing key is the only one a human ever chose.** `PairStartRequest`\n * carries the device's {@link PublicIdentity} and says why: *\"Pairing is\n * where the two parties learn each other's identities, because it is the\n * one moment a human is already deciding to trust: the approval click. A\n * key exchanged anywhere else would be a key nobody chose.\"* A fresh\n * trust-on-first-use pin at the first console session is precisely a key\n * nobody chose — it trusts whoever answers first, which on a brokered\n * channel is whoever the broker points at.\n * 2. **Two pins of one box can disagree, and silently.** A console pin\n * separate from the pairing pin is a second record of the same fact, which\n * is this project's most-repeated defect. When they diverge, nothing reads\n * both, so nothing notices.\n * 3. **Alarm-on-change comes free from the split already in `keys.ts`.** The\n * Ed25519 identity is the pinned half and the X25519 encryption key is\n * signed by it, so {@link verifyPublicIdentity} lets the box rotate its\n * encryption key without a new ceremony while an IDENTITY change fails to\n * verify and alarms — which is what the ruling asks for, and it is already\n * written.\n *\n * **What this does not claim.** Pinning the pairing key does not make the hub\n * unable to lie about which key that was; the hub is the one telling the\n * browser. The ruling is explicit that we build the operator-ACCOUNTABLE\n * version, not the operator-incapable one, and item 4's session feed is where\n * that accountability is paid. What the pin buys is that a CHANGE is\n * detectable, and that the key being pinned is one an owner approved rather\n * than one a broker supplied.\n */\n\n/** Domain tag for the plaintext inside a console envelope. */\nexport const CONSOLE_FRAME_VERSION = \"byollm/v1/console\";\n\n/**\n * The largest `data` payload one frame may carry, before base64.\n *\n * Far below {@link MAX_ENVELOPE_BYTES}, and deliberately: an envelope cap\n * stops a memory attack, while this stops a latency one. A console is\n * interactive, so a peer that batches a megabyte into one frame has made the\n * stream unusable without ever exceeding a limit.\n */\nexport const CONSOLE_MAX_DATA_BYTES = 64 * 1024;\n\n/**\n * Encode one frame's payload. Canonical, and the only encoder either end may\n * use — see {@link decodeConsoleData} for what retyping it cost.\n */\nexport function encodeConsoleData(bytes: Uint8Array): string {\n return toBase64Url(bytes);\n}\n\n/**\n * Decode one frame's payload, accepting either base64 alphabet.\n *\n * The two alphabets disagree on three characters — `+`, `/`, and the `=`\n * padding — and a box that encoded with Node's standard base64 produced\n * frames that sealed, opened, verified against the pinned identity, and\n * ordered correctly, and then decoded to nothing in a strict base64url\n * reader. Nothing faulted, because a decode that returns nothing is not a\n * fault anywhere in this file. What an operator saw was a console that ate\n * every keystroke and roughly two output chunks in three: one typed character\n * is one byte, which always pads, while a longer chunk survives exactly when\n * its length is a multiple of three and its bytes happen to avoid `+` and `/`.\n *\n * So the tolerance here is deliberate, not lax. A box is software on someone\n * else's machine, and a browser that accepted only the canonical spelling\n * would fix the console for whoever upgraded and for nobody else. Anything\n * that is neither spelling still returns `undefined`, and {@link ConsoleFrame}\n * rejects it at the schema so it fails loudly rather than vanishing.\n */\nexport function decodeConsoleData(text: string): Uint8Array | undefined {\n /* Base64 pads to a multiple of four with at most two `=`. More than two is\n not a lenient spelling of anything, so it falls through and is refused. */\n const padding = /(={0,2})$/.exec(text)?.[1]?.length ?? 0;\n const body = text.slice(0, text.length - padding);\n return fromBase64Url(body.replace(/\\+/g, \"-\").replace(/\\//g, \"_\"));\n}\n\n/**\n * The bytes of a payload that has already passed {@link ConsoleFrame}.\n *\n * Total on purpose. The schema refuses a payload that cannot be read, so both\n * ends would otherwise carry a fallback arm that no input can reach — and an\n * arm nothing can reach is an arm nothing can test. The guarantee lives here,\n * once, where a test can hold it to both answers.\n */\nexport function consoleDataBytes(data: string): Uint8Array {\n return decodeConsoleData(data) ?? new Uint8Array();\n}\n\nconst data = z\n .string()\n .max(Math.ceil((CONSOLE_MAX_DATA_BYTES * 4) / 3) + 4)\n /* A law with a check. This field spent its whole life described as base64\n and validated as nothing, which is why a box could disagree with a\n browser about what it was sending and no test anywhere could tell. */\n .refine((text) => decodeConsoleData(text) !== undefined, {\n message: \"not base64\",\n });\n\n/** Terminal geometry. Bounded because a pty rejects absurd sizes anyway. */\nconst cols = z.number().int().min(1).max(10_000);\nconst rows = z.number().int().min(1).max(10_000);\n\n/**\n * A frame's position in its direction's stream. Starts at 1, never repeats,\n * never skips — see {@link consoleOrder} for what each of those catches.\n */\nconst seq = z.number().int().positive();\n\nexport const ConsoleHello = z\n .object({\n v: z.literal(CONSOLE_FRAME_VERSION),\n kind: z.literal(\"hello\"),\n seq: z.literal(1),\n /**\n * The browser's EPHEMERAL identity for this session, and the reason hello\n * exists as its own frame.\n *\n * A browser has no long-term key — it is a tab, not a machine — so it\n * generates one per session and the box seals its output to it. That key\n * has to reach the box without the hub being able to substitute one of its\n * own, which is the classic broker attack. So it travels SEALED TO THE\n * BOX'S PINNED IDENTITY like every other frame: the hub cannot read it and\n * cannot replace it, because replacing it means producing a sealed box\n * the box's key opens and the browser's key signed.\n *\n * The box does not pin this. It cannot — it is new every session, and\n * nothing authorises it cryptographically. What authorises the browser is\n * the hub's per-session grant (ruling item 2); what this key does is keep\n * the hub from READING what it authorised.\n */\n browser: PublicIdentity,\n cols,\n rows,\n })\n .strict();\nexport type ConsoleHello = z.infer<typeof ConsoleHello>;\n\n/**\n * Two schemas rather than one with a `kind: z.enum([...])`, because the union\n * below discriminates on `kind` and a discriminator that is itself a set is\n * how a union quietly stops discriminating.\n */\nexport const ConsoleStdin = z\n .object({\n v: z.literal(CONSOLE_FRAME_VERSION),\n /** Browser→box only. A `stdin` arriving from the box is `wrong-way`. */\n kind: z.literal(\"stdin\"),\n seq,\n data,\n })\n .strict();\nexport type ConsoleStdin = z.infer<typeof ConsoleStdin>;\n\nexport const ConsoleStdout = z\n .object({\n v: z.literal(CONSOLE_FRAME_VERSION),\n /** Box→browser only. */\n kind: z.literal(\"stdout\"),\n seq,\n data,\n })\n .strict();\nexport type ConsoleStdout = z.infer<typeof ConsoleStdout>;\n\nexport const ConsoleResize = z\n .object({\n v: z.literal(CONSOLE_FRAME_VERSION),\n kind: z.literal(\"resize\"),\n seq,\n cols,\n rows,\n })\n .strict();\nexport type ConsoleResize = z.infer<typeof ConsoleResize>;\n\nexport const ConsoleBye = z\n .object({\n v: z.literal(CONSOLE_FRAME_VERSION),\n kind: z.literal(\"bye\"),\n seq,\n /** Shown to the owner in the session feed, so it is a sentence. */\n reason: z.string().min(1).max(200),\n })\n .strict();\nexport type ConsoleBye = z.infer<typeof ConsoleBye>;\n\nexport const ConsoleFrame = z.discriminatedUnion(\"kind\", [\n ConsoleHello,\n ConsoleStdin,\n ConsoleStdout,\n ConsoleResize,\n ConsoleBye,\n]);\nexport type ConsoleFrame = z.infer<typeof ConsoleFrame>;\n\n/**\n * The envelope context for a console frame.\n *\n * Exported so that neither end computes it: the session id goes in `jobId`\n * and the direction is derived, and if the two ends disagreed about either,\n * every envelope would fail to open with `not-for-us` — a failure that looks\n * exactly like an attack.\n */\nexport function consoleEnvelope(input: {\n sessionId: string;\n from: \"browser\" | \"box\";\n senderKeyId: string;\n recipientKeyId: string;\n deadlineAt: number;\n}): EnvelopeContext {\n return {\n jobId: input.sessionId,\n senderKeyId: input.senderKeyId,\n recipientKeyId: input.recipientKeyId,\n deadlineAt: input.deadlineAt,\n direction: input.from === \"browser\" ? \"payload\" : \"result\",\n };\n}\n\n/** Why a frame was refused. Each one is a distinct thing a router can do. */\nexport type ConsoleOrderFault =\n /** Seq went backwards or repeated — the router sent it twice. */\n | \"replayed\"\n /** Seq skipped — the router dropped what was between. */\n | \"gap\"\n /** A `hello` that was not the first frame, or a first frame that was not `hello`. */\n | \"out-of-turn\"\n /** A `stdin` from the box, or a `stdout` from the browser. */\n | \"wrong-way\"\n /** Anything after `bye`. The stream is over. */\n | \"closed\";\n\nexport type ConsoleOrderResult =\n | { readonly ok: true }\n | { readonly ok: false; readonly fault: ConsoleOrderFault };\n\n/**\n * One direction's ordering rule, which both ends run over what they receive.\n *\n * **Strictly +1, not merely increasing.** Increasing would catch replay and\n * reorder while letting a DROP through silently, and a dropped frame on a\n * terminal is a truncated command that still runs. There is no benign gap\n * here to tolerate: the transport underneath is an ordered, reliable stream,\n * so a gap means something between the ends removed a frame.\n *\n * Every fault is fatal to the session by design. A console has no\n * resynchronisation story that is safe — you cannot ask \"what did I miss\" of\n * a party that may be the one who took it.\n */\n/**\n * One direction's receiver-side ordering state.\n *\n * Named as an interface rather than inferred, so the box's agent and the\n * browser hold the SAME type — an inferred one would let the two ends drift\n * apart without a compiler ever objecting.\n */\nexport interface ConsoleOrder {\n /** The last sequence accepted. 0 before anything has been. */\n readonly seen: number;\n accept(frame: ConsoleFrame): ConsoleOrderResult;\n}\n\nexport function consoleOrder(from: \"browser\" | \"box\"): ConsoleOrder {\n /**\n * The two directions are NOT symmetric, and reading them as symmetric was\n * this function's first bug: `hello` carries the browser's ephemeral key, so\n * the browser sends exactly one and the box never sends any. A rule that\n * demanded a leading `hello` in both directions would reject every real box\n * stream at its first frame.\n */\n /**\n * What this side is allowed to send AT ALL, rather than a special case per\n * kind. CW's review caught `resize` travelling box→browser unchecked: the\n * rule named stdin and stdout and said nothing about the rest, so every\n * kind added later would have defaulted to \"allowed in both directions\"\n * and needed somebody to notice. A list of what each side may send has no\n * default to forget.\n */\n const maySend: Readonly<Record<\"browser\" | \"box\", readonly string[]>> = {\n // The browser drives: it opens, it types, it sets the size, it leaves.\n browser: [\"hello\", \"stdin\", \"resize\", \"bye\"],\n // The box answers, and can end a session. Nothing else.\n box: [\"stdout\", \"bye\"],\n };\n const allowed = maySend[from];\n const opensWithHello = from === \"browser\";\n\n let last = 0;\n let closed = false;\n\n return {\n /** The last sequence accepted. 0 before anything has been. */\n get seen(): number {\n return last;\n },\n accept(frame: ConsoleFrame): ConsoleOrderResult {\n if (closed) return { ok: false, fault: \"closed\" };\n\n if (!allowed.includes(frame.kind)) {\n return { ok: false, fault: \"wrong-way\" };\n }\n\n // `hello` opens the browser's stream, appears once, and never opens the\n // box's. Both halves matter: a second `hello` mid-stream would be a new\n // browser key, which is the substitution the sealing exists to stop.\n const isFirst = last === 0;\n const wantsHello = isFirst && opensWithHello;\n if (wantsHello !== (frame.kind === \"hello\")) {\n return { ok: false, fault: \"out-of-turn\" };\n }\n\n if (frame.seq <= last) return { ok: false, fault: \"replayed\" };\n if (frame.seq !== last + 1) return { ok: false, fault: \"gap\" };\n\n last = frame.seq;\n if (frame.kind === \"bye\") closed = true;\n return { ok: true };\n },\n };\n}\n"],"mappings":";AAAA,SAAS,SAAS;AAkBX,IAAM,iBAAiB,EAC3B,OAAO;AAAA;AAAA,EAEN,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA,EAE1B,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ5B,eAAe,EAAE,OAAO,EAAE,IAAI,CAAC;AACjC,CAAC,EACA,OAAO;;;ACLV,IAAM,WACJ;AAGF,IAAM,QAA2B,SAAS,MAAM,EAAE;AAGlD,IAAM,SAA0B,uBAAM;AACpC,QAAM,QAAQ,IAAI,WAAW,GAAG,EAAE,KAAK,GAAG;AAC1C,WAAS,KAAK,GAAG,KAAK,SAAS,QAAQ,MAAM,GAAG;AAC9C,UAAM,SAAS,WAAW,EAAE,CAAC,IAAI;AAAA,EACnC;AACA,SAAO;AACT,GAAG;AAGI,SAAS,YAAY,OAA2B;AACrD,MAAI,MAAM;AACV,WAAS,KAAK,GAAG,KAAK,MAAM,QAAQ,MAAM,GAAG;AAC3C,UAAM,IAAI,MAAM,EAAE,KAAK;AACvB,UAAM,IAAI,MAAM,KAAK,CAAC;AACtB,UAAM,IAAI,MAAM,KAAK,CAAC;AACtB,UAAM,OAAQ,KAAK,MAAQ,KAAK,MAAM,KAAM,KAAK;AACjD,WAAO,MAAO,QAAQ,KAAM,EAAE,KAAK;AACnC,WAAO,MAAO,QAAQ,KAAM,EAAE,KAAK;AACnC,QAAI,MAAM,OAAW,QAAO,MAAO,QAAQ,IAAK,EAAE,KAAK;AACvD,QAAI,MAAM,OAAW,QAAO,MAAM,OAAO,EAAE,KAAK;AAAA,EAClD;AACA,SAAO;AACT;AAGO,SAAS,cAAc,MAAsC;AAClE,QAAM,SAAS,KAAK;AAEpB,MAAI,SAAS,MAAM,EAAG,QAAO;AAC7B,QAAM,QAAQ,IAAI,WAAW,KAAK,MAAO,SAAS,IAAK,CAAC,CAAC;AACzD,MAAI,UAAU;AACd,MAAI,OAAO;AACX,MAAI,OAAO;AACX,WAAS,KAAK,GAAG,KAAK,QAAQ,MAAM,GAAG;AACrC,UAAM,OAAO,KAAK,WAAW,EAAE;AAC/B,UAAM,QAAQ,OAAO,MAAM,OAAO,IAAI,IAAI;AAC1C,QAAI,UAAU,UAAa,UAAU,IAAK,QAAO;AACjD,WAAQ,QAAQ,IAAK;AACrB,YAAQ;AACR,QAAI,QAAQ,GAAG;AACb,cAAQ;AACR,YAAM,OAAO,IAAK,QAAQ,OAAQ;AAClC,iBAAW;AAAA,IACb;AAAA,EACF;AACA,SAAO,MAAM,SAAS,GAAG,OAAO;AAClC;AAGO,IAAM,wBAAwB;AAoB9B,SAAS,mBACd,SACA,WACY;AACZ,SAAO,IAAI,YAAY,EAAE;AAAA,IACvB,KAAK,UAAU;AAAA,MACb,GAAG;AAAA,MACH,OAAO,QAAQ;AAAA,MACf,aAAa,QAAQ;AAAA,MACrB,gBAAgB,QAAQ;AAAA,MACxB,YAAY,QAAQ;AAAA,MACpB,WAAW,QAAQ;AAAA,MACnB;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAGO,SAAS,oBACd,MACA,WACQ;AACR,SAAO,KAAK,UAAU,EAAE,MAAM,YAAY,IAAI,GAAG,UAAU,CAAC;AAC9D;AAcO,SAAS,oBAAoB,MAAyC;AAC3E,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,IAAI;AAAA,EAC1B,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,OAAO,OAAO,SAAS,YAAY,OAAO,OAAO,cAAc,UAAU;AAC3E,WAAO;AAAA,EACT;AACA,QAAM,OAAO,cAAc,OAAO,IAAI;AACtC,MAAI,SAAS,OAAW,QAAO;AAC/B,SAAO,EAAE,MAAM,WAAW,OAAO,UAAU;AAC7C;;;AC1JA,SAAS,KAAAA,UAAS;AA8EX,IAAM,wBAAwB;AAU9B,IAAM,yBAAyB,KAAK;AAMpC,SAAS,kBAAkB,OAA2B;AAC3D,SAAO,YAAY,KAAK;AAC1B;AAqBO,SAAS,kBAAkB,MAAsC;AAGtE,QAAM,UAAU,YAAY,KAAK,IAAI,IAAI,CAAC,GAAG,UAAU;AACvD,QAAM,OAAO,KAAK,MAAM,GAAG,KAAK,SAAS,OAAO;AAChD,SAAO,cAAc,KAAK,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,CAAC;AACnE;AAUO,SAAS,iBAAiBC,OAA0B;AACzD,SAAO,kBAAkBA,KAAI,KAAK,IAAI,WAAW;AACnD;AAEA,IAAM,OAAOC,GACV,OAAO,EACP,IAAI,KAAK,KAAM,yBAAyB,IAAK,CAAC,IAAI,CAAC,EAInD,OAAO,CAAC,SAAS,kBAAkB,IAAI,MAAM,QAAW;AAAA,EACvD,SAAS;AACX,CAAC;AAGH,IAAM,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAM;AAC/C,IAAM,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAM;AAM/C,IAAM,MAAMA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAE/B,IAAM,eAAeA,GACzB,OAAO;AAAA,EACN,GAAGA,GAAE,QAAQ,qBAAqB;AAAA,EAClC,MAAMA,GAAE,QAAQ,OAAO;AAAA,EACvB,KAAKA,GAAE,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBhB,SAAS;AAAA,EACT;AAAA,EACA;AACF,CAAC,EACA,OAAO;AAQH,IAAM,eAAeA,GACzB,OAAO;AAAA,EACN,GAAGA,GAAE,QAAQ,qBAAqB;AAAA;AAAA,EAElC,MAAMA,GAAE,QAAQ,OAAO;AAAA,EACvB;AAAA,EACA;AACF,CAAC,EACA,OAAO;AAGH,IAAM,gBAAgBA,GAC1B,OAAO;AAAA,EACN,GAAGA,GAAE,QAAQ,qBAAqB;AAAA;AAAA,EAElC,MAAMA,GAAE,QAAQ,QAAQ;AAAA,EACxB;AAAA,EACA;AACF,CAAC,EACA,OAAO;AAGH,IAAM,gBAAgBA,GAC1B,OAAO;AAAA,EACN,GAAGA,GAAE,QAAQ,qBAAqB;AAAA,EAClC,MAAMA,GAAE,QAAQ,QAAQ;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AACF,CAAC,EACA,OAAO;AAGH,IAAM,aAAaA,GACvB,OAAO;AAAA,EACN,GAAGA,GAAE,QAAQ,qBAAqB;AAAA,EAClC,MAAMA,GAAE,QAAQ,KAAK;AAAA,EACrB;AAAA;AAAA,EAEA,QAAQA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AACnC,CAAC,EACA,OAAO;AAGH,IAAM,eAAeA,GAAE,mBAAmB,QAAQ;AAAA,EACvD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAWM,SAAS,gBAAgB,OAMZ;AAClB,SAAO;AAAA,IACL,OAAO,MAAM;AAAA,IACb,aAAa,MAAM;AAAA,IACnB,gBAAgB,MAAM;AAAA,IACtB,YAAY,MAAM;AAAA,IAClB,WAAW,MAAM,SAAS,YAAY,YAAY;AAAA,EACpD;AACF;AA6CO,SAAS,aAAa,MAAuC;AAgBlE,QAAM,UAAkE;AAAA;AAAA,IAEtE,SAAS,CAAC,SAAS,SAAS,UAAU,KAAK;AAAA;AAAA,IAE3C,KAAK,CAAC,UAAU,KAAK;AAAA,EACvB;AACA,QAAM,UAAU,QAAQ,IAAI;AAC5B,QAAM,iBAAiB,SAAS;AAEhC,MAAI,OAAO;AACX,MAAI,SAAS;AAEb,SAAO;AAAA;AAAA,IAEL,IAAI,OAAe;AACjB,aAAO;AAAA,IACT;AAAA,IACA,OAAO,OAAyC;AAC9C,UAAI,OAAQ,QAAO,EAAE,IAAI,OAAO,OAAO,SAAS;AAEhD,UAAI,CAAC,QAAQ,SAAS,MAAM,IAAI,GAAG;AACjC,eAAO,EAAE,IAAI,OAAO,OAAO,YAAY;AAAA,MACzC;AAKA,YAAM,UAAU,SAAS;AACzB,YAAM,aAAa,WAAW;AAC9B,UAAI,gBAAgB,MAAM,SAAS,UAAU;AAC3C,eAAO,EAAE,IAAI,OAAO,OAAO,cAAc;AAAA,MAC3C;AAEA,UAAI,MAAM,OAAO,KAAM,QAAO,EAAE,IAAI,OAAO,OAAO,WAAW;AAC7D,UAAI,MAAM,QAAQ,OAAO,EAAG,QAAO,EAAE,IAAI,OAAO,OAAO,MAAM;AAE7D,aAAO,MAAM;AACb,UAAI,MAAM,SAAS,MAAO,UAAS;AACnC,aAAO,EAAE,IAAI,KAAK;AAAA,IACpB;AAAA,EACF;AACF;","names":["z","data","z"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,84 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { S as StoredKeys, P as PublicIdentity } from './portable-
|
|
3
|
-
export { C as CONSOLE_FRAME_VERSION, a as CONSOLE_MAX_DATA_BYTES, b as ConsoleBye, c as ConsoleFrame, d as ConsoleHello, e as ConsoleOrder, f as ConsoleOrderFault, g as ConsoleOrderResult, h as ConsoleResize, i as ConsoleStdin, j as ConsoleStdout, E as ENCRYPTION_KEY_CONTEXT, k as ENVELOPE_BODY_VERSION, l as ENVELOPE_MAX_AGE_MS, m as EnvelopeBodyContext, n as EnvelopeContext, o as EnvelopeDirection, p as EnvelopeFailure, q as EnvelopeInner, O as OpenResult, r as SealedEnvelope, s as
|
|
2
|
+
import { S as StoredKeys, P as PublicIdentity } from './portable-C6rfiCXi.js';
|
|
3
|
+
export { C as CONSOLE_FRAME_VERSION, a as CONSOLE_MAX_DATA_BYTES, b as ConsoleBye, c as ConsoleFrame, d as ConsoleHello, e as ConsoleOrder, f as ConsoleOrderFault, g as ConsoleOrderResult, h as ConsoleResize, i as ConsoleStdin, j as ConsoleStdout, E as ENCRYPTION_KEY_CONTEXT, k as ENVELOPE_BODY_VERSION, l as ENVELOPE_MAX_AGE_MS, m as EnvelopeBodyContext, n as EnvelopeContext, o as EnvelopeDirection, p as EnvelopeFailure, q as EnvelopeInner, O as OpenResult, r as SealedEnvelope, s as consoleDataBytes, t as consoleEnvelope, u as consoleOrder, v as cryptoReady, w as decodeConsoleData, x as decodeEnvelopeInner, y as encodeConsoleData, z as encodeEnvelopeInner, A as envelopeSignedBody, B as fingerprint, D as fromBase64Url, F as generateKeys, G as keyId, H as open, I as publicIdentityOf, J as seal, K as signWith, L as toBase64Url, M as verifyPublicIdentity, N as verifyWith } from './portable-C6rfiCXi.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* What byollm.cloud can see, in the words a person reads — B039.
|
|
7
|
+
*
|
|
8
|
+
* ## Why a sentence is in a published package
|
|
9
|
+
*
|
|
10
|
+
* This one sentence has to be true in three places at once: the privacy page
|
|
11
|
+
* that prints it, the check beside the hub's schema that proves every recorded
|
|
12
|
+
* column is claimed by one of its clauses, and the page test that pins the
|
|
13
|
+
* wording. Two of those live in `byollm-cloud`, one in `byollm-cloud-web`, and
|
|
14
|
+
* **a check cannot read another repository** — so until now the sentence was
|
|
15
|
+
* written out three times and nothing compared the copies.
|
|
16
|
+
*
|
|
17
|
+
* That is not a tidiness problem. An enumeration is a promise, and a promise
|
|
18
|
+
* kept in three places drifts in two of them: the copy beside the schema is
|
|
19
|
+
* the one that fails when a column is added, and if it is not the copy on the
|
|
20
|
+
* page, the page stays reassuring and stops being true. Which is worse than
|
|
21
|
+
* never having made the promise.
|
|
22
|
+
*
|
|
23
|
+
* `byollm_023` named the only two shapes — a copy per repository (they
|
|
24
|
+
* diverge, silently) or one source both import (it goes stale, loudly, as a
|
|
25
|
+
* version pin). **Todd ruled shape 2 on 2026-09-17**, and the reason is the
|
|
26
|
+
* one that decides it: staleness is a number somebody can compare, and B164's
|
|
27
|
+
* cross-repository pin comparison is the thing that compares it. Divergence
|
|
28
|
+
* has no such number.
|
|
29
|
+
*
|
|
30
|
+
* ## Why it lives in `@byollm/protocol` and not a package of its own
|
|
31
|
+
*
|
|
32
|
+
* It was one, for a day. **Todd ruled on 2026-09-19: no seventh package** —
|
|
33
|
+
* *"I do think just adding it to protocol and importing that makes a ton of
|
|
34
|
+
* sense"* — and `packages/agreements` was deleted rather than marked private.
|
|
35
|
+
* Both consuming repositories already pin `@byollm/protocol`, so the sentence
|
|
36
|
+
* arrives on a pin they carry instead of a name they would have to adopt, and
|
|
37
|
+
* the cut stops carrying a package that had never been published.
|
|
38
|
+
*
|
|
39
|
+
* ## Published, not internal
|
|
40
|
+
*
|
|
41
|
+
* It ships to npm rather than living in a private repository, and that is a
|
|
42
|
+
* property rather than an accident: a promise about what a hosted service can
|
|
43
|
+
* see is worth more when anybody can install the package, read the sentence,
|
|
44
|
+
* and check it against what the service does. Protocol is public, so that is
|
|
45
|
+
* unchanged by the move.
|
|
46
|
+
*/
|
|
47
|
+
/**
|
|
48
|
+
* The hub fence, verbatim — ruled by Todd, 2026-09-04.
|
|
49
|
+
*
|
|
50
|
+
* Asserted whole rather than by keyword wherever it is checked: "close
|
|
51
|
+
* enough" is not a standard a page about what we can see gets to use, and a
|
|
52
|
+
* paraphrase that drifted would leave the other repository checking a sentence
|
|
53
|
+
* nobody ships.
|
|
54
|
+
*/
|
|
55
|
+
declare const HUB_FENCE: string;
|
|
56
|
+
/**
|
|
57
|
+
* A clause of {@link HUB_FENCE}, and the columns it accounts for.
|
|
58
|
+
*
|
|
59
|
+
* The mapping is here rather than beside the schema for the same reason the
|
|
60
|
+
* sentence is: it is a fact about the sentence, and the sentence is shared.
|
|
61
|
+
* What stays beside the schema is the CHECK — every recorded column must be
|
|
62
|
+
* claimed by one of these before that suite passes — because the columns are
|
|
63
|
+
* the hub's and only the hub's repository can enumerate them.
|
|
64
|
+
*
|
|
65
|
+
* Coupling copy to columns by check rather than by convention is the whole of
|
|
66
|
+
* the ruling: the enumeration is only a promise if something fails when the
|
|
67
|
+
* code outgrows it.
|
|
68
|
+
*/
|
|
69
|
+
interface FenceClause {
|
|
70
|
+
/** The clause as it appears in {@link HUB_FENCE}. */
|
|
71
|
+
readonly says: string;
|
|
72
|
+
/** The recorded columns this clause accounts for. */
|
|
73
|
+
readonly covers: readonly string[];
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Every clause, with what it covers.
|
|
77
|
+
*
|
|
78
|
+
* A column not claimed by any clause is a fact about somebody that the page
|
|
79
|
+
* does not mention, which is what the check beside the schema refuses.
|
|
80
|
+
*/
|
|
81
|
+
declare const HUB_FENCE_CLAUSES: readonly FenceClause[];
|
|
4
82
|
|
|
5
83
|
/**
|
|
6
84
|
* Protocol version carried on every request; servers refuse what they can't
|
|
@@ -25,7 +103,7 @@ export { C as CONSOLE_FRAME_VERSION, a as CONSOLE_MAX_DATA_BYTES, b as ConsoleBy
|
|
|
25
103
|
* own words, from the release that silenced a fleet by adding a backend id.
|
|
26
104
|
* The same sentence applies to removing an offer scope.
|
|
27
105
|
*/
|
|
28
|
-
declare const PROTOCOL_VERSION: "
|
|
106
|
+
declare const PROTOCOL_VERSION: "2";
|
|
29
107
|
/**
|
|
30
108
|
* Every protocol version this build can serve, **oldest first**.
|
|
31
109
|
*
|
|
@@ -268,7 +346,7 @@ type GrantRef = z.infer<typeof GrantRef>;
|
|
|
268
346
|
* and nothing works over a copied string alone.
|
|
269
347
|
*/
|
|
270
348
|
declare const PairStartRequest: z.ZodObject<{
|
|
271
|
-
protocolVersion: z.ZodLiteral<"
|
|
349
|
+
protocolVersion: z.ZodLiteral<"2">;
|
|
272
350
|
action: z.ZodLiteral<"start">;
|
|
273
351
|
daemon: z.ZodObject<{
|
|
274
352
|
version: z.ZodString;
|
|
@@ -333,7 +411,7 @@ declare const PairStartResponse: z.ZodObject<{
|
|
|
333
411
|
}, z.core.$strict>;
|
|
334
412
|
type PairStartResponse = z.infer<typeof PairStartResponse>;
|
|
335
413
|
declare const PairPollRequest: z.ZodObject<{
|
|
336
|
-
protocolVersion: z.ZodLiteral<"
|
|
414
|
+
protocolVersion: z.ZodLiteral<"2">;
|
|
337
415
|
action: z.ZodLiteral<"poll">;
|
|
338
416
|
deviceCode: z.ZodString;
|
|
339
417
|
}, z.core.$strict>;
|
|
@@ -358,7 +436,7 @@ declare const PairPollResponse: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
358
436
|
}, z.core.$strict>], "status">;
|
|
359
437
|
type PairPollResponse = z.infer<typeof PairPollResponse>;
|
|
360
438
|
declare const PairRequest: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
361
|
-
protocolVersion: z.ZodLiteral<"
|
|
439
|
+
protocolVersion: z.ZodLiteral<"2">;
|
|
362
440
|
action: z.ZodLiteral<"start">;
|
|
363
441
|
daemon: z.ZodObject<{
|
|
364
442
|
version: z.ZodString;
|
|
@@ -413,13 +491,13 @@ declare const PairRequest: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
413
491
|
}>;
|
|
414
492
|
}, z.core.$strict>>;
|
|
415
493
|
}, z.core.$strict>, z.ZodObject<{
|
|
416
|
-
protocolVersion: z.ZodLiteral<"
|
|
494
|
+
protocolVersion: z.ZodLiteral<"2">;
|
|
417
495
|
action: z.ZodLiteral<"poll">;
|
|
418
496
|
deviceCode: z.ZodString;
|
|
419
497
|
}, z.core.$strict>], "action">;
|
|
420
498
|
type PairRequest = z.infer<typeof PairRequest>;
|
|
421
499
|
declare const ClaimRequest: z.ZodObject<{
|
|
422
|
-
protocolVersion: z.ZodLiteral<"
|
|
500
|
+
protocolVersion: z.ZodLiteral<"2">;
|
|
423
501
|
runnerId: z.ZodString;
|
|
424
502
|
capabilities: z.ZodArray<z.ZodObject<{
|
|
425
503
|
kind: z.ZodEnum<{
|
|
@@ -506,7 +584,7 @@ declare const ClaimResponse: z.ZodObject<{
|
|
|
506
584
|
}, z.core.$strict>;
|
|
507
585
|
type ClaimResponse = z.infer<typeof ClaimResponse>;
|
|
508
586
|
declare const HeartbeatRequest: z.ZodObject<{
|
|
509
|
-
protocolVersion: z.ZodLiteral<"
|
|
587
|
+
protocolVersion: z.ZodLiteral<"2">;
|
|
510
588
|
runnerId: z.ZodString;
|
|
511
589
|
daemonVersion: z.ZodString;
|
|
512
590
|
capabilities: z.ZodArray<z.ZodObject<{
|
|
@@ -564,7 +642,6 @@ declare const HeartbeatRequest: z.ZodObject<{
|
|
|
564
642
|
jobId: z.ZodString;
|
|
565
643
|
leaseId: z.ZodString;
|
|
566
644
|
}, z.core.$strict>>;
|
|
567
|
-
paused: z.ZodBoolean;
|
|
568
645
|
}, z.core.$strict>;
|
|
569
646
|
type HeartbeatRequest = z.infer<typeof HeartbeatRequest>;
|
|
570
647
|
declare const HeartbeatResponse: z.ZodObject<{
|
|
@@ -616,7 +693,7 @@ declare const ResultDisposition: z.ZodEnum<{
|
|
|
616
693
|
}>;
|
|
617
694
|
type ResultDisposition = z.infer<typeof ResultDisposition>;
|
|
618
695
|
declare const ResultRequest: z.ZodObject<{
|
|
619
|
-
protocolVersion: z.ZodLiteral<"
|
|
696
|
+
protocolVersion: z.ZodLiteral<"2">;
|
|
620
697
|
runnerId: z.ZodString;
|
|
621
698
|
jobId: z.ZodString;
|
|
622
699
|
leaseId: z.ZodString;
|
|
@@ -644,7 +721,7 @@ declare const ResultResponse: z.ZodObject<{
|
|
|
644
721
|
}, z.core.$strict>;
|
|
645
722
|
type ResultResponse = z.infer<typeof ResultResponse>;
|
|
646
723
|
declare const ReleaseRequest: z.ZodObject<{
|
|
647
|
-
protocolVersion: z.ZodLiteral<"
|
|
724
|
+
protocolVersion: z.ZodLiteral<"2">;
|
|
648
725
|
runnerId: z.ZodString;
|
|
649
726
|
leases: z.ZodArray<z.ZodObject<{
|
|
650
727
|
jobId: z.ZodString;
|
|
@@ -713,7 +790,7 @@ type WireError = z.infer<typeof WireError>;
|
|
|
713
790
|
/** HTTP status each error code is served with. */
|
|
714
791
|
declare const ERROR_STATUS: Readonly<Record<WireErrorCode, number>>;
|
|
715
792
|
declare const FetchRequest: z.ZodObject<{
|
|
716
|
-
protocolVersion: z.ZodLiteral<"
|
|
793
|
+
protocolVersion: z.ZodLiteral<"2">;
|
|
717
794
|
runnerId: z.ZodString;
|
|
718
795
|
jobId: z.ZodString;
|
|
719
796
|
leaseId: z.ZodString;
|
|
@@ -1555,6 +1632,44 @@ declare const ClaimedJob: z.ZodObject<{
|
|
|
1555
1632
|
}, z.core.$strict>;
|
|
1556
1633
|
}, z.core.$strict>;
|
|
1557
1634
|
type ClaimedJob = z.infer<typeof ClaimedJob>;
|
|
1635
|
+
/**
|
|
1636
|
+
* The closed set, as a schema — so the values exist once.
|
|
1637
|
+
*
|
|
1638
|
+
* A bare union would mean anything that has to VALIDATE a stop reason (the
|
|
1639
|
+
* ingress log, and the wire when step 4 lands) retyping the four strings
|
|
1640
|
+
* beside it. Instruction 9: one definition, both ends, and where a consumer
|
|
1641
|
+
* needs a runtime check the definition has to be one it can run.
|
|
1642
|
+
*
|
|
1643
|
+
* The type below is inferred from this rather than written twice, so the
|
|
1644
|
+
* compiler and the validator cannot disagree about what a stop reason is.
|
|
1645
|
+
*/
|
|
1646
|
+
declare const StopReasonSchema: z.ZodEnum<{
|
|
1647
|
+
length: "length";
|
|
1648
|
+
unknown: "unknown";
|
|
1649
|
+
end: "end";
|
|
1650
|
+
"stop-sequence": "stop-sequence";
|
|
1651
|
+
}>;
|
|
1652
|
+
type StopReason =
|
|
1653
|
+
/** The model finished on its own. */
|
|
1654
|
+
"end"
|
|
1655
|
+
/** The model stopped at its own output ceiling. */
|
|
1656
|
+
| "length"
|
|
1657
|
+
/** A configured stop token ended it. */
|
|
1658
|
+
| "stop-sequence"
|
|
1659
|
+
/**
|
|
1660
|
+
* The adapter cannot tell, and says so.
|
|
1661
|
+
*
|
|
1662
|
+
* **The default, and never `"end"`.** An adapter nobody has updated — or
|
|
1663
|
+
* one somebody adds next year — must not be able to claim completion by
|
|
1664
|
+
* saying nothing. If absence meant "end", every un-updated adapter would go
|
|
1665
|
+
* on telling exactly the lie this exists to fix, and every new adapter
|
|
1666
|
+
* would inherit it in silence.
|
|
1667
|
+
*
|
|
1668
|
+
* It is the opposite-boolean rule this codebase keeps arriving at: when you
|
|
1669
|
+
* cannot tell, guess toward silence rather than toward a claim. "We do not
|
|
1670
|
+
* know" is a thing a site can act on; "it finished" when it did not is not.
|
|
1671
|
+
*/
|
|
1672
|
+
| "unknown";
|
|
1558
1673
|
/**
|
|
1559
1674
|
* The provenance that travels with every result to the delivery seam.
|
|
1560
1675
|
*
|
|
@@ -1575,6 +1690,13 @@ declare const ResultProvenance: z.ZodObject<{
|
|
|
1575
1690
|
}>;
|
|
1576
1691
|
model: z.ZodString;
|
|
1577
1692
|
untrusted: z.ZodBoolean;
|
|
1693
|
+
stop: z.ZodOptional<z.ZodEnum<{
|
|
1694
|
+
length: "length";
|
|
1695
|
+
unknown: "unknown";
|
|
1696
|
+
end: "end";
|
|
1697
|
+
"stop-sequence": "stop-sequence";
|
|
1698
|
+
}>>;
|
|
1699
|
+
stopReported: z.ZodOptional<z.ZodBoolean>;
|
|
1578
1700
|
}, z.core.$strict>;
|
|
1579
1701
|
type ResultProvenance = z.infer<typeof ResultProvenance>;
|
|
1580
1702
|
/**
|
|
@@ -1587,6 +1709,9 @@ declare function provenanceFor(input: {
|
|
|
1587
1709
|
runnerOwner: string;
|
|
1588
1710
|
backendClass: BackendClass;
|
|
1589
1711
|
model: string;
|
|
1712
|
+
/** From the sealed `ran`; absent on a cancelled or errored job — B260. */
|
|
1713
|
+
stop?: StopReason | undefined;
|
|
1714
|
+
stopReported?: boolean | undefined;
|
|
1590
1715
|
}): ResultProvenance;
|
|
1591
1716
|
/**
|
|
1592
1717
|
* What the daemon did, sealed with the answer — cloud_008 §2.5.
|
|
@@ -1603,44 +1728,6 @@ declare function provenanceFor(input: {
|
|
|
1603
1728
|
* opens them, nothing in between sees them, and the disposition check that
|
|
1604
1729
|
* already compares clear-text against ciphertext extends to cover them.
|
|
1605
1730
|
*/
|
|
1606
|
-
/**
|
|
1607
|
-
* The closed set, as a schema — so the values exist once.
|
|
1608
|
-
*
|
|
1609
|
-
* A bare union would mean anything that has to VALIDATE a stop reason (the
|
|
1610
|
-
* ingress log, and the wire when step 4 lands) retyping the four strings
|
|
1611
|
-
* beside it. Instruction 9: one definition, both ends, and where a consumer
|
|
1612
|
-
* needs a runtime check the definition has to be one it can run.
|
|
1613
|
-
*
|
|
1614
|
-
* The type below is inferred from this rather than written twice, so the
|
|
1615
|
-
* compiler and the validator cannot disagree about what a stop reason is.
|
|
1616
|
-
*/
|
|
1617
|
-
declare const StopReasonSchema: z.ZodEnum<{
|
|
1618
|
-
length: "length";
|
|
1619
|
-
unknown: "unknown";
|
|
1620
|
-
end: "end";
|
|
1621
|
-
"stop-sequence": "stop-sequence";
|
|
1622
|
-
}>;
|
|
1623
|
-
type StopReason =
|
|
1624
|
-
/** The model finished on its own. */
|
|
1625
|
-
"end"
|
|
1626
|
-
/** The model stopped at its own output ceiling. */
|
|
1627
|
-
| "length"
|
|
1628
|
-
/** A configured stop token ended it. */
|
|
1629
|
-
| "stop-sequence"
|
|
1630
|
-
/**
|
|
1631
|
-
* The adapter cannot tell, and says so.
|
|
1632
|
-
*
|
|
1633
|
-
* **The default, and never `"end"`.** An adapter nobody has updated — or
|
|
1634
|
-
* one somebody adds next year — must not be able to claim completion by
|
|
1635
|
-
* saying nothing. If absence meant "end", every un-updated adapter would go
|
|
1636
|
-
* on telling exactly the lie this exists to fix, and every new adapter
|
|
1637
|
-
* would inherit it in silence.
|
|
1638
|
-
*
|
|
1639
|
-
* It is the opposite-boolean rule this codebase keeps arriving at: when you
|
|
1640
|
-
* cannot tell, guess toward silence rather than toward a claim. "We do not
|
|
1641
|
-
* know" is a thing a site can act on; "it finished" when it did not is not.
|
|
1642
|
-
*/
|
|
1643
|
-
| "unknown";
|
|
1644
1731
|
declare const RunMetadata: z.ZodObject<{
|
|
1645
1732
|
model: z.ZodString;
|
|
1646
1733
|
backendClass: z.ZodEnum<{
|
|
@@ -1840,6 +1927,13 @@ declare const DeliveredResult: z.ZodObject<{
|
|
|
1840
1927
|
}>;
|
|
1841
1928
|
model: z.ZodString;
|
|
1842
1929
|
untrusted: z.ZodBoolean;
|
|
1930
|
+
stop: z.ZodOptional<z.ZodEnum<{
|
|
1931
|
+
length: "length";
|
|
1932
|
+
unknown: "unknown";
|
|
1933
|
+
end: "end";
|
|
1934
|
+
"stop-sequence": "stop-sequence";
|
|
1935
|
+
}>>;
|
|
1936
|
+
stopReported: z.ZodOptional<z.ZodBoolean>;
|
|
1843
1937
|
}, z.core.$strict>>;
|
|
1844
1938
|
fallback: z.ZodOptional<z.ZodLiteral<true>>;
|
|
1845
1939
|
}, z.core.$strict>;
|
|
@@ -2281,6 +2375,74 @@ declare function verifyRequest(input: {
|
|
|
2281
2375
|
* what a single-purpose site's one purpose actually is.
|
|
2282
2376
|
*/
|
|
2283
2377
|
declare const RESERVED_PURPOSE = "default";
|
|
2378
|
+
/**
|
|
2379
|
+
* How a purpose's work is routed — RESERVED at 0.1.0, not yet acted on (B236).
|
|
2380
|
+
*
|
|
2381
|
+
* ## Why a key nothing reads is the highest-leverage thing in this file
|
|
2382
|
+
*
|
|
2383
|
+
* {@link Purpose} is `.strict()`, and that is right: a manifest is written by
|
|
2384
|
+
* hand by a third party, and a typo'd key that is silently ignored is a site
|
|
2385
|
+
* whose consent screen quietly says something other than what its author
|
|
2386
|
+
* wrote. The cost of `.strict()` is that **there is no such thing as an
|
|
2387
|
+
* additive change to it.** A key added in 1.4 is rejected by every validator
|
|
2388
|
+
* built before 1.4, and the OSS repository ships the server — so those
|
|
2389
|
+
* validators will exist, on machines nobody can upgrade, run by people who
|
|
2390
|
+
* have no idea a key was added.
|
|
2391
|
+
*
|
|
2392
|
+
* The window in which this field can be introduced is therefore now: before
|
|
2393
|
+
* the wire is declared stable, while every validator in existence is ours.
|
|
2394
|
+
* After that the shape is load-bearing whether or not anything reads it.
|
|
2395
|
+
*
|
|
2396
|
+
* So the values are the ruled ones (B232 house lanes, B233 fallback lanes),
|
|
2397
|
+
* the schema refuses anything else, and no code branches on it. A site may
|
|
2398
|
+
* write `routing` today and get exactly the behaviour it gets without it,
|
|
2399
|
+
* which is the point: the manifest it writes today is still valid the day
|
|
2400
|
+
* the lanes land.
|
|
2401
|
+
*
|
|
2402
|
+
* ## What each value will mean, when something reads it
|
|
2403
|
+
*
|
|
2404
|
+
* - `user-choice` — the person maps this purpose to one of their own
|
|
2405
|
+
* services, and that mapping is the consent. Today's only behaviour, and
|
|
2406
|
+
* the default for a manifest that says nothing.
|
|
2407
|
+
* - `site-fixed` — the site pays for and pins the service (B232's house
|
|
2408
|
+
* lane). The person is told, and consents to that rather than to a mapping.
|
|
2409
|
+
* - `user-first-with-fallback` — the person's service if they have one, the
|
|
2410
|
+
* site's if they do not (B233).
|
|
2411
|
+
*
|
|
2412
|
+
* **The commitment attached to those last two** is written in the lock
|
|
2413
|
+
* document rather than here, because it binds behaviour this file cannot
|
|
2414
|
+
* enforce: a hub that does not implement a lane treats the purpose as
|
|
2415
|
+
* `user-choice` and SAYS SO in a field rather than silently downgrading it,
|
|
2416
|
+
* and a lane added later carries its own disclosure and never weakens an
|
|
2417
|
+
* existing lane's promise.
|
|
2418
|
+
*/
|
|
2419
|
+
declare const PurposeRouting: z.ZodEnum<{
|
|
2420
|
+
"user-choice": "user-choice";
|
|
2421
|
+
"site-fixed": "site-fixed";
|
|
2422
|
+
"user-first-with-fallback": "user-first-with-fallback";
|
|
2423
|
+
}>;
|
|
2424
|
+
type PurposeRouting = z.infer<typeof PurposeRouting>;
|
|
2425
|
+
/**
|
|
2426
|
+
* What a purpose that does not say means.
|
|
2427
|
+
*
|
|
2428
|
+
* Named once, here, rather than written into the schema as `.default()`. A
|
|
2429
|
+
* zod default is applied at PARSE, which would mean every manifest read by
|
|
2430
|
+
* anything becomes a manifest with a `routing` key — and a hub that parses a
|
|
2431
|
+
* site's manifest, stores it and serves it back would be handing a key to
|
|
2432
|
+
* readers that predate it. The thing this field exists to avoid, performed by
|
|
2433
|
+
* the field itself.
|
|
2434
|
+
*
|
|
2435
|
+
* Parsing stays shape-preserving; the default is applied where the value is
|
|
2436
|
+
* USED, by {@link routingOf}.
|
|
2437
|
+
*/
|
|
2438
|
+
declare const DEFAULT_ROUTING: PurposeRouting;
|
|
2439
|
+
/**
|
|
2440
|
+
* The routing a purpose asks for, defaulted.
|
|
2441
|
+
*
|
|
2442
|
+
* The one place the absent case is answered, so that when B232 and B233 do
|
|
2443
|
+
* act on this there is no second opinion about what "not stated" meant.
|
|
2444
|
+
*/
|
|
2445
|
+
declare function routingOf(purpose: Purpose): PurposeRouting;
|
|
2284
2446
|
declare const Purpose: z.ZodObject<{
|
|
2285
2447
|
label: z.ZodString;
|
|
2286
2448
|
description: z.ZodOptional<z.ZodString>;
|
|
@@ -2288,6 +2450,11 @@ declare const Purpose: z.ZodObject<{
|
|
|
2288
2450
|
"llm.generate": "llm.generate";
|
|
2289
2451
|
"llm.chat": "llm.chat";
|
|
2290
2452
|
}>>;
|
|
2453
|
+
routing: z.ZodOptional<z.ZodEnum<{
|
|
2454
|
+
"user-choice": "user-choice";
|
|
2455
|
+
"site-fixed": "site-fixed";
|
|
2456
|
+
"user-first-with-fallback": "user-first-with-fallback";
|
|
2457
|
+
}>>;
|
|
2291
2458
|
}, z.core.$strict>;
|
|
2292
2459
|
type Purpose = z.infer<typeof Purpose>;
|
|
2293
2460
|
/**
|
|
@@ -2320,6 +2487,11 @@ declare const Manifest: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
|
2320
2487
|
"llm.generate": "llm.generate";
|
|
2321
2488
|
"llm.chat": "llm.chat";
|
|
2322
2489
|
}>>;
|
|
2490
|
+
routing: z.ZodOptional<z.ZodEnum<{
|
|
2491
|
+
"user-choice": "user-choice";
|
|
2492
|
+
"site-fixed": "site-fixed";
|
|
2493
|
+
"user-first-with-fallback": "user-first-with-fallback";
|
|
2494
|
+
}>>;
|
|
2323
2495
|
}, z.core.$strict>>;
|
|
2324
2496
|
type Manifest = z.infer<typeof Manifest>;
|
|
2325
2497
|
/**
|
|
@@ -2806,4 +2978,4 @@ declare const MUST_IDS: readonly ("PAIR_ONE_USER" | "PAIR_INTERACTIVE" | "PAIR_C
|
|
|
2806
2978
|
/** Every MUST verified a particular way. */
|
|
2807
2979
|
declare function mustsVerifiedBy(kind: MustVerification): MustId[];
|
|
2808
2980
|
|
|
2809
|
-
export { ABOUT, ABOUT_SHORT, ABOUT_SHORT_LEDE, ABOUT_SHORT_TAIL, AUDIENCES, Audience, BACKENDS, BACKEND_CLASSES, 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, ENDPOINTS, ERROR_STATUS, type Endpoint, FetchRequest, FetchResponse, type FloorRefusal, 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_ENVELOPE_BYTES, MAX_PURPOSES, 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, PAYLOAD_LIMITS, PROTOCOL_PREFIX, PROTOCOL_VERSION, PairPollRequest, PairPollResponse, PairRequest, PairStartRequest, PairStartResponse, type PayloadFor, PublicIdentity, Purpose, REFUSAL_MESSAGES, REFUSAL_TEXT, RESERVED_PURPOSE, RETIREMENT_WINDOW_MS, RefusalReason, ReleaseRequest, ReleaseResponse, RequestSignature, ResultDisposition, ResultProvenance, ResultRequest, ResultResponse, RunMetadata, SIZE_CLASSES, SIZE_CLASS_LIMITS, SUCCESSION_CONTEXT, SUPPORTED_PROTOCOL_VERSIONS, SealedOutcome, type SignatureFailure, SignedGrant, SizeClass, type SpendConsent, type StopReason, StopReasonSchema, StoredKeys, Succession, type SuccessionFailure, type SuccessionWalk, TERMINAL_STATES, UPDATE_OFFER_SINCE, UPGRADE_COMMAND, type VersionRefusal, WireError, WireErrorCode, WithheldKind, backendDescriptor, backendName, canTransition, canonicalRequest, checkDaemonFloor, checkProtocolVersion, classifyCost, compareVersions, declaredVersion, describeBytes, effectiveOfferScope, envelopeBytes, grantStatement, isBackendId, isCloudTaggedModel, isJobKind, isLocalHost, isTerminal, kindsOf, matchAudience, mayOfferUpdate, mentionsWireField, mustsVerifiedBy, payloadTextLength, provenanceFor, resolveCost, signGrant, signRequest, signSiteRequest, signSuccession, singlePurposeManifest, sizeClassCeiling, sizeClassOf, successionStatement, tooLargeMessage, updateOfferFor, verifyGrant, verifyLink, verifyRequest, verifySiteRequest, walkSuccession, withoutComments };
|
|
2981
|
+
export { ABOUT, ABOUT_SHORT, ABOUT_SHORT_LEDE, ABOUT_SHORT_TAIL, AUDIENCES, Audience, BACKENDS, BACKEND_CLASSES, BACKEND_IDS, BackendClass, BackendCost, type BackendDescriptor, type BackendId, BackendIdSchema, CLOCK_ATTRIBUTION_MS, CLOCK_SKEW_WARN_MS, Capability, CapabilityMatrix, ChatMessage, ChatPayload, ClaimRequest, ClaimResponse, ClaimedJob, ClaimedStub, DEFAULT_ROUTING, DeliveredResult, ENDPOINTS, ERROR_STATUS, type Endpoint, type FenceClause, FetchRequest, FetchResponse, type FloorRefusal, GRANT_CONTEXT, GRANT_MAX_AGE_MS, GRANT_SIGNED_FIELDS, GeneratePayload, type GrantClaims, GrantRef, type GrantRefusal, HUB_FENCE, HUB_FENCE_CLAUSES, HeartbeatRequest, HeartbeatResponse, JOB_KINDS, JobKind, JobOutcome, JobPayload, JobRefused, JobResultCanceled, JobResultError, JobResultOk, JobState, JobStub, KindedPayload, Lease, MAX_CLOCK_SKEW_MS, MAX_ENVELOPE_BYTES, MAX_PURPOSES, 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, PAYLOAD_LIMITS, PROTOCOL_PREFIX, PROTOCOL_VERSION, PairPollRequest, PairPollResponse, PairRequest, PairStartRequest, PairStartResponse, type PayloadFor, PublicIdentity, Purpose, PurposeRouting, REFUSAL_MESSAGES, REFUSAL_TEXT, RESERVED_PURPOSE, RETIREMENT_WINDOW_MS, RefusalReason, ReleaseRequest, ReleaseResponse, RequestSignature, ResultDisposition, ResultProvenance, ResultRequest, ResultResponse, RunMetadata, SIZE_CLASSES, SIZE_CLASS_LIMITS, SUCCESSION_CONTEXT, SUPPORTED_PROTOCOL_VERSIONS, SealedOutcome, type SignatureFailure, SignedGrant, SizeClass, type SpendConsent, type StopReason, StopReasonSchema, StoredKeys, Succession, type SuccessionFailure, type SuccessionWalk, TERMINAL_STATES, UPDATE_OFFER_SINCE, UPGRADE_COMMAND, type VersionRefusal, WireError, WireErrorCode, WithheldKind, backendDescriptor, backendName, canTransition, canonicalRequest, checkDaemonFloor, checkProtocolVersion, classifyCost, compareVersions, declaredVersion, describeBytes, effectiveOfferScope, envelopeBytes, grantStatement, isBackendId, isCloudTaggedModel, isJobKind, isLocalHost, isTerminal, kindsOf, matchAudience, mayOfferUpdate, mentionsWireField, mustsVerifiedBy, payloadTextLength, provenanceFor, resolveCost, routingOf, signGrant, signRequest, signSiteRequest, signSuccession, singlePurposeManifest, sizeClassCeiling, sizeClassOf, successionStatement, tooLargeMessage, updateOfferFor, verifyGrant, verifyLink, verifyRequest, verifySiteRequest, walkSuccession, withoutComments };
|