Context. surface studio · domain aja · route /studio/aja/content-watermarking · auth signed-in + studio entitlement · source apps/oshun/web/src/app/studio/aja/content-watermarking/page.tsx
Last walked. 2026-05-29 automated runtime walk (Playwright headless) — render, /v1 data (2xx), console/page-errors, expected content, screenshot verified; live screen-reader, touch, offline, and telemetry-delivery checks pending a manual AT pass. Evidence: WALKTHROUGH/results/runtime-sweep-2026-05-29.md; body re-derived 2026-06-03 from current source (lane-console architecture)
Purpose#
Admin lane console for the real @aja/content-watermarking MotionWatermarker
payload codec. The operator fills a provenance / leak-tracing payload
(watermark id, content id, owner id, ISO-8601 timestamp, optional custom JSON)
and encodes it into watermark bytes plus an integrity checksum; a second action
decodes those bytes back to the original payload to confirm round-trip detection.
Entry points#
- Direct URL / bookmark —
/studio/aja/content-watermarking; metadata canonical to this path - Studio nav — Domain-bridge studios section of
/studio - Breadcrumb parent —
/studio/aja/content-security(declared in the page.tsx breadcrumb<ol>) - Sibling quick-actions on this page: Content Security, Content Moderation, Privacy Protection, Data Retention, Back to Studio
- Operator surfacing — see
../../studio-overview.md
Layout regions#
page.tsx renders inside <ShellLayout active="studio">:
- Breadcrumb panel (
data-aja-content-watermarking-breadcrumbs):<nav aria-label="Aja Content Watermarking breadcrumbs">→Studio / Aja Content Security / Content Watermarking - Workspace (
<StudioAjaContentWatermarkingWorkspace />, archetype: LEAF):<h1>(WorkspaceHeading) "Aja Content Watermarking Workspace"- Summary
<p data-aja-cw-summary>— encode a payload into watermark bytes (with checksum) and decode bytes back - The encode form lane + the encoded/decoded result blocks
- Route Map panel (
data-aja-content-watermarking-route-map):<h2>Route Map</h2>listing 6 entries fromSTUDIO_AJA_CONTENT_WATERMARKING_ROUTE_MAP(primary, rules, traces, packages, parity, governance) - Quick-action panel: five
Link.quickActionanchors — Content Security, Content Moderation, Privacy Protection, Data Retention, Back to Studio
States#
- Loading — GETs the codec catalog on mount; renders
<p data-aja-cw-loading>"Loading watermark codec…" - Unauthorized — 401/403 renders
data-aja-cw-unauthorized("Access restricted." + admin-scope message, default "Aja workspace scope required to view content watermarking.") - Error — non-OK / malformed / unreachable renders
data-aja-cw-error("Could not load content watermarking." + reason) - Ready (form) — success renders the
data-aja-cw-encode-form - Encoded — a successful encode renders
data-aja-cw-encodedwithdata-aja-cw-checksum,data-aja-cw-bytelength, and adata-aja-cw-decode-submitbutton - Decoded — a successful decode renders
data-aja-cw-decodedwithdata-aja-cw-detectedand (if present)data-aja-cw-recovered(recovered owner / content) - Action error — invalid custom JSON, missing required fields, decode
without an encode, or POST failure renders
data-aja-cw-action-error - Empty / Standalone PWA / offline — N/A beyond the above; shell SSR, lane is a client fetch on mount
Interactions#
Encode lane (data-aja-cw-encode-form)#
- Watermark id (
data-aja-cw-field-id, input, label "Watermark id") - Content id (
data-aja-cw-field-content, input, label "Content id") - Owner id (
data-aja-cw-field-owner, input, label "Owner id") - Timestamp (
data-aja-cw-field-timestamp, input, label "Timestamp (ISO-8601)") - Custom data (
data-aja-cw-field-custom, input, label "Custom data (JSON, optional)") - "Encode watermark" (
data-aja-cw-encode-submit, submit) — firesPOST /v1/admin/aja/content-watermarking/encodewith{ id, contentId, ownerId, timestamp, customData? } - "Decode it back" (
data-aja-cw-decode-submit, button) — firesPOST /v1/admin/aja/content-watermarking/decodewith the encoded{ dataBase64 }
Route Map panel#
- Route entries (6 ×
<article>) — non-interactive path+purpose
Quick-action panel#
- "Open Aja Content Security workspace" →
/studio/aja/content-security - "Open Aja Content Moderation workspace" →
/studio/aja/content-moderation - "Open Aja Privacy Protection workspace" →
/studio/aja/privacy-protection - "Open Aja Data Retention workspace" →
/studio/aja/data-retention - "Back to Studio workspace index" →
/studio
Data & contracts#
- Reads:
GET /v1/admin/aja/content-watermarkingon mount — catalog{ payloadFields: string[], codec } - Writes:
POST /v1/admin/aja/content-watermarking/encode→{ encoded }(dataBase64, byteLength, checksum)POST /v1/admin/aja/content-watermarking/decode→{ detected, payload }
- Realtime: none
- Caching: client
fetchon mount withcache: 'no-store'andbuildBffAuthHeaders(); SSR shell only - Auth/role check: BFF endpoints admin-scoped + fail-closed (401/403 → unauthorized render); route behind the signed-in + studio proxy gate
Cross-references#
- Parent:
../../studio-overview.md - Shell:
../../../shell/04-auth-session.md - Sibling routes:
./studio-aja-content-security.md(breadcrumb parent),./studio-aja-content-moderation.md,./studio-aja-privacy-protection.md,./studio-aja-data-retention.md - Component sources:
apps/oshun/web/src/components/studio/StudioAjaContentWatermarkingWorkspace.tsxapps/oshun/web/src/components/studio/StudioAjaContentWatermarkingRouteMap.ts
Open questions / known gaps#
- The decode action requires an in-session encode first (it reuses the
encoded
dataBase64); there is no standalone "paste bytes to decode" path - Route-map sub-routes are advertised but have no
page.tsxin V1