Architecture

August 26, 2026 ยท View on GitHub

DSH BenchUp has two deliberately separate parts.

dsh-benchup is a host-side CLI. It expands an experiment into the product of models, variants, scenarios, and repetitions; gives each cell an isolated workspace and persistent-state directory; starts a short-lived dsh --profile child; then evaluates the resulting workspace and response.

The package is also the Cordis plugin dsh-benchup. The runner inserts it only into benchmark children. It observes the durable session/event stream, writes raw JSONL traces, derives core counters, and exposes ctx.benchMetrics for the variant under test to add diagnostics. Its agent/request waterfall listener applies the configured provider/model/generation fields, so the effective request remains visible in the Harness session log.

Isolation and state

Each cell gets a private scratch tree:

cell/
  workspace/     # agent-visible files
  persistent/    # passed as DSH_BENCHUP_STATE_ROOT

Episode state controls whether each directory is reset or retained. cold is represented by resetting both. warm memory retains persistent while resetting the workspace and starting a fresh process. A persistent-memory plugin must intentionally use DSH_BENCHUP_STATE_ROOT (or provide an equivalent configured root); BenchUp never changes DSH_HOME, because profiles and settings live there.

The first release runs every episode in a fresh child. The schema already accepts session: continue and process: reuse, but the runner rejects them loudly rather than silently giving a false warm-session result. A future persistent driver can add those modes without changing experiment files.

Measurements

Core metrics are derived from the session event stream: prompt/output/cache token usage, LLM turns, tool calls, subagent descriptors, retries, tool-result errors, wall time, repeated file reads, repeated searches, repeated commands, and mechanically identical tool calls. Repeated reads include the file/range and a local write revision, so reading a file again after a successful recorded write is not counted as wasted repetition.

Custom metrics use a small extension API:

ctx.benchMetrics.register({
  name: 'memcore.memory_hits',
  unit: 'count', aggregation: 'sum', dimension: 'diagnostic', scope: 'episode',
})
ctx.benchMetrics.add('memcore.memory_hits')

Names must be namespaced. Each run artifact includes their definitions and values, and comparison output shows them independently instead of folding them into a score.

Results

runs/<run-id>/ contains the normalized experiment, per-cell child patches, raw traces/*.jsonl, per-episode summary.json, machine-readable runs.json, and comparison.json, plus a concise report.md. Reports keep quality, efficiency, robustness, and diagnostics separate. baseline is a conventionally named variant; deltas are only calculated against a matching baseline model and scenario.

Trace artifacts can contain prompts, tool arguments, output, and file paths. Store them as sensitive engineering data and do not upload them blindly.