version: 1
name: gpuaas-production-enforcement
mode: enforce

metadata:
  owner: platform-architecture
  description: "Machine-readable enforcement policy for prototype-to-production guardrails."

controls:
  - id: ENF-001
    title: balance-thresholds-config-driven
    status: enforce
    layer: runtime
    priority: critical
    requirement:
      - "No hardcoded minimum balance / low-balance thresholds in production code paths."
      - "Thresholds must be config-driven with override-ready model (per SKU/per org)."
    checks:
      - type: startup_policy_check
        gate: runtime_config_validation
      - type: code_scan
        gate: reviewguard
        deny_patterns:
          - "MIN_PROVISION_BALANCE\\s*="
          - "LOW_BALANCE_THRESHOLD\\s*="

  - id: ENF-002
    title: billing-window-policy
    status: enforce
    layer: code
    priority: critical
    requirement:
      - "Billing resolution/window is product policy and config, not ad-hoc timer logic."
      - "No setInterval-based billing loops in production workers."
    checks:
      - type: code_scan
        gate: reviewguard
        deny_patterns:
          - "setInterval\\s*\\(.*billing"
      - type: integration_test
        gate: ci
        name: billing_window_policy_test

  - id: ENF-003
    title: system-generated-linux-identity
    status: enforce
    layer: code
    priority: critical
    requirement:
      - "Node-level Linux identity must be deterministic system-generated and collision-free."
      - "Platform display username must not be used as OS account identity."
    checks:
      - type: code_review_rule
        gate: reviewguard
        deny_patterns:
          - "alloc\\.username"
          - "user\\.username.*linux"

  - id: ENF-004
    title: refund-policy-explicit
    status: enforce
    layer: contract
    priority: high
    requirement:
      - "Refund semantics must be policy-defined before API finalization."
      - "Endpoint naming must match behavior (internal credit vs provider refund)."
    checks:
      - type: pr_check
        gate: reviewguard
        require_pr_description_contains:
          - "Refund Policy Decision"
          - "Internal Credit"
          - "Provider Refund"
      - type: contract_review
        gate: api_signoff

  - id: ENF-005
    title: sku-api-domain-clean
    status: enforce
    layer: contract
    priority: high
    requirement:
      - "Public SKU schema must not expose UI-only styling fields."
      - "Frontend display mapping is owned by UI layer."
    checks:
      - type: openapi_schema_check
        gate: contracts_validate
        deny_fields:
          - color
          - bg
      - type: spectral
        gate: contracts_validate

  - id: ENF-006
    title: concurrent-allocation-policy
    status: enforce
    layer: runtime
    priority: critical
    requirement:
      - "Per-user concurrency limit must be configurable and auditable."
      - "Override mechanism for admin/org policy tier must be supported by model."
    checks:
      - type: startup_policy_check
        gate: runtime_config_validation
      - type: integration_test
        gate: ci
        name: concurrency_limit_enforcement_test

  - id: ENF-007
    title: storage-backend-object-store
    status: enforce
    layer: runtime
    priority: critical
    requirement:
      - "Production storage backend must be S3-compatible object storage."
      - "Local filesystem backend forbidden in prod."
    checks:
      - type: startup_policy_check
        gate: runtime_config_validation
        deny_values:
          - local_fs
          - filesystem
      - type: deployment_policy
        gate: deploy

  - id: ENF-008
    title: terminal-token-security
    status: enforce
    layer: contract
    priority: critical
    requirement:
      - "Terminal connect token must be short-lived, single-use, and allocation-scoped."
      - "Client obtains token via API, then uses token for websocket connect."
      - "Token-in-query transport is forbidden for terminal/notification websocket auth."
      - "Terminal websocket uses path allocation identifier + header-based auth/token transport."
    checks:
      - type: async_contract_check
        gate: contracts_validate
      - type: security_test
        gate: ci
        name: terminal_token_scope_ttl_single_use_test

  - id: ENF-009
    title: policy-values-table-driven
    status: enforce
    layer: runtime
    priority: critical
    requirement:
      - "Operational policy values must be resolved from config/DB policy tables, not hardcoded constants."
      - "Policy updates must be auditable and validated against bounds."
      - "Scope hierarchy must support global/plan/org/user overrides where applicable."
    checks:
      - type: startup_policy_check
        gate: runtime_config_validation
      - type: integration_test
        gate: ci
        name: policy_resolution_hierarchy_test
      - type: integration_test
        gate: ci
        name: policy_change_audit_test
      - type: code_scan
        gate: reviewguard
        deny_patterns:
          - "MIN_PROVISION_BALANCE\\s*="
          - "LOW_BALANCE_THRESHOLD\\s*="
          - "MAX_ACTIVE_ALLOCATIONS_PER_USER\\s*="

  - id: ENF-010
    title: no-hardcoded-runtime-policy-constants
    status: enforce
    layer: code
    priority: critical
    requirement:
      - "Runtime business-policy values must not be hardcoded in service code."
      - "Only test/fixture code may contain literal policy constants."
    checks:
      - type: code_scan
        gate: reviewguard
        deny_patterns:
          - "(?i)RATE_LIMIT(_|\\b).*=\\s*\\d+"
          - "(?i)BILLING_WINDOW(_|\\b).*=\\s*\\d+"
          - "(?i)REFUND_WINDOW(_|\\b).*=\\s*\\d+"
          - "(?i)MAX_.*ALLOCATIONS?.*=\\s*\\d+"
      - type: path_allowlist
        gate: reviewguard
        allowed_paths:
          - "**/*test*"
          - "**/*spec*"
          - "**/fixtures/**"

gate_mapping:
  contracts_validate:
    includes: [ENF-004, ENF-005, ENF-008]
  reviewguard:
    includes: [ENF-001, ENF-002, ENF-003, ENF-004, ENF-009, ENF-010]
  runtime_config_validation:
    includes: [ENF-001, ENF-006, ENF-007, ENF-009]
  ci:
    includes: [ENF-002, ENF-006, ENF-008, ENF-009]
  deploy:
    includes: [ENF-007]
