pleach
Cookbook

enterpriseAgent

Compliance scrubber + sub-agent attribution + procurement-visible permittedFamilies envelope, stacked into one factory. The frontier-lab direct-enterprise recipe — two of the three pillars wired in-process; the third (gateway-side family failover) reads the envelope at runtime.

enterpriseAgent stacks two of the three pillars frontier-lab direct-enterprise buyers purchase Pleach for into a single factory: compliance scrubbing on the user message boundary, and sub-agent attribution paths for joinable cost and usage rows. The third pillar — gateway-side provider failover — is procurement-visible only at this layer: the recipe stamps a declared permittedFamilies envelope on the runtime via a sentinel symbol so a gateway-aware host wiring can read it and enforce the cascade.

Best fit: a frontier-lab direct enterprise. The defining question is "We already pay Anthropic / OpenAI directly. What does Pleach give us that the SDK doesn't?" This recipe is the in-process answer to two thirds of that question.

Quickstart

import { init } from "@pleach/observe";
import { memory } from "@pleach/observe/destinations";
import { enterpriseAgent, ENTERPRISE_PERMITTED_FAMILIES_TAG } from "@pleach/recipes/enterprise-agent";

init({ destination: memory() });

const bot = enterpriseAgent({
  profile: "soc2", // hipaa | gdpr | pci-dss | soc2 — P16 canonical baseline is soc2
  serviceName: "notion-ai",
  subTenantId: "workspace-abc",
  permittedFamilies: ["anthropic", "openai"], // declared failover envelope
  orchestratorConfig: {
    provider: "anthropic",
    model: "claude-sonnet-4-6",
    apiKey: process.env.ANTHROPIC_API_KEY!,
  },
});

await bot.ask("Summarize this PR for the eng review channel.");

// A gateway-aware host wiring reads the declared envelope:
const envelope = bot.runtime[ENTERPRISE_PERMITTED_FAMILIES_TAG];
// -> Object.freeze(["anthropic", "openai"])

What it does

The recipe layers three things on top of simpleChatbot:

  1. Compliance scrubbing — delegates to compliantChatbot({profile}) for PHI/PII redaction on user messages. The profile selects a curated bundle from @pleach/compliance/scrubbers; extraScrubbers runs after the profile bundle (last-wins on overlap).
  2. Sub-agent attribution — wraps ask() in subagent(serviceName).run(...) from @pleach/observe. When subTenantId is set, a nested subagent(subTenantId).run(...) runs inside the outer scope, so the attribution path becomes [serviceName, subTenantId].
  3. Declared failover envelope — when permittedFamilies is supplied, the recipe stamps the frozen array on the returned runtime via the ENTERPRISE_PERMITTED_FAMILIES_TAG Symbol.for(...) key. A gateway-aware host reads runtime[ENTERPRISE_PERMITTED_FAMILIES_TAG] to enforce the cascade. The recipe itself does NOT enforce.

Config reference

type ComplianceProfile = "hipaa" | "gdpr" | "pci-dss" | "soc2";

interface EnterpriseAgentConfig extends Omit<CompliantChatbotConfig, "profile"> {
  /**
   * Compliance scrubber profile — same enum as compliantChatbot.
   * Defaults to "soc2" (the canonical enterprise baseline). Buyers with
   * stricter regulatory needs set explicitly.
   */
  profile?: ComplianceProfile;

  /**
   * Sub-agent attribution label — the buyer's service name as it
   * appears on the dashboard. Defaults to "pleach-enterprise".
   */
  serviceName?: string;

  /**
   * Optional sub-tenant identifier appended to the attribution
   * path. When set, the path becomes [serviceName, subTenantId].
   * The recipe does NOT validate the sub-tenant against a tenant
   * store; that's @pleach/gateway's TenantResolver boundary.
   */
  subTenantId?: string;

  /**
   * Declared provider-failover envelope. Procurement-visible
   * only — the recipe surfaces this on the runtime via
   * ENTERPRISE_PERMITTED_FAMILIES_TAG so a gateway-aware host
   * can enforce the cascade. The recipe itself does NOT
   * enforce. Canonical values: subset of ["anthropic",
   * "openai", "google", "deepseek", "moonshot", "mistral"].
   */
  permittedFamilies?: readonly string[];

  /** Extra scrubbers run AFTER the profile bundle. */
  extraScrubbers?: readonly ComplianceScrubber[];
}

export const ENTERPRISE_PERMITTED_FAMILIES_TAG: unique symbol;

Common gotchas

  • permittedFamilies is gateway-aware, not gateway-bound. Without @pleach/gateway wired into your host, the envelope is informational only — the recipe stamps it on the runtime, but no in-process code enforces the cascade. The gateway is the commercial SKU; reach for it when the failover claim needs to be enforced at the provider boundary.
  • subTenantId nests inside serviceName. The attribution path is [serviceName, subTenantId] — outer first, inner second. Pick the order to match the GROUP BY your billing schema runs.
  • Compliance scope-limit: user messages only, not assistant responses. Scrubbing applies to the user message before the runtime sees it. The model's reply is not post-processed. If you need to redact PII from generated text, run a scrubber pass in your UI layer or compose ComplianceRuntime from @pleach/compliance directly.
  • init({destination}) is a process-singleton. Call once at app boot, before any ask(). The recipe does NOT call init itself.
  • The recipe does NOT bundle an EvalSuite. Provider neutrality is unverified without a parity validator. Use evalLab from @pleach/recipes/eval-lab alongside this recipe for the validation loop.
  • Two optional peers. @pleach/compliance and @pleach/observe are OPTIONAL peers of @pleach/recipes. Install both alongside this recipe. The compliance peer gracefully degrades (warns and returns a no-redaction chatbot per the compliantChatbot contract); the observe peer must be installed for the subpath import to resolve.

See also

On this page