Skip to content
Playground

Harness Control Surface

Last updated today · 55e6c0c

Updated today

"docs: add next-step navigation to 51 pages, fix 2 real coverage/rendering gaps" · 55e6c0c · 2026-09-06

  • ## What's Next

.withHarness({...}) is the typed control surface for the 14 harness mechanisms — tool disclosure, discovery, the tool index, verbose rules, stable tool surface, context budgets, thought continuity, observe symmetry, rationale audit, and the Tree-of-Thought explore budget. Before this surface existed, every one of these mechanisms was reachable only through a process-global RA_* environment variable read at its call site, so two agents in one process could not differ and no sub-agent inherited anything from its parent.

Resolution happens once per run, at the runtime boundary, and is threaded through RunEnvelope.harnessKernelInput.harness to every consuming call site. Sub-agents inherit the resolved harness automatically — it rides the existing parentReasoningOptions passthrough, no separate mechanism needed.

  1. Explicit config.withHarness({...}) on the builder. Typed, per-agent, wins over everything.
  2. Environment variable — the matching RA_* variable (see harness-flags.ts). Process-global, used only where the config layer didn’t decide.
  3. Built-in default — what the framework does with nothing set. Every default resolves to today’s behavior; this page introduces no default changes.
// Small-model profile: show everything, no discovery round trips:
agent.withHarness({
lazyDisclosure: false,
toolDiscovery: false,
verboseRules: true,
})
FieldTypeDefaultEnv fallback
lazyDisclosurebooleantrueRA_LAZY_TOOLS (=0 to disable)
toolDiscoverybooleanfollows lazyDisclosureRA_TOOL_DISCOVERY
toolIndexbooleanfalseRA_TOOL_INDEX
toolIndexMaxEntriesnumber (unset = tier decides)unsetRA_TOOL_INDEX_MAX_ENTRIES
verboseRulesbooleanfalseRA_VERBOSE_RULES
recencyBudgetCharsnumber (unset = derived from window)unsetRA_RECENCY_BUDGET_CHARS
toolResultBudgetCharsnumber (unset = tier table decides)unsetRA_TOOL_RESULT_BUDGET_CHARS
thoughtContinuitybooleanfalseRA_THOUGHT_CONTINUITY
toolObserveSymmetrybooleanfalseRA_TOOL_OBSERVE_SYMMETRY
auditRationalebooleanfalseRA_RATIONALE_AUDIT
treeOfThoughtExploreBudgetMsnumber120000RA_TOT_EXPLORE_BUDGET_MS
assemblyDebugbooleanfalseRA_ASSEMBLY_DEBUG
promptDumpPathPrefixstring (unset = disabled)unsetRA_PROMPT_DUMP

Fields whose “unset” state is meaningful (toolIndexMaxEntries, recencyBudgetChars, toolResultBudgetChars, promptDumpPathPrefix) are absent from the resolved harness — not undefined — when nothing sets them, so a fallback distinguishes “no override” from “override of zero.”

toolDisclosureMode (set on a ContextProfile, or expanded via fromDisclosureMode()) is shorthand for three of the mechanism switches above — lazyDisclosure, toolDiscovery, and toolIndex:

ModelazyDisclosuretoolDiscoverytoolIndexPick this when…
"full"offoffoffThe tool catalog is small enough that pruning is pure overhead — every tool stays visible every turn.
"discover"ononoffToday’s default posture: lazy per-iteration pruning, with the discover-tools meta-tool as the escape hatch when the model needs something hidden.
"index"onoffonPruning stays on, but hidden tools get a cheap always-visible name+one-line index instead of a reactive meta-tool round trip. Best for small/local models that don’t reliably think to call discover-tools.
"hybrid"onononLarge catalogs: a capped index (toolIndexMaxEntries) covers the common case, discover-tools covers the overflow.

fromDisclosureMode() expands a mode into a plain HarnessConfig, so you can spread it and override any single field:

import { fromDisclosureMode } from "@reactive-agents/reasoning"
import { ReactiveAgents } from "@reactive-agents/runtime"
const agent = ReactiveAgents.create()
.withProvider("anthropic")
.withReasoning()
.withHarness({ ...fromDisclosureMode("index"), verboseRules: true })

CONTEXT_PROFILES sets one of these as the per-tier default value (again: as typed data, not yet as applied runtime behavior — see the caution above):

TierDefault mode
local"index"
mid"hybrid"
large"discover"
frontier"discover"

These four tier defaults are declarations of intent, not measured verdicts, pending future ablation-warden measurement. No cross-tier lift data backs them yet — treat them as a reasonable starting posture per tier, not a benchmarked recommendation. Once a live consumer exists, an explicit .withHarness({...}) or toolDisclosureMode on a contextProfile override is intended to always win over the tier default; today, use fromDisclosureMode() explicitly to get any effect at all.

A 4B–8B Ollama model tends to ignore reactive tool-discovery hints and benefits from everything being spelled out up front rather than pruned:

import { ReactiveAgents } from "@reactive-agents/runtime"
const agent = ReactiveAgents.create()
.withProvider("ollama")
.withModel("qwen3:4b")
.withReasoning()
.withTools({ builtins: true })
.withContextProfile({ tier: "local" }) // "local" tier's default mode is "index" (data only — not yet applied automatically, see caution above)
.withHarness({
// Explicitly override the mechanism switches themselves: show everything,
// skip both pruning and the index text — the model rarely needs more
// than a handful of tools on any given task. (Not a "tier default"
// override in the resolution-pipeline sense — that pipeline hook does
// not exist yet.)
lazyDisclosure: false,
toolDiscovery: false,
toolIndex: false,
verboseRules: true, // spell out the ReAct loop instead of assuming it
})
.build()
  • No default changes. With no .withHarness() call and no RA_* variables set, every mechanism resolves exactly as it did before this surface existed.
  • overhaulEnabled() (RA_OVERHAUL) stays env-only. It is a build-time construction switch (runtime-construction.ts), not a per-run mechanism, so it is deliberately outside HarnessConfig.
  • packages/tools/src/flags.ts and packages/a2a/src/flags.ts are untouched. They gate deployment/sandbox concerns in packages that cannot import harness-flags.ts without a dependency cycle — a different problem from the one this surface solves.
  • Harness Control Flow — the entropy sensor and reactive controller mechanics this config surface tunes
  • Reasoning — how tool disclosure mode changes what a strategy sees each turn
  • Local Models — where the tightest disclosure postures matter most