---
path: /studio/audit-compliance-surfaces
surface: studio
domain: governance
auth: signed-in + studio entitlement
source: apps/oshun/web/src/app/studio/audit-compliance-surfaces/page.tsx
status: walked
last_walked:
  '2026-07-03 real-infra Playwright walk — anonymous redirect, studio-admin
  catalog load, quick actions, intact audit-chain verification, tamper
  detection, broken-link and sequence-gap detection, client JSON validation,
  live BFF 400 details, catalog loading/503/malformed/network failures, verify
  transport/malformed failures, pending-submit lockout, non-admin fail-closed
  auth, direct BFF auth/schema gates, 44 px controls, and mobile containment
  verified in Chromium. Evidence:
  apps/oshun/web/e2e/studio-audit-compliance-surfaces.spec.ts and
  WALKTHROUGH/results/v1-real-infra-run-2026-06-22.md'
---

# Studio · Audit and Compliance Surfaces

## Purpose

Verify a tamper-evident audit log with the real hash-chain verifier: the Audit
Chain Integrity Lane recomputes every entry hash and re-links the chain to
detect tampering, broken links, and sequence gaps. It is a live admin console
wired to `/v1/admin/studio/audit-chain`, not an in-page simulation.

## Entry points

- **Direct URL / bookmark** — `/studio/audit-compliance-surfaces` (signed-in +
  studio entitlement; admin scope required to verify)
- **Sibling Studio routes** — reached via the quick-action panel on
  color-system, rbac-permission-policy, enterprise-tenant-isolation, and other
  governance pages

## Layout regions

`page.tsx` mounts `<ShellLayout active="studio">` and renders
`<StudioAuditComplianceSurfacesWorkspace />` followed by a single `panel` of
quick-action links.

- **Shell**: `ShellLayout` chrome with the Studio tab active
- **Workspace heading**: `WorkspaceHeading` renders the page `<h1>` "Studio
  Audit & Compliance Surfaces", followed by the `data-audit-compliance-summary`
  paragraph
- **Audit Chain Integrity Lane**: an `<h2>` `data-ac-lane-heading` ("Audit Chain
  Integrity Lane") section with the load states and, when ready, the verify form
  and result table
- **Quick-actions panel** (`data-audit-compliance-quick-actions`): 8 sibling
  `quickAction` `Link`s with stable `data-audit-compliance-quick-action` ids —
  "Back to Enterprise Tenant Isolation workspace", Notification Center, Activity
  and Change Feeds, Real-Time Collaboration Substrate, Commenting and Annotation
  System, Review and Approval Workflows, "Back to RBAC and Permission Policy UX
  workspace", and "Back to Session and Device Management workspace". No
  self-link and no Route Map panel.

## States

- [x] **Loading** — `data-ac-loading` ("Loading audit verifier…")
- [x] **Unauthorized** — `data-ac-unauthorized` ("Access restricted.") on
      401/403
- [x] **Error** — `data-ac-error` ("Could not load the audit verifier.")
- [x] **Ready / form** — `data-ac-enums` ("genesis … · N integrity checks") plus
      the `data-ac-form` verify form
- [x] **Pending verify** — `data-ac-form-state="pending"`,
      `data-ac-submit-state="pending"`, disabled submit, and `aria-busy="true"`
      while the verify POST is in flight
- [x] **Result** — `data-ac-result` headline (`data-ac-headline` with
      `data-valid`) and the `data-ac-entries` table of `data-ac-entry-row` rows
      (`data-ac-computed-hash`, `data-ac-entry-issues`) inside a named focusable
      scroller (`data-ac-entries-scroll`)
- [x] **Verify error** — `data-ac-verify-error` for invalid JSON or a non-200
      response

## Interactions

- [x] **Audit entries (JSON)** — `textarea` `data-ac-payload`,
      `aria-label="audit     entries json"`, seeded with
      `{ entries[{ seq, actor, action,     recordedPrevHash, recordedHash }] }`
- [x] **Verify chain** — `button` `data-ac-submit` (`type="submit"`); POSTs
      `{ entries }` to `/v1/admin/studio/audit-chain/verify`, setting
      `data-ac-result` on a 200 with a valid `result`, or `data-ac-verify-error`
      otherwise
- [x] **Quick-action links** — each `quickAction` `Link` navigates to its
      sibling Studio route (see Layout regions for the 8 targets)

## Data & contracts

- **Reads**: `GET /v1/admin/studio/audit-chain` on mount — returns the catalog
  (`genesisHash`, `integrityIssues[]`)
- **Writes**: `POST /v1/admin/studio/audit-chain/verify` — body `{ entries }`,
  returns
  `{ result: { entries[], valid, tamperCount, brokenLinkCount, gapCount, firstInvalidSeq } }`
- **Realtime**: none
- **Caching**: client `fetch` with `cache: 'no-store'`; `buildBffAuthHeaders()`
  attaches the bearer token
- **Auth/role check**: admin-scoped fail-closed — `admin:*` or `admin:studio`,
  401/403 under the studio workspace gate

## Cross-references

- Parent: [`../studio-overview.md`](../studio-overview.md)
- Sibling:
  [`studio-rbac-permission-policy.md`](./studio-rbac-permission-policy.md),
  [`studio-enterprise-tenant-isolation.md`](./studio-enterprise-tenant-isolation.md),
  [`studio-data-retention-lifecycle-controls.md`](./studio-data-retention-lifecycle-controls.md)
- Component source:
  `apps/oshun/web/src/components/studio/StudioAuditComplianceSurfacesWorkspace.tsx`
- BFF store: `apps/oshun/bff/src/studio/audit-chain-store.ts` behind
  `/v1/admin/studio/audit-chain`

## Open questions / known gaps

- [x] Confirm whether the page will gain a breadcrumb/Route Map panel like other
      Studio surfaces, or keep the flat quick-action panel: current V1 keeps the
      flat quick-action panel only, with no self-link and no Route Map panel.
- [x] Document the live audit-log source the verifier should re-link once it
      runs against the persisted compliance chain: current V1 BFF verifies the
      caller-supplied `{ entries }` payload through
      `apps/oshun/bff/src/studio/audit-chain-store.ts`; it does not yet read a
      persisted compliance-chain feed.
