{
  "contract_id": "millwork.verifier-dock.v1",
  "contract_version": "1.0.0",
  "published_url": "https://docs.getmillwork.dev/contracts/verifier-dock/v1.json",
  "title": "Millwork verifier dock contract, version 1",
  "summary": "Everything an endpoint must honour to serve as a Millwork verifier dock: the request Millwork sends, the response it will accept, the reserved probe, the timing budgets, the transport and access rules, and which response fields survive onto a receipt.",
  "embedded_schemas": "`request.schema` and `response.schema` are complete draft-2020-12 schemas. Extract either one and hand it to a validator as it stands. Neither carries an `$id`: a JSON Schema identifier may not contain a fragment, and these are embedded in this document rather than served at their own URL.",
  "stability": "Additive only within version 1. A change that would reject a dock that conforms today is published as version 2 at its own URL; this document and its URL keep their meaning.",
  "request": {
    "method": "POST",
    "path": "the URL registered for the verifier; Millwork appends nothing to it",
    "headers": {
      "content-type": "application/json",
      "authorization": "present only for an authenticated dock; see access.modes"
    },
    "body_is_the_whole_contract": "The body carries exactly one property. Millwork sends no execution, slice, verifier or request identifier, so a dock cannot correlate a call to a Millwork run from the request alone.",
    "schema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "title": "Millwork verifier dock request body",
      "type": "object",
      "properties": {
        "candidate": {
          "description": "The output being checked. Any JSON value, including a string, an object, null, or a number. A dock must not assume an object.",
          "$comment": "JSON Schema has no keyword for 'any value', and omitting `type` is exactly that."
        }
      },
      "required": ["candidate"],
      "additionalProperties": false
    }
  },
  "response": {
    "status": "Millwork accepts a verdict only from a 2xx response. Any other status is a technical failure, never a rejection of the candidate.",
    "body_media_type": "application/json",
    "unknown_properties": "ignored",
    "unknown_properties_detail": "Millwork reads the four properties below and ignores every other top-level property. A dock may return extra fields; they are neither rejected nor recorded.",
    "invalid_response_is_not_a_verdict": "A body that fails this schema is a contract violation. Millwork records no verdict for it; it does not read it as `is_correct: false`.",
    "schema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "title": "Millwork verifier dock response body",
      "type": "object",
      "properties": {
        "is_correct": {
          "description": "The verdict. A real JSON boolean; the string \"true\" and the number 1 are rejected, never coerced.",
          "type": "boolean"
        },
        "quality_score": {
          "description": "How good the output was, independent of the verdict. A finite number from 0 to 1 inclusive.",
          "type": "number",
          "minimum": 0,
          "maximum": 1
        },
        "anchor_results": {
          "description": "Named rules and whether each held. Every value must be a boolean. This is the field that tells a reader which rule failed without re-running anything.",
          "type": "object",
          "additionalProperties": { "type": "boolean" }
        },
        "named_metrics": {
          "description": "Named numeric measurements. Every value must be a finite number. Validated on arrival and then dropped: see retention.",
          "type": "object",
          "additionalProperties": { "type": "number" }
        }
      },
      "required": ["is_correct", "quality_score"],
      "additionalProperties": true
    }
  },
  "reserved_probe": {
    "candidate": { "solverapi_probe": "registration_preflight" },
    "when_sent": "At registration and whenever a connection is tested. The probe carries no tenant workload content.",
    "required_behaviour": "Answer that exact candidate object directly with 2xx and a valid response body. Do not call a model, evaluator, or any paid or slow service for it.",
    "expected_body": { "is_correct": false, "quality_score": 0 },
    "expected_body_note": "A valid negative result. A dock that answers the probe with `is_correct: true` still registers; the negative result is what keeps the probe from being mistaken for a real pass.",
    "fail_closed": "An ordinary candidate that happens to equal the marker must be refused the same way. The marker is never a path to a passing verdict.",
    "registration_is_not_gated_on_the_verdict": "A valid negative probe response registers the verifier. Contract validation does not decide readiness on the verdict's value."
  },
  "timing": {
    "probe_budget_ms": 3000,
    "probe_budget_note": "Tighter than a run: the probe holds the registration request's database transaction open while it runs.",
    "run_budget_ms": 10000,
    "run_budget_note": "Fixed, not configurable by the tenant. A managed connection may be given less than this when its authorization window is shorter; a dock cannot rely on receiving the full budget.",
    "retries": 0,
    "retries_note": "Millwork does not retry a verifier call. A dock that exceeds its budget produces a technical failure, not a rejection.",
    "max_response_bytes": 1048576,
    "max_response_bytes_note": "The connection is destroyed at this ceiling rather than growing the caller's memory."
  },
  "transport": {
    "scheme": "https",
    "scheme_note": "http is refused before any request is made, including for a loopback address.",
    "redirects": "not followed",
    "redirects_note": "A 3xx comes back as the dispatch result. It is not a verdict and not a reachable endpoint.",
    "address_policy": "DNS is re-resolved on every dispatch, and a resolved address in a private or otherwise reserved range is refused. No address is cached across calls.",
    "request_body_framing": "chunked",
    "request_body_framing_note": "Millwork sends no Content-Length header, so the POST body is chunked. A gateway that refuses a chunked request body cannot serve as a dock.",
    "secrets_in_the_url": "refused",
    "secrets_in_the_url_note": "A registered endpoint URL carrying credential-shaped material is refused at registration."
  },
  "access": {
    "modes": {
      "public": "No Authorization header is sent. The dock must answer an unauthenticated POST.",
      "managed": "Millwork holds a key for the dock and sends it as `Authorization: Bearer <key>`. This is the remote connection mode, named on `millwork verifier connect --access`."
    },
    "local_test_modes_are_a_different_vocabulary": "The local compatibility kit's `--access public|authenticated` describes what the adapter under test expects, in a process that never contacts Millwork. The remote `public|managed` describes who holds the key for a real connection. The two vocabularies are deliberately distinct and neither is a synonym for the other.",
    "authentication_failure": "For a connection that supplies a credential, a 401 or 403 is an authentication failure, not a verdict."
  },
  "retention": {
    "on_the_receipt": ["is_correct", "quality_score", "anchor_results"],
    "validated_then_dropped": ["named_metrics"],
    "named_metrics_note": "`named_metrics` is validated on arrival and never reaches a receipt. A dock that reports twelve measurements there will find that a receipt shows one boolean, one score and the named anchors only. Put anything a reader must see on the receipt into `anchor_results`.",
    "never_sent_to_the_dock": ["the prompt", "the model output beyond the candidate", "any Millwork identifier"]
  },
  "conformance": {
    "what_a_passing_compatibility_run_proves": "That the dock answers the request shape, honours the access mode it was tested for, returns a valid response, and stays inside the timing budget.",
    "what_it_does_not_prove": "That the check is correct. Conformance is a transport and shape result; whether the verdict is right is the dock author's responsibility."
  }
}
