hyf

Context-aware query service for Radroots
git clone https://radroots.dev/git/hyf.git
Log | Files | Refs | README | LICENSE

test_measurement_contract.mojo (47226B)


      1 """H005A measurement contract tests (ADR-0012 D29, ADR-0014 D34, ADR-0019 D39).
      2 
      3 Drives the governed persistent-process measurement tooling against a real
      4 build of the existing product entry point and against controlled child
      5 processes, proving that the reproduced H005/R56/R57 defects and the period-10
      6 counterexamples now fail the measurement instead of reporting success:
      7 
      8 * MR01 — extra, coalesced, split, unterminated and malformed trailing stdout,
      9   early EOF and a nonzero child exit;
     10 * MR02 — a valid response or exit that arrives after the one work budget, a
     11   sampling subprocess that would outlive it, stderr overflow and a
     12   deadline-bounded EINTR retry;
     13 * MR03 — repeated failing public measurement calls leave no descriptor or
     14   child behind, with successful recovery afterward;
     15 * MR04 — source/binary identity drift rejection, delayed-startup timing and
     16   truthful per-request/instrumentation accounting.
     17 
     18 This module is test-only tooling. It changes no product policy, schema,
     19 dependency or lock.
     20 """
     21 
     22 from std.collections import List
     23 from std.testing import TestSuite, assert_equal, assert_true
     24 
     25 import std.os
     26 from std.pathlib import Path
     27 
     28 from safe_tempdir import SafeTempDir
     29 
     30 from parent_lifecycle import (
     31     CleanupGuard,
     32     now_ms,
     33     open_fd_count_checked,
     34     owned_pid,
     35 )
     36 from stdio_process_helper import (
     37     HYF_PATHS_PROFILE_ENV,
     38     HYF_PATHS_REPO_LOCAL_ROOT_ENV,
     39     ScopedEnvVar,
     40 )
     41 from measurement_process_helper import (
     42     MeasurementFaults,
     43     MeasurementSession,
     44     build_product_binary,
     45     build_status_frame,
     46     child_process_count,
     47     file_sha256,
     48     measure_persistent_process,
     49     measurement_poll,
     50     measurement_poll_retry,
     51     measurement_tooling_files,
     52     require_clean_source,
     53     run_capture,
     54     sample_fd_count,
     55     sample_rss_kb,
     56     sha256_file_set,
     57     source_identity,
     58     source_manifest_sha256,
     59     tooling_manifest_sha256,
     60     validate_status_frame,
     61 )
     62 from json import Value, loads
     63 
     64 from hyf_core.request_context import default_request_context
     65 from hyf_provider.client import post_max_local_chat_completion
     66 from hyf_provider.config import MaxLocalProviderConfig
     67 from hyf_provider.result import parse_query_analysis_from_chat_completion
     68 from hyf_provider.schema import build_query_rewrite_request_body
     69 from max_local_process_helper import spawn_max_local_stub
     70 
     71 
     72 comptime MEASUREMENT_DEADLINE_MS = 120000
     73 comptime WARMUP_FRAMES = 20
     74 comptime MEASURED_FRAMES = 200
     75 
     76 # One valid sys.status response for request/trace index 0.
     77 comptime STATUS0 = (
     78     '{"version":1,"request_id":"meas-status-0","trace_id":"meas-trace-0",'
     79     '"ok":true,"output":{"daemon":"hyfd"}}'
     80 )
     81 comptime WRONG_REVISION = "0000000000000000000000000000000000000000"
     82 comptime WRONG_DIGEST = (
     83     "0000000000000000000000000000000000000000000000000000000000000000"
     84 )
     85 
     86 
     87 def _one_response() -> String:
     88     """A well-behaved responder: answer exactly one request, then consume the
     89     rest of stdin until EOF so the child exits cleanly and closes stdout.
     90     """
     91     return (
     92         "IFS= read -r line; printf '%s\\n' '"
     93         + STATUS0
     94         + "'; while IFS= read -r line; do :; done"
     95     )
     96 
     97 
     98 def _sh(args_text: String) -> List[String]:
     99     var args = List[String]()
    100     args.append("-c")
    101     args.append(args_text)
    102     return args^
    103 
    104 
    105 def _multi_response() -> String:
    106     """A well-behaved responder for any frame count.
    107 
    108     Request ids/trace ids are deterministic (``meas-status-<index>``), so a
    109     counter reproduces the exact expected correlation for each frame in order.
    110     """
    111     return (
    112         "i=0\n"
    113         "while IFS= read -r line; do\n"
    114         'printf \'{"version":1,"request_id":"meas-status-%s",'
    115         '"trace_id":"meas-trace-%s","ok":true,'
    116         '"output":{"daemon":"hyfd"}}\\n\' "$i" "$i"\n'
    117         "i=$((i+1))\n"
    118         "done"
    119     )
    120 
    121 
    122 def _run_sh_measurement(
    123     args_text: String,
    124     warmup: Int,
    125     measured: Int,
    126     mut guard: CleanupGuard,
    127     rss_sampler: String = "ps",
    128     fd_sampler: String = "lsof",
    129     deadline_ms: Int = MEASUREMENT_DEADLINE_MS,
    130     faults: MeasurementFaults = MeasurementFaults(),
    131 ) raises -> MeasurementSession:
    132     var argv = _sh(args_text)
    133     return measure_persistent_process(
    134         ".",
    135         "/bin/sh",
    136         argv^,
    137         warmup,
    138         measured,
    139         deadline_ms,
    140         guard,
    141         rss_sampler,
    142         fd_sampler,
    143         "",
    144         "",
    145         "",
    146         faults,
    147     )
    148 
    149 
    150 def _run_sh_failure(
    151     args_text: String,
    152     warmup: Int,
    153     measured: Int,
    154     mut guard: CleanupGuard,
    155     rss_sampler: String = "ps",
    156     fd_sampler: String = "lsof",
    157     deadline_ms: Int = MEASUREMENT_DEADLINE_MS,
    158     faults: MeasurementFaults = MeasurementFaults(),
    159 ) -> String:
    160     try:
    161         _ = _run_sh_measurement(
    162             args_text,
    163             warmup,
    164             measured,
    165             guard,
    166             rss_sampler,
    167             fd_sampler,
    168             deadline_ms,
    169             faults,
    170         )
    171     except e:
    172         return String(e)
    173     return ""
    174 
    175 
    176 def _failing_hasher(root: String, mut guard: CleanupGuard) raises -> String:
    177     """Owned hasher stand-in that fails without touching live tools or host
    178     settings (ADR-0021 MP01). The script is created inside the isolated owned
    179     temp root and exits 7 with an explicit stage error.
    180     """
    181     var path = root + "/failing-hasher.sh"
    182     Path(path).write_text(
    183         "#!/bin/sh\nprintf 'failing hasher stage\\n' >&2\nexit 7\n"
    184     )
    185     var chmod_args = List[String]()
    186     chmod_args.append("+x")
    187     chmod_args.append(path)
    188     var chmodded = run_capture("chmod", chmod_args^, 20000, guard)
    189     assert_equal(chmodded.exit_code, 0)
    190     return path^
    191 
    192 
    193 def _copy_tooling_files(
    194     root: String, mut guard: CleanupGuard, start: Int = 0
    195 ) raises:
    196     """Copy declared tooling inputs into an isolated owned ``tests`` root.
    197 
    198     ``start`` > 0 deliberately omits the leading declared inputs, producing a
    199     present-but-partial input set for the missing-one-input control.
    200     """
    201     var tests_dir = root + "/tests"
    202     _ = std.os.makedirs(tests_dir, exist_ok=True)
    203     var sources = measurement_tooling_files(".")
    204     assert_true(len(sources) > start + 1)
    205     var cp_args = List[String]()
    206     for index in range(start, len(sources)):
    207         cp_args.append(sources[index])
    208     cp_args.append(tests_dir)
    209     var copied = run_capture("cp", cp_args^, 20000, guard)
    210     assert_equal(copied.exit_code, 0)
    211 
    212 
    213 # ── Positive persistent measurement ─────────────────────────────────────────
    214 
    215 
    216 def test_persistent_measurement_validates_every_frame() raises:
    217     # D29/MR01: one process serves warmup and measured frames; every frame has
    218     # a parsed envelope, matching correlation and expected outcome, the whole
    219     # stream is accounted through EOF, with numeric RSS/FD samples, a checked
    220     # child exit and proved cleanup. The recorded environment profile is the
    221     # verified live profile of the measured child.
    222     var guard = CleanupGuard()
    223     with SafeTempDir() as temp_dir:
    224         with ScopedEnvVar(HYF_PATHS_PROFILE_ENV, "repo_local"):
    225             with ScopedEnvVar(HYF_PATHS_REPO_LOCAL_ROOT_ENV, temp_dir):
    226                 var built = build_product_binary(".", temp_dir, guard)
    227                 assert_equal(built.binary_sha256.byte_length(), 64)
    228                 assert_equal(built.source.dirty_status, "")
    229                 assert_equal(built.source.manifest_sha256.byte_length(), 64)
    230                 assert_true(built.build_ms > 0)
    231                 var argv = List[String]()
    232                 var session = measure_persistent_process(
    233                     ".",
    234                     built.binary_path,
    235                     argv^,
    236                     WARMUP_FRAMES,
    237                     MEASURED_FRAMES,
    238                     MEASUREMENT_DEADLINE_MS,
    239                     guard,
    240                     "ps",
    241                     "lsof",
    242                     built.source.revision,
    243                     built.source.manifest_sha256,
    244                     built.binary_sha256,
    245                 )
    246                 assert_equal(session.ok_frames, WARMUP_FRAMES + MEASURED_FRAMES)
    247                 assert_equal(session.failed_frames, 0)
    248                 assert_equal(session.first_failure, "")
    249                 # Startup is measured from spawn to the first validated
    250                 # response; instrumentation is recorded separately.
    251                 assert_true(session.startup_ms >= 0)
    252                 assert_true(session.startup_wall_ms >= session.startup_ms)
    253                 assert_true(session.startup_sampling_ms >= 0)
    254                 # Measured-phase wall time excludes sampling instrumentation.
    255                 assert_true(session.measured_ms >= 0)
    256                 assert_true(session.measured_wall_ms >= session.measured_ms)
    257                 assert_true(session.measured_sampling_ms >= 0)
    258                 assert_true(session.request_total_ms > 0)
    259                 assert_true(session.request_max_ms >= session.request_min_ms)
    260                 # Numeric sampling with recorded units, method and cadence.
    261                 assert_true(session.rss_kb_before_warmup > 0)
    262                 assert_true(session.rss_kb_after_warmup > 0)
    263                 assert_true(session.rss_kb_after_measured > 0)
    264                 assert_true(session.rss_kb_peak >= session.rss_kb_after_warmup)
    265                 assert_true(session.fd_before_warmup > 0)
    266                 assert_true(session.fd_after_measured > 0)
    267                 assert_true(session.fd_peak >= session.fd_after_measured)
    268                 assert_true(session.sampling_method.find("kB") >= 0)
    269                 assert_true(session.sampling_method.find("-F f") >= 0)
    270                 assert_true(session.sampling_cadence.find("every") >= 0)
    271                 # The declared per-process request policy is characterized, not
    272                 # assumed: the persistent loop does not enforce it.
    273                 assert_equal(session.declared_max_requests_per_process, 1)
    274                 assert_true(session.child_exit.find("exited=0") >= 0)
    275                 assert_true(session.stderr_excerpt == "")
    276                 # Exact, truthful identity: clean verified source/tree plus a
    277                 # deterministic content manifest, binary, pixi files, toolchain,
    278                 # host and the verified environment profile.
    279                 assert_equal(session.identity.binding, "clean_product_tree")
    280                 assert_equal(
    281                     session.identity.binary_sha256, built.binary_sha256
    282                 )
    283                 assert_equal(
    284                     session.identity.source_revision, built.source.revision
    285                 )
    286                 assert_equal(
    287                     session.identity.source_manifest_sha256,
    288                     built.source.manifest_sha256,
    289                 )
    290                 assert_equal(session.identity.source_tree_state, "clean")
    291                 assert_equal(session.identity.source_tree.byte_length(), 40)
    292                 assert_equal(
    293                     session.identity.tooling_manifest_sha256.byte_length(), 64
    294                 )
    295                 assert_equal(
    296                     session.identity.pixi_lock_sha256.byte_length(), 64
    297                 )
    298                 assert_equal(
    299                     session.identity.pixi_toml_sha256.byte_length(), 64
    300                 )
    301                 assert_equal(session.identity.source_revision.byte_length(), 40)
    302                 assert_true(session.identity.cwd.find("oss/hyf") >= 0)
    303                 assert_true(
    304                     session.identity.env_profile.find(
    305                         "HYF_PATHS_PROFILE=repo_local"
    306                     )
    307                     >= 0
    308                 )
    309                 assert_true(session.identity.env_profile.find(temp_dir) >= 0)
    310                 assert_true(session.identity.toolchain_version != "")
    311                 assert_true(
    312                     session.identity.host_platform.find("Darwin") >= 0
    313                     or session.identity.host_platform.find("Linux") >= 0
    314                 )
    315                 assert_true(
    316                     session.summary().find(
    317                         "frames=" + String(WARMUP_FRAMES + MEASURED_FRAMES)
    318                     )
    319                     >= 0
    320                 )
    321     guard.assert_clean()
    322 
    323 
    324 def test_measurement_identity_drift_is_rejected() raises:
    325     # MR04: a product measurement must reject a binary/source binding that does
    326     # not match the observed clean source identity.
    327     var guard = CleanupGuard()
    328     var message = ""
    329     with SafeTempDir() as temp_dir:
    330         var built = build_product_binary(".", temp_dir, guard)
    331         var wrong_revision = WRONG_REVISION
    332         var argv = List[String]()
    333         try:
    334             _ = measure_persistent_process(
    335                 ".",
    336                 built.binary_path,
    337                 argv^,
    338                 0,
    339                 1,
    340                 MEASUREMENT_DEADLINE_MS,
    341                 guard,
    342                 "ps",
    343                 "lsof",
    344                 wrong_revision,
    345                 built.source.manifest_sha256,
    346                 built.binary_sha256,
    347             )
    348         except e:
    349             message = String(e)
    350     assert_true(message.find("drift") >= 0)
    351     guard.assert_clean()
    352 
    353 
    354 def test_measurement_rejects_wrong_binary_digest() raises:
    355     # MR04: the recorded binary digest is enforced, not merely recorded.
    356     var guard = CleanupGuard()
    357     var message = ""
    358     with SafeTempDir() as temp_dir:
    359         var built = build_product_binary(".", temp_dir, guard)
    360         var argv = List[String]()
    361         try:
    362             _ = measure_persistent_process(
    363                 ".",
    364                 built.binary_path,
    365                 argv^,
    366                 0,
    367                 1,
    368                 MEASUREMENT_DEADLINE_MS,
    369                 guard,
    370                 "ps",
    371                 "lsof",
    372                 built.source.revision,
    373                 built.source.manifest_sha256,
    374                 WRONG_DIGEST,
    375             )
    376         except e:
    377             message = String(e)
    378     assert_true(message.find("binary drift") >= 0)
    379     guard.assert_clean()
    380 
    381 
    382 def test_measurement_reports_delayed_startup() raises:
    383     # MR04: startup timing is spawn-relative and truthful, so a deliberately
    384     # delayed child is observed as such rather than as a near-zero value.
    385     var guard = CleanupGuard()
    386     var session = _run_sh_measurement(
    387         "sleep 0.3; " + _one_response(), 0, 1, guard
    388     )
    389     assert_equal(session.ok_frames, 1)
    390     assert_true(session.startup_ms >= 200)
    391     assert_true(session.startup_wall_ms >= session.startup_ms)
    392     guard.assert_clean()
    393 
    394 
    395 def test_measurement_sampling_is_numeric_and_units_are_recorded() raises:
    396     # D29: the sampler must return real numeric values with explicit
    397     # unavailability, never a placeholder.
    398     var guard = CleanupGuard()
    399     var self_pid = owned_pid()
    400     var rss = sample_rss_kb(self_pid, "ps", guard)
    401     assert_true(rss > 0)
    402     var fds = sample_fd_count(self_pid, "lsof", guard)
    403     assert_true(fds > 0)
    404     guard.assert_clean()
    405 
    406 
    407 comptime ANALYSIS_JSON_TEXT = (
    408     '{"original_text":"eggs near me",'
    409     '"normalized_text":"eggs near me",'
    410     '"rewritten_text":"eggs",'
    411     '"query_terms":["eggs"],'
    412     '"normalization_signals":["local_intent_detected"],'
    413     '"ranking_hints":["prefer_local_results"],'
    414     '"extracted_filters":{'
    415     '"local_intent":true,'
    416     '"fulfillment":"unspecified",'
    417     '"time_window":"unspecified"'
    418     "}}"
    419 )
    420 
    421 
    422 def test_direct_provider_request_and_client_schema_characterization() raises:
    423     # D29/MR04: distinguish startup, a deterministic daemon request, a direct
    424     # local provider request and connection counts, and characterize
    425     # client/schema construction with numeric recorded values and source
    426     # evidence. The Morph daemon-assisted path is out of scope here and remains
    427     # an explicit H024 obligation.
    428     var guard = CleanupGuard()
    429     var stub_start = now_ms()
    430     with spawn_max_local_stub(0, "count_requests", 1, guard) as stub:
    431         var stub_startup_ms = now_ms() - stub_start
    432         assert_true(stub_startup_ms >= 0)
    433         var config = MaxLocalProviderConfig(
    434             base_url="http://127.0.0.1:" + String(stub.port) + "/v1/",
    435             health_url="http://127.0.0.1:" + String(stub.port) + "/health",
    436             model="max-local-query-rewrite",
    437             request_timeout_ms=15000,
    438         )
    439         var context = default_request_context()
    440         context.return_provenance = True
    441         var construct_start = now_ms()
    442         var body = build_query_rewrite_request_body(
    443             config, "eggs near me", context
    444         )
    445         var construct_ms = now_ms() - construct_start
    446         # Schema construction is deterministic and source-verifiable, with a
    447         # numeric field/message count that is recorded rather than asserted as
    448         # a bare non-negative duration.
    449         assert_true(construct_ms >= 0)
    450         assert_true(body.object_count() > 0)
    451         assert_equal(body["messages"].array_count(), 2)
    452         assert_equal(body["model"].string_value(), "max-local-query-rewrite")
    453         assert_equal(body["messages"][0]["role"].string_value(), "system")
    454         assert_equal(body["messages"][1]["role"].string_value(), "user")
    455         assert_equal(
    456             body["response_format"]["type"].string_value(), "json_schema"
    457         )
    458         assert_equal(
    459             body["response_format"]["json_schema"]["name"].string_value(),
    460             "query_rewrite",
    461         )
    462         # One direct provider request over one verified connection, with a
    463         # numeric elapsed time that is asserted to be a plausible positive
    464         # measurement.
    465         var request_start = now_ms()
    466         var outcome = post_max_local_chat_completion(config, body)
    467         var request_ms = now_ms() - request_start
    468         assert_true(not outcome.failure)
    469         assert_true(request_ms >= 0)
    470         stub.wait()
    471         assert_equal(stub.request_count(), 1)
    472         assert_equal(stub.connection_count(), 1)
    473     # Client-side response parsing is also deterministic.
    474     var response = loads("{}")
    475     var choices = loads("[]")
    476     var choice = loads("{}")
    477     var message = loads("{}")
    478     message.set("content", Value(ANALYSIS_JSON_TEXT))
    479     choice.set("message", message)
    480     choices.append(choice)
    481     response.set("choices", choices)
    482     var analysis = parse_query_analysis_from_chat_completion(response)
    483     assert_equal(analysis.original_text, "eggs near me")
    484     assert_equal(analysis.rewritten_text, "eggs")
    485     assert_equal(len(analysis.query_terms), 1)
    486     guard.assert_clean()
    487 
    488 
    489 def test_measurement_poll_eintr_is_deadline_bounded() raises:
    490     # MR02: a real poll EINTR is retried but can never outlive the budget.
    491     var start = now_ms()
    492     var pr = measurement_poll_retry(-1, 0, -1, 0, -1, 0, 60, 1)
    493     var elapsed = now_ms() - start
    494     assert_true(pr.interrupted)
    495     assert_true(elapsed >= 50)
    496     assert_true(elapsed < 2000)
    497     # An ordinary no-readiness poll is not misclassified as interrupted.
    498     var quiet = measurement_poll(-1, 0, -1, 0, -1, 0, 0)
    499     assert_equal(quiet.count, 0)
    500     assert_true(not quiet.interrupted)
    501 
    502 
    503 # ── R56/R57/R69 counterexamples must fail the measurement ───────────────────
    504 
    505 
    506 def test_measurement_rejects_not_json_response() raises:
    507     var guard = CleanupGuard()
    508     var message = _run_sh_failure(
    509         "while IFS= read -r line; do printf 'not-json\\n'; done",
    510         0,
    511         2,
    512         guard,
    513     )
    514     assert_true(message.find("not_json") >= 0)
    515     guard.assert_clean()
    516 
    517 
    518 def test_measurement_rejects_wrong_correlation() raises:
    519     var guard = CleanupGuard()
    520     var message = _run_sh_failure(
    521         (
    522             "while IFS= read -r line; do printf '%s\\n' "
    523             '\'{"version":1,"request_id":"wrong","trace_id":"wrong",'
    524             '"ok":true,"output":{"daemon":"hyfd"}}\'; done'
    525         ),
    526         0,
    527         2,
    528         guard,
    529     )
    530     assert_true(message.find("correlation_mismatch") >= 0)
    531     guard.assert_clean()
    532 
    533 
    534 def test_measurement_rejects_unterminated_response() raises:
    535     var guard = CleanupGuard()
    536     var message = _run_sh_failure(
    537         (
    538             "IFS= read -r line; printf '%s' "
    539             '\'{"version":1,"request_id":"meas-status-0",'
    540             '"trace_id":"meas-trace-0","ok":true,'
    541             '"output":{"daemon":"hyfd"}}\'; exit 0'
    542         ),
    543         0,
    544         1,
    545         guard,
    546     )
    547     assert_true(message.find("newline-terminated") >= 0)
    548     guard.assert_clean()
    549 
    550 
    551 def test_measurement_rejects_extra_response_frame() raises:
    552     # MR01/R69: an extra unvalidated frame after the expected response must
    553     # fail, not be reported as success.
    554     var guard = CleanupGuard()
    555     var message = _run_sh_failure(
    556         (
    557             "IFS= read -r line; printf '%s\\n%s\\n' '"
    558             + STATUS0
    559             + "' 'EXTRA_UNVALIDATED_FRAME'; while IFS= read -r line; do :; done"
    560         ),
    561         0,
    562         1,
    563         guard,
    564     )
    565     assert_true(message.find("unexpected trailing stdout") >= 0)
    566     guard.assert_clean()
    567 
    568 
    569 def test_measurement_rejects_coalesced_trailing_frame() raises:
    570     # MR01: two frames arriving in the same read chunk are still two frames.
    571     var guard = CleanupGuard()
    572     var message = _run_sh_failure(
    573         (
    574             "IFS= read -r line; printf '%s\\n%s\\n' '"
    575             + STATUS0
    576             + "' '"
    577             + STATUS0
    578             + "'; while IFS= read -r line; do :; done"
    579         ),
    580         0,
    581         1,
    582         guard,
    583     )
    584     assert_true(message.find("unexpected trailing stdout") >= 0)
    585     guard.assert_clean()
    586 
    587 
    588 def test_measurement_rejects_trailing_malformed_bytes() raises:
    589     # MR01: trailing bytes without a complete frame are a bounded failure.
    590     var guard = CleanupGuard()
    591     var message = _run_sh_failure(
    592         (
    593             "IFS= read -r line; printf '%s\\n' '"
    594             + STATUS0
    595             + "'; printf 'garbage'; while IFS= read -r line; do :; done"
    596         ),
    597         0,
    598         1,
    599         guard,
    600     )
    601     assert_true(message.find("unexpected trailing stdout") >= 0)
    602     guard.assert_clean()
    603 
    604 
    605 def test_measurement_rejects_unterminated_trailing_frame() raises:
    606     # MR01: a second frame that never terminates is not silently ignored.
    607     var guard = CleanupGuard()
    608     var message = _run_sh_failure(
    609         (
    610             "IFS= read -r line; printf '%s\\n' '"
    611             + STATUS0
    612             + "'; printf '{\"partial\":true';"
    613             " while IFS= read -r line; do :; done"
    614         ),
    615         0,
    616         1,
    617         guard,
    618     )
    619     assert_true(message.find("unexpected trailing stdout") >= 0)
    620     guard.assert_clean()
    621 
    622 
    623 def test_measurement_rejects_failed_child() raises:
    624     var guard = CleanupGuard()
    625     var message = _run_sh_failure(
    626         (
    627             "while IFS= read -r line; do printf '%s\\n' "
    628             '\'{"version":1,"request_id":"meas-status-0",'
    629             '"trace_id":"meas-trace-0","ok":true,'
    630             '"output":{"daemon":"hyfd"}}\'; done; exit 17'
    631         ),
    632         0,
    633         1,
    634         guard,
    635     )
    636     assert_true(message.find("nonzero") >= 0)
    637     guard.assert_clean()
    638 
    639 
    640 def test_measurement_rejects_early_eof_child() raises:
    641     # A child that never answers and closes its stream must fail as an early
    642     # EOF, not be read as a successful empty response.
    643     var guard = CleanupGuard()
    644     var message = _run_sh_failure("sleep 1; exit 0", 0, 1, guard)
    645     assert_true(message.find("early_eof") >= 0)
    646     guard.assert_clean()
    647 
    648 
    649 # ── MR02 work-budget and pressure controls ──────────────────────────────────
    650 
    651 
    652 def test_measurement_rejects_late_response_after_budget() raises:
    653     # MR02: a valid response that arrives after the one work budget is not
    654     # accepted as a late success.
    655     var guard = CleanupGuard()
    656     var message = _run_sh_failure(
    657         "sleep 2; " + _one_response(), 0, 1, guard, "ps", "lsof", 400
    658     )
    659     assert_true(message.find("work_deadline_expired") >= 0)
    660     guard.assert_clean()
    661 
    662 
    663 def test_measurement_rejects_late_exit_after_budget() raises:
    664     # MR02: complete and valid output does not rescue a child that keeps the
    665     # stream open past the work budget.
    666     var guard = CleanupGuard()
    667     var message = _run_sh_failure(
    668         (
    669             "while IFS= read -r line; do printf '%s\\n' '"
    670             + STATUS0
    671             + "'; done; sleep 2"
    672         ),
    673         0,
    674         1,
    675         guard,
    676         "ps",
    677         "lsof",
    678         400,
    679     )
    680     assert_true(message.find("work_deadline_expired") >= 0)
    681     guard.assert_clean()
    682 
    683 
    684 def test_measurement_rejects_slow_sampling_past_budget() raises:
    685     # MR02: a sampling subprocess consumes the remaining work budget and can
    686     # never extend the measured window.
    687     var guard = CleanupGuard()
    688     with SafeTempDir() as temp_dir:
    689         var script = temp_dir + "/slow_sampler.sh"
    690         var mk = List[String]()
    691         mk.append("-c")
    692         mk.append(
    693             "printf '#!/bin/sh\\nsleep 4\\necho 17\\n' > '"
    694             + script
    695             + "'; chmod +x '"
    696             + script
    697             + "'"
    698         )
    699         var made = run_capture("sh", mk^, 10000, guard)
    700         assert_equal(made.exit_code, 0)
    701         var message = _run_sh_failure(
    702             _one_response(), 0, 1, guard, script, "lsof", 1500
    703         )
    704         assert_true(
    705             message.find("sample_deadline_expired") >= 0
    706             or message.find("work_deadline_expired") >= 0
    707         )
    708     guard.assert_clean()
    709 
    710 
    711 def test_measurement_rejects_stderr_overflow() raises:
    712     # MR02: stderr pressure past the cap fails explicitly instead of being
    713     # silently dropped.
    714     var guard = CleanupGuard()
    715     var message = _run_sh_failure(
    716         (
    717             "IFS= read -r line; printf '%s\\n' '"
    718             + STATUS0
    719             + "'; head -c 200000 /dev/zero | tr '\\0' 'x' 1>&2;"
    720             " while IFS= read -r line; do :; done"
    721         ),
    722         0,
    723         1,
    724         guard,
    725     )
    726     assert_true(message.find("stderr_overflow") >= 0)
    727     guard.assert_clean()
    728 
    729 
    730 def test_measurement_rejects_stderr_read_error() raises:
    731     # MR02: a stderr read error fails explicitly instead of disappearing.
    732     var guard = CleanupGuard()
    733     var message = _run_sh_failure(
    734         (
    735             "IFS= read -r line; printf '%s\\n' '"
    736             + STATUS0
    737             + "'; printf 'x' 1>&2; while IFS= read -r line; do :; done"
    738         ),
    739         0,
    740         1,
    741         guard,
    742         "ps",
    743         "lsof",
    744         MEASUREMENT_DEADLINE_MS,
    745         MeasurementFaults(stderr_read_errors=1),
    746     )
    747     assert_true(message.find("stderr read_error") >= 0)
    748     guard.assert_clean()
    749 
    750 
    751 def test_measurement_unproved_cleanup_is_retained_and_recovered() raises:
    752     # MR03: an unproved cleanup keeps exact retryable ownership and surfaces to
    753     # the caller; recovery against the real owned child then succeeds with no
    754     # descriptor/child leak. The bounded seam leaves the real child running.
    755     var guard = CleanupGuard()
    756     var self_pid = owned_pid()
    757     var child_before = child_process_count(self_pid, guard)
    758     var fd_before = open_fd_count_checked()
    759     var message = _run_sh_failure(
    760         "while IFS= read -r line; do printf 'not-json\\n'; done",
    761         0,
    762         1,
    763         guard,
    764         "ps",
    765         "lsof",
    766         MEASUREMENT_DEADLINE_MS,
    767         MeasurementFaults(cleanup_failures=1),
    768     )
    769     assert_true(message.find("not_json") >= 0)
    770     assert_true(guard.pending() >= 1)
    771     assert_true(guard.retained() >= 1)
    772     assert_equal(guard.recover_all(), 0)
    773     guard.assert_clean()
    774     assert_equal(open_fd_count_checked() - fd_before, 0)
    775     assert_equal(child_process_count(self_pid, guard), child_before)
    776 
    777 
    778 def test_measurement_rejects_unavailable_rss_sampler() raises:
    779     var guard = CleanupGuard()
    780     var message = _run_sh_failure(
    781         "while IFS= read -r line; do printf '%s\\n' ok; done",
    782         0,
    783         1,
    784         guard,
    785         "hyf-no-such-rss-sampler",
    786     )
    787     assert_true(message.find("rss sampling unavailable") >= 0)
    788     guard.assert_clean()
    789 
    790 
    791 def test_measurement_rejects_unavailable_fd_sampler() raises:
    792     var guard = CleanupGuard()
    793     var message = _run_sh_failure(
    794         "while IFS= read -r line; do printf '%s\\n' ok; done",
    795         0,
    796         1,
    797         guard,
    798         "ps",
    799         "hyf-no-such-fd-sampler",
    800     )
    801     assert_true(message.find("descriptor sampling unavailable") >= 0)
    802     guard.assert_clean()
    803 
    804 
    805 def test_measurement_rejects_invalid_frame_counts() raises:
    806     var guard = CleanupGuard()
    807     var message = _run_sh_failure("exit 0", 0, 0, guard)
    808     assert_true(message.find("invalid warmup/measured") >= 0)
    809     guard.assert_clean()
    810 
    811 
    812 # ── MR03 exact resource ownership ───────────────────────────────────────────
    813 
    814 
    815 def test_measurement_repeated_failures_leak_nothing() raises:
    816     # MR03: repeated failing public measurement calls must leave no descriptor
    817     # or child behind, and a subsequent supported call must still succeed.
    818     var guard = CleanupGuard()
    819     var self_pid = owned_pid()
    820     var child_before = child_process_count(self_pid, guard)
    821     var fd_before = open_fd_count_checked()
    822     for index in range(4):
    823         var message = _run_sh_failure(
    824             "while IFS= read -r line; do printf 'not-json\\n'; done",
    825             0,
    826             1,
    827             guard,
    828         )
    829         assert_true(message.find("not_json") >= 0)
    830         guard.assert_clean()
    831     var fd_after = open_fd_count_checked()
    832     assert_equal(fd_after - fd_before, 0)
    833     assert_equal(child_process_count(self_pid, guard), child_before)
    834     var recovered = _run_sh_measurement(_one_response(), 0, 1, guard)
    835     assert_equal(recovered.ok_frames, 1)
    836     assert_equal(recovered.failed_frames, 0)
    837     guard.assert_clean()
    838 
    839 
    840 # ── Direct correlation validation unit controls ─────────────────────────────
    841 
    842 
    843 def test_frame_validation_controls() raises:
    844     var pair = build_status_frame(7)
    845     var frame = pair[0]
    846     var request_id = pair[1]
    847     var trace_id = pair[2]
    848     assert_true(frame.find('"request_id":"meas-status-7"') >= 0)
    849     var good = (
    850         '{"version":1,"request_id":"'
    851         + request_id
    852         + '","trace_id":"'
    853         + trace_id
    854         + '","ok":true,"output":{"daemon":"hyfd",'
    855         + '"limits":{"max_requests_per_process":1}}}'
    856     )
    857     var verdict = validate_status_frame(good, request_id, trace_id)
    858     assert_true(verdict.ok)
    859     assert_equal(verdict.outcome, "sys.status_ok")
    860     assert_equal(verdict.declared_max_requests, 1)
    861     assert_equal(
    862         validate_status_frame("nope", request_id, trace_id).reason, "not_json"
    863     )
    864     assert_equal(
    865         validate_status_frame(
    866             '{"version":2,"request_id":"'
    867             + request_id
    868             + '","trace_id":"'
    869             + trace_id
    870             + '","ok":true}',
    871             request_id,
    872             trace_id,
    873         ).reason,
    874         "version_mismatch",
    875     )
    876     assert_equal(
    877         validate_status_frame(
    878             '{"version":1,"request_id":"other","trace_id":"'
    879             + trace_id
    880             + '","ok":true}',
    881             request_id,
    882             trace_id,
    883         ).reason,
    884         "correlation_mismatch",
    885     )
    886     assert_equal(
    887         validate_status_frame(
    888             '{"version":1,"request_id":"'
    889             + request_id
    890             + '","trace_id":"'
    891             + trace_id
    892             + '","ok":false}',
    893             request_id,
    894             trace_id,
    895         ).reason,
    896         "not_ok",
    897     )
    898     assert_equal(
    899         validate_status_frame(
    900             '{"version":1,"request_id":"'
    901             + request_id
    902             + '","trace_id":"'
    903             + trace_id
    904             + '","ok":true,"error":{}}',
    905             request_id,
    906             trace_id,
    907         ).reason,
    908         "unexpected_error",
    909     )
    910     assert_equal(
    911         validate_status_frame(
    912             '{"version":1,"request_id":"'
    913             + request_id
    914             + '","trace_id":"'
    915             + trace_id
    916             + '","ok":true,"output":{"daemon":"other"}}',
    917             request_id,
    918             trace_id,
    919         ).reason,
    920         "outcome_mismatch",
    921     )
    922 
    923 
    924 # ── MC01 corrected timing windows ───────────────────────────────────────────
    925 
    926 
    927 def test_measurement_zero_warmup_timing_is_initialized() raises:
    928     # ADR-0020 MC01: a zero-warmup measurement must open a bounded measured wall
    929     # interval before its first request. The period-11 defect left the start
    930     # uninitialized, so an 804 ms run reported 347472213 ms (host uptime).
    931     var guard = CleanupGuard()
    932     var session = _run_sh_measurement(_one_response(), 0, 1, guard)
    933     assert_equal(session.warmup_frames, 0)
    934     assert_equal(session.ok_frames, 1)
    935     assert_equal(session.warmup_ms, 0)
    936     assert_true(session.measured_wall_ms >= 0)
    937     assert_true(session.measured_wall_ms <= session.run_wall_ms)
    938     assert_true(session.measured_ms >= 0)
    939     assert_true(session.measured_sampling_ms >= 0)
    940     assert_true(session.measured_ms <= session.measured_wall_ms)
    941     assert_equal(session.accounting_error_ms(), 0)
    942     assert_true(session.rss_kb_after_warmup > 0)
    943     guard.assert_clean()
    944 
    945 
    946 def test_measurement_positive_warmup_timing_accounting() raises:
    947     # ADR-0020 MC01: with a positive warmup the boundary instrumentation is
    948     # taken before the measured interval opens and must not be subtracted from
    949     # the instrumentation total afterwards (that overstated measured time).
    950     var guard = CleanupGuard()
    951     var session = _run_sh_measurement(_multi_response(), 3, 2, guard)
    952     assert_equal(session.warmup_frames, 3)
    953     assert_equal(session.ok_frames, 5)
    954     assert_true(session.warmup_ms >= 0)
    955     assert_true(session.measured_wall_ms >= 0)
    956     assert_true(session.measured_wall_ms <= session.run_wall_ms)
    957     assert_true(session.measured_sampling_ms >= 0)
    958     assert_true(session.measured_ms >= 0)
    959     assert_true(session.measured_ms <= session.measured_wall_ms)
    960     assert_equal(session.accounting_error_ms(), 0)
    961     guard.assert_clean()
    962 
    963 
    964 def test_measurement_known_delayed_request_is_observed() raises:
    965     # ADR-0020 MC01: a known delayed request is reflected in both the per-request
    966     # timing and the measured wall interval, which stay internally consistent.
    967     var guard = CleanupGuard()
    968     var delayed = (
    969         "IFS= read -r line; sleep 0.15; printf '%s\\n' '"
    970         + STATUS0
    971         + "'; while IFS= read -r line; do :; done"
    972     )
    973     var session = _run_sh_measurement(delayed, 0, 1, guard)
    974     assert_equal(session.ok_frames, 1)
    975     assert_true(session.request_total_ms >= 100)
    976     assert_true(session.request_max_ms >= 100)
    977     assert_true(session.measured_wall_ms >= 100)
    978     assert_true(session.measured_wall_ms <= session.run_wall_ms)
    979     assert_true(session.measured_ms >= 0)
    980     assert_equal(session.accounting_error_ms(), 0)
    981     guard.assert_clean()
    982 
    983 
    984 def test_measurement_slow_boundary_sampler_is_excluded_once() raises:
    985     # ADR-0020 MC01: a slow after-warmup boundary sampler runs before the
    986     # measured wall interval opens. It must be excluded exactly once: the
    987     # period-11 code subtracted it from the instrumentation total and reported
    988     # more measured time than the interval contained.
    989     var guard = CleanupGuard()
    990     with SafeTempDir() as temp_dir:
    991         var counter = temp_dir + "/calls"
    992         var sampler = temp_dir + "/slow_rss.sh"
    993         var body = (
    994             '#!/bin/sh\nn=$(cat "'
    995             + counter
    996             + '" 2>/dev/null || echo 0)\n'
    997             + "n=$((n+1))\n"
    998             + 'printf \'%s\' "$n" > "'
    999             + counter
   1000             + '"\n'
   1001             + 'if [ "$n" -le 2 ]; then sleep 1.2; fi\n'
   1002             + "echo 17000\n"
   1003         )
   1004         Path(sampler).write_text(body)
   1005         var chmod_args = List[String]()
   1006         chmod_args.append("+x")
   1007         chmod_args.append(sampler)
   1008         var made = run_capture("chmod", chmod_args^, 10000, guard)
   1009         assert_equal(made.exit_code, 0)
   1010         var session = _run_sh_measurement(
   1011             _multi_response(),
   1012             1,
   1013             1,
   1014             guard,
   1015             sampler,
   1016             "lsof",
   1017             MEASUREMENT_DEADLINE_MS,
   1018         )
   1019         assert_equal(session.ok_frames, 2)
   1020         assert_true(session.measured_sampling_ms >= 0)
   1021         assert_true(session.measured_ms >= 0)
   1022         assert_true(session.measured_ms <= session.measured_wall_ms)
   1023         assert_equal(session.accounting_error_ms(), 0)
   1024         # The two 1.2 s boundary samples stayed outside the measured interval.
   1025         assert_true(session.measured_wall_ms < 1000)
   1026     guard.assert_clean()
   1027 
   1028 
   1029 # ── MC02 fail-closed provenance ─────────────────────────────────────────────
   1030 
   1031 
   1032 def test_measurement_tooling_manifest_rejects_missing_inputs() raises:
   1033     # ADR-0020 MC02: a missing tooling input must fail, never return the valid
   1034     # empty-input digest that the period-11 masked pipeline produced.
   1035     var guard = CleanupGuard()
   1036     with SafeTempDir() as temp_dir:
   1037         var message = ""
   1038         try:
   1039             _ = tooling_manifest_sha256(temp_dir + "/absent-root", guard)
   1040         except e:
   1041             message = String(e)
   1042         assert_true(message.find("sha256") >= 0)
   1043         assert_true(message.find("e3b0c442") < 0)
   1044     guard.assert_clean()
   1045 
   1046 
   1047 def test_measurement_digest_rejects_missing_one_input() raises:
   1048     # ADR-0021 MP01: the expressly required missing-one-input control. Seven of
   1049     # the eight declared tooling inputs are present valid regular files and one
   1050     # declared path is absent, so the checked pipeline must fail instead of
   1051     # returning a digest for the partial present set. The all-input-missing and
   1052     # failed-Git controls do not cover this case.
   1053     var guard = CleanupGuard()
   1054     with SafeTempDir() as root:
   1055         _copy_tooling_files(root, guard, 1)
   1056         var expected = tooling_manifest_sha256(".", guard)
   1057         assert_equal(expected.byte_length(), 64)
   1058         var message = ""
   1059         var reported = ""
   1060         try:
   1061             reported = tooling_manifest_sha256(root, guard)
   1062         except e:
   1063             message = String(e)
   1064         assert_true(message.find("sha256") >= 0)
   1065         assert_true(message.find("e3b0c442") < 0)
   1066         # No partial-set digest may be returned as a valid identity.
   1067         assert_true(reported != expected)
   1068         assert_equal(reported, "")
   1069     guard.assert_clean()
   1070 
   1071 
   1072 def test_measurement_digest_rejects_total_hasher_failure() raises:
   1073     # ADR-0021 MP01: the expressly required failed-hasher-command control. All
   1074     # declared inputs are present valid regular files and both checked hasher
   1075     # stages fail, so the pipeline must reject. A different missing/unreadable
   1076     # input would not substitute for this control; the cause text must show the
   1077     # real nonzero hasher exit rather than only an unavailable command.
   1078     var guard = CleanupGuard()
   1079     with SafeTempDir() as root:
   1080         _copy_tooling_files(root, guard)
   1081         var failing = _failing_hasher(root, guard)
   1082         var message = ""
   1083         var reported = ""
   1084         try:
   1085             reported = tooling_manifest_sha256(root, guard, failing, failing)
   1086         except e:
   1087             message = String(e)
   1088         assert_true(message.find("sha256 unavailable") >= 0)
   1089         assert_true(message.find("exited=7") >= 0)
   1090         assert_true(message.find("e3b0c442") < 0)
   1091         assert_equal(reported, "")
   1092     guard.assert_clean()
   1093 
   1094 
   1095 def test_measurement_digest_fallback_hasher_checked_correct() raises:
   1096     # ADR-0021 MP01: when the primary hasher stage fails but the supported
   1097     # fallback succeeds, the result must be the same checked digest as the
   1098     # default path — the fallback may never silently report a partial or empty
   1099     # identity.
   1100     var guard = CleanupGuard()
   1101     with SafeTempDir() as root:
   1102         _copy_tooling_files(root, guard)
   1103         var failing = _failing_hasher(root, guard)
   1104         var expected = tooling_manifest_sha256(root, guard)
   1105         assert_equal(expected.byte_length(), 64)
   1106         var fallback = tooling_manifest_sha256(root, guard, failing)
   1107         assert_equal(fallback.byte_length(), 64)
   1108         assert_true(fallback == expected)
   1109     guard.assert_clean()
   1110 
   1111 
   1112 def test_measurement_source_manifest_rejects_missing_repository() raises:
   1113     # ADR-0020 MC02: a failed git stage must be an error, not an empty digest.
   1114     var guard = CleanupGuard()
   1115     with SafeTempDir() as temp_dir:
   1116         var message = ""
   1117         try:
   1118             _ = source_manifest_sha256(temp_dir, guard)
   1119         except e:
   1120             message = String(e)
   1121         assert_true(message.find("source content manifest") >= 0)
   1122         assert_true(message.find("e3b0c442") < 0)
   1123     guard.assert_clean()
   1124 
   1125 
   1126 def test_measurement_digest_handles_path_characters() raises:
   1127     # ADR-0020 MC02: paths are argv data, so apostrophes and spaces in a path
   1128     # must be handled literally (the period-11 tooling pipeline interpolated
   1129     # paths into a single-quoted shell string and could mis-hash or fail).
   1130     var guard = CleanupGuard()
   1131     with SafeTempDir() as base:
   1132         var weird = base + "/hyf 'quoted' dir"
   1133         _ = std.os.makedirs(weird, exist_ok=True)
   1134         var one = weird + "/a 'one'.txt"
   1135         var two = weird + "/b two.txt"
   1136         Path(one).write_text("alpha")
   1137         Path(two).write_text("beta")
   1138         var files = List[String]()
   1139         files.append(one)
   1140         files.append(two)
   1141         var digest = sha256_file_set("weird path set", files^, guard)
   1142         assert_equal(digest.byte_length(), 64)
   1143         Path(two).write_text("gamma")
   1144         var files_two = List[String]()
   1145         files_two.append(one)
   1146         files_two.append(two)
   1147         var digest_two = sha256_file_set("weird path set", files_two^, guard)
   1148         assert_true(digest != digest_two)
   1149     guard.assert_clean()
   1150 
   1151 
   1152 def test_measurement_tooling_manifest_binds_imported_helpers() raises:
   1153     # ADR-0020 MC02: the tooling identity must bind the imported helper closure,
   1154     # not only the three top-level tooling files. Mutating an *imported* helper
   1155     # in an isolated copy changes the digest.
   1156     var guard = CleanupGuard()
   1157     with SafeTempDir() as root:
   1158         var tests_dir = root + "/tests"
   1159         _ = std.os.makedirs(tests_dir, exist_ok=True)
   1160         var sources = measurement_tooling_files(".")
   1161         var cp_args = List[String]()
   1162         for index in range(len(sources)):
   1163             cp_args.append(sources[index])
   1164         cp_args.append(tests_dir)
   1165         var copied = run_capture("cp", cp_args^, 20000, guard)
   1166         assert_equal(copied.exit_code, 0)
   1167         var before = tooling_manifest_sha256(root, guard)
   1168         assert_equal(before.byte_length(), 64)
   1169         Path(tests_dir + "/parent_lifecycle.mojo").write_text("// mutated\n")
   1170         var after = tooling_manifest_sha256(root, guard)
   1171         assert_true(before != after)
   1172     guard.assert_clean()
   1173 
   1174 
   1175 def test_measurement_rejects_dirty_measured_tree() raises:
   1176     # ADR-0020 MC02/MR04: a dirty measured build input is rejected at capture.
   1177     # The control uses an isolated owned git repository, never the real
   1178     # checkout, and never changes real index or host flags.
   1179     var guard = CleanupGuard()
   1180     with SafeTempDir() as root:
   1181         _ = std.os.makedirs(root + "/src", exist_ok=True)
   1182         Path(root + "/src/main.mojo").write_text("fn main():\n    pass\n")
   1183         Path(root + "/pixi.toml").write_text("[workspace]\n")
   1184         Path(root + "/pixi.lock").write_text("version: 4\n")
   1185         var init_args = List[String]()
   1186         init_args.append("init")
   1187         init_args.append("--quiet")
   1188         var initialized = run_capture("git", init_args^, 20000, guard, root)
   1189         assert_equal(initialized.exit_code, 0)
   1190         var add_args = List[String]()
   1191         add_args.append("add")
   1192         add_args.append("-A")
   1193         var added = run_capture("git", add_args^, 20000, guard, root)
   1194         assert_equal(added.exit_code, 0)
   1195         var commit_args = List[String]()
   1196         commit_args.append("-c")
   1197         commit_args.append("user.email=hyf-test@invalid")
   1198         commit_args.append("-c")
   1199         commit_args.append("user.name=hyf test")
   1200         commit_args.append("-c")
   1201         commit_args.append("commit.gpgsign=false")
   1202         commit_args.append("commit")
   1203         commit_args.append("--no-verify")
   1204         commit_args.append("--quiet")
   1205         commit_args.append("-m")
   1206         commit_args.append("init")
   1207         var committed = run_capture("git", commit_args^, 20000, guard, root)
   1208         assert_equal(committed.exit_code, 0)
   1209         Path(root + "/src/main.mojo").write_text("fn main():\n    return\n")
   1210         var identity = source_identity(root, guard)
   1211         assert_true(identity.dirty_status != "")
   1212         var message = ""
   1213         try:
   1214             require_clean_source(identity, "test capture")
   1215         except e:
   1216             message = String(e)
   1217         assert_true(message.find("dirty") >= 0)
   1218     guard.assert_clean()
   1219 
   1220 
   1221 # ── MC03 isolated late exit and ownership reuse ─────────────────────────────
   1222 
   1223 
   1224 def test_measurement_rejects_isolated_late_child_exit() raises:
   1225     # ADR-0020 MC03: valid output AND closed stdout/stderr must be proved before
   1226     # the late-exit phase. The child answers, closes its own stdout/stderr and
   1227     # then stays alive past the budget, so the bounded failure is the child-exit
   1228     # wait rather than an output-drain timeout.
   1229     var guard = CleanupGuard()
   1230     var script = (
   1231         "while IFS= read -r line; do printf '%s\\n' '"
   1232         + STATUS0
   1233         + "'; done; exec 1>&- 2>&-; sleep 2"
   1234     )
   1235     var message = _run_sh_failure(script, 0, 1, guard, "ps", "lsof", 400)
   1236     assert_true(message.find("did not exit within its budget") >= 0)
   1237     assert_true(message.find("output drain") < 0)
   1238     assert_true(message.find("frame invalid") < 0)
   1239     guard.assert_clean()
   1240 
   1241 
   1242 def test_measurement_recovery_then_valid_call_leaks_nothing() raises:
   1243     # ADR-0020 MC03/R73: after a retained-and-recovered cleanup, a following
   1244     # valid measurement with the same guard must not skip closing a descriptor
   1245     # number that was reused. The period-11 probe observed FD delta +1 here.
   1246     var guard = CleanupGuard()
   1247     var self_pid = owned_pid()
   1248     var child_before = child_process_count(self_pid, guard)
   1249     var fd_before = open_fd_count_checked()
   1250     var message = _run_sh_failure(
   1251         "while IFS= read -r line; do printf 'not-json\\n'; done",
   1252         0,
   1253         1,
   1254         guard,
   1255         "ps",
   1256         "lsof",
   1257         MEASUREMENT_DEADLINE_MS,
   1258         MeasurementFaults(cleanup_failures=1),
   1259     )
   1260     assert_true(message.find("not_json") >= 0)
   1261     assert_true(guard.retained() >= 1)
   1262     assert_equal(guard.recover_all(), 0)
   1263     guard.assert_clean()
   1264     var recovered = _run_sh_measurement(_one_response(), 0, 1, guard)
   1265     assert_equal(recovered.ok_frames, 1)
   1266     assert_equal(recovered.failed_frames, 0)
   1267     guard.assert_clean()
   1268     assert_equal(open_fd_count_checked() - fd_before, 0)
   1269     assert_equal(child_process_count(self_pid, guard), child_before)
   1270 
   1271 
   1272 def main() raises:
   1273     TestSuite.discover_tests[__functions_in_module()]().run()