harness-everything 0.47.1 → 0.47.3

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 (103) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.github/workflows/ci.yml +14 -0
  4. package/CHANGELOG.md +18 -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/ci/lib/opencode-verification-loader.js +24 -0
  85. package/ci/mechanism-2p-opencode-v2-entrypoint.test.js +8 -1
  86. package/ci/mechanism-325-f3-derived-views.test.js +42 -2
  87. package/ci/mechanism-338-opencode-async.test.js +229 -0
  88. package/ci/mechanism-341-opencode-lane.test.js +14 -3
  89. package/ci/mechanism-36-verify-timeout.test.js +7 -168
  90. package/docs/platform-capabilities.md +8 -0
  91. package/harness-everything/SKILL.md +1 -1
  92. package/harness-everything/scripts/doc-check.js +5 -4
  93. package/hooks/scripts/lib/doc-reconciliation-provider.js +1 -1
  94. package/opencode-plugin/README.md +28 -30
  95. package/opencode-plugin/index.mjs +249 -112
  96. package/opencode-plugin/plugin.json +1 -1
  97. package/package.json +1 -1
  98. package/plugins/harness-everything/.codex-plugin/plugin.json +1 -1
  99. package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-provider.js +1 -1
  100. package/plugins/harness-everything/plugin.json +1 -1
  101. package/plugins/harness-everything/skills/harness-everything/SKILL.md +1 -1
  102. package/plugins/harness-everything/skills/harness-everything/scripts/doc-check.js +5 -4
  103. package/sbom.cdx.json +7 -7
@@ -0,0 +1,166 @@
1
+ """Shared, conservative reference attribution; never execute captured commands.
2
+
3
+ Filesystem access, mixed shell output and identified reference content are
4
+ different metrics. Only paths in the episode's declared document bundle count.
5
+ Unknown transformations remain uncertain, rather than being counted as reads.
6
+ """
7
+ import hashlib
8
+ import re
9
+ import shlex
10
+
11
+ READERS = {'cat', 'sed', 'head', 'tail', 'rg', 'grep', 'get-content', 'gc', 'type'}
12
+
13
+
14
+ def segments(command):
15
+ if not isinstance(command, str):
16
+ return []
17
+ try:
18
+ # Preserve backslashes in PowerShell paths. Quoted shell wrappers are
19
+ # unwrapped before this lexer is used for their actual program.
20
+ command = command.replace('<HARNESS_SOURCE>', '__HARNESS_SOURCE__').replace('<TMP>', '__TMP__')
21
+ lexer = shlex.shlex(command, posix=True, punctuation_chars=';&|()<>')
22
+ lexer.escape = ''
23
+ lexer.whitespace_split = True
24
+ tokens = [token.replace('__HARNESS_SOURCE__', '<HARNESS_SOURCE>').replace('__TMP__', '<TMP>') for token in lexer]
25
+ except (ValueError, TypeError):
26
+ return []
27
+ if tokens and tokens[0].rsplit('/', 1)[-1] in ('sh', 'bash', 'zsh') and len(tokens) == 3 and tokens[1] in ('-c', '-lc'):
28
+ return segments(tokens[2])
29
+ result, current = [], []
30
+ for token in tokens:
31
+ if token and all(c in ';&|()<>' for c in token):
32
+ if current:
33
+ result.append(current)
34
+ current = []
35
+ else:
36
+ current.append(token)
37
+ if current:
38
+ result.append(current)
39
+ return result
40
+
41
+
42
+ def is_content_command(command):
43
+ return any(part and part[0].lower().rsplit('/', 1)[-1] in READERS
44
+ and not (part[0].lower() == 'rg' and '--files' in part)
45
+ for part in segments(command))
46
+
47
+
48
+ def reference_path(value, documents, source=''):
49
+ value = str(value).replace('\\', '/').removeprefix('./')
50
+ for prefix in ('.harness/', '<HARNESS_SOURCE>/', source.rstrip('/') + '/' if source else ''):
51
+ if prefix and value.startswith(prefix):
52
+ relative = value[len(prefix):]
53
+ return relative if relative in documents else None
54
+ # Native Read can supply an absolute workspace/.harness path.
55
+ if '/.harness/' in value:
56
+ relative = value.split('/.harness/', 1)[1]
57
+ return relative if relative in documents else None
58
+ return value if value in documents else None
59
+
60
+
61
+ def observed_read(command, output, documents, source='', native_path=None):
62
+ paths = []
63
+ if native_path is not None:
64
+ relative = reference_path(native_path, documents, source)
65
+ if relative:
66
+ paths.append(relative)
67
+ else:
68
+ for part in segments(command):
69
+ if not part or not is_content_command(shlex.join(part)):
70
+ continue
71
+ for token in part[1:]:
72
+ relative = reference_path(token, documents, source)
73
+ if relative and relative not in paths:
74
+ paths.append(relative)
75
+ if not paths:
76
+ return None
77
+ remaining = output or ''
78
+ matched = []
79
+ # Match complete line runs or complete files. A numeric wc result, a
80
+ # filename listing, or prose mentioning a path does not identify content.
81
+ # Very short isolated fragments stay uncertain to avoid incidental matches.
82
+ for relative in paths:
83
+ content = documents[relative]
84
+ if not content:
85
+ continue
86
+ if content in remaining:
87
+ remaining = remaining.replace(content, '', 1)
88
+ matched.append({'path': relative, 'bytes': len(content.encode()), 'kind': 'full-file'})
89
+ continue
90
+ lines = remaining.splitlines(keepends=True)
91
+ index = 0
92
+ while index < len(lines):
93
+ end = index + 1
94
+ best = None
95
+ while end <= len(lines):
96
+ fragment = ''.join(lines[index:end])
97
+ if fragment not in content:
98
+ break
99
+ if len(fragment.strip()) >= 32:
100
+ best = (end, fragment)
101
+ end += 1
102
+ if best:
103
+ end, fragment = best
104
+ matched.append({'path': relative, 'bytes': len(fragment.encode()), 'kind': 'partial-content'})
105
+ remaining = remaining.replace(fragment, '', 1)
106
+ index = end
107
+ else:
108
+ index += 1
109
+ attributable = sum(item['bytes'] for item in matched)
110
+ total = len((output or '').encode())
111
+ return {'command': command, 'paths': paths, 'filesystem_access_candidates': len(paths),
112
+ 'shell_output_bytes': total, 'returned_bytes': attributable,
113
+ 'exact_reference_bytes': attributable,
114
+ 'uncertain_or_mixed_output_bytes': total - attributable,
115
+ 'matched_content': matched,
116
+ 'content_sha256': hashlib.sha256((output or '').encode()).hexdigest(),
117
+ 'evidence': 'content match against frozen declared bundle; access alone is not returned content'}
118
+
119
+
120
+ def collect_reads(events, documents, source=''):
121
+ reads, commands, errors = [], [], []
122
+ tools = {tool['id']: tool for event in events
123
+ for tool in event.get('message', {}).get('content', [])
124
+ if isinstance(tool, dict) and tool.get('type') == 'tool_use' and tool.get('id')}
125
+ active = 'uncomposed'
126
+ for event in events:
127
+ outputs = []
128
+ item = event.get('item', {})
129
+ if event.get('type') == 'item.completed' and item.get('type') == 'command_execution':
130
+ outputs.append((item.get('command', ''), item.get('aggregated_output', '')))
131
+ if item.get('exit_code') not in (0, None):
132
+ errors.append({'command': item.get('command'), 'exit': item.get('exit_code')})
133
+ result = event.get('tool_use_result')
134
+ if isinstance(result, dict):
135
+ if result.get('type') == 'text' and isinstance(result.get('file'), dict):
136
+ file = result['file']
137
+ read = observed_read('', file.get('content', ''), documents, source, file.get('filePath', ''))
138
+ if read:
139
+ reads.append({'active_step': active, **read})
140
+ if 'stdout' in result:
141
+ command = ''
142
+ for tool in event.get('message', {}).get('content', []):
143
+ if isinstance(tool, dict) and tool.get('type') == 'tool_result':
144
+ command = tools.get(tool.get('tool_use_id'), {}).get('input', {}).get('command', '')
145
+ outputs.append((command, result.get('stdout', '')))
146
+ if result.get('interrupted'):
147
+ errors.append({'command': command, 'interrupted': True})
148
+ elif isinstance(result, str) and result.startswith('Error:'):
149
+ errors.append({'tool_error': result})
150
+ for command, output in outputs:
151
+ commands.append(command)
152
+ if 'workflow-disposition.js' in command:
153
+ import json
154
+ try:
155
+ data, _ = json.JSONDecoder().raw_decode(output.lstrip())
156
+ if isinstance(data, dict):
157
+ if data.get('activeStep'):
158
+ active = data['activeStep']['id']
159
+ elif data.get('activeStages'):
160
+ active = ','.join(stage.get('stageId', '?') for stage in data['activeStages'])
161
+ except (ValueError, KeyError, TypeError):
162
+ pass
163
+ read = observed_read(command, output, documents, source)
164
+ if read:
165
+ reads.append({'active_step': active, **read})
166
+ return reads, commands, errors
@@ -0,0 +1,167 @@
1
+ #!/usr/bin/env python3
2
+ """Rebuild pilot evidence offline, from hash-checked committed inputs only."""
3
+ import argparse
4
+ import hashlib
5
+ import importlib
6
+ import json
7
+ from pathlib import Path, PurePosixPath
8
+ import tarfile
9
+ import tempfile
10
+
11
+ from analyze import inspect_episode
12
+ from reporting import paired_rows, report_tables, summarize_groups
13
+
14
+ HERE = Path(__file__).resolve().parent
15
+ exporter = importlib.import_module('export')
16
+
17
+
18
+ def key(row):
19
+ return (row['series'], row['model']['engine'], row['workload'], row['arm'], row['repeat'])
20
+
21
+
22
+ def extract_verified(target):
23
+ inventory = json.loads((HERE/'evidence/inventory.json').read_text())
24
+ expected = {item['path']: item for item in inventory}
25
+ found = set()
26
+ with tarfile.open(HERE/'evidence.tar.gz') as archive:
27
+ for member in archive.getmembers():
28
+ parts = PurePosixPath(member.name).parts
29
+ if not parts or parts[0] != 'evidence' or '..' in parts or member.issym() or member.islnk():
30
+ raise ValueError('unsafe archive member')
31
+ if member.isdir():
32
+ continue
33
+ relative = '/'.join(parts[1:])
34
+ if relative == 'inventory.json':
35
+ continue
36
+ if not member.isfile() or relative not in expected or relative in found:
37
+ raise ValueError('unexpected/duplicate evidence file')
38
+ raw = archive.extractfile(member).read()
39
+ if hashlib.sha256(raw).hexdigest() != expected[relative]['exported_sha256']:
40
+ raise ValueError('exported evidence hash mismatch')
41
+ exporter.validate_no_secrets(raw.decode())
42
+ path = target/relative
43
+ path.parent.mkdir(parents=True, exist_ok=True)
44
+ path.write_bytes(raw)
45
+ found.add(relative)
46
+ if found != set(expected):
47
+ raise ValueError('missing exported evidence files')
48
+ return len(found)
49
+
50
+
51
+ def regenerate():
52
+ with tempfile.TemporaryDirectory(prefix='harness-pilot-replay-') as temporary:
53
+ root = Path(temporary)
54
+ count = extract_verified(root)
55
+ frozen_rows = json.loads((root/'issue290-final-audit/audited-rows.json').read_text())
56
+ frozen = {key(row): row for row in frozen_rows}
57
+ if len(frozen) != 40:
58
+ raise ValueError('frozen audit count/identity mismatch')
59
+ bundle = json.loads((HERE/'frozen-documents.json').read_text())
60
+ rows = []
61
+ for manifest_path in sorted(root.glob('*/*/manifest.json')):
62
+ episode = manifest_path.parent
63
+ manifest = json.loads(manifest_path.read_text())
64
+ identity = {**manifest, 'series': episode.parent.name}
65
+ documents = {}
66
+ for name, digest in manifest['documents'].items():
67
+ document = bundle['documents'][name]
68
+ if document['source_sha256'] != digest or hashlib.sha256(document['content'].encode()).hexdigest() != digest:
69
+ raise ValueError('document revision differs from episode manifest')
70
+ documents[name] = document['content']
71
+ # The live JS fixture declared ESM, but the original episode
72
+ # exporter retained only the implementation. Restore that pinned
73
+ # launch prerequisite instead of relying on host module detection.
74
+ if manifest['workload'] == 'polyglot-simple-linked-list-staged':
75
+ package = '{"type":"module"}\n'
76
+ if manifest['fixture'].get('package.json') != hashlib.sha256(package.encode()).hexdigest():
77
+ raise ValueError('unexpected module fixture identity')
78
+ (episode/'package.json').write_text(package)
79
+ row = inspect_episode(episode, offline=True, frozen=frozen[key(identity)], documents=documents)
80
+ row['series'] = episode.parent.name
81
+ # No host reasoning, assistant prose, dispatch arguments, or child
82
+ # transcripts are republished by the derived ledger.
83
+ keep = ('series', 'model', 'workload', 'arm', 'repeat', 'preflight', 'classification',
84
+ 'wall_seconds', 'exit', 'stop_reason', 'budget_failure', 'cost_observability',
85
+ 'api_equivalent_cost_usd', 'api_equivalent_input_cost_usd', 'parent_api_equivalent_cost_usd',
86
+ 'reference_returned_bytes', 'exact_reference_bytes_lower_bound',
87
+ 'reference_filesystem_access_candidates', 'reference_shell_output_bytes',
88
+ 'uncertain_or_mixed_output_bytes', 'observed_reference_reads',
89
+ 'effective_effort_reported', 'input_usage_reconciles', 'usage',
90
+ 'child_usage_observability', 'strategies', 'tdd_quality_gate_name_matched_invocation',
91
+ 'independent_grader', 'telemetry_provenance')
92
+ rows.append({name: row.get(name) for name in keep})
93
+ if len(rows) != 40 or {key(row) for row in rows} != set(frozen):
94
+ raise ValueError('replayed episode identities differ')
95
+ rows.sort(key=key)
96
+ pairs = paired_rows(rows)
97
+ output = {'ledger.json': rows, 'group-summary.json': summarize_groups(rows), 'pairs.json': pairs,
98
+ 'provenance.json': {'verified_exported_files': count,
99
+ 'archive_sha256': hashlib.sha256((HERE/'evidence.tar.gz').read_bytes()).hexdigest(),
100
+ 'pricing_assumptions_sha256': hashlib.sha256((HERE/'pricing-assumptions.json').read_bytes()).hexdigest(),
101
+ 'frozen_documents_sha256': hashlib.sha256((HERE/'frozen-documents.json').read_bytes()).hexdigest(),
102
+ 'recomputed': ['parent-stream content attribution', 'artifact checks', 'gate-name invocation', 'metric denominators', 'paired deltas'],
103
+ 'frozen_not_independently_recovered': ['request usage', 'child dispatch metadata', 'effort', 'usage aggregates'],
104
+ 'irretrievable': ['unobserved worker usage/model identities', 'interrupted final usage'],
105
+ 'unknown_policy': 'non-reconstructable whole-run costs remain null; no host-home reads or model calls'}}
106
+ result = {}
107
+ for name, value in output.items():
108
+ text = json.dumps(value, indent=2, ensure_ascii=False, sort_keys=True)+'\n'
109
+ text = text.replace(str(root), '<REPLAY_ROOT>').replace(str(HERE.parent.parent), '<HARNESS_SOURCE>')
110
+ exporter.validate_no_secrets(text)
111
+ result[name] = text
112
+ result['tables.md'] = report_tables(rows, pairs)
113
+ return result
114
+
115
+
116
+ def main():
117
+ parser = argparse.ArgumentParser()
118
+ parser.add_argument('--check', action='store_true', help='compare regenerated data with committed expected values')
119
+ args = parser.parse_args()
120
+ result = regenerate()
121
+ def destination(name):
122
+ return HERE/'evidence'/name if name in ('ledger.json', 'group-summary.json') else HERE/'evidence/replay'/name
123
+ if args.check:
124
+ for name, text in result.items():
125
+ if not destination(name).is_file() or destination(name).read_text() != text:
126
+ if name.endswith('.json') and destination(name).is_file():
127
+ def differences(expected, actual, path='$'):
128
+ if type(expected) is not type(actual):
129
+ yield path+' (type)'
130
+ elif isinstance(expected, dict):
131
+ for field in sorted(set(expected) | set(actual)):
132
+ if field not in expected or field not in actual:
133
+ yield path+'.'+field+' (missing)'
134
+ else:
135
+ yield from differences(expected[field], actual[field], path+'.'+field)
136
+ elif isinstance(expected, list):
137
+ if len(expected) != len(actual):
138
+ yield path+' (length)'
139
+ for index, (left, right) in enumerate(zip(expected, actual)):
140
+ yield from differences(left, right, f'{path}[{index}]')
141
+ elif expected != actual:
142
+ yield path
143
+ import itertools
144
+ print('different fields:', ', '.join(itertools.islice(differences(
145
+ json.loads(destination(name).read_text()), json.loads(text)), 12)))
146
+ raise SystemExit('offline replay differs: '+name)
147
+ readme = (HERE/'README.md').read_text()
148
+ if '<!-- BEGIN REPLAY TABLES -->\n'+result['tables.md']+'<!-- END REPLAY TABLES -->' not in readme:
149
+ raise SystemExit('offline replay differs: README tables')
150
+ print('offline replay PASS: 40 episodes; 621 hashes; ledger, groups, pairs, tables and provenance match')
151
+ else:
152
+ for name, text in result.items():
153
+ path = destination(name)
154
+ path.parent.mkdir(parents=True, exist_ok=True)
155
+ path.write_text(text)
156
+ readme = HERE/'README.md'
157
+ content = readme.read_text()
158
+ if '<!-- BEGIN REPLAY TABLES -->' in content:
159
+ import re
160
+ content = re.sub(r'<!-- BEGIN REPLAY TABLES -->.*?<!-- END REPLAY TABLES -->',
161
+ lambda _: '<!-- BEGIN REPLAY TABLES -->\n'+result['tables.md']+'<!-- END REPLAY TABLES -->', content, flags=re.S)
162
+ readme.write_text(content)
163
+ print('regenerated offline evidence:', len(result), 'files')
164
+
165
+
166
+ if __name__ == '__main__':
167
+ main()
@@ -0,0 +1,82 @@
1
+ """Metric-specific denominators and deterministic descriptive pairs."""
2
+ from collections import defaultdict
3
+
4
+
5
+ def quality_included(row):
6
+ return not row.get('preflight') and (row.get('classification') != 'inconclusive' or row.get('budget_failure'))
7
+
8
+
9
+ def summarize_groups(rows):
10
+ groups = defaultdict(list)
11
+ for row in rows:
12
+ groups[(row['series'], row['model']['engine'], row['workload'], row['arm'])].append(row)
13
+ result = []
14
+ for key, group in sorted(groups.items()):
15
+ included = [row for row in group if quality_included(row)]
16
+ record = dict(zip(('series', 'engine', 'workload', 'arm'), key))
17
+ record.update(n_attempted=len(group), n_quality_included=len(included),
18
+ n_quality_excluded=len(group)-len(included),
19
+ artifact_passes=sum(bool(r['independent_grader'].get('pass')) and not r.get('budget_failure') for r in included),
20
+ budget_failures=sum(bool(r.get('budget_failure')) for r in included))
21
+ for output, field in [('reference_bytes', 'reference_returned_bytes'),
22
+ ('exact_reference_bytes_lower_bound', 'exact_reference_bytes_lower_bound'),
23
+ ('mean_wall_seconds', 'wall_seconds'),
24
+ ('api_equivalent_cost_usd', 'api_equivalent_cost_usd'),
25
+ ('api_equivalent_input_cost_usd', 'api_equivalent_input_cost_usd')]:
26
+ known = [r[field] for r in included if r.get(field) is not None]
27
+ record['n_'+output+'_included'] = len(known)
28
+ record['n_'+output+'_excluded'] = len(group)-len(known)
29
+ # Missing data never becomes zero. A known subtotal is explicitly
30
+ # different from an unknown group total.
31
+ record[output+'_known_subtotal'] = sum(known) if known else None
32
+ record[output] = (sum(known)/len(known) if output.startswith('mean_') else sum(known)) if known and len(known) == len(included) else None
33
+ result.append(record)
34
+ return result
35
+
36
+
37
+ def paired_rows(rows):
38
+ cells = defaultdict(dict)
39
+ for row in rows:
40
+ if quality_included(row):
41
+ key = (row['series'], row['model']['engine'], row['workload'], row['repeat'])
42
+ if row['arm'] in cells[key]:
43
+ raise ValueError('duplicate arm in paired cell')
44
+ cells[key][row['arm']] = row
45
+ pairs = []
46
+ for key, arms in sorted(cells.items()):
47
+ pair = dict(zip(('series', 'engine', 'workload', 'repeat'), key))
48
+ for field in ('reference_returned_bytes', 'api_equivalent_input_cost_usd', 'api_equivalent_cost_usd', 'wall_seconds'):
49
+ a, b = (arms.get(arm, {}).get(field) for arm in ('A', 'B'))
50
+ known = a is not None and b is not None
51
+ pair[field] = {'included': known, 'A': a, 'B': b,
52
+ 'delta_percent': (b-a)/a*100 if known and a else None}
53
+ pairs.append(pair)
54
+ return pairs
55
+
56
+
57
+ def report_tables(rows, pairs):
58
+ lines = ['<!-- Generated by replay.py; parent-stream content attribution only. -->',
59
+ '| Family | Model | Pass / quality n | Excluded attempts |',
60
+ '|---|---|---:|---:|']
61
+ families = defaultdict(list)
62
+ for row in rows:
63
+ if not row.get('preflight'):
64
+ name = 'True Fable' if 'fable' in row['series'] else row['workload']
65
+ families[(name, row['model']['engine'])].append(row)
66
+ for (name, engine), group in sorted(families.items()):
67
+ included = [r for r in group if quality_included(r)]
68
+ passes = sum(bool(r['independent_grader'].get('pass')) and not r.get('budget_failure') for r in included)
69
+ lines.append(f'| {name} | {engine} | {passes}/{len(included)} | {len(group)-len(included)} |')
70
+ for field, title, precision in [('reference_returned_bytes', 'Attributable reference bytes (lower bound)', 0),
71
+ ('api_equivalent_input_cost_usd', 'List-price input cost (frozen telemetry)', 6)]:
72
+ lines.extend(['', '### '+title, '', '| Family | Model | Included / candidate pairs | A | B | Delta |', '|---|---|---:|---:|---:|---:|'])
73
+ grouped = defaultdict(list)
74
+ for pair in pairs:
75
+ name = 'True Fable' if 'fable' in pair['series'] else pair['workload']
76
+ grouped[(name, pair['engine'])].append(pair[field])
77
+ for (name, engine), group in sorted(grouped.items()):
78
+ known = [p for p in group if p['included']]
79
+ a, b = (sum(p[arm] for p in known) for arm in ('A', 'B'))
80
+ values = [f'{a:.{precision}f}', f'{b:.{precision}f}', f'{(b-a)/a*100:+.1f}%' if a else 'unknown'] if known else ['unknown']*3
81
+ lines.append(f'| {name} | {engine} | {len(known)}/{len(group)} | '+ ' | '.join(values)+' |')
82
+ return '\n'.join(lines)+'\n'