Type Checking
This guide covers the unreleased source implementation.
Check skylos . --help and skylos verify --help in your installed build before
using these options.
Type checking is available to anyone running Skylos. Enable it explicitly:
skylos . --type-check
skylos . --type-check --format json
skylos verify src/app.py --type-check
skylos verify . --diff origin/main --type-check
skylos done --type-check
Skylos runs the installed mypy, Pyright, Pyrefly or TypeScript compiler using
the project's configuration. It does not implement its own type system, install
packages, or run a package.json script. Normal scans and verification remain
static unless you request execution with --type-check. A checker can execute
its configured plugins, so enable this on a repository you trust.
Skylos discovers declarations in pyproject.toml, mypy.ini, .mypy.ini,
setup.cfg, pyrightconfig.json, pyrefly.toml and tsconfig.json. Install the
checker using your project's normal setup. Skylos looks in the project's
.venv, venv, node_modules/.bin, then PATH. If several checkers are
configured, select one:
skylos . --type-check --type-checker mypy
Alternatively, declare the choice in the project:
[tool.skylos.type_check]
checker = "mypy"
The compiler checks the project with its actual configuration and import
context. Skylos does not pass a changed filename to tsc and thereby discard
tsconfig.json. A normal project check shows all diagnostics. A single-file
verify displays that canonical file's diagnostics, with counts for errors
elsewhere; another file with the same basename does not match.
Read the result
Text reports show the tool, status, diagnostic locations, codes and origin
labels. JSON includes a separate top-level type_check object. Existing Skylos
findings keep their own rule IDs and severities.
Without a baseline, all current type errors block and have unclassified
origin. With verify --diff REF, a scan's --diff REF, or done, Skylos can
compare against Git's baseline using the same installed checker, configuration
and dependencies:
- introduced: the baseline did not have the diagnostic; it blocks.
- preexisting: the same diagnostic is confirmed on the corresponding unchanged source line; it remains visible and does not block.
- unclassified: attribution is uncertain; it blocks until reviewed.
An edit can break an unchanged caller. A comparable new diagnostic there is
retained with scope: "dependency_impact", even during single-file verification.
Moving or rewriting a line with an existing error does not automatically earn
a preexisting label.
A comparable opted-in check also blocks newly added compiler escape hatches in
production code: Python type-ignore directives, TypeScript @ts-ignore,
@ts-expect-error, @ts-nocheck, and assertions to any. These appear as
type-suppression or type-escape diagnostics with source: "suppression_guard".
Existing or moved suppressions, test code, generated code, and lookalike text
inside strings are excluded. This guard requires a comparable baseline;
escape_guard.status records whether it ran. Existing A118/T104 rule defaults
retain their current behavior when this opt-in check is absent.
The baseline is read into a temporary source snapshot. Skylos does not stage edits, create Git worktrees, install old dependencies, or modify the checkout. Comparison reuses the installed dependency environment and requires it to stay stable throughout the run. Changed dependency files or checker settings, source-path environment overrides, unsupported configuration inheritance, unavailable baseline dependencies, unsupported symlinks/submodules needed for a baseline run, a timeout or a checker crash produce an incomplete comparison. Current diagnostics remain available; Skylos does not claim they are preexisting. TypeScript project-reference builds are not supported by this first project-check adapter.
A missing or ambiguous checker is incomplete, with setup information rather
than a silent pass. For scans and verify, type errors exit 1 and an incomplete
requested check exits 2. --force on scans can override type errors, but cannot
turn an incomplete check into a completed check. verify --no-fail retains its
explicit exit-code override.
For scans and verify, --type-check-timeout SECONDS sets the shared time
budget for the current run and any baseline run (default 120 seconds). This
does not impose a time limit on the separate static analysis.
Enable it in Done and agent stop checks
For a trusted project policy:
[tool.skylos.done]
type_checker = "mypy"
type_check_timeout_seconds = 120
[tool.skylos.done.checks]
type_check = "block"
Done reads policy from the trusted baseline. An edit cannot disable that
policy or replace its checker. type_check = "advise" reports without blocking;
the default is "off". done --type-check explicitly strengthens the check
to blocking. --no-tests does not disable type checking. The Done receipt
includes diagnostics and origin labels, so installed agent stop hooks and
people running the CLI see the same result.
Use --profile to investigate time spent inside Skylos's
static scanner. The external type checker has its own type_check.seconds
measurement; the scanner profile does not profile the compiler or application.