binding-audit

star 69

Audit bindings for coverage gaps — verify every public Rust item is exposed across all generated language bindings. Use this skill any time you need to check that a function/type is present in every target language, audit intentional exclusions, or investigate missing bindings in one or more languages. Covers the full audit flow: config review, attribute scan, item enumeration, cross-binding diff, gap reporting, and triage (alef vs Alef-owned workflow/action vs consumer config).

kreuzberg-dev By kreuzberg-dev schedule Updated 6/4/2026

name: binding-audit description: >- Audit bindings for coverage gaps — verify every public Rust item is exposed across all generated language bindings. Use this skill any time you need to check that a function/type is present in every target language, audit intentional exclusions, or investigate missing bindings in one or more languages. Covers the full audit flow: config review, attribute scan, item enumeration, cross-binding diff, gap reporting, and triage (alef vs Alef-owned workflow/action vs consumer config). license: MIT

Binding Audit

Verify that every public Rust item has a corresponding binding in all target languages. Identify coverage gaps and triage them upstream.

When to apply

  • User asks to audit bindings or check coverage
  • A function or type is missing from one or more generated bindings
  • Preparing to release — confirm all public items are bound
  • Investigating a "why isn't X available in language Y?" question
  • After adding a new public Rust item — verify it appears everywhere

Hard rules

  1. No guessing about intentional removals. Config (alef.toml) and attributes (#[alef::skip], #[alef::exclude], #[alef::opaque]) are canonical. Only flag items not covered by them.
  2. Every gap is triaged. Never report a missing binding without identifying the root cause (alef codegen bug, action script error, or config oversight).
  3. All findings update CHANGELOG.md — each upstream fix gets an [Unreleased] entry.
  4. Commit SHAs and workflow URLs are recorded so consumer repos can pin the exact fix.

Procedure

0. Gather config

From the source repo (the Rust library being bound, not alef itself):

# Open alef.toml and record:
# - [languages] enabled backends
# - [e2e] enabled language suites
# - [crates.exclude] items (global exclusions)
# - [crates.<lang>.exclude] items (per-language exclusions)
# - [workspace.exclude_types]
# - [crates.opaque_types], [workspace.opaque_types]
# - Any per-crate overrides under [workspace.crates."<name>"]
grep -E '^\[' alef.toml | head -20

Record intentional removals. Anything listed here is not a gap.

The current backend surface is Python/PyO3, TypeScript/Node/NAPI, Ruby/Magnus, PHP, Go/cgo, Java, JNI, C#, Elixir/Rustler, WASM, Dart, Kotlin, Kotlin Android, Swift, Zig, C FFI, R/extendr when enabled, and Gleam when generated. Do not invent an expected package for a language that is not enabled in alef.toml.

1. Scan source for attributes

Grep the source Rust crate for intentional skip/exclude/opaque markers:

# Find all #[alef::skip], #[alef::exclude], #[alef::opaque]
find . -name "*.rs" -type f -exec grep -l "#\[alef::" {} \;

# For each file found, inspect the context:
grep -B2 -A2 "#\[alef::" <file.rs>

Record the annotated items — these are intentional and do not flag as gaps.

2. Enumerate public items

From the source Rust crate, list all public items. Adjust the path glob to the source repo's layout (src/, crates/*/src/, or a workspace path):

# Functions:
grep -rE "^pub fn " src --include="*.rs" | wc -l

# Types (structs, enums):
grep -rE "^pub struct|^pub enum|^pub trait" src --include="*.rs"

# Methods (on pub types):
grep -rE "impl.*pub fn" src --include="*.rs"

Build a reference set: {module::ItemName} for each public item, excluding those from step 1.

3. Walk each generated binding

For each enabled language under packages/<lang>/, crates/*-<binding>/, or language-native output dirs:

# Python (generated stubs):
ls -la packages/python/*.pyi
grep -E "^def |^class " packages/python/*.pyi

# TypeScript / Node (generated .d.ts or package entrypoint):
grep -R -E "export (function|class|type|const) " packages/typescript crates/*-node --include="*.ts" --include="*.d.ts"

# Ruby:
grep -R -E "^  def |^    def " packages/ruby crates/*-rb --include="*.rb"

# PHP:
grep -R -E "function |class " packages/php --include="*.php"

# Go (FFI):
grep -R -E "^func " packages/go --include="*.go"

# Java / JNI:
grep -R -E "^\s+(public static|public) (native )?" packages/java packages/jni --include="*.java"

# C#:
grep -R -E "^\s+public (static|extern|class|struct)" packages/csharp --include="*.cs"

# Elixir:
grep -R -E "def |defmodule " packages/elixir --include="*.ex"

# WASM:
grep -R -E "export (function|class|type|const) " packages/wasm --include="*.ts" --include="*.d.ts"

# Dart:
grep -R -E "class |^[a-zA-Z_][a-zA-Z0-9_]*\\(" packages/dart --include="*.dart"

# Kotlin / Kotlin Android:
grep -R -E "fun |class " packages/kotlin packages/kotlin-android --include="*.kt"

# Swift:
grep -R -E "public (func|class|struct|enum)" packages/swift --include="*.swift"

# Zig:
grep -R -E "pub (fn|const|const.*= struct|const.*= enum)" packages/zig --include="*.zig"

# C FFI headers:
grep -R -E "^[a-zA-Z_][a-zA-Z0-9_ *]+ [a-zA-Z_][a-zA-Z0-9_]+\\(" packages/c crates/*-ffi --include="*.h"

# R / extendr:
grep -R -E "^[a-zA-Z.][a-zA-Z0-9_.]* <- function|#' @export" packages/r --include="*.R"

# Gleam:
grep -R -E "^pub (fn|type)" packages/gleam --include="*.gleam"

For each language, build a set of exported items.

4. Diff and report gaps

For each public Rust item, check presence across all binding sets:

# Pseudo-algorithm:
all_langs = [
    "python", "typescript", "ruby", "php", "go", "java", "jni", "csharp", "elixir", "wasm",
    "dart", "kotlin", "kotlin_android", "swift", "zig", "c_ffi", "r", "gleam",
]
enabled_langs = [lang for lang in all_langs if lang is enabled in alef.toml and output exists]

for each item in reference_set:
    langs_present = [lang for lang in enabled_langs if item in binding_sets[lang]]
    if len(langs_present) < len(enabled_langs):
        report(item, langs_present, missing_from=enabled_langs - langs_present)

Output: gap report with columns:

  • Rust item (function/type name)
  • Present in (comma-separated languages)
  • Missing from (comma-separated languages)
  • Intentional? (yes if config or attribute covers it, no otherwise)

5. Triage

For each non-intentional gap:

  • Codegen issue: Does the item appear in the source Rust but fail to generate in all backends? Root cause likely in src/codegen/ or a specific src/backends/<lang>/. Fix in ../alef repo.
  • Alef-owned workflow/action issue: Does an Alef-maintained scaffold or publish workflow have a bug that skips a language? Fix the owning workflow/action repository and retag only the documented action tags for that repository.
  • Consumer config issue: Is the gap listed in the consuming repo's alef.toml under [crates.exclude] or [crates.<lang>.exclude]? That's intentional — no action needed upstream.
  • Package layout issue: Does generated code exist but not in the expected package path? Fix the backend output path or package manifest wiring, not the Rust source item.
  • Unsupported type issue: Does the Rust item use a type the backend cannot express? Add explicit conversion, an opaque wrapper, or an intentional exclusion in config.

6. Document and commit

For each upstream fix:

  1. Update the source repo's CHANGELOG.md [Unreleased] section with the gap and the fix.
  2. Commit the fix (codegen or action change) with a conventional commit message.
  3. If the fix is in an Alef-owned workflow/action repository, follow that repository's documented retag procedure.
  4. For alef fixes, follow the normal release-procedure skill.
  5. Record the commit SHA and workflow URL in consumer issues so they can pin the fix.

Anti-patterns

  • Reporting a gap without checking alef.toml and #[alef::*] attributes first.
  • Assuming a missing binding is a codegen bug without checking the consuming repo's config.
  • Closing an audit issue without confirming every gap is triaged and documented.
  • Fixing a codegen bug without adding a test under tests/ or a fixture under src/e2e/ to prevent regression.

Quick reference

Step Command Output
Config grep -E '^\[' alef.toml Intentional exclusions
Attributes find . -name "*.rs" -exec grep -l "#\[alef::" {} \; Annotated items
Public items grep -rE "^pub fn|^pub struct" src Reference set
Bindings grep -R -E "export|def|func|public|fun " packages crates Per-language sets
Gaps Diff reference set vs per-language sets Gap report
Triage Root-cause analysis (config vs codegen vs action) Fix location
Install via CLI
npx skills add https://github.com/kreuzberg-dev/alef --skill binding-audit
Repository Details
star Stars 69
call_split Forks 10
navigation Branch main
article Path SKILL.md
More from Creator
kreuzberg-dev
kreuzberg-dev Explore all skills →