Skip to content

Commit f7fac74

Browse files
committed
TASK-199: Harden packaged receipt validation and prove installed witnesses
Close seven validation findings by requiring bound-port readiness, mandatory public compile/runtime provenance, and contributing selected static archives. Validate exact HTTP/1 versions and persistent/pipeline counts, strengthen TLS credential and lifecycle predicates, and replace fabricated WebSocket cancellation with measured receive entry, peer-EOF completion, and retirement. Add focused regressions and reconcile adapter documentation and machine evidence. Verification: 144 focused contracts pass; fresh archive-backed TLS-off/on public matrices pass across shared/static managed/external cells; independent receipt validation passes; 41 rehashed semantic negatives and original WebSocket/static probes reject. Reused reduced benchmark receipts revalidate with all 298 source inputs unchanged per lane. Eight applicable review domains approve after two iterations; zero unworked findings. Full release performance remains TASK-185-owned and nonlocal platform checks remain CI/v3-PR-owned.
1 parent 04709f6 commit f7fac74

9 files changed

Lines changed: 1224 additions & 33 deletions

‎docs/v3-packaged-release-adapters.md‎

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,26 @@ catalog covers child receipts, command outputs, process receipts, copied
8585
consumers/fixtures/client code, objects, depfiles, link maps, executable files
8686
and benchmark raw samples. Compilation must use installed public headers,
8787
C++20, and archive-distributed copied sources. Private headers, source/build
88-
includes and `HTTPSERVER_COMPILATION` cannot supply public proof. Static link
89-
commands/maps must name the selected installed archive; shared runtime
90-
inspection must resolve the selected installation. Readiness alone cannot
88+
includes and `HTTPSERVER_COMPILATION` cannot supply public proof. Every cell must retain its family's compile and dependency records, including
89+
H1 WebSocket, TLS profile/rotation, and H2/H3 example consumers where applicable.
90+
Static link maps must show contributing members from the selected installed
91+
archive and no foreign libhttpserver archive contribution; an unused LOAD entry
92+
cannot supply proof. Shared runtime inspection must resolve the selected
93+
installation. The first readiness line must contain at least one valid bound
94+
port. Readiness alone cannot
9195
supply response proof. Child inventories and decoded lifecycle/semantic
9296
observations remain subject to their original validators.
9397

98+
H1 validation requires exact HTTP/1.0 or HTTP/1.1 response prefixes and exactly
99+
two recorded persistent and pipelined responses. WebSocket peer-close evidence
100+
records actual pending receive entry, completion with the public
101+
`connection_closed` outcome, and handler retirement before server stop. The
102+
legacy `cancelled_receive` count represents this observed transport termination;
103+
it does not assert an `outcome_code::cancelled` result. TLS profile rows retain
104+
and validate positive and negative authentication, handler deltas, decoded
105+
responses, callback cancellation/retirement, SNI generations, session rotation,
106+
and applicable ACME observations independently of their scenario names.
107+
94108
TLS authentication rejection controls retain the independent provider client's
95109
exit 2 only with a decoded `connected=false` handshake and the exact bounded
96110
client argument shape. The explicit peer-close cancellation control retains its

‎scripts/check-v3-public-http1.py‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ def websocket(executable, loop, directory, env, codec):
3434
port = child.port()
3535
def counts():
3636
child.process.stdin.write(b'stats\n'); child.process.stdin.flush()
37-
return [int(n) for n in child.line().split()]
37+
observed = [int(n) for n in child.line().split()]
38+
require(len(observed) == 8, 'missing WS receive counters')
39+
return observed
3840
def wait(predicate):
3941
deadline = time.monotonic() + 3
4042
while True:
@@ -70,9 +72,15 @@ def open_peer(path='/echo'):
7072
require(refused.head().startswith(b'HTTP/1.1 426 '), 'invalid WS version accepted')
7173
finally: refused.close()
7274
rows.append(dict(case='refusal', status=426))
73-
peer = open_peer(); peer.close()
74-
wait(lambda c: c[0] == 2)
75-
rows.append(dict(case='close_cancel', clean_close_code=1000, close_callbacks=2, cancelled_receive=1))
75+
peer = open_peer('/cancel')
76+
try:
77+
wait(lambda c: c[3] == 1 and c[4:7] == [0, 0, 0])
78+
finally: peer.close()
79+
observed = wait(lambda c: c[0] == 2 and c[4:7] == [1, 1, 1])
80+
require(observed[7] == 6, 'pending receive did not terminate with connection_closed')
81+
rows.append(dict(case='close_cancel', clean_close_code=1000, close_callbacks=observed[0],
82+
receive_entered=observed[3], receive_completed=observed[4], receive_retired=observed[5],
83+
cancelled_receive=observed[6], receive_outcome='connection_closed'))
7684
peer = codec.Peer(port)
7785
try:
7886
peer.socket.setsockopt(__import__('socket').SOL_SOCKET, __import__('socket').SO_RCVBUF, 4096)

‎scripts/lib/v3_release_package_adapters.py‎

Lines changed: 150 additions & 4 deletions
Large diffs are not rendered by default.

‎scripts/lib/v3_release_package_provenance.py‎

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def validate_process(record, require_port=False):
1414
require(record.get('exit') == 0 and 'error' not in record and record.get('command'), 'process exit/cleanup failure')
1515
if require_port:
1616
lines = record.get('stdout', '').splitlines()
17-
require(lines and all(word.isdecimal() and 0 < int(word) <= 65535 for word in lines[0].split()), 'missing bound readiness port')
17+
require(lines and lines[0].split() and all(word.isdecimal() and 0 < int(word) <= 65535 for word in lines[0].split()), 'missing bound readiness port')
1818

1919

2020
def validate_compile(compiled, linkage, identity, artifacts, commands):
@@ -54,7 +54,8 @@ def bound(path, digest=None):
5454
require('-Wl,-Map,' + str(linkmap) in link, 'wrong link map command')
5555
if linkage == 'static':
5656
archive = str(prefix / 'lib/libhttpserver.a')
57-
require(archive in link and archive in linkmap.read_text(), 'different installed static archive')
57+
contributors = {str(Path(name).resolve()) for name in re.findall(r'([^\s()]+libhttpserver\.a)\([^()\n]+\)', linkmap.read_text())}
58+
require(archive in link and contributors == {archive}, 'different or noncontributing installed static archive')
5859
compile_rows = [row for row in commands if '-c' in row['argv'] and '-o' in row['argv'] and
5960
row['argv'][row['argv'].index('-o') + 1] in link and
6061
row['argv'][row['argv'].index('-c') + 1] in sources]
@@ -170,15 +171,28 @@ def validate_fixture_client(client, identity, artifacts, commands):
170171
require(links[0]['argv'][:len(compiler)] == compiler, 'different independent client compiler')
171172

172173

173-
def validate_child_provenance(child, identity, artifacts, commands):
174+
def validate_child_provenance(child, identity, artifacts, commands, family=None):
174175
require(child.get('status') == 'passed' and child.get('run_id'), 'failed child receipt')
175176
for name, digest in child.get('source_hashes', {}).items():
176177
require(identity['archive']['members'].get(name) == digest, 'child source outside archive')
177178
require(child.get('library_hashes') and all(identity['package'].get(path) == digest for path, digest in child['library_hashes'].items()), 'different installed child library')
178179
cells = child.get('cells', [])
179180
require(len(cells) == 4 and {(c['linkage'], c['loop']) for c in cells} ==
180181
{(a, b) for a in ('shared', 'static') for b in ('managed', 'external')}, 'missing/duplicate child cells')
182+
required = ['compile', 'dependencies']
183+
if family == 'h1': required += ['websocket_compile']
184+
elif family == 'tls':
185+
required += ['profile_compile', 'profile_dependencies']
186+
if identity['tls'] == 'yes': required += ['example_compile', 'example_dependencies']
187+
elif family == 'h3': required += ['example_compile']
188+
for cell in cells:
189+
require(all(isinstance(cell.get(key), dict) and cell[key] for key in required), 'missing required public cell provenance')
190+
examples = child.get('examples', [])
191+
if family == 'h2' and identity['tls'] == 'yes':
192+
require(len(examples) == 2 and {c.get('linkage') for c in examples} == {'shared', 'static'}, 'missing installed example provenance')
193+
require(all(c.get('compile') and c.get('dependencies') for c in examples), 'missing installed example compile/runtime provenance')
181194
client = child.get('independent_client', child.get('credential_fixture_tool'))
195+
require(family != 'tls' and not (family == 'h3' and identity['tls'] == 'yes') or client, 'missing independent client provenance')
182196
if client: validate_fixture_client(client, identity, artifacts, commands)
183197
seen = set()
184198
for cell in cells + child.get('examples', []):

0 commit comments

Comments
 (0)