openmerit 0.1.12 → 0.2.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 +8 -0
- package/README.md +5 -8
- package/dist/pi/scout-extension.mjs +23 -10
- package/dist/terminal/public/app.js +37 -37
- package/dist/terminal/public/styles.css +0 -125
- package/dist/terminal/scout-update.json +1 -1
- package/dist/terminal/src/cli.mjs +2 -0
- package/dist/terminal/src/install.mjs +1 -0
- package/dist/terminal/src/scout-instructions.d.ts +2 -2
- package/dist/terminal/src/scout-instructions.js +23 -10
- package/dist/terminal/src/scout-instructions.ts +23 -10
- package/dist/terminal/src/scout.d.ts +77 -0
- package/dist/terminal/src/scout.js +181 -0
- package/dist/terminal/src/scout.ts +164 -0
- package/dist/terminal/src/server.mjs +1 -1
- package/docs/commands.md +2 -78
- package/docs/getting-started.md +2 -2
- package/docs/index.md +4 -13
- package/docs/inference-terminal.md +2 -63
- package/docs/pi-extension.md +1 -1
- package/docs/roadmap.md +4 -17
- package/docs/scout.md +29 -250
- package/docs/security.md +5 -17
- package/docs/testing.md +7 -35
- package/docs/troubleshooting.md +1 -1
- package/package.json +4 -24
- 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/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/brands/vllm.ico +0 -0
- package/dist/terminal/public/flow.css +0 -1
- package/dist/terminal/public/flow.js +0 -770
- package/dist/terminal/src/demo-policy.mjs +0 -205
- package/dist/terminal/src/enterprise-sample.mjs +0 -151
- 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
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// `openmerit scout`: a conversation with Scout, the agent behind openmerit.ai/scout,
|
|
2
|
+
// for coding agents without the MCP server and for people at a terminal. It calls
|
|
3
|
+
// the same scout_models MCP tool with this device's key, so every client gets the
|
|
4
|
+
// same clarifying questions and per-task shortlists.
|
|
5
|
+
import { readFile } from 'node:fs/promises';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
import { credentialsPath, readCredentials, type DeviceCredentials } from './scout-credentials.ts';
|
|
8
|
+
|
|
9
|
+
export const policyFile = '.openmerit/scout.json';
|
|
10
|
+
export const components = ['input', 'work', 'output', 'criteria', 'constraints'] as const;
|
|
11
|
+
|
|
12
|
+
export const help = `OpenMerit · Scout
|
|
13
|
+
|
|
14
|
+
openmerit scout "<the work models need to do>" [--all-endpoints] [--json]
|
|
15
|
+
openmerit scout --conversation <id> [--brief <component>=<text> ...] [--skip] ["<follow-up>"] [--json]
|
|
16
|
+
|
|
17
|
+
Asks Scout, the agent behind openmerit.ai/scout. Scout may first return a task
|
|
18
|
+
brief with clarifying questions: answer them with --brief (components: input,
|
|
19
|
+
work, output, criteria, constraints) in the same conversation, or --skip to let
|
|
20
|
+
Scout assume. It then splits the work into tasks and recommends up to five
|
|
21
|
+
models for each. A turn usually takes one to three minutes.
|
|
22
|
+
|
|
23
|
+
A new conversation is limited to the endpoint IDs in ${policyFile}
|
|
24
|
+
(set with openmerit project). --all-endpoints searches the whole catalogue and is
|
|
25
|
+
refused under the existing-only policy. Uses the device key that
|
|
26
|
+
"openmerit install" saved for Claude Code or Pi, this project's first. Never include secrets, source files or customer records.
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
type Json = Record<string, unknown>;
|
|
30
|
+
export interface ScoutRequest { prompt?: string; conversationId?: string; brief?: Partial<Record<typeof components[number], string>>; skip?: boolean; endpointIds?: string[] }
|
|
31
|
+
export interface ScoutModel {
|
|
32
|
+
rank: number; id: string; name: string; provider: string; rationale: string; watchOut: string | null;
|
|
33
|
+
quality: { score: number; evidence: Array<{ name: string; rank: number; of: number }> };
|
|
34
|
+
cost: { usdPer1kTasks: number; inputPerMillion: number; outputPerMillion: number; route: string; endpointId: string; providerModelId: string } | null;
|
|
35
|
+
latency?: { seconds: number } | null; recency?: { released: string } | null;
|
|
36
|
+
}
|
|
37
|
+
// How a task's models are ordered. Cost (cheapest first among models that reach the quality bar) is the default.
|
|
38
|
+
type Priority = 'cost' | 'quality' | 'latency' | 'recency';
|
|
39
|
+
export interface ScoutResult {
|
|
40
|
+
conversationId: string; status: 'needs_answers' | 'recommended' | 'working' | 'message' | 'error'; next?: string;
|
|
41
|
+
brief?: Record<string, { text: string; source: string }>; questions?: Array<{ component: string; question: string }>;
|
|
42
|
+
assumptions?: string[]; tasks?: Array<{ title: string; work: string; summary: string; priority?: Priority; models: ScoutModel[] }>;
|
|
43
|
+
text?: string; error?: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const isObject = (v: unknown): v is Json => !!v && typeof v === 'object' && !Array.isArray(v);
|
|
47
|
+
async function readJSON(path: string): Promise<Json | null> {
|
|
48
|
+
try { const value: unknown = JSON.parse(await readFile(path, 'utf8')); return isObject(value) ? value : null; }
|
|
49
|
+
catch (error) { if ((error as NodeJS.ErrnoException).code === 'ENOENT') return null; throw new Error(`Could not read ${path}.`); }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// The device key an installation saved: this project's installation first, then the user's.
|
|
53
|
+
function deviceKey(root: string): DeviceCredentials | null {
|
|
54
|
+
for (const scope of ['project', 'user'] as const) for (const client of ['claude-code', 'pi'] as const) {
|
|
55
|
+
const credentials = readCredentials(credentialsPath(client, scope, root));
|
|
56
|
+
if (credentials) return credentials;
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// One turn through the scout_models MCP tool. Errors are written for the person or agent running it.
|
|
62
|
+
export async function askScout(root: string, request: ScoutRequest, signal?: AbortSignal): Promise<ScoutResult> {
|
|
63
|
+
const credentials = deviceKey(root);
|
|
64
|
+
if (!credentials) throw new Error('This device is not signed in to OpenMerit. Run: npx -y openmerit@latest install');
|
|
65
|
+
const server = credentials.server;
|
|
66
|
+
let response: Response;
|
|
67
|
+
try {
|
|
68
|
+
response = await fetch(`${server}/scout/mcp`, {
|
|
69
|
+
method: 'POST', redirect: 'error',
|
|
70
|
+
// A turn can take minutes; Scout keeps working if the connection drops.
|
|
71
|
+
signal: AbortSignal.any([AbortSignal.timeout(10 * 60_000), ...(signal ? [signal] : [])]),
|
|
72
|
+
headers: { ...credentials.headers, 'Content-Type': 'application/json', Authorization: `Bearer ${credentials.key}`, 'X-Scout-Client': 'cli' },
|
|
73
|
+
body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'tools/call', params: { name: 'scout_models', arguments: request } }),
|
|
74
|
+
});
|
|
75
|
+
} catch (error) {
|
|
76
|
+
const id = request.conversationId;
|
|
77
|
+
throw new Error((error as Error).name === 'TimeoutError' && id ? `Scout is still working. Read the outcome with: openmerit scout --conversation ${id}` : `Could not reach ${server}. Check your connection and retry.`);
|
|
78
|
+
}
|
|
79
|
+
if (response.status === 401) throw new Error('The device key was rejected. Run: npx -y openmerit@latest login, then install again.');
|
|
80
|
+
const body: unknown = await response.json().catch(() => null);
|
|
81
|
+
const result = isObject(body) && isObject(body.result) ? body.result : null;
|
|
82
|
+
if (!result) throw new Error(`Scout returned HTTP ${response.status}${isObject(body) && isObject(body.error) ? `: ${String(body.error.message)}` : ''}.`);
|
|
83
|
+
const text = Array.isArray(result.content) && isObject(result.content[0]) ? String(result.content[0].text) : '';
|
|
84
|
+
if (result.isError && !isObject(result.structuredContent)) throw new Error(text || 'Scout could not finish this turn.');
|
|
85
|
+
return result.structuredContent as unknown as ScoutResult;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// A turn under the project's access policy. A new conversation is limited to the saved
|
|
89
|
+
// inventory; the whole catalogue needs an explicit choice the policy permits.
|
|
90
|
+
export async function scoutTurn(root: string, request: Omit<ScoutRequest, 'endpointIds'> & { allEndpoints?: boolean }, signal?: AbortSignal): Promise<ScoutResult> {
|
|
91
|
+
const { allEndpoints, ...turn } = request;
|
|
92
|
+
if (turn.conversationId) {
|
|
93
|
+
if (allEndpoints) throw new Error('--all-endpoints applies when a conversation starts. Start a new conversation instead.');
|
|
94
|
+
return askScout(root, turn, signal);
|
|
95
|
+
}
|
|
96
|
+
const policy = await readJSON(join(root, policyFile));
|
|
97
|
+
if (!policy) {
|
|
98
|
+
if (!allEndpoints) throw new Error(`${policyFile} is missing. Ask which endpoints this project can use and save them with "npx -y openmerit@latest project --policy existing-only|existing-first --endpoint-id <id> ...", or pass --all-endpoints to search the whole catalogue.`);
|
|
99
|
+
return askScout(root, turn, signal);
|
|
100
|
+
}
|
|
101
|
+
const ids = Array.isArray(policy.endpointIds) && policy.endpointIds.every(id => typeof id === 'string') ? policy.endpointIds as string[] : null;
|
|
102
|
+
if (!ids || !['existing-only', 'existing-first'].includes(String(policy.policy))) throw new Error(`${policyFile} is not a valid Scout policy. Save it again with "openmerit project".`);
|
|
103
|
+
if (allEndpoints && policy.policy === 'existing-only') throw new Error('This project uses the existing-only policy, so Scout cannot search the whole catalogue.');
|
|
104
|
+
return askScout(root, allEndpoints ? turn : { ...turn, endpointIds: ids }, signal);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const money = (usd: number) => `$${usd < 0.1 ? usd.toFixed(3) : usd.toFixed(2)}`;
|
|
108
|
+
const rankings: Record<Exclude<Priority, 'cost'>, string> = { quality: 'Highest quality estimate first.', latency: 'Fastest first.', recency: 'Newest first.' };
|
|
109
|
+
export function renderScout(result: ScoutResult): string {
|
|
110
|
+
const lines: string[] = [];
|
|
111
|
+
if (result.status === 'needs_answers') {
|
|
112
|
+
lines.push('Scout needs more detail. Its task brief:', '');
|
|
113
|
+
for (const c of components) { const part = result.brief?.[c]; lines.push(` ${c.padEnd(12)}${part?.text || '(missing)'}${part ? ` [${part.source}]` : ''}`); }
|
|
114
|
+
lines.push('', 'Questions:', ...(result.questions ?? []).map(q => ` ${q.component}: ${q.question}`), '',
|
|
115
|
+
`Answer: openmerit scout --conversation ${result.conversationId} --brief <component>="<answer>" ...`,
|
|
116
|
+
`Or skip: openmerit scout --conversation ${result.conversationId} --skip`);
|
|
117
|
+
} else if (result.status === 'recommended') {
|
|
118
|
+
const tasks = result.tasks ?? [];
|
|
119
|
+
tasks.forEach((task, i) => {
|
|
120
|
+
if (tasks.length > 1) lines.push(`${i + 1}. ${task.title}`, ` ${task.work}`);
|
|
121
|
+
// As on the page, the default cheapest-first order is unlabelled; another priority is named with the value it sorts by.
|
|
122
|
+
const priority = task.priority ?? 'cost';
|
|
123
|
+
if (priority !== 'cost') lines.push(` ${rankings[priority]}`);
|
|
124
|
+
for (const m of task.models) {
|
|
125
|
+
const price = m.cost ? `${money(m.cost.inputPerMillion)} in / ${money(m.cost.outputPerMillion)} out per 1M via ${m.cost.route} (${m.cost.endpointId})` : 'no priced route';
|
|
126
|
+
const metric = priority === 'latency' ? ` · ${m.latency ? `${m.latency.seconds.toFixed(1)}s per task` : 'time unknown'}`
|
|
127
|
+
: priority === 'recency' ? ` · ${m.recency ? `released ${m.recency.released}` : 'release date unknown'}` : '';
|
|
128
|
+
lines.push(` ${m.rank}. ${m.name}${metric} · quality ${m.quality.score}/100 · ${price}`, ` ${m.rationale}`);
|
|
129
|
+
}
|
|
130
|
+
lines.push(` ${task.summary}`, '');
|
|
131
|
+
});
|
|
132
|
+
if (result.assumptions?.length) lines.push('Assumptions:', ...result.assumptions.map(a => ` - ${a}`), '');
|
|
133
|
+
lines.push(`Refine: openmerit scout --conversation ${result.conversationId} "<follow-up>"`);
|
|
134
|
+
lines.push('Quality is Scout\'s estimate from public benchmarks, not measured accuracy for your application.');
|
|
135
|
+
} else if (result.status === 'working') lines.push(`Scout is still working. Read the outcome with: openmerit scout --conversation ${result.conversationId}`);
|
|
136
|
+
else lines.push(result.text ?? result.error ?? 'Scout replied without an answer.');
|
|
137
|
+
return lines.join('\n');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export async function main(args: string[], { root = process.cwd(), print = console.log } = {}): Promise<number> {
|
|
141
|
+
if (args.includes('--help') || args.includes('-h')) { print(help); return 0; }
|
|
142
|
+
const request: Parameters<typeof scoutTurn>[1] = {};
|
|
143
|
+
const words: string[] = [];
|
|
144
|
+
let json = false;
|
|
145
|
+
for (let i = 0; i < args.length; i++) {
|
|
146
|
+
const arg = args[i] ?? '';
|
|
147
|
+
const value = () => { const v = args[++i]; if (v === undefined || v.startsWith('--')) throw new Error(`${arg} needs a value.`); return v; };
|
|
148
|
+
if (arg === '--conversation') request.conversationId = value();
|
|
149
|
+
else if (arg === '--brief') {
|
|
150
|
+
const [component, ...text] = value().split('=');
|
|
151
|
+
if (!(components as readonly string[]).includes(component ?? '') || !text.length) throw new Error(`--brief takes <component>=<text>; components: ${components.join(', ')}.`);
|
|
152
|
+
request.brief = { ...request.brief, [component as typeof components[number]]: text.join('=') };
|
|
153
|
+
} else if (arg === '--skip') request.skip = true;
|
|
154
|
+
else if (arg === '--all-endpoints') request.allEndpoints = true;
|
|
155
|
+
else if (arg === '--json') json = true;
|
|
156
|
+
else if (arg.startsWith('-')) throw new Error(`Unknown option for scout: ${arg}`);
|
|
157
|
+
else words.push(arg);
|
|
158
|
+
}
|
|
159
|
+
if (words.length) request.prompt = words.join(' ');
|
|
160
|
+
if (!request.prompt && !request.conversationId) { print(help); return 1; }
|
|
161
|
+
const result = await scoutTurn(root, request);
|
|
162
|
+
print(json ? JSON.stringify(result, null, 2) : renderScout(result));
|
|
163
|
+
return result.status === 'error' ? 1 : 0;
|
|
164
|
+
}
|
|
@@ -6,7 +6,7 @@ import { createCollector, loadConfig } from './collect.mjs';
|
|
|
6
6
|
import { sampleSnapshot } from './sample.mjs';
|
|
7
7
|
import { telemetryEnabled, terminalProperties, sendTerminalEvent, errorProperties } from './telemetry.mjs';
|
|
8
8
|
|
|
9
|
-
const assets = new Map([['/', ['index.html', 'text/html']], ['/app.js', ['app.js', 'text/javascript']], ['/
|
|
9
|
+
const assets = new Map([['/', ['index.html', 'text/html']], ['/app.js', ['app.js', 'text/javascript']], ['/styles.css', ['styles.css', 'text/css']], ['/favicon.svg', ['favicon.svg', 'image/svg+xml']]]);
|
|
10
10
|
for (const file of ['baseten.png', 'groq.ico', 'cerebras.png', 'qwen.png', 'meta.ico', 'nomic.png', 'baai.png', 'ollama.png', 'lm-studio.png', 'vllm.png', 'anthropic.png', 'google.png', 'deepseek.ico', 'cohere.png', 'openai.png', 'mistral.png', 'openrouter.png', 'huggingface.svg']) assets.set(`/brands/${file}`, [`brands/${file}`, file.endsWith('.svg') ? 'image/svg+xml' : file.endsWith('.ico') ? 'image/x-icon' : 'image/png']);
|
|
11
11
|
|
|
12
12
|
export async function startTerminal({ root = process.cwd(), port = 4310, interval = 15, demo = false, collect: customCollect, config, fallbackPort = false } = {}) {
|
package/docs/commands.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
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 standalone `openmerit dash` and `openmerit eval` commands are unchanged.
|
|
5
|
+
The standalone `openmerit dash` and `openmerit eval` commands are unchanged. The Pi 0.87 `/openmerit` slash commands were removed with that adapter and have no replacement.
|
|
6
6
|
|
|
7
7
|
Stable npm `openmerit@0.1.7` provides `openmerit eval init`, `doctor`, `plan`, `run`, `watch` and `report`. See [agent evaluations](agent-evaluations.md) for scope selection, repeated task checks and budgets. These are shell commands, separate from Pi commands. The same release includes [Scout setup commands](scout.md#commands), beginning with `npx -y openmerit@latest install --client claude-code`.
|
|
8
8
|
|
|
@@ -13,79 +13,3 @@ Since `0.1.7-preview.2`, `openmerit eval plan [--scope existing|all] [--budget <
|
|
|
13
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
14
|
|
|
15
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.
|
package/docs/getting-started.md
CHANGED
|
@@ -14,7 +14,7 @@ openmerit dash
|
|
|
14
14
|
|
|
15
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
16
|
|
|
17
|
-
To inspect fictional data
|
|
17
|
+
To inspect fictional data, run `openmerit dash --demo` or choose the sample from the environment selector. Sample data never enters the real snapshot or project files.
|
|
18
18
|
|
|
19
19
|
## Connect Scout to a coding agent
|
|
20
20
|
|
|
@@ -48,4 +48,4 @@ See [the Pi extension guide](pi-extension.md) for installed paths, migration fro
|
|
|
48
48
|
|
|
49
49
|
## Evaluate application changes
|
|
50
50
|
|
|
51
|
-
The standalone `openmerit eval` CLI is unchanged by the new Pi adapter. It evaluates Claude Code, Codex and OpenCode through explicit task, scope, budget and grader configuration; see [agent evaluations](agent-evaluations.md).
|
|
51
|
+
The standalone `openmerit eval` CLI is unchanged by the new Pi adapter. It evaluates Claude Code, Codex and OpenCode through explicit task, scope, budget and grader configuration; see [agent evaluations](agent-evaluations.md).
|
package/docs/index.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# OpenMerit documentation
|
|
2
2
|
|
|
3
|
-
These guides distinguish current source work from published behavior. OpenMerit **0.1.12** adds native Scout support for Pi **1.5.0**, replacing the old Pi 0.87 evaluation extension. The Inference Terminal and standalone agent-evaluation CLI are separate products and are unchanged by that replacement. The website,
|
|
3
|
+
These guides distinguish current source work from published behavior. OpenMerit **0.1.12** adds native Scout support for Pi **1.5.0**, replacing the old Pi 0.87 evaluation extension. The Inference Terminal and standalone agent-evaluation CLI are separate products and are unchanged by that replacement. The website, Scout service and npm package are deployed independently; dated receipts describe the versions actually tested.
|
|
4
4
|
|
|
5
5
|
## See your inference environment
|
|
6
6
|
|
|
@@ -14,7 +14,7 @@ openmerit dash
|
|
|
14
14
|
|
|
15
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
16
|
|
|
17
|
-
Start with [installation and setup](getting-started.md) or the [Inference Terminal guide](inference-terminal.md).
|
|
17
|
+
Start with [installation and setup](getting-started.md) or the [Inference Terminal guide](inference-terminal.md).
|
|
18
18
|
|
|
19
19
|
## Discover model candidates
|
|
20
20
|
|
|
@@ -28,17 +28,8 @@ Follow [setup](getting-started.md#connect-scout-to-a-coding-agent) and [the Pi g
|
|
|
28
28
|
|
|
29
29
|
## Evaluate application changes
|
|
30
30
|
|
|
31
|
-
Use [the standalone evaluation CLI](agent-evaluations.md)
|
|
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.
|
|
31
|
+
Use [the standalone evaluation CLI](agent-evaluations.md) to compare CLI revisions across Claude Code, Codex and OpenCode with explicit tasks, model scope, budgets and graders.
|
|
37
32
|
|
|
38
33
|
## Operate and troubleshoot
|
|
39
34
|
|
|
40
|
-
[Troubleshooting](troubleshooting.md), [security and data](security.md), and [current limitations](roadmap.md) explain
|
|
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.
|
|
35
|
+
[Commands](commands.md) lists the terminal, Scout setup and evaluation commands. [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.
|
|
@@ -20,8 +20,6 @@ Transport is best-effort, silent, has no retries, and is bounded to about 750 ms
|
|
|
20
20
|
|
|
21
21
|
The same opt-in enables local terminal events using that process-only UUID: `terminal_visited` (sample/live mode), `terminal_page_viewed` (fixed page category, including the connections map), `terminal_interaction` (inspect, filter, search, map expansion, mode or command action and entity kind only), `terminal_snapshot` (retained model, record, source, host, deployment and distinct observed-agent counts), and `terminal_error` (fixed collection/snapshot/render/uncaught error code and standard error class only). Counts are integers from 0 through 1,000,000,000; they describe the retained view, not complete environment totals. No entity keys, names, search values, source paths, raw source, prompts, credentials, hostname, arbitrary error messages or stacks are transmitted. No session replay or login is added.
|
|
22
22
|
|
|
23
|
-
This instrumentation covers the local terminal, not the hosted fictional preview at `dash.openmerit.ai`. The hosted preview remains uninstrumented and deploys separately.
|
|
24
|
-
|
|
25
23
|
`GET /api/info` exposes the boolean `telemetry` capability. Browser events additionally respect browser Do Not Track, Global Privacy Control and `localStorage['scout-analytics-opt-out'] === '1'`. They go only to the same-origin `POST /api/analytics` relay; the browser CSP still permits connections only to self. The loopback Host/Origin/cross-site guards apply to the relay, which projects every accepted event onto a fixed allowlist, limits JSON bodies to 2 KiB and body arrival to one second. Forwarding has no queue or retries, permits at most 60 terminal events per minute across the process and four in flight, and times out after 750 ms. Browser submission is separately capped at 60 events per minute and two in flight with a one-second timeout. Events can be dropped without affecting collection or UI requests. Collection errors follow process consent independently of browser controls. Outbound analytics carries `X-Scout-Client: cli` and `X-Scout-Analytics: on`.
|
|
26
24
|
|
|
27
25
|
## Install
|
|
@@ -40,16 +38,10 @@ The CLI starts a server bound to `127.0.0.1` and opens the browser before initia
|
|
|
40
38
|
|
|
41
39
|
If npm reports `EACCES`, use a user-owned Node installation/npm prefix rather than `sudo`. If the command is not found after installation, reopen the shell and check that npm's global executable directory is on `PATH`.
|
|
42
40
|
|
|
43
|
-
The **terminal
|
|
41
|
+
The **terminal** follows the device's light/dark preference, including charts and inspectors, and update when that preference changes. There is no theme control or saved override. The npm terminal includes this appearance behavior in 0.1.7.
|
|
44
42
|
|
|
45
43
|
Keep the CLI running while using the dashboard. Files unreadable by your user are reported as unavailable. Configuration can identify services but cannot supply missing request history.
|
|
46
44
|
|
|
47
|
-
## Hosted samples
|
|
48
|
-
|
|
49
|
-
[dash.openmerit.ai](https://dash.openmerit.ai/) shows 200 fictional agents, 699 task IDs, 21 models, and 9.6 million requests over 30 days. The [before/after comparison](https://dash.openmerit.ai/demo) uses a separate fictional insurance scenario with 280 workers and 980 task IDs across fourteen workflows. See [the comparison details](#hosted-enterprise-sample-and-comparison) for selection rules, preference overrides, prices, and limitations.
|
|
50
|
-
|
|
51
|
-
Hosted pages do not connect to your machine, accept project uploads, or run inference. Their public JSON endpoints return fictional data; the local snapshot API is not exposed. They request no search-engine indexing. The local CLI's sample selector uses a smaller 40-agent, 140-task example described below.
|
|
52
|
-
|
|
53
45
|
## Run from a source checkout
|
|
54
46
|
|
|
55
47
|
With dependencies installed in the OpenMerit checkout:
|
|
@@ -79,7 +71,7 @@ openmerit dash --no-open
|
|
|
79
71
|
| `--demo` | Use only a fictional local sample; no local collectors run |
|
|
80
72
|
| `--help` | Show usage |
|
|
81
73
|
|
|
82
|
-
Ctrl+C stops collection. The terminal has no persistent daemon
|
|
74
|
+
Ctrl+C stops collection. The terminal has no persistent daemon. The Pi 1.5.0 Scout adapter exposes no pause or scheduling commands.
|
|
83
75
|
|
|
84
76
|
## Repository indexing
|
|
85
77
|
|
|
@@ -234,59 +226,6 @@ Torph animates changed totals, table measurements, status labels, and source cou
|
|
|
234
226
|
|
|
235
227
|
The environment selector opens `inference-sample`, a fictional enterprise workspace with 40 agents, 140 tasks, 21 models, and 9,600 requests over 24 hours. It includes all five path classifications, traffic bursts, running and failed requests, missing measurements, partial and unavailable sources, three self-hosted runtimes, 27 distinct deployments, 14 shared capacity pools, and an hour of host history. Its six hosts include a workstation and five rack servers across two racks, with eleven accelerators listed. Four hosts have recent readings, one is stale, and one has no measurement. Seven loaded models are placed explicitly across three hosts. Six cloud models have separate `us-1` and `eu-1` example deployments. The capacity sample includes twelve recent readings, one stale reading, and one missing reading. Shared gateway pools connect consumers across reported agent IDs. Names resemble exported configuration keys (for example, `support.review` and `llm-gateway`); some agent/task display names are absent and the UI uses their IDs. These identifiers are fictional, not discovered in the current repository. The sample workstation has no site label; server sites and racks are fictional exporter fields. Baseten, Groq, and Cerebras illustrate serving services distinct from model creators; their sample configuration evidence, deployment modes, and quotas are fictional. Model rates, latency, allocation, and utilization values are illustrative; the sample is for inspecting the interface at scale, not a performance benchmark. Sample data never enters the real snapshot or project files. A command started with `--demo` only exposes a sample workspace; restart without that flag to collect real data.
|
|
236
228
|
|
|
237
|
-
### Hosted enterprise sample and comparison
|
|
238
|
-
|
|
239
|
-
The hosted sample at [dash.openmerit.ai](https://dash.openmerit.ai/) has a separate enterprise scenario: 9.6 million fictional requests over 30 days, represented by 9,600 groups of 1,000 requests, with 200 agent IDs, 699 task IDs and 21 models. Tokens and costs are **group totals**. Overview, model/service counts, activity, maps and inspectors use the represented request count. These sample weights never affect live request records. The local `--demo` and sample selector keep the smaller scenario described above.
|
|
240
|
-
|
|
241
|
-
The comparison at [`dash.openmerit.ai/demo`](https://dash.openmerit.ai/demo) is an **insurance-tech-demo**: 280 fictional workers, 980 task identifiers, and fourteen insurance application workflows. Claim intake, policy extraction, coverage review support, document verification, renewals and correspondence use plausible application declarations. These names were not discovered from a real insurance repository. Both stages preserve the configured service set, workloads, request counts and token volume. Qualified assignments can move between those services; their request paths and service attribution update accordingly. No real claims, underwriting decisions or inference calls are involved.
|
|
242
|
-
|
|
243
|
-
The comparison is the leading panel, with larger Before/After token costs, a prominent stage switch, and the modeled difference beside its evidence link. Overrides remain visible below the totals; workload decisions expand within the panel. On narrow screens the controls and result stack without hiding the evidence. This visual hierarchy does not change selection, pricing or request totals.
|
|
244
|
-
|
|
245
|
-
**After OpenMerit** includes a preference selector: default within the existing stack, bias ZDR, bias open weights, no open weights, bias USA models, or bias Chinese models. Every workload searches the full reviewed catalog across the six configured services. Default chooses the lowest modeled token cost among qualifying replacements and retains the baseline if none qualify.
|
|
246
|
-
|
|
247
|
-
Other preferences first select the lowest-cost qualifying match. If none exists, an already matching baseline is retained. Otherwise, a compatible matching offer may override the benchmark and efficiency criteria. These **Preference overrides** are labeled in the comparison, workload decisions and evidence drawer. The drawer lists every unmet criterion and preserves missing comparisons and known regressions. Overrides are ranked by fewest axes with known regressions, then fewest axes with missing evidence, presence of a verified efficiency improvement, and modeled cost; offer ID breaks ties. This is a disclosed demo fallback, not a measured claim that the selected model is best for the task. Missing evidence never becomes a passing score.
|
|
248
|
-
|
|
249
|
-
Configured services, compatible output contracts and known token prices remain required. **No open weights** still requires every assigned model to be explicitly closed-weight. Only when no compatible closed offer exists does a workload remain unassigned and the full-plan cost stay unavailable. Other biases fall back to the default qualifying choice or baseline if no compatible preference match exists, with the mismatch visible. Overrides are included in all After views and modeled costs; request and token volumes stay fixed.
|
|
250
|
-
|
|
251
|
-
The primary criteria require equal or better selected public benchmark scores for tool use, capabilities and reasoning, plus lower modeled token cost or a lower paired latency measurement. The catalog records benchmark suite, metric, score, source and publisher configuration. Missing or non-comparable evidence prevents qualification even when a preference override selects the model. Decision workflows additionally require accuracy and calibration evidence; an override must disclose missing or regressing decision metrics too. Jev is a typed-decision model, not a general text generator; the configured-service and output-contract constraints keep it out of the After plan.
|
|
252
|
-
|
|
253
|
-
The reviewed catalog contains 26 model/service offers across OpenAI, Anthropic, Google, Groq, Baseten and Mistral; Jev is separately reviewed as an out-of-stack candidate. Model identity is distinct from serving service. Multiple benchmark cohorts remain separate, and every matched metric on each required axis is checked: a passing score cannot hide a matched regression. Model-card scores refer to their published configurations, not measured endpoint performance.
|
|
254
|
-
|
|
255
|
-
Nine workflows qualify for a change, including four application workers that generate actuarial/reporting SQL and reconciliation/reserve-analysis scripts. These are inference inside the fictional insurance product, not coding-harness activity. Their selected capability screen is code generation: LiveCodeBench v6 in the [GLM-4.7 comparison](https://huggingface.co/zai-org/GLM-4.7), or LiveCodeBench Pro in the [Gemini 3 Flash comparison](https://storage.googleapis.com/deepmind-media/gemini/gemini_3_flash_model_evaluation.pdf). Each comparison also supplies tool-use and GPQA reasoning scores for its candidate and Claude Sonnet 4.5 baseline. Percentage and Elo scores remain separate, and these code-generation results are not substituted for general knowledge or visual-document capability.
|
|
256
|
-
|
|
257
|
-
Both GLM-4.7 on Baseten and Gemini 3 Flash qualify for those four workloads. The scenario declares fixed fictional profiles: SQL workers average 14K/700 and 18K/900 input/output tokens per request; script workers average 5K/2K and 6K/2.4K, with deterministic ±15% variation. Profiles include billed reasoning output and remain identical across stages and preferences. Published rates favor Gemini for these input-heavy SQL profiles and GLM for the longer script outputs. No preference changes prices, token volumes or recorded benchmark scores. Exceptions to the benchmark and efficiency requirements remain explicit.
|
|
258
|
-
|
|
259
|
-
The fixed 30-day scenario calculates $344,689.33 Before. Default selects eight model changes and one additional service-only change, with five retained baselines, producing $177,125.39 After (48.6% lower modeled token cost). Under preference overrides the complete After projections are:
|
|
260
|
-
|
|
261
|
-
| Preference | Modeled token cost | Workloads with an override |
|
|
262
|
-
| --- | ---: | ---: |
|
|
263
|
-
| Default | $177,125.39 | 0 |
|
|
264
|
-
| ZDR | $38,281.42 | 8 |
|
|
265
|
-
| Open weights | $50,147.49 | 7 |
|
|
266
|
-
| No open weights | $171,146.32 | 3 |
|
|
267
|
-
| USA | $162,436.44 | 2 |
|
|
268
|
-
| Chinese | $40,953.91 | 9 |
|
|
269
|
-
|
|
270
|
-
Lower cost in a plan containing overrides is not a quality-preserving improvement claim. All six plans now cover fourteen workloads and 9.6 million requests. Closed weights assigns GPT-4.1 mini to claim tagging, fraud review support and broker correspondence with missing-comparison exceptions; claim tagging also loses the verified efficiency improvement and costs more than its baseline. The other eleven closed assignments need no override. Equivalent model mixes, if any, are disclosed instead of changed artificially.
|
|
271
|
-
|
|
272
|
-
Public benchmark scores are publisher-reported point estimates in the linked configurations, **not an OpenMerit insurance-task evaluation**, statistical proof of parity, or a claim of superiority across every benchmark. For example, GPT-4.1's ComplexFuncBench score is below GPT-4o's even though it passes the selected τ-bench retail, MMLU and AIME 2024 screen. The DeepSeek comparison uses AutomationBench, Agent’s Last Exam and GPQA Diamond from its published instruct-model comparison; it is not a claim about every reasoning benchmark. Application quality and latency remain untested. The dated catalog is not exhaustive: retained means no qualifying alternative in the reviewed evidence.
|
|
273
|
-
|
|
274
|
-
ZDR means an endpoint/account retention policy, not a property of weights. This scenario only treats Baseten's documented synchronous default policy as confirmed; other providers' conditional ZDR eligibility is not assumed enabled. Router, gateway and application logging require separate checks. USA and Chinese refer to the model developer's origin, not hosting location or data residency. Open weights does not imply a particular license or privacy policy.
|
|
275
|
-
|
|
276
|
-
Both sides calculate token cost from published standard USD input/output rates checked on 10 October 2026. **Workload decisions** shows each Before/After model, serving service, qualifying-alternative count, per-workload Before/After token cost for the selected window, and preference match. Choices that differ from Default appear first, followed by workloads with more qualifying alternatives. **Swaps & evidence** exposes selected and rejected candidates, rates, public benchmark comparisons and methodology. Inputs are below 33K tokens per represented request; the scenario assumes uncached text, no batch discount, and no regional premium, tool charge, gateway fee, tax or infrastructure cost. Token counts, including billed reasoning output where applicable, are held fixed for comparison; actual tokenization, reasoning budgets and generated output can differ. The broader sample leaves costs unknown when no verified token price is included. It never treats local infrastructure as free.
|
|
277
|
-
|
|
278
|
-
The hosted browser builds deterministic fictional records from a small same-origin seed response. `/api/sample` and `/api/demo?stage=before|after&preference=default|zdr|open|closed|usa|china` expose complete sample snapshots; `/api/sample-seed` supplies the recipe version and timestamp. The comparison metadata includes plan feasibility, model-versus-service changes, preference matches, `equivalentPreferences` for identical model/service assignments, and window totals. An incomplete After snapshot keeps `simulation.feasible: false`, contains request/model/deployment rows only for qualifying assignments, and has no projected complete-plan After cost. Its unresolved assignments and full Before totals remain in comparison metadata. Each window reports both baseline `requests` and `qualifiedRequests`; individual qualifying records and workload totals retain their After costs. Unresolved assignments retain `after: null`, without substituting their open-weight baseline. Unknown preferences fall back to default. Stage and preference survive tab navigation and are shareable in the page URL. No collector, local files, credentials or inference provider is contacted. The comparison holds its dataset fixed while you explore; reload to start a fresh scenario. The hosted scenarios are separate from local collection; exploring them does not change your installed package or application.
|
|
279
|
-
|
|
280
|
-
### Optional map preview
|
|
281
|
-
|
|
282
|
-
The terminal includes an opt-in React Flow + ELK map experiment. Add `?map=flow` before the page hash in your local terminal URL (for example, `http://127.0.0.1:4310/?map=flow#overview`). To try fictional enterprise data instead, use `?sample=1&map=flow#overview`. The existing map remains the default; **Original map** removes the preview flag immediately. No data migration or server restart is needed to switch views.
|
|
283
|
-
|
|
284
|
-
The preview keeps the existing card dimensions and uses ELK to arrange all collapsed groups. Layout is recalculated only when the set of nodes or relationships changes, not when request counts refresh. The graph scrolls at a fixed scale rather than automatically zooming to fit.
|
|
285
|
-
|
|
286
|
-
**Browse all** opens a searchable inventory of every workload, entry connection, and model/service pair in the selected scope. Selecting a stack filters that inventory to its exact members; the visible result count always shows the filter coverage. Selecting a member spotlights its actual recorded paths and brings a matching member to the front of each related stack without expanding the diagram. This does not change the total request counts. **Details** opens the existing inspector; **Clear spotlight** or Escape clears the selection. The browser sits beside the map on wide screens and below it on narrower screens, with independently scrolling lists. Keyboard users can navigate its tabs with arrows, Home, and End.
|
|
287
|
-
|
|
288
|
-
This is an optional presentation experiment, not a new data source. Its separately bundled scripts and styles are loaded from the local server only when the preview is selected. It makes no inference calls and adds no collection permissions. There is additional download and initial layout cost; very large and densely connected environments still need user evaluation. The original map remains available for comparison and rollback.
|
|
289
|
-
|
|
290
229
|
## Collection sources
|
|
291
230
|
|
|
292
231
|
### OpenMerit evidence
|
package/docs/pi-extension.md
CHANGED
|
@@ -55,4 +55,4 @@ Updates are **explicit reinstall only**: rerun `install --client pi` with the sa
|
|
|
55
55
|
|
|
56
56
|
Remove or disable the old `npm:openmerit` Pi package registration before loading this adapter, and explicitly remove any previously authorized background job through its existing management path. New setup does not promise to uninstall a legacy LaunchAgent. Preserve `.openmerit/` evaluation state and evidence if needed; do not delete them as a setup repair.
|
|
57
57
|
|
|
58
|
-
The replacement has no `/openmerit` commands, `openmerit_complete_intent` or `openmerit_report_signal` tools, source preflight, evaluation lifecycle, intent recovery, scheduling, automatic swaps, or LaunchAgent. The [
|
|
58
|
+
The replacement has no `/openmerit` commands, `openmerit_complete_intent` or `openmerit_report_signal` tools, source preflight, evaluation lifecycle, intent recovery, scheduling, automatic swaps, or LaunchAgent. The [standalone evaluation CLI](agent-evaluations.md) is unchanged.
|
package/docs/roadmap.md
CHANGED
|
@@ -2,28 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
## Current status
|
|
4
4
|
|
|
5
|
-
The Inference Terminal provides a read-only view of existing application evidence. The Pi **1.5.0** adapter in OpenMerit **0.1.12** provides only native Scout MCP and shared guidance, not evaluation coordination. The standalone evaluation CLI
|
|
5
|
+
The Inference Terminal provides a read-only view of existing application evidence. The Pi **1.5.0** adapter in OpenMerit **0.1.12** provides only native Scout MCP and shared guidance, not evaluation coordination. The standalone evaluation CLI remains separate. Neither a populated dashboard nor passing implementation tests establishes that an application has better models, trustworthy evaluations, or reliable unattended automation.
|
|
6
6
|
|
|
7
7
|
## Known limitations
|
|
8
8
|
|
|
9
9
|
- The terminal does not instrument the application, call inference providers, route traffic, run evaluations, or apply model changes. It needs supported logs or exports for actual request history. Code/configuration declarations alone cannot supply past requests or spend.
|
|
10
10
|
- History and inventory can be incomplete because of source availability and read/parser limits. “All time” means retained supported evidence, not a complete lifetime archive. Cloud account usage is not fetched.
|
|
11
11
|
- Machine and runtime readings describe shared resources; they are not per-request resource measurements. Static endpoints do not prove deployment, availability, or physical location.
|
|
12
|
-
-
|
|
12
|
+
- The local sample workspace is fictional. Its measurements and prices illustrate the interface, not application quality or latency.
|
|
13
13
|
- The Pi 0.87 evaluation adapter is removed in source. Pi 1.5.0 setup needs explicit browser approval, a new session and an explicit installer rerun for updates. It has no lifecycle commands, scheduler, LaunchAgent or auto-update hooks. The host owns tools, model, permissions and sessions; SDK hosts must load Pi's native MCP extension explicitly.
|
|
14
14
|
- Scout rule/skill availability does not guarantee invocation or measured application quality. Missing project policy requires asking; unavailable or insufficient Scout evidence requires pausing the model choice.
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
- Core pause policy does not cancel active intents or stop explicit commands or the standalone terminal. It is not a command exposed by the new Pi adapter.
|
|
18
|
-
- Challenger accounting depends on reported costs. It cannot independently meter provider billing or stop an in-flight request. Use provider spending controls as well as the confirmed evaluation policy.
|
|
19
|
-
- The source interface and hosted dashboard follow the device's light/dark preference. That UI change is not included in npm 0.1.6.
|
|
20
|
-
|
|
21
|
-
## Next validation milestones
|
|
22
|
-
|
|
23
|
-
1. Establish working evaluations and observability in a representative product.
|
|
24
|
-
2. Inspect generated artifacts, measurements, and side effects.
|
|
25
|
-
3. Collect repeated evidence for the confirmed profile.
|
|
26
|
-
4. Complete a budgeted challenger cycle and inspect the frontier and recommendation.
|
|
27
|
-
5. Perform a supervised swap, post-swap verification, and rollback drill.
|
|
28
|
-
6. Validate background candidate work before relying on unattended operation.
|
|
29
|
-
7. Repeat with materially different workloads before making broad reliability claims.
|
|
15
|
+
- Existing legacy Pi 0.87 background jobs require separate cleanup during migration.
|
|
16
|
+
- Agent-evaluation budget admission depends on reported costs. It cannot independently meter provider billing or stop an in-flight request. Use provider spending controls as well.
|