ffai-cli 0.6.6

The ffai binary — a thin shell over the FFai library crates
[package]

name = "ffai-cli"

description = "The ffai binary — a thin shell over the FFai library crates"

# follows its dependencies.

version = "0.6.6"

edition.workspace = true

rust-version.workspace = true

license.workspace = true

repository.workspace = true

authors.workspace = true

readme = "README.md"

keywords = ["cli", "speech-to-text", "tts", "ocr", "ai"]

categories = ["command-line-utilities", "multimedia", "science"]



[[bin]]

name = "ffai"

path = "src/main.rs"



[dependencies]

ffai-core = { workspace = true }

ffai-media = { workspace = true }

ffai-models = { workspace = true }

ffai-mercury = { workspace = true }

ffai-carmenta = { workspace = true }

ffai-diana = { workspace = true }

ffai-argus = { workspace = true }

ffai-bench = { workspace = true }

anyhow = { workspace = true }

# The allocator is a MEASURED component of this binary, not a preference.

#

# The system allocator re-faults nearly every byte it hands back: 58,634 page

# faults per image, ~234 MiB of freshly-faulted pages against 293.7 MiB/image

# of allocation. Swapping to an allocator that keeps pages mapped measured

# 74.6 -> 45.5 ms per image, 6/6 with non-overlapping ranges.

#

# A library cannot set a global allocator, so it is set here in the binary.

# Downstream users of `ffai-diana` as a crate do NOT inherit it and should

# make the same choice for themselves; the README says so.

#

# SUPERSEDED as the default by `rusty_alloc`, the pure-Rust remake of the same

# design — measured at parity-or-better (z = +2.43 over 49 paired rounds) with

# a better memory profile above the n tier. See the `#[global_allocator]` doc

# comment in `src/main.rs` for the table.

#

# Kept, optional, as the oracle: `--features mimalloc` switches back, which is

# what makes "our pure-Rust allocator matches the C one" a claim anyone can

# re-measure rather than one they have to take on trust.

mimalloc = { version = "0.1", default-features = false, optional = true }

# PINNED EXACTLY, and the `=` is load-bearing. 0.3.1 introduces a

# PROBABILISTIC SEGFAULT: 6 of 8 runs of `detect --track` over 50 frames die,

# where 0.3.0, 0.1.0-alpha.1 and 0.1.0-alpha.2 are 0 of 8. A caret requirement

# ("0.3.0") silently resolved to 0.3.1 mid-session and shipped a crashing

# binary, which is exactly the failure an exact pin exists to prevent.

#

# MOVED 0.3.2 -> 1.1.4 (2026-08-26). **0.3.2 has a segfault of its own**, on a

# different workload than the one that condemned 0.3.1 — which is why pinning

# away from 0.3.1 did not escape the class. Argus's vision tower runs six tile

# workers each churning a 50 MB score tensor, 12 layers x 17 tiles; under

# 0.3.2 a caption segfaults 3/3, and under 1.1.4 it is 0/3 with the allocator

# as the only variable.

#

# This is also the root cause of `ffai bench vlm` dying on its second

# `describe_image` — the crash that blocked re-running the four-gate verdict.

# It reproduced in the CLI (which declares this allocator) and never in an

# example (which declared none and got the system one), and that difference is

# what finally identified it.

rusty_alloc-api = "=1.1.4"

# The core, for `alloc::collect` — see `spawn_page_trimmer` in main.rs.

# Without it rusty_alloc's RSS does not bound on a rayon pool.

rusty_alloc = "=1.1.4"

clap = { workspace = true }



[features]

# Swap the pure-Rust allocator back out for the C library it replaced.

# Enabling this is a measurement tool, not a supported configuration.

mimalloc = ["dep:mimalloc"]



[lints.rust]

# Mirrors [workspace.lints.rust]; restated because this crate needs its own

# [lints.clippy] table, and `[lints] workspace = true` is all-or-nothing.

unsafe_code = "warn"



# Gate H-15: pedantic + nursery, enforced.

#

# The allows below are documentation and style. The numeric-cast lints that

# matter - truncation, sign loss, wrap - are NOT allowed here: this crate does

# not do the arithmetic, it calls the crates that do, and those carry the

# policy that found this audit's defects.

[lints.clippy]

pedantic = { level = "warn", priority = -1 }

nursery = { level = "warn", priority = -1 }

# Documentation debt: revisit 2026-11-15.

missing_errors_doc = "allow"

missing_panics_doc = "allow"

too_long_first_doc_paragraph = "allow"

# Counts and indices converted for display or reporting; rounding only.

cast_precision_loss = "allow"

# The depth-map writer scales a normalised value into u16 range. Guarded twice

# at the site: `is_finite()` rejects NaN and infinities, and `.clamp(0.0, 1.0)`

# bounds the value before scaling. `main` is a single long function, so the

# allow lives here rather than on a 500-line item.

cast_possible_truncation = "allow"

cast_sign_loss = "allow"

# Style preferences that do not change behaviour.

needless_pass_by_value = "allow"

items_after_statements = "allow"

too_many_lines = "allow"

similar_names = "allow"

option_if_let_else = "allow"

single_match_else = "allow"

unnested_or_patterns = "allow"

equatable_if_let = "allow"

manual_let_else = "allow"

default_trait_access = "allow"

missing_const_for_fn = "allow"

unnecessary_wraps = "allow"

format_push_string = "allow"

significant_drop_tightening = "allow"

redundant_closure_for_method_calls = "allow"