Skip to content

User configuration

TopMark runtime configuration may be provided through:

  • topmark.toml
  • pyproject.toml ([tool.topmark])
  • CLI overrides
  • API overlays

Configuration is resolved through layered discovery, normalization, and precedence rules; a higher-precedence layer overrides a lower-precedence layer. For the complete discovery order, discovery-anchor behavior, and configuration-source identity contract, see Configuration discovery, precedence, and policy.

Note

The canonical vocabulary used throughout the documentation is defined in Terminology and Canonical Vocabulary.


CLI, configuration, and API value spelling

Configuration keys use consistent naming across the CLI, API, and TOML configuration surfaces. Some options accept predefined multi-word values such as add_only or whitespace_empty.

TopMark uses different spelling conventions depending on the interface: finite-choice CLI values require exact lowercase spelling and hyphenated forms for multiword values, while TOML configuration, Python API values, and machine-readable output use canonical underscore forms.

CLI spelling vs configuration/API spelling

TopMark uses hyphenated spelling for CLI option names:

topmark check --header-mutation-mode=add-only

Finite-choice CLI values require their exact documented lowercase spelling. Multiword values additionally require hyphens:

topmark check --header-mutation-mode=add-only

Uppercase, mixed-case, and snake_case CLI aliases such as ADD-ONLY, Update-Only, add_only, logical_empty, and REMOVE_BOM are rejected. When lowercasing the token and replacing underscores with hyphens produces an exact declared choice, TopMark suggests that canonical spelling.

TOML configuration, Python API values, and machine-readable output use the canonical underscore form:

[policy]
header_mutation_mode = "add_only"

CLI option names themselves also do not accept underscores. Use --header-mutation-mode, not --header_mutation_mode. These spelling rules apply only to option names and finite-choice values; paths, filenames, globs, header content, and other free-form inputs retain their original case.

Unless otherwise noted, configuration and policy values shown throughout this page use the canonical TOML/API/machine-readable underscore form.


Multiline field values

The target design in #339 changes multiline field rendering. Under that design, custom [fields] values may use TOML multiline strings; TopMark removes their incidental leading and trailing blank lines, then renders multiline values using pipe-prefixed continuation records:

[fields]
notice = """
First line.
Second line.
"""

[header]
fields = ["notice"]

See Multiline header field rendering for continuation, paragraph, validation, and canonicalization details.

Deterministic field wrapping

Under the target design, selected fields treat multiline TOML content as reflowable prose and wrap it into canonical continuation records:

[formatting]
max_header_line_length = 100
wrap_fields = ["notice", "copyright"]

Wrapping is disabled unless both a positive width and an allowlisted field are present. The width counts Unicode code points across the complete physical field line, including comment syntax and indentation but excluding the line terminator. It is a soft target: TopMark wraps only at lossless U+0020 SPACE boundaries and never hard-splits URLs, paths, identifiers, or other unbreakable content.

For a selected field, nonblank TOML line breaks become spaces and blank-line runs become paragraph separators. TopMark wraps each paragraph independently and uses a bare continuation pipe between paragraphs. Unselected multiline fields retain their logical lines. The rendered header is derived from the effective configuration; it is not an independent source of field values.


File type identifiers

TopMark accepts file type identifiers in local form, such as python, or qualified form, such as the qualified file type identifier topmark:python.

Local identifiers are accepted only when unambiguous. Internally, TopMark normalizes identifiers to canonical qualified file type identities before filtering, runtime resolution, policy evaluation, diagnostics, and registry lookup.

See file-type filtering for the full identifier contract.

File type identifiers participate in stable runtime behavior such as:

  • include_file_types
  • exclude_file_types
  • opt_in_file_types
  • policy_by_type
  • CLI file-type filters
  • API file-type filters and policy overlays

File-type filters

File-type filters allow restricting runtime processing to a selected subset of file types.

Example using local identifiers:

[files]
include_file_types = ["python", "markdown"]

Equivalent configuration using canonical qualified file type identifiers:

[files]
include_file_types = ["topmark:python", "topmark:markdown"]

Exclude filters work the same way:

[files]
exclude_file_types = ["topmark:yaml"]

Opt-in activation

File-type filters do not grant processing authorization. A file type declared opt-in requires explicit consent through opt_in_file_types:

[files]
opt_in_file_types = ["topmark:json-as-jsonc"]

As with filters, local identifiers are accepted only when unambiguous and TopMark normalizes them to canonical qualified identities. File types declared default need no entry. File types declared never cannot be made processable by configuration, and an exclusion filter remains a veto even for an explicitly opted-in type.

[NOTE] Internally, TopMark normalizes configured file type identifiers to canonical qualified identities before filtering, runtime resolution, policy evaluation, diagnostics, and registry lookup.


Per-file-type policy

policy_by_type allows file-type-specific policy overrides for selected file types.

Example using a local identifier:

[policy_by_type.python]
header_mutation_mode = "update_only"

Equivalent configuration using canonical qualified file type identifiers:

[policy_by_type."topmark:python"]
header_mutation_mode = "update_only"

Both forms are accepted when the local identifier resolves unambiguously.

Internally, TopMark stores and resolves per-file-type policies using canonical qualified file type identities.

Example: Different policy per file type

[policy]
header_mutation_mode = "add_only"
bom_before_shebang = "reject"
mixed_line_endings = "preserve"

[policy_by_type."topmark:python"]
header_mutation_mode = "update_only"
bom_before_shebang = "remove_bom"
mixed_line_endings = "reject"

[policy_by_type.markdown]
allow_content_probe = false

In this example:

  • the global default header mutation policy uses add_only and mixed line endings are preserved when present
  • Python files override this with update_only
  • Python files also remediate a BOM immediately before a shebang
  • Python files also reject files with mixed line endings
  • Markdown files disable runtime content probing

Ambiguous identifiers

When more than one registered file type shares the same local identifier, TopMark requires the canonical qualified form.

For example, if both:

  • topmark:python
  • acme:python

are registered, then:

include_file_types = ["python"]

is ambiguous.

Use:

include_file_types = ["topmark:python"]

instead.

Ambiguous identifiers are ignored diagnostically during configuration normalization and staged configuration-loading validation.


Unknown and malformed identifiers

Unknown identifiers are ignored diagnostically during configuration normalization and staged configuration-loading validation.

Malformed qualified identifiers are also ignored diagnostically during configuration normalization and staged configuration-loading validation.

Examples of malformed identifiers:

:python
topmark:
topmark:python:extra

CLI and API parity

CLI options, TOML configuration, API overlays, and runtime policy evaluation all share the same file type identity semantics.

Examples:

topmark check --include-file-types python .
topmark check --include-file-types topmark:python .
topmark check --opt-in-file-type topmark:json-as-jsonc .
api.check(
    paths=[repo],
    include_file_types=["topmark:python"],
)

Runtime configuration model

TopMark intentionally separates:

  1. TOML-source loading
  2. configuration-source identity normalization
  3. workspace-root and configuration-discovery anchoring
  4. staged configuration-loading validation
  5. layered configuration deserialization and merging
  6. runtime configuration resolution
  7. runtime overlay application
  8. runtime policy evaluation
  9. filesystem-identity evaluation
  10. processing-path selection
  11. runtime pipeline gatekeeping and execution

Configuration-source identity and filesystem identity are intentionally distinct.

File-backed configuration sources are normalized to resolved configuration targets before precedence, scope applicability, and layered provenance evaluation. Runtime file processing similarly operates on selected processing paths derived from filesystem-identity evaluation. Workspace-root discovery and configuration-discovery anchoring are evaluated independently and may traverse resolved filesystem locations when determining configuration search roots.

If multiple discovered or explicit configuration entries resolve to the same configuration-source identity, TopMark retains only the highest-precedence occurrence for configuration layering and provenance evaluation.

Filesystem-identity evaluation includes:

  • filesystem-identity normalization (for example symlink-path normalization and processing-path selection); and
  • filesystem-identity eligibility checks (for example hard-link policy enforcement).

These normalization stages occur before runtime policy evaluation and pipeline execution.

Reporting, API surfaces, and machine-readable output expose a flattened compatibility view derived from these internal runtime stages.

This layered runtime model keeps behavior deterministic while preserving stable configuration-discovery, configuration, policy, filesystem-identity, diagnostics, and machine-readable compatibility contracts.

Enum-valued runtime policies, including bom_before_shebang = "reject"|"remove_bom" and mixed_line_endings = "reject"|"preserve", use the same field-wise layering and per-file-type inheritance as other policy fields. Machine configuration snapshots serialize canonical underscore values.

Runtime evaluation consumes the effective configuration produced after workspace-root discovery, precedence, normalization, and configuration-source identity resolution have completed.

For configuration files loaded through symlinks, the effective configuration is associated with the resolved configuration target rather than the symlink spelling used to reach it.

Hard-link processing policy is not represented in the runtime configuration model because it is a processing-target eligibility rule evaluated by runtime file-processing commands rather than a configuration-layering concern.


See also