Skip to content

Commit 13e449b

Browse files
committed
TASK-193: Strengthen validated TLS witnesses and mark task complete
1 parent c5c127d commit 13e449b

6 files changed

Lines changed: 106 additions & 38 deletions

File tree

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

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -166,15 +166,21 @@ def launch(name):
166166
port = int(child.line().split()[0])
167167
stalled = [socket.create_connection(('127.0.0.1', port), timeout=3) for _ in range(4)]
168168
accepted(child, 4)
169+
refusal_started = time.monotonic()
169170
with socket.create_connection(('127.0.0.1', port), timeout=3) as overflow:
170-
overflow.settimeout(3)
171+
# Admission refusal must precede the 500 ms handshake timeout.
172+
# Otherwise an admitted fifth stalled handshake looks like refusal.
173+
overflow.settimeout(.2)
171174
check(overflow.recv(1) == b'', 'handshake connection budget bypassed')
175+
refusal_seconds = time.monotonic() - refusal_started
172176
for peer in stalled:
173177
peer.settimeout(3)
174178
check(peer.recv(1) == b'', 'stalled handshake deadline missed')
175179
peer.close()
176180
attempts = recover(port, context)
177-
rows.append(dict(case='bounded_handshake_timeout_and_recovery', stalled=4, recovery_attempts=attempts))
181+
rows.append(dict(case='bounded_handshake_timeout_and_recovery', stalled=4,
182+
refusal_seconds=refusal_seconds, refusal_deadline_seconds=.2,
183+
handshake_deadline_seconds=.5, recovery_attempts=attempts))
178184
child.stop()
179185
for scenario in ('timer_budget', 'storage_budget'):
180186
with launch(scenario) as child:
@@ -201,15 +207,20 @@ def launch(name):
201207
peer.close()
202208
else:
203209
with connect(port, context) as peer:
204-
# Handler stop may close before flush; prove invocation and
205-
# bounded teardown separately from ordinary response proof.
210+
# Keep the peer open until the handler's own shutdown call
211+
# returns. Coordinator stop cannot supply this witness.
206212
peer.sendall(b'GET /installed HTTP/1.1\r\nHost: a.example\r\n\r\n')
207213
deadline = time.monotonic() + 3
208-
while time.monotonic() < deadline and int(command(child, 'stats').split()[1]) == 0:
214+
acknowledgement = 'PENDING'
215+
while time.monotonic() < deadline and acknowledgement == 'PENDING':
216+
acknowledgement = command(child, 'handler_shutdown')
209217
time.sleep(.005)
210-
check(int(command(child, 'stats').split()[1]) == 1, 'handler shutdown not invoked')
218+
expected = 'STOPPED' if scenario == 'handler_stop' else 'DRAINED'
219+
check(acknowledgement == expected, 'handler shutdown did not complete: ' + acknowledgement)
220+
check(int(command(child, 'stats').split()[1]) == 1, 'handler count differs')
211221
child.stop()
212-
rows.append(dict(case=scenario))
222+
rows.append(dict(case=scenario, **({} if scenario.endswith('pending') else
223+
dict(handler_shutdown=acknowledgement))))
213224
with launch('accept_stop') as child:
214225
port = int(child.line().split()[0])
215226
with socket.create_connection(('127.0.0.1', port), timeout=3) as peer:

‎specs/architecture/v3/TASK-193-implementation-evidence.md‎

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ Public receipts under `build/task193/`:
4040

4141
| Lane | Receipt |
4242
| --- | --- |
43-
| Normal off | `normal-off/public-probe-r4qt_59p/matrix/receipt.json` |
44-
| Normal on | `normal-on/public-probe-wd6z5s3j/matrix/receipt.json` |
45-
| ASan off | `asan-off/public-probe-maop2szs/matrix/receipt.json` |
46-
| ASan on | `asan-on/public-probe-ly4e3f6y/matrix/receipt.json` |
47-
| TSan off | `tsan-off/public-probe-xjvjqzto/matrix/receipt.json` |
48-
| TSan on | `tsan-on/public-probe-x8583v2y/matrix/receipt.json` |
43+
| Normal off | `validation-repair-iter1/normal-off/receipt.json` |
44+
| Normal on | `validation-repair-iter1/normal-on/receipt.json` |
45+
| ASan off | `validation-repair-iter1/asan-off/receipt.json` |
46+
| ASan on | `validation-repair-iter1/asan-on/receipt.json` |
47+
| TSan off | `validation-repair-iter1/tsan-off/receipt.json` |
48+
| TSan on | `validation-repair-iter1/tsan-on/receipt.json` |
4949

5050
Each cell checks staged public-only compilation outside source/build trees, exact pkg-config identity, shared/static linkage and dependency graphs. TLS-on scenarios cover H1.0/H1.1, named/default/absent/unknown SNI, listener isolation, atomic invalid/valid replacement, held handshake and established session, concurrent publication, caller destruction, policy-before-TLS, failed/stalled handshakes, capacity/timeout/recovery, pending stop/drain, reentrant hook/handler stop/drain, mixed plaintext/TLS, disabled protocols and partial bind rollback.
5151

@@ -60,3 +60,15 @@ No unresolved local required blocker remains. BSD/macOS/Windows execution and no
6060
## Reuse notes
6161

6262
No configured agent memory store exists. Autotools VPATH setup: `./bootstrap`, configure with Clang 18/C++20 and `--disable-examples`; place selected provider `-L`/rpath in `V3_TLS_LIBS`. Build `src` before scoped `test` targets, setting `check_PROGRAMS`, `TESTS` and `noinst_PROGRAMS` together. Install both `src` and root `install-pkgconfigDATA`. Littletest cases live under `test/unit`/`test/integ`, use `LT_CHECK` and expose counts/no-skip receipts. Macro-free public consumers live under `test/headers`/`test/installed`. ASan requires execution outside ptrace with LSan/stack diagnostics. Git worktree/ref mutations require sandbox escalation. Keep source mutation serialized with library/test builds to avoid stale ABI. Preserve registration identity and other task worktrees.
63+
64+
## Validation repair iteration 1
65+
66+
Two public witness gaps were repaired without changing production code or installed libraries. The connection-budget excess peer must now close within 200 ms, separated from the configured 500 ms stalled-handshake timeout. Its refusal elapsed time, both deadlines and later healthy recovery attempts are retained independently in each public receipt.
67+
68+
Handler stop/drain now has an atomic completion acknowledgement published only after the handler's own shutdown call returns. The runner polls it while its peer is still open and before coordinator stop. The fixture checks `is_running() == false` for stop and a successful typed ticket wait with `drain_status::completed` and zero remaining work for drain. The ticket publication uses release/acquire synchronization. Handler entry counts alone cannot pass either witness.
69+
70+
`build/task193/validation-repair-iter1/red.json` records initial RED: capacity-five fixtures timed out at the new refusal deadline in managed/external modes, and the original consumer could not acknowledge handler shutdown. `mutations.json` in that directory records six decisive rejected cells: capacity five, omitted handler `request_stop`, and omitted handler `begin_drain`, each managed/external. The latter mutations preserve the new acknowledgement stores; the stopped-admission/typed-ticket checks still reject them. Mutation source, executable and library hashes, exact compilation commands and process error receipts are retained.
71+
72+
All six refreshed public lanes in the table above pass shared/static × managed/external: 12 TLS-on cells × 23 scenarios and 12 TLS-off same-source cells. ASan/UBSan retains leak, stack-use-after-return and use-after-scope diagnostics; TSan retains halt-on-error. No suppressions were added. The complete affected tooling suites pass (26 runner contracts and 35 package-policy fixtures), as do changed-file cpplint and whitespace checks. Exact commands, sanitizer environment, source/consumer/library identities and reuse checks are in `build/task193/validation-repair-iter1/summary.json` and its referenced receipts.
73+
74+
Production/lifecycle suites and packaging declarations are unchanged. Their original suite logs were verified against recorded hashes and all installed library hashes match the original six lane receipts. Original package/layout/distribution evidence is retained for those unchanged invariants; the refreshed public receipts supersede the earlier public witnesses. Nonlocal checks remain CI/v3-PR owned.

‎specs/architecture/v3/TASK-193-implementation-receipt.json‎

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -683,8 +683,8 @@
683683
"artifact_sha256": "cfbc862dc428736d3558911cc7801f2b0bb6087f49685bba08c074a6ce8f5bc6"
684684
}
685685
},
686-
"public_receipt": "build/task193/normal-off/public-probe-r4qt_59p/matrix/receipt.json",
687-
"public_receipt_sha256": "6480d2e44907eb552c840fabbf0bac618abf5a3821a754ae37f8d064baef7a36",
686+
"public_receipt": "build/task193/validation-repair-iter1/normal-off/receipt.json",
687+
"public_receipt_sha256": "60ebc0c4ce09899f619c560a557244a2ea1c94975e80d5299cbfddb93bc37e87",
688688
"public_cases": [
689689
1,
690690
1,
@@ -772,7 +772,9 @@
772772
"/usr/lib/python3.12/lib-dynload/_ssl.cpython-312-x86_64-linux-gnu.so"
773773
]
774774
}
775-
}
775+
},
776+
"prior_public_receipt": "build/task193/normal-off/public-probe-r4qt_59p/matrix/receipt.json",
777+
"prior_public_receipt_sha256": "6480d2e44907eb552c840fabbf0bac618abf5a3821a754ae37f8d064baef7a36"
776778
},
777779
"normal-on": {
778780
"unit_commands": "build/task193/normal-on/commands-_jss32bl",
@@ -1748,8 +1750,8 @@
17481750
"artifact_sha256": "025a0ee67162da01e26ff11334790f3dffe2fc62c6344bff637b9cc4bc4a6ae6"
17491751
}
17501752
},
1751-
"public_receipt": "build/task193/normal-on/public-probe-wd6z5s3j/matrix/receipt.json",
1752-
"public_receipt_sha256": "6fe2d06a8067430a628b37bb06ac58c3c611b96ff0ecb1c81f4521f8a01573dc",
1753+
"public_receipt": "build/task193/validation-repair-iter1/normal-on/receipt.json",
1754+
"public_receipt_sha256": "04da27c2e278b6d02b5eeb9dac73a31426a8305c1260f6a766a252844fc052ce",
17531755
"public_cases": [
17541756
23,
17551757
23,
@@ -1837,7 +1839,9 @@
18371839
"/usr/lib/python3.12/lib-dynload/_ssl.cpython-312-x86_64-linux-gnu.so"
18381840
]
18391841
}
1840-
}
1842+
},
1843+
"prior_public_receipt": "build/task193/normal-on/public-probe-wd6z5s3j/matrix/receipt.json",
1844+
"prior_public_receipt_sha256": "6fe2d06a8067430a628b37bb06ac58c3c611b96ff0ecb1c81f4521f8a01573dc"
18411845
},
18421846
"asan-off": {
18431847
"unit_commands": "build/task193/asan-off/commands-z_qhx9av",
@@ -2174,8 +2178,8 @@
21742178
"artifact_sha256": "2f18dc40b041b5733e0e200effebfde65c3fb7c34fa5807465fd4f9966416c9a"
21752179
}
21762180
},
2177-
"public_receipt": "build/task193/asan-off/public-probe-maop2szs/matrix/receipt.json",
2178-
"public_receipt_sha256": "4b2e522ead2c3a901784d530a5dde854c569da24ad82d63ac8a12a3c13d3c7ec",
2181+
"public_receipt": "build/task193/validation-repair-iter1/asan-off/receipt.json",
2182+
"public_receipt_sha256": "1cb5f43ab7afc3f051ffc8ffa27198bcd9cecb1012e8b449793e9af8edd1df2d",
21792183
"public_cases": [
21802184
1,
21812185
1,
@@ -2263,7 +2267,9 @@
22632267
"/usr/lib/python3.12/lib-dynload/_ssl.cpython-312-x86_64-linux-gnu.so"
22642268
]
22652269
}
2266-
}
2270+
},
2271+
"prior_public_receipt": "build/task193/asan-off/public-probe-maop2szs/matrix/receipt.json",
2272+
"prior_public_receipt_sha256": "4b2e522ead2c3a901784d530a5dde854c569da24ad82d63ac8a12a3c13d3c7ec"
22672273
},
22682274
"asan-on": {
22692275
"unit_commands": "build/task193/asan-on/commands-kmc8z0fq",
@@ -2820,8 +2826,8 @@
28202826
"artifact_sha256": "1df8a31f88c1e82ee2eaaa931d07f0a732d3907db824efbd1fd7a7bd087dbf64"
28212827
}
28222828
},
2823-
"public_receipt": "build/task193/asan-on/public-probe-ly4e3f6y/matrix/receipt.json",
2824-
"public_receipt_sha256": "81bb05a206d80bda4987747ca3b7e827eb1077465b99c0779387b0a4e1dc7a0a",
2829+
"public_receipt": "build/task193/validation-repair-iter1/asan-on/receipt.json",
2830+
"public_receipt_sha256": "6e31be326cbc286eb707f8a3e929483d1f1d0412ae957ae9efc07b77fc9b983d",
28252831
"public_cases": [
28262832
23,
28272833
23,
@@ -2909,7 +2915,9 @@
29092915
"/usr/lib/python3.12/lib-dynload/_ssl.cpython-312-x86_64-linux-gnu.so"
29102916
]
29112917
}
2912-
}
2918+
},
2919+
"prior_public_receipt": "build/task193/asan-on/public-probe-ly4e3f6y/matrix/receipt.json",
2920+
"prior_public_receipt_sha256": "81bb05a206d80bda4987747ca3b7e827eb1077465b99c0779387b0a4e1dc7a0a"
29132921
},
29142922
"tsan-off": {
29152923
"unit_commands": "build/task193/tsan-off/commands-g63leiov",
@@ -3066,8 +3074,8 @@
30663074
"artifact_sha256": "4e5d21743b811cd6cd4f9ee7329c1a5559b1ea42bff2e8f4638a378aa4df1f2d"
30673075
}
30683076
},
3069-
"public_receipt": "build/task193/tsan-off/public-probe-xjvjqzto/matrix/receipt.json",
3070-
"public_receipt_sha256": "b256bbea05df92e7c215dae18269eb9ef8f635682fc54e663ba0b42a50735b82",
3077+
"public_receipt": "build/task193/validation-repair-iter1/tsan-off/receipt.json",
3078+
"public_receipt_sha256": "e4e975dee8b1e400b153f3313893487a5272bc01225bfd62fa05a596fc0e3882",
30713079
"public_cases": [
30723080
1,
30733081
1,
@@ -3155,7 +3163,9 @@
31553163
"/usr/lib/python3.12/lib-dynload/_ssl.cpython-312-x86_64-linux-gnu.so"
31563164
]
31573165
}
3158-
}
3166+
},
3167+
"prior_public_receipt": "build/task193/tsan-off/public-probe-xjvjqzto/matrix/receipt.json",
3168+
"prior_public_receipt_sha256": "b256bbea05df92e7c215dae18269eb9ef8f635682fc54e663ba0b42a50735b82"
31593169
},
31603170
"tsan-on": {
31613171
"unit_commands": "build/task193/tsan-on/commands-5ytyyn2n",
@@ -3400,8 +3410,8 @@
34003410
"artifact_sha256": "113b027601794f3368583ca52eeb13932ce6b2e254afcf3a3e7fd6002adcd237"
34013411
}
34023412
},
3403-
"public_receipt": "build/task193/tsan-on/public-probe-x8583v2y/matrix/receipt.json",
3404-
"public_receipt_sha256": "615e00aa2d3a93dbc7804cd318ad630e39ca04e74ca31703d7744d954cf779ea",
3413+
"public_receipt": "build/task193/validation-repair-iter1/tsan-on/receipt.json",
3414+
"public_receipt_sha256": "d41660f7c3b3f85d9e63c6ae615b58f6422e48d91623e6574b5f8a5959bbb3fa",
34053415
"public_cases": [
34063416
23,
34073417
23,
@@ -3489,10 +3499,12 @@
34893499
"/usr/lib/python3.12/lib-dynload/_ssl.cpython-312-x86_64-linux-gnu.so"
34903500
]
34913501
}
3492-
}
3502+
},
3503+
"prior_public_receipt": "build/task193/tsan-on/public-probe-x8583v2y/matrix/receipt.json",
3504+
"prior_public_receipt_sha256": "615e00aa2d3a93dbc7804cd318ad630e39ca04e74ca31703d7744d954cf779ea"
34933505
}
34943506
},
3495-
"source_identity": "4636d82aaa09450792d08b48e65efa9e47be9f3697c1d432aab2ef16d62ab2ba",
3507+
"source_identity": "59192a2aeadc8eb86bdc7b8c8a87ab519040e294fc649b96aba92b41bd759bb6",
34963508
"package": {
34973509
"summary": {
34983510
"status": "passed",
@@ -3519,5 +3531,17 @@
35193531
"public_helper_sha256": "7bc84b312732940fd1079ba4b56a6c19f1d030daef57d80129ba966bf4d27f94"
35203532
},
35213533
"worktree_path": "/home/etr/progs/libhttpserver/.worktrees/TASK-193",
3522-
"nonlocal_checks": "BSD/macOS/Windows execution deferred to CI and v3 PR under AGENTS.md"
3534+
"nonlocal_checks": "BSD/macOS/Windows execution deferred to CI and v3 PR under AGENTS.md",
3535+
"validation_repairs": {
3536+
"iteration": 1,
3537+
"summary": "build/task193/validation-repair-iter1/summary.json",
3538+
"summary_sha256": "c6b1d6d8e19e791c7fdbfe75d9d827e50572cac068c81cba69cd72c0fcafd63b",
3539+
"mutations": "build/task193/validation-repair-iter1/mutations.json",
3540+
"mutations_sha256": "ceef2f37d409c43dfce57b63653cf32447bc65dff1b43429e5eb6fe981b7e9b2",
3541+
"checks": "build/task193/validation-repair-iter1/contracts/commands.json",
3542+
"checks_sha256": "404eb578be91af239746bb69c21133fc0804402da40c465cd4294a9c5a18c59f",
3543+
"public_cells": 24,
3544+
"tls_on_scenarios_per_cell": 23,
3545+
"reuse": "Unchanged production/lifecycle suite logs verified against original hashes; installed library hashes match original lane receipts. Package/layout/distribution receipts remain original evidence for unchanged packaging declarations."
3546+
}
35233547
}

‎specs/tasks/M14-v3-release-repairs/TASK-193.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@
2525
- Blocks: TASK-194, TASK-195, TASK-196, TASK-185
2626
**Related Requirements:** PRD-V3N-REQ-001, PRD-V3N-REQ-002, PRD-V3N-REQ-003, PRD-V3N-REQ-004, PRD-V3N-REQ-014, PRD-V3N-REQ-015, PRD-V3N-REQ-016, PRD-V3N-REQ-031, PRD-V3N-REQ-032, PRD-V3N-REQ-034, PRD-V3N-REQ-037.
2727
**Related Decisions:** DR-V3-001, DR-V3-002, DR-V3-004, DR-V3-006, DR-V3-007, DR-V3-008.
28-
**Status:** In Progress
28+
**Status:** Complete
2929

30-
**Implementation evidence:** [TASK-193 local receipts](../../architecture/v3/TASK-193-implementation-evidence.md). Implementation and local gates are complete; caller-owned Groundwork validation, completion status, merge and cleanup remain pending.
30+
**Implementation evidence:** [TASK-193 local receipts](../../architecture/v3/TASK-193-implementation-evidence.md). Implementation and required local gates passed. Groundwork validation passed in two iterations (two test witness repairs, zero unworked findings), session `e5d117530cde55964d9453385b302bba`. Final receipts include 24 installed public cells, six decisive mutation negatives and 61 tooling tests. Immutable archives: `build/task193-evidence/implementation-c5c127df` and `build/task193-evidence/validation-e5d117530cde55964d9453385b302bba`, with SHA256 manifests. Nonlocal platform checks remain assigned to CI and the v3 PR.

‎specs/tasks/_index.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ Nominally: **13 sequential tasks**, each S–XL. Most other tasks parallelize of
340340
| TASK-190 | [Repair HTTP/2 conformance route-effect ordering](M14-v3-release-repairs/TASK-190.md) | M14 | Complete | TASK-189 |
341341
| TASK-191 | [Repair independent HTTP/3 semantic drain completion](M14-v3-release-repairs/TASK-191.md) | M14 | Complete | TASK-190 |
342342
| TASK-192 | [Implement owned v3 cookie helpers and parity witnesses](M14-v3-release-repairs/TASK-192.md) | M14 | Complete | TASK-191 |
343-
| TASK-193 | [Install public credentials and serve native TCP TLS](M14-v3-release-repairs/TASK-193.md) | M14 | In Progress | TASK-192 |
343+
| TASK-193 | [Install public credentials and serve native TCP TLS](M14-v3-release-repairs/TASK-193.md) | M14 | Complete | TASK-192 |
344344
| TASK-194 | [Complete public TLS profiles, live rotation and ACME selection](M14-v3-release-repairs/TASK-194.md) | M14 | Not Started | TASK-193 |
345345
| TASK-195 | [Route negotiated public HTTP/2 streams through native listeners](M14-v3-release-repairs/TASK-195.md) | M14 | Not Started | TASK-190, TASK-194 |
346346
| TASK-196 | [Add production UDP QUIC ownership and public HTTP/3 routing](M14-v3-release-repairs/TASK-196.md) | M14 | Not Started | TASK-191, TASK-193, TASK-195 |

0 commit comments

Comments
 (0)