Skip to content
Back to skills

Alef Generated Bindings

ASecurity

Alef-managed generated bindings in packages/* and binding crates — the regeneration workflow (task alef:generate / alef:verify), the alef.toml section layout, the core-side edits that break a regen, and the FFI bridge's JSON marshalling requirement. Load before editing anything under packages/* or a binding crate, before adding a trait method or extractor, or when regenerating or verifying Alef output.

  • 9,365 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 3, 2026
developmentpythonrustgojavarubyphpswiftkotlinshellnode

Security analysis

A100/100

Scanned October 3, 2026

npx -y skills add xberg-io/xberg --skill alef-generated-bindings --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Alef Generated Bindings?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Alef Generated Bindings
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/xberg-io-alef-generated-bindings/badge)](https://www.skillsdirectory.com/skills/xberg-io-alef-generated-bindings)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: alef-generated-bindings
description: Alef-managed generated bindings in packages/* and binding crates — the regeneration workflow (task alef:generate / alef:verify), the alef.toml section layout, the core-side edits that break a regen, and the FFI bridge's JSON marshalling requirement. Load before editing anything under packages/* or a binding crate, before adding a trait method or extractor, or when regenerating or verifying Alef output.
---

# Alef-Generated Bindings

Files under `packages/*/` and in the binding crates are generated by Alef — do not hand-edit.

## Workflow

1. Check `alef.toml` before touching anything in `packages/*/` or a binding crate
2. Modify the Rust source or `alef.toml` itself
3. `task alef:generate` → `alef all --clean`. This formats via poly as part of the run; there
   is no `task alef:format`
4. `task alef:verify` → `alef verify --exit-code`
5. `task e2e:generate` then `task e2e:test` (or `task e2e:all`) to verify behaviour
6. Commit Rust source + `alef.toml` + regenerated output atomically

The `alef:*` namespace is exactly: `generate`, `verify`, `build`, `sync`, `docs`,
`verify:readme-paths`, `verify:ffi-formats`. Formatting is `poly fmt` / `poly lint`.

## Freshness check

`task alef:verify`. A hand-rolled `git diff` over `packages/` is under-scoped — generated
output also lands in `crates/xberg-py/`, `crates/xberg-php/`, `crates/xberg-jni/`,
`crates/xberg-node/`, `crates/xberg-wasm/`, `crates/xberg-ffi/`, `packages/dart/rust/`,
`packages/swift/rust/`, and `e2e/`.

Alef tracks both sides under `.alef/`: `sources_hash.cache` (input hashes over the parsed
Rust sources) and `.alef/hashes/xberg.<lang>.output_hashes` (per-file output content hashes).
Neither makes a generated file safe to hand-fix — a regen restores it. Fix `alef.toml` or the
Rust source, then regenerate and re-verify.

## Key `alef.toml` sections

- `[workspace]`, `[workspace.sync]` (version-sync `extra_paths`), `[workspace.docs]`,
  `[workspace.poly]`, `[workspace.generate]`
- `[[crates]]` — the Rust source crate parsed for type/function extraction, plus
  `[[crates.source_crates]]`
- `[crates.<lang>]` — one table per binding: `python`, `node`, `ruby`, `php`, `elixir`,
  `wasm`, `ffi`, `go`, `java`, `dart`, `kotlin_android`, `jni`, `swift`, `csharp`, `zig`
  (each carrying `exclude_functions`, `target_dep_overrides`, stubs, …)
- `[crates.e2e]` — e2e generation (`output = "e2e"`, `[crates.e2e.call.overrides.<lang>]`)
- `[crates.readme]` — README generation (`template_dir = "templates/readme"`,
  `[crates.readme.languages.<lang>]`)
- `[crates.exclude]`, `[crates.output]`, `[crates.custom_modules]`, `[crates.publish]`

There are no `[crate]`, `[languages.*]`, `[e2e]` or `[readme]` top-level tables, and
`alef.toml` declares **no rename mappings** — the generated Go trait type is
`DocumentExtractor`, unchanged.

Canonical e2e tasks: `task e2e:generate`, `e2e:build`, `e2e:test`, `e2e:all`, plus
`e2e:verify`, `e2e:lint`, `e2e:quick`, `e2e:lang`. Do not add legacy aliases.

## Core-side edits that break a regen

- **New extractor struct** — needs `#[cfg_attr(alef, alef(skip))]` on the struct declaration,
  not the impl block. Without it the regen aborts globally and nothing regenerates, leaving
  the tree silently stale. Check this first when a regen dies. (36 of the 42 modules in
  `crates/xberg/src/extractors/` carry the attribute.)
- **Binding-facing types must not be `#[non_exhaustive]`** — alef generates
  `impl From<Mirror> for xberg::TheType` with a struct literal in ~10 binding crates, and
  `#[non_exhaustive]` forbids that (`E0639`). Derive `Default` for forward-compat instead.
  Keep `#[non_exhaustive]` only on types listed in `[crates.exclude]`.
- **A new enum variant on a binding-facing type** breaks exhaustive matches across the
  generated binding crates.

## Trait return types crossing the generated FFI bridge

The generated `XbergOcrBackendBridge` in `crates/xberg-ffi/src/lib.rs` marshals **every**
trait method's return value through JSON (218 `serde_json::from_str::<xberg::…>` call sites
today) and falls back to `Default::default()` on an uninitialised vtable slot, a failing host
callback, or a null result. Whether a variant carries a payload is irrelevant.

Adding a method to a trait with a generated bridge means its return type needs
`Default + Serialize + Deserialize`. Unit-only enums included.

`crates/xberg-ffi` is built by no `ci-rust.yaml` leg — only publish-path jobs — so
`cargo check --workspace` cannot fail on it. Verify with the scoped `cargo check -p xberg-ffi`.
That check rewrites `crates/xberg-ffi/include/xberg.h` and `packages/go/include/xberg.h` to
match whatever feature set you invoked it with, which is usually not the committed one. Revert
that churn rather than committing it.

## Which alef answered

`task alef:generate` shells out to the globally installed `~/.cargo/bin/alef`, not a
`cargo run` against a sibling checkout. A source fix there has zero effect until
`cargo install --path . --force`. Generator fixes ship in order: land upstream → release alef
→ bump the pinned version → regen. Regenerating against a locally modified alef produces a
tree the pinned version cannot reproduce.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…