Skip to content

Connect LuaJIT FFI calls to Rust operation handlers - #2331

Draft
Ahaeflig wants to merge 4 commits into
colbymchenry:mainfrom
Ahaeflig:codex/lua-rust-bridge
Draft

Ahaeflig wants to merge 4 commits into
colbymchenry:mainfrom
Ahaeflig:codex/lua-rust-bridge

Conversation

@Ahaeflig

@Ahaeflig Ahaeflig commented Oct 3, 2026 •

Copy link
Copy Markdown

LuaJIT FFI calls currently stop at the Rust boundary, so callers and impact queries miss native handlers. This adds a source-derived bridge from proven FFI receivers to unique C-ABI exports, then follows literal operations through Lua/Rust wrappers to the handler actually selected and invoked.

Operation edges carry each literal operation to its own handler. A call into an export that dispatches operations is kept as a transport edge, and every walk treats it as a boundary: the export's callers and impact list its Lua call sites, callees and paths end at the export, and code behind the export never fans back out to every Lua caller. The implementation handles lexical aliases and module getters, standard Rust conversions, local Cargo/module identity, function-valued dispatch, and selected declarative macros. It rejects shadowed/mutated receivers, ambiguous exports, guarded or #[cfg] arms and unsupported transforms rather than guessing.

Each file's Lua and Rust analysis is stored in the index under a fingerprint of the analyzers and grammars, so a one-off CLI sync re-analyzes only changed files, and the bridge refreshes only for Lua and Rust files of projects with both languages. Projects without both languages are unaffected, including Lua-only projects' resolution.

Validation against main 6560052 (v1.6.2):

  • Full native suite: 6,184 passed, 34 skipped across 473 test files; TypeScript compilation passed. One daemon-cleanup check in mcp-writer-lock.test.ts failed once on a loaded machine and passed three isolated reruns; the bridge does not touch the daemon.
  • WASM bridge/provenance/transport coverage: 236 passed across 20 files, including stored analyses, incremental updates, compiled workers, concurrent grammar loading and cross-operation negatives.
  • Public RunRustFromLua: 0 → 6 FFI edges. Private gameplay monorepo: 0 → 80 bridge edges, including 72 operation calls; command, history and getter-routed derivation select their respective handlers, with no cross-operation path, callee or caller.
  • Node and edge counts remain stable on re-index. All non-timestamp node data and all 266,071 edge rows in the 5,082-file Ruff control match upstream exactly.
  • Monorepo fresh index: 55.3 s → 61.2 s (medians of three alternating pairs). Incremental syncs from a new process stay within about 1.5 s of upstream (Lua edit 4.1 s → 5.7 s, Rust 1.8 s → 2.8 s).

Draft: required agent A/B is pending. The Sonnet/high harness attempted two repeats per arm for nine questions, but all 36 attempts hit an account usage-limit/API 429 before tool use. No task timing or adoption results are claimed. A large positive Lua/Rust corpus is also still unverified.

The validation record documents coverage, indexing and sync cost, the pending benchmark, conservative analysis limits and two pre-existing ordinary Rust graph gaps. Existing indexes need re-indexing after upgrading (EXTRACTION_VERSION 28); Cargo manifest edits also require re-indexing. No version, dependencies or native-kernel code changed.

🤖 Generated with Claude Code

Ahaeflig and others added 4 commits October 4, 2026 04:06
Speed: the Lua FFI analysis is one lexical scope pass plus a worklist over
per-function flow states on a copied syntax tree, linear in locals and
functions. Each file's Lua and Rust analysis is stored in the index under a
fingerprint of the analyzers and grammars, so a new process reuses it and a
changed file is analyzed once. The bridge refreshes only for Lua and Rust
files of projects with both languages, instead of every synthesis input on
every save.

Visibility: a call into an export that dispatches operations is a transport
boundary. The export's callers and impact list its Lua call sites, callees and
paths end at the export, and code behind it stops there; viewer rails and MCP
labels show transport hops.

Soundness: Lua module invalidation by member path, closure writes, loops,
breaks, multiple values, goto, metatable reads, parameter scoping and cdef asm
labels. Rust first-match arms with guards, cfg arms, or-patterns and wildcards,
guard bindings, destructured fields, trait default methods, C-unwind exports
and Cargo [[bin]], binary-only and custom-lib targets.

The Lua parameter rule applies only where the bridge runs, grammar loading is
safe for concurrent callers, and EXTRACTION_VERSION is 28.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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