Align Epiphany operator bridge v1

This commit is contained in:
Meta Vens 2026-07-19 15:09:26 +01:00
commit dabf7aa320
15 changed files with 216 additions and 41 deletions

View file

@ -2,6 +2,8 @@
# The default compose.local.yaml is self-contained for local smoke testing.
COMPOSE_PROJECT_NAME=bifrost-local
BIFROST_ROOT_VERSE=asgard
BIFROST_MACHINE_ID=yggdrasil
# Epiphany operator admission. Endpoint and trust anchor are explicit; there is
# no localhost or identity-string fallback.

View file

@ -93,6 +93,9 @@ For the full staged roadmap, including contribution points, revenue share, patro
- dry-run a Reddit organizing thread with `node tools/bifrost-bridge.mjs reddit-post --title "Thread title" --persona-name Bifrost --content "Thread body" --dry-run true`
- print the Eve provider advertisement with `node tools/provider-advertisement.mjs print`
- export the Eve provider store with `node tools/provider-advertisement.mjs export --out .bifrost/provider-store.cc`
- inspect the typed six-command Epiphany operator authority map in
`docs/epiphany-operator-boundary.md`; provider advertisement commands require
explicit `BIFROST_ROOT_VERSE` and `BIFROST_MACHINE_ID` deployment identity
- inspect the interactive Motion Verse surface at `/eve/governance/surface` while signed in as an active member
- container smoke test with `docker compose -f compose.local.yaml up --build`
- container smoke tests may hit `/healthz` and `/readyz` as product probes.

View file

@ -0,0 +1,48 @@
# Epiphany operator boundary
## Authority map
- Owner: Bifrost alone authenticates a Discord operator request, resolves the
persisted Discord-to-Bifrost actor link, and signs an expiring Epiphany
admission. Epiphany alone decides and applies the named command.
- Inputs: one strict `voidbot.discord.epiphany_operator_request.v0`, the exact
configured Discord owner, a persisted Bifrost actor link, the deployment's
operator signing identity, and the configured Epiphany runtime/host trust
anchor.
- Outputs: one immutable `bifrost.operator_command.delivery.v1`, one verified
`epiphany.operator_command.sealed_result.v1`, and one bounded
`bifrost.discord.epiphany_operator_delivery.v1` projection.
- Derived state: Discord delivery fields are notification-only projections of
the signed result. Reviews contain at most ten candidate identity/status
summaries. Proposal bodies and private Mind state never cross this boundary.
- Forbidden writers: ordinary Discord conversation, Persona feedback, argv,
shell commands, `/queue-codex`, provider-advertisement metadata, and the
Discord outbox cannot create an Epiphany consequence.
- Shared path: Status, Sleep, Wake, Directive, Reviews, and Review all use the
same request admission, signature, RUDP execution, sealed-result verification,
durable ledger, and Discord projection path.
- Cut line: v0 admissions and sealed results exist only so already-durable
four-command work can drain or replay. Bifrost never mints v0, and v0 cannot
carry Reviews or Review.
## Review command
Review binds the exact current Mind candidate with `mindRequestId`,
`candidateId`, bare 64-hex `candidateSha256`, `expectedModelRevision`, bare
64-hex `expectedModelHash`, and one decision: `adopt`, `refuse`, or `hold`.
Bifrost does not infer a decision from conversation and cannot substitute a
candidate after signing.
## Deployment identity
Provider discovery reads `BIFROST_ROOT_VERSE` and `BIFROST_MACHINE_ID` from the
deployment environment. The canonical Yggdrasil example config supplies
`asgard` and `yggdrasil`; the provider code has no Starfire or machine fallback.
## Verification layer
The Rust-generated fixture owns cross-runtime schema versions, signing
purposes, command vocabulary, bounded review projection, admission bytes, and
sealed-result bytes. Bifrost tests consume that fixture, then run hostile
schema, identity, digest, binding, replay, and tamper cases against the same
ports used by the worker.

View file

@ -23,7 +23,8 @@ public sealed class ProviderAdvertisementTests
AssertEndpoint(root, "patron-support-intake", "bifrost.patron_support_event.v0", "patronage");
AssertEndpoint(root, "github-webhooks", "bifrost.work_item.v0", "github");
AssertEndpoint(root, "epiphany-operator-requests", "voidbot.discord.epiphany_operator_request.v0", "operator");
AssertEndpoint(root, "epiphany-operator-results", "epiphany.operator_command.sealed_result.v0", "epiphany");
AssertEndpoint(root, "epiphany-operator-results", "epiphany.operator_command.sealed_result.v1", "epiphany");
Assert.Equal("asgard.yggdrasil.bifrost", root.GetProperty("locatedService").GetString());
AssertSchemaPurpose(root, "bifrost.crossing_receipt.v1", "canonical Bifrost-owned public crossing receipt");
AssertSchemaPurpose(root, "bifrost.patron_support_event.v0", "current hosted Heimdall-signed patron support fact consumed by Bifrost");
AssertWitness(root, ".bifrost/bridge-receipts.cc", "bifrost.crossing_receipt.v1", "current");
@ -182,6 +183,8 @@ public sealed class ProviderAdvertisementTests
process.StartInfo.Environment["BIFROST_SKIP_LOCAL_ENV"] = "true";
process.StartInfo.Environment["BIFROST_REDDIT_CLIENT_ID"] = string.Empty;
process.StartInfo.Environment["BIFROST_REDDIT_REFRESH_TOKEN"] = string.Empty;
process.StartInfo.Environment["BIFROST_ROOT_VERSE"] = "asgard";
process.StartInfo.Environment["BIFROST_MACHINE_ID"] = "yggdrasil";
process.Start();
var stdout = await process.StandardOutput.ReadToEndAsync();

View file

@ -5,7 +5,7 @@ import {verifyPurpose} from "../tools/bifrost-signed-identity.mjs";
const requireCult=createRequire(resolve("E:/Projects/CultLib/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.v0",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.v0",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"},receipt={schemaVersion:"epiphany.operator_command.sealed_result.v0",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};}
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"));}

View file

@ -9,7 +9,7 @@ import { mkdtemp } from "node:fs/promises";
import { tmpdir } from "node:os";
import { enrollOperatorIdentity } from "../tools/epiphany-operator-commands.mjs";
import { resultReceiptTuple } from "../tools/epiphany-operator-command-documents.mjs";
import { EPIPHANY_RESULT_SIGNING_PURPOSE,EpiphanyOperatorCultNetRudpTransport,verifySealedReceipt } from "../tools/epiphany-operator-cultnet-rudp.mjs";
import { LEGACY_EPIPHANY_RESULT_SIGNING_PURPOSE as EPIPHANY_RESULT_SIGNING_PURPOSE,EpiphanyOperatorCultNetRudpTransport,verifySealedReceipt } from "../tools/epiphany-operator-cultnet-rudp.mjs";
import { signPurpose,trustAnchor } from "../tools/bifrost-signed-identity.mjs";
const requireCult=createRequire(resolve("E:/Projects/CultLib/packages/cultnet-ts/package.json"));

View file

@ -1,3 +1,6 @@
import test from "node:test";
import assert from "node:assert/strict";
import { createRequire } from "node:module";
@ -7,6 +10,6 @@ import { resolve } from "node:path";
import { EpiphanyOperatorDiscordOutbox } from "../tools/epiphany-operator-discord-outbox.mjs";
const requireCache=createRequire(resolve("E:/Projects/CultLib/packages/cultcache-ts/package.json")),requireNet=createRequire(resolve("E:/Projects/CultLib/packages/cultnet-ts/package.json")),cache=requireCache("cultcache-ts"),{encode}=requireNet("@msgpack/msgpack");
function request(id="request-1"){return {schemaName:"voidbot.discord.epiphany_operator_request",schemaVersion:"voidbot.discord.epiphany_operator_request.v0",requestId:id,commandId:id,nonce:id,sourceEventId:id,sourceActorDiscordId:"owner",discordGuildId:"guild",discordChannelId:"ops",discordMessageId:id,targetRuntimeId:"epiphany-yggdrasil",issuedAt:"2026-07-19T12:00:00Z",expiresAt:"2026-07-19T12:01:00Z",producerId:"voidbot",producerRuntimeId:"voidbot-yggdrasil",authorityClass:"operator_request_only",status:"pending",command:{kind:"status"}};}
function receipt(id="request-1"){return {schemaVersion:"epiphany.operator_command.sealed_result.v0",result:{disposition:"observed",detail:"bounded",operatorStatus:"sleeping",stateStatus:"ready",coordinatorAction:"",brakeStatus:"engaged"},resultPayloadSha256:`sha256-${"1".repeat(64)}`,providerIdentityId:"executor",executorSignature:new Uint8Array(64),completedAt:"2026-07-19T12:00:01Z",commandId:id};}
test("Discord outbox publishes immutable request-bound completed and refused deliveries",async()=>{const root=await mkdtemp(resolve(tmpdir(),"operator-outbox-")),path=resolve(root,"deliveries.cc"),outbox=await EpiphanyOperatorDiscordOutbox.open(path,{cultcacheRuntime:cache,encode}),r=request(),completed=await outbox.publishCompleted(r,receipt());assert.equal(completed.deliveryId,r.requestId);assert.match(completed.requestPayloadSha256,/^sha256-[0-9a-f]{64}$/);assert.match(completed.executorSignatureSha256,/^sha256-[0-9a-f]{64}$/);assert.equal(completed.operatorStatus,"sleeping");assert.equal(completed.brakeStatus,"engaged");assert.equal(outbox.isExactDelivery(r),true);assert.equal(outbox.isExactDelivery({...r,discordChannelId:"alien"}),false);assert.equal(completed.privateStateExposed,false);await outbox.publishCompleted(r,receipt());await assert.rejects(()=>outbox.publishCompleted(r,{...receipt(),result:{...receipt().result,disposition:"applied",detail:"changed"}}),/collision/);const refusedRequest=request("request-2"),refused=await outbox.publishRefused(refusedRequest,{failureCode:"foreign-owner",recordedAt:"2026-07-19T12:00:02Z"});assert.equal(refused.status,"refused");assert.equal(refused.failureCode,"foreign-owner");assert.equal(refused.sealedResultPayloadSha256,"");const reopened=await EpiphanyOperatorDiscordOutbox.open(path,{cultcacheRuntime:cache,encode});assert.equal(reopened.get(r.requestId).status,"completed");assert.equal(reopened.get(refusedRequest.requestId).status,"refused");});
function request(id="request-1",command={kind:"status"}){return {schemaName:"voidbot.discord.epiphany_operator_request",schemaVersion:"voidbot.discord.epiphany_operator_request.v0",requestId:id,commandId:id,nonce:id,sourceEventId:id,sourceActorDiscordId:"owner",discordGuildId:"guild",discordChannelId:"ops",discordMessageId:id,targetRuntimeId:"epiphany-yggdrasil",issuedAt:"2026-07-19T12:00:00Z",expiresAt:"2026-07-19T12:01:00Z",producerId:"voidbot",producerRuntimeId:"voidbot-yggdrasil",authorityClass:"operator_request_only",status:"pending",command};}
function receipt(id="request-1"){return {schemaVersion:"epiphany.operator_command.sealed_result.v1",result:{disposition:"observed",detail:"bounded",operatorStatus:"sleeping",stateStatus:"ready",coordinatorAction:"",brakeStatus:"engaged",reviews:[],reviewCandidateId:"candidate-1",reviewDecision:"hold"},resultPayloadSha256:`sha256-${"1".repeat(64)}`,providerIdentityId:"executor",executorSignature:new Uint8Array(64),completedAt:"2026-07-19T12:00:01Z",commandId:id};}
test("Discord outbox publishes immutable request-bound completed and refused deliveries",async()=>{const root=await mkdtemp(resolve(tmpdir(),"operator-outbox-")),path=resolve(root,"deliveries.cc"),outbox=await EpiphanyOperatorDiscordOutbox.open(path,{cultcacheRuntime:cache,encode}),r=request("request-1",{kind:"review",mindRequestId:"mind-1",candidateId:"candidate-1",candidateSha256:"1".repeat(64),expectedModelRevision:41,expectedModelHash:"2".repeat(64),decision:"hold"}),completed=await outbox.publishCompleted(r,receipt());assert.equal(completed.deliveryId,r.requestId);assert.match(completed.requestPayloadSha256,/^sha256-[0-9a-f]{64}$/);assert.match(completed.executorSignatureSha256,/^sha256-[0-9a-f]{64}$/);assert.equal(completed.operatorStatus,"sleeping");assert.equal(completed.brakeStatus,"engaged");assert.equal(completed.schemaVersion,"bifrost.discord.epiphany_operator_delivery.v1");assert.equal(completed.commandId,r.commandId);assert.deepEqual(completed.reviews,[]);assert.equal(completed.reviewCandidateId,"candidate-1");assert.equal(completed.reviewDecision,"hold");assert.equal(outbox.isExactDelivery(r),true);assert.equal(outbox.isExactDelivery({...r,discordChannelId:"alien"}),false);assert.equal(completed.privateStateExposed,false);await outbox.publishCompleted(r,receipt());await assert.rejects(()=>outbox.publishCompleted({...r,command:{...r.command,candidateId:"alien"}},receipt()),/does not bind/);await assert.rejects(()=>outbox.publishCompleted(r,{...receipt(),result:{...receipt().result,disposition:"applied",detail:"changed"}}),/collision/);const refusedRequest=request("request-2"),refused=await outbox.publishRefused(refusedRequest,{failureCode:"foreign-owner",recordedAt:"2026-07-19T12:00:02Z"});assert.equal(refused.status,"refused");assert.equal(refused.failureCode,"foreign-owner");assert.equal(refused.sealedResultPayloadSha256,"");assert.deepEqual(refused.reviews,[]);assert.equal(refused.reviewCandidateId,"");assert.equal(refused.reviewDecision,"");const reopened=await EpiphanyOperatorDiscordOutbox.open(path,{cultcacheRuntime:cache,encode});assert.equal(reopened.get(r.requestId).status,"completed");assert.equal(reopened.get(refusedRequest.requestId).status,"refused");});

View file

@ -11,4 +11,4 @@ import { loadEpiphanyOperatorTrustAnchor,verifySealedReceipt } from "../tools/ep
import { verifyPurpose } from "../tools/bifrost-signed-identity.mjs";
const fixture=process.env.EPIPHANY_OPERATOR_RUST_FIXTURE??resolve("..","EpiphanyAgent",".epiphany-smoke","operator-command-interop-rust"),requireCult=createRequire(resolve("E:/Projects/CultLib/packages/cultnet-ts/package.json")),{decode,encode}=requireCult("@msgpack/msgpack");
test("consumes and verifies the Rust-emitted operator admission and sealed receipt",{skip:!existsSync(resolve(fixture,"manifest.json"))&&"Rust interop fixture is not present in this standalone checkout"},async()=>{const manifest=JSON.parse(await readFile(resolve(fixture,"manifest.json"),"utf8")),admissionBytes=await readFile(resolve(fixture,manifest.admissionFile)),receiptBytes=await readFile(resolve(fixture,manifest.sealedResultFile));assert.equal(`sha256-${createHash("sha256").update(admissionBytes).digest("hex")}`,manifest.admissionSha256);assert.equal(`sha256-${createHash("sha256").update(receiptBytes).digest("hex")}`,manifest.sealedResultSha256);const admission=parseOperatorAdmission(decode(admissionBytes)),receipt=decode(receiptBytes),bifrostAnchor=await loadEpiphanyOperatorTrustAnchor(resolve(fixture,manifest.bifrostRawTrustAnchorFile),{decode}),executorAnchor=await loadEpiphanyOperatorTrustAnchor(resolve(fixture,manifest.executorRawTrustAnchorFile),{decode});assert.equal(verifyPurpose(bifrostAnchor.publicKey,OPERATOR_SIGNING_PURPOSE,encode(admissionTuple(admission)),admission.providerSignature),true);assert.equal(verifySealedReceipt({receipt,admission,trustedIdentity:executorAnchor,encode}).commandId,admission.packet.commandId);assert.throws(()=>verifySealedReceipt({receipt:{...receipt,packetSha256:"sha256-hostile"},admission,trustedIdentity:executorAnchor,encode}),/not bound/);assert.equal(manifest.rudpConnectionId,0xe91f0001);assert.equal(manifest.privateStateExposed,false);});
test("consumes and verifies the Rust-emitted operator admission, protocol, and sealed receipt",{skip:!existsSync(resolve(fixture,"manifest.json"))&&"Rust interop fixture is not present in this standalone checkout"},async()=>{const manifest=JSON.parse(await readFile(resolve(fixture,"manifest.json"),"utf8")),protocolBytes=await readFile(resolve(fixture,manifest.protocolFile)),protocol=JSON.parse(protocolBytes),admissionBytes=await readFile(resolve(fixture,manifest.admissionFile)),receiptBytes=await readFile(resolve(fixture,manifest.sealedResultFile));assert.equal(`sha256-${createHash("sha256").update(admissionBytes).digest("hex")}`,manifest.admissionSha256);assert.equal(`sha256-${createHash("sha256").update(receiptBytes).digest("hex")}`,manifest.sealedResultSha256);assert.equal(`sha256-${createHash("sha256").update(protocolBytes).digest("hex")}`,manifest.protocolSha256);assert.equal(protocol.admissionSchemaVersion,"bifrost.operator_command.delivery.v1");assert.equal(protocol.resultSchemaVersion,"epiphany.operator_command.result.v1");assert.equal(protocol.sealedResultSchemaVersion,"epiphany.operator_command.sealed_result.v1");assert.deepEqual(protocol.commands.map(command=>command.kind),["status","sleep","wake","directive","reviews","review"]);assert.deepEqual(protocol.reviewDecisions,["adopt","refuse","hold"]);assert.equal(protocol.boundedReviewResult.reviews.length,1);assert.equal(protocol.boundedReviewResult.privateStateExposed,false);const admission=parseOperatorAdmission(decode(admissionBytes)),receipt=decode(receiptBytes),bifrostAnchor=await loadEpiphanyOperatorTrustAnchor(resolve(fixture,manifest.bifrostRawTrustAnchorFile),{decode}),executorAnchor=await loadEpiphanyOperatorTrustAnchor(resolve(fixture,manifest.executorRawTrustAnchorFile),{decode});assert.equal(verifyPurpose(bifrostAnchor.publicKey,OPERATOR_SIGNING_PURPOSE,encode(admissionTuple(admission)),admission.providerSignature),true);assert.equal(verifySealedReceipt({receipt,admission,trustedIdentity:executorAnchor,encode}).commandId,admission.packet.commandId);assert.throws(()=>verifySealedReceipt({receipt:{...receipt,packetSha256:"sha256-hostile"},admission,trustedIdentity:executorAnchor,encode}),/not bound/);assert.equal(manifest.rudpConnectionId,0xe91f0001);assert.equal(manifest.privateStateExposed,false);});

View file

@ -0,0 +1,99 @@
import test from "node:test";
import assert from "node:assert/strict";
import {
commandTupleForInterop,
parseOperatorAdmission,
parseOperatorRequest,
parseOperatorResult,
wireResultTuple,
} from "../tools/epiphany-operator-command-documents.mjs";
const hex = "a".repeat(64);
const review = {
kind: "review",
mindRequestId: "mind-1",
candidateId: "candidate-1",
candidateSha256: hex,
expectedModelRevision: 41,
expectedModelHash: "b".repeat(64),
decision: "adopt",
};
function request(command) {
return {
schemaName: "voidbot.discord.epiphany_operator_request",
schemaVersion: "voidbot.discord.epiphany_operator_request.v0",
requestId: "request-1",
commandId: "command-1",
nonce: "nonce-1",
sourceEventId: "event-1",
sourceActorDiscordId: "owner",
discordGuildId: "guild",
discordChannelId: "ops",
discordMessageId: "message-1",
targetRuntimeId: "epiphany-yggdrasil",
issuedAt: "2026-07-19T12:00:00Z",
expiresAt: "2026-07-19T12:01:00Z",
producerId: "voidbot",
producerRuntimeId: "voidbot-yggdrasil",
authorityClass: "operator_request_only",
status: "pending",
command,
};
}
test("six-command v1 accepts bounded Reviews and exact Review identity only", () => {
assert.equal(parseOperatorRequest(request({ kind: "reviews" })).command.kind, "reviews");
assert.deepEqual(commandTupleForInterop(parseOperatorRequest(request(review)).command), [
"review",
["mind-1", "candidate-1", hex, 41, "b".repeat(64), "adopt"],
]);
for (const hostile of [
{ ...review, candidateSha256: `sha256-${hex}` },
{ ...review, decision: "approve" },
{ ...review, expectedModelRevision: -1 },
{ ...review, proposalText: "private" },
]) assert.throws(() => parseOperatorRequest(request(hostile)));
});
test("v0 admission is drain-only and cannot acquire review authority", () => {
const packet = {
commandId: "command-1", nonce: "nonce-1", sourceEventId: "event-1",
sourceActorId: "actor", discordGuildId: "guild", discordChannelId: "ops",
discordMessageId: "message-1", targetRuntimeId: "epiphany-yggdrasil",
issuedAt: "2026-07-19T12:00:00Z", expiresAt: "2026-07-19T12:01:00Z",
command: { kind: "reviews" },
};
const admission = {
schemaName: "bifrost.operator_command.delivery",
schemaVersion: "bifrost.operator_command.delivery.v0",
admissionId: "request-1", packet, packetSha256: `sha256-${hex}`,
sourceObserverId: "voidbot", sourceObserverRuntimeId: "voidbot-yggdrasil",
provider: "bifrost", bifrostAdmissionReceiptId: "request-1",
authority: "exact_operator_command_only", providerIdentityId: "bifrost",
providerSignature: new Uint8Array(64),
};
assert.throws(() => parseOperatorAdmission(admission, { allowLegacy: true }), /cannot carry Mind review/);
assert.throws(() => parseOperatorAdmission(admission), /current admission schema/);
});
test("v1 result exposes only bounded review identities and status", () => {
const result = {
schemaVersion: "epiphany.operator_command.result.v1", resultId: "result-1",
commandId: "command-1", packetSha256: `sha256-${hex}`,
targetRuntimeId: "epiphany-yggdrasil", disposition: "observed",
consequenceKind: "mind-review-candidates", consequenceRef: "",
completedAt: "2026-07-19T12:00:01Z", privateStateExposed: false,
operatorStatus: "", stateStatus: "", coordinatorAction: "", brakeStatus: "",
detail: "1 pending Mind review candidate(s)",
reviews: [{ mindRequestId: "mind-1", candidateId: "candidate-1",
candidateSha256: hex, modelRevision: 41,
modelHash: "b".repeat(64), frontierItemId: "frontier-1",
requestedAt: "2026-07-19T11:59:00Z" }],
reviewCandidateId: "", reviewDecision: "",
};
assert.equal(wireResultTuple(parseOperatorResult(result)).length, 18);
assert.throws(() => parseOperatorResult({ ...result, reviews: [...result.reviews, ...Array(10).fill(result.reviews[0])] }), /bounded/);
assert.throws(() => parseOperatorResult({ ...result, proposalText: "private" }));
});

File diff suppressed because one or more lines are too long

View file

@ -1,36 +1,43 @@
export const operatorRequestType="voidbot.discord.epiphany_operator_request";
export const operatorRequestSchema="voidbot.discord.epiphany_operator_request.v0";
export const operatorAdmissionType="bifrost.operator_command.delivery";
export const operatorAdmissionSchema="bifrost.operator_command.delivery.v0";
export const operatorAdmissionSchema="bifrost.operator_command.delivery.v1";
export const legacyOperatorAdmissionSchema="bifrost.operator_command.delivery.v0";
export const operatorResultType="epiphany.operator_command.result";
export const operatorResultSchema="epiphany.operator_command.result.v0";
export const operatorResultSchema="epiphany.operator_command.result.v1";
export const legacyOperatorResultSchema="epiphany.operator_command.result.v0";
export const operatorResultReceiptType="epiphany.operator_command.sealed_result";
export const operatorResultReceiptSchema="epiphany.operator_command.sealed_result.v0";
export const operatorResultReceiptSchema="epiphany.operator_command.sealed_result.v1";
export const legacyOperatorResultReceiptSchema="epiphany.operator_command.sealed_result.v0";
export const operatorTerminalType="bifrost.operator_command.terminal";
export const operatorTerminalSchema="bifrost.operator_command.terminal.v0";
export const operatorDiscordDeliveryType="bifrost.discord.epiphany_operator_delivery";
export const operatorDiscordDeliverySchema="bifrost.discord.epiphany_operator_delivery.v0";
export const operatorDiscordDeliverySchema="bifrost.discord.epiphany_operator_delivery.v1";
export function buildOperatorDefinitions(defineDocumentType){const make=(type,schemaId,name,parse)=>defineDocumentType({type,schemaName:type,schemaId,schemaVersion:schemaId,contentHash:schemaId,global:false,name,schema:{parse}});return {request:make(operatorRequestType,operatorRequestSchema,"requestId",parseOperatorRequest),admission:make(operatorAdmissionType,operatorAdmissionSchema,"admissionId",parseOperatorAdmission),result:make(operatorResultType,operatorResultSchema,"resultId",parseOperatorResult),sealedResult:make(operatorResultReceiptType,operatorResultReceiptSchema,"commandId",parseOperatorResultReceipt),terminal:make(operatorTerminalType,operatorTerminalSchema,"requestId",parseOperatorTerminal),discordDelivery:make(operatorDiscordDeliveryType,operatorDiscordDeliverySchema,"deliveryId",parseOperatorDiscordDelivery)};}
export function buildOperatorDefinitions(defineDocumentType){const make=(type,schemaId,name,parse)=>defineDocumentType({type,schemaName:type,schemaId,schemaVersion:schemaId,contentHash:schemaId,global:false,name,schema:{parse}});return {request:make(operatorRequestType,operatorRequestSchema,"requestId",parseOperatorRequest),admission:make(operatorAdmissionType,operatorAdmissionSchema,"admissionId",value=>parseOperatorAdmission(value,{allowLegacy:true})),result:make(operatorResultType,operatorResultSchema,"resultId",value=>parseOperatorResult(value,{allowLegacy:true})),sealedResult:make(operatorResultReceiptType,operatorResultReceiptSchema,"commandId",value=>parseOperatorResultReceipt(value,{allowLegacy:true})),terminal:make(operatorTerminalType,operatorTerminalSchema,"requestId",parseOperatorTerminal),discordDelivery:make(operatorDiscordDeliveryType,operatorDiscordDeliverySchema,"deliveryId",parseOperatorDiscordDelivery)};}
export function parseOperatorRequest(value){const v=exactRecord(value,["schemaName","schemaVersion","requestId","commandId","nonce","sourceEventId","sourceActorDiscordId","discordGuildId","discordChannelId","discordMessageId","targetRuntimeId","issuedAt","expiresAt","producerId","producerRuntimeId","authorityClass","status","command"],"operator request"); exact(v.schemaName,operatorRequestType,"schemaName");exact(v.schemaVersion,operatorRequestSchema,"schemaVersion"); for(const k of ["requestId","commandId","nonce","sourceEventId","sourceActorDiscordId","discordGuildId","discordChannelId","discordMessageId","targetRuntimeId","producerRuntimeId"])text(v[k],k); exact(v.producerId,"voidbot","producerId");exact(v.authorityClass,"operator_request_only","authorityClass");exact(v.status,"pending","status"); const issued=date(v.issuedAt,"issuedAt"),expires=date(v.expiresAt,"expiresAt");if(expires<=issued||expires-issued>60000)throw new Error("operator request TTL must be positive and at most 60 seconds.");parseCommand(v.command);return v;}
export function parseOperatorAdmission(v){v=exactRecord(v,["schemaName","schemaVersion","admissionId","packet","packetSha256","sourceObserverId","sourceObserverRuntimeId","provider","bifrostAdmissionReceiptId","authority","providerIdentityId","providerSignature"],"operator admission");exact(v.schemaName,operatorAdmissionType,"schemaName");exact(v.schemaVersion,operatorAdmissionSchema,"schemaVersion");for(const k of ["admissionId","packetSha256","sourceObserverRuntimeId","bifrostAdmissionReceiptId","providerIdentityId"])text(v[k],k);exact(v.sourceObserverId,"voidbot","sourceObserverId");exact(v.provider,"bifrost","provider");exact(v.authority,"exact_operator_command_only","authority");v.providerSignature=bytes(v.providerSignature,"providerSignature",64);parsePacket(v.packet);return v;}
export function parseOperatorResult(v){v=exactRecord(v,["schemaVersion","resultId","commandId","packetSha256","targetRuntimeId","disposition","consequenceKind","consequenceRef","completedAt","privateStateExposed","operatorStatus","stateStatus","coordinatorAction","brakeStatus","detail"],"operator result");exact(v.schemaVersion,operatorResultSchema,"schemaVersion");for(const k of ["resultId","commandId","packetSha256","targetRuntimeId","disposition","consequenceKind","completedAt"])text(v[k],k);if(!["observed","applied","refused"].includes(v.disposition))throw new Error("result disposition is invalid.");if(v.privateStateExposed!==false)throw new Error("operator result must not expose private state.");for(const k of ["consequenceRef","operatorStatus","stateStatus","coordinatorAction","brakeStatus","detail"])if(typeof v[k]!=="string")throw new Error(`${k} must be a string.`);date(v.completedAt,"completedAt");return v;}
export function parseOperatorResultReceipt(v){v=exactRecord(v,["schemaVersion","result","resultPayloadSha256","commandId","packetSha256","targetRuntimeId","completedAt","providerIdentityId","privateStateExposed","executorSignature"],"operator sealed result receipt");exact(v.schemaVersion,operatorResultReceiptSchema,"schemaVersion");parseOperatorResult(v.result);for(const k of ["resultPayloadSha256","commandId","packetSha256","targetRuntimeId","completedAt","providerIdentityId"])text(v[k],k);date(v.completedAt,"completedAt");if(v.privateStateExposed!==false)throw new Error("operator sealed result receipt must not expose private state.");v.executorSignature=bytes(v.executorSignature,"executorSignature",64);return v;}
export function parseOperatorAdmission(v,{allowLegacy=false}={}){v=exactRecord(v,["schemaName","schemaVersion","admissionId","packet","packetSha256","sourceObserverId","sourceObserverRuntimeId","provider","bifrostAdmissionReceiptId","authority","providerIdentityId","providerSignature"],"operator admission");exact(v.schemaName,operatorAdmissionType,"schemaName");if(v.schemaVersion!==operatorAdmissionSchema&&!(allowLegacy&&v.schemaVersion===legacyOperatorAdmissionSchema))throw new Error("schemaVersion must be the current admission schema.");for(const k of ["admissionId","packetSha256","sourceObserverRuntimeId","bifrostAdmissionReceiptId","providerIdentityId"])text(v[k],k);exact(v.sourceObserverId,"voidbot","sourceObserverId");exact(v.provider,"bifrost","provider");exact(v.authority,"exact_operator_command_only","authority");v.providerSignature=bytes(v.providerSignature,"providerSignature",64);parsePacket(v.packet);if(v.schemaVersion===legacyOperatorAdmissionSchema&&["reviews","review"].includes(v.packet.command.kind))throw new Error("legacy v0 admission cannot carry Mind review commands.");return v;}
export function parseOperatorResult(v,{allowLegacy=false}={}){const legacy=v?.schemaVersion===legacyOperatorResultSchema;if(legacy&&!allowLegacy)throw new Error("legacy result is replay-only.");v=exactRecord(v,legacy?["schemaVersion","resultId","commandId","packetSha256","targetRuntimeId","disposition","consequenceKind","consequenceRef","completedAt","privateStateExposed","operatorStatus","stateStatus","coordinatorAction","brakeStatus","detail"]:["schemaVersion","resultId","commandId","packetSha256","targetRuntimeId","disposition","consequenceKind","consequenceRef","completedAt","privateStateExposed","operatorStatus","stateStatus","coordinatorAction","brakeStatus","detail","reviews","reviewCandidateId","reviewDecision"],"operator result");if(!legacy)exact(v.schemaVersion,operatorResultSchema,"schemaVersion");for(const k of ["resultId","commandId","packetSha256","targetRuntimeId","disposition","consequenceKind","completedAt"])text(v[k],k);if(!["observed","applied","refused"].includes(v.disposition))throw new Error("result disposition is invalid.");if(v.privateStateExposed!==false)throw new Error("operator result must not expose private state.");for(const k of ["consequenceRef","operatorStatus","stateStatus","coordinatorAction","brakeStatus","detail"]){if(typeof v[k]!=="string")throw new Error(`${k} must be a string.`);if(v[k].length>512)throw new Error(`${k} exceeds 512 characters.`);}if(!legacy){for(const k of ["reviewCandidateId","reviewDecision"]){if(typeof v[k]!=="string")throw new Error(`${k} must be a string.`);if(v[k].length>256)throw new Error(`${k} exceeds 256 characters.`);}if(!Array.isArray(v.reviews)||v.reviews.length>10)throw new Error("operator reviews must be a bounded array.");v.reviews.forEach(parseReviewSummary);if(v.reviewDecision&&!['adopt','refuse','hold'].includes(v.reviewDecision))throw new Error("reviewDecision is invalid.");}date(v.completedAt,"completedAt");return v;}
export function parseOperatorResultReceipt(v,{allowLegacy=false}={}){v=exactRecord(v,["schemaVersion","result","resultPayloadSha256","commandId","packetSha256","targetRuntimeId","completedAt","providerIdentityId","privateStateExposed","executorSignature"],"operator sealed result receipt");const legacy=v.schemaVersion===legacyOperatorResultReceiptSchema;if(legacy&&!allowLegacy)throw new Error("legacy sealed result is replay-only.");if(!legacy)exact(v.schemaVersion,operatorResultReceiptSchema,"schemaVersion");parseOperatorResult(v.result,{allowLegacy});if(legacy!== (v.result.schemaVersion===legacyOperatorResultSchema))throw new Error("sealed result and embedded result versions differ.");for(const k of ["resultPayloadSha256","commandId","packetSha256","targetRuntimeId","completedAt","providerIdentityId"])text(v[k],k);date(v.completedAt,"completedAt");if(v.privateStateExposed!==false)throw new Error("operator sealed result receipt must not expose private state.");v.executorSignature=bytes(v.executorSignature,"executorSignature",64);return v;}
export function parseOperatorTerminal(v){v=exactRecord(v,["schemaVersion","requestId","commandId","status","failureCode","recordedAt","retryable","privateStateExposed"],"operator terminal disposition");exact(v.schemaVersion,operatorTerminalSchema,"schemaVersion");for(const k of ["requestId","commandId","failureCode","recordedAt"])text(v[k],k);exact(v.status,"refused","status");date(v.recordedAt,"recordedAt");if(v.retryable!==false||v.privateStateExposed!==false)throw new Error("operator terminal disposition must be non-retryable and private-state-free.");return v;}
export function parseOperatorDiscordDelivery(v){v=exactRecord(v,["schemaVersion","deliveryId","requestId","requestPayloadSha256","commandId","discordGuildId","discordChannelId","discordInteractionId","targetRuntimeId","status","disposition","failureCode","detail","operatorStatus","stateStatus","coordinatorAction","brakeStatus","sealedResultPayloadSha256","executorSignatureSha256","resultProviderIdentityId","recordedAt","privateStateExposed"],"operator Discord delivery");exact(v.schemaVersion,operatorDiscordDeliverySchema,"schemaVersion");for(const k of ["deliveryId","requestId","requestPayloadSha256","commandId","discordGuildId","discordChannelId","discordInteractionId","targetRuntimeId","status","recordedAt"])text(v[k],k);if(!/^sha256-[0-9a-f]{64}$/.test(v.requestPayloadSha256))throw new Error("operator Discord delivery request digest is invalid.");if(!["completed","refused"].includes(v.status))throw new Error("operator Discord delivery status is invalid.");for(const k of ["disposition","failureCode","detail","operatorStatus","stateStatus","coordinatorAction","brakeStatus","sealedResultPayloadSha256","executorSignatureSha256","resultProviderIdentityId"])if(typeof v[k]!=="string")throw new Error(`${k} must be a string.`);for(const k of ["detail","operatorStatus","stateStatus","coordinatorAction","brakeStatus"])if(v[k].length>512)throw new Error(`operator Discord delivery ${k} exceeds 512 characters.`);if(v.status==="completed"&&(!v.disposition||!/^sha256-[0-9a-f]{64}$/.test(v.sealedResultPayloadSha256)||!/^sha256-[0-9a-f]{64}$/.test(v.executorSignatureSha256)||!v.resultProviderIdentityId))throw new Error("completed operator Discord delivery lacks sealed-result binding.");if(v.status==="refused"&&!v.failureCode)throw new Error("refused operator Discord delivery lacks failure code.");date(v.recordedAt,"recordedAt");if(v.privateStateExposed!==false)throw new Error("operator Discord delivery must not expose private state.");return v;}
export function parseOperatorDiscordDelivery(v){v=exactRecord(v,["schemaVersion","deliveryId","requestId","requestPayloadSha256","commandId","discordGuildId","discordChannelId","discordInteractionId","targetRuntimeId","status","disposition","failureCode","detail","operatorStatus","stateStatus","coordinatorAction","brakeStatus","reviews","reviewCandidateId","reviewDecision","sealedResultPayloadSha256","executorSignatureSha256","resultProviderIdentityId","recordedAt","privateStateExposed"],"operator Discord delivery");exact(v.schemaVersion,operatorDiscordDeliverySchema,"schemaVersion");for(const k of ["deliveryId","requestId","requestPayloadSha256","commandId","discordGuildId","discordChannelId","discordInteractionId","targetRuntimeId","status","recordedAt"])text(v[k],k);if(!/^sha256-[0-9a-f]{64}$/.test(v.requestPayloadSha256))throw new Error("operator Discord delivery request digest is invalid.");if(!["completed","refused"].includes(v.status))throw new Error("operator Discord delivery status is invalid.");for(const k of ["disposition","failureCode","detail","operatorStatus","stateStatus","coordinatorAction","brakeStatus","reviewCandidateId","reviewDecision","sealedResultPayloadSha256","executorSignatureSha256","resultProviderIdentityId"])if(typeof v[k]!=="string")throw new Error(`${k} must be a string.`);if(!Array.isArray(v.reviews)||v.reviews.length>10)throw new Error("operator Discord delivery reviews must be bounded.");v.reviews.forEach(parseReviewSummary);if(v.reviewDecision&&!['adopt','refuse','hold'].includes(v.reviewDecision))throw new Error("operator Discord delivery reviewDecision is invalid.");for(const k of ["detail","operatorStatus","stateStatus","coordinatorAction","brakeStatus"])if(v[k].length>512)throw new Error(`operator Discord delivery ${k} exceeds 512 characters.`);if(v.status==="completed"&&(!v.disposition||!/^sha256-[0-9a-f]{64}$/.test(v.sealedResultPayloadSha256)||!/^sha256-[0-9a-f]{64}$/.test(v.executorSignatureSha256)||!v.resultProviderIdentityId))throw new Error("completed operator Discord delivery lacks sealed-result binding.");if(v.status==="refused"&&!v.failureCode)throw new Error("refused operator Discord delivery lacks failure code.");date(v.recordedAt,"recordedAt");if(v.privateStateExposed!==false)throw new Error("operator Discord delivery must not expose private state.");return v;}
export function operatorRequestTuple(v){return [v.schemaName,v.schemaVersion,v.requestId,v.commandId,v.nonce,v.sourceEventId,v.sourceActorDiscordId,v.discordGuildId,v.discordChannelId,v.discordMessageId,v.targetRuntimeId,v.issuedAt,v.expiresAt,v.producerId,v.producerRuntimeId,v.authorityClass,v.status,commandTuple(v.command)];}
export function packetTuple(p){return [p.commandId,p.nonce,p.sourceEventId,p.sourceActorId,p.discordGuildId,p.discordChannelId,p.discordMessageId,p.targetRuntimeId,p.issuedAt,p.expiresAt,commandTuple(p.command)];}
export function admissionTuple(a){return [a.schemaVersion,a.admissionId,packetTuple(a.packet),a.packetSha256,a.sourceObserverId,a.sourceObserverRuntimeId,a.provider,a.bifrostAdmissionReceiptId,a.authority,a.providerIdentityId];}
// rmp-serde's compact serializer encodes the nested Rust wire-result struct as
// this positional array inside the signed tuple. The separately hashed result
// payload is encoded with named fields.
export function wireResultTuple(v){return [v.schemaVersion,v.resultId,v.commandId,v.packetSha256,v.targetRuntimeId,v.disposition,v.consequenceKind,v.consequenceRef,v.completedAt,v.privateStateExposed,v.operatorStatus,v.stateStatus,v.coordinatorAction,v.brakeStatus,v.detail];}
export function wireResultTuple(v){const tuple=[v.schemaVersion,v.resultId,v.commandId,v.packetSha256,v.targetRuntimeId,v.disposition,v.consequenceKind,v.consequenceRef,v.completedAt,v.privateStateExposed,v.operatorStatus,v.stateStatus,v.coordinatorAction,v.brakeStatus,v.detail];return v.schemaVersion===legacyOperatorResultSchema?tuple:[...tuple,v.reviews.map(reviewSummaryTuple),v.reviewCandidateId,v.reviewDecision];}
export function resultReceiptTuple(v){return [v.schemaVersion,wireResultTuple(v.result),v.resultPayloadSha256,v.commandId,v.packetSha256,v.targetRuntimeId,v.completedAt,v.providerIdentityId,v.privateStateExposed];}
function parsePacket(v){v=exactRecord(v,["commandId","nonce","sourceEventId","sourceActorId","discordGuildId","discordChannelId","discordMessageId","targetRuntimeId","issuedAt","expiresAt","command"],"operator packet");for(const k of ["commandId","nonce","sourceEventId","sourceActorId","discordGuildId","discordChannelId","discordMessageId","targetRuntimeId"])text(v[k],k);date(v.issuedAt,"issuedAt");date(v.expiresAt,"expiresAt");parseCommand(v.command);return v;}
function parseCommand(v){if(!v||typeof v!=="object"||Array.isArray(v))throw new Error("command must be an object.");if(v.kind==="status"||v.kind==="wake")return exactRecord(v,["kind"],"command");if(v.kind==="sleep"){exactRecord(v,["kind","reason"],"command");text(v.reason,"reason");if(v.reason.length>512)throw new Error("sleep reason exceeds 512 characters.");return v;}if(v.kind==="directive"){exactRecord(v,["kind","objective"],"command");text(v.objective,"objective");if(v.objective.length>4096)throw new Error("directive objective exceeds 4096 characters.");return v;}throw new Error("command kind is invalid.");}
function parseCommand(v){if(!v||typeof v!=="object"||Array.isArray(v))throw new Error("command must be an object.");if(["status","wake","reviews"].includes(v.kind))return exactRecord(v,["kind"],"command");if(v.kind==="sleep"){exactRecord(v,["kind","reason"],"command");text(v.reason,"reason");if(v.reason.length>512)throw new Error("sleep reason exceeds 512 characters.");return v;}if(v.kind==="directive"){exactRecord(v,["kind","objective"],"command");text(v.objective,"objective");if(v.objective.length>4096)throw new Error("directive objective exceeds 4096 characters.");return v;}if(v.kind==="review"){exactRecord(v,["kind","mindRequestId","candidateId","candidateSha256","expectedModelRevision","expectedModelHash","decision"],"command");for(const k of ["mindRequestId","candidateId"]){text(v[k],k);if(v[k].length>256)throw new Error(`${k} exceeds 256 characters.`);}hex64(v.candidateSha256,"candidateSha256");hex64(v.expectedModelHash,"expectedModelHash");if(!Number.isSafeInteger(v.expectedModelRevision)||v.expectedModelRevision<0)throw new Error("expectedModelRevision must be an unsigned safe integer.");if(!["adopt","refuse","hold"].includes(v.decision))throw new Error("review decision is invalid.");return v;}throw new Error("command kind is invalid.");}
// rmp-serde's compact enum form is the snake-case unit variant string, or a
// two-element [variant, sole-field] tuple for these one-field struct variants.
function commandTuple(v){if(v.kind==="sleep")return ["sleep",v.reason];if(v.kind==="directive")return ["directive",v.objective];return v.kind;}
function commandTuple(v){if(v.kind==="sleep")return ["sleep",v.reason];if(v.kind==="directive")return ["directive",v.objective];if(v.kind==="review")return ["review",[v.mindRequestId,v.candidateId,v.candidateSha256,v.expectedModelRevision,v.expectedModelHash,v.decision]];return v.kind;}
export const commandTupleForInterop=commandTuple;
function parseReviewSummary(v){exactRecord(v,["mindRequestId","candidateId","candidateSha256","modelRevision","modelHash","frontierItemId","requestedAt"],"review summary");for(const k of ["mindRequestId","candidateId","frontierItemId"]){text(v[k],k);if(v[k].length>256)throw new Error(`review ${k} exceeds 256 characters.`);}hex64(v.candidateSha256,"candidateSha256");hex64(v.modelHash,"modelHash");if(!Number.isSafeInteger(v.modelRevision)||v.modelRevision<0)throw new Error("review modelRevision is invalid.");date(v.requestedAt,"requestedAt");return v;}
function reviewSummaryTuple(v){return [v.mindRequestId,v.candidateId,v.candidateSha256,v.modelRevision,v.modelHash,v.frontierItemId,v.requestedAt];}
function hex64(v,label){if(typeof v!=="string"||!/^[0-9a-fA-F]{64}$/.test(v))throw new Error(`${label} must be 64 hexadecimal characters.`);return v;}
function exactRecord(v,keys,label){if(!v||typeof v!=="object"||Array.isArray(v))throw new Error(`${label} must be an object.`);const actual=Object.keys(v).sort(),expected=[...keys].sort();if(actual.join("\0")!==expected.join("\0"))throw new Error(`${label} has unknown or missing fields.`);return v;}
function text(v,label){if(typeof v!=="string"||!v.trim())throw new Error(`${label} is required.`);return v;}
function exact(v,e,label){if(v!==e)throw new Error(`${label} must be ${e}.`);}

View file

@ -3,7 +3,7 @@ import { resolve } from "node:path";
import { admissionTuple,operatorAdmissionSchema,parseOperatorAdmission,parseOperatorRequest,parseOperatorResult,parseOperatorResultReceipt,packetTuple } from "./epiphany-operator-command-documents.mjs";
import { enrollSignedIdentity,loadSignedIdentity,signPurpose,trustAnchor } from "./bifrost-signed-identity.mjs";
export const OPERATOR_SIGNING_PURPOSE="bifrost.operator-command.delivery.v0";
export const OPERATOR_SIGNING_PURPOSE="bifrost.operator-command.delivery.v1";
export const defaultOperatorIdentityPath=()=>process.env.BIFROST_EPIPHANY_OPERATOR_PRIVATE_KEY??(process.platform==="win32"?resolve(".bifrost","private","epiphany-operator-ed25519.seed"):"/var/lib/gamecult/bifrost/epiphany-operator/operator-ed25519.seed");
export class OperatorCommandPermanentRefusal extends Error { constructor(code,message){super(message);this.name="OperatorCommandPermanentRefusal";this.code=code;this.retryable=false;} }
@ -17,9 +17,9 @@ export async function admitOperatorRequest({request,ownerDiscordId,actorLink,ide
if(existingAdmission){
await compareAdmission(ledger,request,existingAdmission);
if(existingCompletion){
parseOperatorResultReceipt(existingCompletion);
parseOperatorResultReceipt(existingCompletion,{allowLegacy:true});
if(existingCompletion.commandId!==existingAdmission.packet.commandId||existingCompletion.packetSha256!==existingAdmission.packetSha256||existingCompletion.targetRuntimeId!==existingAdmission.packet.targetRuntimeId)refuse("command-id-collision","operator completion is not bound to this exact durable admission");
transport.verifyReceipt(existingAdmission,existingCompletion);
parseOperatorAdmission(existingAdmission,{allowLegacy:true});transport.verifyReceipt(existingAdmission,existingCompletion);
return {admission:existingAdmission,result:existingCompletion.result,receipt:existingCompletion,resultProviderIdentityId:existingCompletion.providerIdentityId,recovered:true};
}
return executeAdmission({request,admission:existingAdmission,transport,ledger,recovered:true});

View file

@ -6,6 +6,7 @@ import { readFile } from "node:fs/promises";
import { resolve } from "node:path";
import {
operatorAdmissionType,
legacyOperatorResultReceiptSchema,
operatorResultReceiptType,
parseOperatorAdmission,
parseOperatorResultReceipt,
@ -13,7 +14,8 @@ import {
} from "./epiphany-operator-command-documents.mjs";
import { verifyPurpose } from "./bifrost-signed-identity.mjs";
export const EPIPHANY_RESULT_SIGNING_PURPOSE="epiphany.operator-command.sealed-result.v0";
export const EPIPHANY_RESULT_SIGNING_PURPOSE="epiphany.operator-command.sealed-result.v1";
export const LEGACY_EPIPHANY_RESULT_SIGNING_PURPOSE="epiphany.operator-command.sealed-result.v0";
const RUDP_CONNECTION_ID=0xe91f0001;
export class EpiphanyOperatorCultNetRudpTransport {
@ -41,7 +43,7 @@ export class EpiphanyOperatorCultNetRudpTransport {
}
async #executeOne(admission){
parseOperatorAdmission(admission);
parseOperatorAdmission(admission,{allowLegacy:true});
const socket=this.socketFactory("udp4");
await bindSocket(socket);
const connection=this.connectionFactory({runtimeId:this.runtimeId,socket,mode:"client",remoteHost:this.endpoint.host,remotePort:this.endpoint.port,connectionId:RUDP_CONNECTION_ID,resendDelayMs:50,resendPollMs:10});
@ -61,7 +63,7 @@ export class EpiphanyOperatorCultNetRudpTransport {
export async function loadEpiphanyOperatorTrustAnchor(path,{decode}={}){const runtime=decode?{decode}:loadCultNetRuntime().msgpack,value=runtime.decode(await readFile(path));if(!Array.isArray(value)||value.length!==6)throw new Error("Epiphany operator trust anchor must be the raw compact 6-field MessagePack crossing artifact.");return parseTrustAnchor({schemaVersion:value[0],identityId:value[1],publicKey:value[2],assurance:value[3],identityCreatedAt:value[4],sourceIdentityRecordSha256:value[5]});}
export function verifySealedReceipt({receipt,admission,trustedIdentity,encode}){
parseOperatorAdmission(admission);parseOperatorResultReceipt(receipt);const anchor=parseTrustAnchor(trustedIdentity);
parseOperatorAdmission(admission,{allowLegacy:true});parseOperatorResultReceipt(receipt,{allowLegacy:true});const anchor=parseTrustAnchor(trustedIdentity);
if(receipt.providerIdentityId!==anchor.identityId)throw new Error("Epiphany sealed result used an untrusted host identity.");
if(receipt.commandId!==admission.packet.commandId||receipt.packetSha256!==admission.packetSha256||receipt.targetRuntimeId!==admission.packet.targetRuntimeId)throw new Error("Epiphany sealed result receipt is not bound to the admitted command.");
if(receipt.result.commandId!==receipt.commandId||receipt.result.packetSha256!==receipt.packetSha256||receipt.result.targetRuntimeId!==receipt.targetRuntimeId||receipt.result.completedAt!==receipt.completedAt)throw new Error("Epiphany sealed result receipt substituted its embedded application result.");
@ -73,7 +75,8 @@ export function verifySealedReceipt({receipt,admission,trustedIdentity,encode}){
if(completed<issued)throw new Error("Epiphany sealed result predates the admitted command.");
const digest=`sha256-${createHash("sha256").update(encode(receipt.result)).digest("hex")}`;
if(digest!==receipt.resultPayloadSha256)throw new Error("Epiphany sealed result payload digest is invalid.");
if(!verifyPurpose(anchor.publicKey,EPIPHANY_RESULT_SIGNING_PURPOSE,encode(resultReceiptTuple(receipt)),receipt.executorSignature))throw new Error("Epiphany sealed result signature is invalid.");
const purpose=receipt.schemaVersion===legacyOperatorResultReceiptSchema?LEGACY_EPIPHANY_RESULT_SIGNING_PURPOSE:EPIPHANY_RESULT_SIGNING_PURPOSE;
if(!verifyPurpose(anchor.publicKey,purpose,encode(resultReceiptTuple(receipt)),receipt.executorSignature))throw new Error("Epiphany sealed result signature is invalid.");
return receipt;
}

View file

@ -1,3 +1,4 @@
import { createHash } from "node:crypto";
import { createRequire } from "node:module";
import { existsSync } from "node:fs";
@ -9,11 +10,12 @@ export class EpiphanyOperatorDiscordOutbox {
static async open(path,{cultcacheRuntime,encode}={}){const runtime=cultcacheRuntime??loadCultCacheRuntime(),definition=buildOperatorDefinitions(runtime.defineDocumentType).discordDelivery,cache=runtime.CultCache.builder().withDocumentType(definition).withGenericStore(new runtime.SingleFileMessagePackBackingStore(path)).build();if(typeof encode!=="function")throw new Error("operator Discord outbox requires the canonical MessagePack encoder");await cache.pullAllBackingStores();return new EpiphanyOperatorDiscordOutbox(cache,definition,encode);}
get(requestId){return this.cache.get(this.definition,requestId);}
isExactDelivery(request){const value=this.get(request.requestId);return Boolean(value&&value.requestPayloadSha256===this.requestDigest(request)&&value.commandId===request.commandId&&value.discordGuildId===request.discordGuildId&&value.discordChannelId===request.discordChannelId&&value.discordInteractionId===request.sourceEventId&&value.targetRuntimeId===request.targetRuntimeId);}
async publishCompleted(request,receipt){const value=this.base(request,{status:"completed",disposition:receipt.result.disposition,failureCode:"",detail:receipt.result.detail,operatorStatus:receipt.result.operatorStatus,stateStatus:receipt.result.stateStatus,coordinatorAction:receipt.result.coordinatorAction,brakeStatus:receipt.result.brakeStatus,sealedResultPayloadSha256:receipt.resultPayloadSha256,executorSignatureSha256:`sha256-${createHash("sha256").update(receipt.executorSignature).digest("hex")}`,resultProviderIdentityId:receipt.providerIdentityId,recordedAt:receipt.completedAt});return this.put(value);}
async publishRefused(request,terminal){const value=this.base(request,{status:"refused",disposition:"",failureCode:terminal.failureCode,detail:terminal.failureCode,operatorStatus:"",stateStatus:"",coordinatorAction:"",brakeStatus:"",sealedResultPayloadSha256:"",executorSignatureSha256:"",resultProviderIdentityId:"",recordedAt:terminal.recordedAt});return this.put(value);}
async publishCompleted(request,receipt){validateReviewProjection(request,receipt.result);const value=this.base(request,{status:"completed",disposition:receipt.result.disposition,failureCode:"",detail:receipt.result.detail,operatorStatus:receipt.result.operatorStatus,stateStatus:receipt.result.stateStatus,coordinatorAction:receipt.result.coordinatorAction,brakeStatus:receipt.result.brakeStatus,reviews:receipt.result.reviews??[],reviewCandidateId:receipt.result.reviewCandidateId??"",reviewDecision:receipt.result.reviewDecision??"",sealedResultPayloadSha256:receipt.resultPayloadSha256,executorSignatureSha256:`sha256-${createHash("sha256").update(receipt.executorSignature).digest("hex")}`,resultProviderIdentityId:receipt.providerIdentityId,recordedAt:receipt.completedAt});return this.put(value);}
async publishRefused(request,terminal){const value=this.base(request,{status:"refused",disposition:"",failureCode:terminal.failureCode,detail:terminal.failureCode,operatorStatus:"",stateStatus:"",coordinatorAction:"",brakeStatus:"",reviews:[],reviewCandidateId:"",reviewDecision:"",sealedResultPayloadSha256:"",executorSignatureSha256:"",resultProviderIdentityId:"",recordedAt:terminal.recordedAt});return this.put(value);}
requestDigest(request){return `sha256-${createHash("sha256").update(this.encode(operatorRequestTuple(request))).digest("hex")}`;}
base(request,result){return {schemaVersion:"bifrost.discord.epiphany_operator_delivery.v0",deliveryId:request.requestId,requestId:request.requestId,requestPayloadSha256:this.requestDigest(request),commandId:request.commandId,discordGuildId:request.discordGuildId,discordChannelId:request.discordChannelId,discordInteractionId:request.sourceEventId,targetRuntimeId:request.targetRuntimeId,...result,privateStateExposed:false};}
base(request,result){return {schemaVersion:"bifrost.discord.epiphany_operator_delivery.v1",deliveryId:request.requestId,requestId:request.requestId,requestPayloadSha256:this.requestDigest(request),commandId:request.commandId,discordGuildId:request.discordGuildId,discordChannelId:request.discordChannelId,discordInteractionId:request.sourceEventId,targetRuntimeId:request.targetRuntimeId,...result,privateStateExposed:false};}
async put(value){const current=this.get(value.requestId);if(current&&stable(current)!==stable(value))throw new Error("operator Discord delivery identity collision");if(!current)await this.cache.put(this.definition,value.deliveryId,value);return current??value;}
}
function loadCultCacheRuntime(){const root=resolve(import.meta.dirname,".."),projects=resolve(root,".."),cult=resolve(process.env.VOIDBOT_CULTLIB_ROOT||resolve(projects,"CultLib")),pkg=resolve(cult,"packages","cultcache-ts","package.json");if(!existsSync(pkg))throw new Error(`CultCache TypeScript runtime is unavailable at ${pkg}.`);const requireCult=createRequire(pkg);return requireCult("cultcache-ts");}
function validateReviewProjection(request,result){const reviews=result.reviews??[],candidate=result.reviewCandidateId??"",decision=result.reviewDecision??"";if(request.command.kind==="reviews"){if(candidate||decision)throw new Error("Reviews result carries a decision binding");return;}if(request.command.kind==="review"){if(reviews.length||candidate!==request.command.candidateId||decision!==request.command.decision)throw new Error("Review result does not bind the exact requested candidate and decision");return;}if(reviews.length||candidate||decision)throw new Error("non-review result carries Mind review state");}
function stable(v){return JSON.stringify(v,(_k,x)=>x instanceof Uint8Array?Buffer.from(x).toString("hex"):x);}

View file

@ -158,19 +158,18 @@ const surfaceSchemaId = "gamecult.eve.surface_state.v1";
const interfaceBindingDocumentType = "gamecult.eve.interface_binding";
const interfaceBindingSchemaId = "gamecult.eve.interface_binding.v1";
const verseId = "bifrost.local";
const rootVerse = "asgard";
const currentMachine = "starfire";
const rootVerse = requiredDeploymentIdentity("BIFROST_ROOT_VERSE");
const currentMachine = requiredDeploymentIdentity("BIFROST_MACHINE_ID");
const canonicalService = `${rootVerse}.bifrost`;
const locatedService = `${rootVerse}.${currentMachine}.bifrost`;
const plannedLocatedService = `${rootVerse}.yggdrasil.bifrost`;
const motionSurfaceCultMeshUri = `cultmesh://${locatedService}/eve/governance/surface`;
const motionCommandCultMeshUri = `cultmesh://${locatedService}/commands/motion`;
const epiphanyOperatorRequestSchemaId = "voidbot.discord.epiphany_operator_request.v0";
const epiphanyOperatorAdmissionSchemaId = "bifrost.operator_command.delivery.v0";
const epiphanyOperatorResultSchemaId = "epiphany.operator_command.result.v0";
const epiphanyOperatorSealedResultSchemaId = "epiphany.operator_command.sealed_result.v0";
const epiphanyOperatorAdmissionSchemaId = "bifrost.operator_command.delivery.v1";
const epiphanyOperatorResultSchemaId = "epiphany.operator_command.result.v1";
const epiphanyOperatorSealedResultSchemaId = "epiphany.operator_command.sealed_result.v1";
const epiphanyOperatorTerminalSchemaId = "bifrost.operator_command.terminal.v0";
const epiphanyOperatorDiscordDeliverySchemaId = "bifrost.discord.epiphany_operator_delivery.v0";
const epiphanyOperatorDiscordDeliverySchemaId = "bifrost.discord.epiphany_operator_delivery.v1";
const advertisementDefinition = defineDocumentType({
type: documentType,
@ -323,7 +322,6 @@ function buildAdvertisement(options) {
rootVerse,
canonicalService,
locatedService,
plannedLocatedService,
cultMeshAddress: locatedService,
endpoints: [
endpoint("operator-tui", `${locatedService}/eve/tui`, "gamecult.eve.surface.v1", ["tui", "nightwing-tui"]),
@ -349,7 +347,7 @@ function buildAdvertisement(options) {
presentationOwner: "Eve/CultUI",
discoveryOwner: "Odin through CultMesh",
stateOwner: "Bifrost typed state with CultCache .cc witnesses or export paths",
runtimeMigration: `currently ${locatedService}; planned move target ${plannedLocatedService}`,
runtimeMigration: `deployment identity ${locatedService}`,
},
namespaces: [
namespace("gamecult.bifrost.service", "service registration, build/version, schema catalog, and command discovery"),
@ -971,7 +969,6 @@ function buildInterfaceBinding(surface, stats) {
cultMeshAddress: `${locatedService}/eve/tui`,
canonicalService,
locatedService,
plannedLocatedService,
endpoints: [
endpoint("operator-tui", `${locatedService}/eve/tui`, "gamecult.eve.surface.v1", ["tui", "nightwing-tui"]),
endpoint("operator-gui", `${locatedService}/eve/gui`, "gamecult.eve.surface.v1", ["gui", "browser", "eve-native"]),
@ -1186,7 +1183,6 @@ function parseAdvertisement(input, { requireCurrentContract = true } = {}) {
rootVerse: optionalString(input.rootVerse, rootVerse),
canonicalService: optionalString(input.canonicalService, canonicalService),
locatedService: optionalString(input.locatedService, locatedService),
plannedLocatedService: typeof input.plannedLocatedService === "string" ? input.plannedLocatedService.trim() : "",
cultMeshAddress: optionalString(input.cultMeshAddress, locatedService),
endpoints: Array.isArray(input.endpoints) ? requireObjectArray(input.endpoints, "endpoints") : [],
routes: Array.isArray(input.routes) ? requireObjectArray(input.routes, "routes") : [],
@ -1305,6 +1301,14 @@ function resolveOptionPath(path) {
return resolve(process.cwd(), path);
}
function requiredDeploymentIdentity(name) {
const value = process.env[name];
if (typeof value !== "string" || !/^[a-z0-9][a-z0-9-]*$/.test(value)) {
throw new Error(`${name} must explicitly name this deployment using lowercase letters, digits, or hyphens.`);
}
return value;
}
function printJson(value) {
process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
}