Skip to content

Releases: dekobon/big-code-analysis

v2.0.0

Choose a tag to compare

@github-actions github-actions released this 29 Jun 17:18

The project's first major version bump since 1.0, and the first
stable release on the 2.x line. It collects every breaking change
staged across the 1.x cycle behind a single major boundary. The
detailed (breaking) entries are listed under the headings below;
the migration notes here summarise the surface and consolidate the
serialized key map and the metric-value re-baseline that the
contract promised the 2.0.0 entry would carry. (The 2.0.0-rc1
release candidate, tagged 2026-06-19, carried the same change set
ahead of this stable cut.)

Migration from 1.x

The breaking changes fall into a few groups, each detailed under its
own (breaking) entry below:

  • Library Stats accessors and metric naming — Halstead,
    NArgs, and MI accessors were renamed to a uniform wire
    vocabulary, the exit metric module was renamed to nexits, and
    the Metric::NArgs / Metric::Exit variants became
    Metric::Nargs / Metric::Nexits.
  • Serialized output shape — metric keys were normalised
    (#510, #511), integer-valued metrics now serialize as integers and
    their accessors return u64 (#530), non-finite floats serialize as
    a uniform null (#531), and several wire keys were renamed (see the
    key map below).
  • CLI grammar — flags renamed (--language-type--language,
    --num-jobs--jobs, --warning--warnings), exit codes
    restructured (argv errors exit 1; 2–5 reserved for metric gates),
    and several argument-parsing behaviours tightened.
  • REST schema — uniform {error, error_kind, id} error and
    {id, language} analysis envelopes, stricter unknown-field
    rejection, a nested per-file vcs object, and removal of the
    unprefixed route aliases.
  • Default grammars.js / .jsx now parse through upstream
    tree-sitter-javascript (the Mozilla fork is demoted to the opt-in
    mozjs, owning only .jsm), .cpp / .h through upstream
    tree-sitter-cpp (Mozilla fork demoted to opt-in mozcpp), .c
    through a new LANG::C, and .m through a new LANG::Objc.
  • Python bindings — the typed surface tightened and
    analyze_batch's skip_generated default flipped from False to
    True.

Metric-value re-baseline

2.0.0 is a one-time metric-value re-baseline boundary. Values
shifted across the 1.x cycle from metric-definition fixes
(divide-by-zero guards across the suite, the per-function
cyclomatic average) and, at 2.0, from the default-grammar flips:
.c files now parse through tree-sitter-c, .m through
tree-sitter-objc, and the Mozilla C++ overlay was swapped for
upstream tree-sitter-cpp — each moves the affected files' numbers.
The integration snapshots were re-baselined in lockstep. Consumers
comparing across the 1.x2.0 boundary should treat it as a
single re-baseline rather than reconciling the union of every
patch-level drift; pin an exact version and store it alongside your
results if you need bit-for-bit reproducibility.

Serialized key & accessor renames

Library Stats accessor renames — serialized output keys are
unchanged
(these are Rust method names only):

Metric Old accessor New accessor
Halstead u_operators unique_operators
Halstead operators total_operators
Halstead u_operands unique_operands
Halstead operands total_operands
NArgs fn_args (+ _sum/_average/_min/_max) function_args (+ _sum/_average/_min/_max)
NArgs nargs_total / nargs_average total / average
MI mi_original / mi_sei / mi_visual_studio original / sei / visual_studio
Nexits (was exit) exit (+ _sum/_average/_min/_max) nexits (+ _sum/_average/_min/_max)

Module / variant renames: the exit metric module became nexits
(crate::exitcrate::nexits), Metric::ExitMetric::Nexits,
Metric::NArgsMetric::Nargs. The retired "exit" metric parse
alias no longer resolves — only "nexits" parses.

Serialized wire-key renames (JSON / YAML / TOML / CBOR, and the
matching CSV columns):

Block Old key New key
npm classes / interfaces class_npm_sum / interface_npm_sum
npa classes / interfaces class_npa_sum / interface_npa_sum
wmc classes / interfaces class_wmc_sum / interface_wmc_sum
tokens tokens_average / tokens_min / tokens_max average / min / max

The bare-sum tokens leaf is kept, and the terminal dump's
tokens-sum label changed sumtokens. The truthful sibling keys
on npm / npa / wmc (class_methods, total, coa, cda, …)
are unchanged.

Type / shape: integer-valued metrics (every count, sum, and min/max,
plus Halstead length / vocabulary and all WMC values) now
serialize as integers and their Stats accessors return u64
instead of f64; ratios, averages, ABC magnitude, the derived
Halstead scores, and MI stay f64. No value changes — only the type.

Added

  • Python Node is now a closer py-tree-sitter drop-in: a type property
    aliases kind (the py-tree-sitter spelling — kind stays the canonical
    bca name), and text is now a property rather than a method, matching
    py-tree-sitter's node.text. Together these erase the two most-common
    mechanical edits when porting a py-tree-sitter walker. The text
    method→property shape change is part of the still-unreleased #728 surface,
    so it lands free before 2.0. Covered by the make py-stubtest gate (#975).
  • Public metric_catalog::MetricScope enum (File / Function /
    Container) with MetricScope::admits(SpaceKind), a
    metric_catalog::scope(id) lookup, a scope field on the
    #[non_exhaustive] MetricInfo, and SpaceKind::from_serialized
    the single source of truth for which space kind each threshold metric
    gates (#969), shared by the CLI gate and the Python to_sarif binding
    so they cannot drift.
  • Lazy Node traversal handle for Python (big_code_analysis.Node) over
    the tree retained by Ast, so a caller walks the AST py-tree-sitter-style
    kind (with the py-tree-sitter-compatible type alias), byte offsets,
    points, children, child_by_field_name, the text property, a lazy
    pre-order walk(), descendants_by_kind()without
    materialising the tree into dicts the way dump() does (#728). Reach one
    through the new Ast.root_node property or Ast.find(filters); the node
    keeps its Ast alive, so it stays valid after every other reference to
    the parse is dropped, and is safe to share across a ThreadPoolExecutor.
    Kinds are the raw grammar kinds (not the Alterator-curated kinds
    dump() emits — they intentionally disagree on altered nodes such as
    string literals), and each node exposes its location in every vocabulary:
    start_byte/end_byte, 0-based start_point/end_point (py-tree-sitter
    parity), and 1-based start_line/end_line plus a span dict matching
    dump(). Covered by the make py-stubtest gate.
  • Node::preorder() (a pre-order iterator) and
    Node::descendants_by_kind(kinds) on the Rust Node surface — the
    Rust counterparts the Python walk() / descendants_by_kind() mirror,
    so Rust callers gain the same ergonomic traversal helpers (#728).
  • Python Ast parse-once handle (big_code_analysis.Ast) binds the Rust
    Ast seam, so a Python caller parses a source once and draws both
    metrics and the AST from the same parse instead of parsing twice — once
    in py-tree-sitter, once in analyze() (#727). Ast.parse(code, language) and Ast.from_path(path) construct the handle; .metrics()
    (byte-for-byte analyze_source), .dump() (the bca dump / /ast node
    tree), .functions(), .ops(), .count(), .strip_comments(), and
    .suppressions() all reuse the one parse. from_path is no-magic: it
    reads through the same text reader as analyze (so metrics match) but
    does not skip generated files and never silently returns nothing. New
    AstNodeDict / SpanDict / FunctionSpanDict / OpsDict /
    SuppressionMarkerDict TypedDicts; all covered by the make py-stubtest
    gate.
  • Ast::from_path on the Rust surface (the file-backed counterpart to
    Ast::parse): reads + language-detects + parses one file, returning a
    new FromPathError for each distinct failure (I/O, non-UTF-8 path,
    empty/binary/non-text file, unknown language, disabled-language build)
    (#727).
  • language_grammar_version(language) (Python) and LANG::grammar_version
    (Rust) return the pinned tree-sitter grammar crate version backing a
    language (e.g. "0.25.1" for bash) — the exact upstream version for
    crates.io grammars, the fork crate version for the vendored forks
    (#727).
  • Byte offsets in the AST dump span: every dump node's span now carries
    start_byte / end_byte (0-based, half-open) alongside the existing
    1-based line/column pairs, across the library, CLI dump, web /ast,
    and the Python dump() (#727). Structural consumers can slice the
    original source for any node — including internal nodes whose value
    the dump omits — without re-deriving offsets from lines and columns.
    (See ...
Read more

v1.1.0

Choose a tag to compare

@github-actions github-actions released this 26 May 00:21

Added

  • bca --exclude-from <FILE> global flag reads --exclude glob
    patterns from a file (one per line, .gitignore-style: blank lines
    and #-prefixed comments are skipped). Patterns union with any
    inline --exclude <GLOB> flags into a single deny-set. The
    convention is a .bcaignore at the repo root so workflow,
    recipe, and local baseline-bootstrap can share one source of truth.
    Use - for stdin. Fixes
    #355.

  • Python bindings shipped — close-out of
    #103
    (umbrella) via phase 9/9 in
    #273.
    big_code_analysis is now installable from PyPI via
    pip install big-code-analysis, exposes the same metric pipeline
    as the bca CLI, and ships abi3 manylinux wheels for Linux
    x86_64 and aarch64 on CPython 3.12+. The public surface is:
    analyze / analyze_source / analyze_batch (never-raise
    per-file errors via AnalysisError), flatten_spaces (scalar
    rows for DataFrames / sqlite), to_sarif (SARIF 2.1.0 ready for
    GitHub Code Scanning), language_for_file,
    supported_languages, language_extensions, and the metrics=
    kwarg threading through every entry point with METRIC_NAMES as
    the validated list. Output dicts match bca metrics --output-format json byte-for-byte (verified by the
    cli_parity.py example and the parametrized parity tests in
    tests/test_smoke.py). The examples/ directory ships
    cli_parity.py (CLI parity smoke test, wired into
    make py-test), pipeline_db.py (directory walk →
    analyze_batchflatten_spaces → sqlite top-N, with a
    deliberately broken file to demonstrate the never-raise
    contract), sarif_upload.py (SARIF emission ready for
    github/codeql-action/upload-sarif@v3), and
    jupyter_quickstart.ipynb (pandas DataFrame + matplotlib
    cyclomatic-per-function plot, executed end-to-end in CI via a
    new python-examples-nbconvert job). Type-checked under
    mypy --strict and pyright; PEP 561 py.typed ships in the
    built wheel. The granular per-phase implementation history lives
    in the sub-issues
    (#265#272)
    and on the commits referenced from them; this umbrella entry is
    the single end-user-facing announcement.

  • Public Ast type for parse-once, compute-many-times analysis. Build
    one with Ast::parse(Source) (re-parses bytes, mirrors analyze)
    or Ast::from_tree_sitter(lang, tree, code, name) (adopts a
    caller-built tree_sitter::Tree, the Source-flavored counterpart
    of metrics_from_tree with no lossy path-to-name conversion). Then
    call Ast::metrics(options) repeatedly against the same parse —
    with different MetricsOptions::with_only selections, interleaved
    with a custom tree-sitter walk via Ast::as_tree_sitter, or cached
    across configuration changes in an analysis pipeline. analyze and
    metrics_from_tree are now thin wrappers around the same seam, so
    the per-language dispatch table lives in exactly one place. See
    library/parse-once.md
    and library/ast-traversal.md
    for working with the held tree_sitter::Tree directly
    (#264).

  • bca check --baseline <path> and --write-baseline <path> flags
    for ratcheting thresholds on an existing codebase without raising
    limits. The baseline is a sorted TOML file keyed on (path, function, start_line, metric) that records today's offender set;
    a baselined function whose value has not worsened is filtered
    from threshold checks, but regressions (current > baseline.value)
    and new offenders still fail. Composes with in-source suppression
    markers — --write-baseline excludes already-suppressed functions
    by default, and --no-suppress --write-baseline records every
    violation for CI-auditor flows. See
    commands/check.md
    and the Baselines recipe
    for the full adoption flow
    (#99).

  • Per-language Cargo features (default: all-languages) so library
    consumers can compile only the grammars they need. Each supported
    language now has its own feature (rust, typescript, python,
    cpp, …) that gates the matching tree-sitter-* grammar crate
    in the dependency graph. The default feature set keeps the
    library's historical "every grammar compiled in" behaviour
    (bca and bca-web both pin features = ["all-languages"]
    explicitly); downstream library consumers can opt into a narrower
    set with default-features = false, features = ["rust", "typescript", …].
    The LANG enum keeps every variant defined regardless of the
    active feature set; selecting a variant whose feature is off
    produces Err(MetricsError::LanguageDisabled(LANG)) from every
    dispatch entry point. A new LANG::is_enabled predicate lets
    callers query the compiled-in set without going through a
    dispatcher
    (#252).

  • New big_code_analysis::prelude module exposing the recommended
    entry points for the 90% case: analyze, metrics_from_tree,
    Source, MetricsOptions, MetricsError, Metric, LANG,
    FuncSpace, CodeMetrics, SpaceKind. Callers can now write
    use big_code_analysis::prelude::*; instead of long
    per-import lists; everything outside the prelude is still
    reachable by its fully-qualified name from the crate root
    (#255).

  • MetricsOptions::with_only(&[Metric]) for selective metric
    computation. Pass a slice of [Metric] values to restrict the
    walker to those metrics; everything outside the set is skipped at
    the per-node level (no T::Halstead::compute, no
    T::Cognitive::compute, etc.) and elided from CodeMetrics
    serialization output. Derived metrics auto-resolve their
    dependencies — with_only(&[Metric::Mi]) silently adds
    Loc + Cyclomatic + Halstead, and with_only(&[Metric::Wmc])
    adds Cyclomatic + Nom. The Metric enum is #[non_exhaustive]
    and the backing bitfield (MetricSet) is exposed alongside it so
    callers can introspect which metrics were computed via the new
    CodeMetrics::selected() accessor. Defaults are unchanged:
    MetricsOptions::default() selects every metric, matching the
    pre-#257 behaviour byte-for-byte
    (#257).

  • New library entry point analyze(Source, MetricsOptions) -> Result<FuncSpace, MetricsError> in src/spaces.rs. Source<'a>
    is #[non_exhaustive] and carries the language, source bytes,
    optional caller-supplied display name (Source::name), optional
    C++-preprocessor path (Source::preproc_path), and optional
    PreprocResults. Construct via Source::new(lang, code) plus
    the with_name / with_preproc_path / with_preproc setters.
    This is the recommended entry point for in-memory analysis —
    callers no longer need to fabricate a &Path to identify a
    buffer
    (#254).

  • Parse seam for callers who already drive tree-sitter. New
    Parser::from_tree(tree, code) accepts a pre-built
    tree_sitter::Tree plus the matching source bytes, skipping the
    bundled parse. A non-generic metrics_from_tree(lang, tree, source, path, pr, options) -> Result<FuncSpace, MetricsError>
    dispatches on &LANG for the common case. The tree_sitter
    crate is re-exported as big_code_analysis::tree_sitter so
    consumers can build trees against the exact version the metric
    walker was compiled against without taking a sibling
    dependency; LANG::get_tree_sitter_language returns the
    matching grammar. Both seam entry points accept tree_sitter::Tree
    directly, so the internal Tree wrapper stays crate-private.
    The re-exported tree_sitter API and the
    LANG::get_tree_sitter_language return type follow the
    underlying grammar pin and are documented as value-not-stable
    in STABILITY.md. The library/reuse-tree book chapter is
    upgraded from a stub to a working example
    (#251).

  • Top-level STABILITY.md documenting the versioning contract for
    the 0.x line: which types and entry points are shape-stable,
    why no value stability is offered until 1.0, the escape hatches
    (Node.0, the still-direct tree-sitter dependency,
    #[doc(hidden)] items), and the MSRV policy
    (rust-version = "1.94" workspace-wide). Linked from the README
    under a new "Using as a library" section
    (#258).

  • In-source suppression markers for metric threshold checks. Comments
    matching bca: suppress, bca: suppress(metric, ...),
    bca: suppress-file, bca: suppress-file(metric, ...),
    #lizard forgives, or #lizard forgive global silence offending
    bca check violations without editing source. A new --no-suppress
    flag forces all markers to be ignored for CI auditors. FuncSpace
    gains a suppressed: SuppressionScope field (elided from JSON when
    empty so existing snapshots are unchanged). New public types:
    MetricKind, SuppressionScope, and SuppressionPolicy. Documented
    in the new Suppression markers book chapter
    (#98,
    #263).

  • (breaking) AstNode JSON output now carries a FieldName
    key holding the tree-sitter grammar field through which each
    node was reached (left, `rig...

Read more

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 25 May 15:12
b82d41e

Fork-anchor note. Forked from Mozilla's
rust-code-analysis
at commit 007ee15 on 2026-04-26 and renamed to big-code-analysis.
This entry consolidates all changes through the first
public release; there were no intermediate tagged releases between
the fork point and 1.0.0.

Added

New languages

  • Bash — full Checker / Getter / Alterator and metric implementations.
  • C# — full implementation with Java-parity test coverage, including
    shebang-free detection and aliased-kind_id variant handling.
  • Lua — full implementation.
  • Perl — full implementation with metrics.
  • PHP — full implementation with per-metric test matrix at Java parity
    and integration-suite wiring into the big-code-analysis-output submodule.
  • Tcl — full implementation.
  • Kotlin / Go — promoted from default implement_metric_trait! stubs
    to real per-language metric implementations. Kotlin gained Checker,
    Getter, and all seven metric traits; Go gained a real Cognitive
    complexity implementation. Both languages parsed pre-fork but emitted
    default/no-op metric values.

New metrics and metric variants

  • Per-function Tokens metric with markdown-report column wiring.
  • Modified cyclomatic complexity exposed alongside the standard count
    for languages that distinguish bare-wildcard / fall-through arms.

CLI (bca)

  • New check subcommand with a threshold engine for CI gates
    (per-metric ceilings, exit-code-driven).
  • CLI restructured into subcommand verbs (breaking) — e.g.
    bca metrics, bca check, bca find, bca count. Old top-level
    flag invocations no longer work; see the migration notes in
    big-code-analysis-book/.
  • --list-metrics command to enumerate every metric the binary supports.
  • -O markdown aggregated hotspot report with --top and
    --strip-prefix flags, padded for plain-text readability.
  • -O html aggregated hotspot report (separate from the per-file HTML
    output): hover tooltips on aggregate headers, per-language section
    tinting with a stable palette.
  • Gitignore-aware path traversal and --paths-from <file> for piping
    pre-computed file lists.
  • Mutually exclusive action flags enforced via clap ArgGroup so
    conflicting modes fail at parse time.
  • Auto-skip files marked as generated (e.g. @generated headers).
  • Shebang-based language detection for extensionless scripts.

Output formats

  • CSV output.
  • Checkstyle XML output (with reusable OffenderRecord stub).
  • SARIF 2.1.0 output for GitHub Code Scanning ingestion.
  • Clang/GCC and MSVC warning-line output formats for editor /
    CI integration.
  • Self-contained HTML per-file report.

REST API (bca-web)

  • Synchronous parsing offloaded to the blocking thread pool so the
    async runtime stays responsive under load.
  • Bounded tracking of orphaned blocking tasks; new requests are
    rejected with a clear status when the threshold is exceeded.
  • HTTP 500 responses now sanitise internal error details before
    emission.

Tooling and CI

  • Makefile-based developer and CI gate (make pre-commit,
    make ci); install targets built with target-cpu=native.
  • Workspace builds the CLI and web crates by default
    (no opt-in feature flag required).
  • Per-PR snapshot-anchor lint
    (check-snapshot-anchors.py + .github/workflows/snapshot-anchors.yml)
    enforced via baseline file .snapshot-anchor-baseline.txt.
  • Scheduled cargo-mutants job over src/metrics/,
    src/checker.rs, and src/getter.rs (quarterly cron;
    auto-files GitHub issues on escapes).
  • CI lint blocking new bare insta snapshots in src/metrics/.

Documentation

  • mdBook documentation tree at big-code-analysis-book/ with
    Recipes section, file/language detection workflow, per-output-format
    chapters, and a developer guide for adding new languages.
  • add-lang skill under .claude/skills/ codifying the end-to-end
    workflow for wiring a new tree-sitter language.
  • Lessons learned 9–14 added to
    docs/development/lessons_learned.md.

Changed

  • Project renamed from rust-code-analysis to big-code-analysis
    (fork anchor 007ee15).
  • Binaries renamed (breaking) to bca (formerly
    rust-code-analysis-cli) and bca-web (formerly
    rust-code-analysis-web). Distribution package names follow.
  • Default branch renamed from master to main.
  • Integration-snapshot submodule renamed from tests/repositories/rca-output
    to tests/repositories/big-code-analysis-output
    (remote: dekobon/big-code-analysis-output).
  • tree-sitter bumped to 0.26.8 (with Node::child(u32) signature
    adaptation in our wrapper).
  • CLI Format enum replaced with clap ValueEnum derivation —
    -O / --format accepts the same values, but error messages and
    shell completions are now generated from the type.
  • Output writers consolidated under a single dispatch path; HTML
    per-function metrics format folded into the unified writer set.
  • FindCfg / CountCfg filter lists now stored as Arc<[String]>
    (breaking, library-level) for cheaper cloning; downstream
    callers constructing these structs by hand must wrap their
    Vec<String> accordingly. bca's CLI internals also moved to
    Arc<[String]> for find/count filters.
  • FuncSpace and Ops now carry a name_was_lossy flag so callers
    can detect when a non-UTF-8 path component was lossily converted
    for display.
  • Internal cleanup: numerous refactor:, chore:, and style:
    commits across the workspace tightened visibility, removed dead
    code, consolidated test helpers, modernised Rust syntax, and
    bumped internal-only dependencies (e.g. askama 0.15 → 0.16 in
    the enums/ codegen helper crate, which is excluded from the
    default workspace). See
    git log 007ee15..HEAD --grep '^refactor\|^chore\|^style\|^build(deps)'
    for the full list.

Fixed

Metrics

  • Cognitive: handle unary negation in Kotlin and Go boolean
    sequences; exclude else arms of Kotlin when expressions from
    cognitive complexity; correct sibling boolean-sequence detection;
    generalise depth-stop tracking with correct per-language
    boundaries; implement is_else_if for Java and C# to fix
    else if over-counting.
  • Cyclomatic: skip bare wildcard _ => arms in Rust standard
    CCN; remove the spurious CaseStatement container increment
    in Bash standard CCN.
  • Nargs: count bare-identifier arrow-function parameters in
    JS/TS; correct Java and Kotlin argument counting.
  • Nom: add missing comma separators in the Stats Display
    implementation.
  • Loc: wrap parses with a synthetic Unit space when the
    grammar's root node is not Unit (e.g. languages whose root is
    program / module).
  • C#: match all aliased kind_id variants so that aliased
    syntax doesn't silently fall through.

Output

  • dump_metrics now uses cognitive_sum / cyclomatic_sum
    (was previously emitting per-function values where sums were
    expected).
  • Eliminated panic paths in the alterator + output pipeline; added
    regression tests.
  • Flattened the String2 variant in JS / TS / TSX alterators so
    template-literal substrings serialise consistently.

Web (bca-web)

  • Comment-stripping handler swaps the C++ grammar to Ccomment
    (matches the CLI's behaviour for plain-text comment removal).
  • Explicit serde derive feature flag enabled (was relying on
    transitive activation).

Robustness

  • Normalise CR and CRLF line endings before parsing
    (previously, lone-CR and CRLF inputs could drift line counts).
  • Walk the parent's children in Node::has_sibling
    (was walking the wrong node and missing siblings).
  • Spaces: handle non-UTF-8 paths via lossy conversion when
    computing the top-level space name.
  • CLI: trim whitespace from --paths-from lines before
    PathBuf construction; warn instead of silently dropping when
    non-UTF-8 path components appear in handle_path.
  • C macro lookup: switched to binary_search with short-circuit
    || for hit-path branch prediction; dropped the static
    DOLLARS buffer to avoid a panic on long identifiers.

Build / scripts / documentation

  • ops.rs — removed stray println! debug output.
  • loc.rs — fixed cloc_min / cloc_max doc comments that
    said Ploc instead of Cloc.
  • WebCommentResponse.code doc comment corrected.
  • enums/ build script — regenerate language enums after
    grammar version bumps.
  • split-minimal-tests.py — use a raw f-string so regex
    metacharacters in metric names aren't misinterpreted; escape
    metric_name before regex interpolation.
  • Cargo repository URLs updated to reference the main branch.

Removed

  • HTML per-function metrics output format
    (refactor(output): remove HTML metrics output format,
    commit eb57500). HTML output remains available via the new
    self-contained per-file HTML report (commit 7af09d1) and the
    aggregated hotspot HTML report (commit 5eb41fd); migrate
    depending on whether you want per-file or cross-file output.

Security

  • bca-web error sanitisation: HTTP 500 responses no longer
    leak internal error details (fix(web): sanitize internal error details from HTTP 500 responses, commit 99a2691).
  • bca-web orphan-task tracking: bounded tracking of orphaned
    blocking tasks rejects new requests when a configurable threshold
    is exceeded, mitigating slow-loris-style resource exhaustion of
    the blocking thread pool (fix(web): track orphaned blocking tasks and reject when threshold exceeded, commit 94c8141).

[1....

Read more