Gate deployments with typed release authority

This commit is contained in:
Meta Vens 2026-07-16 18:28:13 +01:00
commit 3bd250f811
3 changed files with 409 additions and 0 deletions

View file

@ -8,6 +8,15 @@ import {
beginCrossingReceipt,
crossingProvenanceFromOptions,
} from "./bifrost-crossing-documents.mjs";
import {
buildAuthorizedRelease,
canonicalCommitSha,
canonicalRef,
canonicalRepository,
openRepositoryReleaseAuthorityStore,
releaseAuthorityId,
revokeAuthorizedRelease,
} from "./bifrost-repository-release-authority.mjs";
const PERSONA_WEBHOOK_NAME = "Bifrost Persona Pipe";
const PERSONA_WEBHOOK_CACHE_PATH = resolve(".bifrost/discord-webhook-cache.json");
@ -45,11 +54,101 @@ async function main() {
case "other-request":
await requestOtherBridgeAction(options);
return;
case "authorize-release":
await authorizeRepositoryRelease(options);
return;
case "revoke-release":
await revokeRepositoryRelease(options);
return;
default:
throw new Error(`Unknown command "${command}". Run "node tools/bifrost-bridge.mjs help".`);
}
}
async function authorizeRepositoryRelease(options) {
ensureGitHubBridgeGate(options);
const commandId = optionalString(options["cultmesh-command-id"]) ?? optionalString(process.env.BIFROST_CULTMESH_COMMAND_ID);
if (!commandId) throw new Error("authorize-release requires BIFROST_CULTMESH_COMMAND_ID or --cultmesh-command-id.");
const repository = canonicalRepository(requireOption(options, "repository"));
const ref = canonicalRef(requireOption(options, "ref"));
const commitSha = canonicalCommitSha(requireOption(options, "commit-sha"));
const policyDecisionId = requireOption(options, "policy-decision-id");
const authorityReference = requireOption(options, "authority-ref");
const actorIdentity = requireOption(options, "identity");
const sourceKind = requireOption(options, "source-kind");
const sourceId = requireOption(options, "source-id");
const epiphanyRunId = requireOption(options, "epiphany-run-id");
const epiphanyLaneId = requireOption(options, "epiphany-lane-id");
const epiphanyAgentIdentity = requireOption(options, "epiphany-agent-identity");
const remoteUrl = options["remote-url"] ?? `https://github.com/${repository}.git`;
const gitCommand = optionalString(options["git-executable"]) ?? resolveGitCommand();
const gitPrefixArgs = optionalString(options["git-exec-args"])?.split("\u001f").filter(Boolean) ?? [];
const remote = run(gitCommand, [...gitPrefixArgs, "ls-remote", "--refs", remoteUrl, ref], repoRoot).stdout.trim().split(/\r?\n/).filter(Boolean);
if (remote.length !== 1) throw new Error(`Remote ref ${repository}:${ref} did not resolve exactly once.`);
const [remoteSha, remoteRef] = remote[0].trim().split(/\s+/);
if (canonicalCommitSha(remoteSha) !== commitSha || remoteRef !== ref) {
throw new Error(`Remote ref ${repository}:${ref} does not exactly match requested commit ${commitSha}.`);
}
const storePath = resolve(options["release-authority-store"] ?? process.env.BIFROST_REPOSITORY_RELEASE_AUTHORITY_STORE ?? ".bifrost/repository-release-authority.cc");
const store = await openRepositoryReleaseAuthorityStore(storePath);
const authorityId = releaseAuthorityId(repository, ref, commitSha);
const existing = store.get(authorityId);
if (existing) {
if (existing.commandId === commandId && existing.status === "authorized") {
printJson({ ok: true, action: "authorize-release", authority: existing, idempotent: true });
return;
}
throw new Error(`Release authority ${authorityId} already exists; immutable authority records cannot be replaced.`);
}
const competing = store.getAll().find((authority) =>
authority.repositoryFullName === repository &&
authority.upstreamRef === ref &&
authority.status === "authorized"
);
if (competing) {
throw new Error(
`Release authority ${competing.authorityId} already authorizes ${repository}:${ref}; revoke it before authorizing another commit.`,
);
}
const externalReceiptUrl = `https://github.com/${repository}/commit/${commitSha}`;
const crossing = await beginCrossingReceipt({ ...options, "receipt-id": undefined }, {
commandId,
crossingKind: "github.repository_release_verification",
actor: { kind: "service", name: actorIdentity, bifrostIdentity: actorIdentity },
source: { kind: sourceKind, id: sourceId },
authority: { authorityRef: authorityReference, policyDecisionId },
epiphany: { runId: epiphanyRunId, laneId: epiphanyLaneId, agentIdentity: epiphanyAgentIdentity },
target: { surface: "GitHub", repositoryFullName: repository, upstreamRef: ref, commitSha },
});
await crossing.start();
await crossing.complete({ externalReceipt: { url: externalReceiptUrl, id: commitSha, repositoryFullName: repository, upstreamRef: ref, commitSha } });
const authority = await store.put(buildAuthorizedRelease({
repositoryFullName: repository, upstreamRef: ref, commitSha, commandId,
crossingReceiptId: crossing.receiptId, policyDecisionId, authorityReference,
actorIdentity, sourceKind, sourceId, epiphanyRunId, epiphanyLaneId,
epiphanyAgentIdentity, externalReceiptUrl, externalReceiptId: commitSha,
authorizedAt: new Date().toISOString(), expiresAt: optionalString(options["expires-at"]) ?? "",
}));
printJson({ ok: true, action: "authorize-release", authority });
}
async function revokeRepositoryRelease(options) {
ensureGitHubBridgeGate(options);
const commandId = optionalString(options["cultmesh-command-id"]) ?? optionalString(process.env.BIFROST_CULTMESH_COMMAND_ID);
if (!commandId) throw new Error("revoke-release requires BIFROST_CULTMESH_COMMAND_ID or --cultmesh-command-id.");
const repository = canonicalRepository(requireOption(options, "repository"));
const ref = canonicalRef(requireOption(options, "ref"));
const commitSha = canonicalCommitSha(requireOption(options, "commit-sha"));
const reason = requireOption(options, "reason");
const storePath = resolve(options["release-authority-store"] ?? process.env.BIFROST_REPOSITORY_RELEASE_AUTHORITY_STORE ?? ".bifrost/repository-release-authority.cc");
const store = await openRepositoryReleaseAuthorityStore(storePath);
const authorityId = releaseAuthorityId(repository, ref, commitSha);
const current = store.get(authorityId);
if (!current) throw new Error(`Release authority ${authorityId} does not exist.`);
const authority = await store.put(revokeAuthorizedRelease(current, { commandId, reason, revokedAt: new Date().toISOString() }));
printJson({ ok: true, action: "revoke-release", authority });
}
function loadBifrostLocalEnv() {
if (process.env.BIFROST_SKIP_LOCAL_ENV === "true") {
return;
@ -1360,6 +1459,8 @@ Commands:
discord-dm Send a Discord DM through Bifrost's bridge-owned bot token
reddit-post Create a self-post in r/GameCultOrg through the Bifrost Reddit app
other-request Record a Bifrost-gated request for a future outside-world surface
authorize-release Authorize one exact remote GitHub ref and commit for downstream deployment
revoke-release Revoke the current authorization for one GitHub repository ref
Examples:
node tools/bifrost-bridge.mjs github-draft-pr --repo-root E:/Projects/AetheriaLore --identity nibu --title "Nibu: Glitchcraft" --path Aetheria/Articles/Nibu/glitchcraft.md --content-file article.md

View file

@ -0,0 +1,169 @@
import { createRequire } from "node:module";
import { existsSync } from "node:fs";
import { mkdir } from "node:fs/promises";
import { dirname, resolve } from "node:path";
const repoRoot = resolve(import.meta.dirname, "..");
const projectsRoot = resolve(repoRoot, "..");
const cultLibRoot = resolve(process.env.VOIDBOT_CULTLIB_ROOT || resolve(projectsRoot, "CultLib"));
export const repositoryReleaseAuthorityDocumentType = "bifrost.repository_release_authority";
export const repositoryReleaseAuthoritySchemaId = "bifrost.repository_release_authority.v1";
export const defaultRepositoryReleaseAuthorityStorePath = resolve(repoRoot, ".bifrost", "repository-release-authority.cc");
let cachedRuntime;
let cachedDefinition;
export function repositoryReleaseAuthorityDefinition(defineDocumentTypeInput) {
const defineDocumentType = defineDocumentTypeInput ?? loadCultCacheRuntime().defineDocumentType;
cachedDefinition ??= defineDocumentType({
type: repositoryReleaseAuthorityDocumentType,
schemaId: repositoryReleaseAuthoritySchemaId,
schemaName: repositoryReleaseAuthorityDocumentType,
schemaVersion: repositoryReleaseAuthoritySchemaId,
contentHash: repositoryReleaseAuthoritySchemaId,
global: false,
name: "authorityId",
indexes: { repositoryFullName: "repositoryFullName", upstreamRef: "upstreamRef", commitSha: "commitSha", status: "status" },
schema: { parse: parseRepositoryReleaseAuthority },
members: [
{ slot: 1, memberName: "authorityId", typeName: "string", isName: true },
{ slot: 2, memberName: "commandId", typeName: "string" },
{ slot: 3, memberName: "crossingReceiptId", typeName: "string" },
{ slot: 4, memberName: "repositoryFullName", typeName: "string", indexAlias: "repositoryFullName" },
{ slot: 5, memberName: "upstreamRef", typeName: "string", indexAlias: "upstreamRef" },
{ slot: 6, memberName: "commitSha", typeName: "string", indexAlias: "commitSha" },
{ slot: 7, memberName: "decision", typeName: "string" },
{ slot: 8, memberName: "status", typeName: "string", indexAlias: "status" },
{ slot: 9, memberName: "policyDecisionId", typeName: "string" },
{ slot: 10, memberName: "authorityReference", typeName: "string" },
{ slot: 11, memberName: "actorIdentity", typeName: "string" },
{ slot: 12, memberName: "sourceKind", typeName: "string" },
{ slot: 13, memberName: "sourceId", typeName: "string" },
{ slot: 14, memberName: "epiphanyRunId", typeName: "string" },
{ slot: 15, memberName: "epiphanyLaneId", typeName: "string" },
{ slot: 16, memberName: "epiphanyAgentIdentity", typeName: "string" },
{ slot: 17, memberName: "externalReceiptUrl", typeName: "string" },
{ slot: 18, memberName: "externalReceiptId", typeName: "string" },
{ slot: 19, memberName: "authorizedAt", typeName: "string" },
{ slot: 20, memberName: "expiresAt", typeName: "string" },
{ slot: 21, memberName: "revokedAt", typeName: "string" },
{ slot: 22, memberName: "revocationReason", typeName: "string" },
],
});
return cachedDefinition;
}
export async function openRepositoryReleaseAuthorityStore(storePath = defaultRepositoryReleaseAuthorityStorePath) {
const { CultCache, SingleFileMessagePackBackingStore } = loadCultCacheRuntime();
await mkdir(dirname(storePath), { recursive: true });
const cache = CultCache.builder().withDocumentType(repositoryReleaseAuthorityDefinition()).withGenericStore(new SingleFileMessagePackBackingStore(storePath)).build();
await cache.pullAllBackingStores();
return {
storePath,
async put(document) {
const parsed = parseRepositoryReleaseAuthority(document);
await cache.put(repositoryReleaseAuthorityDefinition(), parsed.authorityId, parsed);
return parsed;
},
get(authorityId) { return cache.get(repositoryReleaseAuthorityDefinition(), authorityId); },
getAll() { return cache.getAll(repositoryReleaseAuthorityDefinition()); },
};
}
export function releaseAuthorityId(repositoryFullName, upstreamRef, commitSha) {
return `release:${canonicalRepository(repositoryFullName)}:${canonicalRef(upstreamRef)}:${canonicalCommitSha(commitSha)}`;
}
export function buildAuthorizedRelease(input) {
const repositoryFullName = canonicalRepository(input.repositoryFullName);
const upstreamRef = canonicalRef(input.upstreamRef);
const commitSha = canonicalCommitSha(input.commitSha);
return parseRepositoryReleaseAuthority({
schemaName: repositoryReleaseAuthorityDocumentType,
schemaVersion: repositoryReleaseAuthoritySchemaId,
authorityId: releaseAuthorityId(repositoryFullName, upstreamRef, commitSha),
commandId: input.commandId,
crossingReceiptId: input.crossingReceiptId,
repositoryFullName,
upstreamRef,
commitSha,
decision: "authorize",
status: "authorized",
policyDecisionId: input.policyDecisionId,
authorityReference: input.authorityReference,
actorIdentity: input.actorIdentity,
sourceKind: input.sourceKind,
sourceId: input.sourceId,
epiphanyRunId: input.epiphanyRunId,
epiphanyLaneId: input.epiphanyLaneId,
epiphanyAgentIdentity: input.epiphanyAgentIdentity,
externalReceiptUrl: input.externalReceiptUrl,
externalReceiptId: input.externalReceiptId,
authorizedAt: input.authorizedAt,
expiresAt: input.expiresAt ?? "",
revokedAt: "",
revocationReason: "",
});
}
export function revokeAuthorizedRelease(current, input) {
const parsed = parseRepositoryReleaseAuthority(current);
if (parsed.status !== "authorized") throw new Error(`Release authority ${parsed.authorityId} is already revoked.`);
return parseRepositoryReleaseAuthority({ ...parsed, status: "revoked", revokedAt: requiredString(input.revokedAt, "revokedAt"), revocationReason: requiredString(input.reason, "revocationReason") });
}
export function canonicalRepository(value) {
const repository = requiredString(value, "repositoryFullName").replace(/^https?:\/\/github\.com\//i, "").replace(/\.git$/i, "").replace(/^\/+|\/+$/g, "");
if (!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repository)) throw new Error("repositoryFullName must be a canonical GitHub owner/name.");
return repository;
}
export function canonicalRef(value) {
const ref = requiredString(value, "upstreamRef");
if (!/^refs\/(heads|tags)\/[A-Za-z0-9._\/-]+$/.test(ref) || ref.includes("..") || ref.endsWith("/")) throw new Error("upstreamRef must be a canonical refs/heads/... or refs/tags/... name.");
return ref;
}
export function canonicalCommitSha(value) {
const sha = requiredString(value, "commitSha").toLowerCase();
if (!/^[0-9a-f]{40}$/.test(sha)) throw new Error("commitSha must be an exact 40-character hexadecimal Git commit SHA.");
return sha;
}
function parseRepositoryReleaseAuthority(input) {
if (!input || typeof input !== "object" || Array.isArray(input)) throw new Error("Bifrost repository release authority must be an object.");
const repositoryFullName = canonicalRepository(input.repositoryFullName);
const upstreamRef = canonicalRef(input.upstreamRef);
const commitSha = canonicalCommitSha(input.commitSha);
const document = {
schemaName: repositoryReleaseAuthorityDocumentType,
schemaVersion: repositoryReleaseAuthoritySchemaId,
authorityId: requiredString(input.authorityId, "authorityId"), commandId: requiredString(input.commandId, "commandId"),
crossingReceiptId: requiredString(input.crossingReceiptId, "crossingReceiptId"), repositoryFullName, upstreamRef, commitSha,
decision: requiredString(input.decision, "decision"), status: requiredString(input.status, "status"), policyDecisionId: requiredString(input.policyDecisionId, "policyDecisionId"),
authorityReference: requiredString(input.authorityReference, "authorityReference"), actorIdentity: requiredString(input.actorIdentity, "actorIdentity"),
sourceKind: requiredString(input.sourceKind, "sourceKind"), sourceId: requiredString(input.sourceId, "sourceId"),
epiphanyRunId: requiredString(input.epiphanyRunId, "epiphanyRunId"), epiphanyLaneId: requiredString(input.epiphanyLaneId, "epiphanyLaneId"), epiphanyAgentIdentity: requiredString(input.epiphanyAgentIdentity, "epiphanyAgentIdentity"),
externalReceiptUrl: requiredString(input.externalReceiptUrl, "externalReceiptUrl"), externalReceiptId: requiredString(input.externalReceiptId, "externalReceiptId"),
authorizedAt: requiredString(input.authorizedAt, "authorizedAt"), expiresAt: optionalString(input.expiresAt) ?? "", revokedAt: optionalString(input.revokedAt) ?? "", revocationReason: optionalString(input.revocationReason) ?? "",
};
if (document.authorityId !== releaseAuthorityId(repositoryFullName, upstreamRef, commitSha)) throw new Error("authorityId must be derived from repositoryFullName, upstreamRef, and commitSha.");
if (document.decision !== "authorize") throw new Error("Repository release authority decision must be authorize.");
if (!new Set(["authorized", "revoked"]).has(document.status)) throw new Error(`Repository release authority status "${document.status}" is not valid.`);
if (document.status === "authorized" && (document.revokedAt || document.revocationReason)) throw new Error("Authorized release authority cannot carry revocation state.");
if (document.status === "revoked" && (!document.revokedAt || !document.revocationReason)) throw new Error("Revoked release authority requires revocation time and reason.");
return document;
}
function loadCultCacheRuntime() {
if (cachedRuntime) return cachedRuntime;
const candidates = [resolve(cultLibRoot, "packages", "cultcache-ts", "dist", "index.js"), resolve(projectsRoot, "CultCacheTS", "dist", "index.js")];
const entryPoint = candidates.find(existsSync);
if (!entryPoint) throw new Error(`CultCache TypeScript runtime is unavailable. Tried: ${candidates.join(", ")}`);
cachedRuntime = createRequire(entryPoint)(entryPoint);
return cachedRuntime;
}
function requiredString(value, field) { const result = optionalString(value); if (!result) throw new Error(`Bifrost repository release authority field "${field}" must be a non-empty string.`); return result; }
function optionalString(value) { if (typeof value !== "string") return undefined; const trimmed = value.trim(); return trimmed || undefined; }