---
path: /policy
surface: tenant-admin
domain: governance
auth: signed-in + tenant:admin (getTenantServerSession)
source: apps/oshun/tenant-admin/src/app/policy/page.tsx
status: drafted
last_walked: '—'
---

# Policy and configuration

## 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 item `data-workspace-id="policy"`
- Notifications inbox deep link target `/policy` (see
  [notifications.md](notifications.md))
- Direct URL `/policy` (bookmarkable; middleware-gated)

## Layout regions

Inside `TenantShell`:

- **Header**: `TenantHeader` shows `tenant · <tenantId>` › **"Policy and
  configuration"**
- **Main**:
  `<section data-testid="tenant-policy-panel" data-tenant-id={tenantId}>`
  - `<h1>Policy and configuration</h1>` + subtitle paragraph
  - `.summaryGrid` — three `.summaryItem` tiles: **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**
    (`sourceTenantByKey` or "base"); rows sorted by key `localeCompare`

## 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** when `canEnterTenantWorkspace` is 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; current
      `aria-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 `Tenant` fixtures
  (`<tenantId>-district` of kind `district`, `<tenantId>` of kind `school`) and
  a `Map<string, TenantPolicyOverlay>`, then calls:
  - `resolvePolicy({ chain: [district, school], overlays, base, schema })` →
    `policy.values` (effective) and `policy.errors` (violations). Schema marks
    `max-agent-budget` / `dsar-export-days` as `tighten-only`, `voice-cloning` /
    `default-locale` as `override`.
  - `entries` = sorted `[...policy.values.entries()]`; `sourceTenantByKey`
    derived by scanning overlay key origins
  - `NOW = 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` —
  group `governance`, `requiredScopes: ['tenant:admin:*']`,
  `iconToken: 'shield-check'`)
- Shell: `TenantShell.tsx`, `TenantSidebar.tsx`, `TenantHeader.tsx`
- Sibling routes: [roles.md](roles.md), [status.md](status.md),
  [integrations.md](integrations.md), [members.md](members.md),
  [notifications.md](notifications.md)
- Conventions:
  [../WALKTHROUGH/00-conventions.md](../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 `primaryJob` describing both. Verify where
      attestation/override actions are intended to live.
- [ ] Tile labels say "Residency" but show `dataResidencyRegion` ("us") not the
      contract `region` ("us-east"); confirm which is canonical for display.
