Skip to content

Contributing

AEndrix edited this page May 15, 2026 · 2 revisions

Contributing

This page is the developer onboarding for working on graft itself, not on memories stored inside it.

Layout recap

src/          C11 sources, one subdir per concern (insert/, retrieve/, ...)
include/      public-style headers (ops.h, types.h, config.h, http.h)
tests/        C-based test executables, one per file (test_*.c)
docs/         per-area markdown docs (the wiki summarizes these)
viewer/       Vue 3 + three.js SPA
integrations/ adapters for Claude Code, MCP, etc.
third_party/  submodules: BLAKE3, llama.cpp, mpack, sqlite-vec
Formula/      Homebrew formula
bucket/       Scoop manifest
.github/workflows/ CI: homebrew-bottle, scoop-bucket, release

Build

git clone --recurse-submodules https://github.com/AEndrix03/Graft.git
cd Graft

# llama.cpp first (shared libs are needed by graft)
cmake -S third_party/llama.cpp -B third_party/llama.cpp/build \
  -DBUILD_SHARED_LIBS=ON -DGGML_NATIVE=OFF \
  -DLLAMA_BUILD_TESTS=OFF -DLLAMA_BUILD_EXAMPLES=OFF \
  -DCMAKE_BUILD_TYPE=Release
cmake --build third_party/llama.cpp/build --parallel 2

# graft itself
cmake -S . -B build \
  -DCMAKE_BUILD_TYPE=Release \
  -DGRAFT_BUILD_TESTS=ON
cmake --build build --parallel

Test

cd build
ctest --output-on-failure

Tests live in tests/test_*.c. Each is a stand-alone executable that links graft_core. Add new tests by dropping a test_<name>.c in tests/ — the cmake glob picks it up automatically.

Commit conventions

Conventional Commits, enforced by .git/hooks/commit-msg (the same hook used in the homebrew formula sanity check).

<type>(<scope>): <description>

<type>feat | fix | chore | docs | style | refactor | test | perf | build | ci. Subject ≤ 70 chars. No body. No Co-Authored-By: trailer.

Examples:

feat(insert): add atomic supersession via --supersedes
fix(verify): handle empty title in trigram path
ci(brew): cap llama.cpp parallelism to avoid linux oom

Adding a new op

  1. Add the prototype to include/graft/ops.h.
  2. Implement mg_op_<name> in the appropriate src/<area>/ folder.
  3. Register it in the dispatch table in src/daemon/dispatch.c.
  4. Add a CLI subcommand in src/cli/main.c.
  5. (Optional) Add a REST endpoint in src/http/handlers.c + server.c routing.
  6. Add tests/test_<name>.c covering happy path + 1–2 edge cases.
  7. Update docs/cli/README.md.
  8. Update this wiki's Operations and CLI Reference pages.

Adding a config knob

  1. Add the field to mg_config_t in include/graft/config.h.
  2. Parse it in src/config/config.c.
  3. Bump config.example.yaml with a comment block on rationale + range.
  4. Document in this wiki's Configuration page.

Style notes

  • C11, no GCC/Clang extensions in headers.
  • All public symbols prefixed mg_ (legacy name, kept for ABI stability).
  • Error type: mg_err_t. Propagate via MG_TRY(...) macro pattern.
  • No malloc on fixed-size hot paths (use the per-thread scratch in mg_ctx_t).
  • Heap allocations on the cold paths use mg_malloc/mg_free (instrumentable).

Submitting a PR

  1. Branch off master: git checkout -b feat/whatever.
  2. Squash if there are many small fixups; otherwise keep meaningful commits.
  3. PR description should answer: what changed, why, and what's the test?
  4. The CI matrix runs on Linux x86_64 only for now (macOS/Windows targets are temporarily off the matrix — see release.yml for context).

Dependency updates

Formula/graft.rb, bucket/graft.json, and third_party/* submodules pin specific revisions. Bumping any of them:

  1. git -C third_party/<lib> checkout <new-sha>.
  2. Update the revision: in Formula/graft.rb.
  3. git add the submodule pointer + the formula.
  4. Open a PR titled chore(deps): bump <lib> to <short-sha>.

Discrepancies to fix as we ship

These are open editorial items the maintainer should sweep at some point:

  1. README still calls the cross-encoder a stub — it isn't. (Code in src/verify/crossencoder.c is complete.)
  2. README mentions Host-header DNS-rebinding mitigation — couldn't find the validation in src/http/server.c. Either implement it or remove the claim.
  3. graft profile remote sync currently accepts only local file paths. docs/profiles/README.md should make that explicit (the wiki does).

Clone this wiki locally