topmark.pipeline.context.policy ¶
Policy helpers for interpreting configuration in the pipeline context.
This module centralizes helpers that interpret the effective FrozenPolicy in the context of a single file. Functions here operate on a ProcessingContext instance to decide whether certain operations (for example, inserting into empty files or tolerating mixed newlines) are permitted.
is_empty_for_insert ¶
Return whether this file should be treated as "empty" for insertion decisions.
This helper interprets the effective per-type policy setting
FrozenPolicy.empty_insert_mode
and maps it onto the file's observed state.
The distinction matters because TopMark may need to preserve stable round-trips:
- A true empty file (0 bytes) is represented by
FsStatus.EMPTY. - A file can be logically empty (BOM stripped, optional whitespace, optional single trailing newline) even when it is not 0 bytes.
- A file can be effectively empty (no non-whitespace characters) while containing multiple blank lines.
The selected mode controls which of these categories is considered "empty" when deciding whether inserting a header is allowed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
SupportsPolicyEvaluation
|
Processing context (or compatible protocol) providing filesystem status and decoded image emptiness flags. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the current file qualifies as empty under the configured insertion mode. |
Notes
- This predicate is only about classification of emptiness for insert gating.
It does not check whether insertion is allowed; use
allow_insert_into_empty_likefor that. FsStatus.EMPTYis always treated as empty, regardless of mode.
Source code in src/topmark/pipeline/context/policy.py
is_empty_for_insert_unchanged_by_default ¶
Return True when an insertion-empty file should default to UNCHANGED.
This helper is for bucketing/reporting, not mutation.
It captures the default policy interpretation for files that are classified as "empty for insertion":
- If the file counts as empty under
is_empty_for_insert(ctx), and - policy does not allow inserting into such files,
then TopMark should generally treat the file as compliant / unchanged rather than as "missing header".
This avoids surprising "would insert" or "missing header" outcomes for placeholder files such as:
- true 0-byte files
- BOM-only files
- newline-only files
- other empty-like images covered by the configured
EmptyInsertMode
The actual definition of "empty" is delegated to is_empty_for_insert(ctx),
so this helper automatically obeys the effective EmptyInsertMode
(bytes_empty, logical_empty, or whitespace_empty).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
SupportsPolicyEvaluation
|
Processing context (or compatible protocol). |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the file is classified as empty-for-insert and policy does not |
bool
|
allow inserting into such files; otherwise False. |
Notes
- Use this in outcome bucketing and summaries.
- Mutation steps should instead use
allow_insert_into_empty_like(ctx).
Source code in src/topmark/pipeline/context/policy.py
allow_insert_into_empty_like ¶
Return True if policy permits inserting a header into an empty-like file.
This is the primary policy gate used by planner/updater when a file has no meaningful body content.
The decision is a conjunction of:
1) whether the file is considered empty for insert (see
is_empty_for_insert), and
2) whether the effective policy enables insertion into empty files
(FrozenPolicy.allow_header_in_empty_files).
Because this helper delegates classification to is_empty_for_insert, it
automatically obeys the configured EmptyInsertMode (bytes_empty,
logical_empty, or whitespace_empty).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
SupportsPolicyEvaluation
|
Processing context (or compatible protocol). |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if insertion is allowed for this file given its empty-like state and the |
bool
|
effective policy. |
Guidance
- Use this in mutation steps (planner/updater) when deciding whether an insert/update is allowed to proceed.
- Do not use it to skip reading/analysis steps; those should be governed by filesystem/content feasibility (e.g., unreadable/binary/mixed-newlines).
Source code in src/topmark/pipeline/context/policy.py
allow_empty_header ¶
Return True if the effective policy allows empty header insertion.
This helper inspects the effective per-type policy (global configuration overlaid by per-type overrides) and reports whether an empty rendered header is considered acceptable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
SupportsPolicyEvaluation
|
Processing context containing status and configuration. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
|
Source code in src/topmark/pipeline/context/policy.py
allow_content_reflow ¶
Return True if the effective policy allows content reflow.
This covers transformations that may adjust layout or whitespace around
the header region and are controlled by the allow_reflow flag.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
SupportsPolicyEvaluation
|
Processing context containing status and configuration. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if policy allows reflowing content around the header, |
bool
|
False otherwise. |
Source code in src/topmark/pipeline/context/policy.py
allow_mixed_line_endings ¶
Return whether the filesystem state may pass the mixed-newline gate.
Healthy and empty files may proceed. Mixed physical line endings may also
proceed only when the effective explicit mode is preserve; all other
filesystem problem states are refused.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
SupportsPolicyEvaluation
|
Processing context containing filesystem status and configuration. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
Source code in src/topmark/pipeline/context/policy.py
bom_before_shebang_mode ¶
Return the effective explicit BOM-before-shebang handling mode.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
SupportsPolicyEvaluation
|
Processing context containing filesystem status and configuration. |
required |
Returns:
| Type | Description |
|---|---|
BomBeforeShebangMode
|
The resolved mode for the current file type. |
Source code in src/topmark/pipeline/context/policy.py
should_remove_bom_before_shebang ¶
Return whether the detected BOM/shebang conflict must be remediated.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
SupportsPolicyEvaluation
|
Processing context containing detection facts and resolved policy. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
Source code in src/topmark/pipeline/context/policy.py
source_lines_with_remediated_bom ¶
Restore the source BOM to normalized lines for edit and diff boundaries.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lines
|
list[str]
|
Reader-normalized source lines. |
required |
ctx
|
SupportsPolicyEvaluation
|
Processing context containing detection facts and resolved policy. |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
A copy whose first line includes the source BOM when remediation is active. |
Source code in src/topmark/pipeline/context/policy.py
check_permitted_by_policy ¶
Whether the active check policy allows the intended header mutation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
SupportsPolicyEvaluation
|
Processing context for the current file. |
required |
Returns:
| Type | Description |
|---|---|
bool | None
|
|
bool | None
|
|
bool | None
|
|
Source code in src/topmark/pipeline/context/policy.py
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 | |
would_change ¶
Return whether a change would occur (tri-state).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
SupportsPolicyEvaluation
|
Processing context for the current file. |
required |
Returns:
| Type | Description |
|---|---|
bool | None
|
|
bool | None
|
or the strip step prepared/attempted a removal), |
bool | None
|
(e.g., UNCHANGED or strip NOT_NEEDED), and |
bool | None
|
comparison was skipped/pending and the strip step did not run. |
Source code in src/topmark/pipeline/context/policy.py
can_change ¶
Return whether a mutation can be applied safely for this file.
This helper answers a narrow question:
If the pipeline intends to mutate this file, is that mutation structurally and operationally allowed to proceed?
It combines three categories of checks:
1) Baseline feasibility The file must have resolved successfully, strip preparation must not have failed, and the header state must not be one of the malformed states that block safe mutation.
2) Normal files and explicit BOM remediation
For ordinary files (FsStatus.OK), mutation is allowed once baseline
feasibility is satisfied. A detected BOM-before-shebang conflict is also
mutable when the effective mode is remove_bom.
3) Empty / empty-like files
For files that are considered "empty for insert", mutation is allowed only
when policy explicitly permits inserting into such files. Importantly,
emptiness classification is delegated to is_empty_for_insert(ctx), which
obeys the configured EmptyInsertMode.
This means:
- true 0-byte files may be mutable if policy allows it
- logically empty placeholders may be mutable if policy allows it
- whitespace-only files may be mutable if policy allows it
(depending on EmptyInsertMode)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
SupportsPolicyEvaluation
|
Processing context for the current file. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if a mutation is structurally and operationally safe to apply, |
bool
|
otherwise False. |
Source code in src/topmark/pipeline/context/policy.py
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 | |
would_add_or_update ¶
Intent for check/apply: True if we'd insert or replace a header.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
SupportsPolicyEvaluation
|
Processing context for the current file. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
|
Source code in src/topmark/pipeline/context/policy.py
effective_would_add_or_update ¶
True iff add/update is intended, feasible, and allowed by policy.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
SupportsPolicyEvaluation
|
Processing context for the current file. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
|
Source code in src/topmark/pipeline/context/policy.py
would_strip ¶
Intent for strip: True if a removal would occur.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
SupportsPolicyEvaluation
|
Processing context for the current file. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
|
Source code in src/topmark/pipeline/context/policy.py
effective_would_strip ¶
True iff a strip is intended and feasible.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
SupportsPolicyEvaluation
|
Processing context for the current file. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
|