Context. surface tenant-admin · domain governance · route /policy · auth signed-in + tenant:admin (getTenantServerSession) · source apps/oshun/tenant-admin/src/app/policy/page.tsx
Last walked. —
Purpose#
Read-only view of the tenant's effective policy resolved down a district →
school inheritance chain, with tighten-only rules enforced and violations
surfaced before tenant attestation. Backs the policy workspace (governance
group) in libs/oshun/navigation/src/tenant-ia.ts.
Entry points#
- Shell sidebar (
TenantSidebar) — "Policy" (shortLabel) under the Governance group, link to/policy(data-workspace-id="policy") - Workspace grid on
/(home) — list itemdata-workspace-id="policy" - Notifications inbox deep link target
/policy(see notifications.md) - Direct URL
/policy(bookmarkable; middleware-gated)
Layout regions#
Inside TenantShell:
- Header:
TenantHeadershowstenant · <tenantId>› "Policy and configuration" - Main:
<section data-testid="tenant-policy-panel" data-tenant-id={tenantId}><h1>Policy and configuration</h1>+ subtitle paragraph.summaryGrid— three.summaryItemtiles: Policy keys (entries.length), Violations (policy.errors.length), Residency (school.contract.dataResidencyRegion).table— effective-policy table: columns Policy key (code), Effective value (String(value)), Source tenant (sourceTenantByKeyor "base"); rows sorted by keylocaleCompare
States#
- Loading — N/A; server component resolves the policy chain in one pass
- Empty — N/A; the base map + overlays always yield ≥1 key
(
default-locale,max-agent-budget,dsar-export-days,voice-cloning) - Populated (short) — sorted policy keys render; Violations shows
policy.errors.length(0 with the default fixture); Residency "us" - Populated (long) — N/A; fixture defines a fixed key set
- Error (recoverable) — N/A; no runtime query
- Error (unrecoverable) — no session →
redirect('/unauthorized?reason=missing-session&returnTo=/policy') - Offline — N/A for data (SSR-rendered)
- Gated —
getTenantServerSession()null → redirect to/unauthorized; sidebar Locked whencanEnterTenantWorkspaceis false - Standalone PWA — verify; no manifest/SW confirmed in source
Interactions#
The <main> content is a static report — no buttons, inputs, override
editors, or attestation action. All interactivity is shell chrome:
- Skip to main content (link,
TenantShell) → anchors#tenant-main - Sidebar workspace links (links,
TenantSidebar) → navigate; currentaria-current="page"; Locked when gated - Policy rows — non-interactive; key as
code, value stringified, source tenant resolved from overlays
Data & contracts#
- Reads: no BFF/network read. The page builds two
Tenantfixtures (<tenantId>-districtof kinddistrict,<tenantId>of kindschool) and aMap<string, TenantPolicyOverlay>, then calls:resolvePolicy({ chain: [district, school], overlays, base, schema })→policy.values(effective) andpolicy.errors(violations). Schema marksmax-agent-budget/dsar-export-daysastighten-only,voice-cloning/default-localeasoverride.entries= sorted[...policy.values.entries()];sourceTenantByKeyderived by scanning overlay key originsNOW = Date.UTC(2026, 4, 11, 15)(seconds)
- Writes: None.
- Realtime: None.
- Caching: SSR (server component); deterministic per
tenantId - Auth/role check:
getTenantServerSession()in page; middleware gate
Contracts: Tenant, TenantPolicyOverlay, resolvePolicy from
@oshun/tenant-console (libs/oshun/tenant-console).
Cross-references#
- Workspace definition:
libs/oshun/navigation/src/tenant-ia.ts(policy— groupgovernance,requiredScopes: ['tenant:admin:*'],iconToken: 'shield-check') - Shell:
TenantShell.tsx,TenantSidebar.tsx,TenantHeader.tsx - Sibling routes: roles.md, status.md, integrations.md, members.md, notifications.md
- Conventions: ../WALKTHROUGH/00-conventions.md
Open questions / known gaps#
- No live policy BFF route is wired — page renders a static district/school overlay fixture, not the tenant's real inherited policy bundle.
- No attestation control or tighten-only override editor exists on this
route despite the workspace
primaryJobdescribing both. Verify where attestation/override actions are intended to live. - Tile labels say "Residency" but show
dataResidencyRegion("us") not the contractregion("us-east"); confirm which is canonical for display.