Skip to content

RandomCodeSpace/code-signal

Repository files navigation

code-signal

Built-in, offline code quality signal for polyglot repositories

Aggregate static scan reports. No telemetry. No external analyzers. No per-file leakage.

CI Security Perf Gate SonarCloud Quality Gate

OpenSSF Best Practices OpenSSF Scorecard License


What it does

code-signal is a standalone Go CLI that scans a repository and reports aggregate code-quality signals: score, issue totals, issue categories, rule counts, detected languages/modules, and duplicate density. It is designed for local developer machines, CI jobs, and air-gapped environments.

The scanner deliberately does not invoke PMD, ESLint, Ruff, ShellCheck, Hadolint, SonarQube, or any other project-provided analyzer. Every rule is built into the binary and deterministic.

Install

go install github.com/randomcodespace/code-signal/cmd/scanner@latest

Or build from source:

git clone https://github.com/RandomCodeSpace/code-signal.git
cd code-signal
go build -trimpath -o scanner ./cmd/scanner

Quickstart

# Scan the current repository
scanner scan .

# Emit aggregate JSON
scanner scan . --json

# Exclude well-known test files and test directories
scanner scan . --exclude-tests

# Detect languages and module roots
scanner detect .

# Compare complete local git snapshots
scanner diff --base main --head HEAD .

# Check offline readiness
scanner doctor

Completed scan, diff, and detect commands exit 0 after producing a report, even when the quality score is poor or a regression is detected. Non-zero exits are reserved for CLI usage errors, invalid configuration, local git/runtime errors, context cancellation, and output write failures.

Built-in rules

Current ruleset: 0.5.0.

Rule Category Severity Signal
generic.long-line style warning Lines over the configured maximum, default 120.
generic.trailing-whitespace style warning Trailing spaces or tabs.
generic.todo maintainability info TODO, FIXME, and HACK markers in comments.
generic.duplicate-block maintainability warning Duplicate normalized 10-line logical windows.
generic.deep-nesting complexity warning Python indentation nesting and brace-control nesting for C-like languages.
generic.risky-shell security error Risky shell patterns such as `curl
generic.merge-conflict bug error Unresolved git conflict markers.
generic.parse-json bug error Invalid JSON.
generic.parse-go bug error Invalid Go syntax.
generic.go-complexity complexity warning Go cyclomatic complexity over 15.
generic.generated-skip maintainability info Generated, minified, vendor, and build-output skip policy metadata.

These are real checks, not placeholders. They are not intended to be SonarQube-compatible counts; they are code-signal's own deterministic quality signal.

Supported languages

code-signal detects and analyzes these languages with built-in lexical/parser checks:

go, javascript, typescript, python, ruby, rust, java, csharp, php, shell, dockerfile, json, toml, yaml.

Detection uses extensions, shebangs, and common manifests such as go.mod, package.json, pyproject.toml, Cargo.toml, pom.xml, Gradle files, .csproj, .sln, composer.json, Gemfile, Dockerfile, Containerfile, and *.dockerfile.

Aggregate line statistics

Scan JSON includes lines_scanned, blank_lines, code_lines, comment_lines, comment_only_lines, inline_comment_lines, and comment_density_percent. The same aggregate fields are reported for totals, by_language, and by_module; diff JSON includes before/after/delta values under totals_delta.

lines_scanned is physical scanned lines. code_lines excludes blank lines and comment-only lines, but keeps lines that contain code plus an inline comment. The score model uses code_lines when available and falls back to physical lines for older reports.

Comment detection is lexical and language-aware for supported languages: it recognizes //, #, /* ... */, Rust nested block comments, Ruby =begin/=end, and standalone Python triple-quoted doc/comment blocks where those forms are valid. It ignores common markers inside quoted strings/raw strings/template literals and JavaScript/TypeScript regex literals, and never emits per-file locations or source snippets.

Ignore files, test exclusion, and skip policy

Working-tree scans parse .gitignore, .ignore, and .git/info/exclude using gitignore-style rules before reading candidate files.

Pass --exclude-tests to scan or diff to skip well-known test-case paths from aggregate analysis. The built-in defaults cover common Go (*_test.go, testdata), Java (src/test/**, *Test.java, *Tests.java, *IT.java), Python (tests/**, test_*.py, *_test.py, conftest.py), TypeScript/JavaScript (__tests__/**, *.test.*, *.spec.*, cypress/**, playwright/**, e2e/**), and Rust (tests/**, benches/**, *_test.rs) conventions.

Built-in skips still apply for common dependency, generated, build, coverage, and minified paths such as node_modules, vendor, target, dist, build, .next, coverage, third_party, generated, gen, *.min.js, *.min.css, *.pb.go, and *_generated.go.

Configuration

Configuration is optional. If present, scanner.json is loaded from the scanned repository root or from --config.

{
  "scan": {
    "default_timeout_seconds": 0,
    "max_file_analysis_ms": 2000,
    "max_file_bytes": 1048576,
    "follow_symlinks": false,
    "workers": 0,
    "exclude_tests": false
  },
  "score": {
    "fail_under": 75,
    "error": 10,
    "warning": 4,
    "info": 1
  },
  "diff": {
    "fail_on_score_drop": true,
    "max_allowed_new_errors": 0,
    "category_regression_threshold": 1
  }
}

Unknown config fields and trailing JSON values are rejected.

scan.default_timeout_seconds is disabled by default; use --timeout or set a positive value when a whole-command emergency brake is needed. Files larger than scan.max_file_bytes are skipped before content is read. Files whose built-in analysis exceeds scan.max_file_analysis_ms are skipped after the bounded attempt. These are included in totals.files_skipped_due_to_size or totals.files_skipped_due_to_timeout. When this happens, scan and diff reports set incomplete: true, so the score is clearly a quick optimistic signal over the scanned subset.

Score model

The score is a bounded weighted issue-density signal, not a SonarQube debt rating:

weighted_density_per_kloc = round((errors*10 + warnings*4 + info*1) * 1000 / max(code_lines, 1000))
score = round(100 * 100 / (100 + weighted_density_per_kloc))

Error caps still apply after density scoring: any error caps the score at 89, and five or more errors cap it at 69. Bands are excellent for 90+, good for 75-89, needs work for 50-74, and poor below 50.

Privacy and output contract

Reports are aggregate-only. Facts and report JSON do not include file paths, line/column coordinates, snippets, clone groups, per-file findings, or source text. The scanner reads local files and local git objects only; it performs no telemetry, update checks, remote rule downloads, package installs, or network calls.

Development

go test ./...
go vet ./...
go run ./cmd/scanner scan .

Main is protected. Feature work should use a branch and pull request. Required checks mirror the CI/security pattern used by RandomCodeSpace/codeiq: Go vet/test/static analysis, OSS security scanners, duplication gate, SBOM generation, perf/self-scan gate, and OpenSSF Scorecard.

License

MIT. See LICENSE.

About

Built-in offline aggregate code-quality scanner for polyglot repositories.

Topics

Resources

License

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages