Skip to content

v0.1.0 — first feature-complete release

Choose a tag to compare

@acceptha acceptha released this 26 Oct 06:17
· 17 commits to main since this release

First feature-complete release.

Pipeline

  • extract — ELF parser written in C (elfdump.c, loaded with ctypes) with a pyelftools
    fallback that must produce identical results; PE via pefile (imports, VS_VERSION_INFO).
    Version-string candidates keep their file offsets. Corrupted inputs are bounds-checked and
    fuzzed in tests.
  • identify — 10 CPE-grounded YAML signature rules (OpenSSL, zlib, curl, SQLite, Expat,
    libpng, BusyBox, PCRE2, libxml2, nginx); components are marked bundled (code inside the
    file, matched) or linked (a dependency to scan separately).
  • identify --llm-hint (opt-in) — version strings no rule claimed go to the LLM; a
    suggestion is kept only if the version occurs verbatim at the cited offset and its CPE
    vendor:product is on an allowlist (every extra entry checked against the NVD CPE API on
    2026-10-23). Accepted/rejected counts are traced.
  • match — NVD CPE query with a local range re-check, fixed_in from the range ends, OSV
    references as enrichment; disk cache and recorded fixtures for offline runs.
  • retrieve — allowlisted advisory fetcher (redirects re-checked, size cap, per-host
    spacing), SQLite FTS5/BM25 index with a pure-Python BM25 fallback. Debian/Ubuntu tracker
    pages and recorded fixture pages are looked up for every CVE, not only NVD references;
    one passage per page is taken before a second from the same page.
  • advise — Anthropic (structured output) or Ollama (JSON schema) writes the Korean guide
    from a facts JSON plus <document>-wrapped passages; injection-looking passages are flagged.
    Batch size is provider-aware (Ollama 4 CVEs per call, Anthropic 12; --batch-size
    overrides) after CPU Ollama timed out on 12-CVE batches; the Ollama request timeout is
    BCPG_OLLAMA_TIMEOUT (default 600 s). Null-like fixed_in strings from the model
    ("null", "None", "N/A", "없음", "", …) are coerced to null and whitespace is
    stripped before the gate; the count is traced as normalized_fields.
  • validate — deterministic gate, rules (a)–(g) on the structured fields and (h)–(j) on the
    free text: inline citations must belong to the CVE (and to the finding's evidence), every
    version in the text must be installed / a fixed_in / a range bound, no upgrade target for a
    CVE without a fixed version, and priority words next to a CVE id must match its CVSS
    priority. Rejections are sent back verbatim (≤ 2 retries), then the template is used.
  • report — Korean report.md, report.json, and trace.json with every stage, attempt,
    rejection reason, token count and page-fetch outcome.

Tools

  • bcpg scan, bcpg identify, bcpg bench [--sets] [--online].
  • bcpg-mcp MCP server: scan_binary, lookup_cve, identify_strings.
  • Benchmark: synthetic (10 binaries) and distro (44 real libraries from Debian 10/11 and
    Ubuntu 18.04/20.04) — bundled-component precision/recall and version accuracy 100%.

Quality

  • Test suite runs with zero network and zero LLM calls (recorded NVD/OSV/page fixtures,
    scripted fake provider); tests/conftest.py blocks non-loopback sockets and the Ollama
    port, stubs the Ollama probe and clears provider/API-key/offline variables, so local
    services and shell settings cannot change results. The Anthropic SDK is imported only when
    a real client is built or an SDK error is mapped, which took a cold-venv run from 46 s to
    13 s on Windows (about 10 s warm). CI on Ubuntu with the optional extras installed.
  • Sample reports in docs/sample/: zlib 1.2.11 regenerated live with 0.1.0 (CPU Ollama; the
    gate rejected all three replies, so the template report shipped) and a template OpenSSL
    1.1.1n report.