Configuration Reference¶
Every key you can set in .lgtmaybe.yml, with its type, default and allowed values.
ReviewConfig¶
The user-facing configuration model. Fields map directly to .lgtmaybe.yml keys and CLI flags.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
api_base |
string / null | No | null |
Api Base |
auto_describe |
boolean | No | True |
Auto Describe |
auto_diagram |
boolean | No | True |
Auto Diagram |
batching |
BatchingConfig | No | {'include_paths': [], 'exclude_paths': [], 'max_files': 50, 'max_file_diff_lines': 2000, 'max_input_tokens': 100000, 'recursive': True, 'context_lines': 20, 'function_context': True} |
|
categories |
list[architecture / complexity / correctness / deprecation / documentation / intent / performance / ponytail / security / spec / tests] |
No | ['security', 'correctness', 'deprecation', 'tests', 'documentation', 'performance', 'complexity', 'intent', 'ponytail', 'architecture', 'spec'] |
Categories |
directory_rules |
list[DirectoryRule] | No | [] |
Directory Rules |
extra_lenses |
list[CustomLens] | No | [] |
Extra Lenses |
fail_on |
critical / high / info / low / medium / null |
No | null |
|
fallback_model |
string / null | No | null |
Fallback Model |
finding_rules |
list[FindingRule] | No | [] |
Finding Rules |
high_impact |
boolean | No | True |
High Impact |
ignore_fingerprints |
list[string] | No | [] |
Ignore Fingerprints |
incremental |
boolean / null | No | null |
Incremental |
language |
string / null | No | null |
Language |
learn_feedback |
boolean | No | True |
Learn Feedback |
limits |
LimitsConfig | No | {'max_review_seconds': 3600, 'max_review_tokens': 0, 'max_findings_per_lens': 50, 'max_concurrency': None} |
|
mid_review_retrieval |
boolean | No | False |
Mid Review Retrieval |
min_confidence |
integer | No | 0 |
Min Confidence |
min_severity |
critical / high / info / low / medium |
No | low |
|
model |
string | Yes | — | Model |
pr_labels |
boolean | No | False |
Pr Labels |
preset |
fast / full |
No | fast |
|
project |
ProjectProfile | No | — | |
provider |
anthropic / azure / bedrock / chatgpt / ollama / openai / openai-compatible / openrouter / vertex / zai |
Yes | — | |
reflect |
boolean | No | True |
Reflect |
reflect_model |
string / null | No | null |
Reflect Model |
repair_unparseable |
boolean | No | True |
Repair Unparseable |
request |
RequestConfig | No | {'timeout': None, 'temperature': 0.0, 'max_tokens': None, 'reasoning_effort': None, 'num_ctx': None} |
|
resolve_fixed |
boolean | No | True |
Resolve Fixed |
retry_without_schema |
boolean | No | True |
Retry Without Schema |
risk |
RiskConfig | No | {'enabled': True, 'core_paths': []} |
|
spec_paths |
list[string] | No | [] |
Spec Paths |
spec_review |
boolean | No | True |
Spec Review |
static_analysis |
StaticAnalysisConfig | No | {'enabled': True, 'tools': ['ruff', 'bandit', 'semgrep', 'mypy', 'gitleaks', 'zizmor', 'ast-grep', 'osv-scanner'], 'min_severity': 'info', 'tool_min_severity': {}, 'tool_mode': {}, 'semgrep_rules': None, 'ast_grep_rules': None} |
|
structured_output |
boolean | No | True |
Structured Output |
summary_template |
string / null | No | null |
Summary Template |
symbol_resolution |
boolean | No | True |
Symbol Resolution |
triage_model |
string / null | No | null |
Triage Model |
unanchored_min_severity |
critical / high / info / low / medium |
No | high |
Grouped settings¶
Settings one stage reads together sit in a group. Set each key flat at the top level, as before, or under its group. Both forms load the same config. Setting one key both ways is an error.
max_input_tokens: 40000 # flat
batching:
context_lines: 5 # nested
batching¶
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
context_lines |
integer | No | 20 |
Context Lines |
exclude_paths |
list[string] | No | [] |
Exclude Paths |
function_context |
boolean | No | True |
Function Context |
include_paths |
list[string] | No | [] |
Include Paths |
max_file_diff_lines |
integer | No | 2000 |
Max File Diff Lines |
max_files |
integer | No | 50 |
Max Files |
max_input_tokens |
integer | No | 100000 |
Max Input Tokens |
recursive |
boolean | No | True |
Recursive |
limits¶
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
max_concurrency |
integer / null | No | null |
Max Concurrency |
max_findings_per_lens |
integer | No | 50 |
Max Findings Per Lens |
max_review_seconds |
integer | No | 3600 |
Max Review Seconds |
max_review_tokens |
integer | No | 0 |
Max Review Tokens |
request¶
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
max_tokens |
integer / null | No | null |
Max Tokens |
num_ctx |
integer / null | No | null |
Num Ctx |
reasoning_effort |
string / null | No | null |
Reasoning Effort |
temperature |
number | No | 0.0 |
Temperature |
timeout |
integer / null | No | null |
Timeout |
Enums¶
Provider¶
LLM backend selected by --provider. Cloud providers (bedrock, vertex, azure) use ambient credentials — azure also needs the resource endpoint (--api-base) and accepts a key as an alternative. openai-compatible points at any server speaking the OpenAI /v1 wire format (DeepSeek, llama.cpp, LM Studio, vLLM) via --api-base; the key is optional so keyless local servers work.
anthropicazurebedrockchatgptollamaopenaiopenai-compatibleopenroutervertexzai
Severity¶
Finding severity, ordered low to high. Use min_severity in config to suppress findings below a threshold.
criticalhighinfolowmedium
ReviewFinding¶
The structured output the model must return for each inline comment. All fields are validated by pydantic before anything is posted.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
anchor |
string / null | No | null |
Anchor |
anchored |
boolean | No | True |
Anchored |
body |
string | Yes | — | Body |
broad |
boolean | No | False |
Broad |
category |
string / null | No | null |
Category |
confidence |
integer / null | No | null |
Confidence |
failure_scenario |
string / null | No | null |
Failure Scenario |
line |
integer | Yes | — | Line |
path |
string | Yes | — | Path |
severity |
critical / high / info / low / medium |
Yes | — | |
side |
string | No | RIGHT |
Side |
suggestion |
string / null | No | null |
Suggestion |
title |
string | Yes | — | Title |
ProviderResult¶
The normalised return value of one LLM completion, including token usage.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
attempts |
integer | No | 1 |
Attempts |
cache_creation_tokens |
integer | No | 0 |
Cache Creation Tokens |
cache_read_tokens |
integer | No | 0 |
Cache Read Tokens |
cost_usd |
number / null | No | null |
Cost Usd |
input_tokens |
integer | Yes | — | Input Tokens |
model |
string / null | No | null |
Model |
output_ceiling |
integer / null | No | null |
Output Ceiling |
output_tokens |
integer | Yes | — | Output Tokens |
reasoning_tokens |
integer / null | No | null |
Reasoning Tokens |
schema_dropped |
boolean | No | False |
Schema Dropped |
temperature_dropped |
boolean | No | False |
Temperature Dropped |
text |
string | Yes | — | Text |
PRContext¶
Everything the engine needs about a pull request. Fetched via the GitHub REST API — PR code is never checked out.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
base_sha |
string | Yes | — | Base Sha |
changed_files |
list[string] | Yes | — | Changed Files |
commit_messages |
list[string] | No | [] |
Commit Messages |
description |
string | No | `` | Description |
diff |
string | Yes | — | Diff |
feedback_downvotes |
list[string] | No | [] |
Feedback Downvotes |
file_contents |
object | No | — | File Contents |
head_branch |
string | No | `` | Head Branch |
head_sha |
string | Yes | — | Head Sha |
open_finding_threads |
integer | No | 0 |
Open Finding Threads |
pr_number |
integer | Yes | — | Pr Number |
repo |
string | Yes | — | Repo |
risk |
RiskAssessment / null | No | null |
|
scan_contents |
object | No | — | Scan Contents |
stack |
PRStack / null | No | null |
|
title |
string | No | `` | Title |
Raw JSON schemas¶
The canonical machine-readable schemas. These are the source of truth for provider output validation.
ReviewConfig¶
{
"$defs": {
"BatchingConfig": {
"additionalProperties": false,
"description": "How the diff becomes model calls: which files, how much of each, how much\ncontext around a hunk, and the per-call input budget.\n\nRead by the preparation stages that filter, cap, expand and split the diff,\nand wherever a later pass sizes its own prompt against ``max_input_tokens``.\nEach key can also be set flat at the top level of the config (see\n``ReviewConfig``).",
"properties": {
"context_lines": {
"default": 20,
"title": "Context Lines",
"type": "integer"
},
"exclude_paths": {
"items": {
"type": "string"
},
"title": "Exclude Paths",
"type": "array"
},
"function_context": {
"default": true,
"title": "Function Context",
"type": "boolean"
},
"include_paths": {
"items": {
"type": "string"
},
"title": "Include Paths",
"type": "array"
},
"max_file_diff_lines": {
"default": 2000,
"minimum": 0,
"title": "Max File Diff Lines",
"type": "integer"
},
"max_files": {
"default": 50,
"title": "Max Files",
"type": "integer"
},
"max_input_tokens": {
"default": 100000,
"title": "Max Input Tokens",
"type": "integer"
},
"recursive": {
"default": true,
"title": "Recursive",
"type": "boolean"
}
},
"title": "BatchingConfig",
"type": "object"
},
"CustomLens": {
"additionalProperties": false,
"description": "A user-defined review lens \u2014 a \"skill file\" run alongside the built-ins.\n\nThe engine fans it out as its own focused LLM call (same pipeline as a\nbuilt-in ``ReviewCategory``) and merges its findings with the rest. A lens is\ndeclared in **trusted** config (``.lgtmaybe.yml`` or a file referenced by\n``lens_paths``), never from PR-author content, so its text is safe to put in\nthe system prompt. Supplying a worked example (``example_diff`` +\n``example_finding``) is optional but sharply improves a small model's output.",
"properties": {
"example_diff": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Example Diff"
},
"example_finding": {
"anyOf": [
{
"$ref": "#/$defs/ReviewFinding"
},
{
"type": "null"
}
],
"default": null
},
"id": {
"title": "Id",
"type": "string"
},
"instructions": {
"title": "Instructions",
"type": "string"
},
"title": {
"default": "",
"title": "Title",
"type": "string"
}
},
"required": [
"id",
"instructions"
],
"title": "CustomLens",
"type": "object"
},
"DirectoryRule": {
"additionalProperties": false,
"description": "Extra review instructions and context scoped to part of the repo.\n\nA monorepo is not uniform: ``payments/**`` wants strictness that would be\nnoise in ``tests/**``, and reviewing ``src/**`` well may need a design doc\nthe diff never shows. Each rule names the paths it applies to (fnmatch globs\nagainst the repo-relative path, a ``**/`` prefix also matching at the repo\nroot \u2014 the same matcher the path filters use; an EMPTY list applies the rule\neverywhere, mirroring ``FindingRuleMatch``), free-text ``instructions``, and\n``context_files`` read from the checked-out workspace.\n\nBoth are trusted configuration: on ``pull_request_target`` the workspace is\nthe BASE branch, so neither the instructions nor the context text is ever\nPR-author content.",
"properties": {
"context_files": {
"items": {
"type": "string"
},
"title": "Context Files",
"type": "array"
},
"instructions": {
"default": "",
"title": "Instructions",
"type": "string"
},
"paths": {
"items": {
"type": "string"
},
"title": "Paths",
"type": "array"
}
},
"title": "DirectoryRule",
"type": "object"
},
"FindingRule": {
"additionalProperties": false,
"description": "One declarative post-processing rule, applied in list order.\n\nThe safe alternative to arbitrary user hooks: rules can only filter or\nre-grade findings \u2014 no user code ever executes.",
"properties": {
"action": {
"$ref": "#/$defs/FindingRuleAction"
},
"match": {
"$ref": "#/$defs/FindingRuleMatch",
"default": {
"category": null,
"min_severity": null,
"path": null,
"title_contains": null
}
}
},
"required": [
"action"
],
"title": "FindingRule",
"type": "object"
},
"FindingRuleAction": {
"additionalProperties": false,
"description": "What a matched rule does: drop the finding, or remap its severity.",
"properties": {
"drop": {
"default": false,
"title": "Drop",
"type": "boolean"
},
"set_severity": {
"anyOf": [
{
"$ref": "#/$defs/Severity"
},
{
"type": "null"
}
],
"default": null
}
},
"title": "FindingRuleAction",
"type": "object"
},
"FindingRuleMatch": {
"additionalProperties": false,
"description": "The selector of a finding rule. Every specified field must match (AND).\n\nAn empty match selects every finding. ``path`` is an fnmatch glob against\nthe repo-relative path (a ``**/`` prefix also matches at the repo root,\nlike the path filters); ``category`` is the originating lens id;\n``title_contains`` is a case-insensitive substring; ``min_severity``\nselects findings at or above that severity.",
"properties": {
"category": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Category"
},
"min_severity": {
"anyOf": [
{
"$ref": "#/$defs/Severity"
},
{
"type": "null"
}
],
"default": null
},
"path": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Path"
},
"title_contains": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Title Contains"
}
},
"title": "FindingRuleMatch",
"type": "object"
},
"LimitsConfig": {
"additionalProperties": false,
"description": "Whole-run ceilings: wall clock, billable tokens, findings per call, and\nhow many calls run at once.\n\nRead by the run state every call shares and by the fan-out pool. Each key\ncan also be set flat at the top level of the config.",
"properties": {
"max_concurrency": {
"anyOf": [
{
"minimum": 1,
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Max Concurrency"
},
"max_findings_per_lens": {
"default": 50,
"minimum": 0,
"title": "Max Findings Per Lens",
"type": "integer"
},
"max_review_seconds": {
"default": 3600,
"minimum": 0,
"title": "Max Review Seconds",
"type": "integer"
},
"max_review_tokens": {
"default": 0,
"minimum": 0,
"title": "Max Review Tokens",
"type": "integer"
}
},
"title": "LimitsConfig",
"type": "object"
},
"ProjectProfile": {
"additionalProperties": false,
"description": "What the repository is, so a review can be calibrated to the workload.\n\nA weekend prototype and a regulated payments service should not get the\nsame review. ``stage`` sets defaults for existing settings (a prototype\nraises the ``min_severity`` default to ``medium``; a regulated workload\nfloors the risk verdict of any change that isn't only docs and tests at\n``medium``), and an explicitly configured setting always wins. All three\nfields also render one short trusted paragraph in the shared review\npreamble. Empty (the default) is byte-identical to a review without the\nfeature.\n\nStructured on purpose: reading AGENTS.md or similar wholesale brings\ncoding-agent instructions the reviewer has no use for, and usually more\ntext than the context budget takes.",
"properties": {
"domain": {
"anyOf": [
{
"maxLength": 80,
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Domain"
},
"notes": {
"default": "",
"maxLength": 1000,
"title": "Notes",
"type": "string"
},
"stage": {
"anyOf": [
{
"enum": [
"prototype",
"production",
"regulated"
],
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Stage"
}
},
"title": "ProjectProfile",
"type": "object"
},
"Provider": {
"description": "The backend selected by the `--provider` flag.",
"enum": [
"openai",
"openrouter",
"anthropic",
"bedrock",
"vertex",
"azure",
"ollama",
"openai-compatible",
"zai",
"chatgpt"
],
"title": "Provider",
"type": "string"
},
"RequestConfig": {
"additionalProperties": false,
"description": "How each completion request is shaped: its timeout, sampling, output and\nreasoning budget, and ollama's context window.\n\nRead only where the provider client is built. Each key can also be set flat\nat the top level of the config.",
"properties": {
"max_tokens": {
"anyOf": [
{
"minimum": 0,
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Max Tokens"
},
"num_ctx": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Num Ctx"
},
"reasoning_effort": {
"anyOf": [
{
"enum": [
"none",
"minimal",
"low",
"medium",
"high",
"xhigh",
"default"
],
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Reasoning Effort"
},
"temperature": {
"default": 0.0,
"title": "Temperature",
"type": "number"
},
"timeout": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Timeout"
}
},
"title": "RequestConfig",
"type": "object"
},
"ReviewCategory": {
"description": "A single review lens. The engine asks for each one in its own LLM call.\n\n``intent`` checks the diff against the PR's stated intent (title, description,\ncommit messages); it only runs when the context carries some stated intent.\n``ponytail`` is the \"lazy senior dev\" lens \u2014 the best code is the code you\nnever wrote \u2014 flagging code that needn't exist at all (YAGNI, reach for the\nstandard library, do it in fewer lines).\n``architecture`` flags design decisions the diff introduces that are\nexpensive to reverse \u2014 coupling across boundaries, dependency direction,\nbroken substitutability, misuse-prone public surface \u2014 each tied to a\nconcrete change scenario.\n``spec`` checks the diff against a specification the repository commits\n(OpenSpec, GitHub Spec Kit, Kiro); like ``intent`` it only runs when there is\nsomething to check against \u2014 here, a detected spec that matches the PR.",
"enum": [
"security",
"correctness",
"deprecation",
"tests",
"documentation",
"performance",
"complexity",
"intent",
"ponytail",
"architecture",
"spec"
],
"title": "ReviewCategory",
"type": "string"
},
"ReviewFinding": {
"additionalProperties": false,
"description": "A single inline review comment the model wants to post.",
"properties": {
"anchor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Anchor"
},
"anchored": {
"default": true,
"title": "Anchored",
"type": "boolean"
},
"body": {
"title": "Body",
"type": "string"
},
"broad": {
"default": false,
"title": "Broad",
"type": "boolean"
},
"category": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Category"
},
"confidence": {
"anyOf": [
{
"maximum": 10,
"minimum": 0,
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Confidence"
},
"failure_scenario": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Failure Scenario"
},
"line": {
"minimum": 1,
"title": "Line",
"type": "integer"
},
"path": {
"title": "Path",
"type": "string"
},
"severity": {
"$ref": "#/$defs/Severity"
},
"side": {
"default": "RIGHT",
"enum": [
"LEFT",
"RIGHT"
],
"title": "Side",
"type": "string"
},
"suggestion": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Suggestion"
},
"title": {
"title": "Title",
"type": "string"
}
},
"required": [
"path",
"line",
"severity",
"title",
"body"
],
"title": "ReviewFinding",
"type": "object"
},
"ReviewPreset": {
"description": "How many model calls a review spends: the everyday path or the deep audit.\n\n``fast`` (the default) covers all ten everyday categories in FIVE calls,\none per concern: security, correctness (with stated intent folded in), code\nhealth, artefacts (tests + documentation), and architecture. The same five\nrun on every provider \u2014 worker count changes the schedule, not the call\ncount. A matched spec adds a sixth.\n``full`` runs each category as its own call for release\nbranches and deep audits. An explicit ``categories`` list always wins over\nthe preset.",
"enum": [
"fast",
"full"
],
"title": "ReviewPreset",
"type": "string"
},
"RiskConfig": {
"additionalProperties": false,
"description": "Risk of change: a deterministic low/medium/high/critical verdict per PR.\n\nBuilt from the change's blast radius (how many workspace files import each\nchanged file, via an ast-grep scan), the High Impact path signals, change\nsize, and whether code changed without a test changing. No model call, so\nthe verdict is free, stable across re-runs, and something a gate can read.",
"properties": {
"core_paths": {
"items": {
"type": "string"
},
"title": "Core Paths",
"type": "array"
},
"enabled": {
"default": true,
"title": "Enabled",
"type": "boolean"
}
},
"title": "RiskConfig",
"type": "object"
},
"Severity": {
"description": "Finding severity, ordered low \u2192 high for `min_severity` filtering.",
"enum": [
"info",
"low",
"medium",
"high",
"critical"
],
"title": "Severity",
"type": "string"
},
"StaticAnalysisConfig": {
"additionalProperties": false,
"description": "Static-analysis fusion: deterministic tool findings as LLM grounding.\n\nOn by default: the installed tools run over the already-fetched\nchanged-file texts (sandboxed subprocess, scrubbed environment, no network,\nnever a checkout) and, in the default ``hint`` mode, their findings enter\neach lens prompt as untrusted HINTS (\"confirm, contextualise, or discard\"),\nraising recall on the deterministic bugs models miss without posting raw\nlinter noise. A tool that isn't installed is skipped silently, so the\nfeature degrades to nothing on a minimal install.",
"properties": {
"ast_grep_rules": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Ast Grep Rules"
},
"enabled": {
"default": true,
"title": "Enabled",
"type": "boolean"
},
"min_severity": {
"$ref": "#/$defs/Severity",
"default": "info"
},
"semgrep_rules": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Semgrep Rules"
},
"tool_min_severity": {
"additionalProperties": {
"$ref": "#/$defs/Severity"
},
"propertyNames": {
"$ref": "#/$defs/StaticAnalysisTool"
},
"title": "Tool Min Severity",
"type": "object"
},
"tool_mode": {
"additionalProperties": {
"$ref": "#/$defs/ToolMode"
},
"propertyNames": {
"$ref": "#/$defs/StaticAnalysisTool"
},
"title": "Tool Mode",
"type": "object"
},
"tools": {
"default": [
"ruff",
"bandit",
"semgrep",
"mypy",
"gitleaks",
"zizmor",
"ast-grep",
"osv-scanner"
],
"items": {
"$ref": "#/$defs/StaticAnalysisTool"
},
"title": "Tools",
"type": "array"
}
},
"title": "StaticAnalysisConfig",
"type": "object"
},
"StaticAnalysisTool": {
"description": "A deterministic linter/SAST tool whose findings feed the review.\n\nThe value is the binary name looked up on PATH, so it may differ from the\nmember name where the binary is hyphenated.",
"enum": [
"ruff",
"bandit",
"semgrep",
"mypy",
"gitleaks",
"zizmor",
"ast-grep",
"osv-scanner"
],
"title": "StaticAnalysisTool",
"type": "string"
},
"ToolMode": {
"description": "How a tool's findings reach the review.\n\n``hint`` (the default for every tool): findings become an untrusted HINTS\nblock the model confirms, contextualises, or discards, so every tool takes\none path and the model sees each hit in context. ``finding`` skips the model\nentirely and posts the tool's result as a review comment.\n\n``finding`` is a per-tool opt-in through ``static_analysis.tool_mode``, for a\ntool whose claims need no interpretation: in hint mode the model can discard\na real hit, such as a committed secret. Defaults live in\n``engine.static_analysis``.",
"enum": [
"hint",
"finding"
],
"title": "ToolMode",
"type": "string"
}
},
"additionalProperties": false,
"description": "How to run one review: provider/model, severity floor, filters, caps.\n\nSettings one stage reads together live in a group (``batching``, ``limits``,\n``request``, like ``static_analysis`` and ``risk``), so a reader names the\ngroup it depends on: ``cfg.batching.max_input_tokens``. Every surface that\nsets config still speaks the flat keys (``max_input_tokens: 40000`` in\n``.lgtmaybe.yml``, ``lgtmaybe config set``, CLI flags, Action inputs,\n``ReviewConfig(max_input_tokens=...)``): ``_lift_groups`` moves each into\nits group before validation. ``flat_fields`` is that flat key set.",
"properties": {
"api_base": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Api Base"
},
"auto_describe": {
"default": true,
"title": "Auto Describe",
"type": "boolean"
},
"auto_diagram": {
"default": true,
"title": "Auto Diagram",
"type": "boolean"
},
"batching": {
"$ref": "#/$defs/BatchingConfig",
"default": {
"context_lines": 20,
"exclude_paths": [],
"function_context": true,
"include_paths": [],
"max_file_diff_lines": 2000,
"max_files": 50,
"max_input_tokens": 100000,
"recursive": true
}
},
"categories": {
"default": [
"security",
"correctness",
"deprecation",
"tests",
"documentation",
"performance",
"complexity",
"intent",
"ponytail",
"architecture",
"spec"
],
"items": {
"$ref": "#/$defs/ReviewCategory"
},
"title": "Categories",
"type": "array"
},
"directory_rules": {
"items": {
"$ref": "#/$defs/DirectoryRule"
},
"title": "Directory Rules",
"type": "array"
},
"extra_lenses": {
"items": {
"$ref": "#/$defs/CustomLens"
},
"title": "Extra Lenses",
"type": "array"
},
"fail_on": {
"anyOf": [
{
"$ref": "#/$defs/Severity"
},
{
"type": "null"
}
],
"default": null
},
"fallback_model": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Fallback Model"
},
"finding_rules": {
"items": {
"$ref": "#/$defs/FindingRule"
},
"title": "Finding Rules",
"type": "array"
},
"high_impact": {
"default": true,
"title": "High Impact",
"type": "boolean"
},
"ignore_fingerprints": {
"items": {
"type": "string"
},
"title": "Ignore Fingerprints",
"type": "array"
},
"incremental": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"title": "Incremental"
},
"language": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Language"
},
"learn_feedback": {
"default": true,
"title": "Learn Feedback",
"type": "boolean"
},
"limits": {
"$ref": "#/$defs/LimitsConfig",
"default": {
"max_concurrency": null,
"max_findings_per_lens": 50,
"max_review_seconds": 3600,
"max_review_tokens": 0
}
},
"mid_review_retrieval": {
"default": false,
"title": "Mid Review Retrieval",
"type": "boolean"
},
"min_confidence": {
"default": 0,
"maximum": 10,
"minimum": 0,
"title": "Min Confidence",
"type": "integer"
},
"min_severity": {
"$ref": "#/$defs/Severity",
"default": "low"
},
"model": {
"title": "Model",
"type": "string"
},
"pr_labels": {
"default": false,
"title": "Pr Labels",
"type": "boolean"
},
"preset": {
"$ref": "#/$defs/ReviewPreset",
"default": "fast"
},
"project": {
"$ref": "#/$defs/ProjectProfile"
},
"provider": {
"$ref": "#/$defs/Provider"
},
"reflect": {
"default": true,
"title": "Reflect",
"type": "boolean"
},
"reflect_model": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Reflect Model"
},
"repair_unparseable": {
"default": true,
"title": "Repair Unparseable",
"type": "boolean"
},
"request": {
"$ref": "#/$defs/RequestConfig",
"default": {
"max_tokens": null,
"num_ctx": null,
"reasoning_effort": null,
"temperature": 0.0,
"timeout": null
}
},
"resolve_fixed": {
"default": true,
"title": "Resolve Fixed",
"type": "boolean"
},
"retry_without_schema": {
"default": true,
"title": "Retry Without Schema",
"type": "boolean"
},
"risk": {
"$ref": "#/$defs/RiskConfig",
"default": {
"core_paths": [],
"enabled": true
}
},
"spec_paths": {
"items": {
"type": "string"
},
"title": "Spec Paths",
"type": "array"
},
"spec_review": {
"default": true,
"title": "Spec Review",
"type": "boolean"
},
"static_analysis": {
"$ref": "#/$defs/StaticAnalysisConfig",
"default": {
"ast_grep_rules": null,
"enabled": true,
"min_severity": "info",
"semgrep_rules": null,
"tool_min_severity": {},
"tool_mode": {},
"tools": [
"ruff",
"bandit",
"semgrep",
"mypy",
"gitleaks",
"zizmor",
"ast-grep",
"osv-scanner"
]
}
},
"structured_output": {
"default": true,
"title": "Structured Output",
"type": "boolean"
},
"summary_template": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Summary Template"
},
"symbol_resolution": {
"default": true,
"title": "Symbol Resolution",
"type": "boolean"
},
"triage_model": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Triage Model"
},
"unanchored_min_severity": {
"$ref": "#/$defs/Severity",
"default": "high"
}
},
"required": [
"provider",
"model"
],
"title": "ReviewConfig",
"type": "object"
}
ReviewFinding¶
{
"$defs": {
"Severity": {
"description": "Finding severity, ordered low \u2192 high for `min_severity` filtering.",
"enum": [
"info",
"low",
"medium",
"high",
"critical"
],
"title": "Severity",
"type": "string"
}
},
"additionalProperties": false,
"description": "A single inline review comment the model wants to post.",
"properties": {
"anchor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Anchor"
},
"anchored": {
"default": true,
"title": "Anchored",
"type": "boolean"
},
"body": {
"title": "Body",
"type": "string"
},
"broad": {
"default": false,
"title": "Broad",
"type": "boolean"
},
"category": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Category"
},
"confidence": {
"anyOf": [
{
"maximum": 10,
"minimum": 0,
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Confidence"
},
"failure_scenario": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Failure Scenario"
},
"line": {
"minimum": 1,
"title": "Line",
"type": "integer"
},
"path": {
"title": "Path",
"type": "string"
},
"severity": {
"$ref": "#/$defs/Severity"
},
"side": {
"default": "RIGHT",
"enum": [
"LEFT",
"RIGHT"
],
"title": "Side",
"type": "string"
},
"suggestion": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Suggestion"
},
"title": {
"title": "Title",
"type": "string"
}
},
"required": [
"path",
"line",
"severity",
"title",
"body"
],
"title": "ReviewFinding",
"type": "object"
}
ProviderResult¶
{
"additionalProperties": false,
"description": "The normalised return of one LLM completion, with token usage.",
"properties": {
"attempts": {
"default": 1,
"minimum": 1,
"title": "Attempts",
"type": "integer"
},
"cache_creation_tokens": {
"default": 0,
"title": "Cache Creation Tokens",
"type": "integer"
},
"cache_read_tokens": {
"default": 0,
"title": "Cache Read Tokens",
"type": "integer"
},
"cost_usd": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"title": "Cost Usd"
},
"input_tokens": {
"title": "Input Tokens",
"type": "integer"
},
"model": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Model"
},
"output_ceiling": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Output Ceiling"
},
"output_tokens": {
"title": "Output Tokens",
"type": "integer"
},
"reasoning_tokens": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Reasoning Tokens"
},
"schema_dropped": {
"default": false,
"title": "Schema Dropped",
"type": "boolean"
},
"temperature_dropped": {
"default": false,
"title": "Temperature Dropped",
"type": "boolean"
},
"text": {
"title": "Text",
"type": "string"
}
},
"required": [
"text",
"input_tokens",
"output_tokens"
],
"title": "ProviderResult",
"type": "object"
}
PRContext¶
{
"$defs": {
"PRStack": {
"additionalProperties": false,
"description": "Where a pull request sits in a stack of pull requests, each built on the last.\n\n``position`` counts from the bottom (1 is the layer that targets\n``base_ref``, the branch the whole stack lands on). ``below`` and ``above``\nare the other open layers, each ordered bottom to top. A layer's diff shows\nonly its own changes, so what the other layers change is not shown to it.",
"properties": {
"above": {
"items": {
"$ref": "#/$defs/StackLayer"
},
"title": "Above",
"type": "array"
},
"base_ref": {
"title": "Base Ref",
"type": "string"
},
"below": {
"items": {
"$ref": "#/$defs/StackLayer"
},
"title": "Below",
"type": "array"
},
"complete": {
"default": true,
"title": "Complete",
"type": "boolean"
},
"position": {
"minimum": 1,
"title": "Position",
"type": "integer"
},
"size": {
"minimum": 1,
"title": "Size",
"type": "integer"
}
},
"required": [
"position",
"size",
"base_ref"
],
"title": "PRStack",
"type": "object"
},
"RiskAssessment": {
"additionalProperties": false,
"description": "A change's risk verdict: its level, the ranked reasons, and the gaps.\n\n``level`` None means the assessment itself failed and nothing is claimed.\n``unassessed`` lists changed code files whose blast radius was not measured,\nso a ``low`` verdict can never pass for a measured clean result.",
"properties": {
"level": {
"anyOf": [
{
"enum": [
"low",
"medium",
"high",
"critical"
],
"type": "string"
},
{
"type": "null"
}
],
"title": "Level"
},
"reasons": {
"items": {
"$ref": "#/$defs/RiskReason"
},
"title": "Reasons",
"type": "array"
},
"unassessed": {
"items": {
"type": "string"
},
"title": "Unassessed",
"type": "array"
}
},
"required": [
"level"
],
"title": "RiskAssessment",
"type": "object"
},
"RiskReason": {
"additionalProperties": false,
"description": "One reason a risk verdict is at its level.\n\n``factor`` names the rule that fired and ``key`` what makes it distinct from\nanother reason of the same factor (the High Impact area, or the factor\nitself): two distinct ``high`` reasons make a change ``critical``, while two\nTerraform files are one reason. ``text`` is rendered Markdown, paths already\nbacktick-stripped.",
"properties": {
"factor": {
"enum": [
"blast_radius",
"area",
"size",
"untested",
"scope",
"profile"
],
"title": "Factor",
"type": "string"
},
"key": {
"title": "Key",
"type": "string"
},
"level": {
"enum": [
"low",
"medium",
"high",
"critical"
],
"title": "Level",
"type": "string"
},
"text": {
"title": "Text",
"type": "string"
}
},
"required": [
"factor",
"key",
"level",
"text"
],
"title": "RiskReason",
"type": "object"
},
"StackLayer": {
"additionalProperties": false,
"description": "Another pull request in the same stack: its number, title and changed files.\n\nWritten by whoever opened that PR, so untrusted like a diff: the engine\nredacts and wraps it before it reaches a model.",
"properties": {
"files": {
"items": {
"type": "string"
},
"title": "Files",
"type": "array"
},
"number": {
"minimum": 1,
"title": "Number",
"type": "integer"
},
"title": {
"default": "",
"title": "Title",
"type": "string"
}
},
"required": [
"number"
],
"title": "StackLayer",
"type": "object"
}
},
"additionalProperties": false,
"description": "Everything the engine needs about a PR \u2014 fetched via API, never checkout.",
"properties": {
"base_sha": {
"title": "Base Sha",
"type": "string"
},
"changed_files": {
"items": {
"type": "string"
},
"title": "Changed Files",
"type": "array"
},
"commit_messages": {
"items": {
"type": "string"
},
"title": "Commit Messages",
"type": "array"
},
"description": {
"default": "",
"title": "Description",
"type": "string"
},
"diff": {
"title": "Diff",
"type": "string"
},
"feedback_downvotes": {
"default": [],
"items": {
"type": "string"
},
"title": "Feedback Downvotes",
"type": "array",
"uniqueItems": true
},
"file_contents": {
"additionalProperties": {
"type": "string"
},
"title": "File Contents",
"type": "object"
},
"head_branch": {
"default": "",
"title": "Head Branch",
"type": "string"
},
"head_sha": {
"title": "Head Sha",
"type": "string"
},
"open_finding_threads": {
"default": 0,
"minimum": 0,
"title": "Open Finding Threads",
"type": "integer"
},
"pr_number": {
"title": "Pr Number",
"type": "integer"
},
"repo": {
"title": "Repo",
"type": "string"
},
"risk": {
"anyOf": [
{
"$ref": "#/$defs/RiskAssessment"
},
{
"type": "null"
}
],
"default": null
},
"scan_contents": {
"additionalProperties": {
"type": "string"
},
"title": "Scan Contents",
"type": "object"
},
"stack": {
"anyOf": [
{
"$ref": "#/$defs/PRStack"
},
{
"type": "null"
}
],
"default": null
},
"title": {
"default": "",
"title": "Title",
"type": "string"
}
},
"required": [
"diff",
"changed_files",
"base_sha",
"head_sha",
"repo",
"pr_number"
],
"title": "PRContext",
"type": "object"
}