> ## Documentation Index
> Fetch the complete documentation index at: https://docs.parmanasystems.com/llms.txt
> Use this file to discover all available pages before exploring further.

# List pending policy changes (maker-checker)

> Lists Pending Policy Changes, each alongside a diff view: current (the live content at (policyName, policyVersion) today, or null if that version has never been published) and proposed (the change's own proposedContent). Requires a human-authenticated caller, the same discipline as POST .../pending-changes.




## OpenAPI

````yaml /openapi.bundled.yaml get /policies/pending-changes
openapi: 3.1.0
info:
  title: Parmana API
  version: 1.0.0
  description: >
    Parmana is an Execution Trust Infrastructure that ensures there is no gap
    between what humans decide and what AI systems do. The API enables creation,
    execution, verification, replay, and auditing of Business Transactions
    through cryptographically verifiable Execution Trust Records.


    **Every route requires a caller bearer key**, except the liveness/readiness
    probes and documentation/verification routes that must be reachable with no
    credential: GET /health, GET /ready, GET /openapi.yaml, GET /documentation,
    GET /reference, POST /refusal/verify, POST /audit/verify, GET /keys/{keyId},
    and GET /.well-known/jwks.json. Send `Authorization: Bearer <key>` on every
    other request. Keys are issued by `scripts/generate-api-key.ts` and
    configured server-side via `PARMANA_API_KEYS`; only a hash of each key is
    ever held by the server, verified in constant time. A missing or invalid
    credential returns 401 before a Business Transaction is even constructed,
    independent of Policy evaluation and gateway attestation, see
    `packages/api/src/middleware/caller-auth.ts` and
    [Authentication](/api-reference/authentication). Local development may set
    `PARMANA_AUTH_DISABLED=true` to skip this middleware entirely; that flag
    must never be set in a real deployment.
  contact:
    name: Parmana Systems
    email: founder@parmanasystems.com
  license:
    name: Proprietary, source-available for evaluation only, see LICENSE
    url: https://github.com/pavancharak/AgentLabsBuildathon/blob/main/LICENSE
servers:
  - url: http://localhost:3000
    description: Local (packages/api, PORT env var, default 3000)
security:
  - bearerAuth: []
tags:
  - name: Execution
    description: >-
      Executes a Business Transaction through the complete Execution Trust
      pipeline
  - name: Transactions
    description: Business Transaction creation and retrieval
  - name: Verification
    description: Deterministic verification of an Execution Trust Record
  - name: Receipts
    description: Cryptographically signed Execution Trust Receipts
  - name: Trust Records
    description: Execution Trust Record retrieval
  - name: Replay
    description: Deterministic replay of a recorded Execution Trust Record
  - name: Policies
    description: Policy existence/readability check
  - name: Policy Governance
    description: Maker-checker proposal, listing, approval, and rejection of policy changes
  - name: Refusal Records
    description: >-
      Durable, signed evidence that a policy decision rejected a transaction
      (RFC-0021)
  - name: Audit
    description: >-
      Signed caller-authentication audit events, independently
      third-party-verifiable
  - name: System
    description: Operational endpoints
paths:
  /policies/pending-changes:
    get:
      tags:
        - Policy Governance
      summary: List pending policy changes (maker-checker)
      description: >
        Lists Pending Policy Changes, each alongside a diff view: current (the
        live content at (policyName, policyVersion) today, or null if that
        version has never been published) and proposed (the change's own
        proposedContent). Requires a human-authenticated caller, the same
        discipline as POST .../pending-changes.
      operationId: listPendingPolicyChanges
      parameters:
        - name: status
          in: query
          required: false
          schema:
            type: string
            enum:
              - PENDING_APPROVAL
              - APPROVED
              - REJECTED
      responses:
        '200':
          description: Pending Policy Changes, with diff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pending-changes-list-response.schema'
              examples:
                oneOpen:
                  summary: Real captured response
                  value:
                    changes:
                      - pendingPolicyChangeId: 6f4e4020-adf5-4449-938d-27aab58f66b7
                        policyName: openapi-capture-demo
                        policyVersion: 1.0.0
                        proposedContent:
                          policyId: openapi-capture-demo
                          policyVersion: 1.0.0
                          schemaVersion: 1.0.0
                          rules:
                            - id: always-approve
                              condition:
                                always: true
                              outcome:
                                action: approve
                                reason: OpenAPI spec capture fixture
                        proposedBy: human-maker
                        proposedAt: '2026-09-15T03:47:13.920Z'
                        status: PENDING_APPROVAL
                        reason: >-
                          Capture a real Pending Policy Change for the OpenAPI
                          spec
                        diff:
                          current: null
                          proposed:
                            policyId: openapi-capture-demo
                            policyVersion: 1.0.0
                            schemaVersion: 1.0.0
                            rules:
                              - id: always-approve
                                condition:
                                  always: true
                                outcome:
                                  action: approve
                                  reason: OpenAPI spec capture fixture
        '400':
          description: >-
            status query param is not one of PENDING_APPROVAL, APPROVED,
            REJECTED.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.schema'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: Caller is not human-credentialed (NON_HUMAN_CALLER_DENIED).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.schema'
components:
  schemas:
    pending-changes-list-response.schema:
      title: Pending Changes List Response
      description: >-
        Response returned by GET /policies/pending-changes. Each entry is a
        Pending Policy Change plus a diff view: current (the live content at
        (policyName, policyVersion) today, or null if that version has never
        been published) and proposed (the change's own proposedContent).
      type: object
      additionalProperties: false
      required:
        - changes
      properties:
        changes:
          type: array
          items:
            allOf:
              - $ref: '#/components/schemas/pending-policy-change.schema'
              - type: object
                required:
                  - diff
                properties:
                  diff:
                    type: object
                    additionalProperties: false
                    required:
                      - current
                      - proposed
                    properties:
                      current:
                        description: >-
                          The live policy.json content today, or null if this
                          version has never been published.
                      proposed:
                        description: The same value as this entry's own proposedContent.
      examples:
        - changes:
            - pendingPolicyChangeId: 6f4e4020-adf5-4449-938d-27aab58f66b7
              policyName: openapi-capture-demo
              policyVersion: 1.0.0
              proposedContent:
                policyId: openapi-capture-demo
                policyVersion: 1.0.0
                schemaVersion: 1.0.0
                rules:
                  - id: always-approve
                    condition:
                      always: true
                    outcome:
                      action: approve
                      reason: OpenAPI spec capture fixture
              proposedBy: human-maker
              proposedAt: '2026-09-15T03:47:13.920Z'
              status: PENDING_APPROVAL
              reason: Capture a real Pending Policy Change for the OpenAPI spec
              diff:
                current: null
                proposed:
                  policyId: openapi-capture-demo
                  policyVersion: 1.0.0
                  schemaVersion: 1.0.0
                  rules:
                    - id: always-approve
                      condition:
                        always: true
                      outcome:
                        action: approve
                        reason: OpenAPI spec capture fixture
    error.schema:
      title: Error Response
      description: >-
        Shared error envelope produced by
        packages/api/src/middleware/error-handler.ts and by every route's inline
        validation checks. error is always a plain human-readable string (never
        a nested object). code is present only when the failure was a
        RuntimeError subclass reaching the centralized error handler
        (VerificationFailedError, ReceiptGenerationError, or an uncategorized
        RuntimeError); it is absent from every inline route-level check
        (businessTransactionId format/required checks) and from
        BusinessTransactionValidationError, PolicyValidationError,
        SignalValidationError, PolicyNotFoundError,
        DuplicateBusinessTransactionError, and the generic 500 fallback. POST
        /policies/validate does NOT use this envelope at all. See its own
        response schema. For the triggering condition and recommended caller
        action behind any specific error/code/status combination, see the Error
        catalog at /api-reference/error-catalog.
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          type: string
          description: Human-readable error message.
        code:
          type: string
          description: >-
            Stable machine-readable error code. Only present for errors that
            reach the handler as a RuntimeError.
          examples:
            - RUNTIME_ERROR
            - VERIFICATION_FAILED
            - RECEIPT_GENERATION_FAILED
      examples:
        - error: businessTransactionId must be a valid UUID.
        - error: >-
            Business Transaction 'eed2a972-1bf5-4166-8472-761f76fbf1b2' already
            exists.
        - error: >-
            Execution rejected: Vendor payment rejected because the assessed
            payment risk exceeds the maximum permitted threshold.
          code: RUNTIME_ERROR
    pending-policy-change.schema:
      title: Pending Policy Change
      description: >-
        A proposed change to a policy's content, held in a durable pending state
        until a second, distinct human explicitly approves or rejects it (Policy
        Governance, maker-checker). Only ever moves from PENDING_APPROVAL to
        APPROVED or REJECTED, exactly once.
      type: object
      additionalProperties: true
      required:
        - pendingPolicyChangeId
        - policyName
        - policyVersion
        - proposedContent
        - proposedBy
        - proposedAt
        - status
        - reason
      properties:
        pendingPolicyChangeId:
          type: string
          description: Unique Pending Policy Change identifier.
        policyName:
          type: string
          description: >-
            The policy this proposal targets, same identifier as
            Policy.policyId.
        policyVersion:
          type: string
          description: >-
            The existing version this proposal is a change against ("the version
            being replaced"). Not necessarily equal to proposedContent's own
            declared version: an in-place patch and a version bump are both
            legitimate.
        proposedContent:
          type: object
          description: >-
            The full proposed policy.json content, in its entirety, not a diff
            or patch.
          additionalProperties: true
        proposedBy:
          type: string
          description: >-
            Identity of the proposer (maker). Always a human-authenticated
            (credentialHolderType USER) caller.
        proposedAt:
          type: string
          format: date-time
        status:
          type: string
          enum:
            - PENDING_APPROVAL
            - APPROVED
            - REJECTED
        reason:
          type: string
          description: Free-text justification from the proposer, required at creation.
        resolvedBy:
          type: string
          description: >-
            Identity of the resolver (checker). Absent while PENDING_APPROVAL.
            Never equal to proposedBy.
        resolvedAt:
          type: string
          format: date-time
          description: Absent while PENDING_APPROVAL.
        rejectionReason:
          type: string
          description: Present only when status is REJECTED.
        coverageWarnings:
          type: array
          description: >-
            Present only when non-empty: uncovered-fact warnings from
            PolicyValidator.findUncoveredFacts against proposedContent.
          items:
            type: string
        ruleConflicts:
          type: array
          description: >-
            Present only when non-empty: advisory rule-conflict warnings from
            PolicyValidator.findRuleConflicts against proposedContent, never
            blocking.
          items:
            type: string
      examples:
        - pendingPolicyChangeId: 6f4e4020-adf5-4449-938d-27aab58f66b7
          policyName: openapi-capture-demo
          policyVersion: 1.0.0
          proposedContent:
            policyId: openapi-capture-demo
            policyVersion: 1.0.0
            schemaVersion: 1.0.0
            rules:
              - id: always-approve
                condition:
                  always: true
                outcome:
                  action: approve
                  reason: OpenAPI spec capture fixture
          proposedBy: human-maker
          proposedAt: '2026-09-15T03:47:13.920Z'
          status: APPROVED
          reason: Capture a real Pending Policy Change for the OpenAPI spec
          resolvedBy: human-checker
          resolvedAt: '2026-09-15T03:48:03.586Z'
  responses:
    Unauthorized:
      description: >-
        Missing or invalid caller credential (StaticKeyAuthenticator returned no
        identity). Real captured response,
        packages/api/src/middleware/caller-auth.ts.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/error.schema'
          examples:
            authRequired:
              summary: Real captured response, missing or invalid Authorization header
              value:
                error: authentication required
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >
        Caller API key issued by scripts/generate-api-key.ts. Sent as
        Authorization: Bearer <key>. Verified against a stored SHA-256 hash in
        constant time by packages/api/src/auth/StaticKeyAuthenticator.ts.
        Required on every route not listed as exempt in this document's
        top-level description. See /api-reference/authentication.

````