Oshun Platform · Features

Isis Generation Control

A focused page within the Oshun Platform Features documentation. The full map and every sibling page live in the Features hub.

10sections15 minread3tables

On this page

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, External Model Intelligence and Execution Providers, and Output Gallery, Lineage, Branch, and Replay.

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). 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.

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 and Review, Compliance, and Trust & Safety). 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 for the full resolver and surface allowlists.