harness-everything 0.20.7 → 0.21.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.
Files changed (37) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +14 -0
  4. package/benchmarks/fixtures/system-one-routing.json +549 -0
  5. package/benchmarks/results/system-one/cua-s1-forms-cpu-2026-09-23/README.md +62 -0
  6. package/benchmarks/results/system-one/cua-s1-forms-cpu-2026-09-23/report.json +856 -0
  7. package/ci/fixtures/system-one-provider.cjs +13 -0
  8. package/ci/mechanism-system-one-contract.test.js +48 -0
  9. package/ci/mechanism-system-one-evaluation.test.js +87 -0
  10. package/ci/mechanism-system-one-install.test.js +95 -0
  11. package/ci/mechanism-system-one-provider.test.js +63 -0
  12. package/ci/mechanism-system-one-router.test.js +101 -0
  13. package/ci/system-one-adapter-test.py +56 -0
  14. package/docs/platform-capabilities.md +11 -0
  15. package/docs/system-one-routing.md +202 -0
  16. package/harness-everything/SKILL.md +1 -1
  17. package/harness-everything/scripts/system-one/contract.js +45 -0
  18. package/harness-everything/scripts/system-one/cua_adapter.py +94 -0
  19. package/harness-everything/scripts/system-one/evaluate.js +98 -0
  20. package/harness-everything/scripts/system-one/install.js +152 -0
  21. package/harness-everything/scripts/system-one/provider.js +76 -0
  22. package/harness-everything/scripts/system-one/router.js +37 -0
  23. package/harness-everything/scripts/tier-router.js +16 -0
  24. package/opencode-plugin/plugin.json +1 -1
  25. package/package.json +2 -1
  26. package/plugins/harness-everything/.codex-plugin/plugin.json +1 -1
  27. package/plugins/harness-everything/plugin.json +1 -1
  28. package/plugins/harness-everything/skills/harness-everything/SKILL.md +1 -1
  29. package/plugins/harness-everything/skills/harness-everything/scripts/system-one/contract.js +45 -0
  30. package/plugins/harness-everything/skills/harness-everything/scripts/system-one/cua_adapter.py +94 -0
  31. package/plugins/harness-everything/skills/harness-everything/scripts/system-one/evaluate.js +98 -0
  32. package/plugins/harness-everything/skills/harness-everything/scripts/system-one/install.js +152 -0
  33. package/plugins/harness-everything/skills/harness-everything/scripts/system-one/provider.js +76 -0
  34. package/plugins/harness-everything/skills/harness-everything/scripts/system-one/router.js +37 -0
  35. package/plugins/harness-everything/skills/harness-everything/scripts/tier-router.js +16 -0
  36. package/sbom.cdx.json +7 -7
  37. package/scripts/evaluate-system-one.js +57 -0
@@ -0,0 +1,202 @@
1
+ # System One routing migration
2
+
3
+ Status: experimental engineering; issue [#233](https://github.com/dyphn1/Harness-everything/issues/233).
4
+ The default router stays lexical until a Harness checkpoint passes the rollout gates.
5
+ Implement each phase in **documentation → failing tests → implementation** order.
6
+
7
+ ## Phase 0: scorer contract
8
+
9
+ System One scores a complete, caller-owned candidate list in one pass. It cannot
10
+ generate a workflow, execute actions, authorize tools, or write memory. Policy and
11
+ contract assembly remain deterministic. This boundary does not add execution locks.
12
+
13
+ `createRequest(task, context, options)` returns a version-1 request. Task names and
14
+ candidate IDs use lowercase letters, digits, dots, underscores or hyphens (1–80
15
+ characters). Context is nonempty UTF-8 (at most 65,536 bytes). There are 2–256
16
+ unique `{id, text}` options; text is nonempty and at most 4,096 bytes. Empty,
17
+ malformed, unknown-field and wrong-type inputs are errors. Input objects are not
18
+ mutated. Candidate order matters. `catalogHash` is SHA-256 of JSON-encoded
19
+ `{task, options}`; `requestHash` additionally binds the exact context. Neither
20
+ fingerprint grants permission or authenticates a model.
21
+
22
+ The provider response has exactly `schemaVersion`, `requestHash`, `catalogHash`,
23
+ `model`, and `scores`. Model has nonempty `id`, `revision`, and `domain` strings.
24
+ Scores have exactly `{id, probability}` in request order. All candidates occur
25
+ exactly once; probabilities are finite numbers in [0, 1], summing to one within
26
+ 1e-6. Unknown fields, stale request/catalog hashes, and version mismatches fail.
27
+
28
+ `decide(request, response, policy)` returns exactly `status`, `reason`,
29
+ `selectedId`, `confidence`, `margin`, and `model`. Status is `accepted`, `abstain`,
30
+ or `invalid-output`; nonaccepted results always have `selectedId: null`.
31
+ Policy requires a domain (default `harness-routing-v1`), minimum confidence
32
+ (default 0.9) and minimum margin (default 0.2). Invalid policy is a caller error.
33
+ Reject domain mismatch, tied winners, low confidence and low margin. A softmax
34
+ score is not calibrated correctness probability. Invalid output returns no raw
35
+ response, exception, or prompt. Identical inputs give identical decisions.
36
+
37
+ ## Phase 1: local provider
38
+
39
+ `provider.score(request, manifestPath)` uses a trusted host-configured manifest,
40
+ never a prompt-supplied executable. No shell or automatic download is used.
41
+ The manifest is version 1 with `python` (executable), `checkpoint` (absolute
42
+ `.safetensors` path), `weightsSha256`, `configSha256` (matching `.json` sidecar),
43
+ `modelId`, `revision`, `domain`, and optional `timeoutMs` (1–10000, default 2000).
44
+ All fields are required except the timeout; unknown fields are rejected. Hashes
45
+ must be lowercase SHA-256. Revision and domain are artifact-owner declarations,
46
+ not independently verified quality claims. The known `cua-ai/cua-s1-forms` ID
47
+ must use domain `forms-v1`. No pickle format or remote URL is accepted.
48
+
49
+ Install the optional `cua_s1` source in a dedicated Python 3.11–3.13 environment
50
+ from upstream revision `b7f7e2d8714609853a29c7d049140bc46aec0954`, using the
51
+ `libs/cua-s1/python` project. This npm package does not install Python, torch or
52
+ weights. Configure its Python executable in the manifest. A manifest alone does
53
+ not prove which Python package was installed, so `provider.provenance(manifestPath)`
54
+ runs `cua_adapter.py --provenance` with the configured interpreter. The probe
55
+ reads installed metadata only (no torch import, no checkpoint load) and reports
56
+ the Python implementation/version, the distribution providing `cua_s1`, its
57
+ version, the torch version, and the source revision. Only a PEP 610
58
+ `direct_url.json` VCS `commit_id` counts as a source revision, so install from a
59
+ VCS URL pinned to that commit (not an editable or local-directory install).
60
+ The status is `pinned` when it matches, `mismatch` otherwise, or `unavailable`
61
+ when no revision is recorded. Malformed probe output is `provider-json`.
62
+
63
+ `npm run system-one:install` (or `node harness-everything/scripts/system-one/install.js`)
64
+ performs these steps on explicit request; hooks never run it. It selects a
65
+ Python 3.11–3.13 interpreter (`--python` overrides; 3.14 is rejected by upstream),
66
+ creates `<dir>/venv`, installs CPU-only torch from the PyTorch CPU index, then
67
+ installs the pinned `cua_s1` Git URL. It downloads the `cua-ai/cua-s1-forms`
68
+ safetensors weights and JSON sidecar at Hugging Face revision
69
+ `f54adbf447f4ca6ec259f529ee3f2e3e09f8cc71`, verifies pinned sizes and SHA-256
70
+ before an atomic write (the pickle `.pt` is never fetched), and writes
71
+ `<dir>/manifest.json` with `timeoutMs: 10000`. The default `<dir>` is
72
+ `~/.agents/harness-everything/system-one`; `--dir` takes an absolute path and
73
+ `--dry-run` prints the plan without changes. Acceptance requires a `pinned`
74
+ provenance probe and one real CPU inference; otherwise the exit code is 1.
75
+ Torch/numpy/safetensors versions resolve at install time and are recorded by
76
+ the probe. The installer does not change the router mode: it prints
77
+ `HARNESS_SYSTEM_ONE_MODE=shadow` and the manifest path for the host
78
+ environment. This checkpoint declares domain `forms-v1`, so shadow diagnostics
79
+ report `domain-mismatch` and prefer never applies it. It also rejects context
80
+ above its 224-byte limit (`provider-exit`), so installing it proves the local
81
+ inference path only, not Harness routing quality.
82
+
83
+ The adapter verifies both files before `load_checkpoint(..., 'cpu')`, sets one
84
+ torch thread and deterministic inference, calls the upstream collator/model,
85
+ and returns a probability for every option. It rejects context or option text
86
+ that exceeds the loaded byte limits before collation (no silent truncation).
87
+ No prompts or model values are written to disk or echoed in error messages.
88
+
89
+ The Node transport has a hard timeout and a 1 MiB stdout/stderr bound; it kills
90
+ the direct child on timeout. It starts one short-lived Python process per score
91
+ request. This is an evaluation bridge, not a warm, persistent low-latency server.
92
+ The process cannot execute actions and is not given a CUA driver. Failures return
93
+ `{status: 'unavailable', reason}` with a bounded reason code; malformed score
94
+ responses are checked by Phase 0. Transport fixtures prove IPC and failure
95
+ handling only. Real checkpoint inference and measured CPU latency remain a
96
+ separate gate, with explicit unavailable evidence if dependencies are absent.
97
+
98
+ ## Phase 2: tier integration and rollback
99
+
100
+ Set `HARNESS_SYSTEM_ONE_MODE=off|shadow|prefer` in the host environment. Default
101
+ is `off`: no provider process, diagnostic, or contract change. Supply an absolute
102
+ `HARNESS_SYSTEM_ONE_CONFIG` path to the Phase 1 manifest for the other modes.
103
+ An unknown mode reports `invalid-mode` and leaves the lexical result unchanged.
104
+ Shadow records the decision but never changes the route. Prefer replaces only
105
+ the recommended tier when a valid `harness-routing-v1` result passes Phase 0
106
+ thresholds. The full fixed tier catalog (tier1, tier2, tier3, unclassified) is
107
+ always scored; it is never filtered using lexical matches. `unclassified` means
108
+ abstention and keeps the existing route. Explicit strategy/model requests keep
109
+ precedence and prevent model tier replacement. Set mode back to `off` to roll back.
110
+
111
+ Prefer can raise a tier but never lower it below the deterministic structural
112
+ floor: a macro-scope signal sets floor `tier3`, and multi-task, multi-sentence
113
+ structure (other than a trivial docs edit) sets floor `tier2`. An accepted result
114
+ below the floor is not applied and reports `structural-floor`, so repository-wide
115
+ work keeps its Tier 3 strategy, independent verification and worktree
116
+ invariants. Tier-3 keywords are lexical guesses, not structural floors. The
117
+ policy assembler still consumes the original structural and risk signals.
118
+ Safety, explicit prohibitions, memory ownership, and verification are not model
119
+ outputs. This phase does not yet replace guide matching, dynamic
120
+ skill triggers, fact-audit reminders, or the structural workflow signals.
121
+ The same scorer API can evaluate caller-supplied text options; additional routing
122
+ surfaces require their own catalog and held-out evidence before integration.
123
+
124
+ When enabled, a single `SYSTEM ONE` JSON diagnostic reports mode, status, reason,
125
+ selected candidate, model identity, confidence and margin; it omits prompt text,
126
+ score vectors and artifact paths. The existing router contract schema is unchanged.
127
+ Kernel/packaged entry points inherit these host environment variables. Prompts
128
+ and hook payload fields cannot set model configuration or launch executables.
129
+ Repository tests establish mechanism/package evidence only; actual host loading
130
+ and semantic quality remain unverified until retained sessions demonstrate them.
131
+
132
+ ## Phase 3: corpus and paired evaluation
133
+
134
+ Use `node scripts/evaluate-system-one.js corpus.json /absolute/manifest.json report.json`.
135
+ The corpus is `{schemaVersion: 1, cases: [...]}`. Each case has exactly `id`,
136
+ `family`, `split` (`train|validation|holdout`), `language` (`en|zh-TW`), `source`
137
+ (human-reviewed provenance, not baseline-generated gold), `reviewed` (boolean),
138
+ `request` (Phase 0 tier request), and `gold` (candidate ID, or null for abstention).
139
+ The complete fixed tier catalog must match. IDs and request hashes are unique;
140
+ no family may span splits. Evaluation uses only holdout, never training labels.
141
+ The committed seed corpus is a mechanism fixture, not an independently reviewed
142
+ holdout. Expand and review it separately before making quality claims.
143
+
144
+ The CLI runs the real lexical baseline and the configured provider twice per
145
+ holdout case. Records contain IDs, baseline prediction, decision, model identity,
146
+ the catalog-order probability vector (`scores`; null for unavailable or invalid
147
+ output), latency, and `coldStart: true`; they do not copy prompts into the
148
+ report. A scored run's confidence and margin must match its vector. Gold
149
+ `unclassified` is represented by null. Nonaccepted model results also predict
150
+ null. The evaluator rejects missing, duplicate or unknown cases, unsupported
151
+ predictions, malformed measurements, and inconsistent model identities. Reruns
152
+ compare the full decision, model identity and score vector, but not measured
153
+ latency: equal top-2 values with a reordered tail still disagree.
154
+ No normalization is permitted for candidate IDs or model revision.
155
+
156
+ Report both baseline and model accuracy/macro-F1, model coverage, accepted
157
+ precision/error rate, abstention, repeated-decision agreement, and separate
158
+ cold/warm p95. Zero accepted decisions has null precision and never passes.
159
+ Unavailable responses remain abstentions and count against coverage. Null gold
160
+ is included in macro-F1's class set; the four catalog labels are always included
161
+ even when unobserved, preventing favorable per-run class selection.
162
+
163
+ The evaluator emits explicit rollout checks, not an automatic deployment. It
164
+ requires reviewed holdout counts, semantic/coverage thresholds, repeatability,
165
+ warm measurements, a `pinned` source revision, plus independently retained
166
+ policy and live-host evidence. The report's `evidence.source` keeps the probe
167
+ result (including `mismatch` or `unavailable`) and `environment.python`.
168
+ The latter evidence is not supplied by this offline runner, so it always reports
169
+ those gates pending. With the one-shot adapter, all latency is cold and the warm
170
+ gate also remains pending. Exporting a report never changes router defaults.
171
+
172
+ ## Model suitability
173
+
174
+ The [CUA-S1-FORMS model card](https://huggingface.co/cua-ai/cua-s1-forms)
175
+ describes a form-specific option scorer, with English-centric training and short
176
+ byte contexts. These results do not establish Harness routing quality. Its
177
+ checkpoint is an experimental baseline, not a production routing checkpoint.
178
+ The [upstream source](https://github.com/trycua/cua/tree/main/libs/cua-s1)
179
+ has a source-only release description; source and checkpoint provenance/licenses
180
+ must be checked independently. Do not infer a published Python wheel or use an
181
+ unversioned download during a prompt hook.
182
+
183
+ ## Planned phases
184
+
185
+ | Phase | Deliverable | Acceptance evidence |
186
+ | --- | --- | --- |
187
+ | 0 | Versioned option-scoring boundary | Complete positive/negative contract tests |
188
+ | 1 | Local CUA-S1 adapter | Bounded subprocess, artifact validation, explicit failures |
189
+ | 2 | Router integration | Off/shadow/prefer, existing policy invariants, rollback |
190
+ | 3 | Corpus and paired evaluator | Leakage checks, coverage/error metrics, repeatability |
191
+ | 4 | Harness training and rollout | Real checkpoint, reviewed holdout, measured host results |
192
+
193
+ ## Rollout gates
194
+
195
+ Phase 4 requires a separately reviewed, family-disjoint holdout of at least 200
196
+ cases, at least 50 each in English and Traditional Chinese. Accepted precision
197
+ must be ≥98%, coverage ≥80%, and macro-F1 at least the lexical baseline.
198
+ Policy invariants must remain intact in every case; repeat decisions twice with
199
+ 100% agreement. Record checkpoint/source hashes, CPU, OS, runtime, thread count,
200
+ cold latency and warm p95 (target ≤100ms). Synthetic fixtures and mock providers
201
+ only validate mechanisms. They cannot satisfy these model/behavior gates.
202
+ Until measured evidence passes, retain the default, fallback and this open issue.
@@ -4,7 +4,7 @@ description: "Route software/project work through Harness: classify tier/topolog
4
4
  license: Apache-2.0
5
5
  metadata:
6
6
  author: Miya Daniel
7
- version: 0.19.1
7
+ version: 0.21.0
8
8
  ---
9
9
 
10
10
  # Harness Everything
@@ -0,0 +1,45 @@
1
+ 'use strict';
2
+ const { createHash } = require('node:crypto');
3
+ const hash = value => createHash('sha256').update(JSON.stringify(value)).digest('hex');
4
+ const exact = (value, keys) => value && typeof value === 'object' && !Array.isArray(value)
5
+ && Object.keys(value).length === keys.length && keys.every(k => Object.hasOwn(value, k));
6
+ const text = (value, max = 4096) => typeof value === 'string' && value.trim().length > 0 && Buffer.byteLength(value, 'utf8') <= max;
7
+ const id = value => typeof value === 'string' && /^[a-z0-9._-]{1,80}$/.test(value);
8
+ const probability = value => typeof value === 'number' && Number.isFinite(value) && value >= 0 && value <= 1;
9
+ function fail(code) { throw Object.assign(new TypeError(code), { code }); }
10
+ function createRequest(task, context, options) {
11
+ if (!id(task) || !text(context, 65536) || !Array.isArray(options) || options.length < 2 || options.length > 256
12
+ || options.some(o => !exact(o, ['id', 'text']) || !id(o.id) || !text(o.text))
13
+ || new Set(options.map(o => o.id)).size !== options.length) fail('invalid-request');
14
+ const copy = options.map(o => ({ id: o.id, text: o.text }));
15
+ const catalogHash = hash({ task, options: copy });
16
+ return { schemaVersion: 1, task, context, options: copy, catalogHash, requestHash: hash({ catalogHash, context }) };
17
+ }
18
+ function validateRequest(req) {
19
+ if (!exact(req, ['schemaVersion', 'task', 'context', 'options', 'catalogHash', 'requestHash']) || req.schemaVersion !== 1) fail('invalid-request');
20
+ const rebuilt = createRequest(req.task, req.context, req.options);
21
+ if (req.catalogHash !== rebuilt.catalogHash || req.requestHash !== rebuilt.requestHash) fail('invalid-request');
22
+ return true;
23
+ }
24
+ function decide(req, res, policy = {}) {
25
+ validateRequest(req);
26
+ if (!policy || typeof policy !== 'object' || Array.isArray(policy)
27
+ || Object.keys(policy).some(k => !['domain', 'minConfidence', 'minMargin'].includes(k))) fail('invalid-policy');
28
+ const { domain = 'harness-routing-v1', minConfidence = 0.9, minMargin = 0.2 } = policy;
29
+ if (!text(domain) || !probability(minConfidence) || !probability(minMargin)) fail('invalid-policy');
30
+ const empty = { status: 'invalid-output', reason: 'invalid-response', selectedId: null, confidence: null, margin: null, model: null };
31
+ if (!exact(res, ['schemaVersion', 'requestHash', 'catalogHash', 'model', 'scores'])
32
+ || res.schemaVersion !== 1 || res.requestHash !== req.requestHash || res.catalogHash !== req.catalogHash
33
+ || !exact(res.model, ['id', 'revision', 'domain']) || !Object.values(res.model).every(v => text(v))
34
+ || !Array.isArray(res.scores) || res.scores.length !== req.options.length
35
+ || res.scores.some((s, i) => !exact(s, ['id', 'probability']) || s.id !== req.options[i].id || !probability(s.probability))
36
+ || Math.abs(res.scores.reduce((s, o) => s + o.probability, 0) - 1) > 1e-6) return empty;
37
+ const ranked = [...res.scores].sort((a, b) => b.probability - a.probability);
38
+ const confidence = ranked[0].probability;
39
+ const margin = confidence - ranked[1].probability;
40
+ const reason = res.model.domain !== domain ? 'domain-mismatch' : margin === 0 ? 'tie'
41
+ : confidence < minConfidence ? 'low-confidence' : margin < minMargin ? 'low-margin' : 'scored';
42
+ return { status: reason === 'scored' ? 'accepted' : 'abstain', reason,
43
+ selectedId: reason === 'scored' ? ranked[0].id : null, confidence, margin, model: { ...res.model } };
44
+ }
45
+ module.exports = { createRequest, validateRequest, decide };
@@ -0,0 +1,94 @@
1
+ """Optional CPU CUA-S1 bridge. Stdout is protocol-only; never execute UI actions."""
2
+ import hashlib
3
+ import json
4
+ from pathlib import Path
5
+ import re
6
+ import sys
7
+
8
+
9
+ def verify_artifacts(manifest):
10
+ weights = Path(manifest['checkpoint'])
11
+ if not weights.is_absolute() or weights.suffix != '.safetensors':
12
+ raise ValueError('checkpoint-format')
13
+ for file, key in [(weights, 'weightsSha256'), (weights.with_suffix('.json'), 'configSha256')]:
14
+ with file.open('rb') as handle:
15
+ digest = hashlib.file_digest(handle, 'sha256').hexdigest()
16
+ if digest != manifest[key]:
17
+ raise ValueError('artifact-hash')
18
+ return weights
19
+
20
+
21
+ def check_limits(request, config):
22
+ if len(request['context'].encode('utf-8')) > config['context_tokens'] or any(
23
+ len(option['text'].encode('utf-8')) > config['option_tokens'] for option in request['options']
24
+ ):
25
+ raise ValueError('input-too-long')
26
+
27
+
28
+ def infer(request, manifest):
29
+ weights = verify_artifacts(manifest)
30
+ import torch
31
+ from cua_s1.model import ChoiceExample, load_checkpoint
32
+
33
+ torch.set_num_threads(1)
34
+ torch.use_deterministic_algorithms(True)
35
+ model, collator, config = load_checkpoint(weights, 'cpu')
36
+ check_limits(request, config)
37
+ example = ChoiceExample(context=request['context'], options=tuple(o['text'] for o in request['options']), label=0)
38
+ with torch.inference_mode():
39
+ probabilities = model(collator([example])).softmax(-1)[0].tolist()
40
+ return {
41
+ 'schemaVersion': 1, 'requestHash': request['requestHash'], 'catalogHash': request['catalogHash'],
42
+ 'model': {'id': manifest['modelId'], 'revision': manifest['revision'], 'domain': manifest['domain']},
43
+ 'scores': [{'id': option['id'], 'probability': probability} for option, probability in zip(request['options'], probabilities, strict=True)],
44
+ }
45
+
46
+
47
+ def source_revision(direct_url_text):
48
+ """Return the PEP 610 VCS commit recorded at install time, or None when unprovable."""
49
+ try:
50
+ commit = json.loads(direct_url_text)['vcs_info']['commit_id']
51
+ except Exception:
52
+ return None
53
+ return commit if isinstance(commit, str) and re.fullmatch(r'[0-9a-f]{40}', commit) else None
54
+
55
+
56
+ def provenance():
57
+ """Installed runtime/source facts only; never imports torch or loads a checkpoint."""
58
+ import importlib.metadata as metadata
59
+ import platform
60
+
61
+ cua = {'distribution': None, 'version': None, 'sourceRevision': None}
62
+ names = sorted(set(metadata.packages_distributions().get('cua_s1', [])))
63
+ if len(names) == 1:
64
+ dist = metadata.distribution(names[0])
65
+ cua = {'distribution': names[0], 'version': dist.version, 'sourceRevision': source_revision(dist.read_text('direct_url.json'))}
66
+ try:
67
+ torch = metadata.version('torch')
68
+ except metadata.PackageNotFoundError:
69
+ torch = None
70
+ return {'schemaVersion': 1, 'python': {'implementation': platform.python_implementation(), 'version': platform.python_version()},
71
+ 'cuaS1': cua, 'torch': torch}
72
+
73
+
74
+ def main():
75
+ try:
76
+ if sys.argv[1:] == ['--provenance']:
77
+ print(json.dumps(provenance(), allow_nan=False))
78
+ return 0
79
+ manifest = json.loads(sys.argv[1])
80
+ raw = sys.stdin.buffer.read(2 * 1024 * 1024 + 1)
81
+ if len(raw) > 2 * 1024 * 1024:
82
+ raise ValueError('request-limit')
83
+ request = json.loads(raw)
84
+ result = infer(request, manifest)
85
+ print(json.dumps(result, allow_nan=False))
86
+ except Exception:
87
+ # No raw prompt, selected values, artifact paths, or traceback on the wire.
88
+ print('cua-provider-unavailable', file=sys.stderr)
89
+ return 1
90
+ return 0
91
+
92
+
93
+ if __name__ == '__main__':
94
+ sys.exit(main())
@@ -0,0 +1,98 @@
1
+ 'use strict';
2
+ const { validateRequest } = require('./contract');
3
+ const { TIER_OPTIONS } = require('./router');
4
+ const exact = (obj, keys) => obj && typeof obj === 'object' && !Array.isArray(obj) && Object.keys(obj).length === keys.length && keys.every(k => Object.hasOwn(obj, k));
5
+ const nonempty = v => typeof v === 'string' && v.trim().length > 0;
6
+ const labels = ['tier1', 'tier2', 'tier3', null];
7
+ const finite = v => typeof v === 'number' && Number.isFinite(v);
8
+ const fail = () => { throw new TypeError('invalid-evaluation-input'); };
9
+ function validateCorpus(corpus) {
10
+ if (!exact(corpus, ['schemaVersion', 'cases']) || corpus.schemaVersion !== 1 || !Array.isArray(corpus.cases) || !corpus.cases.length) fail();
11
+ const ids = new Set(); const hashes = new Set(); const families = new Map();
12
+ for (const c of corpus.cases) {
13
+ if (!exact(c, ['id', 'family', 'split', 'language', 'source', 'reviewed', 'request', 'gold'])
14
+ || ![c.id, c.family, c.source].every(nonempty) || !['train', 'validation', 'holdout'].includes(c.split)
15
+ || !['en', 'zh-TW'].includes(c.language) || typeof c.reviewed !== 'boolean' || !labels.includes(c.gold)) fail();
16
+ validateRequest(c.request);
17
+ if (c.request.task !== 'tier' || JSON.stringify(c.request.options) !== JSON.stringify(TIER_OPTIONS)
18
+ || ids.has(c.id) || hashes.has(c.request.requestHash) || (families.has(c.family) && families.get(c.family) !== c.split)) fail();
19
+ ids.add(c.id); hashes.add(c.request.requestHash); families.set(c.family, c.split);
20
+ }
21
+ return true;
22
+ }
23
+ function prediction(decision) {
24
+ if (exact(decision, ['status', 'reason']) && decision.status === 'unavailable' && nonempty(decision.reason)) return null;
25
+ if (!exact(decision, ['status', 'reason', 'selectedId', 'confidence', 'margin', 'model'])
26
+ || !['accepted', 'abstain', 'invalid-output'].includes(decision.status) || !nonempty(decision.reason)
27
+ || !labels.includes(decision.selectedId) || (decision.status === 'accepted') !== (decision.selectedId !== null)) fail();
28
+ for (const key of ['confidence', 'margin']) if (decision[key] !== null && (!finite(decision[key]) || decision[key] < 0 || decision[key] > 1)) fail();
29
+ if (decision.model !== null && (!exact(decision.model, ['id', 'revision', 'domain']) || !Object.values(decision.model).every(nonempty))) fail();
30
+ if (decision.status === 'accepted' && (decision.confidence === null || decision.margin === null || decision.model?.domain !== 'harness-routing-v1')) fail();
31
+ return decision.selectedId;
32
+ }
33
+ // Scored decisions carry the full catalog-order probability vector; unavailable/invalid outputs carry null.
34
+ function checkScores(decision, scores) {
35
+ const scored = ['accepted', 'abstain'].includes(decision.status);
36
+ if (!scored) { if (scores !== null) fail(); return; }
37
+ if (!Array.isArray(scores) || scores.length !== TIER_OPTIONS.length
38
+ || scores.some(p => !finite(p) || p < 0 || p > 1) || Math.abs(scores.reduce((s, p) => s + p, 0) - 1) > 1e-6) fail();
39
+ const ranked = [...scores].sort((a, b) => b - a);
40
+ if (decision.confidence !== ranked[0] || decision.margin !== ranked[0] - ranked[1]) fail();
41
+ }
42
+ function metrics(gold, predicted) {
43
+ const count = gold.length;
44
+ const accepted = predicted.filter(x => x !== null).length;
45
+ const correct = predicted.filter((x, i) => x === gold[i]).length;
46
+ const acceptedCorrect = predicted.filter((x, i) => x !== null && x === gold[i]).length;
47
+ const macroF1 = labels.reduce((sum, label) => {
48
+ const tp = gold.filter((g, i) => g === label && predicted[i] === label).length;
49
+ const fp = gold.filter((g, i) => g !== label && predicted[i] === label).length;
50
+ const fn = gold.filter((g, i) => g === label && predicted[i] !== label).length;
51
+ return sum + (2 * tp + fp + fn ? 2 * tp / (2 * tp + fp + fn) : 0);
52
+ }, 0) / labels.length;
53
+ return { accuracy: correct / count, macroF1, coverage: accepted / count, abstentionRate: 1 - accepted / count,
54
+ acceptedPrecision: accepted ? acceptedCorrect / accepted : null,
55
+ acceptedErrorRate: accepted ? (accepted - acceptedCorrect) / accepted : null };
56
+ }
57
+ function p95(values) { return values.length ? [...values].sort((a, b) => a - b)[Math.ceil(values.length * 0.95) - 1] : null; }
58
+ // sourceEvidence is the provider provenance result; only the pinned cua_s1 revision satisfies the gate.
59
+ function evaluate(corpus, records, sourceEvidence = null) {
60
+ validateCorpus(corpus);
61
+ const cases = corpus.cases.filter(c => c.split === 'holdout');
62
+ if (!cases.length || !Array.isArray(records) || records.length !== cases.length) fail();
63
+ const byId = new Map(); const models = new Set(); const cold = []; const warm = [];
64
+ for (const record of records) {
65
+ if (!exact(record, ['id', 'baseline', 'runs']) || byId.has(record.id) || !cases.some(c => c.id === record.id)
66
+ || !labels.includes(record.baseline) || !Array.isArray(record.runs) || record.runs.length !== 2) fail();
67
+ for (const run of record.runs) {
68
+ if (!exact(run, ['decision', 'scores', 'latencyMs', 'coldStart']) || !finite(run.latencyMs) || run.latencyMs < 0 || typeof run.coldStart !== 'boolean') fail();
69
+ prediction(run.decision);
70
+ checkScores(run.decision, run.scores);
71
+ if (run.decision.model) models.add(JSON.stringify([run.decision.model.id, run.decision.model.revision, run.decision.model.domain]));
72
+ (run.coldStart ? cold : warm).push(run.latencyMs);
73
+ }
74
+ byId.set(record.id, record);
75
+ }
76
+ if (models.size > 1) fail();
77
+ const gold = cases.map(c => c.gold);
78
+ const baseline = metrics(gold, cases.map(c => byId.get(c.id).baseline));
79
+ const model = metrics(gold, cases.map(c => prediction(byId.get(c.id).runs[0].decision)));
80
+ const canonicalRun = ({ decision: d, scores }) => JSON.stringify([d.status, d.reason, d.selectedId ?? null, d.confidence ?? null, d.margin ?? null,
81
+ d.model ? [d.model.id, d.model.revision, d.model.domain] : null, scores]);
82
+ const agreement = records.filter(r => canonicalRun(r.runs[0]) === canonicalRun(r.runs[1])).length / cases.length;
83
+ const latency = { coldP95Ms: p95(cold), warmP95Ms: p95(warm), coldSamples: cold.length, warmSamples: warm.length };
84
+ const gates = {
85
+ reviewedHoldout: cases.length >= 200 && cases.every(c => c.reviewed)
86
+ && ['en', 'zh-TW'].every(lang => cases.filter(c => c.language === lang).length >= 50),
87
+ acceptedPrecision: model.acceptedPrecision !== null && model.acceptedPrecision >= 0.98,
88
+ coverage: model.coverage >= 0.8,
89
+ macroF1: model.macroF1 >= baseline.macroF1,
90
+ repeatability: agreement === 1,
91
+ warmLatency: warm.length >= cases.length && latency.warmP95Ms <= 100,
92
+ sourceProvenance: sourceEvidence?.status === 'recorded' && sourceEvidence.provenance?.cuaS1?.sourceRevisionStatus === 'pinned',
93
+ policyEvidence: false,
94
+ liveHostEvidence: false,
95
+ };
96
+ return { schemaVersion: 1, cases: cases.length, baseline, model, agreement, latency, gates, rolloutReady: Object.values(gates).every(Boolean) };
97
+ }
98
+ module.exports = { validateCorpus, evaluate };
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ // Opt-in System One installer: a dedicated venv, pinned cua_s1 source, and a pinned CPU checkpoint.
4
+ // It is never run from hooks, and it never changes the router mode; it prints the environment to set.
5
+ const fs = require('node:fs');
6
+ const os = require('node:os');
7
+ const path = require('node:path');
8
+ const { createHash } = require('node:crypto');
9
+ const { spawnSync } = require('node:child_process');
10
+ const { performance } = require('node:perf_hooks');
11
+ const { validateManifest, provenance, score, PINNED_CUA_S1_REVISION } = require('./provider');
12
+ const { createRequest, decide } = require('./contract');
13
+ const { TIER_OPTIONS } = require('./router');
14
+
15
+ const PINS = Object.freeze({
16
+ cuaS1Revision: PINNED_CUA_S1_REVISION,
17
+ cuaS1Spec: `cua-s1 @ git+https://github.com/trycua/cua@${PINNED_CUA_S1_REVISION}#subdirectory=libs/cua-s1/python`,
18
+ torchSpec: 'torch>=2.2,<3',
19
+ torchIndex: 'https://download.pytorch.org/whl/cpu',
20
+ modelId: 'cua-ai/cua-s1-forms',
21
+ modelRevision: 'f54adbf447f4ca6ec259f529ee3f2e3e09f8cc71',
22
+ domain: 'forms-v1',
23
+ // sha256/size from the Hugging Face tree API at modelRevision (LFS oid for weights; the JSON
24
+ // sidecar's git blob id d8f8426a... was re-hashed to confirm these exact CRLF bytes).
25
+ files: Object.freeze({
26
+ weights: Object.freeze({ name: 'cua-s1-forms.safetensors', size: 2828784, sha256: '05954c1caf51c2fb6c13ea4acbfc88a2e7653dea192252bb51dc89e76a356ddc' }),
27
+ config: Object.freeze({ name: 'cua-s1-forms.json', size: 1053, sha256: '62d31e2f9a001a8e9b6f8534c5194d07ebdd3f9d62ef1ac281906622992650ca' }),
28
+ }),
29
+ });
30
+ const USAGE = 'Usage: install.js [--dir <absolute dir>] [--python <3.11-3.13 executable>] [--dry-run]';
31
+
32
+ const defaultDir = () => path.join(os.homedir(), '.agents', 'harness-everything', 'system-one');
33
+ const fileUrl = name => `https://huggingface.co/${PINS.modelId}/resolve/${PINS.modelRevision}/${name}`;
34
+ const checkpointDir = dir => path.join(dir, 'checkpoints', PINS.modelRevision);
35
+ const venvPython = (dir, platform = process.platform) => (platform === 'win32'
36
+ ? path.join(dir, 'venv', 'Scripts', 'python.exe') : path.join(dir, 'venv', 'bin', 'python'));
37
+ function supportedPython(version) {
38
+ const match = typeof version === 'string' && /^3\.(\d+)\.\d+$/.exec(version);
39
+ return Boolean(match) && Number(match[1]) >= 11 && Number(match[1]) <= 13;
40
+ }
41
+ function pythonCandidates(platform = process.platform) {
42
+ return platform === 'win32'
43
+ ? [['py', '-3.13'], ['py', '-3.12'], ['py', '-3.11'], ['python'], ['python3']]
44
+ : [['python3.13'], ['python3.12'], ['python3.11'], ['python3'], ['python']];
45
+ }
46
+ function parseArgs(argv) {
47
+ const opts = { dir: defaultDir(), python: null, dryRun: false };
48
+ const seen = new Set();
49
+ for (let i = 0; i < argv.length; i++) {
50
+ const flag = argv[i];
51
+ if (seen.has(flag)) throw new Error('usage');
52
+ seen.add(flag);
53
+ if (flag === '--dry-run') opts.dryRun = true;
54
+ else if (flag === '--dir' || flag === '--python') {
55
+ const value = argv[++i];
56
+ if (!value || value.startsWith('--')) throw new Error('usage');
57
+ if (flag === '--dir' && !path.isAbsolute(value)) throw new Error('usage');
58
+ opts[flag.slice(2)] = flag === '--dir' ? path.resolve(value) : value;
59
+ } else throw new Error('usage');
60
+ }
61
+ return opts;
62
+ }
63
+ function buildManifest(dir, python) {
64
+ const manifest = { schemaVersion: 1, python, checkpoint: path.join(checkpointDir(dir), PINS.files.weights.name),
65
+ weightsSha256: PINS.files.weights.sha256, configSha256: PINS.files.config.sha256,
66
+ modelId: PINS.modelId, revision: PINS.modelRevision, domain: PINS.domain,
67
+ // Each score starts a fresh Python process that imports torch; cold start dominates latency.
68
+ timeoutMs: 10000 };
69
+ validateManifest(manifest);
70
+ return manifest;
71
+ }
72
+ const matches = (buf, spec) => buf.length === spec.size && createHash('sha256').update(buf).digest('hex') === spec.sha256;
73
+ async function httpFetch(url) {
74
+ const res = await fetch(url, { redirect: 'follow' });
75
+ if (!res.ok) throw new Error(`download-failed:${res.status}`);
76
+ return Buffer.from(await res.arrayBuffer());
77
+ }
78
+ async function ensureFile(url, dest, spec, fetcher = httpFetch) {
79
+ if (fs.existsSync(dest) && matches(fs.readFileSync(dest), spec)) return 'verified-existing';
80
+ const bytes = await fetcher(url);
81
+ if (!Buffer.isBuffer(bytes) || !matches(bytes, spec)) throw new Error(`download-verification:${spec.name}`);
82
+ const tmp = `${dest}.${process.pid}.tmp`;
83
+ fs.writeFileSync(tmp, bytes);
84
+ fs.renameSync(tmp, dest);
85
+ return 'downloaded';
86
+ }
87
+ function exec(cmd, args, capture = false) {
88
+ const result = spawnSync(cmd, args, { shell: false, windowsHide: true, encoding: 'utf8', stdio: capture ? 'pipe' : 'inherit' });
89
+ if (result.error || result.status !== 0) throw new Error(`command-failed: ${[cmd, ...args].join(' ')}`);
90
+ return capture ? result.stdout.trim() : '';
91
+ }
92
+ const VERSION_PROBE = ['-c', 'import sys; print("%d.%d.%d" % sys.version_info[:3])'];
93
+ function findPython(explicit) {
94
+ for (const [cmd, ...pre] of explicit ? [[explicit]] : pythonCandidates()) {
95
+ const result = spawnSync(cmd, [...pre, ...VERSION_PROBE], { shell: false, windowsHide: true, encoding: 'utf8' });
96
+ const version = result.status === 0 ? result.stdout.trim() : null;
97
+ if (supportedPython(version)) return { cmd, pre, version };
98
+ }
99
+ throw new Error(explicit ? 'python-unsupported: need Python 3.11-3.13' : 'python-not-found: install Python 3.11-3.13 or pass --python');
100
+ }
101
+ function plan(opts) {
102
+ const venvPy = venvPython(opts.dir);
103
+ const manifestPath = path.join(opts.dir, 'manifest.json');
104
+ return { dir: opts.dir, manifest: manifestPath,
105
+ steps: [
106
+ `create venv ${path.join(opts.dir, 'venv')} with ${opts.python || 'first Python 3.11-3.13 found'}`,
107
+ `${venvPy} -m pip install --index-url ${PINS.torchIndex} "${PINS.torchSpec}"`,
108
+ `${venvPy} -m pip install "${PINS.cuaS1Spec}"`,
109
+ ...Object.values(PINS.files).map(f => `download ${fileUrl(f.name)} (sha256 ${f.sha256})`),
110
+ `write ${manifestPath}`,
111
+ 'verify provenance (pinned revision) and one real CPU inference',
112
+ ],
113
+ env: { HARNESS_SYSTEM_ONE_MODE: 'shadow', HARNESS_SYSTEM_ONE_CONFIG: manifestPath } };
114
+ }
115
+ function verify(manifestPath) {
116
+ const source = provenance(manifestPath);
117
+ const request = createRequest('tier', 'fix a typo in README', TIER_OPTIONS);
118
+ const start = performance.now();
119
+ const result = score(request, manifestPath);
120
+ const latencyMs = Math.round(performance.now() - start);
121
+ const decision = result.status === 'scored' ? decide(request, result.response) : result;
122
+ const scores = result.status === 'scored' && decision.status !== 'invalid-output' ? result.response.scores : null;
123
+ const ok = source.status === 'recorded' && source.provenance.cuaS1.sourceRevisionStatus === 'pinned' && scores !== null;
124
+ return { ok, source, decision, scores, latencyMs };
125
+ }
126
+ async function main(argv) {
127
+ const opts = parseArgs(argv);
128
+ const p = plan(opts);
129
+ if (opts.dryRun) { process.stdout.write(`${JSON.stringify({ dryRun: true, ...p }, null, 2)}\n`); return 0; }
130
+ const base = findPython(opts.python);
131
+ const venvPy = venvPython(opts.dir);
132
+ fs.mkdirSync(checkpointDir(opts.dir), { recursive: true });
133
+ if (!fs.existsSync(venvPy)) exec(base.cmd, [...base.pre, '-m', 'venv', path.join(opts.dir, 'venv')]);
134
+ const venvVersion = exec(venvPy, VERSION_PROBE, true);
135
+ if (!supportedPython(venvVersion)) throw new Error(`python-unsupported: existing venv uses ${venvVersion}`);
136
+ exec(venvPy, ['-m', 'pip', 'install', '--disable-pip-version-check', '--index-url', PINS.torchIndex, PINS.torchSpec]);
137
+ exec(venvPy, ['-m', 'pip', 'install', '--disable-pip-version-check', PINS.cuaS1Spec]);
138
+ for (const spec of Object.values(PINS.files)) {
139
+ console.error(`${spec.name}: ${await ensureFile(fileUrl(spec.name), path.join(checkpointDir(opts.dir), spec.name), spec)}`);
140
+ }
141
+ fs.writeFileSync(p.manifest, `${JSON.stringify(buildManifest(opts.dir, venvPy), null, 2)}\n`);
142
+ const check = verify(p.manifest);
143
+ process.stdout.write(`${JSON.stringify({ dryRun: false, ...p, verification: check }, null, 2)}\n`);
144
+ return check.ok ? 0 : 1;
145
+ }
146
+ if (require.main === module) {
147
+ main(process.argv.slice(2)).then(code => { process.exitCode = code; }, err => {
148
+ if (err.message === 'usage') { console.error(USAGE); process.exitCode = 2; return; }
149
+ console.error(`System One install failed: ${err.message}`); process.exitCode = 1;
150
+ });
151
+ }
152
+ module.exports = { PINS, fileUrl, venvPython, supportedPython, pythonCandidates, parseArgs, buildManifest, ensureFile, plan, verify };