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

# Explain why a job is not running.

> When dequeue is a policy decision, "it is available but not running" has a
specific, knowable cause. Without this, a job held back by a misconfigured rate
class is indistinguishable from a slow worker -- which is the failure mode that
makes operators distrust a limiter and turn it off.




## OpenAPI

````yaml /api/headgate.openapi.yaml get /jobs/{id}/admission
openapi: 3.1.0
info:
  title: headgate control API
  version: 0.1.0
  description: >
    The web UI is one client of this control API and gets no

    privileged access — asynqmon reads Redis directly, which is why its
    compatibility

    note is three minor versions stale.


    Both the Go and Rust implementations serve this spec, and the conformance
    suite

    asserts identical responses. Every list endpoint is bounded to prevent
    inspection

    from becoming an unbounded store operation: asynq's

    GetQueueInfo is O(number of groups) and has pinned Redis CPU for seconds in

    production. Monitoring caused the outage.


    DERIVED FROM THE ARCHITECTURE, NOT FROM A PREDECESSOR'S UI. The first draft
    of this

    spec was the asynq Inspector surface -- list by state, act on one job, pause
    a queue

    -- with new nouns bolted on. That inherited three problems: it omitted bulk

    operations, history, and enqueue (which asynq and apalis-board respectively
    DO have),

    and more importantly it had no endpoint for the question this system's own
    design

    creates. When dequeue is an admission decision, the operator's first
    question is not

    "what is in the queue" but "why is THIS job not running" -- see
    /jobs/{id}/admission.

    No predecessor needs that endpoint because no predecessor has a gate.
servers:
  - url: /api/v1
security: []
paths:
  /jobs/{id}/admission:
    get:
      summary: Explain why a job is not running.
      description: >
        When dequeue is a policy decision, "it is available but not running" has
        a

        specific, knowable cause. Without this, a job held back by a
        misconfigured rate

        class is indistinguishable from a slow worker -- which is the failure
        mode that

        makes operators distrust a limiter and turn it off.
      parameters:
        - $ref: '#/components/parameters/Id'
      responses:
        '200':
          description: Current admission decision and blocking policy details.
          content:
            application/json:
              schema:
                type: object
                required:
                  - admissible
                properties:
                  admissible:
                    type: boolean
                  blocked_by:
                    type:
                      - string
                      - 'null'
                    enum:
                      - rate_class
                      - concurrency_limit
                      - fairness
                      - quarantine
                      - schedule
                      - queue_paused
                      - null
                    description: >
                      The policy currently preventing admission. Null means no
                      policy is

                      blocking the job: it may already be running, be pending
                      promotion,

                      or have reached a terminal state. Use `detail.state` to
                      distinguish

                      those lifecycle cases.
                  detail:
                    type: object
                    description: >-
                      State of the blocking policy — tokens left, position in
                      the partition queue, crash count.
                  estimated_admission_ms:
                    type:
                      - integer
                      - 'null'
                    description: >
                      Estimated wait when a time-based estimate can be
                      calculated. Null

                      means no estimate is available; it does not by itself mean
                      the

                      condition requires operator action.
components:
  parameters:
    Id:
      name: id
      in: path
      required: true
      schema:
        type: string

````