Skip to content

Commit 7af3027

Browse files
committed
TASK-198: Enforce benchmark receipt integrity and effective optimization
Bind required protocol coverage to the expected TLS identity, compare exported metrics with raw samples, and require complete consumer/tool provenance with matching digests. Honor the final compiler optimization option and add regression coverage for all four defects. Preserve the original immutable full measurements and record separate validation equivalence, a fresh reduced smoke run, and refreshed distribution evidence. Validation: nine applicable domains approved after focused closure; eight blocking findings fixed, with one approved duplicate resolved incidentally. Passed 18 benchmark, 27 installed-consumer and 3 resource contracts; TLS-on/off memory/resource suites; 20 retained full cells (81,920 measured requests); fresh 16-cell smoke; artifact and distribution checks. Nonlocal checks remain CI/v3-PR owned.
1 parent a14f1d0 commit 7af3027

6 files changed

Lines changed: 263 additions & 27 deletions

File tree

‎docs/native-v3-benchmarks.md‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ make bench BENCH_PREFIX="$PREFIX" BENCH_PROVIDER_PREFIX="$PROVIDER" \
3030

3131
Repeat with a distinct fresh build/prefix/output and `--enable-v3-tls=no`,
3232
`BENCH_TLS=no`. Library and consumer optimization flags are recorded. The runner
33-
rejects nonoptimized libraries, sanitizer flags/symbols and allocator preload.
33+
requires the final optimization option to be `-O2` or `-O3`, and rejects
34+
sanitizer flags/symbols and allocator preload.
3435
Sanitizer measurements are correctness evidence and cannot enter comparisons.
3536
The direct entry point provides `--source`, `--build`, `--prefix`,
3637
`--provider-prefix`, `--tls`, `--compiler`, `--client-python` and `--output`.
@@ -88,7 +89,12 @@ after orderly shutdown. Client exit zero alone is insufficient.
8889
`validate(path, expected_identity, expected_run_id)` is available from
8990
`scripts/run-v3-native-benchmarks.py` for release adapter integration. Offline
9091
verification checks current source/package/build/workload identities and every
91-
artifact, then recomputes samples/statistics and compares server counts. A caller
92+
artifact, then recomputes samples/statistics and compares server counts. The
93+
expected TLS identity selects the required matrix, and every exported cell metric
94+
must agree with raw observations in the declared units. Required consumer source,
95+
local header, executable, link map, command, copied client/fixture and client-input
96+
records must remain present and consistent; installed headers are bound by the
97+
expected package identity. A caller
9298
requiring new execution must obtain the fresh runner's run ID; revalidating an old
9399
receipt is integrity verification, not a new benchmark. CLI `--validate RECEIPT`
94100
accepts `--expected-run-id`. Hashes establish integrity against recorded inputs;

‎scripts/lib/v3_native_benchmark.py‎

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,18 @@ def validate_observation(value, run_id, protocol):
100100
following = bisect_right(epoch_ends, row['start_ns'])
101101
require(following == len(epochs) or row['end_ns'] <= epochs[following]['start_ns'], 'warmup contamination')
102102
expected = statistics(samples, epochs)
103-
require(set(value['statistics']) == set(expected), 'missing statistics or units')
104-
for key, result in expected.items():
105-
actual = value['statistics'][key]
106-
require(type(actual) in (int, float) and math.isfinite(actual) and actual > 0 and
107-
math.isclose(actual, result, rel_tol=1e-12), 'statistics disagreement: ' + key)
103+
validate_statistics(value['statistics'], expected)
108104
return expected
109105

110106

107+
def validate_statistics(actual, expected):
108+
require(set(actual) == set(expected), 'missing statistics or units')
109+
for key, result in expected.items():
110+
number = actual[key]
111+
require(type(number) in (int, float) and math.isfinite(number) and number > 0 and
112+
math.isclose(number, result, rel_tol=1e-12), 'statistics disagreement: ' + key)
113+
114+
111115
def artifact(path):
112116
path = Path(path).resolve()
113117
return dict(path=str(path), bytes=path.stat().st_size, sha256=hashlib.sha256(path.read_bytes()).hexdigest())
@@ -129,18 +133,76 @@ def validate_server(server, observation):
129133
measured=observation['completed'], errors=0), 'server/client counts differ')
130134

131135

136+
def validate_provenance(receipt, expected_identity):
137+
records = {record['path']: record for record in receipt['artifacts']}
138+
require(len(records) == len(receipt['artifacts']), 'duplicate artifact paths')
139+
140+
def bound(path, expected=None):
141+
path = str(Path(path).resolve())
142+
require(path in records, 'unbound provenance artifact: ' + path)
143+
if expected is not None:
144+
require(records[path]['sha256'] == expected, 'provenance digest disagreement: ' + path)
145+
return records[path]
146+
147+
directory = Path(receipt['consumer_directory'])
148+
copies = {'consumer.cpp': 'test/installed/v3_benchmark_consumer.cpp',
149+
'v3_host_poll.hpp': 'examples/v3_host_poll.hpp',
150+
'client.py': 'test/installed/v3_benchmark_client.py'}
151+
local = {str(directory / name): expected_identity['source'][source] for name, source in copies.items()}
152+
for path, sha256 in local.items(): bound(path, sha256)
153+
for name, sha256 in expected_identity['fixtures'].items(): bound(directory / 'fixtures' / name, sha256)
154+
require(set(receipt['consumers']) == {'shared', 'static'}, 'missing consumer provenance')
155+
for linkage, consumer in receipt['consumers'].items():
156+
compiled = consumer['compile']
157+
bound(directory / linkage, compiled['artifact_sha256'])
158+
require(compiled['private_test_headers'] is False, 'private consumer headers')
159+
require(compiled['sources'] == {str(directory / 'consumer.cpp'): local[str(directory / 'consumer.cpp')]},
160+
'wrong consumer sources')
161+
deps = compiled['dependency_sha256']
162+
require(set(compiled['dependencies']) == set(deps), 'missing dependency digests')
163+
resolved = {str(Path(path).resolve()): sha256 for path, sha256 in deps.items()}
164+
require(all(path in resolved for path in local if not path.endswith('client.py')), 'missing local dependencies')
165+
require(any(path in expected_identity['package'] for path in resolved), 'missing installed headers')
166+
for path, sha256 in resolved.items():
167+
# Installed headers are bound by the independently supplied package identity.
168+
expected = expected_identity['package'].get(path, local.get(path))
169+
require(expected is not None and sha256 == expected, 'unexpected consumer dependency: ' + path)
170+
require(artifact(path)['sha256'] == sha256, 'changed consumer dependency: ' + path)
171+
if path in local: bound(path, sha256)
172+
require(Path(compiled['link_map']).resolve() == (directory / (linkage + '.map')).resolve(), 'wrong link map')
173+
bound(compiled['link_map'])
174+
output = Path(receipt['cells'][0]['observation']['path']).parent.parent
175+
command_record = bound(output / 'commands.json')
176+
commands = parse_json(Path(command_record['path']).read_text())
177+
require(len(commands) >= 4, 'missing tool commands')
178+
for command in commands:
179+
require(command['exit'] == 0 and 'error' not in command and command['argv'], 'failed provenance command')
180+
bound(command['log'], command['sha256'])
181+
require(records[str(Path(command['log']).resolve())]['bytes'] == command['bytes'], 'wrong command length')
182+
require(set(receipt['tools']) == {'compiler', 'pkg_config', 'clients'}, 'missing tool versions')
183+
for key, command in zip(('compiler', 'pkg_config', 'clients'), commands):
184+
require(receipt['tools'][key] and receipt['tools'][key] == Path(command['log']).read_text(), 'wrong tool version')
185+
inputs = receipt['client_inputs']
186+
require(inputs and [item['path'] for item in inputs] == parse_json(Path(commands[3]['log']).read_text()),
187+
'missing client input provenance')
188+
for record in inputs:
189+
require(bound(record['path']) == record, 'unbound client input')
190+
191+
132192
def validate_receipt(receipt, expected_identity, expected_run_id=None):
133193
require(receipt['schema_version'] == 1 and receipt['status'] == 'passed', 'failed or unknown receipt')
134194
require(receipt['identity'] == expected_identity, 'stale source/package/configuration identity')
135195
require('workload' not in receipt or receipt['workload'] == expected_identity.get('workload'), 'stale workload')
136196
require(len(receipt['run_id']) == 32 and all(c in '0123456789abcdef' for c in receipt['run_id']), 'invalid run identifier')
137197
if expected_run_id is not None:
138198
require(receipt['run_id'] == expected_run_id, 'reused run identifier')
139-
validate_cells([tuple(cell[k] for k in ('linkage', 'loop', 'protocol')) for cell in receipt['cells']], receipt['tls'])
199+
require(receipt['tls'] == expected_identity['tls'], 'contradictory TLS mode')
200+
validate_cells([tuple(cell[k] for k in ('linkage', 'loop', 'protocol')) for cell in receipt['cells']], expected_identity['tls'])
140201
require(receipt['artifacts'], 'missing immutable artifacts')
141202
sample_paths = [cell['observation']['path'] for cell in receipt['cells']]
142203
require(len(sample_paths) == len(set(sample_paths)), 'reused samples across cells')
143204
for record in receipt['artifacts']: verify_artifact(record)
205+
validate_provenance(receipt, expected_identity)
144206
for cell in receipt['cells']:
145207
require(cell['client_exit'] == 0 and cell['fresh_execution'] is True, 'missing live client execution')
146208
for key in ('observation', 'server'):
@@ -154,6 +216,7 @@ def validate_receipt(receipt, expected_identity, expected_run_id=None):
154216
expected_epochs, expected_warmup = epoch_workload(cell['protocol'], workload['requests'], concurrency, workload['warmup'])
155217
require(observation['warmup_requested'] == expected_warmup, 'wrong warmup workload')
156218
require(len(observation['epochs']) == expected_epochs, 'wrong epoch count')
157-
validate_observation(observation, receipt['run_id'], cell['protocol'])
219+
expected = validate_observation(observation, receipt['run_id'], cell['protocol'])
220+
validate_statistics(cell['statistics'], expected)
158221
validate_server(parse_json(Path(cell['server']['path']).read_text()), observation)
159222
return receipt

‎scripts/run-v3-native-benchmarks.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ def digest(path): return hashlib.sha256(Path(path).read_bytes()).hexdigest()
2929

3030
def normal_build(makefile, env):
3131
flags = re.findall(r'^CXXFLAGS\s*=\s*(.*)$', makefile, re.M)
32-
bench.require(flags and all(re.search(r'(^|\s)-O[23](\s|$)', flag) for flag in flags), 'optimized library build required')
32+
optimization = [[option for option in shlex.split(flag) if re.fullmatch(r'-O(?:[0-9]+|g|s|z|fast)?', option)] for flag in flags]
33+
bench.require(optimization and all(options and options[-1] in ('-O2', '-O3') for options in optimization), 'optimized library build required')
3334
forbidden = r'sanitize|fprofile|coverage|jemalloc|tcmalloc|mimalloc|asan|ubsan|tsan'
3435
bench.require(not re.search(forbidden, makefile, re.I) or not re.search(forbidden, ' '.join(flags), re.I), 'instrumented/substituted allocator build')
3536
bench.require(not any(env.get(key) for key in ('LD_PRELOAD', 'DYLD_INSERT_LIBRARIES')), 'allocator/interposer injection')

0 commit comments

Comments
 (0)