Harness Control Flow
The harness control flow is the real-time feedback loop that monitors and steers agent reasoning. It connects three systems — the entropy sensor, the reactive controller, and the calibration store — into a single evaluation pipeline that runs after every kernel iteration.
Kernel Step → Entropy Sensor → Score History → Controller → Decisions (5 sources) (10 evaluators) ↓ ↓ Calibration Store ←─── Learning Engine (conformal thresholds)Pipeline Overview
Section titled “Pipeline Overview”After each Think/Act/Observe cycle, the reactive observer (reactive-observer.ts) runs two phases:
-
Entropy scoring — the latest thought is scored across 5 sources (token, structural, semantic, behavioral, context pressure). The composite score and trajectory are appended to
entropyHistory. -
Controller evaluation — the controller receives the full entropy history and calibrated thresholds, then runs 10 decision evaluators to determine whether action is needed.
This happens automatically when .withReactiveIntelligence() is enabled.
Calibration Flow
Section titled “Calibration Flow”The controller’s decision quality depends on accurate thresholds. Without calibration, the system uses hardcoded defaults (convergence: 0.4, high-entropy: 0.8). With calibration data, thresholds adapt to each model’s actual entropy distribution.
How Calibrated Thresholds Reach the Controller
Section titled “How Calibrated Thresholds Reach the Controller”- At each controller evaluation, the observer calls
EntropySensorService.getCalibration(modelId). - The sensor loads stored calibration from the
CalibrationStore(SQLite-backed). - If calibration data exists (≥20 samples), the stored conformal thresholds are used. Otherwise, uncalibrated defaults are returned.
- The controller evaluators use these thresholds for their decisions.
// Automatic — no user code needed// The observer loads calibration before every controller evaluation:const calibration = await sensor.getCalibration(modelId);// → { highEntropyThreshold: 0.72, convergenceThreshold: 0.35, calibrated: true, sampleCount: 25 }Persistent Calibration
Section titled “Persistent Calibration”By default, the calibration store uses an in-memory SQLite database. To persist calibration across runs:
.withReactiveIntelligence({ calibrationDbPath: "./data/calibration.sqlite", controller: { earlyStop: true },})Calibration data accumulates across agent runs, producing more accurate thresholds over time.
Drift Detection
Section titled “Drift Detection”When a model’s entropy distribution shifts significantly, the system detects calibration drift by comparing recent scores against the overall mean (±2σ). When drift is detected:
- A
CalibrationDriftevent is emitted via EventBus. - The event includes the expected mean, observed mean, and deviation sigma.
- Downstream observers can use this to trigger recalibration or alerting.
eventBus.subscribe("CalibrationDrift", (event) => { console.log(`Model ${event.modelId} drifted: expected=${event.expectedMean}, observed=${event.observedMean}`);});Controller Evaluators
Section titled “Controller Evaluators”The reactive controller runs 10 decision evaluators in sequence. Each evaluator examines entropy signals and may produce a decision:
| Evaluator | Decision | Trigger |
|---|---|---|
| Early Stop | early-stop | Entropy converging for N iterations below convergence threshold |
| Strategy Switch | switch-strategy | Flat entropy trajectory suggesting current strategy is ineffective |
| Context Compression | compress | Context pressure exceeds compression threshold |
| Temperature Adjust | temp-adjust | Entropy too high or too low relative to calibrated thresholds |
| Skill Activate | skill-activate | Entropy pattern matches a known skill’s activation profile |
| Prompt Switch | prompt-switch | Current prompt variant underperforming based on entropy signals |
| Tool Inject | tool-inject | Entropy pattern suggests a specific tool would help |
| Memory Boost | memory-boost | Switch from keyword to semantic memory retrieval |
| Skill Reinject | skill-reinject | Reactivate a previously successful skill |
| Human Escalate | human-escalate | All automated interventions exhausted |
Decision Lifecycle
Section titled “Decision Lifecycle”Controller decisions are:
- Published as
ReactiveDecisionevents on the EventBus for observability. - Stored on
KernelState.meta.controllerDecisionsfor the termination oracle. - Accumulated in
controllerDecisionLogfor thepulsemeta-tool to report.
The termination oracle checks for early-stop decisions and signals the kernel runner to exit the loop, potentially saving multiple iterations.
Configuration
Section titled “Configuration”.withReactiveIntelligence({ entropy: { enabled: true, tokenEntropy: true, // Requires logprob-capable provider semanticEntropy: true, // Requires embedding provider trajectoryTracking: true, // Track entropy shape over time }, controller: { earlyStop: true, // Stop when entropy converges contextCompression: true, // Compact context under pressure strategySwitch: true, // Switch strategy on flat entropy }, calibrationDbPath: "./data/calibration.sqlite",})Related
Section titled “Related”- Reactive Intelligence — Full entropy sensor and learning engine documentation
- Observability — EventBus tracing and structured logging