Skip to content

feat(graph-lite): make the public surface a C ABI - #9

Merged
sebyx07 merged 1 commit into
mainfrom
feat/graph-lite-c-abi
Aug 22, 2026
Merged

sebyx07 merged 1 commit into
mainfrom
feat/graph-lite-c-abi

Conversation

@sebyx07

@sebyx07 sebyx07 commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

What

graph-lite's public contract becomes a C ABI (graph-lite.h). graph-lite.hpp becomes a header-only C++ ergonomics layer over it.

Why

The SQLite comparison is not only about being in-process — SQLite's reach comes from a flat C ABI that every language runtime can call. A C++-only surface caps adoption at C++ projects, and does not link reliably even between C++ toolchains.

With a C ABI, Ruby (FFI), JavaScript (N-API / bun:ffi), Python (ctypes/cffi), Rust, Go and C all embed the same library through their own FFI — no wrapper to keep in sync, no serialisation, still in-process.

Decided now because it is a one-way door: a C ABI retrofitted onto a C++-shaped design is a second, worse API wrapping the first, and every binding pins whichever shipped. Rules and rejected alternatives: ADR 0004.

How

  • graph-lite.hextern "C", opaque handles, graph_lite_status codes, caller-owned buffers.
  • graph-lite.hpp — header-only, RAII, graph_lite::Error carrying the code so a caller can still branch on the reason.
  • tests/graph-lite/c_abi_test.c — compiled as C and linked, so the C-compatibility claim is tested rather than asserted.

Two things fell out of writing the C test:

  • graph_lite_status is forced to int width. A binding compiled against a different header will pass a code this build has not heard of, and converting an out-of-range value to a narrow enum is unspecified — the compiler said so.
  • C++-only warning flags are now scoped to CXX, so the C translation unit does not drown in "valid for C++ but not for C".

The vocabulary guard now skips fenced code blocks in markdown only — Bun's FFI genuinely returns a symbols object, and a guard that fires on a third-party API name gets disabled. Source files are still scanned in full; a test pins both halves.

Checks

  • bin/check is green
  • Tests written with the code
  • No warning suppression, disabled guard, or skipped test added
  • No new dependency on an external process, binary, or network service
  • graph-lite/ still depends on nothing in this repo, and names no consumer concept
  • Public contract changed → ADR is in this PR

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

The SQLite comparison is not only about being in-process — SQLite's reach comes
from a flat C ABI that every language runtime can call. A C++-only surface caps
adoption at C++ projects and does not link reliably even between C++ toolchains,
since C++ has no stable ABI across compilers or standard-library versions.

graph-lite.h is now the contract: C linkage, opaque handles, integer status
codes, caller-owned buffers, additive only. Ruby (FFI), JavaScript (N-API /
bun:ffi), Python (ctypes/cffi), Rust, Go and C all bind the same entry points.
graph-lite.hpp is header-only C++ ergonomics over it — RAII, real types, an error
type that carries the code — and exports nothing of its own.

Decided now because it is a one-way door: a C ABI retrofitted onto a C++-shaped
design is a second, worse API wrapping the first, and every binding pins whichever
shipped. ADR 0004 records the rules and the rejected alternatives.

Tested rather than asserted: tests/graph-lite/c_abi_test.c is compiled AS C and
linked into the suite, so a header that stops being C-compatible fails our build
instead of an embedder's integration. Two things fell out of writing it —
graph_lite_status is forced to int width (a binding compiled against a different
header WILL pass an unknown code, and converting it was otherwise unspecified),
and the C++-only warning flags are now scoped to CXX so the C translation unit
does not drown in "valid for C++ but not for C".

The vocabulary guard now skips fenced code blocks in markdown only. Bun's FFI
genuinely returns a `symbols` object, and a guard that fires on a third-party API
name in an example is a guard someone disables. Source files are still scanned in
full, fences included — `SymbolNode` in a header is the leak it exists to catch,
and a test pins both halves.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HLmxQqDABCLu7TCQE3Zzmv
@developerz-ai

developerz-ai Bot commented Aug 22, 2026

Copy link
Copy Markdown

⚠️ Review did not complete

developerz.ai started reviewing this pull request and could not finish — the model review did not complete.

This is a failure of the review run, not a verdict on the changes — nothing here says the diff is good or bad. The run is recorded on this task's audit trail; a new push re-triggers the review.

🤖 developerz.ai — automated review, running on your box. This run did not complete.

@coderabbitai

coderabbitai Bot commented Aug 22, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your current included review allowance is based on your included PR review attempts over the past 7 days.

Next review available in: 46 minutes

Limit details: You’ve used the included review currently available. Your 70 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

You’re in a promotional period — use the checkbox below to run this review for free:

  • Run review for free

On-demand reviews are free for the next 29 days. After that, they cost $0.25 per reviewed file.

How can I continue?

Run this review now using the option above, or comment @coderabbitai review --use-credits.

You can also wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0789e1a0-dc23-4e4c-ab93-25fd2baa3914

📥 Commits

Reviewing files that changed from the base of the PR and between 18ee5d7 and 82e8961.

📒 Files selected for processing (20)
  • CHANGELOG.md
  • CLAUDE.md
  • README.md
  • cmake/CompilerWarnings.cmake
  • docs/architecture/decisions/0004-graph-lite-c-abi.md
  • docs/architecture/decisions/README.md
  • docs/graph-lite/README.md
  • docs/graph-lite/data-model.md
  • docs/spec.md
  • graph-lite/CLAUDE.md
  • graph-lite/CMakeLists.txt
  • graph-lite/README.md
  • graph-lite/include/graph-lite.h
  • graph-lite/include/graph-lite.hpp
  • graph-lite/src/version.cpp
  • scripts/lint/graph-lite-vocabulary.test.ts
  • scripts/lint/graph-lite-vocabulary.ts
  • tests/graph-lite/CMakeLists.txt
  • tests/graph-lite/c_abi_test.c
  • tests/graph-lite/version_test.cpp

Warning

.coderabbit.yaml has a parsing error

The CodeRabbit configuration file in this repository has a parsing error and default settings were used instead. Please fix the error(s) in the configuration file. You can initialize chat with CodeRabbit to get help with the configuration file.

💥 Parsing errors (1)
Validation error: Too big: expected string to have <=250 characters at "tone_instructions"
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Comment @coderabbitai help to get the list of available commands.

@sebyx07
sebyx07 merged commit 4988e6a into main Aug 22, 2026
9 checks passed
@sebyx07
sebyx07 deleted the feat/graph-lite-c-abi branch August 22, 2026 15:35
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