@byollm/conformance 0.1.0-alpha.9 → 0.1.0-alpha.91

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.
@@ -29,7 +29,6 @@ import {
29
29
  signRequest
30
30
  } from "@byollm/protocol";
31
31
  import {
32
- Allowlist,
33
32
  Budgets,
34
33
  IngressLog,
35
34
  SpendLedger,
@@ -41,6 +40,13 @@ import {
41
40
  DaemonConfig
42
41
  } from "byollm";
43
42
  var EchoBackend = class {
43
+ /* The conformance kit's own backend, answering the question every adapter
44
+ must — byollm_021. It echoes rather than generating, so there is no
45
+ model ceiling to hit and nothing to read. */
46
+ stopReasons = {
47
+ kind: "unavailable",
48
+ why: "the conformance echo backend generates nothing, so no model ever stops early"
49
+ };
44
50
  id = "openai-http";
45
51
  class = "http";
46
52
  /** Prompts this backend was asked to run, in order. */
@@ -76,7 +82,6 @@ var EchoBackend = class {
76
82
  ok: false,
77
83
  code: "canceled",
78
84
  message: "the job was canceled",
79
- retryable: false,
80
85
  durationMs: Date.now() - started
81
86
  };
82
87
  }
@@ -94,9 +99,11 @@ function daemonConfig(options) {
94
99
  const baseUrl = metered ? metered.baseUrl : options.subscription ? void 0 : "http://127.0.0.1:11434/v1";
95
100
  return resolveConfig(
96
101
  DaemonConfig.parse({
97
- backends: {
102
+ services: {
98
103
  primary: {
99
- backend: backendId,
104
+ model: "echo-model",
105
+ kinds: ["llm.generate", "llm.chat"],
106
+ type: backendId,
100
107
  ...baseUrl === void 0 ? {} : { baseUrl },
101
108
  offer: options.offer,
102
109
  ...metered === void 0 ? {} : {
@@ -107,10 +114,6 @@ function daemonConfig(options) {
107
114
  }
108
115
  }
109
116
  },
110
- routes: {
111
- "llm.generate": { backend: "primary", model: "echo-model" },
112
- "llm.chat": { backend: "primary", model: "echo-model" }
113
- },
114
117
  concurrency: 4
115
118
  })
116
119
  );
@@ -118,12 +121,10 @@ function daemonConfig(options) {
118
121
  async function pairDaemon(target, options) {
119
122
  const home = await mkdtemp(join(tmpdir(), "byollm-conformance-"));
120
123
  const loaded = daemonConfig({
121
- offer: options.offer ?? "self",
124
+ offer: options.offer,
122
125
  subscription: options.subscription ?? false,
123
126
  ...options.metered === void 0 ? {} : { metered: options.metered }
124
127
  });
125
- const allowlist = new Allowlist(join(home, "allow.json"));
126
- await allowlist.load();
127
128
  const budgets = new Budgets(
128
129
  join(home, "budgets.json"),
129
130
  loaded.config.community
@@ -140,6 +141,7 @@ async function pairDaemon(target, options) {
140
141
  const fetchImpl = (input, init) => target.fetch(new Request(input, init));
141
142
  const capabilities = loaded.routes.map((route) => ({
142
143
  kind: route.kind,
144
+ service: route.service,
143
145
  backendId: route.backendId,
144
146
  backendClass: route.backendClass,
145
147
  model: route.model,
@@ -203,12 +205,13 @@ async function pairDaemon(target, options) {
203
205
  owner: result.pairing.owner,
204
206
  identity: {
205
207
  keys: () => deviceIdentity.load(Date.now()),
206
- // Pinned at pairing, exactly as a real daemon does.
207
- sitePinned: result.pairing.site
208
+ // Pinned at pairing, exactly as a real daemon does — the set the
209
+ // upstream answered with, keyed by each site's identity key id
210
+ // (cloud_009 §5). A direct site is one entry.
211
+ sites: new Map(Object.entries(result.pairing.sites))
208
212
  },
209
213
  daemonVersion: "conformance",
210
214
  loaded,
211
- allowlist,
212
215
  budgets,
213
216
  spend,
214
217
  ingress,
@@ -217,13 +220,11 @@ async function pairDaemon(target, options) {
217
220
  return {
218
221
  runner,
219
222
  backend,
220
- allowlist,
221
223
  runnerId: result.pairing.runnerId,
222
224
  owner: result.pairing.owner,
223
- token: result.pairing.token,
224
225
  keys: await deviceIdentity.load(Date.now()),
225
226
  identityKeys: () => deviceIdentity.load(Date.now()),
226
- sitePinned: result.pairing.site,
227
+ sitePinned: Object.values(result.pairing.sites)[0],
227
228
  home,
228
229
  ingress,
229
230
  spend,
@@ -309,6 +310,37 @@ async function claimOne(target, daemon) {
309
310
  if (!job) throw new Error("claim returned no jobs");
310
311
  return job;
311
312
  }
313
+ async function claimRaw(target, daemon, capabilityOverride) {
314
+ const capabilities = capabilityOverride ?? await daemon.runner.detectCapabilities();
315
+ const body = JSON.stringify({
316
+ protocolVersion: PROTOCOL_VERSION,
317
+ runnerId: daemon.runnerId,
318
+ capabilities,
319
+ max: 10
320
+ });
321
+ const signature = signRequest(daemon.keys, {
322
+ endpoint: "claim",
323
+ runnerId: daemon.runnerId,
324
+ issuedAt: Date.now(),
325
+ body
326
+ });
327
+ const response = await target.fetch(
328
+ new Request(`${target.origin}/byollm/claim`, {
329
+ method: "POST",
330
+ headers: {
331
+ "content-type": "application/json",
332
+ "x-byollm-runner": signature.runnerId,
333
+ "x-byollm-issued-at": String(signature.issuedAt),
334
+ "x-byollm-signature": signature.signature
335
+ },
336
+ body
337
+ })
338
+ );
339
+ if (response.status !== 200) {
340
+ throw new Error(`claim answered ${String(response.status)}`);
341
+ }
342
+ return (await response.json()).jobs;
343
+ }
312
344
  async function releaseLease(target, daemon, jobId, leaseId) {
313
345
  const body = JSON.stringify({
314
346
  protocolVersion: PROTOCOL_VERSION,
@@ -383,7 +415,11 @@ async function postResult(target, daemon, input) {
383
415
  const keys = await daemon.identityKeys();
384
416
  const sealer = input.sealWith ?? keys;
385
417
  const envelope = await seal({
386
- plaintext: JSON.stringify(input.outcome),
418
+ // `{ outcome, ran }` — cloud_008 §2.5.
419
+ plaintext: JSON.stringify({
420
+ outcome: input.outcome,
421
+ ran: { model: "test-model", backendClass: "http", durationMs: 1 }
422
+ }),
387
423
  senderKeys: sealer,
388
424
  recipientEncryptionPublic: daemon.sitePinned.encryption,
389
425
  context: {
@@ -401,11 +437,9 @@ async function postResult(target, daemon, input) {
401
437
  protocolVersion: PROTOCOL_VERSION,
402
438
  runnerId: daemon.runnerId,
403
439
  jobId: input.jobId,
440
+ leaseId: input.leaseId,
404
441
  envelope,
405
- disposition: input.disposition ?? input.outcome.outcome,
406
- model: "conformance-model",
407
- backendClass: "http",
408
- durationMs: 1
442
+ disposition: input.disposition ?? input.outcome.outcome
409
443
  });
410
444
  const signature = signRequest(daemon.keys, {
411
445
  endpoint: "result",
@@ -445,7 +479,7 @@ async function fetchGenuine(target, daemon, owner = "alice") {
445
479
  // The target's own name for the user, not the id it mapped that to —
446
480
  // passing a mapped id back in addresses a user the target never made.
447
481
  owner,
448
- audience: "self"
482
+ audience: "private"
449
483
  });
450
484
  for (let attempt = 0; attempt < 20; attempt += 1) {
451
485
  try {
@@ -475,13 +509,19 @@ var CHECKS = [
475
509
  title: "a runner token is bound to exactly the approving user",
476
510
  musts: ["PAIR_ONE_USER", "PAIR_INTERACTIVE"],
477
511
  async run(target) {
478
- const alice = await pairDaemon(target, { owner: "alice" });
512
+ const alice = await pairDaemon(target, {
513
+ owner: "alice",
514
+ offer: "private"
515
+ });
479
516
  try {
480
517
  assert(
481
518
  alice.owner === await ownerIdFor(target, "alice"),
482
519
  `runner was bound to "${alice.owner}", not to the approving user`
483
520
  );
484
- const bob = await pairDaemon(target, { owner: "bob" });
521
+ const bob = await pairDaemon(target, {
522
+ owner: "bob",
523
+ offer: "private"
524
+ });
485
525
  assert(
486
526
  bob.owner !== alice.owner,
487
527
  "two different approvers produced the same runner owner"
@@ -491,7 +531,7 @@ var CHECKS = [
491
531
  kind: "llm.generate",
492
532
  payload: prompt("alice's private prompt"),
493
533
  owner: "alice",
494
- audience: "self"
534
+ audience: "private"
495
535
  });
496
536
  await bob.runner.tick();
497
537
  await sleep(50);
@@ -513,7 +553,10 @@ var CHECKS = [
513
553
  title: "an enqueued job runs on the owner's daemon and the result comes back",
514
554
  musts: ["CLAIM_REQUIRES_CAPABILITY", "RESULT_IDEMPOTENT"],
515
555
  async run(target) {
516
- const daemon = await pairDaemon(target, { owner: "alice" });
556
+ const daemon = await pairDaemon(target, {
557
+ owner: "alice",
558
+ offer: "private"
559
+ });
517
560
  try {
518
561
  const job = await target.enqueue({
519
562
  kind: "llm.generate",
@@ -543,7 +586,10 @@ var CHECKS = [
543
586
  title: "a daemon is never handed a kind it did not advertise",
544
587
  musts: ["KIND_TYPED_ONLY", "CLAIM_REQUIRES_CAPABILITY"],
545
588
  async run(target) {
546
- const daemon = await pairDaemon(target, { owner: "alice" });
589
+ const daemon = await pairDaemon(target, {
590
+ owner: "alice",
591
+ offer: "private"
592
+ });
547
593
  try {
548
594
  const job = await target.enqueue({
549
595
  kind: "llm.chat",
@@ -562,6 +608,25 @@ var CHECKS = [
562
608
  daemon.backend.seen.length > before,
563
609
  "the advertised kind never reached the backend"
564
610
  );
611
+ const chat = await target.enqueue({
612
+ kind: "llm.chat",
613
+ payload: { messages: [{ role: "user", content: "not for you" }] },
614
+ owner: "alice"
615
+ });
616
+ const generateOnly = await claimRaw(target, daemon, [
617
+ {
618
+ kind: "llm.generate",
619
+ service: "local",
620
+ backendId: "openai-http",
621
+ backendClass: "http",
622
+ model: "echo-model",
623
+ offerScope: "private"
624
+ }
625
+ ]);
626
+ assert(
627
+ !generateOnly.some((offered) => offered.id === chat.id),
628
+ "a server offered `llm.chat` to a claim advertising only `llm.generate`"
629
+ );
565
630
  } finally {
566
631
  await daemon.dispose();
567
632
  }
@@ -572,14 +637,18 @@ var CHECKS = [
572
637
  title: "a job whose runner vanished is offered again, losing nothing",
573
638
  musts: ["LEASE_RECLAIMABLE", "LEASE_HONORED"],
574
639
  async run(target) {
575
- const dead = await pairDaemon(target, { owner: "alice", label: "dead" });
640
+ const dead = await pairDaemon(target, {
641
+ owner: "alice",
642
+ label: "dead",
643
+ offer: "private"
644
+ });
576
645
  const job = await target.enqueue({
577
646
  kind: "llm.generate",
578
647
  payload: prompt("work"),
579
648
  owner: "alice"
580
649
  });
581
650
  dead.backend.hangMs = 6e4;
582
- await dead.runner.tick();
651
+ const firstLease = await claimOne(target, dead);
583
652
  await waitFor(
584
653
  async () => {
585
654
  const state = await target.job(job.id);
@@ -591,35 +660,61 @@ var CHECKS = [
591
660
  await advance(target, target.leaseMs + 500);
592
661
  const alive = await pairDaemon(target, {
593
662
  owner: "alice",
594
- label: "alive"
663
+ label: "alive",
664
+ offer: "private"
595
665
  });
596
666
  try {
597
- await alive.runner.tick();
598
- await waitFor(async () => (await target.job(job.id))?.state === "ok", {
599
- what: "the reclaimed job to complete"
667
+ const reclaimed = await claimOne(target, alive);
668
+ assert(
669
+ reclaimed.id === job.id,
670
+ "the reclaiming daemon did not get the job"
671
+ );
672
+ const late = await postResult(target, dead, {
673
+ jobId: job.id,
674
+ leaseId: firstLease.lease.id,
675
+ outcome: { outcome: "ok", text: "from the machine that vanished" }
676
+ });
677
+ const lateBody = await late.json().catch(() => ({}));
678
+ assert(
679
+ lateBody.accepted !== true,
680
+ "a site accepted a result from a runner whose lease had lapsed"
681
+ );
682
+ const midflight = await target.job(job.id);
683
+ assert(
684
+ !midflight?.outcome,
685
+ "a lapsed holder's result was recorded over a live grant"
686
+ );
687
+ const proper = await postResult(target, alive, {
688
+ jobId: job.id,
689
+ leaseId: reclaimed.lease.id,
690
+ outcome: { outcome: "ok", text: "from the machine that took over" }
600
691
  });
692
+ assert(
693
+ proper.status === 200,
694
+ `the reclaiming daemon could not finish the job (${String(proper.status)})`
695
+ );
696
+ const final = await target.job(job.id);
697
+ assert(
698
+ final?.outcome?.text === "from the machine that took over",
699
+ "the reclaimed job did not record the current holder's result"
700
+ );
601
701
  } finally {
602
702
  await alive.dispose();
703
+ await dead.dispose();
603
704
  }
604
705
  }
605
706
  },
606
707
  {
607
708
  id: "C005_AUDIENCE_MATRIX",
608
- title: "all nine audience \xD7 offer-scope combinations behave as specified",
709
+ title: "all four audience x offer-scope combinations behave as specified",
609
710
  musts: ["AUDIENCE_BOTH_SIDES", "NAMED_LOCAL_ALLOWLIST"],
610
711
  async run(target) {
611
712
  const expected = {
612
- "self:self": false,
613
- "self:named": false,
614
- "self:public": false,
615
- "named:self": false,
616
- "named:named": false,
617
- // refused locally — allowlist is empty
618
- "named:public": true,
619
- "public:self": false,
620
- "public:named": false,
621
- // refused locally — allowlist is empty
622
- "public:public": true
713
+ "private:private": false,
714
+ "private:team": false,
715
+ "team:private": false,
716
+ "team:team": false
717
+ // refused locally — nothing admits alice
623
718
  };
624
719
  for (const audience of AUDIENCES) {
625
720
  for (const offer of OFFER_SCOPES) {
@@ -650,16 +745,30 @@ var CHECKS = [
650
745
  },
651
746
  {
652
747
  id: "C006_NAMED_LOCAL_ALLOWLIST",
653
- title: "a named job runs only once the daemon's own allowlist admits it",
748
+ /**
749
+ * Renamed with the release that made the sentence true — Amendment G, B2.
750
+ *
751
+ * The old title read "a named job runs only once the daemon's own
752
+ * allowlist admits it", which was true only under a generous reading of
753
+ * "own": the list was per-person and local, and a team member had to be
754
+ * enrolled on every machine by hand.
755
+ *
756
+ * The id does not change, per the id-stability law. What changes is the
757
+ * sentence, and it now names all three of the things a reader would
758
+ * otherwise take on faith — that the list is local, that its authority was
759
+ * established out of band, and that admission is a property of the asker
760
+ * rather than of the request.
761
+ */
762
+ title: "a team job is refused by a device whose upstream cannot say who the asker is, and is not offered to it again",
654
763
  musts: ["NAMED_LOCAL_ALLOWLIST", "REFUSAL_NOT_REOFFERED"],
655
764
  async run(target) {
656
- const bob = await pairDaemon(target, { owner: "bob", offer: "named" });
765
+ const bob = await pairDaemon(target, { owner: "bob", offer: "team" });
657
766
  try {
658
767
  const refused = await target.enqueue({
659
768
  kind: "llm.generate",
660
769
  payload: prompt("before"),
661
770
  owner: "alice",
662
- audience: "named"
771
+ audience: "team"
663
772
  });
664
773
  await bob.runner.tick();
665
774
  await sleep(80);
@@ -667,27 +776,10 @@ var CHECKS = [
667
776
  (await target.job(refused.id))?.state !== "ok",
668
777
  "a named job ran without the daemon's local allowlist admitting it"
669
778
  );
670
- const before = bob.backend.seen.length;
671
- await bob.runner.tick();
672
- await sleep(50);
779
+ const reoffered = await claimRaw(target, bob);
673
780
  assert(
674
- bob.backend.seen.length === before,
675
- "a refused job was re-offered to the runner that refused it"
676
- );
677
- await bob.allowlist.add(
678
- { origin: target.origin, owner: await ownerIdFor(target, "alice") },
679
- Date.now()
680
- );
681
- const allowed = await target.enqueue({
682
- kind: "llm.generate",
683
- payload: prompt("after"),
684
- owner: "alice",
685
- audience: "named"
686
- });
687
- await bob.runner.tick();
688
- await waitFor(
689
- async () => (await target.job(allowed.id))?.state === "ok",
690
- { what: "the allowed named job to run" }
781
+ !reoffered.some((job) => job.id === refused.id),
782
+ "a server re-offered a job to the runner that refused it"
691
783
  );
692
784
  } finally {
693
785
  await bob.dispose();
@@ -701,19 +793,15 @@ var CHECKS = [
701
793
  async run(target) {
702
794
  const bob = await pairDaemon(target, {
703
795
  owner: "bob",
704
- offer: "public",
796
+ offer: "team",
705
797
  subscription: true
706
798
  });
707
799
  try {
708
- await bob.allowlist.add(
709
- { origin: target.origin, owner: await ownerIdFor(target, "alice") },
710
- Date.now()
711
- );
712
800
  const job = await target.enqueue({
713
801
  kind: "llm.generate",
714
802
  payload: prompt("someone else's work"),
715
803
  owner: "alice",
716
- audience: "public"
804
+ audience: "team"
717
805
  });
718
806
  await bob.runner.tick();
719
807
  await sleep(80);
@@ -730,7 +818,7 @@ var CHECKS = [
730
818
  kind: "llm.generate",
731
819
  payload: prompt("my own work"),
732
820
  owner: "bob",
733
- audience: "self"
821
+ audience: "private"
734
822
  });
735
823
  await bob.runner.tick();
736
824
  await waitFor(async () => (await target.job(own.id))?.state === "ok", {
@@ -744,9 +832,17 @@ var CHECKS = [
744
832
  {
745
833
  id: "C008_REVOCATION",
746
834
  title: "a revoked daemon stops mid-queue",
747
- musts: ["REVOCATION_HONORED"],
835
+ // Both halves, and this check already proved both: the daemon learns it
836
+ // is revoked (`REVOCATION_HONORED`), *and* the upstream leaves the job
837
+ // queued rather than granting it (`REVOCATION_IMMEDIATE`). The second
838
+ // assertion was here and cited nothing — which is how a MUST comes to be
839
+ // declared in a spec, absent from the registry, and tested all along.
840
+ musts: ["REVOCATION_HONORED", "REVOCATION_IMMEDIATE"],
748
841
  async run(target) {
749
- const daemon = await pairDaemon(target, { owner: "alice" });
842
+ const daemon = await pairDaemon(target, {
843
+ owner: "alice",
844
+ offer: "private"
845
+ });
750
846
  try {
751
847
  await target.revokeRunner(daemon.runnerId);
752
848
  const job = await target.enqueue({
@@ -774,7 +870,10 @@ var CHECKS = [
774
870
  title: "cancel aborts a running job's backend call",
775
871
  musts: ["CANCEL_HONORED"],
776
872
  async run(target) {
777
- const daemon = await pairDaemon(target, { owner: "alice" });
873
+ const daemon = await pairDaemon(target, {
874
+ owner: "alice",
875
+ offer: "private"
876
+ });
778
877
  try {
779
878
  daemon.backend.hangMs = 3e4;
780
879
  const job = await target.enqueue({
@@ -802,39 +901,73 @@ var CHECKS = [
802
901
  title: "the first terminal outcome wins",
803
902
  musts: ["RESULT_IDEMPOTENT"],
804
903
  async run(target) {
805
- const daemon = await pairDaemon(target, { owner: "alice" });
904
+ const daemon = await pairDaemon(target, {
905
+ owner: "alice",
906
+ offer: "private"
907
+ });
806
908
  try {
807
909
  const job = await target.enqueue({
808
910
  kind: "llm.generate",
809
911
  payload: prompt("once"),
810
912
  owner: "alice"
811
913
  });
812
- await daemon.runner.tick();
813
- await waitFor(async () => (await target.job(job.id))?.state === "ok", {
814
- what: "the job to complete"
914
+ const claimed = await claimOne(target, daemon);
915
+ assert(claimed.id === job.id, "the harness could not claim its job");
916
+ const first = await postResult(target, daemon, {
917
+ jobId: job.id,
918
+ leaseId: claimed.lease.id,
919
+ outcome: { outcome: "ok", text: "the answer that counts" }
815
920
  });
816
- const first = await target.job(job.id);
817
- const response = await target.fetch(
818
- new Request(`${target.origin}/byollm/result`, {
819
- method: "POST",
820
- headers: { "content-type": "application/json" },
821
- body: JSON.stringify({
822
- protocolVersion: "0",
823
- runnerId: daemon.runnerId,
824
- jobId: job.id,
825
- outcome: { outcome: "ok", text: "SECOND ANSWER" },
826
- model: "echo-model",
827
- backendClass: "http",
828
- durationMs: 1
829
- })
830
- })
921
+ assert(
922
+ first.status === 200,
923
+ `a site refused the first result (${String(first.status)})`
924
+ );
925
+ const replay = await postResult(target, daemon, {
926
+ jobId: job.id,
927
+ leaseId: claimed.lease.id,
928
+ outcome: { outcome: "ok", text: "SECOND ANSWER" }
929
+ });
930
+ assert(
931
+ replay.status === 200,
932
+ `a replayed result was rejected rather than ignored (${String(replay.status)})`
933
+ );
934
+ const body = await replay.json();
935
+ assert(
936
+ body.accepted === false,
937
+ "a site reported a replayed result as newly accepted"
938
+ );
939
+ assert(
940
+ body.duplicate === true,
941
+ "a replay from the device that finished the job was not called a duplicate"
831
942
  );
832
- void response;
833
943
  const after = await target.job(job.id);
834
944
  assert(
835
- after?.outcome?.text === first?.outcome?.text,
836
- "a second result overwrote the first"
945
+ after?.outcome?.text === "the answer that counts",
946
+ `a second result overwrote the first (${String(after?.outcome?.text)})`
837
947
  );
948
+ const stranger = await pairDaemon(target, {
949
+ owner: "alice",
950
+ offer: "private"
951
+ });
952
+ try {
953
+ const foreign = await postResult(target, stranger, {
954
+ jobId: job.id,
955
+ leaseId: claimed.lease.id,
956
+ outcome: { outcome: "ok", text: "not this device's to answer" }
957
+ });
958
+ const foreignBody = await foreign.json().catch(() => ({}));
959
+ assert(
960
+ foreignBody["duplicate"] !== true,
961
+ "a site told a device that never held this job it was a duplicate"
962
+ );
963
+ const stillFirst = await target.job(job.id);
964
+ assert(
965
+ stillFirst?.outcome?.text === "the answer that counts",
966
+ "a stranger's result overwrote a terminal job"
967
+ );
968
+ } finally {
969
+ await stranger.dispose();
970
+ }
838
971
  } finally {
839
972
  await daemon.dispose();
840
973
  }
@@ -845,20 +978,23 @@ var CHECKS = [
845
978
  title: "a dependent job waits for its dependency, across two daemons",
846
979
  musts: ["DEPENDS_ON_GATING", "TTL_EXPIRY"],
847
980
  async run(target) {
848
- const alice = await pairDaemon(target, { owner: "alice" });
849
- const bob = await pairDaemon(target, { owner: "bob" });
981
+ const alice = await pairDaemon(target, {
982
+ owner: "alice",
983
+ offer: "private"
984
+ });
985
+ const bob = await pairDaemon(target, { owner: "bob", offer: "private" });
850
986
  try {
851
987
  const first = await target.enqueue({
852
988
  kind: "llm.generate",
853
989
  payload: prompt("step one"),
854
990
  owner: "bob",
855
- audience: "self"
991
+ audience: "private"
856
992
  });
857
993
  const second = await target.enqueue({
858
994
  kind: "llm.generate",
859
995
  payload: prompt("step two"),
860
996
  owner: "alice",
861
- audience: "self",
997
+ audience: "private",
862
998
  dependsOn: [first.id]
863
999
  });
864
1000
  await alice.runner.tick();
@@ -919,7 +1055,10 @@ var CHECKS = [
919
1055
  title: "a dependent job's TTL starts when it becomes claimable, not at enqueue",
920
1056
  musts: ["TTL_EXPIRY"],
921
1057
  async run(target) {
922
- const daemon = await pairDaemon(target, { owner: "alice" });
1058
+ const daemon = await pairDaemon(target, {
1059
+ owner: "alice",
1060
+ offer: "private"
1061
+ });
923
1062
  try {
924
1063
  daemon.backend.hangMs = target.ttlMs * 2;
925
1064
  const first = await target.enqueue({
@@ -949,35 +1088,19 @@ var CHECKS = [
949
1088
  {
950
1089
  id: "C014_RESULT_PROVENANCE",
951
1090
  title: "a community result arrives marked untrusted, a self result does not",
952
- musts: ["RESULT_PROVENANCE"],
1091
+ // `PROVENANCE_NAMES_DEVICE` supersedes `RESULT_PROVENANCE` — a
1092
+ // strengthening rather than a rename. C030 is the other half: a label
1093
+ // means nothing unless a result whose signature does not verify against
1094
+ // the granted device is refused rather than recorded.
1095
+ musts: ["PROVENANCE_NAMES_DEVICE"],
953
1096
  async run(target) {
954
- const bob = await pairDaemon(target, { owner: "bob", offer: "public" });
1097
+ const bob = await pairDaemon(target, { owner: "bob", offer: "team" });
955
1098
  try {
956
- const community = await target.enqueue({
957
- kind: "llm.generate",
958
- payload: prompt("run this anywhere"),
959
- owner: "alice",
960
- audience: "public"
961
- });
962
- await bob.runner.tick();
963
- await waitFor(
964
- async () => (await target.job(community.id))?.state === "ok",
965
- { what: "the community job to complete" }
966
- );
967
- const delivered = await target.job(community.id);
968
- assert(
969
- delivered?.provenance?.untrusted === true,
970
- "a public result was not marked untrusted"
971
- );
972
- assert(
973
- delivered.provenance.runnerOwner === "bob",
974
- "the result did not carry the runner's owner"
975
- );
976
1099
  const own = await target.enqueue({
977
1100
  kind: "llm.generate",
978
1101
  payload: prompt("my own"),
979
1102
  owner: "bob",
980
- audience: "self"
1103
+ audience: "private"
981
1104
  });
982
1105
  await bob.runner.tick();
983
1106
  await waitFor(async () => (await target.job(own.id))?.state === "ok", {
@@ -997,7 +1120,10 @@ var CHECKS = [
997
1120
  title: "every executed prompt is in the ingress log before it runs",
998
1121
  musts: ["INGRESS_LOGGED_BEFORE_EXECUTION"],
999
1122
  async run(target) {
1000
- const daemon = await pairDaemon(target, { owner: "alice" });
1123
+ const daemon = await pairDaemon(target, {
1124
+ owner: "alice",
1125
+ offer: "private"
1126
+ });
1001
1127
  let ticking = Promise.resolve();
1002
1128
  try {
1003
1129
  daemon.backend.hangMs = 3e4;
@@ -1031,7 +1157,13 @@ var CHECKS = [
1031
1157
  {
1032
1158
  id: "C016_UNAUTHENTICATED_REFUSED",
1033
1159
  title: "the protocol endpoints refuse an unknown token",
1034
- musts: ["PAIR_ONE_USER"],
1160
+ // `CONSENT_BEFORE_ROUTE` on this plane. A relay has a consent record; a
1161
+ // direct site has pairing, and it is the same obligation — an upstream
1162
+ // routes to a device it has a record binding, and there is no discovery
1163
+ // path by which an unbound device receives work. Every endpoint is
1164
+ // checked rather than just `claim`, which is what makes it the absence
1165
+ // of a path rather than the absence of one door.
1166
+ musts: ["PAIR_ONE_USER", "CONSENT_BEFORE_ROUTE"],
1035
1167
  async run(target) {
1036
1168
  for (const endpoint of ["claim", "heartbeat", "result", "release"]) {
1037
1169
  const response = await target.fetch(
@@ -1041,7 +1173,7 @@ var CHECKS = [
1041
1173
  "content-type": "application/json",
1042
1174
  authorization: "Bearer definitely-not-a-real-token"
1043
1175
  },
1044
- body: JSON.stringify({ protocolVersion: "0" })
1176
+ body: JSON.stringify({ protocolVersion: PROTOCOL_VERSION2 })
1045
1177
  })
1046
1178
  );
1047
1179
  assert(
@@ -1054,11 +1186,19 @@ var CHECKS = [
1054
1186
  {
1055
1187
  id: "C017_METERED_DEFAULTS_SELF",
1056
1188
  title: "a paid backend is not shared until its owner says so, with a ceiling",
1057
- musts: ["METERED_DEFAULTS_SELF", "COST_NOT_CONFIGURABLE"],
1189
+ // `EFFECTIVE_OFFER_ONLY` too: bob asks for `public`, what reaches the
1190
+ // server is `self`, and the server acts on what it was told rather than
1191
+ // on what was wanted. That *is* the effective-offer rule, proved here
1192
+ // without being named.
1193
+ musts: [
1194
+ "METERED_DEFAULTS_SELF",
1195
+ "COST_NOT_CONFIGURABLE",
1196
+ "EFFECTIVE_OFFER_ONLY"
1197
+ ],
1058
1198
  async run(target) {
1059
1199
  const bob = await pairDaemon(target, {
1060
1200
  owner: "bob",
1061
- offer: "public",
1201
+ offer: "team",
1062
1202
  // Pointed at localhost — which changes nothing, because a named
1063
1203
  // provider's cost comes from the registry, not from an address
1064
1204
  // ({@link MUSTS.COST_NOT_CONFIGURABLE}).
@@ -1066,22 +1206,18 @@ var CHECKS = [
1066
1206
  });
1067
1207
  try {
1068
1208
  assert(
1069
- bob.loaded.routes.every((route) => route.offerScope === "self"),
1209
+ bob.loaded.routes.every((route) => route.offerScope === "private"),
1070
1210
  "a metered backend was advertised beyond its owner without consent"
1071
1211
  );
1072
1212
  assert(
1073
1213
  bob.loaded.routes.every((route) => route.cost === "metered"),
1074
1214
  "a metered provider was read as free because of its base URL"
1075
1215
  );
1076
- await bob.allowlist.add(
1077
- { origin: target.origin, owner: await ownerIdFor(target, "alice") },
1078
- Date.now()
1079
- );
1080
1216
  const job = await target.enqueue({
1081
1217
  kind: "llm.generate",
1082
1218
  payload: prompt("spend someone else's money"),
1083
1219
  owner: "alice",
1084
- audience: "public"
1220
+ audience: "team"
1085
1221
  });
1086
1222
  await bob.runner.tick();
1087
1223
  await sleep(80);
@@ -1097,7 +1233,7 @@ var CHECKS = [
1097
1233
  const availability = await target.runnerAvailability({
1098
1234
  kind: "llm.generate",
1099
1235
  owner: "alice",
1100
- audience: "public"
1236
+ audience: "team"
1101
1237
  });
1102
1238
  assert(
1103
1239
  !availability.available,
@@ -1107,7 +1243,7 @@ var CHECKS = [
1107
1243
  kind: "llm.generate",
1108
1244
  payload: prompt("my own work"),
1109
1245
  owner: "bob",
1110
- audience: "self"
1246
+ audience: "private"
1111
1247
  });
1112
1248
  await bob.runner.tick();
1113
1249
  await waitFor(async () => (await target.job(own.id))?.state === "ok", {
@@ -1125,7 +1261,7 @@ var CHECKS = [
1125
1261
  async run(target) {
1126
1262
  const bob = await pairDaemon(target, {
1127
1263
  owner: "bob",
1128
- offer: "public",
1264
+ offer: "team",
1129
1265
  metered: {
1130
1266
  // The generic backend pointed at a remote address. No registry entry
1131
1267
  // says what this costs; it is metered because of where it goes
@@ -1142,30 +1278,15 @@ var CHECKS = [
1142
1278
  "a remote backend was treated as free"
1143
1279
  );
1144
1280
  assert(
1145
- bob.loaded.routes.every((route) => route.offerScope === "public"),
1281
+ bob.loaded.routes.every((route) => route.offerScope === "team"),
1146
1282
  "a deliberately shared metered backend was narrowed anyway"
1147
1283
  );
1148
- await bob.allowlist.add(
1149
- { origin: target.origin, owner: await ownerIdFor(target, "alice") },
1150
- Date.now()
1151
- );
1152
- const first = await target.enqueue({
1153
- kind: "llm.generate",
1154
- payload: prompt("work bob agreed to pay for"),
1155
- owner: "alice",
1156
- audience: "public"
1157
- });
1158
- await bob.runner.tick();
1159
- await waitFor(
1160
- async () => (await target.job(first.id))?.state === "ok",
1161
- { what: "a consented metered job to run" }
1162
- );
1163
1284
  await bob.spend.record("primary", 900, Date.now());
1164
1285
  const second = await target.enqueue({
1165
1286
  kind: "llm.generate",
1166
1287
  payload: prompt("work past the ceiling"),
1167
1288
  owner: "alice",
1168
- audience: "public"
1289
+ audience: "team"
1169
1290
  });
1170
1291
  const seenBefore = bob.backend.seen.length;
1171
1292
  await bob.runner.tick();
@@ -1183,7 +1304,7 @@ var CHECKS = [
1183
1304
  kind: "llm.generate",
1184
1305
  payload: prompt("my own work, my own key"),
1185
1306
  owner: "bob",
1186
- audience: "self"
1307
+ audience: "private"
1187
1308
  });
1188
1309
  await bob.runner.tick();
1189
1310
  await waitFor(async () => (await target.job(own.id))?.state === "ok", {
@@ -1199,14 +1320,22 @@ var CHECKS = [
1199
1320
  title: "two runners racing one job \u2014 exactly one gets it",
1200
1321
  musts: ["CLAIM_ATOMIC"],
1201
1322
  async run(target) {
1202
- const a = await pairDaemon(target, { owner: "alice", label: "laptop" });
1203
- const b = await pairDaemon(target, { owner: "alice", label: "desktop" });
1323
+ const a = await pairDaemon(target, {
1324
+ owner: "alice",
1325
+ label: "laptop",
1326
+ offer: "private"
1327
+ });
1328
+ const b = await pairDaemon(target, {
1329
+ owner: "alice",
1330
+ label: "desktop",
1331
+ offer: "private"
1332
+ });
1204
1333
  try {
1205
1334
  const job = await target.enqueue({
1206
1335
  kind: "llm.generate",
1207
1336
  payload: prompt("only once, please"),
1208
1337
  owner: "alice",
1209
- audience: "self"
1338
+ audience: "private"
1210
1339
  });
1211
1340
  await Promise.all([a.runner.tick(), b.runner.tick()]);
1212
1341
  await waitFor(async () => (await target.job(job.id))?.state === "ok", {
@@ -1281,7 +1410,10 @@ var CHECKS = [
1281
1410
  title: "a runner advertises only what is installed and healthy",
1282
1411
  musts: ["CAPABILITY_IS_DETECTED"],
1283
1412
  async run(target) {
1284
- const daemon = await pairDaemon(target, { owner: "alice" });
1413
+ const daemon = await pairDaemon(target, {
1414
+ owner: "alice",
1415
+ offer: "private"
1416
+ });
1285
1417
  try {
1286
1418
  daemon.backend.healthy = false;
1287
1419
  const advertised = await daemon.runner.detectCapabilities();
@@ -1319,7 +1451,10 @@ var CHECKS = [
1319
1451
  // check does not establish.
1320
1452
  musts: ["KIND_NO_CODE"],
1321
1453
  async run(target) {
1322
- const daemon = await pairDaemon(target, { owner: "alice" });
1454
+ const daemon = await pairDaemon(target, {
1455
+ owner: "alice",
1456
+ offer: "private"
1457
+ });
1323
1458
  const SMUGGLED = ["command", "argv", "model", "baseUrl"];
1324
1459
  try {
1325
1460
  let refused = false;
@@ -1334,7 +1469,7 @@ var CHECKS = [
1334
1469
  baseUrl: "http://evil.test/v1"
1335
1470
  },
1336
1471
  owner: "alice",
1337
- audience: "self"
1472
+ audience: "private"
1338
1473
  });
1339
1474
  } catch {
1340
1475
  refused = true;
@@ -1364,7 +1499,7 @@ var CHECKS = [
1364
1499
  kind: "llm.generate",
1365
1500
  payload: prompt("ordinary text"),
1366
1501
  owner: "alice",
1367
- audience: "self"
1502
+ audience: "private"
1368
1503
  });
1369
1504
  await daemon.runner.tick();
1370
1505
  await waitFor(async () => (await target.job(ok.id))?.state === "ok", {
@@ -1471,7 +1606,7 @@ var CHECKS = [
1471
1606
  };
1472
1607
  const pending = await poll();
1473
1608
  assert(
1474
- pending["site"] === void 0,
1609
+ pending["sites"] === void 0,
1475
1610
  "a pending poll disclosed the site's keys before anyone approved"
1476
1611
  );
1477
1612
  await target.approvePairing(pairing.userCode, "alice");
@@ -1480,8 +1615,19 @@ var CHECKS = [
1480
1615
  approved["status"] === "approved",
1481
1616
  `poll after approval said "${String(approved["status"])}"`
1482
1617
  );
1483
- const site = PublicIdentity.safeParse(approved["site"]);
1484
- assert(site.success, "the approval carried no usable site identity");
1618
+ const offered = approved["sites"];
1619
+ assert(
1620
+ typeof offered === "object" && offered !== null,
1621
+ "the approval carried no sites to pin"
1622
+ );
1623
+ const parsed = Object.values(offered).map(
1624
+ (value) => PublicIdentity.safeParse(value)
1625
+ );
1626
+ assert(
1627
+ parsed.length > 0 && parsed.every((entry) => entry.success),
1628
+ "the approval carried no usable site identity"
1629
+ );
1630
+ const site = parsed[0];
1485
1631
  assert(
1486
1632
  verifyPublicIdentity(site.data),
1487
1633
  "the site's encryption key is not signed by the identity it presented"
@@ -1493,7 +1639,10 @@ var CHECKS = [
1493
1639
  title: "authentication is a signature over the request, not a secret",
1494
1640
  musts: ["REQUESTS_SIGNED_NOT_BEARER"],
1495
1641
  async run(target) {
1496
- const daemon = await pairDaemon(target, { owner: "alice" });
1642
+ const daemon = await pairDaemon(target, {
1643
+ owner: "alice",
1644
+ offer: "private"
1645
+ });
1497
1646
  try {
1498
1647
  const body = JSON.stringify({
1499
1648
  protocolVersion: PROTOCOL_VERSION2,
@@ -1565,13 +1714,16 @@ var CHECKS = [
1565
1714
  title: "a release acts on the lease it names, not whatever lease exists",
1566
1715
  musts: ["LEASE_SCOPED_BY_GRANT"],
1567
1716
  async run(target) {
1568
- const daemon = await pairDaemon(target, { owner: "alice" });
1717
+ const daemon = await pairDaemon(target, {
1718
+ owner: "alice",
1719
+ offer: "private"
1720
+ });
1569
1721
  try {
1570
1722
  const job = await target.enqueue({
1571
1723
  kind: "llm.generate",
1572
1724
  payload: prompt("run me once"),
1573
1725
  owner: "alice",
1574
- audience: "self"
1726
+ audience: "private"
1575
1727
  });
1576
1728
  const first = await claimOne(target, daemon);
1577
1729
  assert(
@@ -1605,13 +1757,16 @@ var CHECKS = [
1605
1757
  title: "a claim carries routing metadata and no work",
1606
1758
  musts: ["STUB_METADATA_EXHAUSTIVE"],
1607
1759
  async run(target) {
1608
- const daemon = await pairDaemon(target, { owner: "alice" });
1760
+ const daemon = await pairDaemon(target, {
1761
+ owner: "alice",
1762
+ offer: "private"
1763
+ });
1609
1764
  try {
1610
1765
  await target.enqueue({
1611
1766
  kind: "llm.generate",
1612
1767
  payload: prompt("this must not appear in a claim response"),
1613
1768
  owner: "alice",
1614
- audience: "self"
1769
+ audience: "private"
1615
1770
  });
1616
1771
  const stub = await claimOne(target, daemon);
1617
1772
  const asRecord = stub;
@@ -1670,13 +1825,16 @@ var CHECKS = [
1670
1825
  musts: ["ENVELOPE_SEALED_AND_SIGNED"],
1671
1826
  async run(target) {
1672
1827
  const secret = "a prompt nobody should read from storage";
1673
- const daemon = await pairDaemon(target, { owner: "alice" });
1828
+ const daemon = await pairDaemon(target, {
1829
+ owner: "alice",
1830
+ offer: "private"
1831
+ });
1674
1832
  try {
1675
1833
  const job = await target.enqueue({
1676
1834
  kind: "llm.generate",
1677
1835
  payload: prompt(secret),
1678
1836
  owner: "alice",
1679
- audience: "self"
1837
+ audience: "private"
1680
1838
  });
1681
1839
  const stored = await target.job(job.id);
1682
1840
  assert(
@@ -1709,7 +1867,10 @@ var CHECKS = [
1709
1867
  title: "a daemon refuses work not signed by the site it pinned",
1710
1868
  musts: ["ENVELOPE_SEALED_AND_SIGNED"],
1711
1869
  async run(target) {
1712
- const daemon = await pairDaemon(target, { owner: "alice" });
1870
+ const daemon = await pairDaemon(target, {
1871
+ owner: "alice",
1872
+ offer: "private"
1873
+ });
1713
1874
  try {
1714
1875
  const keys = await daemon.identityKeys();
1715
1876
  const relay = generateKeys(Date.now());
@@ -1754,9 +1915,16 @@ var CHECKS = [
1754
1915
  {
1755
1916
  id: "C030_SITE_REFUSES_UNSIGNED_RESULTS",
1756
1917
  title: "a site refuses a result not signed by the device that ran it",
1757
- musts: ["ENVELOPE_SEALED_AND_SIGNED"],
1918
+ // The proof-of-possession half of `PROVENANCE_NAMES_DEVICE`: attribution
1919
+ // by a signature that verifies against the device the lease was granted
1920
+ // to, rather than by a key id carried beside the result. Carrying an id
1921
+ // is not proving possession, and a forger writes whatever it likes.
1922
+ musts: ["ENVELOPE_SEALED_AND_SIGNED", "PROVENANCE_NAMES_DEVICE"],
1758
1923
  async run(target) {
1759
- const daemon = await pairDaemon(target, { owner: "alice" });
1924
+ const daemon = await pairDaemon(target, {
1925
+ owner: "alice",
1926
+ offer: "private"
1927
+ });
1760
1928
  try {
1761
1929
  const job = await target.enqueue({
1762
1930
  kind: "llm.generate",
@@ -1768,6 +1936,7 @@ var CHECKS = [
1768
1936
  const relay = generateKeys(Date.now());
1769
1937
  const forged = await postResult(target, daemon, {
1770
1938
  jobId: job.id,
1939
+ leaseId: claimed.lease.id,
1771
1940
  outcome: { outcome: "ok", text: "an answer the device never gave" },
1772
1941
  sealWith: relay
1773
1942
  });
@@ -1782,6 +1951,7 @@ var CHECKS = [
1782
1951
  );
1783
1952
  const real = await postResult(target, daemon, {
1784
1953
  jobId: job.id,
1954
+ leaseId: claimed.lease.id,
1785
1955
  outcome: { outcome: "ok", text: "the genuine answer" }
1786
1956
  });
1787
1957
  assert(
@@ -1790,6 +1960,7 @@ var CHECKS = [
1790
1960
  );
1791
1961
  const lying = await postResult(target, daemon, {
1792
1962
  jobId: job.id,
1963
+ leaseId: claimed.lease.id,
1793
1964
  outcome: {
1794
1965
  outcome: "error",
1795
1966
  code: "backend-error",
@@ -1806,11 +1977,101 @@ var CHECKS = [
1806
1977
  await daemon.dispose();
1807
1978
  }
1808
1979
  }
1980
+ },
1981
+ {
1982
+ id: "C032_SERVER_REFUSES_TO_OFFER",
1983
+ title: "a claim is not answered with work the claimer may not run",
1984
+ musts: ["AUDIENCE_BOTH_SIDES"],
1985
+ async run(target) {
1986
+ const bob = await pairDaemon(target, { owner: "bob", offer: "team" });
1987
+ try {
1988
+ const priv = await target.enqueue({
1989
+ kind: "llm.generate",
1990
+ payload: prompt("alice's own machines only"),
1991
+ owner: "alice",
1992
+ audience: "private"
1993
+ });
1994
+ const offered = await claimRaw(target, bob);
1995
+ assert(
1996
+ !offered.some((job) => job.id === priv.id),
1997
+ "a server offered a `self` job to a device its owner does not own"
1998
+ );
1999
+ const shared = await target.enqueue({
2000
+ kind: "llm.generate",
2001
+ payload: prompt("anyone may run this"),
2002
+ owner: "alice",
2003
+ audience: "team"
2004
+ });
2005
+ const second = await claimRaw(target, bob);
2006
+ assert(
2007
+ second.some((job) => job.id === shared.id),
2008
+ "a server withheld a `public` job from a public-offering device"
2009
+ );
2010
+ } finally {
2011
+ await bob.dispose();
2012
+ }
2013
+ }
2014
+ },
2015
+ {
2016
+ id: "C031_ROSTER_NOT_DISCLOSED",
2017
+ title: "a claimed stub carries no list of who may run the job",
2018
+ musts: ["ROSTER_NOT_DISCLOSED"],
2019
+ async run(target) {
2020
+ const daemon = await pairDaemon(target, {
2021
+ owner: "alice",
2022
+ offer: "private"
2023
+ });
2024
+ try {
2025
+ const job = await target.enqueue({
2026
+ kind: "llm.generate",
2027
+ payload: prompt("who else is on this roster"),
2028
+ owner: "alice",
2029
+ audience: "team",
2030
+ // The site restricts the job to people who are not this daemon's
2031
+ // owner. A stub that carried the list would be handing a routing
2032
+ // party the membership of alice's group.
2033
+ audienceAllow: ["alice", "carol", "erin"]
2034
+ });
2035
+ const claimed = await claimOne(target, daemon);
2036
+ assert(
2037
+ claimed.id === job.id,
2038
+ "the harness could not claim its own named job"
2039
+ );
2040
+ const asRecord = claimed;
2041
+ assert(
2042
+ asRecord["audienceAllow"] === void 0,
2043
+ "a claimed stub carried audienceAllow"
2044
+ );
2045
+ const parsed = ClaimedStub.safeParse(claimed);
2046
+ assert(
2047
+ parsed.success,
2048
+ "the claim response is not a valid stub, so its fields prove nothing"
2049
+ );
2050
+ const wire = JSON.stringify(claimed);
2051
+ for (const member of ["carol", "erin"]) {
2052
+ assert(
2053
+ !wire.includes(member),
2054
+ `a claimed stub disclosed roster member "${member}"`
2055
+ );
2056
+ }
2057
+ assert(
2058
+ claimed.audience === "team",
2059
+ "the stub lost the audience routing decides on"
2060
+ );
2061
+ assert(
2062
+ typeof claimed.owner === "string" && claimed.owner.length > 0,
2063
+ "the stub lost the owner"
2064
+ );
2065
+ } finally {
2066
+ await daemon.dispose();
2067
+ }
2068
+ }
1809
2069
  }
1810
2070
  ];
1811
2071
 
1812
2072
  // src/certify.ts
1813
2073
  import {
2074
+ kindsOf,
1814
2075
  MUSTS,
1815
2076
  MUST_IDS,
1816
2077
  mustsVerifiedBy
@@ -1854,7 +2115,7 @@ function uncoveredMusts(checks = CHECKS) {
1854
2115
  return mustsVerifiedBy("conformance").filter((id) => !covered.has(id));
1855
2116
  }
1856
2117
  function miscoveredMusts(checks = CHECKS) {
1857
- return [...new Set(checks.flatMap((check) => check.musts))].filter((id) => MUSTS[id].verifiedBy !== "conformance").sort();
2118
+ return [...new Set(checks.flatMap((check) => check.musts))].filter((id) => !kindsOf(MUSTS[id]).includes("conformance")).sort();
1858
2119
  }
1859
2120
  var VERIFICATION_NOTE = "(`adversarial` = proved by the reference daemon's own suites; `construction` = true by code shape; `operator` = a deployment claim, verifiable only by audit or source. None is asserted by this run.)";
1860
2121
  function formatReport(report) {
@@ -1882,13 +2143,13 @@ function formatReport(report) {
1882
2143
  }
1883
2144
  }
1884
2145
  const elsewhere = MUST_IDS.filter(
1885
- (id) => MUSTS[id].verifiedBy !== "conformance"
2146
+ (id) => !kindsOf(MUSTS[id]).includes("conformance")
1886
2147
  );
1887
2148
  if (elsewhere.length > 0) {
1888
2149
  lines.push("");
1889
2150
  lines.push(" Verified elsewhere, not by this kit:");
1890
2151
  for (const kind of ["adversarial", "construction", "operator"]) {
1891
- const ids = elsewhere.filter((id) => MUSTS[id].verifiedBy === kind);
2152
+ const ids = elsewhere.filter((id) => kindsOf(MUSTS[id]).includes(kind));
1892
2153
  if (ids.length === 0) continue;
1893
2154
  lines.push(` ${kind}: ${ids.join(", ")}`);
1894
2155
  }
@@ -1911,4 +2172,4 @@ export {
1911
2172
  miscoveredMusts,
1912
2173
  formatReport
1913
2174
  };
1914
- //# sourceMappingURL=chunk-EXNALQ5D.js.map
2175
+ //# sourceMappingURL=chunk-OPJBI7WK.js.map