{
  "openapi": "3.1.0",
  "info": {
    "title": "GroundIT — Org & Admin",
    "version": "0.1.0",
    "description": "Config/setup plane (`org`) and governance plane (`admin`) — fsd-docs/01-org-admin-fsd.md, db-docs/02-org-admin.md, features-docs/01-org-admin-features.md. Both are web-portal (§W, Next.js) surfaces; the Flutter app only reads this config indirectly via other modules. `org` and `admin` are sources: they never join another module's schema — downstream consumers hold `ref→` soft references.\n"
  },
  "servers": [
    {
      "url": "/api/v1"
    }
  ],
  "security": [
    {
      "bearerJWT": []
    }
  ],
  "tags": [
    {
      "name": "org",
      "description": "Config/setup plane — fsd-docs/01 §W Org Setup."
    },
    {
      "name": "admin",
      "description": "Governance plane — fsd-docs/01 §W User Access, Governance & Tenant."
    },
    {
      "name": "legal-entity",
      "description": "ORG-S01."
    },
    {
      "name": "compliance-pack",
      "description": "Platform reference data bound by legal entities."
    },
    {
      "name": "department",
      "description": "ORG-S02."
    },
    {
      "name": "designation",
      "description": "ORG-S02."
    },
    {
      "name": "grade",
      "description": "ORG-S02."
    },
    {
      "name": "org-unit",
      "description": "ORG-S03."
    },
    {
      "name": "work-location",
      "description": "ORG-S04."
    },
    {
      "name": "geofence",
      "description": "ORG-S04."
    },
    {
      "name": "shift",
      "description": "ORG-S05."
    },
    {
      "name": "roster",
      "description": "ORG-S05."
    },
    {
      "name": "leave-type",
      "description": "ORG-S06."
    },
    {
      "name": "leave-policy",
      "description": "ORG-S06."
    },
    {
      "name": "holiday-calendar",
      "description": "ORG-S07."
    },
    {
      "name": "pay-component",
      "description": "ORG-S08."
    },
    {
      "name": "pay-structure",
      "description": "ORG-S08."
    },
    {
      "name": "pay-group",
      "description": "ORG-S12 — the per-legal-entity population segment: frequency, attendance-cycle anchor, cutoff, pay day, proration basis (ADR 0028)."
    },
    {
      "name": "rate-card",
      "description": "ORG-S12 — versioned daily-wage rates per skill category and state (ADR 0033)."
    },
    {
      "name": "piece-rate-catalog",
      "description": "ORG-S12 — versioned per-unit piece prices; `unit_code` is the vocabulary muster capture records against (ADR 0033)."
    },
    {
      "name": "statutory-config",
      "description": "ORG-S09."
    },
    {
      "name": "template",
      "description": "ORG-S10."
    },
    {
      "name": "dashboard",
      "description": "ADM-S01."
    },
    {
      "name": "role",
      "description": "ADM-S02."
    },
    {
      "name": "permission",
      "description": "ADM-S02."
    },
    {
      "name": "branch",
      "description": "ADM-S03."
    },
    {
      "name": "member-grant",
      "description": "ADM-S02 / PPL-S14 — employee role grants (ADR 0024)."
    },
    {
      "name": "audit-log",
      "description": "ADM-S04."
    },
    {
      "name": "report",
      "description": "ADM-S05."
    },
    {
      "name": "tenant-config",
      "description": "ADM-S06."
    },
    {
      "name": "entitlement",
      "description": "ADM-S06."
    },
    {
      "name": "division",
      "description": "ADM-S08 — the ORG_UNIT-scoped division console (ADR 0026)."
    }
  ],
  "paths": {
    "/legal-entities": {
      "get": {
        "operationId": "org.legal_entity.list",
        "summary": "List legal entities for the tenant",
        "tags": [
          "org",
          "legal-entity"
        ],
        "x-token": "org.legal_entity.list",
        "x-realizes-features": [
          "ORG-F01"
        ],
        "x-screens": [
          "ORG-S01",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.legal_entities"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "The legal-entities grid (fsd 01 ORG-S01). Sort whitelist: `entity_code`, `legal_name`, `created_at` (default `entity_code`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "market",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "IN",
                "KSA"
              ]
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "INACTIVE",
                "DISSOLVED"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of legal entities.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LegalEntityListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "org.legal_entity.create",
        "summary": "Create a legal entity",
        "tags": [
          "org",
          "legal-entity"
        ],
        "x-token": "org.legal_entity.create",
        "x-realizes-features": [
          "ORG-F01"
        ],
        "x-screens": [
          "ORG-S01",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.legal_entities"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Root config scope every employee/payroll/compliance record hangs beneath (fsd 01 ORG-S01). `market` + `compliance_pack_id` are fixed once created (db 02 §1.1 `legal_entities`). Access: Super Admin.\n\n**Plan limits:** this is the operation the `maxLegalEntities` numeric limit gates (ADR 0009 §e); it therefore declares `402`. The check runs inside the create transaction, behind a per-tenant advisory lock, and counts every entity that is not soft-deleted and not `DISSOLVED` — an `INACTIVE` entity still holds the tenant's statutory history and so still occupies a seat. Absent key or `-1` means unlimited. The same count is reported by `platform.tenant.get_usage` as `usage.legalEntities`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/LegalEntityFields"
                  },
                  {
                    "required": [
                      "entity_code",
                      "legal_name",
                      "display_name",
                      "market",
                      "compliance_pack_id",
                      "base_currency",
                      "fiscal_year_start_month",
                      "work_week"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Legal entity created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LegalEntity"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/legal-entities/{id}": {
      "get": {
        "operationId": "org.legal_entity.get",
        "summary": "Get a legal entity",
        "tags": [
          "org",
          "legal-entity"
        ],
        "x-token": "org.legal_entity.get",
        "x-realizes-features": [
          "ORG-F01"
        ],
        "x-screens": [
          "ORG-S01"
        ],
        "x-touches-entities": [
          "org.legal_entities"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Company profile detail panel + branding preview (fsd 01 ORG-S01).",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "Legal entity.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LegalEntity"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "org.legal_entity.update",
        "summary": "Update a legal entity",
        "tags": [
          "org",
          "legal-entity"
        ],
        "x-token": "org.legal_entity.update",
        "x-realizes-features": [
          "ORG-F01"
        ],
        "x-screens": [
          "ORG-S01"
        ],
        "x-touches-entities": [
          "org.legal_entities"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Save on ORG-S01. `market`/`compliance_pack_id` are immutable after create (service-rejects a change, 422). Branding fields (logo/brand colour) are NOT here — they route to `admin.tenant_config.update` via the platform seam (fsd 01 *gaps* 5). Access: Super Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LegalEntityFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Legal entity updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LegalEntity"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "operationId": "org.legal_entity.delete",
        "summary": "Delete a legal entity",
        "tags": [
          "org",
          "legal-entity"
        ],
        "x-token": "org.legal_entity.delete",
        "x-realizes-features": [
          "ORG-F01"
        ],
        "x-screens": [
          "ORG-S01"
        ],
        "x-touches-entities": [
          "org.legal_entities"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Soft-delete a legal entity from the ORG-S01 company profile. Refused with 409 while any live config or workforce still belongs to it — employees, payroll runs, departments, designations, grades, org units, work locations, shifts, rosters, leave types, leave policies, holiday calendars, statutory configurations, pay components, pay structures, document templates or branches — with the dependent type and count named in the problem detail. Access HR Admin. Requires a TENANT-scoped role: the dependency counts span `people.*`/`leave.*`, whose row-level ownership overlay hides rows from a narrower grant scope — so a role scoped to a legal entity or branch is refused with 403 rather than deleting on an incomplete count.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "204": {
            "description": "Legal entity deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/legal-entities/{id}/apply-pack-defaults": {
      "post": {
        "operationId": "org.legal_entity.apply_pack_defaults",
        "summary": "Apply the bound compliance pack's master defaults to this legal entity",
        "tags": [
          "org",
          "legal-entity"
        ],
        "x-token": "org.legal_entity.apply_pack_defaults",
        "x-realizes-features": [
          "ORG-F01",
          "ORG-F05",
          "ORG-F06"
        ],
        "x-screens": [
          "ORG-S01",
          "ORG-S06",
          "ORG-S07",
          "ORG-S08",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.pay_components",
          "org.pay_structures",
          "org.leave_types",
          "org.leave_policies",
          "org.holiday_calendars"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Instantiates the **pack-seeded tenant baseline** (db 16 §3.3) for this legal entity — the master rows a freshly provisioned tenant has none of. `ORG-S01` states that binding the pack \"seeds currency/fiscal/week/RTL/holiday/leave/component defaults\" and `ORG-S06`'s empty state is \"pre-seeded with pack defaults on a new tenant\"; this is the operation that performs it, callable from the `ADM-S01` first-login setup flow or re-run later from `ORG-S08`.\nThe market is **derived from the entity's effective `legal_entity_compliance_packs` binding** — never passed by the client — so the applied set cannot disagree with the bound pack (`XC-F01`). Values come from the pack's `rules` where it declares them and from the deployment default catalogue otherwise; no statutory rate, ceiling or entitlement is invented (`PAY-F02` is fail-closed on `org.statutory_config`).\n**Idempotent by insert-if-absent on each documented natural key** (db 16 §2.1), not upsert: re-applying reports `created: 0` and never rewrites a row the tenant has customized. Seeded `pay_structures` / `leave_policies` / `holiday_calendars` land as `DRAFT` — **Publish** stays the explicit action `ORG-S06`/`S07`/`S08` specify, because publishing stamps a version onto payslips and balance ledgers. Access HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "Defaults applied; the per-set counts report what this call created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PackDefaultsResult"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "description": "The legal entity has no compliance pack in force today, so no market can be derived — bind a pack on `ORG-S01` first (problem+json, `../_shared.yaml` Problem).\n",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/compliance-packs": {
      "get": {
        "operationId": "org.compliance_pack.list",
        "summary": "List published compliance packs (for legal-entity pack binding)",
        "tags": [
          "org",
          "compliance-pack"
        ],
        "x-token": "org.compliance_pack.list",
        "x-realizes-features": [
          "ORG-F01",
          "ORG-F07"
        ],
        "x-screens": [
          "ORG-S01",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.compliance_packs"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": true,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Platform-global reference data (db 02 §1.1 `compliance_packs`) — INSERT-only by `app_migrate`, never writable by this API. Populates the pack selector on `ORG-S01`. Sort whitelist: `pack_code`, `effective_from` (default `pack_code`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "jurisdiction",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "IN",
                "KSA"
              ]
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "DRAFT",
                "PUBLISHED",
                "SUPERSEDED"
              ],
              "default": "PUBLISHED"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of compliance packs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompliancePackListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/compliance-packs/{id}": {
      "get": {
        "operationId": "org.compliance_pack.get",
        "summary": "Read one compliance pack, including the `rules` it will apply",
        "tags": [
          "org",
          "compliance-pack"
        ],
        "x-token": "org.compliance_pack.get",
        "x-realizes-features": [
          "ORG-F01",
          "ORG-F07"
        ],
        "x-screens": [
          "ORG-S01",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.compliance_packs"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": true,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "The pack **selector** (`org.compliance_pack.list`) deliberately projects identity only, so an admin binding a pack on `ORG-S01` could not see what they were agreeing to — and two `PUBLISHED` versions of the same `pack_code` were indistinguishable beyond `version_no`. This operation is the read that closes that: the same row plus its `rules` document (currency, fiscal calendar, work week, locales/RTL, the statutory tables, leave/holiday defaults, filing formats, identity, retention, and — KSA only — nationalization), so the binding screen can render the pack in plain language and diff two versions field-by-field from the data rather than from a hand-authored changelog.\nStill **platform-global reference data** (db 02 §1.1 `compliance_packs`, db 16 §2.2): no `tenant_id`, INSERT-only by `app_migrate`, and version-frozen once `PUBLISHED` — a rate change is a new `version_no`, never an edit, because a payroll run stamps `compliance_pack_version` and must recompute identically years later. Tenant-specific overrides are **not** made here; they live one layer down on the tenant-scoped `org.statutory_config` (`org.statutory_config.create` / `.update`), seeded from a pack by `org.legal_entity.apply_pack_defaults`.\nSections of `rules` may carry `status: PLACEHOLDER_PENDING_COMPLIANCE_REVIEW`. That is returned verbatim and must be surfaced as provisional by consumers, never presented as settled policy.\n`ETag` is the row's optimistic-lock counter `version` (`\"v0\"` for every seeded pack, since a published pack never changes); the pack's own edition is `version_no`. The two are different numbers — do not conflate them.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "The compliance pack and its full `rules` document.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompliancePackDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "description": "`id` is not a UUID (problem+json, `../_shared.yaml` Problem).\n",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/departments": {
      "get": {
        "operationId": "org.department.list",
        "summary": "List departments",
        "tags": [
          "org",
          "department"
        ],
        "x-token": "org.department.list",
        "x-realizes-features": [
          "ORG-F02"
        ],
        "x-screens": [
          "ORG-S02",
          "ORG-S03",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.departments"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Departments Tree ⇄ Table grid (fsd 01 ORG-S02). Sort whitelist: `dept_code`, `name`, `created_at` (default `dept_code`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "parent_department_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "INACTIVE"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of departments.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DepartmentListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "org.department.create",
        "summary": "Create a department",
        "tags": [
          "org",
          "department"
        ],
        "x-token": "org.department.create",
        "x-realizes-features": [
          "ORG-F02"
        ],
        "x-screens": [
          "ORG-S02",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.departments"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "+ New department drawer (fsd 01 ORG-S02). Access: HR Admin.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/DepartmentFields"
                  },
                  {
                    "required": [
                      "legal_entity_id",
                      "dept_code",
                      "name"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Department created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Department"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/departments/{id}": {
      "patch": {
        "operationId": "org.department.update",
        "summary": "Update a department",
        "tags": [
          "org",
          "department"
        ],
        "x-token": "org.department.update",
        "x-realizes-features": [
          "ORG-F02"
        ],
        "x-screens": [
          "ORG-S02"
        ],
        "x-touches-entities": [
          "org.departments"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Save / drag-to-reparent / bulk Move-to-department (fsd 01 ORG-S02). `parent_department_id` must stay acyclic and within the same legal entity (db 02 check constraints). Access: HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DepartmentFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Department updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Department"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "operationId": "org.department.delete",
        "summary": "Delete a department (only when it has zero employees)",
        "tags": [
          "org",
          "department"
        ],
        "x-token": "org.department.delete",
        "x-realizes-features": [
          "ORG-F02"
        ],
        "x-screens": [
          "ORG-S02"
        ],
        "x-touches-entities": [
          "org.departments"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Delete allowed only when the department has 0 employees, else 409 (fsd 01 ORG-S02 States). Access: Super Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "204": {
            "description": "Department deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/designations": {
      "get": {
        "operationId": "org.designation.list",
        "summary": "List designations",
        "tags": [
          "org",
          "designation"
        ],
        "x-token": "org.designation.list",
        "x-realizes-features": [
          "ORG-F02"
        ],
        "x-screens": [
          "ORG-S02",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.designations"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Designations tab grid (fsd 01 ORG-S02); also feeds `recruit` requisition/offer title pickers (db 02 §1.2). Sort whitelist: `designation_code`, `title`, `created_at` (default `designation_code`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "grade_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "INACTIVE"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of designations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DesignationListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "org.designation.create",
        "summary": "Create a designation",
        "tags": [
          "org",
          "designation"
        ],
        "x-token": "org.designation.create",
        "x-realizes-features": [
          "ORG-F02"
        ],
        "x-screens": [
          "ORG-S02",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.designations"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "+ New designation drawer (fsd 01 ORG-S02). Access: HR Admin.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/DesignationFields"
                  },
                  {
                    "required": [
                      "legal_entity_id",
                      "designation_code",
                      "title"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Designation created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Designation"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/designations/{id}": {
      "patch": {
        "operationId": "org.designation.update",
        "summary": "Update a designation",
        "tags": [
          "org",
          "designation"
        ],
        "x-token": "org.designation.update",
        "x-realizes-features": [
          "ORG-F02"
        ],
        "x-screens": [
          "ORG-S02"
        ],
        "x-touches-entities": [
          "org.designations"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Save on ORG-S02 Designations tab. Access HR Admin.",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DesignationFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Designation updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Designation"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "operationId": "org.designation.delete",
        "summary": "Delete a designation",
        "tags": [
          "org",
          "designation"
        ],
        "x-token": "org.designation.delete",
        "x-realizes-features": [
          "ORG-F02"
        ],
        "x-screens": [
          "ORG-S02"
        ],
        "x-touches-entities": [
          "org.designations"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Delete a designation from the ORG-S02 Designations tab. Refused with 409 while any active employee still holds it (dependent type and count are named in the problem detail). Access HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "204": {
            "description": "Designation deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/grades": {
      "get": {
        "operationId": "org.grade.list",
        "summary": "List grades",
        "tags": [
          "org",
          "grade"
        ],
        "x-token": "org.grade.list",
        "x-realizes-features": [
          "ORG-F02"
        ],
        "x-screens": [
          "ORG-S02",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.grades"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Grades tab grid (fsd 01 ORG-S02); also populates the CTC-band picker on `ORG-S08` pay structures. Sort whitelist: `level`, `grade_code`, `created_at` (default `level`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "INACTIVE"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of grades.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GradeListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "org.grade.create",
        "summary": "Create a grade",
        "tags": [
          "org",
          "grade"
        ],
        "x-token": "org.grade.create",
        "x-realizes-features": [
          "ORG-F02"
        ],
        "x-screens": [
          "ORG-S02",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.grades"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "+ New grade drawer (fsd 01 ORG-S02). Access: HR Admin.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/GradeFields"
                  },
                  {
                    "required": [
                      "legal_entity_id",
                      "grade_code",
                      "name",
                      "level"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Grade created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Grade"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/grades/{id}": {
      "patch": {
        "operationId": "org.grade.update",
        "summary": "Update a grade",
        "tags": [
          "org",
          "grade"
        ],
        "x-token": "org.grade.update",
        "x-realizes-features": [
          "ORG-F02"
        ],
        "x-screens": [
          "ORG-S02"
        ],
        "x-touches-entities": [
          "org.grades"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Save on ORG-S02 Grades tab; `max_ctc_amount >= min_ctc_amount` (db 02 check). Access HR Admin.",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GradeFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Grade updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Grade"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "operationId": "org.grade.delete",
        "summary": "Delete a grade",
        "tags": [
          "org",
          "grade"
        ],
        "x-token": "org.grade.delete",
        "x-realizes-features": [
          "ORG-F02"
        ],
        "x-screens": [
          "ORG-S02"
        ],
        "x-touches-entities": [
          "org.grades"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Delete a grade from the ORG-S02 Grades tab. Refused with 409 while any designation, active employee or leave policy still references it (dependent type and count are named in the problem detail). Access HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "204": {
            "description": "Grade deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/org-units": {
      "get": {
        "operationId": "org.org_unit.list",
        "summary": "List org tree units",
        "tags": [
          "org",
          "org-unit"
        ],
        "x-token": "org.org_unit.list",
        "x-realizes-features": [
          "ORG-F02"
        ],
        "x-screens": [
          "ORG-S03"
        ],
        "x-touches-entities": [
          "org.org_units"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Feeds the org-chart canvas (fsd 01 ORG-S03). The reporting tree that manager scope, approval routing, and RBAC branch scope resolve against. Sort whitelist: `unit_code`, `created_at` (default `unit_code`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "parent_org_unit_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "unit_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "DIVISION",
                "BUSINESS_UNIT",
                "DEPARTMENT",
                "TEAM"
              ]
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "INACTIVE"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of org units.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrgUnitListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "org.org_unit.create",
        "summary": "Create an org tree unit",
        "tags": [
          "org",
          "org-unit"
        ],
        "x-token": "org.org_unit.create",
        "x-realizes-features": [
          "ORG-F02"
        ],
        "x-screens": [
          "ORG-S03"
        ],
        "x-touches-entities": [
          "org.org_units"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Side PT-MODAL drawer create on the org chart (fsd 01 ORG-S03). Access HR Admin.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/OrgUnitFields"
                  },
                  {
                    "required": [
                      "legal_entity_id",
                      "unit_code",
                      "name",
                      "unit_type"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Org unit created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrgUnit"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/org-units/{id}": {
      "get": {
        "operationId": "org.org_unit.get",
        "summary": "Get an org tree unit",
        "tags": [
          "org",
          "org-unit"
        ],
        "x-token": "org.org_unit.get",
        "x-realizes-features": [
          "ORG-F02"
        ],
        "x-screens": [
          "ORG-S03"
        ],
        "x-touches-entities": [
          "org.org_units"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Org-unit edit drawer detail (fsd 01 ORG-S03).",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "Org unit.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrgUnit"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "org.org_unit.update",
        "summary": "Update an org tree unit",
        "tags": [
          "org",
          "org-unit"
        ],
        "x-token": "org.org_unit.update",
        "x-realizes-features": [
          "ORG-F02"
        ],
        "x-screens": [
          "ORG-S03"
        ],
        "x-touches-entities": [
          "org.org_units"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Save unit / re-parent a node (fsd 01 ORG-S03); acyclic within the same legal entity (db 02 check constraints). Approval routing and manager-scope RLS overlays resolve through this tree. Access HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrgUnitFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Org unit updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrgUnit"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "operationId": "org.org_unit.delete",
        "summary": "Delete an org tree unit",
        "tags": [
          "org",
          "org-unit"
        ],
        "x-token": "org.org_unit.delete",
        "x-realizes-features": [
          "ORG-F02"
        ],
        "x-screens": [
          "ORG-S03"
        ],
        "x-touches-entities": [
          "org.org_units"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Soft-delete a unit from the ORG-S03 org tree. Refused with 409 while child units still report to it, active employees still sit in it, or rosters still target it (dependent type and count are named in the problem detail). Access HR Admin. Requires a TENANT-scoped role: the dependency counts span `people.*`/`leave.*`, whose row-level ownership overlay hides rows from a narrower grant scope — so a role scoped to a legal entity or branch is refused with 403 rather than deleting on an incomplete count.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "204": {
            "description": "Org unit deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/work-locations": {
      "get": {
        "operationId": "org.work_location.list",
        "summary": "List work locations",
        "tags": [
          "org",
          "work-location"
        ],
        "x-token": "org.work_location.list",
        "x-realizes-features": [
          "ORG-F03"
        ],
        "x-screens": [
          "ORG-S04",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.work_locations"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Work-locations grid (fsd 01 ORG-S04). Sort whitelist: `location_code`, `created_at` (default `location_code`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "location_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "OFFICE",
                "SITE",
                "CLIENT",
                "REMOTE",
                "FIELD"
              ]
            }
          },
          {
            "name": "punch_enforcement",
            "in": "query",
            "required": false,
            "description": "\"Which of my sites actually enforce their perimeter\" (#1317).",
            "schema": {
              "type": "string",
              "enum": [
                "ADVISORY",
                "BLOCKING"
              ]
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "INACTIVE"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of work locations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkLocationListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "org.work_location.create",
        "summary": "Create a work location",
        "tags": [
          "org",
          "work-location"
        ],
        "x-token": "org.work_location.create",
        "x-realizes-features": [
          "ORG-F03"
        ],
        "x-screens": [
          "ORG-S04",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.work_locations"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "+ Add location drawer, map picker centroid (fsd 01 ORG-S04). Access HR Admin.\n\n**Plan limits:** this is the operation the `maxWorkLocations` numeric limit gates (ADR 0009 §e); it therefore declares `402`. The check runs inside the create transaction, behind a per-tenant advisory lock. `org.work_locations` has no terminal state, so every non-soft-deleted row counts (`ACTIVE` and `INACTIVE` alike). Absent key or `-1` means unlimited. The same count is reported by `platform.tenant.get_usage` as `usage.workLocations`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WorkLocationFields"
                  },
                  {
                    "required": [
                      "legal_entity_id",
                      "location_code",
                      "name",
                      "location_type",
                      "timezone"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Work location created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkLocation"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/work-locations/{id}": {
      "get": {
        "operationId": "org.work_location.get",
        "summary": "Get a work location",
        "tags": [
          "org",
          "work-location"
        ],
        "x-token": "org.work_location.get",
        "x-realizes-features": [
          "ORG-F03"
        ],
        "x-screens": [
          "ORG-S04"
        ],
        "x-touches-entities": [
          "org.work_locations"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Location detail drawer with map + geofence overlay (fsd 01 ORG-S04).",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "Work location.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkLocation"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "org.work_location.update",
        "summary": "Update a work location",
        "tags": [
          "org",
          "work-location"
        ],
        "x-token": "org.work_location.update",
        "x-realizes-features": [
          "ORG-F03"
        ],
        "x-screens": [
          "ORG-S04"
        ],
        "x-touches-entities": [
          "org.work_locations"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Save location (fsd 01 ORG-S04); consumed by `attend` geofenced-punch attestation (ATT-F01, XC-F10). Access HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WorkLocationFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Work location updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkLocation"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "operationId": "org.work_location.delete",
        "summary": "Delete a work location",
        "tags": [
          "org",
          "work-location"
        ],
        "x-token": "org.work_location.delete",
        "x-realizes-features": [
          "ORG-F03"
        ],
        "x-screens": [
          "ORG-S04"
        ],
        "x-touches-entities": [
          "org.work_locations",
          "org.geofences"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Soft-delete a work location from ORG-S04. Refused with 409 while active employees are based there, or org units, rosters, holiday calendars or statutory configurations are still scoped to it (dependent type and count are named in the problem detail). The location's own geofences are soft-deleted with it in the same transaction — a geofence has no meaning apart from its location and nothing else references one. Access HR Admin. Requires a TENANT-scoped role: the dependency counts span `people.*`/`leave.*`, whose row-level ownership overlay hides rows from a narrower grant scope — so a role scoped to a legal entity or branch is refused with 403 rather than deleting on an incomplete count.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "204": {
            "description": "Work location deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/geofences": {
      "get": {
        "operationId": "org.geofence.list",
        "summary": "List geofences",
        "tags": [
          "org",
          "geofence"
        ],
        "x-token": "org.geofence.list",
        "x-realizes-features": [
          "ORG-F03"
        ],
        "x-screens": [
          "ORG-S04"
        ],
        "x-touches-entities": [
          "org.geofences"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Geofence overlay list for a location (fsd 01 ORG-S04); a location may carry several zones, `REMOTE` carries none. Sort whitelist: `created_at` (default `-created_at`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "work_location_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "is_active",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of geofences.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GeofenceListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "org.geofence.create",
        "summary": "Create a geofence",
        "tags": [
          "org",
          "geofence"
        ],
        "x-token": "org.geofence.create",
        "x-realizes-features": [
          "ORG-F03"
        ],
        "x-screens": [
          "ORG-S04"
        ],
        "x-touches-entities": [
          "org.geofences"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Geofence editor — circle (centre + radius) or polygon ring (fsd 01 ORG-S04); shape-conditional fields enforced by db 02 check constraints. Access HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/GeofenceFields"
                  },
                  {
                    "required": [
                      "work_location_id",
                      "shape"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Geofence created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Geofence"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/geofences/{id}": {
      "patch": {
        "operationId": "org.geofence.update",
        "summary": "Update a geofence",
        "tags": [
          "org",
          "geofence"
        ],
        "x-token": "org.geofence.update",
        "x-realizes-features": [
          "ORG-F03"
        ],
        "x-screens": [
          "ORG-S04"
        ],
        "x-touches-entities": [
          "org.geofences"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Save / toggle active on the geofence editor (fsd 01 ORG-S04). Access HR Admin.",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GeofenceFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Geofence updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Geofence"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "operationId": "org.geofence.delete",
        "summary": "Delete a geofence",
        "tags": [
          "org",
          "geofence"
        ],
        "x-token": "org.geofence.delete",
        "x-realizes-features": [
          "ORG-F03"
        ],
        "x-screens": [
          "ORG-S04"
        ],
        "x-touches-entities": [
          "org.geofences"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Soft-delete a geofence from the ORG-S04 geofence editor. Refused with 409 while any shift assignment attests against it, or any punch ever has (`attend.geofence_attestations` is append-only anti-fraud evidence, so every row counts). Also refused when this is the LAST geofence of a non-REMOTE work location, which would leave that location with no boundary to attest clock-ins against. NOTE that the create path does not yet enforce the same pairing — a non-REMOTE location can be created with zero geofences (api-docs GAP-20 / security SGAP-14) — so this guard upholds the rule at one end only. Access HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "204": {
            "description": "Geofence deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/shifts": {
      "get": {
        "operationId": "org.shift.list",
        "summary": "List shifts",
        "tags": [
          "org",
          "shift"
        ],
        "x-token": "org.shift.list",
        "x-realizes-features": [
          "ORG-F04"
        ],
        "x-screens": [
          "ORG-S05",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.shifts"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Shifts tab grid (fsd 01 ORG-S05); consumed by `attend` schedules/OT/regularization (ATT-F02). Sort whitelist: `shift_code`, `start_time`, `created_at` (default `shift_code`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "INACTIVE"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of shifts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShiftListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "org.shift.create",
        "summary": "Create a shift",
        "tags": [
          "org",
          "shift"
        ],
        "x-token": "org.shift.create",
        "x-realizes-features": [
          "ORG-F04"
        ],
        "x-screens": [
          "ORG-S05",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.shifts"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "+ Add shift drawer (fsd 01 ORG-S05). Access HR Admin.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/ShiftFields"
                  },
                  {
                    "required": [
                      "legal_entity_id",
                      "shift_code",
                      "name",
                      "start_time",
                      "end_time"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Shift created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Shift"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/shifts/{id}": {
      "patch": {
        "operationId": "org.shift.update",
        "summary": "Update a shift",
        "tags": [
          "org",
          "shift"
        ],
        "x-token": "org.shift.update",
        "x-realizes-features": [
          "ORG-F04"
        ],
        "x-screens": [
          "ORG-S05"
        ],
        "x-touches-entities": [
          "org.shifts"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Save on ORG-S05 Shifts tab. Access HR Admin.",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ShiftFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Shift updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Shift"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "operationId": "org.shift.delete",
        "summary": "Delete a shift",
        "tags": [
          "org",
          "shift"
        ],
        "x-token": "org.shift.delete",
        "x-realizes-features": [
          "ORG-F04"
        ],
        "x-screens": [
          "ORG-S05"
        ],
        "x-touches-entities": [
          "org.shifts"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Soft-delete a shift from the ORG-S05 Shifts tab. Refused with 409 while any roster still runs it (dependent type and count are named in the problem detail). Access HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "204": {
            "description": "Shift deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/rosters": {
      "get": {
        "operationId": "org.roster.list",
        "summary": "List rosters",
        "tags": [
          "org",
          "roster"
        ],
        "x-token": "org.roster.list",
        "x-realizes-features": [
          "ORG-F04"
        ],
        "x-screens": [
          "ORG-S05"
        ],
        "x-touches-entities": [
          "org.rosters"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "team",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Rosters tab grid (fsd 01 ORG-S05); Manager sees rosters within their unit scope. Consumed by `attend` (ATT-F02) to build per-day schedules. Sort whitelist: `effective_from`, `roster_code` (default `-effective_from`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "org_unit_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "employee_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "DRAFT",
                "ACTIVE",
                "INACTIVE"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of rosters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RosterListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "org.roster.create",
        "summary": "Create a roster",
        "tags": [
          "org",
          "roster"
        ],
        "x-token": "org.roster.create",
        "x-realizes-features": [
          "ORG-F04"
        ],
        "x-screens": [
          "ORG-S05"
        ],
        "x-touches-entities": [
          "org.rosters"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "team",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "+ Add roster drawer (fsd 01 ORG-S05); requires ≥1 of `org_unit_id`/`employee_id` (db 02 check constraint). Access HR Admin; Manager may roster within unit scope (XC-F04).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/RosterFields"
                  },
                  {
                    "required": [
                      "legal_entity_id",
                      "roster_code",
                      "shift_id",
                      "rotation",
                      "effective_from"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Roster created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Roster"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/rosters/{id}": {
      "patch": {
        "operationId": "org.roster.update",
        "summary": "Update a roster",
        "tags": [
          "org",
          "roster"
        ],
        "x-token": "org.roster.update",
        "x-realizes-features": [
          "ORG-F04"
        ],
        "x-screens": [
          "ORG-S05"
        ],
        "x-touches-entities": [
          "org.rosters"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "team",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Save on ORG-S05 Rosters tab. Access HR Admin; Manager within unit scope (XC-F04).",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RosterFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Roster updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Roster"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "operationId": "org.roster.delete",
        "summary": "Delete a roster",
        "tags": [
          "org",
          "roster"
        ],
        "x-token": "org.roster.delete",
        "x-realizes-features": [
          "ORG-F04"
        ],
        "x-screens": [
          "ORG-S05"
        ],
        "x-touches-entities": [
          "org.rosters"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "team",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Soft-delete a roster from the ORG-S05 Rosters tab. A DRAFT or INACTIVE roster deletes; an ACTIVE one returns 409 and must be set to INACTIVE first, because a live roster is what the workforce is scheduled against today. Also refused while attendance schedules generated from it are still live. Access Manager within unit scope (XC-F04).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "204": {
            "description": "Roster deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/leave-types": {
      "get": {
        "operationId": "org.leave_type.list",
        "summary": "List leave types",
        "tags": [
          "org",
          "leave-type"
        ],
        "x-token": "org.leave_type.list",
        "x-realizes-features": [
          "ORG-F05"
        ],
        "x-screens": [
          "ORG-S06",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.leave_types"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Leave-types grid (fsd 01 ORG-S06). Sort whitelist: `type_code`, `category`, `created_at` (default `type_code`).\n\n`applicable_to=me` narrows the page to the leave types the CALLER may actually apply against — those carrying a `PUBLISHED` leave policy for the caller's own legal entity and grade. Applicant-facing surfaces (ESS/PWA/mobile leave-apply pickers) must send it: the unfiltered list also carries master rows seeded by a market pack that no policy covers, so an unfiltered picker can offer two identically named leave types of which only one has a balance. A principal with no linked employee matches nothing and receives an empty page.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ANNUAL",
                "SICK",
                "CASUAL",
                "MATERNITY",
                "PATERNITY",
                "HAJJ",
                "UNPAID",
                "COMP_OFF",
                "OPTIONAL_HOLIDAY",
                "OTHER"
              ]
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "INACTIVE"
              ]
            }
          },
          {
            "name": "applicable_to",
            "in": "query",
            "required": false,
            "description": "Restrict to the leave types the caller is entitled to apply against.",
            "schema": {
              "type": "string",
              "enum": [
                "me"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of leave types.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeaveTypeListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "org.leave_type.create",
        "summary": "Create a leave type",
        "tags": [
          "org",
          "leave-type"
        ],
        "x-token": "org.leave_type.create",
        "x-realizes-features": [
          "ORG-F05"
        ],
        "x-screens": [
          "ORG-S06"
        ],
        "x-touches-entities": [
          "org.leave_types"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "+ Add leave type drawer (fsd 01 ORG-S06). Access HR Admin (Finance for encashable policies).",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/LeaveTypeFields"
                  },
                  {
                    "required": [
                      "legal_entity_id",
                      "type_code",
                      "name",
                      "category",
                      "unit"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Leave type created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeaveType"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/leave-types/{id}": {
      "patch": {
        "operationId": "org.leave_type.update",
        "summary": "Update a leave type",
        "tags": [
          "org",
          "leave-type"
        ],
        "x-token": "org.leave_type.update",
        "x-realizes-features": [
          "ORG-F05"
        ],
        "x-screens": [
          "ORG-S06"
        ],
        "x-touches-entities": [
          "org.leave_types"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Save on ORG-S06 leave-type drawer. Access HR Admin.",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeaveTypeFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Leave type updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeaveType"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "operationId": "org.leave_type.delete",
        "summary": "Delete a leave type",
        "tags": [
          "org",
          "leave-type"
        ],
        "x-token": "org.leave_type.delete",
        "x-realizes-features": [
          "ORG-F05"
        ],
        "x-screens": [
          "ORG-S06"
        ],
        "x-touches-entities": [
          "org.leave_types"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Soft-delete a leave type from ORG-S06. Refused with 409 while leave policies grant it, or leave applications, balance entries, comp-off credits or encashments are booked against it (dependent type and count are named in the problem detail). Balances are append-only, so every entry ever written still counts. Access HR Admin. Requires a TENANT-scoped role: the dependency counts span `people.*`/`leave.*`, whose row-level ownership overlay hides rows from a narrower grant scope — so a role scoped to a legal entity or branch is refused with 403 rather than deleting on an incomplete count.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "204": {
            "description": "Leave type deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/leave-policies": {
      "get": {
        "operationId": "org.leave_policy.list",
        "summary": "List leave policies",
        "tags": [
          "org",
          "leave-policy"
        ],
        "x-token": "org.leave_policy.list",
        "x-realizes-features": [
          "ORG-F05"
        ],
        "x-screens": [
          "ORG-S06",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.leave_policies"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Policy list within the leave-type drawer (fsd 01 ORG-S06). Sort whitelist: `policy_code`, `version_no`, `created_at` (default `-version_no`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "leave_type_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "grade_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "DRAFT",
                "PUBLISHED",
                "SUPERSEDED"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of leave policies.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeavePolicyListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "org.leave_policy.create",
        "summary": "Create a leave policy (draft)",
        "tags": [
          "org",
          "leave-policy"
        ],
        "x-token": "org.leave_policy.create",
        "x-realizes-features": [
          "ORG-F05"
        ],
        "x-screens": [
          "ORG-S06"
        ],
        "x-touches-entities": [
          "org.leave_policies"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Entitlement/accrual/carry-forward/eligibility policy for a leave type (fsd 01 ORG-S06); created `DRAFT`. Access HR Admin (Finance for encashable policies).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/LeavePolicyFields"
                  },
                  {
                    "required": [
                      "legal_entity_id",
                      "leave_type_id",
                      "policy_code",
                      "entitlement_days",
                      "accrual_method"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Leave policy created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeavePolicy"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/leave-policies/{id}": {
      "get": {
        "operationId": "org.leave_policy.get",
        "summary": "Get a leave policy",
        "tags": [
          "org",
          "leave-policy"
        ],
        "x-token": "org.leave_policy.get",
        "x-realizes-features": [
          "ORG-F05"
        ],
        "x-screens": [
          "ORG-S06"
        ],
        "x-touches-entities": [
          "org.leave_policies"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Policy detail (rules composite) on the leave-type drawer (fsd 01 ORG-S06).",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "Leave policy.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeavePolicy"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "org.leave_policy.update",
        "summary": "Update a leave policy (while DRAFT)",
        "tags": [
          "org",
          "leave-policy"
        ],
        "x-token": "org.leave_policy.update",
        "x-realizes-features": [
          "ORG-F05"
        ],
        "x-screens": [
          "ORG-S06"
        ],
        "x-touches-entities": [
          "org.leave_policies"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Save on the policy drawer (fsd 01 ORG-S06). Editing a `PUBLISHED` policy mints a new `version_no` (service-managed) rather than mutating the frozen version. Access HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeavePolicyFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Leave policy updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeavePolicy"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "operationId": "org.leave_policy.delete",
        "summary": "Delete a leave policy",
        "tags": [
          "org",
          "leave-policy"
        ],
        "x-token": "org.leave_policy.delete",
        "x-realizes-features": [
          "ORG-F05"
        ],
        "x-screens": [
          "ORG-S06"
        ],
        "x-touches-entities": [
          "org.leave_policies"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Soft-delete a DRAFT or SUPERSEDED leave policy version from ORG-S06. A PUBLISHED policy returns 409 — publish a new version to supersede it first, then delete the superseded one. Also refused while balances were accrued, applications decided or encashments priced under it (dependent type and count are named in the problem detail). Access HR Admin. Requires a TENANT-scoped role: the dependency counts span `people.*`/`leave.*`, whose row-level ownership overlay hides rows from a narrower grant scope — so a role scoped to a legal entity or branch is refused with 403 rather than deleting on an incomplete count.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "204": {
            "description": "Leave policy deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/leave-policies/{id}/publish": {
      "post": {
        "operationId": "org.leave_policy.publish",
        "summary": "Publish a leave policy",
        "tags": [
          "org",
          "leave-policy"
        ],
        "x-token": "org.leave_policy.publish",
        "x-realizes-features": [
          "ORG-F05"
        ],
        "x-screens": [
          "ORG-S06"
        ],
        "x-touches-entities": [
          "org.leave_policies"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.leave_policy.published",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Publish policy → `status = PUBLISHED`, `published_at` set (fsd 01 ORG-S06). Consumed by `leave` (LVE-F01/F03), which stamps `version_no` onto the balance ledger so a later edit never re-accrues a frozen period (db 02 §1.4). An employee-facing \"policy updated\" notification rides `XC-F05`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "200": {
            "description": "Leave policy published.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeavePolicy"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/holiday-calendars": {
      "get": {
        "operationId": "org.holiday_calendar.list",
        "summary": "List holiday calendars",
        "tags": [
          "org",
          "holiday-calendar"
        ],
        "x-token": "org.holiday_calendar.list",
        "x-realizes-features": [
          "ORG-F05"
        ],
        "x-screens": [
          "ORG-S07",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.holiday_calendars"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Year picker + location filter (fsd 01 ORG-S07). Sort whitelist: `fiscal_year`, `calendar_code` (default `-fiscal_year`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "fiscal_year",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "work_location_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "DRAFT",
                "ACTIVE",
                "INACTIVE"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of holiday calendars.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HolidayCalendarListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "org.holiday_calendar.create",
        "summary": "Create a holiday calendar",
        "tags": [
          "org",
          "holiday-calendar"
        ],
        "x-token": "org.holiday_calendar.create",
        "x-realizes-features": [
          "ORG-F05"
        ],
        "x-screens": [
          "ORG-S07",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.holiday_calendars"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "+ Add holiday calendar (fsd 01 ORG-S07). Access HR Admin.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/HolidayCalendarFields"
                  },
                  {
                    "required": [
                      "legal_entity_id",
                      "calendar_code",
                      "name",
                      "fiscal_year"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Holiday calendar created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HolidayCalendar"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/holiday-calendars/{id}": {
      "get": {
        "operationId": "org.holiday_calendar.get",
        "summary": "Get a holiday calendar",
        "tags": [
          "org",
          "holiday-calendar"
        ],
        "x-token": "org.holiday_calendar.get",
        "x-realizes-features": [
          "ORG-F05"
        ],
        "x-screens": [
          "ORG-S07"
        ],
        "x-touches-entities": [
          "org.holiday_calendars"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Calendar grid + holiday list side-by-side (fsd 01 ORG-S07).",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "Holiday calendar.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HolidayCalendar"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "org.holiday_calendar.update",
        "summary": "Update a holiday calendar (add/edit/import holidays)",
        "tags": [
          "org",
          "holiday-calendar"
        ],
        "x-token": "org.holiday_calendar.update",
        "x-realizes-features": [
          "ORG-F05"
        ],
        "x-screens": [
          "ORG-S07"
        ],
        "x-touches-entities": [
          "org.holiday_calendars"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Add / Import holiday (CSV / govt API, preview before confirm) writes the full `holidays[]` array (fsd 01 ORG-S07); duplicate holiday dates warn, not block. Access HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HolidayCalendarFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Holiday calendar updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HolidayCalendar"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "operationId": "org.holiday_calendar.delete",
        "summary": "Delete a holiday calendar",
        "tags": [
          "org",
          "holiday-calendar"
        ],
        "x-token": "org.holiday_calendar.delete",
        "x-realizes-features": [
          "ORG-F05"
        ],
        "x-screens": [
          "ORG-S07"
        ],
        "x-touches-entities": [
          "org.holiday_calendars"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Soft-delete a DRAFT holiday calendar from ORG-S07. No table carries a `holiday_calendar_id` — calendars are resolved by (legal entity, fiscal year, work location) — so there is no dependent to count; the guard is the in-force state instead. An ACTIVE calendar returns 409. Access HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "204": {
            "description": "Holiday calendar deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/holiday-calendars/{id}/publish": {
      "post": {
        "operationId": "org.holiday_calendar.publish",
        "summary": "Publish a holiday calendar to employees",
        "tags": [
          "org",
          "holiday-calendar"
        ],
        "x-token": "org.holiday_calendar.publish",
        "x-realizes-features": [
          "ORG-F05"
        ],
        "x-screens": [
          "ORG-S07"
        ],
        "x-touches-entities": [
          "org.holiday_calendars"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.holiday_calendar.published",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Publish to employees → `status = ACTIVE` (fsd 01 ORG-S07); pushes a notification to all employees (`XC-F05`). Cannot un-publish — only add/delete individual holidays afterward via `update`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "200": {
            "description": "Holiday calendar published.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HolidayCalendar"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/pay-components": {
      "get": {
        "operationId": "org.pay_component.list",
        "summary": "List pay components",
        "tags": [
          "org",
          "pay-component"
        ],
        "x-token": "org.pay_component.list",
        "x-realizes-features": [
          "ORG-F06"
        ],
        "x-screens": [
          "ORG-S08",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "org.pay_components"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Components tab grid (fsd 01 ORG-S08); statutory lines are pack-driven and country-aware (India PF/ESIC/PT/TDS vs KSA GOSI). Sort whitelist: `component_code`, `component_type`, `created_at` (default `component_code`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "component_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "EARNING",
                "DEDUCTION",
                "EMPLOYER_CONTRIBUTION",
                "REIMBURSEMENT"
              ]
            }
          },
          {
            "name": "is_statutory",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "INACTIVE"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of pay components.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayComponentListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "org.pay_component.create",
        "summary": "Create a pay component",
        "tags": [
          "org",
          "pay-component"
        ],
        "x-token": "org.pay_component.create",
        "x-realizes-features": [
          "ORG-F06"
        ],
        "x-screens": [
          "ORG-S08"
        ],
        "x-touches-entities": [
          "org.pay_components"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "+ Add component drawer (fsd 01 ORG-S08). Access Finance, HR Admin.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/PayComponentFields"
                  },
                  {
                    "required": [
                      "legal_entity_id",
                      "component_code",
                      "name",
                      "component_type"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Pay component created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayComponent"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/pay-components/{id}": {
      "patch": {
        "operationId": "org.pay_component.update",
        "summary": "Update a pay component",
        "tags": [
          "org",
          "pay-component"
        ],
        "x-token": "org.pay_component.update",
        "x-realizes-features": [
          "ORG-F06"
        ],
        "x-screens": [
          "ORG-S08"
        ],
        "x-touches-entities": [
          "org.pay_components"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Save / drag-to-reorder on ORG-S08 Components tab. `show_on_payslip` hides employer-contribution lines (db 02 §1.4). Access Finance, HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PayComponentFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pay component updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayComponent"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/pay-structures": {
      "get": {
        "operationId": "org.pay_structure.list",
        "summary": "List pay structures",
        "tags": [
          "org",
          "pay-structure"
        ],
        "x-token": "org.pay_structure.list",
        "x-realizes-features": [
          "ORG-F06"
        ],
        "x-screens": [
          "ORG-S08"
        ],
        "x-touches-entities": [
          "org.pay_structures"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Structures tab grid (fsd 01 ORG-S08). Sort whitelist: `structure_code`, `version_no`, `created_at` (default `-version_no`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "grade_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "DRAFT",
                "PUBLISHED",
                "SUPERSEDED"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of pay structures.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayStructureListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "org.pay_structure.create",
        "summary": "Create a pay structure (draft)",
        "tags": [
          "org",
          "pay-structure"
        ],
        "x-token": "org.pay_structure.create",
        "x-realizes-features": [
          "ORG-F06"
        ],
        "x-screens": [
          "ORG-S08"
        ],
        "x-touches-entities": [
          "org.pay_structures"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Builder drawer with live payslip preview (fsd 01 ORG-S08); created `DRAFT`. Money is exact decimal, never float. Access Finance, HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/PayStructureFields"
                  },
                  {
                    "required": [
                      "legal_entity_id",
                      "structure_code",
                      "name",
                      "currency_code",
                      "frequency"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Pay structure created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayStructure"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/pay-structures/{id}": {
      "get": {
        "operationId": "org.pay_structure.get",
        "summary": "Get a pay structure",
        "tags": [
          "org",
          "pay-structure"
        ],
        "x-token": "org.pay_structure.get",
        "x-realizes-features": [
          "ORG-F06"
        ],
        "x-screens": [
          "ORG-S08"
        ],
        "x-touches-entities": [
          "org.pay_structures"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Structure builder detail — ordered component lines (fsd 01 ORG-S08).",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "Pay structure.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayStructure"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "org.pay_structure.update",
        "summary": "Update a pay structure (while DRAFT)",
        "tags": [
          "org",
          "pay-structure"
        ],
        "x-token": "org.pay_structure.update",
        "x-realizes-features": [
          "ORG-F06"
        ],
        "x-screens": [
          "ORG-S08"
        ],
        "x-touches-entities": [
          "org.pay_structures"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Save on the structure builder (fsd 01 ORG-S08); `components[].sequence` strictly increasing, `currency_code` = entity base currency (db 02 check constraints). Access Finance, HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PayStructureFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pay structure updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayStructure"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/pay-structures/{id}/publish": {
      "post": {
        "operationId": "org.pay_structure.publish",
        "summary": "Publish a pay structure",
        "tags": [
          "org",
          "pay-structure"
        ],
        "x-token": "org.pay_structure.publish",
        "x-realizes-features": [
          "ORG-F06"
        ],
        "x-screens": [
          "ORG-S08"
        ],
        "x-touches-entities": [
          "org.pay_structures"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.pay_structure.published",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Publish structure → `status = PUBLISHED`, `published_at` set, components frozen (fsd 01 ORG-S08); requires a non-empty `components[]`. Consumed by `pay` (PAY-F02/F04), which stamps `pay_structure_version` + the resolved component set onto each published payslip as an immutable snapshot (db 02 §1.4).\n\n**Fails closed on design-time validation** *(2026-08-14, `#574`)*. This operation re-runs `org.pay_structure.validate`'s check inside its own transaction — after the row is locked, so a concurrent `PATCH` cannot remove the absorber between the check and the transition — and refuses any `HARD` finding with `409 STATE_TRANSITION_INVALID` (\"This structure cannot publish: …\", naming each offending line). `SOFT` findings never block. The builder calls `.validate` first so the refusal arrives as the specific lines to fix rather than as a surprise, but skipping that call changes nothing about what can be published: this gate, not the builder's, is the guarantee.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "200": {
            "description": "Pay structure published.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayStructure"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/pay-structures/{id}/new-version": {
      "post": {
        "operationId": "org.pay_structure.new_version",
        "summary": "Branch a published pay structure into a new draft",
        "tags": [
          "org",
          "pay-structure"
        ],
        "x-token": "org.pay_structure.new_version",
        "x-realizes-features": [
          "ORG-F06"
        ],
        "x-screens": [
          "ORG-S08"
        ],
        "x-touches-entities": [
          "org.pay_structures"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "**Edit after publish** on ORG-S08. A `PUBLISHED` structure is immutable from the payslip's point of view — every payslip computed under it stamped its `pay_structure_version` and resolved component set as a snapshot (db 02 §1.4) — so amending one is never an UPDATE. This copies the source row's components into a fresh `DRAFT` at `version_no + 1`, leaving the published row untouched and every historical payslip still reconcilable against the structure it was actually computed from. The predecessor is superseded by `org.pay_structure.publish` on the new draft, not here.\n\nDistinct from `org.pay_structure.create`, which mints a structure_code that did not exist. This one cannot invent a code — it inherits the source's — and it is refused (`409`) on a source that is not `PUBLISHED`: branching a draft would produce two editable rows for one code. Access Finance, HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "201": {
            "description": "New DRAFT version created. The source structure is unchanged and still PUBLISHED.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayStructure"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/pay-structures/{id}/validate": {
      "post": {
        "operationId": "org.pay_structure.validate",
        "summary": "Validate a pay structure against the wage floor — live, in the builder",
        "tags": [
          "org",
          "pay-structure"
        ],
        "x-token": "org.pay_structure.validate",
        "x-realizes-features": [
          "ORG-F06",
          "PAY-F09"
        ],
        "x-screens": [
          "ORG-S08"
        ],
        "x-touches-entities": [
          "org.pay_structures",
          "org.pay_components",
          "org.statutory_config"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "**ADR 0029 §(d) step 5 — the Labour-Code 50 % wage floor, caught at design time.** Under the India Labour Codes (in force **21 November 2025**) \"wages\" must be at least **50 % of total remuneration**; where Basic + DA falls below that floor the shortfall is **added to Basic and funded by reducing a designated absorber component** — in practice Special Allowance — so total remuneration is unchanged and the split is corrected. The adjusted Basic then **cascades into every downstream statutory base**: PF wage, gratuity wage, bonus eligibility, overtime hourly rate, and leave-encashment rate all read the post-adjustment figure. That cascade is the whole point of the Labour Codes and the single most commonly mis-implemented rule in the Indian payroll market.\n\n**The absorber is a structure-design property, not a runtime choice.** A structure whose components cannot absorb a floor adjustment **fails validation here**, so the failure is caught by the person authoring the structure and never by the payroll manager on the 28th. This operation is called **live by the ORG-S08 builder** as components are edited — it is a pure read that computes findings and **writes nothing**, so calling it on a `DRAFT` or a `PUBLISHED` structure is equally safe and it never advances a lifecycle.\n\nFindings carry a severity and a component reference — see `PayStructureValidationFinding.code` for the vocabulary. A structure with no `HARD` findings is safe to publish; `SOFT` findings are advisory and do not block. Answering with findings is a `200`, not a `422` — an in-progress structure being incomplete is the normal state of a builder, not a protocol error.\n\n**This is a courtesy to the builder, not the guarantee.** `org.pay_structure.publish` **re-runs the same gate inside its own transaction, after the row is locked, and refuses on any `HARD` finding** with `409 STATE_TRANSITION_INVALID` (\"This structure cannot publish: …\"). Calling `.validate` first is what turns that refusal into the specific lines to fix before anything is sent; skipping it changes nothing about what can be published. The rules themselves live in ONE place — `packages/pay-calc`'s `validatePayStructure` — so the answer the builder shows and the answer publish enforces cannot drift.\n\nThe Labour-Code roles the check reads (`wage_role`, `is_wage_floor_absorber`, `is_wage_floor_anchor`, `counts_toward_remuneration`) are authored onto the structure's own `components[]` lines by this builder and stored in that jsonb — they are properties of a LINE of a structure version, not columns on the structure. Whether the floor applies at all is decided by the bound compliance pack's wage-floor section (ADR 0005, never a literal): a pack carrying none — every KSA pack, and every India pack still awaiting compliance ratification — yields no absorber findings, only the market-neutral design ones.\n\n**KSA scope has not been worked on at all in this wave.** The 50 % floor and its absorber mechanic are India Labour Code constructs resolved from the India compliance pack; no KSA wage-definition rule is implemented, and a structure under a KSA legal entity returns no floor findings rather than wrong ones. Access Finance, HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PayStructureValidateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Validation result — findings, and the resolved floor the structure was measured against.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayStructureValidationResult"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/pay-groups": {
      "get": {
        "operationId": "org.pay_group.list",
        "summary": "List pay groups",
        "tags": [
          "org",
          "pay-group"
        ],
        "x-token": "org.pay_group.list",
        "x-realizes-features": [
          "ORG-F06",
          "PAY-F09"
        ],
        "x-screens": [
          "ORG-S11"
        ],
        "x-touches-entities": [
          "org.pay_groups"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "**The population segment payroll has never had** (ADR 0028 §(a)) — one row per `(tenant, legal_entity, group)` carrying frequency, attendance-cycle anchor, cutoff day, pay day, proration basis, variance threshold and timezone. It exists because real operations customers run mixed populations *inside* one entity — monthly salaried on a calendar month, site labour on a 21st–20th cycle, piece-rate crews weekly — and a pay group is the smallest unit that actually varies. It replaces the `admin.tenant_config` `PAYROLL` `{cutoff_day, pay_day}` key, which is **deprecated and never read going forward**: one scalar pair per tenant cannot segment a population, cannot express a per-legal-entity calendar, and has no effective dating.\n\nEvery existing legal entity acquires one **`DEFAULT`** group at migration time (calendar-month cycle, `CALENDAR_DAYS` proration, cutoff/pay day lifted from `tenant_config` where present), so no tenant needs operator action to keep working. Sort whitelist: `name`, `effective_from`, `-effective_from` (default `name`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/PayGroupStatus"
            }
          },
          {
            "name": "effective_on",
            "in": "query",
            "required": false,
            "description": "Return the row effective on this date. Effective dating is a `[)` daterange with an exclusion constraint — overlapping rows are refused by the database, not by review.",
            "schema": {
              "$ref": "#/components/schemas/DateOnly"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of pay groups.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayGroupListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "org.pay_group.create",
        "summary": "Create a pay group",
        "tags": [
          "org",
          "pay-group"
        ],
        "x-token": "org.pay_group.create",
        "x-realizes-features": [
          "ORG-F06",
          "PAY-F09"
        ],
        "x-screens": [
          "ORG-S11"
        ],
        "x-touches-entities": [
          "org.pay_groups"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Creating a group opens a new effective-dated row; the `pay.generate_pay_periods` cron job then maintains its rolling 12-month period horizon, idempotently. `pay_frequency` reuses the existing `pay.pay_frequency` enum but **v1 accepts `MONTHLY` only** (`422` otherwise) — the other members are reserved and the enum is append-extensible for `SEMI_MONTHLY`/`DAILY` later. Access Finance, HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/PayGroupFields"
                  },
                  {
                    "required": [
                      "pay_group_code",
                      "legal_entity_id",
                      "name",
                      "pay_frequency",
                      "attendance_cycle_anchor",
                      "cutoff_day",
                      "pay_day",
                      "timezone",
                      "effective_from"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Pay group created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayGroup"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/pay-groups/{id}": {
      "get": {
        "operationId": "org.pay_group.get",
        "summary": "Get a pay group",
        "tags": [
          "org",
          "pay-group"
        ],
        "x-token": "org.pay_group.get",
        "x-realizes-features": [
          "ORG-F06",
          "PAY-F09"
        ],
        "x-screens": [
          "ORG-S11"
        ],
        "x-touches-entities": [
          "org.pay_groups"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "One effective-dated pay group with its cycle anchor, cutoff, pay day, proration basis and variance threshold.",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "The pay group.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayGroup"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "org.pay_group.update",
        "summary": "Update a pay group (opens a new effective-dated row for cycle-shaping fields)",
        "tags": [
          "org",
          "pay-group"
        ],
        "x-token": "org.pay_group.update",
        "x-realizes-features": [
          "ORG-F06",
          "PAY-F09"
        ],
        "x-screens": [
          "ORG-S11"
        ],
        "x-touches-entities": [
          "org.pay_groups"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Cosmetic fields (`name`, `variance_flag_threshold_pct`, `status`) update in place. Changing anything that **shapes a cycle** — `attendance_cycle_anchor`, `anchor_day`, `cutoff_day`, `pay_day`, `pay_date_shift_rule`, `proration_basis`, `timezone` — requires an `effective_from` and **opens a new row** rather than editing the live one: a silent edit would retro-rewrite the meaning of months that are already closed and paid. Supplying such a field without `effective_from` is a `422`. Access Finance, HR Admin. `pay_group_code` is required on creation and immutable thereafter; supplying it on this operation is a `422`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PayGroupFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pay group updated (or superseded by a new effective-dated row).",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayGroup"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/rate-cards": {
      "get": {
        "operationId": "org.rate_card.list",
        "summary": "List daily-wage rate cards",
        "tags": [
          "org",
          "rate-card"
        ],
        "x-token": "org.rate_card.list",
        "x-realizes-features": [
          "ORG-F06",
          "PAY-F10"
        ],
        "x-screens": [
          "ORG-S12"
        ],
        "x-touches-entities": [
          "org.rate_cards"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "`org.rate_cards` (ADR 0033 §(b)) — one row per `(legal_entity_id, name, skill_category, state_code)` with a `daily_rate` and effective dates, **superseded rather than edited**. `skill_category` and `state_code` exist because that is the shape the statutory minimum-wage schedules themselves take (unskilled / semi-skilled / skilled / highly-skilled, per state, per zone), so a tenant's own card can be compared to the applicable floor **without a translation step**.\n\nThe floor itself is **compliance-pack content, never a tenant table** (ADR 0033 §(d)): it is government-published, identical for every tenant, and a number a payroll must be able to *prove* it used. A mutable table would let an operator lower the floor that protects the worker, and would leave a recomputed historical run unable to recover the rate that was in force. What the jurisdiction says is pack; what the employer chooses is this table. Sort whitelist: `name`, `skill_category`, `effective_from`, `-effective_from` (default `name`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "skill_category",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/SkillCategory"
            }
          },
          {
            "name": "state_code",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "effective_on",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/DateOnly"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of rate cards.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateCardListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "org.rate_card.create",
        "summary": "Create a daily-wage rate card",
        "tags": [
          "org",
          "rate-card"
        ],
        "x-token": "org.rate_card.create",
        "x-realizes-features": [
          "ORG-F06",
          "PAY-F10"
        ],
        "x-screens": [
          "ORG-S12"
        ],
        "x-touches-entities": [
          "org.rate_cards"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Authoring surface on ORG-S12, shown **beside the read-only minimum-wage schedule resolved from the active compliance pack** so an admin authoring a card below the statutory floor sees it at authoring time rather than at the first payslip. The pack view is deliberately read-only — the floor is not a control an operator gets to override from a screen. `daily_rate` is exact decimal, never float. Access Finance, HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/RateCardFields"
                  },
                  {
                    "required": [
                      "legal_entity_id",
                      "rate_card_code",
                      "name",
                      "skill_category",
                      "state_code",
                      "daily_rate",
                      "effective_from"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Rate card created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateCard"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/rate-cards/{id}": {
      "get": {
        "operationId": "org.rate_card.get",
        "summary": "Get a rate card",
        "tags": [
          "org",
          "rate-card"
        ],
        "x-token": "org.rate_card.get",
        "x-realizes-features": [
          "ORG-F06",
          "PAY-F10"
        ],
        "x-screens": [
          "ORG-S12"
        ],
        "x-touches-entities": [
          "org.rate_cards"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "One effective-dated rate card, with the pack-resolved minimum-wage floor applicable to its `(state_code, skill_category)` shown alongside for comparison.",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "The rate card.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateCard"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "org.rate_card.update",
        "summary": "Update a rate card (a rate change supersedes, never edits)",
        "tags": [
          "org",
          "rate-card"
        ],
        "x-token": "org.rate_card.update",
        "x-realizes-features": [
          "ORG-F06",
          "PAY-F10"
        ],
        "x-screens": [
          "ORG-S12"
        ],
        "x-touches-entities": [
          "org.rate_cards"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "`name` and `status` update in place. Changing `daily_rate`, `skill_category` or `state_code` requires an `effective_from` and **supersedes the row** — a rate edited in place would silently reprice a period that was already paid, and would leave a recomputed historical run unable to recover the rate actually in force. Access Finance, HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RateCardFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Rate card updated (or superseded by a new effective-dated row).",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateCard"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/piece-rate-catalogs": {
      "get": {
        "operationId": "org.piece_rate_catalog.list",
        "summary": "List piece-rate catalogues",
        "tags": [
          "org",
          "piece-rate-catalog"
        ],
        "x-token": "org.piece_rate_catalog.list",
        "x-realizes-features": [
          "ORG-F06",
          "PAY-F10"
        ],
        "x-screens": [
          "ORG-S12"
        ],
        "x-touches-entities": [
          "org.piece_rate_catalogs",
          "org.piece_rate_items"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "`org.piece_rate_catalogs` (ADR 0033 §(c)) — the named, effective-dated set an employee's compensation row binds to. Its **items** are the priced units: a stable `unit_code`, a **locale-keyed `unit_name`** (`{ en, ar }`, because these strings reach a payslip an Arabic-reading worker may open), `rate_per_unit`, and effective dates. `unit_code` is exactly what `attend.muster_entries.units_done` is recorded against, so the capture surface and the pricing surface share **one vocabulary** and need no translation step. Sort whitelist: `name`, `effective_from`, `-effective_from` (default `name`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "effective_on",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/DateOnly"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of piece-rate catalogues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PieceRateCatalogListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "org.piece_rate_catalog.create",
        "summary": "Create a piece-rate catalogue with its priced units",
        "tags": [
          "org",
          "piece-rate-catalog"
        ],
        "x-token": "org.piece_rate_catalog.create",
        "x-realizes-features": [
          "ORG-F06",
          "PAY-F10"
        ],
        "x-screens": [
          "ORG-S12"
        ],
        "x-touches-entities": [
          "org.piece_rate_catalogs",
          "org.piece_rate_items"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Catalogue + items authored together on ORG-S12. All units and rates are **decimal, never floating point**: `units_done` arrives from `attend.muster_entries` as a decimal string and stays one all the way through pricing. Piece earnings are floored at `min_wage_daily × payable_days` at computation time, and **the top-up is an explicit `MINIMUM_WAGE_TOP_UP` earning line, never a silent adjustment** (ADR 0033 §(e)) — a worker who produced less than the floor must be able to see that the law, not their employer's generosity, put the number where it is. Access Finance, HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/PieceRateCatalogFields"
                  },
                  {
                    "required": [
                      "legal_entity_id",
                      "catalog_code",
                      "name",
                      "effective_from",
                      "items"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Catalogue created with its items.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PieceRateCatalog"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/piece-rate-catalogs/{id}": {
      "get": {
        "operationId": "org.piece_rate_catalog.get",
        "summary": "Get a piece-rate catalogue with its items",
        "tags": [
          "org",
          "piece-rate-catalog"
        ],
        "x-token": "org.piece_rate_catalog.get",
        "x-realizes-features": [
          "ORG-F06",
          "PAY-F10"
        ],
        "x-screens": [
          "ORG-S12"
        ],
        "x-touches-entities": [
          "org.piece_rate_catalogs",
          "org.piece_rate_items"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "The catalogue and its priced units, each with its own effective dates.",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "The catalogue.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PieceRateCatalog"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "org.piece_rate_catalog.update",
        "summary": "Update a piece-rate catalogue (a price change supersedes the item, never edits it)",
        "tags": [
          "org",
          "piece-rate-catalog"
        ],
        "x-token": "org.piece_rate_catalog.update",
        "x-realizes-features": [
          "ORG-F06",
          "PAY-F10"
        ],
        "x-screens": [
          "ORG-S12"
        ],
        "x-touches-entities": [
          "org.piece_rate_catalogs",
          "org.piece_rate_items"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "`name`, `status` and `unit_name` translations update in place. Changing a `rate_per_unit` requires an `effective_from` and **supersedes that item** — units already captured and priced under the old rate stay priced under it, which is the whole point of dating the catalogue. A unit is retired with `status: INACTIVE`, never by omission: the code is the vocabulary muster capture uses, so vanishing it silently would orphan captured units. (The stricter rule — a `409` when muster entries still reference the code — arrives with `attend.muster_entries` itself, which `ATT-S20` has not yet landed.) An `ACTIVE` catalogue must keep at least one `ACTIVE` unit, enforced here rather than in the database because items are a child table. Access Finance, HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PieceRateCatalogFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Catalogue updated (priced items superseded where a rate changed).",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PieceRateCatalog"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/statutory-configs": {
      "get": {
        "operationId": "org.statutory_config.list",
        "summary": "List statutory configs",
        "tags": [
          "org",
          "statutory-config"
        ],
        "x-token": "org.statutory_config.list",
        "x-realizes-features": [
          "ORG-F07"
        ],
        "x-screens": [
          "ORG-S09"
        ],
        "x-touches-entities": [
          "org.statutory_config"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Country-filtered integration-card grid (fsd 01 ORG-S09) — India EPFO/ESIC/PT/TDS, KSA GOSI/WPS/Mudad. Sort whitelist: `statute`, `created_at` (default `statute`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "statute",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "EPFO",
                "ESIC",
                "PT",
                "TDS",
                "GOSI",
                "WPS",
                "MUDAD"
              ]
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "DRAFT",
                "PUBLISHED",
                "SUPERSEDED"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of statutory configs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatutoryConfigListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "org.statutory_config.create",
        "summary": "Create a statutory config",
        "tags": [
          "org",
          "statutory-config"
        ],
        "x-token": "org.statutory_config.create",
        "x-realizes-features": [
          "ORG-F07"
        ],
        "x-screens": [
          "ORG-S09"
        ],
        "x-touches-entities": [
          "org.statutory_config"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Configure drawer registration parameters (fsd 01 ORG-S09); `statute` must be consistent with the entity's `market` (db 02 check). `credential_ref` is write-only — the secret itself lives in the platform secret store (`XC-F02`), never in this DB. Access Super Admin / Finance Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/StatutoryConfigFields"
                  },
                  {
                    "required": [
                      "legal_entity_id",
                      "statute",
                      "effective_from"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Statutory config created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatutoryConfig"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/statutory-configs/{id}": {
      "get": {
        "operationId": "org.statutory_config.get",
        "summary": "Get a statutory config",
        "tags": [
          "org",
          "statutory-config"
        ],
        "x-token": "org.statutory_config.get",
        "x-realizes-features": [
          "ORG-F07"
        ],
        "x-screens": [
          "ORG-S09"
        ],
        "x-touches-entities": [
          "org.statutory_config"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Configure drawer detail — parameters, connection status, last sync (fsd 01 ORG-S09).",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "Statutory config.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatutoryConfig"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "org.statutory_config.update",
        "summary": "Update a statutory config (while DRAFT)",
        "tags": [
          "org",
          "statutory-config"
        ],
        "x-token": "org.statutory_config.update",
        "x-realizes-features": [
          "ORG-F07"
        ],
        "x-screens": [
          "ORG-S09"
        ],
        "x-touches-entities": [
          "org.statutory_config"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Save on ORG-S09 Configure drawer. Access Super Admin / Finance Admin (privileged; reads audited).",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StatutoryConfigFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Statutory config updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatutoryConfig"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "operationId": "org.statutory_config.delete",
        "summary": "Delete a statutory config (while DRAFT)",
        "tags": [
          "org",
          "statutory-config"
        ],
        "x-token": "org.statutory_config.delete",
        "x-realizes-features": [
          "ORG-F07"
        ],
        "x-screens": [
          "ORG-S09"
        ],
        "x-touches-entities": [
          "org.statutory_config"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Delete/deactivate a draft statutory registration on ORG-S09. Access Super Admin / HR Admin.",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "204": {
            "description": "Statutory config deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/statutory-configs/{id}/publish": {
      "post": {
        "operationId": "org.statutory_config.publish",
        "summary": "Publish a statutory config",
        "tags": [
          "org",
          "statutory-config"
        ],
        "x-token": "org.statutory_config.publish",
        "x-realizes-features": [
          "ORG-F07"
        ],
        "x-screens": [
          "ORG-S09"
        ],
        "x-touches-entities": [
          "org.statutory_config"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.statutory_config.published",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Publish config → `status = PUBLISHED` (fsd 01 ORG-S09). Any other `PUBLISHED` config for the same legal entity, statute and location is superseded in the same write. This does NOT mint a new `version_no` — that counter advances only on `create` (`GAP-19`); publish bumps the row's optimistic-lock `version` like any other mutation, so its `ETag` changes across the transition. Consumed by `pay` (PAY-F02 — deductions) and `comply` (CMP-F01/F02 — filings), which stamp the effective parameters onto published payslips/filings (db 02 §1.5).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "200": {
            "description": "Statutory config published.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatutoryConfig"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/statutory-configs/{id}/test-connection": {
      "post": {
        "operationId": "org.statutory_config.test_connection",
        "summary": "Test / sync the statutory portal connection",
        "tags": [
          "org",
          "statutory-config"
        ],
        "x-token": "org.statutory_config.test_connection",
        "x-realizes-features": [
          "ORG-F07"
        ],
        "x-screens": [
          "ORG-S09"
        ],
        "x-touches-entities": [
          "org.statutory_config"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "async",
        "x-emits-event": "org.statutory_config.sync_completed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Test / Sync CTA on the integration card (fsd 01 ORG-S09); runs on the jobs tier (`XC-F08`) using the `credential_ref` secret (`XC-F02`) and updates `integration_status`/`last_sync_*` — mutable runtime state, **no new `version_no`** (db 02 §1.5). A `FAILED`/`EXPIRING` result raises a compliance alert surfaced on `ADM-S01`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "202": {
            "description": "Test/Sync queued on the jobs tier.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatutoryConfigSyncJob"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/templates": {
      "get": {
        "operationId": "org.template.list",
        "summary": "List templates",
        "tags": [
          "org",
          "template"
        ],
        "x-token": "org.template.list",
        "x-realizes-features": [
          "ORG-F08"
        ],
        "x-screens": [
          "ORG-S10"
        ],
        "x-touches-entities": [
          "org.templates"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Searchable, category-filtered template list (fsd 01 ORG-S10). Sort whitelist: `template_code`, `kind`, `created_at` (default `template_code`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "LETTER",
                "POLICY",
                "NOTIFICATION",
                "EMAIL"
              ]
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "DRAFT",
                "PUBLISHED",
                "SUPERSEDED"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of templates.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "org.template.create",
        "summary": "Create a template (draft)",
        "tags": [
          "org",
          "template"
        ],
        "x-token": "org.template.create",
        "x-realizes-features": [
          "ORG-F08"
        ],
        "x-screens": [
          "ORG-S10"
        ],
        "x-touches-entities": [
          "org.templates"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "New-template modal (fsd 01 ORG-S10); this is the **authoring surface** — `docs`/`engage`/notifications render `ref→org.templates` and never write here. Access HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/TemplateFields"
                  },
                  {
                    "required": [
                      "template_code",
                      "kind",
                      "bodies",
                      "variables"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Template created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/templates/restore-defaults": {
      "post": {
        "operationId": "org.template.restore_defaults",
        "summary": "Restore every missing default template",
        "tags": [
          "org",
          "template"
        ],
        "x-token": "org.template.restore_defaults",
        "x-realizes-features": [
          "ORG-F08"
        ],
        "x-screens": [
          "ORG-S10"
        ],
        "x-touches-entities": [
          "org.templates"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "`G-19`⑤ closure (default-template concept + Restore action, issue #865): insert every entry of the default catalogue (`@groundit/db` `TEMPLATE_DEFAULTS`) the tenant currently has no row for — tenant-wide (`legal_entity_id = null`), `PUBLISHED`, `is_seeded_default = true`. **Insert-if- absent on `seed_key`, not upsert** — a tenant that has edited or deleted its copy of a default is never reset by this call, so it is safe to run repeatedly (the same idempotency `org.legal_entity.apply_pack_defaults` gives the pack-defaults baseline). Access HR Admin.\n",
        "responses": {
          "200": {
            "description": "Restore pass complete; the per-`seed_key` outcome list reports what happened.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateRestoreDefaultsResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/templates/{id}": {
      "get": {
        "operationId": "org.template.get",
        "summary": "Get a template",
        "tags": [
          "org",
          "template"
        ],
        "x-token": "org.template.get",
        "x-realizes-features": [
          "ORG-F08"
        ],
        "x-screens": [
          "ORG-S10"
        ],
        "x-touches-entities": [
          "org.templates"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Rich-text editor + token picker + live preview (fsd 01 ORG-S10). The `ETag` is `\"v<version>\"` off `org.templates.version`, the row's optimistic-lock counter — send it back as `If-Match` on the `PATCH` and on `publish`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "Template.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "org.template.update",
        "summary": "Update a template (while DRAFT)",
        "tags": [
          "org",
          "template"
        ],
        "x-token": "org.template.update",
        "x-realizes-features": [
          "ORG-F08"
        ],
        "x-screens": [
          "ORG-S10"
        ],
        "x-touches-entities": [
          "org.templates"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Save on the template editor; placeholder tokens in `bodies` must resolve against `variables` (validated at publish, fsd 01 ORG-S10). Refused unless the row is `DRAFT`. Access HR Admin. **The `If-Match` precondition is enforced (`GAP-17`① closed, 2026-07-29).** Absent header → `428`; a value that is not an `\"v<n>\"` ETag → `422`; an ETag that no longer matches `org.templates.version` → `412`, evaluated as a predicate on the UPDATE itself so a write landing between a client's read and its save cannot be lost. A successful save increments `version` and answers the new `ETag`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TemplateFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Template updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "operationId": "org.template.delete",
        "summary": "Delete a draft template",
        "tags": [
          "org",
          "template"
        ],
        "x-token": "org.template.delete",
        "x-realizes-features": [
          "ORG-F08"
        ],
        "x-screens": [
          "ORG-S10"
        ],
        "x-touches-entities": [
          "org.templates"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Hard-delete a `DRAFT` template (issue #865). Refused with **409** in three cases, checked in order: (1) a **default template** (`is_seeded_default` or a non-null `seed_key`) — the problem detail names the `seed_key` and points at `org.template.restore` as the intended action instead of deletion; (2) an **in-use** template — every nonzero dependent count is named together in the problem detail (`org.template_renders`, `people.onboarding_flows`, `recruit.refusal_reasons`, `recruit.offer_letters`, `docs.letters`, `xc.mail_messages`), so the caller sees the whole shape of what to unpick, not just the first hit; (3) a **non-`DRAFT`** row — `PUBLISHED`/`SUPERSEDED` templates are immutable at the database layer (`org.protect_published_template()`, migration 0042/0117); create and publish a new draft instead. Access HR Admin. The `If-Match` precondition is enforced exactly as `update`/`publish`: absent header → `428`, malformed → `422`, a stale version → `412`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "204": {
            "description": "Template deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/templates/{id}/publish": {
      "post": {
        "operationId": "org.template.publish",
        "summary": "Publish a template",
        "tags": [
          "org",
          "template"
        ],
        "x-token": "org.template.publish",
        "x-realizes-features": [
          "ORG-F08"
        ],
        "x-screens": [
          "ORG-S10"
        ],
        "x-touches-entities": [
          "org.templates"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.template.published",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Publish → `status = PUBLISHED`, and any OTHER `PUBLISHED` row with the same `template_code` becomes `SUPERSEDED`. A generated `docs.letters` row stamps this `version_no` so the rendered artifact is reproducible (db 02 §1.5). **`version_no` is assigned at CREATE, not here** (`GAP-17`③/`G-19`③ — the FSD/design-doc correction landed 2026-07-29; this line states the as-built behaviour plainly rather than carrying the residual claim). `version_no` is `max(version_no) + 1` for the code at the moment `POST /templates` runs; because `PATCH` is refused for any non-`DRAFT` status, the only way to reach a new version is to create a new draft under the same code — publish flips this row's `status` and its siblings', nothing more. Publish is also refused unless the row is `DRAFT` (a `PUBLISHED` row returns unchanged). **Refuses `422` (naming the field) rather than publishing something no consumer could render** (`GAP-17`⑤/`G-19`⑥ and the `subjects` half of the same closure, 2026-08-13): no locale has a non-blank body, a locale's body is whitespace-only, an `EMAIL` template (or a `NOTIFICATION` on the `EMAIL` channel) carries no `subjects` entry, or a `{{token}}` in either `bodies` or `subjects` is undeclared in `variables`. **The `If-Match` precondition is enforced (`GAP-17`① closed, 2026-07-29)**, with the same `428`/`422`/`412` mapping as the `PATCH`: publishing is the irreversible action, so a caller holding a stale ETag would otherwise publish a body it has never seen. Both the published row and the sibling rows this call moves to `SUPERSEDED` have their `version` incremented, so no ETag taken before a publish stays usable afterwards. The already-`PUBLISHED` replay still answers `200`, but only for a matching ETag.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "200": {
            "description": "Template published.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/templates/{id}/restore-default": {
      "post": {
        "operationId": "org.template.restore",
        "summary": "Restore one template to its default-catalogue content",
        "tags": [
          "org",
          "template"
        ],
        "x-token": "org.template.restore",
        "x-realizes-features": [
          "ORG-F08"
        ],
        "x-screens": [
          "ORG-S10"
        ],
        "x-touches-entities": [
          "org.templates"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "org.config.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "`G-19`⑤ closure (issue #865). Resolves the targeted row's own `seed_key` against the default catalogue and restores its `bodies`/`subjects`/`variables`. **409** when the row has no `seed_key` — it was never a default, so there is nothing to restore it to. Behaviour is dictated by `org.protect_published_template()`'s immutability, not chosen freely: a **`DRAFT`** row is updated in place (re-flagged `is_seeded_default = true`) and the response's `new_draft_created` is `false`. A **`PUBLISHED`/`SUPERSEDED`** row is immutable — the trigger refuses any content `UPDATE` — so this instead INSERTs a **new `DRAFT`** under the same `template_code` at `max(version_no) + 1`, carrying the same `seed_key` and the catalogue content; `new_draft_created` is `true` and `template` describes the NEW draft, not the row named in the path, which is never touched. **Publish the new draft to make it live** — this operation never publishes on the caller's behalf. Access HR Admin. `If-Match` targets the row named in the path in both cases (even the branch that writes a different row): `428` absent, `422` malformed, `412` stale.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "200": {
            "description": "Restored. `new_draft_created` says whether `template` is the row named in the path (updated in place) or a new draft under the same code (the row named in the path was immutable).\n",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateRestoreOneResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/templates/{id}/send-test": {
      "post": {
        "operationId": "org.template.send_test",
        "summary": "Send a test render of a template",
        "tags": [
          "org",
          "template"
        ],
        "x-token": "org.template.send_test",
        "x-realizes-features": [
          "ORG-F08"
        ],
        "x-screens": [
          "ORG-S10"
        ],
        "x-touches-entities": [
          "org.templates"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "async",
        "x-emits-event": "xc.email.requested",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Send test action (fsd 01 ORG-S10) — renders the template with sample data, wraps it in the branded HTML shell (mail leg 5, ADR 0038), and queues it as a real outbound mail. Does not persist a template change. **`GAP-17`②/design `G-19`② CLOSED.** Before 2026-08-13 this handler dispatched nothing — it interpolated the body and answered a literal `status: 'DISPATCHED_STUB'`. It now renders the body via `mergeTemplateBody`, resolves the locale's subject (falling back through `en` to the template code for a `LETTER`, which has no subject line), wraps both via `wrapBrandedEmail` with the tenant's own branding, and — in one transaction — INSERTs a `QUEUED` `xc.mail_messages` row and emits the `xc.email.requested` outbox event that wakes the jobs-tier dispatcher (`apps/jobs/src/jobs/mail-jobs.ts`). **The API tier never opens a socket to a mail host itself** (ADR 0038 / api-docs/08 §14.8 SSRF posture) — this operation only ever queues; delivery is the dispatcher's job. Answers **202**, and consumers must not treat it as proof of delivery — poll `admin.email_settings.list_status`, filtering on the returned `mail_message_id`, for that.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TemplateSendTestRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Test send queued. Nothing is delivered yet — poll the mail-deliveries surface.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateSendTestResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/templates/{id}/render": {
      "post": {
        "operationId": "org.template.render",
        "summary": "Render a template to PDF",
        "tags": [
          "org",
          "template"
        ],
        "x-token": "org.template.render",
        "x-realizes-features": [
          "ORG-F08"
        ],
        "x-screens": [
          "ORG-S10"
        ],
        "x-touches-entities": [
          "org.templates",
          "org.template_renders"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "async",
        "x-emits-event": "org.template_render.requested",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Queue a **server-side PDF render** of this template's saved body for one locale, merging the caller-supplied values into its declared `{{variables}}` (ADR 0023, issue #371). Answers **202**: the bytes are produced by the jobs tier, and the returned `TemplateRender` is `QUEUED` — poll `org.template.render_status` for the outcome and the download link. **Validated synchronously, so a 202 is honest.** `400` is returned for an unknown locale body, a locale this renderer cannot typeset, a missing required variable value, a placeholder that would survive the merge, or a value over the 4 KB cap. Only a request that could succeed becomes a job. **`locale` is restricted to the renderer's supported set (`en` today).** The in-product renderer draws with the PDF standard-14 fonts, which cannot represent Arabic, and performs no bidirectional reordering; an `ar` render is refused rather than typeset incorrectly. ADR 0023 §Consequences records this and the two exits (an embedded Unicode font + bidi stack, or the Wave-2 platform doc-generation service — ADR 0020, issue #272). **PII.** `variableValues` are the contents of a letter. They are persisted only on the FORCE-RLS'd `org.template_renders` row, are never echoed in a response, never enter the emitted event's payload, and are cleared when the render completes (migration `0063`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TemplateRenderRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Render accepted and queued. Nothing is downloadable yet: `status` is `QUEUED` and `downloadUrl` is absent. Poll `GET /templates/{id}/renders/{renderId}`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateRender"
                }
              }
            }
          },
          "400": {
            "description": "The render could never succeed as requested — unsupported locale, no body for the locale, a missing required variable value, a placeholder that would survive the merge, or an over-cap value. No job is queued.\n",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblem"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "description": "This workspace already has 25 renders `QUEUED` or `RUNNING`. Rendering is CPU-bound and the outbox is drained without per-tenant fairness, so the in-flight count is capped per tenant rather than letting one workspace monopolise the worker tier. Retry after the `Retry-After` interval, once an earlier render settles.\n",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/templates/{id}/renders/{renderId}": {
      "get": {
        "operationId": "org.template.render_status",
        "summary": "Read the status of a template render",
        "tags": [
          "org",
          "template"
        ],
        "x-token": "org.template.render_status",
        "x-realizes-features": [
          "ORG-F08"
        ],
        "x-screens": [
          "ORG-S10"
        ],
        "x-touches-entities": [
          "org.template_renders"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "The poll behind `org.template.render`'s 202 (ADR 0023). `status` walks `QUEUED → RUNNING → COMPLETED | FAILED`. Once `COMPLETED`, the response carries a **presigned `downloadUrl` minted per call and valid for 15 minutes** (`expiresAt` states when it lapses) — the API never proxies document bytes, matching `pay.payslip.download`. A `FAILED` render carries a machine-prefixed `error` (`UNSUPPORTED_LOCALE`, `TIMEOUT`, `OUTPUT_TOO_LARGE`, `ENGINE_FAILURE`, `INVALID_INPUT`) and no `downloadUrl`; it never reports success with nothing attached. The read is scoped to BOTH the template in the path and the render id, so a render cannot be read through a different template's URL. **This operation exists as a separate token only because `operationId` IS the permission token** (ADR 0015) — two operations cannot share one. It carries the same role grant as `org.template.render`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "renderId",
            "in": "path",
            "required": true,
            "description": "The `org.template_renders.id` returned by `org.template.render`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The render's current state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateRender"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/admin-dashboard": {
      "get": {
        "operationId": "admin.dashboard.get",
        "summary": "Get the role-aware admin dashboard projection",
        "tags": [
          "admin",
          "dashboard"
        ],
        "x-token": "admin.dashboard.get",
        "x-realizes-features": [
          "ADM-F03",
          "XC-F09"
        ],
        "x-screens": [
          "ADM-S01"
        ],
        "x-touches-entities": [
          "org.statutory_config"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "team",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Headcount, hiring, compliance health, payroll status, pending approvals, and active alerts as a **read-only projection** (fsd 01 ADM-S01) — no `org`/`admin` table backs it; every value reads a reporting projection (`XC-F15`) over `people`/`recruit`/`comply`/`pay`/`leave`, plus `org` statutory-integration health and `ref→audit.audit_log` for the activity feed. Tiles are role-filtered — a Manager sees only in-scope KPIs (`XC-F04`).\n",
        "responses": {
          "200": {
            "description": "Dashboard projection.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DashboardProjection"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/role-catalog": {
      "get": {
        "operationId": "admin.role_catalog.list",
        "summary": "List the platform-aligned role catalogue",
        "tags": [
          "admin",
          "role"
        ],
        "x-token": "admin.role_catalog.list",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "ADM-S02"
        ],
        "x-touches-entities": [
          "admin.role_catalog"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Catalogue-identity picker on the role editor (fsd 01 ADM-S02); `default_permissions` seeds the matrix when a role instances a catalogue entry. Sort whitelist: `catalog_key` (default `catalog_key`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "DEPRECATED"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of role-catalogue entries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoleCatalogListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/roles": {
      "get": {
        "operationId": "admin.role.list",
        "summary": "List roles",
        "tags": [
          "admin",
          "role"
        ],
        "x-token": "admin.role.list",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "ADM-S02",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "admin.roles"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Left role list (built-in roles lock-iconed) on the permission matrix (fsd 01 ADM-S02). Sort whitelist: `role_key`, `created_at` (default `role_key`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "scope_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "PLATFORM",
                "TENANT",
                "LEGAL_ENTITY",
                "ORG_UNIT",
                "BRANCH",
                "SELF"
              ]
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "INACTIVE"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of roles.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoleListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "admin.role.create",
        "summary": "Create a role",
        "tags": [
          "admin",
          "role"
        ],
        "x-token": "admin.role.create",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "ADM-S02"
        ],
        "x-touches-entities": [
          "admin.roles"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "+ Add custom role (fsd 01 ADM-S02); `scope_type = PLATFORM` permitted only on `is_system` roles (db 02 check). Published to the platform (`/platform/roles`, `/platform/role-catalog`) which maps principals to roles (`XC-F02`/`XC-F04`). Access Super Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/RoleFields"
                  },
                  {
                    "required": [
                      "role_key",
                      "name",
                      "scope_type"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Role created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Role"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/roles/{id}": {
      "get": {
        "operationId": "admin.role.get",
        "summary": "Get a role",
        "tags": [
          "admin",
          "role"
        ],
        "x-token": "admin.role.get",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "ADM-S02"
        ],
        "x-touches-entities": [
          "admin.roles"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Role detail for the permission matrix (fsd 01 ADM-S02).",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "Role.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Role"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "admin.role.update",
        "summary": "Update a role",
        "tags": [
          "admin",
          "role"
        ],
        "x-token": "admin.role.update",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "ADM-S02"
        ],
        "x-touches-entities": [
          "admin.roles"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Save role (name/scope/status) on ADM-S02 (fsd 01); `is_system` roles are read-only to tenant admins (db 02 check) — service rejects with 403. Access Super Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RoleFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Role updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Role"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/roles/{id}/duplicate": {
      "post": {
        "operationId": "admin.role.duplicate",
        "summary": "Copy a role's permission set into a new role",
        "tags": [
          "admin",
          "role"
        ],
        "x-token": "admin.role.duplicate",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "ADM-S02"
        ],
        "x-touches-entities": [
          "admin.roles",
          "admin.role_permissions"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Copy role action on the matrix (fsd 01 ADM-S02) — duplicates the permission set. Access Super Admin.",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RoleDuplicateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Role duplicated.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Role"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/permissions": {
      "get": {
        "operationId": "admin.permission.list",
        "summary": "List the tenant-visible permission catalogue",
        "tags": [
          "admin",
          "permission"
        ],
        "x-token": "admin.permission.list",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "ADM-S02"
        ],
        "x-touches-entities": [
          "admin.permissions"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "The matrix column set (fsd 01 ADM-S02) — `<module>.<entity>.<action>` tokens (db 02 §2.1 `permissions`). The authoritative token catalogue and resolution semantics are owned by the Security/RBAC set; this is the tenant-visible read. Sort whitelist: `permission_key`, `module` (default `module`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "module",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "DEPRECATED"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of permissions.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PermissionListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/roles/{id}/permissions": {
      "get": {
        "operationId": "admin.role_permission.list",
        "summary": "List a role's granted permissions",
        "tags": [
          "admin",
          "role"
        ],
        "x-token": "admin.role_permission.list",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "ADM-S02"
        ],
        "x-touches-entities": [
          "admin.role_permissions"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "The checked cells for a matrix row (fsd 01 ADM-S02). Sort whitelist: `created_at` (default `created_at`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Page of role-permission grants.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RolePermissionListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "admin.role_permission.replace",
        "summary": "Replace a role's granted permission set (matrix Save)",
        "tags": [
          "admin",
          "role"
        ],
        "x-token": "admin.role_permission.replace",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "ADM-S02"
        ],
        "x-touches-entities": [
          "admin.role_permissions"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Matrix **Save** (fsd 01 ADM-S02) — replaces the role's full grant set in one call (dependency rules, e.g. enabling Create auto-checks View, are enforced server-side). Picked up by RBAC enforcement (`XC-F04`) on the next resolution. `is_system` role grants are read-only to tenant admins. Access Super Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RolePermissionReplaceRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Grant set replaced.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RolePermissionListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/branches": {
      "get": {
        "operationId": "admin.branch.list",
        "summary": "List branches",
        "tags": [
          "admin",
          "branch"
        ],
        "x-token": "admin.branch.list",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "ADM-S03"
        ],
        "x-touches-entities": [
          "admin.branches"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Branch hierarchy tree/grid (fsd 01 ADM-S03) — the branch dimension of RBAC scope, distinct from the `org` reporting tree. Sort whitelist: `branch_code`, `created_at` (default `branch_code`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "parent_branch_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "HEAD_OFFICE",
                "REGIONAL",
                "BRANCH"
              ]
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "INACTIVE"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of branches.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BranchListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "admin.branch.create",
        "summary": "Create a branch",
        "tags": [
          "admin",
          "branch"
        ],
        "x-token": "admin.branch.create",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "ADM-S03"
        ],
        "x-touches-entities": [
          "admin.branches"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "+ Add branch drawer (fsd 01 ADM-S03); `type = HEAD_OFFICE` implies no parent, and only one `HEAD_OFFICE` node is the root (db 02 check constraints). Access Super Admin / HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/BranchFields"
                  },
                  {
                    "required": [
                      "branch_code",
                      "name",
                      "type"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Branch created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Branch"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/branches/{id}": {
      "patch": {
        "operationId": "admin.branch.update",
        "summary": "Update a branch",
        "tags": [
          "admin",
          "branch"
        ],
        "x-token": "admin.branch.update",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "ADM-S03"
        ],
        "x-touches-entities": [
          "admin.branches"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Save branch (fsd 01 ADM-S03); branch scope is consumed by RBAC enforcement (`XC-F04`) and the `BRANCH`-scoped RLS overlay. Access Super Admin / HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BranchFields"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Branch updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Branch"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "operationId": "admin.branch.delete",
        "summary": "Delete a branch",
        "tags": [
          "admin",
          "branch"
        ],
        "x-token": "admin.branch.delete",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "ADM-S03"
        ],
        "x-touches-entities": [
          "admin.branches"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "admin.branch.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Delete a branch. Refused with 409 while any child branch or branch-scoped role permission still references it (dependent type and count are named in the problem detail). Access Tenant Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "204": {
            "description": "Branch deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/role-grants": {
      "get": {
        "operationId": "admin.member_grant.list_all",
        "summary": "List who holds which role, tenant-wide",
        "tags": [
          "admin",
          "member-grant"
        ],
        "x-token": "admin.member_grant.list",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "ADM-S02",
          "ADM-S07"
        ],
        "x-touches-entities": [
          "admin.member_grants",
          "admin.roles",
          "people.employees"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "The ACTIVE `EMPLOYEE`-subject grants of the whole tenant, joined to the role and the person — the \"who can administer this workspace\" list behind the setup wizard's access step (fsd 01 ADM-S07, issue #636) and the roster view of the permission matrix (ADM-S02). Its per-employee sibling answers \"what does this person hold\"; answering the tenant-wide question by walking the employee directory would be a read amplification that worsens with headcount.\n\n**It carries the same `x-token` as that sibling on purpose.** A token is a capability — \"may read who holds which role\" — and these are two shapes of one capability, both tenant-admin only and both bounded by the same RLS; a second token would grow the catalogue without widening what anyone can see. `WORKSPACE_MEMBER` grants are excluded here exactly as they are there (ADR 0024): they are Sysmedac One's to issue and are never addressable in GroundIT. A grant whose employee row was since soft-deleted is still returned, with a null `employee_name` — an admin needs to see and revoke it, not have it disappear.\n\nSort whitelist: `granted_at`, `role_key` (default `-granted_at`). Filters: `role_id`, `employee_id`. Access Tenant Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "role_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "employee_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of active employee role grants.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoleGrantListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/employees/{employeeId}/role-grants": {
      "get": {
        "operationId": "admin.member_grant.list",
        "summary": "List an employee's role grants",
        "tags": [
          "admin",
          "member-grant"
        ],
        "x-token": "admin.member_grant.list",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "PPL-S14"
        ],
        "x-touches-entities": [
          "admin.member_grants",
          "admin.roles",
          "people.employee_subjects"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "The Access & role panel on the employee 360 (fsd 02 PPL-S14). Answers two lists that are never merged: `grants` are the ACTIVE EMPLOYEE-subject rows this surface may write, and `platform_grants` are the ACTIVE grants of the workspace member this employee is linked to — owned by Sysmedac One, read-only here, and returned **without row ids** so nothing on this surface can address them. `platform_member_linked` separates \"no portal member exists\" from \"one exists and holds nothing\". Not paginated: a person's role set is bounded by the tenant's role catalogue. Access Tenant Admin.\n",
        "parameters": [
          {
            "name": "employeeId",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The employee's product-issued grants and their platform-issued grants.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmployeeRoleGrants"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "admin.member_grant.create",
        "summary": "Grant a role to an employee",
        "tags": [
          "admin",
          "member-grant"
        ],
        "x-token": "admin.member_grant.create",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "PPL-S14"
        ],
        "x-touches-entities": [
          "admin.member_grants",
          "admin.roles",
          "admin.role_permissions",
          "audit.audit_log"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "admin.member_grant.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Issue a role to an employee as an EMPLOYEE-subject `admin.member_grants` row (ADR 0024). Refused with **403 SCOPE_DENIED** unless the role passes the no-escalation rule: it must be ACTIVE, must not be `PLATFORM`-scoped, every permission it confers must already be held by the caller, and its `scope_type` must rank at or below the caller's own widest. A role the employee already actively holds is **409**; a previously revoked grant for the same pair is reactivated and answers **201** carrying the SAME grant id (the row is the assignment, its history is the status column). Audited on `audit.audit_log`. This grant is **not** mirrored to Sysmedac One — the portal's product-to-portal channel is V2-reserved (api-docs/08 §14.6). Access Tenant Admin.\n",
        "parameters": [
          {
            "name": "employeeId",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberGrantCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The role is now granted to this employee.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberGrant"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/employees/{employeeId}/role-grants/{grantId}": {
      "delete": {
        "operationId": "admin.member_grant.revoke",
        "summary": "Revoke an employee's role grant",
        "tags": [
          "admin",
          "member-grant"
        ],
        "x-token": "admin.member_grant.revoke",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "PPL-S14"
        ],
        "x-touches-entities": [
          "admin.member_grants",
          "audit.audit_log"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "admin.member_grant.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Revoke a role from an employee. The row is never deleted — `status` flips to `REVOKED` with a `revoked_at` stamp, so the assignment's history stays readable. Answers **200 with the revoked grant** rather than 204: the caller needs the new `version` and the stamp. A `grantId` naming a platform-owned (WORKSPACE_MEMBER-subject) grant, or one belonging to a different employee, answers **404** — this surface never addresses those rows, so a guessed id must not confirm their existence (security-docs/03 §2). An already-revoked grant is **409**. Revoking here does **not** revoke the same person's portal-issued grants; those are Sysmedac One's to remove. Access Tenant Admin.\n",
        "parameters": [
          {
            "name": "employeeId",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "grantId",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "200": {
            "description": "Grant revoked.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberGrant"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/employees/{employeeId}/portal-access": {
      "post": {
        "operationId": "admin.member.create",
        "summary": "Grant an employee management-portal access",
        "tags": [
          "admin",
          "member-grant"
        ],
        "x-token": "admin.member.create",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "PPL-S14"
        ],
        "x-touches-entities": [
          "xc.identities",
          "people.employee_subjects",
          "admin.member_grants",
          "admin.roles",
          "audit.audit_log"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "admin.member.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Give an employee a management-portal seat and the roles that go with it, in ONE transaction: the `platform_member_id` binding is placed on the employee's EXISTING self-service identity (one row, two bindings — a second row could never be signed into, because first sign-in is email-first OTP against the self-service account), the `PLATFORM_MEMBER` subject link is written, and each role is issued as a WORKSPACE_MEMBER-subject `admin.member_grants` row. Any failure rolls back all of it. Every role is checked against the SAME no-escalation rule as `admin.member_grant.create` before anything is written — ACTIVE, not `PLATFORM`-scoped, every permission it confers already held by the caller, scope ranking at or below the caller's own — and a failure is **403 SCOPE_DENIED** carrying which role was refused and how many permissions were in excess (never which). Granting to yourself, on either hat, is **403**. The seat is metered by the plan's `maxUsers` limit and answers **402 PLAN_LIMIT_EXCEEDED** when it is reached; only a call that actually creates a seat is metered, so adding a role to an existing seat is never refused for capacity. An employee with no self-service account yet (no work email), or an address that is already another principal's seat, is **409 STATE_TRANSITION_INVALID** naming the fix; a malformed body is **422**. Re-running with a role the person already holds converges rather than conflicting — this is a make-it-so operation over a set. Access Tenant Admin.\n",
        "parameters": [
          {
            "name": "employeeId",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PortalAccessGrantRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The employee now holds a management-portal seat with these roles.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortalAccessGrantResult"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "operationId": "admin.member.revoke",
        "summary": "Withdraw an employee's management-portal access",
        "tags": [
          "admin",
          "member-grant"
        ],
        "x-token": "admin.member.revoke",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "PPL-S14"
        ],
        "x-touches-entities": [
          "xc.identities",
          "people.employee_subjects",
          "admin.member_grants",
          "audit.audit_log"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "admin.member.changed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Withdraw **every** WORKSPACE_MEMBER-subject grant the seat holds, whoever minted it, then detach the seat in one of two shapes. **PRODUCT** (a seat this door minted): `platform_member_id` is cleared — which is what frees the `maxUsers` seat — and the `PLATFORM_MEMBER` subject link is unlinked. The identity row is NOT deactivated: it is the same person's self-service principal, and taking their payslips away is not what withdrawing back-office access means. **PLATFORM** (a seat Sysmedac One minted — the shape every seat on a live tenant has): the principal's `status` becomes `SUSPENDED`, which the login refuses, and the row, its binding and its subject link are left exactly as the control plane wrote them, for the control plane to retire (ADR 0009). Its binding cannot be cleared (`identities_member_has_platform_binding`), and unlinking its subject would leave a seat that still signs in and then resolves `employeeId: null`. `seat_released` / `seat_suspended` / `seat_owner` say which happened; `portal_access_granted` is the postcondition both shapes share, in the same words the read answers it in. Re-granting afterwards RESUMES a suspended seat (`seat_resumed`) rather than minting a second one under the same address. Gated by the same yardstick as issuing: you may withdraw only what you could have granted, else **403**. No `If-Match` — this revokes a SET, so there is no single row version to pin; the per-grant sibling keeps its ETag. An employee with no portal access at all — or one whose access has already been withdrawn — is **409 STATE_TRANSITION_INVALID**, and so is an attempt to withdraw your OWN access on either hat: an administrator who removes their own seat has no portal left to restore it from. Access Tenant Admin.\n",
        "parameters": [
          {
            "name": "employeeId",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "Portal access withdrawn.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortalAccessRevokeResult"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/audit-log-entries": {
      "get": {
        "operationId": "admin.audit_log.list",
        "summary": "List audit log entries",
        "tags": [
          "admin",
          "audit-log"
        ],
        "x-token": "admin.audit_log.list",
        "x-realizes-features": [
          "ADM-F02"
        ],
        "x-screens": [
          "ADM-S04"
        ],
        "x-touches-entities": [
          "audit.audit_log"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": true,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Read-only, filterable lens over the append-only, hash-chained `audit.audit_log` (fsd 01 ADM-S04) — no `admin` table backs it. **Never a mutation path**; a privileged read here is itself audited (db-docs `15-audit`). Sort whitelist: `created_at` (default `-created_at`; default filter window last 30 days).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "date_from",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Timestamp"
            }
          },
          {
            "name": "date_to",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Timestamp"
            }
          },
          {
            "name": "action",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "entity_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "changed_by",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of audit log entries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditLogEntryListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/audit-log-entries/{id}": {
      "get": {
        "operationId": "admin.audit_log.get",
        "summary": "Get an audit log entry",
        "tags": [
          "admin",
          "audit-log"
        ],
        "x-token": "admin.audit_log.get",
        "x-realizes-features": [
          "ADM-F02"
        ],
        "x-screens": [
          "ADM-S04"
        ],
        "x-touches-entities": [
          "audit.audit_log"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": true,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Detail drawer with the colour-coded before/after JSON diff (fsd 01 ADM-S04). Access Super Admin / Finance (privileged; the read is itself audited).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "Audit log entry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditLogEntry"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/audit-log-entries/export": {
      "post": {
        "operationId": "admin.audit_log.export",
        "summary": "Export filtered audit log entries",
        "tags": [
          "admin",
          "audit-log"
        ],
        "x-token": "admin.audit_log.export",
        "x-realizes-features": [
          "ADM-F02"
        ],
        "x-screens": [
          "ADM-S04"
        ],
        "x-touches-entities": [
          "audit.audit_log"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "async",
        "x-emits-event": "admin.audit_log.export_completed",
        "x-rls-scope": "tenant",
        "x-append-only": true,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Export CTA with a compliance-sensitive-data confirm (fsd 01 ADM-S04) — CSV/PDF artifact generated on the jobs tier (`XC-F07`); the export request itself is audited. Access Super Admin / Finance.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AuditLogExportRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Export queued.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditLogExportJob"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/report-definitions": {
      "get": {
        "operationId": "admin.report_definition.list",
        "summary": "List standard report definitions",
        "tags": [
          "admin",
          "report"
        ],
        "x-token": "admin.report_definition.list",
        "x-realizes-features": [
          "ADM-F03"
        ],
        "x-screens": [
          "ADM-S05"
        ],
        "x-touches-entities": [
          "admin.report_definitions"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "xc.analytics",
        "x-provisional": null,
        "description": "Report-category card grid (fsd 01 ADM-S05) — standard library only; the `CUSTOM` self-serve builder is **Later** (`ADM-F03`, features-docs/01 §8) and is not specced by any operation in this file (design-docs/04 `G-14`⑤ owner decision open). Sort whitelist: `report_code`, `category` (default `category`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "HEADCOUNT",
                "ATTRITION",
                "ATTENDANCE",
                "PAYROLL",
                "LEAVE",
                "COMPLIANCE"
              ]
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "DRAFT",
                "ACTIVE",
                "RETIRED"
              ],
              "default": "ACTIVE"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of report definitions.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportDefinitionListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/report-definitions/{id}": {
      "get": {
        "operationId": "admin.report_definition.get",
        "summary": "Get a report definition",
        "tags": [
          "admin",
          "report"
        ],
        "x-token": "admin.report_definition.get",
        "x-realizes-features": [
          "ADM-F03"
        ],
        "x-screens": [
          "ADM-S05"
        ],
        "x-touches-entities": [
          "admin.report_definitions"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "xc.analytics",
        "x-provisional": null,
        "description": "Generate params modal reads the definition's declared filters (fsd 01 ADM-S05).",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "Report definition.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportDefinition"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "admin.report_definition.update",
        "summary": "Update a report definition's schedule",
        "tags": [
          "admin",
          "report"
        ],
        "x-token": "admin.report_definition.update",
        "x-realizes-features": [
          "ADM-F03"
        ],
        "x-screens": [
          "ADM-S05"
        ],
        "x-touches-entities": [
          "admin.report_definitions"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "xc.analytics",
        "x-provisional": null,
        "description": "Schedule cadence/recipients modal (fsd 01 ADM-S05) — writes `is_scheduled`/`schedule` only; the catalogue fields (`report_code`, `category`, `parameters`, …) are system-defined and read-only. Scheduled runs ride the jobs tier (`XC-F08`). Access HR Admin / Finance.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReportDefinitionScheduleUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Report definition updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportDefinition"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/report-runs": {
      "get": {
        "operationId": "admin.report_run.list",
        "summary": "List report runs",
        "tags": [
          "admin",
          "report"
        ],
        "x-token": "admin.report_run.list",
        "x-realizes-features": [
          "ADM-F03"
        ],
        "x-screens": [
          "ADM-S05"
        ],
        "x-touches-entities": [
          "admin.report_runs"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "xc.analytics",
        "x-provisional": null,
        "description": "Run-history grid (fsd 01 ADM-S05) — run · requester · trigger · status · rows · download. Sort whitelist: `created_at`, `status` (default `-created_at`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "report_definition_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "QUEUED",
                "RUNNING",
                "COMPLETED",
                "FAILED"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of report runs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportRunListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "admin.report_run.create",
        "summary": "Generate a report run",
        "tags": [
          "admin",
          "report"
        ],
        "x-token": "admin.report_run.create",
        "x-realizes-features": [
          "ADM-F03"
        ],
        "x-screens": [
          "ADM-S05"
        ],
        "x-touches-entities": [
          "admin.report_runs"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "async",
        "x-emits-event": "admin.report_run.completed",
        "x-rls-scope": "tenant",
        "x-append-only": true,
        "x-entitlement": "xc.analytics",
        "x-provisional": null,
        "description": "Generate CTA (fsd 01 ADM-S05) — a new `admin.report_runs` row (`QUEUED → RUNNING → COMPLETED|FAILED`, append-only — a re-run makes a new row); reads the reporting platform's materialized views/projections (`XC-F15`), never live cross-schema joins. A privileged report (e.g. payroll register) is gated by the definition's `required_permission` and the run is auditable (`ref→audit.audit_log`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReportRunCreateRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Report run queued.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportRun"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/report-runs/{id}": {
      "get": {
        "operationId": "admin.report_run.get",
        "summary": "Get a report run",
        "tags": [
          "admin",
          "report"
        ],
        "x-token": "admin.report_run.get",
        "x-realizes-features": [
          "ADM-F03"
        ],
        "x-screens": [
          "ADM-S05"
        ],
        "x-touches-entities": [
          "admin.report_runs"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": true,
        "x-entitlement": "xc.analytics",
        "x-provisional": null,
        "description": "Run status poll + download (fsd 01 ADM-S05); `file` carries a freshly minted presigned URL once `status = COMPLETED` — bytes never transit Postgres.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "Report run.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportRun"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/tenant-config": {
      "get": {
        "operationId": "admin.tenant_config.list",
        "summary": "List tenant configuration keys",
        "tags": [
          "admin",
          "tenant-config"
        ],
        "x-token": "admin.tenant_config.list",
        "x-realizes-features": [
          "ADM-F04"
        ],
        "x-screens": [
          "ADM-S06"
        ],
        "x-touches-entities": [
          "admin.tenant_config"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Configuration tab — namespaced key/value settings grouped by `category` (fsd 01 ADM-S06). Sort whitelist: `config_key`, `category` (default `category`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "BRANDING",
                "PAYROLL",
                "NOTIFICATION",
                "LOCALE",
                "GENERAL"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of tenant config keys.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantConfigListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "admin.tenant_config.create",
        "summary": "Bootstrap a tenant configuration key",
        "tags": [
          "admin",
          "tenant-config"
        ],
        "x-token": "admin.tenant_config.create",
        "x-realizes-features": [
          "ADM-F04"
        ],
        "x-screens": [
          "ADM-S06"
        ],
        "x-touches-entities": [
          "admin.tenant_config"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Creates a tenant-config row the tenant has never written — `admin.tenant_config` is a platform-fed mirror (db 02 §2.4) and `/platform/tenants/provision` only ever writes through the three branding keys, so a freshly provisioned tenant has NO `locale.*` rows to `PATCH`. This is the narrow bootstrap for exactly that gap: `config_key` is restricted to the small, known catalogue ADM-S06 renders (currently the three `locale.*` keys — see the request schema's enum), never an arbitrary key, and each key's `value` is validated against its own closed shape (e.g. `locale.supported` must be a non-empty array of `LocaleCode`, `locale.default` must already be a member of the tenant's `locale.supported`) — never saved as an unrecognised value that a later read would just discard. `ON CONFLICT (tenant_id, config_key) DO NOTHING` makes a concurrent create race for the SAME value a benign 201 returning the already-created row; a race for a DIFFERENT value answers `409` instead of a false-success 201, so the caller re-reads rather than believing a write that was silently discarded. Access Super Admin / HR Admin, same as `admin.tenant_config.update`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TenantConfigCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Tenant configuration key created (or already existed with the identical value).",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantConfig"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "410": {
            "$ref": "#/components/responses/Gone"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/tenant-config/{id}": {
      "get": {
        "operationId": "admin.tenant_config.get",
        "summary": "Get a tenant configuration key",
        "tags": [
          "admin",
          "tenant-config"
        ],
        "x-token": "admin.tenant_config.get",
        "x-realizes-features": [
          "ADM-F04"
        ],
        "x-screens": [
          "ADM-S06"
        ],
        "x-touches-entities": [
          "admin.tenant_config"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Config-key detail on ADM-S06 (fsd 01).",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "Tenant configuration key.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantConfig"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "admin.tenant_config.update",
        "summary": "Update a tenant configuration key",
        "tags": [
          "admin",
          "tenant-config"
        ],
        "x-token": "admin.tenant_config.update",
        "x-realizes-features": [
          "ADM-F04"
        ],
        "x-screens": [
          "ADM-S06",
          "ORG-S01"
        ],
        "x-touches-entities": [
          "admin.tenant_config"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Save config (fsd 01 ADM-S06) — this admin surface **authors** local tenant configuration only after resolving `admin.tenant_config.update` for the tenant scope. The command then uses the platform writer for this single version-checked mutation plus its atomic audit/outbox evidence; it cannot grant roles, alter entitlements, or mutate tenant-cache state. `config_version` is bumped and the resolved key→version map is later stamped into downstream snapshots (db 02 §2.4). Also backs the branding fields previewed on `ORG-S01` (fsd 01 *gaps* 5). Access Super Admin / HR Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TenantConfigUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tenant configuration key updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantConfig"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/email-settings": {
      "get": {
        "operationId": "admin.email_settings.get",
        "summary": "Read the workspace outbound-mail configuration",
        "tags": [
          "admin",
          "email-settings"
        ],
        "x-token": "admin.email_settings.get",
        "x-realizes-features": [
          "ADM-F04"
        ],
        "x-screens": [
          "ADM-S06"
        ],
        "x-touches-entities": [
          "xc.tenant_email_settings",
          "admin.tenant_config",
          "org.legal_entities"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "The Email section's read (ADR 0038). Never 404s — \"not configured yet\" is the normal first state and answers the empty shape. Alongside the stored configuration it reports `configured` + `missing_fields` (computed from the same `MAIL_PROVIDERS` registry `createMailClient` validates against, so \"sendable\" and \"constructible\" cannot diverge), the deployment's shared default sender, the `effective_sender` a mail queued now would leave through, and branding READ-ONLY from the authoritative `admin.tenant_config['branding.*']` + `org.legal_entities`. `xc.tenant_email_settings.{logo_url, primary_color, footer_html}` are retired as a branding source. Access Super Admin.\n",
        "responses": {
          "200": {
            "description": "The workspace mail configuration. Secret slots are reported as booleans only.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailSettings"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "admin.email_settings.update",
        "summary": "Update the workspace outbound-mail configuration",
        "tags": [
          "admin",
          "email-settings"
        ],
        "x-token": "admin.email_settings.update",
        "x-realizes-features": [
          "ADM-F04"
        ],
        "x-screens": [
          "ADM-S06"
        ],
        "x-touches-entities": [
          "xc.tenant_email_settings",
          "admin.tenant_config"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Merge-PATCH with a real clear: an ABSENT field is left alone, an explicit `null` clears it. The third state is what lets an admin retire a stale host when they switch provider. **`If-Match` is REQUIRED and is the only concurrency control** — `xc.tenant_email_settings` has no `version` column, so the ETag quotes `updated_at` (`\"t<epochMillis>\"`, `\"t0\"` for a workspace that has never configured mail) and the write is guarded on it inside the same transaction. That is also why this operation takes **no `Idempotency-Key`**: a replayed PATCH carries a now-stale `If-Match` and fails closed with `412`. The four credential fields are reduced to a boolean declaration at the HTTP boundary and only the deterministic secret-store reference is stored; the plaintext reaches no audit row, no outbox payload and no log line. Access Super Admin.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmailSettingsUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configuration saved. Secret slots are reported as booleans only.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailSettings"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/email-settings/test": {
      "post": {
        "operationId": "admin.email_settings.test",
        "summary": "Queue a test message through the workspace mail configuration",
        "tags": [
          "admin",
          "email-settings"
        ],
        "x-token": "admin.email_settings.test",
        "x-realizes-features": [
          "ADM-F04"
        ],
        "x-screens": [
          "ADM-S06"
        ],
        "x-touches-entities": [
          "xc.mail_messages",
          "xc.outbox"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "async",
        "x-emits-event": "xc.email.requested",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "**202 Accepted, not 200.** The API request path never opens a socket to a tenant-supplied mail host (§14.8's SSRF posture, unchanged by ADR 0038) — it writes a `QUEUED` `xc.mail_messages` row plus one `xc.email.requested` event in a single transaction and returns, and the jobs tier dials the relay. `ok: true` therefore means ACCEPTED, never DELIVERED, and `verified_at` is **not** stamped here: it is echoed exactly as stored and only the dispatcher stamps it, on a confirmed send through the tenant's OWN configuration. `409` when the tenant configuration is incomplete AND the deployment's shared sender is off — queueing a row that can only settle as `SUPPRESSED (NO_SENDER)` would answer 202 to a request that had no chance, so the refusal names the missing fields instead. Poll `admin.email_settings.list_status` for the outcome. Access Super Admin.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmailSettingsTestRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted for sending. Not a delivery confirmation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailSettingsTestAccepted"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/email-settings/status": {
      "get": {
        "operationId": "admin.email_settings.list_status",
        "summary": "List recent outbound-mail deliveries for the workspace",
        "tags": [
          "admin",
          "email-settings"
        ],
        "x-token": "admin.email_settings.list_status",
        "x-realizes-features": [
          "ADM-F04"
        ],
        "x-screens": [
          "ADM-S06"
        ],
        "x-touches-entities": [
          "xc.mail_messages"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "The Email section's recent-deliveries table — the newest `xc.mail_messages` rows for this workspace plus a terminal-state tally. `last_error` is the provider's OWN text, returned verbatim (the column CHECK already caps it at 2000 characters): replacing it with house copy is exactly how an admin ends up unable to tell a wrong password from a blocked port. A `SUPPRESSED` row always carries its `suppression_reason` — a mail with no sender is recorded and surfaced, never silently dropped. Access Super Admin.\n",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "description": "How many of the most recent rows to return."
          }
        ],
        "responses": {
          "200": {
            "description": "Recent deliveries, newest first, with a terminal-state tally.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MailDeliveryListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/entitlements": {
      "get": {
        "operationId": "admin.entitlement.list",
        "summary": "List entitlement / feature-flag / limit keys",
        "tags": [
          "admin",
          "entitlement"
        ],
        "x-token": "admin.entitlement.list",
        "x-realizes-features": [
          "ADM-F04"
        ],
        "x-screens": [
          "ADM-S06"
        ],
        "x-touches-entities": [
          "admin.entitlements"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": true,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Entitlements tab — **read-only** (fsd 01 ADM-S06); platform-authored via inbound `/platform/*` only (ADR 0009 — the cache is inbound-write-only, this API never writes it). Displayed for transparency; never edited here. Sort whitelist: `entitlement_key`, `kind` (default `entitlement_key`).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "$ref": "#/components/parameters/SortParam"
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "FEATURE_FLAG",
                "LIMIT",
                "QUOTA"
              ]
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "SUSPENDED"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of entitlements.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntitlementListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/entitlements/{id}": {
      "get": {
        "operationId": "admin.entitlement.get",
        "summary": "Get an entitlement key",
        "tags": [
          "admin",
          "entitlement"
        ],
        "x-token": "admin.entitlement.get",
        "x-realizes-features": [
          "ADM-F04"
        ],
        "x-screens": [
          "ADM-S06"
        ],
        "x-touches-entities": [
          "admin.entitlements"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": true,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Entitlement-key detail row (fsd 01 ADM-S06) — read-only.",
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "Entitlement.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Entitlement"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/division/summary": {
      "get": {
        "operationId": "admin.division_summary.read",
        "summary": "Get the division console aggregate for the caller's org-unit closure",
        "tags": [
          "admin",
          "division"
        ],
        "x-token": "admin.division_summary.read",
        "x-realizes-features": [
          "ADM-F05"
        ],
        "x-screens": [
          "ADM-S08"
        ],
        "x-touches-entities": [
          "admin.role_permissions",
          "xc.dashboard_projections",
          "xc.approval_inbox"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "org_unit",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "The Division Manager's console aggregate (fsd 01 ADM-S08): subtree headcount, present-today, on-leave-today, task velocity, and a leave-calendar summary for the selected period — plus the pending/escalated count of the division's expense queue. **Every figure is event-projection-sourced** (`xc.dashboard_projections`, `XC-F09` / `XC-F15`): the `people`, `attend`, `leave` and `work` values are read from their projections, never joined out of another module's schema. Each region therefore carries its projection's **as-of** time — these are eventually-consistent read models, not live truth — and a region whose projection read failed reports itself as unavailable rather than blanking the whole response.\n\n**As built (#433) — three region states, never two.** Each region reports `status`, and an `unavailable` region says WHY: absent `reason` means the caller's role does not hold that module's own token (the console gates every region on the owning token independently of the screen token), and `reason: projection_missing` means the projection has not been written yet. **Neither is ever rendered as zero.** An `available` region also carries `freshness`: `fresh` within 60 seconds of its `as_of`, `delayed` to five minutes, `stale` thereafter.\n\n**Scope — `org_unit`, the first operation on the new axis (ADR 0026 §(b), api-docs/02 §4).** Rows are confined by a RESTRICTIVE overlay to the org-tree **closure** of the caller's `role_permissions.scope.org_unit_ids` roots, expanded at session build into the `app.org_unit_ids` GUC, with tenant FORCE-RLS underneath. `org_unit` is the **org tree**; `branch` is **geography** — orthogonal axes, so this is not a branch view. `org_unit_id` may only narrow to a root the caller is already anchored to; any other value answers `404` (§5 disclosure posture), never a widened read. A caller with the token but **no anchor** resolves an empty closure — fail-closed by construction, which is why `ADM-S08` renders *\"your account is not anchored to a division\"* from `anchored_org_units` being empty rather than from an error. A caller who holds this token only through a TENANT-wide grant is in that same state on purpose: they were never confined to a subtree, so they have no division to be the console *of*.\n\n**No P&L, deliberately.** No revenue, margin, or budget-vs-actual figure is returned, and no workforce-cost money value either: cost lives under Payroll > Costs behind Finance's own cost tokens (`pay.payslip.cost_summary`, PAY-S20 at /pay/costs/explorer). A division manager holding no `pay` read token sees no cost figure here — the intended outcome, not a gap. (Rev. 2026-09-02: was \"the Finance console (PAY-S19/S20)\"; PAY-S19 is withdrawn and the cost views re-home under Payroll, ADR 0069 (a)/(h). This boundary is unchanged - it is what the re-home was designed to preserve.)\n",
        "parameters": [
          {
            "name": "org_unit_id",
            "in": "query",
            "required": false,
            "description": "Narrow to one of the caller's own anchored roots (and its closure). Omitted, the response covers the caller's full closure. A unit outside the closure answers `404`, never a filtered-empty `200`.\n",
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "period_start",
            "in": "query",
            "required": false,
            "description": "Any date inside the wanted month; the `YYYY-MM` it falls in selects the period-keyed regions (`attendance_period`, `leave_calendar`, `velocity`) and is echoed back as `period`. Defaults to the current month. There is no `period_end`: the period regions are projected per calendar month, so a range would promise an aggregation no projection key exists for. The headcount, attendance-today and leave-today regions are day-keyed and ignore it entirely.\n",
            "schema": {
              "$ref": "#/components/schemas/DateOnly"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Division console aggregate for the caller's closure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DivisionSummary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/division/roster": {
      "get": {
        "operationId": "admin.division_roster.list",
        "summary": "List the division subtree roster",
        "tags": [
          "admin",
          "division"
        ],
        "x-token": "admin.division_roster.list",
        "x-realizes-features": [
          "ADM-F05"
        ],
        "x-screens": [
          "ADM-S08"
        ],
        "x-touches-entities": [
          "admin.role_permissions",
          "xc.dashboard_projections"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "org_unit",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "The read-only subtree roster behind ADM-S08's roster panel — **name · unit · designation only**. No compensation, no statutory identifier, no contact PII: the employee record itself stays on `PPL-S14` behind HR's own tokens, and a roster row is a link there only for a caller who also holds that token. Rows are read from the roster projection (`xc.dashboard_projections`, `XC-F09`), never from a `people` join, so the page carries the projection's as-of time like every other region of the console.\n\nSame `org_unit` confinement as `admin.division_summary.read` above: the caller's `org_unit_ids` closure via the `app.org_unit_ids` GUC, tenant FORCE-RLS underneath, an empty closure yielding an empty page rather than a widened one. The page also carries a `freshness` block with the same three states the summary's regions use — a caller without `people.org_directory.list` gets an empty page marked `unavailable`, not a page that looks like an empty division.\n",
        "parameters": [
          {
            "name": "pageSize",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "page[after]",
            "in": "query",
            "required": false,
            "description": "An opaque cursor from the previous page's `next_cursor`. As built it is a non-negative row offset over the folded roster, because the rows arrive inside one projection payload per direct unit rather than from a keyset query — there is no ordered column in the database to page on. `page[before]` and `sort` are therefore NOT accepted: the order is fixed (`full_name`), and backwards paging over a re-projected array could silently skip or repeat a row.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "org_unit_id",
            "in": "query",
            "required": false,
            "description": "Narrow to one of the caller's own anchored roots (and its closure); outside it, `404`.",
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Free-text match on employee name within the closure — a filter over rows already confined by the overlay, never a widening search.",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of roster rows inside the caller's org-unit closure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DivisionRosterListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/division/approval-inbox": {
      "get": {
        "operationId": "admin.division_approval_inbox.list",
        "summary": "List live expense approvals routed to the caller inside the division subtree",
        "tags": [
          "admin",
          "division"
        ],
        "x-token": "admin.division_approval_inbox.list",
        "x-realizes-features": [
          "ADM-F05"
        ],
        "x-screens": [
          "ADM-S08"
        ],
        "x-touches-entities": [
          "admin.role_permissions",
          "xc.approval_inbox"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "org_unit",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "ADM-S08's expense panel, backed **directly by the unified `xc.approval_inbox`** — not a division-owned projection and not a second approval store (ADR 0027 §(d)/(e)). Unlike every other region of this console it is live, not a read model, because an approval queue that lags is a queue somebody double-decides.\n\n**Three predicates hold at once, and each is load-bearing.** (1) The approver arm — rows keep `current_approver_id = <caller> OR effective_approver_id = <caller>`, so this is the caller's own queue seen through a division lens, never the division's queue. Delegation (`XC-F14`) therefore applies here exactly as it does in the inbox. (2) The closure arm — `org_unit_id` must be inside the caller's resolved `org_unit` closure; the anchor is the requester's **submission-time** org placement, snapshotted at routing time, so a transfer mid-flight cannot move a pending claim between division queues. (3) The RESTRICTIVE overlays behind both (migrations 0021/0094 and 0164). A row with no anchor — every pre-#433 row outside the migration's `PENDING`/`ESCALATED` backfill — fails closed here.\n\nReturns only `EXPENSE` rows in `PENDING` or `ESCALATED` state. The caller must independently hold `xc.approval_inbox.list`; without it this answers an empty page rather than 403, because the console renders the region as restricted rather than failing the whole screen. **Decisions stay on `xc.approval_inbox.decide`** — the console reuses that route, its SSE stream and its optimistic interaction, and deliberately offers no action of its own.\n",
        "parameters": [
          {
            "name": "org_unit_id",
            "in": "query",
            "required": false,
            "description": "Narrow to an anchored root and its closure; a non-root or foreign value is `404`.",
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Optional state narrowing; omitted returns both pending and escalated rows.",
            "schema": {
              "type": "string",
              "enum": [
                "PENDING",
                "ESCALATED"
              ]
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The scoped live inbox view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DivisionApprovalInboxPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/workspace-invitations": {
      "post": {
        "operationId": "admin.workspace_invitation.create",
        "summary": "Invite an identity in this workspace to bind their sign-in subject",
        "tags": [
          "admin",
          "identity"
        ],
        "x-token": "admin.workspace_invitation.create",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "ADM-S02"
        ],
        "x-touches-entities": [
          "xc.workspace_invitations",
          "xc.identities",
          "xc.mail_messages"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Mints a single-use, expiring invitation for an identity row in the CALLER'S OWN workspace and queues it to that identity's address over the ADR 0038 mail rail, in the same transaction — so there is never a live secret nobody was told about, nor a mail naming a row that rolled back.\n\n**The response never contains the token.** Only the secret's SHA-256 is stored, and the secret itself exists in memory just long enough to reach the mail body; returning it would place a working credential in a log, a proxy and a browser history.\n\nRe-inviting the same identity REVOKES the previous live invitation rather than adding a second one — two live secrets for one row means revoking the one you know about still leaves a way in. The target must be a live, non-`SERVICE` identity carrying an address; `SERVICE` is refused for the same reason the workspace picker excludes it (migration `0057`).\n\n**An invitation is not a grant.** It binds an identity to a sign-in subject; what that identity may then do is whatever `admin.member_grants` already says. Inviting into a workspace where the row holds no grants yields a session that can do nothing — the intended outcome.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "identity_id"
                ],
                "additionalProperties": false,
                "properties": {
                  "identity_id": {
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/Uuid"
                      }
                    ],
                    "description": "The `xc.identities` row to invite. Named by ID, never by address: `xc.identities.email` carries no unique constraint, so resolving a target from an address picks an arbitrary row when duplicates exist (ADR 0061 §(c)).\n"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The invitation was minted and queued for delivery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceInvitation"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/workspace-invitations/{id}/revoke": {
      "post": {
        "operationId": "admin.workspace_invitation.revoke",
        "summary": "Revoke a live workspace invitation",
        "tags": [
          "admin",
          "identity"
        ],
        "x-token": "admin.workspace_invitation.revoke",
        "x-realizes-features": [
          "ADM-F01"
        ],
        "x-screens": [
          "ADM-S02"
        ],
        "x-touches-entities": [
          "xc.workspace_invitations"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": null,
        "x-provisional": null,
        "description": "Kills a live invitation. Idempotent: revoking one that is already revoked or already accepted returns its current state rather than failing, so a double-click and a race resolve the same way. An id that does not exist in this workspace is `404` — whether a given invitation id exists here is not something a caller learns by guessing.\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 500
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The invitation's state after the revoke.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceInvitation"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerJWT": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Product session token. Two mint paths, one contract (ADR 0010): employees/managers authenticate against Keycloak (mobile + web); workspace staff arrive from the One portal via bridge-token SSO (`POST /api/sso/exchange` verifies the platform's Ed25519 token and mints the product session). The token carries IDENTITY ONLY — `sub`, `tenantUid`, `principal_class`, MFA level, session ref, `exp`. Roles/permissions are re-resolved server-side per request. Enforcement is layered: gateway (TLS/WAF/routing only — NEVER trusted for auth) → NestJS auth guard (validates token, builds the request auth-context) → entitlement middleware (subscription-status → feature-flag → numeric-limit, ADR 0009) → `SET LOCAL app.tenant_id` / `app.user_id` → Postgres FORCED RLS. `tenantUid` is NEVER a path, query, or body parameter.\n"
      }
    },
    "schemas": {
      "LegalEntityFields": {
        "type": "object",
        "description": "Writable fields of db 02 §1.1 `org.legal_entities`.",
        "additionalProperties": false,
        "properties": {
          "entity_code": {
            "type": "string",
            "description": "tenant-unique short code."
          },
          "legal_name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 150
          },
          "display_name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "market": {
            "type": "string",
            "enum": [
              "IN",
              "KSA"
            ],
            "description": "immutable after create (fsd 01 ORG-S01)."
          },
          "compliance_pack_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "base_currency": {
            "$ref": "#/components/schemas/CurrencyCode"
          },
          "fiscal_year_start_month": {
            "type": "integer",
            "minimum": 1,
            "maximum": 12
          },
          "work_week": {
            "type": "object",
            "description": "Pack-seeded `{ week_off_days, first_day, half_days }` (db 02 §1.1).",
            "properties": {
              "week_off_days": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 6
                }
              },
              "first_day": {
                "type": "integer",
                "minimum": 0,
                "maximum": 6
              },
              "half_days": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 6
                }
              }
            }
          },
          "registered_address": {
            "type": "object",
            "additionalProperties": true,
            "description": "Structured postal JSONB."
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "INACTIVE",
              "DISSOLVED"
            ]
          }
        }
      },
      "LegalEntity": {
        "type": "object",
        "description": "db 02 §1.1 `org.legal_entities` — root config scope every employee/payroll/compliance record hangs beneath.",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "entity_code",
              "legal_name",
              "market",
              "base_currency",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              }
            }
          },
          {
            "$ref": "#/components/schemas/LegalEntityFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "LegalEntityListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LegalEntity"
                }
              }
            }
          }
        ]
      },
      "CompliancePack": {
        "type": "object",
        "description": "db 02 §1.1 `org.compliance_packs` — platform-global reference data (no `tenant_id`), INSERT-only by `app_migrate`. Read here only to populate the pack selector on `ORG-S01`.\n",
        "required": [
          "id",
          "pack_code",
          "jurisdiction",
          "version_no",
          "status"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "pack_code": {
            "type": "string"
          },
          "jurisdiction": {
            "type": "string",
            "enum": [
              "IN",
              "KSA"
            ]
          },
          "version_no": {
            "type": "integer",
            "minimum": 1
          },
          "effective_from": {
            "$ref": "#/components/schemas/DateOnly"
          },
          "status": {
            "type": "string",
            "enum": [
              "DRAFT",
              "PUBLISHED",
              "SUPERSEDED"
            ]
          }
        }
      },
      "CompliancePackListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/CompliancePack"
                }
              }
            }
          }
        ]
      },
      "CompliancePackRules": {
        "type": "object",
        "additionalProperties": true,
        "description": "The pack's frozen policy document (db 02 §1.1 `org.compliance_packs.rules`). Sections are OPTIONAL and genuinely absent on some packs — a narrow single-purpose pack may carry `statutory` alone — so a consumer must render \"not declared by this pack\" rather than a zero or a guessed default. Any section may instead carry `status: PLACEHOLDER_PENDING_COMPLIANCE_REVIEW`, which means the section is a stub awaiting compliance sign-off and must be shown as provisional. `additionalProperties` stays open on purpose: the rules document is reference data whose shape grows by pack version (v2 of `IN-2026` added `statutory.gratuity` over v1), and a closed schema would make a new section unreadable to old consumers.\n",
        "properties": {
          "jurisdiction": {
            "type": "string",
            "enum": [
              "IN",
              "KSA"
            ]
          },
          "currency": {
            "$ref": "#/components/schemas/CurrencyCode"
          },
          "calendar": {
            "type": "object",
            "description": "Fiscal-year start and the calendar systems in play (ADR 0012 — Hijri/Umm-al-Qura display for KSA).",
            "additionalProperties": true,
            "properties": {
              "canonical": {
                "type": "string",
                "description": "Storage calendar, e.g. `GREGORIAN`."
              },
              "display": {
                "type": "string",
                "description": "Display calendar where it differs, e.g. `UMM_AL_QURA`."
              },
              "fiscalYearStartMonth": {
                "type": "integer",
                "minimum": 1,
                "maximum": 12
              }
            }
          },
          "workWeek": {
            "type": "object",
            "description": "ISO day numbers (1 = Monday … 7 = Sunday) — IN weeks off Sat/Sun, KSA Fri/Sat.",
            "additionalProperties": true,
            "properties": {
              "firstDay": {
                "type": "integer",
                "minimum": 1,
                "maximum": 7
              },
              "weekOffDays": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 7
                }
              }
            }
          },
          "locales": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "BCP-47 language subtags, e.g. `[\"en\",\"ar\"]`."
          },
          "rtl": {
            "type": "boolean",
            "description": "Whether the market's primary locale renders right-to-left."
          },
          "statutory": {
            "type": "object",
            "description": "The statutory tables the pack freezes — per-state professional-tax slabs and gratuity parameters for IN, GOSI for KSA. This is the **baseline**, not the tenant's editable copy: overrides live on `org.statutory_config`.\n",
            "additionalProperties": true,
            "properties": {
              "status": {
                "type": "string",
                "description": "`PUBLISHED`, or `PLACEHOLDER_PENDING_COMPLIANCE_REVIEW` when the section is a stub."
              }
            }
          },
          "leaveDefaults": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "holidayDefaults": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "filingFormats": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "identity": {
            "type": "object",
            "additionalProperties": true,
            "description": "Identity documents the market requires (PAN/Aadhaar for IN, Iqama for KSA)."
          },
          "retention": {
            "type": "object",
            "additionalProperties": true,
            "description": "Record-retention periods the market's statutes impose (DPDP / PDPL)."
          },
          "nationalization": {
            "type": "object",
            "additionalProperties": true,
            "description": "KSA only — Nitaqat/Saudization banding. Absent on IN packs."
          }
        }
      },
      "CompliancePackDetail": {
        "description": "One compliance pack including its `rules`. Same identity fields the list op returns, plus the frozen policy document and the row's `version` (the optimistic-lock counter behind the `ETag` — NOT the pack's `version_no`).\n",
        "allOf": [
          {
            "$ref": "#/components/schemas/CompliancePack"
          },
          {
            "type": "object",
            "required": [
              "rules"
            ],
            "properties": {
              "rules": {
                "$ref": "#/components/schemas/CompliancePackRules"
              },
              "version": {
                "type": "integer",
                "minimum": 0,
                "description": "Row optimistic-lock counter; the `ETag` is `\"v<version>\"`."
              }
            }
          }
        ]
      },
      "AppliedDefaultsCount": {
        "type": "object",
        "description": "Rows this call wrote vs. rows already present for one reference set. A repeat apply reports `created: 0` — the operation is insert-if-absent on the set's natural key (db 16 §2.1).\n",
        "required": [
          "created",
          "existing"
        ],
        "properties": {
          "created": {
            "type": "integer",
            "minimum": 0
          },
          "existing": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "PackDefaultsResult": {
        "type": "object",
        "description": "Outcome of applying the pack-seeded tenant baseline (db 16 §3.3) to one legal entity, with the pack the market was derived from so the caller can show which jurisdiction was applied.\n",
        "required": [
          "legal_entity_id",
          "jurisdiction",
          "pack_code",
          "compliance_pack_version",
          "applied"
        ],
        "properties": {
          "legal_entity_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "jurisdiction": {
            "type": "string",
            "enum": [
              "IN",
              "KSA"
            ]
          },
          "pack_code": {
            "type": "string"
          },
          "compliance_pack_version": {
            "type": "integer",
            "minimum": 1
          },
          "fiscal_year": {
            "type": "integer",
            "description": "Fiscal year of the seeded holiday-calendar shell."
          },
          "applied": {
            "type": "object",
            "required": [
              "pay_components",
              "pay_structures",
              "leave_types",
              "leave_policies",
              "holiday_calendars"
            ],
            "properties": {
              "pay_components": {
                "$ref": "#/components/schemas/AppliedDefaultsCount"
              },
              "pay_structures": {
                "$ref": "#/components/schemas/AppliedDefaultsCount"
              },
              "leave_types": {
                "$ref": "#/components/schemas/AppliedDefaultsCount"
              },
              "leave_policies": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/AppliedDefaultsCount"
                  }
                ],
                "description": "Written only for leave types whose entitlement the bound pack supplies; zero while the launch packs carry `PLACEHOLDER_PENDING_COMPLIANCE_REVIEW` leave values (db 16 §3.1).\n"
              },
              "holiday_calendars": {
                "$ref": "#/components/schemas/AppliedDefaultsCount"
              }
            }
          }
        }
      },
      "DepartmentFields": {
        "type": "object",
        "description": "Writable fields of db 02 §1.2 `org.departments`.",
        "additionalProperties": false,
        "properties": {
          "legal_entity_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "dept_code": {
            "type": "string"
          },
          "name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "parent_department_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "head_employee_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "description": "ref→people.employees (soft ref) — resolves even for a terminal-state head."
          },
          "cost_center": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "INACTIVE"
            ]
          }
        }
      },
      "Department": {
        "type": "object",
        "description": "db 02 §1.2 `org.departments`.",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "dept_code",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              }
            }
          },
          {
            "$ref": "#/components/schemas/DepartmentFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "DepartmentListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Department"
                }
              }
            }
          }
        ]
      },
      "DesignationFields": {
        "type": "object",
        "description": "Writable fields of db 02 §1.2 `org.designations`.",
        "additionalProperties": false,
        "properties": {
          "legal_entity_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "designation_code": {
            "type": "string"
          },
          "title": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "grade_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "INACTIVE"
            ]
          }
        }
      },
      "Designation": {
        "type": "object",
        "description": "db 02 §1.2 `org.designations`.",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "designation_code",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              }
            }
          },
          {
            "$ref": "#/components/schemas/DesignationFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "DesignationListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Designation"
                }
              }
            }
          }
        ]
      },
      "GradeFields": {
        "type": "object",
        "description": "Writable fields of db 02 §1.2 `org.grades`.",
        "additionalProperties": false,
        "properties": {
          "legal_entity_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "grade_code": {
            "type": "string"
          },
          "name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "level": {
            "type": "integer",
            "minimum": 0,
            "description": "ordinal seniority (lower = junior)."
          },
          "min_ctc": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/GradeBandMoney"
              },
              {
                "type": "null"
              }
            ],
            "description": "db columns `min_ctc_amount` + `currency_code`, composed with the key `currency`."
          },
          "max_ctc": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/GradeBandMoney"
              },
              {
                "type": "null"
              }
            ],
            "description": "db columns `max_ctc_amount` + `currency_code`, composed with the key `currency`; max ≥ min (db check)."
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "INACTIVE"
            ]
          }
        }
      },
      "GradeBandMoney": {
        "type": "object",
        "description": "Exact decimal money as `org.grades` serves it — `{ amount, currency }`. Identical to the shared `Money` schema EXCEPT for the currency key, which is `currency` here and `currency_code` everywhere else. See the note on `GradeFields.min_ctc`; this schema exists to stop the difference being invisible.\n",
        "required": [
          "amount",
          "currency"
        ],
        "additionalProperties": false,
        "properties": {
          "amount": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d{1,2})?$",
            "description": "numeric(18,2) as a string, e.g. \"800000.00\". Never a float."
          },
          "currency": {
            "$ref": "#/components/schemas/CurrencyCode"
          }
        }
      },
      "Grade": {
        "type": "object",
        "description": "db 02 §1.2 `org.grades`.",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "grade_code",
              "level",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              }
            }
          },
          {
            "$ref": "#/components/schemas/GradeFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "GradeListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Grade"
                }
              }
            }
          }
        ]
      },
      "OrgUnitFields": {
        "type": "object",
        "description": "Writable fields of db 02 §1.2 `org.org_units`.",
        "additionalProperties": false,
        "properties": {
          "legal_entity_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "unit_code": {
            "type": "string"
          },
          "name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "unit_type": {
            "type": "string",
            "enum": [
              "DIVISION",
              "BUSINESS_UNIT",
              "DEPARTMENT",
              "TEAM"
            ]
          },
          "parent_org_unit_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "department_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "work_location_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "manager_employee_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "description": "ref→people.employees (soft ref) — resolves the management chain for approvals/RLS."
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "INACTIVE"
            ]
          }
        }
      },
      "OrgUnit": {
        "type": "object",
        "description": "db 02 §1.2 `org.org_units` — the reporting tree manager scope, approval routing, and RBAC branch scope resolve against.",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "unit_code",
              "unit_type",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              }
            }
          },
          {
            "$ref": "#/components/schemas/OrgUnitFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "OrgUnitListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/OrgUnit"
                }
              }
            }
          }
        ]
      },
      "WorkLocationFields": {
        "type": "object",
        "description": "Writable fields of db 02 §1.3 `org.work_locations`.",
        "additionalProperties": false,
        "properties": {
          "legal_entity_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "location_code": {
            "type": "string"
          },
          "name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "location_type": {
            "type": "string",
            "enum": [
              "OFFICE",
              "SITE",
              "CLIENT",
              "REMOTE",
              "FIELD"
            ]
          },
          "boundary_mode": {
            "type": "string",
            "enum": [
              "SHARED",
              "EMPLOYEE_SPECIFIC"
            ],
            "default": "SHARED",
            "description": "Immutable after creation. SHARED uses company geofences (REMOTE means anywhere). EMPLOYEE_SPECIFIC is a template such as Work from home: no shared coordinates or geofences; Admin/HR configures each employee's private circle on their profile. EMPLOYEE_SPECIFIC requires ADVISORY enforcement and uses out-of-zone review.\n"
          },
          "punch_enforcement": {
            "type": "string",
            "enum": [
              "ADVISORY",
              "BLOCKING"
            ],
            "default": "ADVISORY",
            "description": "db 02 §1.3 `org.punch_enforcement` (migration `0201`, issue #1317, ADR 0067) — whether this location's geofence GOVERNS a punch or only records it. `ADVISORY` (the default, and exactly the behaviour every location had before this field existed) measures containment, stores the attestation, files an `attend.out_of_zone_events` row for review, and ACCEPTS the punch. `BLOCKING` refuses `403` when the SERVER itself placed the punch outside THIS location's own fence, and refuses an evidence-free `attend.punch.web` punch against it — but still accepts a punch it could not verify (no coordinates, unreadable boundary, config gap), so a boundary failure never strands someone at a gate. A `REMOTE` location may never be `BLOCKING`: `422 VALIDATION_FAILED` with a `cross-field` rule on `/punch_enforcement`.\n"
          },
          "address": {
            "type": "object",
            "additionalProperties": true,
            "description": "Structured postal JSONB."
          },
          "timezone": {
            "type": "string",
            "description": "IANA tz, e.g. `Asia/Kolkata`, `Asia/Riyadh`."
          },
          "geo": {
            "type": "object",
            "description": "Centroid display anchor `{ lat, lng }`; the boundary lives in `geofences`.",
            "properties": {
              "lat": {
                "type": "number",
                "minimum": -90,
                "maximum": 90
              },
              "lng": {
                "type": "number",
                "minimum": -180,
                "maximum": 180
              }
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "INACTIVE"
            ]
          }
        }
      },
      "WorkLocation": {
        "type": "object",
        "description": "db 02 §1.3 `org.work_locations`.",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "location_code",
              "location_type",
              "timezone",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              }
            }
          },
          {
            "$ref": "#/components/schemas/WorkLocationFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "WorkLocationListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/WorkLocation"
                }
              }
            }
          }
        ]
      },
      "GeofenceFields": {
        "type": "object",
        "description": "Writable fields of db 02 §1.3 `org.geofences`.",
        "additionalProperties": false,
        "properties": {
          "work_location_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "zone label."
          },
          "shape": {
            "type": "string",
            "enum": [
              "CIRCLE",
              "POLYGON"
            ]
          },
          "center_lat": {
            "anyOf": [
              {
                "type": "number",
                "minimum": -90,
                "maximum": 90
              },
              {
                "type": "null"
              }
            ],
            "description": "required for CIRCLE."
          },
          "center_lng": {
            "anyOf": [
              {
                "type": "number",
                "minimum": -180,
                "maximum": 180
              },
              {
                "type": "null"
              }
            ],
            "description": "required for CIRCLE."
          },
          "radius_m": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "metres; required for CIRCLE."
          },
          "polygon": {
            "anyOf": [
              {
                "type": "array",
                "minItems": 3,
                "items": {
                  "type": "object",
                  "required": [
                    "lat",
                    "lng"
                  ],
                  "properties": {
                    "lat": {
                      "type": "number",
                      "minimum": -90,
                      "maximum": 90
                    },
                    "lng": {
                      "type": "number",
                      "minimum": -180,
                      "maximum": 180
                    }
                  }
                }
              },
              {
                "type": "null"
              }
            ],
            "description": "ordered ring, ≥3 vertices; required for POLYGON."
          },
          "is_active": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "Geofence": {
        "type": "object",
        "description": "db 02 §1.3 `org.geofences` — the spatial anchor on-device clock-in and field-visit attestation are checked against.",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "work_location_id",
              "shape"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              }
            }
          },
          {
            "$ref": "#/components/schemas/GeofenceFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "GeofenceListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Geofence"
                }
              }
            }
          }
        ]
      },
      "ShiftFields": {
        "type": "object",
        "description": "Writable fields of db 02 §1.3 `org.shifts`, plus the read-only `working_hours` the server derives.\n\n`working_hours` is NOT an input. On every create and update the server computes it as\n**span − `break_minutes`**, where the span is `end_time − start_time` wrapping midnight when\n`end_time <= start_time` (22:00–06:00 is 480 minutes; an `end_time` equal to `start_time` is a full\n24-hour pattern). A value sent by a client is accepted for backward compatibility and then discarded —\nit is never stored, so do not rely on sending it. Because it is discarded before the request is\napplied, a PATCH body whose ONLY property is `working_hours` contains no mutable field and is\nrejected with `422 VALIDATION_FAILED` at pointer `/` — send a field you actually want changed.\n\nThe span rules below are checked whenever a request supplies `start_time`, `end_time`,\n`break_minutes`, `grace_in_minutes` or `grace_out_minutes`. A PATCH that touches none of them (say,\n`status` alone) is not re-validated against them and leaves `working_hours` untouched, so a shift\nstored before this rule existed stays editable.\n\n`422 VALIDATION_FAILED` is returned, with the pointer shown, when:\n`break_minutes >= span` (`/break_minutes`), `grace_in_minutes > span` (`/grace_in_minutes`),\n`grace_out_minutes > span` (`/grace_out_minutes`), any of those three is negative, or\n`work_location_id` does not name a live work location in the same legal entity (`/work_location_id`).\n",
        "additionalProperties": false,
        "properties": {
          "legal_entity_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "shift_code": {
            "type": "string"
          },
          "name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "start_time": {
            "type": "string",
            "pattern": "^([01]\\d|2[0-3]):[0-5]\\d(:[0-5]\\d)?$",
            "description": "local clock time, rendered in the location tz."
          },
          "end_time": {
            "type": "string",
            "pattern": "^([01]\\d|2[0-3]):[0-5]\\d(:[0-5]\\d)?$",
            "description": "may be < start_time for overnight shifts."
          },
          "is_night_shift": {
            "type": "boolean",
            "default": false
          },
          "break_minutes": {
            "type": "integer",
            "minimum": 0,
            "default": 0
          },
          "absence_after_minutes": {
            "type": "integer",
            "minimum": 1,
            "description": "Minutes from shift start before absence and HR-required clock-in. Must exceed grace_in_minutes. Omitted on create defaults to max(60, grace_in_minutes + 1)."
          },
          "grace_in_minutes": {
            "type": "integer",
            "minimum": 0,
            "default": 0
          },
          "grace_out_minutes": {
            "type": "integer",
            "minimum": 0,
            "default": 0
          },
          "work_location_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional site the pattern is worked at; null (the default) means any location. Must belong to the same legal entity. Send null to un-pin."
          },
          "working_hours": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DecimalHours"
              }
            ],
            "readOnly": true,
            "description": "Server-derived from start_time/end_time/break_minutes. Ignored if sent."
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "INACTIVE"
            ]
          }
        }
      },
      "Shift": {
        "type": "object",
        "description": "db 02 §1.3 `org.shifts`.",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "shift_code",
              "start_time",
              "end_time",
              "working_hours",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              }
            }
          },
          {
            "$ref": "#/components/schemas/ShiftFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "ShiftListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Shift"
                }
              }
            }
          }
        ]
      },
      "RosterFields": {
        "type": "object",
        "description": "Writable fields of db 02 §1.3 `org.rosters`.",
        "additionalProperties": false,
        "properties": {
          "legal_entity_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "roster_code": {
            "type": "string"
          },
          "shift_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "org_unit_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "work_location_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "employee_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "description": "ref→people.employees — individual override; ≥1 of org_unit_id/employee_id required."
          },
          "rotation": {
            "type": "string",
            "enum": [
              "FIXED",
              "WEEKLY",
              "CONTINENTAL",
              "CUSTOM"
            ]
          },
          "week_off_pattern": {
            "type": "object",
            "description": "Defaults from `legal_entities.work_week` when unset.",
            "properties": {
              "days": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 6
                }
              },
              "rotation_cycle": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "effective_from": {
            "$ref": "#/components/schemas/DateOnly"
          },
          "effective_to": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DateOnly"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "DRAFT",
              "ACTIVE",
              "INACTIVE"
            ]
          }
        }
      },
      "Roster": {
        "type": "object",
        "description": "db 02 §1.3 `org.rosters` — the temporal plan `attend` materializes into daily schedules.",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "roster_code",
              "shift_id",
              "rotation",
              "effective_from",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              }
            }
          },
          {
            "$ref": "#/components/schemas/RosterFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "RosterListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Roster"
                }
              }
            }
          }
        ]
      },
      "LeaveTypeFields": {
        "type": "object",
        "description": "Writable fields of db 02 §1.4 `org.leave_types`.",
        "additionalProperties": false,
        "properties": {
          "legal_entity_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "type_code": {
            "type": "string",
            "description": "UPPER_SNAKE, e.g. AL, SL, ML, HAJ."
          },
          "name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "category": {
            "type": "string",
            "enum": [
              "ANNUAL",
              "SICK",
              "CASUAL",
              "MATERNITY",
              "PATERNITY",
              "HAJJ",
              "UNPAID",
              "COMP_OFF",
              "OPTIONAL_HOLIDAY",
              "OTHER"
            ]
          },
          "is_paid": {
            "type": "boolean",
            "default": true
          },
          "unit": {
            "type": "string",
            "enum": [
              "DAY",
              "HALF_DAY",
              "HOUR"
            ]
          },
          "gender_eligibility": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "ANY",
                  "FEMALE",
                  "MALE"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "INACTIVE"
            ]
          }
        }
      },
      "LeaveType": {
        "type": "object",
        "description": "db 02 §1.4 `org.leave_types`.",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "type_code",
              "category",
              "unit",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              }
            }
          },
          {
            "$ref": "#/components/schemas/LeaveTypeFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "LeaveTypeListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LeaveType"
                }
              }
            }
          }
        ]
      },
      "LeavePolicyFields": {
        "type": "object",
        "description": "Writable fields of db 02 §1.4 `org.leave_policies`.",
        "additionalProperties": false,
        "properties": {
          "legal_entity_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "leave_type_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "policy_code": {
            "type": "string"
          },
          "grade_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "description": "grade-scoped policy; null = all."
          },
          "entitlement_days": {
            "$ref": "#/components/schemas/DecimalHours"
          },
          "accrual_method": {
            "type": "string",
            "enum": [
              "ANNUAL",
              "MONTHLY",
              "ON_CONFIRMATION",
              "ACCRUAL_RULE"
            ]
          },
          "carry_forward_cap": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DecimalHours"
              },
              {
                "type": "null"
              }
            ]
          },
          "encashable": {
            "type": "boolean",
            "default": false
          },
          "rules": {
            "type": "object",
            "description": "db 02 §1.4 `leave_policies.rules` — eligibility, waiting period, pro-ration, negative-balance.",
            "properties": {
              "waiting_period_days": {
                "type": "integer",
                "minimum": 0
              },
              "proration": {
                "type": "string",
                "enum": [
                  "NONE",
                  "DOJ",
                  "MONTHLY"
                ]
              },
              "min_block": {
                "$ref": "#/components/schemas/DecimalHours"
              },
              "max_consecutive": {
                "$ref": "#/components/schemas/DecimalHours"
              },
              "negative_balance": {
                "type": "boolean"
              },
              "monthly_limit_days": {
                "type": "string",
                "pattern": "^(?:0|[1-9]\\d{0,6})(?:\\.\\d{1,2})?$",
                "description": "Positive calendar-month usage ceiling. Approved and pending working days count; cancelled, rejected and withdrawn requests release quota. Unused monthly quota never rolls forward. This supplements, rather than replaces, the accrued balance check."
              },
              "monthly_grant_days": {
                "type": "string",
                "pattern": "^(?:0|[1-9]\\d{0,6})(?:\\.\\d{1,2})?$",
                "description": "MONTHLY policies only (#1886). Monthly grant mode: the accrual job credits exactly this many days at the start of every month (the current month included), effective the 1st or the joining date if later, from the latest of the fiscal-year start, grant_from and the joining month. Replaces entitlement_days/12 pro-rating and the year-to-date shortfall; months before grant_from are never back-filled. Ledger key ACCRUAL:YYYY-MM, so a month already credited is skipped. Ignored on non-MONTHLY policies. Unused days stay on the balance until year-end carry-forward/lapse."
              },
              "grant_from": {
                "type": "string",
                "pattern": "^\\d{4}-(?:0[1-9]|1[0-2])$",
                "description": "YYYY-MM first month monthly_grant_days credits. Requires monthly_grant_days."
              },
              "eligibility": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "key": {
                      "type": "string"
                    },
                    "operator": {
                      "type": "string"
                    },
                    "value": {
                      "type": "string"
                    }
                  }
                }
              },
              "notice_days": {
                "type": "integer",
                "minimum": 0
              }
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "DRAFT",
              "PUBLISHED",
              "SUPERSEDED"
            ]
          }
        }
      },
      "LeavePolicy": {
        "type": "object",
        "description": "db 02 §1.4 `org.leave_policies` — version-stamped downstream onto the `leave` balance ledger so a later edit never re-accrues a frozen period.\n",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "policy_code",
              "leave_type_id",
              "entitlement_days",
              "accrual_method",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              },
              "version_no": {
                "type": "integer",
                "minimum": 1,
                "readOnly": true
              },
              "published_at": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/Timestamp"
                  },
                  {
                    "type": "null"
                  }
                ],
                "readOnly": true
              }
            }
          },
          {
            "$ref": "#/components/schemas/LeavePolicyFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "LeavePolicyListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LeavePolicy"
                }
              }
            }
          }
        ]
      },
      "HolidayCalendarFields": {
        "type": "object",
        "description": "Writable fields of db 02 §1.4 `org.holiday_calendars`.",
        "additionalProperties": false,
        "properties": {
          "legal_entity_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "calendar_code": {
            "type": "string"
          },
          "name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "fiscal_year": {
            "type": "integer"
          },
          "work_location_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "description": "null = entity-wide."
          },
          "holidays": {
            "type": "array",
            "description": "db 02 §1.4 `holiday_calendars.holidays[]`.",
            "items": {
              "type": "object",
              "required": [
                "date",
                "name",
                "type"
              ],
              "properties": {
                "date": {
                  "$ref": "#/components/schemas/DateOnly"
                },
                "name": {
                  "$ref": "#/components/schemas/LocalizedText"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "PUBLIC",
                    "RELIGIOUS",
                    "NATIONAL",
                    "REGIONAL",
                    "RESTRICTED"
                  ]
                },
                "is_optional": {
                  "type": "boolean",
                  "default": false
                },
                "hijri": {
                  "$ref": "#/components/schemas/HijriDisplay"
                }
              }
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "DRAFT",
              "ACTIVE",
              "INACTIVE"
            ]
          }
        }
      },
      "HolidayCalendar": {
        "type": "object",
        "description": "db 02 §1.4 `org.holiday_calendars` — the public-holiday list `leave` and `attend` resolve working days against.",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "calendar_code",
              "fiscal_year",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              }
            }
          },
          {
            "$ref": "#/components/schemas/HolidayCalendarFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "HolidayCalendarListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/HolidayCalendar"
                }
              }
            }
          }
        ]
      },
      "PayComponentFields": {
        "type": "object",
        "description": "Writable fields of db 02 §1.4 `org.pay_components`.",
        "additionalProperties": false,
        "properties": {
          "legal_entity_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "component_code": {
            "type": "string",
            "description": "e.g. BASIC, HRA, PF, GOSI."
          },
          "name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "component_type": {
            "type": "string",
            "enum": [
              "EARNING",
              "DEDUCTION",
              "EMPLOYER_CONTRIBUTION",
              "REIMBURSEMENT"
            ]
          },
          "is_statutory": {
            "type": "boolean",
            "default": false,
            "description": "PF/ESIC/PT/TDS · GOSI vs discretionary; pack-driven."
          },
          "is_taxable": {
            "type": "boolean",
            "default": true
          },
          "show_on_payslip": {
            "type": "boolean",
            "default": true,
            "description": "employer-contribution lines typically false."
          },
          "gl_account_code": {
            "type": [
              "string",
              "null"
            ]
          },
          "default_calc": {
            "type": "object",
            "description": "default basis/rate when not overridden by a structure line.",
            "properties": {
              "basis": {
                "type": "string",
                "enum": [
                  "FLAT",
                  "PCT_OF",
                  "FORMULA"
                ]
              },
              "of": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "amount": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/Money"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "rate": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/Rate"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "formula": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "INACTIVE"
            ]
          }
        }
      },
      "PayComponent": {
        "type": "object",
        "description": "db 02 §1.4 `org.pay_components`.",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "component_code",
              "component_type",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              }
            }
          },
          {
            "$ref": "#/components/schemas/PayComponentFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "PayComponentListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PayComponent"
                }
              }
            }
          }
        ]
      },
      "PayStructureFields": {
        "type": "object",
        "description": "Writable fields of db 02 §1.4 `org.pay_structures`.",
        "additionalProperties": false,
        "properties": {
          "legal_entity_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "structure_code": {
            "type": "string"
          },
          "name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "grade_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "currency_code": {
            "$ref": "#/components/schemas/CurrencyCode"
          },
          "frequency": {
            "type": "string",
            "enum": [
              "MONTHLY",
              "WEEKLY",
              "BIWEEKLY"
            ]
          },
          "components": {
            "type": "array",
            "description": "ordered component lines; `sequence` strictly increasing; non-empty to publish.",
            "items": {
              "type": "object",
              "required": [
                "component_code",
                "sequence",
                "calc"
              ],
              "properties": {
                "component_code": {
                  "type": "string",
                  "description": "resolves a `pay_components` row."
                },
                "name": {
                  "description": "READ-ONLY. The head's locale-keyed name, joined from the `org.pay_components` row `component_code` resolves to, or `null` when it resolves to none. Only `component_code` is stored on the line; every reader needs the name to LABEL it, so the API resolves it once rather than making each consumer fetch the catalogue (issue #1482). Ignored on write — a read-modify-write round trip never persists it. A line has no frequency of its own: the structure's `frequency` governs all lines.\n",
                  "readOnly": true,
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/LocalizedText"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "sequence": {
                  "type": "integer",
                  "minimum": 0
                },
                "calc": {
                  "type": "object",
                  "properties": {
                    "basis": {
                      "type": "string",
                      "enum": [
                        "FLAT",
                        "PCT_OF",
                        "FORMULA"
                      ]
                    },
                    "of": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "amount": {
                      "anyOf": [
                        {
                          "$ref": "#/components/schemas/Money"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "rate": {
                      "anyOf": [
                        {
                          "$ref": "#/components/schemas/Rate"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "formula": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                },
                "prorate": {
                  "type": "boolean",
                  "default": false
                },
                "wage_role": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "enum": [
                    "WAGE",
                    "EXCLUDED",
                    null
                  ],
                  "description": "The Labour-Code classification of this line (ADR 0029 §(d)5, db 07 §1.1). `WAGE` counts toward the 50 %-of-remuneration numerator (Basic, DA); `EXCLUDED` does not (HRA, conveyance, special allowance). **Absent is not a default** — `packages/pay-calc` treats an unclassified line as NOT wage, which is also what makes it fall outside the PF wage base (see `include_in_pf_wage`), so a structure that classifies nothing produces a PF wage of zero. `org.pay_structure.validate` reports the design-time consequences before publish.\n"
                },
                "include_in_pf_wage": {
                  "type": [
                    "boolean",
                    "null"
                  ],
                  "description": "Whether this line is inside the **EPF wage base** the India provident-fund contribution is computed on. Absent falls back to `wage_role == 'WAGE'`, which is why an entirely unclassified structure contributes ₹0 of PF wage and a PF-enrolled employee on it raises the `HARD` `PF_WAGE_ZERO` run validation (db 07 §1.7). Stated explicitly on the seeded India `STD-MONTHLY` blueprint: `true` on `BASIC`, `false` on `HRA` and `SPECIAL_ALLOWANCE`.\n"
                },
                "include_in_esi_gross": {
                  "type": [
                    "boolean",
                    "null"
                  ],
                  "description": "Whether this line is inside the **ESI gross** the state-insurance threshold and contribution are measured on. Absent defaults to `true` for every earning — ESI gross is the whole wage, not the PF subset — so this is stated only to EXCLUDE a line. The seeded blueprints deliberately leave it unstated rather than restating the default.\n"
                },
                "is_wage_floor_absorber": {
                  "type": [
                    "boolean",
                    "null"
                  ],
                  "description": "The one reducible line a required Labour-Code wage-floor correction is funded FROM — conventionally Special Allowance. At most one per structure; a structure with none fails `org.pay_structure.validate` with `WAGE_FLOOR_ABSORBER_MISSING` and cannot be published, which is what turns the run-time `WAGE_FLOOR_BREACH` into an alarm rather than a monthly occurrence. The absorber is never over-drawn into a negative line: the engine funds what it can and reports the remainder.\n"
                },
                "is_wage_floor_anchor": {
                  "type": [
                    "boolean",
                    "null"
                  ],
                  "description": "Where a wage-floor top-up LANDS — conventionally Basic. Defaults to the first `WAGE` line when unstated; `WAGE_FLOOR_ANCHOR_MISSING` when there is no such line.\n"
                },
                "counts_toward_remuneration": {
                  "type": [
                    "boolean",
                    "null"
                  ],
                  "description": "Whether this line is inside **total remuneration**, the denominator of the wage-floor test. Absent defaults to \"every earning\". Stated to exclude a line that is paid but is not remuneration for the purpose of the floor.\n"
                }
              }
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "DRAFT",
              "PUBLISHED",
              "SUPERSEDED"
            ]
          }
        }
      },
      "PayStructure": {
        "type": "object",
        "description": "db 02 §1.4 `org.pay_structures` — the salary blueprint; `pay_structure_version` + the resolved component set are stamped onto every published payslip computed under it.\n",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "structure_code",
              "currency_code",
              "frequency",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              },
              "version_no": {
                "type": "integer",
                "minimum": 1,
                "readOnly": true
              },
              "published_at": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/Timestamp"
                  },
                  {
                    "type": "null"
                  }
                ],
                "readOnly": true
              }
            }
          },
          {
            "$ref": "#/components/schemas/PayStructureFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "PayStructureListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PayStructure"
                }
              }
            }
          }
        ]
      },
      "PayGroupStatus": {
        "type": "string",
        "enum": [
          "ACTIVE",
          "INACTIVE"
        ],
        "description": "org.pay_group_status. Deactivating a group does not delete its periods or its history."
      },
      "AttendanceCycleAnchor": {
        "type": "string",
        "enum": [
          "CALENDAR_MONTH",
          "DAY_ANCHORED"
        ],
        "description": "'org.attendance_cycle_anchor (ADR 0028 §(a)).' `DAY_ANCHORED` with `anchor_day: 21` is a 21st-to-20th cycle — the shape a factory or facilities contractor actually measures on, and the reason the cycle is a per-population property rather than a per-tenant one.\n"
      },
      "PayDateShiftRule": {
        "type": "string",
        "enum": [
          "PREVIOUS_WORKING_DAY",
          "NEXT_WORKING_DAY"
        ],
        "description": "'org.pay_date_shift_rule.' Resolved against `org.holiday_calendars`, which is `fiscal_year`-scoped and optionally `work_location_id`-scoped: a pay group spanning locations with different calendars resolves against the **entity-level** calendar, and per-location pay dates are deliberately out of scope.\n"
      },
      "ProrationBasis": {
        "type": "string",
        "enum": [
          "CALENDAR_DAYS",
          "FIXED_30",
          "WORKING_DAYS"
        ],
        "description": "'org.proration_basis. `CALENDAR_DAYS` is the DEFAULT.' `WORKING_DAYS` is modelled but its interaction with per-location weekly-off patterns is under-specified and should be revisited before it is enabled in a tenant (ADR 0028 residue).\n"
      },
      "SkillCategory": {
        "type": "string",
        "enum": [
          "UNSKILLED",
          "SEMI_SKILLED",
          "SKILLED",
          "HIGHLY_SKILLED"
        ],
        "description": "'org.skill_category (ADR 0033 §(b)).' Deliberately the same taxonomy the statutory minimum-wage schedules use, per state and per zone, so a tenant''s own rate card can be compared to the applicable floor without a translation step.\n"
      },
      "PayGroupFields": {
        "type": "object",
        "description": "Writable fields of `org.pay_groups` (ADR 0028 §(a)). Fields that SHAPE A CYCLE — `attendance_cycle_anchor`, `anchor_day`, `cutoff_day`, `pay_day`, `pay_date_shift_rule`, `proration_basis`, `timezone` — may only be changed with an `effective_from`, which opens a new row; changing one in place would retro-rewrite the meaning of closed months.\n",
        "additionalProperties": false,
        "properties": {
          "pay_group_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[A-Z][A-Z0-9_-]*$",
            "description": "Tenant-wide group identifier (for example `SITE-21`). Required on creation and immutable thereafter; an effective-dated successor retains its code. This field is rejected on `PATCH /pay-groups/{id}`. Migration-created defaults use deterministic `DEFAULT-<ENTITY_CODE>-<ID_SUFFIX>` codes so one default can exist per legal entity in the tenant-wide namespace.\n"
          },
          "legal_entity_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "pay_frequency": {
            "type": "string",
            "enum": [
              "MONTHLY",
              "BIWEEKLY",
              "WEEKLY"
            ],
            "description": "Reuses the existing `pay.pay_frequency` enum. **v1 accepts `MONTHLY` only** — validated in the service, with the other members reserved and the enum append-extensible for `SEMI_MONTHLY`/`DAILY` later. Anything else is a `422`.\n"
          },
          "attendance_cycle_anchor": {
            "$ref": "#/components/schemas/AttendanceCycleAnchor"
          },
          "anchor_day": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 28,
            "description": "Required when `attendance_cycle_anchor = DAY_ANCHORED`; must be null otherwise (`422`, rule `cross-field`). Capped at 28 so no cycle is undefined in February."
          },
          "cutoff_day": {
            "type": "integer",
            "minimum": 1,
            "maximum": 28,
            "description": "Resolved into a `cutoff_at` **instant** in this group's `timezone` on each generated period — a cutoff is a moment, not a fuzzy day."
          },
          "pay_day": {
            "type": "integer",
            "minimum": 1,
            "maximum": 31
          },
          "pay_date_shift_rule": {
            "$ref": "#/components/schemas/PayDateShiftRule"
          },
          "proration_basis": {
            "$ref": "#/components/schemas/ProrationBasis"
          },
          "variance_flag_threshold_pct": {
            "$ref": "#/components/schemas/Rate",
            "description": "The per-population variance gate threshold (ADR 0030 §(e)). It sits here, not tenant-wide, because a threshold that flags nothing is theatre and one that flags everything is worse — and monthly staff and a site crew do not move the same way."
          },
          "timezone": {
            "type": "string",
            "description": "IANA zone (e.g. `Asia/Kolkata`). Resolves `cutoff_at` and the pay-date shift."
          },
          "effective_from": {
            "$ref": "#/components/schemas/DateOnly"
          },
          "effective_to": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DateOnly"
              },
              {
                "type": "null"
              }
            ],
            "description": "Closed by the next effective-dated row, never set by hand. A `[)` daterange exclusion constraint refuses overlaps at the database."
          },
          "status": {
            "$ref": "#/components/schemas/PayGroupStatus"
          }
        }
      },
      "PayGroup": {
        "type": "object",
        "description": "`org.pay_groups` — the per-legal-entity population segment that owns frequency, attendance-cycle anchor, cutoff, pay day and proration basis (ADR 0028 §(a)). Read by `pay` to generate `pay.pay_periods` and by `attend` to scope a cycle finalization; never written by either.\n",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "pay_group_code",
              "legal_entity_id",
              "name",
              "pay_frequency",
              "attendance_cycle_anchor",
              "cutoff_day",
              "pay_day",
              "pay_date_shift_rule",
              "proration_basis",
              "variance_flag_threshold_pct",
              "timezone",
              "effective_from",
              "status",
              "is_default",
              "headcount"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              },
              "is_default": {
                "type": "boolean",
                "readOnly": true,
                "description": "True for the default group auto-created per legal entity at migration. Its deterministic `DEFAULT-<ENTITY_CODE>-<ID_SUFFIX>` code preserves the tenant-wide namespace; it reproduces today's implicit behaviour, but is a default someone must eventually review."
              },
              "headcount": {
                "type": "integer",
                "minimum": 0,
                "readOnly": true,
                "description": "Employees whose effective compensation row is bound to this pay-group version on the requested `effective_on` date (today when omitted)."
              }
            }
          },
          {
            "$ref": "#/components/schemas/PayGroupFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "PayGroupListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PayGroup"
                }
              }
            }
          }
        ]
      },
      "RateCardFields": {
        "type": "object",
        "description": "Writable fields of `org.rate_cards` (ADR 0033 §(b)). Changing `daily_rate`, `skill_category`, `state_code` or `zone_code` requires an `effective_from` and supersedes the row; `legal_entity_id` and `rate_card_code` are immutable once authored.",
        "additionalProperties": false,
        "properties": {
          "legal_entity_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "rate_card_code": {
            "type": "string",
            "maxLength": 64,
            "pattern": "^[A-Z][A-Z0-9_-]*$",
            "description": "Tenant-unique code — unique WITHIN its effective window, which the `[)` daterange exclusion constraint enforces (db-docs/02 §1.4); there is deliberately no plain unique index, so a superseding rate is insertable and an overlapping one is not."
          },
          "name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "skill_category": {
            "$ref": "#/components/schemas/SkillCategory"
          },
          "state_code": {
            "type": "string",
            "description": "ISO 3166-2 subdivision of the applicable schedule (e.g. `IN-KA`) — one of the two axes the statutory schedules are published on."
          },
          "zone_code": {
            "type": [
              "string",
              "null"
            ],
            "description": "The schedule zone within the state, where the jurisdiction publishes one; null where the state publishes a single schedule."
          },
          "daily_rate": {
            "$ref": "#/components/schemas/Money",
            "description": "Exact decimal string. `gross = payable_days × daily_rate` for a `DAILY_WAGE` employee, plus overtime at **not less than twice the ordinary rate** per the Code on Wages — including contract and casual workers, who are inside the Code's wage definition."
          },
          "effective_from": {
            "$ref": "#/components/schemas/DateOnly"
          },
          "effective_to": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DateOnly"
              },
              {
                "type": "null"
              }
            ],
            "description": "Closed by the superseding row",
            "never set by hand.": null
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "INACTIVE"
            ]
          }
        }
      },
      "RateCard": {
        "type": "object",
        "description": "`org.rate_cards` — versioned daily rates. The tenant's own numbers; the statutory floor beside them is pack content and read-only.",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "legal_entity_id",
              "name",
              "skill_category",
              "daily_rate",
              "effective_from"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              },
              "pack_min_wage_daily": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/Money"
                  },
                  {
                    "type": "null"
                  }
                ],
                "readOnly": true,
                "description": "The applicable minimum wage for this `(state_code, zone_code, skill_category)`, **resolved from the active compliance pack** (ADR 0033 §(d)) and surfaced beside the tenant''s own rate so an admin authoring below the floor sees it at authoring time. Read-only by design: a mutable floor would let an operator lower the protection the law provides, and would leave a recomputed historical run unable to recover the rate that was in force.\n\n**`null` today for every card**: the published `IN-2026` pack carries no minimum-wage schedule (`SGAP-30`), so no floor can be resolved. It is returned as `null` rather than as a plausible default — a fabricated floor reads as a compliance check that was performed, and `ORG-S12` renders the absence as a named pack gap instead.\n"
              },
              "pack_version": {
                "type": [
                  "string",
                  "null"
                ],
                "readOnly": true,
                "description": "The compliance-pack version `pack_min_wage_daily` was resolved from — a citable artefact, which a row someone edited is not."
              },
              "below_statutory_floor": {
                "type": [
                  "boolean",
                  "null"
                ],
                "readOnly": true,
                "description": "True when `daily_rate < pack_min_wage_daily`; **`null` when no floor could be resolved** — an unanswered question, not a passed check. Surfaced, never blocked: an authoring-time warning belongs to the admin, and the binding enforcement is the payslip-time floor line."
              }
            }
          },
          {
            "$ref": "#/components/schemas/RateCardFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "RateCardListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/RateCard"
                }
              }
            }
          }
        ]
      },
      "PieceRateItem": {
        "type": "object",
        "description": "`org.piece_rate_items` — one priced unit. `unit_code` is the stable machine key that `attend.muster_entries.units_done` is recorded against, so capture and pricing share one vocabulary.\n",
        "required": [
          "unit_code",
          "rate_per_unit"
        ],
        "additionalProperties": false,
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "piece_rate_catalog_id": {
            "$ref": "#/components/schemas/Uuid",
            "readOnly": true
          },
          "unit_code": {
            "type": "string",
            "maxLength": 64,
            "pattern": "^[A-Z][A-Z0-9_]*$",
            "description": "Stable machine key — never renamed, because muster entries reference it."
          },
          "unit_name": {
            "$ref": "#/components/schemas/LocalizedText",
            "description": "Locale-keyed `{ en, ar }` (ADR 0012) — e.g. `{ \"en\": \"Shirts stitched\", \"ar\": \"…\" }` — because these strings reach a payslip an Arabic-reading worker may open. **No Arabic content is authored in this wave.**"
          },
          "rate_per_unit": {
            "$ref": "#/components/schemas/Money",
            "description": "Exact decimal string. `piece_earnings = Σ(units × rate_per_unit)`, then `gross = max(piece_earnings, min_wage_daily × payable_days)` with the difference posted as an explicit `MINIMUM_WAGE_TOP_UP` line — never folded invisibly into the piece total."
          },
          "effective_from": {
            "$ref": "#/components/schemas/DateOnly"
          },
          "effective_to": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DateOnly"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "INACTIVE"
            ]
          }
        }
      },
      "PieceRateCatalogFields": {
        "type": "object",
        "description": "Writable fields of `org.piece_rate_catalogs` + its items (ADR 0033 §(c)). A `rate_per_unit` change requires an `effective_from` and supersedes that item rather than editing it.",
        "additionalProperties": false,
        "properties": {
          "legal_entity_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "catalog_code": {
            "type": "string",
            "maxLength": 64,
            "pattern": "^[A-Z][A-Z0-9_-]*$",
            "description": "Tenant-unique code — unique within its effective window (the exclusion constraint is the uniqueness rule). Immutable once authored."
          },
          "name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "effective_from": {
            "$ref": "#/components/schemas/DateOnly"
          },
          "effective_to": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DateOnly"
              },
              {
                "type": "null"
              }
            ]
          },
          "items": {
            "type": "array",
            "description": "The priced units. Non-empty for a catalogue an employee can bind to.",
            "items": {
              "$ref": "#/components/schemas/PieceRateItem"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "INACTIVE"
            ]
          }
        }
      },
      "PieceRateCatalog": {
        "type": "object",
        "description": "`org.piece_rate_catalogs` — the named, effective-dated set a `PIECE_RATE` compensation row binds to.",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "legal_entity_id",
              "name",
              "effective_from"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              }
            }
          },
          {
            "$ref": "#/components/schemas/PieceRateCatalogFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "PieceRateCatalogListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PieceRateCatalog"
                }
              }
            }
          }
        ]
      },
      "PayStructureValidateInput": {
        "type": "object",
        "description": "Optional. The builder sends the **in-progress** component set so validation reflects what is on screen rather than what is stored — that is what makes the check live. Omitted, the stored structure is validated as-is.\n",
        "additionalProperties": false,
        "properties": {
          "components": {
            "type": "array",
            "description": "Draft component lines to validate instead of the stored set. Nothing is persisted.",
            "items": {
              "type": "object",
              "required": [
                "component_code",
                "sequence"
              ],
              "properties": {
                "component_code": {
                  "type": "string"
                },
                "sequence": {
                  "type": "integer",
                  "minimum": 0
                },
                "calc": {
                  "type": "object",
                  "properties": {
                    "basis": {
                      "type": "string",
                      "enum": [
                        "FLAT",
                        "PCT_OF",
                        "FORMULA"
                      ]
                    },
                    "of": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "amount": {
                      "anyOf": [
                        {
                          "$ref": "#/components/schemas/Money"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "rate": {
                      "anyOf": [
                        {
                          "$ref": "#/components/schemas/Rate"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "formula": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                },
                "prorate": {
                  "type": "boolean"
                },
                "is_wage_floor_absorber": {
                  "type": "boolean",
                  "description": "Designates the component the floor shortfall is funded from — in practice Special Allowance. A structure with no designation and a floor shortfall fails validation."
                }
              }
            }
          },
          "sample_ctc_amount": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Money"
              }
            ],
            "description": "Optional probe amount, so the floor check could be evaluated against a realistic total remuneration rather than abstractly. **NOT ACCEPTED by the current build (`#574`, 2026-08-14):** the implemented design-time core inspects the structure's DESIGN, not amounts, so supplying this is refused with `422` rather than accepted and ignored — accepting a field and dropping it would let a builder believe a percentage was checked when nothing was. It stays specced because the probe-driven findings (`ABSORBER_INSUFFICIENT`, `WAGE_FLOOR_UNREACHABLE`) and `computed_wages_pct` are the operation's intended second half.\n"
          }
        }
      },
      "PayStructureValidationFinding": {
        "type": "object",
        "description": "One design-time finding. `HARD` blocks publish; `SOFT` is advisory.",
        "required": [
          "code",
          "severity"
        ],
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "NO_ABSORBER_DESIGNATED",
              "MULTIPLE_ABSORBERS_DESIGNATED",
              "ABSORBER_INELIGIBLE",
              "ABSORBER_INSUFFICIENT",
              "WAGE_FLOOR_UNREACHABLE",
              "BASIC_COMPONENT_MISSING",
              "PRORATE_FLAG_UNSET",
              "DOUBLE_PRORATION",
              "SEQUENCE_AMBIGUOUS",
              "FORMULA_INVALID",
              "COMPONENT_REFERENCE_UNRESOLVED"
            ],
            "description": "Append-only vocabulary, mirroring the run-time `pay.run_validations` rule-code discipline: a code is never renamed and never reused. Grown 2026-08-14 (`#574`) when the operation was built, because the engine's design-time core (`packages/pay-calc` `validatePayStructure`) reports five conditions the original six codes could not name without collapsing distinct authoring mistakes into one. `MULTIPLE_ABSORBERS_DESIGNATED` (more than one line ticked — exactly one is required) and `ABSORBER_INELIGIBLE` (the designated line is itself a wage component, or is not remuneration-bearing, so funding the floor from it cannot raise the wage share) are both distinct from `NO_ABSORBER_DESIGNATED`, which would otherwise have told an admin a structure has no absorber while the builder shows one ticked. `SEQUENCE_AMBIGUOUS`, `DOUBLE_PRORATION` (`prorate: true` on a line whose base is already prorated — advisory; the engine applies the factor once), `FORMULA_INVALID` and `COMPONENT_REFERENCE_UNRESOLVED` are the market-neutral design findings, reported whether or not a wage floor applies.\n\n**Not emitted by the current build:** `ABSORBER_INSUFFICIENT`, `WAGE_FLOOR_UNREACHABLE` and `PRORATE_FLAG_UNSET`. The first two need a concrete remuneration probe (see `sample_ctc_amount`) that the design-time core does not take; they are retained here rather than removed so the enum is not re-minted when that half lands.\n"
          },
          "severity": {
            "type": "string",
            "enum": [
              "HARD",
              "SOFT"
            ]
          },
          "component_code": {
            "type": [
              "string",
              "null"
            ],
            "description": "The component the finding is about",
            "where it is about one.": null
          },
          "detail": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "PayStructureValidationResult": {
        "type": "object",
        "description": "A pure read — nothing is written and no lifecycle advances, so the builder can call it on every edit. `wage_floor_ok: false` with `findings: []` is not a state this operation produces: an unreachable floor always names its reason.\n",
        "required": [
          "wage_floor_ok",
          "findings"
        ],
        "properties": {
          "wage_floor_ok": {
            "type": "boolean",
            "description": "True when the structure can absorb a Labour-Code 50 % floor adjustment without changing total remuneration."
          },
          "wage_floor_pct": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Rate"
              },
              {
                "type": "null"
              }
            ],
            "description": "The floor the structure was measured against, resolved from the active compliance pack — quoted here for reviewability, never a literal in code (ADR 0005)."
          },
          "computed_wages_pct": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Rate"
              },
              {
                "type": "null"
              }
            ],
            "description": "Basic + DA as a fraction of total remuneration under the submitted component set. **Always `null` in the current build** — deriving it requires the `sample_ctc_amount` probe the design-time core does not take, and inventing amounts to quote a percentage from would be worse than declining to quote one."
          },
          "absorber_component_code": {
            "type": [
              "string",
              "null"
            ],
            "description": "The designated absorber, when one is designated."
          },
          "pack_version": {
            "type": [
              "string",
              "null"
            ],
            "description": "The compliance-pack version the floor came from. Packs still carrying `PLACEHOLDER_PENDING_COMPLIANCE_REVIEW` are not statutory authority."
          },
          "findings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PayStructureValidationFinding"
            }
          }
        }
      },
      "StatutoryConfigFields": {
        "type": "object",
        "description": "Writable fields of db 02 §1.5 `org.statutory_config`.",
        "additionalProperties": false,
        "properties": {
          "legal_entity_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "statute": {
            "type": "string",
            "enum": [
              "EPFO",
              "ESIC",
              "PT",
              "TDS",
              "GOSI",
              "WPS",
              "MUDAD"
            ],
            "description": "must be consistent with the entity market."
          },
          "registration_no": {
            "type": [
              "string",
              "null"
            ]
          },
          "establishment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "required for KSA GOSI/WPS/MUDAD."
          },
          "work_location_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "parameters": {
            "type": "object",
            "description": "db 02 §1.5 `statutory_config.parameters` — pack-seeded rates as fractions.",
            "properties": {
              "rate": {
                "$ref": "#/components/schemas/Rate"
              },
              "employer_rate": {
                "$ref": "#/components/schemas/Rate"
              },
              "wage_ceiling": {
                "$ref": "#/components/schemas/Money"
              },
              "slabs": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "from": {
                      "$ref": "#/components/schemas/Money"
                    },
                    "to": {
                      "$ref": "#/components/schemas/Money"
                    },
                    "rate": {
                      "$ref": "#/components/schemas/Rate"
                    }
                  }
                }
              },
              "filing_cadence": {
                "type": "string",
                "enum": [
                  "MONTHLY",
                  "QUARTERLY",
                  "ANNUAL"
                ]
              },
              "identifiers": {
                "type": "object",
                "additionalProperties": true
              }
            }
          },
          "effective_from": {
            "$ref": "#/components/schemas/DateOnly"
          },
          "status": {
            "type": "string",
            "enum": [
              "DRAFT",
              "PUBLISHED",
              "SUPERSEDED"
            ]
          },
          "credential_ref": {
            "type": [
              "string",
              "null"
            ],
            "writeOnly": true,
            "description": "Reference key into the platform secret store (`XC-F02`) — the credential itself is never stored in this DB and cannot be read back (fsd 01 *gaps* 6).\n"
          }
        }
      },
      "StatutoryConfig": {
        "type": "object",
        "description": "db 02 §1.5 `org.statutory_config` — India EPFO/ESIC/PT/TDS · KSA GOSI/WPS/Mudad, one hub, both markets.",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "statute",
              "effective_from",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              },
              "version_no": {
                "type": "integer",
                "minimum": 1,
                "readOnly": true
              },
              "integration_status": {
                "type": "string",
                "enum": [
                  "NOT_CONNECTED",
                  "CONNECTED",
                  "EXPIRING",
                  "FAILED"
                ],
                "readOnly": true,
                "description": "live portal-connection health, distinct from the config-version `status`."
              },
              "last_sync_at": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/Timestamp"
                  },
                  {
                    "type": "null"
                  }
                ],
                "readOnly": true
              },
              "last_sync_detail": {
                "type": [
                  "string",
                  "null"
                ],
                "readOnly": true
              }
            }
          },
          {
            "$ref": "#/components/schemas/StatutoryConfigFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "StatutoryConfigListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/StatutoryConfig"
                }
              }
            }
          }
        ]
      },
      "StatutoryConfigSyncJob": {
        "type": "object",
        "description": "Queued Test/Sync job on the jobs tier (`XC-F08`); the 202 body for `org.statutory_config.test_connection`.",
        "required": [
          "job_id",
          "status"
        ],
        "properties": {
          "job_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "QUEUED",
              "RUNNING",
              "COMPLETED",
              "FAILED"
            ]
          },
          "integration_status": {
            "type": "string",
            "enum": [
              "NOT_CONNECTED",
              "CONNECTED",
              "EXPIRING",
              "FAILED"
            ]
          },
          "last_sync_detail": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "TemplateFields": {
        "type": "object",
        "description": "Writable fields of db 02 §1.5 `org.templates`.",
        "additionalProperties": false,
        "properties": {
          "legal_entity_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "description": "null = tenant-wide template."
          },
          "template_code": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "LETTER",
              "POLICY",
              "NOTIFICATION",
              "EMAIL"
            ]
          },
          "sub_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "e.g. OFFER, CTC, INCREMENT, RELIEVING (within LETTER)."
          },
          "bodies": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "subjects": {
            "allOf": [
              {
                "$ref": "#/components/schemas/LocalizedText"
              }
            ],
            "description": "Locale-keyed subject line, sibling of `bodies` (migration 0117). `{}` for a `LETTER` (no subject line). A PUBLISHED `EMAIL` (or `NOTIFICATION` on the `EMAIL` channel) must carry at least one — enforced at publish (`422` naming `/subjects` if not) and by the database CHECK `templates_published_email_has_subject`.\n"
          },
          "variables": {
            "type": "array",
            "description": "declared placeholder variable set, validated at publish.",
            "items": {
              "type": "object",
              "required": [
                "key",
                "type"
              ],
              "properties": {
                "key": {
                  "type": "string"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "TEXT",
                    "NUMBER",
                    "DATE",
                    "MONEY"
                  ]
                },
                "required": {
                  "type": "boolean",
                  "default": false
                }
              }
            }
          },
          "channel": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "EMAIL",
                  "SMS",
                  "WHATSAPP",
                  "PUSH",
                  "IN_APP"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "required when kind = NOTIFICATION."
          },
          "status": {
            "type": "string",
            "enum": [
              "DRAFT",
              "PUBLISHED",
              "SUPERSEDED"
            ]
          }
        }
      },
      "Template": {
        "type": "object",
        "description": "db 02 §1.5 `org.templates` — the authoring surface for offer/CTC/increment/relieving letters, HR policies, and notification/email messages; consumers hold only a `template_ref`.\n",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "template_code",
              "kind",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              },
              "version_no": {
                "type": "integer",
                "minimum": 1,
                "readOnly": true
              },
              "published_at": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/Timestamp"
                  },
                  {
                    "type": "null"
                  }
                ],
                "readOnly": true
              },
              "is_seeded_default": {
                "type": "boolean",
                "readOnly": true,
                "description": "True while this row's content is unmodified default-catalogue content (migration 0117). Set by `org.template.restore_defaults`/`org.template.restore`; cleared by the first edit that changes `bodies`, `subjects` or `variables`. A seeded row refuses `org.template.delete` — restore it instead.\n"
              },
              "seed_key": {
                "type": [
                  "string",
                  "null"
                ],
                "readOnly": true,
                "description": "The default-catalogue entry this row was materialised from (e.g. `letter.offer`), or `null` for a hand-authored template. Carried by every version row in the code's chain, so a restored draft is still recognisable as the same default.\n"
              }
            }
          },
          {
            "$ref": "#/components/schemas/TemplateFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "TemplateListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          }
        ]
      },
      "TemplateRestoreOutcome": {
        "type": "object",
        "description": "One default-catalogue entry's outcome from `org.template.restore_defaults`.",
        "required": [
          "seed_key",
          "outcome",
          "template_id"
        ],
        "additionalProperties": false,
        "properties": {
          "seed_key": {
            "type": "string",
            "example": "letter.offer"
          },
          "outcome": {
            "type": "string",
            "enum": [
              "restored",
              "already_present",
              "superseded_draft_created"
            ],
            "description": "`restored` — the tenant had no row for this `seed_key`; one was inserted `PUBLISHED`. `already_present` — the tenant already has a row for this `seed_key` (any status); nothing changed. `superseded_draft_created` is reserved for parity with `org.template.restore`'s per-template outcome vocabulary; this bulk operation's insert-if-absent logic never touches an existing row, so it does not itself produce this value.\n"
          },
          "template_id": {
            "$ref": "#/components/schemas/Uuid"
          }
        }
      },
      "TemplateRestoreDefaultsResponse": {
        "type": "object",
        "required": [
          "outcomes",
          "counts"
        ],
        "additionalProperties": false,
        "properties": {
          "outcomes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateRestoreOutcome"
            }
          },
          "counts": {
            "type": "object",
            "required": [
              "restored",
              "already_present"
            ],
            "additionalProperties": false,
            "properties": {
              "restored": {
                "type": "integer",
                "minimum": 0
              },
              "already_present": {
                "type": "integer",
                "minimum": 0
              }
            }
          }
        }
      },
      "TemplateRestoreOneResponse": {
        "type": "object",
        "required": [
          "template",
          "new_draft_created",
          "message"
        ],
        "additionalProperties": false,
        "properties": {
          "template": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Template"
              }
            ],
            "description": "The row named in the path when `new_draft_created` is `false`; a NEW draft under the same `template_code` when it is `true` — see `new_draft_created`.\n"
          },
          "new_draft_created": {
            "type": "boolean",
            "description": "`false` — the targeted `DRAFT` row was updated in place. `true` — the targeted row was `PUBLISHED`/`SUPERSEDED` (immutable), so a new `DRAFT` was inserted instead; `template` describes that new draft, and it still needs `org.template.publish`.\n"
          },
          "message": {
            "type": "string",
            "description": "Human-readable statement of what happened."
          }
        }
      },
      "TemplateSendTestRequest": {
        "type": "object",
        "required": [
          "recipient"
        ],
        "additionalProperties": false,
        "properties": {
          "recipient": {
            "type": "string",
            "description": "email address / phone number the test render is dispatched to."
          },
          "sample_data": {
            "type": "object",
            "additionalProperties": true,
            "description": "override values for declared `variables`; unset keys use placeholder samples."
          }
        }
      },
      "TemplateSendTestResponse": {
        "type": "object",
        "description": "The honest async shape (G-19②/GAP-17② closed): a `QUEUED` `xc.mail_messages` row now exists and an `xc.email.requested` outbox event has been emitted to wake the jobs-tier dispatcher (`apps/jobs/src/jobs/mail-jobs.ts`) — `queued: true` reports that a send was accepted, never that delivery happened. Poll delivery status via the mail-deliveries surface (`admin.email_settings.list_status`), filtering on `mail_message_id`.\n",
        "required": [
          "queued",
          "recipient",
          "mail_message_id",
          "queued_at",
          "locale"
        ],
        "additionalProperties": false,
        "properties": {
          "queued": {
            "type": "boolean"
          },
          "recipient": {
            "type": "string"
          },
          "mail_message_id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "description": "The `xc.mail_messages.id` this test send was queued as."
          },
          "queued_at": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "locale": {
            "type": "string",
            "example": "en"
          }
        }
      },
      "TemplateRenderRequest": {
        "type": "object",
        "description": "The values to merge for one server-side PDF render (ADR 0023). Keys are the template's own declared `variables[].key`; anything undeclared is ignored rather than rejected, so a stale client keeps working.\n",
        "properties": {
          "locale": {
            "type": "string",
            "default": "en",
            "description": "Which `bodies` entry to render. MUST be a locale the renderer supports (`en` today) — see `org.template.render`'s description for why `ar` is refused rather than mis-typeset.\n",
            "example": "en"
          },
          "variableValues": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "maxProperties": 200,
            "description": "One value per declared variable. Every variable marked `required` must be present and non-blank. Each value is capped at 4096 characters, and C0/C1 controls, Unicode bidi overrides and zero-width characters are stripped before the merge. **PII** — these are the contents of a letter; see the operation description for where they are and are not persisted.\n",
            "example": {
              "employee_name": "Asha Menon",
              "ctc_amount": "1200000.00"
            }
          }
        }
      },
      "TemplateRender": {
        "type": "object",
        "description": "One server-side render of a template — an `org.template_renders` row (db 02 §1.5, ADR 0023). Returned by `org.template.render` (as `QUEUED`) and by `org.template.render_status` on every poll. Note what is absent: the `variableValues` the caller supplied are never echoed back.\n",
        "required": [
          "id",
          "templateId",
          "templateVersionNo",
          "locale",
          "status"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "templateId": {
            "$ref": "#/components/schemas/Uuid"
          },
          "templateVersionNo": {
            "type": "integer",
            "description": "The template `version_no` this render was taken from, stamped at request time so superseding the template cannot re-interpret an already-issued letter.\n"
          },
          "locale": {
            "type": "string",
            "example": "en"
          },
          "status": {
            "type": "string",
            "enum": [
              "QUEUED",
              "RUNNING",
              "COMPLETED",
              "FAILED"
            ],
            "description": "`org.template_render_status`. Only `COMPLETED` carries a `downloadUrl`."
          },
          "contentHash": {
            "type": "string",
            "nullable": true,
            "description": "sha-256 over the produced PDF; null until COMPLETED."
          },
          "byteSize": {
            "type": "integer",
            "nullable": true,
            "description": "Size of the produced PDF; null until COMPLETED."
          },
          "error": {
            "type": "string",
            "nullable": true,
            "description": "Present only when `status` is `FAILED`, prefixed with the machine reason — `UNSUPPORTED_LOCALE`, `TIMEOUT`, `OUTPUT_TOO_LARGE`, `ENGINE_FAILURE` or `INVALID_INPUT`.\n"
          },
          "requestedAt": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "downloadUrl": {
            "type": "string",
            "format": "uri",
            "description": "Presigned object-storage URL, minted per poll and valid for 15 minutes. Absent unless `status` is `COMPLETED`. Treat it as a bearer credential for the document: do not log it or persist it.\n"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "description": "When `downloadUrl` lapses. Poll again for a fresh one."
          }
        }
      },
      "DashboardProjection": {
        "type": "object",
        "description": "fsd 01 ADM-S01 — role-aware, read-only reporting projection (`XC-F15`); **no `org`/`admin` table backs this**. Tiles are role-filtered server-side.\n",
        "properties": {
          "headcount": {
            "type": "object",
            "description": "projection over `people`.",
            "properties": {
              "total": {
                "type": "integer"
              },
              "trend": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "period": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "open_positions": {
            "type": "object",
            "description": "projection over `recruit`.",
            "properties": {
              "total": {
                "type": "integer"
              }
            }
          },
          "compliance_health": {
            "type": "object",
            "description": "projection over `comply`.",
            "properties": {
              "score": {
                "type": "number"
              },
              "band": {
                "type": "string",
                "enum": [
                  "GREEN",
                  "AMBER",
                  "RED"
                ]
              }
            }
          },
          "payroll_status": {
            "type": "object",
            "description": "projection over `pay`.",
            "properties": {
              "latest_run_status": {
                "type": "string"
              },
              "total_cost": {
                "$ref": "#/components/schemas/Money"
              }
            }
          },
          "leave_pending": {
            "type": "object",
            "description": "projection over `leave`.",
            "properties": {
              "total": {
                "type": "integer"
              }
            }
          },
          "active_alerts": {
            "type": "array",
            "description": "priority-sorted; includes `org` statutory-integration `FAILED`/`EXPIRING` health.",
            "items": {
              "type": "object",
              "properties": {
                "severity": {
                  "type": "string",
                  "enum": [
                    "CRITICAL",
                    "HIGH",
                    "MEDIUM"
                  ]
                },
                "message": {
                  "type": "string"
                },
                "source_ref": {
                  "$ref": "#/components/schemas/SoftRef"
                }
              }
            }
          },
          "recent_activity": {
            "type": "array",
            "description": "ref→audit.audit_log feed.",
            "items": {
              "type": "object",
              "properties": {
                "occurred_at": {
                  "$ref": "#/components/schemas/Timestamp"
                },
                "summary": {
                  "type": "string"
                },
                "source_ref": {
                  "$ref": "#/components/schemas/SoftRef"
                }
              }
            }
          }
        }
      },
      "RoleCatalog": {
        "type": "object",
        "description": "db 02 §2.1 `admin.role_catalog` — the platform-aligned catalogue of role definitions.",
        "required": [
          "id",
          "catalog_key",
          "is_system",
          "status"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "catalog_key": {
            "type": "string"
          },
          "name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "description": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "is_system": {
            "type": "boolean"
          },
          "default_permissions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "DEPRECATED"
            ]
          }
        }
      },
      "RoleCatalogListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/RoleCatalog"
                }
              }
            }
          }
        ]
      },
      "RoleFields": {
        "type": "object",
        "description": "Writable fields of db 02 §2.1 `admin.roles`.",
        "additionalProperties": false,
        "properties": {
          "role_key": {
            "type": "string",
            "description": "tenant-stable code."
          },
          "name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "role_catalog_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "scope_type": {
            "type": "string",
            "enum": [
              "PLATFORM",
              "TENANT",
              "LEGAL_ENTITY",
              "ORG_UNIT",
              "BRANCH",
              "SELF"
            ],
            "description": "Bounds the RLS overlay (db 00 §4). Ladder: PLATFORM > TENANT > LEGAL_ENTITY > ORG_UNIT ≥ BRANCH > SELF — ORG_UNIT (the org tree) and BRANCH (geography) are orthogonal dimensions ranked EQUAL by convention, for ADR 0024's grantable-role ceiling only. PLATFORM is permitted only on is_system roles. ORG_UNIT is presently READ-ONLY on this field: it is a live `admin.role_scope` value (migration 0162) carried by the seeded `division_manager`, but `admin.role.create`/`.update` refuse to AUTHOR it until the overlays outside the division console learn the org-unit axis — today they read any non-SELF scope as \"staff\", so a hand-authored ORG_UNIT role would promise a subtree and resolve as wide as a BRANCH one (security-docs/06 `SGAP-31`).\n"
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "INACTIVE"
            ]
          }
        }
      },
      "Role": {
        "type": "object",
        "description": "db 02 §2.1 `admin.roles` — the tenant-authored role instance the platform issues grants against. GroundIT defines what a role means; the platform decides who holds it.\n",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "role_key",
              "scope_type",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              },
              "is_system": {
                "type": "boolean",
                "readOnly": true
              }
            }
          },
          {
            "$ref": "#/components/schemas/RoleFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "RoleListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Role"
                }
              }
            }
          }
        ]
      },
      "RoleDuplicateRequest": {
        "type": "object",
        "required": [
          "role_key",
          "name"
        ],
        "additionalProperties": false,
        "properties": {
          "role_key": {
            "type": "string",
            "description": "the new role's tenant-stable code."
          },
          "name": {
            "$ref": "#/components/schemas/LocalizedText"
          }
        }
      },
      "MemberGrant": {
        "type": "object",
        "description": "db 02 §2.1 `admin.member_grants` — one principal-to-role assignment. This shape is the EMPLOYEE half only: `subject_kind` is always `EMPLOYEE` and `subject_ref` is the employee id. The WORKSPACE_MEMBER half is platform-owned and is never returned with an id (ADR 0024).\n",
        "required": [
          "id",
          "role_id",
          "subject_kind",
          "subject_ref",
          "status",
          "granted_at",
          "version"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "role_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "role_key": {
            "type": "string",
            "description": "the granted role's tenant-stable code."
          },
          "subject_kind": {
            "type": "string",
            "enum": [
              "EMPLOYEE"
            ]
          },
          "subject_ref": {
            "$ref": "#/components/schemas/Uuid"
          },
          "employee_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "REVOKED"
            ]
          },
          "granted_at": {
            "type": "string",
            "format": "date-time"
          },
          "revoked_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "version": {
            "type": "integer"
          }
        }
      },
      "MemberGrantCreateRequest": {
        "type": "object",
        "required": [
          "role_id"
        ],
        "additionalProperties": false,
        "properties": {
          "role_id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "description": "the role to issue. Subject to the no-escalation rule (ADR 0024): ACTIVE, not `PLATFORM`-scoped, its permission set a subset of the caller's own, and its `scope_type` at or below the caller's widest.\n"
          }
        }
      },
      "PlatformRoleGrant": {
        "type": "object",
        "description": "A grant Sysmedac One issued to the workspace member this employee is linked to. Read-only on this surface and deliberately id-less — the portal owns these rows and GroundIT must not offer a handle to them (ADR 0024).\n",
        "required": [
          "role_id",
          "role_key",
          "source"
        ],
        "properties": {
          "role_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "role_key": {
            "type": "string"
          },
          "role_name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "scope_type": {
            "type": "string",
            "enum": [
              "PLATFORM",
              "TENANT",
              "LEGAL_ENTITY",
              "ORG_UNIT",
              "BRANCH",
              "SELF"
            ]
          },
          "granted_at": {
            "type": "string",
            "format": "date-time"
          },
          "source": {
            "type": "string",
            "enum": [
              "PLATFORM"
            ]
          }
        }
      },
      "RoleGrantHolder": {
        "type": "object",
        "description": "One ACTIVE `EMPLOYEE`-subject grant with the role and the person it joins — the tenant-wide roster shape (`admin.member_grant.list_all`). `employee_name`/`employee_no` are null when the employee row has been soft-deleted while the grant is still live.\n",
        "required": [
          "id",
          "role_id",
          "role_key",
          "employee_id",
          "status",
          "granted_at",
          "version"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "role_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "role_key": {
            "type": "string"
          },
          "role_name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "scope_type": {
            "type": "string",
            "enum": [
              "PLATFORM",
              "TENANT",
              "LEGAL_ENTITY",
              "ORG_UNIT",
              "BRANCH",
              "SELF"
            ]
          },
          "is_system": {
            "type": "boolean"
          },
          "employee_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "employee_no": {
            "type": [
              "string",
              "null"
            ]
          },
          "employee_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE"
            ]
          },
          "granted_at": {
            "type": "string",
            "format": "date-time"
          },
          "version": {
            "type": "integer"
          }
        }
      },
      "RoleGrantListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/RoleGrantHolder"
                }
              }
            }
          }
        ]
      },
      "EmployeeRoleGrants": {
        "type": "object",
        "required": [
          "employee_id",
          "grants",
          "platform_grants",
          "platform_member_linked",
          "portal_access",
          "grantable_roles"
        ],
        "properties": {
          "employee_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "grants": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemberGrant"
            }
          },
          "platform_grants": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlatformRoleGrant"
            }
          },
          "platform_member_linked": {
            "type": "boolean",
            "description": "whether this employee has an active `PLATFORM_MEMBER` link (people.employee_subjects). `false` means there is no portal member to show, not that the read failed.\n"
          },
          "portal_access": {
            "$ref": "#/components/schemas/PortalAccessState"
          },
          "grantable_roles": {
            "type": "array",
            "description": "every ACTIVE role in the tenant's catalogue with the caller's own verdict on it (#1641) — the picker's data. Computed from the SAME no-escalation rule the write leg enforces, so a role the screen offers is a role the write leg accepts.\n",
            "items": {
              "$ref": "#/components/schemas/GrantableRole"
            }
          }
        }
      },
      "PortalAccessState": {
        "type": "object",
        "description": "Whether this employee can sign in to the MANAGEMENT portal, and what may be done about it (#1641). `granted` is the `xc.identities.platform_member_id` binding — the column `derivePrincipalClass` reads to make a WEB session a WORKSPACE_MEMBER one.\n",
        "required": [
          "granted",
          "seat_owner",
          "revocable",
          "eligible",
          "ineligible_reason"
        ],
        "properties": {
          "granted": {
            "type": "boolean",
            "description": "the seat row carries the binding AND is in a state that can sign in (`ACTIVE` or `INVITED`). Never derived from the employee↔member subject link, which a Sysmedac One seat keeps after access is withdrawn.\n"
          },
          "seat_owner": {
            "type": "string",
            "nullable": true,
            "enum": [
              "PRODUCT",
              "PLATFORM",
              null
            ],
            "description": "who may retire the seat. `PRODUCT` — minted here, releasable here. `PLATFORM` — Sysmedac One's principal: its roles can still be withdrawn, its identity row cannot. `null` when there is no seat.\n"
          },
          "revocable": {
            "type": "boolean",
            "description": "access can be withdrawn from EITHER shape — they differ in HOW (detach vs suspend), not in whether. Equal to `granted`.\n"
          },
          "eligible": {
            "type": "boolean",
            "description": "whether a seat could be created now. Always true when `granted` is true."
          },
          "ineligible_reason": {
            "type": "string",
            "nullable": true,
            "description": "the human-readable blocker and its fix (no self-service account yet, no work email, or a principal not in a state to be seated). Null exactly when `eligible` is true.\n"
          }
        }
      },
      "GrantableRole": {
        "type": "object",
        "required": [
          "id",
          "role_key",
          "role_name",
          "scope_type",
          "is_system",
          "grantable",
          "reason"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "role_key": {
            "type": "string"
          },
          "role_name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "scope_type": {
            "type": "string"
          },
          "is_system": {
            "type": "boolean"
          },
          "grantable": {
            "type": "boolean"
          },
          "reason": {
            "type": "string",
            "nullable": true,
            "description": "why this role is not offered — which test failed, and for the permission-subset test HOW MANY tokens are in excess, never WHICH (that set is by construction what the caller is not entitled to, and printing it is role-composition enumeration). Null when `grantable`.\n"
          }
        }
      },
      "PortalAccessGrantRequest": {
        "type": "object",
        "required": [
          "roles"
        ],
        "properties": {
          "roles": {
            "type": "array",
            "minItems": 1,
            "maxItems": 20,
            "description": "role IDS — the same currency `admin.member_grant.create` takes, so one picker feeds both doors. Duplicates collapse. At least one: a seat that confers nothing is a login with no purpose and a plan seat consumed for it.\n",
            "items": {
              "$ref": "#/components/schemas/Uuid"
            }
          }
        }
      },
      "PortalAccessGrantResult": {
        "type": "object",
        "required": [
          "employee_id",
          "platform_member_linked",
          "seat_created",
          "seat_resumed",
          "seat_owner",
          "granted_role_ids",
          "granted_role_keys",
          "newly_granted"
        ],
        "properties": {
          "employee_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "platform_member_linked": {
            "type": "boolean"
          },
          "seat_created": {
            "type": "boolean",
            "description": "false when the person already held a seat and only roles were added."
          },
          "seat_resumed": {
            "type": "boolean",
            "description": "a SUSPENDED seat was put back into service rather than a second one minted. The member id is derived from the address, so two seats under one address are unrepresentable (`identities_tenant_platform_member_id_key`) — re-granting resumes. No plan seat is consumed: a suspended binding is still counted by `maxUsers`.\n"
          },
          "seat_owner": {
            "type": "string",
            "nullable": true,
            "enum": [
              "PRODUCT",
              "PLATFORM",
              null
            ]
          },
          "granted_role_ids": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          "granted_role_keys": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "newly_granted": {
            "type": "integer",
            "description": "how many of the requested roles were not already held."
          }
        }
      },
      "PortalAccessRevokeResult": {
        "type": "object",
        "required": [
          "employee_id",
          "portal_access_granted",
          "platform_member_linked",
          "revoked_grants",
          "seat_released",
          "seat_suspended",
          "seat_owner"
        ],
        "properties": {
          "employee_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "portal_access_granted": {
            "type": "boolean",
            "description": "the postcondition, always `false`, in the SAME words `EmployeeRoleGrants.portal_access .granted` answers it in — so a read taken immediately afterwards agrees with this response in both seat shapes.\n"
          },
          "platform_member_linked": {
            "type": "boolean",
            "description": "the `people.employee_subjects` fact, which is NOT the access fact. A PRODUCT seat is unlinked (`false`); a PLATFORM seat KEEPS its link (`true`), because that member is still this employee and the control plane may reinstate them.\n"
          },
          "revoked_grants": {
            "type": "integer"
          },
          "seat_released": {
            "type": "boolean",
            "description": "PRODUCT shape — `platform_member_id` cleared and the `maxUsers` seat freed. The identity row lives on as the same person's self-service login; it is never deactivated.\n"
          },
          "seat_suspended": {
            "type": "boolean",
            "description": "PLATFORM shape — the principal's `status` is set to `SUSPENDED`, which the login refuses, and the row plus its subject link are left for Sysmedac One to retire. Its binding cannot be cleared (`identities_member_has_platform_binding`), and unlinking its subject would leave a seat that still signs in and resolves `employeeId: null`.\n"
          },
          "seat_owner": {
            "type": "string",
            "nullable": true,
            "enum": [
              "PRODUCT",
              "PLATFORM",
              null
            ]
          }
        }
      },
      "Permission": {
        "type": "object",
        "description": "db 02 §2.1 `admin.permissions` — the `<module>.<entity>.<action>` token catalogue roles grant; the authoritative catalogue and resolution semantics are owned by the Security/RBAC set.\n",
        "required": [
          "id",
          "permission_key",
          "module",
          "status"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "permission_key": {
            "type": "string"
          },
          "module": {
            "type": "string"
          },
          "description": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "is_privileged": {
            "type": "boolean"
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "DEPRECATED"
            ]
          }
        }
      },
      "PermissionListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Permission"
                }
              }
            }
          }
        ]
      },
      "RolePermission": {
        "type": "object",
        "description": "db 02 §2.1 `admin.role_permissions` — one grant of one permission token to one role.",
        "required": [
          "id",
          "role_id",
          "permission_id"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "role_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "permission_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "scope": {
            "type": "object",
            "description": "optional grant-level scope qualifier narrowing the role's scope_type; empty = unqualified.",
            "properties": {
              "legal_entity_ids": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Uuid"
                }
              },
              "branch_ids": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Uuid"
                }
              },
              "org_unit_ids": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Uuid"
                },
                "description": "Org-tree **anchor roots** (`ref→org.org_units`), not the reach itself: the authorization engine expands each into its subtree closure (`app.org_unit_closure`, migration 0162) at session build and publishes that as the `app.org_unit_ids` GUC the `org_unit` overlays read. ADR 0026 §(b) — the org tree, orthogonal to `branch_ids` (geography). At request time an `ORG_UNIT`-scoped grant carrying **no** roots is an explicit `SCOPE_DENIED`, never a silent widening to the tenant; so is one whose root no longer resolves inside its own closure.\n"
              }
            }
          }
        }
      },
      "RolePermissionListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/RolePermission"
                }
              }
            }
          }
        ]
      },
      "RolePermissionReplaceRequest": {
        "type": "object",
        "required": [
          "grants"
        ],
        "additionalProperties": false,
        "description": "The matrix Save body — the role's full grant set, replacing all prior grants in one call.",
        "properties": {
          "grants": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "permission_id"
              ],
              "properties": {
                "permission_id": {
                  "$ref": "#/components/schemas/Uuid"
                },
                "scope": {
                  "type": "object",
                  "properties": {
                    "legal_entity_ids": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Uuid"
                      }
                    },
                    "branch_ids": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Uuid"
                      }
                    },
                    "org_unit_ids": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Uuid"
                      },
                      "description": "Org-tree **anchor roots** expanded server-side to their subtree closure (see `RolePermission.scope.org_unit_ids`). Validated twice on Save: syntactically here, then against the tenant inside the write transaction — each id must be a live org unit of this tenant, so a foreign or deleted root is refused at authoring time rather than surfacing later as a `SCOPE_DENIED` for the grantee. Duplicates are refused too. Omitting the key entirely is accepted here — the refusal for an unanchored `ORG_UNIT` grant lands at request time, on the grantee, not on Save.\n"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "BranchFields": {
        "type": "object",
        "description": "Writable fields of db 02 §2.1 `admin.branches`.",
        "additionalProperties": false,
        "properties": {
          "branch_code": {
            "type": "string"
          },
          "name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "parent_branch_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "legal_entity_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "description": "ref→org.legal_entities (soft, cross-schema — org/admin are separate schemas)."
          },
          "type": {
            "type": "string",
            "enum": [
              "HEAD_OFFICE",
              "REGIONAL",
              "BRANCH"
            ]
          },
          "geo": {
            "type": "object",
            "properties": {
              "region": {
                "type": "string"
              },
              "state": {
                "type": "string"
              },
              "city": {
                "type": "string"
              },
              "postal_code": {
                "type": "string"
              },
              "lat": {
                "type": "number"
              },
              "lng": {
                "type": "number"
              }
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "INACTIVE"
            ]
          }
        }
      },
      "Branch": {
        "type": "object",
        "description": "db 02 §2.1 `admin.branches` — the branch dimension of RBAC scope, distinct from the `org` reporting tree.",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "branch_code",
              "type",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              }
            }
          },
          {
            "$ref": "#/components/schemas/BranchFields"
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "BranchListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Branch"
                }
              }
            }
          }
        ]
      },
      "AuditLogEntry": {
        "type": "object",
        "description": "db-docs 15-audit `audit.audit_log`, read here as a governed, read-only lens (fsd 01 ADM-S04) — no `admin` table backs it; append-only, hash-chained.\n",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "action",
              "entity_type"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              },
              "action": {
                "type": "string",
                "description": "e.g. UPDATE_LEAVE_POLICY, EXPORT_PAYROLL."
              },
              "entity_type": {
                "type": "string"
              },
              "entity_id": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/Uuid"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "changed_by": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/Uuid"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "changed_by_name": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "ref→people.employees.full_name (changed_by), by projection (issue #1640). `changed_by` is a PRINCIPAL id, so it is walked through `xc.identities.subject_id` to the employee, falling back to the identity's own email. `null` when neither resolves — the Actor column then says so rather than printing the id."
              },
              "changed_by_role": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "before": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": true
              },
              "after": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": true
              },
              "ip_address": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          {
            "$ref": "#/components/schemas/AppendOnlyMeta"
          }
        ]
      },
      "AuditLogEntryListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/AuditLogEntry"
                }
              }
            }
          }
        ]
      },
      "AuditLogExportRequest": {
        "type": "object",
        "required": [
          "format"
        ],
        "additionalProperties": false,
        "properties": {
          "date_from": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "date_to": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "action": {
            "type": "string"
          },
          "entity_type": {
            "type": "string"
          },
          "changed_by": {
            "$ref": "#/components/schemas/Uuid"
          },
          "format": {
            "type": "string",
            "enum": [
              "CSV",
              "PDF"
            ]
          }
        }
      },
      "AuditLogExportJob": {
        "type": "object",
        "description": "Queued export artifact job (`XC-F07`); the export request itself is audited.",
        "required": [
          "job_id",
          "status"
        ],
        "properties": {
          "job_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "QUEUED",
              "RUNNING",
              "COMPLETED",
              "FAILED"
            ]
          },
          "file": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FileDownload"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "ReportDefinition": {
        "type": "object",
        "description": "db 02 §2.3 `admin.report_definitions` — a standard report over the reporting platform's materialized views/projections (`XC-F15`); the catalogue fields are system-defined, only the schedule is tenant-writable.\n",
        "required": [
          "id",
          "report_code",
          "category",
          "default_format",
          "is_scheduled",
          "status"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "report_code": {
            "type": "string",
            "readOnly": true
          },
          "name": {
            "allOf": [
              {
                "$ref": "#/components/schemas/LocalizedText"
              }
            ],
            "readOnly": true
          },
          "category": {
            "type": "string",
            "enum": [
              "HEADCOUNT",
              "ATTRITION",
              "ATTENDANCE",
              "PAYROLL",
              "LEAVE",
              "COMPLIANCE",
              "CUSTOM"
            ],
            "readOnly": true
          },
          "source_view": {
            "type": "string",
            "readOnly": true
          },
          "parameters": {
            "type": "array",
            "readOnly": true,
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "DATE",
                    "ENUM",
                    "UUID",
                    "TEXT"
                  ]
                },
                "required": {
                  "type": "boolean"
                },
                "options": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "default_format": {
            "type": "string",
            "enum": [
              "XLSX",
              "CSV",
              "PDF"
            ],
            "readOnly": true
          },
          "required_permission": {
            "type": [
              "string",
              "null"
            ],
            "readOnly": true
          },
          "is_scheduled": {
            "type": "boolean"
          },
          "schedule": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "cron": {
                    "type": "string"
                  },
                  "timezone": {
                    "type": "string"
                  },
                  "recipients": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "format": {
                    "type": "string",
                    "enum": [
                      "XLSX",
                      "CSV",
                      "PDF"
                    ]
                  }
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "DRAFT",
              "ACTIVE",
              "RETIRED"
            ],
            "readOnly": true
          }
        }
      },
      "ReportDefinitionListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ReportDefinition"
                }
              }
            }
          }
        ]
      },
      "ReportDefinitionScheduleUpdateRequest": {
        "type": "object",
        "required": [
          "is_scheduled"
        ],
        "additionalProperties": false,
        "properties": {
          "is_scheduled": {
            "type": "boolean"
          },
          "schedule": {
            "anyOf": [
              {
                "type": "object",
                "required": [
                  "cron",
                  "timezone",
                  "recipients",
                  "format"
                ],
                "properties": {
                  "cron": {
                    "type": "string"
                  },
                  "timezone": {
                    "type": "string"
                  },
                  "recipients": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "format": {
                    "type": "string",
                    "enum": [
                      "XLSX",
                      "CSV",
                      "PDF"
                    ]
                  }
                }
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "ReportRun": {
        "type": "object",
        "description": "db 02 §2.3 `admin.report_runs` — the evidential record of who ran what report, when, over which data window.",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "report_definition_id",
              "run_no",
              "trigger",
              "status",
              "format"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/Uuid"
              },
              "report_definition_id": {
                "$ref": "#/components/schemas/Uuid"
              },
              "run_no": {
                "$ref": "#/components/schemas/BusinessNo"
              },
              "requested_by": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/Uuid"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "trigger": {
                "type": "string",
                "enum": [
                  "MANUAL",
                  "SCHEDULED",
                  "API"
                ]
              },
              "parameters": {
                "type": "object",
                "additionalProperties": true
              },
              "status": {
                "type": "string",
                "enum": [
                  "QUEUED",
                  "RUNNING",
                  "COMPLETED",
                  "FAILED"
                ]
              },
              "format": {
                "type": "string",
                "enum": [
                  "XLSX",
                  "CSV",
                  "PDF"
                ]
              },
              "file": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/FileDownload"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "presigned URL, set once status = COMPLETED; bytes never transit Postgres."
              },
              "content_hash": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "SHA-256 of the stored artifact, set once status = COMPLETED."
              },
              "byte_size": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Artifact size in bytes, set once status = COMPLETED."
              },
              "row_count": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "error": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "started_at": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/Timestamp"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "completed_at": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/Timestamp"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            }
          },
          {
            "$ref": "#/components/schemas/AuditMeta"
          }
        ]
      },
      "ReportRunListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ReportRun"
                }
              }
            }
          }
        ]
      },
      "ReportRunCreateRequest": {
        "type": "object",
        "required": [
          "report_definition_id",
          "format"
        ],
        "additionalProperties": false,
        "properties": {
          "report_definition_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "resolved values for the definition's declared filters."
          },
          "format": {
            "type": "string",
            "enum": [
              "XLSX",
              "CSV",
              "PDF"
            ]
          }
        }
      },
      "TenantConfig": {
        "type": "object",
        "description": "db 02 §2.4 `admin.tenant_config` — namespaced key/value settings. Inbound platform services may write them, while this permission-checked admin command is the one tightly scoped product-side mutation path.\n",
        "required": [
          "id",
          "config_key",
          "category",
          "config_version"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "config_key": {
            "type": "string",
            "readOnly": true,
            "description": "dot-namespaced, e.g. branding.logo_url, payroll.cutoff_day."
          },
          "value": {
            "type": "object",
            "additionalProperties": true
          },
          "category": {
            "type": "string",
            "enum": [
              "BRANDING",
              "PAYROLL",
              "NOTIFICATION",
              "LOCALE",
              "GENERAL"
            ],
            "readOnly": true
          },
          "config_version": {
            "type": "integer",
            "readOnly": true,
            "description": "monotonic per key; stamped into downstream snapshots as the resolved key→version map."
          }
        }
      },
      "TenantConfigListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/TenantConfig"
                }
              }
            }
          }
        ]
      },
      "TenantConfigUpdateRequest": {
        "type": "object",
        "required": [
          "value"
        ],
        "additionalProperties": false,
        "description": "Only `value` is writable here — `config_key`/`category` are immutable identity; routed through the platform seam.",
        "properties": {
          "value": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "TenantConfigCreateRequest": {
        "type": "object",
        "required": [
          "config_key",
          "category",
          "value"
        ],
        "additionalProperties": false,
        "description": "Bootstraps a tenant-config row that does not exist yet. `config_key` is deliberately an enum, not a free string — this op only fills the gap left by provisioning (branding-only), never lets a caller mint an arbitrary config key. Widen the enum in the same PR that widens the API's own `CREATABLE_TENANT_CONFIG_KEYS` allowlist.\n",
        "properties": {
          "config_key": {
            "type": "string",
            "enum": [
              "locale.default",
              "locale.supported",
              "locale.rtl_locales"
            ]
          },
          "category": {
            "type": "string",
            "enum": [
              "LOCALE"
            ]
          },
          "value": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "Entitlement": {
        "type": "object",
        "description": "db 02 §2.4 `admin.entitlements` — platform-authored feature-flag/limit/quota keys (ADR 0009); the `/platform/*` seam is the only writer, this surface only displays them (cache is inbound-write-only).\n",
        "required": [
          "id",
          "entitlement_key",
          "kind",
          "status"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "entitlement_key": {
            "type": "string",
            "description": "e.g. maxEmployees, feature.payroll, feature.ewa."
          },
          "kind": {
            "type": "string",
            "enum": [
              "FEATURE_FLAG",
              "LIMIT",
              "QUOTA"
            ]
          },
          "bool_value": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "limit_value": {
            "type": [
              "integer",
              "null"
            ]
          },
          "current_usage": {
            "type": [
              "integer",
              "null"
            ]
          },
          "effective_from": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Timestamp"
              },
              {
                "type": "null"
              }
            ]
          },
          "effective_to": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Timestamp"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "SUSPENDED"
            ]
          }
        }
      },
      "EntitlementListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Entitlement"
                }
              }
            }
          }
        ]
      },
      "DivisionScope": {
        "type": "object",
        "description": "What the caller's `org_unit` overlay actually resolved to on this request — the closure the rows below were confined by. Returned so the console can render its scope banner (and the \"not anchored to a division\" state) from the server's own answer rather than inferring it from an empty payload.\n",
        "required": [
          "anchored_org_units",
          "closure_unit_count"
        ],
        "properties": {
          "anchored_org_units": {
            "type": "array",
            "description": "The **roots of the resolved closure** (`ref→org.org_units`) — derived as-built, not echoed from the grant: a unit inside `app.org_unit_ids` whose parent is not also inside it. Deriving is what keeps this list truthful when a configured root has since been deleted or re-parented, and collapses a redundant root nested under another into the one that actually bounds the reach. Empty ⇒ the caller holds the token but resolves no subtree, and the screen says so. Never a widened read.\n",
            "items": {
              "type": "object",
              "required": [
                "org_unit_id",
                "unit_code"
              ],
              "properties": {
                "org_unit_id": {
                  "$ref": "#/components/schemas/Uuid"
                },
                "unit_code": {
                  "type": "string"
                },
                "name": {
                  "$ref": "#/components/schemas/LocalizedText"
                },
                "unit_type": {
                  "type": "string"
                }
              }
            }
          },
          "selected_org_unit_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "description": "The `org_unit_id` the request narrowed to, or `null` when the response covers the full closure."
          },
          "closure_unit_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Org units in the resolved closure",
            "roots included.": null
          }
        }
      },
      "ProjectionFreshness": {
        "type": "object",
        "description": "Per-region read-model status. Every division figure is an eventually-consistent projection (`XC-F09`), so each region reports its own state and its own as-of time — the other regions still render regardless.\n\n**Three states, never two.** `available` — the figure is real, and `freshness` says how old it is. `unavailable` with **no** `reason` — the caller's role does not hold the OWNING module's token (the console gates each region on that token independently of the screen token), and the console renders \"restricted\". `unavailable` with `reason: projection_missing` — nothing has projected this key yet, and the console renders \"not available yet\". **Neither unavailable state is ever rendered as zero**: \"you may not see this\" and \"there is none\" are different facts about a division and conflating them is a lie about headcount.\n",
        "required": [
          "status",
          "as_of"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "available",
              "unavailable"
            ]
          },
          "reason": {
            "type": "string",
            "enum": [
              "projection_missing"
            ]
          },
          "freshness": {
            "type": "string",
            "enum": [
              "fresh",
              "delayed",
              "stale"
            ],
            "description": "Age of `as_of` (the CONSUMER's write time): fresh ≤ 60s, delayed ≤ 5min, stale after."
          },
          "as_of": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Timestamp"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "DivisionSummary": {
        "type": "object",
        "description": "fsd 01 ADM-S08 — the division console aggregate over the caller's org-unit closure. A read-only projection (`XC-F15`); no `org`/`admin` table backs any figure here. Deliberately carries **no money value**: workforce cost is Finance's, on `pay.payslip.cost_summary` (PAY-S20, under Payroll > Costs; PAY-S19 withdrawn 2026-09-02 by ADR 0069 (i)).\n\nEvery region below is a `ProjectionFreshness` envelope with its numbers folded in — the numbers are the SUM across the direct units in the closure, computed at read time under the caller's own authorised reach. A producer never pre-folds a subtree (db-docs 14): doing so would leak a unit the reader is not anchored to, or double-count where two anchors overlap.\n\n**Producer coverage as built (#433).** `headcount` and the roster have a live producer (`people`); the expense queue is read live from `xc.approval_inbox`. `attendance_today`, `attendance_period`, `leave_today`, `leave_calendar`, `work` and `velocity` have their read path, key contract and RLS overlay in place but **no emitting producer in their owning modules yet**, so they answer `unavailable` /`projection_missing` until those land. That is a stated, visible state on the screen — not a zero and not a silent blank.\n",
        "required": [
          "scope",
          "period",
          "headcount",
          "attendance_today",
          "attendance_period",
          "leave_today",
          "work",
          "velocity",
          "leave_calendar",
          "expense_queue"
        ],
        "properties": {
          "scope": {
            "$ref": "#/components/schemas/DivisionScope"
          },
          "period": {
            "type": "string",
            "pattern": "^\\d{4}-(0[1-9]|1[0-2])$",
            "description": "The month the period-keyed regions were resolved for, echoed from `period_start`."
          },
          "headcount": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ProjectionFreshness"
              },
              {
                "type": "object",
                "properties": {
                  "headcount": {
                    "type": "integer",
                    "minimum": 0
                  }
                }
              }
            ],
            "description": "projection over `people` — `ACTIVE` employees in the closure (key `division.people`)."
          },
          "attendance_today": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ProjectionFreshness"
              },
              {
                "type": "object",
                "properties": {
                  "present": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "scheduled": {
                    "type": "integer",
                    "minimum": 0
                  }
                }
              }
            ],
            "description": "projection over `attend` for today (key `division.attendance.today`). `scheduled` comes from the same projection, never a roster join. The console derives `present ÷ scheduled` only when `scheduled > 0` — a rate over a zero denominator would be a fabricated 0%, so the head count is shown instead.\n"
          },
          "attendance_period": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ProjectionFreshness"
              },
              {
                "type": "object",
                "properties": {
                  "present": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "absent": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "half_day": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "late": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "out_of_zone": {
                    "type": "integer",
                    "minimum": 0
                  }
                }
              }
            ],
            "description": "projection over `attend` for the month (key `division.attendance.<YYYY-MM>`)."
          },
          "leave_today": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ProjectionFreshness"
              },
              {
                "type": "object",
                "properties": {
                  "total": {
                    "type": "integer",
                    "minimum": 0
                  }
                }
              }
            ],
            "description": "projection over `leave` — `APPROVED` leave overlapping today (key `division.leave.today`)."
          },
          "work": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ProjectionFreshness"
              },
              {
                "type": "object",
                "properties": {
                  "open_tasks": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "overdue_tasks": {
                    "type": "integer",
                    "minimum": 0
                  }
                }
              }
            ],
            "description": "projection over `work` — the closure's live task load (key `division.work`)."
          },
          "velocity": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ProjectionFreshness"
              },
              {
                "type": "object",
                "properties": {
                  "by_unit": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "org_unit_id": {
                          "$ref": "#/components/schemas/Uuid"
                        },
                        "name": {
                          "$ref": "#/components/schemas/LocalizedText"
                        },
                        "completed": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "opened": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "overdue": {
                          "type": "integer",
                          "minimum": 0
                        }
                      }
                    }
                  }
                }
              }
            ],
            "description": "projection over `work` — per child unit throughput for the period (key `division.velocity.<YYYY-MM>`). **Throughput only, never a per-person ranking** (fsd 01 ADM-S08).\n"
          },
          "leave_calendar": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ProjectionFreshness"
              },
              {
                "type": "object",
                "properties": {
                  "entries": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "employee_id": {
                          "$ref": "#/components/schemas/Uuid"
                        },
                        "employee_name": {
                          "type": "string"
                        },
                        "leave_type_name": {
                          "$ref": "#/components/schemas/LocalizedText"
                        },
                        "start_date": {
                          "$ref": "#/components/schemas/DateOnly"
                        },
                        "end_date": {
                          "$ref": "#/components/schemas/DateOnly"
                        }
                      }
                    }
                  }
                }
              }
            ],
            "description": "projection over `leave` — one entry per approved absence in the period, for the month grid (key `division.leave.<YYYY-MM>`). The work week and holiday set the grid renders are **pack-driven** (`XC-F01`): Mon–Fri (India) vs Sun–Thu (KSA).\n"
          },
          "expense_queue": {
            "type": "object",
            "description": "**Counts only**, and live rather than projected — the pending/escalated size of the caller's own slice of the unified approvals inbox (`xc.approval_inbox`, `request_type = 'EXPENSE'`, closure-scoped, approver-scoped). It counts exactly the rows `admin.division_approval_inbox.list` returns, by construction, so the tile can never print a number the panel beneath it cannot open. `unavailable` when the caller holds no `xc.approval_inbox.list` token or has no employee record to have a queue at all. Every decision stays on `xc.approval_inbox.decide` (13-xc): this console is a **view**, never a second approval store (ADR 0027 §(d)/(e)).\n",
            "required": [
              "status"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "available",
                  "unavailable"
                ]
              },
              "pending": {
                "anyOf": [
                  {
                    "type": "integer",
                    "minimum": 0
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "escalated": {
                "anyOf": [
                  {
                    "type": "integer",
                    "minimum": 0
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            }
          }
        }
      },
      "DivisionRosterEntry": {
        "type": "object",
        "description": "One roster row from the `xc.dashboard_projections` roster projection — `ref→people.employees.full_name`, `ref→org.org_units.name`, `ref→org.designations.title`. **Name, unit and designation only**; no compensation, statutory identifier, or contact PII is projected onto this surface at all.\n",
        "required": [
          "employee_id",
          "full_name"
        ],
        "properties": {
          "employee_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "full_name": {
            "type": "string"
          },
          "org_unit_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "unit_name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "designation_title": {
            "$ref": "#/components/schemas/LocalizedText"
          }
        }
      },
      "DivisionRosterListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "required": [
              "data",
              "scope",
              "freshness"
            ],
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/DivisionRosterEntry"
                }
              },
              "scope": {
                "$ref": "#/components/schemas/DivisionScope"
              },
              "freshness": {
                "$ref": "#/components/schemas/ProjectionFreshness"
              }
            }
          }
        ]
      },
      "WorkspaceInvitation": {
        "type": "object",
        "description": "A cross-tenant binding invitation (#348, ADR 0061) as the API returns it. **The token is absent by construction** — only its SHA-256 is ever stored, and the secret reaches the invited address and nowhere else.\n",
        "required": [
          "id",
          "identity_id",
          "status",
          "expires_at"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "identity_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "ACCEPTED",
              "REVOKED"
            ]
          },
          "expires_at": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "revoked_at": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Timestamp"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "DivisionApprovalInboxItem": {
        "type": "object",
        "description": "One `xc.approval_inbox` row as this panel returns it — a **strict subset** of `13-xc.openapi.yaml`'s `ApprovalInboxItem`, restated here rather than `$ref`'d across files for two reasons. The served Swagger bundle inlines only `_shared.yaml`, so a cross-module reference would reach the mobile and portal teams unresolved; and the subset is the honest contract — the console shows a queue, not a decision record, so the decision, routing-provenance and refusal fields are deliberately absent. This surface adds **no field of its own**: the moment it did, it would be a second approval model (ADR 0027 §(d)/(e)). Everything omitted here is on `xc.approval_inbox.get`/`.list`, which is where a caller goes to act.\n",
        "required": [
          "id",
          "request_type",
          "requested_by",
          "status",
          "created_at",
          "version"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "request_type": {
            "type": "string",
            "enum": [
              "EXPENSE"
            ],
            "description": "Always `EXPENSE` on this surface."
          },
          "requested_by": {
            "$ref": "#/components/schemas/Uuid"
          },
          "current_approver_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "effective_approver_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "description": "The delegatee actually acting, when an `xc.delegations` rule applies (XC-F14)."
          },
          "org_unit_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "description": "The requester's submission-time org placement — the anchor this panel is confined by."
          },
          "amount": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Money"
              },
              {
                "type": "null"
              }
            ],
            "description": "A decimal string, never a float, and never summed into a division total by this console."
          },
          "currency_code": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 3,
            "maxLength": 3
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "ESCALATED"
            ]
          },
          "sla_due_at": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Timestamp"
              },
              {
                "type": "null"
              }
            ]
          },
          "created_at": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "version": {
            "type": "integer",
            "minimum": 0,
            "description": "The ETag the decide route requires as `If-Match`."
          }
        }
      },
      "DivisionApprovalInboxPage": {
        "description": "The division's slice of the ONE approvals inbox. `next_cursor` is always `null` as built: the panel is a fixed-size peek at the top of the queue, and paging an approval queue belongs on the inbox itself.\n",
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPage"
          },
          {
            "type": "object",
            "required": [
              "data",
              "scope"
            ],
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/DivisionApprovalInboxItem"
                }
              },
              "scope": {
                "$ref": "#/components/schemas/DivisionScope"
              }
            }
          }
        ]
      },
      "EmailSettings": {
        "type": "object",
        "description": "The workspace outbound-mail configuration as the org-admin Email section reads it. **No credential and no secret-store reference is present in this shape** — the `has_*` booleans are the entire answer about stored material.\n",
        "required": [
          "configured",
          "missing_fields",
          "provider",
          "effective_sender",
          "default_sender",
          "branding",
          "etag"
        ],
        "additionalProperties": false,
        "properties": {
          "configured": {
            "type": "boolean",
            "description": "The stored configuration is complete enough for `createMailClient` to build a client."
          },
          "missing_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Field NAMES still required for the selected provider (plus `fromAddress`, which every provider needs)."
          },
          "provider": {
            "description": "A stored provider outside the registry is not constructible and reads as unset.",
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "smtp",
                  "ses",
                  "resend",
                  "stub"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "smtp_host": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "smtp_port": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 1,
                "maximum": 65535
              },
              {
                "type": "null"
              }
            ]
          },
          "smtp_user": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "encryption": {
            "description": "The transport posture the jobs tier dials with. `STARTTLS` → `{ secure: false, requireTLS: true }` (the tested 587 reference posture), `TLS` → `{ secure: true }` (465, implicit TLS), `NONE` → plain. The retired `smtp_secure` boolean cannot express 587-STARTTLS vs 465-TLS, which is why migration 0110 replaced it; it is still dual-written for the portal contract and is not exposed here.\n",
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "STARTTLS",
                  "TLS",
                  "NONE"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "ses_region": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "has_smtp_pass": {
            "type": "boolean"
          },
          "has_resend_api_key": {
            "type": "boolean"
          },
          "has_ses_access_key_id": {
            "type": "boolean"
          },
          "has_ses_secret_access_key": {
            "type": "boolean"
          },
          "from_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "from_address": {
            "anyOf": [
              {
                "type": "string",
                "format": "email"
              },
              {
                "type": "null"
              }
            ]
          },
          "reply_to_email": {
            "anyOf": [
              {
                "type": "string",
                "format": "email"
              },
              {
                "type": "null"
              }
            ]
          },
          "bcc_owner": {
            "type": "boolean"
          },
          "verified_at": {
            "description": "The ONLY assertion of a confirmed successful send, stamped by the jobs tier and only for the tenant's own configuration — never by a test-send request, and never when the shared default sender stood in.\n",
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "default_sender": {
            "type": "object",
            "description": "The deployment's shared sender (`MAIL_DEFAULT_*`). Public addresses only — never the credential or its secret name.",
            "additionalProperties": false,
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "from_address": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "email"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "reply_to": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "email"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            }
          },
          "effective_sender": {
            "type": "string",
            "enum": [
              "TENANT",
              "DEFAULT",
              "NONE"
            ],
            "description": "ADR 0038's resolution order evaluated for display: a sendable tenant configuration wins, else the shared default sender (with the tenant's reply-to honoured), else `NONE` — the honest answer that nothing would go out.\n"
          },
          "branding": {
            "type": "object",
            "description": "READ-ONLY here. Authority is `admin.tenant_config['branding.*']` + `org.legal_entities` (ADR 0038); the Email section links to the Branding section to change it.\n",
            "additionalProperties": false,
            "properties": {
              "company_name": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "primary_color": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "logo_url": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "email_footer": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "logo_object_key": {
                "description": "A tenant-scoped XC-F07 object key, validated on write (`assertTenantKey` + `objectExists`).",
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "legal_entity_name": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            }
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "etag": {
            "type": "string",
            "description": "Echoed so a client can round-trip `If-Match` without reading response headers. `\"t<epochMillis>\"`, or `\"t0\"` when unconfigured."
          }
        }
      },
      "EmailSettingsUpdateRequest": {
        "type": "object",
        "minProperties": 1,
        "additionalProperties": false,
        "description": "Merge-PATCH. An ABSENT field is left alone; an explicit `null` CLEARS it. The four credential fields are write-only: they are reduced to a boolean declaration at the boundary and only the deterministic secret-store reference is stored, so they are never echoed back in any form.\n",
        "properties": {
          "provider": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "smtp",
                  "ses",
                  "resend",
                  "stub"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "smtp_host": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ]
          },
          "smtp_port": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 1,
                "maximum": 65535
              },
              {
                "type": "null"
              }
            ]
          },
          "smtp_user": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ]
          },
          "smtp_pass": {
            "description": "WRITE-ONLY. Never stored, never returned; presence declares the `email-smtp-pass` slot, `null` retracts it.",
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500,
                "writeOnly": true
              },
              {
                "type": "null"
              }
            ]
          },
          "encryption": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "STARTTLS",
                  "TLS",
                  "NONE"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "ses_region": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 64
              },
              {
                "type": "null"
              }
            ]
          },
          "ses_access_key_id": {
            "description": "WRITE-ONLY. Declares the `email-ses-access-key-id` slot.",
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500,
                "writeOnly": true
              },
              {
                "type": "null"
              }
            ]
          },
          "ses_secret_access_key": {
            "description": "WRITE-ONLY. Declares the `email-ses-secret-access-key` slot.",
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500,
                "writeOnly": true
              },
              {
                "type": "null"
              }
            ]
          },
          "resend_api_key": {
            "description": "WRITE-ONLY. Declares the `email-resend-api-key` slot.",
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500,
                "writeOnly": true
              },
              {
                "type": "null"
              }
            ]
          },
          "from_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ]
          },
          "from_address": {
            "anyOf": [
              {
                "type": "string",
                "format": "email",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ]
          },
          "reply_to_email": {
            "anyOf": [
              {
                "type": "string",
                "format": "email",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ]
          },
          "bcc_owner": {
            "type": "boolean"
          }
        }
      },
      "EmailSettingsTestRequest": {
        "type": "object",
        "required": [
          "to_address"
        ],
        "additionalProperties": false,
        "description": "The recipient is required — this surface has no owner-email fallback to guess from.",
        "properties": {
          "to_address": {
            "type": "string",
            "format": "email",
            "maxLength": 255
          }
        }
      },
      "EmailSettingsTestAccepted": {
        "type": "object",
        "required": [
          "ok",
          "status",
          "mail_message_id"
        ],
        "additionalProperties": false,
        "properties": {
          "ok": {
            "type": "boolean",
            "description": "Accepted for sending. **Not** a delivery confirmation."
          },
          "status": {
            "type": "string",
            "enum": [
              "QUEUED"
            ]
          },
          "mail_message_id": {
            "description": "The `xc.mail_messages` row minted for this send, so the caller can correlate the outcome.",
            "$ref": "#/components/schemas/Uuid"
          },
          "verified_at": {
            "description": "The stored verification timestamp, unchanged by this call.",
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "MailDelivery": {
        "type": "object",
        "description": "One row of the outbound-mail ledger (`xc.mail_messages`, FORCE RLS).",
        "required": [
          "id",
          "kind",
          "to_address",
          "subject",
          "status",
          "attempt_count",
          "created_at"
        ],
        "additionalProperties": false,
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "kind": {
            "type": "string",
            "description": "Dotted producer key — e.g. `admin.test_send`, `recruit.refusal`, `recruit.offer_letter`."
          },
          "to_address": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "DRAFT",
              "QUEUED",
              "SENDING",
              "SENT",
              "FAILED",
              "SUPPRESSED"
            ]
          },
          "sender_kind": {
            "description": "Which sender the dispatcher resolved. NULL until it runs.",
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "TENANT",
                  "DEFAULT"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "provider": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "attempt_count": {
            "type": "integer",
            "minimum": 0
          },
          "last_error_reason": {
            "description": "The STABLE, machine-readable `MailSendError.reason`.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "last_error": {
            "description": "The provider's own human text, verbatim. This is what makes a failed send fixable.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "suppression_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "queued_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "sent_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "settled_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "MailDeliveryListResponse": {
        "type": "object",
        "required": [
          "deliveries",
          "counts"
        ],
        "additionalProperties": false,
        "properties": {
          "deliveries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MailDelivery"
            }
          },
          "counts": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "sent": {
                "type": "integer",
                "minimum": 0
              },
              "failed": {
                "type": "integer",
                "minimum": 0
              },
              "suppressed": {
                "type": "integer",
                "minimum": 0
              },
              "pending": {
                "type": "integer",
                "minimum": 0,
                "description": "Still in flight: `DRAFT`, `QUEUED` or `SENDING`."
              }
            }
          }
        }
      },
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem detail (application/problem+json). The platform-wide error envelope (03 §1).",
        "required": [
          "type",
          "title",
          "status"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "default": "about:blank",
            "description": "Problem-type URI."
          },
          "title": {
            "type": "string",
            "description": "Short, human-readable summary (stable per type)."
          },
          "status": {
            "type": "integer",
            "description": "HTTP status code, duplicated for convenience."
          },
          "detail": {
            "type": "string",
            "description": "Human-readable explanation specific to this occurrence."
          },
          "instance": {
            "type": "string",
            "description": "URI reference for this specific occurrence."
          },
          "code": {
            "$ref": "#/components/schemas/ErrorCode"
          },
          "correlation_id": {
            "$ref": "#/components/schemas/Uuid"
          }
        }
      },
      "Uuid": {
        "type": "string",
        "format": "uuid",
        "description": "UUIDv7 surrogate primary key (db-docs/00 §3). Never the business identifier."
      },
      "DateOnly": {
        "type": "string",
        "format": "date",
        "description": "Calendar-only value (pay-period date, leave date, due date)."
      },
      "ValidationProblem": {
        "description": "422 field-level validation failure; extends Problem with a per-field error array. `detail` is ALWAYS present on a 422 (#1251) and is the human summary of `errors[]`: one offending field renders as `\"<field>: <its message>\"` (`withholding_amount: is required for an India entity`), several as `\"N fields were refused: a, b, c.\"`, capped at five names. It is display copy derived from members already in the same body — clients keep branching on `code` and mapping `errors[].pointer` back to a control, never parsing this sentence.\n",
        "allOf": [
          {
            "$ref": "#/components/schemas/Problem"
          },
          {
            "type": "object",
            "required": [
              "detail",
              "errors"
            ],
            "properties": {
              "detail": {
                "type": "string",
                "description": "Human summary of `errors[]`, always populated on a 422 so a client never has to fall back to generic copy for the one status that names a fixable field.\n",
                "example": "withholding_amount: is required for an India entity"
              },
              "errors": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "pointer",
                    "rule"
                  ],
                  "properties": {
                    "pointer": {
                      "type": "string",
                      "description": "JSON Pointer to the offending field, e.g. /claim_amount"
                    },
                    "rule": {
                      "type": "string",
                      "enum": [
                        "required",
                        "format",
                        "length",
                        "range",
                        "cross-field",
                        "async-server",
                        "consent-gated",
                        "uniqueness-business",
                        "not_found"
                      ],
                      "description": "FSD validation taxonomy rule (fsd-docs/00 §8.2). `not_found` is the server-side-lookup arm: a body field that REFERENCES another resource (e.g. `project_id` on a work entry) and did not resolve for this caller. It is reported here, under the field's pointer, and NOT as a 404 — the request addresses its own resource, so the failure belongs on the form field the client can actually fix (#805).\n"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "Timestamp": {
        "type": "string",
        "format": "date-time",
        "description": "timestamptz, serialized UTC ISO-8601. Presentation timezone is a client concern."
      },
      "LocalizedText": {
        "type": "object",
        "description": "Locale-keyed content map (db-docs/00 §9) for localized/white-label text (designation titles, announcement bodies, template names). Keys are the legal entity's active locale set.\n",
        "properties": {
          "en": {
            "type": "string"
          },
          "ar": {
            "type": "string"
          }
        },
        "additionalProperties": {
          "type": "string"
        }
      },
      "CurrencyCode": {
        "type": "string",
        "enum": [
          "INR",
          "SAR"
        ],
        "description": "ISO-4217. A legal entity operates in a single currency (db-docs/00 §6)."
      },
      "AuditMeta": {
        "type": "object",
        "description": "Standard mutable-entity columns (db-docs/00 §5). Read-only; present on every mutable read-model.",
        "readOnly": true,
        "properties": {
          "created_at": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "created_by": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "description": "null = system/jobs"
          },
          "updated_at": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "updated_by": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "deleted_at": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Timestamp"
              },
              {
                "type": "null"
              }
            ],
            "description": "soft-delete marker; live rows are null. Deleted rows are excluded by default scope."
          },
          "version": {
            "type": "integer",
            "description": "Optimistic-lock counter (where present); surfaces as the ETag."
          }
        }
      },
      "CursorPage": {
        "type": "object",
        "description": "Generic cursor-pagination envelope. List operations compose it via allOf to type `data`, e.g. `allOf: [ {$ref CursorPage}, { properties: { data: { items: {$ref Employee} } } } ]`.\n",
        "required": [
          "data",
          "page"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {}
          },
          "page": {
            "type": "object",
            "required": [
              "has_more"
            ],
            "properties": {
              "next_cursor": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "prev_cursor": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "has_more": {
                "type": "boolean"
              },
              "total_est": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Optional, capped, APPROXIMATE row estimate for grid \"X of Z\" display only — never an exact COUNT(*) on large tables (attend.attendance_records, xc.notifications, audit.*).\n"
              }
            }
          }
        }
      },
      "DecimalHours": {
        "type": "string",
        "pattern": "^-?\\d+(\\.\\d{1,2})?$",
        "description": "numeric(9,2) decimal hours/days as a string (OT hours, leave days). Never a float."
      },
      "HijriDisplay": {
        "type": "string",
        "readOnly": true,
        "description": "Formatted Umm al-Qura display string (`*_hijri`, db-docs/00 §6) accompanying a canonical Gregorian value on KSA-facing read-models (GOSI/WPS periods, Iqama expiry, KSA payslips). NEVER the source of truth; never accepted as input.\n"
      },
      "Money": {
        "type": "object",
        "description": "Exact decimal money (db-docs/00 §6). `amount` is a STRING so float never enters the wire.",
        "required": [
          "amount",
          "currency_code"
        ],
        "additionalProperties": false,
        "properties": {
          "amount": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d{1,2})?$",
            "description": "numeric(18,2) as a string, e.g. \"45000.00\"."
          },
          "currency_code": {
            "$ref": "#/components/schemas/CurrencyCode"
          }
        }
      },
      "Rate": {
        "type": "string",
        "pattern": "^-?\\d+(\\.\\d{1,6})?$",
        "description": "numeric(9,6) fraction as a string, e.g. \"0.120000\" for the 12% EPF rate. Never a float; percentages are stored as fractions."
      },
      "SoftRef": {
        "type": "object",
        "description": "Polymorphic cross-schema reference (db-docs/00 §13) — `(type → schema.table, id)`. Used by notifications, approvals inbox, audit.",
        "required": [
          "type",
          "id"
        ],
        "additionalProperties": false,
        "properties": {
          "type": {
            "type": "string",
            "description": "Target table, e.g. \"leave.leave_applications\"."
          },
          "id": {
            "$ref": "#/components/schemas/Uuid"
          }
        }
      },
      "AppendOnlyMeta": {
        "type": "object",
        "description": "Standard append-only/immutable columns (db-docs/00 §5/§8). No update/version/delete; corrections are new compensating rows.",
        "readOnly": true,
        "properties": {
          "created_at": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "created_by": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "FileDownload": {
        "type": "object",
        "description": "Authorized file handle (db-docs/00 §14, xc.files). Bytes never transit the API — the backend mints a time-limited presigned URL after authorization. Clients never see storage keys or hold storage credentials; the presigned URL is never persisted.\n",
        "required": [
          "file_id",
          "file_name",
          "url",
          "expires_at"
        ],
        "properties": {
          "file_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "file_name": {
            "type": "string"
          },
          "mime_type": {
            "type": "string"
          },
          "size_bytes": {
            "type": "integer"
          },
          "content_hash": {
            "type": [
              "string",
              "null"
            ],
            "description": "SHA-256",
            "present where tamper-evidence matters (payslips": null,
            "letters": null,
            "e-sign artifacts).": null
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Time-limited presigned URL."
          },
          "expires_at": {
            "$ref": "#/components/schemas/Timestamp"
          }
        }
      },
      "BusinessNo": {
        "type": "string",
        "description": "Tenant-unique, prefixed human reference (`employee_no`, `requisition_no`, `offer_no`, `payslip_no`, `claim_no`, `ticket_no`, `asset_no`, `case_no`). Read-model field; never a path key.\n"
      },
      "ErrorCode": {
        "type": "string",
        "description": "Machine-stable error code (paired with the HTTP status; drives client handling, not display copy).",
        "enum": [
          "VALIDATION_FAILED",
          "IDEMPOTENCY_KEY_REUSE",
          "VERSION_CONFLICT",
          "PRECONDITION_REQUIRED",
          "MAKER_EQUALS_CHECKER",
          "STEP_UP_REQUIRED",
          "CONSENT_REQUIRED",
          "TOKEN_DENIED",
          "SCOPE_DENIED",
          "OWNERSHIP_DENIED",
          "STATE_TRANSITION_INVALID",
          "FACE_MISMATCH",
          "FACE_VERIFICATION_REQUIRED",
          "WITHHOLDING_REVIEW_REQUIRED",
          "FEATURE_NOT_IN_PLAN",
          "PLAN_LIMIT_EXCEEDED",
          "TENANT_PAST_DUE",
          "TENANT_SUSPENDED",
          "TENANT_CANCELLED",
          "RATE_LIMITED",
          "NOT_FOUND"
        ]
      }
    },
    "parameters": {
      "PageSize": {
        "name": "page[size]",
        "in": "query",
        "required": false,
        "description": "Max items per page. Cursor pagination only (03 §2); offset pagination is rejected (ADR 0015).",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 200,
          "default": 50
        }
      },
      "PageAfter": {
        "name": "page[after]",
        "in": "query",
        "required": false,
        "description": "Opaque forward keyset cursor (from a prior page's `page.next_cursor`).",
        "schema": {
          "type": "string"
        }
      },
      "PageBefore": {
        "name": "page[before]",
        "in": "query",
        "required": false,
        "description": "Opaque backward keyset cursor (from a prior page's `page.prev_cursor`).",
        "schema": {
          "type": "string"
        }
      },
      "SortParam": {
        "name": "sort",
        "in": "query",
        "required": false,
        "description": "Comma-separated sort keys; leading `-` = descending. Each key MUST be in the operation's documented sort whitelist (free-form sort is rejected so the keyset cursor stays stable).\n",
        "schema": {
          "type": "string"
        }
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "description": "Client-generated unique key. REQUIRED on every mutation (this round tightens ADR 0015's \"platform + retryable mutations\" floor to ALL mutations for uniformity — offline punch/leave sync depends on it). Scoped (tenant, principal, route, key); a replay within the ~24h window returns the stored response with `Idempotency-Replayed: true`; the same key with a different body → 409 IDEMPOTENCY_KEY_REUSE (04 §1).\n",
        "schema": {
          "type": "string",
          "minLength": 8,
          "maxLength": 255
        }
      },
      "PathId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "UUIDv7 surrogate key of the target resource. Business numbers (`employee_no`, `claim_no`, …) are read-model fields, never path keys.",
        "schema": {
          "$ref": "#/components/schemas/Uuid"
        }
      },
      "IfMatch": {
        "name": "If-Match",
        "in": "header",
        "required": true,
        "description": "Optimistic-concurrency precondition for mutating a VERSIONED mutable entity (db-docs/00 §5 applies `version` where concurrent edits are likely). Value is the entity's current ETag (the row `version`). Absent → 428; stale → 412 (04 §2). N/A for append-only entities and for unversioned low-contention entities (their update ops simply omit this parameter).\n",
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing, expired, or invalid session token (no authenticated principal).",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Authenticated but denied — permission token not granted, out of scope (self/team/branch), not the owner, tenant suspended, or an MC-2 operation without a fresh step-up challenge. `code` ∈ TOKEN_DENIED | SCOPE_DENIED | OWNERSHIP_DENIED | MAKER_EQUALS_CHECKER | STEP_UP_REQUIRED | CONSENT_REQUIRED | TENANT_SUSPENDED. A plan feature-flag being off is 402 FEATURE_NOT_IN_PLAN, not 403 (see PaymentRequired).\n",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Per-principal/route rate limit exceeded.",
        "headers": {
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "PaymentRequired": {
        "description": "Plan entitlement refused (ADR 0009 entitlement order). `code` ∈ PLAN_LIMIT_EXCEEDED | FEATURE_NOT_IN_PLAN. For PLAN_LIMIT_EXCEEDED, `detail` names the resource, the current count and the cap; GroundIT publishes four enforced numeric limits — `maxEmployees`, `maxUsers`, `maxLegalEntities`, `maxWorkLocations` (README \"Plan limits and feature flags\"). FEATURE_NOT_IN_PLAN is the plan feature-flag gate (the One portal's `feature_locked` → 402). Both resolve via the One portal plan builder, not in-product.\n",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "Conflict": {
        "description": "Idempotency-key reuse with a different body, an invalid state transition, or a uniqueness/business-rule violation (fsd 00 §8.2). For database-backed uniqueness rules, detail names the exact violated rule; unmapped constraints are not collapsed into a generic 409.\n",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "UnprocessableEntity": {
        "description": "Field-level validation failed. The body carries both `errors[]` (per-field, pointer-addressed) and a `detail` summarising them — never an empty `detail` (#1251).\n",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ValidationProblem"
            },
            "examples": {
              "singleField": {
                "summary": "One refused field — `detail` names it",
                "value": {
                  "type": "about:blank",
                  "title": "Unprocessable Entity",
                  "status": 422,
                  "code": "VALIDATION_FAILED",
                  "detail": "withholding_amount: is required for an India entity",
                  "errors": [
                    {
                      "pointer": "/withholding_amount",
                      "rule": "required",
                      "message": "is required for an India entity"
                    }
                  ]
                }
              },
              "severalFields": {
                "summary": "Several refused fields — `detail` counts and names them",
                "value": {
                  "type": "about:blank",
                  "title": "Unprocessable Entity",
                  "status": 422,
                  "code": "VALIDATION_FAILED",
                  "detail": "2 fields were refused: effective_from, cap_amount.amount.",
                  "errors": [
                    {
                      "pointer": "/effective_from",
                      "rule": "cross-field",
                      "message": "Overlaps an existing version."
                    },
                    {
                      "pointer": "/cap_amount/amount",
                      "rule": "range",
                      "message": "Must be a non-negative decimal string."
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "Locked": {
        "description": "Tenant subscription `past_due` (ADR 0009): WRITES are blocked (423), reads still succeed. `code` = TENANT_PAST_DUE. Mutations return this; list/get operations do not.\n",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource does not exist OR is masked by RLS (tenant/self/team/branch scope) — the API does not distinguish, so existence is never confirmed across a scope boundary (02 §4 disclosure posture).\n",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "PreconditionFailed": {
        "description": "If-Match / ETag mismatch — the row changed since it was read (412, VERSION_CONFLICT).",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "PreconditionRequired": {
        "description": "If-Match header absent on a mutation of a versioned mutable entity (428).",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "Gone": {
        "description": "Tenant cancelled/purged (ADR 0009 V1.5 lifecycle). `code` = TENANT_CANCELLED. Login and all product calls are blocked.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      }
    },
    "headers": {
      "Location": {
        "description": "URI of the created/affected resource.",
        "schema": {
          "type": "string",
          "format": "uri-reference"
        }
      },
      "ETag": {
        "description": "Strong validator of the row `version` (e.g. `\"v7\"`). Use as `If-Match` on the next mutation.",
        "schema": {
          "type": "string"
        }
      },
      "RetryAfter": {
        "description": "Seconds to wait before retrying (on 429 / 503).",
        "schema": {
          "type": "integer"
        }
      }
    }
  }
}