@byollm/server 0.1.0-alpha.4 → 0.1.0-alpha.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,10 +1,134 @@
1
- import { JobKind, StoredKeys, DeliveredResult, Endpoint, Capability } from '@byollm/protocol';
1
+ import { StoredKeys, JobKind, DeliveredResult, Endpoint, Capability } from '@byollm/protocol';
2
2
  import { P as PollingDeliveryDeps, R as ResultDelivery, W as WaitOptions } from './delivery-36nIe-b3.js';
3
3
  export { N as NoRunnerAvailableError, a as PollingDelivery, b as ResultTimeoutError } from './delivery-36nIe-b3.js';
4
- import { B as ByollmStore, E as EnqueueInput, J as JobRecord, R as RunnerRecord, S as StoredJobInput, C as ClaimArgs, a as RenewArgs, b as RenewResult, c as CompleteArgs, d as CompleteResult, e as ReleaseArgs, P as PairingRecord, A as ApproveArgs, T as TouchArgs } from './store-gFEEN1Dt.js';
5
- export { f as JobStore, g as RunnerStore } from './store-gFEEN1Dt.js';
6
- import { H as HandlerConfig } from './handlers-CF3yE-t2.js';
7
- export { B as ByollmHandlers, a as HandlerResult, S as SERVED_PROTOCOL_VERSION } from './handlers-CF3yE-t2.js';
4
+ import { B as ByollmStore, J as JobRecord, E as EnqueueInput, R as RunnerRecord, S as StoredJobInput, C as ClaimArgs, a as RenewArgs, b as RenewResult, A as AdoptArgs, c as CompleteArgs, d as CompleteResult, e as ReleaseArgs, P as PairingRecord, f as ApproveArgs, T as TouchArgs } from './store-Dno2fnHH.js';
5
+ export { g as CompleteHolder, h as JobStore, i as RunnerStore } from './store-Dno2fnHH.js';
6
+ import { H as HandlerConfig } from './handlers-BJYm2kdq.js';
7
+ export { B as ByollmHandlers, a as HandlerResult, S as SERVED_PROTOCOL_VERSION } from './handlers-BJYm2kdq.js';
8
+
9
+ /**
10
+ * The cloud lane — cloud_004 §9.4.
11
+ *
12
+ * `app.enqueue(...)` is identical in every lane; the lane picks the connection
13
+ * plane. In `direct` mode a daemon reaches the site's own handlers. In `cloud`
14
+ * mode it reaches a relay instead, and the site's side of that is this file.
15
+ *
16
+ * ## What actually changes, and what deliberately does not
17
+ *
18
+ * Enqueue does not change at all. The job is validated, sealed at rest to the
19
+ * site's own key and stored, exactly as before — jobs-at-rest encryption is a
20
+ * direct-mode property that the cloud lane inherits rather than replaces.
21
+ *
22
+ * What changes is *who asks for the payload and when*. On the direct plane the
23
+ * daemon asks, and the site answers synchronously because it is the upstream.
24
+ * Through a relay the site is not the upstream, so nobody asks: the site has to
25
+ * find out that a device claimed its job, and seal to that device. Hence a
26
+ * pump rather than a handler.
27
+ *
28
+ * ```
29
+ * enqueue ──stub──▶ relay (payload stays here, sealed at rest)
30
+ * │
31
+ * pump ◀──who claimed it, and what key?
32
+ * ──payload sealed to that device──▶
33
+ * pump ◀──sealed result── ──▶ store.complete → the app's delivery channel
34
+ * ```
35
+ *
36
+ * ## Why the site polls
37
+ *
38
+ * Everything in this product is outbound. A relay that called site webhooks
39
+ * would need every site publicly reachable, which is the connectivity problem
40
+ * the hub exists to remove — and a serverless site has nowhere to receive a
41
+ * webhook anyway. So the site polls, exactly as a daemon does.
42
+ */
43
+ interface CloudLaneOptions {
44
+ /** Where the relay lives, e.g. `https://relay.byollm.cloud`. */
45
+ readonly relayOrigin: string;
46
+ /** This site's id at the relay. */
47
+ readonly siteId: string;
48
+ /** Injectable fetch, for tests and for proxies. */
49
+ readonly fetch?: typeof fetch;
50
+ }
51
+ /** What one pump cycle did, for logging and for tests. */
52
+ /**
53
+ * A relay that could not answer this request — alpha.31.
54
+ *
55
+ * `retryable` is the whole point: a draining pod and a bad signature are both
56
+ * failures, and treating them alike is how a site either falls over on every
57
+ * deploy or stays silently disconnected for a week.
58
+ */
59
+ declare class RelayUnavailable extends Error {
60
+ readonly retryable: boolean;
61
+ /** The protocol's own code, when the relay sent one. */
62
+ readonly code: string;
63
+ constructor(message: string, retryable: boolean, code: string);
64
+ }
65
+ interface PumpReport {
66
+ /** Jobs sealed to a claiming device this cycle. */
67
+ readonly sealed: string[];
68
+ /** Results opened, verified and written to the store. */
69
+ readonly completed: string[];
70
+ /**
71
+ * Jobs the relay offered that this site refused to seal for.
72
+ *
73
+ * Never silent: a site that cannot open its own at-rest envelope has a key
74
+ * problem, and a device waiting on a payload that will never come is
75
+ * exactly the case `awaiting-payload` exists to bound.
76
+ */
77
+ readonly refused: string[];
78
+ /**
79
+ * Why this cycle stopped early, when it did — alpha.31.
80
+ *
81
+ * A relay can legitimately say "ask me later": a pod draining through its
82
+ * `preStop` window answers `503 not-ready` to every routed call, and that
83
+ * happens on **every deploy**. Before this existed the lane read the body
84
+ * of that answer, found no `jobs` in it, and threw `TypeError: finished.jobs
85
+ * is not iterable` — a site falling over because its relay was polite.
86
+ *
87
+ * Absent on an ordinary cycle. Present, with the reason, when the lane
88
+ * deferred: a site that quietly did nothing and a site that was told to wait
89
+ * must not look the same in a log.
90
+ */
91
+ readonly deferred?: string;
92
+ }
93
+ declare class CloudLane {
94
+ #private;
95
+ constructor(deps: {
96
+ options: CloudLaneOptions;
97
+ store: ByollmStore;
98
+ siteKeys: StoredKeys;
99
+ now: () => number;
100
+ });
101
+ /**
102
+ * Publish a job's stub for routing.
103
+ *
104
+ * The stub and nothing else — byollm_009 §6 makes that exhaustive by
105
+ * construction, so this cannot leak a payload even by mistake: there is no
106
+ * field on `JobStub` to put one in.
107
+ */
108
+ publish(record: JobRecord): Promise<void>;
109
+ /**
110
+ * Withdraw a job at the relay — cloud_008 §2.2.
111
+ *
112
+ * `app.cancel()` marks the site's own row terminal, which stops the *next*
113
+ * seal. It cannot stop a device that is already running the work, because
114
+ * on this lane the site is not the upstream: only the relay talks to the
115
+ * daemon, and it answered `cancel: []` unconditionally.
116
+ *
117
+ * So the cancellation has to travel. The relay marks the job, stops
118
+ * offering it, and names it to the holding device at its next heartbeat —
119
+ * the same path the direct plane has always had, arriving one hop later.
120
+ */
121
+ cancel(jobId: string): Promise<void>;
122
+ /**
123
+ * One cycle: seal for anything claimed, collect anything finished.
124
+ *
125
+ * Idempotent and safe to call as often as you like. Exposed as a single
126
+ * cycle rather than hidden behind a timer so a caller decides its own
127
+ * cadence — a serverless site runs it on a cron, a long-lived one on an
128
+ * interval, and a test runs it exactly when it means to.
129
+ */
130
+ pump(): Promise<PumpReport>;
131
+ }
8
132
 
9
133
  /** Why a job cannot presently run. */
10
134
  type NoRunnerReason = "no-runner-paired" | "no-runner-online" | "no-matching-capability" | "audience-admits-nobody";
@@ -53,6 +177,15 @@ interface ByollmAppOptions {
53
177
  * holds plaintext (byollm_009 §10).
54
178
  */
55
179
  readonly siteKeys: StoredKeys;
180
+ /**
181
+ * Which connection plane this site uses — cloud_004 §9.4.
182
+ *
183
+ * Omitted means `direct`: a daemon reaches this site's own handlers, and
184
+ * everything works as it always has. Supplying a relay switches the plane
185
+ * and nothing else — `enqueue` is identical in every lane, which is the
186
+ * property that lets the same app move between them by config.
187
+ */
188
+ readonly lane?: CloudLaneOptions;
56
189
  }
57
190
  /**
58
191
  * An enqueued job, with the delivery channel attached.
@@ -80,6 +213,8 @@ interface JobHandle {
80
213
  */
81
214
  declare class ByollmApp {
82
215
  #private;
216
+ /** Present only in the cloud lane; the site's side of the relay. */
217
+ readonly cloud: CloudLane | undefined;
83
218
  constructor(options: ByollmAppOptions);
84
219
  /**
85
220
  * Enqueue a job.
@@ -97,7 +232,7 @@ declare class ByollmApp {
97
232
  * Check `provenance.untrusted` before rendering. It is true for every
98
233
  * `named`/`public` job, because that text came from someone else's machine
99
234
  * and the app must not present it as its own AI's answer
100
- * ({@link MUSTS.RESULT_PROVENANCE}).
235
+ * ({@link MUSTS.PROVENANCE_NAMES_DEVICE}).
101
236
  */
102
237
  result(jobId: string): Promise<DeliveredResult | null>;
103
238
  /** Ask a runner to stop. Queued jobs cancel at once; held jobs at the next heartbeat. */
@@ -220,8 +355,6 @@ declare function formatSiteKeys(keys: StoredKeys): string;
220
355
 
221
356
  /** A device code: the secret the daemon polls with. Never shown to a user. */
222
357
  declare function generateDeviceCode(): string;
223
- /** A runner bearer token. */
224
- declare function generateRunnerToken(): string;
225
358
  /** A runner id. */
226
359
  declare function generateRunnerId(): string;
227
360
  /** A job id. */
@@ -264,20 +397,23 @@ declare class MemoryStore implements ByollmStore {
264
397
  get(jobId: string): Promise<JobRecord | null>;
265
398
  claim(args: ClaimArgs): Promise<JobRecord[]>;
266
399
  renewLeases(args: RenewArgs): Promise<RenewResult>;
400
+ adopt(args: AdoptArgs): Promise<JobRecord | null>;
267
401
  complete(args: CompleteArgs): Promise<CompleteResult>;
268
402
  subscribe(jobId: string, onChange: () => void): () => void;
269
403
  release(args: ReleaseArgs): Promise<string[]>;
270
404
  expireDue(now: number): Promise<JobRecord[]>;
271
405
  cancel(jobId: string, now: number): Promise<JobRecord | null>;
272
406
  listClaimedBy(runnerId: string): Promise<JobRecord[]>;
273
- listCancelRequests(runnerId: string): Promise<string[]>;
407
+ listCancelRequests(runnerId: string): Promise<{
408
+ jobId: string;
409
+ leaseId: string;
410
+ }[]>;
274
411
  createPairing(record: PairingRecord): Promise<void>;
275
412
  getPairingByDeviceCodeHash(hash: string): Promise<PairingRecord | null>;
276
413
  getPairingByUserCode(userCode: string): Promise<PairingRecord | null>;
277
414
  approvePairing(args: ApproveArgs): Promise<RunnerRecord>;
278
415
  denyPairing(userCode: string, _now: number): Promise<void>;
279
416
  consumePairingToken(deviceCodeHash: string): Promise<void>;
280
- getRunnerByTokenHash(hash: string): Promise<RunnerRecord | null>;
281
417
  getRunner(runnerId: string): Promise<RunnerRecord | null>;
282
418
  touchRunner(args: TouchArgs): Promise<RunnerRecord | null>;
283
419
  revokeRunner(runnerId: string, now: number): Promise<void>;
@@ -288,4 +424,4 @@ declare class MemoryStore implements ByollmStore {
288
424
  /** The capability that would serve a kind, if any. */
289
425
  declare function capabilityFor(capabilities: readonly Capability[], kind: string): Capability | undefined;
290
426
 
291
- export { ApproveArgs, type AvailabilityQuery, ByollmApp, type ByollmAppOptions, ByollmStore, ClaimArgs, CompleteArgs, CompleteResult, EnqueueInput, HandlerConfig, type JobHandle, JobRecord, MemoryStore, type MemoryStoreOptions, type NoRunnerReason, PairingRecord, PollingDeliveryDeps, ReleaseArgs, RenewArgs, RenewResult, ResultDelivery, type RunnerAvailability, RunnerRecord, TouchArgs, WaitOptions, capabilityFor, createFetchHandler, formatSiteKeys, generateDeviceCode, generateJobId, generateRunnerId, generateRunnerToken, generateSiteKeys, generateUserCode, hashSecret, normalizeUserCode, routeEndpoint, secretsMatch, signatureFrom, siteKeysFromEnv };
427
+ export { AdoptArgs, ApproveArgs, type AvailabilityQuery, ByollmApp, type ByollmAppOptions, ByollmStore, ClaimArgs, CloudLane, type CloudLaneOptions, CompleteArgs, CompleteResult, EnqueueInput, HandlerConfig, type JobHandle, JobRecord, MemoryStore, type MemoryStoreOptions, type NoRunnerReason, PairingRecord, PollingDeliveryDeps, type PumpReport, RelayUnavailable, ReleaseArgs, RenewArgs, RenewResult, ResultDelivery, type RunnerAvailability, RunnerRecord, TouchArgs, WaitOptions, capabilityFor, createFetchHandler, formatSiteKeys, generateDeviceCode, generateJobId, generateRunnerId, generateSiteKeys, generateUserCode, hashSecret, normalizeUserCode, routeEndpoint, secretsMatch, signatureFrom, siteKeysFromEnv };