harness-everything 0.23.0 → 0.25.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +23 -0
- package/benchmarks/results/system-one/labeler-holdout-check-2026-09-23/README.md +55 -0
- package/benchmarks/results/system-one/labeler-holdout-check-2026-09-23/report.json +1104 -0
- package/ci/fixtures/system-one-resident-stub.py +3 -0
- package/ci/mechanism-system-one-collect.test.js +158 -0
- package/ci/mechanism-system-one-label.test.js +105 -0
- package/ci/mechanism-system-one-resident.test.js +36 -2
- package/ci/mechanism-system-one-router.test.js +13 -0
- package/ci/mechanism-system-one-train.test.js +82 -0
- package/ci/system-one-train-test.py +55 -0
- package/docs/system-one-corpus.md +4 -0
- package/docs/system-one-routing.md +8 -1
- package/docs/system-one-training.md +131 -0
- package/harness-everything/SKILL.md +1 -1
- package/harness-everything/scripts/system-one/provider.js +12 -5
- package/harness-everything/scripts/system-one/router.js +1 -1
- package/opencode-plugin/plugin.json +1 -1
- package/package.json +1 -1
- package/plugins/harness-everything/.codex-plugin/plugin.json +1 -1
- package/plugins/harness-everything/plugin.json +1 -1
- package/plugins/harness-everything/skills/harness-everything/SKILL.md +1 -1
- package/plugins/harness-everything/skills/harness-everything/scripts/system-one/provider.js +12 -5
- package/plugins/harness-everything/skills/harness-everything/scripts/system-one/router.js +1 -1
- package/sbom.cdx.json +7 -7
- package/scripts/evaluate-system-one.js +1 -1
- package/scripts/system-one-calibrate.js +44 -0
- package/scripts/system-one-collect.js +200 -0
- package/scripts/system-one-label.js +145 -0
- package/scripts/system-one-train.py +168 -0
|
@@ -18,6 +18,9 @@ def factory(weights, manifest):
|
|
|
18
18
|
def score(request):
|
|
19
19
|
if manifest['modelId'] == 'stub-slow':
|
|
20
20
|
time.sleep(3)
|
|
21
|
+
if manifest['modelId'] == 'stub-soft':
|
|
22
|
+
rest = 0.3 / (len(request['options']) - 1)
|
|
23
|
+
return [0.7] + [rest] * (len(request['options']) - 1)
|
|
21
24
|
return [1.0] + [0.0] * (len(request['options']) - 1)
|
|
22
25
|
return score, {'context_tokens': 224, 'option_tokens': 96}
|
|
23
26
|
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { test } = require('node:test');
|
|
3
|
+
const assert = require('node:assert/strict');
|
|
4
|
+
const fs = require('node:fs');
|
|
5
|
+
const os = require('node:os');
|
|
6
|
+
const path = require('node:path');
|
|
7
|
+
const { spawnSync } = require('node:child_process');
|
|
8
|
+
const collect = require('../scripts/system-one-collect');
|
|
9
|
+
const root = path.resolve(__dirname, '..');
|
|
10
|
+
const jsonl = rows => rows.map(r => JSON.stringify(r)).join('\n');
|
|
11
|
+
|
|
12
|
+
// A fake home with one history file per source; each holds user text plus records that must be ignored.
|
|
13
|
+
function fakeHome() {
|
|
14
|
+
const home = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-s1-collect-'));
|
|
15
|
+
const appdata = path.join(home, 'AppData', 'Roaming');
|
|
16
|
+
const write = (rel, body) => { const p = path.join(home, rel); fs.mkdirSync(path.dirname(p), { recursive: true }); fs.writeFileSync(p, body); };
|
|
17
|
+
write('.claude/projects/p1/s-claude.jsonl', jsonl([
|
|
18
|
+
{ type: 'user', message: { content: 'fix the typo in README' } },
|
|
19
|
+
{ type: 'user', message: { content: [{ type: 'text', text: 'commit all changes' }] } },
|
|
20
|
+
{ type: 'user', isMeta: true, message: { content: 'meta text must be skipped' } },
|
|
21
|
+
{ type: 'user', isSidechain: true, message: { content: 'sidechain text must be skipped' } },
|
|
22
|
+
{ type: 'user', message: { content: [{ type: 'tool_result', tool_use_id: 'x', content: 'tool output must be skipped' }] } },
|
|
23
|
+
{ type: 'user', message: { content: '<system-reminder>injected</system-reminder>' } },
|
|
24
|
+
{ type: 'user', message: { content: '<command-name>/compact</command-name>' } },
|
|
25
|
+
{ type: 'assistant', message: { content: 'assistant text must be skipped' } },
|
|
26
|
+
]));
|
|
27
|
+
write('.codex/sessions/2026/09/01/rollout-a.jsonl', jsonl([
|
|
28
|
+
{ type: 'session_meta', payload: { originator: 'codex_vscode', source: 'vscode' } },
|
|
29
|
+
{ type: 'response_item', payload: { type: 'message', role: 'user', content: [{ type: 'input_text', text: '<environment_context>cwd</environment_context>' }] } },
|
|
30
|
+
{ type: 'response_item', payload: { type: 'message', role: 'user', content: [{ type: 'input_text', text: 'duplicate of the event message' }] } },
|
|
31
|
+
{ type: 'event_msg', payload: { type: 'user_message', message: 'add a --verbose flag with tests' } },
|
|
32
|
+
]));
|
|
33
|
+
write('.codex/sessions/2026/09/02/rollout-b.jsonl', jsonl([
|
|
34
|
+
{ type: 'session_meta', payload: { originator: 'Codex Desktop', source: 'vscode' } },
|
|
35
|
+
{ type: 'response_item', payload: { type: 'message', role: 'user', content: [{ type: 'input_text', text: '<user_instructions>agents</user_instructions>' }] } },
|
|
36
|
+
{ type: 'response_item', payload: { type: 'message', role: 'user', content: [{ type: 'input_text', text: 'older session without event messages' }] } },
|
|
37
|
+
]));
|
|
38
|
+
write('.copilot/session-state/c1/events.jsonl', jsonl([
|
|
39
|
+
{ type: 'system.message', data: { content: 'system prompt must be skipped' } },
|
|
40
|
+
{ type: 'user.message', data: { content: 'run npm test and report failures' } },
|
|
41
|
+
]));
|
|
42
|
+
write('AppData/Roaming/Code/User/workspaceStorage/w1/chatSessions/old.json', JSON.stringify({
|
|
43
|
+
requests: [{ message: { text: '把 parseCfg 改名成 parseConfig' } }, { message: { text: '' } }] }));
|
|
44
|
+
write('AppData/Roaming/Code/User/workspaceStorage/w1/chatSessions/new.jsonl', jsonl([
|
|
45
|
+
{ kind: 0, v: { sessionId: 's', requests: [{ message: { text: '整個 repo 遷移到 ESM' } }] } },
|
|
46
|
+
{ kind: 2, k: ['requests'], v: [{ message: { text: '繼續' } }] },
|
|
47
|
+
{ kind: 2, k: ['requests', 0, 'response'], v: [{ value: 'response text must be skipped' }] },
|
|
48
|
+
{ kind: 1, k: ['requests', 0, 'result'], v: { metadata: { renderedUserMessage: 'rendered prompt must be skipped' } } },
|
|
49
|
+
]));
|
|
50
|
+
write('AppData/Roaming/Code/User/globalStorage/emptyWindowChatSessions/e.jsonl', jsonl([
|
|
51
|
+
{ kind: 0, v: { requests: [{ message: { text: 'explain the backoff in retry.go' } }] } },
|
|
52
|
+
]));
|
|
53
|
+
return { home, appdata };
|
|
54
|
+
}
|
|
55
|
+
const texts = rows => rows.map(r => r.text).sort();
|
|
56
|
+
|
|
57
|
+
test('S1-C101 each source yields only owner-typed text', () => {
|
|
58
|
+
const { home, appdata } = fakeHome();
|
|
59
|
+
try {
|
|
60
|
+
const rows = collect.readSources({ home, appdata });
|
|
61
|
+
assert.deepEqual(texts(rows), texts([
|
|
62
|
+
{ text: 'fix the typo in README' }, { text: 'commit all changes' }, { text: 'add a --verbose flag with tests' },
|
|
63
|
+
{ text: 'older session without event messages' }, { text: 'run npm test and report failures' },
|
|
64
|
+
{ text: '把 parseCfg 改名成 parseConfig' }, { text: '整個 repo 遷移到 ESM' }, { text: '繼續' }, { text: 'explain the backoff in retry.go' },
|
|
65
|
+
]));
|
|
66
|
+
const bySource = Object.fromEntries(['claude', 'codex', 'copilot-cli', 'vscode'].map(s => [s, rows.filter(r => r.source === s).length]));
|
|
67
|
+
assert.deepEqual(bySource, { claude: 2, codex: 2, 'copilot-cli': 1, vscode: 4 });
|
|
68
|
+
assert.ok(rows.every(r => typeof r.family === 'string' && r.family.length > 0));
|
|
69
|
+
const claude = rows.filter(r => r.source === 'claude');
|
|
70
|
+
assert.equal(new Set(claude.map(r => r.family)).size, 1, 'one session file is one family');
|
|
71
|
+
} finally { fs.rmSync(home, { recursive: true, force: true }); }
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('S1-C106 only interactive Codex sessions count, and VS Code terminal notifications are dropped', () => {
|
|
75
|
+
const home = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-s1-collect-'));
|
|
76
|
+
const appdata = path.join(home, 'AppData', 'Roaming');
|
|
77
|
+
const session = (name, meta, text) => {
|
|
78
|
+
const p = path.join(home, '.codex', 'sessions', '2026', '09', '03', `${name}.jsonl`);
|
|
79
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
80
|
+
fs.writeFileSync(p, jsonl([{ type: 'session_meta', payload: meta }, { type: 'event_msg', payload: { type: 'user_message', message: text } }]));
|
|
81
|
+
};
|
|
82
|
+
try {
|
|
83
|
+
session('ide', { originator: 'codex_vscode', source: 'vscode' }, 'typed in the IDE');
|
|
84
|
+
session('desktop', { originator: 'Codex Desktop', source: 'vscode' }, 'typed in the desktop app');
|
|
85
|
+
session('tui', { originator: 'codex-tui', source: 'cli' }, 'typed in the terminal');
|
|
86
|
+
session('from-claude', { originator: 'Claude Code', source: 'vscode' }, 'dispatched by another agent');
|
|
87
|
+
session('exec', { originator: 'codex_exec', source: 'exec' }, 'an exec lane prompt');
|
|
88
|
+
session('ide-exec', { originator: 'codex_vscode', source: 'exec' }, 'another exec prompt');
|
|
89
|
+
session('subagent', { originator: 'codex_vscode', source: { subagent: { thread_spawn: {} } } }, 'a sub-agent prompt');
|
|
90
|
+
session('no-meta', null, 'a session without metadata');
|
|
91
|
+
const chat = path.join(appdata, 'Code', 'User', 'workspaceStorage', 'w', 'chatSessions', 's.jsonl');
|
|
92
|
+
fs.mkdirSync(path.dirname(chat), { recursive: true });
|
|
93
|
+
fs.writeFileSync(chat, jsonl([{ kind: 0, v: { requests: [
|
|
94
|
+
{ message: { text: '[Terminal 808808ce-309f notification: command completed with exit code 0]' } },
|
|
95
|
+
{ message: { text: 'a real chat prompt' } }] } }]));
|
|
96
|
+
assert.deepEqual(texts(collect.readSources({ home, appdata })), texts([
|
|
97
|
+
{ text: 'typed in the IDE' }, { text: 'typed in the desktop app' }, { text: 'typed in the terminal' }, { text: 'a real chat prompt' }]));
|
|
98
|
+
} finally { fs.rmSync(home, { recursive: true, force: true }); }
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test('S1-C102 filters, redaction and deduplication', () => {
|
|
102
|
+
assert.equal(collect.keep('go'), true);
|
|
103
|
+
assert.equal(collect.keep('x'.repeat(1024)), true);
|
|
104
|
+
assert.equal(collect.keep('x'.repeat(1025)), false);
|
|
105
|
+
assert.equal(collect.keep('中'.repeat(342)), false, '1026 UTF-8 bytes');
|
|
106
|
+
assert.equal(collect.keep('/compact'), false);
|
|
107
|
+
assert.equal(collect.keep('This session is being continued from a previous conversation that ran out of context.'), false);
|
|
108
|
+
assert.equal(collect.keep(' '), false);
|
|
109
|
+
assert.equal(collect.redact('mail dev.lead@example.com now'), 'mail <email> now');
|
|
110
|
+
assert.equal(collect.redact('open C:\\Users\\alice\\repo\\a.md'), 'open <home>\\repo\\a.md');
|
|
111
|
+
assert.equal(collect.redact('read /home/alice/p and /Users/bob/q'), 'read <home>/p and <home>/q');
|
|
112
|
+
const rows = collect.dedupe([{ text: 'fix it', family: 'a' }, { text: 'fix it', family: 'b' }, { text: 'other', family: 'c' }]);
|
|
113
|
+
assert.deepEqual(rows.map(r => r.family), ['a', 'c']);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test('S1-C103 prompts that near-duplicate a holdout prompt are dropped', () => {
|
|
117
|
+
const holdout = ['把 parseCfg 改名成 parseConfig, 只有這個檔案有用到', 'Rebase this branch onto the latest main.'];
|
|
118
|
+
const guard = collect.leakGuard(holdout);
|
|
119
|
+
assert.equal(guard('把 parseCfg 改名成 parseConfig'), true, 'contained, longer than 12 chars');
|
|
120
|
+
assert.equal(guard('rebase this branch onto the latest main'), true, 'normalized near-duplicate');
|
|
121
|
+
assert.equal(guard('add pagination to the users endpoint'), false);
|
|
122
|
+
assert.equal(guard('main'), false, 'short containment does not count');
|
|
123
|
+
assert.ok(collect.jaccard('abcdef', 'abcdef') === 1 && collect.jaccard('abc', 'xyz') === 0);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test('S1-C104 splits are stable per family and near 15% validation', () => {
|
|
127
|
+
assert.equal(collect.splitFor('family-a'), collect.splitFor('family-a'));
|
|
128
|
+
const families = Array.from({ length: 2000 }, (_, i) => `session-${i}`);
|
|
129
|
+
const share = families.filter(f => collect.splitFor(f) === 'validation').length / families.length;
|
|
130
|
+
assert.ok(share > 0.12 && share < 0.18, String(share));
|
|
131
|
+
assert.ok(families.every(f => ['train', 'validation'].includes(collect.splitFor(f))));
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test('S1-C105 CLI writes a deterministic local dataset outside the repository', () => {
|
|
135
|
+
const { home, appdata } = fakeHome();
|
|
136
|
+
const out = path.join(home, 'out');
|
|
137
|
+
const holdout = path.join(home, 'holdout.json');
|
|
138
|
+
fs.writeFileSync(holdout, JSON.stringify({ schemaVersion: 1, cases: [{ request: { context: 'Commit all changes.' } }] }));
|
|
139
|
+
try {
|
|
140
|
+
const run = () => spawnSync(process.execPath, [path.join(root, 'scripts/system-one-collect.js'), '--home', home, '--appdata', appdata, '--out', out, '--holdout', holdout],
|
|
141
|
+
{ encoding: 'utf8', cwd: root });
|
|
142
|
+
const one = run();
|
|
143
|
+
assert.equal(one.status, 0, one.stderr);
|
|
144
|
+
const first = fs.readFileSync(path.join(out, 'prompts.jsonl'), 'utf8');
|
|
145
|
+
const stats = JSON.parse(one.stdout);
|
|
146
|
+
assert.equal(stats.kept, 8);
|
|
147
|
+
assert.equal(stats.dropped.leak, 1);
|
|
148
|
+
assert.deepEqual(Object.keys(stats.bySource).sort(), ['claude', 'codex', 'copilot-cli', 'vscode']);
|
|
149
|
+
assert.match(stats.sha256, /^[0-9a-f]{64}$/);
|
|
150
|
+
const rows = first.trim().split('\n').map(l => JSON.parse(l));
|
|
151
|
+
assert.ok(rows.every(r => Object.keys(r).sort().join() === 'family,id,source,split,text' && /^[0-9a-f]{16}$/.test(r.id)));
|
|
152
|
+
assert.equal(run().status, 0);
|
|
153
|
+
assert.equal(fs.readFileSync(path.join(out, 'prompts.jsonl'), 'utf8'), first, 'deterministic');
|
|
154
|
+
const inRepo = spawnSync(process.execPath, [path.join(root, 'scripts/system-one-collect.js'), '--home', home, '--appdata', appdata, '--out', path.join(root, 'tmp-dataset'), '--holdout', holdout], { encoding: 'utf8', cwd: root });
|
|
155
|
+
assert.equal(inRepo.status, 1, 'refuses to write the dataset inside the repository');
|
|
156
|
+
assert.equal(fs.existsSync(path.join(root, 'tmp-dataset')), false);
|
|
157
|
+
} finally { fs.rmSync(home, { recursive: true, force: true }); }
|
|
158
|
+
});
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { test } = require('node:test');
|
|
3
|
+
const assert = require('node:assert/strict');
|
|
4
|
+
const fs = require('node:fs');
|
|
5
|
+
const os = require('node:os');
|
|
6
|
+
const path = require('node:path');
|
|
7
|
+
const { spawnSync } = require('node:child_process');
|
|
8
|
+
const label = require('../scripts/system-one-label');
|
|
9
|
+
const root = path.resolve(__dirname, '..');
|
|
10
|
+
const items = n => Array.from({ length: n }, (_, i) => ({ id: `id${i}`, text: `prompt number ${i}` }));
|
|
11
|
+
const reply = (batch, gold = () => 'tier1') => ({ labels: batch.map((_, i) => ({ i, gold: gold(i) })) });
|
|
12
|
+
|
|
13
|
+
test('S1-L01 the instructions carry the owner rules from the corpus document and every item', () => {
|
|
14
|
+
const rules = label.rulesFromDoc(fs.readFileSync(path.join(root, 'docs/system-one-corpus.md'), 'utf8'));
|
|
15
|
+
assert.match(rules, /\| `tier1` \|/);
|
|
16
|
+
assert.match(rules, /Label the work the prompt would start/);
|
|
17
|
+
assert.doesNotMatch(rules, /## Cases/);
|
|
18
|
+
const prompt = label.buildPrompt(rules, items(3));
|
|
19
|
+
assert.ok(prompt.includes(rules));
|
|
20
|
+
for (let i = 0; i < 3; i++) assert.ok(prompt.includes(JSON.stringify({ i, text: `prompt number ${i}` })));
|
|
21
|
+
assert.throws(() => label.rulesFromDoc('# no gold section'));
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('S1-L02 a batch reply must label every index exactly once with a known label', () => {
|
|
25
|
+
const batch = items(3);
|
|
26
|
+
assert.deepEqual(label.validateReply(batch, reply(batch, i => ['tier1', 'null', 'tier3'][i])), ['tier1', null, 'tier3']);
|
|
27
|
+
const bad = [
|
|
28
|
+
{ labels: [{ i: 0, gold: 'tier1' }, { i: 1, gold: 'tier1' }] },
|
|
29
|
+
{ labels: [...reply(batch).labels, { i: 0, gold: 'tier2' }] },
|
|
30
|
+
{ labels: [{ i: 0, gold: 'tier1' }, { i: 1, gold: 'tier1' }, { i: 7, gold: 'tier1' }] },
|
|
31
|
+
{ labels: [{ i: 0, gold: 'tier1' }, { i: 1, gold: 'tier4' }, { i: 2, gold: 'tier1' }] },
|
|
32
|
+
{ labels: 'nope' }, null,
|
|
33
|
+
];
|
|
34
|
+
for (const r of bad) assert.equal(label.validateReply(batch, r), null);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('S1-L03 invalid replies are retried once, persistent failures are recorded, never partially accepted, and runs resume', async () => {
|
|
38
|
+
const data = items(250);
|
|
39
|
+
const calls = [];
|
|
40
|
+
let flaky = true;
|
|
41
|
+
const run = async (prompt, batch) => {
|
|
42
|
+
calls.push(batch.length);
|
|
43
|
+
if (batch[0].id === 'id100' && flaky) { flaky = false; return { labels: [] }; }
|
|
44
|
+
if (batch[0].id === 'id200') return { labels: [] };
|
|
45
|
+
return reply(batch, i => (i % 2 ? 'tier2' : 'null'));
|
|
46
|
+
};
|
|
47
|
+
const reasons = [];
|
|
48
|
+
const first = await label.labelAll(data, { run, rules: 'R', batchSize: 100, concurrency: 2, done: new Set(), onFailure: (batch, reason) => reasons.push([batch[0].id, reason]) });
|
|
49
|
+
assert.deepEqual(reasons, [['id100', 'invalid-reply'], ['id200', 'invalid-reply'], ['id200', 'invalid-reply']], 'every failed attempt is reported with its reason');
|
|
50
|
+
const thrown = [];
|
|
51
|
+
await label.labelAll(items(1), { run: async () => { throw new Error('rate limited'); }, rules: 'R', retryDelayMs: 0, onFailure: (b, r) => thrown.push(r) });
|
|
52
|
+
assert.deepEqual(thrown, ['rate limited', 'rate limited']);
|
|
53
|
+
assert.equal(first.labeled.length, 200);
|
|
54
|
+
assert.deepEqual(first.failed.sort(), data.slice(200).map(d => d.id).sort());
|
|
55
|
+
assert.equal(calls.filter(n => n === 100).length, 3, 'the flaky batch ran twice');
|
|
56
|
+
assert.equal(first.labeled.find(r => r.id === 'id101').gold, 'tier2');
|
|
57
|
+
assert.equal(first.labeled.find(r => r.id === 'id100').gold, null);
|
|
58
|
+
calls.length = 0;
|
|
59
|
+
const again = await label.labelAll(data, { run, rules: 'R', batchSize: 100, concurrency: 2, done: new Set(first.labeled.map(r => r.id)) });
|
|
60
|
+
assert.deepEqual(calls, [50, 50], 'only the unlabeled remainder is sent, retried once');
|
|
61
|
+
assert.equal(again.labeled.length, 0);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('S1-L04 holdout agreement reports overall, per-class recall and confusion', () => {
|
|
65
|
+
const gold = [['a', 'tier1'], ['b', 'tier1'], ['c', 'tier2'], ['d', null]];
|
|
66
|
+
const pred = { a: 'tier1', b: 'tier2', c: 'tier2', d: null };
|
|
67
|
+
const r = label.agreement(gold.map(([id, g]) => ({ id, gold: g })), pred);
|
|
68
|
+
assert.equal(r.cases, 4); assert.equal(r.agreement, 0.75);
|
|
69
|
+
assert.deepEqual(r.recall, { tier1: 0.5, tier2: 1, tier3: null, unclassified: 1 });
|
|
70
|
+
assert.equal(r.confusion['tier1->tier2'], 1);
|
|
71
|
+
assert.equal(r.missing, 0);
|
|
72
|
+
assert.equal(label.agreement([{ id: 'x', gold: 'tier1' }], {}).missing, 1);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test('S1-L05 CLI labels through the configured command, resumes, checks the holdout and refuses repository output', () => {
|
|
76
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-s1-label-'));
|
|
77
|
+
try {
|
|
78
|
+
const fake = path.join(dir, 'fake-claude.js');
|
|
79
|
+
fs.writeFileSync(fake, `let s='';process.stdin.on('data',d=>s+=d).on('end',()=>{const m=[...s.matchAll(/\\{"i":(\\d+),"text"/g)];
|
|
80
|
+
process.stdout.write(JSON.stringify({is_error:false,structured_output:{labels:m.map(x=>({i:Number(x[1]),gold:'tier2'}))}}));});`);
|
|
81
|
+
const input = path.join(dir, 'prompts.jsonl');
|
|
82
|
+
fs.writeFileSync(input, items(5).map(r => JSON.stringify({ ...r, family: 'f', source: 'claude', split: 'train' })).join('\n') + '\n');
|
|
83
|
+
const env = { ...process.env, HARNESS_S1_LABEL_COMMAND: JSON.stringify([process.execPath, fake]) };
|
|
84
|
+
const cli = args => spawnSync(process.execPath, [path.join(root, 'scripts/system-one-label.js'), ...args], { encoding: 'utf8', cwd: root, env });
|
|
85
|
+
const out = path.join(dir, 'labels.jsonl');
|
|
86
|
+
const one = cli(['label', '--in', input, '--out', out]);
|
|
87
|
+
assert.equal(one.status, 0, one.stderr);
|
|
88
|
+
assert.deepEqual(JSON.parse(one.stdout), { labeled: 5, failed: 0, total: 5 });
|
|
89
|
+
const rows = fs.readFileSync(out, 'utf8').trim().split('\n').map(l => JSON.parse(l));
|
|
90
|
+
assert.ok(rows.every(r => r.gold === 'tier2' && r.labeler.model === 'sonnet' && /^[0-9a-f]{16}$/.test(r.labeler.rulesSha256)));
|
|
91
|
+
assert.deepEqual(JSON.parse(cli(['label', '--in', input, '--out', out]).stdout), { labeled: 0, failed: 0, total: 5 });
|
|
92
|
+
const partial = path.join(dir, 'partial.jsonl');
|
|
93
|
+
assert.deepEqual(JSON.parse(cli(['label', '--in', input, '--out', partial, '--batch', '2', '--max-batches', '1']).stdout), { labeled: 2, failed: 0, total: 5 });
|
|
94
|
+
assert.deepEqual(JSON.parse(cli(['label', '--in', input, '--out', partial, '--batch', '2', '--max-batches', '1']).stdout), { labeled: 2, failed: 0, total: 5 }, 'resumes with the next batch');
|
|
95
|
+
assert.equal(fs.readFileSync(partial, 'utf8').trim().split('\n').length, 4);
|
|
96
|
+
const report = path.join(dir, 'check.json');
|
|
97
|
+
const check = cli(['check-holdout', '--out', report]);
|
|
98
|
+
assert.equal(check.status, 0, check.stderr);
|
|
99
|
+
const r = JSON.parse(fs.readFileSync(report, 'utf8'));
|
|
100
|
+
assert.equal(r.cases, 215);
|
|
101
|
+
assert.equal(typeof r.agreement, 'number');
|
|
102
|
+
assert.equal(cli(['label', '--in', input, '--out', path.join(root, 'tmp-labels.jsonl')]).status, 1);
|
|
103
|
+
assert.equal(fs.existsSync(path.join(root, 'tmp-labels.jsonl')), false);
|
|
104
|
+
} finally { fs.rmSync(dir, { recursive: true, force: true }); }
|
|
105
|
+
});
|
|
@@ -16,13 +16,13 @@ const request = createRequest('tier', 'fix a typo in README', TIER_OPTIONS);
|
|
|
16
16
|
const sha = file => createHash('sha256').update(fs.readFileSync(file)).digest('hex');
|
|
17
17
|
const sleep = ms => Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
18
18
|
|
|
19
|
-
function fixture(modelId = 'stub') {
|
|
19
|
+
function fixture(modelId = 'stub', extra = {}) {
|
|
20
20
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-s1-resident-'));
|
|
21
21
|
const checkpoint = path.join(dir, 'model.safetensors');
|
|
22
22
|
fs.writeFileSync(checkpoint, 'synthetic-not-real-weights');
|
|
23
23
|
fs.writeFileSync(path.join(dir, 'model.json'), '{}');
|
|
24
24
|
const manifest = { schemaVersion: 1, python, checkpoint, weightsSha256: sha(checkpoint), configSha256: sha(path.join(dir, 'model.json')),
|
|
25
|
-
modelId, revision: 'v1', domain: 'harness-routing-v1', transport: 'resident', idleTimeoutMs: 60000 };
|
|
25
|
+
modelId, revision: 'v1', domain: 'harness-routing-v1', transport: 'resident', idleTimeoutMs: 60000, ...extra };
|
|
26
26
|
const manifestPath = path.join(dir, 'manifest.json');
|
|
27
27
|
fs.writeFileSync(manifestPath, JSON.stringify(manifest));
|
|
28
28
|
const spawns = [];
|
|
@@ -294,3 +294,37 @@ test('S1-RS12 the evaluator times the async path: no worker thread per warm scor
|
|
|
294
294
|
assert.ok(Number(fs.readFileSync(countFile, 'utf8')) < report.records.length * 2, 'warm scores must not start a worker thread each');
|
|
295
295
|
} finally { cleanup(f); }
|
|
296
296
|
});
|
|
297
|
+
|
|
298
|
+
test('S1-RS13 manifest acceptance thresholds are validated, carried by scored results and applied by the evaluator', async () => {
|
|
299
|
+
const acceptance = { minConfidence: 0.6, minMargin: 0.3 };
|
|
300
|
+
const base = fixture();
|
|
301
|
+
try {
|
|
302
|
+
for (const ok of [acceptance, { minConfidence: 0.5, minMargin: 0 }, { minConfidence: 0.99, minMargin: 0.9 }]) assert.equal(provider.validateManifest({ ...base.manifest, acceptance: ok }), true);
|
|
303
|
+
for (const bad of [{ minConfidence: 0.49, minMargin: 0.2 }, { minConfidence: 1, minMargin: 0.2 }, { minConfidence: 0.9, minMargin: 0.91 }, { minConfidence: 0.9 }, { minConfidence: 0.9, minMargin: 0.2, extra: 1 }, { minConfidence: '0.9', minMargin: 0.2 }, null, []]) {
|
|
304
|
+
assert.throws(() => provider.validateManifest({ ...base.manifest, acceptance: bad }), JSON.stringify(bad));
|
|
305
|
+
}
|
|
306
|
+
} finally { cleanup(base); }
|
|
307
|
+
const root = path.resolve(__dirname, '..');
|
|
308
|
+
const corpus = path.join(root, 'benchmarks/fixtures/system-one-routing.json');
|
|
309
|
+
const evaluateWith = f => {
|
|
310
|
+
const output = path.join(f.dir, 'report.json');
|
|
311
|
+
const child = spawnSync(process.execPath, [path.join(root, 'scripts/evaluate-system-one.js'), corpus, f.manifestPath, output], { cwd: root, encoding: 'utf8' });
|
|
312
|
+
assert.equal(child.status, 0, child.stderr);
|
|
313
|
+
return JSON.parse(fs.readFileSync(output, 'utf8')).records.flatMap(r => r.runs).filter(r => r.decision.reason !== 'provider-exit');
|
|
314
|
+
};
|
|
315
|
+
const soft = fixture('stub-soft', { acceptance });
|
|
316
|
+
try {
|
|
317
|
+
assert.equal(resident.ensureReady(soft.manifest, soft.manifestPath, 20000, soft.deps), true);
|
|
318
|
+
const result = provider.score(request, soft.manifestPath);
|
|
319
|
+
assert.equal(result.status, 'scored');
|
|
320
|
+
assert.deepEqual(result.acceptance, acceptance);
|
|
321
|
+
assert.deepEqual((await provider.scoreAsync(request, soft.manifestPath)).acceptance, acceptance);
|
|
322
|
+
assert.ok(evaluateWith(soft).every(r => r.decision.status === 'accepted' && r.decision.selectedId === 'tier1'));
|
|
323
|
+
} finally { cleanup(soft); }
|
|
324
|
+
const strict = fixture('stub-soft');
|
|
325
|
+
try {
|
|
326
|
+
assert.equal(resident.ensureReady(strict.manifest, strict.manifestPath, 20000, strict.deps), true);
|
|
327
|
+
assert.equal(provider.score(request, strict.manifestPath).acceptance, undefined);
|
|
328
|
+
assert.ok(evaluateWith(strict).every(r => r.decision.status === 'abstain' && r.decision.reason === 'low-confidence'));
|
|
329
|
+
} finally { cleanup(strict); }
|
|
330
|
+
});
|
|
@@ -99,6 +99,19 @@ test('S1-R05 structural floor: a scorer can raise but never lower a deterministi
|
|
|
99
99
|
assert.equal(plan.verification.independent, true);
|
|
100
100
|
} finally { provider.score = original; console.log = log; if (mode === undefined) delete process.env.HARNESS_SYSTEM_ONE_MODE; else process.env.HARNESS_SYSTEM_ONE_MODE = mode; }
|
|
101
101
|
});
|
|
102
|
+
test('S1-R07 a scored result with calibrated acceptance thresholds decides with them', () => {
|
|
103
|
+
const env = { HARNESS_SYSTEM_ONE_MODE: 'prefer' };
|
|
104
|
+
const input = { prompt: 'rename tmp to buffer', tier: 'Unclassified' };
|
|
105
|
+
const soft = (acceptance) => req => ({ status: 'scored', ...(acceptance ? { acceptance } : {}), response: { schemaVersion: 1, requestHash: req.requestHash, catalogHash: req.catalogHash,
|
|
106
|
+
model: { id: 'fixture', revision: 'v1', domain: 'harness-routing-v1' }, scores: req.options.map(o => ({ id: o.id, probability: o.id === 'tier2' ? 0.7 : 0.1 })) } });
|
|
107
|
+
const without = selectTier(input, env, soft(null));
|
|
108
|
+
assert.equal(without.diagnostic.reason, 'low-confidence');
|
|
109
|
+
assert.equal(without.tier, input.tier);
|
|
110
|
+
const withThresholds = selectTier(input, env, soft({ minConfidence: 0.6, minMargin: 0.3 }));
|
|
111
|
+
assert.equal(withThresholds.diagnostic.status, 'accepted');
|
|
112
|
+
assert.equal(withThresholds.tier, 'Tier 2 (Standard Task)');
|
|
113
|
+
assert.equal(selectTier(input, env, soft({ minConfidence: 0.6, minMargin: 0.7 })).diagnostic.reason, 'low-margin');
|
|
114
|
+
});
|
|
102
115
|
test('S1-R06 prescoreTier: off loads nothing; a matching request reuses the async result; mismatch and failure keep sync semantics', async () => {
|
|
103
116
|
const { prescoreTier } = require('../harness-everything/scripts/system-one/router');
|
|
104
117
|
const provider = require('../harness-everything/scripts/system-one/provider');
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { test } = require('node:test');
|
|
3
|
+
const assert = require('node:assert/strict');
|
|
4
|
+
const fs = require('node:fs');
|
|
5
|
+
const os = require('node:os');
|
|
6
|
+
const path = require('node:path');
|
|
7
|
+
const { spawnSync } = require('node:child_process');
|
|
8
|
+
const { calibrate, decideRow } = require('../scripts/system-one-calibrate');
|
|
9
|
+
const root = path.resolve(__dirname, '..');
|
|
10
|
+
const python = process.env.PYTHON || (process.platform === 'win32' ? 'python' : 'python3');
|
|
11
|
+
|
|
12
|
+
test('S1-T01 trainer data handling is exercised without torch', () => {
|
|
13
|
+
const r = spawnSync(python, [path.join(__dirname, 'system-one-train-test.py')], { encoding: 'utf8', env: { ...process.env, PYTHONDONTWRITEBYTECODE: '1' } });
|
|
14
|
+
assert.equal(r.status, 0, r.stdout + r.stderr);
|
|
15
|
+
assert.match(r.stdout, /trainer data tests passed/);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const row = (gold, probs) => ({ gold, probs });
|
|
19
|
+
test('S1-T02 a validation row is accepted only above both thresholds and never as unclassified', () => {
|
|
20
|
+
assert.deepEqual(decideRow([0.95, 0.03, 0.01, 0.01], { minConfidence: 0.9, minMargin: 0.2 }), 'tier1');
|
|
21
|
+
assert.equal(decideRow([0.85, 0.1, 0.03, 0.02], { minConfidence: 0.9, minMargin: 0.2 }), null);
|
|
22
|
+
assert.equal(decideRow([0.55, 0.45, 0, 0], { minConfidence: 0.5, minMargin: 0.2 }), null);
|
|
23
|
+
assert.equal(decideRow([0.01, 0.01, 0.01, 0.97], { minConfidence: 0.5, minMargin: 0 }), null);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('S1-T03 calibration maximizes coverage subject to accepted precision on validation only', () => {
|
|
27
|
+
const rows = [
|
|
28
|
+
...Array.from({ length: 90 }, () => row('tier1', [0.97, 0.01, 0.01, 0.01])),
|
|
29
|
+
...Array.from({ length: 5 }, () => row('tier2', [0.8, 0.15, 0.03, 0.02])),
|
|
30
|
+
...Array.from({ length: 5 }, () => row('tier2', [0.1, 0.85, 0.03, 0.02])),
|
|
31
|
+
];
|
|
32
|
+
const c = calibrate(rows, { minPrecision: 0.98 });
|
|
33
|
+
assert.ok(c.precision >= 0.98, JSON.stringify(c));
|
|
34
|
+
assert.equal(c.coverage, 0.95, JSON.stringify(c));
|
|
35
|
+
// Either threshold may separate the rows; the chosen pair must reject the wrong ones and keep the right ones.
|
|
36
|
+
assert.equal(decideRow([0.8, 0.15, 0.03, 0.02], c), null, JSON.stringify(c));
|
|
37
|
+
assert.equal(decideRow([0.1, 0.85, 0.03, 0.02], c), 'tier2', JSON.stringify(c));
|
|
38
|
+
const none = calibrate([row('tier1', [0.3, 0.7, 0, 0])], { minPrecision: 0.98 });
|
|
39
|
+
assert.equal(none.feasible, false);
|
|
40
|
+
assert.equal(none.coverage, 0);
|
|
41
|
+
assert.deepEqual(calibrate(rows, { minPrecision: 0.98 }), c, 'deterministic');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('S1-T04 calibration CLI reads validation scores and writes thresholds', () => {
|
|
45
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-s1-cal-'));
|
|
46
|
+
try {
|
|
47
|
+
const input = path.join(dir, 'val-scores.jsonl');
|
|
48
|
+
fs.writeFileSync(input, Array.from({ length: 50 }, (_, i) => JSON.stringify({ id: `v${i}`, gold: 'tier2', probs: [0.02, 0.95, 0.02, 0.01] })).join('\n') + '\n');
|
|
49
|
+
const out = path.join(dir, 'calibration.json');
|
|
50
|
+
const r = spawnSync(process.execPath, [path.join(root, 'scripts/system-one-calibrate.js'), input, out], { encoding: 'utf8' });
|
|
51
|
+
assert.equal(r.status, 0, r.stderr);
|
|
52
|
+
const c = JSON.parse(fs.readFileSync(out, 'utf8'));
|
|
53
|
+
assert.equal(c.feasible, true); assert.equal(c.coverage, 1); assert.equal(c.rows, 50);
|
|
54
|
+
assert.equal(spawnSync(process.execPath, [path.join(root, 'scripts/system-one-calibrate.js')], { encoding: 'utf8' }).status, 1);
|
|
55
|
+
} finally { fs.rmSync(dir, { recursive: true, force: true }); }
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('S1-T05 a real tiny training run produces a checkpoint the adapter loads (skipped without torch)', t => {
|
|
59
|
+
const probe = spawnSync(python, ['-c', 'import torch, cua_s1'], { encoding: 'utf8' });
|
|
60
|
+
if (probe.status !== 0) { t.skip('torch/cua_s1 not installed; mechanism tests above still run'); return; }
|
|
61
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-s1-train-'));
|
|
62
|
+
try {
|
|
63
|
+
const data = path.join(dir, 'data'); fs.mkdirSync(data);
|
|
64
|
+
const texts = ['commit all changes', 'push and open a pr', 'add a flag with tests', 'migrate every service', 'go', 'yes'];
|
|
65
|
+
const golds = ['tier1', 'tier1', 'tier3', 'tier3', null, null];
|
|
66
|
+
const prompts = []; const labels = [];
|
|
67
|
+
for (let k = 0; k < 8; k++) texts.forEach((t, i) => { const id = `p${k}-${i}`; prompts.push({ id, family: `f${k}`, source: 'claude', split: k < 6 ? 'train' : 'validation', text: `${t} ${k}` }); labels.push({ id, gold: golds[i] }); });
|
|
68
|
+
fs.writeFileSync(path.join(data, 'prompts.jsonl'), prompts.map(p => JSON.stringify(p)).join('\n') + '\n');
|
|
69
|
+
fs.writeFileSync(path.join(data, 'labels.jsonl'), labels.map(p => JSON.stringify(p)).join('\n') + '\n');
|
|
70
|
+
const out = path.join(dir, 'model');
|
|
71
|
+
const r = spawnSync(python, [path.join(root, 'scripts/system-one-train.py'), '--data-dir', data, '--out', out, '--epochs', '2', '--context-tokens', '64'], { encoding: 'utf8' });
|
|
72
|
+
assert.equal(r.status, 0, r.stdout + r.stderr);
|
|
73
|
+
const report = JSON.parse(fs.readFileSync(path.join(out, 'train-report.json'), 'utf8'));
|
|
74
|
+
assert.equal(report.counts.train, 36); assert.equal(report.counts.validation, 12);
|
|
75
|
+
const scores = fs.readFileSync(path.join(out, 'val-scores.jsonl'), 'utf8').trim().split('\n').map(l => JSON.parse(l));
|
|
76
|
+
assert.equal(scores.length, 12);
|
|
77
|
+
assert.ok(scores.every(s => s.probs.length === 4 && Math.abs(s.probs.reduce((a, b) => a + b, 0) - 1) < 1e-5));
|
|
78
|
+
const load = spawnSync(python, ['-c', `from cua_s1.model import load_checkpoint; m,c,cfg=load_checkpoint(r'${path.join(out, 'harness-routing-v1.safetensors')}','cpu'); print(cfg['context_tokens'])`], { encoding: 'utf8' });
|
|
79
|
+
assert.equal(load.status, 0, load.stderr);
|
|
80
|
+
assert.equal(load.stdout.trim(), '64');
|
|
81
|
+
} finally { fs.rmSync(dir, { recursive: true, force: true }); }
|
|
82
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""Stdlib-only tests for the System One trainer's data handling (no torch needed)."""
|
|
2
|
+
import importlib.util
|
|
3
|
+
import json
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
import sys
|
|
6
|
+
import tempfile
|
|
7
|
+
|
|
8
|
+
sys.dont_write_bytecode = True
|
|
9
|
+
ROOT = Path(__file__).resolve().parents[1]
|
|
10
|
+
spec = importlib.util.spec_from_file_location('trainer', ROOT / 'scripts' / 'system-one-train.py')
|
|
11
|
+
trainer = importlib.util.module_from_spec(spec)
|
|
12
|
+
spec.loader.exec_module(trainer)
|
|
13
|
+
assert 'torch' not in sys.modules, 'importing the trainer must not import torch'
|
|
14
|
+
|
|
15
|
+
catalog = trainer.catalog_from_holdout(ROOT / 'benchmarks' / 'fixtures' / 'system-one-holdout.json')
|
|
16
|
+
assert [o['id'] for o in catalog] == ['tier1', 'tier2', 'tier3', 'unclassified'], catalog
|
|
17
|
+
assert all(o['text'] for o in catalog)
|
|
18
|
+
assert trainer.label_index('tier2', catalog) == 1
|
|
19
|
+
assert trainer.label_index(None, catalog) == 3
|
|
20
|
+
try:
|
|
21
|
+
trainer.label_index('tier9', catalog)
|
|
22
|
+
raise SystemExit('unknown gold must be rejected')
|
|
23
|
+
except ValueError:
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
prompts = [
|
|
27
|
+
{'id': 'a', 'family': 'f1', 'source': 'claude', 'split': 'train', 'text': 'commit'},
|
|
28
|
+
{'id': 'b', 'family': 'f2', 'source': 'vscode', 'split': 'validation', 'text': 'fix the parser'},
|
|
29
|
+
{'id': 'c', 'family': 'f3', 'source': 'codex', 'split': 'train', 'text': 'unlabeled prompt'},
|
|
30
|
+
{'id': 'd', 'family': 'f4', 'source': 'codex', 'split': 'train', 'text': 'owner override'},
|
|
31
|
+
]
|
|
32
|
+
labels = [{'id': 'a', 'gold': 'tier1'}, {'id': 'b', 'gold': None}, {'id': 'd', 'gold': 'tier3'}]
|
|
33
|
+
overrides = [{'id': 'd', 'gold': 'tier2'}]
|
|
34
|
+
examples = trainer.join(prompts, labels, overrides)
|
|
35
|
+
assert [(e['id'], e['split'], e['gold']) for e in examples] == [('a', 'train', 'tier1'), ('b', 'validation', None), ('d', 'train', 'tier2')], examples
|
|
36
|
+
try:
|
|
37
|
+
trainer.join(prompts, labels + [{'id': 'a', 'gold': 'tier2'}], [])
|
|
38
|
+
raise SystemExit('duplicate labels must be rejected')
|
|
39
|
+
except ValueError:
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
lengths = [10, 1024, 300, 5, 700, 1024, 50] * 20
|
|
43
|
+
batches = trainer.make_batches(lengths, token_budget=4096)
|
|
44
|
+
flat = sorted(i for b in batches for i in b)
|
|
45
|
+
assert flat == list(range(len(lengths))), 'every example exactly once'
|
|
46
|
+
assert all(len(b) * max(lengths[i] for i in b) <= 4096 or len(b) == 1 for b in batches), 'budget respected'
|
|
47
|
+
assert batches == trainer.make_batches(lengths, token_budget=4096), 'deterministic'
|
|
48
|
+
|
|
49
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
50
|
+
p = Path(tmp) / 'rows.jsonl'
|
|
51
|
+
p.write_text('\n'.join(json.dumps(r) for r in prompts) + '\n', encoding='utf-8')
|
|
52
|
+
assert trainer.load_jsonl(p) == prompts
|
|
53
|
+
assert len(trainer.sha256_file(p)) == 64
|
|
54
|
+
|
|
55
|
+
print('system-one trainer data tests passed')
|
|
@@ -27,6 +27,10 @@ Rules:
|
|
|
27
27
|
2. Label the work requested, not the words used. Searching every repository and
|
|
28
28
|
reporting is `tier1`; changing every repository is `tier3`.
|
|
29
29
|
3. Pick the smallest tier that covers the whole request.
|
|
30
|
+
A question, a confirmation, a discussion point, or a request to restate,
|
|
31
|
+
reformat or extend the assistant's previous answer without changing files is
|
|
32
|
+
`tier1`. A requested change to code or configuration, however small, is at
|
|
33
|
+
least `tier2`. Only the smallest doc fixes listed in the table stay `tier1`.
|
|
30
34
|
4. Explicit workflow words ("use fable", "no subagents") do not change the gold.
|
|
31
35
|
Precedence is a router policy, not a label.
|
|
32
36
|
5. Never derive gold from the lexical router or any model output. A reviewer may
|
|
@@ -41,7 +41,11 @@ never a prompt-supplied executable. No shell or automatic download is used.
|
|
|
41
41
|
The manifest is version 1 with `python` (executable), `checkpoint` (absolute
|
|
42
42
|
`.safetensors` path), `weightsSha256`, `configSha256` (matching `.json` sidecar),
|
|
43
43
|
`modelId`, `revision`, `domain`, and optional `timeoutMs` (1–10000, default 2000).
|
|
44
|
-
All fields are required except the timeout; unknown fields are rejected.
|
|
44
|
+
All fields are required except the timeout; unknown fields are rejected. An
|
|
45
|
+
optional `acceptance` object holds exactly `minConfidence` (0.5–0.99) and
|
|
46
|
+
`minMargin` (0–0.9). These are the thresholds calibrated on validation for this
|
|
47
|
+
checkpoint. A scored result carries them, and the router and the evaluator pass
|
|
48
|
+
them to `decide`. Without the field the Phase 0 defaults apply. Hashes
|
|
45
49
|
must be lowercase SHA-256. Revision and domain are artifact-owner declarations,
|
|
46
50
|
not independently verified quality claims. The known `cua-ai/cua-s1-forms` ID
|
|
47
51
|
must use domain `forms-v1`. No pickle format or remote URL is accepted.
|
|
@@ -279,6 +283,9 @@ unversioned download during a prompt hook.
|
|
|
279
283
|
| 3 | Corpus and paired evaluator | Leakage checks, coverage/error metrics, repeatability |
|
|
280
284
|
| 4 | Harness training and rollout | Real checkpoint, reviewed holdout, measured host results |
|
|
281
285
|
|
|
286
|
+
Phase 4 training data, labeling, calibration and release are defined in
|
|
287
|
+
[system-one-training.md](system-one-training.md).
|
|
288
|
+
|
|
282
289
|
## Rollout gates
|
|
283
290
|
|
|
284
291
|
Phase 4 requires a separately reviewed, family-disjoint holdout of at least 200
|