Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Cargo feature flags for crates/xberg — ORT-incompatible targets (WASM, Android x86_64 emulator), type-only and tract inference companion features, WASM/Android-safe variants, PDF backend, mutually-exclusive ORT variants, platform-conditional deps, aggregate feature sets, and build profiles. Load when adding, wiring, or debugging a Cargo feature, or when reasoning about what compiles on WASM/Android/Windows/macOS-intel targets.
.claude/skills/xberg-io-feature-flag-policy/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 28% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 200% | 0% |
| case-04 | ✗→✓ | ▲ Improved | -8% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 94% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 101% | 0% |
All features in crates/xberg/Cargo.toml.
Only ORT-dependent paths are incompatible. The same paths block both WASM (no native ORT linkage at all) and the x86_64-linux-android emulator triple (no pyke prebuilt; aarch64-linux-android does ship a prebuilt and gets full ORT):
paddle-ocr — ONNX Runtime + native C++ deps: not WASM-safe; no Android x86_64 prebuiltlayout-detection — depends on ONNX Runtime layout models: not WASM-safe; no Android x86_64 prebuilt (RT-DETR + table classifier are available off-ORT via the layout-tract sibling, below)embeddings — depends on ONNX Runtime sentence-transformer models: not WASM-safe; no Android x86_64 prebuiltauto-rotate — depends on ONNX Runtime orientation classifier: not WASM-safe; no Android x86_64 prebuilt (available off-ORT via the auto-rotate-tract sibling, below)formula-recognition — LaTeX recognition for layout formula regions (RapidLaTeXOCR ONNX): ORT-dependent, opt-in, excluded from full/formatsPure-Rust type-only companion features expose the public config/result types for the above without pulling in ORT:
layout-types — LayoutDetectionConfig, TableModel, BBox, DetectionResult, LayoutClass, LayoutDetection, RecognizedTable. layout-detection implies layout-types.auto-rotate-types — OrientationResult. auto-rotate implies auto-rotate-types.embedding-presets — EmbeddingPreset (already existed; pure-Rust preset metadata).paddle-ocr-types — the PaddleOCR config/result types without the engine. This is what no-ort-target carries in place of paddle-ocr.Pure-Rust tract inference variants run select ONNX models where native ORT cannot link, loading the same .onnx artifacts through the tract engine (CPU-only, no native library):
layout-detection (ORT) → layout-tract (tract): RT-DETR layout detection + the PP-LCNetwired/wireless table classifier run on WASM and the Android x86_64 emulator. TATR, SLANeXT, PP-DocLayout-V3, and YOLO stay ONNX Runtime-only (tract 0.23.4 op-coverage gaps).
auto-rotate (ORT) → auto-rotate-tract (tract): PP-LCNet document-orientation on WASM and theAndroid x86_64 emulator.
WASM/Android-safe variants:
ocr (native) → ocr-wasm (uses tesseract-wasm + safe image deps) — Android keeps native ocrexcel (native) → excel-wasm (drops tokio-runtime) — Android keeps native exceltree-sitter (native dlopen) → tree-sitter-wasm (statically-linked grammar pack). NOT in wasm-target: the 371-language grammar pack pushes the browser .wasm past jsDelivr's 50 MB per-file cap, breaking the CDN-hosted demo. WASM has no code intelligence; Android keeps native tree-sitter.liter-llm — NOT in no-ort-target: tokenizers → hf-hub → ureq → rustls + socks are wasm-incompatible. Enabled explicitly by android-target and full; WASM has no LLM pathstopwords — pure-Rust, included in no-ort-targetkeywords — pure-Rust YAKE/RAKE, included in no-ort-targetThe no-ort-target aggregate is the shared no-ORT base used by both wasm-target and android-target. wasm-target = no-ort-target + excel-wasm + ocr-wasm + layout-tract + auto-rotate-tract + ner-candle-wasm (NO tree-sitter — see above). android-target adds to no-ort-target: excel, tree-sitter, ocr, sceptre-ocr-tract, paddle-ocr-tract, layout-tract, auto-rotate-tract, api, mcp, liter-llm, structured, hwpx, diff, classification, captioning, ner-llm, url-ingestion. Read the manifest before assuming a member — both lists are edited often.
pdf — the canonical PDF feature. It is a pure alias: pdf = ["pdf-native"], and pdf-native carries the dependency set (dep:xberg-native-pdf, lopdf, image, flate2, html, image-encode). There is no feature literally named xberg-native-pdf. Included in formats, full, no-ort-target, and wasm-target.pdf-pdfium — the pdfium FFI comparison backend (crates/xberg-pdfium-render). Implies tokio-runtime because the pdfium calls are synchronous and must run under spawn_blocking. Opt-in; in no aggregate. Without it, selecting the pdfium backend fails loudly rather than falling back.Config value, not feature: PdfConfig.backend (core/config/pdf.rs) parses exactly "native" and "pdfium". The pre-1.1.0 spelling "pdf_oxide" is rejected, not aliased — deliberately, so it cannot survive in configs. Omitting the field defaults to Native.
ort-bundled — downloads official Microsoft ORT binaries; default when OCR/ML features activeort-dynamic — load ORT from system; only when system ORT is guaranteed presentxberg-paddle-ocr, hf-hub, pprof — excluded on wasm32ureq: rustls on non-Windows; native-tls on Windowsxberg-ffi and xberg-dart cargo dependencies are target-conditional: cfg(target_os = "android") (both ABIs — aarch64 and x86_64) and cfg(target_os = "ios") select android-target, the pure-Rust tract ML surface with no ONNX Runtime; cfg(target_os = "windows") selects windows-target (full ORT ML via ort-bundled); cfg(all(target_os = "macos", target_arch = "x86_64")) selects macos-intel-target. All other targets (Linux, macOS arm64) get the full ORT-enabled feature set. Android and iOS run inference through tract, not ORT, on every ABI — there is no arch split that gives arm64 Android phones a native ORT build.| Feature | Description | | --- | --- | | formats | Document formats only: pdf, excel, office, notebook, hwp, hwpx, iwork, email, html, xml, archives, mdx, svg, heic, wordperfect. No api/mcp/otel, no chunking, no OCR, no ML | | analysis | language-detection, chunking, quality, keywords, markdown-footnotes, diff | | services | api, mcp, otel | | full | formats + analysis + services + url-ingestion + every OCR backend + every ML feature | | formats-no-heic / full-no-heic | Same lists minus heic (and minus candle for full-no-heic), for targets with no libheif / no aarch64 fullfp16 | | no-ort-target | Pure-Rust base: every capability that does not depend on ONNX Runtime | | wasm-target | no-ort-target + excel-wasm + ocr-wasm + layout-tract + auto-rotate-tract + ner-candle-wasm (no tree-sitter — grammar pack exceeds the CDN 50 MB cap) | | android-target | no-ort-target + the native-Linux/tract set (see above); for the x86_64-linux-android emulator | | windows-target | Curated Windows host set: full minus heic (no libheif on the runner) | | windows-gnu-target | windows-target minus everything reaching ORT — pyke ships no gnu-ABI prebuilt | | macos-intel-target | ["full-no-heic", "ort-dynamic"] — no osx-x86_64 ORT prebuilt exists past 1.23 | | mobile | formats + analysis + ocr + tree-sitter + api-types + tokio-runtime |
Member lists change often. Read crates/xberg/Cargo.toml before relying on any of these descriptions for a specific feature.
task verify:feature-parity runs python3 scripts/ci/check-feature-parity.py crates/xberg/Cargo.toml.
It compares only code-bearing features — those whose definition pulls a dep:, or whose name appears in a #[cfg(feature = "…")] under crates/xberg/src. Pure aliases drop out while their members are still compared, so the rule cannot manufacture a false pass.
Guarded pairs, with the deltas each subset is allowed:
| Superset | Subset | May lack | | --- | --- | --- | | full | windows-target | heic | | formats | formats-no-heic | heic | | full | full-no-heic | heic + candle | | full | macos-intel-target | heic + candle | | full | windows-gnu-target | heic + candle + ORT-dependent |
android-target and no-ort-target are deliberately unguarded (UNGUARDED in the script): they substitute the tract stack or drop ORT outright, so encoding their deltas would turn the check into a change-detector that fires on every legitimate edit.
Consequence: adding a feature to full without adding it to windows-target fails CI.
release — LTO thin, codegen-units=1, stripprofiling — inherits release, retains debug infoxberg-wasm override: opt-level="z" (size-optimized)sevenz-rust2 override: opt-level=1 — not 2. The manifest comment is explicit: "opt-level=2 still SIGBUS'd in go:e2e". Raising it reintroduces the crashzip override: opt-level=2 (prevents SIGBUS on macOS ARM64)| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 6,709 | 6,253 | -7% | 1 | 1 | 0% | 1,161 | 3,800 | +227% | 0 | 0 | — |
case-02 | fail→pass | 25,415 | 12,797 | -50% | 1 | 1 | 0% | 3,911 | 5,025 | +28% | 0 | 0 | — |
case-03 | fail→pass | 6,094 | 3,953 | -35% | 1 | 1 | 0% | 1,135 | 3,402 | +200% | 0 | 0 | — |
case-04 | fail→pass | 22,862 | 4,390 | -81% | 1 | 1 | 0% | 3,766 | 3,468 | -8% | 0 | 0 | — |
case-05 | fail→pass | 12,369 | 4,917 | -60% | 1 | 1 | 0% | 1,814 | 3,515 | +94% | 0 | 0 | — |
case-06 | fail→pass | 10,651 | 3,204 | -70% | 1 | 1 | 0% | 1,583 | 3,186 | +101% | 0 | 0 | — |
case-07 | fail→pass | 8,974 | 2,162 | -76% | 1 | 1 | 0% | 1,575 | 3,005 | +91% | 0 | 0 | — |
case-08 | fail→pass | 17,156 | 7,211 | -58% | 1 | 1 | 0% | 2,570 | 4,074 | +59% | 0 | 0 | — |
case-09 | fail→pass | 18,058 | 2,829 | -84% | 1 | 1 | 0% | 2,957 | 3,101 | +5% | 0 | 0 | — |
case-10 | fail→pass | 14,912 | 3,266 | -78% | 1 | 1 | 0% | 2,591 | 3,237 | +25% | 0 | 0 | — |
case-11 | fail→pass | 15,941 | 2,375 | -85% | 1 | 1 | 0% | 2,614 | 3,082 | +18% | 0 | 0 | — |
case-12 | fail→pass | 8,450 | 3,173 | -62% | 1 | 1 | 0% | 1,486 | 3,194 | +115% | 0 | 0 | — |
case-13 | fail→pass | 13,929 | 3,227 | -77% | 1 | 1 | 0% | 2,203 | 3,244 | +47% | 0 | 0 | — |
case-14 | pass→pass | 10,092 | 3,174 | -69% | 1 | 1 | 0% | 1,588 | 3,189 | +101% | 0 | 0 | — |
case-15 | pass→pass | 10,026 | 2,250 | -78% | 1 | 1 | 0% | 1,583 | 2,992 | +89% | 0 | 0 | — |
case-16 | pass→pass | 13,072 | 3,486 | -73% | 1 | 1 | 0% | 1,893 | 3,235 | +71% | 0 | 0 | — |
case-17 | fail→pass | 9,834 | 4,800 | -51% | 1 | 1 | 0% | 1,530 | 3,617 | +136% | 0 | 0 | — |
case-18 | fail→pass | 12,991 | 1,930 | -85% | 1 | 1 | 0% | 1,866 | 2,918 | +56% | 0 | 0 | — |
case-19 | fail→pass | 17,829 | 3,905 | -78% | 1 | 1 | 0% | 2,740 | 3,235 | +18% | 0 | 0 | — |
case-20 | pass→pass | 6,955 | 5,449 | -22% | 1 | 1 | 0% | 1,243 | 3,563 | +187% | 0 | 0 | — |
case-21 | pass→pass | 8,063 | 7,666 | -5% | 1 | 1 | 0% | 1,416 | 3,987 | +182% | 0 | 0 | — |
case-22 | pass→pass | 4,196 | 3,070 | -27% | 1 | 1 | 0% | 648 | 3,058 | +372% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +68 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 8/18/2026 | +68% |
| gemini-3.6-flash | verified | 8/12/2026 | +64% |
Other measured skills in the registry, with their headline benchmark lift.