Skip to main content

NoEllipsis

CI Latest release Python 3.11+ MIT

A fast, local CLI that detects incomplete or dangerously truncated LLM-generated code before you paste, commit, or deploy it.

NoEllipsis is a deterministic static checker. It does not call a model, does not need an API key, and never uploads your source. It never executes the files it scans and never changes Git state.

It is not an AI-content detector, a full compiler, a vulnerability scanner, a rewriter, or a hosted service.

Terminal demo

2-minute landing

python -m pip install "noellipsis @ git+https://github.com/hoodbroskillson/NoEllipsis.git@v1.1.0"
noellipsis --version
noellipsis check examples/ok_examples.py --format text
noellipsis check examples/incomplete.py --format text
noellipsis compare examples/generated_snippet.py --against examples/original_module.py --format text

A clean file prints No issues found. An unfinished function reports NE002 and a one-line count such as 1 finding: 1 error. Compare reports shrink / removed-symbol rules (NE101NE104) plus any placeholders in the candidate.

The image above is a static terminal snapshot generated from real CLI output (see docs/demo.tape). It is not an animated GIF.

Install

Requires Python 3.11+. The project is not on PyPI yet (no version badge). After the first Trusted Publisher upload, pipx install noellipsis / pip install noellipsis will work. Until then, install from the git tag:

python -m pip install "noellipsis @ git+https://github.com/hoodbroskillson/NoEllipsis.git@v1.1.0"

Then:

noellipsis --help
python -m noellipsis --help

Local development:

python -m pip install -e ".[dev]"
ruff check .
pytest -q

The dev extra includes pytest, pytest-cov, ruff, build, twine, Hypothesis, and pre-commit. Runtime dependencies remain empty.

Commands

Shared options may appear before or after the subcommand:

noellipsis --format json check src/
noellipsis check src/ --format json
noellipsis --fail-on warning compare candidate.py --against original.py
noellipsis compare candidate.py --against original.py --fail-on warning
noellipsis --format github git-diff --staged
noellipsis git-diff --staged --format github

noellipsis check FILE_OR_DIRECTORY

Scan a file or a tree. Default excludes include .git, virtualenvs, node_modules, vendor, dist, build, coverage output, __pycache__, minified JS, and common binaries.

noellipsis check src/
noellipsis check examples/incomplete.py --format text

noellipsis compare GENERATED --against ORIGINAL

Compare a model’s candidate against the file it was supposed to edit. Reports percent size reduction, removed top-level functions/classes/methods, removed imports, snippet-as-replacement, and any placeholders the candidate introduced.

noellipsis compare examples/generated_snippet.py --against examples/original_module.py

noellipsis git-diff / noellipsis git-diff --staged

Inspect added lines in the working-tree (or staged) diff. Requires a Git repository. Uses subprocess.run with an argument list and shell=False. Does not stage, commit, reset, restore, or checkout anything.

noellipsis git-diff
noellipsis git-diff --staged --format github

Outside a repository the command exits 2 with a clear error.

noellipsis rules

Print the built-in catalog (deterministic order). --format json or text.

noellipsis rules
noellipsis rules --format json

Options

Option Meaning
--format text|json|github|sarif Human text, stable JSON, GitHub Actions annotations, or SARIF 2.1.0
--fail-on error|warning Minimum severity that yields exit code 1
--exclude PATTERN Extra glob (repeatable)
--disable RULE_ID Turn off a rule (repeatable)
--shrink-threshold 40 Percent shrinkage that triggers NE101 (integer 0–100)
--verbose Progress on stderr

Invalid CLI flags or invalid [tool.noellipsis] values print a clear error and exit 2.

Exit codes

Code Meaning
0 Nothing at or above --fail-on
1 One or more findings at or above the threshold
2 Invalid arguments, invalid config, unreadable path, not a git repo, or internal error

Rules

ID Default What it catches
NE001 error Placeholder phrases in real comments (Rest of code unchanged, Insert your code here, stub-like TODO/FIXME)
NE002 error Bare ellipsis / incomplete body. A Python function whose entire body is ... is an error
NE003 warning pass-only (or raise NotImplementedError-only) function, unless abstract or clearly intentional
NE004 error Unclosed Markdown code fence
NE005 error Unbalanced (), [], {} via a state machine that skips strings and comments
NE006 error Python syntax error / truncated statement (ast.parse)
NE007 error Unresolved merge-conflict markers
NE101 error Candidate dramatically shorter than the original (default 40% smaller)
NE102 error Top-level function, class, or method removed
NE103 warning Imports unexpectedly removed
NE104 error Probable full-file replacement with a partial snippet

Each finding includes: rule id, severity, file, line (when known), a short explanation, and a suggested next action.

What NoEllipsis deliberately does not flag

These are regression-tested:

  • print("...")
  • const copy = [...items]; and function collect(...args) {}
  • Prose such as Wait... what happened?
  • URLs and quoted documentation
  • Placeholder-looking text inside docstrings, JS/TS templates, Go raw strings, Rust raw strings, and shell heredocs
  • Intentional Python @abstractmethod / Protocol stubs
  • .pyi stub files
  • Empty constructors (def __init__(self): pass)
  • JavaScript spread / rest (...args)

Language support: strong AST for Python. Conservative heuristics for JS/TS/JSX/TSX, Java, Go, Rust, C/C++, C#, Ruby, PHP, Shell, and Markdown. Prefer a miss over a false positive.

A shared lexer classifies code / string / comment regions. Suppression phrases and placeholder detection look at comments only. The tool never executes scanned code.

Configuration

pyproject.toml:

[tool.noellipsis]
shrink-threshold = 40
fail-on = "error"
exclude = ["vendor/**", "generated/**"]
disable = ["NE103"]

See noellipsis.example.toml. CLI flags override the file.

Suppressions

Works in real comments (#, //, /* */, <!-- -->). Phrases inside strings or docstrings never suppress.

def experimental():
    ...  # noellipsis: ignore[NE002]
# noellipsis: ignore-file

Multiple ids: noellipsis: ignore[NE002,NE003].

pre-commit

repos:
  - repo: https://github.com/hoodbroskillson/NoEllipsis
    rev: v1.1.0
    hooks:
      - id: noellipsis

The hook runs noellipsis git-diff --staged with no filename arguments and does not mutate Git. Exit codes match the table above.

GitHub Actions

- uses: actions/checkout@v4
- uses: actions/setup-python@v5
  with:
    python-version: "3.12"
- run: python -m pip install "noellipsis @ git+https://github.com/hoodbroskillson/NoEllipsis.git@v1.1.0"
- run: noellipsis git-diff --format github

Reusable action (exact tag, never a floating v1):

- uses: hoodbroskillson/NoEllipsis@v1.1.0
  with:
    path: .
    command: check
    format: github
    fail-on: error

See action/README.md. SARIF upload example: .github/workflows/noellipsis-sarif.yml (contents: read, security-events: write, github/codeql-action/upload-sarif@v4).

This repository’s own CI is .github/workflows/ci.yml. The release.yml workflow builds once, checksums and attests artifacts, attaches the same bytes to the GitHub Release, and is prepared to publish to PyPI via Trusted Publisher (environment: pypi). Do not publish from a laptop.

Output

Text:

src/example.py:84:5 ERROR NE002 Bare ellipsis used as function body
  Replace the placeholder with an implementation or suppress NE002 if intentional.
1 finding: 1 error

A clean scan prints No issues found.

GitHub Actions (special characters in paths and messages are escaped):

::error file=src/example.py,line=84,col=5::NE002 Bare ellipsis used as function body

JSON is deterministic (sorted keys, findings ordered by file / line / rule). SARIF is a standalone JSON document on stdout (see docs/sarif.md).

Limitations (honest)

  • Not a type checker, compiler, formatter, or security scanner.
  • Not an AI-content detector and will not tell you whether a human wrote a file.
  • Heuristics for non-Python languages miss some syntax and ignore some comments inside unusual constructs.
  • --shrink-threshold compare is byte-size based; a shorter-but-complete rewrite can still trip NE101.
  • False positives should be reported as issues with a minimal file. Prefer a suppression over loosening a rule globally.

Safety / privacy

  • No network requests at runtime
  • No evaluation or exec of scanned files
  • Scanned files are never modified
  • Git is read-only (git rev-parse, git diff)
  • Runs entirely on the machine you invoke it on

License

MIT © 2026 hoodbroskillson

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

noellipsis-1.1.0.tar.gz (48.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

noellipsis-1.1.0-py3-none-any.whl (34.1 kB view details)

Uploaded Python 3

File details

Details for the file noellipsis-1.1.0.tar.gz.

File metadata

  • Download URL: noellipsis-1.1.0.tar.gz
  • Upload date:
  • Size: 48.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for noellipsis-1.1.0.tar.gz
Algorithm Hash digest
SHA256 154ec70778eed56725118c768cab0d5bed00c8b69264306d928ab546aa6b96b3
MD5 79de17474d9882beab0acdd2221123bf
BLAKE2b-256 3f1cca523e89eaa9cbdfb602f44fb3570e45fc0222812f5f0c1e7ef9dc02fd7e

See more details on using hashes here.

Provenance

The following attestation bundles were made for noellipsis-1.1.0.tar.gz:

Publisher: release.yml on hoodbroskillson/NoEllipsis

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file noellipsis-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: noellipsis-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 34.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for noellipsis-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 06d10994dabc7658247a07fbf362f743f5a242577c7ba69ef5d7a13d35926a84
MD5 db6a2248b8a25f8bb5fb189ddc56e232
BLAKE2b-256 c6fbaca60587775b52fb49c9923a3b1c8188c0dabe798c51aecbf11f6570b454

See more details on using hashes here.

Provenance

The following attestation bundles were made for noellipsis-1.1.0-py3-none-any.whl:

Publisher: release.yml on hoodbroskillson/NoEllipsis

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.1.2

2 files

This release

1.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page