openmerit 0.1.12 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +11 -27
- package/dist/pi/scout-extension.mjs +23 -10
- package/dist/terminal/scout-update.json +1 -1
- package/dist/terminal/src/browser.mjs +2 -4
- package/dist/terminal/src/cli.mjs +6 -56
- package/dist/terminal/src/install.mjs +3 -2
- package/dist/terminal/src/scout-instructions.js +23 -10
- package/dist/terminal/src/scout-pi.js +1 -1
- package/dist/terminal/src/scout.js +181 -0
- package/dist/terminal/src/telemetry.mjs +8 -60
- package/docs/agent-evaluations.md +8 -148
- package/docs/commands.md +4 -86
- package/docs/getting-started.md +2 -16
- package/docs/index.md +4 -27
- package/docs/inference-terminal.md +13 -655
- package/docs/pi-extension.md +1 -1
- package/docs/roadmap.md +4 -17
- package/docs/scout.md +34 -251
- package/docs/security.md +8 -33
- package/docs/testing.md +7 -47
- package/docs/troubleshooting.md +3 -3
- package/package.json +13 -46
- package/dist/core/src/index.d.ts +0 -101
- package/dist/core/src/index.js +0 -1649
- package/dist/core/src/store.d.ts +0 -35
- package/dist/core/src/store.js +0 -102
- package/dist/eval/src/adapters.mjs +0 -112
- package/dist/eval/src/cli.mjs +0 -151
- package/dist/eval/src/config.mjs +0 -108
- package/dist/eval/src/process.mjs +0 -44
- package/dist/eval/src/report.mjs +0 -59
- package/dist/eval/src/runner.mjs +0 -123
- package/dist/eval/src/scout.mjs +0 -48
- package/dist/protocol/src/index.d.ts +0 -484
- package/dist/protocol/src/index.js +0 -47
- package/dist/protocol/src/schemas.d.ts +0 -576
- package/dist/protocol/src/schemas.js +0 -280
- package/dist/terminal/public/app.js +0 -298
- package/dist/terminal/public/brands/anthropic.png +0 -0
- package/dist/terminal/public/brands/baai.png +0 -0
- package/dist/terminal/public/brands/baseten.png +0 -0
- package/dist/terminal/public/brands/cerebras.png +0 -0
- package/dist/terminal/public/brands/cohere.png +0 -0
- package/dist/terminal/public/brands/deepseek.ico +0 -0
- package/dist/terminal/public/brands/google.png +0 -0
- package/dist/terminal/public/brands/groq.ico +0 -0
- package/dist/terminal/public/brands/huggingface.svg +0 -8
- package/dist/terminal/public/brands/lm-studio.png +0 -0
- package/dist/terminal/public/brands/meta.ico +0 -0
- package/dist/terminal/public/brands/mistral.png +0 -0
- package/dist/terminal/public/brands/nomic.png +0 -0
- package/dist/terminal/public/brands/ollama.png +0 -0
- package/dist/terminal/public/brands/openai.png +0 -0
- package/dist/terminal/public/brands/openrouter.png +0 -0
- package/dist/terminal/public/brands/qwen.png +0 -0
- package/dist/terminal/public/brands/vllm.ico +0 -0
- package/dist/terminal/public/brands/vllm.png +0 -0
- package/dist/terminal/public/favicon.svg +0 -1
- package/dist/terminal/public/flow.css +0 -1
- package/dist/terminal/public/flow.js +0 -770
- package/dist/terminal/public/index.html +0 -22
- package/dist/terminal/public/styles.css +0 -1046
- package/dist/terminal/src/activity-merge.mjs +0 -66
- package/dist/terminal/src/collect.mjs +0 -370
- package/dist/terminal/src/coverage.mjs +0 -33
- package/dist/terminal/src/demo-policy.mjs +0 -205
- package/dist/terminal/src/discovery.mjs +0 -99
- package/dist/terminal/src/enterprise-sample.mjs +0 -151
- package/dist/terminal/src/hardware.mjs +0 -57
- package/dist/terminal/src/history.mjs +0 -32
- package/dist/terminal/src/log-continuity.mjs +0 -26
- package/dist/terminal/src/project-activity.mjs +0 -157
- package/dist/terminal/src/repository-background.mjs +0 -37
- package/dist/terminal/src/repository-index.mjs +0 -267
- package/dist/terminal/src/repository-policy.mjs +0 -3
- package/dist/terminal/src/repository-syntax.mjs +0 -236
- package/dist/terminal/src/repository-worker.mjs +0 -15
- package/dist/terminal/src/sample.mjs +0 -171
- package/dist/terminal/src/scout-credentials.d.ts +0 -12
- package/dist/terminal/src/scout-credentials.ts +0 -44
- package/dist/terminal/src/scout-instructions.d.ts +0 -5
- package/dist/terminal/src/scout-instructions.ts +0 -106
- package/dist/terminal/src/scout-pi.d.ts +0 -44
- package/dist/terminal/src/scout-pi.ts +0 -76
- package/dist/terminal/src/server.mjs +0 -95
- package/dist/terminal/src/service-registry.mjs +0 -78
- package/dist/terminal/src/services.mjs +0 -44
- package/dist/terminal/src/topology.mjs +0 -30
- package/dist/terminal/src/updates.d.ts +0 -62
- package/dist/terminal/src/updates.ts +0 -313
- package/docs/adapter-guide.md +0 -191
- package/docs/architecture.md +0 -61
- package/docs/automation.md +0 -76
- package/docs/budgets.md +0 -39
- package/docs/demo-backfill.md +0 -31
- package/docs/demo-fieldkit.md +0 -49
- package/docs/demo-placement.md +0 -32
- package/docs/demo-spam.md +0 -17
- package/docs/demo-support.md +0 -44
- package/docs/demo.md +0 -74
- package/docs/first-trial.md +0 -62
- package/docs/interactive-demo.md +0 -118
- package/docs/lifecycle.md +0 -32
- package/docs/metrics-and-evidence.md +0 -48
- package/docs/operations.md +0 -40
- package/docs/pareto-spec.md +0 -76
- package/docs/ux-reference.md +0 -32
|
@@ -5,12 +5,8 @@ export let clientVersion;
|
|
|
5
5
|
for (const path of ['../../../package.json', '../../../../package.json']) {
|
|
6
6
|
try { const pkg = JSON.parse(readFileSync(new URL(path, import.meta.url), 'utf8')); if (pkg.name === 'openmerit') { clientVersion = pkg.version; break; } } catch {}
|
|
7
7
|
}
|
|
8
|
-
|
|
9
|
-
const applicationURLs = frameFiles.
|
|
10
|
-
const diagnostics = new WeakMap();
|
|
11
|
-
export function scoutDiagnostic(error, trace, code) {
|
|
12
|
-
if (error && typeof error === 'object' && ['scout_network_error', 'scout_http_error', 'scout_response_error', 'scout_timeout'].includes(code)) diagnostics.set(error, { operation: 'scout_recommend', code, ...(typeof trace === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(trace) ? { trace_id: trace } : {}) });
|
|
13
|
-
}
|
|
8
|
+
const frameFiles = Object.freeze(['cli.mjs', 'install.mjs']);
|
|
9
|
+
const applicationURLs = frameFiles.map(file => new URL(`../../terminal/src/${file}`, import.meta.url).href);
|
|
14
10
|
export function safeFrames(error) {
|
|
15
11
|
try {
|
|
16
12
|
const stack = error?.stack;
|
|
@@ -24,7 +20,7 @@ export function safeFrames(error) {
|
|
|
24
20
|
} catch { return []; }
|
|
25
21
|
}
|
|
26
22
|
export function errorProperties(error) {
|
|
27
|
-
try { return { error_type: errorType(error), frames: safeFrames(error)
|
|
23
|
+
try { return { error_type: errorType(error), frames: safeFrames(error) }; }
|
|
28
24
|
catch { return { error_type: 'Error', frames: [] }; }
|
|
29
25
|
}
|
|
30
26
|
const environment = () => ({ ...(clientVersion ? { client_version: clientVersion } : {}), platform: ['darwin', 'linux', 'win32'].includes(process.platform) ? process.platform : 'unknown', runtime_major: Number(process.versions.node.split('.')[0]) });
|
|
@@ -99,65 +95,17 @@ export async function sendInstallationEvent(input) {
|
|
|
99
95
|
} catch { /* Never affect setup, even if the transport ignores abort. */ }
|
|
100
96
|
finally { clearTimeout(timer); }
|
|
101
97
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const out = {};
|
|
106
|
-
const select = (key, values) => { if (!values.includes(input[key])) return false; out[key] = input[key]; return true; };
|
|
107
|
-
if (event === 'terminal_error') {
|
|
108
|
-
if (!select('code', ['collection_error', 'snapshot_error', 'render_error', 'uncaught_error']) || !select('error_type', ['Error', 'TypeError', 'RangeError', 'SyntaxError', 'ReferenceError', 'URIError', 'EvalError', 'AggregateError', 'AbortError'])) return null;
|
|
109
|
-
if (Array.isArray(input.frames)) out.frames = input.frames.slice(0, 8).filter(f => f && frameFiles.includes(f.filename) && Number.isInteger(f.lineno) && f.lineno > 0 && f.lineno <= 1000000 && Number.isInteger(f.colno) && f.colno > 0 && f.colno <= 1000000).map(f => ({ filename: f.filename, lineno: f.lineno, colno: f.colno }));
|
|
110
|
-
return out;
|
|
111
|
-
}
|
|
112
|
-
if (!select('mode', ['sample', 'live'])) return null;
|
|
113
|
-
if (event === 'terminal_visited') return out;
|
|
114
|
-
if (event === 'terminal_page_viewed') return select('page', ['overview', 'models', 'services', 'activity', 'compute', 'sources', 'connections']) ? out : null;
|
|
115
|
-
if (event === 'terminal_interaction') return select('action', ['inspect', 'filter', 'search', 'map_expand', 'mode', 'command']) && select('kind', ['model', 'agent', 'task', 'service', 'source', 'host', 'deployment', 'pool', 'record', 'path', 'other']) ? out : null;
|
|
116
|
-
if (event !== 'terminal_snapshot') return null;
|
|
117
|
-
for (const key of ['model_count', 'record_count', 'source_count', 'host_count', 'deployment_count', 'agent_count']) {
|
|
118
|
-
if (!Number.isInteger(input[key]) || input[key] < 0 || input[key] > 1000000000) return null;
|
|
119
|
-
out[key] = input[key];
|
|
120
|
-
}
|
|
121
|
-
return out;
|
|
122
|
-
}
|
|
123
|
-
// Shared, process-wide budget; no queue and at most four in-flight requests.
|
|
124
|
-
let windowStart = 0, count = 0, active = 0;
|
|
125
|
-
export function sendTerminalEvent(event, input) {
|
|
126
|
-
if (!telemetryEnabled()) return;
|
|
127
|
-
const properties = terminalProperties(event, input);
|
|
128
|
-
if (!properties) return;
|
|
129
|
-
if (Date.now() - windowStart >= 60000) { windowStart = Date.now(); count = 0; }
|
|
130
|
-
if (count >= 60 || active >= 4) return;
|
|
131
|
-
count++; active++;
|
|
132
|
-
void sendAnalytics(event, properties).finally(() => active--);
|
|
133
|
-
}
|
|
134
|
-
async function sendAnalytics(event, properties) {
|
|
135
|
-
const controller = new AbortController();
|
|
136
|
-
const body = JSON.stringify({ event, event_id: randomUUID(), anonymousId, properties: { ...properties, ...environment() } });
|
|
137
|
-
let timer;
|
|
138
|
-
try {
|
|
139
|
-
await Promise.race([
|
|
140
|
-
Promise.resolve().then(() => fetch('https://openmerit.ai/scout/api/analytics', {
|
|
141
|
-
method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Scout-Client': 'cli', 'X-Scout-Analytics': 'on', ...(process.env.OPENMERIT_ANALYTICS_ACCOUNT === 'off' ? { 'X-Scout-Analytics-Account': 'off' } : {}) },
|
|
142
|
-
body, signal: controller.signal, redirect: 'error',
|
|
143
|
-
})).then(response => response.body?.cancel()),
|
|
144
|
-
new Promise(resolve => { timer = setTimeout(() => { controller.abort(); resolve(); }, 750); timer.unref(); }),
|
|
145
|
-
]);
|
|
146
|
-
} catch { /* Never affect product behavior. */ }
|
|
147
|
-
finally { clearTimeout(timer); }
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Consent is independent of terminal discovery. Command identity is ephemeral;
|
|
151
|
-
// the installer separately manages the owned installation's correlation IDs.
|
|
98
|
+
const errorType = error => ['Error', 'TypeError', 'RangeError', 'SyntaxError', 'ReferenceError', 'URIError', 'EvalError', 'AggregateError', 'AbortError'].includes(error?.name) ? error.name : 'Error';
|
|
99
|
+
// Command identity is ephemeral; the installer separately manages the owned
|
|
100
|
+
// installation's correlation IDs.
|
|
152
101
|
export function commandTelemetry(args) {
|
|
153
102
|
const setup = ['install', 'status', 'remove', 'login', 'logout', 'project', 'doctor'];
|
|
154
103
|
const enabled = () => telemetryEnabled(setup.includes(args[0]));
|
|
155
104
|
if (!enabled()) return async () => {};
|
|
156
105
|
const started = performance.now();
|
|
157
106
|
const command_id = randomUUID();
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
? 'help' : args[0] === 'dash' ? 'dash' : setup.includes(args[0]) ? args[0] : args[0] === 'eval' && actions.includes(args[1]) ? `eval_${args[1]}` : 'unknown';
|
|
107
|
+
const command = !args.length || args.includes('--help') || args.includes('-h')
|
|
108
|
+
? 'help' : setup.includes(args[0]) ? args[0] : 'unknown';
|
|
161
109
|
async function send(event, properties) {
|
|
162
110
|
if (!enabled()) return;
|
|
163
111
|
const controller = new AbortController();
|
|
@@ -1,155 +1,15 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Agent-evaluation CLI retirement
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**npm 0.3.0, 4 November 2026.** The standalone `openmerit eval` CLI is retired in full, including `init`, `doctor`, `plan`, `run`, `watch` and `report`. Older installed packages keep it until they are upgraded. The old Scout JSON recommendation API is retired in unreleased source and goes offline only with a separate Scout deployment.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
After an approved Scout release, `/scout/api/recommend` and its legacy alpha/versioned paths return 404, regardless of authentication. There is no replacement frozen-plan protocol. Use the [Scout conversational agent or MCP](scout.md) for provisional model guidance and your own representative task checks for evaluation. The Inference Terminal is [retired as well](inference-terminal.md); the Pi adapter remains a native Scout MCP integration, not an evaluation runner.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Existing local artifacts
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Upgrading does not delete `.openmerit/eval.json`, reports, budget ledgers, task fixtures or grader files. Review and retain or remove them yourself. Stop any old foreground watcher before upgrading. Instructions previously appended to `AGENTS.md` or `CLAUDE.md` are not automatically rewritten; remove obsolete evaluation instructions deliberately, preserving unrelated project guidance.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Historical reports remain evidence only for the versions and tasks actually tested. Unknown costs do not become known, and past budget reservations are not reconciled provider bills. Retirement does not cancel external agent/provider work, erase historical Scout analytics, change provider retention or enforce billing limits.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
## Preserved capabilities
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Scout planning requests carry `X-Scout-Client: cli` and `X-Scout-Analytics: off` unless explicitly opted in without Do Not Track. They always include `X-Scout-Analytics-Content: off`, so task descriptions required for planning are not opted into richer product-analytics content collection even when command analytics is enabled. The server owns search-completion counts; the CLI does not emit another search event. This opt-out affects optional PostHog product events, not task processing or historical private Cloudflare prompt records. Planning still sends the task descriptions and model scope required by its protocol. Evaluation planning requires a current Clerk session token; the separate device key from coding-agent setup grants MCP recommendations only, not JSON API access.
|
|
18
|
-
|
|
19
|
-
## Set up
|
|
20
|
-
|
|
21
|
-
Install the stable release and initialize it inside the project you want to evaluate:
|
|
22
|
-
|
|
23
|
-
```sh
|
|
24
|
-
npm install -g openmerit@latest
|
|
25
|
-
openmerit eval init
|
|
26
|
-
openmerit eval doctor
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
Init creates `.openmerit/eval.json`, a tiny extraction fixture, a tool and a standalone grader. It appends marked instructions to `AGENTS.md` and `CLAUDE.md`, preserving existing contents. Codex/OpenCode can read `AGENTS.md`; Claude Code reads `CLAUDE.md`. The instructions ask the agent to configure representative tasks, choose scope, obtain the user's budget, and rerun after CLI changes. These are instructions the host must follow, not guaranteed hooks. There are no install-time hooks or background services. A second init refuses to overwrite the suite.
|
|
30
|
-
|
|
31
|
-
Replace the starter before drawing product conclusions. Have your agent author representative fixtures and graders with you, and reserve fresh cases for final validation.
|
|
32
|
-
|
|
33
|
-
## Choose scope and connections
|
|
34
|
-
|
|
35
|
-
```sh
|
|
36
|
-
openmerit eval plan
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
The first interactive plan asks: **existing project connections or all models Scout indexes?** It then asks for a **$10, custom or no-fixed-cap budget**. Both choices are saved. Noninteractive agents must ask the user and pass `--scope existing` or `--scope all` together with `--budget <USD|unlimited>` on first setup; missing input never chooses scope or spending automatically.
|
|
40
|
-
|
|
41
|
-
Add explicit routes to `connections` in the config, for example:
|
|
42
|
-
|
|
43
|
-
```json
|
|
44
|
-
{
|
|
45
|
-
"id": "claude-project",
|
|
46
|
-
"agent": "claude",
|
|
47
|
-
"scoutId": "anthropic/claude-haiku-4.5",
|
|
48
|
-
"model": "claude-haiku-4-5-20251001",
|
|
49
|
-
"env": ["ANTHROPIC_API_KEY"]
|
|
50
|
-
}
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
`scoutId` is Scout's catalogue ID. `model` is the native identifier your authenticated agent accepts. `command` optionally selects another executable path. `env` lists environment variable **names**, never values. Only basic OS variables and explicitly listed names pass to child agents. Saved authentication remains available through the normal home directory. No dotenv files are loaded automatically. Configure endpoint details through the native agent or named environment variables.
|
|
54
|
-
|
|
55
|
-
An SDK dependency or key-variable name does not prove access. The agent should inspect the project's intended connections and declare the models they can serve. This preview does not automatically enumerate endpoint catalogues. Multiple connections can test one Scout model through different agents/routes. Prefer pinned model versions; aliases can change.
|
|
56
|
-
|
|
57
|
-
Existing scope sends IDs and requires Scout to acknowledge filtering **before ranking five**. Fewer than five eligible models remain fewer. All scope searches the index, but missing authenticated routes block execution until configured and replanned. Inaccessible candidates are not silently replaced. Unranked Hugging Face specialists are not executed automatically.
|
|
58
|
-
|
|
59
|
-
Scout receives only each task's `description`, plus IDs for existing scope. Scout sends descriptions to OpenAI Decisions. Fixtures, execution prompts, endpoint URLs and credentials stay out of this request. The shortlist, warnings and ranking context are frozen locally. Scout scores are screening evidence, not measured success with your harness.
|
|
60
|
-
|
|
61
|
-
## Tasks and variants
|
|
62
|
-
|
|
63
|
-
Each task needs `id`, `description` (for Scout, at most 4,000 characters), `prompt` (for execution), `fixture` (a project-relative directory) and `grader` (a standalone Node `.mjs` file).
|
|
64
|
-
|
|
65
|
-
Each variant needs `id`, `files` and `instructions`. The starter compares `bare` against `cli`. Bare omits your CLI/docs; native agent tools remain available. Across agents you are comparing different harnesses, with different permission systems. A no-native-tools experiment needs a separately controlled configuration.
|
|
66
|
-
|
|
67
|
-
Selected files, including uncommitted changes, are snapshotted before execution. Variant paths must not overwrite fixture inputs and retain their project-relative locations; fixture contents go at the workspace root. Include self-contained CLI artifacts and lean docs explicitly. Dependencies are not installed automatically; tools must be bundled or have their runtime requirements already available. Symlinks, parent-directory paths, `.env*`, `.git`, `.openmerit` and `node_modules` are rejected. Each selected snapshot is limited to 25 MB. Do not select credentials stored under other filenames.
|
|
68
|
-
|
|
69
|
-
The grader reads `{ "workspace": "/temporary/path", "output": "final response" }` from stdin and prints exactly `{ "quality": 0.0 }`, with a finite score from 0 to 1. It can check generated files using executable assertions. Keep it self-contained: imports beside it are not copied automatically. Graders are copied outside agent workspaces; never also include them or answer keys in fixtures/variant files. Test graders against correct and incorrect answers. A broken grader stops the experiment with unknown quality. Ordinary agent failures/timeouts count as quality zero; recognized budget, environment and connection blocks instead stop with unknown quality. See [failure classification](#accounting-and-blocked-executions).
|
|
70
|
-
|
|
71
|
-
## Run after changes
|
|
72
|
-
|
|
73
|
-
The starter's `budget.maxUsd` is zero. After the user's scope and budget choices, for example:
|
|
74
|
-
|
|
75
|
-
```sh
|
|
76
|
-
openmerit eval plan --scope existing --budget 10
|
|
77
|
-
openmerit eval run
|
|
78
|
-
# Edit your CLI or its documentation.
|
|
79
|
-
openmerit eval run
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
For repeated local development:
|
|
83
|
-
|
|
84
|
-
```sh
|
|
85
|
-
openmerit eval watch
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Watch runs initially, then after selected source/docs/fixture/grader/config bytes change and remain stable for two polls. Result writes do not trigger it. Runs never overlap; edits during execution become the next revision. Ctrl+C stops the watcher and active child process. No OS schedule or daemon is installed. `OPENMERIT_EVAL=1` tells cooperating agent instructions not to recurse into another evaluation.
|
|
89
|
-
|
|
90
|
-
Every attempt uses a new workspace and agent session. Each task runs balanced rounds across all selected connections and variants; order rotates and reverses. The default is 3–10 repetitions. After three, rounds continue while any group's quality range exceeds 5 percentage points, an attempt failed, or cost, input-token or latency variation has a coefficient of variation above 0.25. Ten is the maximum. Missing metrics cannot establish stability. Set `repeats.min` equal to `repeats.max` for fixed repetitions, useful for holdouts. This heuristic is not a significance test, and repetition is not task diversity.
|
|
91
|
-
|
|
92
|
-
The frozen plan survives CLI changes. Changes to descriptions, scope or connections require replanning. Previous-revision comparisons require matching prompts, fixtures, graders, routes, repeat settings, selected candidates, variant IDs, timeouts, agent versions, runner versions, invocation settings and reported model identities. CLI/docs bytes and variant instructions are the interventions. Keep external services and native agent settings stable too; they are not hermetically captured.
|
|
93
|
-
|
|
94
|
-
## Metrics
|
|
95
|
-
|
|
96
|
-
```sh
|
|
97
|
-
openmerit eval report
|
|
98
|
-
openmerit eval report --json
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
Reports show quality mean/range, failures, mean input/output tokens, mean reported dollars and median full-process seconds per task/connection/variant. They retain Scout ranks but do not force a weighted winner. Lower cost with lower quality is a tradeoff. Matching complete revisions show deltas; partial/invalid experiments do not.
|
|
102
|
-
|
|
103
|
-
Claude provides aggregate and per-model usage and cost estimates, reconciled without counting the same usage twice. Codex JSON events provide tokens but not billed dollars, so cost stays unknown. OpenCode per-step usage/cost is summed across the episode, including tools; missing or zero step pricing leaves full cost unknown and preserves partial estimates. Input totals include separately reported cache reads/writes; cached tokens are retained separately without counting them twice. OpenCode output totals include separately reported reasoning tokens. Agent accounting and subscriptions differ. Reported costs are not reconciled provider bills; zero pricing is treated as unknown. Catalogue prices never replace unknown measured costs.
|
|
104
|
-
|
|
105
|
-
Preflight requires supported noninteractive JSON interfaces: Claude print JSON, Codex `exec --json --ephemeral --sandbox workspace-write`, and OpenCode `run --format json --auto`. OpenCode's auto option approves tool requests that are not explicitly denied, avoiding an interactive approval stall. Claude uses an explicit local tool allowlist without inherited MCP configuration; Codex and OpenCode retain native global settings. Recognized permission failures stop as connection problems, not model-quality evidence. OpenMerit does not add a sandbox around Claude/OpenCode. The old 2025 Codex CLI is unsupported. Native references: [Claude Code](https://code.claude.com/docs/en/headless), [Codex](https://developers.openai.com/codex/noninteractive), [OpenCode](https://opencode.ai/docs/cli/).
|
|
106
|
-
|
|
107
|
-
## Budget and data
|
|
108
|
-
|
|
109
|
-
`budget.maxUsd` applies cumulatively across runs and restarts. Before each attempt the runner persists a reservation. It retains the greater of that reservation and the available full or partial cost estimate; estimates never release reserved allowance. Partial events never count as a complete bill. Insufficient remaining allowance stops a partial run. Raising maxUsd extends the allowance, not resets it. Do not delete unknown spend from the ledger. This is admission control, not a billing cutoff: one attempt may exceed its reservation. Finite budgets also use Claude's native maximum-budget flag. Use provider-side limits for hard monetary caps. Each attempt also has a timeout and 4 MB process-output limit. See [budget selection](#budget-selection) for the three choices and automatic reservations.
|
|
110
|
-
|
|
111
|
-
`.openmerit/eval/` holds `plan.json`, `budget.json`, `latest.json`, `runs/*.json` and `lock/pid`. Init ignores it in Git. Reports contain identities, metrics, hashes and status, not full transcripts or final outputs. Temporary files are removed afterward. Native agents/providers may retain their own data; Claude/Codex receive ephemeral flags, while OpenCode uses native storage. `.openmerit/eval.json` can be versioned without credentials.
|
|
112
|
-
|
|
113
|
-
Fresh workspaces are not security sandboxes. Trusted agents and graders execute with native permissions and user-level resources. Hard kills may leave temporary directories. After a crash, inspect the lock's PID and remove it only if that process is gone. This preview does not change Pi approvals, swap production models or upload results into Scout rankings.
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
## VM acceptance limits
|
|
117
|
-
|
|
118
|
-
The published `0.1.7-preview.1` package was tested on an Ubuntu ARM64 VM with Node 22.23.1 on 15 October 2026. Claude Code 2.1.300 and OpenCode 1.19.0 executed a small CSV CLI task before and after a parser change. A separate OpenCode watcher completed three attempts per revision and emitted comparison deltas. Codex 0.162.1 passed interface preflight but could not execute filesystem tools because that VM denied the required Linux user namespaces. CLI flag checks do not establish that the native sandbox works on a host.
|
|
119
|
-
|
|
120
|
-
In that earlier `0.1.7-preview.1` test, a native budget stop could appear as a generic agent failure, and a successful final response explaining a host permission problem could receive zero from the task grader. These did not establish poor model quality; the corrections below address recognized native failures. The combined VM run also stopped before its final repetition because conservative reservations and agent cost estimates exhausted its local allowance; partial reports correctly omitted automatic comparison. Agent-reported cost differed substantially from OpenRouter account usage. This was one integration fixture, not validation of general task quality, exact model order, or billing accuracy.
|
|
121
|
-
|
|
122
|
-
## Accounting and blocked executions
|
|
123
|
-
|
|
124
|
-
Since `0.1.7-preview.2`, recognized budget, sandbox, permission, authentication and model-access blocks are separate from task failures. A blocked attempt has `quality: null`, stops the run and cannot produce a revision comparison. Reports distinguish scored attempts, blocked attempts and task-check failures. Ordinary wrong outputs still receive their grader score; ordinary agent failures and configured timeouts still count as failures. Cancellation, a missing executable and output-limit interruption are unscored. Error classification uses native failure fields and failed-tool diagnostics, not arbitrary task text or model commentary. Unrecognized host failures can still require manual review.
|
|
125
|
-
|
|
126
|
-
On Linux, Codex preflight also runs a local sandbox probe before any model request or budget reservation. It uses the configured executable and the workspace-write policy; it does not weaken sandbox permissions. A failed probe produces `environment_blocked` with no task score. Doctor performs this same probe. Other operating systems still have interface checks only.
|
|
127
|
-
|
|
128
|
-
Claude's per-model totals recover usage omitted from aggregate budget-stop responses, without adding the same aggregate and model counters twice. Costs carry `costBasis` and remain native estimates. Zero or missing pricing is unknown; incomplete OpenCode step pricing stays partial. Partial costs survive into the row, summary and ledger, including failed attempts. No provider bill is reconstructed from these estimates, and no account-wide spend delta is assigned to individual attempts.
|
|
129
|
-
|
|
130
|
-
Budget admission now retains the greater of each reservation and its available full or partial estimate, including old ledger entries. Estimates never release a reservation. This may exhaust an existing allowance earlier; increasing it requires an explicit budget decision. The displayed reserved allowance is not billed spend, and a provider-side limit is still needed for a hard cap. Report version 2 prevents comparisons with the earlier accounting rules. There is no new provider integration, proxy, background service or model-specific rule.
|
|
131
|
-
|
|
132
|
-
## Budget selection
|
|
133
|
-
|
|
134
|
-
After choosing existing connections or all indexed models, the first interactive `eval plan` asks:
|
|
135
|
-
|
|
136
|
-
1. **$10** — a cumulative evaluation allowance for this project.
|
|
137
|
-
2. **Custom amount** — asks how much in USD.
|
|
138
|
-
3. **No fixed cap** — run the configured suite without a monetary admission limit.
|
|
139
|
-
|
|
140
|
-
Nothing is preselected. Blank, invalid or cancelled input cannot enable spending. Init still starts at zero. Newly generated project instructions tell coding agents to ask the same follow-up and pass the answer explicitly, for example:
|
|
141
|
-
|
|
142
|
-
```sh
|
|
143
|
-
openmerit eval plan --scope existing --budget 10
|
|
144
|
-
# Alternatives after the user's choice:
|
|
145
|
-
openmerit eval plan --budget 25.50
|
|
146
|
-
openmerit eval plan --budget unlimited
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
`--budget` belongs to `plan`, accepts positive USD amounts with at most two decimal places or the exact word `unlimited`, and never starts evaluation by itself. Noninteractive planning requires explicit flags when scope or budget has not been chosen. Existing positive budgets are reused. The choices are saved even if Scout subsequently fails, so a retry does not ask again. Init does not rewrite instructions in already-initialized projects; an agent in such a project can use these flags directly.
|
|
150
|
-
|
|
151
|
-
The allowance is cumulative across runs, watched edits, restarts and replanning. Changing from $10 to $20 raises the total allowance to $20; it does not add $20 or erase earlier reservations. Changing to or from no fixed cap also preserves the ledger. A normal `eval plan` reuses the saved choice. To change it, pass a new `--budget` value; setting `budget.maxUsd` back to zero in the config disables paid execution and prompts again on the next interactive plan.
|
|
152
|
-
|
|
153
|
-
Reservations are internal. New suites and budget choices use `reservationUsd: "auto"`: the smaller of $0.25 and the total allowance divided across the minimum planned attempts (tasks × selected connections × variants × minimum repetitions). No fixed cap uses $0.25 for ledger bookkeeping. This is a conservative starting allowance, not a prediction of an attempt's price or a guarantee the suite will finish. Higher reported charges still consume more allowance. Existing explicitly configured numeric reservations remain supported. Finite budgets retain Claude's native per-attempt budget flag; as before, an attempt can exceed its reservation, and provider limits are needed for a hard billing cap.
|
|
154
|
-
|
|
155
|
-
No fixed cap is stored explicitly as `budget.maxUsd: "unlimited"`; missing, null or invalid values never mean unlimited. It also removes Claude's per-attempt dollar limit, while keeping the same task count, 3–10 repetition bounds, timeouts and native permissions. Provider/account limits still apply. Usage and cost estimates remain recorded. `eval watch` can incur further charges after each selected change until stopped; Ctrl+C stops it and the active attempt. No background service or automatic production model change is added.
|
|
15
|
+
Scout's agent, MCP, coding-agent setup, catalogue refresh/publication, status and account/privacy controls remain. Shared evidence preparation and model projections remain available to those consumers. See [commands](commands.md), [security](security.md) and [testing](testing.md) for the remaining interfaces and verification boundary.
|
package/docs/commands.md
CHANGED
|
@@ -1,91 +1,9 @@
|
|
|
1
1
|
# Commands
|
|
2
2
|
|
|
3
|
-
**Pi
|
|
3
|
+
**Pi adapter — npm 0.1.12 and later:** Pi 1.5.0 uses only native Scout MCP and shared guidance. Run `npx -y openmerit@latest install --client pi [--scope user|project]` and approve in the browser. Shell `login`, `logout`, `status`, `remove`, and `doctor` accept the same target flags. Updates require explicit reinstall; no Pi update hooks or scheduler are installed. See [Pi setup](pi-extension.md).
|
|
4
4
|
|
|
5
|
-
The
|
|
5
|
+
The Pi 0.87 `/openmerit` slash commands were removed with that adapter and have no replacement.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
**Retired in npm 0.3.0:** `openmerit dash` ([details](inference-terminal.md)) and all `openmerit eval` commands, including `plan`. Existing local files are untouched. Unreleased Scout source also retires `/scout/api/recommend`; use Scout's conversational agent or MCP. Hosted Workers change only through separate approved deployments. See [retirement details](agent-evaluations.md).
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
## Inference Terminal
|
|
12
|
-
|
|
13
|
-
Install with `npm install -g openmerit` to use `openmerit dash [path]` for a passive local view of models, connections, usage, and compute. From this checkout, use `npm run dash -- [path]`. It is independent of Pi setup and does not run model comparisons or inference.
|
|
14
|
-
|
|
15
|
-
See the [Inference Terminal guide](inference-terminal.md) for local installation, automatic discovery, `--no-discovery`, `--json`, `--demo`, collection intervals, and data limitations. Discovery is part of `dash` and is scoped to application evidence. Coding-harness histories are not collected.
|
|
16
|
-
|
|
17
|
-
## Inspect status
|
|
18
|
-
|
|
19
|
-
```text
|
|
20
|
-
/openmerit
|
|
21
|
-
/openmerit status
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
Both show the task profile, metric readiness, evaluation status, active work, next assessment, lifecycle stage, incumbent candidate, candidate and assessment counts, challenger spend, proposed candidate, and pause flag. A readiness label is based on the harness’s structured reports; inspect the evidence for the underlying measurements.
|
|
25
|
-
|
|
26
|
-
## Start or recover setup
|
|
27
|
-
|
|
28
|
-
```text
|
|
29
|
-
/openmerit setup
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Requests setup explicitly or reopens setup to correct stale target/incumbent state. Accepted replacement setup clears prior candidate, assessment, frontier, and baseline handoffs while retaining the audit log.
|
|
33
|
-
|
|
34
|
-
Request setup explicitly only when recovering, rerunning, or configuring a custom integration. An unconfigured project starts setup when bounded source detection finds an application LLM call at session start or after a settled Pi build turn. OpenMerit refuses another intent while work is active.
|
|
35
|
-
|
|
36
|
-
## Cancel interrupted work
|
|
37
|
-
|
|
38
|
-
```text
|
|
39
|
-
/openmerit cancel
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
Record the active intent as cancelled after an interrupted or abandoned harness run. This clears durable active-work state without claiming success and releases any interactive request that was queued behind setup.
|
|
43
|
-
|
|
44
|
-
## Request an assessment
|
|
45
|
-
|
|
46
|
-
```text
|
|
47
|
-
/openmerit assess
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
Ask OpenMerit core to check stored baseline metric windows now. It reports missing or immature required metrics without starting Pi, or starts candidate discovery when they pass. It does not create missing measurements or override sample requirements.
|
|
51
|
-
|
|
52
|
-
## Request a frontier
|
|
53
|
-
|
|
54
|
-
```text
|
|
55
|
-
/openmerit frontier
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
Ask the harness to calculate a model comparison now. OpenMerit validates the returned frontier against the confirmed profile and supplied assessments. The command does not itself authorize a model change.
|
|
59
|
-
|
|
60
|
-
## Approve a proposal
|
|
61
|
-
|
|
62
|
-
```text
|
|
63
|
-
/openmerit approve
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
Approve the current proposal after its frontier result has passed validation. If there is no proposal in the expected lifecycle stage, the command reports that no verified proposal is awaiting approval. See [comparisons and swaps](lifecycle.md) for automatic-swap policy.
|
|
67
|
-
|
|
68
|
-
## Pause and resume
|
|
69
|
-
|
|
70
|
-
```text
|
|
71
|
-
/openmerit pause
|
|
72
|
-
/openmerit resume
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Pause is persisted in `.openmerit/state.json`, blocks automatic due decisions and lifecycle follow-ups, and unloads the project's managed macOS LaunchAgent. Incoming signals can still be recorded. Resume clears pause and restores scheduling only when the confirmed policy authorizes it. Neither command cancels an already-active intent; explicit commands remain available. The standalone Inference Terminal is independent and keeps collecting until its CLI process exits.
|
|
76
|
-
|
|
77
|
-
## Locate logs and evidence
|
|
78
|
-
|
|
79
|
-
```text
|
|
80
|
-
/openmerit logs
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
Show the local audit, exporter-error, evidence-manifest, and state paths. See [project files and logs](operations.md) for their contents.
|
|
84
|
-
|
|
85
|
-
## Check the installation
|
|
86
|
-
|
|
87
|
-
```text
|
|
88
|
-
/openmerit doctor
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
Show adapter diagnostics, UI availability, and scheduling support. This checks extension wiring; it does not prove provider authentication, successful evaluations, or a completed model swap.
|
|
9
|
+
The [Scout setup commands](scout.md#commands) remain available, beginning with `npx -y openmerit@latest install --client claude-code`.
|
package/docs/getting-started.md
CHANGED
|
@@ -1,20 +1,6 @@
|
|
|
1
1
|
# Getting started
|
|
2
2
|
|
|
3
|
-
OpenMerit provides
|
|
4
|
-
|
|
5
|
-
## Open your inference environment
|
|
6
|
-
|
|
7
|
-
With Node.js 22.19 or newer and npm installed, run:
|
|
8
|
-
|
|
9
|
-
```sh
|
|
10
|
-
npm install -g openmerit
|
|
11
|
-
cd /path/to/your/application
|
|
12
|
-
openmerit dash
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
The Inference Terminal opens a local, read-only view of the selected application's services, models, recorded requests, and linked compute. It does not require Pi or a provider API key, make inference calls, or change model assignments. Supported code/configuration declarations identify inventory; request history requires existing supported logs or exports. See [the terminal guide](inference-terminal.md) for collection, privacy, configuration, and diagnostics.
|
|
16
|
-
|
|
17
|
-
To inspect fictional data without installation, open the [hosted dashboard](https://dash.openmerit.ai/) or its [before/after comparison](https://dash.openmerit.ai/demo). Neither connects to your machine.
|
|
3
|
+
OpenMerit provides Scout model-selection guidance. The Inference Terminal (`openmerit dash`) is [retired in npm 0.3.0](inference-terminal.md). Pi Scout setup requires OpenMerit **0.1.12** or newer and Pi **1.5.0**. Package publication and website deployment are independent releases.
|
|
18
4
|
|
|
19
5
|
## Connect Scout to a coding agent
|
|
20
6
|
|
|
@@ -48,4 +34,4 @@ See [the Pi extension guide](pi-extension.md) for installed paths, migration fro
|
|
|
48
34
|
|
|
49
35
|
## Evaluate application changes
|
|
50
36
|
|
|
51
|
-
The standalone
|
|
37
|
+
The standalone evaluation CLI is retired in npm 0.3.0, and the legacy JSON recommendation API in unreleased Scout source. Scout guidance is not measured application quality; use your own task checks and provider budget controls. See [retirement details](agent-evaluations.md).
|
package/docs/index.md
CHANGED
|
@@ -1,24 +1,10 @@
|
|
|
1
1
|
# OpenMerit documentation
|
|
2
2
|
|
|
3
|
-
These guides distinguish current source work from published behavior. OpenMerit **0.1.12**
|
|
4
|
-
|
|
5
|
-
## See your inference environment
|
|
6
|
-
|
|
7
|
-
With Node.js 22.19 or newer:
|
|
8
|
-
|
|
9
|
-
```sh
|
|
10
|
-
npm install -g openmerit
|
|
11
|
-
cd /path/to/your/application
|
|
12
|
-
openmerit dash
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
The terminal shows application services, model declarations, recorded requests, and linked compute. It reads supported local evidence, needs no Pi installation or provider API key, and makes no inference calls or model changes. Configuration can identify declared services; actual activity requires existing supported logs or exports.
|
|
16
|
-
|
|
17
|
-
Start with [installation and setup](getting-started.md) or the [Inference Terminal guide](inference-terminal.md). Explore the [hosted sample](https://dash.openmerit.ai/) and [before/after dashboard demo](https://dash.openmerit.ai/demo) without connecting your machine. The [demo guide](demo.md) explains their fictional data and comparison limits.
|
|
3
|
+
These maintained Markdown guides distinguish current source work from published behavior. OpenMerit **0.1.12** added native Scout support for Pi **1.5.0**, replacing the old Pi 0.87 evaluation extension. OpenMerit **0.3.0** retires the Inference Terminal (`openmerit dash`) and standalone evaluation CLI. Unreleased source also retires the legacy recommendation API and the unpublished docs website shell. The policy, protected memo, Scout service and npm package are deployed independently; dated receipts describe the versions actually tested.
|
|
18
4
|
|
|
19
5
|
## Discover model candidates
|
|
20
6
|
|
|
21
|
-
|
|
7
|
+
Start with [installation and setup](getting-started.md). The [Scout beta](scout.md) provides conversational application-model guidance at [openmerit.ai/scout/](https://openmerit.ai/scout/) and through MCP for coding agents. The legacy prompt-only JSON recommendation endpoint is retired in source.
|
|
22
8
|
|
|
23
9
|
## Connect Scout to Pi
|
|
24
10
|
|
|
@@ -28,17 +14,8 @@ Follow [setup](getting-started.md#connect-scout-to-a-coding-agent) and [the Pi g
|
|
|
28
14
|
|
|
29
15
|
## Evaluate application changes
|
|
30
16
|
|
|
31
|
-
Use
|
|
32
|
-
|
|
33
|
-
- [Metrics and evidence](metrics-and-evidence.md): measurements, sample requirements, and readiness.
|
|
34
|
-
- [Comparisons and swaps](lifecycle.md): baseline, challenger trials, approval, verification, and rollback.
|
|
35
|
-
- [Budgets and permissions](budgets.md): challenger accounting and provider-spend limits.
|
|
36
|
-
- [Automatic checks](automation.md): durable signals, cadence, and authorized macOS scheduling.
|
|
17
|
+
Use your own representative task checks to evaluate model candidates. The [standalone evaluation CLI is retired in npm 0.3.0](agent-evaluations.md); existing local artifacts are not deleted.
|
|
37
18
|
|
|
38
19
|
## Operate and troubleshoot
|
|
39
20
|
|
|
40
|
-
[
|
|
41
|
-
|
|
42
|
-
## Build an integration
|
|
43
|
-
|
|
44
|
-
Pi now supplies a native Scout connection, not an evaluation `HarnessAdapter`. Custom evaluation harnesses can implement the protocol and coordinator boundary described in [architecture](architecture.md) and [the adapter guide](adapter-guide.md). The [Pareto specification](pareto-spec.md) defines comparison rules; [testing and validation](testing.md) distinguishes automated coverage from product evidence.
|
|
21
|
+
[Commands](commands.md) lists the Scout and setup commands. The [Inference Terminal is retired in npm 0.3.0](inference-terminal.md); existing local files are not deleted. [Troubleshooting](troubleshooting.md), [security and data](security.md), and [current limitations](roadmap.md) explain setup failures and product boundaries. [Testing and validation](testing.md) distinguishes automated coverage from product evidence.
|