diff --git a/docs/agent-transport.md b/docs/agent-transport.md index bf32cbe..3c1c589 100644 --- a/docs/agent-transport.md +++ b/docs/agent-transport.md @@ -115,6 +115,8 @@ node .\tools\agent-transport.mjs snapshot --out E:\tmp\bifrost-agent-transport.m node .\tools\agent-transport.mjs apply-snapshot --in E:\tmp\bifrost-agent-transport.msgpack ``` +Dispatch receipts should use Bifrost's own public persona in the Bifrost governance channel. `tools/dispatch-agent-requests.mjs` reads `BIFROST_DISCORD_CHANNEL_ID` or `DISCORD_BIFROST_CHANNEL_ID` for the receipt target, uses persona name `Bifrost`, and defaults the persona avatar to the public `src/Bifrost.Web/wwwroot/img/bifrost-profile.png` raw GitHub URL unless `BIFROST_DISCORD_PERSONA_AVATAR_URL` or `DISCORD_PERSONA_AVATAR_URL_BIFROST` overrides it. + The `snapshot` command writes a MessagePack-encoded `cultnet.snapshot_response_raw.v0` message. This keeps CultCache payload bytes intact for peers that share the document binding. ## Codex Intake Plugin diff --git a/tools/dispatch-agent-requests.mjs b/tools/dispatch-agent-requests.mjs index dccccee..f40942d 100644 --- a/tools/dispatch-agent-requests.mjs +++ b/tools/dispatch-agent-requests.mjs @@ -13,6 +13,8 @@ const defaultStatusDir = resolve(bifrostRoot, ".bifrost", "agent-dispatch"); const defaultProjectsRoot = resolve(bifrostRoot, ".."); const defaultAquariumChannelId = "1501196543150264332"; const defaultPersonaName = "Bifrost"; +const defaultPersonaAvatarUrl = + "https://raw.githubusercontent.com/GameCult/Bifrost/main/src/Bifrost.Web/wwwroot/img/bifrost-profile.png"; async function main() { loadLocalEnv(resolve(bifrostRoot, ".env")); @@ -391,8 +393,13 @@ ${request.requestMarkdown} } function postDispatchReceipt(request, dispatchRecord, options) { - const channelId = options["channel-id"] ?? defaultAquariumChannelId; - const personaName = options["persona-name"] ?? defaultPersonaName; + const channelId = resolveDispatchReceiptChannelId(options); + const personaName = options["persona-name"] ?? process.env.BIFROST_DISCORD_PERSONA_NAME ?? defaultPersonaName; + const personaAvatarUrl = + optionalString(options["persona-avatar-url"]) ?? + optionalString(process.env.BIFROST_DISCORD_PERSONA_AVATAR_URL) ?? + optionalString(process.env.DISCORD_PERSONA_AVATAR_URL_BIFROST) ?? + defaultPersonaAvatarUrl; const topic = summarizeRequestTopic(request); const content = [ `Bifrost dispatch: ${request.targetAgentIdentity ?? "repo agent"} has this.`, @@ -408,10 +415,19 @@ function postDispatchReceipt(request, dispatchRecord, options) { "--channel-id", channelId, "--persona-name", personaName, "--content", content, - ...optionalArg("--persona-avatar-url", options["persona-avatar-url"]), + ...optionalArg("--persona-avatar-url", personaAvatarUrl), ], bifrostRoot); } +function resolveDispatchReceiptChannelId(options) { + return ( + optionalString(options["channel-id"]) ?? + optionalString(process.env.BIFROST_DISCORD_CHANNEL_ID) ?? + optionalString(process.env.DISCORD_BIFROST_CHANNEL_ID) ?? + defaultAquariumChannelId + ); +} + class CodexAppServerClient { constructor({ command, logPath }) { this.command = command;