Skip to content

Configuration Reference

Complete reference for codepol.toml.

Overview

Codepol uses a TOML config file so the policy stays language-agnostic and easy to author in any repo. The config is pure data:

  • targets define which files belong to a named scope.
  • rules define what to enforce against those targets.
  • plugins declare where rule capabilities come from.
  • eslintConfigPath optionally points to your ESLint config for host integrations.

Complete Example

toml
eslintConfigPath = "./eslint.config.mjs"
exclude = ["dist/**", "node_modules/**"]

[[plugins]]
id = "@codepol/plugin"
source = { kind = "builtin" }

[[plugins]]
id = "@your-org/custom-plugin"

[plugins.source]
kind = "process"
command = "python3"
args = ["./tools/codepol_plugin.py"]
timeoutMs = 5000

[targets.typescript-src]
language = "typescript"
files = ["src/**/*.ts", "src/**/*.tsx"]
exclude = ["**/*.spec.ts", "**/*.test.ts"]

[[rules]]
id = "function-logging"
ruleId = "@codepol/plugin/require-logger-enter-exit"
severity = "error"
targets = ["typescript-src"]

[rules.args.logger]
identifier = "logger"
enterMethod = "enter"
exitMethod = "exit"
import = { module = "@your-org/logger", named = "logger" }

[[rules]]
ruleId = "@your-org/custom-plugin/no-duplicate-exports"
severity = "warn"
targets = ["typescript-src"]

Top-Level Properties

PropertyTypeRequiredDescription
targetstableYesNamed target definitions referenced by rules
rulesarray of tablesYesEnforcement rules
pluginsarray of tablesNoBuilt-in or subprocess plugin declarations
excludestring arrayNoGlobal file patterns to exclude
eslintConfigPathstringNoOptional path to your ESLint config

Targets

Targets live under the top-level targets table and are referenced by name from rules.

toml
[targets.typescript-src]
language = "typescript"
files = ["src/**/*.ts", "src/**/*.tsx"]
exclude = ["**/*.spec.ts", "**/*.test.ts"]

[targets.python-src]
language = "python"
files = ["src/**/*.py"]

Target Fields

FieldTypeRequiredDescription
languagestringYesLanguage identifier
filesstring arrayYesInclude globs
excludestring arrayNoExclude globs
parserstringNoOptional parser override

Rules

Rules are array items under [[rules]].

toml
[[rules]]
id = "function-logging"
ruleId = "@codepol/plugin/require-logger-enter-exit"
description = "Ensure functions are instrumented"
severity = "error"
providers = ["eslint", "tree-sitter"]
targets = ["typescript-src"]

Rule Fields

FieldTypeRequiredDescription
ruleIdstringYesNamespaced rule identifier, for example @scope/plugin/rule-name
targetsstring arrayYesNames of target entries to apply the rule to
idstringNoUser-defined identifier for reporting
descriptionstringNoHuman-readable summary
severity"error" | "warn" | "off"NoDefault is error
providersstring arrayNoOptional provider filter
argstableNoRule-specific arguments

Rule Args

Rule arguments are plugin-defined. For the built-in logger rule:

toml
[[rules]]
ruleId = "@codepol/plugin/require-logger-enter-exit"
targets = ["typescript-src"]

[rules.args.logger]
identifier = "logger"
enterMethod = "enter"
exitMethod = "exit"
import = { module = "@your-org/logger", named = "logger" }

For the built-in enforce-casing rule, configure symbol kinds and/or path segments. Supported styles per name: camelCase, snake_case, PascalCase, SCREAMING_SNAKE_CASE, kebab-case. Omitted symbol kinds are not checked. Path checks apply to each directory segment and the file basename (see enforce-casing for details).

toml
[[rules]]
ruleId = "@codepol/plugin/enforce-casing"
targets = ["typescript-src"]

[rules.args.symbols]
function = ["camelCase"]
class = ["PascalCase"]
interface = ["PascalCase"]
type = ["PascalCase"]
variable = ["camelCase"]
const = ["camelCase", "SCREAMING_SNAKE_CASE"]

[rules.args.paths]
file = ["kebab-case"]
directory = ["kebab-case"]
ignoreExtensions = true

The built-in no-mixed-exports rule applies to JavaScript and TypeScript targets matched by the rule (see no-mixed-exports). It accepts an optional args.preferredStyle = "named" | "default" to control which side of a mixed module is treated as the preferred export style in diagnostics.

toml
[[rules]]
ruleId = "@codepol/plugin/no-mixed-exports"
targets = ["typescript-src"]
args.preferredStyle = "named"

The built-in forbidden-declarations rule bans configured declaration categories in JS/TS files. Use args.symbols, args.bindings, and args.syntax to choose which declaration families to report (see forbidden-declarations).

toml
[[rules]]
ruleId = "@codepol/plugin/forbidden-declarations"
targets = ["typescript-src"]
args.symbols = ["class", "interface", "type"]
args.bindings = ["import"]
args.syntax = ["var"]

Plugin Declarations

Codepol no longer resolves plugins as Node module imports from the config file. Policies declare a stable plugin id plus a transport-specific source.

Built-In Plugin

toml
[[plugins]]
id = "@codepol/plugin"
source = { kind = "builtin" }

Use this for plugins that are registered by the host process, for example the CLI or an ESLint config that calls pluginBuiltinRegister().

Subprocess Plugin

toml
[[plugins]]
id = "@your-org/custom-plugin"

[plugins.source]
kind = "process"
command = "python3"
args = ["./tools/codepol_plugin.py"]
cwd = "."
timeoutMs = 5000

Plugin Fields

FieldTypeRequiredDescription
idstringYesStable plugin namespace used in ruleId
source.kind"builtin" | "process"YesPlugin transport
source.commandstringProcess onlyExecutable or script to launch
source.argsstring arrayNoProcess arguments
source.cwdstringNoWorking directory for process plugins
source.envtableNoExtra environment variables
source.timeoutMsintegerNoRequest timeout in milliseconds

Provider Filtering

Use providers when you want a rule to apply only on specific hosts:

toml
[[rules]]
ruleId = "@codepol/plugin/require-logger-enter-exit"
providers = ["tree-sitter"]
targets = ["typescript-src"]

Common provider values:

  • eslint
  • biome
  • tree-sitter
  • ruff

If omitted, the rule applies everywhere the host can adapt it.

biome providers are executed by the CLI via biome lint on JS/TS files that match this rule’s targets (and only when the rule selects the biome provider, if providers is set). Biome’s own config discovery still applies unless the provider supplies an explicit configPath. Multiple distinct Biome provider configurations result in multiple biome lint subprocess runs (one per normalized config group). Policy severity and args do not currently alter Biome diagnostics; configure rules in Biome’s config instead.

Notes

  • codepol.toml is the only discovered config format.
  • Built-in rule IDs keep their namespaced form, for example @codepol/plugin/no-interface, @codepol/plugin/forbidden-declarations, or @codepol/plugin/enforce-casing.
  • Direct ESLint usage should combine policyPluginRulesGet() with providerRulesConfigGet('eslint').