npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@buildaharness/harness

v0.3.0

Published

TypeScript implementation of the Build A Harness 11-layer agent reasoning and control architecture — a resumable async engine (world model, control state, verification, recovery, reviewer pass).

Readme

@buildaharness/harness

TypeScript implementation of the 11-layer harness — World Model, Evidence, Hypothesis, Contradiction, Diagnostics, Control State, Planning, Execution, Verification, Recovery, Reviewer Pass — a governance and reliability control plane around an autonomous agent: the agent proposes, the harness decides what's allowed to happen next, evidence decides whether the result is accepted (see ADR-003, harness consolidation, for the 5-primitive model every layer here implements). Its pure-data constants (thresholds, the recovery-dependency table, LAYER_TIER) are generated from one shared source with the Python harness (adapter/harness/) rather than hand-copied field-for-field — see "Relationship to the Python harness" below. Since the HarnessRuntime rewrite it's also a real, resumable execution engine, not just a set of types.

This package has zero runtime/browser dependencies (only zod). It runs anywhere JS runs — browser, Node, edge — and knows nothing about storage; persistence is left entirely to the caller (see @buildaharness/runtime for IndexedDB/Dexie-backed implementations).

Running a harness

import { HarnessRuntime } from '@buildaharness/harness'

const runtime = new HarnessRuntime()

const outcome = await runtime.run(
  'Fix the failing test',
  ['tests pass'],
  {
    initialTasks: [{
      id: 'fix-test',
      description: 'Fix the failing test',
      status: 'PENDING',
      risk_level: 'MEDIUM',
      depends_on: [],
      parallel_write_domains: [],
      abstraction_level: 1,
      assigned_strategy: null,
    }],
    max_steps: 20,
    toolExecutors: { default: () => runMyTool() },
  },
)

if (outcome.status === 'complete') {
  console.log(outcome.result.finalResult, outcome.result.stepsUsed)
}

A run either resolves { status: 'complete', result: HarnessRunResult }, or throws EscalationHalt when the control-state resolver halts for human input (budget exhausted, cannot-make-progress, a review failure, etc.) — catch it and inspect err.blocker.

Pausing and resuming a run

run()/resume() are async and internally drive a generator that yields a serializable HarnessCheckpoint after every main-loop iteration that makes task progress. Use onCheckpoint to persist checkpoints as they happen, and shouldPause to stop the run early instead of running to completion:

import { HarnessRuntime, type HarnessCheckpoint } from '@buildaharness/harness'

const runtime = new HarnessRuntime()
let lastCheckpoint: HarnessCheckpoint | undefined

const outcome = await runtime.run(objective, successCriteria, {
  initialTasks,
  runId: 'my-run-id',              // used to key persisted checkpoints; auto-generated if omitted
  onCheckpoint: (checkpoint) => { lastCheckpoint = checkpoint },
  shouldPause: (checkpoint) => checkpoint.progress.stepsUsed >= 3, // stop after 3 steps
})

if (outcome.status === 'paused') {
  // Persist outcome.checkpoint (it's plain JSON — JSON.stringify/parse round-trips it)
  // and continue it later, even in a different process:
  const resumed = await runtime.resume(outcome.checkpoint, {
    toolExecutors: { default: () => runMyTool() }, // live objects aren't serialized — re-supply them
  })
}

Live objects — experienceStore, updateChannel, toolExecutors — are never part of a checkpoint. Re-supply them to resume(), the same way Python's state_store expects a fresh db_session_factory after load().

saveHarnessCheckpoint/loadHarnessCheckpoint/deleteHarnessCheckpoint persist a checkpoint by runId against any object shaped like { get, set, delete } (a CheckpointStore) — @buildaharness/runtime's InMemoryAdapter and IndexedDBAdapter both satisfy this without any adapter code:

import { saveHarnessCheckpoint, loadHarnessCheckpoint } from '@buildaharness/harness'
import { IndexedDBAdapter } from '@buildaharness/runtime'

const store = new IndexedDBAdapter({ namespace: 'my-app-checkpoints' })
await saveHarnessCheckpoint(store, outcome.checkpoint)
const reloaded = await loadHarnessCheckpoint(store, 'my-run-id')

Suspend point: propose → gate → execute

driveMainLoop has a second, earlier pause point in addition to the end-of-iteration checkpoint above: it yields immediately after action_gate produces a decision (PASS / BLOCK / ESCALATE) but before execute() runs, stashing the proposal as ctx.pendingProposal ({ taskId, gateResult, shouldGatherEvidence }) on the checkpoint's HarnessRunProgressData. This lets a caller inject a real approval step — "the LLM proposed this action, a human/policy layer needs to approve it" — between the harness deciding what it wants to do and actually doing it, instead of only being able to observe an action after it already ran.

A shouldPause callback that wants to stop here specifically (rather than at the default post-execution checkpoint) can key off the last pushed node being 'action_gate'. Nothing stops on this point by default — supplying no shouldPause reproduces the pre-existing end-to-end run behavior unchanged. On resume, if ctx.pendingProposal is present, driveMainLoop re-derives the same task/decision from the stored data instead of re-running task selection, risk estimation, and VOI evaluation a second time (which would double-count stepsUsed and re-mutate diagnostics).

Known scope boundary: resuming after a real process restart (not just an in-memory pause) loses select_task's opportunistic concurrent-task parallel-execution candidate — the resumed task executes serially. A same-process pause/resume never hits this, since the concurrent-task candidate only exists within the run that already selected it.

This suspend-point contract — propose, gate, then execute, with the option to pause between the two — is shared conceptually with Python's loop.py (both implement the same five-tier resolve_control_state() / resolveControlState() decision before any execution happens), but as of this writing the contract is not yet cross-referenced from loop.py's own docs/ADR, and Python's loop has no equivalent mid-iteration yield — it is synchronous, not a resumable generator. Treat this section as the TypeScript-side suspend point specifically, not a claim of a mirrored Python suspend point.

Cross-run learning (ExperienceStore)

ExperienceStore (strategy weights, learned decompositions, verification plans, recovery sequences) is a separate, fully synchronous interface — it's called mid-loop by HarnessRuntime, so implementations can't do async I/O inline. This package ships two:

  • InMemoryExperienceStore — in-process, resets every run. The default.
  • UnavailableExperienceStore — every method is a no-op; available is false. Used when no store is supplied — a run behaves identically to one with no learning layer at all.

For an implementation that survives a page reload, see DexieExperienceStore in @buildaharness/runtime.

Relationship to the Python harness (adapter/harness/)

State shapes are mirrored 1:1 (all 13 structures round-trip via toJSON()/fromJSON(), matching Python's to_dict()/from_dict()). Storage is not mirrored 1:1 by design — Python's state_store.py and experience_store.py are Postgres-backed because the Python harness runs server-side; this package stays storage-agnostic so it can run fully client-side. The one thing that is now equivalent in capability (not implementation) is pause/resume: Python gets it from an async graph runtime with DB-backed checkpoints, this package gets it from the async-generator HarnessRuntime described above.

Shared semantic core. The pure-data constants both languages' resolvers read — CRITICAL_THRESHOLD/CAUTION_THRESHOLD, the recovery-dependency tables, LAYER_TIER — are generated from one file, spec/harness-core.json, by spec/gen-harness-core.mjs, into adapter/harness/_core_generated.py and this package's src/_core-generated.ts. Neither generated file is hand-edited (each is stamped "DO NOT EDIT" at the top); CI fails if either is stale relative to the source. The ~150-line resolver algorithm (resolve-control-state.ts here, control_state.py in Python) is still hand-mirrored, not generated — the conformance run (scripts/harness-conformance/, 53 resolver fixtures + committed goldens) found the two implementations already byte-identical, so generating the algorithm too would solve a problem that doesn't exist. That fixture suite is the actual equivalence contract, run against both interpreters on every PR; it replaced an earlier field-by-field sync-checking script. See ADR-004 (shared semantic core).

Verification's validator-list model. verify.ts (mirroring Python's verification.py) is a typed list of validators, each classified into one of three epistemic tiers via the shared LAYER_TIER map — mechanical (a real subprocess-backed check, e.g. syntax/unit tests), environmental (a real state inspection, e.g. consistency), or model (an LLM judgment). A model tier result is never counted as independent confirmation of a mechanical one — VerificationResult.critical_failure_tiers names which tiers contributed a FAIL, and a structural check enforces it's non-empty if and only if has_critical_failure is true. verify() has its own TS/Python conformance pair (compare-verify.mjs, 25 fixtures) comparing the per-layer status projection; it surfaced that output_contract_partial inspects different contract fields on each runtime (TS required_sections vs Python required_interface_fields), now a tracked discrepancy rather than an invisible one.

Package structure

| Path | Contents | |---|---| | src/state/ | The 13 state structures (WorldModel, TaskGraph, ControlState, Diagnostics, EvidenceStore, HypothesisSet, MemoryState, StrategyState, FailureDiagnostics, OutputContract, CallerState, ExperienceStore) | | src/nodes/ | One file per harness node (gather-evidence.ts, resolve-control-state.ts, execute.ts, verify.ts, reviewer-pass.ts, etc.) | | src/harness-runtime.ts | HarnessRuntime — the resumable main loop | | src/harness-checkpoint.ts | HarnessCheckpoint/CheckpointStore types + save/load/delete helpers | | src/harness-run-state.ts | HarnessRunState — serializes/deserializes all 13 structures together | | src/process-concept.ts, process-registry.ts | Reusable task-graph seeding "process concepts" |

Commands

npm run build --workspace=packages/harness
npm test --workspace=packages/harness
npm run typecheck --workspace=packages/harness