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

# Re-run a finding's attacks to confirm a fix

> Re-runs every attack under the finding against the live target and drives its verification status. Call AFTER marking the finding fixed (PATCH .../close status=fixed) -- validating a finding that is not marked fixed returns verdict='not_eligible'. Returns the terminal verdict when the re-run finishes quickly; otherwise returns verdict='validating' with a replay_run_id -- re-read the finding's status via the findings list. Cross-workspace ids resolve to 404.



## OpenAPI

````yaml https://api.enokilabs.ai/openapi.json post /api/v1/findings/{finding_id}/validate
openapi: 3.1.0
info:
  title: Enoki External API
  description: >-
    Programmatic API for CI/CD integration. Authenticate with `Authorization:
    Bearer egk_...`.
  version: 0.1.0
servers: []
security: []
paths:
  /api/v1/findings/{finding_id}/validate:
    post:
      tags:
        - findings
      summary: Re-run a finding's attacks to confirm a fix
      description: >-
        Re-runs every attack under the finding against the live target and
        drives its verification status. Call AFTER marking the finding fixed
        (PATCH .../close status=fixed) -- validating a finding that is not
        marked fixed returns verdict='not_eligible'. Returns the terminal
        verdict when the re-run finishes quickly; otherwise returns
        verdict='validating' with a replay_run_id -- re-read the finding's
        status via the findings list. Cross-workspace ids resolve to 404.
      operationId: api_validate_finding_api_v1_findings__finding_id__validate_post
      parameters:
        - name: finding_id
          in: path
          required: true
          schema:
            type: string
            title: Finding Id
        - name: Authorization
          in: header
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            description: Bearer token with API key
            title: Authorization
          description: Bearer token with API key
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiValidateResponse'
        '404':
          description: Finding not found
        '409':
          description: A validation is already running for this finding
        '422':
          description: The finding's target cannot be wired for replay
        '429':
          description: Concurrency or daily replay cap exceeded
components:
  schemas:
    ApiValidateResponse:
      properties:
        finding_id:
          type: string
          title: Finding Id
          description: The finding that was validated.
        replay_run_id:
          type: string
          title: Replay Run Id
          description: >-
            The replay run that re-ran the finding's attacks. Empty when the
            finding was not eligible and no run was spent.
        verdict:
          type: string
          enum:
            - resolved
            - still_broken
            - not_eligible
            - validating
          title: Verdict
          description: >-
            resolved: every attack no longer reproduces (finding
            FIXED_VERIFIED). still_broken: at least one attack still reproduces
            or could not be judged. not_eligible: mark the finding fixed before
            validating -- it was not in a verifiable state. validating: still
            running -- re-read the finding's status via the findings list.
        finding:
          $ref: '#/components/schemas/ApiFindingItem'
          description: >-
            Post-validate finding, incl. status and per-attack
            last_replay_status.
      type: object
      required:
        - finding_id
        - replay_run_id
        - verdict
        - finding
      title: ApiValidateResponse
      description: |-
        Outcome of POST /api/v1/findings/{finding_id}/validate.

        Ships one derived convenience field, ``verdict``, alongside the
        embedded finding. The finding carries the durable truth -- its
        fine-grained ``status`` and every attack's ``last_replay_status`` --
        while ``verdict`` collapses that into the single signal a remediation
        loop acts on.
    ApiFindingItem:
      properties:
        finding_id:
          type: string
          title: Finding Id
        lens:
          $ref: '#/components/schemas/Lens'
        category:
          type: string
          title: Category
        severity:
          $ref: '#/components/schemas/FindingSeverity'
        description:
          type: string
          title: Description
        expected_behavior:
          type: string
          title: Expected Behavior
        status:
          type: string
          title: Status
        created_at:
          type: string
          title: Created At
        attacks:
          items:
            $ref: '#/components/schemas/ApiAttackItem'
          type: array
          title: Attacks
      type: object
      required:
        - finding_id
        - lens
        - category
        - severity
        - description
        - expected_behavior
        - status
        - created_at
        - attacks
      title: ApiFindingItem
      description: |-
        One finding in the external API response.

        ``severity`` is typed as the canonical ``FindingSeverity`` enum so
        OpenAPI publishes the allowed values and JSON output is always
        lowercase. ``attacks`` carries the per-probe replay artefacts; the
        finding row carries only the technique-level narrative shared
        across every attack under it.
    Lens:
      type: string
      enum:
        - security
        - safety
        - quality
        - policy
      title: Lens
      description: |-
        Taxonomy partition a Finding (or test suite) is scoped to.

        Each lens is a top-level taxonomy bucket prefix. ``security`` and
        ``safety`` are the v1 lenses; ``quality`` and ``policy`` are
        reserved for future expansion. The lens drives:

        * Discriminator on the persisted ``Finding`` (security vs safety
          subtypes).
        * Security-scope enforcement at ingest (security-lens runs may
          only emit ``security.*`` categories).
        * Per-lens system prompts at the generator and retest layers.
    FindingSeverity:
      type: string
      enum:
        - critical
        - high
        - medium
        - low
      title: FindingSeverity
      description: Business-impact severity levels, ordered from most to least severe.
    ApiAttackItem:
      properties:
        attack_id:
          type: string
          title: Attack Id
        score:
          type: integer
          title: Score
        source:
          $ref: '#/components/schemas/ApiAttackSource'
        replay_script:
          items:
            $ref: '#/components/schemas/ReplayStepResponse'
          type: array
          title: Replay Script
        last_replay_status:
          type: string
          enum:
            - pending
            - succeeded
            - failed
            - inconclusive
            - stale
          title: Last Replay Status
        last_replayed_at:
          anyOf:
            - type: string
            - type: 'null'
          title: Last Replayed At
        created_at:
          type: string
          title: Created At
      type: object
      required:
        - attack_id
        - score
        - source
        - replay_script
        - last_replay_status
        - created_at
      title: ApiAttackItem
      description: One attack inside a finding in the external API response.
    ApiAttackSource:
      properties:
        source_type:
          $ref: '#/components/schemas/FindingSourceType'
        assessment_id:
          type: string
          title: Assessment Id
        attack_index:
          type: integer
          title: Attack Index
        date:
          anyOf:
            - type: string
            - type: 'null'
          title: Date
      type: object
      required:
        - source_type
        - assessment_id
        - attack_index
        - date
      title: ApiAttackSource
      description: Provenance block of one attack in the external API response.
    ReplayStepResponse:
      properties:
        step:
          type: string
          enum:
            - chat
            - http
            - assert
          title: Step
        message:
          anyOf:
            - type: string
            - type: 'null'
          title: Message
        response:
          anyOf:
            - type: string
            - type: 'null'
          title: Response
        session_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Session Id
        method:
          anyOf:
            - type: string
            - type: 'null'
          title: Method
        url:
          anyOf:
            - type: string
            - type: 'null'
          title: Url
        headers:
          anyOf:
            - additionalProperties:
                type: string
              type: object
            - type: 'null'
          title: Headers
        body:
          anyOf:
            - type: string
            - type: 'null'
          title: Body
        response_status:
          anyOf:
            - type: integer
            - type: 'null'
          title: Response Status
        response_body:
          anyOf:
            - type: string
            - type: 'null'
          title: Response Body
        target:
          anyOf:
            - type: string
            - type: 'null'
          title: Target
        assertion:
          anyOf:
            - type: string
            - type: 'null'
          title: Assertion
        expected_behavior:
          anyOf:
            - type: string
            - type: 'null'
          title: Expected Behavior
        capture_as:
          anyOf:
            - type: string
            - type: 'null'
          title: Capture As
      type: object
      required:
        - step
      title: ReplayStepResponse
      description: |-
        One replay-script step exposed via API.

        Uses a flat shape (rather than a discriminated union per type) to
        keep the wire representation simple -- the frontend reads ``step``
        to decide how to render each entry.
    FindingSourceType:
      type: string
      enum:
        - manual
        - adaptive_attacker
        - test_suite
        - drill_down
      title: FindingSourceType
      description: |-
        Pipeline that produced an ``Attack``.

        Drives source-conditional ingest behaviour: security-scope
        enforcement is gated on ``ADAPTIVE_ATTACKER`` because the SDK
        runner filters its agent prompt to ``security.*`` and the gate at
        ingest rejects out-of-scope categories. ``MANUAL`` and
        ``TEST_SUITE`` bypass that gate -- curated pentest yamls have
        already been triaged, and suite-runner findings are scoped by the
        suite's own category list. ``DRILL_DOWN`` is a synthetic
        ``assessment_id`` keyed by the drill-down run that produced the
        variant attack.

````