# Isis Generation Control

Isis is the governed-generation control plane of V1: every image, video, audio,
voice, 3D, and Living Scene render the product produces must pass through an
Isis-registered workflow class, an Isis-registered model, and the Isis
release-gate machinery before it can reach a customer. Raw provider machinery —
ComfyUI on RunPod, Stability, ElevenLabs, Suno, fal.ai-hosted video, Civitai
model intake — is never customer-facing; **Isis is the only path**. This page is
the substrate companion to the audience-facing surfaces: it specifies the
registries, the promotion lifecycle, the fail-closed dispatch seam, provenance
bundles, release gates, failover policy, and the operator surface. For how those
capabilities are exposed to different customers, see
[Generation Audience Tiers and Surface Boundaries](./generation-tiers-and-surfaces.md),
[External Model Intelligence and Execution Providers](./external-models-and-execution.md),
and [Output Gallery, Lineage, Branch, and Replay](./output-gallery-lineage.md).

## Where Isis sits, and what is real versus gated

The Isis control plane in V1 is a fully typed, unit-tested **contract and policy
layer**, with the live provider execution deliberately held behind a deploy-time
boundary. It is honest to call out exactly which pieces are enforced in-repo and
which depend on credentials:

- **Real, in-repo, unit-tested.** The whole `@oshun/generation-control-isis`
  library: the workflow-template / model / provider registry specs, the
  environment-promotion state machine, the release-gate model, the
  `CanonicalProvenanceBundle` schema, the per-family failover policy with
  circuit breaker, the Civitai intake spec and review pipeline, the ComfyUI
  governance module, and — most importantly — the fail-closed
  `evaluateIsisDispatch` / `dispatchGuardedGeneration` seam that makes "Isis is
  the only path" _structurally_ true rather than merely aspirational. The Zod
  contracts `WorkflowTemplate` / `ModelCard` / `ModelVersion` /
  `ProvenanceBundle` also exist in `libs/contracts/src/common/`. The
  `apps/isis/*` services exist (`cli`, `generation-api`, `gpu-worker`,
  `output-registry`, `web`, `workflow-registry`).
- **Boundary-gated / aspirational.** The actual provider execution. The
  generation route ships a fail-closed `notConfiguredProviderExecutor` by
  default — the real ComfyUI/RunPod (and Stability/ElevenLabs/Suno/fal.ai)
  client is swapped in only at the app boundary, at deploy time, with live keys.
  So _the gate is always exercised_, but _end-to-end live generation_ depends on
  deploy creds and is not run in the default e2e suite. The provenance/ledger
  assertions execute only behind the
  `OSHUN_ISIS_PROVENANCE_LEDGER_FIXTURE=clean` +
  `OSHUN_ENABLE_TEST_HARNESSES=true` test-harness env gate. The operator
  release-gate dashboard is data-modeled (`admin-view-models.ts`); a rendered
  admin UI is planned but not verified here.

The library is published as the workspace package
`@oshun/generation-control-isis`
(`libs/oshun/generation-control-isis/package.json`). It has a single runtime
dependency, `@oshun/types`; `main`/`types` point at `./src/index.ts` (source,
not a built `dist`), and it exposes two subpath exports, `./adapter` and
`./canonical-adapter`. The barrel `src/index.ts` re-exports twenty modules:
`types`, `control-model`, `adapter`, `canonical-adapter`,
`workflow-template-registry-spec`, `model-registry-spec`,
`provider-registry-spec`, `environment-promotion-model`, `release-gate-model`,
`provenance-bundle-schema`, `staging-recipe-schema`, `provider-failover-policy`,
`request-routing`, `promotion-routing`, `admin-view-models`,
`civitai-intake-spec`, `civitai-review-pipeline`, `comfyui-governance`,
`dispatch-guard`, and `generation-dispatcher`.

## The dispatch guard — the single enforcement seam

The claim that "Isis is the only path; raw provider machinery is never
customer-facing" is not a slogan in V1 — it is a single, concrete, fail-closed
code seam. Two files carry it, and their own header comments record the audit
finding that motivated them: the release gate was real and tested, but the
library had _no tsconfig alias and zero importers_, so nothing actually
consulted the gate before dispatching a generation. The seam closes that gap.

### `evaluateIsisDispatch` (`dispatch-guard.ts`)

`evaluateIsisDispatch(request: IsisDispatchRequest): IsisDispatchDecision` is
the fail-closed decision function. It takes a release-gate `measurement` plus an
optional list of pre-computed runtime `admissions` (each an
`IsisRuntimeAdmission` with a `name`, an `admitted` boolean, and an optional
`reason`) and returns:

```ts
interface IsisDispatchDecision {
  permitted: boolean; // true ONLY when gate allows AND every admission admitted
  mode: IsisReleaseGateMode; // 'allow' | 'review' | 'block' ('block' if the gate threw)
  blockedReasons: readonly string[];
  reviewReasons: readonly string[];
  gateResult: CanonicalReleaseGateResult | null; // null if evaluation threw
}
```

The logic is fail-closed in every branch:

- If `evaluateReleaseGate` _throws_, the decision is `permitted: false`,
  `mode: 'block'`, with a `gate-error: …` reason and `gateResult: null`.
- `permitted` is `true` only when `gateResult.mode === 'allow'` **and** there
  are zero denied admissions.
- A `review` verdict, a `block` verdict, or any denied admission denies — a
  generation is never released on the strength of a missing or ambiguous check.

### `dispatchGuardedGeneration` (`generation-dispatcher.ts`)

`dispatchGuardedGeneration<T>(request, runGeneration)` is the runtime seam that
actually calls the provider. It evaluates the dispatch; if `decision.permitted`
is false, it returns `{ outcome: 'denied', decision }` **without ever invoking
`runGeneration`**; only when permitted does it `await runGeneration(decision)`
and return `{ outcome: 'dispatched', decision, output }`. The injected
`runGeneration` _is_ the raw provider machinery — so the provider is physically
unreachable except through a permitting gate.

### BFF route `POST /v1/isis/generate`

`apps/oshun/bff/src/isis/generation-route.ts` registers
`POST /v1/isis/generate`, the HTTP face of the seam. Its `IsisProviderExecutor`
is injected, so the **gate** — not the route and not the provider — decides
whether generation runs. The response contract:

| Status | Condition                                                                        | Body                                                         |
| ------ | -------------------------------------------------------------------------------- | ------------------------------------------------------------ |
| `400`  | No `measurement` in the body                                                     | `{ error: 'invalid_request', message }`                      |
| `403`  | `dispatchGuardedGeneration` returned `outcome: 'denied'` (provider never called) | `{ outcome: 'denied', mode, blockedReasons, reviewReasons }` |
| `503`  | Executor threw `isis_provider_not_configured`                                    | `{ error: 'isis_provider_not_configured', message }`         |
| `200`  | `outcome: 'dispatched'`                                                          | `{ outcome: 'dispatched', output }`                          |

The default executor is `notConfiguredProviderExecutor()`, which always throws
`isis_provider_not_configured`. The deployable swaps in a real ComfyUI/RunPod
client executor at the app boundary. This is the honest shape of V1: the gate
and route ship and are enforced; the live provider is creds-gated.

## Workflow, model, and provider registries

Every generation pipeline, model, and provider endpoint is a versioned,
state-machined artifact in one of three registries.

### Workflow template registry

Each generation pipeline is a versioned **workflow class** declaring its
parameter guardrails (locked ranges per parameter), disallowed graph patterns,
cost class, persona/tone-policy binding, and Sophia grounding requirement (see
[Sophia Grounding](./sophia-grounding.md)). Templates are diffable per node and
per parameter, and a portability check verifies a class runs identically across
approved nodes. The ComfyUI specialization of this lives in
`comfyui-governance.ts`, which exposes `CanonicalComfyTemplateClassSpec`,
`CanonicalParameterGuardrail`, `diffComfyTemplateGraphs` (per-node /
per-parameter diff), `checkComfyTemplatePortability`,
`checkComfyParameterGuardrails`, and the runtime admission gate
`admitComfyTemplateForRuntime` — whose result is exactly the kind of
`IsisRuntimeAdmission` that the dispatch guard folds in.

The Zod contract `WorkflowTemplate` is a `z.infer` type at
`libs/contracts/src/common/workflow-template.ts:956`.

### Staging recipe schema

A **staging recipe** (`staging-recipe-schema.ts`) is a named, versioned,
environment-bound recipe that pins a workflow class to a model set and a
provider set for a given environment, so dev / staging / prod each resolve a
deterministic generation configuration. Civitai-imported models seed recipes
through `buildCivitaiStagingRecipeSeed` (see below).

### Model registry

Per-model lineage, license, version, deprecation flag, and eval scorecard;
deprecated models stay resolvable for kept artifacts but drop from
new-generation selection. The model lifecycle (`model-registry-spec.ts`) carries
the `CanonicalModelState` machine
(`draft → scanning → verified → published → deprecated`), license ids,
type→format maps, and size caps. The Zod contracts `ModelCard` and
`ModelVersion` live at `libs/contracts/src/common/model-card.ts:728` and
`model-version.ts:802`.

### Provider registry

Per-provider endpoint registration, health checks, region-aware routing,
concurrency and cost controls, retry/backoff, dead-letter rules, secret
rotation, and per-provider failover chain. The endpoint lifecycle
(`provider-registry-spec.ts`) carries the `CanonicalProviderEndpointState`
machine (`draft → validating → active → deprecated`). Endpoints group into the
eleven `IsisProviderFamily` values: `comfyui`, `sd`, `flux`,
`character-consistency`, `cinematic-video`, `three-d`, `texture`, `audio-sfx`,
`audio-voice`, `audio-music`, and `custom`.

> **Note on the concrete V1 provider set.** Earlier prose described the stack
> generically ("Civitai, ComfyUI on RunPod, voice/music/3D providers"). That
> phrasing is not wrong but is stale relative to what is now wired at the BFF
> boundary: the V1 providers are specific and env-gated — **Stability SD3.5**
> (image), **ElevenLabs** (voice/TTS), **Suno** (music), and **fal.ai-hosted
> LTX-Video** (video). RunPod/ComfyUI are the operator execution _substrate_,
> but no live ComfyUI/RunPod client is wired by default — the route falls back
> to the fail-closed `notConfiguredProviderExecutor`. See
> [External Model Intelligence and Execution Providers](./external-models-and-execution.md).

### Generation types

The `IsisGenerationType` union enumerates fifteen kinds: `text-to-image`,
`image-to-image`, `text-to-video`, `image-to-video`, `text-to-3d`,
`image-to-3d`, `text-to-audio`, `voice-synthesis`, `music-generation`,
`upscaling`, `inpainting`, `blender-render`, `gaussian-splatting`,
`mesh-processing`, and `texture-upscale`.

## Environment promotion and release gates

### The environment-promotion state machine

`IsisControlPlaneEnvironment` is a **four-environment** union — `development`,
`staging`, `production`, **and `test`**. (The older "dev → staging → prod"
shorthand omitted `test`.) The canonical rank order is
`test (0) → development (1) → staging (2) → production (3)`
(`CANONICAL_ENVIRONMENT_ORDER` / `CANONICAL_ENVIRONMENT_RANK`). Promotions move
up at most one rank at a time; skip-steps are forbidden. Limited downward moves
are allowed for incident response (production → staging, staging → development)
per `CANONICAL_ENVIRONMENT_TRANSITIONS`.

`canPromoteEnvironment(request)` (`environment-promotion-model.ts:303`) is the
decision function. It composes the transition rules, an **admissibility
matrix**, per-target gate evidence, and a **minimum bake-off window**:

- **Admissibility** (`CANONICAL_ARTEFACT_ENVIRONMENT_ADMISSIBILITY`,
  `isArtefactHostedAdmissibly`): which lifecycle states may live in which
  environment, per artifact kind. For example, a workflow template may be
  `draft` in test, `draft`/`in-review` in development, `in-review`/`published`
  in staging, and `published`/`deprecated` in production; a model may be
  `scanning`/`verified` only in development, never in production.
- **Minimum bake-off hours** (`CANONICAL_ENVIRONMENT_MIN_BAKEOFF_HOURS`): how
  long an artifact must remain in the lower environment before stepping up.

| Target environment | Min bake-off hours |
| ------------------ | ------------------ |
| `test`             | 0                  |
| `development`      | 0                  |
| `staging`          | 4                  |
| `production`       | 24                 |

- **Per-environment gates** (`CANONICAL_ENVIRONMENT_PROMOTION_GATES`): test
  requires `unit-tests-passed`; development adds `artefact-shape-valid`; staging
  adds `integration-tests-passed` and `min-bakeoff-hours`; higher environments
  add QA sign-off, shadow-traffic clearance, change-management approval,
  governance sign-off, and a rollback plan (carried on
  `EnvironmentPromotionEvidence`).

Every transition is recorded with actor, rationale, and the eval evidence that
satisfied the gate.

### Release gate model and concrete floors

Promotion to a customer-facing environment requires the class's regression eval
suite to pass; any safety- or quality-eval drop strictly greater than the
declared MDE (minimum detectable effect) blocks promotion. The regression
metrics are `safety-scan-score` and `quality-aggregate`
(`CANONICAL_RELEASE_REGRESSION_METRICS`), each measured as a
baseline-versus-candidate mean with a per-metric `minimumDetectableEffect`.

Beyond MDE, the release-gate model exposes concrete, named **floors** that the
prose summary never surfaced:

- **`CANONICAL_SAFETY_SCORE_FLOOR = 0.9`** — the minimum safety-scan score
  (scored `[0,1]`, higher is safer). Below it, release is **blocked** regardless
  of any other gate.
- **`CANONICAL_QUALITY_AGGREGATE_FLOOR`** — a per-output-kind quality floor.
  Falling below it does not block; it routes to **review**.
- **`CANONICAL_WATERMARK_COVERAGE_FLOOR`** — a per-output-kind watermark
  coverage floor (fraction of frames/turns). For example, `image` and `texture`
  require full coverage (`1`), `video`/`audio`/`animation` require `0.99`, and
  `3d-model`/`point-cloud`/`document`/`data` require `0`.

`evaluateReleaseGate(measurement)` runs the gates required for the output's kind
(adding `human-review-ready` whenever the release is customer-facing or any
trigger fired), each gate yielding a `CanonicalReleaseGateStatus` of
`pass | review | block | not-applicable`. The overall `IsisReleaseGateMode`
aggregates: **`block`** if any required gate blocks; otherwise **`review`** if
any gate reviews or a human-review trigger fired; otherwise **`allow`**.

A set of **human-review triggers** (`CANONICAL_HUMAN_REVIEW_TRIGGERS`) force a
`review` disposition even when every other gate passes — e.g.
`minor-likeness-detected`, `real-person-likeness-detected`, `cloned-voice-used`,
`clinical-content-detected`, `legal-prescription-detected`,
`financial-forecast-detected`, `spiritual-prescription-detected`,
`political-campaign-detected`, `cross-domain-memory-write`,
`high-risk-policy-class`. A triggered artifact without an assigned reviewer
**blocks**; with a reviewer assigned, it routes to **review**.

### Staged rollout, rollback, failover, and fallback

- **Staged rollout.** Promoted classes ramp by percentage with canary gating;
  canary anomalies halt the ramp and route to operator review.
- **Rollback.** Any production workflow class, model, or provider routing can be
  rolled back to a prior version with bound evaluation evidence; in-flight
  generations complete on the current version, new requests resolve to the
  rolled-back version.
- **Failover** is per-provider (an endpoint failure reroutes to the next
  provider in the chain); **fallback** is per-class degradation (e.g. a video
  class falls back to a still render) declared and tested per workflow class.

#### The per-family circuit breaker (`provider-failover-policy.ts`)

Failover in V1 is a real circuit-breaker model, not just prose. The breaker has
three states — `closed`, `open`, `half-open`
(`CANONICAL_CIRCUIT_BREAKER_STATES`) — governed by per-family thresholds
(default error-rate `0.1`, consecutive-failure threshold `5`, p95 latency
`5000ms`, open-hold `60s`, half-open recovery successes `3`, flap-dampen
`120s`). `assessProviderFailover(input)` evaluates the live health signals and
returns a `FailoverAssessment` naming the primary endpoint and the fallback
chain; `computeRetryBackoffMs(...)` derives the exponential backoff (default
`maxAttempts 3`, `initialBackoffMs 250`, `maxBackoffMs 4000`, multiplier `2`,
with jitter).

`CANONICAL_FALLBACK_FAMILY_ORDER` defines per-family fallback preference — e.g.
`flux → sd → comfyui → custom`, with `custom` always the last-chance fallback.
Critically, two families forbid cross-family fallback because the substitution
would itself be a trust failure: `character-consistency` (identity drift is a
trust signal) and `audio-voice` (cloned voices must never silently fall back to
a different family) both set `crossFamilyFallbackForbidden: true` and a
`degradedMode: 'block'`. When no partner is healthy, the breaker selects a
`CanonicalDegradedMode` from `block`, `queue-and-wait`, `serve-cached`, or
`synthetic-refusal` (`CANONICAL_DEGRADED_MODES`); the default is
`queue-and-wait`. All per-family policies are pinned in
`CANONICAL_PER_FAMILY_FAILOVER_POLICIES`.

## Provenance bundles

Every generation emits a provenance bundle that is persisted and travels with
the artifact, an append-only generation-event ledger makes any output auditable
and replayable, and provenance is surfaced wherever it adds trust value.

### `CanonicalProvenanceBundle` — the real schema

The earlier doc summarized the bundle as a flat list ("consent ID, prompt,
model, workflow class, watermark hash, timestamp, invoking user, tenant"). The
real `CanonicalProvenanceBundle` (`provenance-bundle-schema.ts:271`) is
materially richer and **does not** carry top-level `prompt` / `consentId` /
`invokingUser` / `tenant` fields by those names — those are modeled through
`actors[]` and `claims[]` rather than as flat fields. The full field set:

| Field                   | Meaning                                                                                                                                                                                                                                                           |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `specVersion`           | Bundle spec version                                                                                                                                                                                                                                               |
| `bundleId`              | `prov_` + 26 Crockford base32 chars (`CANONICAL_PROVENANCE_BUNDLE_ID_PATTERN`); quotable verbatim in logs                                                                                                                                                         |
| `outputId`              | The output this bundle attests                                                                                                                                                                                                                                    |
| `outputKind`            | An `IsisOutputFileType` (`image`, `video`, `audio`, `3d-model`, `point-cloud`, `animation`, `texture`, `material`, `document`, `data`, `other`)                                                                                                                   |
| `outputHash`            | `{ algorithm, value }` — algorithm ∈ `sha256` / `sha512` / `blake3`                                                                                                                                                                                               |
| `sizeBytes`             | Output size                                                                                                                                                                                                                                                       |
| `productionContext`     | `workflowTemplateId`, `workflowVersion`, `modelId`, `modelVersion`, `providerFamily`, `providerEndpointId`, `generationType`, `seed?`, `deterministicReplayable`, `modifierModelIds[]` (LoRA/controlnet/adapter fingerprints)                                     |
| `actors[]`              | Typed participants (`kind` ∈ software/hardware/service/human-reviewer; `role` ∈ oshun-control-plane, isis-dispatcher, provider-endpoint, watermark-embedder, safety-scanner, quality-evaluator, human-reviewer, …) with optional version + public-key fingerprint |
| `claims[]`              | Ordered `created`/`generated`/`modified`/`reviewed`/`released`/`redacted`/… claims, each with `claimId`, actor, monotonic `atUnixSeconds`, rationale, and output hash                                                                                             |
| `lineage[]`             | Parent/derivation inputs                                                                                                                                                                                                                                          |
| `watermark`             | A `CanonicalWatermarkAttestation` or `null`                                                                                                                                                                                                                       |
| `releaseGateEvidence[]` | Stamped release-gate evidence                                                                                                                                                                                                                                     |
| `humanReviewTriggers[]` | Triggers that fired                                                                                                                                                                                                                                               |
| `retention`             | A `CanonicalRetentionStamp` (`totalRetentionDays`, …)                                                                                                                                                                                                             |
| `license`               | A `CanonicalLicenseStamp` (`licenseId`, `licenseDisplayName`, `commercialUseAdmissible`, `validUntilUnixSeconds \| null`)                                                                                                                                         |
| `aggregateSignature`    | Root signature over every claim + production context — `{ algorithm, value, publicKeyFingerprint, signedAtUnixSeconds }`; algorithm ∈ `ed25519` / `ecdsa-p256` (both enforced as 64-byte / 128-hex)                                                               |

Hash and signature lengths are validated: `sha256`/`blake3` = 64 hex chars,
`sha512` = 128; `ed25519` and `ecdsa-p256` signatures = 128 hex (the canonical
64-byte raw `(r||s)` form for P-256).

> The Zod contract `ProvenanceBundle`
> (`libs/contracts/src/common/provenance-bundle.ts:944`) is a distinct, parallel
> contract from the adapter's `Canonical`-prefixed variant. The two families
> coexist: the contracts layer holds
> `WorkflowTemplate`/`ModelCard`/`ModelVersion`/`ProvenanceBundle` as Zod
> schemas; the `generation-control-isis` adapter does **not** re-export those
> names — it exports `Canonical`-prefixed schemas (`CanonicalProvenanceBundle`,
> canonical workflow-template / model registry specs). Anything claiming the
> adapter exports the bare contract names is conflating the two layers.

### Immutable ledger and surfaces

Every generation appends to an append-only generation-event ledger so any output
is auditable and replayable from its inputs. Provenance is inspectable in Oshun
Admin for every output and surfaced to the customer wherever it adds trust value
(synthetic-content badges, citation trails, attestation pages). The web
provenance-ledger e2e is gated behind two env switches:
`OSHUN_ENABLE_TEST_HARNESSES=true` **and**
`OSHUN_ISIS_PROVENANCE_LEDGER_FIXTURE=clean` — the loader at
`apps/oshun/web/src/lib/server/isis-provenance-loader.ts` returns `null` (no
fixture) unless both are set.

## Civitai intake and external-model review

External models enter Isis through a typed intake-and-review pipeline, never
directly into generation.

- **Intake spec** (`civitai-intake-spec.ts`). `CANONICAL_EXTERNAL_MODEL_SOURCES`
  enumerates the allowed origins (`civitai`, `huggingface`, `internal-transfer`,
  `partner-feed`). `CANONICAL_EXTERNAL_MODEL_INTAKE_POLICY` pins the default
  mode (`manual-review`), per-source modes (Civitai and partner-feed →
  manual-review; HuggingFace and internal-transfer → auto-ingest-with-review),
  forbidden license ids (e.g. `stability-ai-non-commercial`), allowed model
  types (`lora`/`controlnet`/`checkpoint`/`embedding`),
  `allowNsfwAutoIngest: false`, and a minimum creator reputation (`0.7`) for
  auto-ingest. `decideIntakeAdmission({ policy, record })` returns either
  `{ admissible: true, mode }` or `{ admissible: false, blockers }` — and even
  when admissible, an NSFW record, a low-reputation creator, or an explicit /
  graphic-violence / hate-or-harassment content label forces the final mode back
  to `manual-review`. `normalizeIntakeToCanonicalModel` maps an admitted record
  onto a canonical model card.
- **Review pipeline** (`civitai-review-pipeline.ts`). The review queue is a
  state machine —
  `intake-pending → rights-review → safety-review → preview-review → approved`,
  with `rejected` and `takedown` as terminal states
  (`CANONICAL_CIVITAI_REVIEW_STATES` / `CANONICAL_CIVITAI_REVIEW_TRANSITIONS`).
  `admitCivitaiImportedModelAtRuntime(...)` produces the runtime admission
  folded into the dispatch guard; `buildCivitaiStagingRecipeSeed(...)` seeds a
  staging recipe from an approved import; `CivitaiDenylistEntry` /
  `checkCivitaiDenylist` enforce a denylist at intake.

## Canonical adapter

`createCanonicalIsisGenerationControlAdapter({ apiAdapter })`
(`canonical-adapter.ts:35`) wraps an injected `IsisGenerationControlApiAdapter`
and layers the canonical control-plane behavior on top. It exposes
`listWorkflowCatalog` / `getWorkflowCatalogEntry`, `listModelCatalog` /
`getModelCatalogEntry`, `getProviderRoutingSummary`, `planGeneration`,
`dispatchGeneration` (which refuses to run when the plan is not approved),
`getGenerationExecution` / `getJob`, and provenance / retention /
release-readiness inspectors (`getProvenanceBundle`, `getReleaseReadiness`).
This is the single typed surface the higher services compose against.

## Operator surface

Routing of approved media generation, model promotions, workflow promotions,
provenance inspection, release readiness, and rollback status flows through
Oshun Admin (see [Admin Products — Web and Mobile](./admin-products.md) and
[Review, Compliance, and Trust & Safety](./review-trust-safety.md)). A
**release-gate dashboard** surfaces per-class eval scores, promotion state,
canary status, and the rollback control — its data is modeled in
`admin-view-models.ts`; the rendered admin UI is planned. The Isis test surface
covers validation, promotion, rollback, provenance, load, audit, and
release-gate regression, plus outage and performance tests on provider
endpoints.

### Customer surface migration — legacy provider routes are hard-blocked

The legacy provider-machinery route tree under
`apps/oshun/web/src/app/studio/isis/*` is now hard-blocked (`404`) for **all**
segments: `STUDIO_ISIS_ALLOWED_ROUTE_SEGMENTS = Object.freeze([])` at
`libs/isis/entitlements/src/studio-boundary.ts:60`, and `isAaaOnlyRoute` returns
`true` for every non-empty segment. The real customer inspector home moved to
`/studio/generation-gallery` (with approved generation under
`/studio/generation/*`). This keeps raw machinery off the contemplative product
by construction: adding any legacy route back requires a deliberate edit to the
frozen allowlist.

## A correction on the audience-tier names

A note for cross-referencing readers: both this document and
`V1/ARCHITECTURE.md` historically declared the four "canonical" tier names as
`Customer`, `Curated-Creator`, `AAA-Creator`, `Operator`, "used verbatim." The
**implementation** `GenerationTier` union
(`libs/isis/entitlements/src/generation-tier.ts:23`) is in fact
`'operator-admin' | 'aaa-creator' | 'curated-creator' | 'contemplative'`. Two of
the four diverge: the customer tier is **`contemplative`** in code (not
`Customer`), and the operator tier is **`operator-admin`** (not `Operator`). The
"used verbatim" claim is false against the code; the authoritative names are the
union members above. See
[Generation Audience Tiers and Surface Boundaries](./generation-tiers-and-surfaces.md)
for the full resolver and surface allowlists.

## Related

- [Generation Audience Tiers and Surface Boundaries](./generation-tiers-and-surfaces.md)
- [External Model Intelligence and Execution Providers](./external-models-and-execution.md)
- [Creator Surfaces, Voice, Music, and 3D Generation](./creator-voice-music-3d.md)
- [Output Gallery, Lineage, Branch, and Replay](./output-gallery-lineage.md)
- [Sophia Grounding](./sophia-grounding.md)
- [Review, Compliance, and Trust & Safety](./review-trust-safety.md)
- [Admin Products — Web and Mobile](./admin-products.md)
- [Subsystem Glossary](./glossary.md)
- [Architecture, Platform Foundations, and Security](./platform-foundations-and-security.md)
- Hub: [../features.md](../features.md)
