Intelligence

Artifacts

Browse the repository, read documents, and manage the governance folders. Source, runtime, and infrastructure are read-only.

Repository
README.md
CONSTITUTION_COMPLIANCE_AUDIT_V1.mdREADME.md
repositories/aaf-holdings/hq01/lib/executives/registry.ts
3.3 KB
import fs from "node:fs";
import path from "node:path";
import {
  CONSTITUTIONS_DIR,
  ORGANIZATION,
  REGISTRY_FILE,
  REGISTRY_ROOT,
} from "./config";
import { EXECUTIVE_OFFICES, INITIAL_ACTIVE_IDS } from "./offices";
import type { ExecutiveOffice, RegistryEntry } from "./types";

/**
 * Filesystem-first registry of executive offices. The registry is the runtime
 * source of truth (which offices exist, and which are active/executable). It is
 * seeded once from the office catalogue and thereafter mutated only through
 * approved proposals.
 */

function entryFromOffice(office: ExecutiveOffice): RegistryEntry {
  return {
    id: office.id,
    office: office.office,
    displayName: office.displayName,
    department: office.department,
    parent: office.parent,
    organization: ORGANIZATION,
    constitutionPath: path.join(CONSTITUTIONS_DIR, office.id) + path.sep,
    allowedRepositories: ["*"],
    allowedTools: [
      "claude-cli",
      "filesystem-read",
      "filesystem-write-approved",
      "session-manager",
    ],
    routes: office.routes,
    status: INITIAL_ACTIVE_IDS.has(office.id) ? "active" : "inactive",
  };
}

function writeRegistry(entries: RegistryEntry[]): void {
  fs.mkdirSync(REGISTRY_ROOT, { recursive: true });
  const tmp = `${REGISTRY_FILE}.tmp`;
  fs.writeFileSync(tmp, JSON.stringify(entries, null, 2) + "\n", "utf8");
  fs.renameSync(tmp, REGISTRY_FILE);
}

/**
 * Load the registry, seeding it on first use. Any office in the catalogue that
 * is missing from the registry is added (inactive) so new offices appear without
 * losing existing activation state — additive by construction.
 */
export function loadRegistry(): RegistryEntry[] {
  let entries: RegistryEntry[] = [];
  try {
    entries = JSON.parse(fs.readFileSync(REGISTRY_FILE, "utf8")) as RegistryEntry[];
  } catch {
    entries = [];
  }

  const byId = new Map(entries.map((e) => [e.id, e]));
  let changed = entries.length === 0;
  for (const office of EXECUTIVE_OFFICES) {
    if (!byId.has(office.id)) {
      byId.set(office.id, entryFromOffice(office));
      changed = true;
    }
  }

  const merged = [...byId.values()];
  if (changed) writeRegistry(merged);
  return merged;
}

export function getEntry(id: string): RegistryEntry | undefined {
  return loadRegistry().find((e) => e.id === id);
}

export function isActive(id: string): boolean {
  return getEntry(id)?.status === "active";
}

/** Persist a single entry (insert or replace by id). */
export function upsertEntry(entry: RegistryEntry): void {
  const entries = loadRegistry();
  const idx = entries.findIndex((e) => e.id === entry.id);
  if (idx >= 0) entries[idx] = entry;
  else entries.push(entry);
  writeRegistry(entries);
}

/** Activate an office (used when a proposal is approved). Returns the entry. */
export function activateOffice(
  id: string,
  patch: Partial<RegistryEntry> = {},
): RegistryEntry {
  const existing = getEntry(id);
  const office = EXECUTIVE_OFFICES.find((o) => o.id === id);
  const base = existing ?? (office ? entryFromOffice(office) : undefined);
  if (!base) {
    throw new Error(`No office definition for "${id}".`);
  }
  const entry: RegistryEntry = { ...base, ...patch, status: "active" };
  // Ensure the constitution folder exists for the now-active office.
  fs.mkdirSync(entry.constitutionPath, { recursive: true });
  upsertEntry(entry);
  return entry;
}

root · /srv/aaf