Skip to content

[FEATURE]: Go bindings (cpex-ffi + cgo) #18

@terylt

Description

@terylt

Epic: CPEX Rust Core (#12)

Summary

Create the C FFI layer (cpex-ffi crate) and Go bindings (go/ package) as the first language binding for the Rust core. Go is prioritized for K8s deployments expressed interest and Python already has a complete implementation.

Motivation

Kagenti and other Go-based agent platforms need CPEX plugin execution with the same semantics as the Python/Rust implementations. A shared Rust core with Go bindings ensures behavioral parity without reimplementing the PluginManager in Go.

Scope

cpex-ffi crate

  • #[repr(C)] result struct — continue_processing, violation_code, violation_reason, modified_payload (pointer + length)
  • Opaque handle types — cpex_manager_t, managed via Arc internally
  • Lifecycle — cpex_manager_new(), cpex_manager_free()
  • Hook dispatch — cpex_invoke_hook() with payload as byte buffer (MessagePack default, JSON debug)
  • Result access — cpex_result_blocked(), cpex_result_payload(), cpex_result_free()
  • Error reporting — cpex_last_error() (thread-local)
  • ABI versioning — cpex_abi_version()
  • cbindgen.toml → generates include/cpex.h

Go bindings (go/)

  • go.mod with module path github.com/contextforge/cpex/go, package name cpex
  • cpex.goNewManager(), InvokeHook(), Close()
  • types.goPluginResult, HookType, Extensions
  • errors.go — error types bridging cpex_last_error()
  • internal/ffi.go — cgo bindings to cpex.h (pkg-config + relative path fallback)
  • internal/memory.go — handle lifecycle, free safety

Wire Format

  • MessagePack as default (fast, compact, schema-less)
  • JSON as debug option (human-readable)
  • Zero-copy where possible: Go pins memory for input, Rust reads directly. C struct envelope for result scalars.

Acceptance Criteria

  • go test ./... passes from the monorepo (cargo build -p cpex-ffi && cd go && go test)
  • cpex.NewManager() initializes a Rust PluginManager via cgo
  • cpex.InvokeHook() dispatches through the 5-phase executor
  • ABI version check at init time
  • Result envelope readable without deserialization (C struct scalars)
  • Payload serialized only when modified

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    In progress

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions