Skip to main content
Checkfu speaks one wire to every curated harness: the Agent Client Protocol plus a small, namespaced set of Checkfu-defined extensions. The extensions exist because stock ACP cannot carry three things customers feel — mid-turn steering with an attributable acknowledgement, a cooperative (non-kill) interrupt, and attributed subagent activity. The first-party Checkfu harness is the reference emitter, but nothing here is private to it: every slot, the declaration handshake, and the conformance grammar are open to any bring-your-own-harness image that declares them. The first-party harness wins by citizenship, never by privileged infrastructure. This page is the contract a harness author builds against. For adoption paths and catalog mechanics, see Harnesses and models.

Machine-readable author kit

The checked-in author kit is generated from the same Effect Schemas the control plane and generic Runner adapters decode. Treat its revision literals as compatibility identities: changing a protocol, driver, schema, or golden-vector revision requires an explicit review, not an in-place reinterpretation. The JSON Schema is a portable structural preview. The Checkfu decoder remains authoritative for cross-field rules such as placeholder/transport agreement. Vendor shims consume these vectors only in tests or builds and keep their production dependency manifests free of @checkfu/* packages. Passing a local harness diagnostic is useful author feedback; only server-issued, signature-verified conformance evidence qualifies a release. Configuration schemas use JSON Schema 2020-12 with a deliberately bounded safety profile. They may be boolean or object documents up to 32 KiB, with bounded depth, nodes, combinators, and local #/... references. Remote, recursive, dynamic, cyclic, or deeply expanding reference graphs are rejected. Patterns use a conservative linear-work subset: groups, backreferences, *, +, unbounded repetitions, and ambiguous variable-width repetition are rejected, as is uniqueItems: true. The CLI, dashboard, and API all apply this same validator, so an author sees the failure before an unsafe schema can reach a Runner or block a worker.

From wrapper to qualified release

Start with the smallest runnable wrapper, then increase fidelity only when the product needs it:
That build-context command builds an ephemeral image and exercises the production Docker Runner, one-shot driver, governed model relay, prompt transport, normalized observations, declared resume and output-schema paths, and teardown. Its JSON result is deliberately unsigned_local_only: it creates neither a harness profile nor server evidence. A passing build-context result tells you to publish and retest; it never suggests registering an ephemeral localhost image. An existing ACP implementation uses the same image lane without a Checkfu-specific runtime dependency. If it is already published, test its immutable image directly:
The immutable-image command does not rebuild or publish the image. Its diagnostic performs a real ACP initialize, session creation, governed model exchange, normalized observation, and teardown against the supplied digest. An ACP wrapper follows the same path, with only its protocol-specific process arguments changing:
The ACP result reports initialize_handshake, session_start, and prompt_exchange only after the real ACP driver completes an initialize/session exchange, the fresh diagnostic prompt reaches the governed model relay, its nonce-bearing response reaches normalized public output, and owned Docker resources are drained. It never reports one-shot resume or output-schema checks for an ACP release. Publish the image, resolve its immutable name@sha256:<digest> reference, and repeat the same command with --image in place of --build-context. Supply --sandbox <sandbox-profile> and --model <model-routing-profile> to either diagnostic command, or pass a --connection-file <path> whose defaults contain both. With both selectors resolved, the immutable-image result contains exact checkfu harness add oci ... and checkfu harness verify ... commands, preserving any --api-url or --connection-file context. Without both selectors, it returns the exact add command, names the missing flags in required_flags, and labels the verify command as a template rather than an executable next step. A passing build-context result preserves the same supplied context in its exact published-image retest command. Run the emitted add command, then request authoritative evidence:
The final verification runs in the server-owned lane and produces signed conformance evidence; local diagnostic output is never qualification. If a VM-hosted Docker daemon cannot push to the default loopback-only temporary registry, rerun the build-context test with --allow-registry-all-interfaces and heed its exposure warning. Use oneshot-v1 when a CLI can accept one prompt, emit text or normalized stream JSON, persist state at a turn boundary, and exit. If the CLI cannot expose prompt or schema files, use the stdin/text subset and omit undeclared checks. Choose acp-v1 when the experience needs a live session, structured tool and subagent observations, approvals, mid-turn input, or cooperative interruption. ACP extensions enrich that lane; they are not requirements for the portable one-shot floor.

The mechanism

Extensions ride ACP’s sanctioned extensibility surface — namespaced checkfu.* keys inside the _meta object that every ACP message and every session/update member already carries, plus _-prefixed extension methods for the two verbs ACP lacks. Never a forked SDK type, never a new sessionUpdate kind. Three governance rules hold:
  • No dead vocabulary. Every extension key ships with a platform-side consumer in the same change as (or before) its first emitter. A key nothing reads is deleted.
  • Optional fidelity is fail-open; requested authority is fail-closed. A consumer ignores unknown checkfu.* keys and undecodable optional harness-to-client fidelity data. A recognized authority-bearing session/new member such as built-in scoping, continuity, runtime configuration, resume state, or output schema is instead rejected when malformed or unsupported, before model work. The ACP grammar itself (methods, update kinds, stop reasons) also stays fail-closed.
  • Declaration before emission. A harness declares each fidelity extension it emits in its initialize response _meta under checkfu.capabilities. Emitting a gated member without the declaration fails conformance.

The slots

This inventory is generated from the same import-safe catalog the ACP client uses. Change the decoder/catalog first, then regenerate this page. Subagent ids in checkfu.subagent are harness-local; the platform’s normalizing adapter mints the durable correlation id, so raw harness thread ids never cross the observation boundary. phase: "activity" attributes exactly the update carrying it; absence of the key means the primary loop authored the update. Completion evidence has no _meta key by design: it rides as data on the tool result itself.

The declaration handshake

The server owns a capability envelope per driver — a harness assertion can never promote it. Exactly three axes may rise above that envelope, and only through the checkfu.capabilities declaration admitted at the ready handshake: builtin_tool_scoping: "enforced", structured_output: "response_format" | "submit_tool", staged_files: "resource_links", and native_checkpoint: "external_custody" are also declared in this slot, but they are mechanism/ceiling inputs rather than further semantic capability axes. The first says the harness enforces the built-in-tool list handed to session/new; response_format says the harness gives the exact Agent JSON Schema to its native response-format mechanism and validates the final value at the adapter boundary, while submit_tool says it validates a parent-only final tool submission before emitting it. The staged-files value says the harness consumes one ordered standard ACP resource link per immutable File already staged into its colocated sandbox; the native-checkpoint value says the harness exports its native state for client-side custody (checkfu.journal_checkpoint) and imports it back through checkfu.resume instead of trusting agent-readable disk. None promotes the stored three-axis capability set. The admission is exact and one-directional: a handshake that smuggles any other promotion, any downgrade, or an intermediate value is rejected. A non-declaring harness’s envelope, handshake, and stored capability sets are byte-identical to a platform without the extensions. Declaring a capability the harness does not serve is worse than not declaring it: the platform will exercise the declared surface and the failure modes are honest — a refused steer stays on the ordered promotion path, but an acknowledgement that goes missing fails the Run rather than leaving a maybe-delivered input. Declaration is not semantic proof. The generic conformance turn actively exercises the attributed-subagent lifecycle, so the checkfu and claude-code catalog ceilings may advertise subagents: "observed". The signed suite also delivers a scripted steer to every declared native mid-run-input axis (steering_delivered), and a scripted cooperative drain case (cooperative_interrupt_drained) exists but stays opt-in until a truncation-safe drain probe lands. A declared axis crosses into the realized capability set only with its exact passing active case; the catalog keeps mid_run_input: "unsupported" and interrupt: "kill_only" until exact-adapter signed evidence exists. Grammar-only checks never promote control.steer or control.interrupt.

The conformance grammar

Conformance executes the exact pinned release/driver/sandbox tuple and derives evidence from normalized observations. The grammar holds every declarer — first-party or bring-your-own — to the same rules: The server independently proves the model plane was reached through the lease-fenced gateway and, when platform tools are granted, that tool delivery happened at the sandbox boundary (the execution-locus check). A harness cannot pass by narrating plausible activity; the platform’s own served-call record is the authority.

Generated harness support snapshot

The table below is generated from the same catalog and revision bundle served by GET /v1/support/harnesses. It is intentionally stricter than a feature checklist. Projection checkfu:harness-support@1; catalog sha256:191a18d151b2a39df84239e5b9110df072a4d664504369f84fd726935b3485a8. Experience checkfu:harness-experience-profiles@2; conformance checkfu:harness-conformance@9 / checkfu:harness-conformance-case-set@6; evidence checkfu:harness-conformance-evidence-identity@2 / checkfu:conformance-evidence-manifest@6; readiness checkfu:harness-readiness@2. Supply says whether Checkfu can adopt an artifact today. Catalog evidence says whether the exact default artifact has a signed readiness receipt. Neither answers whether one customer’s harness/model/sandbox tuple is compatible: POST /v1/sessions/preflight evaluates that tuple against current signed conformance evidence before execution.

Capability ceilings and server envelopes

The matrix below is generated from the catalog and the envelope code — it cannot be edited by hand, and generation fails if the catalog ever declares a ceiling the envelope plus declaration admission cannot realize. A catalog ceiling describes what an integration can realize; a particular run’s capability set also depends on retention, its ready handshake, platform policy, and current conformance evidence.

Catalog capability ceilings by entry

* Declaration-admitted: above the server envelope for the entry’s driver, reachable only when the harness’s initialize response declares the extension and the ready handshake admits exactly that axis. An axis shown as — is undeclared: the entry keeps the pre-axis flatten behavior. A connected entry’s ceiling is owned by the connected-runtime lane, not a Runner driver envelope. These are catalog ceilings, not claims about a particular run: exact realization additionally intersects retention, the ready handshake, platform policy, and current conformance evidence.

Server-owned envelope by driver and retention mode

The server envelope never carries the subagents axis: it is declaration-admitted at the ready handshake, and its absence keeps every stored capability set byte-identical to the pre-axis representation.

Declaration-gated emissions

Every other RunnerObservation member is lane-universal vocabulary. Emitting a gated member without the declared axis fails the conformance grammar.

Which harnesses can reach which model providers

Capability ceilings say what an integration can do. This section says something narrower and more physical: whether a harness and a model provider can speak to each other at all. A harness that only knows how to POST Anthropic’s /v1/messages cannot drive an OpenAI-compatible route, no matter what its ModelRoutingProfile says — and until this table existed that constraint was emergent, discovered as a provider-shaped rejection partway through a turn. It is now declared data. Each catalog image contract may state the model wire dialects its binary speaks, the reviewed provider table states which dialects each provider accepts, and the platform model gateway’s own request-path allow-list is derived from that same table rather than restating it. The matrix below is generated from both; generation fails rather than publishing a declaration no priced provider could serve. Read it as a necessary condition, not a support claim. A reachable cell means the wire fits. Whether that exact tuple is supported is still, and only, the set of current passing ConformanceReports.

Model wire dialects and their gateway paths

An unlisted provider accepts anthropic_messages, openai_chat, openai_responses. The gateway’s per-provider path allow-list is derived from this same table, so a path it forwards and a dialect the platform reasons about cannot disagree.

Harness x model-provider reachability

An undeclared entry is unconstrained, not universal: Checkfu has no in-repo evidence of which dialects that image speaks, so it declares none rather than guessing, and every cell reads —. A reachable cell means the harness and the provider can physically speak to each other through the platform model gateway. That is a necessary condition for a Run and nothing more — it is not a support claim, and it never promotes a cell that lacks a current passing ConformanceReport. A provider with no reviewed dialect entry accepts all three dialects, because a customer-supplied compatible endpoint is a first-class route.

The one-shot floor remains the tail tier

None of this raises the bar for bringing an arbitrary harness. The floor stays the zero-integration on-ramp for any CLI, and the extensions are an enrichment lane above it. The floor’s definition and structural limits live in what the one-shot floor cannot do.

Enrichment requires evidence

A lane is enriched only when a canonical scenario proves a customer-felt fidelity loss — before and after, both kept green — never on enthusiasm. That record lives in the decision log, and every future enrichment (including the SDK-native shims for third-party engines) copies its shape: the axis and its exact transition, the before/after scenarios by name, the loss in product terms, and the mechanism.