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.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"]

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