topmark strip¶
Purpose: Strip TopMark headers.
The strip command removes the entire TopMark header block from targeted files. It is dry-run by
default (summaries end with - previewed) and becomes destructive only with --apply (summaries
end with - removed).
Note
The canonical vocabulary used throughout the documentation is defined in Terminology and Canonical Vocabulary.
Note
Path representation
TopMark serializes machine-readable filesystem path fields with POSIX / separators on all
platforms.
Path serialization is a presentation contract and is distinct from filesystem identity.
TopMark first determines the selected processing path for the filesystem target being processed and then serializes that processing path according to the machine-output contract.
This contract applies to:
- header metadata path fields;
- processing machine-output payloads;
- probe machine-output payloads;
- configuration machine-output payloads; and
- TOML/config provenance payloads.
Examples:
may refer to the same filesystem identity and therefore produce the same serialized processing path.
TopMark's machine-readable path fields remain path-based and are derived from the selected processing path for each processing target.
Filesystem identity policy is a separate concern from path serialization. TopMark may apply additional filesystem-identity rules when determining whether a processing target is eligible for processing. For example, selected hard-linked files are detected using device/inode identity and are reported as unsupported processing targets. Such checks do not alter the serialized path values emitted in machine-readable output.
Human-facing output follows display-path policy instead:
- CLI and Markdown reports may use the host platform's native path representation;
- STDIN-backed processing displays the logical
--stdin-filenamewhen available; and - unified diff file labels are human-facing display labels, not machine-readable path fields.
Synthetic configuration-source identifiers (for example built-in defaults) are serialized as stable labels rather than filesystem paths.
Quick start¶
# Dry-run: show which files would have their TopMark header removed
topmark strip src/
# Apply in place
topmark strip --apply src/
# Show unified diffs in human output
topmark strip --diff src/
# Summary-only view (CI-friendly)
topmark strip --summary src/
# Suppress TEXT rendering and rely on the exit code
topmark strip --quiet src/
# Render document-oriented Markdown output
topmark strip --output-format markdown src/
# Treat staged configuration-loading validation warnings as errors for this run
topmark strip --strict src/
# Read targets from stdin (one path per line) and generate unified diff output
git ls-files | topmark strip --files-from - --diff
# Read targets from a file
find src -name '*.py' > files.txt
topmark strip --files-from files.txt
Input applicability¶
- Dry-run by default; exit code
WOULD_CHANGE (3)when removals would occur. --applyand--diffare mutually exclusive. Use--diffto preview removals or--applyto write them.- Preserves the file's original newline style (LF/CRLF/CR).
- Preserves a leading UTF-8 BOM if present.
- Honors XML/HTML placement rules and preserves the XML declaration (
<?xml ...?>). - Respects Markdown fenced code blocks: header-like snippets inside fences are ignored.
- Idempotent: once stripped, subsequent runs are no-ops.
STDIN modes¶
strip supports both list STDIN mode (--files-from -, --include-from -, or --exclude-from -)
and content STDIN mode (- plus --stdin-filename NAME). These modes are mutually exclusive.
--files-from FILE may also be used without positional PATH arguments. When the referenced file
is empty, the command proceeds normally and reports that there are no files to process rather than
treating the invocation as invalid CLI usage.
With --apply in content mode, transformed content is written to STDOUT and diagnostics are routed
to STDERR.
See shared input modes for the full STDIN contract,
including why TopMark does not provide a --stdin option flag.
Configuration and validation¶
strip supports --strict / --no-strict to override the effective strict value for the run.
Before any file processing begins, TopMark performs whole-source TOML schema validation during configuration loading. TOML-source diagnostics (including missing-section INFO diagnostics) are evaluated together with merged-config and runtime applicability diagnostics during staged configuration-loading validation for the run.
Note
[config].strict is a TOML-source-local strictness preference controlling staged
configuration-loading validation for the current TOML source.
Effective strictness is evaluated across:
- TOML-source diagnostics;
- merged-config diagnostics;
- runtime applicability diagnostics.
When strict validation fails, TopMark exits with CONFIG_ERROR. The diagnostics that triggered
the failure remain visible in human-readable and machine-readable output formats.
strict is resolved during TOML loading and does not become a layered configuration field.
In non-strict mode, configuration diagnostics remain advisory. Markdown reports include advisory
diagnostics for completeness. Default TEXT output may instead report only the resulting runtime
outcome, such as a file being filtered after configuration normalization. When --strict is
enabled, advisory diagnostics become fatal configuration errors and are surfaced consistently
across output formats.
TopMark resolves configuration from defaults, user config, the project chain discovered from the
resolved discovery anchor, explicit --config files, and CLI overrides before staged validation
produces the effective runtime configuration. For path-processing commands such as strip, the
discovery anchor is derived from the first selected input path when one is available, or from the
current working directory otherwise.
Configuration discovery is evaluated before runtime filesystem-identity evaluation selects
processing paths. Symlinked discovery anchors therefore affect which project configuration files are
found before selected processing paths, stripping behavior, or machine-readable result.path fields
are produced. See
Configuration discovery, precedence, and policy for the full
configuration-loading and validation contract.
Filtering and file discovery¶
TopMark determines which files to process using a combination of path-based filters and file-type filters.
Path arguments, --files-from file lists, include/exclude patterns, and file-type filters follow
the shared TopMark filtering pipeline. Positional paths and relative patterns are resolved from the
current working directory; path-based filters run before file-type filters, and exclude rules take
precedence. See Filtering for the full path
discovery contract.
During discovery, TopMark performs filesystem-identity evaluation and selects processing paths. If
multiple path spellings resolve to the same filesystem target (for example a symlink and its
target), strip processes the resolved target once. Downstream filtering, probing, stripping, and
machine-readable output operate on the selected processing path rather than the original spelling.
Hard-link policy is evaluated separately from processing-path selection: if multiple selected
processing paths are hard links to the same filesystem object, each affected path is reported as an
unsupported, policy-blocked processing target.
This runtime discovery stage is separate from configuration discovery. Project-chain configuration
files have already been selected from the resolved discovery anchor before strip evaluates file
filters and processing-target identity.
File type filters¶
--include-file-types / -tRestrict processing to the given file type identifiers. May be repeated and/or provided as a comma-separated list.--exclude-file-types / -TExclude the given file type identifiers. May be repeated and/or provided as a comma-separated list.
Exclude rules take precedence over include rules.
TopMark accepts file type identifiers in local form, such as python, or qualified form, such as
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.
Examples:
topmark strip --include-file-types python src/
topmark strip --include-file-types topmark:python src/
topmark strip --exclude-file-types topmark:markdown docs/
Path-based filters¶
--include,--excludeInclude or exclude glob patterns.--include-from,--exclude-fromLoad patterns from files (one per line).--files-fromProvide an explicit list of files to process.
--files-from contributes explicit processing inputs in the same way as positional paths. It may
therefore be used on its own or together with positional paths. By contrast, --include-from and
--exclude-from provide filtering rules only and do not contribute processing inputs by themselves.
See Filtering for CWD-resolution rules, missing vs unmatched input behavior, include/exclude precedence, and STDIN interactions.
Notes:
- Existing filesystem inputs are normalized to selected processing paths before runtime processing.
- Symlink spellings are not preserved for runtime identity or machine-readable
result.pathfields. - Hard-linked selected paths are handled as processing-target eligibility failures. Each affected path is reported independently and blocked from processing; TopMark does not select a preferred source, target, winner, or loser path.
--reportcontrols the scope of the human per-file report for TEXT and Markdown output. It does not affect pipeline execution, mutation behavior, summary aggregation, diff generation, machine-readable output, or exit-code selection. When--diffis requested, unified diffs are rendered as a separate human-output section after the per-file report. Diff visibility is determined solely by whether a diff was produced for a file and is independent of the selected report scope.
Values:
actionable: show files that are actionable for the selected command, failed, or otherwise require attention; hide unsupported entries from the per-file listing while summaries may still count them.noncompliant: show actionable entries plus unsupported entries.all: show every processed result, including unchanged/compliant entries.
Notes:
- Report filtering applies only to the human per-file report section.
- Unified diff output is rendered separately from the per-file report and is not filtered by
--report. - Machine-readable formats ignore
--report; JSON detail embeds per-result diff payloads and NDJSON detail emits adjacent standalonediffrecords when--diffis requested. - Machine-readable summary output suppresses per-file diff payloads even when
--diffis requested and emits a warning tostderr.
Example¶
# Use include/exclude files with relative patterns
printf "*.py\n" > inc.txt
printf "tests/*\n# ignored\n" > exc.txt
topmark strip --include-from inc.txt --exclude-from exc.txt --diff
Command-specific policy options¶
The strip command supports only shared runtime resolution and file-type-detection policy options.
See also: Policy guide.
Policy overrides passed to strip follow the same runtime resolution semantics as TOML
configuration and API overlays.
Shared policy¶
--allow-content-probe / --no-allow-content-probe
Controls whether file-type detection may inspect file contents when needed.
Header insertion and update policies (such as mutation mode, empty-file behavior, or
generated-header formatting) do not apply to strip and are rejected when provided.
Behavior details¶
- Removal policy: if a valid TopMark header is detected (policy-aware), remove the whole block. A
permissive fallback accepts legacy single-line-wrapped markers (e.g., HTML/XML
<!-- ... -->). - Newline/BOM preservation: preserved across removal. Reader normalizes in-memory; updater re-attaches BOM and keeps line endings.
- XML/HTML processors: keep the XML declaration as the first logical line; maintains a single intentional blank as needed.
- Markdown processor: ignores code fences for detection; header-like text inside fences is not removed.
- Processing-path identity: if a file is reached through a symlink, stripping operates on the resolved target TopMark reads and writes rather than the symlink spelling used to reach it.
- Hard-link safety: if multiple selected paths refer to the same filesystem object through hard
links,
stripblocks every affected path. No header removal is performed for those paths, and no source, target, winner, or loser path is selected.
Output behavior¶
Output format, TEXT verbosity, quiet mode, color output, and shared exit-code behavior are documented in shared options and exit codes.
Shared output controls¶
TEXT verbosity is separate from internal logging:
-v,--verboseincreases TEXT output detail forstrip, such as per-line diagnostics and additional hints.-q,--quietsuppresses TEXT rendering while preserving the command's exit status.- Markdown output is document-oriented and renders diagnostics and hints when present without
requiring
-v. - Machine-readable JSON and NDJSON output ignore TEXT-oriented verbosity and quiet controls.
Notes:
- Summary mode aggregates outcomes and suppresses per-file guidance lines.
- In TEXT rendering, per-line diagnostics are shown with
-vand above. - Primary/headline hint selection is presentation-level guidance and is not part of the stable CLI contract; rely on exit codes and machine-readable output for automation.
- The
--diffoption is supported by both human and machine-readable output. TEXT and Markdown render unified diffs for human review; JSON and NDJSON expose structured diff payloads in detail mode. With human output, unified diffs are written to STDOUT and report/guidance output is routed to STDERR. --applyand--diffare mutually exclusive because--diffreserves STDOUT for preview payloads while--applyperforms mutation.
Machine-readable output¶
Use --output-format json or --output-format ndjson to emit output suitable for tooling:
- JSON: a single machine-readable JSON document containing
meta, the effective runtime configuration snapshot,config_diagnostics, and then eitherresults(detail mode) orsummary(summary mode). - NDJSON: one machine-readable NDJSON record per line. Every record includes
kindandmeta, and the payload is stored under a container key that matcheskind.
For the canonical schema, stable kind values, and shared conventions, see:
Note
- Verbosity (
-v/--verbose) affects only TEXT rendering. - Quiet mode (
-q/--quiet) suppresses TEXT rendering for commands that support it. - Markdown and machine-readable output are not affected by TEXT verbosity controls.
Machine-readable output emits selected processing paths with POSIX / separators and resolved file
type identities using canonical qualified identity strings when available. If a stripped file is
reached through a symlink, per-file result.path describes the resolved processing target rather
than the symlink spelling. If selected paths are hard links to the same filesystem object, strip
emits one result per selected path and reports each affected path as a policy-blocked unsupported
processing target. Configuration payloads also emit normalized file type filters and
policy_by_type keys.
Notes:
- The
--diffoption is supported for machine-readable detail output. JSON embeds an optionaldiffobject under each affected result, while NDJSON emits an adjacent standalonekind="diff"record after the corresponding result record. - Machine-readable summary output omits per-file diff payloads even when
--diffis requested. TopMark emits a warning on STDERR to make that suppression explicit. - Summary mode aggregates outcomes and suppresses per-file guidance lines.
- The
configpayload in JSON and NDJSON is the resolved runtime configuration snapshot after per-source TOML validation, layered configuration merge, staged configuration-loading validation, and CLI override application. - Per-file
result.pathvalues are selected processing paths serialized with POSIX/separators on all platforms. This path serialization contract applies to processing result payloads; human TEXT output remains display-oriented.
JSON schema (detail mode)¶
When --summary is not set, topmark strip emits a single JSON object:
{
"meta": { /* MetaPayload */ },
"config": { /* RuntimeConfigPayload */ },
"config_diagnostics": { /* ConfigDiagnosticsPayload */ },
"results": [
{ /* per-file strip result payload */ }
]
}
The per-file result payload mirrors check but reflects the strip intent (e.g.
outcome.strip.* fields instead of outcome.check.*). When --diff is requested, changed results
may include an optional diff object with a diff_text field. See
Machine-readable output for the canonical schema.
When --diff is combined with machine-readable summary mode, per-file diff payloads are omitted and
TopMark emits a warning on STDERR.
JSON schema (summary mode)¶
In summary mode (--summary), results is omitted and replaced by a flat summary list of rows:
{
"meta": { /* MetaPayload */ },
"config": { /* RuntimeConfigPayload */ },
"config_diagnostics": { /* ConfigDiagnosticsPayload */ },
"summary": [
{ "outcome": "would strip", "reason": "header detected, ready for stripping", "count": 30 },
{ "outcome": "skipped", "reason": "known file type, headers not supported", "count": 1 }
]
}
NDJSON schema (detail vs summary)¶
NDJSON is a stream with a stable prefix followed by either per-file result records (detail mode)
or per-bucket summary records (summary mode):
- Prefix records:
kind="config"(effective runtime configuration snapshot)kind="config_diagnostics"(counts-only)- zero or more
kind="diagnostic"records (each withdomain="config"; these may originate from TOML-source, merged-config, or runtime applicability diagnostics) - Then:
- detail mode (no
--summary): onekind="result"record per file, optionally followed by an adjacentkind="diff"record when--diffis requested and a diff is available for that file - summary mode (
--summary): onekind="summary"record per(outcome, reason)bucket; per-fileresultanddiffrecords are omitted
Example (summary mode):
{"kind":"config","meta":{...},"config":{...}}
{"kind":"config_diagnostics","meta":{...},"config_diagnostics":{"diagnostic_counts":{"info":0,"warning":0,"error":0}}}
{"kind":"summary","meta":{...},"summary":{"outcome":"would strip","reason":"header detected, ready for stripping","count":30}}
Command-specific options¶
| Option | Description |
|---|---|
--apply |
Write changes to files (off by default; mutually exclusive with --diff). |
--diff |
Preview diffs; emits human unified diffs or machine diff payloads. |
--summary |
Show outcome counts instead of per-file details. |
-q, --quiet |
Suppress TEXT rendering while preserving the command's exit status. |
--files-from |
Read newline-delimited paths from file (use '-' for STDIN). |
- (PATH) |
Read one virtual file from STDIN content (requires --stdin-filename). |
--include |
Add paths by glob (can be used multiple times). |
--include-from |
File of patterns to include (one per line, # comments allowed). |
--exclude |
Exclude paths by glob (can be used multiple times). |
--exclude-from |
File of patterns to exclude. |
--include-file-types / -t |
Restrict to local or qualified TopMark file type identifiers. |
--exclude-file-types / -T |
Exclude local or qualified TopMark file type identifiers. |
--report |
Control reporting scope: actionable, noncompliant, or all. |
--allow-content-probe / --no-allow-content-probe |
Shared policy override for file-type detection. |
--strict / --no-strict |
Override effective configuration-loading validation strictness for this run. |
--stdin-filename |
Assumed filename when PATH is '-' (content from STDIN). |
Run
topmark strip -hfor the full list of options and help text.
Exit codes¶
topmark strip uses exit code WOULD_CHANGE (3) as a stable dry-run signal when removals would be
needed. Successful no-op runs and successful --apply runs exit with SUCCESS (0).
Common strip exit codes:
| Scenario | Exit code |
|---|---|
| Clean run / successful apply | SUCCESS (0) |
| Dry-run would remove headers | WOULD_CHANGE (3) |
| Missing explicit input path | FILE_NOT_FOUND (66) |
| Write/apply failure | IO_ERROR (74) |
| Permission failure | PERMISSION_DENIED (77) |
| Configuration error | CONFIG_ERROR (78) |
| Invalid CLI usage | USAGE_ERROR (64) |
Notes:
- Click parser-level usage errors (for example, unknown commands, unknown options, or invalid option
values) may exit with code
2before command logic runs. - Explicit missing literal paths are hard input errors and produce
FILE_NOT_FOUND (66). - Unmatched glob patterns are soft discovery diagnostics and do not fail
strip. - In mixed-result runs, hard input and filesystem errors take precedence over
WOULD_CHANGE (3).
See Exit codes for the complete CLI-wide exit-code contract.
Typical workflows¶
1) Remove headers from a project¶
2) Review a change set¶
3) CI: summarize and fail when removals are needed¶
4) Run with strict config checking¶
# Fail when staged configuration-loading validation warnings are present
# (for example TOML-source, merged-config, or runtime applicability warnings)
topmark strip --strict src/
Pre-commit integration¶
There is currently no dedicated topmark-strip pre-commit hook.
Use topmark strip --apply directly when you intentionally want to remove TopMark headers from a
selected set of files.
For general pre-commit integration guidance, CI workflows, and repository hook configuration, see Pre-commit integration.
Related commands¶
topmark check- add or update detected TopMark headers.topmark probe- explain file-type and processor resolution.topmark config check- validate the effective runtime configuration and report diagnostics.topmark config dump- inspect the effective runtime configuration, including normalized file type identifiers.
Related docs¶
- Command overview
- Configuration
- Filtering
- Policies
- Shared options
- Exit codes
- Header placement rules
- Machine-readable output
- Machine-readable format conventions
- Pre-commit integration
- Terminology and Canonical Vocabulary
Troubleshooting¶
- No files to process: Ensure you passed positional paths, or selected the correct STDIN mode
(
--files-from -for list mode, or-with--stdin-filenamefor content mode). Use-vvfor detailed TEXT rendering; use logging options for internal debug logs. - Patterns do not match: Remember that include/exclude patterns are relative to CWD.
cdinto the project root before running. - Symlink path not shown in output:
stripoperates on selected processing paths. If a symlink and its target resolve to the same file, machine-readable output reports the resolved processing target rather than the symlink spelling. - Hard-linked files are reported as unsupported:
stripblocks processing when multiple selected paths refer to the same filesystem object through hard links. Each affected path is reported independently; no preferred path is selected from the hard-link group. - File type filter does not match: use
topmark probeto inspect resolution decisions, and prefer qualified identifiers such astopmark:pythonwhen local identifiers may be ambiguous. - Missing file error: A literal path such as
fubar.pyis treated as an explicit input and fails withFILE_NOT_FOUND (66)when it does not exist. Use a glob pattern when an empty match set should be non-fatal. - "Header not detected": Header-like text inside code fences or strings is intentionally
ignored;
stripwon't remove it.