CERT-C issue candidate detector and fixed-code candidate generator for C code
Project description
certfix
certfix is a CLI tool for detecting CERT-C issue candidates and generating fixed-code candidates for C source code with LLMs.
Features
- Detect CERT-C security violation candidates in C source code
- Use a bundled catalog of 115 CERT-C rule targets across PRE, DCL, EXP, INT, FLP, ARR, STR, MEM, FIO, ENV, SIG, ERR, CON, MSC, and POS categories
- Write AI-generated fixed-code candidates and patches
- Run the standard local path with Qwen3.6 MTP through
llama-server - Use local servers and cloud APIs through OpenAI-compatible API backends
- v0.1.1 ships profiles for local
llama-serverwith Qwen3.6-27B, OpenRouter with DeepSeek V4 Flash / Gemini 3 Flash Preview, and DeepSeek's official API with DeepSeek V4 Flash
- v0.1.1 ships profiles for local
- Reduce risk with compile validation, violation-removal checks, and semantic review gates
- Produce machine-readable JSON / SARIF output and exit codes
Installation And Requirements
Install
pip install certfix
Requirements
- Python 3.10+
- A C compiler for compile validation, such as
gccorclang
Install a compiler first:
# Ubuntu / Debian / WSL
sudo apt update
sudo apt install build-essential
# Fedora
sudo dnf install gcc
# macOS
xcode-select --install
Check the environment:
gcc --version
certfix doctor
To use clang, set validation.compile.command: clang in .certfix.yaml.
API Keys
API profiles are optional.
- OpenRouter:
OPENROUTER_API_KEY - DeepSeek official API:
DEEPSEEK_API_KEY
API routes send source code to the configured provider. Confirm your project data policy before using a cloud provider.
Local Qwen3.6-27B Setup
For local inference, run an MTP-capable llama-server separately from certfix.
You need:
- MTP-capable
llama-server- Verified:
am17an/llama.cppmtp-cleanfork, commita957b7747 - Other builds may work if they support
--spec-type draft-mtp
- Verified:
- Qwen3.6-27B MTP GGUF
- Recommended:
unsloth/Qwen3.6-27B-MTP-GGUF:UD-Q4_K_XL
- Recommended:
- Enough RAM / VRAM for the selected GGUF
- Rough minimum: 24GB VRAM + 32GB RAM
- Recommended: 32GB+ VRAM + 64GB RAM
- 16GB VRAM may require lower-bit quantization or partial offload
- Network access for the first model download, unless you already have the GGUF
Build example for Linux / WSL with NVIDIA GPU:
sudo apt update
sudo apt install -y git cmake build-essential
git clone https://github.com/am17an/llama.cpp
cd llama.cpp
git checkout a957b7747
cmake -B build -DGGML_CUDA=ON
cmake --build build --config Release -t llama-server -j "$(nproc)"
See also:
- llama.cpp build guide: https://github.com/ggml-org/llama.cpp/blob/master/docs/build.md
- llama-server README: https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md
- certfix Qwen3.6 runtime notes: docs/QWEN36_MTP_RUNTIME.md
Put the binary in PATH, or run it by explicit path:
sudo install -m 755 build/bin/llama-server /usr/local/bin/llama-server
llama-server --help | grep -- "--spec-type"
If --spec-type is not listed, that build is not the intended MTP runtime.
Start the Qwen3.6 MTP server:
llama-server \
-hf unsloth/Qwen3.6-27B-MTP-GGUF:UD-Q4_K_XL \
-ngl 99 -c 8192 -fa on -np 1 \
--host 127.0.0.1 --port 8952 \
--cache-ram 0 \
--spec-type draft-mtp --spec-draft-n-max 2 \
--reasoning-budget 1024
In another terminal:
certfix config qwen36-mtp-local --output .certfix.yaml
certfix doctor
certfix doctor shows a warning and a server command example if the local
server is not reachable. v0.1.1 does not auto-start llama-server.
Quick Start
In a cloned certfix repository checkout, try the bundled samples in
examples/input/. They include a MEM30-C use-after-free example and a
multi-function file with EXP33-C / STR31-C violations.
If you installed certfix from PyPI only, examples/input/ will not be created
in your current directory. Use your own .c file, or clone the repository to
run the bundled examples.
The commands below write results to examples/certfix-output. Source files are
not modified. certfix check writes reports, and certfix fix writes
comment-stripped fixed-code candidates under fixes/ plus patches under
patches/.
API Only
No local GPU or llama-server is required.
Docker users can run the API-only image with the current directory mounted as
/workspace. API routes send source code to the configured provider.
docker run --rm -e OPENROUTER_API_KEY -v "$PWD":/workspace ghcr.io/safe-c-ai/certfix:edge --help
See docs/DOCKER.md for Docker and Docker Compose examples.
OpenRouter with DeepSeek V4 Flash:
export OPENROUTER_API_KEY=<openrouter-key>
certfix config deepseek-v4-flash-openrouter --output .certfix.yaml
certfix check examples/input/ --output-dir examples/certfix-output
certfix fix examples/input/ --output-dir examples/certfix-output
OpenRouter with Gemini 3 Flash Preview:
export OPENROUTER_API_KEY=<openrouter-key>
certfix config gemini-3-flash-preview-openrouter --output .certfix.yaml
certfix check examples/input/ --output-dir examples/certfix-output
certfix fix examples/input/ --output-dir examples/certfix-output
Local Qwen3.6-27B Only
Start llama-server first, then run:
certfix config qwen36-mtp-local --output .certfix.yaml
certfix doctor
certfix check examples/input/ --output-dir examples/certfix-output
certfix fix examples/input/ --output-dir examples/certfix-output
This path keeps inference local and does not send code to a cloud API.
API And Local Combined
This profile uses local Qwen3.6-27B for detection and DeepSeek V4 Flash for
repair/validation. It requires both OPENROUTER_API_KEY and a running
llama-server.
export OPENROUTER_API_KEY=<openrouter-key>
certfix config local-detection-deepseek-fix --output .certfix.yaml
certfix doctor
certfix check examples/input/ --output-dir examples/certfix-output
certfix fix examples/input/ --output-dir examples/certfix-output
Example Output
For certfix check, the output directory contains machine-readable reports:
examples/certfix-output/
+-- reports/
| +-- check.json
| +-- check.sarif
| `-- summary.json
For certfix fix, certfix writes reviewable fixed-code candidates and patches
without editing the original source files:
examples/certfix-output/
+-- reports/
| +-- fixes.json
| +-- fixes.sarif
| `-- summary.json
+-- fixes/
| `-- mem30_use_after_free.fixed.c
`-- patches/
`-- mem30_use_after_free.c.patch
Paths vary by input file and function name. Treat generated code and patches as candidates for manual review, not as automatic source changes.
Commands
Basic flow:
- Create
.certfix.yamlin the directory where you run certfix. - Run
certfix doctorto check the environment, API keys, and local server. - Run
certfix check <path>to detect CERT-C violation candidates. - Run
certfix fix <path>to generate repair candidates and validation results. - Review
certfix-output/fixed-code candidates and patches, then merge changes manually if appropriate.
| Command | First argument | Description |
|---|---|---|
certfix config <profile> |
Profile name | Print or write a bundled config profile |
certfix doctor |
None | Check environment, API keys, and local server connectivity |
certfix check <path> |
C file or directory | Detect CERT-C violation candidates |
certfix fix <path> |
C file or directory | Generate repair candidates and validation results without editing source files |
Common options:
| Option | Commands | Description |
|---|---|---|
--config <file> |
doctor, check, fix, setup |
Use a config file other than .certfix.yaml |
--output-dir <dir> |
check, fix |
Save reports, comment-stripped fixed-code candidates, and patches |
--format text|json|sarif |
check, fix |
Select output format |
--force |
config |
Overwrite an existing output file |
Use certfix --help or certfix <command> --help for the full CLI reference.
certfix setup shows optional model-file diagnostics. It is not required for
the normal API or external llama-server paths.
Model Profiles
certfix writes bundled profiles to .certfix.yaml. Without --config, certfix
reads .certfix.yaml from the current working directory.
certfix config qwen36-mtp-local --output .certfix.yaml
A local Qwen3.6 profile contains connection details like:
detection:
backend: local_llama_server
prompt_profile: qwen36_certfix_check_v1
batch_size: 1
api:
base_url: http://127.0.0.1:8952/v1
model: unsloth/Qwen3.6-27B-MTP-GGUF:UD-Q4_K_XL
api_key_env: ""
For API providers, put keys in your shell environment or in a local .env file.
Existing shell environment variables take precedence over .env.
OPENROUTER_API_KEY=<openrouter-key>
DEEPSEEK_API_KEY=<deepseek-key>
Bundled profiles:
| Purpose | Profile | Notes |
|---|---|---|
| Local standard | qwen36-mtp-local |
Local Qwen3.6-27B MTP for detection and repair |
| Local check only | qwen36-mtp-check |
Detection without repair |
| API only: DeepSeek | deepseek-v4-flash-openrouter |
DeepSeek V4 Flash through OpenRouter |
| API only: Gemini | gemini-3-flash-preview-openrouter |
Gemini 3 Flash Preview through OpenRouter |
| API only: DeepSeek direct | deepseek-v4-flash-api |
DeepSeek official API |
| Local detection + API repair | local-detection-deepseek-fix |
Qwen3.6-27B detection with DeepSeek repair/validation |
| Advanced routing | deepseek-gemini-step-overrides |
Example for routing selected steps to different models |
Repair-quality guideline from the v0.1.0 CERT-C repair release test set:
Qwen3.6-27B local < DeepSeek V4 Flash < Gemini 3 Flash Preview
See docs/BENCHMARK_SUMMARY.md for benchmark context and caveats.
Selection guideline:
- Use
qwen36-mtp-localwhen you have a local GPU and do not want to send code to an external API. - Use
deepseek-v4-flash-openrouterwhen you do not have a local GPU and want a lower-cost API route. - Use
local-detection-deepseek-fixwhen you have local Qwen3.6 detection but want low-cost API repair. - Use
gemini-3-flash-preview-openrouterwhen API repair quality matters more than cost.
API routes send source code to the configured provider. For v0.1.1, the only
supported local LLM profile is Qwen3.6-27B MTP through llama-server.
Configuration
certfix reads .certfix.yaml to choose the model route, API provider,
validation gates, and project-specific exclusions.
Config lookup:
- With
--config <file>: certfix reads the specified file. - Without
--config: certfix reads.certfix.yamlin the current working directory.
If .certfix.yaml is missing, built-in defaults are incomplete for public use.
Create a profile first with certfix config <profile> --output .certfix.yaml.
Common project-specific edits:
check:
exclude:
- "tests/"
- "vendor/"
validation:
compile:
command: gcc
args: ["-fsyntax-only"]
include_paths:
- "include/"
check.exclude: files or directories to skipvalidation.compile.command: C compiler for compile validationvalidation.compile.include_paths: project header search paths for compiler validation
For header context used by analysis prompts, advanced routing, token tuning for long functions, and the full schema, see docs/CONFIGURATION.md.
Exit Codes
certfix check:
| Code | Meaning |
|---|---|
| 0 | No violations found |
| 1 | Violations found |
| 2 | Usage, configuration, model, or runtime error |
certfix fix:
| Code | Meaning |
|---|---|
| 0 | Command completed and no failed fixes were reported. Source files were not changed. |
| 1 | At least one detected issue could not be fixed or failed validation |
| 2 | Usage, configuration, model, or runtime error |
certfix doctor is diagnostic. Warnings such as a disconnected local server do
not change its exit code unless config loading itself fails. Use certfix check
exit codes for CI violation gating.
Limitations
- C only. C++ is not supported.
- Supported CERT-C coverage is limited to the 115 bundled rule targets. CERT-C recommendations are not supported. See docs/SUPPORTED_RULES.md for the supported rule catalog.
- Directory input scans
.c/.hfiles.certfix-output/is skipped. - certfix does not detect every violation, and detected violations are not always repaired correctly.
- Analysis is file/function scoped, not whole-program semantic analysis.
- Repair assumes one violation per function. Multiple violations in one function are not supported as a single repair task.
- Functions up to about 200 lines are the expected case. Results may become less stable above that, and functions over about 300 lines should be split before running certfix. See docs/CONFIGURATION.md for best-effort token/context tuning.
- Header handling is limited. System headers and deep include graphs are not fully expanded.
- v0.1.1 fixed-code candidates are comment-stripped; comment-preserving repair is not implemented.
- Source files are not modified. Review generated fixed-code candidates and patches, then merge changes manually.
- Validation gates reduce risk but do not guarantee semantic preservation, security correctness, or compile success in your target build environment.
- For release test set success rates and caveats, see docs/BENCHMARK_SUMMARY.md.
- Local LLMs require a separately running
llama-server. certfix does not auto-start it or load GGUF files in-process. - API routes send source code to the configured provider.
Documentation
The main public documents are:
| Document | Purpose |
|---|---|
| docs/INDEX.md | Documentation index |
| docs/DOCKER.md | API-only Docker and Docker Compose usage |
| docs/CONFIGURATION.md | Config lookup, bundled profiles, common edits, include paths, advanced routing, and token/context tuning |
| docs/SUPPORTED_RULES.md | Supported CERT-C rule target catalog and category coverage |
| docs/QWEN36_MTP_RUNTIME.md | Local Qwen3.6 MTP llama-server setup and verified runtime notes |
| docs/BENCHMARK_SUMMARY.md | v0.1.0 benchmark summary, release test set aggregate results, and caveats |
| docs/ARCHITECTURE.md | Release-side architecture and pipeline design |
| docs/RESEARCH_NOTES.md | Boundary between public release docs and research/archive materials |
| THIRD_PARTY_NOTICES.md | SARIF, CERT-C metadata, and dataset boundary notices |
AI-Assisted Development
certfix was developed with assistance from Codex and Claude Code for implementation, review, planning, and documentation support. Proprietary LLM outputs were not used as training targets, training-data labels, or per-record training-data audit decisions. See docs/RESEARCH_NOTES.md for the release/research boundary.
License
MIT. See LICENSE.
See THIRD_PARTY_NOTICES.md for bundled standard fixtures and rule metadata notices.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file certfix-0.1.1.tar.gz.
File metadata
- Download URL: certfix-0.1.1.tar.gz
- Upload date:
- Size: 169.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a4e3e4ae266dbc44cda3580052976e568cf3f5a231f12ee63ed005fac4f48df4
|
|
| MD5 |
26d7ea4a024928ff5b56152e98c64264
|
|
| BLAKE2b-256 |
5fb8ac016e071af716d62e6fa94a6efb851dea58b413734c99790c75b339cb14
|
File details
Details for the file certfix-0.1.1-py3-none-any.whl.
File metadata
- Download URL: certfix-0.1.1-py3-none-any.whl
- Upload date:
- Size: 103.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c51303d0a051f4812d6c54b59b96f2272356ae3d39d909eb8e272ef24c8ac1c
|
|
| MD5 |
f39b228d4720357d1f44c3c0a11b2965
|
|
| BLAKE2b-256 |
793ffc553d75277f8082862b63dcbe52103ad792016774a2bed9abf37043af07
|