4.8 KiB
Differential Review Report — Fold symbolic/assertion changes
Date: 2026-06-04 Scope: unstaged Fold diff covering symbolic path modeling, P-Code path pruning, assertion layer/DBUILD checks, reporting evidence, router/build options, and tests.
Verdict
Major review completed with 3 agents plus local verification. Several concrete issues were fixed during review. Four larger design findings remain as follow-up tasks because they require broader modeling changes.
Fixed during review
-
Fold assertions were masked as recoverable TU crashes
- Risk:
FOLD_ASSERT/FOLD_PRECONDITIONinside source analysis raisedSIGABRT, andrunClangShardTranslationUnitcould quarantine the TU instead of failing the scan. - Fix:
include/fold/core/assert.hppnow tracks assertion-failure-in-flight;src/cli/clang_shard_tu.cppresets/checks this flag and aborts on Fold assertion failures instead of treating them as ordinary TU signals.
- Risk:
-
FOLD_DCHECKtest did not match macro semantics- Risk: test assumed only
FOLD_ENABLE_DCHECKcontrolsFOLD_DCHECK, but macro also enables under!NDEBUG. - Fix:
tests/unit/test_signal_isolation.cppnow requiresFOLD_ENABLE_DCHECKfor the test build and always expectsSIGABRT.
- Risk: test assumed only
-
Debug-only abort conflicted with guarded-fact invalid-subject skip policy
- Risk:
GuardedFactStore::addaborted in test/canary builds for invalidAccessPathwhile release silently skipped. - Fix:
src/symbolic/guarded_facts.cppnow consistently treats invalid subjects as skipped facts, then asserts only scalar/boolean payload invariants for valid facts.
- Risk:
-
P-Code path invariant was debug-only before release dereference
- Risk:
path_was checked withFOLD_DCHECKbefore release dereference. - Fix:
src/symbolic/pcode_encoder.cppnow uses always-onFOLD_ASSERTfor initialized/boolean P-Code path before feasibility/observer paths.
- Risk:
-
Disabled Rust/Swift frontend options broke compilation
- Risk:
-Drust-frontend=false/-Dswift-frontend=falseomitted backend sources butscan_runner.cppstill instantiated them. - Fix:
src/cli/scan_runner.cppnow gates backend construction withFOLD_HAVE_RUST/FOLD_HAVE_SWIFTand throws clear disabled-frontend errors.
- Risk:
-
DCHECK canary docs reused another build dir's native file
- Risk:
BUILD.mdexample pointedbuild/dcheckatbuild/release/conan_meson_native.ini. - Fix: docs now use independent
build/dcheckConan/Meson files and showmeson configure ... -Denable-dcheck=truefor existing builds.
- Risk:
Remaining findings / follow-up tasks
-
High — P-Code CBRANCH assumes all later ops are fallthrough
- Ref:
src/symbolic/pcode_encoder.cpp:437-444. - Scenario: if lifted P-Code is ordered taken-block-first, global
path && !condcan suppress real hazards in the taken path. Unconditional branch/return boundaries are also not modeled. - Follow-up: task #12.
- Ref:
-
Medium — unknown-call havoc does not clear AccessPath-backed facts
- Ref:
src/symbolic/encoder.cpp:1038-1069. - Scenario: mutable calls clear member-value cache but not AccessPath ranges/non-null/guarded facts, so facts like
obj.v.size() > 0may survivemutate(&obj). - Follow-up: task #13.
- Ref:
-
Low/Medium — latent/precondition evidence is serialized but not produced by detectors
- Refs:
src/report/finding_json.cpp:104-107,src/report/sarif.cpp:283-290. - Scenario: real raw-pointer/config-derived precondition findings still appear as ordinary findings until detector emission is wired.
- Follow-up: task #14.
- Refs:
-
Low — hybrid profile merge drops timing/counter fields
- Ref:
src/cli/scan_router.cpp:454-476. - Scenario: hybrid profiles merge detector rows and counts but omit lane timing/prefilter counters, reducing benchmark/profile fidelity.
- Follow-up: task #15.
- Ref:
Validation run after fixes
Passed:
ninja -C build/release \
tests/unit/test_signal_isolation tests/unit/test_guarded_facts \
tests/unit/test_pcode_encoder tests/integration/test_scan_e2e \
tests/integration/test_subprocess_fanout
meson test -C build/release \
fold:signal_isolation fold:guarded_facts fold:pcode_encoder \
fold:scan_e2e fold:subprocess_fanout --print-errorlogs
git diff --check
Result: 5/5 OK, 0 failures.
Also passed no-frontends build smoke:
meson setup build/review-no-frontends ... \
-Dbuild-tests=false -Drust-frontend=false -Dswift-frontend=false \
-Dghidra=disabled -Dcapstone=disabled -Dradare2=disabled \
-Dbuild-mcp-server=false -Dbuild-lsp-server=false
ninja -C build/review-no-frontends libfold-core.a
Coverage limits
This was a differential review over the current unstaged diff, not a full architectural audit. The largest remaining risks are path-model semantics and fact invalidation, which need dedicated implementation/testing passes.