Skip to content

feat!: replace the analysis engine with a sound object model - #40

Merged
owenthcarey merged 7 commits into
mainfrom
rfc0031-object-engine
Oct 2, 2026
Merged

owenthcarey merged 7 commits into
mainfrom
rfc0031-object-engine

Conversation

@owenthcarey

Copy link
Copy Markdown
Contributor

What

Implements RFC 0031: the path-based engine behind the RFC 0030 seam is replaced by an engine whose facts live on abstract objects and symbolic values, so every alias sees every fact by construction. Summary format 30 and unit record format 29 replace formats 29 and 28 (breaking: objects built by earlier versions must be rebuilt). The old engine and its tests are removed.

RFC 0030 and RFC 0031 are marked Implemented. Every design decision made while implementing is recorded in RFC 0031's Implementation amendments.

Gates (reference machine, final tree)

Gate Result
G1 soundness 481/481 cases under --asan and --checks verify; no proven facet trapped in any corpus test suite built in verify mode
G2, G3 481/481 cases; evaluation 76/76, pairs 24/24, recall 67/67 pins, engine 143/143 pins, soundness 137/137, injections 30/31
G4 errors and traps 0 definite errors on the original configs; 0 traps in their test suites
G5 held-out no definite error triaged false; every project builds and passes its tests, except sqlite, whose build stops at three unsafe-operation errors triaged true (RFC 0004)
G7 153 units x 3 configurations byte-identical
G8 bench Lua 1.08, zlib 1.01, cJSON 1.15
G9, G10 Lua whole program 114 s; zlib make -j8 1.7 s
G11 4 of 9,588 functions over budget
G12 single units sqlite3.c 486 s / 2.3 GB; mujs/one.c 12 s
G13 per-unit cost within the ratchet's tolerance of v0.11.0 (Lua 1.02x, zlib 0.67x, jansson 0.97x in retired instructions)
H2, H3 hygiene passes; docs tests and build pass

H1 (CI timings) is measured by this PR's CI.

Targets not met, carried forward

Three numeric targets set before the engine existed are not met. By the owner's decision they leave this RFC's acceptance, the measured values become ratchets, and the targets move to Future work (RFC 0031, Gates carried forward):

  • G6 unresolved shares: original configs 0.42 spatial / 0.35 temporal (targets 0.35 / 0.30); held-out 0.50 temporal (target 0.35). Held mostly by hooks the program does not close (Lua's lua_CFunction slot and collector, sqlite's allocator/mutex/VFS) and by extents the code does not state. Goes to RFC 0032.
  • G12 build ratio: 2x to 47x the reference compiler's CPU (target 8x); the link step re-analyses the program per executable. Now reported, not limited. Goes to RFC 0033.
  • G4 possible temporal warnings: 65, all triaged (limit was 60, now 65); values a summary cannot describe share one unknown object.

Known caveat

lz4's fuzz test (frametest) can trap depending on its random seed: on a corrupt frame LZ4_memcpy_using_offset_base calls memcpy(dst, dst, 2) (overlapping, undefined in C; lz4's comment notes offset 0 happens in testing). The check is a true report, but the gate script still counts it as a trap, so a full held-out run can fail G5 on an unlucky seed.

Testing

  • ctest --preset dev suites: Core 176, Analysis 388, Frontend 127 unit tests; 160 lit tests; 481 cases.
  • scripts/corpus-gate.py --full --held-out (trap and verify modes), --inject, --bench; scripts/codegen-identity.py; scripts/check-hygiene.py; npm test && npm run build in docs/.
  • test/corpus/expected.json is re-recorded on the new engine for darwin-arm64 only; the linux-x86_64 record still needs --update from a CI run.

Replaces the path-based engine behind the RFC 0030 seam with an engine
whose facts live on abstract objects and symbolic values, so every alias
sees every fact by construction (docs/rfcs/0031-object-engine.md).

- Core: the heap domain (objects, cells, element ranges, focus objects,
  dead copies), a sparse zone of difference bounds, persistent maps.
- Analysis: the object engine behind SafetyEngine (lib/Analysis/Engine*),
  format-30 summaries with cases, recursion widening and incomplete
  summaries, alias contexts, owning slots, carried-value and local
  liveness, loop budgets.
- Frontend: unit record format 29, the link step and --whole-program over
  the new engine, the computed-goto edge split.
- The old engine (FunctionDataflow and its trackers) and its tests are
  removed.
- Tests: object-domain, alias-probe and held-out repro cases; eleven
  held-out corpus configs; the corpus ratchet re-recorded.

BREAKING CHANGE: summary format 30 and unit record format 29 replace
formats 29 and 28; objects built by earlier versions must be rebuilt.

RFC 0030 and RFC 0031 are marked Implemented. Three numeric targets of
RFC 0031 were not met and are carried forward as future work, with the
measured values kept as ratchets (RFC 0031, "Gates carried forward"):
the unresolved shares of G6, the build-cost bound of G12 and G4's count
of possible temporal warnings.
@owenthcarey owenthcarey changed the title feat!: the object engine (RFC 0031) feat!: replace the analysis engine with a sound object model Oct 2, 2026
@owenthcarey
owenthcarey merged commit 01bb1d2 into main Oct 2, 2026
12 checks passed
@owenthcarey
owenthcarey deleted the rfc0031-object-engine branch October 2, 2026 03:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant