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

# Run the Checkfu harness end to end

> Build the first-party harness image, adopt and verify it like a stranger's, then drive a settled Session through the public API.

<Warning>
  The Agent creation and Session-launch portion of this guide is migration-fenced:
  it still shows the retired Draft/Release API. Use [Agents](/concepts/agents)
  for current Agent creation; CMA-compatible Session launch is not yet available.
</Warning>

This guide walks the `checkfu` catalog entry — the first-party harness —
from nothing to a settled Session: build the image, adopt it as a
HarnessProfile, pass conformance for your exact tuple, publish an Agent,
and read the settled event log. The first-party harness earns nothing
extra from the platform: it is admitted, driven, conformance-checked, and
capability-bounded through exactly the public
`POST /v1/harness-profiles` + verification path a stranger's image takes,
and this guide uses only that surface. Concept truth lives in
[Harnesses and models](/concepts/harnesses-and-models#the-first-party-checkfu-harness);
this page is the journey.

## Where this harness stands

* The catalog entry is `image_required`: Checkfu publishes no default image
  yet, so you build the checked-in `apps/harness` package — Apache-2.0
  licensed, with a Dockerfile and lockfile-pinned dependency closure — and
  adopt the digest you built.
* The harness is pi's agent libraries behind a Checkfu-authored ACP stdio
  server, with externally escrowed same-Run recovery, native steering,
  cooperative interrupt, governed subagents, and per-turn telemetry
  declared at `initialize`. The advertised catalog ceiling records only the
  actively qualified axes; declarations alone never raise it.
* If the model needs ordinary human input, the parent loop can emit a bounded
  structured Question. Checkfu persists the Question, ends the active
  sandbox attempt, and starts a fresh continuation only after a complete
  answer. This is input, not an ActionApproval, and no compute waits for the human.
* Checkfu has not yet recorded a default-tuple ConformanceReport for this
  entry, so it does not yet clear the full
  [support ladder](/concepts/harnesses-and-models#capability-evidence-and-conformance).
  The verification below produces that evidence for *your* tuple; until one
  passes, ordinary Runs on the profile are refused by design.

<Warning>
  The Checkfu CLI has no self-service public installation channel during
  private alpha. CLI examples below assume access through an explicitly
  authorized alpha arrangement; see
  [CLI access in private alpha](/getting-started/cli-access) for the
  source-checkout and HTTP alternatives.
</Warning>

<Steps>
  <Step title="Build the first-party image" titleSize="h2">
    The build context is the checked-in `apps/harness` package in the
    Checkfu source checkout: a digest-pinned base image, a reviewed immutable
    Debian snapshot, and pi's exact dependency closure from the committed
    lockfile.

    ```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
    pnpm harness-images:build checkfu
    ```

    The command builds the image, publishes it through an owned local
    registry so the result is content-addressed, verifies it against the
    published image contract, and prints the immutable `name@sha256:...`
    reference. Keep it:

    ```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
    export CHECKFU_HARNESS_IMAGE="<the printed name@sha256:... reference>"
    ```
  </Step>

  <Step title="Adopt the image as a HarnessProfile" titleSize="h2">
    <CodeGroup>
      ```sh CLI theme={"theme":{"light":"github-light","dark":"github-dark"}}
      pnpm exec checkfu harness add checkfu \
        --name checkfu-harness \
        --image "$CHECKFU_HARNESS_IMAGE"
      ```

      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --request POST https://api.checkfu.com/v1/harness-profiles \
        --header "Authorization: Bearer $CHECKFU_API_KEY" \
        --header "Checkfu-Version: 2026-08-27" \
        --header "Idempotency-Key: adopt-checkfu-$(uuidgen)" \
        --header "Content-Type: application/json" \
        --data '{
          "name": "checkfu-harness",
          "source": {
            "kind": "recipe",
            "name": "checkfu",
            "image": "'"$CHECKFU_HARNESS_IMAGE"'"
          }
        }'
      ```
    </CodeGroup>

    The response is the profile with `version: 1` and the pinned
    `driver_version: "checkfu:acp-v1@1"`. The profile admits nothing yet —
    custom OCI profiles are fail-closed until their exact runtime tuple
    passes conformance, and the first-party image gets no exception.
  </Step>

  <Step title="Verify conformance for your exact tuple" titleSize="h2">
    Select the SandboxProfile and ModelRoutingProfile the Agent will actually use.
    The harness selects among all three model wire dialects from its
    environment (OpenAI responses by default, OpenAI chat, or Anthropic
    messages), so any platform-routed model routing profile is reachable.

    <CodeGroup>
      ```sh CLI theme={"theme":{"light":"github-light","dark":"github-dark"}}
      pnpm exec checkfu harness verify checkfu-harness \
        --sandbox standard \
        --model primary \
        --wait
      pnpm exec checkfu harness status checkfu-harness
      ```

      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --request POST \
        "https://api.checkfu.com/v1/harness-profiles/$CHECKFU_HARNESS_PROFILE_ID/verifications" \
        --header "Authorization: Bearer $CHECKFU_API_KEY" \
        --header "Checkfu-Version: 2026-08-27" \
        --header "Idempotency-Key: verify-checkfu-$(uuidgen)" \
        --header "Content-Type: application/json" \
        --data '{
          "expected_version": 1,
          "environment": "standard",
          "model_routing_profile_key": "primary"
        }'
      ```
    </CodeGroup>

    Verification queues a conformance Run that an enrolled Runner claims and
    executes against the real image. The passing ConformanceReport is pinned
    to the image digest, profile version, driver, sandbox, model routing profile,
    policy, and suite revision; changing any of them — or reaching the
    report's 30-day expiry — requires fresh evidence. If your harness calls
    platform tools, add `prove_platform_mcp: true` (CLI:
    `--prove-platform-mcp`) to also prove tool delivery at the execution
    locus.
  </Step>

  <Step title="Create and publish an Agent" titleSize="h2">
    With a passing report, the profile is an ordinary harness name an Agent
    can reference:

    ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
    curl --request POST https://api.checkfu.com/v1/agents \
      --header "Authorization: Bearer $CHECKFU_API_KEY" \
      --header "Checkfu-Version: 2026-08-27" \
      --header "Idempotency-Key: create-agent-$(uuidgen)" \
      --header "Content-Type: application/json" \
      --data '{
        "name": "research-assistant",
        "instructions": "Answer with evidence from the mounted project.",
        "harness": "checkfu-harness",
        "model_routing_profile_key": "primary",
        "environment": "standard"
      }'
    ```

    Publish version 1 with `POST /v1/agents/{id}/releases` and grant the
    Agent `use_harness`, `use_model`, and `use_environment` on the three
    governed resources, plus `invoke` for your Principal — the exact
    sequence [Create and publish an Agent](/guides/create-and-publish-an-agent)
    walks. Session admission intentionally fails closed while any one PermissionAssignment
    is absent.
  </Step>

  <Step title="Upgrade or roll back the profile" titleSize="h2">
    Rebuild and locally test the next private-monorepo image, then keep the
    logical profile name stable while advancing its immutable version:

    ```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
    pnpm exec checkfu harness update checkfu-harness oci \
      --image "$NEXT_CHECKFU_HARNESS_IMAGE" \
      --entrypoint /opt/checkfu/bin/checkfu-harness \
      --working-directory /workspace \
      --platform linux/amd64 \
      --expected-version 1 \
      --verify \
      --sandbox standard \
      --model primary
    ```

    The CLI prints the old and new release IDs plus an exact rollback command.
    A rollback publishes the next HarnessProfileRevision pointing at the old
    release; it does not mutate history. Existing Runs retain their pins, and
    every changed tuple needs fresh conformance before new admission. This is
    all inside `andyrewlee/checkfu`: the command creates private Workspace API
    resources and makes no source-publication or catalog-readiness claim.
  </Step>

  <Step title="Run a Session and read the settled log" titleSize="h2">
    <CodeGroup>
      ```sh CLI theme={"theme":{"light":"github-light","dark":"github-dark"}}
      pnpm exec checkfu session chat \
        --agent "$CHECKFU_AGENT_ID" \
        --principal "$CHECKFU_PRINCIPAL_ID" \
        "Summarize what this harness can and cannot do."
      ```

      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl "https://api.checkfu.com/v1/sessions/$CHECKFU_SESSION_ID/events?limit=100" \
        --header "Authorization: Bearer $CHECKFU_API_KEY" \
        --header "Checkfu-Version: 2026-08-27" \
      ```
    </CodeGroup>

    Settlement is read from the durable event log, never inferred from
    response timing. A successful first turn ends with `run.completed`
    followed by `session.status_idle`, with the `agent.message` content and
    the model-routing, usage, and sandbox-cleanup evidence recorded between
    `run.created` and settlement. The [event catalog](/reference/events)
    names every type you will see.

    A turn that needs input instead records `agent.question` and
    `run.requires_action` before the Session pauses. Answer it by posting a
    `user.question_answer` to this same events endpoint with the Question ID
    and one answer for every item. The answer creates a new Run with fresh
    compute; it never revives the process that asked.
  </Step>
</Steps>

## Forking it

The `apps/harness` package doubles as the reference for custom harnesses:
it includes architecture notes and compatibility fixtures so a team can
fork the loop without copying any proprietary control-plane package. The
dependency-free walkthrough of the same boundary is the custom ACP example
in the repository (`examples/custom-acp`), which this guide's arc mirrors.

## Next steps

<CardGroup cols={2}>
  <Card title="Harnesses and models" icon="cpu" href="/concepts/harnesses-and-models">
    The adoption-path model, capability ceilings, and conformance evidence rules.
  </Card>

  <Card title="Harness extensions" icon="puzzle-piece" href="/concepts/harness-extensions">
    The checkfu ACP extensions this harness declares at initialize.
  </Card>
</CardGroup>
