Clarify Bifrost observability receipts

This commit is contained in:
Meta Vens 2026-05-21 19:55:53 +01:00
commit db1d908de2
3 changed files with 63 additions and 11 deletions

View file

@ -215,13 +215,19 @@ function allowsUnmirrored(options) {
function renderRequestMirrorFallback(request) {
const actor = request.createdByAgent ? `${request.createdByAgent} queued` : "Queued";
return [
`Bifrost intake: ${actor} a work request.`,
`Bifrost update request queued`,
"",
`**${request.targetRepoName}: ${request.title}**`,
`Request: \`${request.id}\``,
`Target: ${request.targetAgentIdentity ? `${request.targetAgentIdentity} / ` : ""}${request.targetRepoName}`,
`Status: queued`,
`Codex job: no - this request is waiting for the dispatcher`,
"",
`${actor} this work request.`,
"",
summarizeRequestMarkdown(request.requestMarkdown),
"",
`Request: \`${request.id}\``,
`Next: a separate \`Bifrost Codex dispatch started\` receipt means a Codex turn actually began.`,
].join("\n");
}

View file

@ -427,11 +427,15 @@ function renderDispatchReceiptContent(request) {
? `${request.targetAgentIdentity} / ${request.targetRepoName}`
: request.targetRepoName;
return [
`Bifrost dispatch receipt`,
`Bifrost Codex dispatch started`,
``,
`**${request.targetRepoName}: ${topic}**`,
`Request: \`${request.id}\``,
`Target: ${actor}`,
`Status: claimed by dispatcher`,
`Codex job: started`,
``,
`Codex has started a turn for ${actor}. The claim is now specific enough to inspect, and the work is no longer sitting unclaimed in chat.`,
`Codex has started a turn. The claim is now specific enough to inspect, and the work is no longer sitting unclaimed in chat.`,
`Keep discussion here if it sharpens this request; Bifrost will carry the result back across the bridge.`,
].join("\n");
}

View file

@ -359,9 +359,11 @@ async function mirrorTopicActivityOrThrow(cache, topic, input) {
optionalString(process.env.BIFROST_DISCORD_PERSONA_AVATAR_URL) ??
optionalString(process.env.DISCORD_PERSONA_AVATAR_URL_BIFROST) ??
defaultPersonaAvatarUrl;
const mirrorContent =
await readOptionalMarkdownOption(input.options, "mirror-content") ??
renderMirrorFallback(topic, input.eventLabel, input.fallbackContent);
const mirrorContent = renderGovernanceMirrorContent(
topic,
input.eventLabel,
await readOptionalMarkdownOption(input.options, "mirror-content") ?? input.fallbackContent,
);
const now = new Date().toISOString();
const receipt = runNodeJson([
@ -403,16 +405,56 @@ function allowsUnmirrored(options) {
return options["allow-unmirrored"] === "true" || process.env.BIFROST_ALLOW_UNMIRRORED_GOVERNANCE === "true";
}
function renderMirrorFallback(topic, eventLabel, content) {
function renderGovernanceMirrorContent(topic, eventLabel, content) {
const event = governanceMirrorEvent(eventLabel);
return [
`Bifrost ${eventLabel}: ${topic.title}`,
`Bifrost governance: ${event.label}`,
"",
content.trim(),
`**${topic.title}**`,
`Topic: \`${topic.id}\``,
`Jurisdiction: ${topic.jurisdictionRepoName}${topic.jurisdictionAgentIdentity ? ` / ${topic.jurisdictionAgentIdentity}` : ""}`,
`Topic status: ${topic.status}`,
`Codex job: ${event.codexJob}`,
"",
`Topic: ${topic.id}`,
truncateMarkdown(content.trim(), 1200),
"",
event.nextStep,
].join("\n");
}
function governanceMirrorEvent(eventLabel) {
switch (eventLabel) {
case "opened":
return {
label: "topic opened",
codexJob: "no - this is discussion/proposal intake only",
nextStep: "Next: comments, jurisdiction review, or approval. Nothing has been dispatched.",
};
case "approved":
return {
label: "topic approved",
codexJob: "no - approved topics still need promotion before dispatch",
nextStep: "Next: promotion creates a Bifrost update request. A separate dispatch receipt means Codex actually started.",
};
case "dispatched":
return {
label: "topic promoted to update request",
codexJob: "queued - Codex has not necessarily started yet",
nextStep: "Next: wait for a `Bifrost Codex dispatch started` receipt before treating this as an active Codex job.",
};
default:
return {
label: `topic ${eventLabel}`,
codexJob: "no - this is governance discussion, not dispatch",
nextStep: "Next: keep discussing, approve, or promote when the jurisdiction owner is ready.",
};
}
}
function truncateMarkdown(value, maxLength) {
return value.length > maxLength ? `${value.slice(0, maxLength - 3)}...` : value;
}
function listTopics(cache, options) {
const topics = cache.getAll(topicDefinition)
.filter((topic) => !options.status || topic.status === options.status)