Bifrost/tests/epiphany-operator-command.test.mjs
2026-07-19 18:43:49 +01:00

17 lines
7.5 KiB
JavaScript

import test from "node:test";import assert from "node:assert/strict";import {mkdtemp} from "node:fs/promises";import {tmpdir} from "node:os";import {resolve} from "node:path";import {createRequire} from "node:module";
import {admitOperatorRequest,enrollOperatorIdentity,OPERATOR_SIGNING_PURPOSE} from "../tools/epiphany-operator-commands.mjs";
import {admissionTuple,packetTuple,parseOperatorRequest} from "../tools/epiphany-operator-command-documents.mjs";
import {verifyPurpose} from "../tools/bifrost-signed-identity.mjs";
const cultLibRoot=process.env.VOIDBOT_CULTLIB_ROOT||"E:/Projects/CultLib",requireCult=createRequire(resolve(cultLibRoot,"packages/cultnet-ts/package.json")),{encode}=requireCult("@msgpack/msgpack");
const actorLink={guildId:"guild",discordAuthorId:"owner",bifrostActorId:"actor",heimdallActorRef:"heimdall:actor:1"};
function request(command={kind:"status"}){return {schemaName:"voidbot.discord.epiphany_operator_request",schemaVersion:"voidbot.discord.epiphany_operator_request.v1",requestId:"interaction-1",commandId:"interaction-1",nonce:"interaction-1",sourceEventId:"interaction-1",sourceActorDiscordId:"owner",discordGuildId:"guild",discordChannelId:"channel",discordMessageId:"interaction-1",targetRuntimeId:"epiphany-yggdrasil",issuedAt:"2026-07-19T10:00:00.000Z",expiresAt:"2026-07-19T10:00:30.000Z",producerId:"voidbot",producerRuntimeId:"voidbot-yggdrasil",authorityClass:"operator_request_only",status:"pending",command};}
function result(admission){const value={schemaVersion:"epiphany.operator_command.result.v1",resultId:"result-1",commandId:admission.packet.commandId,packetSha256:admission.packetSha256,targetRuntimeId:admission.packet.targetRuntimeId,disposition:"observed",consequenceKind:"operator-snapshot",consequenceRef:"snapshot-1",completedAt:"2026-07-19T10:00:01.000Z",privateStateExposed:false,operatorStatus:"sleeping",stateStatus:"ready",coordinatorAction:"",brakeStatus:"engaged",detail:"bounded",reviews:[],reviewCandidateId:"",reviewDecision:""},receipt={schemaVersion:"epiphany.operator_command.sealed_result.v1",result:value,resultPayloadSha256:"sha256-result",commandId:value.commandId,packetSha256:value.packetSha256,targetRuntimeId:value.targetRuntimeId,completedAt:value.completedAt,providerIdentityId:"epiphany-host",privateStateExposed:false,executorSignature:new Uint8Array(64)};return {providerIdentityId:"epiphany-host",result:value,receipt};}
const transport=(execute)=>({trustedIdentityId:"epiphany-host",execute,verifyReceipt:(_admission,receipt)=>receipt});
class TestLedger{constructor(){this.requests=new Map();this.admissions=new Map();this.completions=new Map();this.terminals=new Map();}admit(id,request,value){const oldRequest=this.requests.get(id),old=this.admissions.get(id);if(oldRequest&&JSON.stringify(oldRequest)!==JSON.stringify(request)||old&&JSON.stringify(old)!==JSON.stringify(value))throw new Error("operator request identity collision");this.requests.set(id,request);this.admissions.set(id,value);}complete(_id,result,_provider,receipt){this.completions.set(result.commandId,receipt??{...result,result,providerIdentityId:"epiphany-host"});}getRequest(id){return this.requests.get(id);}getAdmission(id){return this.admissions.get(id);}getCompletion(id){return this.completions.get(id);}terminalize(value){this.terminals.set(value.requestId,value);}getTerminal(id){return this.terminals.get(id);}}
async function identity(){const d=await mkdtemp(resolve(tmpdir(),"bifrost-operator-"));return enrollOperatorIdentity(resolve(d,"operator.seed"));}
test("signs the exact Rust packet and admission tuples",async()=>{const id=await identity(),out=await admitOperatorRequest({request:request(),ownerDiscordId:"owner",actorLink,identity:id,encode,now:new Date("2026-07-19T10:00:01Z"),ledger:new TestLedger(),transport:transport(async a=>result(a))});assert.equal(out.admission.packetSha256,`sha256-${(await import("node:crypto")).createHash("sha256").update(encode(packetTuple(out.admission.packet))).digest("hex")}`);assert.ok(verifyPurpose(id.publicKey,OPERATOR_SIGNING_PURPOSE,encode(admissionTuple(out.admission)),out.admission.providerSignature));assert.equal(out.result.disposition,"observed");});
test("requires exact owner and admitted Bifrost actor link",async()=>{const id=await identity();for(const args of [{ownerDiscordId:"other",actorLink},{ownerDiscordId:"owner",actorLink:null}])await assert.rejects(()=>admitOperatorRequest({request:request(),identity:id,encode,now:new Date("2026-07-19T10:00:01Z"),ledger:new TestLedger(),transport:transport(async a=>result(a)),...args}));const provenanceOnly={...actorLink,heimdallActorRef:""};assert.equal((await admitOperatorRequest({request:request(),ownerDiscordId:"owner",actorLink:provenanceOnly,identity:id,encode,now:new Date("2026-07-19T10:00:01Z"),ledger:new TestLedger(),transport:transport(async a=>result(a))})).result.disposition,"observed");});
test("strict request, ttl, command bounds, and expiry fail closed",()=>{assert.throws(()=>parseOperatorRequest({...request(),schemaVersion:"voidbot.discord.epiphany_operator_request.v0"}));assert.throws(()=>parseOperatorRequest({...request(),extra:true}));assert.throws(()=>parseOperatorRequest({...request(),expiresAt:"2026-07-19T10:01:01Z"}));assert.throws(()=>parseOperatorRequest(request({kind:"argv",args:["whoami"]})));assert.throws(()=>parseOperatorRequest(request({kind:"sleep",reason:""})));});
test("does not synthesize success without an authenticated transport result",async()=>{const id=await identity(),base={request:request(),ownerDiscordId:"owner",actorLink,identity:id,encode,now:new Date("2026-07-19T10:00:01Z"),ledger:new TestLedger()};await assert.rejects(()=>admitOperatorRequest(base),/authenticated Epiphany/);await assert.rejects(()=>admitOperatorRequest({...base,transport:transport(async a=>({...result(a),providerIdentityId:"impostor"}))}),/authenticated Epiphany/);await assert.rejects(()=>admitOperatorRequest({...base,transport:transport(async a=>({...result(a),result:{...result(a).result,packetSha256:"sha256-wrong"}}))}),/not bound/);});
test("retransmits an exact durable admission after expiry without mutable actor or signer state",async()=>{const id=await identity(),ledger=new TestLedger(),r=request(),base={request:r,ownerDiscordId:"owner",actorLink,identity:id,encode,ledger};await assert.rejects(()=>admitOperatorRequest({...base,now:new Date("2026-07-19T10:00:01Z"),transport:transport(async()=>{throw new Error("lost result")})}),/lost result/);let calls=0;const recovered=await admitOperatorRequest({...base,ownerDiscordId:"rotated-owner",actorLink:null,identity:null,now:new Date("2026-07-19T10:02:00Z"),transport:transport(async a=>{calls++;return result(a)})});assert.equal(calls,1);assert.equal(recovered.recovered,true);const fresh={...r,requestId:"interaction-2",commandId:"interaction-2",nonce:"interaction-2",sourceEventId:"interaction-2",discordMessageId:"interaction-2"};await assert.rejects(()=>admitOperatorRequest({...base,request:fresh,ledger:new TestLedger(),now:new Date("2026-07-19T10:02:00Z"),transport:transport(async a=>result(a))}),error=>error.code==="expired-new-request");});
test("does not hide command-id collisions behind an existing completion",async()=>{const id=await identity(),ledger=new TestLedger(),base={ownerDiscordId:"owner",actorLink,identity:id,encode,ledger,now:new Date("2026-07-19T10:00:01Z"),transport:transport(async a=>result(a))};await admitOperatorRequest({...base,request:request()});const collision={...request(),requestId:"interaction-alien",nonce:"alien",sourceEventId:"alien",discordMessageId:"alien"};await assert.rejects(()=>admitOperatorRequest({...base,request:collision}),error=>error.code==="command-id-collision");});