Documentation Index Fetch the complete documentation index at: https://tally.wharflab.com/llms.txt
Use this file to discover all available pages before exploring further.
tally supports configuration via TOML config files, environment variables, and CLI flags. Sources cascade in a predictable order so you can set
project defaults while allowing per-run overrides.
Priority order
Configuration sources are applied highest-priority first:
CLI flags — --fail-level error
Environment variables — TALLY_OUTPUT_FAIL_LEVEL=error
Config file — .tally.toml or tally.toml
Built-in defaults
Config file
File names
tally looks for these config file names, in order:
.tally.toml (hidden file, recommended)
tally.toml
Discovery
tally uses cascading config discovery similar to Ruff :
Starting from the Dockerfile’s directory, walks up the filesystem.
Stops at the first .tally.toml or tally.toml found.
Uses that config — no merging with parent configs.
This allows monorepo setups with per-directory configurations:
monorepo/
├── .tally.toml # Default config for most services
├── services/
│ ├── api/
│ │ └── Dockerfile # Uses monorepo/.tally.toml
│ └── legacy/
│ ├── .tally.toml # Override for legacy service
│ └── Dockerfile # Uses services/legacy/.tally.toml
Explicit config path
Override discovery with --config:
tally lint --config /path/to/.tally.toml Dockerfile
Config file reference
[output]
Fixes
[rules]
[inline-directives]
[ai]
[file-validation]
[slow-checks]
Controls how tally reports violations. [ output ]
format = "text" # text, json, sarif, github-actions, markdown
path = "stdout" # stdout, stderr, or a file path
show-source = true # Show source code snippets
fail-level = "style" # Minimum severity for exit code 1
Option Default Description format"text"Output format: text, json, sarif, github-actions, markdown path"stdout"Output destination: stdout, stderr, or a file path show-sourcetrueShow source code snippets alongside violations fail-level"style"Minimum severity that produces exit code 1: error, warning, info, style, none
Controls auto-fix safety when fixes are requested. Option Default Description unsafe-fixesunset Enable application of unsafe fixes when --fix is used
Controls which rules are enabled and how they are configured. Rule selection Use glob patterns to include or exclude rules by namespace or by specific rule code: [ rules ]
include = [ "buildkit/*" , "tally/*" , "hadolint/*" ]
exclude = [
"buildkit/MaintainerDeprecated" ,
"hadolint/DL3008" ,
]
Per-rule configuration Configure individual rules with severity and rule-specific options: # Syntax: [rules.<namespace>.<rule-name>]
[ rules . tally . max-lines ]
severity = "error"
max = 500
skip-blank-lines = true
skip-comments = true
[ rules . buildkit . StageNameCasing ]
severity = "info" # Downgrade from warning to info
[ rules . hadolint . DL3026 ]
severity = "warning"
trusted-registries = [ "docker.io" , "gcr.io" , "ghcr.io" ]
Severity levels Severity Description "off"Disable the rule "error"Critical issues that should block CI "warning"Important issues that should be addressed "info"Informational suggestions "style"Style preferences
Enabling off-by-default rules Some rules are disabled by default (for example, experimental rules). Enable them by providing configuration: # DL3026 is off by default — providing config auto-enables it
[ rules . hadolint . DL3026 ]
trusted-registries = [ "docker.io" , "ghcr.io" ]
# Or set severity explicitly
[ rules . tally . prefer-copy-heredoc ]
severity = "style"
Controls how inline ignore comments are processed. [ inline-directives ]
enabled = true # Process inline directives (default: true)
warn-unused = false # Warn about unused directives (default: false)
validate-rules = false # Warn about unknown rule codes (default: false)
require-reason = false # Require reason= on all ignore directives (default: false)
Option Default Description enabledtrueProcess inline directives warn-unusedfalseWarn about directives that don’t suppress any violations validate-rulesfalseWarn about unknown rule codes in directives require-reasonfalseRequire reason= on all ignore directives
Configuration for AI AutoFix via ACP. See AI AutoFix (ACP) for the full guide. [ ai ]
enabled = false
command = [ "gemini" , "--experimental-acp" , "--allowed-mcp-server-names=none" , "--model=gemini-3-flash-preview" ]
timeout = "90s"
max-input-bytes = 262144
redact-secrets = true
Setting Default Description enabledfalseMaster kill-switch for AI features command(empty) ACP agent argv (stdio). If empty, AI fixes can’t run timeout"90s"Per-fix timeout for the ACP interaction max-input-bytes262144Maximum prompt size to send to the agent redact-secretstrueRedact obvious secrets in prompts (best-effort)
Pre-parse file validation. Useful for rejecting unexpectedly large files before linting. [ file-validation ]
max-file-size = 102400 # bytes; 0 = unlimited
Option Default Description max-file-size102400 (100 KB)Maximum file size in bytes. Files above this limit are rejected before parsing. Set to 0 for unlimited.
Controls registry-aware and other slow checks that require network access. [ slow-checks ]
mode = "auto" # auto, on, off
timeout = "20s"
fail-fast = true
Option Default Description mode"auto"auto skips slow checks in CI; on always runs them; off always skips themtimeout"20s"Timeout for slow checks fail-fasttrueSkip slow checks for files that already have error-severity violations from fast rules
You can also control this via CLI: tally lint --slow-checks=on --slow-checks-timeout=30s Dockerfile
Environment variables
Output variables
Rule variables
File discovery variables
Directive variables
AI variables
Variable Description TALLY_OUTPUT_FORMATOutput format: text, json, sarif, github-actions, markdown TALLY_FORMATAlias for TALLY_OUTPUT_FORMAT TALLY_OUTPUT_PATHOutput destination: stdout, stderr, or file path TALLY_OUTPUT_SHOW_SOURCEShow source snippets: true / false TALLY_OUTPUT_FAIL_LEVELMinimum severity for non-zero exit NO_COLORDisable colored output (standard env var)
Variable Description TALLY_RULES_MAX_LINES_MAXMaximum lines allowed TALLY_RULES_MAX_LINES_SKIP_BLANK_LINESExclude blank lines: true / false TALLY_RULES_MAX_LINES_SKIP_COMMENTSExclude comment lines: true / false TALLY_RULES_SELECTEnable specific rules (comma-separated patterns) TALLY_RULES_IGNOREDisable specific rules (comma-separated patterns)
Variable Description TALLY_EXCLUDEGlob pattern(s) to exclude files (comma-separated) TALLY_CONTEXTBuild context directory for direct Dockerfile linting TALLY_SLOW_CHECKSSlow checks mode: auto, on, off TALLY_SLOW_CHECKS_TIMEOUTTimeout for slow checks (e.g. 20s) TALLY_FIXApply safe fixes automatically: true / false TALLY_FIX_UNSAFEAlso apply unsafe fixes: true / false TALLY_UNSAFE_FIXESConfig-shaped alias for unsafe-fixes: true / false TALLY_FIX_RULELimit fixes to specific rules (comma-separated)
Variable Description TALLY_NO_INLINE_DIRECTIVESDisable inline directive processing: true / false TALLY_INLINE_DIRECTIVES_WARN_UNUSEDWarn about unused directives: true / false TALLY_INLINE_DIRECTIVES_REQUIRE_REASONRequire reason= on ignore directives: true / false
Variable Description TALLY_AI_ENABLEDEnable AI AutoFix: true / false TALLY_ACP_COMMANDACP agent command line TALLY_AI_TIMEOUTPer-fix timeout (e.g. 90s) TALLY_AI_MAX_INPUT_BYTESMaximum prompt size in bytes TALLY_AI_REDACT_SECRETSRedact secrets before sending to agent: true / false
CLI flags
Core flags
Output flags
Rule flags
Directive flags
Fix flags
Flag Description --config, -cPath to config file (overrides discovery) --no-configSkip config file discovery and use defaults plus env/CLI overrides --excludeGlob pattern(s) to exclude files (repeatable) --contextBuild context directory for direct Dockerfile linting --targetBake target or group to lint (repeatable; Bake entrypoints only) --serviceCompose service to lint (repeatable; Compose entrypoints only) --selectEnable specific rules (repeatable) --ignoreDisable specific rules (repeatable)
Flag Description --format, -fOutput format: text, json, sarif, github-actions, markdown --output, -oOutput destination: stdout, stderr, or file path --no-colorDisable colored output --show-sourceShow source code snippets (default: true) --hide-sourceHide source code snippets --fail-levelMinimum severity for non-zero exit
Flag Description --max-lines, -lMaximum number of lines allowed (0 = unlimited) --skip-blank-linesExclude blank lines from the line count --skip-commentsExclude comment lines from the line count
Flag Description --no-inline-directivesDisable processing of inline ignore directives --warn-unused-directivesWarn about directives that don’t suppress any violations --require-reasonWarn about ignore directives without a reason= explanation
Flag Description --fixApply safe auto-fixes automatically --fix-ruleOnly fix specific rules (repeatable) --fix-unsafeAlso apply unsafe fixes (requires --fix) --aiEnable AI AutoFix (requires an ACP agent command) --acp-commandACP agent command line --ai-timeoutPer-fix AI timeout (e.g. 90s) --ai-max-input-bytesMaximum prompt size in bytes --ai-redact-secretsRedact secrets before sending to agent
Build context and invocation flags
--context applies only when you lint Dockerfiles directly:
tally lint --context . Dockerfile
When you pass a Bake or Compose file, tally reads the build context from the selected target or service instead:
tally lint docker-bake.hcl --target api
tally lint compose.yaml --service api
Do not combine --context with a Bake or Compose entrypoint. Use --target only with Bake, and --service only with Compose. See
Build invocations for the full entrypoint behavior.
Inline directives
Suppress specific violations using inline comment directives directly in your Dockerfile.
Suppress violations on the next line : # tally ignore=StageNameCasing
FROM alpine AS Build
Suppress multiple rules with comma-separated values: # tally ignore=StageNameCasing,DL3006
FROM Ubuntu AS Build
Suppress all rules on a line: # tally ignore=all
FROM Ubuntu AS Build
Suppress violations throughout the entire file : # tally global ignore=max-lines
FROM alpine
# ... rest of file is not checked for max-lines
Document why a rule is suppressed using ;reason=: # tally ignore=DL3006;reason=Using older base image for compatibility
FROM ubuntu:16.04
# tally global ignore=max-lines;reason=Generated file, size is expected
Use --require-reason (or require-reason = true in .tally.toml) to enforce that all ignore directives include an explanation.
tally supports directive formats from other linters, making migration easy: # hadolint ignore=DL3006
FROM ubuntu
# hadolint global ignore=DL3008
FROM alpine
# check=skip=StageNameCasing
FROM alpine AS Build
Example configurations
Strict CI
# .tally.toml - Strict settings for CI
[ output ]
format = "sarif"
path = "tally-results.sarif"
fail-level = "warning"
[ rules ]
include = [ "buildkit/*" , "tally/*" , "hadolint/*" ]
[ rules . tally . max-lines ]
max = 50
skip-blank-lines = true
skip-comments = true
[ inline-directives ]
require-reason = true
warn-unused = true
Relaxed development
# .tally.toml - Relaxed settings for development
[ output ]
format = "text"
show-source = true
fail-level = "error"
[ rules ]
include = [ "buildkit/*" , "tally/*" ]
exclude = [ "buildkit/MaintainerDeprecated" ]
[ rules . tally . max-lines ]
severity = "warning"
max = 200
Monorepo setup
Place a root .tally.toml with shared defaults, then override for specific services:
monorepo/
├── .tally.toml # Shared defaults
├── services/
│ ├── api/
│ │ └── Dockerfile # Inherits root config
│ └── legacy/
│ ├── .tally.toml # Legacy overrides
│ └── Dockerfile
# services/legacy/.tally.toml - Gradual migration from hadolint
[ output ]
format = "text"
fail-level = "error"
[ rules ]
# Start with just BuildKit rules; add hadolint rules gradually
include = [ "buildkit/*" ]
[ rules . buildkit . StageNameCasing ]
severity = "info" # Downgrade during migration