Metadata-Version: 2.4
Name: signal-engine
Version: 0.3.0
Summary: Aggregate, normalize, and analyze static code analysis results.
Author-email: Paolo Perego <paolo@armoredcode.com>
License: AGPL-3.0
Project-URL: Homepage, https://github.com/armoredcode/signal-engine
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: typer>=0.9
Requires-Dist: appdirs>=1.4.4
Dynamic: license-file

# Signal Engine

Signal Engine is a modular tool for aggregating, normalizing, and analyzing the
output of static code analysis tools.  
It is designed to provide insight into top rules, top files, and clusters of
findings across multiple scans.

Signal Engine takes scan outputs, in JSON format, and transforms them into
actionable insights:

- Top Rules – see which rules are triggered most frequently
- Top Files – identify the files with the highest number of findings
- Clusters – group related findings to reveal patterns and correlations

## Currently supported tools

- semgrep

## Features

- Ingest and parse JSON outputs from supported tools
- Normalize findings into a consistent structure
- Compute top rules and top files
- Group findings into basic clusters
- Export results in CSV format

## Installation

```sh
pip install signal-engine
```

## Usage

### Ingesting results

Ingest findings from static analysis JSON files into the repository database.

#### Ingest multiple JSON files from a directory

```sh
signal-cli ingest --repo-name myrepo --tool semgrep /path/to/json_reports/
```

- --repo-name → name of the repository
- --tool → the tool that generated the findings (semgrep, bandit, etc.)
- positional argument → path to JSON file or directory containing multiple JSON
  files

#### Ingest a single JSON file

```sh
signal-cli ingest --repo-name myrepo --tool semgrep /path/to/json_reports/report.json
```

After ingest, all findings are stored in a SQLite database located in the
standard user data directory, and can be queried with analyze or info.

### Analyzing ingested results

By default, analyze prints results to standard output:

```sh
signal-cli analyze --repo-name myrepo
```

Optional CSV export with -o / --output:

```sh
signal-cli analyze --repo-name myrepo -o analysis.csv
```

### Show Repository Info

Basic info about a repository’s ingestion:

```sh
signal-cli info --repo-name myrepo
```

A possible output can be something like:

```sh
Repository: myrepo
DB path: /home/user/.local/share/signal-engine/<hash>.db
Ingest time: 2026-02-03T14:25:01+00:00
Number of findings: 153
```

Verbose mode with top rules and tools:

```sh
signal-cli info --repo-name myrepo --verbose
```

```sh
Repository: myrepo
DB path: /home/user/.local/share/signal-engine/<hash>.db
Ingest time: 2026-02-03T14:25:01+00:00
Number of findings: 153
Tool version used for ingest: 0.1.2
Tools in DB: semgrep, bandit
Top 5 rules:
  javascript.browser.security.eval-detected.eval-detected: 12
  python.security.audit.use-of-exec: 8
  ...
```

## Database migrations

Signal Engine uses a lightweight migration system to manage database schema
changes over time. Each repository database keeps track of applied migrations
via the `schema_migrations` table.

Migrations are distributed with the package and applied explicitly via the CLI.
This allows existing databases to be upgraded safely when new features introduce
schema changes (e.g. new tables such as `metrics`).

When running migrations, Signal Engine will:

- Detect which migrations are missing for a given repository database
- Apply them in order
- Record their application to avoid reapplying them in the future

This approach ensures backward compatibility with existing databases while
allowing the schema to evolve as new analysis features are introduced.

### Applying database migrations

Signal Engine ships with database migrations to evolve the schema of repository
databases over time (for example, when introducing new tables such as
`metrics`).

To apply migrations to a specific repository database, use the `migrate` command
and pass the repository name:

```sh
signal-cli migrate --repo-name myrepo
```

To check if a migration is needed, you can use the --check flag. Please note
that this don't apply pending migrations.

```sh
signal-cli migrate --repo-name myrepo
```

## LICENSE

[License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg) This
project is licensed under the [AGPLv3](LICENSE.md) license.
