Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

57 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HarnessRanger - Enhanced Tool Harness for OpenClaw

A production-ready plugin implementing advanced harness patterns from Claude Code's porting workspace:

  • Enhanced Tool Registry with semantic matching
  • Permission-Aware Tool Execution
  • Token-Aware Session Management with intelligent compaction
  • Structured Streaming Responses with event pipeline
  • Evidence-Gated Artifact Evolution with redacted telemetry, immutable candidates, host-specific evaluation, canary promotion, and rollback

The self-improvement subsystem is disabled by default and only evolves allowlisted text artifacts. See the feature guide for its safety model, setup, CLI, service API, and host adapters.

Architecture

harness-ranger/
├── src/
│   ├── tool-registry.js        # Semantic tool discovery & metadata management
│   ├── permission-context.js   # Permission-aware execution gating
│   ├── session-manager.js      # Token-aware session persistence
│   └── streaming-responses.js  # Structured event streaming pipeline
├── self-improvement/            # Evidence-gated text-artifact evolution
├── index.js                     # Plugin entrypoint & lifecycle hooks
├── package.json
└── README.md

Installation

Automatic harness setup

The npm package contains native bundles for OpenClaw, Claude Code, Codex, and Hermes. Run the explicit setup command after installation; npm installation itself never modifies harness configuration.

npx @synchronic1/harness-ranger setup

When one harness is detected, --auto selects it. When several are detected, choose interactively or pass --target/--all:

npx @synchronic1/harness-ranger setup --auto
npx @synchronic1/harness-ranger setup --target claude --scope user
npx @synchronic1/harness-ranger setup --target codex --scope project --dry-run
npx @synchronic1/harness-ranger setup --all

Use detect --json, status, and uninstall --target <host> for automation and lifecycle management. OpenClaw supports user scope only; project-scoped Hermes plugins require HERMES_ENABLE_PROJECT_PLUGINS=1. Setup never restarts a harness unless --restart is supplied.

Supported integrations and demo scope

The installable integration bundles are OpenClaw, Claude Code, Codex, and Hermes. These are the only hosts whose lifecycle adapters and generated installation bundles are currently implemented. The EvidenceProvider entries for those hosts are intentionally dashboard-visible planning scaffolds; they do not yet change host retrieval or request paths.

The public interactive demo is a static, illustrative operations dashboard. Its sample instances and metrics are not live connector data, and it must not be read as a claim that LangGraph or custom HTTP integrations are shipped. Use the local setup command and the validation commands below to test the implemented integrations.

Optional offline LLM judge

The LLM judge is disabled by default and runs only as an explicit, offline evaluation worker. It never executes in a live hook and cannot promote a candidate by itself. After installing a compatible local llama.cpp worker and model outside this repository, inspect the profile and create a launch plan:

harness-evolve judge-profiles --workspace .
harness-judge plan --backend local-cpu --threads 8
harness-evolve judge-health --workspace . --backend local-cpu

Queue bounded, redacted evaluation cases only after the health check succeeds. A CUDA worker may be selected explicitly where available; see the evidence-gated evolution guide for the 6 GB VRAM starting profile, model-worker setup, and case format.

Optional HeurChain memory

HeurChain is disabled by default. The OpenClaw service exposes getHeurChainMemoryDashboard() for a dashboard to render the selected transport, configuration readiness, capture toggles, recall policy, limits, and non-sensitive counters; checkHeurChainMemoryHealth() is an explicit health probe for a dashboard refresh.

  • local-broker connects to the existing CT203 broker contract.
  • cloud-api connects to https://api.heurchain.com only after cloud.apiKey and cloud.tenant are supplied by the host. It is intentionally a separate adapter, not a URL substitution for the legacy broker.
  • Typed memory stores redacted, bounded fact, procedure, and episode records. Compaction and incident capture can be toggled independently.
  • Recall is explicit and returned as untrusted context. Automatic prompt recall is shown as unavailable because HarnessRanger has no verified host-owned prompt-injection point for it.
  • The older unredacted heurchain_store and heurchain_search local-broker compatibility tools are disabled by default (enableLegacyTools: false) and are never registered for Cloud API mode.
{
  "heurchain": {
    "enabled": true,
    "transport": "cloud-api",
    "agentName": "openclaw",
    "cloud": {
      "apiKey": "set-by-host",
      "tenant": "set-by-host"
    },
    "memory": {
      "enabled": true,
      "captureCompaction": true,
      "captureIncidents": true,
      "recallMode": "explicit"
    }
  }
}

Manual OpenClaw setup

  1. Clone or copy to ~/.openclaw/plugins/harness-ranger

  2. Add to openclaw.json:

{
  "plugins": {
    "allow": ["harness-ranger"],
    "entries": {
      "harness-ranger": {
        "enabled": true,
        "config": {
          "maxContextTurns": 12,
          "maxBudgetTokens": 4000,
          "compactAfterTurns": 16,
          "semanticMatchingThreshold": 0.6
        }
      }
    }
  }
}
  1. Install dependencies:
cd ~/.openclaw/plugins/harness-ranger
npm install

Usage

Enhanced Tool Registry

Register tools with metadata:

plugin.registerTool('analyze-code', codeAnalyzer, {
  description: 'Analyzes source code for patterns and issues',
  category: 'analysis',
  tags: ['code', 'patterns', 'linting'],
  permission: 'user'
});

Find tools using semantic matching:

const matches = plugin.findTools('analyze my python code', {
  category: 'analysis',
  recentToolNames: ['code-review']
});

// Returns tools sorted by relevance score

Permission-Aware Execution

The plugin automatically checks permissions before tool execution:

const result = await plugin.beforeToolExecution('analyze-code', params, {
  user: { id: 'user123', roles: ['developer'] },
  resource: '/path/to/code',
  sessionId: 'sess-456'
});

if (!result.allowed) {
  console.log(`Denied: ${result.reason}`);
}

Token-Aware Session Management

Sessions automatically compact when token budgets are exceeded:

const session = await plugin.getSession('sess-456');
// Compaction happens automatically if needed

plugin.addTurn('sess-456', 'Analyze this code', 'Here\'s the analysis...', []);

Structured Streaming

Stream responses with structured events:

for await (const event of plugin.streamResponse(generator, { 
  sessionId: 'sess-456' 
})) {
  switch (event.type) {
    case 'message_start':
      console.log('Starting response...');
      break;
    case 'message_delta':
      console.log('Content:', event.content);
      break;
    case 'message_stop':
      console.log(`Complete (${event.totalTokens} tokens)`);
      break;
  }
}

Configuration

{
  // Session management
  maxContextTurns: 12,              // Keep last N turns in memory
  maxBudgetTokens: 4000,            // Max tokens before compaction
  compactAfterTurns: 16,            // Force compact after this many turns
  
  // Tool discovery
  semanticMatchingThreshold: 0.6,   // Min score for tool matches (0-1)
  
  // Storage
  sessionDir: '.openclaw/sessions', // Where to persist sessions
  
  // Security
  deniedTools: ['exec', 'shell'],   // Tools that are always denied
  restrictedResources: {
    'admin-panel': ['root-user']    // Tool -> allowed resources
  }
}

Patterns Implemented

1. Modular Registry Pattern

Central registry with discoverable capabilities, metadata-driven tool dispatch, and permission-aware filtering.

const registry = plugin.toolRegistry;
registry.registerTool(name, handler, metadata);
const matches = registry.findTools(query, context);

2. Permission Gating

Contextual permission checks before tool execution with support for user roles, resource restrictions, and rate limiting.

const permission = plugin.permissionContext.canExecute(
  toolName, user, resource
);

3. Session Persistence

Token-aware session management with automatic compaction, usage tracking, and conversation replay.

The deterministic compaction fallback preserves bounded structured rows, code, and date-bearing lines rather than replacing structured values with a placeholder. The composed prompt also includes a context_preservation section so model-backed compaction retains answer-bearing tables, schedules, tool results, state changes, and temporal anchors.

const session = plugin.sessionManager.getSession(sessionId);
plugin.sessionManager.recordToolCall(sessionId, toolName, params);

4. Streaming Pipeline

Structured event streaming with clear visibility into decision-making: message_startcommand_matchtool_matchmessage_deltamessage_stop

for await (const event of plugin.streamResponse(generator, context)) {
  // Handle different event types
}

Testing

npm run build:release       # Generate and validate all harness bundles
npm run lint:release        # Lint release-owned JavaScript
npm test                     # Run the full unit suite
npm run test:install         # Verify the plugin export and parseability
npm pack --dry-run --json    # Verify the published-package boundary

CI/CD

GitHub Actions workflows included:

  • ci.yml - Lint, test, build, security audit
  • code-review.yml - Automated PR code review with analysis

API Reference

Plugin Instance Methods

  • initialize(runtime) - Initialize with OpenClaw runtime
  • findTools(query, context) - Find tools by semantic match
  • getSession(sessionId) - Get or create session
  • registerTool(name, handler, metadata) - Register custom tool
  • streamResponse(generator, context) - Stream with structured events
  • getStatus() - Get plugin metrics and status

Evolution Service Methods

  • getEvolutionStatus() - Inspect feature mode and lifecycle state
  • getActiveArtifactVersion(host, artifactId, sessionId?) - Resolve stable or session-sticky versions
  • getEvolutionPointers(host, artifactId) - Inspect stable, canary, and rollback pointers
  • listEvolutionCandidates(filters) - List immutable candidate manifests
  • evaluateEvolutionCandidate(version, metrics) - Apply offline evidence gates
  • triageEvolutionResults(results) - Diagnose offline context, selection, answer, judge, and safety failure stages
  • planEvolutionReplay(results, options?) - Produce an offline targeted-stage rerun plan without invoking a host or model
  • cacheEvolutionStage(stage, input, output) - Persist a redacted immutable offline stage result
  • getCachedEvolutionStage(stage, input) - Retrieve a cached offline stage result without changing it
  • benchmarkHostAdapter(host, eventName, payloads, options?) - Measure deterministic adapter normalization; optional recorded baselines exclude fixture payloads
  • selectEvolutionEvidence(query, evidence, options?) - Select a bounded multi-evidence union and report uncovered needs
  • searchTemporalEvolutionEvidence(query, evidence, options?) - Search date-tagged evidence only when temporal routing applies
  • getEvidenceProviderDashboard() - Dashboard-safe readiness matrix for the four future host providers
  • registerEvidenceProvider(provider) - Register explicit future-stage handlers without enabling retrieval
  • getJudgeDashboard() - Dashboard-safe offline judge configuration, model profiles, and worker readiness
  • checkJudgeHealth() - Explicitly health-check the offline judge worker; never runs in a hook
  • runJudgeEvaluation(input) - Explicitly run and cache one bounded, redacted offline judge case
  • startEvolutionCanary(version, metrics) - Start a passing fresh-session canary
  • promoteEvolutionCanary(host, artifactId, metrics) - Promote after live evidence passes
  • rollbackEvolution(host, artifactId, version?) - Restore a prior stable version
  • getEvolvedToolDescriptions(sessionId) - Resolve versioned tool descriptions

Live metrics are process-local snapshots exposed by getMetricsCollector(): numeric tool-call status counts, permission decisions, observed tool lifecycle latency, tracked-session count, compaction count, and hook/tool errors. They are operational observations, not task-success evidence; use paired offline or canary outcomes for impact claims.

Measurement and safe tuning

The runtime records the operational metrics above automatically through its normal hooks. It does not include an autonomous corpus-tuning cron or infer that latency, tool success, or judge output means the agent completed a user task. Calibrated outcome ingestion must be supplied explicitly by the host or evaluator as labeled task results.

Once a host supplies those labels, run offline evaluation and canary analysis as a separate, operator-scheduled job (for example, scheduled CI or a platform scheduler), never from a request-path hook. A scheduled job may collect bounded, redacted evidence and evaluate a candidate, but promotion must remain evidence-gated; without host-provided outcome labels, it must report insufficient evidence and make no tuning or promotion decision.

Full configuration and examples are in the evidence-gated evolution guide.

Tool Registry

  • registerTool(name, handler, metadata)
  • findTools(query, context)
  • getTool(name)
  • getToolMetadata(name)
  • listTools(filter)
  • updateToolMetadata(name, updates)
  • removeTool(name)
  • export()

Permission Context

  • canExecute(toolName, user, resource)
  • denyTool(toolName)
  • allowTool(toolName)
  • restrictResource(toolName, resources)
  • getDeniedTools()

Session Manager

  • getSession(sessionId)
  • addTurn(sessionId, userMsg, assistantMsg, toolCalls)
  • recordToolCall(sessionId, toolName, params)
  • recordToolResult(sessionId, toolName, result)
  • shouldCompact(sessionId)
  • compactSession(sessionId)
  • saveSession(sessionId)
  • loadSession(sessionId)
  • deleteSession(sessionId)
  • listSessions()

Contributing

  1. Create a branch for your feature
  2. Make changes and add tests
  3. Run npm test && npm run lint
  4. Push and create a PR
  5. CI/CD pipeline runs automatically with code review feedback

Agent contributors

Coding agents must read the repository-level AGENTS.md. Changes under self-improvement/ must also follow the scoped self-improvement agent instructions, which define the telemetry, evidence, promotion, rollback, dependency, and validation invariants for this feature.

OpenAI GPT-5.6 through Codex provided significant engineering input during the July 20–21, 2026 up-revision and refactoring of HarnessRanger, including its evaluation-harness additions. See AI-Assisted Development Attribution for the credited areas, implemented features, and provenance notes.

License

MIT

References

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages