@byollm/relay 0.1.0-alpha.88 → 0.1.0-alpha.89

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 CHANGED
@@ -1,5 +1,5 @@
1
1
  > [!WARNING]
2
- > **Alpha (`0.1.0-alpha.88`) — under active development. Don't use this yet.**
2
+ > **Alpha (`0.1.0-alpha.89`) — under active development. Don't use this yet.**
3
3
  >
4
4
  > This is a walking skeleton. It routes real jobs between real daemons and real
5
5
  > sites, and it is the fixture byollm_009 freezes against — but it keeps its
@@ -322,6 +322,23 @@ function describeStoreContract(name, options) {
322
322
  expect(await store.job(SITE, "late")).toBeUndefined();
323
323
  await done();
324
324
  });
325
+ it("reports what a sweep removed, not only what it requeued \u2014 B096", async () => {
326
+ const { store, done } = await make();
327
+ await store.enqueue({
328
+ id: "expired",
329
+ siteId: SITE,
330
+ stub: { ...stub("expired"), deadlineAt: Date.now() - 1e3 }
331
+ });
332
+ await store.enqueue({ id: "alive", siteId: SITE, stub: stub("alive") });
333
+ const swept = await store.sweep();
334
+ expect(
335
+ swept.map((job) => job.id),
336
+ "a sweep removed a job and reported nothing about it"
337
+ ).toContain("expired");
338
+ expect(swept.map((job) => job.id)).not.toContain("alive");
339
+ expect(await store.job(SITE, "alive")).toBeDefined();
340
+ await done();
341
+ });
325
342
  it("names a cancelled job to the device holding it, and offers it to nobody", async () => {
326
343
  const { store, done } = await make();
327
344
  await store.enqueue({ id: "a", siteId: SITE, stub: stub("a") });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/store-contract.ts"],"sourcesContent":["import { generateKeys, publicIdentityOf, type JobStub } from \"@byollm/protocol\";\nimport { describe, expect, it } from \"vitest\";\nimport { routeKey } from \"./state.js\";\nimport type { RoutingStore } from \"./store.js\";\n\n/**\n * The routing store's behaviour, written once and run against every\n * implementation — cloud_008 finding 54.\n *\n * There were two copies. This package tested `RelayState`; `byollm-cloud`\n * tested `ValkeyRoutingStore` with a file that opened by explaining it was\n * \"written once and parameterised… a second copy of the scenario is a second\n * place for two implementations to quietly diverge\" — and was itself the\n * second copy. It had drifted to sixteen cases against the eighteen in the\n * ledger, which is exactly the divergence the sentence predicted, happening\n * to the sentence.\n *\n * So the contract lives here, in the package that declares `RoutingStore`,\n * and both repositories import it. A store that cannot pass this is not a\n * routing store, whatever it implements.\n *\n * ## Why this ships in the published package\n *\n * Because the implementation that matters most is in another repository. A\n * contract only the author can run is a description; one a third party runs\n * against their own implementation is a contract. `@byollm/relay/store-contract`\n * is a subpath export so nothing that imports the relay itself pulls in a\n * test framework.\n *\n * ## What this cannot prove\n *\n * `CLAIM_ATOMIC` is a MUST and every case here would pass against a store\n * that read, decided and wrote in three steps — in one process there is\n * nothing to interleave. Concurrency belongs with the implementation that\n * has a network in it, and `byollm-cloud`'s suite runs it against Valkey with\n * many connections. Named here so the omission is a decision rather than an\n * oversight.\n */\n\n/** The control-plane site id these cases route under. */\nexport const CONTRACT_SITE = \"site_store\";\n\n/** A site's identity key id — byollm_009 Amendment A §A.3. */\nconst SITE_KEY_ID = \"BYOLLM-TEST-SITE-KEY-ID\";\n\nconst SITE = CONTRACT_SITE;\n\nconst stub = (id: string, owner = \"alice\"): JobStub => ({\n id,\n kind: \"llm.generate\",\n owner,\n site: SITE_KEY_ID,\n audience: \"private\",\n sizeClass: \"small\",\n streaming: false,\n deadlineAt: 4_102_444_800_000,\n});\n\n/** One advertised route, as a daemon describes it on every heartbeat. */\nconst capability = (model: string) => ({\n kind: \"llm.generate\" as const,\n service: model,\n backendId: \"ollama\" as const,\n backendClass: \"process\" as const,\n model,\n offerScope: \"private\" as const,\n});\n\nconst ENVELOPE = {\n ciphertext: \"AAAA\",\n recipientKeyId: \"r\",\n senderKeyId: \"s\",\n direction: \"payload\" as const,\n deadlineAt: 4_102_444_800_000,\n};\n\n/**\n * A claim, with its routes written out — cloud_009 §3.\n *\n * `routes` replaced `siteId` + `owners`, and the cases that pass `owners`\n * below now pass the pairs those owners are reachable through. That rewrite\n * is the contract's own statement of the rule: there is no way to express\n * \"this owner, any site\" here, because that is not a thing consent says.\n */\nconst claimArgs = (\n over: { owners?: string[]; sites?: string[] } & Record<string, unknown> = {},\n) => {\n const { owners = [\"alice\"], sites = [SITE], ...rest } = over;\n return {\n runnerId: \"runner_1\",\n owner: \"alice\",\n device: publicIdentityOf(generateKeys(Date.now())),\n kinds: new Set([\"llm.generate\"]),\n routes: new Set(\n sites.flatMap((site) => owners.map((owner) => routeKey(site, owner))),\n ),\n max: 10,\n leaseMs: 60_000,\n ...rest,\n };\n};\n\nexport interface StoreContractOptions {\n /**\n * A fresh, empty store, and how to dispose of it.\n *\n * Arrow-typed rather than a method, because the caller passes these\n * around: a method signature lets `this` travel with the call, and a\n * factory read off an options object is exactly where that goes wrong.\n */\n readonly make: () => Promise<{\n store: RoutingStore;\n done: () => Promise<void>;\n }>;\n /**\n * Whether this store writes stubs as bytes and reads them back.\n *\n * An in-process store holds typed objects and cannot hold a stub it cannot\n * parse; a serialising one can, because what it wrote may have been written\n * by a previous version. The case that covers it is skipped rather than\n * hidden — a reader should know which half of this contract each store is\n * proving (cloud_008 §2.1a).\n */\n readonly serialising?: boolean;\n /** Write a stub's raw bytes, bypassing serialisation. */\n readonly writeRawStub?: (\n store: RoutingStore,\n id: string,\n raw: string,\n ) => Promise<void>;\n}\n\n/** Run the contract. Call inside a suite; it declares its own `describe`. */\nexport function describeStoreContract(\n name: string,\n options: StoreContractOptions,\n): void {\n const { make, serialising, writeRawStub } = options;\n describe(`the routing store — ${name}`, () => {\n it(\"is idempotent by job id\", async () => {\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n await store.claim(claimArgs());\n // A republish must not disturb work in flight — byollm_009 §4.2's replay\n // argument rests on it.\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n expect((await store.job(SITE, \"a\"))?.state).toBe(\"awaiting-payload\");\n await done();\n });\n\n it(\"gives two sites the same id without either seeing the other\", async () => {\n // cloud_009 §3. Keyed by the bare id, the second site's enqueue returned\n // the *first* site's job (cloud_008 finding 58), and the refusal that\n // fixed it was a cross-tenant existence oracle: a site knows its own stub\n // is well-formed, so any answer it can tell apart from success confirms\n // somebody else holds that id. Keyed by (site, id), the collision does\n // not exist and there is nothing to answer.\n const { store, done } = await make();\n await store.enqueue({ id: \"shared\", siteId: SITE, stub: stub(\"shared\") });\n await store.enqueue({\n id: \"shared\",\n siteId: \"site_other\",\n stub: stub(\"shared\", \"bob\"),\n });\n\n // Two jobs, each its own site's.\n expect((await store.job(SITE, \"shared\"))?.stub.owner).toBe(\"alice\");\n expect((await store.job(\"site_other\", \"shared\"))?.stub.owner).toBe(\"bob\");\n\n // And a claim for one site does not see the other's, which is the\n // property the key exists for rather than a restatement of it.\n const granted = await store.claim(claimArgs());\n expect(granted.map((job) => job.id)).toEqual([\"shared\"]);\n expect(granted[0]?.owner).toBe(\"alice\");\n\n // The same site republishing is still absorbed — byollm_009 §4.2's\n // replay argument, which is what idempotence is for.\n const replay = await store.enqueue({\n id: \"shared\",\n siteId: SITE,\n stub: stub(\"shared\"),\n });\n expect(replay).toEqual(await store.job(SITE, \"shared\"));\n await done();\n });\n\n it(\"grants only what the owners set allows\", async () => {\n const { store, done } = await make();\n await store.enqueue({ id: \"mine\", siteId: SITE, stub: stub(\"mine\") });\n await store.enqueue({\n id: \"theirs\",\n siteId: SITE,\n stub: stub(\"theirs\", \"mallory\"),\n });\n const granted = await store.claim(claimArgs());\n expect(granted.map((job) => job.id)).toEqual([\"mine\"]);\n await done();\n });\n\n it(\"refuses a stale lease and honours the current one\", async () => {\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs());\n await store.seal({ jobId: \"a\", siteId: SITE, envelope: ENVELOPE });\n\n expect(\n await store.takePayload({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: \"an-older-grant\",\n }),\n ).toEqual({ refused: \"stale-lease\" });\n\n expect(\n await store.takePayload({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: granted!.lease.id,\n }),\n ).toEqual({ envelope: ENVELOPE });\n await done();\n });\n\n it(\"will not answer for one job with another job's lease\", async () => {\n // cloud_009 §3. Holder-scoped calls carry a lease id and no site, so the\n // store resolves the job *from the lease* — and a lease id belonging to a\n // different job must not be a way to reach that job's payload.\n //\n // A mutation that dropped the \"does this lease's job match the id the\n // caller named\" check survived every other case in this contract, on both\n // implementations, because nothing else here ever presents a mismatched\n // pair. The holder of a valid grant is exactly the party who could try\n // it.\n const { store, done } = await make();\n await store.enqueue({ id: \"mine\", siteId: SITE, stub: stub(\"mine\") });\n await store.enqueue({ id: \"other\", siteId: SITE, stub: stub(\"other\") });\n const granted = await store.claim(claimArgs());\n const mine = granted.find((job) => job.id === \"mine\");\n const other = granted.find((job) => job.id === \"other\");\n await store.seal({ jobId: \"other\", siteId: SITE, envelope: ENVELOPE });\n\n // The right runner, a real lease, the wrong job.\n expect(\n await store.takePayload({\n jobId: \"other\",\n runnerId: \"runner_1\",\n leaseId: mine!.lease.id,\n }),\n ).toEqual({ refused: \"stale-lease\" });\n\n // And the honest pairing still works, so this is not \"refuse everything\".\n expect(\n await store.takePayload({\n jobId: \"other\",\n runnerId: \"runner_1\",\n leaseId: other!.lease.id,\n }),\n ).toEqual({ envelope: ENVELOPE });\n await done();\n });\n\n it(\"renews a grant it still holds, and extends the sweep with it\", async () => {\n // cloud_008 §0.6, at the contract level: renewal has to be one operation,\n // because between a read and a write another replica can sweep the lease\n // — and the renewal would then resurrect a grant on a job already back in\n // the queue. In Valkey that is a script; in memory it is a method; the\n // guarantee is the same one, so it is tested here rather than twice.\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs({ leaseMs: 1_000 }));\n\n const renewed = await store.renewLeases({\n runnerId: \"runner_1\",\n leases: [{ jobId: \"a\", leaseId: granted!.lease.id }],\n leaseMs: 60_000,\n });\n\n expect(renewed.lost).toEqual([]);\n expect(renewed.renewed.map((r) => r.jobId)).toEqual([\"a\"]);\n // The store's own clock did the arithmetic — the caller passed a duration,\n // never an instant, which is what keeps two replicas from measuring one\n // lease against two clocks (cloud_006 §3.4).\n expect(renewed.renewed[0]!.expiresAt).toBeGreaterThan(\n granted!.lease.expiresAt,\n );\n\n // And it is the *stored* grant that moved, not just the number returned.\n // Reporting a renewal without performing one is the mutation that\n // survived the first version of the relay's own test for this.\n expect((await store.job(SITE, \"a\"))?.claimedBy?.leaseExpiresAt).toBe(\n renewed.renewed[0]!.expiresAt,\n );\n await done();\n });\n\n it(\"reports a lease the runner no longer holds as lost, and renews nothing\", async () => {\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs({ leaseMs: 1_000 }));\n const before = (await store.job(SITE, \"a\"))?.claimedBy?.leaseExpiresAt;\n\n const renewed = await store.renewLeases({\n runnerId: \"runner_1\",\n leases: [{ jobId: \"a\", leaseId: \"a-grant-that-ended\" }],\n leaseMs: 60_000,\n });\n\n expect(renewed.renewed).toEqual([]);\n expect(renewed.lost).toEqual([\n { jobId: \"a\", leaseId: \"a-grant-that-ended\" },\n ]);\n // A refusal must not advance anything — the current holder's grant is\n // untouched by somebody else's stale renewal.\n expect((await store.job(SITE, \"a\"))?.claimedBy?.leaseExpiresAt).toBe(\n before,\n );\n expect((await store.job(SITE, \"a\"))?.claimedBy?.leaseId).toBe(\n granted!.lease.id,\n );\n await done();\n });\n\n it(\"does not hand out a stub it cannot parse\", async () => {\n // cloud_008 §2.1a, and the case is not hypothetical: two jobs enqueued\n // before alpha.15 had no `site`, came back in a claim, and the daemon's\n // `.strict()` parse rejected the whole response. Two dead rows denied\n // claims to every device on the hub, and the queue could not drain past\n // them.\n //\n // The store had `JSON.parse(stub) as JobStub` — trusting what it wrote,\n // when what it wrote was written by a previous version. A routing store\n // outlives the deployment that filled it, so a wire change to `JobStub`\n // is a data migration whether or not anyone plans one.\n //\n // Only meaningful against a store that serialises: `RelayState` holds\n // typed objects and cannot reach this state, so it passes by\n // construction — which is worth saying rather than hiding, because a\n // reader should know which half of this contract each store is proving.\n const { store, done } = await make();\n if (!serialising || writeRawStub === undefined) {\n await done();\n return;\n }\n\n await store.enqueue({ id: \"good\", siteId: SITE, stub: stub(\"good\") });\n await store.enqueue({ id: \"old\", siteId: SITE, stub: stub(\"old\") });\n // Exactly what alpha.14 wrote: a stub with no `site`.\n const legacy = { ...stub(\"old\") } as Record<string, unknown>;\n delete legacy[\"site\"];\n await writeRawStub(store, \"old\", JSON.stringify(legacy));\n\n const granted = await store.claim(claimArgs({ max: 10 }));\n\n // The good one is still handed out — \"return nothing\" would pass a test\n // that only checked the bad one was absent, and would stop all routing.\n expect(granted.map((job) => job.id)).toEqual([\"good\"]);\n // And the bad one is back in the queue rather than stuck holding a lease\n // nobody received.\n expect((await store.job(SITE, \"old\"))?.state).toBe(\"queued\");\n await done();\n });\n\n it(\"honours a self job's audience\", async () => {\n // cloud_008 §2.1 at the contract level. The owners set is everyone this\n // device may run for, which for a Team owner's machine is the whole\n // roster — right for public and named, wrong for the one audience a user\n // picks because they want their own machine.\n const { store, done } = await make();\n await store.enqueue({\n id: \"private\",\n siteId: SITE,\n stub: { ...stub(\"private\", \"alice\"), audience: \"private\" },\n });\n\n // A roster owner's machine: may run alice's work in general.\n const granted = await store.claim(\n claimArgs({ owner: \"owner\", owners: [\"owner\", \"alice\"] }),\n );\n\n expect(granted).toEqual([]);\n expect((await store.job(SITE, \"private\"))?.state).toBe(\"queued\");\n await done();\n });\n\n it(\"still offers that job to its owner's own machine\", async () => {\n const { store, done } = await make();\n await store.enqueue({\n id: \"private\",\n siteId: SITE,\n stub: { ...stub(\"private\", \"alice\"), audience: \"private\" },\n });\n const granted = await store.claim(\n claimArgs({ owner: \"alice\", owners: [\"alice\"] }),\n );\n expect(granted.map((job) => job.id)).toEqual([\"private\"]);\n await done();\n });\n\n it(\"does not offer a job back to the runner that refused it\", async () => {\n // `REFUSAL_NOT_REOFFERED`. `releaseLeases` gained an **optional** reason,\n // which means a store can ignore it and still typecheck — this class has\n // now diverged from the interface that way twice, so the contract is the\n // only thing that catches it.\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs());\n\n await store.releaseLeases({\n runnerId: \"runner_1\",\n leases: [{ jobId: \"a\", leaseId: granted!.lease.id }],\n reason: \"refused\",\n });\n\n expect(await store.claim(claimArgs())).toEqual([]);\n expect((await store.job(SITE, \"a\"))?.state).toBe(\"queued\");\n // And somebody else may still run it.\n expect(\n (await store.claim(claimArgs({ runnerId: \"runner_2\" }))).map(\n (j) => j.id,\n ),\n ).toEqual([\"a\"]);\n await done();\n });\n\n it(\"does not offer a job back to a runner before its not-before\", async () => {\n /**\n * The middle ground between \"not ever\" and \"immediately\".\n *\n * A control plane declining a job for something the world can change —\n * an unfilled mapping slot, a resolution naming another machine, a\n * store that was briefly unreachable — means neither. Released\n * immediately, the device re-claims at once and is declined again; a\n * spin, and in a deployment one database read per turn of it.\n *\n * Asserted with an explicit moment rather than by moving a clock,\n * because a store on the other side of a network has its own and this\n * contract cannot reach it.\n */\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs());\n\n await store.releaseLeases({\n runnerId: \"runner_1\",\n leases: [{ jobId: \"a\", leaseId: granted!.lease.id }],\n retryAfter: Date.now() + 600_000,\n });\n\n expect(await store.claim(claimArgs())).toEqual([]);\n expect((await store.job(SITE, \"a\"))?.state).toBe(\"queued\");\n // And it is *not* a refusal: another device gets it at once, which is\n // the entire reason this is a different thing.\n expect(\n (await store.claim(claimArgs({ runnerId: \"runner_2\" }))).map(\n (j) => j.id,\n ),\n ).toEqual([\"a\"]);\n await done();\n });\n\n it(\"offers it again once the not-before has passed\", async () => {\n // The other half, and the one that makes it a rate rather than a\n // refusal: a person who fixes their mapping gets their queued work.\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs());\n\n await store.releaseLeases({\n runnerId: \"runner_1\",\n leases: [{ jobId: \"a\", leaseId: granted!.lease.id }],\n retryAfter: Date.now() - 1_000,\n });\n\n expect((await store.claim(claimArgs())).map((j) => j.id)).toEqual([\"a\"]);\n await done();\n });\n\n it(\"will not un-finish a job that is already done\", async () => {\n /**\n * The third holder-scoped door — byollm-review 2026-08-27.\n *\n * A release naming a valid lease on a **done** job flipped it back to\n * `queued`. The recorded result survives on the row and becomes\n * unreachable, because `finished()` filters on state — so the site\n * never collects it, the job is offered again, and somebody's hardware\n * runs it a second time and overwrites the first answer.\n *\n * Not hypothetical: the daemon's own shutdown races it. A release and a\n * result for one lease are in flight together, and if the result won,\n * this undid it.\n *\n * `takePayload` got a terminal guard at V1-6 and `complete` at\n * cloud_008 §3.6. This one was left open, and no contract case existed\n * for it — so neither implementation could fail for it. Three doors,\n * one rule, shut one at a time; this is the rule stated where every\n * store has to answer for it.\n */\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs());\n const lease = granted!.lease.id;\n\n await store.takePayload({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: lease,\n });\n await store.complete({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: lease,\n envelope: ENVELOPE,\n disposition: \"ok\",\n });\n\n const released = await store.releaseLeases({\n runnerId: \"runner_1\",\n leases: [{ jobId: \"a\", leaseId: lease }],\n reason: \"shutdown\",\n });\n\n // Released nothing, and said so — a caller that believed this had\n // requeued would be as wrong as the store that did.\n expect(released).toEqual([]);\n expect((await store.job(SITE, \"a\"))?.state).toBe(\"done\");\n\n // And the result is still collectable, which is the harm the state\n // change actually caused: `finished()` filters on state, so a job\n // flipped back to `queued` hid an answer that had already been paid\n // for.\n expect((await store.finished(SITE)).map((j) => j.id)).toEqual([\"a\"]);\n\n // Nor is it offered to anybody again. The second execution is the\n // expensive half — somebody's tokens, spent twice, for one job.\n expect(await store.claim(claimArgs({ runnerId: \"runner_2\" }))).toEqual(\n [],\n );\n await done();\n });\n\n it(\"keeps a job claimable by a runner that only went away\", async () => {\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs());\n\n await store.releaseLeases({\n runnerId: \"runner_1\",\n leases: [{ jobId: \"a\", leaseId: granted!.lease.id }],\n reason: \"shutdown\",\n });\n\n expect((await store.claim(claimArgs())).map((j) => j.id)).toEqual([\"a\"]);\n await done();\n });\n\n it(\"stops offering a job past its deadline, and drops the ciphertext\", async () => {\n // cloud_008 §2.2. `deadlineAt` travelled on every stub and nothing read\n // it, so expired jobs were offered forever and their sealed payloads kept\n // for as long as the store lived.\n const { store, done } = await make();\n await store.enqueue({\n id: \"late\",\n siteId: SITE,\n stub: { ...stub(\"late\"), deadlineAt: Date.now() - 1_000 },\n });\n\n expect(await store.claim(claimArgs())).toEqual([]);\n expect(await store.job(SITE, \"late\")).toBeUndefined();\n await done();\n });\n\n it(\"names a cancelled job to the device holding it, and offers it to nobody\", async () => {\n // cloud_008 §2.2.\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n await store.claim(claimArgs());\n\n expect(await store.cancel({ jobId: \"a\", siteId: SITE })).toBe(true);\n // Named by grant — V1-3, so a daemon holding two sites' `a` knows\n // which one the site withdrew.\n const held = (await store.job(SITE, \"a\"))?.claimedBy?.leaseId;\n expect(await store.cancelRequests(\"runner_1\")).toEqual([\n { jobId: \"a\", leaseId: held },\n ]);\n\n // Scoped to the caller's site: a site must not reach another's work by\n // guessing an id.\n expect(await store.cancel({ jobId: \"a\", siteId: \"someone_else\" })).toBe(\n false,\n );\n await done();\n });\n\n it(\"records a result once\", async () => {\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs());\n\n const first = await store.complete({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: granted!.lease.id,\n envelope: ENVELOPE,\n disposition: \"ok\",\n });\n const replay = await store.complete({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: granted!.lease.id,\n envelope: { ...ENVELOPE, ciphertext: \"different\" },\n disposition: \"error\",\n });\n\n expect(first).toEqual({ accepted: true, state: \"done\" });\n // `duplicate` — cloud_008 §3.6. Case 18 above is the one that says why.\n expect(replay).toEqual({\n accepted: false,\n duplicate: true,\n state: \"done\",\n });\n // The property, not the boolean: the second result did not overwrite.\n expect((await store.job(SITE, \"a\"))?.disposition).toBe(\"ok\");\n await done();\n });\n\n it(\"answers the device that finished it with `duplicate`\", async () => {\n // Contract case 18 — cloud_008 §3.6, and the eighteenth exists because\n // the compiler cannot see any of this: the return type's `duplicate` is\n // optional, so a store that never sets it typechecks perfectly while\n // enforcing `RESULT_IDEMPOTENT` by accident or not at all.\n //\n // A daemon whose acknowledgment was lost hears that its answer is already\n // recorded, rather than that its lease is stale — the second message\n // invents a worry about a result safely on disk.\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs());\n\n const first = await store.complete({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: granted!.lease.id,\n envelope: ENVELOPE,\n disposition: \"ok\",\n });\n expect(first).toEqual({ accepted: true, state: \"done\" });\n\n const replay = await store.complete({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: granted!.lease.id,\n envelope: { ...ENVELOPE, ciphertext: \"a-different-result\" },\n disposition: \"error\",\n });\n expect(replay).toEqual({\n accepted: false,\n duplicate: true,\n state: \"done\",\n });\n\n // A *different* device, on a job that is terminal, gets the refusal it\n // would get for one that is not — otherwise the two answers differ and a\n // job id becomes a terminality probe.\n const stranger = await store.complete({\n jobId: \"a\",\n runnerId: \"runner_2\",\n leaseId: granted!.lease.id,\n envelope: ENVELOPE,\n disposition: \"ok\",\n });\n expect(stranger).toEqual({ refused: \"not-holder\" });\n\n // And the first answer is what survived, which is the property rather\n // than any of the booleans above.\n expect((await store.job(SITE, \"a\"))?.disposition).toBe(\"ok\");\n await done();\n });\n\n it(\"refuses a result produced under a grant that ended\", async () => {\n // cloud_008 §1.4a at the contract level, and it belongs here more than\n // anywhere: `RoutingStore.complete` gained `leaseId` and this class kept\n // typechecking without it, because a parameter object with fewer\n // properties is assignable to one with more. The relay would have\n // enforced LEASE_HONORED on the memory store and not on the store that\n // runs in production, with nothing red on the way.\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n await store.claim(claimArgs());\n\n const late = await store.complete({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: \"a-grant-that-ended\",\n envelope: ENVELOPE,\n disposition: \"ok\",\n });\n\n expect(late).toEqual({ refused: \"stale-lease\" });\n // Untouched: the current holder can still finish it.\n expect((await store.job(SITE, \"a\"))?.state).toBe(\"awaiting-payload\");\n expect((await store.job(SITE, \"a\"))?.result).toBeUndefined();\n await done();\n });\n\n it(\"refuses a payload for a job that already finished [V1-6]\", async () => {\n // The holder and lease checks both pass for a job this runner finished\n // moments ago — completing does not end the grant. So a replayed fetch\n // set `state = 'running'` on a **done** job: the site stopped being able\n // to collect its result, and the sweep requeued completed work as though\n // the device had died holding it.\n //\n // Which is `RESULT_IDEMPOTENT` broken through the other door: a\n // duplicate request undoing a finished job.\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs());\n await store.seal({ jobId: \"a\", siteId: SITE, envelope: ENVELOPE });\n await store.takePayload({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: granted!.lease.id,\n });\n await store.complete({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: granted!.lease.id,\n envelope: ENVELOPE,\n disposition: \"ok\",\n });\n\n const replay = await store.takePayload({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: granted!.lease.id,\n });\n // Its own refusal, not `not-ready`: one says keep asking and this says\n // stop, and a daemon that read them alike would poll a finished job\n // until its lease ran out.\n expect(replay).toEqual({ refused: \"terminal\" });\n // And the finished job is still finished, which is the property.\n expect((await store.job(SITE, \"a\"))?.state).toBe(\"done\");\n await done();\n });\n\n it(\"tells a runner nothing about another site's job id [V1-8]\", async () => {\n // Job ids are chosen per site, so a bare id is a guess about somebody\n // else's namespace. The answer used to depend on whether that guess\n // landed: an id belonging to another tenant came back `not-holder`,\n // an id belonging to nobody came back `not-found`. Two status codes,\n // one bit of somebody else's business — finding 58's oracle, reached\n // through the holder door instead of the site plane.\n const { store, done } = await make();\n // Another tenant's job, under an id this caller can guess but a site it\n // does not route for.\n await store.enqueue({\n id: \"secret\",\n siteId: \"site_somebody_else\",\n stub: stub(\"secret\"),\n });\n await store.enqueue({ id: \"mine\", siteId: SITE, stub: stub(\"mine\") });\n const granted = await store.claim(claimArgs());\n const mine = granted.find((job) => job.id === \"mine\");\n\n // Asking about a job this runner does not hold, under a lease it does.\n const other = await store.takePayload({\n jobId: \"secret\",\n runnerId: \"runner_1\",\n leaseId: mine!.lease.id,\n });\n const absent = await store.takePayload({\n jobId: \"no-such-job-anywhere\",\n runnerId: \"runner_1\",\n leaseId: mine!.lease.id,\n });\n\n expect(other).toEqual(absent);\n expect(other).toEqual({ refused: \"not-found\" });\n await done();\n });\n\n // ── routing by kind ─────────────────────────────────────────────────\n //\n // The selection cases lived here: a job could name one of the owner's\n // services and a store had to offer it only to a device advertising that\n // exact (kind, service) pair. Amendment L removed the field — sites\n // declare purposes and people map them — so a store now matches on kind\n // alone, and the pairs it used to carry are gone from `ClaimInput`.\n //\n // What replaces those cases is the property that a store must *not* have\n // opinions it no longer has the inputs for.\n\n it(\"offers a job to any device that serves its kind\", async () => {\n // Which of the owner's services answers is resolved at claim by a\n // control plane, from a mapping this store never sees. A store that\n // narrowed further would be deciding something it cannot know, and the\n // job would sit queued behind a judgement nobody made.\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n\n const claimed = await store.claim(\n claimArgs({ runnerId: \"runner_any\", kinds: new Set([\"llm.generate\"]) }),\n );\n expect(claimed.map((j) => j.id)).toEqual([\"a\"]);\n await done();\n });\n\n it(\"does not offer a job to a device that serves a different kind\", async () => {\n // The control. Kind is the whole of the match, so it has to actually\n // match — a store that offered everything to everybody would push the\n // narrowing onto a control plane that would then decline it, which is\n // a round trip and a wait for a fact this side already had.\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n\n const claimed = await store.claim(\n claimArgs({ runnerId: \"runner_chat\", kinds: new Set([\"llm.chat\"]) }),\n );\n expect(claimed).toEqual([]);\n await done();\n });\n\n // ── presence ────────────────────────────────────────────────────────\n //\n // The seam had no contract coverage at all: presence was exercised\n // against `RelayState` and nothing held a shared store to the same\n // behaviour. That is the shape the pairing ceiling was found in — one\n // seam, two implementations, and the check driving the one nobody\n // deploys — so these land with `Presence.capabilities` rather than after\n // somebody notices.\n\n it(\"remembers a device, and what it says it can run\", async () => {\n const { store, done } = await make();\n const device = publicIdentityOf(generateKeys(3_000_000_000_000));\n await store.seen({\n runnerId: \"runner_1\",\n owner: \"alice\",\n device,\n capabilities: [capability(\"llama3\")],\n withheld: [],\n });\n\n const known = await store.presence(\"runner_1\");\n expect(known?.owner).toBe(\"alice\");\n expect(known?.device.identity).toBe(device.identity);\n expect(known?.capabilities.map((row) => row.model)).toEqual([\"llama3\"]);\n await done();\n });\n\n it(\"replaces the matrix rather than merging it\", async () => {\n // The heartbeat re-sends the whole matrix every time so a server never\n // matches against a stale one. A store that kept the union would go on\n // advertising a backend the machine has lost — and work would route to\n // it, which is worse than forgetting one it still has.\n const { store, done } = await make();\n const device = publicIdentityOf(generateKeys(3_000_000_000_001));\n const seen = { runnerId: \"runner_2\", owner: \"alice\", device };\n await store.seen({\n ...seen,\n capabilities: [capability(\"llama3\")],\n withheld: [],\n });\n await store.seen({\n ...seen,\n capabilities: [capability(\"mistral\")],\n withheld: [],\n });\n\n const known = await store.presence(\"runner_2\");\n expect(known?.capabilities.map((row) => row.model)).toEqual([\"mistral\"]);\n await done();\n });\n\n it(\"keeps an empty matrix, because empty is an answer\", async () => {\n // A paired machine with no healthy backend — the connect-first ruling's\n // whole point. A store that treated empty as \"nothing to record\" would\n // leave the last non-empty matrix standing and the machines page would\n // show models that are gone.\n const { store, done } = await make();\n const device = publicIdentityOf(generateKeys(3_000_000_000_002));\n const seen = { runnerId: \"runner_3\", owner: \"alice\", device };\n await store.seen({\n ...seen,\n capabilities: [capability(\"llama3\")],\n withheld: [],\n });\n await store.seen({ ...seen, capabilities: [], withheld: [] });\n\n expect((await store.presence(\"runner_3\"))?.capabilities).toEqual([]);\n await done();\n });\n\n it(\"remembers which kinds are withheld, and drops them when resolved\", async () => {\n // byollm_016. Two services answering one kind with no `defaults` entry\n // is a state only the daemon can see: from the matrix alone a withheld\n // kind and an absent one are the same shape, so a store that dropped\n // this field would leave the owner's page saying \"nothing serves\n // llm.generate\" — true, and useless, when the real sentence is \"two\n // services answer it and you have not chosen\".\n //\n // It lives in the contract rather than one store's tests because the\n // pairing ceiling was found exactly that way: one seam, two\n // implementations, and the check driving the one nobody deploys.\n const { store, done } = await make();\n const device = publicIdentityOf(generateKeys(3_000_000_000_004));\n const seen = { runnerId: \"runner_withheld\", owner: \"alice\", device };\n\n await store.seen({\n ...seen,\n capabilities: [],\n withheld: [\n {\n kind: \"llm.generate\",\n claimants: [\n { service: \"ollama\", offer: \"team\" },\n { service: \"mlx\", offer: \"private\" },\n ],\n },\n ],\n });\n\n const held = await store.presence(\"runner_withheld\");\n expect(held?.withheld.map((row) => row.kind)).toEqual([\"llm.generate\"]);\n // The claimants survive the round trip, because naming them is the\n // whole difference between a prompt and a complaint.\n expect(held?.withheld[0]?.claimants.map((c) => c.service)).toEqual([\n \"ollama\",\n \"mlx\",\n ]);\n\n // The owner chooses a default: the kind resolves and stops being\n // reported, or the page goes on asking for a decision already made.\n await store.seen({\n ...seen,\n capabilities: [capability(\"llama3\")],\n withheld: [],\n });\n expect((await store.presence(\"runner_withheld\"))?.withheld).toEqual([]);\n await done();\n });\n\n it(\"stamps presence from its own clock, and moves it on the next beat\", async () => {\n // `lastSeenAt` is liveness, and liveness is only true if something\n // advances it. It was written once at pairing and never again, so it\n // reported the pairing time under the name \"last seen\" — a field that\n // is quietly a different fact.\n const { store, done } = await make();\n const device = publicIdentityOf(generateKeys(3_000_000_000_003));\n const seen = { runnerId: \"runner_4\", owner: \"alice\", device };\n\n const before = await store.now();\n const first = await store.seen({\n ...seen,\n capabilities: [],\n withheld: [],\n });\n expect(first.lastSeenAt).toBeGreaterThanOrEqual(before);\n\n const later = await store.seen({\n ...seen,\n capabilities: [],\n withheld: [],\n });\n expect(later.lastSeenAt).toBeGreaterThanOrEqual(first.lastSeenAt);\n await done();\n });\n\n it(\"lists everyone it has seen\", async () => {\n const { store, done } = await make();\n await store.seen({\n runnerId: \"runner_5\",\n owner: \"alice\",\n device: publicIdentityOf(generateKeys(3_000_000_000_004)),\n capabilities: [],\n withheld: [],\n });\n await store.seen({\n runnerId: \"runner_6\",\n owner: \"bob\",\n device: publicIdentityOf(generateKeys(3_000_000_000_005)),\n capabilities: [],\n withheld: [],\n });\n\n const everyone = await store.everyone();\n const ids = everyone.map((row) => row.runnerId);\n expect(ids).toContain(\"runner_5\");\n expect(ids).toContain(\"runner_6\");\n await done();\n });\n\n it(\"does not know a runner it has never seen\", async () => {\n const { store, done } = await make();\n expect(await store.presence(\"runner_never\")).toBeUndefined();\n await done();\n });\n\n it(\"stamps deadlines from its own clock\", async () => {\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const before = await store.now();\n const [granted] = await store.claim(claimArgs({ leaseMs: 45_000 }));\n const after = await store.now();\n\n // Bracketed rather than exact: a real store's clock moves between the two\n // reads, which is the whole reason it is the store's clock and not ours.\n expect(granted!.lease.expiresAt).toBeGreaterThanOrEqual(before + 45_000);\n expect(granted!.lease.expiresAt).toBeLessThanOrEqual(after + 45_000);\n await done();\n });\n });\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/store-contract.ts"],"sourcesContent":["import { generateKeys, publicIdentityOf, type JobStub } from \"@byollm/protocol\";\nimport { describe, expect, it } from \"vitest\";\nimport { routeKey } from \"./state.js\";\nimport type { RoutingStore } from \"./store.js\";\n\n/**\n * The routing store's behaviour, written once and run against every\n * implementation — cloud_008 finding 54.\n *\n * There were two copies. This package tested `RelayState`; `byollm-cloud`\n * tested `ValkeyRoutingStore` with a file that opened by explaining it was\n * \"written once and parameterised… a second copy of the scenario is a second\n * place for two implementations to quietly diverge\" — and was itself the\n * second copy. It had drifted to sixteen cases against the eighteen in the\n * ledger, which is exactly the divergence the sentence predicted, happening\n * to the sentence.\n *\n * So the contract lives here, in the package that declares `RoutingStore`,\n * and both repositories import it. A store that cannot pass this is not a\n * routing store, whatever it implements.\n *\n * ## Why this ships in the published package\n *\n * Because the implementation that matters most is in another repository. A\n * contract only the author can run is a description; one a third party runs\n * against their own implementation is a contract. `@byollm/relay/store-contract`\n * is a subpath export so nothing that imports the relay itself pulls in a\n * test framework.\n *\n * ## What this cannot prove\n *\n * `CLAIM_ATOMIC` is a MUST and every case here would pass against a store\n * that read, decided and wrote in three steps — in one process there is\n * nothing to interleave. Concurrency belongs with the implementation that\n * has a network in it, and `byollm-cloud`'s suite runs it against Valkey with\n * many connections. Named here so the omission is a decision rather than an\n * oversight.\n */\n\n/** The control-plane site id these cases route under. */\nexport const CONTRACT_SITE = \"site_store\";\n\n/** A site's identity key id — byollm_009 Amendment A §A.3. */\nconst SITE_KEY_ID = \"BYOLLM-TEST-SITE-KEY-ID\";\n\nconst SITE = CONTRACT_SITE;\n\nconst stub = (id: string, owner = \"alice\"): JobStub => ({\n id,\n kind: \"llm.generate\",\n owner,\n site: SITE_KEY_ID,\n audience: \"private\",\n sizeClass: \"small\",\n streaming: false,\n deadlineAt: 4_102_444_800_000,\n});\n\n/** One advertised route, as a daemon describes it on every heartbeat. */\nconst capability = (model: string) => ({\n kind: \"llm.generate\" as const,\n service: model,\n backendId: \"ollama\" as const,\n backendClass: \"process\" as const,\n model,\n offerScope: \"private\" as const,\n});\n\nconst ENVELOPE = {\n ciphertext: \"AAAA\",\n recipientKeyId: \"r\",\n senderKeyId: \"s\",\n direction: \"payload\" as const,\n deadlineAt: 4_102_444_800_000,\n};\n\n/**\n * A claim, with its routes written out — cloud_009 §3.\n *\n * `routes` replaced `siteId` + `owners`, and the cases that pass `owners`\n * below now pass the pairs those owners are reachable through. That rewrite\n * is the contract's own statement of the rule: there is no way to express\n * \"this owner, any site\" here, because that is not a thing consent says.\n */\nconst claimArgs = (\n over: { owners?: string[]; sites?: string[] } & Record<string, unknown> = {},\n) => {\n const { owners = [\"alice\"], sites = [SITE], ...rest } = over;\n return {\n runnerId: \"runner_1\",\n owner: \"alice\",\n device: publicIdentityOf(generateKeys(Date.now())),\n kinds: new Set([\"llm.generate\"]),\n routes: new Set(\n sites.flatMap((site) => owners.map((owner) => routeKey(site, owner))),\n ),\n max: 10,\n leaseMs: 60_000,\n ...rest,\n };\n};\n\nexport interface StoreContractOptions {\n /**\n * A fresh, empty store, and how to dispose of it.\n *\n * Arrow-typed rather than a method, because the caller passes these\n * around: a method signature lets `this` travel with the call, and a\n * factory read off an options object is exactly where that goes wrong.\n */\n readonly make: () => Promise<{\n store: RoutingStore;\n done: () => Promise<void>;\n }>;\n /**\n * Whether this store writes stubs as bytes and reads them back.\n *\n * An in-process store holds typed objects and cannot hold a stub it cannot\n * parse; a serialising one can, because what it wrote may have been written\n * by a previous version. The case that covers it is skipped rather than\n * hidden — a reader should know which half of this contract each store is\n * proving (cloud_008 §2.1a).\n */\n readonly serialising?: boolean;\n /** Write a stub's raw bytes, bypassing serialisation. */\n readonly writeRawStub?: (\n store: RoutingStore,\n id: string,\n raw: string,\n ) => Promise<void>;\n}\n\n/** Run the contract. Call inside a suite; it declares its own `describe`. */\nexport function describeStoreContract(\n name: string,\n options: StoreContractOptions,\n): void {\n const { make, serialising, writeRawStub } = options;\n describe(`the routing store — ${name}`, () => {\n it(\"is idempotent by job id\", async () => {\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n await store.claim(claimArgs());\n // A republish must not disturb work in flight — byollm_009 §4.2's replay\n // argument rests on it.\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n expect((await store.job(SITE, \"a\"))?.state).toBe(\"awaiting-payload\");\n await done();\n });\n\n it(\"gives two sites the same id without either seeing the other\", async () => {\n // cloud_009 §3. Keyed by the bare id, the second site's enqueue returned\n // the *first* site's job (cloud_008 finding 58), and the refusal that\n // fixed it was a cross-tenant existence oracle: a site knows its own stub\n // is well-formed, so any answer it can tell apart from success confirms\n // somebody else holds that id. Keyed by (site, id), the collision does\n // not exist and there is nothing to answer.\n const { store, done } = await make();\n await store.enqueue({ id: \"shared\", siteId: SITE, stub: stub(\"shared\") });\n await store.enqueue({\n id: \"shared\",\n siteId: \"site_other\",\n stub: stub(\"shared\", \"bob\"),\n });\n\n // Two jobs, each its own site's.\n expect((await store.job(SITE, \"shared\"))?.stub.owner).toBe(\"alice\");\n expect((await store.job(\"site_other\", \"shared\"))?.stub.owner).toBe(\"bob\");\n\n // And a claim for one site does not see the other's, which is the\n // property the key exists for rather than a restatement of it.\n const granted = await store.claim(claimArgs());\n expect(granted.map((job) => job.id)).toEqual([\"shared\"]);\n expect(granted[0]?.owner).toBe(\"alice\");\n\n // The same site republishing is still absorbed — byollm_009 §4.2's\n // replay argument, which is what idempotence is for.\n const replay = await store.enqueue({\n id: \"shared\",\n siteId: SITE,\n stub: stub(\"shared\"),\n });\n expect(replay).toEqual(await store.job(SITE, \"shared\"));\n await done();\n });\n\n it(\"grants only what the owners set allows\", async () => {\n const { store, done } = await make();\n await store.enqueue({ id: \"mine\", siteId: SITE, stub: stub(\"mine\") });\n await store.enqueue({\n id: \"theirs\",\n siteId: SITE,\n stub: stub(\"theirs\", \"mallory\"),\n });\n const granted = await store.claim(claimArgs());\n expect(granted.map((job) => job.id)).toEqual([\"mine\"]);\n await done();\n });\n\n it(\"refuses a stale lease and honours the current one\", async () => {\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs());\n await store.seal({ jobId: \"a\", siteId: SITE, envelope: ENVELOPE });\n\n expect(\n await store.takePayload({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: \"an-older-grant\",\n }),\n ).toEqual({ refused: \"stale-lease\" });\n\n expect(\n await store.takePayload({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: granted!.lease.id,\n }),\n ).toEqual({ envelope: ENVELOPE });\n await done();\n });\n\n it(\"will not answer for one job with another job's lease\", async () => {\n // cloud_009 §3. Holder-scoped calls carry a lease id and no site, so the\n // store resolves the job *from the lease* — and a lease id belonging to a\n // different job must not be a way to reach that job's payload.\n //\n // A mutation that dropped the \"does this lease's job match the id the\n // caller named\" check survived every other case in this contract, on both\n // implementations, because nothing else here ever presents a mismatched\n // pair. The holder of a valid grant is exactly the party who could try\n // it.\n const { store, done } = await make();\n await store.enqueue({ id: \"mine\", siteId: SITE, stub: stub(\"mine\") });\n await store.enqueue({ id: \"other\", siteId: SITE, stub: stub(\"other\") });\n const granted = await store.claim(claimArgs());\n const mine = granted.find((job) => job.id === \"mine\");\n const other = granted.find((job) => job.id === \"other\");\n await store.seal({ jobId: \"other\", siteId: SITE, envelope: ENVELOPE });\n\n // The right runner, a real lease, the wrong job.\n expect(\n await store.takePayload({\n jobId: \"other\",\n runnerId: \"runner_1\",\n leaseId: mine!.lease.id,\n }),\n ).toEqual({ refused: \"stale-lease\" });\n\n // And the honest pairing still works, so this is not \"refuse everything\".\n expect(\n await store.takePayload({\n jobId: \"other\",\n runnerId: \"runner_1\",\n leaseId: other!.lease.id,\n }),\n ).toEqual({ envelope: ENVELOPE });\n await done();\n });\n\n it(\"renews a grant it still holds, and extends the sweep with it\", async () => {\n // cloud_008 §0.6, at the contract level: renewal has to be one operation,\n // because between a read and a write another replica can sweep the lease\n // — and the renewal would then resurrect a grant on a job already back in\n // the queue. In Valkey that is a script; in memory it is a method; the\n // guarantee is the same one, so it is tested here rather than twice.\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs({ leaseMs: 1_000 }));\n\n const renewed = await store.renewLeases({\n runnerId: \"runner_1\",\n leases: [{ jobId: \"a\", leaseId: granted!.lease.id }],\n leaseMs: 60_000,\n });\n\n expect(renewed.lost).toEqual([]);\n expect(renewed.renewed.map((r) => r.jobId)).toEqual([\"a\"]);\n // The store's own clock did the arithmetic — the caller passed a duration,\n // never an instant, which is what keeps two replicas from measuring one\n // lease against two clocks (cloud_006 §3.4).\n expect(renewed.renewed[0]!.expiresAt).toBeGreaterThan(\n granted!.lease.expiresAt,\n );\n\n // And it is the *stored* grant that moved, not just the number returned.\n // Reporting a renewal without performing one is the mutation that\n // survived the first version of the relay's own test for this.\n expect((await store.job(SITE, \"a\"))?.claimedBy?.leaseExpiresAt).toBe(\n renewed.renewed[0]!.expiresAt,\n );\n await done();\n });\n\n it(\"reports a lease the runner no longer holds as lost, and renews nothing\", async () => {\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs({ leaseMs: 1_000 }));\n const before = (await store.job(SITE, \"a\"))?.claimedBy?.leaseExpiresAt;\n\n const renewed = await store.renewLeases({\n runnerId: \"runner_1\",\n leases: [{ jobId: \"a\", leaseId: \"a-grant-that-ended\" }],\n leaseMs: 60_000,\n });\n\n expect(renewed.renewed).toEqual([]);\n expect(renewed.lost).toEqual([\n { jobId: \"a\", leaseId: \"a-grant-that-ended\" },\n ]);\n // A refusal must not advance anything — the current holder's grant is\n // untouched by somebody else's stale renewal.\n expect((await store.job(SITE, \"a\"))?.claimedBy?.leaseExpiresAt).toBe(\n before,\n );\n expect((await store.job(SITE, \"a\"))?.claimedBy?.leaseId).toBe(\n granted!.lease.id,\n );\n await done();\n });\n\n it(\"does not hand out a stub it cannot parse\", async () => {\n // cloud_008 §2.1a, and the case is not hypothetical: two jobs enqueued\n // before alpha.15 had no `site`, came back in a claim, and the daemon's\n // `.strict()` parse rejected the whole response. Two dead rows denied\n // claims to every device on the hub, and the queue could not drain past\n // them.\n //\n // The store had `JSON.parse(stub) as JobStub` — trusting what it wrote,\n // when what it wrote was written by a previous version. A routing store\n // outlives the deployment that filled it, so a wire change to `JobStub`\n // is a data migration whether or not anyone plans one.\n //\n // Only meaningful against a store that serialises: `RelayState` holds\n // typed objects and cannot reach this state, so it passes by\n // construction — which is worth saying rather than hiding, because a\n // reader should know which half of this contract each store is proving.\n const { store, done } = await make();\n if (!serialising || writeRawStub === undefined) {\n await done();\n return;\n }\n\n await store.enqueue({ id: \"good\", siteId: SITE, stub: stub(\"good\") });\n await store.enqueue({ id: \"old\", siteId: SITE, stub: stub(\"old\") });\n // Exactly what alpha.14 wrote: a stub with no `site`.\n const legacy = { ...stub(\"old\") } as Record<string, unknown>;\n delete legacy[\"site\"];\n await writeRawStub(store, \"old\", JSON.stringify(legacy));\n\n const granted = await store.claim(claimArgs({ max: 10 }));\n\n // The good one is still handed out — \"return nothing\" would pass a test\n // that only checked the bad one was absent, and would stop all routing.\n expect(granted.map((job) => job.id)).toEqual([\"good\"]);\n // And the bad one is back in the queue rather than stuck holding a lease\n // nobody received.\n expect((await store.job(SITE, \"old\"))?.state).toBe(\"queued\");\n await done();\n });\n\n it(\"honours a self job's audience\", async () => {\n // cloud_008 §2.1 at the contract level. The owners set is everyone this\n // device may run for, which for a Team owner's machine is the whole\n // roster — right for public and named, wrong for the one audience a user\n // picks because they want their own machine.\n const { store, done } = await make();\n await store.enqueue({\n id: \"private\",\n siteId: SITE,\n stub: { ...stub(\"private\", \"alice\"), audience: \"private\" },\n });\n\n // A roster owner's machine: may run alice's work in general.\n const granted = await store.claim(\n claimArgs({ owner: \"owner\", owners: [\"owner\", \"alice\"] }),\n );\n\n expect(granted).toEqual([]);\n expect((await store.job(SITE, \"private\"))?.state).toBe(\"queued\");\n await done();\n });\n\n it(\"still offers that job to its owner's own machine\", async () => {\n const { store, done } = await make();\n await store.enqueue({\n id: \"private\",\n siteId: SITE,\n stub: { ...stub(\"private\", \"alice\"), audience: \"private\" },\n });\n const granted = await store.claim(\n claimArgs({ owner: \"alice\", owners: [\"alice\"] }),\n );\n expect(granted.map((job) => job.id)).toEqual([\"private\"]);\n await done();\n });\n\n it(\"does not offer a job back to the runner that refused it\", async () => {\n // `REFUSAL_NOT_REOFFERED`. `releaseLeases` gained an **optional** reason,\n // which means a store can ignore it and still typecheck — this class has\n // now diverged from the interface that way twice, so the contract is the\n // only thing that catches it.\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs());\n\n await store.releaseLeases({\n runnerId: \"runner_1\",\n leases: [{ jobId: \"a\", leaseId: granted!.lease.id }],\n reason: \"refused\",\n });\n\n expect(await store.claim(claimArgs())).toEqual([]);\n expect((await store.job(SITE, \"a\"))?.state).toBe(\"queued\");\n // And somebody else may still run it.\n expect(\n (await store.claim(claimArgs({ runnerId: \"runner_2\" }))).map(\n (j) => j.id,\n ),\n ).toEqual([\"a\"]);\n await done();\n });\n\n it(\"does not offer a job back to a runner before its not-before\", async () => {\n /**\n * The middle ground between \"not ever\" and \"immediately\".\n *\n * A control plane declining a job for something the world can change —\n * an unfilled mapping slot, a resolution naming another machine, a\n * store that was briefly unreachable — means neither. Released\n * immediately, the device re-claims at once and is declined again; a\n * spin, and in a deployment one database read per turn of it.\n *\n * Asserted with an explicit moment rather than by moving a clock,\n * because a store on the other side of a network has its own and this\n * contract cannot reach it.\n */\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs());\n\n await store.releaseLeases({\n runnerId: \"runner_1\",\n leases: [{ jobId: \"a\", leaseId: granted!.lease.id }],\n retryAfter: Date.now() + 600_000,\n });\n\n expect(await store.claim(claimArgs())).toEqual([]);\n expect((await store.job(SITE, \"a\"))?.state).toBe(\"queued\");\n // And it is *not* a refusal: another device gets it at once, which is\n // the entire reason this is a different thing.\n expect(\n (await store.claim(claimArgs({ runnerId: \"runner_2\" }))).map(\n (j) => j.id,\n ),\n ).toEqual([\"a\"]);\n await done();\n });\n\n it(\"offers it again once the not-before has passed\", async () => {\n // The other half, and the one that makes it a rate rather than a\n // refusal: a person who fixes their mapping gets their queued work.\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs());\n\n await store.releaseLeases({\n runnerId: \"runner_1\",\n leases: [{ jobId: \"a\", leaseId: granted!.lease.id }],\n retryAfter: Date.now() - 1_000,\n });\n\n expect((await store.claim(claimArgs())).map((j) => j.id)).toEqual([\"a\"]);\n await done();\n });\n\n it(\"will not un-finish a job that is already done\", async () => {\n /**\n * The third holder-scoped door — byollm-review 2026-08-27.\n *\n * A release naming a valid lease on a **done** job flipped it back to\n * `queued`. The recorded result survives on the row and becomes\n * unreachable, because `finished()` filters on state — so the site\n * never collects it, the job is offered again, and somebody's hardware\n * runs it a second time and overwrites the first answer.\n *\n * Not hypothetical: the daemon's own shutdown races it. A release and a\n * result for one lease are in flight together, and if the result won,\n * this undid it.\n *\n * `takePayload` got a terminal guard at V1-6 and `complete` at\n * cloud_008 §3.6. This one was left open, and no contract case existed\n * for it — so neither implementation could fail for it. Three doors,\n * one rule, shut one at a time; this is the rule stated where every\n * store has to answer for it.\n */\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs());\n const lease = granted!.lease.id;\n\n await store.takePayload({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: lease,\n });\n await store.complete({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: lease,\n envelope: ENVELOPE,\n disposition: \"ok\",\n });\n\n const released = await store.releaseLeases({\n runnerId: \"runner_1\",\n leases: [{ jobId: \"a\", leaseId: lease }],\n reason: \"shutdown\",\n });\n\n // Released nothing, and said so — a caller that believed this had\n // requeued would be as wrong as the store that did.\n expect(released).toEqual([]);\n expect((await store.job(SITE, \"a\"))?.state).toBe(\"done\");\n\n // And the result is still collectable, which is the harm the state\n // change actually caused: `finished()` filters on state, so a job\n // flipped back to `queued` hid an answer that had already been paid\n // for.\n expect((await store.finished(SITE)).map((j) => j.id)).toEqual([\"a\"]);\n\n // Nor is it offered to anybody again. The second execution is the\n // expensive half — somebody's tokens, spent twice, for one job.\n expect(await store.claim(claimArgs({ runnerId: \"runner_2\" }))).toEqual(\n [],\n );\n await done();\n });\n\n it(\"keeps a job claimable by a runner that only went away\", async () => {\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs());\n\n await store.releaseLeases({\n runnerId: \"runner_1\",\n leases: [{ jobId: \"a\", leaseId: granted!.lease.id }],\n reason: \"shutdown\",\n });\n\n expect((await store.claim(claimArgs())).map((j) => j.id)).toEqual([\"a\"]);\n await done();\n });\n\n it(\"stops offering a job past its deadline, and drops the ciphertext\", async () => {\n // cloud_008 §2.2. `deadlineAt` travelled on every stub and nothing read\n // it, so expired jobs were offered forever and their sealed payloads kept\n // for as long as the store lived.\n const { store, done } = await make();\n await store.enqueue({\n id: \"late\",\n siteId: SITE,\n stub: { ...stub(\"late\"), deadlineAt: Date.now() - 1_000 },\n });\n\n expect(await store.claim(claimArgs())).toEqual([]);\n expect(await store.job(SITE, \"late\")).toBeUndefined();\n await done();\n });\n\n it(\"reports what a sweep removed, not only what it requeued — B096\", async () => {\n /**\n * The fact the contract never asked about, and the two implementations\n * were free to differ on exactly it.\n *\n * `RelayState.sweep` returns removed jobs on purpose, and says why:\n * *\"a caller that logs 'requeued' and never mentions expiry would\n * report a shrinking queue with no reason for it.\"* The Valkey store\n * that runs in production structurally could not — the Lua `DEL`s the\n * key, then `sweep()` maps the ids back through `job()` and drops\n * every `undefined`, so a removed job was built into the list and lost\n * one line later.\n *\n * So the reasoning the memory store wrote down never reached the\n * deployment: `main.ts` logs `requeued`, and a job the hub gave up on\n * is not in the number. B042 did not create this — deadline drops were\n * already invisible the same way — but it added a second class of\n * silent removal, and it is the class where silence matters most: a\n * site that never seals is an operator's problem whose only trace is a\n * queue that quietly shrinks.\n *\n * Asserted on the RETURN VALUE, which is the half that was missing.\n * The case above already proves the job is gone.\n */\n const { store, done } = await make();\n await store.enqueue({\n id: \"expired\",\n siteId: SITE,\n stub: { ...stub(\"expired\"), deadlineAt: Date.now() - 1_000 },\n });\n await store.enqueue({ id: \"alive\", siteId: SITE, stub: stub(\"alive\") });\n\n const swept = await store.sweep();\n expect(\n swept.map((job) => job.id),\n \"a sweep removed a job and reported nothing about it\",\n ).toContain(\"expired\");\n\n /* The control, and it is what stops \"report everything\" passing: a job\n the sweep did not touch is not in the list. */\n expect(swept.map((job) => job.id)).not.toContain(\"alive\");\n expect(await store.job(SITE, \"alive\")).toBeDefined();\n await done();\n });\n\n it(\"names a cancelled job to the device holding it, and offers it to nobody\", async () => {\n // cloud_008 §2.2.\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n await store.claim(claimArgs());\n\n expect(await store.cancel({ jobId: \"a\", siteId: SITE })).toBe(true);\n // Named by grant — V1-3, so a daemon holding two sites' `a` knows\n // which one the site withdrew.\n const held = (await store.job(SITE, \"a\"))?.claimedBy?.leaseId;\n expect(await store.cancelRequests(\"runner_1\")).toEqual([\n { jobId: \"a\", leaseId: held },\n ]);\n\n // Scoped to the caller's site: a site must not reach another's work by\n // guessing an id.\n expect(await store.cancel({ jobId: \"a\", siteId: \"someone_else\" })).toBe(\n false,\n );\n await done();\n });\n\n it(\"records a result once\", async () => {\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs());\n\n const first = await store.complete({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: granted!.lease.id,\n envelope: ENVELOPE,\n disposition: \"ok\",\n });\n const replay = await store.complete({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: granted!.lease.id,\n envelope: { ...ENVELOPE, ciphertext: \"different\" },\n disposition: \"error\",\n });\n\n expect(first).toEqual({ accepted: true, state: \"done\" });\n // `duplicate` — cloud_008 §3.6. Case 18 above is the one that says why.\n expect(replay).toEqual({\n accepted: false,\n duplicate: true,\n state: \"done\",\n });\n // The property, not the boolean: the second result did not overwrite.\n expect((await store.job(SITE, \"a\"))?.disposition).toBe(\"ok\");\n await done();\n });\n\n it(\"answers the device that finished it with `duplicate`\", async () => {\n // Contract case 18 — cloud_008 §3.6, and the eighteenth exists because\n // the compiler cannot see any of this: the return type's `duplicate` is\n // optional, so a store that never sets it typechecks perfectly while\n // enforcing `RESULT_IDEMPOTENT` by accident or not at all.\n //\n // A daemon whose acknowledgment was lost hears that its answer is already\n // recorded, rather than that its lease is stale — the second message\n // invents a worry about a result safely on disk.\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs());\n\n const first = await store.complete({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: granted!.lease.id,\n envelope: ENVELOPE,\n disposition: \"ok\",\n });\n expect(first).toEqual({ accepted: true, state: \"done\" });\n\n const replay = await store.complete({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: granted!.lease.id,\n envelope: { ...ENVELOPE, ciphertext: \"a-different-result\" },\n disposition: \"error\",\n });\n expect(replay).toEqual({\n accepted: false,\n duplicate: true,\n state: \"done\",\n });\n\n // A *different* device, on a job that is terminal, gets the refusal it\n // would get for one that is not — otherwise the two answers differ and a\n // job id becomes a terminality probe.\n const stranger = await store.complete({\n jobId: \"a\",\n runnerId: \"runner_2\",\n leaseId: granted!.lease.id,\n envelope: ENVELOPE,\n disposition: \"ok\",\n });\n expect(stranger).toEqual({ refused: \"not-holder\" });\n\n // And the first answer is what survived, which is the property rather\n // than any of the booleans above.\n expect((await store.job(SITE, \"a\"))?.disposition).toBe(\"ok\");\n await done();\n });\n\n it(\"refuses a result produced under a grant that ended\", async () => {\n // cloud_008 §1.4a at the contract level, and it belongs here more than\n // anywhere: `RoutingStore.complete` gained `leaseId` and this class kept\n // typechecking without it, because a parameter object with fewer\n // properties is assignable to one with more. The relay would have\n // enforced LEASE_HONORED on the memory store and not on the store that\n // runs in production, with nothing red on the way.\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n await store.claim(claimArgs());\n\n const late = await store.complete({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: \"a-grant-that-ended\",\n envelope: ENVELOPE,\n disposition: \"ok\",\n });\n\n expect(late).toEqual({ refused: \"stale-lease\" });\n // Untouched: the current holder can still finish it.\n expect((await store.job(SITE, \"a\"))?.state).toBe(\"awaiting-payload\");\n expect((await store.job(SITE, \"a\"))?.result).toBeUndefined();\n await done();\n });\n\n it(\"refuses a payload for a job that already finished [V1-6]\", async () => {\n // The holder and lease checks both pass for a job this runner finished\n // moments ago — completing does not end the grant. So a replayed fetch\n // set `state = 'running'` on a **done** job: the site stopped being able\n // to collect its result, and the sweep requeued completed work as though\n // the device had died holding it.\n //\n // Which is `RESULT_IDEMPOTENT` broken through the other door: a\n // duplicate request undoing a finished job.\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const [granted] = await store.claim(claimArgs());\n await store.seal({ jobId: \"a\", siteId: SITE, envelope: ENVELOPE });\n await store.takePayload({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: granted!.lease.id,\n });\n await store.complete({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: granted!.lease.id,\n envelope: ENVELOPE,\n disposition: \"ok\",\n });\n\n const replay = await store.takePayload({\n jobId: \"a\",\n runnerId: \"runner_1\",\n leaseId: granted!.lease.id,\n });\n // Its own refusal, not `not-ready`: one says keep asking and this says\n // stop, and a daemon that read them alike would poll a finished job\n // until its lease ran out.\n expect(replay).toEqual({ refused: \"terminal\" });\n // And the finished job is still finished, which is the property.\n expect((await store.job(SITE, \"a\"))?.state).toBe(\"done\");\n await done();\n });\n\n it(\"tells a runner nothing about another site's job id [V1-8]\", async () => {\n // Job ids are chosen per site, so a bare id is a guess about somebody\n // else's namespace. The answer used to depend on whether that guess\n // landed: an id belonging to another tenant came back `not-holder`,\n // an id belonging to nobody came back `not-found`. Two status codes,\n // one bit of somebody else's business — finding 58's oracle, reached\n // through the holder door instead of the site plane.\n const { store, done } = await make();\n // Another tenant's job, under an id this caller can guess but a site it\n // does not route for.\n await store.enqueue({\n id: \"secret\",\n siteId: \"site_somebody_else\",\n stub: stub(\"secret\"),\n });\n await store.enqueue({ id: \"mine\", siteId: SITE, stub: stub(\"mine\") });\n const granted = await store.claim(claimArgs());\n const mine = granted.find((job) => job.id === \"mine\");\n\n // Asking about a job this runner does not hold, under a lease it does.\n const other = await store.takePayload({\n jobId: \"secret\",\n runnerId: \"runner_1\",\n leaseId: mine!.lease.id,\n });\n const absent = await store.takePayload({\n jobId: \"no-such-job-anywhere\",\n runnerId: \"runner_1\",\n leaseId: mine!.lease.id,\n });\n\n expect(other).toEqual(absent);\n expect(other).toEqual({ refused: \"not-found\" });\n await done();\n });\n\n // ── routing by kind ─────────────────────────────────────────────────\n //\n // The selection cases lived here: a job could name one of the owner's\n // services and a store had to offer it only to a device advertising that\n // exact (kind, service) pair. Amendment L removed the field — sites\n // declare purposes and people map them — so a store now matches on kind\n // alone, and the pairs it used to carry are gone from `ClaimInput`.\n //\n // What replaces those cases is the property that a store must *not* have\n // opinions it no longer has the inputs for.\n\n it(\"offers a job to any device that serves its kind\", async () => {\n // Which of the owner's services answers is resolved at claim by a\n // control plane, from a mapping this store never sees. A store that\n // narrowed further would be deciding something it cannot know, and the\n // job would sit queued behind a judgement nobody made.\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n\n const claimed = await store.claim(\n claimArgs({ runnerId: \"runner_any\", kinds: new Set([\"llm.generate\"]) }),\n );\n expect(claimed.map((j) => j.id)).toEqual([\"a\"]);\n await done();\n });\n\n it(\"does not offer a job to a device that serves a different kind\", async () => {\n // The control. Kind is the whole of the match, so it has to actually\n // match — a store that offered everything to everybody would push the\n // narrowing onto a control plane that would then decline it, which is\n // a round trip and a wait for a fact this side already had.\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n\n const claimed = await store.claim(\n claimArgs({ runnerId: \"runner_chat\", kinds: new Set([\"llm.chat\"]) }),\n );\n expect(claimed).toEqual([]);\n await done();\n });\n\n // ── presence ────────────────────────────────────────────────────────\n //\n // The seam had no contract coverage at all: presence was exercised\n // against `RelayState` and nothing held a shared store to the same\n // behaviour. That is the shape the pairing ceiling was found in — one\n // seam, two implementations, and the check driving the one nobody\n // deploys — so these land with `Presence.capabilities` rather than after\n // somebody notices.\n\n it(\"remembers a device, and what it says it can run\", async () => {\n const { store, done } = await make();\n const device = publicIdentityOf(generateKeys(3_000_000_000_000));\n await store.seen({\n runnerId: \"runner_1\",\n owner: \"alice\",\n device,\n capabilities: [capability(\"llama3\")],\n withheld: [],\n });\n\n const known = await store.presence(\"runner_1\");\n expect(known?.owner).toBe(\"alice\");\n expect(known?.device.identity).toBe(device.identity);\n expect(known?.capabilities.map((row) => row.model)).toEqual([\"llama3\"]);\n await done();\n });\n\n it(\"replaces the matrix rather than merging it\", async () => {\n // The heartbeat re-sends the whole matrix every time so a server never\n // matches against a stale one. A store that kept the union would go on\n // advertising a backend the machine has lost — and work would route to\n // it, which is worse than forgetting one it still has.\n const { store, done } = await make();\n const device = publicIdentityOf(generateKeys(3_000_000_000_001));\n const seen = { runnerId: \"runner_2\", owner: \"alice\", device };\n await store.seen({\n ...seen,\n capabilities: [capability(\"llama3\")],\n withheld: [],\n });\n await store.seen({\n ...seen,\n capabilities: [capability(\"mistral\")],\n withheld: [],\n });\n\n const known = await store.presence(\"runner_2\");\n expect(known?.capabilities.map((row) => row.model)).toEqual([\"mistral\"]);\n await done();\n });\n\n it(\"keeps an empty matrix, because empty is an answer\", async () => {\n // A paired machine with no healthy backend — the connect-first ruling's\n // whole point. A store that treated empty as \"nothing to record\" would\n // leave the last non-empty matrix standing and the machines page would\n // show models that are gone.\n const { store, done } = await make();\n const device = publicIdentityOf(generateKeys(3_000_000_000_002));\n const seen = { runnerId: \"runner_3\", owner: \"alice\", device };\n await store.seen({\n ...seen,\n capabilities: [capability(\"llama3\")],\n withheld: [],\n });\n await store.seen({ ...seen, capabilities: [], withheld: [] });\n\n expect((await store.presence(\"runner_3\"))?.capabilities).toEqual([]);\n await done();\n });\n\n it(\"remembers which kinds are withheld, and drops them when resolved\", async () => {\n // byollm_016. Two services answering one kind with no `defaults` entry\n // is a state only the daemon can see: from the matrix alone a withheld\n // kind and an absent one are the same shape, so a store that dropped\n // this field would leave the owner's page saying \"nothing serves\n // llm.generate\" — true, and useless, when the real sentence is \"two\n // services answer it and you have not chosen\".\n //\n // It lives in the contract rather than one store's tests because the\n // pairing ceiling was found exactly that way: one seam, two\n // implementations, and the check driving the one nobody deploys.\n const { store, done } = await make();\n const device = publicIdentityOf(generateKeys(3_000_000_000_004));\n const seen = { runnerId: \"runner_withheld\", owner: \"alice\", device };\n\n await store.seen({\n ...seen,\n capabilities: [],\n withheld: [\n {\n kind: \"llm.generate\",\n claimants: [\n { service: \"ollama\", offer: \"team\" },\n { service: \"mlx\", offer: \"private\" },\n ],\n },\n ],\n });\n\n const held = await store.presence(\"runner_withheld\");\n expect(held?.withheld.map((row) => row.kind)).toEqual([\"llm.generate\"]);\n // The claimants survive the round trip, because naming them is the\n // whole difference between a prompt and a complaint.\n expect(held?.withheld[0]?.claimants.map((c) => c.service)).toEqual([\n \"ollama\",\n \"mlx\",\n ]);\n\n // The owner chooses a default: the kind resolves and stops being\n // reported, or the page goes on asking for a decision already made.\n await store.seen({\n ...seen,\n capabilities: [capability(\"llama3\")],\n withheld: [],\n });\n expect((await store.presence(\"runner_withheld\"))?.withheld).toEqual([]);\n await done();\n });\n\n it(\"stamps presence from its own clock, and moves it on the next beat\", async () => {\n // `lastSeenAt` is liveness, and liveness is only true if something\n // advances it. It was written once at pairing and never again, so it\n // reported the pairing time under the name \"last seen\" — a field that\n // is quietly a different fact.\n const { store, done } = await make();\n const device = publicIdentityOf(generateKeys(3_000_000_000_003));\n const seen = { runnerId: \"runner_4\", owner: \"alice\", device };\n\n const before = await store.now();\n const first = await store.seen({\n ...seen,\n capabilities: [],\n withheld: [],\n });\n expect(first.lastSeenAt).toBeGreaterThanOrEqual(before);\n\n const later = await store.seen({\n ...seen,\n capabilities: [],\n withheld: [],\n });\n expect(later.lastSeenAt).toBeGreaterThanOrEqual(first.lastSeenAt);\n await done();\n });\n\n it(\"lists everyone it has seen\", async () => {\n const { store, done } = await make();\n await store.seen({\n runnerId: \"runner_5\",\n owner: \"alice\",\n device: publicIdentityOf(generateKeys(3_000_000_000_004)),\n capabilities: [],\n withheld: [],\n });\n await store.seen({\n runnerId: \"runner_6\",\n owner: \"bob\",\n device: publicIdentityOf(generateKeys(3_000_000_000_005)),\n capabilities: [],\n withheld: [],\n });\n\n const everyone = await store.everyone();\n const ids = everyone.map((row) => row.runnerId);\n expect(ids).toContain(\"runner_5\");\n expect(ids).toContain(\"runner_6\");\n await done();\n });\n\n it(\"does not know a runner it has never seen\", async () => {\n const { store, done } = await make();\n expect(await store.presence(\"runner_never\")).toBeUndefined();\n await done();\n });\n\n it(\"stamps deadlines from its own clock\", async () => {\n const { store, done } = await make();\n await store.enqueue({ id: \"a\", siteId: SITE, stub: stub(\"a\") });\n const before = await store.now();\n const [granted] = await store.claim(claimArgs({ leaseMs: 45_000 }));\n const after = await store.now();\n\n // Bracketed rather than exact: a real store's clock moves between the two\n // reads, which is the whole reason it is the store's clock and not ours.\n expect(granted!.lease.expiresAt).toBeGreaterThanOrEqual(before + 45_000);\n expect(granted!.lease.expiresAt).toBeLessThanOrEqual(after + 45_000);\n await done();\n });\n });\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@byollm/relay",
3
- "version": "0.1.0-alpha.88",
3
+ "version": "0.1.0-alpha.89",
4
4
  "type": "module",
5
5
  "description": "The reference relay: routes sealed byollm jobs between sites and daemons, holding no decryption keys by construction.",
6
6
  "license": "MIT",
@@ -31,7 +31,7 @@
31
31
  ],
32
32
  "dependencies": {
33
33
  "zod": "^4.1.13",
34
- "@byollm/protocol": "0.1.0-alpha.88"
34
+ "@byollm/protocol": "0.1.0-alpha.89"
35
35
  },
36
36
  "publishConfig": {
37
37
  "access": "public"
@@ -39,10 +39,10 @@
39
39
  "devDependencies": {
40
40
  "@supabase/supabase-js": "^2.112.2",
41
41
  "vitest": "^4.1.10",
42
- "@byollm/conformance": "0.1.0-alpha.88",
43
- "@byollm/control-plane": "0.1.0-alpha.88",
44
- "@byollm/server": "0.1.0-alpha.88",
45
- "byollm": "0.1.0-alpha.88"
42
+ "@byollm/control-plane": "0.1.0-alpha.89",
43
+ "byollm": "0.1.0-alpha.89",
44
+ "@byollm/conformance": "0.1.0-alpha.89",
45
+ "@byollm/server": "0.1.0-alpha.89"
46
46
  },
47
47
  "peerDependencies": {
48
48
  "vitest": ">=3"