Configuration reference
Every setting the bot reads, with the environment variable that sets it. A row shows the short alias application.properties defines for it where there is one; every thrillhousebot.* key also accepts its standard Quarkus name (the key in uppercase with each . and - replaced by _), which overrides the alias. What the features do is described in the README's Configuration section.
Durations take Quarkus' format (10s, 5m, 24h, or an ISO-8601 value such as PT1M). A list is comma-separated.
Quarkus and LangChain4j settings
Section titled “Quarkus and LangChain4j settings”These variables set Quarkus and LangChain4j keys rather than a thrillhousebot.* key.
| Variable | Description | Default | Sets |
|---|---|---|---|
AI_API_KEY | API key for the AI provider. Required. | (none) | quarkus.langchain4j.openai.api-keyquarkus.langchain4j.openai.concise.api-key |
AI_BASE_URL | OpenAI-compatible base URL of the AI provider. | https://api.deepseek.com/v1 | quarkus.langchain4j.openai.base-urlquarkus.langchain4j.openai.concise.base-url |
AI_MODEL | Chat model name. It also selects the model's entry in the per-model settings and the pricing map. | deepseek-chat | quarkus.langchain4j.openai.chat-model.model-namequarkus.langchain4j.openai.concise.chat-model.model-name |
AI_TIMEOUT | Per-request timeout of an AI call. | 300s | quarkus.langchain4j.openai.timeoutquarkus.langchain4j.openai.concise.timeout |
DATABASE_URL | JDBC URL of the production database (jdbc:postgresql://db:5432/thrillhouse in Docker Compose). | %prod: jdbc:postgresql://localhost:5432/thrillhouse | quarkus.datasource.jdbc.url |
DATASOURCE_DB_KIND | h2 or postgresql. Quarkus fixes this at build time, so released images are PostgreSQL builds and ignore h2. | h2; %prod: postgresql | quarkus.datasource.db-kind |
DS_INPUT_PRICE | Price of 1,000 input tokens on deepseek-chat, in US dollars. | 0.00014 | thrillhousebot.ai.pricing.deepseek-chat.input-per-1k |
DS_OUTPUT_PRICE | Price of 1,000 output tokens on deepseek-chat, in US dollars. | 0.00028 | thrillhousebot.ai.pricing.deepseek-chat.output-per-1k |
OTEL_EXPORTER_ENDPOINT | OTLP endpoint traces, metrics and logs are exported to. | http://localhost:4317 | quarkus.otel.exporter.otlp.endpoint |
OTEL_EXPORTER_TIMEOUT | How long one OTLP export may wait for the collector. Keep it above the collector's 60-second HTTP/2 keep-alive: below it, an export after an idle pause can be sent twice. | 65s | quarkus.otel.exporter.otlp.traces.timeoutquarkus.otel.exporter.otlp.metrics.timeoutquarkus.otel.exporter.otlp.logs.timeout |
OTEL_HTTP_SERVER_METRICS_ENABLED | Record Quarkus's HTTP server metrics (http.server.request.duration), exported over OTLP and served on /metrics. | true | quarkus.otel.instrument.http-server-metrics |
OTEL_JVM_METRICS_ENABLED | Record Quarkus's JVM metrics (jvm.*), exported over OTLP and served on /metrics. | true | quarkus.otel.instrument.jvm-metrics |
OTEL_LOGS_ENABLED | Also export the bot's log records over OTLP, beside the console. Off by default, so a collector does not start receiving every log line without an opt-in. | false | quarkus.otel.logs.handler.enabled |
OTEL_SDK_DISABLED | Turn telemetry off: nothing is exported over OTLP and the Prometheus endpoint answers 404. | false | quarkus.otel.sdk.disabled |
PORT | HTTP port the bot listens on (webhooks, dashboard, health and metrics). | 8080 | quarkus.http.port |
REVIEW_CONCISE_MAX_OUTPUT_TOKENS | Response cap (max_tokens) for the calls on the concise model: the summary call, the verifier and replies. A summary cut at this cap is salvaged or replaced by a counts-only summary, and the findings are kept. Set it empty to send no cap. | 8192 | quarkus.langchain4j.openai.concise.chat-model.max-tokens |
thrillhousebot
Section titled “thrillhousebot”| Variable | Description | Type | Default |
|---|---|---|---|
HTTP_CONNECT_TIMEOUTthrillhousebot.http-connect-timeout | Outbound HTTP connect timeout (GitHub API, OAuth). | duration | 10s |
HTTP_REQUEST_TIMEOUTthrillhousebot.http-request-timeout | Outbound HTTP request timeout (GitHub API, OAuth). | duration | 10s |
WEBSOCKET_KEEPALIVE_MSthrillhousebot.websocket-keepalive-ms | Dashboard WebSocket keepalive in milliseconds, so reverse proxies do not close idle connections. 0 or less disables it and stale replay-buffer eviction. | integer | 25000 |
thrillhousebot.ai
Section titled “thrillhousebot.ai”| Variable | Description | Type | Default |
|---|---|---|---|
(follows quarkus.langchain4j.openai.base-url)thrillhousebot.ai.base-url | The AI base URL, read from AI_BASE_URL; used to derive the telemetry provider when AI_PROVIDER is unset. Set AI_BASE_URL rather than this key. | string | https://api.deepseek.com/v1 |
AI_MAX_CONCURRENT_CALLSthrillhousebot.ai.max-concurrent-calls | Most model calls in flight at once across the process (review batches, summaries, the verifier, replies and commands). A call past it waits for a slot, up to THRILLHOUSEBOT_REVIEW_AI_TIMEOUT_SECONDS, and a wait over 5 seconds is logged at INFO. A provider's rate-limit or concurrent-slot refusal is retried after 30 seconds either way. 0 means no limit. | integer | 0 |
AI_PROVIDERthrillhousebot.ai.provider-name | Provider label for telemetry (gen_ai.provider.name); derived from AI_BASE_URL when unset. | string | (none) |
thrillhousebot.ai.models.<model>
Section titled “thrillhousebot.ai.models.<model>”Model-specific settings, keyed by the model name (the AI_MODEL value). Only the active model's entry is read, so you can keep entries for several models and switch AI_MODEL freely. Quote a model name that contains . or / (thrillhousebot.ai.models."gpt-5.5".max-input-tokens). From the environment, hyphen-only names use underscores (THRILLHOUSEBOT_AI_MODELS_DEEPSEEK_V4_PRO_MAX_INPUT_TOKENS=1000000) and dotted names the quoted form (THRILLHOUSEBOT_AI_MODELS__GPT_5_5__MAX_INPUT_TOKENS=256000); either needs an empty max-input-tokens= line for that model in application.properties, which ships one for the models it knows. See Per-model AI settings.
| Variable | Description | Type | Default |
|---|---|---|---|
THRILLHOUSEBOT_AI_MODELS_<MODEL>_CONTEXT_TOKENSthrillhousebot.ai.models.<model>.context-tokens | The model's total context window. On a shared window the prompt and the completion are both charged to it, so boot fails when max-input-tokens + max-output-tokens does not fit inside it, or when the effective budget plus the largest response cap in play (max-output-tokens or REVIEW_CONCISE_MAX_OUTPUT_TOKENS) does not. Unset, the ceiling is not checked. | integer | (none) |
THRILLHOUSEBOT_AI_MODELS_<MODEL>_FREQUENCY_PENALTYthrillhousebot.ai.models.<model>.frequency-penalty | frequency_penalty sent on every chat call, in [-2, 2]. Positive values discourage repeating tokens in proportion to how often they already appeared. Unset keeps the provider default. | number | (none) |
THRILLHOUSEBOT_AI_MODELS_<MODEL>_MAX_INPUT_TOKENSthrillhousebot.ai.models.<model>.max-input-tokens | Input-token cap for this model. The effective review budget is the smaller of REVIEW_MAX_INPUT_TOKENS and this cap; a model without one gets 128000. It is a cap, not the budget: to go beyond it on a large-context model, raise both. Startup logs a warning when the cap lowers the budget. | integer | (none) |
THRILLHOUSEBOT_AI_MODELS_<MODEL>_MAX_OUTPUT_TOKENSthrillhousebot.ai.models.<model>.max-output-tokens | Response cap (max_tokens) sent on the review call and the command generators. output-buffer-tokens only reserves room in the input budget, so set both when you cap output. Unset leaves the provider default. | integer | (none) |
THRILLHOUSEBOT_AI_MODELS_<MODEL>_OUTPUT_BUFFER_TOKENSthrillhousebot.ai.models.<model>.output-buffer-tokens | This model's REVIEW_OUTPUT_BUFFER_TOKENS: tokens reserved from the input budget for the response. On a shared window it must be at least max-output-tokens, or boot fails. Ignored with separate-output-budget set. | integer | (none) |
THRILLHOUSEBOT_AI_MODELS_<MODEL>_PRESENCE_PENALTYthrillhousebot.ai.models.<model>.presence-penalty | presence_penalty sent on every chat call, in [-2, 2]. Positive values discourage repeating any token that already appeared. Unset keeps the provider default. | number | (none) |
THRILLHOUSEBOT_AI_MODELS_<MODEL>_SEEDthrillhousebot.ai.models.<model>.seed | seed sent on every chat call, asking for repeatable sampling on providers that support it; others ignore it. For steadier reviews, lower temperature first. Unset sends no seed. | integer | (none) |
THRILLHOUSEBOT_AI_MODELS_<MODEL>_SEPARATE_OUTPUT_BUDGETthrillhousebot.ai.models.<model>.separate-output-budget | Set true only when the provider bills the response outside the context window (1M in with 384K out on top, rather than 384K carved out of the 1M). It switches off both the output-buffer-tokens reservation and the context-tokens ceiling. Getting it wrong is costly either way; check the provider's documented window first. | boolean | (none) |
THRILLHOUSEBOT_AI_MODELS_<MODEL>_TEMPERATUREthrillhousebot.ai.models.<model>.temperature | Sampling temperature sent on every chat call, in [0, 2]. Unset keeps the default (1.0). | number | (none) |
THRILLHOUSEBOT_AI_MODELS_<MODEL>_TOKEN_SAFETY_MARGINthrillhousebot.ai.models.<model>.token-safety-margin | This model's REVIEW_TOKEN_SAFETY_MARGIN: the fraction of the input budget actually used, to absorb token-estimate error. | number | (none) |
THRILLHOUSEBOT_AI_MODELS_<MODEL>_TOP_Pthrillhousebot.ai.models.<model>.top-p | Nucleus-sampling top_p sent on every chat call, in (0, 1]. Unset keeps the default (1.0). top_k is not part of the OpenAI-compatible API, so it cannot be set. | number | (none) |
thrillhousebot.ai.pricing.<model>
Section titled “thrillhousebot.ai.pricing.<model>”Prices used for cost tracking, keyed by model name (the AI_MODEL value) like the per-model settings. application.properties ships prices for the models it knows. When you change AI_MODEL, add a matching pair; without one, tokens are still recorded and the model's sessions are flagged "no pricing" in the dashboard instead of showing $0.
| Variable | Description | Type | Default |
|---|---|---|---|
THRILLHOUSEBOT_AI_PRICING_<MODEL>_INPUT_PER_1Kthrillhousebot.ai.pricing.<model>.input-per-1k | Price of 1,000 input tokens, in US dollars. | number | (none) |
THRILLHOUSEBOT_AI_PRICING_<MODEL>_OUTPUT_PER_1Kthrillhousebot.ai.pricing.<model>.output-per-1k | Price of 1,000 output tokens, in US dollars. | number | (none) |
thrillhousebot.ai.reasoning
Section titled “thrillhousebot.ai.reasoning”| Variable | Description | Type | Default |
|---|---|---|---|
AI_REASONING_EFFORT_CONCISEthrillhousebot.ai.reasoning.concise-effort | Effort for the calls on the concise model (summary, verifier, replies), which do not follow AI_REASONING_EFFORT. Same values. Unset means low, or AI_REASONING_EFFORT when that is lower. | string | (none) |
AI_REASONING_EFFORTthrillhousebot.ai.reasoning.effort | Effort for the review and the on-demand commands: none, low, medium, high, xhigh or max. Reasoning tokens are billed as output. A provider that does not know a tier rejects the call. See Per-model AI settings. | string | low |
AI_REASONING_ENABLEDthrillhousebot.ai.reasoning.enabled | Send a reasoning-effort hint (reasoning_effort). When false, no reasoning parameter is sent and the provider default applies, except on the one repeat of a call that spent its whole output cap reasoning, which sends the lane's effort. | boolean | false |
AI_REASONING_REPEAT_EFFORTthrillhousebot.ai.reasoning.repeat-effort | Effort for the one repeat of a call that stopped at its response cap with no content, its reasoning having spent the whole allowance (#839). Same values. Unset means low while reasoning is enabled, with no repeat on a lane that already sends low or none; while it is off, the lane's effort as it would go out enabled. A value equal to what the first call sent makes no repeat. | string | (none) |
thrillhousebot.ai.routing
Section titled “thrillhousebot.ai.routing”| Variable | Description | Type | Default |
|---|---|---|---|
AI_FALLBACK_MODELthrillhousebot.ai.routing.fallback-model | Secondary model for the streamed review and summary calls. When an attempt fails with a provider error (HTTP 5xx, an unknown model) or a rate limit, the call's remaining retries go to this model instead. Unset keeps every retry on the first model. | string | (none) |
AI_ROUTING_HIGH_RISK_PATHSthrillhousebot.ai.routing.high-risk-paths | Comma-separated gitignore-style globs of high-risk files, under the new or the old name of a renamed file. A pull request touching one is never routed to the low-risk model, however small it is and even when the file also matches AI_ROUTING_LOW_RISK_PATHS. | list | .github/workflows/, **/*.sql, **/migrations/, **/auth/, **/security/, **/Dockerfile |
AI_ROUTING_LOW_RISK_MAX_CHANGED_LINESthrillhousebot.ai.routing.low-risk-max-changed-lines | Most changed lines (additions plus deletions over the reviewable files) a pull request may have to count as low risk by size. 0 routes by paths alone; a negative value is rejected at boot. | integer | 100 |
AI_ROUTING_LOW_RISK_MODELthrillhousebot.ai.routing.low-risk-model | Cheaper model for low-risk pull requests: those that touch no AI_ROUTING_HIGH_RISK_PATHS file and either have every reviewable file matching AI_ROUTING_LOW_RISK_PATHS or change at most AI_ROUTING_LOW_RISK_MAX_CHANGED_LINES lines. Only the review calls are routed; the summary call, the verifier and the commands keep their own models. Unset turns routing off. | string | (none) |
AI_ROUTING_LOW_RISK_PATHSthrillhousebot.ai.routing.low-risk-paths | Comma-separated gitignore-style globs of low-risk files (docs, text, lockfiles). A pull request whose every reviewable file matches is routed to AI_ROUTING_LOW_RISK_MODEL whatever its size, unless one of them also matches AI_ROUTING_HIGH_RISK_PATHS. Same pattern syntax as THRILLHOUSEBOT_REVIEW_IGNORED_FILES. | list | **/*.md, **/*.mdx, **/*.rst, **/*.txt, **/*.adoc, docs/, **/*.lock, **/go.sum |
thrillhousebot.dashboard
Section titled “thrillhousebot.dashboard”| Variable | Description | Type | Default |
|---|---|---|---|
THRILLHOUSEBOT_DASHBOARD_GITHUB_ACCOUNT_OWNERthrillhousebot.dashboard.github.account-owner | Optional. When set, the dashboard serves only the installation on this account. Unset serves every installation the signed-in user can access. Either way a user sees only the repositories GitHub lets them read. | string | (none) |
GITHUB_CLIENT_IDthrillhousebot.dashboard.github.client-id | OAuth client ID for dashboard login, from the GitHub App's settings. Leave it and GITHUB_CLIENT_SECRET unset to disable login. | string | (none) |
GITHUB_CLIENT_SECRETthrillhousebot.dashboard.github.client-secret | OAuth client secret for dashboard login, from the GitHub App's settings. | string | (none) |
GITHUB_OAUTH_URLthrillhousebot.dashboard.github.oauth-url | Base URL of GitHub's OAuth endpoints. | string | https://github.com/login/oauth |
THRILLHOUSEBOT_DASHBOARD_GITHUB_REDIRECT_URIthrillhousebot.dashboard.github.redirect-uri | OAuth callback URL registered on the GitHub App; follows DASHBOARD_URL. | string | ${DASHBOARD_URL}/api/auth/callback |
DASHBOARD_REASONING_STREAM_ENABLEDthrillhousebot.dashboard.reasoning-stream-enabled | Streams the review call's reasoning to the dashboard's live activity page (#66), apart from its output. Only a provider that returns its reasoning as reasoning_content on the OpenAI-compatible stream sends any. Off by default: the reasoning can quote the reviewed code, and it is shown to every dashboard user who may read the repository. | boolean | false |
DASHBOARD_URLthrillhousebot.dashboard.url | Public dashboard URL, used for the OAuth callback and the session links posted to GitHub. | string | http://localhost:8080 |
thrillhousebot.github
Section titled “thrillhousebot.github”| Variable | Description | Type | Default |
|---|---|---|---|
GITHUB_ALLOWED_ACCOUNTSthrillhousebot.github.allowed-accounts | Comma-separated logins of the accounts whose installations the bot serves. An event from an installation on any other account is ignored before any work, and the dashboard lists no other installation. Set it when the GitHub App is public, which dashboard sign-in for anyone but the App's owner requires, since anyone can install a public App. Unset serves every installation. | list | (none) |
GITHUB_APP_IDthrillhousebot.github.app-id | GitHub App ID, from the App's settings page. Required. | string | (none) |
GITHUB_BOT_LOGINSthrillhousebot.github.bot-logins | Comma-separated bot logins the bot ignores so it never answers itself. Override when the App slug differs (<app-slug>[bot]). | list | thrillhousebot[bot], thrillhouse-bot[bot] |
GITHUB_PRIVATE_KEYthrillhousebot.github.private-key | GitHub App private key (PEM), on one line with each newline written as \n, unquoted. Required. | string | (none) |
GITHUB_WEBHOOK_SECRETthrillhousebot.github.webhook-secret | The GitHub App's webhook secret, used to check each delivery's HMAC signature. Required. | string | (none) |
GITHUB_WRITE_MAX_WAITthrillhousebot.github.write-max-wait | Longest one caller waits for its write slot before it goes out unpaced and the backoff handles any refusal. | duration | 90s |
GITHUB_WRITE_MIN_INTERVALthrillhousebot.github.write-min-interval | Minimum spacing between two content-creating GitHub calls (comments, review comments, replies, reviews), shared by the whole process. GitHub's guidance is at most one per second; it answers faster writes with 403, 429 or a 422 "was submitted too quickly". When GitHub throttles a write anyway, every queued write waits with it. 0 disables pacing. | duration | 1s |
GITHUB_WRITE_RETRY_BUDGETthrillhousebot.github.write-retry-budget | Longest one review may spend waiting on GitHub's rate limit across all its writes. Once spent, later throttled writes are not retried, and the review body names the findings they carried and asks for a re-run. 0 disables the limit. | duration | 5m |
thrillhousebot.metrics
Section titled “thrillhousebot.metrics”| Variable | Description | Type | Default |
|---|---|---|---|
PROMETHEUS_METRICS_ENABLEDthrillhousebot.metrics.prometheus-enabled | Serves the OpenTelemetry metrics in Prometheus text format at GET /metrics on the main HTTP port, alongside the OTLP export. Off by default: the endpoint is unauthenticated, so shield it at the proxy before enabling it on internet-facing deployments. | boolean | false |
thrillhousebot.notifications.webhook
Section titled “thrillhousebot.notifications.webhook”| Variable | Description | Type | Default |
|---|---|---|---|
NOTIFICATIONS_WEBHOOK_ALLOW_HTTPthrillhousebot.notifications.webhook.allow-http | Accept a plain http:// URL, for local testing. | boolean | false |
NOTIFICATIONS_WEBHOOK_EVENTSthrillhousebot.notifications.webhook.events | Comma-separated outcomes to send: completed, failed. | list | completed, failed |
NOTIFICATIONS_WEBHOOK_FORMATthrillhousebot.notifications.webhook.format | Body format: json (the structured payload), slack or discord (an incoming-webhook message for that chat service). | string | json |
NOTIFICATIONS_WEBHOOK_INCLUDE_CONTENTthrillhousebot.notifications.webhook.include-content | Also send the PR title and each finding's severity, file, line and title. | boolean | false |
NOTIFICATIONS_WEBHOOK_MAX_ATTEMPTSthrillhousebot.notifications.webhook.max-attempts | Attempts per notification (1–5). A timeout, connection failure, 429 or 5xx is retried after 1, 2, 4 and 8 seconds, then dropped with a WARN. | integer | 3 |
NOTIFICATIONS_WEBHOOK_SECRETthrillhousebot.notifications.webhook.secret | HMAC-SHA256 key; when set, each request carries X-Thrillhousebot-Signature-256: sha256=<hex> computed over the exact request body. | string | (none) |
NOTIFICATIONS_WEBHOOK_TIMEOUTthrillhousebot.notifications.webhook.timeout | Per-attempt timeout (at most 60s). | duration | 10s |
NOTIFICATIONS_WEBHOOK_URLthrillhousebot.notifications.webhook.url | Receiver of review-outcome notifications; unset turns them off. Must be https://. Treated as a secret and logged only as scheme, host and port. See Outgoing notifications. | string | (none) |
thrillhousebot.review
Section titled “thrillhousebot.review”| Variable | Description | Type | Default |
|---|---|---|---|
ACK_REACTION_TIMEOUTthrillhousebot.review.ack-reaction-timeout | Time limit on posting the 👀 reaction to a command; the reaction may land late. | duration | 3s |
REVIEW_ADD_DOCS_ENABLEDthrillhousebot.review.add-docs-enabled | Allow /add-docs, which posts generated docs for the changed symbols as committable suggestions. | boolean | true |
THRILLHOUSEBOT_REVIEW_AI_RETRY_BASE_DELAY_MSthrillhousebot.review.ai-retry-base-delay-ms | Base delay of the exponential retry backoff, in milliseconds. | integer | 2000 |
THRILLHOUSEBOT_REVIEW_AI_TIMEOUT_SECONDSthrillhousebot.review.ai-timeout-seconds | Client-side wait per streaming attempt, in seconds. Keep it at or above AI_TIMEOUT so a timed-out attempt does not leave a stream open at the provider. A second timeout fails the call. | integer | 300 |
AUTO_REVIEW_MIN_INTERVALthrillhousebot.review.auto-review-min-interval | Minimum time between automatic reviews of one PR. Pushes inside the window are skipped, even on a new head (in memory, per replica). /review always runs. 0 reviews every push. | duration | 0 |
REVIEW_BLOCKING_STRICTNESSthrillhousebot.review.blocking-strictness | Which findings request changes: balanced, strict or lenient. See Blocking strictness. | string | balanced |
REVIEW_CI_GATINGthrillhousebot.review.ci-gating | How CI affects approval: strict holds approval while required CI is pending, failing or unreadable; warn approves and notes the CI state; off ignores CI. See CI gating. | string | strict |
REVIEW_CONVERSATIONAL_REPLIES_ENABLEDthrillhousebot.review.conversational-replies-enabled | Answer @thrillhousebot mentions in PR threads and replies to findings. | boolean | true |
REVIEW_DECLINE_RECHECK_ENABLEDthrillhousebot.review.decline-recheck-enabled | Check a maintainer's decline against the reviewed code before recording the finding justified. See Re-checking declines. false makes any reply final. | boolean | true |
REVIEW_DIMENSION_ROUTING_ENABLEDthrillhousebot.review.dimension-routing-enabled | Give each review call only the review-dimension blocks its files can use, instead of all ten. See Dimension routing. | boolean | false |
REVIEW_GENERATE_TESTS_ENABLEDthrillhousebot.review.generate-tests-enabled | Allow /generate-tests, which posts proposed unit tests for the changed code as a comment to copy in. Nothing is committed. | boolean | true |
THRILLHOUSEBOT_REVIEW_IGNORED_FILESthrillhousebot.review.ignored-files | Comma-separated gitignore-style globs never reviewed. A pattern without / matches at any depth (*.lock, vendor); one with / is anchored at the root (docs/generated/**); a trailing / means the directory's tree; * does not cross /. Write a {a,b} alternation as separate patterns. Setting it replaces the default list, which covers lockfiles, generated and minified code, sourcemaps, and build and vendor trees. Build manifests such as pom.xml, package.json and Cargo.toml are reviewed; every file the list excludes is named in the summary's scope note. | list | **/package-lock.json, **/pnpm-lock.yaml, **/go.sum, **/*.lock, **/*.generated.*, **/*.pb.go, **/*_pb2.py, **/*.min.js, **/*.min.css, **/*.map, **/target/**, **/node_modules/**, **/dist/**, **/build/**, **/out/**, **/.next/**, **/vendor/**, **/__pycache__/**, **/.venv/**, **/bin/**, **/obj/** |
REVIEW_IMPROVE_ENABLEDthrillhousebot.review.improve-enabled | Allow /improve, which posts a whole-PR improvement pass as committable suggestions. | boolean | true |
THRILLHOUSEBOT_REVIEW_INSTRUCTIONS_FILEthrillhousebot.review.instructions-file | Repository path of the review instructions file. | string | .github/thrillhousebot.md |
THRILLHOUSEBOT_REVIEW_MANUAL_TRIGGER_ALLOWED_LOGINSthrillhousebot.review.manual-trigger-allowed-logins | Comma-separated logins allowed to run slash commands without write access. Does not apply to the resolved and declined directives. Unset means only users with write access. | list | (none) |
MANUAL_TRIGGER_AUTH_TIMEOUTthrillhousebot.review.manual-trigger-auth-timeout | Time limit on the write-access check for a command. Slower answers from GitHub deny the command. | duration | 5s |
REVIEW_MAX_AI_CALLSthrillhousebot.review.max-ai-calls | Most AI calls per review (batch calls plus the summary call) and per command run (batch calls plus, for /describe and /changelog, the merge call). At 1, a review that makes its review call has none left for the summary and posts a counts-only summary that says so. Verifier calls are not counted. | integer | 6 |
THRILLHOUSEBOT_REVIEW_MAX_AI_RETRIESthrillhousebot.review.max-ai-retries | Attempts per failed AI call. At most two may end in a timeout. | integer | 5 |
REVIEW_MAX_DIFF_LINESthrillhousebot.review.max-diff-lines | Line cap for single-call diff renders (replies, base comparison, reviews with budgeting off). Token-budgeted reviews and the batched commands ignore it. 0 disables it. | integer | 5000 |
REVIEW_MAX_INPUT_TOKENSthrillhousebot.review.max-input-tokens | Input-token budget per call for reviews and the batched commands; larger PRs are split into batches. Capped by the model's max-input-tokens (see the per-model settings). 0 disables budgeting. | integer | 48000 |
THRILLHOUSEBOT_REVIEW_MAX_REVIEW_COMMENTSthrillhousebot.review.max-review-comments | Most inline comments per review; the rest are listed in the summary. | integer | 50 |
REVIEW_MAX_TOKENS_PER_REVIEWthrillhousebot.review.max-tokens-per-review | Most tokens one review may use across all its calls, as the provider reports them, retries and the summary call included. Once reached, no further call is made: the remaining batches are named as not reviewed, the summary degrades to counts only, and the findings already paid for are kept. An on-request command or a maintainer reply that reached it only skips the repeat of a call that spent its whole cap reasoning. 0 disables it. | integer | 0 |
REVIEW_OUTPUT_BUFFER_TOKENSthrillhousebot.review.output-buffer-tokens | Tokens reserved from the input budget for the response. A model with separate-output-budget set reserves nothing. | integer | 8192 |
THRILLHOUSEBOT_REVIEW_REPO_CONFIG_ENABLEDthrillhousebot.review.repo-config-enabled | Read .github/thrillhousebot.yml from each repository (extra ignore globs, path-scoped rules, coverage artifact). See Repository configuration. | boolean | true |
REVIEW_RESPONSE_REPAIR_ENABLEDthrillhousebot.review.response-repair-enabled | When a review or summary answer is not valid review JSON, send only that answer and the parser's error in one small call and ask for the same content in the required shape, before resending the whole prompt. Also asks again for the walkthrough's file summaries when the summary answer wrote them as a string. See AI call budget. | boolean | true |
REVIEW_SUMMARY_VERIFICATION_ENABLEDthrillhousebot.review.summary-verification-enabled | Check the summary's sentences, walkthrough rows and diagram against the diff and the findings, and remove what they contradict. One more call per review. See AI call budget. | boolean | false |
REVIEW_TOKEN_SAFETY_MARGINthrillhousebot.review.token-safety-margin | Fraction of the input budget actually used, to absorb token-estimate error. | number | 0.9 |
REVIEW_TRIAGE_ENABLEDthrillhousebot.review.triage-enabled | Pack a large pull request's files into batches by review priority (#666): build manifests, then files matching AI_ROUTING_HIGH_RISK_PATHS, then the rest, then files matching AI_ROUTING_LOW_RISK_PATHS, the larger change first within each. When the call cap leaves files out, the low-risk ones go first. Off, the order is build manifests then size. | boolean | false |
REVIEW_VERIFIER_ENABLEDthrillhousebot.review.verifier-enabled | Run a second, skeptical pass that re-checks each finding against the diff and drops or downgrades what it cannot confirm. See AI call budget. | boolean | true |
thrillhousebot.review.ci-context
Section titled “thrillhousebot.review.ci-context”| Variable | Description | Type | Default |
|---|---|---|---|
REVIEW_CI_CONTEXT_ENABLEDthrillhousebot.review.ci-context.enabled | Include the checks that had already failed on the head commit. See CI-failure context. | boolean | false |
REVIEW_CI_CONTEXT_INCLUDE_LOGSthrillhousebot.review.ci-context.include-logs | Also include the last 30 lines of up to two failing GitHub Actions job logs. Ignored unless REVIEW_CI_CONTEXT_ENABLED is on. | boolean | false |
REVIEW_CI_CONTEXT_MAX_CHARSthrillhousebot.review.ci-context.max-chars | Character cap on the CI section (500–20000). | integer | 4000 |
thrillhousebot.review.diagram
Section titled “thrillhousebot.review.diagram”| Variable | Description | Type | Default |
|---|---|---|---|
REVIEW_DIAGRAM_ENABLEDthrillhousebot.review.diagram.enabled | Add a Mermaid control-flow diagram to the summary. | boolean | false |
thrillhousebot.review.follow-up-summary
Section titled “thrillhousebot.review.follow-up-summary”| Variable | Description | Type | Default |
|---|---|---|---|
REVIEW_FOLLOW_UP_SUMMARY_ENABLEDthrillhousebot.review.follow-up-summary.enabled | Include new, resolved and still-open counts in the follow-up review outcome, naming closed findings once. No separate delta comment; nothing is added when no finding is raised or closed. | boolean | false |
thrillhousebot.review.labels
Section titled “thrillhousebot.review.labels”| Variable | Description | Type | Default |
|---|---|---|---|
REVIEW_LABELS_ALLOW_CREATEthrillhousebot.review.labels.allow-create | Allow creating a suggested label that does not exist yet. | boolean | false |
REVIEW_LABELS_APPLYthrillhousebot.review.labels.apply | Add the labels to the PR instead of suggesting them in a comment. | boolean | false |
REVIEW_LABELS_BLOCKEDthrillhousebot.review.labels.blocked | Comma-separated label names the bot never suggests, applies or creates, matched ignoring case: labels a team keeps for its own workflow, such as review. They are left out of the list the model sees and dropped from its suggestions. | list | (none) |
REVIEW_LABELS_ENABLEDthrillhousebot.review.labels.enabled | Suggest PR labels. See PR labels. | boolean | false |
REVIEW_LABELS_MAXthrillhousebot.review.labels.max-labels | Most labels applied or suggested per PR. | integer | 3 |
thrillhousebot.review.large-pr-nudge
Section titled “thrillhousebot.review.large-pr-nudge”| Variable | Description | Type | Default |
|---|---|---|---|
REVIEW_LARGE_PR_NUDGE_ENABLEDthrillhousebot.review.large-pr-nudge.enabled | On a large PR whose review opened no inline finding and left no earlier finding open, add a note to the summary pointing at /review and /improve. No extra AI call; the verdict is unchanged. | boolean | false |
REVIEW_LARGE_PR_NUDGE_MIN_CHANGED_LINESthrillhousebot.review.large-pr-nudge.min-changed-lines | Added plus deleted lines at which a PR counts as large; either test is enough. 0 turns this test off. | integer | 1000 |
REVIEW_LARGE_PR_NUDGE_MIN_FILESthrillhousebot.review.large-pr-nudge.min-files | Changed files (ignored files included) at which a PR counts as large. 0 turns this test off. | integer | 20 |
thrillhousebot.review.learnings
Section titled “thrillhousebot.review.learnings”| Variable | Description | Type | Default |
|---|---|---|---|
REVIEW_LEARNINGS_ENABLEDthrillhousebot.review.learnings.enabled | Remember maintainer declines and /remember conventions per repository and show them to later reviews. See Review learnings. Startup fails if this is on while REVIEW_DECLINE_RECHECK_ENABLED is off. | boolean | false |
REVIEW_LEARNINGS_MAX_PER_REPOthrillhousebot.review.learnings.max-per-repo | Active learnings one repository may hold (1–1000). At the cap a new learning is refused, not evicted; two captures racing at the cap can each add one. | integer | 100 |
REVIEW_LEARNINGS_PROMPT_MAX_CHARSthrillhousebot.review.learnings.prompt-max-chars | Character cap on the learnings section (500–20000). | integer | 3000 |
REVIEW_LEARNINGS_PROMPT_MAX_ITEMSthrillhousebot.review.learnings.prompt-max-items | Most learnings in one review prompt (1–50). | integer | 10 |
thrillhousebot.review.patch-coverage
Section titled “thrillhousebot.review.patch-coverage”| Variable | Description | Type | Default |
|---|---|---|---|
REVIEW_PATCH_COVERAGE_ENABLEDthrillhousebot.review.patch-coverage.enabled | Tell the review which added lines the repository's own coverage report never ran. Needs coverage-artifact in .github/thrillhousebot.yml (see Repository configuration). | boolean | false |
thrillhousebot.review.security-scan
Section titled “thrillhousebot.review.security-scan”| Variable | Description | Type | Default |
|---|---|---|---|
REVIEW_SECRET_SCAN_ENTROPY_THRESHOLDthrillhousebot.review.security-scan.entropy-threshold | Minimum Shannon entropy (bits per character) for the generic credential-assignment rule; the known token formats ignore it. Must be in (0, 8]. | number | 3.5 |
REVIEW_IAC_SCAN_ENABLEDthrillhousebot.review.security-scan.iac-enabled | Scan added lines for risky infrastructure-as-code settings (Terraform, Kubernetes, CloudFormation, Dockerfiles). | boolean | false |
REVIEW_SECRET_SCAN_ENABLEDthrillhousebot.review.security-scan.secrets-enabled | Scan added lines for leaked credentials (provider token formats, private keys, JWTs, assignments). See Security scan. | boolean | false |
REVIEW_SECURITY_SCAN_SKIPPED_FILESthrillhousebot.review.security-scan.skipped-files | Comma-separated globs the scan skips on top of the review's ignore list, for fixtures and snapshots where token-shaped sample data is expected. | list | **/fixtures/**, **/__fixtures__/**, **/testdata/**, **/test-data/**, **/__snapshots__/**, **/*.snap |
thrillhousebot.review.ticket-context
Section titled “thrillhousebot.review.ticket-context”| Variable | Description | Type | Default |
|---|---|---|---|
REVIEW_TICKET_CONTEXT_ENABLEDthrillhousebot.review.ticket-context.enabled | Include the issues the PR links and list unaddressed acceptance criteria in the summary. See Linked-issue context. | boolean | false |
REVIEW_TICKET_CONTEXT_FROM_BRANCHthrillhousebot.review.ticket-context.from-branch | Also take an issue number from the head branch name (issue-57, fix/57-short-name) when nothing else links one. | boolean | false |
REVIEW_TICKET_CONTEXT_MAX_CHARSthrillhousebot.review.ticket-context.max-chars | Character cap on the linked-issue section (1000–20000). | integer | 6000 |
REVIEW_TICKET_CONTEXT_MAX_ISSUESthrillhousebot.review.ticket-context.max-issues | Linked issues read per review (1–5); once this many are read, later references are ignored. | integer | 3 |
REVIEW_TICKET_CONTEXT_PROVIDERthrillhousebot.review.ticket-context.provider | Where linked issues are read from. Only github exists. | string | github |
thrillhousebot.webhook
Section titled “thrillhousebot.webhook”| Variable | Description | Type | Default |
|---|---|---|---|
WEBHOOK_DEDUP_TTLthrillhousebot.webhook.dedup-ttl | How long a webhook delivery id (X-GitHub-Delivery) is remembered, to ignore GitHub redeliveries instead of reviewing twice. Kept in memory, per replica. | duration | 24h |
thrillhousebot.webhook.triggers
Section titled “thrillhousebot.webhook.triggers”| Variable | Description | Type | Default |
|---|---|---|---|
WEBHOOK_BASE_BRANCHESthrillhousebot.webhook.triggers.base-branches | Comma-separated globs; auto-review only PRs whose base branch matches one (main,release/*). * does not cross /; use ** for that. Unset means every base branch. | list | (none) |
WEBHOOK_EXCLUDED_AUTHORSthrillhousebot.webhook.triggers.excluded-authors | Comma-separated logins; skip auto-review of PRs opened by any (case-insensitive exact match, dependabot[bot]). Unlike a label, the author is in every opened payload, so it holds when a bot labels its PR after opening it. | list | (none) |
WEBHOOK_EXCLUDED_LABELSthrillhousebot.webhook.triggers.excluded-labels | Comma-separated labels; skip auto-review of PRs carrying any (case-insensitive exact match). Wins over WEBHOOK_REQUIRED_LABELS. | list | (none) |
WEBHOOK_IGNORED_BASE_BRANCHESthrillhousebot.webhook.triggers.ignored-base-branches | Comma-separated globs; skip auto-review of PRs whose base branch matches one (gh-pages). Wins over WEBHOOK_BASE_BRANCHES. | list | (none) |
WEBHOOK_REQUIRED_LABELSthrillhousebot.webhook.triggers.required-labels | Comma-separated labels; auto-review only PRs carrying at least one (case-insensitive exact match). Unset means no label is required. | list | (none) |
WEBHOOK_SKIP_DRAFTSthrillhousebot.webhook.triggers.skip-drafts | Do not auto-review drafts; the PR is reviewed once marked ready (ready_for_review). | boolean | false |