A Harness is a composition of control, tool, and model layers that standardizes how QM backends handle turns: it ties a control transport (mock, HTTP, in-process) and tool transport (plugin, MCP, dynamic) to optional model utilities like history compaction and security screening, all instantiated through defineHarness. A HarnessTurnInput lets callers control per-turn behavior—model selection, thinking level, tool approval gates, security screening—while HarnessTurnResult surfaces outcomes (pending approvals, cache usage, LLM telemetry) from a single turn of execution.
The Harness interface in src/harness/harness.ts composes three sub-interfaces: HarnessTurnController (executes turns), HarnessModelUtilities (optional model utilities such as compact history and security screening), and HarnessToolPresentation (tool name formatting).[1] defineHarness in src/harness/harness.ts is the factory for constructing a Harness: it takes a HarnessAdapterProfile, a combined HarnessImplementation (turn controller plus model utilities), and an optional HarnessToolPresentation, returning a bound Harness object.[1] When no HarnessToolPresentation is supplied, defineHarness defaults to an identity mapping — name: (coreName) => coreName — so tool names are passed through unchanged unless a harness explicitly overrides it.[1]
HarnessAdapterProfile declares the valid control transports ("mock" | "in-process" | "sdk" | "http" | "json-rpc" | "api"), tool transports ("mock" | "in-process" | "plugin" | "dynamic" | "in-process-mcp" | "mcp"), and capabilities ("abort" | "steer" | "images" | "thinking-level" | "fast-mode" | "provider-sessions").[1]
HarnessTurnInput supports optional per-turn model selection (model?), harness override (harness?), thinking level (thinkingLevel?), fast mode (fastMode?), and read-only mode (readOnly?).[1] HarnessTurnInput also accepts a tapeMode of "shadow" or "serve" along with tapeRows and tapeFold, enabling the tape-fold conversation healing mechanism.[1] Per-turn security screening is available via HarnessTurnInput.screenExternalContent, an optional callback that receives the content, tool name, and source, and returns a SecurityScreenVerdict or undefined.[1] HarnessTurnInput.toolApprovalGate is a synchronous per-turn predicate; returning true for a tool name blocks its execution and routes it into the pending-approvals workflow.[1]
HarnessTurnResult carries a pendingApprovals array of { command, reason, kind?, matched?, purpose?, approvalKey? } objects and a pausedOnApproval flag for the command-approval gate workflow.[1] HarnessTurnResult.cacheUsage surfaces three token-budget dimensions: cacheRead, cacheWrite, and uncachedInput.[1]
HarnessModelUtilities is entirely optional: every method — shouldRespond, compactHistory, contextTokenBudget, oneShot, judge, screenSecurity, pickAckEmoji, generateTitle, and summarizeApproval — is an optional property, so harness implementations may omit any subset.[1]
HarnessLlmRequestRecord captures per-step LLM call telemetry including time-to-first-token (ttftMs), total duration (durationMs), step-gap time (stepGapMs), per-tool-call wall times (toolWallMs), gap phases, and token usage.[1]
Sources