harness-everything 0.47.1 → 0.47.2

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 (88) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.github/workflows/ci.yml +12 -0
  4. package/CHANGELOG.md +9 -0
  5. package/benchmarks/issue290-pilot/README.md +199 -0
  6. package/benchmarks/issue290-pilot/analyze.py +299 -0
  7. package/benchmarks/issue290-pilot/analyze.test.py +146 -0
  8. package/benchmarks/issue290-pilot/check.py +19 -0
  9. package/benchmarks/issue290-pilot/evidence/archive.json +7 -0
  10. package/benchmarks/issue290-pilot/evidence/group-summary.json +684 -0
  11. package/benchmarks/issue290-pilot/evidence/inventory.json +3728 -0
  12. package/benchmarks/issue290-pilot/evidence/ledger.json +4644 -0
  13. package/benchmarks/issue290-pilot/evidence/replay/pairs.json +482 -0
  14. package/benchmarks/issue290-pilot/evidence/replay/provenance.json +24 -0
  15. package/benchmarks/issue290-pilot/evidence/replay/tables.md +37 -0
  16. package/benchmarks/issue290-pilot/evidence.tar.gz +0 -0
  17. package/benchmarks/issue290-pilot/export.py +110 -0
  18. package/benchmarks/issue290-pilot/export.test.py +65 -0
  19. package/benchmarks/issue290-pilot/fable-supplement.py +55 -0
  20. package/benchmarks/issue290-pilot/fixture.test.py +28 -0
  21. package/benchmarks/issue290-pilot/fixtures/polyglot/instructions.md +19 -0
  22. package/benchmarks/issue290-pilot/fixtures/polyglot/package.json +29 -0
  23. package/benchmarks/issue290-pilot/fixtures/polyglot/simple-linked-list.js +44 -0
  24. package/benchmarks/issue290-pilot/fixtures/polyglot/simple-linked-list.spec.js +131 -0
  25. package/benchmarks/issue290-pilot/fixtures/quixbugs/LICENSE +7 -0
  26. package/benchmarks/issue290-pilot/fixtures/quixbugs/cases.json +7 -0
  27. package/benchmarks/issue290-pilot/fixtures/quixbugs/find_in_sorted.py +31 -0
  28. package/benchmarks/issue290-pilot/fixtures/quixbugs/test_find_in_sorted.py +15 -0
  29. package/benchmarks/issue290-pilot/frozen-documents.json +41 -0
  30. package/benchmarks/issue290-pilot/grader.cjs +43 -0
  31. package/benchmarks/issue290-pilot/grader.test.cjs +10 -0
  32. package/benchmarks/issue290-pilot/hook.test.cjs +27 -0
  33. package/benchmarks/issue290-pilot/host-hook.cjs +35 -0
  34. package/benchmarks/issue290-pilot/metrics.test.py +131 -0
  35. package/benchmarks/issue290-pilot/preflight/amendment.md +32 -0
  36. package/benchmarks/issue290-pilot/preflight/environment.json +15 -0
  37. package/benchmarks/issue290-pilot/preflight/fable-amendment.md +20 -0
  38. package/benchmarks/issue290-pilot/preflight/fable-frozen-files.json +4 -0
  39. package/benchmarks/issue290-pilot/preflight/fable-infrastructure-amendment.md +27 -0
  40. package/benchmarks/issue290-pilot/preflight/fable-retry-frozen-files.json +4 -0
  41. package/benchmarks/issue290-pilot/preflight/fable-supplement-v1.py +47 -0
  42. package/benchmarks/issue290-pilot/preflight/frozen-files.json +18 -0
  43. package/benchmarks/issue290-pilot/preflight/graders.json +67 -0
  44. package/benchmarks/issue290-pilot/pricing-assumptions.json +29 -0
  45. package/benchmarks/issue290-pilot/protocol.json +32 -0
  46. package/benchmarks/issue290-pilot/read_metrics.py +166 -0
  47. package/benchmarks/issue290-pilot/replay.py +167 -0
  48. package/benchmarks/issue290-pilot/reporting.py +82 -0
  49. package/benchmarks/issue290-pilot/run.py +262 -0
  50. package/benchmarks/issue290-pilot/sources.json +10 -0
  51. package/benchmarks/issue290-pilot/verification/analyzer-tests.log +5 -0
  52. package/benchmarks/issue290-pilot/verification/final-gates.json +58 -0
  53. package/benchmarks/issue290-pilot/verification/fixture-tests.log +5 -0
  54. package/benchmarks/issue290-pilot/verification/gates.json +58 -0
  55. package/benchmarks/issue290-pilot/verification/npm-audit.json +84 -0
  56. package/benchmarks/issue290-pilot/verification/offline-correction.json +59 -0
  57. package/benchmarks/issue290-pilot/verification/post-report/helper-tests.log +22 -0
  58. package/benchmarks/issue290-pilot/verification/post-report/test-consistency.log +626 -0
  59. package/benchmarks/issue290-pilot/verification/post-report/test-references.log +6 -0
  60. package/benchmarks/issue290-pilot/verification/post-report/waza-tokens.log +710 -0
  61. package/benchmarks/issue290-pilot/verification/test-collision.log +28 -0
  62. package/benchmarks/issue290-pilot/verification/test-consistency.log +28 -0
  63. package/benchmarks/issue290-pilot/verification/test-docs-capabilities.log +131 -0
  64. package/benchmarks/issue290-pilot/verification/test-mechanism.log +1829 -0
  65. package/benchmarks/issue290-pilot/verification/test-mutations.log +16 -0
  66. package/benchmarks/issue290-pilot/verification/test-platform-compatibility.log +9 -0
  67. package/benchmarks/issue290-pilot/verification/test-plugin-openai.log +6 -0
  68. package/benchmarks/issue290-pilot/verification/test-plugin-submission.log +5 -0
  69. package/benchmarks/issue290-pilot/verification/test-references.log +6 -0
  70. package/benchmarks/issue290-pilot/verification/test-release.log +59 -0
  71. package/benchmarks/issue290-pilot/verification/test-repo-contract.log +5 -0
  72. package/benchmarks/issue290-pilot/verification/test-routing-invariants.log +785 -0
  73. package/benchmarks/issue290-pilot/verification/test-routing-skills.log +28 -0
  74. package/benchmarks/issue290-pilot/verification/test.log +3373 -0
  75. package/benchmarks/issue290-pilot/verification/verification-report.md +76 -0
  76. package/benchmarks/issue290-pilot/verification/waza-tokens.log +710 -0
  77. package/benchmarks/issue290-pilot/verification/with-dependencies/gates.json +26 -0
  78. package/benchmarks/issue290-pilot/verification/with-dependencies/test-collision.log +8 -0
  79. package/benchmarks/issue290-pilot/verification/with-dependencies/test-consistency.log +626 -0
  80. package/benchmarks/issue290-pilot/verification/with-dependencies/test-mechanism.log +1693 -0
  81. package/benchmarks/issue290-pilot/verification/with-dependencies/test-release.log +38 -0
  82. package/benchmarks/issue290-pilot/verification/with-dependencies/test-routing-skills.log +44 -0
  83. package/benchmarks/issue290-pilot/verification/with-dependencies/test.log +3253 -0
  84. package/opencode-plugin/plugin.json +1 -1
  85. package/package.json +1 -1
  86. package/plugins/harness-everything/.codex-plugin/plugin.json +1 -1
  87. package/plugins/harness-everything/plugin.json +1 -1
  88. package/sbom.cdx.json +7 -7
@@ -0,0 +1,35 @@
1
+ 'use strict';
2
+
3
+ // Experiment-only host adapter. Calls the unchanged canonical router through
4
+ // UserPromptSubmit; all other event handling is read-only observation.
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const { spawnSync } = require('child_process');
8
+ let raw = '';
9
+ process.stdin.setEncoding('utf8');
10
+ process.stdin.on('data', chunk => { raw += chunk; });
11
+ process.stdin.on('end', () => {
12
+ const payload = JSON.parse(raw);
13
+ const config = JSON.parse(fs.readFileSync(path.join(process.cwd(), '.pilot.json'), 'utf8'));
14
+ const event = payload.hook_event_name || process.argv[2];
15
+ const record = {
16
+ event, session: payload.session_id, tool: payload.tool_name,
17
+ input: payload.tool_input, time: new Date().toISOString(),
18
+ };
19
+ fs.appendFileSync(config.trace, JSON.stringify(record) + '\n');
20
+ if (event !== 'UserPromptSubmit') return;
21
+ const result = spawnSync(process.execPath, [path.join(config.source, 'harness-everything/scripts/kernel-router.js')], {
22
+ input: raw, encoding: 'utf8', cwd: process.cwd(), env: process.env,
23
+ });
24
+ fs.appendFileSync(config.routerTrace, result.stdout || '');
25
+ if (result.stderr) fs.appendFileSync(config.routerTrace, result.stderr);
26
+ let context = result.stdout || '';
27
+ context += '\nEXPERIMENT REFERENCE TIMING: All files in .harness are identical in both arms. Preserve selected workflow, checks, permissions, bindings, status and labels.\n';
28
+ if (config.arm === 'A') {
29
+ context += 'For this controlled timing ablation only, read every listed reference now, including later-step material. Apply a contract only when its step is applicable. This experiment instruction overrides only the active-step read-timing restriction.\n';
30
+ context += config.documents.map(p => path.join(process.cwd(), '.harness', p)).join('\n');
31
+ } else {
32
+ context += 'Read only the references needed by the current active step; defer later-step documents until applicable. Resolve the required bindings before passing their steps.\n';
33
+ }
34
+ console.log(JSON.stringify({hookSpecificOutput: {hookEventName: 'UserPromptSubmit', additionalContext: context}}));
35
+ });
@@ -0,0 +1,131 @@
1
+ import importlib.util
2
+ import json
3
+ from pathlib import Path
4
+ import subprocess
5
+ import tempfile
6
+ import unittest
7
+ from unittest.mock import patch
8
+
9
+ import analyze
10
+ from read_metrics import collect_reads, observed_read
11
+ from reporting import paired_rows, summarize_groups
12
+
13
+
14
+ class ReadMetricTest(unittest.TestCase):
15
+ def setUp(self):
16
+ self.path = 'find-skills/SKILL.md'
17
+ self.content = '# A sufficiently distinctive reference title\nA second sufficiently distinctive line of reference text.\n'
18
+ self.documents = {self.path: self.content}
19
+
20
+ def test_compound_both_orders_separate_mixed_output(self):
21
+ for command in ('cat .harness/find-skills/SKILL.md && ls', 'ls && cat .harness/find-skills/SKILL.md'):
22
+ with self.subTest(command=command):
23
+ row = observed_read(command, self.content+'inventory\n', self.documents)
24
+ self.assertEqual(row['returned_bytes'], len(self.content.encode()))
25
+ self.assertEqual(row['uncertain_or_mixed_output_bytes'], len('inventory\n'))
26
+ self.assertEqual(row['filesystem_access_candidates'], 1)
27
+
28
+ def test_transformed_output_is_not_content(self):
29
+ row = observed_read('cat .harness/find-skills/SKILL.md | wc -l', '2\n', self.documents)
30
+ self.assertEqual(row['returned_bytes'], 0)
31
+ self.assertEqual(row['uncertain_or_mixed_output_bytes'], 2)
32
+
33
+ def test_partial_content_counts_only_matched_lines(self):
34
+ partial = self.content.splitlines(keepends=True)[0]
35
+ row = observed_read("sed -n '1p' .harness/find-skills/SKILL.md", partial, self.documents)
36
+ self.assertEqual(row['returned_bytes'], len(partial.encode()))
37
+ self.assertEqual(row['matched_content'][0]['kind'], 'partial-content')
38
+
39
+ def test_powershell_paths_and_alias(self):
40
+ for command in (r'Get-Content .harness\find-skills\SKILL.md', r'gc -Raw .harness\find-skills\SKILL.md'):
41
+ self.assertEqual(observed_read(command, self.content, self.documents)['returned_bytes'], len(self.content.encode()))
42
+
43
+ def test_frozen_source_placeholder_and_wrapped_shell(self):
44
+ for command in ('cat <HARNESS_SOURCE>/find-skills/SKILL.md', '/bin/bash -lc "cat .harness/find-skills/SKILL.md && ls"'):
45
+ self.assertEqual(observed_read(command, self.content, self.documents)['returned_bytes'], len(self.content.encode()))
46
+
47
+ def test_bundle_excludes_arbitrary_repository_files_and_mentions(self):
48
+ for command in ('cat <HARNESS_SOURCE>/grader.cjs', 'cat .harness/unknown/SKILL.md', 'echo .harness/find-skills/SKILL.md', 'rg --files .harness/find-skills/SKILL.md'):
49
+ self.assertIsNone(observed_read(command, self.content, self.documents))
50
+
51
+ def test_native_read_cannot_identify_unknown_content_as_bytes(self):
52
+ row = observed_read('', 'unmatched output', self.documents, native_path='.harness/'+self.path)
53
+ self.assertEqual(row['returned_bytes'], 0)
54
+ self.assertEqual(row['uncertain_or_mixed_output_bytes'], 16)
55
+
56
+
57
+ class AccountingTest(unittest.TestCase):
58
+ def episode(self, root, engine='claude', workload='profile-lookup', events=None):
59
+ row = {'model': {'engine': engine, 'model': 'fixture'}, 'workload': workload,
60
+ 'grader': {'pass': False}, 'usage': None, 'router_attributed': True}
61
+ (root/'analysis.json').write_text(json.dumps(row))
62
+ (root/'manifest.json').write_text('{}')
63
+ (root/'transcript.jsonl').write_text('\n'.join(json.dumps(e) for e in (events or [])))
64
+
65
+ def test_offline_never_reads_host_home_or_invents_cost(self):
66
+ with tempfile.TemporaryDirectory() as directory:
67
+ root = Path(directory)
68
+ self.episode(root)
69
+ with patch.object(Path, 'home', side_effect=AssertionError('host home accessed')):
70
+ row = analyze.inspect_episode(root, offline=True, documents={})
71
+ self.assertIsNone(row['api_equivalent_cost_usd'])
72
+ self.assertIn('unknown', row['child_usage_observability'])
73
+
74
+ def test_missing_claude_child_logs_make_whole_cost_unknown(self):
75
+ with tempfile.TemporaryDirectory() as directory:
76
+ root = Path(directory)
77
+ self.episode(root, events=[{'type':'assistant','message':{'content':[{'type':'tool_use','name':'Task','id':'worker'}]}},
78
+ {'tool_use_result':{'agentId':'missing'}}])
79
+ with patch.object(Path, 'home', return_value=root):
80
+ row = analyze.inspect_episode(root, documents={})
81
+ self.assertIsNone(row['api_equivalent_cost_usd'])
82
+ self.assertIn('unknown', row['child_usage_observability'])
83
+
84
+ def test_polyglot_grader_timeout_is_retained_failure(self):
85
+ with tempfile.TemporaryDirectory() as directory:
86
+ root = Path(directory)
87
+ self.episode(root, workload='polyglot-simple-linked-list-staged')
88
+ with patch('analyze.subprocess.run', side_effect=subprocess.TimeoutExpired('node', 20)):
89
+ row = analyze.inspect_episode(root, offline=True, documents={})
90
+ self.assertEqual(row['independent_grader'], {'pass':False, 'timeout':True})
91
+
92
+ def test_filesystem_enumeration_order_does_not_change_binding_attribution(self):
93
+ with tempfile.TemporaryDirectory() as directory:
94
+ root = Path(directory)
95
+ content = 'A sufficiently distinctive reference content line.\n'
96
+ self.episode(root, events=[{'type':'item.completed', 'item':{
97
+ 'type':'command_execution', 'command':'cat .harness/find-skills/SKILL.md',
98
+ 'aggregated_output':content, 'exit_code':0}}])
99
+ state = root/'state'
100
+ state.mkdir()
101
+ for name in ('z', 'a'):
102
+ (state/(name+'.json')).write_text(json.dumps({'schemaVersion':2, 'stageId':name,
103
+ 'runId':'fixture', 'requiredBindings':[{'id':'read', 'path':'find-skills/SKILL.md'}]}))
104
+ documents = {'find-skills/SKILL.md':content}
105
+ first = analyze.inspect_episode(root, offline=True, documents=documents)
106
+ original = Path.rglob
107
+ def reverse_listing(path, pattern):
108
+ return iter(reversed(list(original(path, pattern))))
109
+ with patch.object(Path, 'rglob', reverse_listing):
110
+ second = analyze.inspect_episode(root, offline=True, documents=documents)
111
+ self.assertEqual(first['observed_reference_reads'], second['observed_reference_reads'])
112
+
113
+ def test_null_costs_and_metric_specific_denominators(self):
114
+ base = {'series':'test', 'model':{'engine':'codex'}, 'workload':'test', 'arm':'A', 'repeat':1,
115
+ 'preflight':False, 'classification':'definitive', 'independent_grader':{'pass':True},
116
+ 'budget_failure':False, 'reference_returned_bytes':3, 'exact_reference_bytes_lower_bound':3,
117
+ 'wall_seconds':1, 'api_equivalent_cost_usd':1, 'api_equivalent_input_cost_usd':1}
118
+ failure = {**base, 'arm':'B', 'classification':'definitive-agent-budget-failure', 'budget_failure':True,
119
+ 'api_equivalent_cost_usd':None, 'api_equivalent_input_cost_usd':None}
120
+ infrastructure = {**base, 'classification':'inconclusive', 'repeat':2}
121
+ groups = summarize_groups([base, failure, infrastructure])
122
+ self.assertEqual(groups[0]['n_quality_included'], 1)
123
+ self.assertEqual(groups[0]['n_quality_excluded'], 1)
124
+ self.assertEqual(groups[1]['artifact_passes'], 0)
125
+ self.assertEqual(groups[1]['budget_failures'], 1)
126
+ self.assertIsNone(groups[1]['api_equivalent_cost_usd'])
127
+ self.assertFalse(paired_rows([base, failure])[0]['api_equivalent_cost_usd']['included'])
128
+
129
+
130
+ if __name__ == '__main__':
131
+ unittest.main()
@@ -0,0 +1,32 @@
1
+ # Preflight amendment — 2026-10-14
2
+
3
+ Before formal A/B calls, the initial two host probes established real
4
+ UserPromptSubmit/router attribution and model access. The Haiku probe exhausted
5
+ the runner's three-turn smoke cap after opening the correct lookup references,
6
+ before producing its final answer. This was a preflight configuration failure,
7
+ not a product failure or a formal A/B observation. Both original probes are
8
+ retained; the corrected preflight repeats both models with the same 35-turn cap
9
+ as the formal runner. No formal trial outcome has been observed yet.
10
+
11
+ The frozen fixture adaptation runs all 23 Polyglot assertions using the
12
+ explicit matcher adapter in grader.cjs, avoiding unrelated npm setup work. An
13
+ independently authored reference passes all 23; the untouched skeleton fails.
14
+ QuixBugs uses all seven pinned upstream JSON cases with Python's built-in
15
+ assertions, avoiding a pytest installation; its upstream reference passes and
16
+ the original fails with RecursionError. This is an adapted subset, not an
17
+ official leaderboard score. Gold implementations are outside agent fixtures.
18
+
19
+ The staged prompt adds three ordered, dependent implementation stages to the
20
+ public linked-list instruction. Profile lookup is a synthetic Harness contract
21
+ probe. Only the small repair directly uses an unmodified public repair task.
22
+ The experiment tests eager *required reads*, not merely file availability;
23
+ eager treatment may not reproduce organic behavior of any historical release.
24
+ The exact per-family document bundles and prompts are fixed in run.py.
25
+
26
+ Codex uses reviewed explicit native hooks with its documented automation hook
27
+ trust option; Claude uses project-scoped settings. Neither comparison claims
28
+ full-plugin parity. Normal native UserPromptSubmit invokes the unchanged
29
+ canonical router in both hosts. Subscription auth is reused without reading or
30
+ copying credential material. Workflow state is isolated per fixture.
31
+
32
+ Lookup completion checks both the six exact selection fields and JSON-only output after removing the mandatory hidden turn label (an enclosing JSON fence is accepted). Prose outside JSON fails. This rubric is frozen before formal trials; preflight showed why field extraction alone was insufficient.
@@ -0,0 +1,15 @@
1
+ {
2
+ "os": "macOS-26.6.2-arm64-arm-64bit-Mach-O",
3
+ "python": "3.14.4",
4
+ "architecture": "arm64",
5
+ "macos": "26.6.2",
6
+ "cpu": "Apple M4",
7
+ "ram_bytes": "17179869184",
8
+ "logical_cpus": "10",
9
+ "codex": "codex-cli 0.162.1",
10
+ "claude": "2.1.299 (Claude Code)",
11
+ "inspection_shell_node": "v25.9.0",
12
+ "agent_node_versions_observed": [
13
+ "v24.14.1"
14
+ ]
15
+ }
@@ -0,0 +1,20 @@
1
+ # Fable family correction — preregistered 2026-10-14 before staged trials
2
+
3
+ The deterministic current router selects iterative-single for the original
4
+ three-stage single-module linked-list prompt. This is a bounded staged task,
5
+ not a demonstrated Fable execution, and is not classified as a router bug.
6
+ All eight planned bounded-stage rows remain retained and reported separately.
7
+ Their outcomes have not been observed when this correction is registered.
8
+
9
+ The genuine Fable supplement prefixes the identical original prompt with
10
+ `Use Fable staged execution.` Current tier-router selects tier3/fable-staged for
11
+ that prompt. This deliberately requests the topology whose obligations #290
12
+ must preserve; it is not a neutral whole-Harness effectiveness benchmark.
13
+
14
+ Eight additional episodes: same two models, two repeats, AB then BA. The
15
+ supplement creates a linked Git worktree before each agent starts, satisfying
16
+ the existing Fable isolation obligation symmetrically. Grading targets that
17
+ linked worktree. The original aggregate 7,200 agent wall-second / 500,000
18
+ output-token limits are shared across the original and supplemental series;
19
+ no higher budget or outcome-selected rerun is authorized by this amendment.
20
+ Other A/B intervention, documents, API contract, tests and rubric are unchanged.
@@ -0,0 +1,4 @@
1
+ {
2
+ "fable-supplement.py": "bdba9df11ad45c03abdee895f017ed01474a3f7caa727982e8ac02f2a395f73b",
3
+ "preflight/fable-amendment.md": "d1a752cd5e4385c888eab89df27233ab7c86862f420a12c94bc1023cc9b5f978"
4
+ }
@@ -0,0 +1,27 @@
1
+ # Linked-fixture infrastructure diagnosis — 2026-10-14
2
+
3
+ The first four Claude Fable launches exited before model execution with
4
+ `Settings file not found: .../hook-settings.json`. None emitted UserPromptSubmit,
5
+ model usage, or router attribution. They are infrastructure/inconclusive rows,
6
+ not four model failures. All are retained without selective removal.
7
+
8
+ Read-only root-cause reconstruction: run.py prepares and commits fixture files,
9
+ then writes hook-settings.json. A new linked Git worktree receives only the
10
+ committed snapshot. Codex passes its hooks inline, but Claude requires the
11
+ missing settings file. The original linked-fixture preflight checked Git linkage
12
+ and source presence without asserting this host-specific startup prerequisite.
13
+ The unattended supplement also failed to stop on absent router attribution.
14
+
15
+ After these repeated same-signature setup failures, stop edits, reconstruct the
16
+ full setup path, and record this diagnosis before recovery. Add a failing
17
+ fixture prerequisite test, copy the identical settings into the linked checkout,
18
+ assert all required launch files exist, and stop immediately on absent initial
19
+ router attribution. The original script/hash is preserved as v1.
20
+
21
+ One symmetric infrastructure retry for the two Claude pairs is registered
22
+ before any retry model call: AB then BA, identical prompt/model/effort/documents,
23
+ tests, budgets and canonical Harness revision. The four original startup errors
24
+ remain outside the behavioral denominator. No Luna outcome is rerun, and no
25
+ valid agent failure is excluded. The same original 7,200 agent wall-second and
26
+ 500,000 output-token budgets include original + retry attempts. No higher limit
27
+ or additional outcome-selected repeat is introduced.
@@ -0,0 +1,4 @@
1
+ {
2
+ "fable-supplement.py": "f8a77fd584eb555eff56681307be95ea5df53d4ad6bc0f3a7eabd0844b033982",
3
+ "preflight/fable-infrastructure-amendment.md": "cea92a4a6277b4992dc0299b12bc2b3005fcc580e26ce9a13783832806a5c999"
4
+ }
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env python3
2
+ """Preregistered Fable-only supplement; original bounded-stage rows stay retained."""
3
+ import importlib.util
4
+ import json
5
+ from pathlib import Path
6
+ import subprocess
7
+ import tempfile
8
+ import time
9
+
10
+ HERE=Path(__file__).resolve().parent
11
+ spec=importlib.util.spec_from_file_location('pilot',HERE/'run.py')
12
+ pilot=importlib.util.module_from_spec(spec)
13
+ spec.loader.exec_module(pilot)
14
+ original_prepare=pilot.prepare
15
+ WORKLOAD='polyglot-simple-linked-list-staged'
16
+ PROMPT="Use Fable staged execution. "+pilot.PROMPTS[WORKLOAD]
17
+
18
+ def linked_prepare(*args, **kwargs):
19
+ episode,primary,hooks=original_prepare(*args,**kwargs)
20
+ linked=Path(tempfile.mkdtemp(prefix='harness290-fable-'))
21
+ subprocess.run(['git','worktree','add','-q','-b','pilot-linked',str(linked)],cwd=primary,check=True)
22
+ return episode,linked,hooks
23
+
24
+ if __name__=='__main__':
25
+ import argparse
26
+ parser=argparse.ArgumentParser();parser.add_argument('--output',required=True)
27
+ args=parser.parse_args();base=Path(args.output).resolve();base.mkdir(parents=True,exist_ok=True)
28
+ pilot.prepare=linked_prepare
29
+ pilot.PROMPTS[WORKLOAD]=PROMPT
30
+ start=time.monotonic()
31
+ for model in pilot.PROTOCOL['models']:
32
+ for repeat in [1,2]:
33
+ for arm in (['A','B'] if repeat==1 else ['B','A']):
34
+ existing_seconds=0;existing_output=0
35
+ for root in [Path('/tmp/issue290-formal-20261014'),base]:
36
+ for file in root.glob('*/result.json'):
37
+ existing_seconds+=json.loads(file.read_text())['wall_seconds']
38
+ for file in root.glob('*/transcript.jsonl'):
39
+ for line in file.read_text().splitlines():
40
+ try:e=json.loads(line)
41
+ except json.JSONDecodeError:continue
42
+ if e.get('type') in ['result','turn.completed']:
43
+ existing_output+=e.get('usage',{}).get('output_tokens',0)
44
+ if existing_seconds>pilot.PROTOCOL['aggregate_wall_budget_seconds'] or existing_output>pilot.PROTOCOL['aggregate_output_token_cap']:
45
+ raise SystemExit('shared original budget reached; remaining Fable rows unattempted')
46
+ pilot.run_episode(base,model,WORKLOAD,arm,repeat)
47
+ pilot.summarize(base)
@@ -0,0 +1,18 @@
1
+ {
2
+ "sources.json": "453260eac66351761d91603c4d6653470d81eb3002097dc672bb5919837b6bb2",
3
+ "run.py": "5b7b80ab9ed9177cff3fc5b8bd707e52d9ad3aac39dcd8f47726b8c2ae727389",
4
+ "grader.cjs": "e14dfba2b13d4027279c8ac3e8735f08dba9657791941eb432c1d4d8a2c773fe",
5
+ "protocol.json": "ad0c893f71a4c6ff73ae6cc723e3bf7bfd91e678b10cac43f9a538b6c4528b32",
6
+ "host-hook.cjs": "30d1775088aebc10bbe09eb60f01d5af0b9cf2eb574a81cf54ca8d1604ad3021",
7
+ "hook.test.cjs": "36e5e30b7b139177a9732af5bb3f20a25d0836281695b550c4da7d3e52a202a8",
8
+ "preflight/graders.json": "33e9c64af560d1a04db7f8e44d53b00fec7fe463f04cbf19d09c9f262fed4be0",
9
+ "preflight/amendment.md": "5340c74ff3a462ff7885ee23d5253d29c32629fe4570a6081e1faf6d91e1413c",
10
+ "fixtures/polyglot/simple-linked-list.js": "f305a2ba4fea7f8dd036989bd635f2466bd36c75d25bec049145a683dd22b8f1",
11
+ "fixtures/polyglot/simple-linked-list.spec.js": "7a181633077ca3586a47961a00858f1071b90d12cca9f114284707fb82d30255",
12
+ "fixtures/polyglot/package.json": "14a0a23e784a338496939c2f1a8719661c1b2eb36c17f4c7d6d146f2fa33519e",
13
+ "fixtures/polyglot/instructions.md": "ddf0b0d7a6d0a7b39a70a8dac0ae2e5cc4b7d9ad4163f4a103988bb53abeb914",
14
+ "fixtures/quixbugs/LICENSE": "3bb03003929be645f6557a66fcb9820f527df7ce2b51b491405d233cb191d517",
15
+ "fixtures/quixbugs/test_find_in_sorted.py": "a943c5c1df1e87360308b23341a651da9cfb31b1f1e2954cdca75c2cf4b6ba54",
16
+ "fixtures/quixbugs/cases.json": "21e0348affa246a85a6907f1d0f8b0b76454bf3c2c133ed1bff808a97ee82dfe",
17
+ "fixtures/quixbugs/find_in_sorted.py": "b640b4bcb1b2c0f7875de8f13df191f4e61ddf7e6fbdcfc42d477ec60885d3c7"
18
+ }
@@ -0,0 +1,67 @@
1
+ [
2
+ {
3
+ "name": "polyglot-untouched",
4
+ "result": {
5
+ "argv": [
6
+ "node",
7
+ "<HARNESS_SOURCE>/benchmarks/issue290-pilot/grader.cjs",
8
+ "<TMP>/issue290-grader-ae68mbog/simple-linked-list.js"
9
+ ],
10
+ "exit": 1,
11
+ "stdout": "{\"pass\":false,\"tests\":23,\"results\":[{\"name\":\"has constructor\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"value reflects constructor arg\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"has null for next by default\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"has constructor\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"new lists should have length 0\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"can add a element\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"adding a element increments length\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"adding two elements increments twice\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"new Lists have a null head element\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"adding an Element to an empty list sets the head Element\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"adding a second Element updates the head Element\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"can get the next Element from the head\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"can be initialized with an array\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"with correct length\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"with correct head value\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"can traverse the list\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"can convert to an array\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"head of list is final element from input array\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"can convert longer list to an array\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"can be reversed\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"can be reversed when it has more elements\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"can reverse with many elements\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"},{\"name\":\"can reverse a reversal\",\"pass\":false,\"error\":\"Remove this statement and implement this function\"}]}\n",
12
+ "stderr": ""
13
+ }
14
+ },
15
+ {
16
+ "name": "polyglot-independent-reference",
17
+ "result": {
18
+ "argv": [
19
+ "node",
20
+ "<HARNESS_SOURCE>/benchmarks/issue290-pilot/grader.cjs",
21
+ "<TMP>/issue290-grader-ae68mbog/simple-linked-list.js"
22
+ ],
23
+ "exit": 0,
24
+ "stdout": "{\"pass\":true,\"tests\":23,\"results\":[{\"name\":\"has constructor\",\"pass\":true},{\"name\":\"value reflects constructor arg\",\"pass\":true},{\"name\":\"has null for next by default\",\"pass\":true},{\"name\":\"has constructor\",\"pass\":true},{\"name\":\"new lists should have length 0\",\"pass\":true},{\"name\":\"can add a element\",\"pass\":true},{\"name\":\"adding a element increments length\",\"pass\":true},{\"name\":\"adding two elements increments twice\",\"pass\":true},{\"name\":\"new Lists have a null head element\",\"pass\":true},{\"name\":\"adding an Element to an empty list sets the head Element\",\"pass\":true},{\"name\":\"adding a second Element updates the head Element\",\"pass\":true},{\"name\":\"can get the next Element from the head\",\"pass\":true},{\"name\":\"can be initialized with an array\",\"pass\":true},{\"name\":\"with correct length\",\"pass\":true},{\"name\":\"with correct head value\",\"pass\":true},{\"name\":\"can traverse the list\",\"pass\":true},{\"name\":\"can convert to an array\",\"pass\":true},{\"name\":\"head of list is final element from input array\",\"pass\":true},{\"name\":\"can convert longer list to an array\",\"pass\":true},{\"name\":\"can be reversed\",\"pass\":true},{\"name\":\"can be reversed when it has more elements\",\"pass\":true},{\"name\":\"can reverse with many elements\",\"pass\":true},{\"name\":\"can reverse a reversal\",\"pass\":true}]}\n",
25
+ "stderr": ""
26
+ }
27
+ },
28
+ {
29
+ "name": "quixbugs-untouched",
30
+ "result": {
31
+ "argv": [
32
+ "python3",
33
+ "check.py"
34
+ ],
35
+ "exit": 1,
36
+ "stdout": "",
37
+ "stderr": "Traceback (most recent call last):\n File \"<TMP>/issue290-grader-ae68mbog/check.py\", line 6, in <module>\n assert find_in_sorted(*args) == expected, (args,expected)\n ~~~~~~~~~~~~~~^^^^^^^\n File \"<TMP>/issue290-grader-ae68mbog/find_in_sorted.py\", line 13, in find_in_sorted\n return binsearch(0, len(arr))\n File \"<TMP>/issue290-grader-ae68mbog/find_in_sorted.py\", line 9, in binsearch\n return binsearch(mid, end)\n File \"<TMP>/issue290-grader-ae68mbog/find_in_sorted.py\", line 7, in binsearch\n return binsearch(start, mid)\n File \"<TMP>/issue290-grader-ae68mbog/find_in_sorted.py\", line 7, in binsearch\n return binsearch(start, mid)\n File \"<TMP>/issue290-grader-ae68mbog/find_in_sorted.py\", line 9, in binsearch\n return binsearch(mid, end)\n File \"<TMP>/issue290-grader-ae68mbog/find_in_sorted.py\", line 9, in binsearch\n return binsearch(mid, end)\n File \"<TMP>/issue290-grader-ae68mbog/find_in_sorted.py\", line 9, in binsearch\n return binsearch(mid, end)\n [Previous line repeated 992 more times]\nRecursionError: maximum recursion depth exceeded\n"
38
+ }
39
+ },
40
+ {
41
+ "name": "quixbugs-upstream-reference",
42
+ "source": "https://raw.githubusercontent.com/jkoppel/QuixBugs/4257f44b0ff1181dedaedee6a447e133219fcebf/correct_python_programs/find_in_sorted.py",
43
+ "sha256": "cce13769543e2972d66ea61c9d1f1751836c719abf336be8f50f2702d19477ea",
44
+ "result": {
45
+ "argv": [
46
+ "python3",
47
+ "check.py"
48
+ ],
49
+ "exit": 0,
50
+ "stdout": "PASS: all 7 pinned upstream cases\n",
51
+ "stderr": ""
52
+ }
53
+ },
54
+ {
55
+ "name": "normal-node-require",
56
+ "result": {
57
+ "argv": [
58
+ "node",
59
+ "-e",
60
+ "require(\"node:fs\");console.log(\"PASS require\")"
61
+ ],
62
+ "exit": 0,
63
+ "stdout": "PASS require\n",
64
+ "stderr": ""
65
+ }
66
+ }
67
+ ]
@@ -0,0 +1,29 @@
1
+ {
2
+ "status": "frozen historical pilot assumptions, not a verified provider price capture",
3
+ "recorded_date": "2026-10-14",
4
+ "currency": "USD per million tokens",
5
+ "codex": {
6
+ "model": "gpt-6-luna",
7
+ "input": 0.10,
8
+ "cache_read": 0.01,
9
+ "cache_write": 0.125,
10
+ "output": 0.50,
11
+ "large_context_above": 272000,
12
+ "large_context_input_multiplier": 2,
13
+ "large_context_output_multiplier": 1.5,
14
+ "reported_source": "https://developers.openai.com/api/docs/models/gpt-6-luna"
15
+ },
16
+ "claude": {
17
+ "model": "claude-haiku-5-5",
18
+ "input": 0.10,
19
+ "cache_read": 0.01,
20
+ "cache_write_5m": 0.125,
21
+ "cache_write_1h": 0.20,
22
+ "output": 0.50,
23
+ "large_context_above": 100000,
24
+ "large_context_multiplier": 5,
25
+ "reported_source": "https://platform.claude.com/docs/en/about-claude/pricing",
26
+ "multiplier_provenance": "Present in the original analyzer; no immutable provider page capture was retained. Assumption only."
27
+ },
28
+ "limitation": "Replays reproduce these historical assumptions; they do not validate actual charges or current/provider pricing."
29
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "schema_version": 1,
3
+ "registered_date": "2026-10-14",
4
+ "status": "preregistered-before-model-calls",
5
+ "source_revision": "ac519fa204ec90feb5067bc2525381b8820d045e",
6
+ "question": "Does active-step reference disclosure reduce observed reference reads and execution overhead without losing required workflow behavior?",
7
+ "models": [
8
+ {"engine": "codex", "model": "gpt-6-luna", "effort": "high", "cli": "0.162.1"},
9
+ {"engine": "claude", "model": "claude-haiku-5-5", "effort": "high", "cli": "2.1.299"}
10
+ ],
11
+ "arms": {
12
+ "A": "Same canonical router and available documents, plus experiment-only eager document-read timing instruction.",
13
+ "B": "Same canonical router and available documents, current active-step-only disclosure/read timing."
14
+ },
15
+ "workloads": ["profile-lookup", "quixbugs-find-in-sorted", "polyglot-simple-linked-list-staged"],
16
+ "repeats_per_model_workload": 2,
17
+ "planned_episodes": 24,
18
+ "host_preflight_episodes": 2,
19
+ "order": "Repeat 1 AB; repeat 2 BA within each model/workload block; alternating model blocks. Provider cache residency is uncontrolled.",
20
+ "episode_timeout_seconds": {"profile-lookup": 180, "quixbugs-find-in-sorted": 300, "polyglot-simple-linked-list-staged": 600},
21
+ "aggregate_wall_budget_seconds": 7200,
22
+ "episode_output_token_cap": 80000,
23
+ "aggregate_output_token_cap": 500000,
24
+ "budget_note": "Subscription login, no new API keys. Caps checked at emitted usage events; telemetry can arrive only at episode end. No actual-billing assertion. Stop on inaccessible model, absent router attribution or invalid grader before expanding trials.",
25
+ "useful_effect": "At least 10% lower paired price-weighted input cost or reference-read content tokens, with no observed critical correctness/semantic regression; workload-specific screening only.",
26
+ "quality": "External acceptance checks plus attributed router/read/workflow evidence. Two repeats cannot establish a <=2 pp non-inferiority bound.",
27
+ "exclusions": "Infrastructure failures retained and marked inconclusive. Agent errors, valid budget exhaustion and incomplete work count as failures. No outcome-selected reruns.",
28
+ "closure": "Pilot only. Does not satisfy issue290 >=5 paired repeats per family; no automatic closure or general benefit claim.",
29
+ "public_selection_provenance": "0b221bf75b89b5834bc72869ddb9a6847db9760d; source selection reused, not the unrelated skill-text vs vanilla contrast.",
30
+ "required_preflight": ["pinned public fixture downloaded", "untouched fixture fails", "reference solution passes", "normal Node require and fixture commands work", "real host invokes canonical router", "actual model/effort recorded", "reference-open trace and usage collected"],
31
+ "reporting": "Per model/host and workload: completion, actual reference reads, uncached/cache creation/cache read/input/output/reasoning where exposed, estimated cost only where priced, wall time, tool counts, all errors/exclusions. Missing fields are unknown."
32
+ }