# enterpriseAgent (/docs/recipes/enterprise-agent)



`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*&#x2A;. The
defining question is &#x2A;"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 [#quickstart]

```ts
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 [#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 [#config-reference]

```ts
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 [#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`](/docs/recipes/eval-lab) 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 [#see-also]

* [`@pleach/recipes` overview](/docs/recipes-pleach-recipes)
  — every recipe in one page.
* [`@pleach/compliance`](/docs/compliance) — scrubber
  library and `ComplianceRuntime`.
* [`@pleach/observe`](/docs/observe) — `init`, `recordCall`,
  `subagent`, the four destinations.
* [`@pleach/gateway`](/docs/gateway) — the commercial SKU
  whose cascade reads the declared envelope.
* [`compliantChatbot`](/docs/recipes/compliant-chatbot) —
  the underlying compliance recipe `enterpriseAgent`
  composes.
* [`evalLab`](/docs/recipes/eval-lab) — the provider-parity
  validator that pairs with `enterpriseAgent` for the
  failover-claim verification loop.
* [`Regulated domain agent`](/docs/regulated-domain-agent)
  — full-system pattern with hash-chain attestation.
