---
path: /studio/isis/content-safety
surface: studio
domain: isis
auth: signed-in Studio shell + Studio Isis route boundary; admin-scoped BFF
source: apps/oshun/web/src/app/studio/isis/content-safety/page.tsx
status: walked
last_walked:
  '2026-07-21 focused Playwright + unit/BFF/PostgreSQL verification: direct
  boundary, empty durable history, authenticated live screening and reload,
  duplicate/auth-spoof/customer-field rejection, deleted-subject and storage
  failures, malformed contracts, route map, responsive containment, touch
  targets, and axe.'
---

# Isis Content Safety

## Purpose

Admin diagnostic console that screens approved, de-identified internal
prompt/output fixtures through the real model-fine-tuning `validateSample`
evaluator: token-length floor/ceiling, quality floor, missing content, and the
default toxicity keyword list. Any critical/error issue flags the fixture. This
surface creates internal review-package evidence only: it neither moderates live
traffic nor authorizes release. Never enter customer content, customer ids,
source assets, or personal information.

All reads and screenings flow through `/v1/admin/isis/content-safety`; the route
is admin-scoped, derives evaluator attribution from authentication, requires
durable PostgreSQL storage in production, and fails closed when storage or the
response contract cannot be trusted.

## Entry points

- Sibling quick-action from `/studio/isis/collection-management`
- Studio index (`/studio`)
- Direct URL / bookmark

## Layout regions

`page.tsx` mounts `<ShellLayout active="studio">` (no breadcrumb panel) and
three panels: the workspace, the Route Map, and sibling quick-actions.

- **Header**: shell header
- **Workspace panel** (`data-isis-content-safety-workspace`):
  - `<h1>` (`WorkspaceHeading`) "Isis Content Safety Workspace"
  - Summary paragraph (`data-safety-summary`)
  - Diagnostic-only/privacy boundary (`data-safety-authority-note`)
  - Aggregate counts (`data-safety-aggregate`, `data-safety-flagged-count`)
  - Screen-sample form (`data-safety-form`)
  - Screen list (`data-safety-screens`), each
    `data-safety-screen-card=<screenId>` with `data-safety-verdict` /
    `data-safety-flagged`; empty state `data-safety-screens-empty`
- **Route Map panel** (`data-isis-content-safety-route-map`):
  `<h2>Route Map</h2>` over `STUDIO_ISIS_CONTENT_SAFETY_ROUTE_MAP` (5 entries)
- **Sibling quick-actions panel**: `/studio/isis/collection-management`,
  `/studio`

## States

- [x] **Loading** — `data-safety-loading`
- [x] **Unauthorized** — 401/403 admin-scope fail-closed;
      `data-safety-unauthorized`
- [x] **Error** — non-OK or malformed response; `data-safety-error`
- [x] **Storage unavailable** — 503 renders a specific fail-closed message; no
      history is presented as trustworthy
- [x] **Ready (form)** — response present; aggregate + form + screen list render
- [x] **Empty durable history** — no seeded/example records;
      `data-safety-screens-empty`
- [x] **Result** — after a screen POST, `data-safety-result`
      (`data-safety-status`); the fixture is reported FLAGGED or CLEAR
      (`data-safety-issues` with `data-safety-issue-type` /
      `data-safety-issue-severity`)
- [x] **Deleted operator** — 410 explains that the erased account cannot create
      new evidence

## Interactions

### Screen-sample form (`data-safety-form`)

- [x] **Screen id** (`data-safety-screenid`, text input)
- [x] **Role** (`data-safety-role`, `<select>`)
- [x] **Content** (`data-safety-content`, `<textarea>`)
- [x] **Record diagnostic** (`data-safety-screen`, button; "Screening…" while
      submitting) — `POST /v1/admin/isis/content-safety`; the exact
      acknowledgement is inserted immediately, then remains after reload

### Route Map

- [x] **Route-map articles** ×5

### Sibling quick-actions

- [x] **Open Isis Collection Management workspace** →
      `/studio/isis/collection-management`
- [x] **Back to Studio workspace index** → `/studio`

## Data & contracts

- **Reads**: `GET /v1/admin/isis/content-safety` (canonical ISO generation
  timestamp, strictly newest-first unique screens, exact recomputed aggregate,
  toxicity keyword count, and evaluator thresholds)
- **Writes**: `POST /v1/admin/isis/content-safety` with only `screenId` and 1–64
  `{ role, content }` messages; roles are `system|user|assistant|tool`. The 201
  acknowledgement returns exactly `{ ok, screen }`, including evaluator revision
  and auth-derived `screenedBy` attribution. Caller-supplied attribution,
  unknown nested/top-level fields, controls, non-canonical ids, oversize inputs,
  and duplicate ids are rejected.
- **Durability**: normalized PostgreSQL operator-state, screen, ordered-message,
  and ordered-issue rows. A lifecycle row serializes writes and account erasure;
  database primary/foreign/check constraints and application re-evaluation make
  cross-replica duplicates and corrupted projections fail closed.
- **Privacy/retention**: account erasure pseudonymizes evaluator attribution and
  leaves a permanent write fence. Review packages use the canonical seven-year
  retention partition, honor legal holds and retention exceptions, and purge
  messages/issues through cascading deletion.
- **Realtime**: none
- **Caching**: client fetch on mount, `cache: 'no-store'`,
  `buildBffAuthHeaders()`
- **Auth/role check**: direct route is hard-blocked by the Studio Isis boundary;
  localhost E2E lane reaches the signed-in shell; BFF remains admin-scoped and
  fail-closed (401/403)
- **Component sources**:
  - `apps/oshun/web/src/components/studio/StudioIsisContentSafetyWorkspace.tsx`
  - `apps/oshun/web/src/components/studio/StudioIsisContentSafetyRouteMap.ts`

## Automated coverage

- `apps/oshun/web/e2e/studio-isis-content-safety.spec.ts`
  - direct Studio Isis boundary hard-block
  - authenticated localhost lane starts with empty durable history and no seeded
    examples, then records a live diagnostic and proves it survives reload
  - browser GET/POST auth headers are forwarded to the live BFF
  - duplicate ids, auth-attribution spoofing, and customer/source metadata
    fields are rejected by the live BFF
  - diagnostic-only/privacy copy, route map, 44px controls, responsive Pixel 7
    containment, and axe accessibility automation
  - controlled deleted-subject (410) and durable-storage-unavailable (503)
    states
- `apps/oshun/web/src/components/__tests__/StudioIsisContentSafetyWorkspace.test.tsx`
  covers empty durable history, unauthorized, storage-unavailable, and malformed
  catalog/aggregate fail-closed behavior.
- `apps/oshun/web/src/components/__tests__/StudioIsisContentSafetyWorkspace.integration.test.tsx`
  covers the minimal POST payload plus auth-derived acknowledgement, optimistic
  insertion, duplicate rejection, deleted-operator handling, and malformed
  successful acknowledgements.
- `apps/oshun/bff/src/__tests__/admin-isis-content-safety-route.test.ts` covers
  auth/scope, empty history, real evaluation, exact attribution, duplicate ids,
  strict nested/top-level payloads, deletion fences, and persistence failures.
- `apps/oshun/bff/src/isis/content-safety-store-durability.integration.spec.ts`
  runs against real PostgreSQL for restart/replica/concurrency behavior,
  evaluate-versus-erasure races, pseudonymization, legal hold/retention
  exception, purge/cascade/fence behavior, transaction rollback, and
  stored-evidence tamper detection.
- `libs/oshun/persistence/src/content-safety-schema.spec.ts` checks rendered
  schema drift and the migration's lifecycle, projection, vocabulary, ordering,
  foreign-key, cascade, and index constraints.

## Cross-references

- Studio overview: [`../../studio-overview.md`](../../studio-overview.md)
- Sibling routes:
  - [`studio-isis-collection-management.md`](./studio-isis-collection-management.md)
  - [`studio-isis-anomaly-detection.md`](./studio-isis-anomaly-detection.md)
  - [`studio-isis-artifact-detection.md`](./studio-isis-artifact-detection.md)

## Open questions / known gaps

- [ ] No breadcrumb on this route — navigation is via sibling quick-actions
- [ ] Diagnostic evaluation uses the model-fine-tuning library's deterministic
      default keyword list, not an ML moderation provider. This is intentionally
      not presented as runtime moderation; provider selection remains a separate
      product and safety decision.
