# Cursor/index microbenchmarks and build-directive review — 2026-10-17

Measured source: `15acc99220fb6f1bbd8903a16caaa90cc24fa212`, clean before freezing.
The documentation was integrated onto later main; these measurements remain attached to
that frozen revision. This record is private because it contains environment-specific results.

## Decisions

- Rust ThinLTO with one code-generation unit improves cursor extraction by 10–12%,
  but slows every index case by 3–6%. Keep the existing explicit Stage2 selector and
  document the application/workspace-root Cargo profile in both Rust READMEs. There
  is no supported universal default change. The existing round-trip benchmark's fat
  LTO profile was not compared with ThinLTO in this experiment.
- Adding `-flto=1` to .NET-native improves the equal-weight median aggregate by only
  0.3%, with no demonstrated batch-p99 improvement. Keep its current build recipe.
- C++ and Java-JNI already use native CPU tuning and LTO. Java-pure uses the normal
  JVM JIT; .NET-pure is optimized Release code. The .NET diagnostic tiering policy
  below is a measurement control, not a deployment recommendation.
- Compiler flags do not remove per-field native calls. JNI still makes 20/23/75
  calls for full D/8/W cursor walks versus one index call. Preserve lazy `next()`;
  evaluate a separately named coarse scan/projection API for full-scan consumers.

## Scope and admission

The baseline contains 72 cells: six flavours × four cursor/index operations × three
fixtures. The structural observer folds metadata; extraction includes contracted
conversion/observer work. Neither row isolates parser-kernel cost. D/8/W frames have
184/216/746 bytes and 18/21/73 fields. Each reported raw timing is a 32-operation
batch average. Individual-message tails and session/network latency require a
separate experiment.

Current host: Intel Xeon Platinum 8370C, kernel 6.18.55, five exposed vCPUs and four
CPU-equivalents of cgroup quota. Timed processes used CPU 4; launcher/telemetry used
CPUs 0–3. All ahead-of-time compilation finished before timing. Earlier AMD EPYC
results are separate experiments and are never pooled here.

Toolchains: GCC 14.2.0, Rust 1.99.1, Java 21.0.12.1, .NET 10.0.13/SDK 10.0.402.
Native target selection, source, profile, features and runtimes are frozen inputs.
Rust uses `default-features=false` and no optional delimiter kernel in both builds.

Functional evidence:

- Prior SDK validation at the measured source: 26,664 C++ checks; 119 Java tests
  across four JVM runs (476 passes); 84 .NET tests on each actual runtime 8.0.32 and
  10.0.13; 24 Rust default/scalar checks; 152 Stage2 harness tests; 14 inventory
  tests; 36 compiled benchmark mode smoke checks.
- Fresh full admission: all 72 normal cells and all 144 negative probes passed.
- Baseline repeated campaigns: 720 all-six forks plus 240 longer-warmup .NET forks;
  all 144 and 48 repeated probes passed, respectively.
- Build comparison: 240 Rust forks plus 360 native forks; all 48 and 72 repeated
  probes passed. No parity bypass; no >5% first/last-quarter drift flag in those 600
  forks. Stock and LTO native bundles each also passed 12 normal rows and 24 probes
  before timing.
- ThinLTO candidate: all 16 existing codec tests passed in an optimized external
  checker reusing the exact compiled SDK dependency/profile; includes binary DATA,
  deferred cursor errors, rewind, capacity and error precedence.
- LTO native candidate: 84 tests passed on each actual runtime 8.0.32/10.0.13.
  Per-process loader traces prove the tested candidate was initialized. ABI 69 and
  all 213 public `hftnet_*` exports match; managed assemblies stayed unchanged.

The following tables are retained from the frozen experiment reports.

## All-six baseline

10 fresh processes per cell, 200,000 untimed invocations and 10,000 measured batches per process; 720 processes total. .NET tiering and dynamic PGO disabled; Java uses its normal JIT policy. Values below are medians of process p50 values, in ns per message. Columns include their contracted metadata or converted-value observer work; they do not isolate parser-kernel cost.

| Flavour | Fixture | Cursor structural | Index structural | Cursor extract | Index extract |
| --- | --- | ---: | ---: | ---: | ---: |
| C++ | D | 151 | 188 | 206 | 264 |
| C++ | 8 | 171 | 217 | 235 | 307 |
| C++ | W | 601 | 779 | 922.5 | 1188 |
| Java-pure | D | 184.5 | 230 | 330 | 348 |
| Java-pure | 8 | 210 | 273 | 411.5 | 427 |
| Java-pure | W | 639 | 900.5 | 1327 | 1535.5 |
| Java-JNI | D | 1047.5 | 306 | 1166 | 434 |
| Java-JNI | 8 | 1186.5 | 339.5 | 1384.5 | 513 |
| Java-JNI | W | 3634.5 | 911 | 4354 | 1622.5 |
| .NET-pure | D | 412 | 550 | 713 | 727 |
| .NET-pure | 8 | 473 | 640 | 868.5 | 880 |
| .NET-pure | W | 1522 | 2064 | 3512 | 3323 |
| .NET-native | D | 371.5 | 303 | 692 | 470 |
| .NET-native | 8 | 419.5 | 349 | 828 | 580 |
| .NET-native | W | 1360 | 1135 | 3344 | 2360.5 |
| Rust | D | 198 | 220 | 318 | 315 |
| Rust | 8 | 225.5 | 258 | 366 | 375 |
| Rust | W | 830 | 894 | 1446.5 | 1452.5 |

## Longer-warmup .NET policies

5 fresh processes per cell/profile, 2,000,000 untimed invocations and 10,000 batches per process. Both profiles use the same count. The 240 processes are a separate experiment from the 200k all-six lane; do not substitute or pool individual rows. Intervals with five forks are exploratory.

| Flavour | Fixture | Policy | Cursor structural | Index structural | Cursor extract | Index extract |
| --- | --- | --- | ---: | ---: | ---: | ---: |
| .NET-pure | D | diagnostic | 411 | 549 | 715 | 727 |
| .NET-pure | D | default | 296 | 410 | 479 | 572 |
| .NET-pure | 8 | diagnostic | 471 | 634 | 866 | 887 |
| .NET-pure | 8 | default | 346 | 482 | 574 | 688 |
| .NET-pure | W | diagnostic | 1518 | 2064 | 3516 | 3320 |
| .NET-pure | W | default | 1072 | 1541 | 2391 | 2788 |
| .NET-native | D | diagnostic | 368 | 302 | 692 | 469 |
| .NET-native | D | default | 330 | 575 | 521 | 448 |
| .NET-native | 8 | diagnostic | 421 | 349 | 828 | 580 |
| .NET-native | 8 | default | 396 | 656 | 635 | 558 |
| .NET-native | W | diagnostic | 1366 | 1135 | 3343 | 2360 |
| .NET-native | W | default | 1288 | 1131 | 2544 | 2242 |

Fixed call counts do not certify steady-state JIT tiers for every cell. Separate disassembly checks below cover selected cursor cases only.

## Baseline variance

| Campaign | Forks | >5% within-process drift | VM aggregate steal | CPU4 sampled steal | Throttled forks |
| --- | ---: | ---: | ---: | ---: | ---: |
| all-six-diagnostic | 720 | 7 | 3.25% | 6.75% | 0 |
| dotnet-long-warmup | 240 | 0 | 2.68% | 5.88% | 2 |

Aggregate steal sums CPU-counter deltas over complete fork windows on all five vCPUs. CPU4 steal uses enclosing 250ms telemetry samples over each campaign and includes inter-process gaps/parity execution. Cgroup counters cover the whole container. None isolates the timed batches or proves the cause of a particular outlier. Drift compares first/last-quarter raw batch medians; lack of drift does not certify the intended JIT tier.

## Selected JIT evidence

These instrumented diagnostic processes ran separately from timing, on the same CPU4 affinity and frozen applications/runtime. Disassembly and host tracing can affect compilation scheduling; these checks do not certify the uninstrumented timed processes. Listings show compiled versions observed over the entire process; a Tier1 listing alone does not prove that all measured batches used it.

| Flavour | Fixture / operation | Warm-up | Access method versions |
| --- | --- | ---: | --- |
| .NET-pure | D / cursor_parse_extract | 200000 | Instrumented Tier0 |
| .NET-pure | D / cursor_parse_extract | 2000000 | Instrumented Tier0; Instrumented Tier0; Tier1 |
| .NET-pure | W / cursor_parse_only | 200000 | Instrumented Tier0 |
| .NET-pure | W / cursor_parse_only | 2000000 | Instrumented Tier0; Instrumented Tier0; Tier1 |
| .NET-native | D / cursor_parse_extract | 200000 | Instrumented Tier0 |
| .NET-native | D / cursor_parse_extract | 2000000 | Instrumented Tier0; Instrumented Tier0; Tier1 |
| .NET-native | W / cursor_parse_only | 200000 | Instrumented Tier0 |
| .NET-native | W / cursor_parse_only | 2000000 | Instrumented Tier0; Instrumented Tier0; Tier1 |

The JNI full-walk cursor still makes 20/23/75 native calls for D/8/W, versus one native index call. That structural boundary cost remains distinct from VM interference and JIT policy. C++ can fuse cursor parsing and observation; indexing additionally materializes descriptors. Extraction and structural rows use different observers, so their difference is not a clean conversion cost.

## Build-directive comparisons

**Diagnostic shared-VM experiment; no exclusive-host qualification.** Ratios are candidate/reference latency: below 1 is faster, above 1 is slower.

Each cell pairs process statistics by fork-round number, operation and fixture. The point estimate is the geometric mean of 10 paired latency ratios. The nominal 95% percentile bootstrap resamples 10 whole fork-round blocks, using the same resamples for all cells/contrasts within each campaign. Aggregate ratios give each selected cell equal weight and retain correlations within rounds.

Rounds are randomized scheduling blocks, not adjacent ABBA pairs. Ten rounds do not establish calibrated physical-host confidence. Intervals are descriptive, have no multiple-comparison correction, and are not a guarantee of production gains. Rounded per-operation statistics can create narrow or degenerate intervals; small sub-percent changes should not be overinterpreted.

p50 and p99 below are statistics of 32-operation batch averages. A paired process-p99 ratio is not individual-message tail latency. An aggregate of those ratios is not an overall/pool p99. Results do not isolate parser kernels from their contracted observer work.

All forks, including drift-flagged forks, are retained. No post hoc outlier exclusion is used. Historical AMD results and earlier separate experiments are not pooled into this Intel-host analysis.

Recorded host: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz; kernel 6.18.55; source `15acc99220fb6f1bbd8903a16caaa90cc24fa212`. Timed CPU4; launcher/telemetry affinity [0, 1, 2, 3]. Quota: `400000 100000`.

## rust-profile-comparison

240 processes; 48 exact unique negative probes passed. Diagnostic runtime policy, 200k warmups, 10k measured batches, 10 rounds. Prepared workload seals match.

| Variant | Forks | >5% drift | VM aggregate steal in fork windows | Throttled forks / µs |
|---|---:|---:|---:|---:|
| default | 120 | 0 (0.0%) | 8.87% | 2 / 417224 |
| thin_scalar | 120 | 0 (0.0%) | 7.98% | 1 / 681831 |

CPU4 sampled steal over the enclosing campaign window: 20.04%. This includes startup, warmup, gaps, parity and final verification, not just measured batches. Aggregate counters cover all VM CPUs and cgroup throttling covers the entire container; none attributes a particular paired change to scheduling.

### ThinLTO / default release

| Statistic | Equal-weight geometric latency ratio, 12 cells | Nominal 95% block interval | Change |
|---|---:|---:|---:|
| p50_ns | 0.990 | 0.989–0.992 | -1.0% |
| p99_ns | 1.004 | 0.895–1.141 | +0.4% |

| Operation | Fixture | Process-p50 ratio | Nominal 95% interval | Process-p99 ratio | Nominal 95% interval |
|---|---|---:|---:|---:|---:|
| cursor_parse_only | D | 1.015 | 1.009–1.019 | 1.228 | 0.958–1.648 |
| cursor_parse_only | 8 | 1.020 | 1.002–1.032 | 1.175 | 1.048–1.324 |
| cursor_parse_only | W | 0.930 | 0.927–0.932 | 0.762 | 0.513–1.048 |
| cursor_parse_extract | D | 0.897 | 0.891–0.903 | 0.994 | 0.827–1.320 |
| cursor_parse_extract | 8 | 0.883 | 0.878–0.886 | 0.941 | 0.867–1.035 |
| cursor_parse_extract | W | 0.891 | 0.889–0.893 | 1.134 | 0.916–1.606 |
| index_parse_only | D | 1.054 | 1.051–1.056 | 0.856 | 0.614–1.068 |
| index_parse_only | 8 | 1.037 | 1.035–1.040 | 0.950 | 0.774–1.190 |
| index_parse_only | W | 1.052 | 1.050–1.053 | 1.015 | 0.916–1.128 |
| index_parse_extract | D | 1.041 | 1.039–1.044 | 0.948 | 0.831–1.065 |
| index_parse_extract | 8 | 1.033 | 1.030–1.036 | 1.074 | 0.922–1.258 |
| index_parse_extract | W | 1.060 | 1.058–1.062 | 1.075 | 0.747–1.473 |

## native-lto-comparison

360 processes; 72 exact unique negative probes passed. Diagnostic runtime policy, 200k warmups, 10k measured batches, 10 rounds. Prepared workload seals match.

| Variant | Forks | >5% drift | VM aggregate steal in fork windows | Throttled forks / µs |
|---|---:|---:|---:|---:|
| original | 120 | 0 (0.0%) | 3.06% | 0 / 0 |
| stock | 120 | 0 (0.0%) | 2.57% | 0 / 0 |
| lto | 120 | 0 (0.0%) | 4.30% | 1 / 19018 |

CPU4 sampled steal over the enclosing campaign window: 6.66%. This includes startup, warmup, gaps, parity and final verification, not just measured batches. Aggregate counters cover all VM CPUs and cgroup throttling covers the entire container; none attributes a particular paired change to scheduling.

### Fresh stock / original control

| Statistic | Equal-weight geometric latency ratio, 12 cells | Nominal 95% block interval | Change |
|---|---:|---:|---:|
| p50_ns | 0.999 | 0.998–1.001 | -0.1% |
| p99_ns | 1.006 | 0.976–1.034 | +0.6% |

| Operation | Fixture | Process-p50 ratio | Nominal 95% interval | Process-p99 ratio | Nominal 95% interval |
|---|---|---:|---:|---:|---:|
| cursor_parse_only | D | 0.991 | 0.977–1.007 | 1.065 | 0.943–1.211 |
| cursor_parse_only | 8 | 1.000 | 0.988–1.014 | 0.962 | 0.755–1.186 |
| cursor_parse_only | W | 0.997 | 0.993–1.001 | 0.953 | 0.829–1.041 |
| cursor_parse_extract | D | 1.004 | 1.000–1.010 | 0.994 | 0.924–1.074 |
| cursor_parse_extract | 8 | 1.001 | 1.000–1.002 | 1.011 | 0.885–1.197 |
| cursor_parse_extract | W | 1.000 | 1.000–1.000 | 1.032 | 0.896–1.227 |
| index_parse_only | D | 1.002 | 0.998–1.008 | 0.866 | 0.724–1.007 |
| index_parse_only | 8 | 1.000 | 0.999–1.001 | 1.104 | 0.965–1.257 |
| index_parse_only | W | 1.001 | 1.000–1.002 | 1.079 | 1.029–1.145 |
| index_parse_extract | D | 0.999 | 0.997–1.002 | 0.921 | 0.824–1.031 |
| index_parse_extract | 8 | 0.999 | 0.996–1.000 | 1.004 | 0.896–1.177 |
| index_parse_extract | W | 0.999 | 0.998–1.000 | 1.106 | 0.957–1.328 |

### LTO / fresh stock (directive effect)

| Statistic | Equal-weight geometric latency ratio, 12 cells | Nominal 95% block interval | Change |
|---|---:|---:|---:|
| p50_ns | 0.997 | 0.995–0.999 | -0.3% |
| p99_ns | 1.027 | 0.971–1.108 | +2.7% |

| Operation | Fixture | Process-p50 ratio | Nominal 95% interval | Process-p99 ratio | Nominal 95% interval |
|---|---|---:|---:|---:|---:|
| cursor_parse_only | D | 0.997 | 0.983–1.010 | 0.922 | 0.798–1.068 |
| cursor_parse_only | 8 | 0.990 | 0.980–1.000 | 1.074 | 0.848–1.386 |
| cursor_parse_only | W | 0.999 | 0.996–1.003 | 1.110 | 0.966–1.379 |
| cursor_parse_extract | D | 1.000 | 0.993–1.004 | 0.999 | 0.869–1.163 |
| cursor_parse_extract | 8 | 1.004 | 1.002–1.005 | 0.993 | 0.942–1.040 |
| cursor_parse_extract | W | 1.001 | 1.000–1.003 | 1.061 | 0.837–1.410 |
| index_parse_only | D | 0.980 | 0.973–0.984 | 0.976 | 0.842–1.128 |
| index_parse_only | 8 | 0.987 | 0.985–0.989 | 1.103 | 0.922–1.347 |
| index_parse_only | W | 0.997 | 0.995–0.998 | 1.026 | 0.931–1.130 |
| index_parse_extract | D | 0.999 | 0.998–1.000 | 1.028 | 0.916–1.151 |
| index_parse_extract | 8 | 1.004 | 1.002–1.008 | 1.104 | 0.990–1.292 |
| index_parse_extract | W | 1.002 | 1.000–1.005 | 0.948 | 0.848–1.041 |

### LTO / original (context)

| Statistic | Equal-weight geometric latency ratio, 12 cells | Nominal 95% block interval | Change |
|---|---:|---:|---:|
| p50_ns | 0.996 | 0.995–0.998 | -0.4% |
| p99_ns | 1.032 | 0.974–1.117 | +3.2% |

| Operation | Fixture | Process-p50 ratio | Nominal 95% interval | Process-p99 ratio | Nominal 95% interval |
|---|---|---:|---:|---:|---:|
| cursor_parse_only | D | 0.988 | 0.977–0.999 | 0.982 | 0.823–1.150 |
| cursor_parse_only | 8 | 0.991 | 0.982–0.999 | 1.033 | 0.940–1.143 |
| cursor_parse_only | W | 0.997 | 0.993–1.000 | 1.058 | 0.980–1.158 |
| cursor_parse_extract | D | 1.004 | 1.003–1.005 | 0.993 | 0.872–1.135 |
| cursor_parse_extract | 8 | 1.005 | 1.004–1.005 | 1.003 | 0.884–1.209 |
| cursor_parse_extract | W | 1.002 | 1.000–1.003 | 1.095 | 0.909–1.410 |
| index_parse_only | D | 0.982 | 0.981–0.984 | 0.845 | 0.696–1.006 |
| index_parse_only | 8 | 0.987 | 0.985–0.989 | 1.217 | 1.055–1.494 |
| index_parse_only | W | 0.998 | 0.997–0.998 | 1.107 | 1.019–1.230 |
| index_parse_extract | D | 0.999 | 0.997–1.000 | 0.947 | 0.822–1.079 |
| index_parse_extract | 8 | 1.003 | 0.999–1.008 | 1.108 | 0.931–1.490 |
| index_parse_extract | W | 1.001 | 0.998–1.004 | 1.048 | 0.985–1.134 |

## Interpretation limits and decision gate

Rust compares explicit ThinLTO/codegen-units 1 against the ordinary release profile with scalar delimiter selection; it does not change the SDK default profile or enable an optional SIMD kernel. Native LTO/stock is the directive comparison; stock/original tests reconstruction/control effects, and LTO/original is contextual. A control shift must remain visible rather than being folded into an LTO claim.

Prefer a repeatable practical gain (initially about 5%) across relevant cells without material unrelated regressions. Do not promote defaults from the equal-weight aggregate alone: inspect every cell, process-p99 behavior, controls, build time and binary size. Confirm close effects in another independently randomized same-host experiment and a diversified corpus. Preserve grammar, safety, allocation behavior and documented build portability.

Process p50/p99 values come from the retained driver records, which were checked against raw samples by the driver. This analysis verifies coverage, receipts, workload/snapshot-manifest seals and its consumed file hashes; it does not rerun the raw batch parser or rehash every frozen runtime byte. The timing driver verified full snapshots before and after execution.

See BUILD_COMPARISON.json for per-round ratios, subgroup aggregates, snapshot/build identities and SHA256 of every consumed receipt/table. The analysis script and source data are external experiment artifacts. Subsequent repository edits document the opt-in and retain this record.

## Build costs and attribution

The Rust normal adapter is 638,688 bytes under the ordinary release profile and
574,008 bytes with ThinLTO/CU1 (10.1% smaller). Recorded normal preparation times
were 39.726s and 50.313s; these were not controlled build-time comparisons and must
not be interpreted as a causal build-time penalty estimate.

Fresh native stock is 27,165,368 bytes and LTO 27,110,168 bytes (0.2% smaller).
Stock differs from the original binary because absolute versus relative include
paths change `__FILE__` diagnostic strings and their relocations. Parser entry
points, section layout, exported symbols and dependencies match; inspected changed
instructions refer to equivalent strings or jump tables with identical branch
destinations. Fresh-stock versus LTO is the flag comparison; original versus stock
remains visible as a control. Stock/LTO managed application/runtime bytes and
native source inputs match. The only native flag addition is `-flto=1`.

## Remaining improvement plan

1. Certify actual managed execution state. Add bounded time-window warmup and
   compilation/inlining/GC evidence for the timed methods. The selected separate
   .NET traces above do not certify every timed cell. Keep startup separate from
   warmed application work.
2. Attribute observer and bridge costs. Add a minimal-observable full parser,
   predecoded metadata/typed observers and native-call controls; inspect emitted
   code. Preserve existing combined rows and do not subtract medians as additive
   component costs.
3. Normalize declared-tag conversion work under a new observer/oracle version.
   Current language-specific selection/conversion paths differ; cross-language
   extraction deltas are not clean parser-quality rankings.
4. Add seeded message diversity: field counts independent of byte length, binary
   DATA, varied value lengths/alignment, repeats, early-stop reads and repeated or
   random lookups. Distinguish partial from complete validation; current `Find`
   scans the descriptor table linearly.
5. Prioritize JNI boundary decomposition and a separate coarse projection API;
   profile Java selection/converters, .NET decimal/consumer branches, and Rust
   remaining parser calls/inlining/layout. Keep the six lazy cursor contracts.
   Test further Rust release profiles against both cursor and index workloads;
   do not change a fat-LTO workspace from a default-versus-Thin comparison.
6. Confirm only practical gains on a diversified held-out corpus and another
   independently randomized run. PGO/BOLT need representative training and
   appropriate target tools; optional SIMD and CPU-specific settings need explicit
   target policy. Preserve grammar, error precedence, lazy failure timing, buffer
   lifetimes and warmed allocation behavior.

## Retained local artifacts

These absolute directories are local experiment artifacts, not Git dependencies:

- `/workspace/build/libhft/final-perf-20261017/`: `RESULTS.md`,
  `variance-audit.json`, `host-telemetry.jsonl`, `toolchain-identities.json`,
  frozen snapshot/source archive, `all-six-diagnostic/` and
  `dotnet-long-warmup/` (all forks, raw batches, probe verdicts and intervals),
  plus `jit-evidence/` receipts/disassembly/host traces.
- `/workspace/build/libhft/build-directive-experiments/`: `BUILD_COMPARISON.md`,
  `.json`, `analyze_comparisons.py`, `run_comparisons.py`, `execution.json`,
  telemetry, both comparison campaigns and their raw batches, candidate build
  recipes/frozen snapshots, SDK validation receipts and loader traces.

Artifact SHA256 values:

- `final-perf-20261017/RESULTS.md`: `dd60e8ee9d5cabb8c519ea865d19564104344513f3a6f6194111b83b8d07f9d4`
- `final-perf-20261017/variance-audit.json`: `1c97cab3826cb0d9032e866ed81573200a5dd2a5f6744ed7e5b7f30a51ae56ac`
- `final-perf-20261017/frozen/snapshot/snapshot.json`: `79b20cafcdbd833ecb0ea29927ae3cb95901c97adf4ceb9a6ce066226a2f45c4`
- `build-directive-experiments/BUILD_COMPARISON.md`: `a66084e38ece2e6b5770e03925993c670fc9fcdf04e2b7e759c0576661834c9f`
- `build-directive-experiments/BUILD_COMPARISON.json`: `9301d5d9a3d846ae87a403cbd9bc017c736154c91d419de2bd6b48d60316a8f5`
- `build-directive-experiments/execution.json`: `60878df5f8f62e46535459d57ca0c539e8e3281844ab05a1fd2ab3a9cb9931bf`
- `build-directive-experiments/analyze_comparisons.py`: `52158098fa7f698314c5ac47dd2927d2ec6a30420607660a19a3cd9ad798311e`
- `build-directive-experiments/dotnet-native-lto/comparison-ready.json`: `b1d09cc7cd498e35ea5bf0f793abc38840a9bb1804a65bf6650ae302e9db5028`
- `build-directive-experiments/rust-thin-scalar/conformance-checker/run-logs/receipt.json`: `3a923cc4193b7f006b4f2921caaafb78e342b31f2c5253eff2419c4872dac38f`
- `build-directive-experiments/dotnet-native-lto/validation/run/receipt.json`: `c26b03ca83a1ac7ffc586113e4da994d5efd8b99e3056a1ae9acf33d312ff769`
