Skip to main content

Synopsis

Requirements

crucihil analyze requires the analyze optional extra:
This installs tree-sitter, tree-sitter-c, and tree-sitter-cpp.

What it does

Real firmware components never reference DBC signal names directly. Instead, they go through shim layers:
crucihil analyze bridges this gap using a three-step pipeline:
  1. Parse — tree-sitter walks every .c, .cpp, .h, .hpp file in the source directory and collects all identifiers (functions, variables, macros, type names).
  2. Corpus — DBC files from [rig.definitions] in the rig TOML (or from --dbc) are parsed with cantools. Every MessageName.SignalName pair becomes a corpus entry, tagged with its interface type (CAN, ETH, etc.).
  3. Match — An AI (Claude, GPT-4o, or Gemini) receives the filtered identifier list and the full signal corpus. It returns JSON: which identifiers map to which signals, whether each is an input or output, and a confidence score.
The result is the signal interface contract of the component — which signals it reads (inputs) and writes (outputs) — without needing to manually trace every RTE wrapper.

Options

path
required
Path to the SWC source directory or a single .c/.cpp/.h file. All .c, .cpp, .cc, .cxx, .h, .hpp files under this path are included. Short form: -s.
string
required
Label for this component in the output (e.g. BrakeController, EngineManagement). Short form: -c.
path
Path to a rig TOML config. CruciHiL reads [rig.definitions] and auto-discovers DBC files. Interface type is inferred from the key name: can_dbc → CAN, eth_dbc → ETH. Can be combined with --dbc.
path
Path to a DBC file. Repeatable — pass multiple DBC files for multi-bus components. Interface type defaults to unknown unless inferred from key name in TOML. Example: --dbc defs/powertrain.dbc --dbc defs/chassis.dbc.
path
Path to a shim header directory or another SWC path to parse alongside the primary source. Repeatable. Use this to include RTE headers, COM module headers, or any other files where signal-related identifiers are defined. See Dependency resolution below.
string
AI provider override. One of anthropic, openai, gemini. If omitted, auto-detected from environment variables in this order: ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_API_KEY. Short form: -p.
string
default:"pretty"
Output format. pretty prints a human-readable summary. json prints the raw result as JSON.

API key setup

Set one of these environment variables before running:
The provider is auto-detected from whichever key is present. If multiple keys are set, Anthropic takes priority, then OpenAI, then Google.

Example

Example output

JSON output

Confidence scores

Every signal match comes with a confidence score:
Focus review on matches where review_required: true. These are signals where the AI found a plausible but not obvious connection between the shim identifier and the DBC signal name.

Dependency resolution

The --dep option is the most powerful knob for improving result quality. In many AUTOSAR projects, the SWC source file contains calls like Rte_Read_BC_BrakeDemandVal(...) but the actual identifier definition lives in rte/Rte_BrakeController.h. Without that header, the AI sees the call but not the type information that makes the semantic match clearer. Pass only the shim headers for the SWC you are analyzing:
Passing the entire RTE directory as --dep includes identifiers from every SWC. This increases identifier count and can confuse the AI into making cross-component matches. Pass only headers that belong to the component you are analyzing.

Without an AI key

If no API key is found, crucihil analyze returns the extracted identifiers and corpus size for manual inspection:
The JSON output includes identifiers_extracted (list) and signal_corpus_size so you can perform the matching manually or with a separate tool.

Tips for best results

Use the rig TOML instead of bare --dbc flags. The rig TOML’s [rig.definitions] section specifies interface type per key (can_dbc → CAN, eth_dbc → ETH). This gives the AI better context about which bus each signal lives on.
Analyze one SWC at a time. The tool is calibrated for a single component’s identifier space. Passing multiple SWCs in one --source call degrades precision because the AI context window fills with unrelated identifiers.
Use --output json for CI integration. The JSON output is stable and machine-readable. Pipe it to jq to extract only high-confidence matches: jq '.inputs[] | select(.review_required == false)'.
Review medium-confidence matches against the actual header. A medium confidence (0.60–0.84) match is the AI saying “these names are semantically related but I’m not certain.” Ten minutes with the relevant .h file usually confirms or refutes each one.

How to use the output

The JSON output from crucihil analyze can be fed directly into generate_test_suite as context_items:

See also