# Notification, Policy, Quota, And Portal Surface Model v1

Status: draft for architecture review (PSSM Phase 5)
Owner: Platform Architecture
Last updated: 2026-06-01

## Purpose

Define the Phase 5 shared-surface model for notifications, policy snapshots,
quota composition, tenant customization, and portal publication tracks.

This model keeps these capabilities platform-owned and product-neutral. Products
can contribute registry entries, default policy values, and portal pages, but
they should not fork notification dispatch, entitlement snapshots, quota math,
or publication rules.

## Scope

In scope:

- notification template registry and delivery intent;
- versioned policy and entitlement snapshots;
- cross-product quota composition;
- tenant customization boundaries;
- public, customer, partner, and internal portal tracks;
- first implementation outputs and evidence.

Out of scope for this phase:

- replacing the existing notification relay;
- final tenant billing/rating plans;
- full external documentation access control;
- quota purchase, sales approval, or commercial packaging workflow;
- customer-managed notification template authoring.

## Operating Principles

1. Templates, policies, quotas, and portal visibility are platform contracts,
   not product-local constants.
2. Runtime decisions that affect access, billing, notifications, or launch
   eligibility snapshot the policy or registry version they used.
3. Tenant customization narrows or configures defaults; it does not bypass
   global hard-deny, security, audit, or release rules.
4. Quota posture is distinct from physical capacity. Both must pass before a
   launch or app workflow proceeds.
5. Portal publication tracks are derived from page metadata and review state,
   not from raw GitHub directory layout.
6. Privileged writes fail closed when policy, entitlement, quota, or template
   freshness is outside the approved budget.

## Shared Surface Map

| Surface | Platform-owned contract | Product contribution | First evidence |
|---|---|---|---|
| Notification templates | template ID, severity, channels, variables, delivery intent, preference defaults | product events and variable values | registry validation and dispatch dry-run |
| Policy snapshots | policy key, value, scope, version, effective time, freshness budget | default values and product-specific policy keys | snapshot read model and stale-policy guard |
| Entitlement snapshots | actor, tenant/project/product/resource scope, decision, source version | app/product entitlement rows and SKU/region eligibility | access read model with source versions |
| Quotas | limit, usage source, scope hierarchy, composition rule, reset window | product usage units and consumption signals | quota posture read model |
| Portal tracks | visibility metadata, review routing, redaction rules, build target | portal-native pages and source-doc links | publication readiness checker |

## Notification Template And Delivery Intent

The notification template registry defines stable template IDs and their
delivery posture. The dispatch layer consumes a delivery intent that is separate
from the rendered message.

Delivery intent shape:

| Field | Meaning |
|---|---|
| `template_id` | registry-backed notification template ID |
| `template_version` | template version used for render and preference lookup |
| `owner_product_id` | product or platform service that owns the notice |
| `event_ref` | source event, audit action, evidence item, or status component |
| `audience` | `user`, `project_admin`, `tenant_admin`, `operator`, `security`, `developer` |
| `scope` | org, project, product, resource, or release context |
| `severity` | `info`, `warning`, `critical` |
| `channels` | eligible channels after policy/preference evaluation |
| `variables` | validated render variables, with sensitive values forbidden |
| `dedupe_key` | stable key for suppressing repeated notices |
| `correlation_id` | traceability across source event and dispatch |

Initial delivery rules:

- source systems emit notification intent or domain events, not product-local
  email/websocket bodies;
- dispatch evaluates template registry, channel policy, user preference, and
  tenant suppression rules before delivery;
- `critical` notices cannot be globally suppressed by product code;
- delivery failures produce Status/Ops evidence, including channel, template,
  and age of oldest undelivered critical notice;
- rendered content must pass the same PII/credential redaction posture used for
  logs and traces.

## Policy And Entitlement Snapshots

`platform_policy_values` remains the implemented source for current policy keys. Phase 5
adds a shared snapshot contract so long-lived resources can prove which version
of policy or entitlement posture they used.

Snapshot shape:

| Field | Meaning |
|---|---|
| `snapshot_id` | unique snapshot identifier |
| `snapshot_kind` | `policy`, `entitlement`, `quota`, `notification_preference` |
| `scope_kind` | `global`, `tenant`, `project`, `product`, `resource`, `actor` |
| `scope_id` | concrete scope ID or `global` |
| `source_ref` | policy key, entitlement row, registry entry, or generated read model |
| `source_version` | registry/config/version value used for decision |
| `effective_at` | decision effective timestamp |
| `expires_at` | freshness deadline, if any |
| `decision` | `allow`, `deny`, `limit`, `notify`, `suppress`, or `unknown` |
| `reason_code` | stable machine-readable reason |
| `metadata` | non-sensitive details for audit/evidence |

Freshness behavior:

- read-only pages may display stale snapshots with an explicit stale indicator;
- launch, publish, credential, billing, and privileged writes fail closed when a
  required snapshot is missing or stale;
- global hard-deny, security disable, and emergency tenant disable override
  lower-scope allow decisions;
- policy snapshot writes are audit-relevant and must include `correlation_id`.

## Quota Composition

Quota is the platform policy decision that combines configured limits,
entitlements, current usage, and physical capacity signals. It should use one
composition model across GPUaaS, App Platform, Token Factory, storage, and
network surfaces.

Quota dimensions:

| Dimension | Examples | Usage source |
|---|---|---|
| compute | active allocations, GPU count, CPU VM count | provisioning/read models |
| app runtime | app instances, app runtime hours, shared runtime slots | app-platform read models and usage events |
| inference/token | API requests, token units, model concurrency | token-factory events/read models |
| storage | GiB, bucket count, object count | storage read models |
| network | managed ingress routes, bandwidth, endpoint count | ingress/read models |

Resolution order:

1. global defaults;
2. product defaults;
3. tenant overrides;
4. project overrides;
5. resource or app entitlement overrides.

Composition rules:

- most-specific scope wins unless a higher scope sets hard-deny;
- overrides may narrow limits without explicit approval;
- overrides that raise limits require a privileged mutation and audit row;
- usage must be measured from product-neutral read models or usage events;
- quota posture output must distinguish `ok`, `near_limit`, and `blocked`;
- quota posture must also explain whether the blocker is policy quota,
  entitlement, dependency freshness, or physical capacity.

The current V3 access quota and platform config quota read models are the first
UI/read-model surface. This document makes the model cross-product rather than
GPUaaS-only.

## Tenant Customization Boundary

Tenant customization is configuration, not service forking.

Allowed:

- policy value overrides within approved bounds;
- notification channel preference and suppression rules for non-critical
  notices;
- app entitlement enable/disable and narrowing policy overlays;
- quota overrides with audit and approval posture;
- portal visibility selection for customer-safe pages.

Not allowed:

- product-specific copies of shared notification dispatch;
- product-local entitlement engines;
- hardcoded tenant exceptions in handlers or UI;
- bypassing registry validation for scopes, usage units, templates, or
  evidence types;
- disabling critical security, billing, release, or credential notices from
  product code.

## Portal Publication Tracks

The documentation portal has four tracks:

| Track | Audience | Default access | Required review |
|---|---|---|---|
| Internal | product, architecture, development, CISO, ops, infra, app developers | authenticated internal | content owner |
| Customer | customer admins, customer security reviewers, tenant operators | customer-authenticated or review pack | product, security, architecture |
| Partner | partner app developers, integration teams | partner-authenticated | product, developer experience, security |
| Public | prospects, public developers, public reviewers | unauthenticated | product, security, legal/comms when required |

Publication rules:

- portal-native pages carry `visibility`, `audience`, `review_domain`,
  `status`, `freshness_risk`, and `source_docs` metadata;
- non-internal tracks publish only from portal pages, not raw `doc/**` files;
- external tracks require redaction review for hostnames, internal paths,
  sensitive evidence, break-glass details, and unresolved risks;
- API playground behavior is track-specific: internal can target UAT/dev,
  customer and partner tracks use approved sandbox/playground targets, and
  public defaults to mock behavior until approved;
- diagrams and images inherit the page visibility until asset-level metadata is
  available.

## Implementation Outputs

| Phase 5 task | First output | Verification |
|---|---|---|
| `PSS-C5-NOTIFICATION-TEMPLATES` | registry contract plus delivery intent model | registry doc includes template family and intent fields |
| `PSS-C5-POLICY-SNAPSHOTS` | policy/entitlement snapshot contract | snapshot shape and fail-closed freshness behavior documented |
| `PSS-C5-QUOTA-COMPOSITION` | cross-product quota composition model | dimensions cover GPU, app runtime, token/request, storage, and network |
| `PSS-C5-PORTAL-TRACKS` | publication track and access-control assumptions | Docusaurus portal page links this model |

## Open Review Questions

1. Should notification preferences be stored as a platform policy snapshot or a
   separate notification-owned table?
2. Which write paths should be the first hard fail-closed consumers of stale
   policy snapshots: app launch, allocation create, artifact promotion, or all
   privileged writes?
3. Should customer quota UX expose hard-deny reasons directly or translate them
   into customer-safe request/approval language?
4. Which portal track should be piloted first after the internal build:
   customer review pack or partner developer track?

