Skip to content

topmark.config.policy

topmark / config / policy

Policy model for TopMark (global and per-file-type).

This module defines the policy layer used to control run intent and safety rules, both globally and with per-file-type overrides.

Design
  • MutablePolicy uses tri-state options (bool | None / Enum | None) to represent explicit values versus unset. This enables non-destructive merges and inheritance when composing multiple sources (defaults -> user -> project -> CLI).
  • FrozenPolicy is the fully resolved, immutable runtime view with plain values, so pipeline steps do not branch on None.
  • MutablePolicy.resolve(base) fills unset fields from base and returns an immutable FrozenPolicy; use it at MutableConfig.freeze() time.

TOML mapping:

```toml
[policy]
header_mutation_mode = "all"
allow_header_in_empty_files = false
empty_insert_mode = "logical_empty"
allow_content_probe = true

[policy_by_type.python]
allow_header_in_empty_files = true
```

HeaderMutationMode

Bases: str, Enum

Defines how headers may be mutated.

Attributes:

Name Type Description
ALL

Allow both inserting missing headers and updating existing headers (default).

ADD_ONLY

Only add headers when no header present.

UPDATE_ONLY

Only update existing headers.

EmptyInsertMode

Bases: str, Enum

How TopMark classifies "empty" inputs for header insertion.

The selected mode determines which files count as "empty" when evaluating Policy.allow_header_in_empty_files.

Attributes:

Name Type Description
BYTES_EMPTY

Only true 0-byte files (FsStatus.EMPTY).

LOGICAL_EMPTY

0-byte files plus logically-empty placeholders (optional BOM, optional horizontal whitespace, and at most one trailing newline).

WHITESPACE_EMPTY

0-byte files plus any effectively-empty decoded image (no non-whitespace characters; whitespace/newlines allowed).

FrozenPolicy dataclass

FrozenPolicy(
    *,
    header_mutation_mode=HeaderMutationMode.ALL,
    allow_header_in_empty_files=False,
    empty_insert_mode=EmptyInsertMode.LOGICAL_EMPTY,
    render_empty_header_when_no_fields=False,
    allow_reflow=False,
    allow_content_probe=True,
)

Immutable, runtime policy used by processing steps.

Attributes:

Name Type Description
header_mutation_mode HeaderMutationMode

Defines how headers may be mutated: process all files if (ALL, default); only add headers when no header present (ADD_ONLY); only update existing headers (UPDATE_ONLY).

allow_header_in_empty_files bool

Allow inserting headers into files that are classified as empty under empty_insert_mode.

empty_insert_mode EmptyInsertMode

Defines which files are considered "empty" for insertion policy (bytes_empty, logical_empty, or whitespace_empty).

render_empty_header_when_no_fields bool

Allow inserting an otherwise empty header when no fields are configured.

allow_reflow bool

Allow reflowing file content when inserting a header. Enabling this can break check/strip idempotence.

allow_content_probe bool

Whether the resolver may consult file contents during file-type detection. True allows content-based probes; False forces name/extension-only resolution.

thaw

thaw()

Return a mutable builder initialized from this immutable policy.

Returns:

Type Description
MutablePolicy

A tri-state mutable policy.

Source code in src/topmark/config/policy.py
def thaw(self) -> MutablePolicy:
    """Return a mutable builder initialized from this immutable policy.

    Returns:
        A tri-state mutable policy.
    """
    return MutablePolicy(
        header_mutation_mode=self.header_mutation_mode,
        allow_header_in_empty_files=self.allow_header_in_empty_files,
        empty_insert_mode=self.empty_insert_mode,
        render_empty_header_when_no_fields=self.render_empty_header_when_no_fields,
        allow_reflow=self.allow_reflow,
        allow_content_probe=self.allow_content_probe,
    )

to_dict

to_dict()

Serialize this resolved policy to a TOML-friendly dictionary.

Returns:

Type Description
dict[str, object]

Dictionary containing primitive TOML-serializable values.

Notes

This is an export helper for documentation, machine payloads, and config rendering. Resolved FrozenPolicy instances always emit all fields.

Source code in src/topmark/config/policy.py
def to_dict(self) -> dict[str, object]:
    """Serialize this resolved policy to a TOML-friendly dictionary.

    Returns:
        Dictionary containing primitive TOML-serializable values.

    Notes:
        This is an export helper for documentation, machine payloads, and config rendering.
        Resolved [`FrozenPolicy`][topmark.config.policy.FrozenPolicy] instances always emit
        all fields.
    """
    return policy_to_dict(self)

MutablePolicy dataclass

MutablePolicy(
    *,
    header_mutation_mode=None,
    allow_header_in_empty_files=None,
    empty_insert_mode=None,
    render_empty_header_when_no_fields=None,
    allow_reflow=None,
    allow_content_probe=None,
)

Mutable policy builder suitable for config loading/merging.

This class is merged in a last-wins manner when reading multiple config files.

Attributes:

Name Type Description
header_mutation_mode HeaderMutationMode | None

See FrozenPolicy. None means "inherit".

allow_header_in_empty_files bool | None

See FrozenPolicy. None means "inherit".

empty_insert_mode EmptyInsertMode | None

See FrozenPolicy. None means "inherit".

render_empty_header_when_no_fields bool | None

See FrozenPolicy. None means "inherit".

allow_reflow bool | None

See FrozenPolicy. None means "inherit".

allow_content_probe bool | None

See FrozenPolicy. None means "inherit".

merge_with

merge_with(other)

Return a new MutablePolicy by applying other over self (last-wins).

None fields in other do not override explicit values in self.

Parameters:

Name Type Description Default
other MutablePolicy

The policy whose values override current ones.

required

Returns:

Type Description
MutablePolicy

Merged policy.

Source code in src/topmark/config/policy.py
def merge_with(self, other: MutablePolicy) -> MutablePolicy:
    """Return a new `MutablePolicy` by applying ``other`` over ``self`` (last-wins).

    ``None`` fields in ``other`` do not override explicit values in ``self``.

    Args:
        other: The policy whose values override current ones.

    Returns:
        Merged policy.
    """
    return MutablePolicy(
        header_mutation_mode=overlay(
            override=other.header_mutation_mode,
            current=self.header_mutation_mode,
        ),
        allow_header_in_empty_files=overlay(
            override=other.allow_header_in_empty_files,
            current=self.allow_header_in_empty_files,
        ),
        empty_insert_mode=overlay(
            override=other.empty_insert_mode,
            current=self.empty_insert_mode,
        ),
        render_empty_header_when_no_fields=overlay(
            override=other.render_empty_header_when_no_fields,
            current=self.render_empty_header_when_no_fields,
        ),
        allow_reflow=overlay(
            override=other.allow_reflow,
            current=self.allow_reflow,
        ),
        allow_content_probe=overlay(
            override=other.allow_content_probe,
            current=self.allow_content_probe,
        ),
    )

resolve

resolve(base)

Resolve tri-state fields against a base immutable policy.

Parameters:

Name Type Description Default
base FrozenPolicy

Base policy that provides defaults for unset fields.

required

Returns:

Type Description
FrozenPolicy

A fully-resolved immutable policy with plain booleans.

Source code in src/topmark/config/policy.py
def resolve(self, base: FrozenPolicy) -> FrozenPolicy:
    """Resolve tri-state fields against a base immutable policy.

    Args:
        base: Base policy that provides defaults for unset fields.

    Returns:
        A fully-resolved immutable policy with plain booleans.
    """
    return FrozenPolicy(
        header_mutation_mode=(
            base.header_mutation_mode
            if self.header_mutation_mode is None
            else self.header_mutation_mode
        ),
        allow_header_in_empty_files=(
            base.allow_header_in_empty_files
            if self.allow_header_in_empty_files is None
            else self.allow_header_in_empty_files
        ),
        empty_insert_mode=(
            base.empty_insert_mode if self.empty_insert_mode is None else self.empty_insert_mode
        ),
        render_empty_header_when_no_fields=(
            base.render_empty_header_when_no_fields
            if self.render_empty_header_when_no_fields is None
            else self.render_empty_header_when_no_fields
        ),
        allow_reflow=base.allow_reflow if self.allow_reflow is None else self.allow_reflow,
        allow_content_probe=(
            base.allow_content_probe
            if self.allow_content_probe is None
            else self.allow_content_probe
        ),
    )

freeze

freeze()

Freeze to a concrete FrozenPolicy using the built-in policy defaults.

Returns:

Type Description
FrozenPolicy

Fully resolved immutable policy.

Notes

This is equivalent to resolving against FrozenPolicy().

Source code in src/topmark/config/policy.py
def freeze(self) -> FrozenPolicy:
    """Freeze to a concrete `FrozenPolicy` using the built-in policy defaults.

    Returns:
        Fully resolved immutable policy.

    Notes:
        This is equivalent to resolving against
        [`FrozenPolicy()`][topmark.config.policy.FrozenPolicy].
    """
    return self.resolve(FrozenPolicy())

from_toml_table classmethod

from_toml_table(tbl)

Create a MutablePolicy from a TOML table.

Unspecified keys remain None so they can inherit from the base policy during resolve().

Parameters:

Name Type Description Default
tbl Mapping[str, object] | None

TOML table mapping for [policy] or [policy_by_type.<name>].

required

Returns:

Type Description
MutablePolicy

Parsed mutable policy.

Source code in src/topmark/config/policy.py
@classmethod
def from_toml_table(cls, tbl: Mapping[str, object] | None) -> MutablePolicy:
    """Create a MutablePolicy from a TOML table.

    Unspecified keys remain `None` so they can inherit from the base policy during `resolve()`.

    Args:
        tbl: TOML table mapping for `[policy]` or `[policy_by_type.<name>]`.

    Returns:
        Parsed mutable policy.
    """
    if not tbl:
        return cls()

    return cls(
        header_mutation_mode=opt_enum(
            tbl,
            key=Toml.KEY_POLICY_HEADER_MUTATION_MODE,
            enum_cls=HeaderMutationMode,
        ),
        allow_header_in_empty_files=opt_bool(
            tbl,
            key=Toml.KEY_POLICY_ALLOW_HEADER_IN_EMPTIES,
        ),
        empty_insert_mode=opt_enum(
            tbl,
            key=Toml.KEY_POLICY_EMPTIES_INSERT_MODE,
            enum_cls=EmptyInsertMode,
        ),
        render_empty_header_when_no_fields=opt_bool(
            tbl,
            key=Toml.KEY_POLICY_ALLOW_EMPTY_HEADER,
        ),
        allow_reflow=opt_bool(
            tbl,
            key=Toml.KEY_POLICY_ALLOW_REFLOW,
        ),
        allow_content_probe=opt_bool(
            tbl,
            key=Toml.KEY_POLICY_ALLOW_CONTENT_PROBE,
        ),
    )

HasPolicyConfig

Bases: Protocol

Read-only view of resolved policy configuration.

This protocol captures the minimum surface required by helpers like make_policy_registry and effective_frozen_policy.

It intentionally avoids importing the concrete FrozenConfig / MutableConfig classes to prevent type-check-time import cycles.

Implementations are expected to expose resolved runtime policies: - policy is a fully resolved FrozenPolicy - policy_by_type maps file-type identifiers to resolved per-type FrozenPolicy

Attributes are defined as read-only properties so both immutable FrozenConfig and mutable MutableConfig builders can satisfy the protocol.

policy property

policy

Resolved global policy.

policy_by_type property

policy_by_type

Mapping of file-type identifiers to resolved per-type policies.

PolicyRegistry dataclass

PolicyRegistry(*, global_policy, by_type)

Immutable registry of effective policies per file type.

Instances of this class are derived from a resolved FrozenConfig and provide constant-time lookup of the effective FrozenPolicy to apply for a given file type.

for_type

for_type(name)

Return the effective policy for the given file-type name.

Parameters:

Name Type Description Default
name str | None

File type name, or None for the global/default case.

required

Returns:

Type Description
FrozenPolicy

The resolved per-type policy if present; otherwise the global policy.

Source code in src/topmark/config/policy.py
def for_type(self, name: str | None) -> FrozenPolicy:
    """Return the effective policy for the given file-type name.

    Args:
        name: File type name, or None for the global/default case.

    Returns:
        The resolved per-type policy if present; otherwise the global policy.
    """
    if name is None:
        return self.global_policy
    return self.by_type.get(name, self.global_policy)

policy_to_dict

policy_to_dict(policy)

Serialize a resolved or tri-state policy to a TOML-friendly dictionary.

Parameters:

Name Type Description Default
policy FrozenPolicy

Frozen FrozenPolicy object.

required

Returns:

Type Description
dict[str, object]

Dictionary containing all policy fields as TOML-friendly primitives. Enum values are

dict[str, object]

serialized via .value.

Source code in src/topmark/config/policy.py
def policy_to_dict(policy: FrozenPolicy) -> dict[str, object]:
    """Serialize a resolved or tri-state policy to a TOML-friendly dictionary.

    Args:
        policy: Frozen [`FrozenPolicy`][topmark.config.policy.FrozenPolicy] object.

    Returns:
        Dictionary containing all policy fields as TOML-friendly primitives. Enum values are
        serialized via `.value`.
    """
    out: dict[str, object] = {}
    out[Toml.KEY_POLICY_HEADER_MUTATION_MODE] = policy.header_mutation_mode.value  # StrEnum
    out[Toml.KEY_POLICY_ALLOW_HEADER_IN_EMPTIES] = policy.allow_header_in_empty_files
    out[Toml.KEY_POLICY_EMPTIES_INSERT_MODE] = policy.empty_insert_mode.value  # StrEnum
    out[Toml.KEY_POLICY_ALLOW_EMPTY_HEADER] = policy.render_empty_header_when_no_fields
    out[Toml.KEY_POLICY_ALLOW_REFLOW] = policy.allow_reflow
    out[Toml.KEY_POLICY_ALLOW_CONTENT_PROBE] = policy.allow_content_probe
    return out

make_policy_registry

make_policy_registry(config)

Build an immutable PolicyRegistry from a resolved config-like object.

Parameters:

Name Type Description Default
config HasPolicyConfig

Resolved configuration object exposing global and per-type policy mappings through the HasPolicyConfig protocol.

required

Returns:

Type Description
PolicyRegistry

Immutable effective policy registry.

Source code in src/topmark/config/policy.py
def make_policy_registry(config: HasPolicyConfig) -> PolicyRegistry:
    """Build an immutable `PolicyRegistry` from a resolved config-like object.

    Args:
        config: Resolved configuration object exposing global and per-type policy
            mappings through the `HasPolicyConfig` protocol.

    Returns:
        Immutable effective policy registry.
    """
    return PolicyRegistry(
        global_policy=config.policy,
        by_type=config.policy_by_type,
    )

effective_frozen_policy

effective_frozen_policy(cfg, file_type_id)

Return the effective policy for a given file type.

Per-type overrides take precedence over the global policy. If file_type_id is None or no per-type policy exists for that identifier, the global policy is returned.

This helper assumes that both cfg.policy and entries in cfg.policy_by_type are already fully resolved FrozenPolicy instances (that is, no tri-state inheritance remains at runtime).

Parameters:

Name Type Description Default
cfg HasPolicyConfig

Resolved runtime configuration.

required
file_type_id str | None

File type identifier (for example, "python").

required

Returns:

Type Description
FrozenPolicy

Effective policy to use for processing.

Source code in src/topmark/config/policy.py
def effective_frozen_policy(cfg: HasPolicyConfig, file_type_id: str | None) -> FrozenPolicy:
    r"""Return the effective policy for a given file type.

    Per-type overrides take precedence over the global policy. If `file_type_id`
    is `None` or no per-type policy exists for that identifier, the global policy
    is returned.

    This helper assumes that both `cfg.policy` and entries in `cfg.policy_by_type`
    are already fully resolved [`FrozenPolicy`][topmark.config.policy.FrozenPolicy]
    instances (that is, no tri-state inheritance remains at runtime).

    Args:
        cfg: Resolved runtime configuration.
        file_type_id: File type identifier (for example, `"python"`).

    Returns:
        Effective policy to use for processing.
    """
    if file_type_id is None:
        return cfg.policy

    override: FrozenPolicy | None = cfg.policy_by_type.get(file_type_id)
    if override is not None:
        return override
    return cfg.policy