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.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β
| Option | Type | Default | Description |
|---|---|---|---|
complexity | int | 10 | Maximum cyclomatic complexity before flagging a function |
nesting | int | 3 | Maximum nesting depth before flagging |
max_args | int | 5 | Maximum function arguments before flagging |
max_lines | int | 50 | Maximum function length in lines |
Analysis Optionsβ
| Option | Type | Default | Description |
|---|---|---|---|
ignore | list | [] | List of rule IDs to suppress (e.g., ["SKY-L002", "SKY-Q301"]) |
model | string | "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.
| Option | Type | Default | Description |
|---|---|---|---|
collect_local_signals | bool | false | Record local structural accept/dismiss/learn events |
contribute_public_corpus | bool | false | Reserved for public corpus contribution; keep disabled unless you explicitly opt in |
structural_signatures_only | bool | true | Store rule/category/severity/file extension/line bucket/hashes instead of source text |
include_source | bool | false | Always 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:
| Option | Type | Default | Description |
|---|---|---|---|
fail_on_critical | bool | true | Block deployment if CRITICAL security issues or secrets are found |
max_security | int | 0 | Maximum allowed security findings before gate fails |
max_quality | int | 10 | Maximum allowed quality findings before gate fails |
strict | bool | false | When 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"]
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 pattern | skylos whitelist 'handle_*' or add to names = [] |
| Document why | skylos whitelist x --reason "why" or add to [tool.skylos.whitelist.documented] |
| Temporary whitelist | Add to [tool.skylos.whitelist.temporary] with expires date |
| Per-folder rules | Add [tool.skylos.overrides."path/*"] section |
| View all whitelists | skylos 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