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

65 lines
2.9 KiB
Markdown

# 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.