@mnemom/mnemom 0.17.34 → 0.17.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/agent-config.js +3 -0
- package/dist/commands/agent-goal.d.ts +8 -3
- package/dist/commands/agent-goal.js +22 -8
- package/dist/commands/agent-run.d.ts +14 -2
- package/dist/commands/agent-run.js +28 -7
- package/dist/commands/agent-share-render.js +1 -1
- package/dist/commands/agent-slack.js +32 -0
- package/dist/commands/durable-inbox.d.ts +51 -0
- package/dist/commands/durable-inbox.js +134 -0
- package/dist/commands/durable-questions.d.ts +64 -0
- package/dist/commands/durable-questions.js +161 -0
- package/dist/commands/scan.d.ts +13 -3
- package/dist/commands/scan.js +48 -10
- package/dist/durable/seat-proxy.d.ts +12 -1
- package/dist/durable/seat-proxy.js +55 -9
- package/dist/durable/seat-socket.d.ts +20 -2
- package/dist/durable/seat-socket.js +58 -0
- package/dist/durable/turn-chain.d.ts +8 -0
- package/dist/durable/turn-chain.js +25 -4
- package/dist/host/client.d.ts +41 -0
- package/dist/host/client.js +7 -0
- package/dist/host/control.d.ts +7 -0
- package/dist/host/control.js +15 -0
- package/dist/host/daemon.d.ts +20 -0
- package/dist/host/daemon.js +74 -1
- package/dist/host/inbox-delivery.d.ts +174 -0
- package/dist/host/inbox-delivery.js +453 -0
- package/dist/host/run.d.ts +18 -0
- package/dist/host/run.js +61 -0
- package/dist/host/s1-names.d.ts +2 -0
- package/dist/host/s1-names.js +2 -0
- package/dist/host/tmux.d.ts +7 -0
- package/dist/host/tmux.js +19 -0
- package/dist/index.js +62 -3
- package/dist/lib/api.d.ts +5 -0
- package/dist/lib/api.js +16 -0
- package/dist/lib/config.d.ts +7 -0
- package/dist/lib/config.js +21 -0
- package/dist/lib/durable/api.d.ts +11 -0
- package/dist/lib/durable/api.js +28 -3
- package/dist/lib/durable/gate.d.ts +1 -1
- package/dist/lib/durable/gate.js +8 -1
- package/dist/lib/durable/live.d.ts +5 -0
- package/dist/lib/durable/live.js +19 -0
- package/dist/lib/experimental.js +3 -0
- package/dist/lib/goal-api.d.ts +11 -4
- package/dist/lib/goal-api.js +4 -3
- package/dist/lib/launcher-config.d.ts +5 -0
- package/dist/lib/launcher-config.js +17 -2
- package/dist/lib/prompt.d.ts +4 -2
- package/dist/lib/prompt.js +15 -5
- package/dist/lib/runner/job.d.ts +2 -2
- package/dist/lib/runner/job.js +16 -3
- package/dist/lib/runner/pr-body.d.ts +17 -0
- package/dist/lib/runner/pr-body.js +42 -0
- package/dist/lib/runner/proxy.d.ts +18 -3
- package/dist/lib/runner/proxy.js +24 -5
- package/dist/lib/scan/pr-source.js +2 -0
- package/dist/lib/scan/record.d.ts +60 -9
- package/dist/lib/scan/record.js +157 -39
- package/dist/lib/scan/repo-picker.d.ts +32 -0
- package/dist/lib/scan/repo-picker.js +80 -0
- package/dist/lib/scan/report.d.ts +6 -8
- package/dist/lib/scan/report.js +21 -7
- package/dist/lib/scan/share.d.ts +5 -1
- package/dist/lib/scan/share.js +15 -5
- package/dist/lib/slack-durable.d.ts +123 -0
- package/dist/lib/slack-durable.js +237 -0
- package/dist/lib/slack-router.d.ts +7 -0
- package/dist/lib/slack-router.js +50 -4
- package/dist/vendor/durable-contract/index.js +992 -34
- package/dist/vendor/shared/durable-contract/admission.d.ts +81 -2
- package/dist/vendor/shared/durable-contract/admission.js +319 -2
- package/dist/vendor/shared/durable-contract/cli-surface.js +21 -0
- package/dist/vendor/shared/durable-contract/codes.d.ts +60 -0
- package/dist/vendor/shared/durable-contract/codes.js +22 -0
- package/dist/vendor/shared/durable-contract/events.d.ts +4 -2
- package/dist/vendor/shared/durable-contract/events.js +55 -1
- package/dist/vendor/shared/durable-contract/freeze-record.d.ts +14 -0
- package/dist/vendor/shared/durable-contract/inbox.d.ts +299 -0
- package/dist/vendor/shared/durable-contract/inbox.js +462 -0
- package/dist/vendor/shared/durable-contract/index.d.ts +2 -0
- package/dist/vendor/shared/durable-contract/index.js +2 -0
- package/dist/vendor/shared/durable-contract/question.d.ts +218 -0
- package/dist/vendor/shared/durable-contract/question.js +373 -0
- package/dist/vendor/shared/durable-contract/routes.d.ts +44 -2
- package/dist/vendor/shared/durable-contract/routes.js +43 -1
- package/dist/vendor/shared/durable-contract/turn.d.ts +15 -1
- package/dist/vendor/shared/durable-contract/turn.js +33 -1
- package/dist/vendor/shared/durable-contract/vectors.d.ts +45 -0
- package/dist/vendor/shared/durable-contract/vectors.js +49 -0
- package/node_modules/@mnemom/aip-verifier/LICENSE +190 -0
- package/node_modules/@mnemom/aip-verifier/dist/claim-lint-CVITIRcU.d.cts +478 -0
- package/node_modules/@mnemom/aip-verifier/dist/claim-lint-CVITIRcU.d.ts +478 -0
- package/node_modules/@mnemom/aip-verifier/dist/index.cjs +971 -0
- package/node_modules/@mnemom/aip-verifier/dist/index.cjs.map +1 -0
- package/node_modules/@mnemom/aip-verifier/dist/index.d.cts +330 -0
- package/node_modules/@mnemom/aip-verifier/dist/index.d.ts +330 -0
- package/node_modules/@mnemom/aip-verifier/dist/index.js +933 -0
- package/node_modules/@mnemom/aip-verifier/dist/index.js.map +1 -0
- package/node_modules/@mnemom/aip-verifier/dist/render-lines.cjs +879 -0
- package/node_modules/@mnemom/aip-verifier/dist/render-lines.cjs.map +1 -0
- package/node_modules/@mnemom/aip-verifier/dist/render-lines.d.cts +96 -0
- package/node_modules/@mnemom/aip-verifier/dist/render-lines.d.ts +96 -0
- package/node_modules/@mnemom/aip-verifier/dist/render-lines.js +875 -0
- package/node_modules/@mnemom/aip-verifier/dist/render-lines.js.map +1 -0
- package/node_modules/@mnemom/aip-verifier/package.json +86 -0
- package/node_modules/@noble/ed25519/LICENSE +21 -0
- package/node_modules/@noble/ed25519/README.md +371 -0
- package/node_modules/@noble/ed25519/index.d.ts +391 -0
- package/node_modules/@noble/ed25519/index.js +933 -0
- package/node_modules/@noble/ed25519/index.ts +1134 -0
- package/node_modules/@noble/ed25519/package.json +54 -0
- package/node_modules/@noble/hashes/LICENSE +21 -0
- package/node_modules/@noble/hashes/README.md +478 -0
- package/node_modules/@noble/hashes/_blake.d.ts +20 -0
- package/node_modules/@noble/hashes/_blake.js +59 -0
- package/node_modules/@noble/hashes/_md.d.ts +95 -0
- package/node_modules/@noble/hashes/_md.js +209 -0
- package/node_modules/@noble/hashes/_u64.d.ts +36 -0
- package/node_modules/@noble/hashes/_u64.js +77 -0
- package/node_modules/@noble/hashes/argon2.d.ts +148 -0
- package/node_modules/@noble/hashes/argon2.js +577 -0
- package/node_modules/@noble/hashes/blake1.d.ts +162 -0
- package/node_modules/@noble/hashes/blake1.js +630 -0
- package/node_modules/@noble/hashes/blake2.d.ts +203 -0
- package/node_modules/@noble/hashes/blake2.js +573 -0
- package/node_modules/@noble/hashes/blake3.d.ts +68 -0
- package/node_modules/@noble/hashes/blake3.js +310 -0
- package/node_modules/@noble/hashes/eskdf.d.ts +91 -0
- package/node_modules/@noble/hashes/eskdf.js +225 -0
- package/node_modules/@noble/hashes/hkdf.d.ts +70 -0
- package/node_modules/@noble/hashes/hkdf.js +152 -0
- package/node_modules/@noble/hashes/hmac.d.ts +50 -0
- package/node_modules/@noble/hashes/hmac.js +93 -0
- package/node_modules/@noble/hashes/index.d.ts +1 -0
- package/node_modules/@noble/hashes/index.js +34 -0
- package/node_modules/@noble/hashes/legacy.d.ts +107 -0
- package/node_modules/@noble/hashes/legacy.js +348 -0
- package/node_modules/@noble/hashes/package.json +91 -0
- package/node_modules/@noble/hashes/pbkdf2.d.ts +66 -0
- package/node_modules/@noble/hashes/pbkdf2.js +176 -0
- package/node_modules/@noble/hashes/scrypt.d.ts +98 -0
- package/node_modules/@noble/hashes/scrypt.js +304 -0
- package/node_modules/@noble/hashes/sha2.d.ts +176 -0
- package/node_modules/@noble/hashes/sha2.js +446 -0
- package/node_modules/@noble/hashes/sha3-addons.d.ts +533 -0
- package/node_modules/@noble/hashes/sha3-addons.js +973 -0
- package/node_modules/@noble/hashes/sha3.d.ts +208 -0
- package/node_modules/@noble/hashes/sha3.js +475 -0
- package/node_modules/@noble/hashes/src/_blake.ts +67 -0
- package/node_modules/@noble/hashes/src/_md.ts +227 -0
- package/node_modules/@noble/hashes/src/_u64.ts +111 -0
- package/node_modules/@noble/hashes/src/argon2.ts +693 -0
- package/node_modules/@noble/hashes/src/blake1.ts +677 -0
- package/node_modules/@noble/hashes/src/blake2.ts +648 -0
- package/node_modules/@noble/hashes/src/blake3.ts +344 -0
- package/node_modules/@noble/hashes/src/eskdf.ts +265 -0
- package/node_modules/@noble/hashes/src/hkdf.ts +161 -0
- package/node_modules/@noble/hashes/src/hmac.ts +130 -0
- package/node_modules/@noble/hashes/src/index.ts +33 -0
- package/node_modules/@noble/hashes/src/legacy.ts +361 -0
- package/node_modules/@noble/hashes/src/pbkdf2.ts +219 -0
- package/node_modules/@noble/hashes/src/scrypt.ts +375 -0
- package/node_modules/@noble/hashes/src/sha2.ts +486 -0
- package/node_modules/@noble/hashes/src/sha3-addons.ts +1157 -0
- package/node_modules/@noble/hashes/src/sha3.ts +525 -0
- package/node_modules/@noble/hashes/src/utils.ts +978 -0
- package/node_modules/@noble/hashes/src/webcrypto.ts +283 -0
- package/node_modules/@noble/hashes/utils.d.ts +560 -0
- package/node_modules/@noble/hashes/utils.js +687 -0
- package/node_modules/@noble/hashes/webcrypto.d.ts +121 -0
- package/node_modules/@noble/hashes/webcrypto.js +228 -0
- package/package.json +5 -2
- package/plugins/integrity-manifest.json +6 -2
- package/plugins/mnemom/hooks/hooks.json +12 -0
- package/plugins/mnemom/hooks/seat-ask.mjs +221 -0
|
@@ -36,8 +36,8 @@ function bytesToHex(bytes) {
|
|
|
36
36
|
for (const b of bytes) out += HEX[b];
|
|
37
37
|
return out;
|
|
38
38
|
}
|
|
39
|
-
function utf8(
|
|
40
|
-
return new TextEncoder().encode(
|
|
39
|
+
function utf8(text2) {
|
|
40
|
+
return new TextEncoder().encode(text2);
|
|
41
41
|
}
|
|
42
42
|
async function sha256Hex(input) {
|
|
43
43
|
const bytes = typeof input === "string" ? utf8(input) : input;
|
|
@@ -61,13 +61,13 @@ function base64urlEncode(bytes) {
|
|
|
61
61
|
return btoa(bin).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
62
62
|
}
|
|
63
63
|
var B64URL_RE = /^[A-Za-z0-9_-]*$/;
|
|
64
|
-
function base64urlDecode(
|
|
65
|
-
if (!B64URL_RE.test(
|
|
66
|
-
const padded =
|
|
64
|
+
function base64urlDecode(text2) {
|
|
65
|
+
if (!B64URL_RE.test(text2) || text2.length % 4 === 1) return null;
|
|
66
|
+
const padded = text2.replace(/-/g, "+").replace(/_/g, "/") + "===".slice(0, (4 - text2.length % 4) % 4);
|
|
67
67
|
const bin = atob(padded);
|
|
68
68
|
const out = new Uint8Array(bin.length);
|
|
69
69
|
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
|
|
70
|
-
return base64urlEncode(out) ===
|
|
70
|
+
return base64urlEncode(out) === text2 ? out : null;
|
|
71
71
|
}
|
|
72
72
|
var HEX64_RE = /^[0-9a-f]{64}$/;
|
|
73
73
|
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
@@ -367,7 +367,8 @@ var RESOLVER_SCHEMA = {
|
|
|
367
367
|
},
|
|
368
368
|
epoch: { type: "integer", nullable: false },
|
|
369
369
|
fenced: { type: "boolean", nullable: false },
|
|
370
|
-
|
|
370
|
+
// The opaque agents.id text, e.g. "mnm-<hex>" (ruling 33.29), never a uuid.
|
|
371
|
+
agent_id: { type: "string", nullable: false },
|
|
371
372
|
home_cell: { type: "enum", nullable: false, values: CANONICAL_CELL_IDS },
|
|
372
373
|
posture: {
|
|
373
374
|
type: "enum",
|
|
@@ -434,6 +435,15 @@ var GUARD_STATE_OK = Object.freeze({ spend_usd: 0 });
|
|
|
434
435
|
var GUARD_STATE_FAULT = Object.freeze({
|
|
435
436
|
spend_usd: "unparseable"
|
|
436
437
|
});
|
|
438
|
+
function guardStateV1Ok(guard) {
|
|
439
|
+
if (guard === null || guard.schema_version !== 1) return false;
|
|
440
|
+
return [guard.turns, guard.spend_usd].every(
|
|
441
|
+
(v) => typeof v === "number" && Number.isFinite(v) && v >= 0
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
function unattendedPoolEligible(d) {
|
|
445
|
+
return d.durable_mode === "locked" && d.pool === true && !d.fenced && d.lease_executor_id !== null && (d.effective_state === "running" || d.effective_state === "resuming") && d.sealed && Number.isSafeInteger(d.charter_version) && d.charter_version >= 1;
|
|
446
|
+
}
|
|
437
447
|
function nofenceHonoured(durableAdmit) {
|
|
438
448
|
return durableAdmit === NOFENCE_ADMIT_VALUE;
|
|
439
449
|
}
|
|
@@ -480,6 +490,12 @@ function isUnchainedCountTokens(r) {
|
|
|
480
490
|
return r.method === "POST" && isCountTokensPath(r.path) && !r.chain;
|
|
481
491
|
}
|
|
482
492
|
var RESOLVER_FAULT = "fault";
|
|
493
|
+
var INBOX_OPEN_MAX = 64;
|
|
494
|
+
var INBOX_SHA_RE = /^[0-9a-f]{64}$/;
|
|
495
|
+
function unattendedHomedInboxEligible(d, inboxSha2) {
|
|
496
|
+
const open = d.inbox_open;
|
|
497
|
+
return d.durable_mode === "locked" && d.pool !== true && !d.fenced && d.lease_executor_id !== null && (d.effective_state === "running" || d.effective_state === "resuming") && d.sealed && Number.isSafeInteger(d.charter_version) && d.charter_version >= 1 && d.host_unattended === true && typeof inboxSha2 === "string" && INBOX_SHA_RE.test(inboxSha2) && Array.isArray(open) && open.length <= INBOX_OPEN_MAX && open.includes(inboxSha2);
|
|
498
|
+
}
|
|
483
499
|
function admit(input) {
|
|
484
500
|
const fenceSource = nofenceHonoured(input.durableAdmit) ? "nofence" : "fresh";
|
|
485
501
|
const posture = input.posture ?? "unattended";
|
|
@@ -519,6 +535,24 @@ function admit(input) {
|
|
|
519
535
|
writes: false
|
|
520
536
|
};
|
|
521
537
|
if (posture === "unattended") {
|
|
538
|
+
if (unattendedPoolEligible(d) || unattendedHomedInboxEligible(d, input.inboxSha)) {
|
|
539
|
+
if (guardStateV1Ok(d.guard_state))
|
|
540
|
+
return {
|
|
541
|
+
kind: "admit",
|
|
542
|
+
step: "admit",
|
|
543
|
+
posture: "unattended",
|
|
544
|
+
guardFault: false,
|
|
545
|
+
fenceSource,
|
|
546
|
+
helloTransition: false
|
|
547
|
+
};
|
|
548
|
+
return {
|
|
549
|
+
kind: "refuse",
|
|
550
|
+
step: "posture",
|
|
551
|
+
code: "durable_guard_unavailable",
|
|
552
|
+
posture,
|
|
553
|
+
fenceSource
|
|
554
|
+
};
|
|
555
|
+
}
|
|
522
556
|
return {
|
|
523
557
|
kind: "refuse",
|
|
524
558
|
step: "posture",
|
|
@@ -670,6 +704,120 @@ function admissionTruthTable() {
|
|
|
670
704
|
}
|
|
671
705
|
return out;
|
|
672
706
|
}
|
|
707
|
+
var GUARD_STATE_V1_OK = Object.freeze({
|
|
708
|
+
schema_version: 1,
|
|
709
|
+
turns: 0,
|
|
710
|
+
spend_usd: 0
|
|
711
|
+
});
|
|
712
|
+
var UNATTENDED_POOL_VECTORS = Object.freeze([
|
|
713
|
+
{ name: "all hold: admitted unattended", over: {}, nofence: false, outcome: "admit" },
|
|
714
|
+
{
|
|
715
|
+
name: "all hold, resuming: admitted, no hello",
|
|
716
|
+
over: { effective_state: "resuming", state: "resuming" },
|
|
717
|
+
nofence: false,
|
|
718
|
+
outcome: "admit"
|
|
719
|
+
},
|
|
720
|
+
{
|
|
721
|
+
name: "(b) pool absent",
|
|
722
|
+
over: { pool: void 0 },
|
|
723
|
+
nofence: false,
|
|
724
|
+
outcome: "durable_unattended_unavailable"
|
|
725
|
+
},
|
|
726
|
+
{
|
|
727
|
+
name: "(b) pool false",
|
|
728
|
+
over: { pool: false },
|
|
729
|
+
nofence: false,
|
|
730
|
+
outcome: "durable_unattended_unavailable"
|
|
731
|
+
},
|
|
732
|
+
{
|
|
733
|
+
name: "(c) fenced key under nofence",
|
|
734
|
+
over: { fenced: true },
|
|
735
|
+
nofence: true,
|
|
736
|
+
outcome: "durable_unattended_unavailable"
|
|
737
|
+
},
|
|
738
|
+
{
|
|
739
|
+
name: "(c) no lease executor",
|
|
740
|
+
over: { lease_executor_id: null },
|
|
741
|
+
nofence: false,
|
|
742
|
+
outcome: "durable_unattended_unavailable"
|
|
743
|
+
},
|
|
744
|
+
{
|
|
745
|
+
name: "(c) lease lapsed (detached)",
|
|
746
|
+
over: { effective_state: "detached" },
|
|
747
|
+
nofence: false,
|
|
748
|
+
outcome: "durable_unattended_unavailable"
|
|
749
|
+
},
|
|
750
|
+
{
|
|
751
|
+
name: "(d) not sealed",
|
|
752
|
+
over: { sealed: false },
|
|
753
|
+
nofence: false,
|
|
754
|
+
outcome: "durable_unattended_unavailable"
|
|
755
|
+
},
|
|
756
|
+
{
|
|
757
|
+
name: "(d) no charter version",
|
|
758
|
+
over: { charter_version: null },
|
|
759
|
+
nofence: false,
|
|
760
|
+
outcome: "durable_unattended_unavailable"
|
|
761
|
+
},
|
|
762
|
+
{
|
|
763
|
+
name: "(d) charter version 0",
|
|
764
|
+
over: { charter_version: 0 },
|
|
765
|
+
nofence: false,
|
|
766
|
+
outcome: "durable_unattended_unavailable"
|
|
767
|
+
},
|
|
768
|
+
{
|
|
769
|
+
name: "(d) charter version not an integer",
|
|
770
|
+
over: { charter_version: 1.5 },
|
|
771
|
+
nofence: false,
|
|
772
|
+
outcome: "durable_unattended_unavailable"
|
|
773
|
+
},
|
|
774
|
+
{
|
|
775
|
+
name: "(e) guard null",
|
|
776
|
+
over: { guard_state: null },
|
|
777
|
+
nofence: false,
|
|
778
|
+
outcome: "durable_guard_unavailable"
|
|
779
|
+
},
|
|
780
|
+
{
|
|
781
|
+
name: "(e) guard without schema_version",
|
|
782
|
+
over: { guard_state: { turns: 0, spend_usd: 0 } },
|
|
783
|
+
nofence: false,
|
|
784
|
+
outcome: "durable_guard_unavailable"
|
|
785
|
+
},
|
|
786
|
+
{
|
|
787
|
+
name: "(e) guard without turns",
|
|
788
|
+
over: { guard_state: { schema_version: 1, spend_usd: 0 } },
|
|
789
|
+
nofence: false,
|
|
790
|
+
outcome: "durable_guard_unavailable"
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
name: "(e) guard turns as a string",
|
|
794
|
+
over: { guard_state: { schema_version: 1, turns: "0", spend_usd: 0 } },
|
|
795
|
+
nofence: false,
|
|
796
|
+
outcome: "durable_guard_unavailable"
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
name: "attended on a pool session: unchanged",
|
|
800
|
+
over: { posture: "attended" },
|
|
801
|
+
nofence: false,
|
|
802
|
+
outcome: "admit"
|
|
803
|
+
}
|
|
804
|
+
]);
|
|
805
|
+
function decideUnattendedPoolVector(v) {
|
|
806
|
+
const base = {
|
|
807
|
+
posture: "unattended",
|
|
808
|
+
pool: true,
|
|
809
|
+
charter_version: 1,
|
|
810
|
+
guard_state: { ...GUARD_STATE_V1_OK }
|
|
811
|
+
};
|
|
812
|
+
const resolver = { ...fixtureResolver(base), ...v.over };
|
|
813
|
+
if (v.over.pool === void 0 && "pool" in v.over) delete resolver.pool;
|
|
814
|
+
return admit({
|
|
815
|
+
resolver,
|
|
816
|
+
pinAgentId: FIXTURE_AGENT,
|
|
817
|
+
posture: resolver.posture,
|
|
818
|
+
durableAdmit: v.nofence ? NOFENCE_ADMIT_VALUE : void 0
|
|
819
|
+
});
|
|
820
|
+
}
|
|
673
821
|
var ADMIT_SWEEP_VECTORS_PATH = "src/vectors/admit-sweep-vectors.json";
|
|
674
822
|
var ADMIT_SWEEP_VALUES = Object.freeze({
|
|
675
823
|
durable_mode: ["locked", "tracked", null],
|
|
@@ -789,8 +937,122 @@ function admitSweepText(sweep) {
|
|
|
789
937
|
}
|
|
790
938
|
}
|
|
791
939
|
async function admitSweepDigest(sweep) {
|
|
792
|
-
const { tuples, text } = admitSweepText(sweep);
|
|
793
|
-
return { tuples, verdicts_sha256: await sha256Hex(
|
|
940
|
+
const { tuples, text: text2 } = admitSweepText(sweep);
|
|
941
|
+
return { tuples, verdicts_sha256: await sha256Hex(text2) };
|
|
942
|
+
}
|
|
943
|
+
var INBOX_SHA_FIXTURE = "ab".repeat(32);
|
|
944
|
+
var HOMED_INBOX_VECTORS = Object.freeze([
|
|
945
|
+
{ name: "all hold: admitted unattended", over: {}, nofence: false, outcome: "admit" },
|
|
946
|
+
{
|
|
947
|
+
name: "all hold, resuming: admitted, no hello",
|
|
948
|
+
over: { effective_state: "resuming", state: "resuming" },
|
|
949
|
+
nofence: false,
|
|
950
|
+
outcome: "admit"
|
|
951
|
+
},
|
|
952
|
+
{
|
|
953
|
+
name: "(a) a pool session takes 58, not 60: still admitted",
|
|
954
|
+
over: { pool: true },
|
|
955
|
+
nofence: false,
|
|
956
|
+
outcome: "admit"
|
|
957
|
+
},
|
|
958
|
+
{
|
|
959
|
+
name: "(b) fenced key under nofence",
|
|
960
|
+
over: { fenced: true },
|
|
961
|
+
nofence: true,
|
|
962
|
+
outcome: "durable_unattended_unavailable"
|
|
963
|
+
},
|
|
964
|
+
{
|
|
965
|
+
name: "(b) no lease executor",
|
|
966
|
+
over: { lease_executor_id: null },
|
|
967
|
+
nofence: false,
|
|
968
|
+
outcome: "durable_unattended_unavailable"
|
|
969
|
+
},
|
|
970
|
+
{
|
|
971
|
+
name: "(b) lease lapsed (detached)",
|
|
972
|
+
over: { effective_state: "detached" },
|
|
973
|
+
nofence: false,
|
|
974
|
+
outcome: "durable_unattended_unavailable"
|
|
975
|
+
},
|
|
976
|
+
{
|
|
977
|
+
name: "(c) not sealed",
|
|
978
|
+
over: { sealed: false },
|
|
979
|
+
nofence: false,
|
|
980
|
+
outcome: "durable_unattended_unavailable"
|
|
981
|
+
},
|
|
982
|
+
{
|
|
983
|
+
name: "(c) no charter version",
|
|
984
|
+
over: { charter_version: null },
|
|
985
|
+
nofence: false,
|
|
986
|
+
outcome: "durable_unattended_unavailable"
|
|
987
|
+
},
|
|
988
|
+
{
|
|
989
|
+
name: "(d) host policy or the owner's opt-out says no",
|
|
990
|
+
over: { host_unattended: false },
|
|
991
|
+
nofence: false,
|
|
992
|
+
outcome: "durable_unattended_unavailable"
|
|
993
|
+
},
|
|
994
|
+
{
|
|
995
|
+
name: "(e) no inbox key on the newest entry",
|
|
996
|
+
over: {},
|
|
997
|
+
inboxSha: null,
|
|
998
|
+
nofence: false,
|
|
999
|
+
outcome: "durable_unattended_unavailable"
|
|
1000
|
+
},
|
|
1001
|
+
{
|
|
1002
|
+
name: "(e) inbox sha not open (acked, dead or never delivered)",
|
|
1003
|
+
over: { inbox_open: ["cd".repeat(32)] },
|
|
1004
|
+
nofence: false,
|
|
1005
|
+
outcome: "durable_unattended_unavailable"
|
|
1006
|
+
},
|
|
1007
|
+
{
|
|
1008
|
+
name: "(e) inbox_open absent",
|
|
1009
|
+
over: { inbox_open: void 0 },
|
|
1010
|
+
nofence: false,
|
|
1011
|
+
outcome: "durable_unattended_unavailable"
|
|
1012
|
+
},
|
|
1013
|
+
{
|
|
1014
|
+
name: "(e) inbox sha malformed",
|
|
1015
|
+
over: { inbox_open: ["AB".repeat(32)] },
|
|
1016
|
+
inboxSha: "AB".repeat(32),
|
|
1017
|
+
nofence: false,
|
|
1018
|
+
outcome: "durable_unattended_unavailable"
|
|
1019
|
+
},
|
|
1020
|
+
{
|
|
1021
|
+
name: "(f) guard null",
|
|
1022
|
+
over: { guard_state: null },
|
|
1023
|
+
nofence: false,
|
|
1024
|
+
outcome: "durable_guard_unavailable"
|
|
1025
|
+
},
|
|
1026
|
+
{
|
|
1027
|
+
name: "(f) guard without schema_version",
|
|
1028
|
+
over: { guard_state: { turns: 0, spend_usd: 0 } },
|
|
1029
|
+
nofence: false,
|
|
1030
|
+
outcome: "durable_guard_unavailable"
|
|
1031
|
+
},
|
|
1032
|
+
{
|
|
1033
|
+
name: "attended on a homed session: unchanged",
|
|
1034
|
+
over: { posture: "attended" },
|
|
1035
|
+
inboxSha: null,
|
|
1036
|
+
nofence: false,
|
|
1037
|
+
outcome: "admit"
|
|
1038
|
+
}
|
|
1039
|
+
]);
|
|
1040
|
+
function decideHomedInboxVector(v) {
|
|
1041
|
+
const base = {
|
|
1042
|
+
posture: "unattended",
|
|
1043
|
+
charter_version: 1,
|
|
1044
|
+
inbox_open: [INBOX_SHA_FIXTURE],
|
|
1045
|
+
guard_state: { ...GUARD_STATE_V1_OK }
|
|
1046
|
+
};
|
|
1047
|
+
const resolver = { ...fixtureResolver(base), ...v.over };
|
|
1048
|
+
if ("inbox_open" in v.over && v.over.inbox_open === void 0) delete resolver.inbox_open;
|
|
1049
|
+
return admit({
|
|
1050
|
+
resolver,
|
|
1051
|
+
pinAgentId: FIXTURE_AGENT,
|
|
1052
|
+
posture: resolver.posture,
|
|
1053
|
+
durableAdmit: v.nofence ? NOFENCE_ADMIT_VALUE : void 0,
|
|
1054
|
+
inboxSha: "inboxSha" in v ? v.inboxSha : INBOX_SHA_FIXTURE
|
|
1055
|
+
});
|
|
794
1056
|
}
|
|
795
1057
|
|
|
796
1058
|
// ../shared/durable-contract/src/codes.ts
|
|
@@ -952,7 +1214,29 @@ var DURABLE_CODES = {
|
|
|
952
1214
|
* POST ROUTES.int_charter names an unknown session, a hash that is not one of its charter
|
|
953
1215
|
* versions, or no charter at all (a malformed body). The gateway refuses admission on it.
|
|
954
1216
|
*/
|
|
955
|
-
durable_charter_not_found: { status: 404, surfaces: ["api"], fields: [] }
|
|
1217
|
+
durable_charter_not_found: { status: 404, surfaces: ["api"], fields: [] },
|
|
1218
|
+
// ---- api inbox, S1 amendment 60 (signed off by Wassim 2026-11-02; inbox.ts INBOX_REJECT_CODES) ----
|
|
1219
|
+
/** An agent sender with no live allowlist row for the recipient agent, set by the session's owner. */
|
|
1220
|
+
durable_inbox_not_allowlisted: { status: 403, surfaces: ["api", "cli"], fields: [] },
|
|
1221
|
+
/** The session cannot take inbox work: reason not_locked, ended, unsealed or unattended_off (host_unattended is not true, so §60 (e) could never admit the turn). */
|
|
1222
|
+
durable_inbox_closed: { status: 409, surfaces: ["api", "cli"], fields: ["reason"] },
|
|
1223
|
+
/** INBOX_OPEN_CAP messages are already open (admitted or delivered). */
|
|
1224
|
+
durable_inbox_full: { status: 429, surfaces: ["api", "cli"], fields: ["open", "cap"] },
|
|
1225
|
+
/** A send, allowlist, take or ack body outside its closed shape or limits; field names the first bad key (null: not an object). */
|
|
1226
|
+
durable_inbox_body_invalid: { status: 422, surfaces: ["api", "cli"], fields: ["field"] },
|
|
1227
|
+
/** An ack of a message not delivered to this session at this epoch with this sha. */
|
|
1228
|
+
durable_inbox_not_open: { status: 409, surfaces: ["api"], fields: [] },
|
|
1229
|
+
/** A sender identity or allowlist change the api refuses; reason is one of inbox.ts INBOX_SENDER_INVALID_REASONS. */
|
|
1230
|
+
durable_inbox_sender_invalid: { status: 422, surfaces: ["api", "cli"], fields: ["reason"] },
|
|
1231
|
+
// ---- api questions, S1 amendment 61 (signed off by Wassim 2026-11-02; question.ts) ----
|
|
1232
|
+
/** An ask, poll, release or answer body outside its closed shape or limits; field names the first bad key. */
|
|
1233
|
+
durable_question_body_invalid: { status: 422, surfaces: ["api", "cli"], fields: ["field"] },
|
|
1234
|
+
/** No question with that approval_id on this session. */
|
|
1235
|
+
durable_question_not_found: { status: 404, surfaces: ["api", "cli"], fields: [] },
|
|
1236
|
+
/** The question is no longer open (answered, dismissed, expired); state names which. */
|
|
1237
|
+
durable_question_closed: { status: 409, surfaces: ["api", "cli"], fields: ["state"] },
|
|
1238
|
+
/** An ask while the session's open question is a different one (another question_sha); approval_id and state name it. Nothing is stored. */
|
|
1239
|
+
durable_question_busy: { status: 409, surfaces: ["api", "cli"], fields: ["approval_id", "state"] }
|
|
956
1240
|
};
|
|
957
1241
|
function isDurableCode(v) {
|
|
958
1242
|
return typeof v === "string" && Object.prototype.hasOwnProperty.call(DURABLE_CODES, v);
|
|
@@ -1387,6 +1671,23 @@ var M1_CLI_SURFACE = Object.freeze([
|
|
|
1387
1671
|
// BACKBONE C4 (line 147: buildDurableLaunchSpec serves 'sessions adopt'); options: C14 spec
|
|
1388
1672
|
// (`sessions adopt --dry-run --json`, `sessions adopt --own-agent`); ruling 32.33.
|
|
1389
1673
|
entry(["agent", "sessions", "adopt"], ["--dry-run", "--json", "--own-agent"]),
|
|
1674
|
+
// S1 amendment 61 (signed off by Wassim 2026-11-02): the owner's answer or dismissal of a locked
|
|
1675
|
+
// session's question (own_answer, via coding_agent).
|
|
1676
|
+
entry(["agent", "sessions", "answer"], ["--dismiss", "--json"]),
|
|
1677
|
+
// S1 amendment 61: the session's questions to its owner (own_questions).
|
|
1678
|
+
entry(["agent", "sessions", "questions"], ["--all", "--json"]),
|
|
1679
|
+
// S1 amendment 60 (signed off by Wassim 2026-11-02): the owner door into a locked session's inbox. `send`
|
|
1680
|
+
// posts own_inbox_send (owner credential, or an allowlisted agent's key named by --sender-key-env);
|
|
1681
|
+
// --agent-id/--conversation address a session the caller cannot list (an allowlisted agent).
|
|
1682
|
+
entry(
|
|
1683
|
+
["agent", "sessions", "send"],
|
|
1684
|
+
["--agent-id", "--conversation", "--idempotency-key", "--json", "--sender-key-env"]
|
|
1685
|
+
),
|
|
1686
|
+
// S1 amendment 60: the owner-managed inbox sender allowlist (own_inbox_senders, _sender_add, _sender_remove).
|
|
1687
|
+
entry(["agent", "sessions", "senders"]),
|
|
1688
|
+
entry(["agent", "sessions", "senders", "add"], ["--json", "--label"]),
|
|
1689
|
+
entry(["agent", "sessions", "senders", "list"], ["--json"]),
|
|
1690
|
+
entry(["agent", "sessions", "senders", "remove"], ["--json"]),
|
|
1390
1691
|
// fixlines.ts launch_spec_change_sole_unlock (`mnemom agent sessions unlock <name>`); C11, C16 and
|
|
1391
1692
|
// C17 specs; no source names an option; ruling 32.33.
|
|
1392
1693
|
entry(["agent", "sessions", "unlock"])
|
|
@@ -1403,6 +1704,13 @@ var M1_CLI_SURFACE_BUILDERS = Object.freeze({
|
|
|
1403
1704
|
"agent lock",
|
|
1404
1705
|
"agent pause",
|
|
1405
1706
|
"agent resume",
|
|
1707
|
+
"agent sessions answer",
|
|
1708
|
+
"agent sessions questions",
|
|
1709
|
+
"agent sessions send",
|
|
1710
|
+
"agent sessions senders",
|
|
1711
|
+
"agent sessions senders add",
|
|
1712
|
+
"agent sessions senders list",
|
|
1713
|
+
"agent sessions senders remove",
|
|
1406
1714
|
"agent sessions unlock"
|
|
1407
1715
|
]),
|
|
1408
1716
|
C2: Object.freeze([
|
|
@@ -1775,8 +2083,8 @@ function substitute(template, params) {
|
|
|
1775
2083
|
}
|
|
1776
2084
|
function placeholdersOf(key) {
|
|
1777
2085
|
const entry2 = FIX_LINES[key];
|
|
1778
|
-
const
|
|
1779
|
-
return [...new Set([...
|
|
2086
|
+
const text2 = entry2.lead + (isRuled(entry2) ? DONE_CLAUSE : "") + entry2.body;
|
|
2087
|
+
return [...new Set([...text2.matchAll(PLACEHOLDER_RE)].map((m) => m[1]))];
|
|
1780
2088
|
}
|
|
1781
2089
|
function renderFixLine(key, ctx) {
|
|
1782
2090
|
const entry2 = FIX_LINES[key];
|
|
@@ -1910,18 +2218,18 @@ var FORBIDDEN_FIX_TOKENS = ["--local", "host breakglass"];
|
|
|
1910
2218
|
function lintFixCatalogue(catalogue = FIX_LINES) {
|
|
1911
2219
|
const out = [];
|
|
1912
2220
|
for (const [key, entry2] of Object.entries(catalogue)) {
|
|
1913
|
-
const
|
|
2221
|
+
const text2 = entry2.lead + entry2.body;
|
|
1914
2222
|
for (const tok of FORBIDDEN_FIX_TOKENS) {
|
|
1915
|
-
if (
|
|
2223
|
+
if (text2.includes(tok)) out.push({ key, problem: `forbidden token ${tok}` });
|
|
1916
2224
|
}
|
|
1917
2225
|
if (entry2.lead.includes(NEW_TOKEN))
|
|
1918
2226
|
out.push({ key, problem: "--new in the lead escapes the rule" });
|
|
1919
|
-
if (
|
|
2227
|
+
if (text2.includes("mnemom agent done <name>"))
|
|
1920
2228
|
out.push({ key, problem: "done clause restated; the rule adds it" });
|
|
1921
|
-
if (
|
|
2229
|
+
if (text2.includes("config set durable always") && key !== "durable_only_agent") {
|
|
1922
2230
|
out.push({ key, problem: "launcher suffix restated; the rule adds it" });
|
|
1923
2231
|
}
|
|
1924
|
-
const commands = [...
|
|
2232
|
+
const commands = [...text2.matchAll(/`([^`]+)`/g)].map((m) => m[1]);
|
|
1925
2233
|
if (entry2.kind === "command" && commands.length === 0)
|
|
1926
2234
|
out.push({ key, problem: "command entry has no command" });
|
|
1927
2235
|
if (entry2.kind === "informational" && commands.length > 0)
|
|
@@ -2422,7 +2730,8 @@ var DURABLE_EVENT_KINDS = [
|
|
|
2422
2730
|
"session.ready",
|
|
2423
2731
|
"session.waiting",
|
|
2424
2732
|
"session.wait_cleared",
|
|
2425
|
-
"executor.turn_continued"
|
|
2733
|
+
"executor.turn_continued",
|
|
2734
|
+
"inbox.acked"
|
|
2426
2735
|
];
|
|
2427
2736
|
function isDurableEventKind(v) {
|
|
2428
2737
|
return typeof v === "string" && DURABLE_EVENT_KINDS.includes(v);
|
|
@@ -2687,7 +2996,62 @@ var KIND_REFS = {
|
|
|
2687
2996
|
"session.wait_cleared": obj({ wait_reason: ENUM(PARKED_ONLY_WAIT_REASONS) }),
|
|
2688
2997
|
// ---- lead ruling 2026-10-28: the spawn that sent the continue; a separate fact, so
|
|
2689
2998
|
// executor.spawned's refs stay exactly {spawn_id} ----
|
|
2690
|
-
"executor.turn_continued": obj({ spawn_id: UUID })
|
|
2999
|
+
"executor.turn_continued": obj({ spawn_id: UUID }),
|
|
3000
|
+
// ---- S1 amendment 60 (signed off by Wassim 2026-11-02): the inbox. Content-free: ids, shas, enums ----
|
|
3001
|
+
"inbox.admitted": obj(
|
|
3002
|
+
{
|
|
3003
|
+
inbox_id: UUID,
|
|
3004
|
+
sha: S({ pattern: HEX64_PATTERN, maxLength: 64 }),
|
|
3005
|
+
sender_kind: ENUM(["owner", "agent"]),
|
|
3006
|
+
sender_agent_id: S({ pattern: "^[A-Za-z0-9_-]{1,64}$" }),
|
|
3007
|
+
in_reply_to: UUID
|
|
3008
|
+
},
|
|
3009
|
+
["inbox_id", "sha", "sender_kind"],
|
|
3010
|
+
[
|
|
3011
|
+
{ field: "sender_kind", equals: "agent", require: ["sender_agent_id"] },
|
|
3012
|
+
{ field: "sender_kind", equals: "owner", forbid: ["sender_agent_id"] }
|
|
3013
|
+
]
|
|
3014
|
+
),
|
|
3015
|
+
"inbox.rejected": obj({
|
|
3016
|
+
reason: ENUM([
|
|
3017
|
+
"not_allowlisted",
|
|
3018
|
+
"not_locked",
|
|
3019
|
+
"ended",
|
|
3020
|
+
"unsealed",
|
|
3021
|
+
"inbox_full",
|
|
3022
|
+
"body_too_large",
|
|
3023
|
+
"body_invalid",
|
|
3024
|
+
"unattended_off"
|
|
3025
|
+
]),
|
|
3026
|
+
sender_kind: ENUM(["owner", "agent"])
|
|
3027
|
+
}),
|
|
3028
|
+
"inbox.coalesced": obj({ inbox_id: UUID, sha: S({ pattern: HEX64_PATTERN, maxLength: 64 }) }),
|
|
3029
|
+
"inbox.delivered": obj({
|
|
3030
|
+
inbox_id: UUID,
|
|
3031
|
+
sha: S({ pattern: HEX64_PATTERN, maxLength: 64 }),
|
|
3032
|
+
attempt: INT(1)
|
|
3033
|
+
}),
|
|
3034
|
+
"inbox.acked": obj({ inbox_id: UUID, sha: S({ pattern: HEX64_PATTERN, maxLength: 64 }) }),
|
|
3035
|
+
"inbox.reverted": obj({
|
|
3036
|
+
inbox_id: UUID,
|
|
3037
|
+
sha: S({ pattern: HEX64_PATTERN, maxLength: 64 }),
|
|
3038
|
+
reason: ENUM(["unconfirmed", "refused", "undeliverable"])
|
|
3039
|
+
}),
|
|
3040
|
+
"inbox.dead": obj({
|
|
3041
|
+
inbox_id: UUID,
|
|
3042
|
+
sha: S({ pattern: HEX64_PATTERN, maxLength: 64 }),
|
|
3043
|
+
reason: ENUM(["expired", "delivery_limit", "session_ended"])
|
|
3044
|
+
}),
|
|
3045
|
+
// ---- S1 amendment 61 (signed off by Wassim 2026-11-02): questions. Content-free: ids, shas, enums ----
|
|
3046
|
+
"question.asked": obj({
|
|
3047
|
+
approval_id: UUID,
|
|
3048
|
+
question_sha: S({ pattern: HEX64_PATTERN, maxLength: 64 })
|
|
3049
|
+
}),
|
|
3050
|
+
"question.answered": obj({
|
|
3051
|
+
approval_id: UUID,
|
|
3052
|
+
outcome: ENUM(["answered", "dismissed"]),
|
|
3053
|
+
via: ENUM(["coding_agent", "slack", "webhook", "mcp", "device"])
|
|
3054
|
+
})
|
|
2691
3055
|
};
|
|
2692
3056
|
function refsSchemaOf(kind) {
|
|
2693
3057
|
return KIND_REFS[kind] ?? EMPTY;
|
|
@@ -2723,10 +3087,10 @@ function validateRefs(kind, refs) {
|
|
|
2723
3087
|
}
|
|
2724
3088
|
function eventDetail(kind, refs) {
|
|
2725
3089
|
const parts = Object.keys(refs).sort().map((k) => `${k}=${refs[k] === null ? "null" : String(refs[k])}`);
|
|
2726
|
-
const
|
|
2727
|
-
if (
|
|
3090
|
+
const text2 = [kind, ...parts].join(" ");
|
|
3091
|
+
if (text2.length > EVENT_DETAIL_MAX_CHARS)
|
|
2728
3092
|
throw new RangeError(`detail over ${EVENT_DETAIL_MAX_CHARS} chars`);
|
|
2729
|
-
return
|
|
3093
|
+
return text2;
|
|
2730
3094
|
}
|
|
2731
3095
|
var EVENT_DETAIL_RE = /^[a-z_]+\.[a-z_]+( [a-z_]+=[A-Za-z0-9_.:-]+)*$/;
|
|
2732
3096
|
var idempotencyKeys = {
|
|
@@ -2760,9 +3124,9 @@ var EVENT_PREIMAGE_FIELDS = [
|
|
|
2760
3124
|
"prev_hash"
|
|
2761
3125
|
];
|
|
2762
3126
|
var TS_RE2 = /^(\d{4}-\d{2}-\d{2})[T ](\d{2}:\d{2}:\d{2})(?:\.(\d{1,6}))?(Z|[+-]00(?::?00)?)$/;
|
|
2763
|
-
function canonicalEventTs(
|
|
2764
|
-
const m = TS_RE2.exec(
|
|
2765
|
-
if (!m) throw new RangeError(`not a UTC timestamp: ${
|
|
3127
|
+
function canonicalEventTs(ts3) {
|
|
3128
|
+
const m = TS_RE2.exec(ts3);
|
|
3129
|
+
if (!m) throw new RangeError(`not a UTC timestamp: ${ts3}`);
|
|
2766
3130
|
return `${m[1]}T${m[2]}.${(m[3] ?? "").padEnd(6, "0")}Z`;
|
|
2767
3131
|
}
|
|
2768
3132
|
function stampEventTs(epochMs) {
|
|
@@ -3314,6 +3678,20 @@ function candidatePosture(entries, schemaKnown = true) {
|
|
|
3314
3678
|
const continuation = newest.origin === "task" && newest.source === "system" && newest.producer === ATTENDED_TASK_PRODUCER && !newest.inbox && entries.slice(0, -1).some(attendedHuman);
|
|
3315
3679
|
return continuation ? "attended" : "unattended";
|
|
3316
3680
|
}
|
|
3681
|
+
var sessionTaskContinuation = (e2) => e2.origin === "task" && e2.source === "system" && e2.producer === ATTENDED_TASK_PRODUCER && !e2.inbox;
|
|
3682
|
+
function inboxShaOf(entries) {
|
|
3683
|
+
const newest = entries[entries.length - 1];
|
|
3684
|
+
if (newest === void 0) return null;
|
|
3685
|
+
const own2 = (e2) => e2.inbox && typeof e2.inboxSha === "string" && TURN_HASH_RE.test(e2.inboxSha) ? e2.inboxSha : null;
|
|
3686
|
+
if (newest.inbox) return own2(newest);
|
|
3687
|
+
if (!sessionTaskContinuation(newest)) return null;
|
|
3688
|
+
for (let i = entries.length - 2; i >= 0; i--) {
|
|
3689
|
+
const e2 = entries[i];
|
|
3690
|
+
if (sessionTaskContinuation(e2)) continue;
|
|
3691
|
+
return own2(e2);
|
|
3692
|
+
}
|
|
3693
|
+
return null;
|
|
3694
|
+
}
|
|
3317
3695
|
async function chainIdOf(rootPromptId) {
|
|
3318
3696
|
if (typeof rootPromptId !== "string" || rootPromptId.length === 0)
|
|
3319
3697
|
throw new RangeError("root promptId is required");
|
|
@@ -3976,8 +4354,8 @@ function parseLaunchSpec(raw) {
|
|
|
3976
4354
|
}
|
|
3977
4355
|
function hasRemoteControl(raw) {
|
|
3978
4356
|
if (raw === null || typeof raw !== "object") return false;
|
|
3979
|
-
const
|
|
3980
|
-
return
|
|
4357
|
+
const text2 = JSON.stringify(raw).toLowerCase();
|
|
4358
|
+
return text2.includes("remote_control") || text2.includes("remote-control") || text2.includes("remotecontrol");
|
|
3981
4359
|
}
|
|
3982
4360
|
async function specHash(spec) {
|
|
3983
4361
|
return sha256Hex(canonicalJson(spec));
|
|
@@ -4206,8 +4584,8 @@ function dekWrapInput(dek) {
|
|
|
4206
4584
|
if (dek.length !== DEK_BYTES) throw new RangeError("DEK must be 32 bytes");
|
|
4207
4585
|
return base64urlEncode(dek);
|
|
4208
4586
|
}
|
|
4209
|
-
function dekFromWrapInput(
|
|
4210
|
-
const b = base64urlDecode(
|
|
4587
|
+
function dekFromWrapInput(text2) {
|
|
4588
|
+
const b = base64urlDecode(text2);
|
|
4211
4589
|
return b !== null && b.length === DEK_BYTES ? b : null;
|
|
4212
4590
|
}
|
|
4213
4591
|
function newDek(random = (n) => crypto.getRandomValues(new Uint8Array(n))) {
|
|
@@ -4235,8 +4613,8 @@ async function sealContract(dek, sessionId, charterVersion, contract, random = (
|
|
|
4235
4613
|
);
|
|
4236
4614
|
return `${ENVELOPE_VERSION}.${base64urlEncode(iv)}.${base64urlEncode(new Uint8Array(ct))}`;
|
|
4237
4615
|
}
|
|
4238
|
-
function parseEnvelope(
|
|
4239
|
-
const parts =
|
|
4616
|
+
function parseEnvelope(text2) {
|
|
4617
|
+
const parts = text2.split(".");
|
|
4240
4618
|
if (parts.length !== 3 || parts[0] !== ENVELOPE_VERSION) return null;
|
|
4241
4619
|
const iv = base64urlDecode(parts[1]);
|
|
4242
4620
|
const ct = base64urlDecode(parts[2]);
|
|
@@ -4409,10 +4787,10 @@ var CEILINGS = [
|
|
|
4409
4787
|
async function splitSealedContract(seal) {
|
|
4410
4788
|
const known = SEALED_CONTRACT_FIELDS;
|
|
4411
4789
|
if (Object.keys(seal).some((k) => !known.includes(k))) return null;
|
|
4412
|
-
const
|
|
4790
|
+
const text2 = {};
|
|
4413
4791
|
for (const k of ["statement", "requirements", "allowed_paths", "forbidden_paths", "goal_id", "work_card", "shape"])
|
|
4414
|
-
if (seal[k] !== void 0)
|
|
4415
|
-
const contract = parseContract(
|
|
4792
|
+
if (seal[k] !== void 0) text2[k] = seal[k];
|
|
4793
|
+
const contract = parseContract(text2);
|
|
4416
4794
|
if (contract === null) return null;
|
|
4417
4795
|
const commitments = {
|
|
4418
4796
|
statement_hash: await statementHash(contract.statement),
|
|
@@ -4488,6 +4866,22 @@ var ROUTES = Object.freeze({
|
|
|
4488
4866
|
exec_ready_list: fixed("GET", "executor_key", "/v1/executor/ready"),
|
|
4489
4867
|
/** Body {oidc_token}; answers a one-lease org-scope executor key or an OIDC_EXCHANGE_REFUSALS refusal. */
|
|
4490
4868
|
exec_oidc_exchange: fixed("POST", "github_oidc", "/v1/executor/oidc/exchange"),
|
|
4869
|
+
// ---- inbox, executor side (S1 amendment 60) ----
|
|
4870
|
+
/** Content-free summary {admitted, delivered, oldest_admitted_at} (inboxSummaryResponseOk); marks nothing. */
|
|
4871
|
+
exec_inbox: scoped("GET", "executor_key", EXEC_SESSION_PRE, "/inbox"),
|
|
4872
|
+
/** Body {epoch, nonce, limit?}: marks up to limit messages delivered at the live epoch, journals inbox.delivered, answers their delivery text. */
|
|
4873
|
+
exec_inbox_take: scoped("POST", "executor_key", EXEC_SESSION_PRE, "/inbox/take"),
|
|
4874
|
+
/** Body {epoch, nonce, inbox_id, sha}: acks a message delivered at this epoch, journals inbox.acked. */
|
|
4875
|
+
exec_inbox_ack: scoped("POST", "executor_key", EXEC_SESSION_PRE, "/inbox/ack"),
|
|
4876
|
+
/** Body {epoch, nonce, inbox_id, sha, reason}: hands a delivered message back undone (admitted again, or dead at the limit), journals inbox.reverted. */
|
|
4877
|
+
exec_inbox_release: scoped("POST", "executor_key", EXEC_SESSION_PRE, "/inbox/release"),
|
|
4878
|
+
// ---- questions, executor side (S1 amendment 61) ----
|
|
4879
|
+
/** Body {epoch, nonce, tool_use_id, questions}: opens the session's question approval (or returns it when the open one has this question_sha), journals question.asked. */
|
|
4880
|
+
exec_question: scoped("POST", "executor_key", EXEC_SESSION_PRE, "/questions"),
|
|
4881
|
+
/** Body {epoch, nonce, approval_id}: the question's state; an answer is handed over once (marked taken). */
|
|
4882
|
+
exec_question_poll: scoped("POST", "executor_key", EXEC_SESSION_PRE, "/questions/poll"),
|
|
4883
|
+
/** Body {epoch, nonce, approval_id}: the seat stopped waiting; the answer (now or later) goes to the inbox. */
|
|
4884
|
+
exec_question_release: scoped("POST", "executor_key", EXEC_SESSION_PRE, "/questions/release"),
|
|
4491
4885
|
// ---- owner session verbs (ruling 33.22) ----
|
|
4492
4886
|
own_lock: scoped("POST", "owner", OWNER_SESSION_PRE, "/lock"),
|
|
4493
4887
|
own_unlock: scoped("POST", "owner", OWNER_SESSION_PRE, "/unlock"),
|
|
@@ -4498,6 +4892,22 @@ var ROUTES = Object.freeze({
|
|
|
4498
4892
|
own_amend: scoped("POST", "owner", OWNER_SESSION_PRE, "/amend"),
|
|
4499
4893
|
own_fail: scoped("POST", "owner", OWNER_SESSION_PRE, "/fail"),
|
|
4500
4894
|
own_events: scoped("GET", "owner", OWNER_SESSION_PRE, "/events"),
|
|
4895
|
+
// ---- inbox, owner side (S1 amendment 60) ----
|
|
4896
|
+
/** Body {text, idempotency_key} (inboxSendBodyOk); answer INBOX_SEND_RESPONSE or an INBOX_REJECT_CODES refusal. */
|
|
4897
|
+
own_inbox_send: scoped("POST", "inbox_sender", OWNER_SESSION_PRE, "/inbox"),
|
|
4898
|
+
/** {messages: [INBOX_LIST_ITEM, ...]}, newest first, content-free. */
|
|
4899
|
+
own_inbox_list: scoped("GET", "owner", OWNER_SESSION_PRE, "/inbox"),
|
|
4900
|
+
/** {recipient_agent_id, senders: [INBOX_SENDER_ITEM, ...]}: the session's agent's live allowlist. */
|
|
4901
|
+
own_inbox_senders: scoped("GET", "owner", OWNER_SESSION_PRE, "/inbox/senders"),
|
|
4902
|
+
/** Body {agent_id, label?}: allowlists one of the owner's own agents in the same org. */
|
|
4903
|
+
own_inbox_sender_add: scoped("POST", "owner", OWNER_SESSION_PRE, "/inbox/senders"),
|
|
4904
|
+
/** Body {agent_id}: revokes it (the row keeps revoked_at and revoked_by). */
|
|
4905
|
+
own_inbox_sender_remove: scoped("DELETE", "owner", OWNER_SESSION_PRE, "/inbox/senders"),
|
|
4906
|
+
// ---- questions, owner side (S1 amendment 61) ----
|
|
4907
|
+
/** {questions: [QUESTION_LIST_ITEM, ...]}, newest first; the owner reads the question text. */
|
|
4908
|
+
own_questions: scoped("GET", "owner", OWNER_SESSION_PRE, "/questions"),
|
|
4909
|
+
/** Body {approval_id, via, answers | dismiss: true}: answers or dismisses, journals question.answered. */
|
|
4910
|
+
own_answer: scoped("POST", "owner", OWNER_SESSION_PRE, "/questions/answer"),
|
|
4501
4911
|
// ---- gateway internal ----
|
|
4502
4912
|
int_events: fixed("POST", "internal", GATEWAY_EVENTS_ROUTE),
|
|
4503
4913
|
int_arm: fixed("GET", "internal", ARM_ROUTE),
|
|
@@ -4624,6 +5034,399 @@ function gatewayEventsBodyOk(v) {
|
|
|
4624
5034
|
return validateRefs(kind, v.refs ?? {});
|
|
4625
5035
|
}
|
|
4626
5036
|
|
|
5037
|
+
// ../shared/durable-contract/src/inbox.ts
|
|
5038
|
+
var INBOX_BODY_MAX_BYTES = 16384;
|
|
5039
|
+
var INBOX_TTL_S = 7 * 24 * 60 * 60;
|
|
5040
|
+
var INBOX_DELIVERY_LIMIT = 5;
|
|
5041
|
+
var INBOX_TAKE_LIMIT_MAX = 8;
|
|
5042
|
+
var INBOX_LIST_LIMIT = 100;
|
|
5043
|
+
var INBOX_SENDERS_MAX = 32;
|
|
5044
|
+
var INBOX_OPEN_CAP = INBOX_OPEN_MAX;
|
|
5045
|
+
var INBOX_REOFFER_S = 15 * 60;
|
|
5046
|
+
var INBOX_IDEMPOTENCY_KEY_RE = /^[A-Za-z0-9_.:-]{1,200}$/;
|
|
5047
|
+
var INBOX_AGENT_ID_RE = /^[A-Za-z0-9_-]{1,64}$/;
|
|
5048
|
+
var INBOX_SENDER_LABEL_RE = /^[ -Z\\^-~]{1,128}$/;
|
|
5049
|
+
var INBOX_STATUSES = ["admitted", "delivered", "acked", "dead"];
|
|
5050
|
+
var INBOX_SENDER_KINDS = ["owner", "agent"];
|
|
5051
|
+
var INBOX_REJECT_REASONS = [
|
|
5052
|
+
"not_allowlisted",
|
|
5053
|
+
"not_locked",
|
|
5054
|
+
"ended",
|
|
5055
|
+
"unsealed",
|
|
5056
|
+
"inbox_full",
|
|
5057
|
+
"body_too_large",
|
|
5058
|
+
"body_invalid",
|
|
5059
|
+
"unattended_off"
|
|
5060
|
+
];
|
|
5061
|
+
var INBOX_DEAD_REASONS = ["expired", "delivery_limit", "session_ended"];
|
|
5062
|
+
var INBOX_RELEASE_REASONS = ["unconfirmed", "refused", "undeliverable"];
|
|
5063
|
+
var INBOX_SENDER_INVALID_REASONS = [
|
|
5064
|
+
"sender",
|
|
5065
|
+
"on_behalf_of",
|
|
5066
|
+
"agent_id",
|
|
5067
|
+
"label",
|
|
5068
|
+
"self",
|
|
5069
|
+
"not_found",
|
|
5070
|
+
"other_org",
|
|
5071
|
+
"not_owned",
|
|
5072
|
+
"too_many"
|
|
5073
|
+
];
|
|
5074
|
+
var INBOX_REJECT_CODES = Object.freeze({
|
|
5075
|
+
not_allowlisted: { code: "durable_inbox_not_allowlisted", status: 403 },
|
|
5076
|
+
not_locked: { code: "durable_inbox_closed", status: 409 },
|
|
5077
|
+
ended: { code: "durable_inbox_closed", status: 409 },
|
|
5078
|
+
unsealed: { code: "durable_inbox_closed", status: 409 },
|
|
5079
|
+
inbox_full: { code: "durable_inbox_full", status: 429 },
|
|
5080
|
+
body_too_large: { code: "durable_inbox_body_invalid", status: 422 },
|
|
5081
|
+
body_invalid: { code: "durable_inbox_body_invalid", status: 422 },
|
|
5082
|
+
unattended_off: { code: "durable_inbox_closed", status: 409 }
|
|
5083
|
+
});
|
|
5084
|
+
var A60_EMITTED_KINDS = [
|
|
5085
|
+
"inbox.admitted",
|
|
5086
|
+
"inbox.rejected",
|
|
5087
|
+
"inbox.coalesced",
|
|
5088
|
+
"inbox.delivered",
|
|
5089
|
+
"inbox.acked",
|
|
5090
|
+
"inbox.reverted",
|
|
5091
|
+
"inbox.dead"
|
|
5092
|
+
];
|
|
5093
|
+
function inboxShaPreimage(m) {
|
|
5094
|
+
return canonicalJson({
|
|
5095
|
+
v: 1,
|
|
5096
|
+
session_id: m.session_id,
|
|
5097
|
+
sender_kind: m.sender_kind,
|
|
5098
|
+
sender_agent_id: m.sender_agent_id ?? null,
|
|
5099
|
+
on_behalf_of: m.on_behalf_of ?? null,
|
|
5100
|
+
in_reply_to: m.in_reply_to ?? null,
|
|
5101
|
+
body: m.body
|
|
5102
|
+
});
|
|
5103
|
+
}
|
|
5104
|
+
async function inboxSha(m) {
|
|
5105
|
+
return sha256Hex(inboxShaPreimage(m));
|
|
5106
|
+
}
|
|
5107
|
+
var INBOX_BODY_CONTROL_RE = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f-\u009f]/;
|
|
5108
|
+
function inboxBodyOk(body) {
|
|
5109
|
+
if (typeof body !== "string" || body.length === 0 || INBOX_BODY_CONTROL_RE.test(body))
|
|
5110
|
+
return false;
|
|
5111
|
+
return utf8(body).length <= INBOX_BODY_MAX_BYTES;
|
|
5112
|
+
}
|
|
5113
|
+
var INBOX_MARKER_RE = /^\[mnemom inbox ([0-9a-f]{64})\]/;
|
|
5114
|
+
function inboxDeliveryText(m) {
|
|
5115
|
+
if (!HEX64_RE.test(m.sha)) throw new RangeError("inbox sha must be 64 lowercase hex");
|
|
5116
|
+
let who = "the owner";
|
|
5117
|
+
if (m.sender_kind === "agent") {
|
|
5118
|
+
const label = m.sender_label ?? "";
|
|
5119
|
+
if (!INBOX_SENDER_LABEL_RE.test(label)) throw new RangeError("inbox sender label invalid");
|
|
5120
|
+
who = `agent ${label} on behalf of the owner`;
|
|
5121
|
+
}
|
|
5122
|
+
if (m.in_reply_to !== null && !UUID_RE.test(m.in_reply_to))
|
|
5123
|
+
throw new RangeError("in_reply_to must be a lowercase uuid");
|
|
5124
|
+
const reply = m.in_reply_to === null ? "" : ` (answer to question ${m.in_reply_to})`;
|
|
5125
|
+
return `[mnemom inbox ${m.sha}] from ${who}${reply}
|
|
5126
|
+
|
|
5127
|
+
${m.body}`;
|
|
5128
|
+
}
|
|
5129
|
+
function inboxMarkerOf(text2) {
|
|
5130
|
+
const nl = text2.indexOf("\n");
|
|
5131
|
+
return INBOX_MARKER_RE.exec(nl < 0 ? text2 : text2.slice(0, nl))?.[1] ?? null;
|
|
5132
|
+
}
|
|
5133
|
+
var isObj2 = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
5134
|
+
var keysExactly2 = (o, keys) => Object.keys(o).length === keys.length && keys.every((k) => k in o);
|
|
5135
|
+
var keysWithin = (o, required, optional) => required.every((k) => k in o) && Object.keys(o).every((k) => required.includes(k) || optional.includes(k));
|
|
5136
|
+
var str = (v, re) => typeof v === "string" && re.test(v);
|
|
5137
|
+
var uuid2 = (v, nullable = false) => fieldOk({ type: "uuid", nullable }, v);
|
|
5138
|
+
var ts = (v, nullable = false) => fieldOk({ type: "timestamp", nullable }, v);
|
|
5139
|
+
var int = (v, min = 0) => Number.isSafeInteger(v) && v >= min;
|
|
5140
|
+
var oneOf = (v, values) => typeof v === "string" && values.includes(v);
|
|
5141
|
+
var agentId = (v) => str(v, INBOX_AGENT_ID_RE);
|
|
5142
|
+
var nonEmpty2 = (v) => typeof v === "string" && v.length > 0;
|
|
5143
|
+
var INBOX_SEND_BODY_KEYS = ["text", "idempotency_key"];
|
|
5144
|
+
function inboxSendBodyOk(v) {
|
|
5145
|
+
return isObj2(v) && keysExactly2(v, INBOX_SEND_BODY_KEYS) && inboxBodyOk(v.text) && str(v.idempotency_key, INBOX_IDEMPOTENCY_KEY_RE);
|
|
5146
|
+
}
|
|
5147
|
+
var INBOX_SEND_RESPONSE = Object.freeze({
|
|
5148
|
+
inbox_id: "uuid",
|
|
5149
|
+
sha: "hex64",
|
|
5150
|
+
status: "inbox_status",
|
|
5151
|
+
coalesced: "boolean",
|
|
5152
|
+
deduped: "boolean",
|
|
5153
|
+
sender_kind: "inbox_sender_kind",
|
|
5154
|
+
sender_agent_id: "agent_id|null",
|
|
5155
|
+
on_behalf_of: "string|null",
|
|
5156
|
+
expires_at: "timestamp"
|
|
5157
|
+
});
|
|
5158
|
+
var senderOk = (v) => oneOf(v.sender_kind, INBOX_SENDER_KINDS) && (v.sender_kind === "owner" ? v.sender_agent_id === null && v.on_behalf_of === null : agentId(v.sender_agent_id) && nonEmpty2(v.on_behalf_of));
|
|
5159
|
+
function inboxSendResponseOk(v) {
|
|
5160
|
+
return isObj2(v) && keysExactly2(v, Object.keys(INBOX_SEND_RESPONSE)) && uuid2(v.inbox_id) && str(v.sha, HEX64_RE) && oneOf(v.status, INBOX_STATUSES) && typeof v.coalesced === "boolean" && typeof v.deduped === "boolean" && senderOk(v) && ts(v.expires_at);
|
|
5161
|
+
}
|
|
5162
|
+
var INBOX_LIST_ITEM = Object.freeze({
|
|
5163
|
+
inbox_id: "uuid",
|
|
5164
|
+
sha: "hex64",
|
|
5165
|
+
status: "inbox_status",
|
|
5166
|
+
sender_kind: "inbox_sender_kind",
|
|
5167
|
+
sender_agent_id: "agent_id|null",
|
|
5168
|
+
on_behalf_of: "string|null",
|
|
5169
|
+
in_reply_to: "uuid|null",
|
|
5170
|
+
body_bytes: "integer>=1",
|
|
5171
|
+
delivery_count: "integer",
|
|
5172
|
+
dead_reason: "inbox_dead_reason|null",
|
|
5173
|
+
created_at: "timestamp",
|
|
5174
|
+
delivered_at: "timestamp|null",
|
|
5175
|
+
acked_at: "timestamp|null",
|
|
5176
|
+
expires_at: "timestamp"
|
|
5177
|
+
});
|
|
5178
|
+
function inboxListItemOk(v) {
|
|
5179
|
+
return isObj2(v) && keysExactly2(v, Object.keys(INBOX_LIST_ITEM)) && uuid2(v.inbox_id) && str(v.sha, HEX64_RE) && oneOf(v.status, INBOX_STATUSES) && senderOk(v) && uuid2(v.in_reply_to, true) && int(v.body_bytes, 1) && v.body_bytes <= INBOX_BODY_MAX_BYTES && int(v.delivery_count) && (v.status === "dead" ? oneOf(v.dead_reason, INBOX_DEAD_REASONS) : v.dead_reason === null) && ts(v.created_at) && ts(v.delivered_at, true) && ts(v.acked_at, true) && ts(v.expires_at);
|
|
5180
|
+
}
|
|
5181
|
+
function inboxListResponseOk(v) {
|
|
5182
|
+
return isObj2(v) && keysExactly2(v, ["messages"]) && Array.isArray(v.messages) && v.messages.length <= INBOX_LIST_LIMIT && v.messages.every(inboxListItemOk);
|
|
5183
|
+
}
|
|
5184
|
+
var INBOX_SENDER_ADD_BODY_KEYS = ["agent_id", "label"];
|
|
5185
|
+
function inboxSenderAddBodyOk(v) {
|
|
5186
|
+
return isObj2(v) && keysWithin(v, ["agent_id"], ["label"]) && str(v.agent_id, INBOX_AGENT_ID_RE) && (!("label" in v) || str(v.label, INBOX_SENDER_LABEL_RE));
|
|
5187
|
+
}
|
|
5188
|
+
var INBOX_SENDER_REMOVE_BODY_KEYS = ["agent_id"];
|
|
5189
|
+
function inboxSenderRemoveBodyOk(v) {
|
|
5190
|
+
return isObj2(v) && keysExactly2(v, INBOX_SENDER_REMOVE_BODY_KEYS) && str(v.agent_id, INBOX_AGENT_ID_RE);
|
|
5191
|
+
}
|
|
5192
|
+
var INBOX_SENDER_ITEM = Object.freeze({
|
|
5193
|
+
sender_agent_id: "agent_id",
|
|
5194
|
+
label: "label|null",
|
|
5195
|
+
added_by: "string|null",
|
|
5196
|
+
created_at: "timestamp"
|
|
5197
|
+
});
|
|
5198
|
+
function inboxSenderItemOk(v) {
|
|
5199
|
+
return isObj2(v) && keysExactly2(v, Object.keys(INBOX_SENDER_ITEM)) && agentId(v.sender_agent_id) && (v.label === null || str(v.label, INBOX_SENDER_LABEL_RE)) && (v.added_by === null || nonEmpty2(v.added_by)) && ts(v.created_at);
|
|
5200
|
+
}
|
|
5201
|
+
function inboxSendersResponseOk(v) {
|
|
5202
|
+
return isObj2(v) && keysExactly2(v, ["recipient_agent_id", "senders"]) && agentId(v.recipient_agent_id) && Array.isArray(v.senders) && v.senders.length <= INBOX_SENDERS_MAX && v.senders.every(inboxSenderItemOk);
|
|
5203
|
+
}
|
|
5204
|
+
function inboxSenderChangeResponseOk(v) {
|
|
5205
|
+
return isObj2(v) && keysExactly2(v, ["recipient_agent_id", "sender_agent_id", "changed"]) && agentId(v.recipient_agent_id) && agentId(v.sender_agent_id) && v.recipient_agent_id !== v.sender_agent_id && typeof v.changed === "boolean";
|
|
5206
|
+
}
|
|
5207
|
+
function inboxSummaryResponseOk(v) {
|
|
5208
|
+
return isObj2(v) && keysExactly2(v, ["admitted", "delivered", "oldest_admitted_at"]) && int(v.admitted) && int(v.delivered) && (v.admitted === 0 ? v.oldest_admitted_at === null : ts(v.oldest_admitted_at));
|
|
5209
|
+
}
|
|
5210
|
+
var INBOX_TAKE_BODY_KEYS = ["epoch", "nonce", "limit"];
|
|
5211
|
+
function inboxTakeBodyOk(v) {
|
|
5212
|
+
return isObj2(v) && keysWithin(v, ["epoch", "nonce"], ["limit"]) && int(v.epoch) && nonEmpty2(v.nonce) && (!("limit" in v) || int(v.limit, 1) && v.limit <= INBOX_TAKE_LIMIT_MAX);
|
|
5213
|
+
}
|
|
5214
|
+
var INBOX_TAKE_ITEM = Object.freeze({
|
|
5215
|
+
inbox_id: "uuid",
|
|
5216
|
+
sha: "hex64",
|
|
5217
|
+
text: "string",
|
|
5218
|
+
attempt: "integer>=1",
|
|
5219
|
+
sender_kind: "inbox_sender_kind",
|
|
5220
|
+
sender_agent_id: "agent_id|null",
|
|
5221
|
+
on_behalf_of: "string|null",
|
|
5222
|
+
in_reply_to: "uuid|null",
|
|
5223
|
+
created_at: "timestamp"
|
|
5224
|
+
});
|
|
5225
|
+
function inboxTakeItemOk(v) {
|
|
5226
|
+
return isObj2(v) && keysExactly2(v, Object.keys(INBOX_TAKE_ITEM)) && uuid2(v.inbox_id) && str(v.sha, HEX64_RE) && typeof v.text === "string" && inboxMarkerOf(v.text) === v.sha && int(v.attempt, 1) && v.attempt <= INBOX_DELIVERY_LIMIT && senderOk(v) && uuid2(v.in_reply_to, true) && ts(v.created_at);
|
|
5227
|
+
}
|
|
5228
|
+
function inboxTakeResponseOk(v) {
|
|
5229
|
+
return isObj2(v) && keysExactly2(v, ["messages"]) && Array.isArray(v.messages) && v.messages.length <= INBOX_TAKE_LIMIT_MAX && v.messages.every(inboxTakeItemOk);
|
|
5230
|
+
}
|
|
5231
|
+
var INBOX_ACK_BODY_KEYS = ["epoch", "nonce", "inbox_id", "sha"];
|
|
5232
|
+
function inboxAckBodyOk(v) {
|
|
5233
|
+
return isObj2(v) && keysExactly2(v, INBOX_ACK_BODY_KEYS) && int(v.epoch) && nonEmpty2(v.nonce) && uuid2(v.inbox_id) && str(v.sha, HEX64_RE);
|
|
5234
|
+
}
|
|
5235
|
+
function inboxAckResponseOk(v) {
|
|
5236
|
+
return isObj2(v) && keysExactly2(v, ["inbox_id", "sha", "status", "deduped"]) && uuid2(v.inbox_id) && str(v.sha, HEX64_RE) && v.status === "acked" && typeof v.deduped === "boolean";
|
|
5237
|
+
}
|
|
5238
|
+
var INBOX_RELEASE_BODY_KEYS = ["epoch", "nonce", "inbox_id", "sha", "reason"];
|
|
5239
|
+
function inboxReleaseBodyOk(v) {
|
|
5240
|
+
return isObj2(v) && keysExactly2(v, INBOX_RELEASE_BODY_KEYS) && int(v.epoch) && nonEmpty2(v.nonce) && uuid2(v.inbox_id) && str(v.sha, HEX64_RE) && oneOf(v.reason, INBOX_RELEASE_REASONS);
|
|
5241
|
+
}
|
|
5242
|
+
function inboxReleaseResponseOk(v) {
|
|
5243
|
+
return isObj2(v) && keysExactly2(v, ["inbox_id", "sha", "status"]) && uuid2(v.inbox_id) && str(v.sha, HEX64_RE) && (v.status === "admitted" || v.status === "dead");
|
|
5244
|
+
}
|
|
5245
|
+
var inboxIdempotencyKeys = {
|
|
5246
|
+
admitted: (inboxId) => `inbox:${inboxId}:admitted`,
|
|
5247
|
+
coalesced: (inboxId, idempotencyKey) => `inbox:${inboxId}:coalesced:${idempotencyKey}`,
|
|
5248
|
+
/**
|
|
5249
|
+
* A refused send: keyed on the caller's idempotency_key when it is well-formed, else on the api's
|
|
5250
|
+
* own request id (a body_invalid refusal may carry no usable key).
|
|
5251
|
+
*/
|
|
5252
|
+
rejected: (sessionId, idempotencyKey, requestId) => typeof idempotencyKey === "string" && INBOX_IDEMPOTENCY_KEY_RE.test(idempotencyKey) ? `inbox:${sessionId}:rejected:${idempotencyKey}` : `inbox:${sessionId}:rejected:request:${requestId}`,
|
|
5253
|
+
delivered: (inboxId, epoch, attempt) => `inbox:${inboxId}:delivered:${epoch}:${attempt}`,
|
|
5254
|
+
acked: (inboxId) => `inbox:${inboxId}:acked`,
|
|
5255
|
+
reverted: (inboxId, epoch, attempt) => `inbox:${inboxId}:reverted:${epoch}:${attempt}`,
|
|
5256
|
+
dead: (inboxId) => `inbox:${inboxId}:dead`
|
|
5257
|
+
};
|
|
5258
|
+
|
|
5259
|
+
// ../shared/durable-contract/src/question.ts
|
|
5260
|
+
var QUESTION_MAX_QUESTIONS = 4;
|
|
5261
|
+
var QUESTION_MIN_OPTIONS = 2;
|
|
5262
|
+
var QUESTION_MAX_OPTIONS = 4;
|
|
5263
|
+
var QUESTION_TEXT_MAX_BYTES = 2048;
|
|
5264
|
+
var QUESTION_HEADER_MAX_BYTES = 64;
|
|
5265
|
+
var QUESTION_LABEL_MAX_BYTES = 256;
|
|
5266
|
+
var QUESTION_DESCRIPTION_MAX_BYTES = 2048;
|
|
5267
|
+
var QUESTION_ANSWER_MAX_BYTES = 4096;
|
|
5268
|
+
var QUESTION_BODY_MAX_BYTES = 16384;
|
|
5269
|
+
var QUESTION_APPROVAL_TTL_S = 24 * 60 * 60;
|
|
5270
|
+
var QUESTION_LIST_LIMIT = 20;
|
|
5271
|
+
var QUESTION_TOOL_USE_ID_RE = /^[A-Za-z0-9_-]{1,128}$/;
|
|
5272
|
+
var QUESTION_RECOMMENDED_SUFFIX = "(Recommended)";
|
|
5273
|
+
var QUESTION_ANSWER_VIAS = ["coding_agent", "slack", "webhook", "mcp", "device"];
|
|
5274
|
+
var QUESTION_OUTCOMES = ["answered", "dismissed"];
|
|
5275
|
+
var QUESTION_STATES = ["open", "answered", "dismissed", "expired", "handed_off"];
|
|
5276
|
+
var A61_EMITTED_KINDS = ["question.asked", "question.answered"];
|
|
5277
|
+
var QUESTION_HANDOFF_REASON = "This question is now with your owner. End your turn now without guessing; the owner's answer will arrive as your next message.";
|
|
5278
|
+
var QUESTION_DISMISSED_REASON = "Your owner dismissed this question without answering. Decide without it, or ask differently.";
|
|
5279
|
+
var isObj3 = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
5280
|
+
var keysExactly3 = (o, keys) => Object.keys(o).length === keys.length && keys.every((k) => k in o);
|
|
5281
|
+
var keysWithin2 = (o, required, optional) => required.every((k) => k in o) && Object.keys(o).every((k) => required.includes(k) || optional.includes(k));
|
|
5282
|
+
var text = (v, min, max) => typeof v === "string" && !v.includes("\0") && utf8(v).length >= min && utf8(v).length <= max;
|
|
5283
|
+
var uuid3 = (v, nullable = false) => fieldOk({ type: "uuid", nullable }, v);
|
|
5284
|
+
var ts2 = (v, nullable = false) => fieldOk({ type: "timestamp", nullable }, v);
|
|
5285
|
+
var int2 = (v, min = 0) => Number.isSafeInteger(v) && v >= min;
|
|
5286
|
+
var nonEmpty3 = (v) => typeof v === "string" && v.length > 0;
|
|
5287
|
+
var oneOf2 = (v, values) => typeof v === "string" && values.includes(v);
|
|
5288
|
+
function optionOk(v) {
|
|
5289
|
+
return isObj3(v) && keysExactly3(v, ["label", "description"]) && text(v.label, 1, QUESTION_LABEL_MAX_BYTES) && text(v.description, 0, QUESTION_DESCRIPTION_MAX_BYTES);
|
|
5290
|
+
}
|
|
5291
|
+
function questionItemOk(v) {
|
|
5292
|
+
if (!isObj3(v) || !keysExactly3(v, ["question", "header", "options", "multiSelect"]) || !text(v.question, 1, QUESTION_TEXT_MAX_BYTES) || !text(v.header, 1, QUESTION_HEADER_MAX_BYTES) || typeof v.multiSelect !== "boolean" || !Array.isArray(v.options) || v.options.length < QUESTION_MIN_OPTIONS || v.options.length > QUESTION_MAX_OPTIONS || !v.options.every(optionOk))
|
|
5293
|
+
return false;
|
|
5294
|
+
const labels = v.options.map((o) => o.label);
|
|
5295
|
+
return new Set(labels).size === labels.length;
|
|
5296
|
+
}
|
|
5297
|
+
function questionsOk(v) {
|
|
5298
|
+
if (!Array.isArray(v) || v.length < 1 || v.length > QUESTION_MAX_QUESTIONS) return false;
|
|
5299
|
+
if (!v.every(questionItemOk)) return false;
|
|
5300
|
+
const texts = v.map((q) => q.question);
|
|
5301
|
+
if (new Set(texts).size !== texts.length) return false;
|
|
5302
|
+
return utf8(canonicalJson(v)).length <= QUESTION_BODY_MAX_BYTES;
|
|
5303
|
+
}
|
|
5304
|
+
function normalizeQuestions(v) {
|
|
5305
|
+
if (!Array.isArray(v)) return null;
|
|
5306
|
+
const out = v.map((q) => {
|
|
5307
|
+
const r = isObj3(q) ? q : {};
|
|
5308
|
+
const opts = Array.isArray(r.options) ? r.options : [];
|
|
5309
|
+
return {
|
|
5310
|
+
question: r.question,
|
|
5311
|
+
header: r.header,
|
|
5312
|
+
options: opts.map((o) => {
|
|
5313
|
+
const x = isObj3(o) ? o : {};
|
|
5314
|
+
return { label: x.label, description: x.description ?? "" };
|
|
5315
|
+
}),
|
|
5316
|
+
multiSelect: r.multiSelect ?? false
|
|
5317
|
+
};
|
|
5318
|
+
});
|
|
5319
|
+
return questionsOk(out) ? out : null;
|
|
5320
|
+
}
|
|
5321
|
+
function recommendedOption(q) {
|
|
5322
|
+
const i = q.options.findIndex((o) => o.label.trimEnd().endsWith(QUESTION_RECOMMENDED_SUFFIX));
|
|
5323
|
+
return i < 0 ? null : i;
|
|
5324
|
+
}
|
|
5325
|
+
function questionShaPreimage(m) {
|
|
5326
|
+
return canonicalJson({
|
|
5327
|
+
v: 1,
|
|
5328
|
+
session_id: m.session_id,
|
|
5329
|
+
tool_use_id: m.tool_use_id,
|
|
5330
|
+
questions: m.questions
|
|
5331
|
+
});
|
|
5332
|
+
}
|
|
5333
|
+
async function questionSha(m) {
|
|
5334
|
+
return sha256Hex(questionShaPreimage(m));
|
|
5335
|
+
}
|
|
5336
|
+
function answersOk(answers, questions) {
|
|
5337
|
+
return isObj3(answers) && keysExactly3(
|
|
5338
|
+
answers,
|
|
5339
|
+
questions.map((q) => q.question)
|
|
5340
|
+
) && Object.values(answers).every((a) => text(a, 1, QUESTION_ANSWER_MAX_BYTES));
|
|
5341
|
+
}
|
|
5342
|
+
function answersShapeOk(answers) {
|
|
5343
|
+
return isObj3(answers) && Object.keys(answers).length >= 1 && Object.keys(answers).length <= QUESTION_MAX_QUESTIONS && Object.keys(answers).every((k) => text(k, 1, QUESTION_TEXT_MAX_BYTES)) && Object.values(answers).every((a) => text(a, 1, QUESTION_ANSWER_MAX_BYTES));
|
|
5344
|
+
}
|
|
5345
|
+
function answerFromChoice(q, choice) {
|
|
5346
|
+
const c = choice.trim();
|
|
5347
|
+
const byNumber = (s) => {
|
|
5348
|
+
if (!/^[1-9][0-9]*$/.test(s)) return null;
|
|
5349
|
+
const o = q.options[Number(s) - 1];
|
|
5350
|
+
return o ? o.label : null;
|
|
5351
|
+
};
|
|
5352
|
+
const parts = q.multiSelect ? c.split(",").map((p) => p.trim()) : [c];
|
|
5353
|
+
if (parts.length > 0 && parts.every((p) => byNumber(p) !== null))
|
|
5354
|
+
return parts.map((p) => byNumber(p)).join(", ");
|
|
5355
|
+
const norm = (s) => s.trim().replace(QUESTION_RECOMMENDED_SUFFIX, "").trim().toLowerCase();
|
|
5356
|
+
const hit = q.options.find((o) => norm(o.label) === norm(c));
|
|
5357
|
+
return hit ? hit.label : c;
|
|
5358
|
+
}
|
|
5359
|
+
function questionAnswerInboxBody(questions, answers) {
|
|
5360
|
+
const lines = ["Your owner answered your question:"];
|
|
5361
|
+
for (const q of questions) {
|
|
5362
|
+
lines.push("", `Q: ${q.question}`, `A: ${answers[q.question] ?? ""}`);
|
|
5363
|
+
}
|
|
5364
|
+
return lines.join("\n");
|
|
5365
|
+
}
|
|
5366
|
+
var QUESTION_ASK_BODY_KEYS = ["epoch", "nonce", "tool_use_id", "questions"];
|
|
5367
|
+
function questionAskBodyOk(v) {
|
|
5368
|
+
return isObj3(v) && keysExactly3(v, QUESTION_ASK_BODY_KEYS) && int2(v.epoch) && nonEmpty3(v.nonce) && typeof v.tool_use_id === "string" && QUESTION_TOOL_USE_ID_RE.test(v.tool_use_id) && questionsOk(v.questions);
|
|
5369
|
+
}
|
|
5370
|
+
function questionAskResponseOk(v) {
|
|
5371
|
+
return isObj3(v) && keysExactly3(v, ["approval_id", "question_sha", "created", "expires_at"]) && uuid3(v.approval_id) && typeof v.question_sha === "string" && HEX64_RE.test(v.question_sha) && typeof v.created === "boolean" && ts2(v.expires_at);
|
|
5372
|
+
}
|
|
5373
|
+
async function questionAskMatches(answer, ask) {
|
|
5374
|
+
return answer.question_sha === await questionSha(ask);
|
|
5375
|
+
}
|
|
5376
|
+
var QUESTION_POLL_BODY_KEYS = ["epoch", "nonce", "approval_id"];
|
|
5377
|
+
function questionPollBodyOk(v) {
|
|
5378
|
+
return isObj3(v) && keysExactly3(v, QUESTION_POLL_BODY_KEYS) && int2(v.epoch) && nonEmpty3(v.nonce) && uuid3(v.approval_id);
|
|
5379
|
+
}
|
|
5380
|
+
function questionPollResponseOk(v) {
|
|
5381
|
+
return isObj3(v) && keysExactly3(v, ["approval_id", "state", "answers"]) && uuid3(v.approval_id) && oneOf2(v.state, QUESTION_STATES) && (v.state === "answered" ? answersShapeOk(v.answers) : v.answers === null);
|
|
5382
|
+
}
|
|
5383
|
+
function questionReleaseResponseOk(v) {
|
|
5384
|
+
return isObj3(v) && keysExactly3(v, ["approval_id", "state", "inbox_id"]) && uuid3(v.approval_id) && oneOf2(v.state, QUESTION_STATES) && uuid3(v.inbox_id, true);
|
|
5385
|
+
}
|
|
5386
|
+
var QUESTION_LIST_ITEM = Object.freeze({
|
|
5387
|
+
approval_id: "uuid",
|
|
5388
|
+
state: "question_state",
|
|
5389
|
+
questions: "questions",
|
|
5390
|
+
recommended: "(integer|null)[]",
|
|
5391
|
+
answers: "answers|null",
|
|
5392
|
+
answered_via: "question_answer_via|null",
|
|
5393
|
+
created_at: "timestamp",
|
|
5394
|
+
expires_at: "timestamp",
|
|
5395
|
+
answered_at: "timestamp|null"
|
|
5396
|
+
});
|
|
5397
|
+
function questionListItemOk(v) {
|
|
5398
|
+
if (!isObj3(v) || !keysExactly3(v, Object.keys(QUESTION_LIST_ITEM))) return false;
|
|
5399
|
+
if (!uuid3(v.approval_id) || !oneOf2(v.state, QUESTION_STATES) || !questionsOk(v.questions))
|
|
5400
|
+
return false;
|
|
5401
|
+
const qs = v.questions;
|
|
5402
|
+
if (!Array.isArray(v.recommended) || v.recommended.length !== qs.length || !v.recommended.every((r, i) => r === recommendedOption(qs[i])))
|
|
5403
|
+
return false;
|
|
5404
|
+
const answered = v.answers !== null;
|
|
5405
|
+
if (answered && !answersOk(v.answers, qs)) return false;
|
|
5406
|
+
if (answered !== (v.answered_via !== null)) return false;
|
|
5407
|
+
if (answered && !oneOf2(v.answered_via, QUESTION_ANSWER_VIAS)) return false;
|
|
5408
|
+
return ts2(v.created_at) && ts2(v.expires_at) && ts2(v.answered_at, true);
|
|
5409
|
+
}
|
|
5410
|
+
function questionListResponseOk(v) {
|
|
5411
|
+
return isObj3(v) && keysExactly3(v, ["questions"]) && Array.isArray(v.questions) && v.questions.length <= QUESTION_LIST_LIMIT && v.questions.every(questionListItemOk);
|
|
5412
|
+
}
|
|
5413
|
+
var QUESTION_ANSWER_BODY_KEYS = ["approval_id", "via", "answers", "dismiss"];
|
|
5414
|
+
function questionAnswerBodyOk(v) {
|
|
5415
|
+
if (!isObj3(v) || !keysWithin2(v, ["approval_id", "via"], ["answers", "dismiss"])) return false;
|
|
5416
|
+
if (!uuid3(v.approval_id) || !oneOf2(v.via, QUESTION_ANSWER_VIAS)) return false;
|
|
5417
|
+
if ("answers" in v === "dismiss" in v) return false;
|
|
5418
|
+
return "dismiss" in v ? v.dismiss === true : answersShapeOk(v.answers);
|
|
5419
|
+
}
|
|
5420
|
+
var QUESTION_DELIVERIES = ["live", "inbox", "none"];
|
|
5421
|
+
function questionAnswerResponseOk(v) {
|
|
5422
|
+
return isObj3(v) && keysExactly3(v, ["approval_id", "outcome", "delivery", "inbox_id"]) && uuid3(v.approval_id) && oneOf2(v.outcome, QUESTION_OUTCOMES) && oneOf2(v.delivery, QUESTION_DELIVERIES) && (v.delivery === "inbox" ? uuid3(v.inbox_id) : v.inbox_id === null) && (v.outcome === "dismissed" ? v.delivery === "none" : v.delivery !== "none");
|
|
5423
|
+
}
|
|
5424
|
+
var questionIdempotencyKeys = {
|
|
5425
|
+
asked: (approvalId) => `question:${approvalId}:asked`,
|
|
5426
|
+
answered: (approvalId) => `question:${approvalId}:answered`
|
|
5427
|
+
};
|
|
5428
|
+
var QUESTION_ID_RE = UUID_RE;
|
|
5429
|
+
|
|
4627
5430
|
// ../shared/durable-contract/src/journal-approvals.ts
|
|
4628
5431
|
var JOURNAL_APPROVAL_KINDS = ["approval.resolved", "approval.consumed"];
|
|
4629
5432
|
var idOf = (e2) => e2.refs !== null && typeof e2.refs.approval_id === "string" ? e2.refs.approval_id : null;
|
|
@@ -5360,7 +6163,53 @@ var SEAL_VECTORS = {
|
|
|
5360
6163
|
"hash": "5a3bb041c155d67e50d18ee9afb0e6903f7a64988c881ab6373d3447fd5906f5"
|
|
5361
6164
|
}
|
|
5362
6165
|
};
|
|
6166
|
+
var INBOX_SHA_VECTORS = [
|
|
6167
|
+
{
|
|
6168
|
+
identity: {
|
|
6169
|
+
session_id: "11111111-2222-4333-8444-555555555555",
|
|
6170
|
+
sender_kind: "owner",
|
|
6171
|
+
sender_agent_id: null,
|
|
6172
|
+
on_behalf_of: null,
|
|
6173
|
+
in_reply_to: null,
|
|
6174
|
+
body: "Please rebase PR 3220 and rerun the contract tests."
|
|
6175
|
+
},
|
|
6176
|
+
sender_label: null,
|
|
6177
|
+
preimage: '{"body":"Please rebase PR 3220 and rerun the contract tests.","in_reply_to":null,"on_behalf_of":null,"sender_agent_id":null,"sender_kind":"owner","session_id":"11111111-2222-4333-8444-555555555555","v":1}',
|
|
6178
|
+
sha: "87fc04e971ee9fde7c3db3536772f4a7402c30a911111eff9fb37cbd3927c72f",
|
|
6179
|
+
text: "[mnemom inbox 87fc04e971ee9fde7c3db3536772f4a7402c30a911111eff9fb37cbd3927c72f] from the owner\n\nPlease rebase PR 3220 and rerun the contract tests."
|
|
6180
|
+
},
|
|
6181
|
+
{
|
|
6182
|
+
identity: {
|
|
6183
|
+
session_id: "11111111-2222-4333-8444-555555555555",
|
|
6184
|
+
sender_kind: "agent",
|
|
6185
|
+
sender_agent_id: "mnm-chief01",
|
|
6186
|
+
on_behalf_of: "user_owner_1",
|
|
6187
|
+
in_reply_to: null,
|
|
6188
|
+
body: "Wassim asks: status on the inbox migration?"
|
|
6189
|
+
},
|
|
6190
|
+
sender_label: "chief",
|
|
6191
|
+
preimage: '{"body":"Wassim asks: status on the inbox migration?","in_reply_to":null,"on_behalf_of":"user_owner_1","sender_agent_id":"mnm-chief01","sender_kind":"agent","session_id":"11111111-2222-4333-8444-555555555555","v":1}',
|
|
6192
|
+
sha: "8a955bd0811770262fa0d400472472b9cd8bc1cff8a41abb2955a2c1582eea54",
|
|
6193
|
+
text: "[mnemom inbox 8a955bd0811770262fa0d400472472b9cd8bc1cff8a41abb2955a2c1582eea54] from agent chief on behalf of the owner\n\nWassim asks: status on the inbox migration?"
|
|
6194
|
+
},
|
|
6195
|
+
{
|
|
6196
|
+
identity: {
|
|
6197
|
+
session_id: "11111111-2222-4333-8444-555555555555",
|
|
6198
|
+
sender_kind: "owner",
|
|
6199
|
+
sender_agent_id: null,
|
|
6200
|
+
on_behalf_of: null,
|
|
6201
|
+
in_reply_to: "aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee",
|
|
6202
|
+
body: "Yes, ship it as a draft. \u2014 W \u2713"
|
|
6203
|
+
},
|
|
6204
|
+
sender_label: null,
|
|
6205
|
+
preimage: '{"body":"Yes, ship it as a draft. \u2014 W \u2713","in_reply_to":"aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee","on_behalf_of":null,"sender_agent_id":null,"sender_kind":"owner","session_id":"11111111-2222-4333-8444-555555555555","v":1}',
|
|
6206
|
+
sha: "f79c83ca6fd83b8b918fe6464479c79ba4abea1ec30f43fd62b9b6d5950cc218",
|
|
6207
|
+
text: "[mnemom inbox f79c83ca6fd83b8b918fe6464479c79ba4abea1ec30f43fd62b9b6d5950cc218] from the owner (answer to question aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee)\n\nYes, ship it as a draft. \u2014 W \u2713"
|
|
6208
|
+
}
|
|
6209
|
+
];
|
|
5363
6210
|
export {
|
|
6211
|
+
A60_EMITTED_KINDS,
|
|
6212
|
+
A61_EMITTED_KINDS,
|
|
5364
6213
|
ABSENT_FUNCTIONS_M1,
|
|
5365
6214
|
ADMISSION_PRECEDENCE,
|
|
5366
6215
|
ADMISSION_REQUEST_KINDS,
|
|
@@ -5521,18 +6370,52 @@ export {
|
|
|
5521
6370
|
GUARD_LISTS,
|
|
5522
6371
|
GUARD_STATE_FAULT,
|
|
5523
6372
|
GUARD_STATE_OK,
|
|
6373
|
+
GUARD_STATE_V1_OK,
|
|
5524
6374
|
HEARTBEAT_DIVISOR,
|
|
5525
6375
|
HEARTBEAT_ENTRY_FIELDS,
|
|
5526
6376
|
HEARTBEAT_REASONS,
|
|
5527
6377
|
HEARTBEAT_REQUEST_KEYS,
|
|
5528
6378
|
HEARTBEAT_RESULT_FIELDS,
|
|
5529
6379
|
HEX64_RE,
|
|
6380
|
+
HOMED_INBOX_VECTORS,
|
|
5530
6381
|
HOST_STATUS_JSON,
|
|
5531
6382
|
HOST_STATUS_JSON_VECTORS,
|
|
5532
6383
|
HOST_STATUS_SEAT,
|
|
5533
6384
|
HOST_STATUS_SESSION,
|
|
5534
6385
|
ID_RE,
|
|
6386
|
+
INBOX_ACK_BODY_KEYS,
|
|
6387
|
+
INBOX_AGENT_ID_RE,
|
|
6388
|
+
INBOX_BODY_MAX_BYTES,
|
|
6389
|
+
INBOX_DEAD_REASONS,
|
|
6390
|
+
INBOX_DELIVERY_LIMIT,
|
|
6391
|
+
INBOX_IDEMPOTENCY_KEY_RE,
|
|
5535
6392
|
INBOX_KEY,
|
|
6393
|
+
INBOX_LIST_ITEM,
|
|
6394
|
+
INBOX_LIST_LIMIT,
|
|
6395
|
+
INBOX_MARKER_RE,
|
|
6396
|
+
INBOX_OPEN_CAP,
|
|
6397
|
+
INBOX_OPEN_MAX,
|
|
6398
|
+
INBOX_REJECT_CODES,
|
|
6399
|
+
INBOX_REJECT_REASONS,
|
|
6400
|
+
INBOX_RELEASE_BODY_KEYS,
|
|
6401
|
+
INBOX_RELEASE_REASONS,
|
|
6402
|
+
INBOX_REOFFER_S,
|
|
6403
|
+
INBOX_SENDERS_MAX,
|
|
6404
|
+
INBOX_SENDER_ADD_BODY_KEYS,
|
|
6405
|
+
INBOX_SENDER_INVALID_REASONS,
|
|
6406
|
+
INBOX_SENDER_ITEM,
|
|
6407
|
+
INBOX_SENDER_KINDS,
|
|
6408
|
+
INBOX_SENDER_LABEL_RE,
|
|
6409
|
+
INBOX_SENDER_REMOVE_BODY_KEYS,
|
|
6410
|
+
INBOX_SEND_BODY_KEYS,
|
|
6411
|
+
INBOX_SEND_RESPONSE,
|
|
6412
|
+
INBOX_SHA_FIXTURE,
|
|
6413
|
+
INBOX_SHA_VECTORS,
|
|
6414
|
+
INBOX_STATUSES,
|
|
6415
|
+
INBOX_TAKE_BODY_KEYS,
|
|
6416
|
+
INBOX_TAKE_ITEM,
|
|
6417
|
+
INBOX_TAKE_LIMIT_MAX,
|
|
6418
|
+
INBOX_TTL_S,
|
|
5536
6419
|
INTERNAL_KEY_HEADER,
|
|
5537
6420
|
IV_BYTES,
|
|
5538
6421
|
JOURNAL_APPROVAL_KINDS,
|
|
@@ -5626,6 +6509,30 @@ export {
|
|
|
5626
6509
|
PURE_FN_M1_PENDING,
|
|
5627
6510
|
PURE_FN_PRODUCT_BASE,
|
|
5628
6511
|
PURE_FN_S1_MODULE,
|
|
6512
|
+
QUESTION_ANSWER_BODY_KEYS,
|
|
6513
|
+
QUESTION_ANSWER_MAX_BYTES,
|
|
6514
|
+
QUESTION_ANSWER_VIAS,
|
|
6515
|
+
QUESTION_APPROVAL_TTL_S,
|
|
6516
|
+
QUESTION_ASK_BODY_KEYS,
|
|
6517
|
+
QUESTION_BODY_MAX_BYTES,
|
|
6518
|
+
QUESTION_DELIVERIES,
|
|
6519
|
+
QUESTION_DESCRIPTION_MAX_BYTES,
|
|
6520
|
+
QUESTION_DISMISSED_REASON,
|
|
6521
|
+
QUESTION_HANDOFF_REASON,
|
|
6522
|
+
QUESTION_HEADER_MAX_BYTES,
|
|
6523
|
+
QUESTION_ID_RE,
|
|
6524
|
+
QUESTION_LABEL_MAX_BYTES,
|
|
6525
|
+
QUESTION_LIST_ITEM,
|
|
6526
|
+
QUESTION_LIST_LIMIT,
|
|
6527
|
+
QUESTION_MAX_OPTIONS,
|
|
6528
|
+
QUESTION_MAX_QUESTIONS,
|
|
6529
|
+
QUESTION_MIN_OPTIONS,
|
|
6530
|
+
QUESTION_OUTCOMES,
|
|
6531
|
+
QUESTION_POLL_BODY_KEYS,
|
|
6532
|
+
QUESTION_RECOMMENDED_SUFFIX,
|
|
6533
|
+
QUESTION_STATES,
|
|
6534
|
+
QUESTION_TEXT_MAX_BYTES,
|
|
6535
|
+
QUESTION_TOOL_USE_ID_RE,
|
|
5629
6536
|
READY_CAUSES,
|
|
5630
6537
|
READY_SESSIONS_LIMIT_MAX,
|
|
5631
6538
|
READY_SESSIONS_LIMIT_MIN,
|
|
@@ -5733,6 +6640,7 @@ export {
|
|
|
5733
6640
|
U05_CHECK_TEXT_ATTESTATION_FAILED,
|
|
5734
6641
|
U05_CHECK_TEXT_RESPAWN_FAILED,
|
|
5735
6642
|
U05_FIXTURE_CHECK,
|
|
6643
|
+
UNATTENDED_POOL_VECTORS,
|
|
5736
6644
|
UNSUPPORTED_FEATURES,
|
|
5737
6645
|
USER_STATES,
|
|
5738
6646
|
UUID_RE,
|
|
@@ -5744,6 +6652,9 @@ export {
|
|
|
5744
6652
|
admitSweepDigest,
|
|
5745
6653
|
admitSweepText,
|
|
5746
6654
|
amendDecision,
|
|
6655
|
+
answerFromChoice,
|
|
6656
|
+
answersOk,
|
|
6657
|
+
answersShapeOk,
|
|
5747
6658
|
applyDeviceStep,
|
|
5748
6659
|
approvalSubjectHash,
|
|
5749
6660
|
approvalTargetOk,
|
|
@@ -5784,6 +6695,8 @@ export {
|
|
|
5784
6695
|
contractPlaintext,
|
|
5785
6696
|
countJournalApprovals,
|
|
5786
6697
|
createReadySessionAnswerOk,
|
|
6698
|
+
decideHomedInboxVector,
|
|
6699
|
+
decideUnattendedPoolVector,
|
|
5787
6700
|
dekFromWrapInput,
|
|
5788
6701
|
dekWrapInput,
|
|
5789
6702
|
deriveEffectiveState,
|
|
@@ -5813,6 +6726,7 @@ export {
|
|
|
5813
6726
|
gatewayEventsBodyOk,
|
|
5814
6727
|
grantWarningDays,
|
|
5815
6728
|
guardStateOk,
|
|
6729
|
+
guardStateV1Ok,
|
|
5816
6730
|
hasRemoteControl,
|
|
5817
6731
|
heartbeatRequestOk,
|
|
5818
6732
|
heartbeatResultOk,
|
|
@@ -5820,6 +6734,30 @@ export {
|
|
|
5820
6734
|
hmacSha256Hex,
|
|
5821
6735
|
hostStatusJsonOk,
|
|
5822
6736
|
idempotencyKeys,
|
|
6737
|
+
inboxAckBodyOk,
|
|
6738
|
+
inboxAckResponseOk,
|
|
6739
|
+
inboxBodyOk,
|
|
6740
|
+
inboxDeliveryText,
|
|
6741
|
+
inboxIdempotencyKeys,
|
|
6742
|
+
inboxListItemOk,
|
|
6743
|
+
inboxListResponseOk,
|
|
6744
|
+
inboxMarkerOf,
|
|
6745
|
+
inboxReleaseBodyOk,
|
|
6746
|
+
inboxReleaseResponseOk,
|
|
6747
|
+
inboxSendBodyOk,
|
|
6748
|
+
inboxSendResponseOk,
|
|
6749
|
+
inboxSenderAddBodyOk,
|
|
6750
|
+
inboxSenderChangeResponseOk,
|
|
6751
|
+
inboxSenderItemOk,
|
|
6752
|
+
inboxSenderRemoveBodyOk,
|
|
6753
|
+
inboxSendersResponseOk,
|
|
6754
|
+
inboxSha,
|
|
6755
|
+
inboxShaOf,
|
|
6756
|
+
inboxShaPreimage,
|
|
6757
|
+
inboxSummaryResponseOk,
|
|
6758
|
+
inboxTakeBodyOk,
|
|
6759
|
+
inboxTakeItemOk,
|
|
6760
|
+
inboxTakeResponseOk,
|
|
5823
6761
|
invalidTransitionFix,
|
|
5824
6762
|
isCountTokensPath,
|
|
5825
6763
|
isDurableCode,
|
|
@@ -5848,6 +6786,7 @@ export {
|
|
|
5848
6786
|
newDek,
|
|
5849
6787
|
nofenceHonoured,
|
|
5850
6788
|
normalizeCellId,
|
|
6789
|
+
normalizeQuestions,
|
|
5851
6790
|
normalizeSessionName,
|
|
5852
6791
|
openContract,
|
|
5853
6792
|
ownerSessionViewOk,
|
|
@@ -5873,7 +6812,24 @@ export {
|
|
|
5873
6812
|
protectionRefusals,
|
|
5874
6813
|
proxyLockPath,
|
|
5875
6814
|
pureFnArgs,
|
|
6815
|
+
questionAnswerBodyOk,
|
|
6816
|
+
questionAnswerInboxBody,
|
|
6817
|
+
questionAnswerResponseOk,
|
|
6818
|
+
questionAskBodyOk,
|
|
6819
|
+
questionAskMatches,
|
|
6820
|
+
questionAskResponseOk,
|
|
6821
|
+
questionIdempotencyKeys,
|
|
6822
|
+
questionItemOk,
|
|
6823
|
+
questionListItemOk,
|
|
6824
|
+
questionListResponseOk,
|
|
6825
|
+
questionPollBodyOk,
|
|
6826
|
+
questionPollResponseOk,
|
|
6827
|
+
questionReleaseResponseOk,
|
|
6828
|
+
questionSha,
|
|
6829
|
+
questionShaPreimage,
|
|
6830
|
+
questionsOk,
|
|
5876
6831
|
readyRowOk,
|
|
6832
|
+
recommendedOption,
|
|
5877
6833
|
recordValueIn,
|
|
5878
6834
|
refsInvalidDetailsOk,
|
|
5879
6835
|
refsPropertyOk,
|
|
@@ -5913,6 +6869,8 @@ export {
|
|
|
5913
6869
|
testModeActive,
|
|
5914
6870
|
toolClassesSupportedM1,
|
|
5915
6871
|
transcriptGuardPath,
|
|
6872
|
+
unattendedHomedInboxEligible,
|
|
6873
|
+
unattendedPoolEligible,
|
|
5916
6874
|
userStateOf,
|
|
5917
6875
|
utf8,
|
|
5918
6876
|
validateRefs,
|