# Platform Policy Quota Capacity Composition v1

Status: active architecture contract
Owner: Platform Policy / IAM / Billing
Last updated: 2026-06-03
Fairway task: `PSSM-PROD-C4-POLICY-QUOTA-CAPACITY-001`

## Purpose

Define how policy, quotas, entitlements, and capacity reservations compose
across GPUaaS, App Platform, Token Factory, and future products.

This document does not implement a full policy engine. It defines the decision
contract that current in-code evaluators and future OPA/OPAL-style engines must
honor.

## Scope Order

Effective decisions evaluate in this order:

```text
global/platform
  -> plan
    -> organization
      -> department
        -> project
          -> principal or api key
            -> request
```

Lower scopes may reduce or specialize a parent decision. They must not raise a
parent ceiling unless the parent explicitly delegates that authority.

Department is mandatory attribution for all projects. Organizations that do not
actively manage departments use the default department, but policy and quota
records should still carry department context.

## Decision Inputs

Every policy or quota decision should be representable as:

```yaml
policy_decision_input:
  actor:
    actor_type: user | service_account | api_key | worker
    actor_id: string
    roles:
      - string
    scopes:
      - string
  hierarchy:
    organization_id: string
    department_id: string
    project_id: string
  product:
    product_id: string
    resource_type: string
    resource_id: string
    action: string
  request:
    dimension: string
    requested_delta: number
    unit: string
    region: string
    sku_or_model: string
  current_usage:
    scope_window: string
    quantity: number
    unit: string
  registry_versions:
    product: string
    scope: string
    usage_unit: string
    quota_dimension: string
    resource_type: string
  correlation_id: string
```

## Decision Output

```yaml
policy_decision_output:
  decision: allow | deny | warn
  reason_code: string
  user_message: string
  effective_ceiling:
    quantity: number
    unit: string
    inherited_from: global | plan | organization | department | project | principal | request
  matched_rules:
    - rule_id: string
      scope: string
      version: string
  evidence:
    snapshot_kind: string
    snapshot_version: string
    correlation_id: string
```

User-facing paths should return product-owned messages. Operator and evidence
paths should preserve the rule ids, snapshot versions, and correlation id.

## Quota Dimensions

| Dimension family | Examples | Owner | Notes |
|---|---|---|---|
| GPU / compute | active allocations, GPU count by SKU class, vCPU, memory GiB | GPUaaS + Platform Policy | Admission must respect SKU/region availability and capacity reservations. |
| App runtime | app instance concurrency, runtime hours, route count | App Platform + Platform Policy | Useful for Jupyter, vLLM, OpenClaw, Headlamp, and future apps. |
| Token / request | requests per minute, tokens per day, model endpoint concurrency | Token Factory + Platform Policy | API key can be the metering principal; project remains billing owner. |
| Storage | bucket bytes, volume bytes, object count, snapshots | Platform Storage / product owner | Provider-specific enforcement can lag, but admission/read model must expose posture. |
| Network | egress GiB, public endpoint count, ingress rule count | Access / Networking | First version may be read-only until access/connectivity product shapes are stable. |
| Capacity reservation | reserved GPU SKU, reserved model capacity, reserved app runtime pool | Platform Capacity / product owner | Reservation is an entitlement to capacity, not a ledger mutation. |

## Capacity Reservation Posture

Capacity reservations are explicit records that allocate capacity intent before
request-time admission. They do not replace billing, quotas, or scheduler truth.

| Resource | Reservation unit | Runtime admission check | Evidence required |
|---|---|---|---|
| GPU nodes | SKU, region, count, window | schedulable inventory and current allocations | reservation snapshot, scheduler decision, release evidence |
| App runtime | runtime class, region, concurrency, window | app runtime pool and route capacity | runtime pool status, launch decision, decommission evidence |
| Model serving | model family, endpoint class, TPM/RPM or concurrency, window | gateway/router capacity and backend health | accepted-usage stream, quota decision, reconciliation status |
| Storage | provider, tier, bytes, window | provider quota and project entitlement | storage usage snapshot, provider reconciliation, audit |

Reservations must have lifecycle state: `draft`, `active`, `exhausted`,
`expired`, `suspended`, or `retired`.

## Mutation Rules

Quota and capacity mutations must:

1. be idempotent;
2. validate parent scope ceilings;
3. validate registry entries for product, resource type, usage unit, and quota
   dimension;
4. write audit with before/after values, actor, scope, and correlation id;
5. produce evidence with snapshot kind and version;
6. invalidate or refresh any read model used for admission;
7. never mutate ledger entries directly.

Rejected mutations should preserve the failing parent scope and rule id in
operator evidence while returning a user-safe message.

## Customer-Facing Model

The customer-facing quota view should compose dimensions into one model:

| View | Shows |
|---|---|
| Organization | plan envelope, billing posture, departments near limit, product enablement |
| Department | child project allocation, chargeback/showback, budget posture, near-limit resources |
| Project | effective launch/app/token/storage quota, current usage, blocked reasons |
| API key / service account | product scopes, per-key rate limits, budget restrictions, expiry |

Products may render product-specific entry points, but they must call the same
platform policy and quota read models.

## Implementation Notes

- `platform_policy_values` remains the global/default policy store.
- Scoped quota records should live in a platform-owned quota assignment table
  rather than growing global policy keys for every tenant/project override.
- Billing owns legal money movement, invoice timing, payment terms, and rated
  ledger truth.
- Policy/quota owns admission and effective limits.
- Capacity reservation owns pre-allocated capacity intent and must reconcile
  against scheduler/provider state.

## Related Docs

- `../Tenant_Admin_Quota_Delegation_v1.md`
- `../Unified_IAM_Billing_Across_Products_v1.md`
- `Notification_Policy_Portal_Surface_Model_v1.md`
- `Platform_Registry_Contract_v1.md`
- `Platform_Evidence_Status_Slice_v1.md`
