harness-everything 0.23.0 → 0.24.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 +13 -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 +129 -0
- package/ci/mechanism-system-one-label.test.js +101 -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-routing.md +8 -1
- package/docs/system-one-training.md +121 -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 +196 -0
- package/scripts/system-one-label.js +144 -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,129 @@
|
|
|
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: 'response_item', payload: { type: 'message', role: 'user', content: [{ type: 'input_text', text: '<environment_context>cwd</environment_context>' }] } },
|
|
29
|
+
{ type: 'response_item', payload: { type: 'message', role: 'user', content: [{ type: 'input_text', text: 'duplicate of the event message' }] } },
|
|
30
|
+
{ type: 'event_msg', payload: { type: 'user_message', message: 'add a --verbose flag with tests' } },
|
|
31
|
+
]));
|
|
32
|
+
write('.codex/sessions/2026/09/02/rollout-b.jsonl', jsonl([
|
|
33
|
+
{ type: 'response_item', payload: { type: 'message', role: 'user', content: [{ type: 'input_text', text: '<user_instructions>agents</user_instructions>' }] } },
|
|
34
|
+
{ type: 'response_item', payload: { type: 'message', role: 'user', content: [{ type: 'input_text', text: 'older session without event messages' }] } },
|
|
35
|
+
]));
|
|
36
|
+
write('.copilot/session-state/c1/events.jsonl', jsonl([
|
|
37
|
+
{ type: 'system.message', data: { content: 'system prompt must be skipped' } },
|
|
38
|
+
{ type: 'user.message', data: { content: 'run npm test and report failures' } },
|
|
39
|
+
]));
|
|
40
|
+
write('AppData/Roaming/Code/User/workspaceStorage/w1/chatSessions/old.json', JSON.stringify({
|
|
41
|
+
requests: [{ message: { text: '把 parseCfg 改名成 parseConfig' } }, { message: { text: '' } }] }));
|
|
42
|
+
write('AppData/Roaming/Code/User/workspaceStorage/w1/chatSessions/new.jsonl', jsonl([
|
|
43
|
+
{ kind: 0, v: { sessionId: 's', requests: [{ message: { text: '整個 repo 遷移到 ESM' } }] } },
|
|
44
|
+
{ kind: 2, k: ['requests'], v: [{ message: { text: '繼續' } }] },
|
|
45
|
+
{ kind: 2, k: ['requests', 0, 'response'], v: [{ value: 'response text must be skipped' }] },
|
|
46
|
+
{ kind: 1, k: ['requests', 0, 'result'], v: { metadata: { renderedUserMessage: 'rendered prompt must be skipped' } } },
|
|
47
|
+
]));
|
|
48
|
+
write('AppData/Roaming/Code/User/globalStorage/emptyWindowChatSessions/e.jsonl', jsonl([
|
|
49
|
+
{ kind: 0, v: { requests: [{ message: { text: 'explain the backoff in retry.go' } }] } },
|
|
50
|
+
]));
|
|
51
|
+
return { home, appdata };
|
|
52
|
+
}
|
|
53
|
+
const texts = rows => rows.map(r => r.text).sort();
|
|
54
|
+
|
|
55
|
+
test('S1-C101 each source yields only owner-typed text', () => {
|
|
56
|
+
const { home, appdata } = fakeHome();
|
|
57
|
+
try {
|
|
58
|
+
const rows = collect.readSources({ home, appdata });
|
|
59
|
+
assert.deepEqual(texts(rows), texts([
|
|
60
|
+
{ text: 'fix the typo in README' }, { text: 'commit all changes' }, { text: 'add a --verbose flag with tests' },
|
|
61
|
+
{ text: 'older session without event messages' }, { text: 'run npm test and report failures' },
|
|
62
|
+
{ text: '把 parseCfg 改名成 parseConfig' }, { text: '整個 repo 遷移到 ESM' }, { text: '繼續' }, { text: 'explain the backoff in retry.go' },
|
|
63
|
+
]));
|
|
64
|
+
const bySource = Object.fromEntries(['claude', 'codex', 'copilot-cli', 'vscode'].map(s => [s, rows.filter(r => r.source === s).length]));
|
|
65
|
+
assert.deepEqual(bySource, { claude: 2, codex: 2, 'copilot-cli': 1, vscode: 4 });
|
|
66
|
+
assert.ok(rows.every(r => typeof r.family === 'string' && r.family.length > 0));
|
|
67
|
+
const claude = rows.filter(r => r.source === 'claude');
|
|
68
|
+
assert.equal(new Set(claude.map(r => r.family)).size, 1, 'one session file is one family');
|
|
69
|
+
} finally { fs.rmSync(home, { recursive: true, force: true }); }
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('S1-C102 filters, redaction and deduplication', () => {
|
|
73
|
+
assert.equal(collect.keep('go'), true);
|
|
74
|
+
assert.equal(collect.keep('x'.repeat(1024)), true);
|
|
75
|
+
assert.equal(collect.keep('x'.repeat(1025)), false);
|
|
76
|
+
assert.equal(collect.keep('中'.repeat(342)), false, '1026 UTF-8 bytes');
|
|
77
|
+
assert.equal(collect.keep('/compact'), false);
|
|
78
|
+
assert.equal(collect.keep('This session is being continued from a previous conversation that ran out of context.'), false);
|
|
79
|
+
assert.equal(collect.keep(' '), false);
|
|
80
|
+
assert.equal(collect.redact('mail dev.lead@example.com now'), 'mail <email> now');
|
|
81
|
+
assert.equal(collect.redact('open C:\\Users\\alice\\repo\\a.md'), 'open <home>\\repo\\a.md');
|
|
82
|
+
assert.equal(collect.redact('read /home/alice/p and /Users/bob/q'), 'read <home>/p and <home>/q');
|
|
83
|
+
const rows = collect.dedupe([{ text: 'fix it', family: 'a' }, { text: 'fix it', family: 'b' }, { text: 'other', family: 'c' }]);
|
|
84
|
+
assert.deepEqual(rows.map(r => r.family), ['a', 'c']);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test('S1-C103 prompts that near-duplicate a holdout prompt are dropped', () => {
|
|
88
|
+
const holdout = ['把 parseCfg 改名成 parseConfig, 只有這個檔案有用到', 'Rebase this branch onto the latest main.'];
|
|
89
|
+
const guard = collect.leakGuard(holdout);
|
|
90
|
+
assert.equal(guard('把 parseCfg 改名成 parseConfig'), true, 'contained, longer than 12 chars');
|
|
91
|
+
assert.equal(guard('rebase this branch onto the latest main'), true, 'normalized near-duplicate');
|
|
92
|
+
assert.equal(guard('add pagination to the users endpoint'), false);
|
|
93
|
+
assert.equal(guard('main'), false, 'short containment does not count');
|
|
94
|
+
assert.ok(collect.jaccard('abcdef', 'abcdef') === 1 && collect.jaccard('abc', 'xyz') === 0);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test('S1-C104 splits are stable per family and near 15% validation', () => {
|
|
98
|
+
assert.equal(collect.splitFor('family-a'), collect.splitFor('family-a'));
|
|
99
|
+
const families = Array.from({ length: 2000 }, (_, i) => `session-${i}`);
|
|
100
|
+
const share = families.filter(f => collect.splitFor(f) === 'validation').length / families.length;
|
|
101
|
+
assert.ok(share > 0.12 && share < 0.18, String(share));
|
|
102
|
+
assert.ok(families.every(f => ['train', 'validation'].includes(collect.splitFor(f))));
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test('S1-C105 CLI writes a deterministic local dataset outside the repository', () => {
|
|
106
|
+
const { home, appdata } = fakeHome();
|
|
107
|
+
const out = path.join(home, 'out');
|
|
108
|
+
const holdout = path.join(home, 'holdout.json');
|
|
109
|
+
fs.writeFileSync(holdout, JSON.stringify({ schemaVersion: 1, cases: [{ request: { context: 'Commit all changes.' } }] }));
|
|
110
|
+
try {
|
|
111
|
+
const run = () => spawnSync(process.execPath, [path.join(root, 'scripts/system-one-collect.js'), '--home', home, '--appdata', appdata, '--out', out, '--holdout', holdout],
|
|
112
|
+
{ encoding: 'utf8', cwd: root });
|
|
113
|
+
const one = run();
|
|
114
|
+
assert.equal(one.status, 0, one.stderr);
|
|
115
|
+
const first = fs.readFileSync(path.join(out, 'prompts.jsonl'), 'utf8');
|
|
116
|
+
const stats = JSON.parse(one.stdout);
|
|
117
|
+
assert.equal(stats.kept, 8);
|
|
118
|
+
assert.equal(stats.dropped.leak, 1);
|
|
119
|
+
assert.deepEqual(Object.keys(stats.bySource).sort(), ['claude', 'codex', 'copilot-cli', 'vscode']);
|
|
120
|
+
assert.match(stats.sha256, /^[0-9a-f]{64}$/);
|
|
121
|
+
const rows = first.trim().split('\n').map(l => JSON.parse(l));
|
|
122
|
+
assert.ok(rows.every(r => Object.keys(r).sort().join() === 'family,id,source,split,text' && /^[0-9a-f]{16}$/.test(r.id)));
|
|
123
|
+
assert.equal(run().status, 0);
|
|
124
|
+
assert.equal(fs.readFileSync(path.join(out, 'prompts.jsonl'), 'utf8'), first, 'deterministic');
|
|
125
|
+
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 });
|
|
126
|
+
assert.equal(inRepo.status, 1, 'refuses to write the dataset inside the repository');
|
|
127
|
+
assert.equal(fs.existsSync(path.join(root, 'tmp-dataset')), false);
|
|
128
|
+
} finally { fs.rmSync(home, { recursive: true, force: true }); }
|
|
129
|
+
});
|
|
@@ -0,0 +1,101 @@
|
|
|
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 report = path.join(dir, 'check.json');
|
|
93
|
+
const check = cli(['check-holdout', '--out', report]);
|
|
94
|
+
assert.equal(check.status, 0, check.stderr);
|
|
95
|
+
const r = JSON.parse(fs.readFileSync(report, 'utf8'));
|
|
96
|
+
assert.equal(r.cases, 215);
|
|
97
|
+
assert.equal(typeof r.agreement, 'number');
|
|
98
|
+
assert.equal(cli(['label', '--in', input, '--out', path.join(root, 'tmp-labels.jsonl')]).status, 1);
|
|
99
|
+
assert.equal(fs.existsSync(path.join(root, 'tmp-labels.jsonl')), false);
|
|
100
|
+
} finally { fs.rmSync(dir, { recursive: true, force: true }); }
|
|
101
|
+
});
|
|
@@ -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')
|
|
@@ -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
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# System One training data and weights
|
|
2
|
+
|
|
3
|
+
This document defines how the `harness-routing-v1` tier checkpoint for
|
|
4
|
+
[System One](system-one-routing.md) is trained, calibrated and released
|
|
5
|
+
(issue [#233](https://github.com/dyphn1/Harness-everything/issues/233), Phase 4).
|
|
6
|
+
Gold labels follow [system-one-corpus.md](system-one-corpus.md). The owner-reviewed
|
|
7
|
+
holdout in that document is used only for evaluation. It is never used for training,
|
|
8
|
+
threshold selection or labeler tuning.
|
|
9
|
+
|
|
10
|
+
## Pipeline
|
|
11
|
+
|
|
12
|
+
1. **Collect**: copy the owner's own prompts from local assistant histories into a local
|
|
13
|
+
dataset (`scripts/system-one-collect.js`).
|
|
14
|
+
2. **Label**: an LLM labels each prompt against the owner's rules. The labeler is checked
|
|
15
|
+
once against the holdout, and the owner spot-checks a sample
|
|
16
|
+
(`scripts/system-one-label.js`).
|
|
17
|
+
3. **Train**: train a fresh `cua_s1` `tinyx` scorer on the train split and select the epoch
|
|
18
|
+
on the validation split.
|
|
19
|
+
4. **Calibrate**: choose the confidence and margin thresholds on validation.
|
|
20
|
+
5. **Evaluate**: produce one paired report on the holdout.
|
|
21
|
+
6. **Release**: publish the weights as a GitHub release asset. The installer pins them by
|
|
22
|
+
SHA-256.
|
|
23
|
+
|
|
24
|
+
## Sources
|
|
25
|
+
|
|
26
|
+
Only text the owner typed is collected. Injected context, tool output and assistant text are
|
|
27
|
+
never collected.
|
|
28
|
+
|
|
29
|
+
| Source | Location | User text |
|
|
30
|
+
| --- | --- | --- |
|
|
31
|
+
| Claude Code | `~/.claude/projects/*/*.jsonl` | `type: "user"` records that are not meta or sidechain, string content or text parts |
|
|
32
|
+
| Codex | `~/.codex/sessions/**/*.jsonl` | `event_msg` `user_message.message`. Older sessions without it fall back to `response_item` user text |
|
|
33
|
+
| Copilot CLI | `~/.copilot/session-state/*/events.jsonl` | `user.message` `data.content` |
|
|
34
|
+
| VS Code Copilot Chat | `%APPDATA%/Code/User/workspaceStorage/*/chatSessions/*.json(l)` and `globalStorage/emptyWindowChatSessions` | `requests[].message.text` in snapshots (`kind: 0`) and request pushes (`kind: 2`, key `["requests"]`) |
|
|
35
|
+
|
|
36
|
+
The following are dropped:
|
|
37
|
+
|
|
38
|
+
- Text that starts with an injected wrapper tag, such as `<environment_context>`,
|
|
39
|
+
`<system-reminder>`, `<command-…>`, `<task-notification>` or `<ide_…>`.
|
|
40
|
+
- Tool results.
|
|
41
|
+
- Slash commands.
|
|
42
|
+
- Session-continuation summaries ("This session is being continued…").
|
|
43
|
+
- Empty text.
|
|
44
|
+
|
|
45
|
+
Codex sessions include prompts that another agent dispatched. They are kept and tagged with
|
|
46
|
+
their source, because Harness routes them in Codex too.
|
|
47
|
+
|
|
48
|
+
## Filters, families and splits
|
|
49
|
+
|
|
50
|
+
- **Length**: at most 1024 UTF-8 bytes, which matches the checkpoint's `context_tokens`. A
|
|
51
|
+
longer prompt is still refused at inference and falls back to lexical routing. It is never
|
|
52
|
+
truncated.
|
|
53
|
+
- **Deduplication**: exact duplicates after whitespace normalization are dropped. The first
|
|
54
|
+
occurrence is kept.
|
|
55
|
+
- **Holdout leakage**: a prompt is dropped if its character-trigram Jaccard similarity to any
|
|
56
|
+
holdout prompt is at least 0.5. The same applies if either prompt contains the other after
|
|
57
|
+
normalization and the shorter one is more than 12 characters long. This matters because
|
|
58
|
+
the holdout includes rewrites of local prompt shapes.
|
|
59
|
+
- **Family**: the source session. Prompts from one conversation never span splits.
|
|
60
|
+
- **Split**: 15% of families go to `validation`, chosen by a stable SHA-256 of the family ID.
|
|
61
|
+
The rest go to `train`.
|
|
62
|
+
|
|
63
|
+
## Privacy
|
|
64
|
+
|
|
65
|
+
- Collected prompts and labels stay on the local machine under
|
|
66
|
+
`~/.agents/harness-everything/system-one/training/` and are **never committed**. The
|
|
67
|
+
repository holds only the scripts, aggregate statistics and the SHA-256 of each dataset
|
|
68
|
+
file.
|
|
69
|
+
- Email addresses and user home paths are replaced with placeholders before storage. Names
|
|
70
|
+
and product terms are not reliably detectable and remain.
|
|
71
|
+
- The released weights come from a 4-way byte-level classifier with about 0.7M parameters. It
|
|
72
|
+
has no text-generation head, but a trained model can still encode fragments of its data.
|
|
73
|
+
The owner accepted this for their own prompts.
|
|
74
|
+
- Labeling sends the prompts to the Claude API. The owner authorized this.
|
|
75
|
+
|
|
76
|
+
## Labeling
|
|
77
|
+
|
|
78
|
+
- **Labeler**: `claude -p` with Sonnet.
|
|
79
|
+
- Flags: `--setting-sources ""` (no hooks or plugins), `--no-session-persistence` (labeling
|
|
80
|
+
sessions never become collectable history), `--tools ""` and a JSON schema.
|
|
81
|
+
- The instructions contain the gold table and rules from
|
|
82
|
+
[system-one-corpus.md](system-one-corpus.md).
|
|
83
|
+
- Prompts go in batches of 100. Every returned index must be labeled exactly once with
|
|
84
|
+
`tier1`, `tier2`, `tier3` or `null`. A malformed batch is retried once and then
|
|
85
|
+
recorded as failed. It is never partially accepted.
|
|
86
|
+
- **Labeler check**: the labeler labels the 215 holdout prompts once, before any training
|
|
87
|
+
data is labeled. The report gives agreement with the owner's gold and the per-class recall.
|
|
88
|
+
- Labeling proceeds only when agreement is at least 80%.
|
|
89
|
+
- The instructions are never tuned on the holdout. If the check fails, the owner reviews
|
|
90
|
+
the disagreements and decides how to proceed.
|
|
91
|
+
- **Owner spot-check**: a random 5% sample of the labeled training data is reviewed on the
|
|
92
|
+
review page, and the disagreement rate is reported. The owner's decisions replace the LLM
|
|
93
|
+
labels for those cases.
|
|
94
|
+
|
|
95
|
+
## Training and calibration
|
|
96
|
+
|
|
97
|
+
- **Model**: a new `cua_s1` `tinyx` scorer built with `make_system`.
|
|
98
|
+
- Config: `width` 128, `rank` 128, `layers` 2, `heads` 4, `context_tokens` 1024 and
|
|
99
|
+
`option_tokens` 96.
|
|
100
|
+
- Weights are initialized fresh, not from the forms checkpoint, whose domain and
|
|
101
|
+
positional range differ.
|
|
102
|
+
- **Target**: each example is the fixed tier catalog with the index of the gold option.
|
|
103
|
+
`null` maps to `unclassified`.
|
|
104
|
+
- **Optimization**:
|
|
105
|
+
- Cross-entropy, AdamW, a fixed seed and CPU.
|
|
106
|
+
- The epoch with the lowest validation negative log-likelihood is kept.
|
|
107
|
+
- The checkpoint metadata records the dataset hashes, the config and the validation metrics.
|
|
108
|
+
- **Calibration**: `minConfidence` and `minMargin` are chosen on validation to maximize
|
|
109
|
+
coverage, subject to an accepted precision of at least 98%. The router currently uses the
|
|
110
|
+
Phase 0 defaults (0.9 and 0.2). Carrying calibrated thresholds into the manifest is a
|
|
111
|
+
separate contract change.
|
|
112
|
+
|
|
113
|
+
## Evaluation and release
|
|
114
|
+
|
|
115
|
+
- **Evaluation**: `scripts/evaluate-system-one.js` runs once on
|
|
116
|
+
`benchmarks/fixtures/system-one-holdout.json` with the new manifest. The rollout gates and
|
|
117
|
+
the lexical baseline (macro-F1 0.254) decide the result. The report goes under
|
|
118
|
+
`benchmarks/results/system-one/`.
|
|
119
|
+
- **Release**: the `.safetensors` and `.json` files are attached to a GitHub release. The
|
|
120
|
+
installer's pins gain the new model ID, revision, `domain: "harness-routing-v1"` and both
|
|
121
|
+
SHA-256 values. Until every rollout gate passes, the router default stays `off`.
|