Skip to main content

Configuration

Skylos uses pyproject.toml for configuration. Run skylos init to generate a configuration file with sensible defaults, or add the [tool.skylos] section to an existing file.

Configuration File

[tool.skylos]
# Quality thresholds
complexity = 10
nesting = 3
max_args = 5
max_lines = 50
duplicate_strings = 3

# Rules to ignore (by rule ID)
ignore = []

# AI model for --fix and --audit
model = "gpt-4.1"

[tool.skylos.whitelist]
# Glob patterns to ignore as unused
names = [
"handle_*",
"visit_*",
"*Plugin",
]

[tool.skylos.whitelist.documented]
# Patterns with reasons (recommended for teams)
"dark_logic" = "Called via globals() string manipulation"
"BasePlugin" = "Discovered via __subclasses__()"

[tool.skylos.whitelist.temporary]
# Temporary whitelist - warns when expired
"legacy_handler" = { reason = "Migration - JIRA-123", expires = "2026-03-01" }

[tool.skylos.overrides."src/plugins/*"]
# Per-path whitelist rules
whitelist = ["*Plugin", "*Handler"]

[tool.skylos.dead_code]
entrypoints = []

[[tool.skylos.dead_code.entrypoints]]
type = "method"
name = ["create", "pre_hook", "post_hook"]
parent = { name = "Main", base_classes = ["Application"] }
path = "src/**"
reason = "project framework lifecycle hook"

[tool.skylos.languages.typescript]
# Language-specific overrides
complexity = 15
nesting = 4

[tool.skylos.languages.java]
complexity = 12

[tool.skylos.gate]
# Quality gate settings
fail_on_critical = true
max_security = 0
max_quality = 10
strict = false

[tool.skylos.contribution]
# Off by default. Stores structural accept/dismiss/learn signals locally only.
collect_local_signals = false
contribute_public_corpus = false
structural_signatures_only = true
include_source = false

Configuration Options

Quality Thresholds

OptionTypeDefaultDescription
complexityint10Maximum cyclomatic complexity before flagging a function
nestingint3Maximum nesting depth before flagging
max_argsint5Maximum function arguments before flagging
max_linesint50Maximum function length in lines

Analysis Options

OptionTypeDefaultDescription
ignorelist[]List of rule IDs to suppress (e.g., ["SKY-L002", "SKY-Q301"])
modelstring"gpt-4.1"LLM model for AI-powered features

Contribution Signals

The [tool.skylos.contribution] section controls AI-code defect signal capture. It is explicit, opt-in, and off by default.

OptionTypeDefaultDescription
collect_local_signalsboolfalseRecord local structural accept/dismiss/learn events
contribute_public_corpusboolfalseReserved for public corpus contribution; keep disabled unless you explicitly opt in
structural_signatures_onlybooltrueStore rule/category/severity/file extension/line bucket/hashes instead of source text
include_sourceboolfalseAlways sanitized to false; raw source is not captured

When local signal capture is enabled, Skylos stores bounded local events at:

.skylos/contribution/events.json

Events are generated from agent-service accept, dismiss, and learn actions. They include structural hashes and message hashes, not raw code. The file is local project state and should normally be gitignored.

[tool.skylos.contribution]
collect_local_signals = true
contribute_public_corpus = false
structural_signatures_only = true
include_source = false

Gate Configuration

The [tool.skylos.gate] section controls the quality gate behavior when using --gate:

OptionTypeDefaultDescription
fail_on_criticalbooltrueBlock deployment if CRITICAL security issues or secrets are found
max_securityint0Maximum allowed security findings before gate fails
max_qualityint10Maximum allowed quality findings before gate fails
strictboolfalseWhen true, prevents bypassing a failed gate interactively

Whitelist Configuration

Suppress false positives permanently without cluttering your code with inline comments.

CLI Commands

# Add a glob pattern
skylos whitelist 'handle_*'

# Add with reason (recommended for teams)
skylos whitelist dark_logic --reason "Called via globals() in dispatcher"

# View current whitelist
skylos whitelist --show

Whitelist Sections

[tool.skylos.whitelist]

Simple glob patterns for names to ignore:

[tool.skylos.whitelist]
names = [
"handle_*", # Event handlers called via getattr
"visit_*", # AST visitor methods
"*Plugin", # Plugin classes discovered via __subclasses__
"*_callback", # Callback functions
]

[tool.skylos.whitelist.documented]

Patterns with reasons - shows up in skylos whitelist --show and helps teams understand why something is whitelisted:

[tool.skylos.whitelist.documented]
"dark_logic" = "Called via globals() string manipulation in trigger_blindspots()"
"BasePlugin" = "Discovered via __subclasses__() at runtime"
"legacy_api" = "Called by external service - do not remove"

[tool.skylos.whitelist.temporary]

Patterns with expiration dates - Skylos warns when these expire to prevent whitelist rot:

[tool.skylos.whitelist.temporary]
"legacy_handler" = { reason = "Migration in progress - JIRA-123", expires = "2026-03-01" }
"old_api_v1" = { reason = "Deprecated, removing in Q2", expires = "2026-06-30" }

[tool.skylos.overrides."path/*"]

Per-file or per-folder whitelist rules:

[tool.skylos.overrides."src/plugins/*"]
whitelist = ["*Plugin", "*Handler"]

[tool.skylos.overrides."src/events/*"]
whitelist = ["on_*", "*_listener"]

Dead-Code Entrypoints

Use [[tool.skylos.dead_code.entrypoints]] when code is live because a project-specific framework, plugin loader, or decorator calls it implicitly. Entrypoint rules are more precise than broad whitelists because they can match definition type, name, path, decorator, base class, and parent class metadata.

[tool.skylos.dead_code]
entrypoints = []

[[tool.skylos.dead_code.entrypoints]]
type = "class"
name = "Main"
path = "**/main.py"
base_classes = ["Application"]
reason = "framework application entrypoint"

[[tool.skylos.dead_code.entrypoints]]
type = "method"
name = ["create", "pre_hook", "post_hook"]
parent = { name = "Main", base_classes = ["Application"] }
reason = "framework lifecycle method"

[[tool.skylos.dead_code.entrypoints]]
type = "function"
decorators = ["runtime_hook"]
path = "src/**"
reason = "registered by runtime_hook"

Supported match fields are type, name, full_name, module, path, decorator, decorators, base_class, base_classes, and parent. The parent rule can match the parent class by name, full_name, module, path, base_class, or base_classes. Rules must include a symbol selector such as name, decorators, base_classes, or parent; path, module, and type only narrow the match.

Inline Ignores

For one-off exceptions, use inline comments instead of config:

# Single line ignore
def dynamic_handler(): # skylos: ignore
pass

# Alternative syntaxes (all equivalent)
def another(): # noqa: skylos
pass

def yet_another(): # pragma: no skylos
pass

# Block ignore (multiple functions)
# skylos: ignore-start
def block_one():
pass

def block_two():
pass
# skylos: ignore-end

Whitelist Summary

Want to...Do this
Whitelist a patternskylos whitelist 'handle_*' or add to names = []
Document whyskylos whitelist x --reason "why" or add to [tool.skylos.whitelist.documented]
Temporary whitelistAdd to [tool.skylos.whitelist.temporary] with expires date
Per-folder rulesAdd [tool.skylos.overrides."path/*"] section
View all whitelistsskylos whitelist --show
Inline ignore# skylos: ignore comment
Block ignore# skylos: ignore-start ... # skylos: ignore-end

Language-Specific Overrides

You can override global settings for specific languages under [tool.skylos.languages.<lang>]:

[tool.skylos.languages.typescript]
complexity = 15
nesting = 4

[tool.skylos.languages.java]
complexity = 12

Currently supported language overrides: typescript and java.

Configuration Resolution

Skylos searches for pyproject.toml by walking up from the target path to the filesystem root. The first file containing [tool.skylos] is used. If no configuration is found, Skylos applies the built-in defaults.

This approach was chosen over per-directory configuration to keep analysis consistent across monorepos while still allowing project-level customization.

Default Excluded Folders

Skylos automatically excludes common non-source directories:

__pycache__
.git
.pytest_cache
.mypy_cache
.tox
htmlcov
.coverage
build
dist
*.egg-info
venv
.venv

To see the current exclusion list:

skylos . --list-default-excludes

To disable default exclusions:

skylos . --no-default-excludes

To force-include a normally excluded folder:

skylos . --include-folder venv