fold/docs/research/fold-self-scan-2026-07-29.md

2.9 KiB

Bounded Fold self-scan — 2026-07-29

Scope

Fold scanned the 21 changed production C++ translation units under src/ using a generated, validated compile database with exactly one command per translation unit. Tests, generated code, vendored code, third_party, and subprojects were excluded. The scan used the security detector group, two processes, a 300-second scan budget, a 60-second per-TU timeout, and a 2,000-millisecond per-query timeout.

Complete initial and verification artifacts are retained under /tmp/fold-self-scan-convergence-2026-07-29/, including SARIF, profiles, stdout/stderr logs, compile database, scope, query output, exit statuses, and a compact summary.json.

Result

Metric Initial Verification
Report-visible findings 18 17
Detector emissions before report filtering/deduplication 74 73
Z3 queries 106 105
Z3 timeouts / unknown 0 / 0 0 / 0
Translation units / functions 21 / 1,722 21 / 1,722
Wall time 108.490 s 79.827 s
Peak RSS 1,734.8 MiB 2,008.3 MiB
Exit status 1 (findings) 1 (findings)

Neither run had an input, policy, process, report, or timeout failure. Exit 1 is the documented actionable-finding status, not an analyzer failure.

Confirmed defects fixed

  1. Automatic process selection converted an unbounded size_t file count to int before clamping. It now bounds the value to the maximum eight workers before conversion.
  2. Profile translation-unit counts could truncate from size_t to unsigned. They now saturate to the profile field's representable range.
  3. MCP source slicing subtracted one from a potentially non-positive location line. It now normalizes the first line before arithmetic.

Focused scan_router_profile, mcp_stdio, and scan_e2e tests passed after the fixes.

Remaining finding disposition

The verification SARIF contains 11 integer-overflow, three integer-truncation, and three sign-conversion reports. Manual path review classified all 17 as false positives:

  • comma-separated substring lengths are guarded by first < end, which also guarantees the trimmed last is not before first;
  • brace and character-class differences follow successful searches that prove endpoint ordering;
  • glob reserve growth is bounded by process argument limits and MCP's 4,096-byte string policy;
  • filtered-source subtraction is between a source collection and its subset;
  • job/query pagination uses min before subtraction and iterator offsets;
  • the source-line value is normalized to at least one before subtraction;
  • tolower receives an unsigned char before its result is narrowed to char;
  • process and profile counts are bounded to their destination ranges before casts, although the detector does not carry those bounds through std::min.

No remaining report identified a confirmed code defect.