UNPKG

@sellable/install

Version:

One-command installer for Sellable MCP in Claude Code, Codex, and Hermes

3,295 lines • 108 kB
import { createHash, randomUUID } from "node:crypto";
import {
  chmodSync,
  chownSync,
  closeSync,
  existsSync,
  fsyncSync,
  lstatSync,
  mkdirSync,
  openSync,
  readFileSync,
  readdirSync,
  realpathSync,
  renameSync,
  rm,
  rmSync,
  statfsSync,
  writeFileSync,
} from "node:fs";
import {
  basename,
  dirname,
  isAbsolute,
  join,
  relative,
  resolve,
} from "node:path";
import { parseDocument } from "yaml";
import {
  SELLABLE_BROWSER_TOOLSET_DEFAULT_MARKER,
  SELLABLE_DEFAULT_SLACK_TOOLSETS,
  sellableSlackToolsetsForMaterialization,
} from "./fly-capabilities-bridge.mjs";
import {
  FLY_CUSTOMER_MODEL_ID,
  FLY_CUSTOMER_MODEL_PROVIDER,
  FLY_CUSTOMER_MODEL_REASONING_EFFORT,
} from "./fly-customer-model.mjs";
import { withProfileSoulLock } from "./fly-soul-bridge.mjs";
import { HERMES_AGENT_BRIDGE_CONTRACT } from "./hermes-bridge.mjs";
import {
  HERMES_SNAPSHOT_HOOKS,
  HERMES_SNAPSHOT_HOOK_ALLOWLIST_BYTES,
  applyHermesSellableHostedPolicy,
  isHermesTransientProfilePath,
  linkHermesState,
  mergeHermesState,
} from "./hermes-memory-snapshot.mjs";
import { createMcpRuntimeBindingV2 } from "./mcp-runtime-binding.mjs";

export const PROFILE_MATERIALIZER_PORTS = Object.freeze({
  hostAppSecret: ["resolveHostSecret"],
  workspaceBotSecret: ["decryptWorkspaceSecret"],
  credential: ["install", "cleanup"],
  gateway: ["start", "stop", "observe"],
  containment: ["probe"],
  mcp: ["discoverTools", "safeRead"],
  ownership: ["apply", "observe", "remove"],
});

export const AGENT_PROFILE_INVENTORY = Object.freeze([
  "agent-profile.json",
  "config.yaml",
  "sellable/mcp.json",
  "SOUL.md",
  "skills/sellable/SKILL.md",
]);

const SAFE_ID = /^[A-Za-z0-9_-]{1,128}$/;
const MODEL_AUTH_ACTIVATION_ID = /^[A-Za-z0-9_.:-]{1,256}$/;
const SHA256 = /^[a-f0-9]{64}$/;
const FINGERPRINT = /^[a-f0-9]{16}$/;
const PRIVATE_REFERENCE = /^(?:secret|oauth-private):\/\/[A-Za-z0-9/_-]+$/;
const RAW_SECRET =
  /(?:^|[^A-Za-z0-9])(?:xapp|xoxb|xoxa|sat)_[A-Za-z0-9_-]+|(?:xapp|xoxb|xoxa)-[A-Za-z0-9_-]+|oauth-provider-secret-byte|asec\.v1\./i;
const NATIVE_SLACK_MATERIALIZATION_MARGIN_BYTES = 64 * 1024 * 1024;
export const SELLABLE_INTERNAL_AGENT_WORKSPACE_ID = "cmj0wv9pe02jx23xdv6wfhg9x";
const PRESSURE_CACHE_PATHS = Object.freeze([
  [".npm", "_npx"],
  [".npm", "_cacache"],
  [".cache", "uv"],
  [".cache", "pip"],
]);

function sha256(value) {
  return createHash("sha256").update(value).digest("hex");
}

function stableJson(value) {
  if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
  if (value && typeof value === "object") {
    return `{${Object.keys(value)
      .sort()
      .map((key) => `${JSON.stringify(key)}:${stableJson(value[key])}`)
      .join(",")}}`;
  }
  return JSON.stringify(value);
}

function filesystemAvailableBytes(pathValue) {
  const stats = statfsSync(pathValue);
  return Number(stats.bavail) * Number(stats.bsize);
}

function removeWithoutFollowing(pathValue) {
  if (!existsSync(pathValue)) return false;
  const entry = lstatSync(pathValue);
  rmSync(pathValue, {
    recursive: entry.isDirectory() && !entry.isSymbolicLink(),
    force: true,
  });
  return true;
}

function scheduleNativeSlackTreeRemoval(root, target) {
  if (dirname(target) !== root || basename(target) === "") {
    throw new Error("native_slack_profile_cleanup_path_rejected");
  }
  let entry;
  try {
    entry = lstatSync(target);
  } catch (error) {
    if (error?.code === "ENOENT") return false;
    throw error;
  }
  if (entry.isSymbolicLink() || !entry.isDirectory()) {
    throw new Error("native_slack_profile_cleanup_entry_rejected");
  }
  rm(target, { recursive: true, force: true }, (error) => {
    if (error && error.code !== "ENOENT") {
      process.stderr.write(
        `${JSON.stringify({
          ok: false,
          code: "native_slack_profile_cleanup_failed",
          entry: basename(target),
        })}\n`
      );
    }
  });
  return true;
}

function sweepStaleNativeSlackTrees(root, profileId) {
  const prefix = `.${profileId}.`;
  let scheduled = 0;
  for (const name of readdirSync(root)) {
    if (!name.startsWith(prefix)) continue;
    const staleRoot = join(root, name);
    let cleanupRoot = staleRoot;
    if (name.endsWith(".staging")) {
      cleanupRoot = join(root, `.${profileId}.${randomUUID()}.cleanup`);
      try {
        renameSync(staleRoot, cleanupRoot);
      } catch (error) {
        // A cleanup scheduled by the prior operation may still be finishing
        // after the profile lock is released. Treat that ENOENT as complete.
        if (error?.code === "ENOENT") continue;
        throw error;
      }
    } else if (!name.endsWith(".cleanup")) {
      continue;
    }
    if (scheduleNativeSlackTreeRemoval(root, cleanupRoot)) scheduled += 1;
  }
  return scheduled;
}

function prunePressureCaches(root) {
  if (basename(root) !== "profiles") return [];
  const dataRoot = dirname(root);
  const removed = [];
  for (const segments of PRESSURE_CACHE_PATHS) {
    const target = join(dataRoot, ...segments);
    if (removeWithoutFollowing(target)) removed.push(target);
  }
  return removed;
}

function materializationCauseCode(error) {
  if (error && typeof error === "object") {
    const code = error.code;
    if (typeof code === "string" && /^[A-Za-z0-9_.:-]{1,128}$/.test(code)) {
      return code;
    }
  }
  if (error instanceof Error) {
    const code = error.message.split(/[:\s]/, 1)[0];
    if (/^[A-Za-z0-9_.-]{1,128}$/.test(code)) return code;
  }
  return "native_slack_profile_unknown_failure";
}

function exactKeys(value, keys) {
  return (
    value &&
    typeof value === "object" &&
    !Array.isArray(value) &&
    Object.keys(value).sort().join("\0") === [...keys].sort().join("\0")
  );
}

function isInside(root, target) {
  const path = relative(root, target);
  return path === "" || (!path.startsWith("..") && !isAbsolute(path));
}

function privateRoot(pathValue) {
  try {
    if (!isAbsolute(pathValue) || !existsSync(pathValue)) return null;
    const link = lstatSync(pathValue);
    if (
      link.isSymbolicLink() ||
      !link.isDirectory() ||
      (link.mode & 0o077) !== 0
    )
      return null;
    return realpathSync(pathValue);
  } catch {
    return null;
  }
}

function traversableProfilesRoot(pathValue) {
  try {
    if (!isAbsolute(pathValue) || !existsSync(pathValue)) return null;
    const link = lstatSync(pathValue);
    const mode = link.mode & 0o777;
    if (
      link.isSymbolicLink() ||
      !link.isDirectory() ||
      (mode & 0o700) !== 0o700 ||
      (mode & 0o066) !== 0
    )
      return null;
    return realpathSync(pathValue);
  } catch {
    return null;
  }
}

export function deriveContainedProfileId(workspaceId, agentId, hostId) {
  return `agent-${createHash("sha256")
    .update(`profile\0${workspaceId}\0${agentId}\0${hostId}`)
    .digest("hex")
    .slice(0, 24)}`;
}

const DESIRED_KEYS = [
  "workspaceId",
  "agentId",
  "hostId",
  "workerId",
  "installationId",
  "slackGeneration",
  "fence",
  "revisionId",
  "revisionSequence",
  "hermesCli",
  "hermesVersion",
  "installerPackage",
  "mcpPackage",
  "workspaceLockId",
  "toolInclude",
  "policyHash",
  "slackManifestHash",
  "slackAppHash",
  "slackTeamHash",
  "slackBotHash",
  "slackChannelHash",
  "slackDefaultChannelHash",
  "slackMemberAllowlistHash",
  "slackChannelIds",
  "slackDefaultChannelId",
  "slackMemberAllowlist",
  "soul",
  "soulHash",
  "skill",
  "skillsHash",
  "providerReference",
  "providerFingerprint",
  "serviceCredentialReference",
  "serviceCredentialFingerprint",
  "serviceCredentialGeneration",
  "xappReference",
  "xappFingerprint",
  "xoxbReference",
  "xoxbCiphertextFingerprint",
];

function validateDesired(desired) {
  if (!exactKeys(desired, DESIRED_KEYS))
    return { ok: false, code: "desired_schema_invalid" };
  for (const key of [
    "workspaceId",
    "agentId",
    "hostId",
    "workerId",
    "installationId",
    "revisionId",
  ]) {
    if (!SAFE_ID.test(desired[key]))
      return { ok: false, code: "desired_identity_invalid", field: key };
  }
  if (
    desired.workspaceLockId !== desired.workspaceId ||
    !/^[1-9][0-9]{0,19}$/.test(desired.fence) ||
    !Number.isSafeInteger(desired.revisionSequence) ||
    desired.revisionSequence < 1 ||
    !Number.isSafeInteger(desired.slackGeneration) ||
    desired.slackGeneration < 1 ||
    !Number.isSafeInteger(desired.serviceCredentialGeneration) ||
    desired.serviceCredentialGeneration < 1 ||
    desired.hermesCli !== "hermes" ||
    desired.hermesVersion !== "0.18.0" ||
    desired.installerPackage !== "@sellable/install@0.1.804" ||
    desired.mcpPackage !== "@sellable/mcp@0.1.957" ||
    !Array.isArray(desired.toolInclude) ||
    desired.toolInclude.length === 0 ||
    desired.toolInclude.some((tool) => !/^[a-z][a-z0-9_]{0,127}$/.test(tool)) ||
    new Set(desired.toolInclude).size !== desired.toolInclude.length ||
    JSON.stringify([...desired.toolInclude].sort()) !==
      JSON.stringify(desired.toolInclude) ||
    !Array.isArray(desired.slackChannelIds) ||
    desired.slackChannelIds.length === 0 ||
    desired.slackChannelIds.some((id) => !/^C[A-Z0-9]{8,20}$/.test(id)) ||
    JSON.stringify([...new Set(desired.slackChannelIds)].sort()) !==
      JSON.stringify(desired.slackChannelIds) ||
    !desired.slackChannelIds.includes(desired.slackDefaultChannelId) ||
    !Array.isArray(desired.slackMemberAllowlist) ||
    desired.slackMemberAllowlist.length === 0 ||
    desired.slackMemberAllowlist.some(
      (id) => !/^[UW][A-Z0-9]{8,20}$/.test(id)
    ) ||
    JSON.stringify([...new Set(desired.slackMemberAllowlist)].sort()) !==
      JSON.stringify(desired.slackMemberAllowlist)
  ) {
    return { ok: false, code: "desired_runtime_invalid" };
  }
  for (const key of [
    "policyHash",
    "slackManifestHash",
    "slackAppHash",
    "slackTeamHash",
    "slackBotHash",
    "slackChannelHash",
    "slackDefaultChannelHash",
    "slackMemberAllowlistHash",
    "soulHash",
    "skillsHash",
    "providerFingerprint",
  ]) {
    if (!SHA256.test(desired[key]))
      return { ok: false, code: "desired_hash_invalid", field: key };
  }
  if (
    sha256(desired.soul) !== desired.soulHash ||
    sha256(desired.skill) !== desired.skillsHash ||
    sha256(stableJson(desired.slackChannelIds)) !== desired.slackChannelHash ||
    sha256(desired.slackDefaultChannelId) !== desired.slackDefaultChannelHash ||
    sha256(stableJson(desired.slackMemberAllowlist)) !==
      desired.slackMemberAllowlistHash ||
    !PRIVATE_REFERENCE.test(desired.providerReference) ||
    !PRIVATE_REFERENCE.test(desired.serviceCredentialReference) ||
    !PRIVATE_REFERENCE.test(desired.xappReference) ||
    !PRIVATE_REFERENCE.test(desired.xoxbReference) ||
    !FINGERPRINT.test(desired.serviceCredentialFingerprint) ||
    !FINGERPRINT.test(desired.xappFingerprint) ||
    !FINGERPRINT.test(desired.xoxbCiphertextFingerprint) ||
    RAW_SECRET.test(desired.soul) ||
    RAW_SECRET.test(desired.skill)
  ) {
    return { ok: false, code: "desired_secret_or_content_invalid" };
  }
  return { ok: true };
}

const MANIFEST_KEYS = [
  "schemaVersion",
  "producer",
  "subject",
  "profileId",
  "workspaceId",
  "agentId",
  "hostId",
  "workerId",
  "installationId",
  "slackGeneration",
  "fence",
  "revisionId",
  "revisionSequence",
  "hermesCli",
  "hermesVersion",
  "installerPackage",
  "mcpPackage",
  "workspaceLockId",
  "toolInclude",
  "policyHash",
  "slackManifestHash",
  "slackAppHash",
  "slackTeamHash",
  "slackBotHash",
  "slackChannelHash",
  "slackDefaultChannelHash",
  "slackMemberAllowlistHash",
  "soulHash",
  "skillsHash",
  "providerReference",
  "slackChannelIds",
  "slackDefaultChannelId",
  "slackMemberAllowlist",
  "providerFingerprint",
  "serviceCredentialReference",
  "serviceCredentialFingerprint",
  "serviceCredentialGeneration",
  "xappReference",
  "xappFingerprint",
  "xoxbReference",
  "xoxbCiphertextFingerprint",
  "fileHashes",
  "profileDigest",
];

function manifestBody(desired) {
  const profileId = deriveContainedProfileId(
    desired.workspaceId,
    desired.agentId,
    desired.hostId
  );
  return {
    schemaVersion: "sellable-agent-profile/v1",
    producer: "sellable-agent-profile-materializer",
    subject: `agent-profile:${profileId}`,
    profileId,
    workspaceId: desired.workspaceId,
    agentId: desired.agentId,
    hostId: desired.hostId,
    workerId: desired.workerId,
    installationId: desired.installationId,
    slackGeneration: desired.slackGeneration,
    fence: desired.fence,
    revisionId: desired.revisionId,
    revisionSequence: desired.revisionSequence,
    hermesCli: desired.hermesCli,
    hermesVersion: desired.hermesVersion,
    installerPackage: desired.installerPackage,
    mcpPackage: desired.mcpPackage,
    workspaceLockId: desired.workspaceLockId,
    toolInclude: [...desired.toolInclude],
    policyHash: desired.policyHash,
    slackManifestHash: desired.slackManifestHash,
    slackAppHash: desired.slackAppHash,
    slackTeamHash: desired.slackTeamHash,
    slackBotHash: desired.slackBotHash,
    slackChannelHash: desired.slackChannelHash,
    slackDefaultChannelHash: desired.slackDefaultChannelHash,
    slackMemberAllowlistHash: desired.slackMemberAllowlistHash,
    slackChannelIds: [...desired.slackChannelIds],
    slackDefaultChannelId: desired.slackDefaultChannelId,
    slackMemberAllowlist: [...desired.slackMemberAllowlist],
    soulHash: desired.soulHash,
    skillsHash: desired.skillsHash,
    providerReference: desired.providerReference,
    providerFingerprint: desired.providerFingerprint,
    serviceCredentialReference: desired.serviceCredentialReference,
    serviceCredentialFingerprint: desired.serviceCredentialFingerprint,
    serviceCredentialGeneration: desired.serviceCredentialGeneration,
    xappReference: desired.xappReference,
    xappFingerprint: desired.xappFingerprint,
    xoxbReference: desired.xoxbReference,
    xoxbCiphertextFingerprint: desired.xoxbCiphertextFingerprint,
  };
}

export function buildAgentProfileManifest(desired) {
  const valid = validateDesired(desired);
  if (!valid.ok) return valid;
  return { ok: true, manifest: manifestBody(desired) };
}

function configFor(desired, profileId) {
  return {
    profile: profileId,
    hermes: { cli: desired.hermesCli, version: desired.hermesVersion },
    slack: {
      appTokenFile: `/run/sellable-agent/${profileId}/slack-app`,
      botTokenFile: `/run/sellable-agent/${profileId}/slack-bot`,
      generation: desired.slackGeneration,
      manifestHash: desired.slackManifestHash,
      appHash: desired.slackAppHash,
      teamHash: desired.slackTeamHash,
      botHash: desired.slackBotHash,
      channelHash: desired.slackChannelHash,
      defaultChannelHash: desired.slackDefaultChannelHash,
      memberAllowlistHash: desired.slackMemberAllowlistHash,
      selectedChannelIds: [...desired.slackChannelIds],
      defaultChannelId: desired.slackDefaultChannelId,
      memberAllowlist: [...desired.slackMemberAllowlist],
    },
    mcp_servers: {
      sellable: {
        command:
          "/usr/local/lib/sellable-agent/external-runtime/mcp/bin/sellable-mcp",
        args: [],
        enabled: true,
        env: {
          SELLABLE_CONFIG_PATH: `/runtime/profiles/${profileId}/sellable/mcp.json`,
          SELLABLE_LOCK_WORKSPACE_ID: desired.workspaceId,
          SELLABLE_REQUIRE_WORKSPACE_LOCK: "1",
        },
      },
    },
    tools: { include: [...desired.toolInclude] },
    provider: {
      reference: desired.providerReference,
      fingerprint: desired.providerFingerprint,
    },
  };
}

const LIVE_SKILLS_CONFIG_KEYS = Object.freeze([
  "disabled",
  "platform_disabled",
]);
const LIVE_PLUGIN_CONFIG_KEYS = Object.freeze(["enabled", "disabled"]);
const LIVE_MUTABLE_STATE_ROOTS = Object.freeze([
  "skills",
  "plugins",
  "plugin-data",
]);

function profileConfigWithoutLiveState(value) {
  const normalized = structuredClone(value);
  if (
    normalized?.skills &&
    typeof normalized.skills === "object" &&
    !Array.isArray(normalized.skills)
  ) {
    for (const key of LIVE_SKILLS_CONFIG_KEYS) delete normalized.skills[key];
    if (Object.keys(normalized.skills).length === 0) delete normalized.skills;
  }
  if (
    normalized?.platform_toolsets &&
    typeof normalized.platform_toolsets === "object" &&
    !Array.isArray(normalized.platform_toolsets)
  ) {
    delete normalized.platform_toolsets.slack;
    if (Object.keys(normalized.platform_toolsets).length === 0)
      delete normalized.platform_toolsets;
  }
  if (
    normalized?.plugins &&
    typeof normalized.plugins === "object" &&
    !Array.isArray(normalized.plugins)
  ) {
    for (const key of LIVE_PLUGIN_CONFIG_KEYS) delete normalized.plugins[key];
    if (Object.keys(normalized.plugins).length === 0) delete normalized.plugins;
  }
  return normalized;
}

function readProfileConfig(pathValue) {
  const document = parseDocument(readFileSync(pathValue, "utf8"));
  const value = document.toJS();
  if (
    document.errors.length > 0 ||
    !value ||
    typeof value !== "object" ||
    Array.isArray(value)
  ) {
    throw new Error("profile config rejected");
  }
  return value;
}

function normalizedProfileConfigBytes(pathValue) {
  return normalizedProfileConfigValueBytes(readProfileConfig(pathValue));
}

function normalizedProfileConfigValueBytes(value) {
  return Buffer.from(
    `${JSON.stringify(profileConfigWithoutLiveState(value), null, 2)}\n`,
    "utf8"
  );
}

function preservedSlackToolsets(
  config,
  profileRoot,
  { normalizeLegacyNativeDefault = false } = {}
) {
  const platformToolsets = config?.platform_toolsets;
  const nativeSlackProfile = existsSync(
    join(profileRoot, ".no-bundled-skills")
  );
  if (
    !nativeSlackProfile &&
    (!platformToolsets ||
      typeof platformToolsets !== "object" ||
      Array.isArray(platformToolsets) ||
      !Object.prototype.hasOwnProperty.call(platformToolsets, "slack"))
  )
    return normalizeLegacyNativeDefault
      ? sellableSlackToolsetsForMaterialization(config)
      : null;
  return sellableSlackToolsetsForMaterialization(config, {
    // Only native Slack profiles adopt the one-time browser default. The
    // contained legacy profile keeps its existing policy unchanged.
    browserDefaultApplied:
      !nativeSlackProfile ||
      existsSync(join(profileRoot, SELLABLE_BROWSER_TOOLSET_DEFAULT_MARKER)),
  });
}

function mergeLiveMutableConfig(sourceRoot, targetRoot) {
  const sourcePath = join(sourceRoot, "config.yaml");
  const targetPath = join(targetRoot, "config.yaml");
  if (!existsSync(sourcePath) || !existsSync(targetPath)) return;
  // Hermes owns this live file and normalizes it from the seed JSON into
  // YAML. Parse both representations so a routine image refresh does not
  // strand a healthy customer runtime before it can acknowledge its secrets.
  const source = readProfileConfig(sourcePath);
  const target = readProfileConfig(targetPath);
  const sourceSkills = source?.skills;
  let changed = false;
  if (
    sourceSkills &&
    (typeof sourceSkills !== "object" || Array.isArray(sourceSkills))
  )
    throw new Error("live skills config rejected");
  if (sourceSkills) {
    const preserved = Object.fromEntries(
      LIVE_SKILLS_CONFIG_KEYS.filter((key) =>
        Object.prototype.hasOwnProperty.call(sourceSkills, key)
      ).map((key) => [key, structuredClone(sourceSkills[key])])
    );
    if (Object.keys(preserved).length > 0) {
      target.skills = {
        ...(target.skills &&
        typeof target.skills === "object" &&
        !Array.isArray(target.skills)
          ? target.skills
          : {}),
        ...preserved,
      };
      changed = true;
    }
  }
  const sourcePlugins = source?.plugins;
  if (
    sourcePlugins &&
    (typeof sourcePlugins !== "object" || Array.isArray(sourcePlugins))
  ) {
    throw new Error("live plugins config rejected");
  }
  if (sourcePlugins) {
    const preserved = Object.fromEntries(
      LIVE_PLUGIN_CONFIG_KEYS.filter((key) =>
        Object.prototype.hasOwnProperty.call(sourcePlugins, key)
      ).map((key) => [key, structuredClone(sourcePlugins[key])])
    );
    if (Object.keys(preserved).length > 0) {
      target.plugins = {
        ...(target.plugins &&
        typeof target.plugins === "object" &&
        !Array.isArray(target.plugins)
          ? target.plugins
          : {}),
        ...preserved,
      };
      changed = true;
    }
  }
  const slackToolsets = preservedSlackToolsets(source, sourceRoot);
  if (slackToolsets !== null) {
    target.platform_toolsets = {
      ...(target.platform_toolsets &&
      typeof target.platform_toolsets === "object" &&
      !Array.isArray(target.platform_toolsets)
        ? target.platform_toolsets
        : {}),
      slack: slackToolsets,
    };
    changed = true;
  }
  if (!changed) return;
  atomicWrite(
    targetPath,
    `${JSON.stringify(target, null, 2)}\n`,
    lstatSync(targetPath).mode & 0o777
  );
}

function mergeLiveMutableState(sourceRoot, targetRoot) {
  if (!existsSync(sourceRoot)) return;
  for (const name of LIVE_MUTABLE_STATE_ROOTS) {
    const source = join(sourceRoot, name);
    if (!existsSync(source)) continue;
    const target = join(targetRoot, name);
    mkdirSync(target, { recursive: true, mode: 0o700 });
    mergeHermesState(source, target);
  }
  mergeLiveMutableConfig(sourceRoot, targetRoot);
}

function preservedLiveStateIdentity(
  profileRoot,
  { normalizeLegacyNativeDefault = false } = {}
) {
  if (!existsSync(profileRoot)) return null;
  const entries = [];
  const walk = (rootName, directory, relativePath = "") => {
    for (const name of readdirSync(directory).sort()) {
      const nextRelative = relativePath ? `${relativePath}/${name}` : name;
      if (rootName === "skills" && nextRelative === "sellable") continue;
      const pathValue = join(directory, name);
      const link = lstatSync(pathValue);
      if (link.isSymbolicLink())
        throw new Error("live mutable state symlink rejected");
      if (link.isDirectory()) walk(rootName, pathValue, nextRelative);
      else if (link.isFile()) {
        entries.push({
          path: `${rootName}/${nextRelative}`,
          sha256: sha256(readFileSync(pathValue)),
        });
      } else throw new Error("live mutable state entry rejected");
    }
  };
  for (const rootName of LIVE_MUTABLE_STATE_ROOTS) {
    const root = join(profileRoot, rootName);
    if (existsSync(root)) walk(rootName, root);
  }
  const configPath = join(profileRoot, "config.yaml");
  let mutableConfig = {};
  let slackToolsets = null;
  if (existsSync(configPath)) {
    const config = readProfileConfig(configPath);
    const skills = config?.skills;
    if (skills && typeof skills === "object" && !Array.isArray(skills)) {
      const liveSkills = Object.fromEntries(
        LIVE_SKILLS_CONFIG_KEYS.filter((key) =>
          Object.prototype.hasOwnProperty.call(skills, key)
        ).map((key) => [key, skills[key]])
      );
      if (Object.keys(liveSkills).length > 0) mutableConfig.skills = liveSkills;
    }
    const plugins = config?.plugins;
    if (plugins && (typeof plugins !== "object" || Array.isArray(plugins))) {
      throw new Error("live plugins config rejected");
    }
    if (plugins) {
      const livePlugins = Object.fromEntries(
        LIVE_PLUGIN_CONFIG_KEYS.filter((key) =>
          Object.prototype.hasOwnProperty.call(plugins, key)
        ).map((key) => [key, plugins[key]])
      );
      if (Object.keys(livePlugins).length > 0)
        mutableConfig.plugins = livePlugins;
    }
    slackToolsets = preservedSlackToolsets(config, profileRoot, {
      normalizeLegacyNativeDefault,
    });
  }
  return sha256(stableJson({ mutableConfig, entries, slackToolsets }));
}

function mcpFor(desired, profileId) {
  return {
    package: desired.mcpPackage,
    workspaceLockId: desired.workspaceLockId,
    requireWorkspaceLock: true,
    tools: { include: [...desired.toolInclude] },
    policyHash: desired.policyHash,
    serviceCredential: {
      reference: desired.serviceCredentialReference,
      fingerprint: desired.serviceCredentialFingerprint,
      generation: desired.serviceCredentialGeneration,
      file: `/run/sellable-agent/${profileId}/service-credential`,
    },
    agentContext: {
      workspaceId: desired.workspaceId,
      agentId: desired.agentId,
      generation: desired.serviceCredentialGeneration,
      policyHash: desired.policyHash,
    },
    requestChannelPolicy: {
      source: "_meta.sellableAgent.channelId",
      selectedChannelIds: [...desired.slackChannelIds],
      defaultChannelId: desired.slackDefaultChannelId,
      memberAllowlist: [...desired.slackMemberAllowlist],
    },
  };
}

function renderedProfileFiles(desired) {
  const profileId = deriveContainedProfileId(
    desired.workspaceId,
    desired.agentId,
    desired.hostId
  );
  return {
    "config.yaml": `${JSON.stringify(configFor(desired, profileId), null, 2)}\n`,
    "sellable/mcp.json": `${JSON.stringify(mcpFor(desired, profileId), null, 2)}\n`,
    "SOUL.md": desired.soul,
    "skills/sellable/SKILL.md": desired.skill,
  };
}

export function computeAgentNonSoulContentHash(fileHashes) {
  const nonSoulFileHashes = Object.fromEntries(
    Object.entries(fileHashes).filter(
      ([logicalPath]) => logicalPath !== "SOUL.md"
    )
  );
  return sha256(stableJson(nonSoulFileHashes));
}

export function computeAgentProfileDigest(desired) {
  const valid = validateDesired(desired);
  if (!valid.ok) return valid;
  const files = renderedProfileFiles(desired);
  const fileHashes = Object.fromEntries(
    Object.keys(files)
      .sort()
      .map((logicalPath) => [
        logicalPath,
        sha256(
          logicalPath === "config.yaml"
            ? normalizedProfileConfigValueBytes(JSON.parse(files[logicalPath]))
            : files[logicalPath]
        ),
      ])
  );
  return {
    ok: true,
    fileHashes,
    profileDigest: sha256(stableJson({ ...manifestBody(desired), fileHashes })),
    nonSoulContentHash: computeAgentNonSoulContentHash(fileHashes),
  };
}

function atomicWrite(pathValue, bytes, mode) {
  mkdirSync(dirname(pathValue), { recursive: true, mode: 0o700 });
  const temp = join(
    dirname(pathValue),
    `.${basename(pathValue)}.${randomUUID()}.tmp`
  );
  writeFileSync(temp, bytes, { mode, flag: "wx" });
  chmodSync(temp, mode);
  const descriptor = openSync(temp, "r");
  try {
    fsyncSync(descriptor);
  } finally {
    closeSync(descriptor);
  }
  renameSync(temp, pathValue);
}

function fsyncDirectory(pathValue) {
  const descriptor = openSync(pathValue, "r");
  try {
    fsyncSync(descriptor);
  } finally {
    closeSync(descriptor);
  }
}

function renderStagedProfile(stageRoot, desired) {
  mkdirSync(stageRoot, { recursive: true, mode: 0o700 });
  const files = renderedProfileFiles(desired);
  for (const [logicalPath, content] of Object.entries(files)) {
    atomicWrite(
      join(stageRoot, logicalPath),
      content,
      logicalPath.endsWith(".md") ? 0o444 : 0o600
    );
  }
  const fileHashes = Object.fromEntries(
    Object.keys(files)
      .sort()
      .map((logicalPath) => [
        logicalPath,
        sha256(
          logicalPath === "config.yaml"
            ? normalizedProfileConfigBytes(join(stageRoot, logicalPath))
            : readFileSync(join(stageRoot, logicalPath))
        ),
      ])
  );
  const base = manifestBody(desired);
  const profileDigest = sha256(stableJson({ ...base, fileHashes }));
  const manifest = { ...base, fileHashes, profileDigest };
  atomicWrite(
    join(stageRoot, "agent-profile.json"),
    `${JSON.stringify(manifest, null, 2)}\n`,
    0o600
  );
  fsyncDirectory(stageRoot);
  return manifest;
}

function inventory(root, { skipTransient = false } = {}) {
  const files = [];
  const walk = (pathValue, relativePath) => {
    const link = lstatSync(pathValue);
    if (link.isSymbolicLink()) throw new Error("profile symlink rejected");
    if (link.isDirectory()) {
      for (const name of readdirSync(pathValue).sort()) {
        const nextRelative = relativePath
          ? `${relativePath}/${name}`
          : name;
        if (skipTransient && isHermesTransientProfilePath(nextRelative))
          continue;
        walk(
          join(pathValue, name),
          nextRelative
        );
      }
      return;
    }
    if (!link.isFile()) throw new Error("profile entry rejected");
    files.push(relativePath);
  };
  walk(root, "");
  return files.sort();
}

function treeInventory(root) {
  const entries = [];
  const walk = (pathValue, relativePath) => {
    const link = lstatSync(pathValue);
    if (link.isSymbolicLink()) throw new Error("profile symlink rejected");
    entries.push({
      path: relativePath || ".",
      type: link.isDirectory() ? "directory" : link.isFile() ? "file" : "other",
      uid: link.uid,
      gid: link.gid,
      mode: link.mode & 0o777,
    });
    if (link.isDirectory()) {
      for (const name of readdirSync(pathValue).sort()) {
        walk(
          join(pathValue, name),
          relativePath ? `${relativePath}/${name}` : name
        );
      }
    }
  };
  walk(root, "");
  return entries;
}

export function createPosixProfileOwnershipPort() {
  return {
    async apply({ profileRoot, uid, gid }) {
      const entries = treeInventory(profileRoot).sort(
        (a, b) => b.path.length - a.path.length
      );
      for (const entry of entries) {
        const pathValue =
          entry.path === "." ? profileRoot : join(profileRoot, entry.path);
        chownSync(pathValue, uid, gid);
        chmodSync(pathValue, entry.type === "directory" ? 0o500 : 0o400);
      }
      return { ok: true };
    },
    async observe({ profileRoot }) {
      return { ok: true, entries: treeInventory(profileRoot) };
    },
    async remove({ profileRoot }) {
      if (existsSync(profileRoot))
        rmSync(profileRoot, { recursive: true, force: true });
      return { ok: true };
    },
  };
}

function validateRuntimeOwnership(observed, runtimeIdentity) {
  if (!observed?.ok || !Array.isArray(observed.entries)) return false;
  const expectedPaths = [
    ".",
    "agent-profile.json",
    "config.yaml",
    "sellable",
    "sellable/mcp.json",
    "SOUL.md",
    "skills",
    "skills/sellable",
    "skills/sellable/SKILL.md",
  ].sort();
  const observedPaths = observed.entries.map((entry) => entry.path);
  if (expectedPaths.some((pathValue) => !observedPaths.includes(pathValue))) {
    return false;
  }
  return observed.entries.every(
    (entry) =>
      entry.uid === runtimeIdentity.uid &&
      entry.gid === runtimeIdentity.gid &&
      (entry.type === "directory"
        ? entry.mode === 0o500
        : entry.type === "file" && entry.mode === 0o400)
  );
}

export function validateAgentProfileBundle({ profileRoot, desired }) {
  const valid = validateDesired(desired);
  if (!valid.ok) return valid;
  try {
    if (
      !isAbsolute(profileRoot) ||
      !existsSync(profileRoot) ||
      lstatSync(profileRoot).isSymbolicLink()
    ) {
      return { ok: false, code: "profile_path_invalid" };
    }
    const foundInventory = inventory(profileRoot);
    const serverOwned = [...AGENT_PROFILE_INVENTORY].sort();
    if (
      serverOwned.some(
        (logicalPath) => !foundInventory.includes(logicalPath)
      ) ||
      foundInventory.some(
        (logicalPath) =>
          !serverOwned.includes(logicalPath) &&
          !["skills/", "plugins/", "plugin-data/"].some((prefix) =>
            logicalPath.startsWith(prefix)
          )
      )
    ) {
      return { ok: false, code: "profile_inventory_open" };
    }
    const manifestPath = join(profileRoot, "agent-profile.json");
    const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
    if (!exactKeys(manifest, MANIFEST_KEYS))
      return { ok: false, code: "manifest_schema_invalid" };
    const expectedBody = manifestBody(desired);
    if (
      Object.entries(expectedBody).some(
        ([key, value]) => stableJson(manifest[key]) !== stableJson(value)
      )
    ) {
      return { ok: false, code: "manifest_identity_drift" };
    }
    const expectedHashes = Object.fromEntries(
      AGENT_PROFILE_INVENTORY.filter((path) => path !== "agent-profile.json")
        .sort()
        .map((logicalPath) => [
          logicalPath,
          sha256(
            logicalPath === "config.yaml"
              ? normalizedProfileConfigBytes(join(profileRoot, logicalPath))
              : readFileSync(join(profileRoot, logicalPath))
          ),
        ])
    );
    if (stableJson(manifest.fileHashes) !== stableJson(expectedHashes)) {
      return { ok: false, code: "profile_file_hash_drift" };
    }
    if (
      manifest.profileDigest !==
      sha256(stableJson({ ...expectedBody, fileHashes: expectedHashes }))
    ) {
      return { ok: false, code: "profile_digest_drift" };
    }
    const config = JSON.parse(
      readFileSync(join(profileRoot, "config.yaml"), "utf8")
    );
    const mcp = JSON.parse(
      readFileSync(join(profileRoot, "sellable", "mcp.json"), "utf8")
    );
    if (
      stableJson(profileConfigWithoutLiveState(config)) !==
      stableJson(
        profileConfigWithoutLiveState(configFor(desired, manifest.profileId))
      )
    ) {
      return { ok: false, code: "config_drift" };
    }
    if (stableJson(mcp) !== stableJson(mcpFor(desired, manifest.profileId))) {
      return { ok: false, code: "mcp_policy_drift" };
    }
    if (
      readFileSync(join(profileRoot, "SOUL.md"), "utf8") !== desired.soul ||
      readFileSync(
        join(profileRoot, "skills", "sellable", "SKILL.md"),
        "utf8"
      ) !== desired.skill
    )
      return { ok: false, code: "content_drift" };
    for (const logicalPath of foundInventory) {
      const pathValue = join(profileRoot, logicalPath);
      const link = lstatSync(pathValue);
      if (
        (link.mode & 0o022) !== 0 ||
        RAW_SECRET.test(readFileSync(pathValue, "utf8"))
      ) {
        return { ok: false, code: "secret_or_mode_drift" };
      }
    }
    return {
      ok: true,
      manifest,
      hashes: {
        ...expectedHashes,
        profile: manifest.profileDigest,
        nonSoulContent: computeAgentNonSoulContentHash(expectedHashes),
      },
    };
  } catch {
    return { ok: false, code: "profile_validation_failed" };
  }
}

function secretBinding(desired, servicePurpose) {
  return {
    workspaceId: desired.workspaceId,
    agentId: desired.agentId,
    installationId: desired.installationId,
    generation: desired.slackGeneration,
    hostId: desired.hostId,
    workerId: desired.workerId,
    fence: desired.fence,
    servicePurpose,
  };
}

function sameBinding(value, expected) {
  return (
    exactKeys(value, Object.keys(expected)) &&
    Object.entries(expected).every(
      ([key, expectedValue]) => value[key] === expectedValue
    )
  );
}

function removeDirect(root, pathValue) {
  const realRoot = realpathSync(root);
  const resolved = resolve(pathValue);
  if (dirname(resolved) !== realRoot || !isInside(realRoot, resolved))
    throw new Error("path confinement failed");
  if (existsSync(resolved)) {
    if (lstatSync(resolved).isSymbolicLink())
      throw new Error("symlink removal rejected");
    rmSync(resolved, { recursive: true, force: true });
  }
}

function cleanupSecrets(runtimeSecretsRoot, profileId) {
  try {
    const root = realpathSync(runtimeSecretsRoot);
    const target = join(root, profileId);
    if (
      dirname(target) === root &&
      existsSync(target) &&
      !lstatSync(target).isSymbolicLink()
    ) {
      rmSync(target, { recursive: true, force: true });
    }
  } catch {}
}

async function materializeRuntimeSecrets({
  desired,
  runtimeSecretsRoot,
  ports,
  serviceCredential,
  runtimeIdentity,
}) {
  const profileId = deriveContainedProfileId(
    desired.workspaceId,
    desired.agentId,
    desired.hostId
  );
  try {
    const appBinding = secretBinding(desired, "slack-app");
    const xapp = await ports.hostAppSecret.resolveHostSecret({
      ...appBinding,
      reference: desired.xappReference,
      expectedFingerprint: desired.xappFingerprint,
    });
    if (
      !sameBinding(xapp?.binding, appBinding) ||
      typeof xapp?.secret !== "string" ||
      !xapp.secret ||
      xapp.fingerprint !== desired.xappFingerprint ||
      sha256(xapp.secret).slice(0, 16) !== desired.xappFingerprint
    )
      return { ok: false, code: "secret_binding_rejected" };

    const botBinding = secretBinding(desired, "slack-bot");
    const xoxb = await ports.workspaceBotSecret.decryptWorkspaceSecret({
      ...botBinding,
      reference: desired.xoxbReference,
      ciphertextFingerprint: desired.xoxbCiphertextFingerprint,
    });
    if (
      !sameBinding(xoxb?.binding, botBinding) ||
      typeof xoxb?.secret !== "string" ||
      !xoxb.secret ||
      xoxb.generation !== desired.slackGeneration ||
      xoxb.fingerprint !== desired.xoxbCiphertextFingerprint ||
      xoxb.fingerprint !== sha256(xoxb.secret).slice(0, 16)
    )
      return { ok: false, code: "secret_binding_rejected" };

    const credentialBinding = {
      workspaceId: desired.workspaceId,
      agentId: desired.agentId,
      installationId: desired.installationId,
      generation: desired.serviceCredentialGeneration,
      hostId: desired.hostId,
      workerId: desired.workerId,
      fence: desired.fence,
      servicePurpose: "mcp-service",
    };
    if (
      !sameBinding(serviceCredential?.binding, credentialBinding) ||
      typeof serviceCredential?.secret !== "string" ||
      !serviceCredential.secret.startsWith("sat_") ||
      serviceCredential.generation !== desired.serviceCredentialGeneration ||
      serviceCredential.fingerprint !== desired.serviceCredentialFingerprint ||
      sha256(serviceCredential.secret).slice(0, 16) !==
        desired.serviceCredentialFingerprint
    )
      return { ok: false, code: "secret_binding_rejected" };

    const credential = await ports.credential.install({
      desired,
      profileId,
      runtimeIdentity,
      serviceCredential,
    });
    if (
      !credential?.ok ||
      credential.profileId !== profileId ||
      credential.fingerprint !== desired.serviceCredentialFingerprint ||
      credential.generation !== desired.serviceCredentialGeneration ||
      typeof credential.path !== "string" ||
      !isAbsolute(credential.path)
    )
      return { ok: false, code: "service_credential_install_rejected" };

    const root = realpathSync(runtimeSecretsRoot);
    const serviceRoot = join(root, profileId);
    if (dirname(serviceRoot) !== root)
      return { ok: false, code: "secret_path_rejected" };
    cleanupSecrets(root, profileId);
    mkdirSync(serviceRoot, { recursive: false, mode: 0o700 });
    const appPath = join(serviceRoot, "slack-app");
    const botPath = join(serviceRoot, "slack-bot");
    atomicWrite(appPath, `${xapp.secret}\n`, 0o600);
    atomicWrite(botPath, `${xoxb.secret}\n`, 0o600);
    fsyncDirectory(serviceRoot);
    const workerUid = process.getuid?.() ?? lstatSync(serviceRoot).uid;
    const workerGid = process.getgid?.() ?? lstatSync(serviceRoot).gid;
    if (
      lstatSync(serviceRoot).uid !== workerUid ||
      lstatSync(serviceRoot).gid !== workerGid ||
      (lstatSync(serviceRoot).mode & 0o777) !== 0o700 ||
      [appPath, botPath].some((pathValue) => {
        const link = lstatSync(pathValue);
        return (
          link.isSymbolicLink() ||
          !link.isFile() ||
          link.uid !== workerUid ||
          link.gid !== workerGid ||
          (link.mode & 0o777) !== 0o600
        );
      })
    )
      throw new Error("worker secret ownership mismatch");
    return {
      ok: true,
      files: [appPath, botPath, credential.path],
      xappFingerprint: xapp.fingerprint,
      xoxbFingerprint: xoxb.fingerprint,
      serviceCredentialFingerprint: serviceCredential.fingerprint,
      serviceCredentialGeneration: serviceCredential.generation,
    };
  } catch {
    cleanupSecrets(runtimeSecretsRoot, profileId);
    try {
      await ports.credential.cleanup({ profileId });
    } catch {}
    return { ok: false, code: "secret_materialization_failed" };
  }
}

function reuseInstalledRuntimeSecrets({
  desired,
  runtimeSecretsRoot,
  mcpCredentialRoot,
  observation,
  runtimeIdentity,
}) {
  const profileId = deriveContainedProfileId(
    desired.workspaceId,
    desired.agentId,
    desired.hostId
  );
  try {
    if (
      observation?.profileId !== profileId ||
      observation.workspaceId !== desired.workspaceId ||
      observation.agentId !== desired.agentId ||
      observation.slack?.xappPresent !== true ||
      observation.slack?.xoxbPresent !== true ||
      observation.serviceCredential?.present !== true ||
      observation.slack.xappFingerprint !== desired.xappFingerprint ||
      observation.slack.xoxbFingerprint !== desired.xoxbCiphertextFingerprint ||
      observation.slack.generation !== desired.slackGeneration ||
      observation.serviceCredential.fingerprint !==
        desired.serviceCredentialFingerprint ||
      observation.serviceCredential.generation !==
        desired.serviceCredentialGeneration
    )
      return { ok: false, code: "installed_secret_identity_rejected" };
    const slackRoot = privateRoot(runtimeSecretsRoot);
    const mcpRoot = resolve(mcpCredentialRoot ?? "");
    if (!slackRoot || !isAbsolute(mcpRoot))
      return { ok: false, code: "installed_secret_root_rejected" };
    const slackProfileRoot = join(slackRoot, profileId);
    const mcpProfileRoot = join(mcpRoot, profileId);
    const files = [
      join(slackProfileRoot, "slack-app"),
      join(slackProfileRoot, "slack-bot"),
      join(mcpProfileRoot, "service-credential"),
    ];
    for (const [index, pathValue] of files.slice(0, 2).entries()) {
      const link = lstatSync(pathValue);
      const expectedUid = process.getuid?.() ?? link.uid;
      const expectedGid = process.getgid?.() ?? link.gid;
      if (
        link.isSymbolicLink() ||
        !link.isFile() ||
        (link.mode & 0o777) !== 0o600 ||
        link.uid !== expectedUid ||
        link.gid !== expectedGid
      )
        throw new Error("installed secret file rejected");
    }
    return {
      ok: true,
      reused: true,
      files,
      xappFingerprint: observation.slack.xappFingerprint,
      xoxbFingerprint: observation.slack.xoxbFingerprint,
      serviceCredentialFingerprint: observation.serviceCredential.fingerprint,
      serviceCredentialGeneration: observation.serviceCredential.generation,
    };
  } catch {
    return { ok: false, code: "installed_secret_readback_rejected" };
  }
}

function portsValid(ports) {
  return Object.entries(PROFILE_MATERIALIZER_PORTS).every(
    ([group, methods]) =>
      ports?.[group] &&
      methods.every((method) => typeof ports[group][method] === "function")
  );
}

function expectedStaticObservation({
  desired,
  profileId,
  validation,
  secrets,
}) {
  return {
    profileId,
    workspaceId: desired.workspaceId,
    agentId: desired.agentId,
    revisionId: desired.revisionId,
    hashes: {
      package: sha256(
        `${desired.installerPackage}\0${desired.mcpPackage}\0${desired.hermesVersion}\0${HERMES_AGENT_BRIDGE_CONTRACT.contractDigest}`
      ),
      config: validation.hashes["config.yaml"],
      mcp: validation.hashes["sellable/mcp.json"],
      content: validation.hashes.profile,
      nonSoulContent: validation.hashes.nonSoulContent,
      policy: desired.policyHash,
      slackManifest: desired.slackManifestHash,
      soul: desired.soulHash,
      skills: desired.skillsHash,
      provider: desired.providerFingerprint,
    },
    slack: {
      app: desired.slackAppHash,
      team: desired.slackTeamHash,
      bot: desired.slackBotHash,
      channels: desired.slackChannelHash,
      defaultChannel: desired.slackDefaultChannelHash,
      memberAllowlist: desired.slackMemberAllowlistHash,
      channelIds: [...desired.slackChannelIds],
      defaultChannelId: desired.slackDefaultChannelId,
      memberIds: [...desired.slackMemberAllowlist],
      generation: desired.slackGeneration,
      xappPresent: true,
      xoxbPresent: true,
      xappFingerprint: secrets.xappFingerprint,
      xoxbFingerprint: secrets.xoxbFingerprint,
    },
    serviceCredential: {
      present: true,
      fingerprint: secrets.serviceCredentialFingerprint,
      generation: secrets.serviceCredentialGeneration,
    },
    hermesBridge: {
      bridgeId: HERMES_AGENT_BRIDGE_CONTRACT.bridgeId,
      contractDigest: HERMES_AGENT_BRIDGE_CONTRACT.contractDigest,
      hermesVersion: HERMES_AGENT_BRIDGE_CONTRACT.hermesVersion,
      state: "installed",
      reasons: [],
      files: HERMES_AGENT_BRIDGE_CONTRACT.files.map((file) => ({
        path: file.path,
        sha256: file.patchedSha256,
      })),
      status: "verified",
    },
  };
}

function validateIndependentObservation(observed, expected, runtimeIdentity) {
  if (!observed || !exactKeys(observed, [...Object.keys(expected), "process"]))
    return false;
  if (
    !exactKeys(observed.process, [
      "ready",
      "pid",
      "startTicks",
      "bootId",
      "serviceUser",
      "uid",
    ])
  ) {
    return false;
  }
  const { process, ...staticObserved } = observed;
  const observedPackageHash = staticObserved.hashes?.package;
  const expectedWithoutPackage = {
    ...expected,
    hashes: { ...expected.hashes, package: undefined },
  };
  const observedWithoutPackage = {
    ...staticObserved,
    hashes: { ...staticObserved.hashes, package: undefined },
  };
  return (
    SHA256.test(observedPackageHash ?? "") &&
    stableJson(observedWithoutPackage) === stableJson(expectedWithoutPackage) &&
    process.ready === true &&
    Number.isSafeInteger(process.pid) &&
    process.pid > 1 &&
    /^[1-9][0-9]{0,31}$/.test(process.startTicks ?? "") &&
    typeof process.bootId === "string" &&
    /^[A-Za-z0-9_-]{1,128}$/.test(process.bootId) &&
    process.serviceUser === runtimeIdentity.user &&
    process.uid === runtimeIdentity.uid
  );
}

const PROMOTION_TRANSACTION_VERSION = "sellable-agent-profile-promotion/v1";
const PROMOTION_SIGNATURE = /^[A-Za-z0-9_-]{64,512}$/;

function promotionTransactionPath(profilesRoot, profileId) {
  return join(profilesRoot, `.${profileId}.promotion.json`);
}

function promotionJournal(input) {
  const journal = input.promotionJournal ?? input.ports?.promotionJournal;
  const operationId = input.operationId ?? journal?.operationId;
  const effectId = input.effectId ?? journal?.effectId;
  if (
    !journal ||
    typeof journal.sign !== "function" ||
    typeof journal.verify !== "function" ||
    !Number.isSafeInteger(journal.signerGeneration) ||
    journal.signerGeneration < 1 ||
    !SAFE_ID.test(operationId ?? "") ||
    !/^sahe_[a-f0-9]{64}$/.test(effectId ?? "")
  )
    throw new Error("promotion journal authority rejected");
  return { journal, operationId, effectId };
}

function promotionSignedBody(transaction) {
  const { signature: _signature, ...body } = transaction;
  return body;
}

function signPromotionTransaction(transaction, authority) {
  const signature = authority.journal.sign(promotionSignedBody(transaction));
  if (!PROMOTION_SIGNATURE.test(signature ?? ""))
    throw new Error("promotion signature rejected");
  return { ...transaction, signature };
}

function promotionObservationCore(observation) {
  const {
    profileDigest: _profileDigest,
    tools: _tools,
    revisionSequence: _revisionSequence,
    ...core
  } = observation ?? {};
  return core;
}

function targetObservationDigest(observation, transaction) {
  const core = promotionObservationCore(observation);
  if (
    core.profileId !== transaction.profileId ||
    core.revisionId !== transaction.targetRevisionId ||
    core.hashes?.content !== transaction.targetProfileDigest ||
    !SHA256.test(core.hashes?.package ?? "") ||
    !core.process?.ready ||
    !Number.isSafeInteger(core.process?.pid) ||
    core.process.pid < 2 ||
    !/^[1-9][0-9]{0,31}$/.test(core.process?.startTicks ?? "")
  )
    throw new Error("promotion target observation rejected");
  return sha256(stableJson(core));
}

function priorObservationCore(observation) {
  const {
    process: _process,
    revisionSequence: _revisionSequence,
    tools: _tools,
    ...core
  } = observation ?? {};
  return core;
}

function validPriorObservation(observation, profileId) {
  return Boolean(
    observation &&
      observation.profileId === profileId &&
      SAFE_ID.test(observation.workspaceId ?? "") &&
      SAFE_ID.test(observation.agentId ?? "") &&
      SAFE_ID.test(observation.revisionId ?? "") &&
      SHA256.test(observation.hashes?.content ?? "") &&
      FINGERPRINT.test(observation.slack?.xappFingerprint ?? "") &&
      FINGERPRINT.test(observation.slack?.xoxbFingerprint ?? "") &&
      FINGERPRINT.test(observation.serviceCredential?.fingerprint ?? "") &&
      Number.isSafeInteger(observation.serviceCredential?.generation) &&
      observation.serviceCredential.generation > 0 &&
      !RAW_SECRET.test(JSON.stringify(observation))
  );
}

function writePromotionTransaction({
  profilesRoot,
  profileId,
  desired,
  targetProfileDigest,
  reusedSecrets,
  priorObservation,
  authority,
}) {
  const transaction = signPromotionTransaction(
    {
      version: PROMOTION_TRANSACTION_VERSION,
      status: "PREPARED",
      profileId,
      operationId: authority.operationId,
      effectId: authority.effectId,
      signerGeneration: authority.journal.signerGeneration,
      targetRevisionId: desired.revisionId,
      targetRevisionSequence: desired.revisionSequence,
      targetProfileDigest,
      fence: desired.fence,
      reusedSecrets,
      priorObservation: reusedSecrets ? priorObservation : null,
      targetObservationDigest: null,
    },
    authority
  );
  if (reusedSecrets && !validPriorObservation(priorObservation, profileId)) {
    throw new Error("prior-good promotion evidence rejected");
  }
  atomicWrite(
    promotionTransactionPath(profilesRoot, profileId),
    `${JSON.stringify(transaction, null, 2)}\n`,
    0o600
  );
  fsyncDirectory(profilesRoot);
}

function removePromotionTransaction(profilesRoot, profileId) {
  const pathValue = promotionTransactionPath(profilesRoot, profileId);
  if (existsSync(pathValue)) {
    const link = lstatSync(pathValue);
    if (link.isSymbolicLink() || !link.isFile())
      throw new Error("promotion transaction rejected");
    rmSync(pathValue);
    fsyncDirectory(profilesRoot);
  }
}

function readPromotionTransaction(
  profilesRoot,
  profileId,
  authority,
  currentFence
) {
  const pathValue = promotionTransactionPath(profilesRoot, profileId);
  if (!existsSync(pathValue)) return null;
  const link = lstatSync(pathValue);
  if (
    link.isSymbolicLink() ||
    !link.isFile() ||
    (link.mode & 0o777) !== 0o600
  ) {
    throw new Error("promotion transaction rejected");
  }
  const transaction = JSON.parse(readFileSync(pathValue, "utf8"));
  if (
    !exactKeys(transaction, [
      "version",
      "status",
      "profileId",
      "operationId",
      "effectId",
      "signerGeneration",
      "targetRevisionId",
      "targetRevisionSequence",
      "targetProfileDigest",
      "fence",
      "reusedSecrets",
      "priorObservation",
      "targetObservationDigest",
      "signature",
    ]) ||
    transaction.version !== PROMOTION_TRANSACTION_VERSION ||
    !["PREPARED", "COMMITTED"].includes(transaction.status) ||
    transaction.profileId !== profileId ||
    !SAFE_ID.test(transaction.targetRevisionId ?? "") ||
    transaction.operationId !== authority.operationId ||
    transaction.effectId !== authority.effectId ||
    transaction.signerGeneration !== authority.journal.signerGeneration ||
    !Number.isSafeInteger(transaction.targetRevisionSequence) ||
    transaction.targetRevisionSequence < 1 ||
    !SHA256.test(transaction.targetProfileDigest ?? "") ||
    !/^[1-9][0-9]{0,19}$/.test(transaction.fence ?? "") ||
    typeof transaction.reusedSecrets !== "boolean" ||
    (transaction.reusedSecrets &&
      !validPriorObservation(transaction.priorObservation, profileId)) ||
    (!transaction.reusedSecrets && transaction.priorObservation !== null) ||
    (transaction.status === "PREPARED" &&
      transaction.targetObservationDigest !== null) ||
    (transaction.status === "COMMITTED" &&
      !SHA256.test(transaction.targetObservationDigest ?? "")) ||
    !PROMOTION_SIGNATURE.test(transaction.signature ?? "") ||
    BigInt(currentFence) < BigInt(transaction.fence) ||
    authority.journal.verify(
      promotionSignedBody(transaction),
      transaction.signature
    ) !== true
  )
    throw new Error("promotion transaction schema rejected");
  return transaction;
}

async function restartAndProvePrior({
  profileRoot,
  profileId,
  priorObservation,
  ports,
  runtimeIdentity,
}) {
  try {
    const manifest = JSON.parse(
      readFileSync(join(profileRoot, "agent-profile.json"), "utf8")
    );
    if (
      manifest.profileId !== profileId ||
      manifest.revisionId !== priorObservation.revisionId ||
      manifest.profileDigest !== priorObservation.hashes.content
    )
      return false;
    await ports.gateway.start({
      profileId,
      profileRoot,
      identity: runtimeIdentity,
      argv: ["hermes", "--profile", profileId, "gateway", "run"],
      env: { HOME: "/profile", NODE_ENV: "production" },
      slackDelivery: {
        supervisorRunScript: "sellable-agent-runtime/run",
        appFd: 8,
        botFd: 9,
      },
      evidence: {
        revisionId: manifest.revisionId,
        profileDigest: manifest.profileDigest,
        xappFingerprint: priorObservation.slack.xappFingerprint,
        xoxbFingerprint: priorObservation.slack.xoxbFingerprint,
        serviceCredentialFingerprint:
          priorObservation.serviceCredential.fingerprint,
        serviceCredentialGeneration:
          priorObservation.serviceCredential.generation,
      },
    });
    const restored = await ports.gateway.observe({
      profileId,
      profileRoot,
      rollback: true,
    });
    const process = restored?.process;
    return Boolean(
      stableJson(priorObservationCore(restored)) ===
        stableJson(priorObservationCore(priorObservation)) &&
        process?.ready &&
        Number.isSafeInteger(process.pid) &&
        process.pid > 1 &&
        /^[1-9][0-9]{0,31}$/.test(process.startTicks ?? "") &&
        process.serviceUser === runtimeIdentity.user &&
        process.uid === runtimeIdentity.uid
    );
  } catch {
    return false;
  }
}

export async function recoverInterruptedProfilePromotion(input = {}) {
  const valid = validateDesired(input.desired);
  const profilesRoot = traversableProfilesRoot(input.profilesRoot);
  const runtimeSecretsRoot = privateRoot(input.runtimeSecretsRoot);
  if (
    !valid.ok ||
    !profilesRoot ||
    !runtimeSecretsRoot ||
    !portsValid(input.ports)
  ) {
    return { ok: false, status: "RECOVERY_INPUT_REJECTED" };
  }
  const profileId = deriveContainedProfileId(
    input.desired.workspaceId,
    input.desired.agentId,
    input.desired.hostId
  );
  try {
    const authority = promotionJournal(input);
    const transaction = readPromotionTransaction(
      profilesRoot,
      profileId,
      authority,
      input.desired.fence
    );
    if (!transaction) return { ok: true, status: "NONE", profileId };
    const profileRoot = join(profilesRoot, profileId);
    const backupRoot = join(profilesRoot, `${profileId}.rollback-prior-good`);
    if (transaction.status === "COMMITTED") {
      if (!existsSync(profileRoot))
        throw new Error("committed promotion target absent");
      const activeManifest = JSON.parse(
        readFileSync(join(profileRoot, "agent-profile.json"), "utf8")
      );
      if (
        activeManifest.profileId !== profileId ||
        activeManifest.revisionId !== transaction.targetRevisionId ||
        activeManifest.revisionSequence !==
          transaction.targetRevisionSequence ||
        activeManifest.profileDigest !== transaction.targetProfileDigest
      )
        throw new Error("committed promotion target rejected");
      const committedObservation = await input.ports.gateway.observe({
        profileId,
        profileRoot,
        committedRecovery: true,
      });
      if (
        targetObservationDigest(committedObservation, transaction) !==
        transaction.targetObservationDigest
      ) {
        throw new Error("committed promotion observation rejected");
      }
      if (existsSync(backupRoot)) {
        await input.ports.ownership.remove({
          profileId,
          profileRoot: backupRoot,
          slot: "BACKUP",
          revisionId: transaction.targetRevisionId,
          fence: transaction.fence,
        });
      }
      if (existsSync(backupRoot))
        throw new Error("committed promotion backup cleanup unproven");
      removePromotionTransaction(profilesRoot, profileId);
      return { ok: true, status: "COMMITTED_FINALIZED", profileId };
    }
    if (existsSync(backupRoot)) {
      if (existsSync(profileRoot)) {
        const activeManifest = JSON.parse(
          readFileSync(join(profileRoot, "agent-profile.json"), "utf8")
        );
        if (
          activeManifest.profileId !== profileId ||
          activeManifest.revisionId !== transaction.targetRevisionId ||
          activeManifest.revisionSequence !==
            transaction.targetRevisionSequence ||
          activeManifest.profileDigest !== transaction.targetProfileDigest
        )
          throw new Error("promotion transaction active target rejected");
        await input.ports.ownership.remove({
          profileId,
          profileRoot,
          slot: "ACTIVE",
          revisionId: transaction.targetRevisionId,
          fence: transaction.fence,
        });
      }
      renameSync(backupRoot, profileRoot);
      fsyncDirectory(profilesRoot);
    }
    if (!existsSync(profileRoot)) throw new Error("prior-good profile absent");
    if (!transaction.reusedSecrets) {
      cleanupSecrets(runtimeSecretsRoot, profileId);
      await input.ports.credential.cleanup({ profileId });
      removePromotionTransaction(profilesRoot, profileId);
      return { ok: false, status: "RECOVERY_UNPROVEN", profileId };
    }
    const proven = await restartAndProvePrior({
      profileRoot,
      profileId,
      priorObservation: transaction.priorObservation,
      ports: input.ports,
      runtimeIdentity: input.runtimeIdentity,
    });
    if (!proven) return { ok: false, status: "RECOVERY_UNPROVEN", profileId };
    removePromotionTransaction(profilesRoot, profileId);
    return {
      ok: true,
      status: "RECOVERED_AND_RESTARTED",
      profileId,
      priorObservation: transaction.priorObservation,
    };
  } catch {
    return { ok: false, status: "RECOVERY_UNPROVEN", profileId };
  }
}

export function commitRetainedProfilePromotion(input = {}) {
  const valid = validateDesired(input.desired);
  const profilesRoot = traversableProfilesRoot(input.profilesRoot);
  if (!valid.ok || !profilesRoot)
    return { ok: false, status: "COMMIT_INPUT_REJECTED" };
  const profileId = deriveContainedProfileId(
    input.desired.workspaceId,
    input.desired.agentId,
    input.desired.hostId
  );
  try {
    const authority = promotionJournal(input);
    const transaction = readPromotionTransaction(
      profilesRoot,
      profileId,
      authority,
      input.desired.fence
    );
    const profileRoot = join(profilesRoot, profileId);
    const backupRoot = join(profilesRoot, `${profileId}.rollback-prior-good`);
    if (!existsSync(profileRoot))
      throw new Error("promotion commit target absent");
    const activeManifest = JSON.parse(
      readFileSync(join(profileRoot, "agent-profile.json"), "utf8")
    );
    if (
      !transaction ||
      transaction.targetRevisionId !== input.desired.revisionId ||
      transaction.targetRevisionSequence !== input.desired.revisionSequence ||
      transaction.fence !== input.desired.fence ||
      transaction.targetProfileDigest !== activeManifest.profileDigest ||
      activeManifest.profileId !== profileId ||
      activeManifest.revisionId !== transaction.targetRevisionId ||
      activeManifest.revisionSequence !== transaction.targetRevisionSequence ||
      !existsSync(backupRoot)
    )
      throw new Error("promotion commit evidence rejected");
    if (transaction.status === "PREPARED") {
      const observedDigest = targetObservationDigest(
        input.targetObservation,
        transaction
      );
      atomicWrite(
        promotionTransactionPath(profilesRoot, profileId),
        `${JSON.stringify(
          signPromotionTransaction(
            {
              ...promotionSignedBody(transaction),
              status: "COMMITTED",
              targetObservationDigest: observedDigest,
            },
            authority
          ),
          null,
          2
        )}\n`,
        0o600
      );
      fsyncDirectory(profilesRoot);
    } else if (transaction.status !== "COMMITTED") {
      throw new Error("promotion commit state rejected");
    }
    return { ok: true, status: "COMMITTED_PENDING_CLEANUP", profileId };
  } catch {
    return { ok: false, status: "COMMIT_UNPROVEN", profileId };
  }
}

export function finalizeRetainedProfilePromotion(input = {}) {
  const valid = validateDesired(input.desired);
  const profilesRoot = traversableProfilesRoot(input.profilesRoot);
  if (!valid.ok || !profilesRoot)
    return { ok: false, status: "FINALIZE_INPUT_REJECTED" };
  const profileId = deriveContainedProfileId(
    input.desired.workspaceId,
    input.desired.agentId,
    input.desired.hostId
  );
  try {
    const authority = promotionJournal(input);
    const transaction = readPromotionTransaction(
      profilesRoot,
      profileId,
      authority,
      input.desired.fence
    );
    const profileRoot = join(profilesRoot, profileId);
    if (
      !transaction ||
      transaction.status !== "COMMITTED" ||
      transaction.targetRevisionId !== input.desired.revisionId ||
      transaction.targetRevisionSequence !== input.desired.revisionSequence ||
      transaction.fence !== input.desired.fence ||
      existsSync(join(profilesRoot, `${profileId}.rollback-prior-good`)) ||
      !existsSync(profileRoot)
    )
      throw new Error("promotion finalize evidence rejected");
    const activeManifest = JSON.parse(
      readFileSync(join(profileRoot, "agent-profile.json"), "utf8")
    );
    if (
      activeManifest.profileId !== profileId ||
      activeManifest.revisionId !== transaction.targetRevisionId ||
      activeManifest.revisionSequence !== transaction.targetRevisionSequence ||
      activeManifest.profileDigest !== transaction.targetProfileDigest
    )
      throw new Error("promotion finalize target rejected");
    removePromotionTransaction(profilesRoot, profileId);
    return { ok: true, status: "FINALIZED", profileId };
  } catch {
    return { ok: false, status: "FINALIZE_UNPROVEN", profileId };
  }
}

async function rollback({
  profilesRoot,
  profileRoot,
  backupRoot,
  runtimeSecretsRoot,
  profileId,
  desired,
  ports,
  started,
  preserveSecrets,
  priorObservation,
  runtimeIdentity,
}) {
  if (started) {
    try {
      await ports.gateway.stop({
        profileId,
        reason: "validation_or_readback_failed",
      });
    } catch {}
  }
  if (existsSync(profileRoot))
    await ports.ownership.remove({
      profileId,
      profileRoot,
      slot: "ACTIVE",
      revisionId: desired.revisionId,
      fence: desired.fence,
    });
  let outcome = "REMOVED";
  if (existsSync(backupRoot)) {
    renameSync(backupRoot, profileRoot);
    outcome = "RESTORED";
  }
  if (!preserveSecrets) {
    cleanupSecrets(runtimeSecretsRoot, profileId);
    try {
      await ports.credential.cleanup({ profileId });
    } catch {}
  }
  fsyncDirectory(profilesRoot);
  if (outcome === "RESTORED") {
    if (!preserveSecrets || !priorObservation) return "RESTORE_UNPROVEN";
    return (await restartAndProvePrior({
      profileRoot,
      profileId,
      priorObservation,
      ports,
      runtimeIdentity,
    }))
      ? "RESTORED_AND_RESTARTED"
      : "RESTORE_UNPROVEN";
  }
  return outcome;
}

async function materializeAgentProfileLocked(input = {}) {
  const valid = validateDesired(input.desired);
  if (!valid.ok)
    return { ok: false, status: "DESIRED_REJECTED", code: valid.code };
  if (!portsValid(input.ports)) return { ok: false, status: "PORT_REJECTED" };
  const profilesRoot = traversableProfilesRoot(input.profilesRoot);
  const runtimeSecretsRoot = privateRoot(input.runtimeSecretsRoot);
  if (!profilesRoot || !runtimeSecretsRoot)
    return { ok: false, status: "PATH_REJECTED" };
  if (
    !input.runtimeIdentity ||
    input.runtimeIdentity.user !== "sellable-agent-runtime" ||
    !Number.isSafeInteger(input.runtimeIdentity.uid) ||
    input.runtimeIdentity.uid < 1 ||
    !Number.isSafeInteger(input.runtimeIdentity.gid) ||
    input.runtimeIdentity.gid < 1
  )
    return { ok: false, status: "IDENTITY_REJECTED" };

  const desired = input.desired;
  const profileId = deriveContainedProfileId(
    desired.workspaceId,
    desired.agentId,
    desired.hostId
  );
  const profileRoot = join(profilesRoot, profileId);
  const stagingRoot = join(
    profilesRoot,
    `${profileId}.staging-${desired.revisionId}-${desired.fence}`
  );
  const backupRoot = join(profilesRoot, `${profileId}.rollback-prior-good`);
  let startAttempted = false;
  let promoted = false;
  let recoveredInterruptedPromotion = false;
  let priorObservation = null;
  let reusedSecrets = false;
  try {
    const authority = promotionJournal(input);
    const recovery = await recoverInterruptedProfilePromotion(input);
    if (!recovery.ok)
      return {
        ok: false,
        status: recovery.status,
        profileId,
        recoveryPredicate: "exact_prior_good_restart_and_observation_required",
      };
    recoveredInterruptedPromotion =
      recovery.status === "RECOVERED_AND_RESTARTED";
    if (existsSync(backupRoot)) {
      return {
        ok: false,
        status: "RECOVERY_UNPROVEN",
        profileId,
        recoveryPredicate: "promotion_transaction_evidence_required",
      };
    }
    await input.ports.ownership.remove({
      profileId,
      profileRoot: stagingRoot,
      slot: "STAGING",
      revisionId: desired.revisionId,
      fence: desired.fence,
    });
    const liveStateIdentity = preservedLiveStateIdentity(profileRoot);
    renderStagedProfile(stagingRoot, desired);
    mergeLiveMutableState(profileRoot, stagingRoot);
    if (
      liveStateIdentity !== null &&
      preservedLiveStateIdentity(stagingRoot) !== liveStateIdentity
    ) {
      throw new Error("live mutable state identity changed during staging");
    }
    const staged = validateAgentProfileBundle({
      profileRoot: stagingRoot,
      desired,
    });
    if (!staged.ok) {
      removeDirect(profilesRoot, stagingRoot);
      return { ok: false, status: "VALIDATION_REJECTED", code: staged.code };
    }
    const ownershipApplied = await input.ports.ownership.apply({
      profileRoot: stagingRoot,
      uid: input.runtimeIdentity.uid,
      gid: input.runtimeIdentity.gid,
      inventory: [...AGENT_PROFILE_INVENTORY],
      profileId,
      revisionId: desired.revisionId,
      fence: desired.fence,
      profileDigest: staged.hashes.profile,
    });
    const ownershipObserved = await input.ports.ownership.observe({
      profileRoot: stagingRoot,
    });
    if (
      !ownershipApplied?.ok ||
      !validateRuntimeOwnership(ownershipObserved, input.runtimeIdentity)
    ) {
      await input.ports.ownership.remove({
        profileId,
        profileRoot: stagingRoot,
        slot: "STAGING",
        revisionId: desired.revisionId,
        fence: desired.fence,
      });
      return { ok: false, status: "OWNERSHIP_REJECTED" };
    }

    const secrets = input.reuseInstalledSecrets
      ? reuseInstalledRuntimeSecrets({
          desired,
          runtimeSecretsRoot,
          mcpCredentialRoot: input.mcpCredentialRoot,
          observation: input.reuseInstalledSecrets,
          runtimeIdentity: input.runtimeIdentity,
        })
      : await materializeRuntimeSecrets({
          desired,
          runtimeSecretsRoot,
          ports: input.ports,
          serviceCredential:
            input.serviceCredential ?? input.ports.serviceCredential,
          runtimeIdentity: input.runtimeIdentity,
        });
    if (!secrets.ok) {
      await input.ports.ownership.remove({
        profileId,
        profileRoot: stagingRoot,
        slot: "STAGING",
        revisionId: desired.revisionId,
        fence: desired.fence,
      });
      if (!secrets.reused) cleanupSecrets(runtimeSecretsRoot, profileId);
      return {
        ok: false,
        status: "SECRET_BINDING_REJECTED",
        code: secrets.code,
      };
    }
    reusedSecrets = secrets.reused === true;
    if (input.prepareOnly !== true) {
      const containment = await input.ports.containment.probe({
        profileRoot: stagingRoot,
        runtimeIdentity: input.runtimeIdentity,
        workerIdentity: { workerId: desired.workerId },
        serviceSecretFiles: secrets.files,
      });
      if (
        !containment?.ok ||
        containment.runtimeUid !== input.runtimeIdentity.uid ||
        [
          "siblingReadDenied",
          "workerReadDenied",
          "adminReadDenied",
          "providerBytesDenied",
          "hostMountDenied",
          "dockerDenied",
          "unexpectedToolDenied",
          "wrongWorkspaceDispatchDenied",
        ].some((key) => containment[key] !== true)
      ) {
        await input.ports.ownership.remove({
          profileId,
          profileRoot: stagingRoot,
          slot: "STAGING",
          revisionId: desired.revisionId,
          fence: desired.fence,
        });
        if (!secrets.reused) {
          cleanupSecrets(runtimeSecretsRoot, profileId);
          await input.ports.credential.cleanup({ profileId });
        }
        return { ok: false, status: "CONTAINMENT_REJECTED" };
      }
    }

    const hadPrior = existsSync(profileRoot);
    if (
      hadPrior &&
      (input.reuseInstalledSecrets || input.priorKnownGoodObservation)
    ) {
      priorObservation =
        input.priorKnownGoodObservation ??
        (await input.ports.gateway.observe({
          profileId,
          profileRoot,
          priorGood: true,
        }));
    }
    if (hadPrior)
      writePromotionTransaction({
        profilesRoot,
        profileId,
        desired,
        targetProfileDigest: staged.hashes.profile,
        reusedSecrets,
        priorObservation,
        authority,
      });
    if (hadPrior) renameSync(profileRoot, backupRoot);
    if (hadPrior && input.checkpoint) await input.checkpoint("after-backup");
    renameSync(stagingRoot, profileRoot);
    fsyncDirectory(profilesRoot);
    promoted = true;
    if (input.checkpoint) await input.checkpoint("after-promote");
    const active = staged;
    if (input.prepareOnly === true) {
      if (!hadPrior || !reusedSecrets || !existsSync(backupRoot)) {
        throw new Error(
          "prepared promotion requires prior-good bytes and reused secrets"
        );
      }
      return {
        ok: true,
        status: "PREPARED",
        profileId,
        recoveredInterruptedPromotion,
        backupRetained: true,
        receipt: {
          producer: "sellable-agent-profile-materializer",
          subject: `agent-profile:${profileId}`,
          revisionId: desired.revisionId,
          profileDigest: active.hashes.profile,
          xappFingerprint: secrets.xappFingerprint,
          xoxbFingerprint: secrets.xoxbFingerprint,
          serviceCredentialFingerprint: secrets.serviceCredentialFingerprint,
          serviceCredentialGeneration: secrets.serviceCredentialGeneration,
        },
      };
    }
    const expected = expectedStaticObservation({
      desired,
      profileId,
      validation: active,
      secrets,
    });
    if (input.provisionOnly === true) {
      if (hadPrior || existsSync(backupRoot)) {
        throw new Error(
          "initial provisioning cannot replace an existing profile"
        );
      }
      return {
        ok: true,
        status: "PROVISIONED",
        profileId,
        recoveredInterruptedPromotion,
        backupRetained: false,
        observedLifecycle: "OFF",
        observation: {
          ...expected,
          revisionSequence: active.manifest.revisionSequence,
          tools: [...desired.toolInclude],
          process: null,
        },
        receipt: {
          producer: "sellable-agent-profile-materializer",
          subject: `agent-profile:${profileId}`,
          revisionId: desired.revisionId,
          profileDigest: active.hashes.profile,
          xappFingerprint: secrets.xappFingerprint,
          xoxbFingerprint: secrets.xoxbFingerprint,
          serviceCredentialFingerprint: secrets.serviceCredentialFingerprint,
          serviceCredentialGeneration: secrets.serviceCredentialGeneration,
        },
      };
    }
    startAttempted = true;
    await input.ports.gateway.start({
      profileId,
      profileRoot,
      identity: input.runtimeIdentity,
      argv: ["hermes", "--profile", profileId, "gateway", "run"],
      env: { HOME: "/profile", NODE_ENV: "production" },
      slackDelivery: {
        supervisorRunScript: "sellable-agent-runtime/run",
        appFd: 8,
        botFd: 9,
      },
      evidence: {
        revisionId: desired.revisionId,
        profileDigest: active.hashes.profile,
        xappFingerprint: secrets.xappFingerprint,
        xoxbFingerprint: secrets.xoxbFingerprint,
        serviceCredentialFingerprint: secrets.serviceCredentialFingerprint,
        serviceCredentialGeneration: secrets.serviceCredentialGeneration,
      },
    });
    const observed = await input.ports.gateway.observe({
      profileId,
      profileRoot,
    });
    if (
      !validateIndependentObservation(observed, expected, input.runtimeIdentity)
    ) {
      throw new Error("gateway readback mismatch");
    }
    const tools = await input.ports.mcp.discoverTools({
      profileId,
      profileRoot,
    });
    if (stableJson(tools) !== stableJson(desired.toolInclude))
      throw new Error("tool inventory mismatch");
    const safeRead = await input.ports.mcp.safeRead({
      profileId,
      workspaceId: desired.workspaceId,
      tool: desired.toolInclude[0],
    });
    if (!safeRead?.ok || safeRead.workspaceId !== desired.workspaceId)
      throw new Error("safe read mismatch");
    const backupRetained =
      input.retainPriorGood === true && existsSync(backupRoot);
    if (hadPrior) {
      const committed = commitRetainedProfilePromotion({
        ...input,
        targetObservation: observed,
      });
      if (!committed.ok) throw new Error("profile promotion commit unproven");
    }
    if (existsSync(backupRoot) && !backupRetained)
      await input.ports.ownership.remove({
        profileId,
        profileRoot: backupRoot,
        slot: "BACKUP",
        revisionId: desired.revisionId,
        fence: desired.fence,
      });
    if (hadPrior && !backupRetained) {
      const finalized = finalizeRetainedProfilePromotion(input);
      if (!finalized.ok) throw new Error("profile promotion finalize unproven");
    }
    return {
      ok: true,
      status: "READY",
      profileId,
      recoveredInterruptedPromotion,
      backupRetained,
      observation: {
        ...observed,
        revisionSequence: active.manifest.revisionSequence,
        tools: [...tools],
      },
      receipt: {
        producer: "sellable-agent-profile-materializer",
        subject: `agent-profile:${profileId}`,
        revisionId: desired.revisionId,
        profileDigest: active.hashes.profile,
        xappFingerprint: secrets.xappFingerprint,
        xoxbFingerprint: secrets.xoxbFingerprint,
        serviceCredentialFingerprint: secrets.serviceCredentialFingerprint,
        serviceCredentialGeneration: secrets.serviceCredentialGeneration,
      },
    };
  } catch (error) {
    if (error?.code === "SIMULATED_CRASH") {
      return {
        ok: false,
        status: "CRASHED",
        profileId,
        recoveryPredicate: "backup_exists_and_active_profile_absent",
      };
    }
    const outcome = await rollback({
      profilesRoot,
      profileRoot,
      backupRoot,
      runtimeSecretsRoot,
      profileId,
      desired,
      ports: input.ports,
      started: startAttempted,
      preserveSecrets: reusedSecrets,
      priorObservation,
      runtimeIdentity: input.runtimeIdentity,
    });
    removePromotionTransaction(profilesRoot, profileId);
    try {
      if (existsSync(stagingRoot))
        await input.ports.ownership.remove({
          profileId,
          profileRoot: stagingRoot,
          slot: "STAGING",
          revisionId: desired.revisionId,
          fence: desired.fence,
        });
    } catch {}
    return {
      ok: false,
      status:
        outcome === "RESTORED_AND_RESTARTED"
          ? "ROLLED_BACK"
          : outcome === "RESTORE_UNPROVEN"
            ? "ROLLBACK_UNPROVEN"
            : "READBACK_REJECTED",
      rolledBack: promoted,
      rollback: { outcome },
    };
  }
}

export async function materializeAgentProfile(input = {}) {
  const valid = validateDesired(input.desired);
  const root = traversableProfilesRoot(input.profilesRoot);
  if (!valid.ok || !root) return materializeAgentProfileLocked(input);
  const profileId = deriveContainedProfileId(
    input.desired.workspaceId,
    input.desired.agentId,
    input.desired.hostId
  );
  try {
    return await withProfileSoulLock(
      profileId,
      () => materializeAgentProfileLocked(input),
      { dataRoot: basename(root) === "profiles" ? dirname(root) : root }
    );
  } catch {
    return { ok: false, status: "LOCK_REJECTED", profileId };
  }
}

export const NATIVE_SLACK_CUSTOMER_PROFILE_INVENTORY = Object.freeze([
  SELLABLE_BROWSER_TOOLSET_DEFAULT_MARKER,
  ".env",
  ".no-bundled-skills",
  "agent-profile.json",
  "config.yaml",
  "shell-hooks-allowlist.json",
  "sellable/mcp.json",
  "sellable/runtime-binding.json",
  "SOUL.md",
  "skills/sellable/SKILL.md",
]);

const LEGACY_INTERNAL_ADMIN_PROFILE_ROOT = "/opt/data/profiles/sellable-admin";

function repointInternalCronProfileReferences(desired, profileRoot) {
  if (desired.workspaceId !== SELLABLE_INTERNAL_AGENT_WORKSPACE_ID) return;
  const jobsPath = join(profileRoot, "cron", "jobs.json");
  if (!existsSync(jobsPath)) return;
  const entry = lstatSync(jobsPath);
  if (
    entry.isSymbolicLink() ||
    !entry.isFile() ||
    (entry.mode & 0o022) !== 0 ||
    entry.size > 1024 * 1024
  ) {
    throw new Error("native_slack_cron_jobs_rejected");
  }
  const current = readFileSync(jobsPath, "utf8");
  JSON.parse(current);
  if (!current.includes(LEGACY_INTERNAL_ADMIN_PROFILE_ROOT)) return;
  const updated = current.replaceAll(
    LEGACY_INTERNAL_ADMIN_PROFILE_ROOT,
    `/opt/data/profiles/${desired.profileId}`
  );
  JSON.parse(updated);
  atomicWrite(jobsPath, updated, entry.mode & 0o777);
}

const NATIVE_SLACK_KEYS = [
  "runtimeMode",
  "workspaceId",
  "agentId",
  "runtimeId",
  "profileId",
  "revisionId",
  "revisionSequence",
  "installationId",
  "teamId",
  "botUserId",
  "slackAppGeneration",
  "slackGeneration",
  "routeGeneration",
  "membershipGeneration",
  "serviceCredentialGeneration",
  "modelCredentialGeneration",
  "modelActivationId",
  "modelBundleGeneration",
  "modelPolicyHash",
  "apiServerKeyGeneration",
  "apiServerKeyFingerprint",
  "runtimeGeneration",
  "selectedChannelIds",
  "defaultChannelId",
  "memberAllowlist",
  "accessPolicyHash",
  "runtimeDesiredHash",
  "hermesVersion",
  "installerPackage",
  "mcpPackage",
  "policyHash",
  "customerProgramTimezone",
  "soul",
  "skill",
];

function isIanaTimezone(value) {
  if (typeof value !== "string" || !value.trim()) return false;
  try {
    new Intl.DateTimeFormat("en", { timeZone: value }).format(new Date(0));
    return true;
  } catch {
    return false;
  }
}

function validateNativeSlackDesired(desired) {
  if (!exactKeys(desired, NATIVE_SLACK_KEYS)) {
    return { ok: false, code: "native_slack_profile_schema_invalid" };
  }
  if (
    desired.runtimeMode !== "native_slack_customer" ||
    !isIanaTimezone(desired.customerProgramTimezone) ||
    [
      "workspaceId",
      "agentId",
      "runtimeId",
      "profileId",
      "revisionId",
      "installationId",
    ].some((key) => !SAFE_ID.test(desired[key] ?? "")) ||
    !/^T[A-Z0-9]{8,20}$/.test(desired.teamId ?? "") ||
    !/^[UW][A-Z0-9]{8,20}$/.test(desired.botUserId ?? "") ||
    !Number.isSafeInteger(desired.revisionSequence) ||
    desired.revisionSequence < 1 ||
    [
      "slackAppGeneration",
      "slackGeneration",
      "routeGeneration",
      "membershipGeneration",
      "serviceCredentialGeneration",
      "modelCredentialGeneration",
      "modelBundleGeneration",
      "apiServerKeyGeneration",
      "runtimeGeneration",
    ].some((key) => !Number.isSafeInteger(desired[key]) || desired[key] < 1) ||
    desired.modelCredentialGeneration !== desired.modelBundleGeneration ||
    !MODEL_AUTH_ACTIVATION_ID.test(desired.modelActivationId ?? "") ||
    !SHA256.test(desired.modelPolicyHash ?? "") ||
    !Array.isArray(desired.selectedChannelIds) ||
    desired.selectedChannelIds.length < 1 ||
    desired.selectedChannelIds.some(
      (value) => !/^C[A-Z0-9]{8,20}$/.test(value)
    ) ||
    stableJson([...new Set(desired.selectedChannelIds)].sort()) !==
      stableJson(desired.selectedChannelIds) ||
    !desired.selectedChannelIds.includes(desired.defaultChannelId) ||
    !Array.isArray(desired.memberAllowlist) ||
    desired.memberAllowlist.some(
      (value) => !/^[UW][A-Z0-9]{8,20}$/.test(value)
    ) ||
    stableJson([...new Set(desired.memberAllowlist)].sort()) !==
      stableJson(desired.memberAllowlist) ||
    !SHA256.test(desired.policyHash ?? "") ||
    !SHA256.test(desired.accessPolicyHash ?? "") ||
    !SHA256.test(desired.runtimeDesiredHash ?? "") ||
    !FINGERPRINT.test(desired.apiServerKeyFingerprint ?? "") ||
    desired.hermesVersion !== "0.21.5" ||
    !/^@sellable\/install@\d+\.\d+\.\d+(?:[-.A-Za-z0-9]+)?$/.test(
      desired.installerPackage ?? ""
    ) ||
    !/^@sellable\/mcp@\d+\.\d+\.\d+(?:[-.A-Za-z0-9]+)?$/.test(
      desired.mcpPackage ?? ""
    ) ||
    typeof desired.soul !== "string" ||
    typeof desired.skill !== "string" ||
    RAW_SECRET.test(desired.soul) ||
    RAW_SECRET.test(desired.skill)
  ) {
    return { ok: false, code: "native_slack_profile_identity_invalid" };
  }
  return { ok: true };
}

function nativeSlackCustomerFiles(desired, soulBytes = desired.soul) {
  const runtimeSecretRoot = `/run/sellable-agent/${desired.profileId}`;
  const runtimeBinding = createMcpRuntimeBindingV2(desired);
  const config = applyHermesSellableHostedPolicy({
    profile: desired.profileId,
    runtime: {
      mode: desired.runtimeMode,
      socketMode: true,
      publicListener: false,
      lazyInstall: false,
    },
    hermes: {
      version: desired.hermesVersion,
      optionalCapabilities: [],
      runtimeInstallAllowed: false,
    },
    cron: {
      wrap_response: false,
    },
    model: {
      provider: FLY_CUSTOMER_MODEL_PROVIDER,
      default: FLY_CUSTOMER_MODEL_ID,
      reasoning_effort: FLY_CUSTOMER_MODEL_REASONING_EFFORT,
      generation: desired.modelBundleGeneration,
      activation_id: desired.modelActivationId,
      policy_hash: desired.modelPolicyHash,
    },
    agent: {
      reasoning_effort: FLY_CUSTOMER_MODEL_REASONING_EFFORT,
    },
    slack: {
      require_mention: true,
      strict_mention: false,
      allow_bots: "none",
      allowed_channels: [...desired.selectedChannelIds],
    },
    platforms: {
      slack: {
        enabled: true,
        reply_to_mode: "all",
        gateway_restart_notification: false,
        typing_indicator: true,
      },
    },
    platform_toolsets: { slack: [...SELLABLE_DEFAULT_SLACK_TOOLSETS] },
    hooks: HERMES_SNAPSHOT_HOOKS,
    mcp_servers: {
      sellable: {
        command:
          "/usr/local/lib/sellable-agent/external-runtime/mcp/bin/sellable-mcp",
        args: [],
        enabled: true,
        env: {
          SELLABLE_CONFIG_PATH: `/opt/data/profiles/${desired.profileId}/sellable/mcp.json`,
          SELLABLE_AGENT_SERVICE_CREDENTIAL_FILE: `${runtimeSecretRoot}/service-credential`,
          SELLABLE_AGENT_PROFILE_ID: desired.profileId,
          SELLABLE_AGENT_WORKSPACE_ID: desired.workspaceId,
          SELLABLE_AGENT_ID: desired.agentId,
          SELLABLE_AGENT_CREDENTIAL_GENERATION: String(
            desired.serviceCredentialGeneration
          ),
          SELLABLE_AGENT_POLICY_HASH: desired.policyHash,
          SELLABLE_AGENT_SELECTED_CHANNEL_IDS: JSON.stringify(
            desired.selectedChannelIds
          ),
          SELLABLE_LOCK_WORKSPACE_ID: desired.workspaceId,
          SELLABLE_REQUIRE_WORKSPACE_LOCK: "1",
        },
      },
      ...(desired.workspaceId === SELLABLE_INTERNAL_AGENT_WORKSPACE_ID
        ? {
            "sellable-admin": {
              command:
                "/usr/local/lib/sellable-agent/internal-admin-mcp/node_modules/.bin/sellable-admin-mcp",
              args: [],
              enabled: true,
              env: {
                SELLABLE_ADMIN_HOME: `${runtimeSecretRoot}/admin-settings`,
                SELLABLE_ADMIN_CONFIG_PATH: `${runtimeSecretRoot}/admin-settings/settings.json`,
                SELLABLE_ADMIN_STATE_PATH: `${runtimeSecretRoot}/admin-settings/config-state.json`,
              },
            },
          }
        : {}),
    },
  });
  const mcp = {
    package: desired.mcpPackage,
    workspaceLockId: desired.workspaceId,
    requireWorkspaceLock: true,
    policyHash: desired.policyHash,
    runtimeMode: desired.runtimeMode,
    transport: {
      nativeHermesSessionContext: true,
      trustedOuterMetadata: "_meta.sellableAgent",
      processGlobalIdentityAllowed: false,
    },
    serviceCredential: {
      file: `${runtimeSecretRoot}/service-credential`,
      generation: desired.serviceCredentialGeneration,
    },
    requestChannelPolicy: {
      source: "_meta.sellableAgent.channelId",
      selectedChannelIds: [...desired.selectedChannelIds],
      defaultChannelId: desired.defaultChannelId,
    },
  };
  return {
    [SELLABLE_BROWSER_TOOLSET_DEFAULT_MARKER]: "enabled\n",
    ".env": "",
    // The runtime materializer owns this profile's exact skill bytes. Avoid
    // Hermes re-scanning and re-copying its entire bundled catalog on every
    // cold gateway start; explicit materialization remains the update path.
    ".no-bundled-skills": "",
    "config.yaml": `${JSON.stringify(config, null, 2)}\n`,
    "shell-hooks-allowlist.json": HERMES_SNAPSHOT_HOOK_ALLOWLIST_BYTES,
    "sellable/mcp.json": `${JSON.stringify(mcp, null, 2)}\n`,
    "sellable/runtime-binding.json": `${JSON.stringify(runtimeBinding, null, 2)}\n`,
    "SOUL.md": soulBytes,
    "skills/sellable/SKILL.md": desired.skill,
  };
}

function nativeSlackManifest(desired, files) {
  const fileHashes = Object.fromEntries(
    Object.entries(files)
      .sort(([left], [right]) => left.localeCompare(right))
      .map(([logicalPath, bytes]) => [
        logicalPath,
        sha256(
          logicalPath === "config.yaml"
            ? normalizedProfileConfigValueBytes(JSON.parse(bytes))
            : bytes
        ),
      ])
  );
  const body = {
    schemaVersion: "sellable-agent-native-slack-profile/v1",
    runtimeMode: desired.runtimeMode,
    workspaceId: desired.workspaceId,
    agentId: desired.agentId,
    runtimeId: desired.runtimeId,
    profileId: desired.profileId,
    revisionId: desired.revisionId,
    revisionSequence: desired.revisionSequence,
    installationId: desired.installationId,
    teamId: desired.teamId,
    botUserId: desired.botUserId,
    slackAppGeneration: desired.slackAppGeneration,
    slackGeneration: desired.slackGeneration,
    routeGeneration: desired.routeGeneration,
    membershipGeneration: desired.membershipGeneration,
    serviceCredentialGeneration: desired.serviceCredentialGeneration,
    modelCredentialGeneration: desired.modelCredentialGeneration,
    modelActivationId: desired.modelActivationId,
    modelBundleGeneration: desired.modelBundleGeneration,
    modelPolicyHash: desired.modelPolicyHash,
    apiServerKeyGeneration: desired.apiServerKeyGeneration,
    apiServerKeyFingerprint: desired.apiServerKeyFingerprint,
    runtimeGeneration: desired.runtimeGeneration,
    installerPackage: desired.installerPackage,
    mcpPackage: desired.mcpPackage,
    hermesVersion: desired.hermesVersion,
    policyHash: desired.policyHash,
    accessPolicyHash: desired.accessPolicyHash,
    runtimeDesiredHash: desired.runtimeDesiredHash,
    fileHashes,
  };
  return { ...body, profileDigest: sha256(stableJson(body)) };
}

function renderNativeSlackCustomerProfile(root, desired, soulBytes) {
  mkdirSync(root, { recursive: false, mode: 0o700 });
  const files = nativeSlackCustomerFiles(desired, soulBytes);
  for (const [logicalPath, bytes] of Object.entries(files)) {
    atomicWrite(
      join(root, logicalPath),
      bytes,
      logicalPath === "SOUL.md"
        ? 0o600
        : logicalPath.endsWith(".md")
          ? 0o444
          : 0o600
    );
  }
  const manifest = nativeSlackManifest(desired, files);
  atomicWrite(
    join(root, "agent-profile.json"),
    `${JSON.stringify(manifest, null, 2)}\n`,
    0o600
  );
  fsyncDirectory(root);
  return manifest;
}

export function validateNativeSlackCustomerProfile({ desired, profileRoot }) {
  const valid = validateNativeSlackDesired(desired);
  if (!valid.ok) return valid;
  try {
    if (
      !isAbsolute(profileRoot) ||
      !existsSync(profileRoot) ||
      lstatSync(profileRoot).isSymbolicLink() ||
      !lstatSync(profileRoot).isDirectory()
    ) {
      return { ok: false, code: "native_slack_profile_path_invalid" };
    }
    // Runtime caches and live gateway coordination files are disposable and
    // can contain large dependency trees, sockets, or symlinks. They are
    // already excluded from profile replacement and snapshots; traversing
    // them here only blocks the lifecycle heartbeat before replacement even
    // starts. Keep the closed inventory walk for every durable path.
    const found = inventory(profileRoot, { skipTransient: true });
    const serverOwned = [...NATIVE_SLACK_CUSTOMER_PROFILE_INVENTORY].sort();
    if (serverOwned.some((logicalPath) => !found.includes(logicalPath))) {
      return { ok: false, code: "native_slack_profile_inventory_open" };
    }
    const soulPath = join(profileRoot, "SOUL.md");
    const soulEntry = lstatSync(soulPath);
    if (
      soulEntry.isSymbolicLink() ||
      !soulEntry.isFile() ||
      (soulEntry.mode & 0o777) !== 0o600 ||
      soulEntry.uid !== (process.getuid?.() ?? soulEntry.uid) ||
      soulEntry.gid !== (process.getgid?.() ?? soulEntry.gid)
    ) {
      return { ok: false, code: "native_slack_soul_file_rejected" };
    }
    const soulBytes = readFileSync(soulPath);
    const files = nativeSlackCustomerFiles(desired, soulBytes);
    for (const [logicalPath, expected] of Object.entries(files)) {
      const pathValue = join(profileRoot, logicalPath);
      const link = lstatSync(pathValue);
      if (
        link.isSymbolicLink() ||
        !link.isFile() ||
        (link.mode & 0o022) !== 0 ||
        !(logicalPath === "config.yaml"
          ? normalizedProfileConfigBytes(pathValue).equals(
              normalizedProfileConfigValueBytes(JSON.parse(expected))
            )
          : readFileSync(pathValue).equals(Buffer.from(expected)))
      ) {
        return { ok: false, code: "native_slack_profile_file_drift" };
      }
    }
    const manifest = JSON.parse(
      readFileSync(join(profileRoot, "agent-profile.json"), "utf8")
    );
    const observedManifest = nativeSlackManifest(desired, files);
    const normalizedManifest = {
      ...manifest,
      fileHashes: {
        ...(manifest.fileHashes ?? {}),
        "SOUL.md": observedManifest.fileHashes["SOUL.md"],
      },
      profileDigest: observedManifest.profileDigest,
    };
    if (stableJson(normalizedManifest) !== stableJson(observedManifest)) {
      return { ok: false, code: "native_slack_profile_manifest_drift" };
    }
    const durableBytes = serverOwned
      .filter((logicalPath) => logicalPath !== "SOUL.md")
      .map((logicalPath) =>
        readFileSync(join(profileRoot, logicalPath), "utf8")
      )
      .join("\n");
    if (
      RAW_SECRET.test(durableBytes) ||
      /(?:0\.0\.0\.0|hostinger|multiplex|peer.?inventory|shared.?app.?token)/i.test(
        durableBytes
      )
    ) {
      return { ok: false, code: "native_slack_profile_policy_rejected" };
    }
    return {
      ok: true,
      manifest: observedManifest,
      revisionManifest: manifest,
      observedSoulRawSha256: sha256(soulBytes),
    };
  } catch {
    return { ok: false, code: "native_slack_profile_validation_failed" };
  }
}

export function materializeNativeSlackCustomerProfile({
  desired,
  profilesRoot,
  diskFreeBytes = filesystemAvailableBytes,
}) {
  const valid = validateNativeSlackDesired(desired);
  if (!valid.ok) return valid;
  const root = traversableProfilesRoot(profilesRoot);
  if (!root) {
    return { ok: false, code: "native_slack_profiles_root_rejected" };
  }
  const activeRoot = join(root, desired.profileId);
  const stagingRoot = join(
    root,
    `.${desired.profileId}.${randomUUID()}.staging`
  );
  const backupRoot = join(root, `.${desired.profileId}.materializer-backup`);
  const materialize = () => {
    try {
      if (dirname(activeRoot) !== root || dirname(stagingRoot) !== root) {
        return { ok: false, code: "native_slack_profile_path_rejected" };
      }
      if (existsSync(backupRoot)) {
        const backup = lstatSync(backupRoot);
        if (backup.isSymbolicLink() || !backup.isDirectory()) {
          throw new Error("native_slack_profile_backup_rejected");
        }
        if (!existsSync(activeRoot)) renameSync(backupRoot, activeRoot);
        else {
          const staleBackupRoot = join(
            root,
            `.${desired.profileId}.${randomUUID()}.cleanup`
          );
          renameSync(backupRoot, staleBackupRoot);
          scheduleNativeSlackTreeRemoval(root, staleBackupRoot);
        }
      }
      sweepStaleNativeSlackTrees(root, desired.profileId);
      const extraProfiles = readdirSync(root).filter((name) => {
        if (name === desired.profileId || name.startsWith(".")) return false;
        const pathValue = join(root, name);
        const entry = lstatSync(pathValue);
        return entry.isDirectory() || entry.isSymbolicLink();
      });
      if (extraProfiles.length > 0) {
        return {
          ok: false,
          code: "native_slack_extra_profile_rejected",
          extraProfiles: extraProfiles.sort(),
        };
      }
      if (existsSync(activeRoot)) {
        if (lstatSync(activeRoot).isSymbolicLink()) {
          throw new Error("active profile symlink rejected");
        }
        repointInternalCronProfileReferences(desired, activeRoot);
        const reusable = validateNativeSlackCustomerProfile({
          desired,
          profileRoot: activeRoot,
        });
        if (reusable.ok) {
          return {
            ok: true,
            status: "REUSED",
            profileId: desired.profileId,
            profileDigest: reusable.manifest.profileDigest,
            observedSoulRawSha256: reusable.observedSoulRawSha256,
          };
        }
      }
      const desiredSeedBytes = Object.values(
        nativeSlackCustomerFiles(desired)
      ).reduce(
        (total, bytes) => total + Buffer.byteLength(bytes),
        Buffer.byteLength(JSON.stringify(nativeSlackManifest(desired, {})))
      );
      // Replacement links durable same-volume state into staging, so it does
      // not need another full copy of the profile. Reserve only the managed
      // seed plus a bounded directory/metadata margin.
      const profileBytes = desiredSeedBytes;
      const requiredBytes =
        profileBytes + NATIVE_SLACK_MATERIALIZATION_MARGIN_BYTES;
      let availableBytes = Number(diskFreeBytes(root));
      if (!Number.isFinite(availableBytes) || availableBytes < 0) {
        throw new Error("native_slack_profile_disk_readback_invalid");
      }
      if (availableBytes < requiredBytes) {
        prunePressureCaches(root);
        availableBytes = Number(diskFreeBytes(root));
      }
      if (availableBytes < requiredBytes) {
        return {
          ok: false,
          code: "native_slack_profile_insufficient_disk",
          requiredBytes,
          availableBytes,
          profileBytes,
        };
      }
      let soulBytes = Buffer.from(desired.soul, "utf8");
      // A workspace snapshot can predate the dedicated native-Slack markers.
      // Materialization intentionally adds the one-time safe default toolsets
      // to that legacy profile. Normalize the source identity to the same
      // target representation so this migration is not mistaken for lost
      // live state while explicit legacy Slack toolsets remain exact.
      const liveStateIdentity = preservedLiveStateIdentity(activeRoot, {
        normalizeLegacyNativeDefault: true,
      });
      if (existsSync(activeRoot)) {
        const soulPath = join(activeRoot, "SOUL.md");
        if (existsSync(soulPath)) {
          const soulEntry = lstatSync(soulPath);
          if (soulEntry.isSymbolicLink() || !soulEntry.isFile()) {
            throw new Error("active soul rejected");
          }
          soulBytes = readFileSync(soulPath);
        }
      }
      const manifest = renderNativeSlackCustomerProfile(
        stagingRoot,
        desired,
        soulBytes
      );
      linkHermesState(activeRoot, stagingRoot);
      repointInternalCronProfileReferences(desired, stagingRoot);
      mergeLiveMutableConfig(activeRoot, stagingRoot);
      if (
        liveStateIdentity !== null &&
        preservedLiveStateIdentity(stagingRoot, {
          normalizeLegacyNativeDefault: true,
        }) !== liveStateIdentity
      ) {
        throw new Error("live mutable state identity changed during staging");
      }
      const staged = validateNativeSlackCustomerProfile({
        desired,
        profileRoot: stagingRoot,
      });
      if (!staged.ok) throw new Error(staged.code);
      if (existsSync(activeRoot)) {
        if (lstatSync(activeRoot).isSymbolicLink()) {
          throw new Error("active profile symlink rejected");
        }
        renameSync(activeRoot, backupRoot);
      }
      renameSync(stagingRoot, activeRoot);
      fsyncDirectory(root);
      if (existsSync(backupRoot)) {
        const cleanupRoot = join(
          root,
          `.${desired.profileId}.${randomUUID()}.cleanup`
        );
        renameSync(backupRoot, cleanupRoot);
        scheduleNativeSlackTreeRemoval(root, cleanupRoot);
      }
      return {
        ok: true,
        status: "MATERIALIZED",
        profileId: desired.profileId,
        profileDigest: manifest.profileDigest,
        observedSoulRawSha256: sha256(soulBytes),
      };
    } catch (error) {
      if (existsSync(stagingRoot) && !lstatSync(stagingRoot).isSymbolicLink()) {
        const cleanupRoot = join(
          root,
          `.${desired.profileId}.${randomUUID()}.cleanup`
        );
        renameSync(stagingRoot, cleanupRoot);
        scheduleNativeSlackTreeRemoval(root, cleanupRoot);
      }
      if (!existsSync(activeRoot) && existsSync(backupRoot)) {
        renameSync(backupRoot, activeRoot);
      }
      return {
        ok: false,
        code: "native_slack_profile_materialization_failed",
        causeCode: materializationCauseCode(error),
      };
    }
  };
  try {
    return withProfileSoulLock(desired.profileId, materialize, {
      dataRoot: basename(root) === "profiles" ? dirname(root) : root,
    });
  } catch (error) {
    return {
      ok: false,
      code: "native_slack_profile_materialization_failed",
      causeCode: materializationCauseCode(error),
    };
  }
}

export const NATIVE_SLACK_ADMIN_PROFILE_INVENTORY = Object.freeze([
  "agent-profile.json",
  "config.yaml",
  "sellable/mcp.json",
  "sellable/runtime-binding.json",
  "SOUL.md",
  "skills/sellable/SKILL.md",
]);

export const ADMIN_SETTINGS_FILE_INVENTORY = Object.freeze([
  ".env",
  "settings.json",
  "config-state.json",
]);

const ADMIN_SETTINGS_CORE_FILES = Object.freeze([
  ".env",
  "settings.json",
  "config-state.json",
]);

export function classifyAdminSettingsReadiness({
  settingsDirectory,
  filePaths = {},
}) {
  const root = privateRoot(settingsDirectory);
  if (
    !root ||
    (lstatSync(root).mode & 0o777) !== 0o700 ||
    Object.keys(filePaths).some(
      (name) => !ADMIN_SETTINGS_FILE_INVENTORY.includes(name)
    )
  ) {
    return { ok: false, code: "admin_settings_root_or_inventory_invalid" };
  }

  const present = new Set();
  for (const name of ADMIN_SETTINGS_FILE_INVENTORY) {
    const candidate = filePaths[name] ?? join(root, name);
    if (!isAbsolute(candidate)) {
      return {
        ok: false,
        code: "admin_settings_file_containment_invalid",
        name,
      };
    }
    if (!existsSync(candidate)) continue;
    let parent;
    let entry;
    try {
      parent = realpathSync(dirname(candidate));
      entry = lstatSync(candidate);
    } catch {
      return { ok: false, code: "admin_settings_file_type_invalid", name };
    }
    if (parent !== root || basename(candidate) !== name) {
      return {
        ok: false,
        code: "admin_settings_file_containment_invalid",
        name,
      };
    }
    if (entry.isSymbolicLink() || !entry.isFile()) {
      return { ok: false, code: "admin_settings_file_type_invalid", name };
    }
    if ((entry.mode & 0o777) !== 0o600) {
      return { ok: false, code: "admin_settings_file_mode_invalid", name };
    }
    present.add(name);
  }

  const missing = ADMIN_SETTINGS_FILE_INVENTORY.filter(
    (name) => !present.has(name)
  );
  return {
    ok: true,
    complete: missing.length === 0,
    coreReady: ADMIN_SETTINGS_CORE_FILES.every((name) => present.has(name)),
    missing,
  };
}

export function selectSellableAgentRuntimeImage({
  kind,
  generation,
  customerImage,
}) {
  if (kind === "CUSTOMER") {
    if (generation != null)
      throw new Error("customer_admin_generation_rejected");
    return { kind, image: customerImage, namespace: "customer" };
  }
  if (
    kind !== "ADMIN" ||
    generation?.agentKind !== "ADMIN" ||
    generation?.state !== "ACTIVE" ||
    generation?.adminImageDigest == null
  )
    throw new Error("admin_runtime_generation_required");
  return {
    kind,
    image: generation.adminImageDigest,
    namespace: `admin:${generation.agentId}`,
  };
}

export function buildNativeSlackAdminMcpProfile({
  customerConfig,
  generation,
  settingsDirectory = "/run/sellable-agent/admin-settings",
}) {
  if (
    generation?.agentKind !== "ADMIN" ||
    generation?.state !== "ACTIVE" ||
    !isAbsolute(settingsDirectory) ||
    (lstatSync(settingsDirectory).mode & 0o777) !== 0o700
  )
    throw new Error("admin_profile_generation_rejected");
  const sellable = customerConfig?.mcp_servers?.sellable;
  if (
    !sellable ||
    !isAbsolute(sellable.command) ||
    Array.isArray(sellable.args) === false ||
    sellable.args.length !== 0
  )
    throw new Error("customer_product_mcp_rejected");
  const adminCommand =
    "/usr/local/lib/sellable-agent/admin-runtime/admin-mcp/bin/sellable-admin-mcp";
  return {
    ...customerConfig,
    mcp_servers: {
      sellable: structuredClone(sellable),
      "sellable-admin": {
        command: adminCommand,
        args: [],
        enabled: true,
        env: { SELLABLE_ADMIN_SETTINGS_DIR: settingsDirectory },
      },
    },
  };
}

/**
 * @param {{
 *   profile: any;
 *   observedServers: readonly string[];
 *   expectedTools?: Record<string, readonly string[]>;
 *   observedTools: Record<string, readonly string[]>;
 *   profileContract?: any;
 * }} input
 */
export function validateClosedAdminMcpInventory({
  profile,
  observedServers,
  expectedTools,
  observedTools,
  profileContract,
}) {
  if (profileContract !== undefined) {
    const { digest: contractDigest, ...unsignedContract } =
      profileContract ?? {};
    const packages = [
      profileContract?.packages?.sellable?.mcp,
      profileContract?.packages?.sellable?.install,
      profileContract?.packages?.["sellable-admin"]?.mcp,
      profileContract?.packages?.["sellable-admin"]?.install,
    ];
    if (
      profileContract?.schemaVersion !== "sellable-admin-profile-contract/v1" ||
      !/^\/opt\/data\/profiles\/[A-Za-z0-9_-]{1,128}$/.test(
        profileContract?.profileHome ?? ""
      ) ||
      stableJson(profileContract?.aliases) !==
        stableJson(["sellable", "sellable-admin"]) ||
      !SHA256.test(profileContract?.contentDigest ?? "") ||
      !SHA256.test(contractDigest ?? "") ||
      sha256(stableJson(unsignedContract)) !== contractDigest ||
      packages.some(
        (entry) =>
          typeof entry?.name !== "string" ||
          !entry.name ||
          typeof entry?.version !== "string" ||
          !entry.version ||
          !/^sha512-[A-Za-z0-9+/]+={0,2}$/.test(entry?.integrity ?? "") ||
          !SHA256.test(entry?.contentSha256 ?? "")
      ) ||
      !Array.isArray(profileContract?.tools?.sellable) ||
      !Array.isArray(profileContract?.tools?.["sellable-admin"])
    ) {
      return { ok: false, code: "admin_profile_contract_invalid" };
    }
    expectedTools = profileContract.tools;
  }
  const names = Object.keys(profile?.mcp_servers ?? {}).sort();
  const expectedNames = profileContract?.aliases ?? [
    "sellable",
    "sellable-admin",
  ];
  if (stableJson(names) !== stableJson(expectedNames))
    return { ok: false, code: "admin_mcp_server_inventory_open" };
  if (stableJson([...observedServers].sort()) !== stableJson(names))
    return { ok: false, code: "admin_mcp_server_readback_drift" };
  for (const name of names) {
    const command = profile.mcp_servers[name]?.command;
    if (
      !isAbsolute(command ?? "") ||
      /(?:@latest|npm|npx|sh|bash)/.test(command) ||
      stableJson([...(observedTools[name] ?? [])].sort()) !==
        stableJson([...(expectedTools[name] ?? [])].sort())
    )
      return { ok: false, code: "admin_mcp_inventory_or_command_drift" };
  }
  return { ok: true };
}

export function verifyExactAdminProfileContract({ expected, actual }) {
  if (
    expected?.schemaVersion !== "sellable-admin-profile-contract/v1" ||
    !SHA256.test(expected?.digest ?? "") ||
    stableJson(expected) !== stableJson(actual)
  ) {
    throw new Error("admin_profile_contract_mismatch");
  }
  const { digest: expectedDigest, ...unsigned } = expected;
  if (sha256(stableJson(unsigned)) !== expectedDigest) {
    throw new Error("admin_profile_contract_digest_invalid");
  }
  return structuredClone(expected);
}