Bifrost/tools/epiphany-operator-command-documents.mjs
2026-07-19 22:54:44 +01:00

86 lines
21 KiB
JavaScript

export const operatorRequestType="voidbot.discord.epiphany_operator_request";
export const operatorRequestSchema="voidbot.discord.epiphany_operator_request.v1";
export const operatorAdmissionType="bifrost.operator_command.delivery";
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.v1";
export const operatorStatusResultSchema="epiphany.operator_command.status_result.v2";
export const legacyOperatorResultSchema="epiphany.operator_command.result.v0";
export const operatorResultReceiptType="epiphany.operator_command.sealed_result";
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.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",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,{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,status=v?.schemaVersion===operatorStatusResultSchema;
if(legacy&&!allowLegacy)throw new Error("legacy result is replay-only.");
const base=["schemaVersion","resultId","commandId","packetSha256","targetRuntimeId","disposition","consequenceKind","consequenceRef","completedAt","privateStateExposed","operatorStatus","stateStatus","coordinatorAction","brakeStatus","detail"],current=[...base,"reviews","reviewCandidateId","reviewDecision"];
v=exactRecord(v,legacy?base:status?[...current,"statusV2"]:current,"operator result");
if(!legacy&&!status)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.");}
if(status)parseOperatorStatusV2(v.statusV2);
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","reviews","reviewCandidateId","reviewDecision","statusV2","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.");if(v.statusV2!==null)parseOperatorStatusV2(v.statusV2);if(v.status!=="completed"&&v.statusV2!==null)throw new Error("refused delivery cannot carry status v2.");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){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];if(v.schemaVersion===legacyOperatorResultSchema)return tuple;const current=[...tuple,v.reviews.map(reviewSummaryTuple),v.reviewCandidateId,v.reviewDecision];return v.schemaVersion===operatorStatusResultSchema?[...current,statusV2Tuple(v.statusV2)]:current;}
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(["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];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];}
export function parseOperatorStatusV2(v){
v=exactRecord(v,["schemaVersion","releaseId","releaseWitnessSha256","sourceCommit","deploymentId","coordinatorSnapshot","coordinatorState","coordinatorAction","brakeStatus","residentStatus","pressureCount","pendingReviewCount","providerSetStatus","providers","privateStateExposed"],"operator status v2");
exact(v.schemaVersion,"epiphany.operator.status.v2","status schemaVersion");
for(const k of ["releaseId","deploymentId","coordinatorSnapshot","coordinatorState","coordinatorAction","brakeStatus","residentStatus"]){text(v[k],k);if(v[k].length>256)throw new Error(`${k} exceeds 256 characters.`);}
digest(v.releaseWitnessSha256,"releaseWitnessSha256");if(!/^[0-9a-f]{40}$/.test(v.sourceCommit))throw new Error("sourceCommit must be a lowercase 40-character commit.");
for(const k of ["pressureCount","pendingReviewCount"])if(!Number.isSafeInteger(v[k])||v[k]<0||v[k]>1_000_000)throw new Error(`${k} is invalid.`);
if(!["complete-authenticated","incomplete"].includes(v.providerSetStatus))throw new Error("providerSetStatus is invalid.");
if(!Array.isArray(v.providers)||v.providers.length!==2)throw new Error("operator status v2 requires exactly two providers.");
const policies=[["yggdrasil-epiphany","epiphany.cultnet-rudp-runtime-health",true],["yggdrasil-bifrost-persona-feedback","bifrost.cultnet-rudp-persona-feedback-health",false]];
v.providers.forEach((p,i)=>parseStatusProvider(p,...policies[i]));
if(v.providers.every(p=>p.availability==="authenticated-current")!==(v.providerSetStatus==="complete-authenticated"))throw new Error("providerSetStatus does not match provider availability.");
if(v.privateStateExposed!==false)throw new Error("operator status v2 must not expose private state.");return v;
}
function parseStatusProvider(v,daemonId,contract,hasLineage){
v=exactRecord(v,["daemonId","healthContract","availability","unavailableReason","state","reasonCode","providerObservedAtUnixMillis","evaluatedAtUnixMillis","expiresAtUnixMillis","releaseId","releaseWitnessSha256","sourceCommit","deploymentId","projectionSha256"],"operator status provider");exact(v.daemonId,daemonId,"daemonId");exact(v.healthContract,contract,"healthContract");
if(!["authenticated-current","unavailable"].includes(v.availability))throw new Error("provider availability is invalid.");if(typeof v.unavailableReason!=="string"||v.unavailableReason.length>256)throw new Error("unavailableReason is invalid.");
for(const k of ["state","reasonCode","releaseId","sourceCommit","deploymentId"])if(v[k]!==null&&(typeof v[k]!=="string"||!v[k]||v[k].length>256))throw new Error(`${k} is invalid.`);
for(const k of ["providerObservedAtUnixMillis","evaluatedAtUnixMillis","expiresAtUnixMillis"])if(v[k]!==null&&(!Number.isSafeInteger(v[k])||v[k]<0))throw new Error(`${k} is invalid.`);
for(const k of ["releaseWitnessSha256","projectionSha256"])if(v[k]!==null)digest(v[k],k);if(v.sourceCommit!==null&&!/^[0-9a-f]{40}$/.test(v.sourceCommit))throw new Error("provider sourceCommit is invalid.");
const observed=["state","reasonCode","providerObservedAtUnixMillis","evaluatedAtUnixMillis","expiresAtUnixMillis","releaseId","releaseWitnessSha256","sourceCommit","deploymentId","projectionSha256"];
if(v.availability==="unavailable"){if(!v.unavailableReason||observed.some(k=>v[k]!==null))throw new Error("unavailable provider must carry only its reason.");}
else{if(v.unavailableReason||["state","reasonCode","providerObservedAtUnixMillis","evaluatedAtUnixMillis","expiresAtUnixMillis","projectionSha256"].some(k=>v[k]===null))throw new Error("authenticated provider lacks current bounded state.");if(hasLineage){if(["releaseId","releaseWitnessSha256","sourceCommit","deploymentId"].some(k=>v[k]===null))throw new Error("Epiphany provider lacks release lineage.");}else if(["releaseId","releaseWitnessSha256","sourceCommit","deploymentId"].some(k=>v[k]!==null))throw new Error("Bifrost provider must not claim Epiphany release lineage.");}
return v;
}
function statusProviderTuple(v){return [v.daemonId,v.healthContract,v.availability,v.unavailableReason,v.state,v.reasonCode,v.providerObservedAtUnixMillis,v.evaluatedAtUnixMillis,v.expiresAtUnixMillis,v.releaseId,v.releaseWitnessSha256,v.sourceCommit,v.deploymentId,v.projectionSha256];}
function statusV2Tuple(v){return [v.schemaVersion,v.releaseId,v.releaseWitnessSha256,v.sourceCommit,v.deploymentId,v.coordinatorSnapshot,v.coordinatorState,v.coordinatorAction,v.brakeStatus,v.residentStatus,v.pressureCount,v.pendingReviewCount,v.providerSetStatus,v.providers.map(statusProviderTuple),v.privateStateExposed];}
function digest(v,label){if(typeof v!=="string"||!/^sha256-[0-9a-f]{64}$/.test(v))throw new Error(`${label} must be a sha256 digest.`);return v;}
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}.`);}
function date(v,label){text(v,label);if(!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(v))throw new Error(`${label} must be RFC3339.`);const n=Date.parse(v);if(!Number.isFinite(n))throw new Error(`${label} must be RFC3339.`);return n;}
function bytes(v,label,length){const normalized=v instanceof Uint8Array?v:Array.isArray(v)&&v.every(x=>Number.isInteger(x)&&x>=0&&x<=255)?Uint8Array.from(v):null;if(!normalized||normalized.length!==length)throw new Error(`${label} must be ${length} bytes.`);return normalized;}