# Suppression Markers ๐Ÿšซ The unified `# noqa` / `# nocheck` syntax that suppresses individual checks across the infinito-nexus test suite. You MUST use these markers only when the check genuinely does not apply. You MUST NOT use them to silence legitimate issues. ## Grammar ๐Ÿ“ A suppression marker is a comment carrying one or more rule keys: ``` (noqa|nocheck): (, )* ``` `noqa` and `nocheck` are case-insensitive synonyms in the parser. Every project rule MUST use `nocheck:` because `# noqa: ` is also parsed by ruff as a flake8 directive and warns on non-flake8 keys. Reserve `noqa:` for real flake8 / ruff codes (`E402`, `F401`, โ€ฆ). [test_noqa_only_ruff_codes.py](../../../../tests/lint/filesystem/python/test_noqa_only_ruff_codes.py) hard-rejects `# noqa: ` whose codes do not match `[A-Z]+\d+`. `` is a kebab-case identifier from the catalog below. Multiple rules MAY be combined comma-separated. | Prefix | Use in | | ------------ | --------------------------------------- | | `#` | Python, YAML, shell, conf, INI, โ€ฆ | | `//` | JS, JSONC, โ€ฆ | | `{# โ€ฆ #}` | Jinja2 templates | | `` | HTML, Markdown | Implementation: [suppress.py](../../../../utils/annotations/suppress.py). ## Position semantics ๐Ÿ“ The placement rule is per check. The catalog "Position" column uses these labels. | Label | Meaning | | ----------------------- | ------------------------------------------------------------------------------------------------------------------ | | `same line` | Marker MUST be on the construct's line. | | `same line / span` | Marker MUST be on the construct's line or any physical line spanned by a multi-line call. | | `line above` | Marker MUST be on the immediately preceding non-empty line. Blank lines break the association. | | `same or above` | Either of the above is accepted. | | `comment block above` | Marker MAY sit on any line of a contiguous comment block above the construct. No blank line between marker and construct. | | `head (first 30 lines)` | Marker MAY appear anywhere in the first 30 lines of the file. For file-level opt-outs that stay visible at the top. | | `anywhere` | Marker MAY appear on any line of the file. For whole-file opt-outs. | ## Catalog ๐Ÿ“š | Rule | Position | Affected test | Effect | | --------------------------- | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `url` | same or above | [test_urls_reachable.py](../../../../tests/external/repository/test_urls_reachable.py) | Skips probing the literal HTTP(S) URL. Use for CDN roots and API base URLs that 4xx without a path. | | `docker-version` | same or above | [test_image_versions.py](../../../../tests/external/update/docker/test_image_versions.py), [test_semver_pinning.py](../../../../tests/lint/ansible/services/test_semver_pinning.py) | Skips both the live version-update warning and the non-semver-pin lint for that image's `version:` key. | | `repository-version` | same or above | [test_repository_versions.py](../../../../tests/external/update/repository/test_repository_versions.py), [test_semver_pinning.py](../../../../tests/lint/ansible/services/test_semver_pinning.py) | Skips both the live ref-update warning and the non-semver-pin lint for that entity's `ref:` key. | | `dockerfile-arg-default` | same or above | [test_arg_without_default.py](../../../../tests/lint/docker/dockerfile/test_arg_without_default.py) | Allows the marked `ARG` to carry a default. The caller normally supplies every build argument so a missing one fails the build instead of selecting a base image nobody chose. | | `direct-yaml` | same line / span | [test_no_direct_calls.py](../../../../tests/lint/repository/yaml/test_no_direct_calls.py) | Allows the marked `yaml.safe_load` / `safe_dump` call to bypass `utils.cache.yaml`. MUST use `nocheck:`, not `noqa:`. | | `curl-timeout` | same or above | [test_curl_via_filter.py](../../../../tests/lint/repository/test_curl_via_filter.py) | Allows a bare curl invocation without the `curl` filter or inline `--max-time`. | | `redundant-bool-ternary` | same line | [test_no_redundant_bool_patterns.py](../../../../tests/lint/filesystem/python/test_no_redundant_bool_patterns.py) | Allows the redundant `\| bool \| ternary('true','false')` pattern when a consumer requires the lowercase tokens. | | `redundant-bool-comparison` | same line | [test_no_redundant_bool_patterns.py](../../../../tests/lint/filesystem/python/test_no_redundant_bool_patterns.py) | Allows `... \| bool == True/False/true/false` when a real tri-state guard is intended (distinguishing `None` from `False`). | | `shared` | comment block above | [test_service_shared_consistency.py](../../../../tests/lint/ansible/services/test_service_shared_consistency.py) | Marks a service whose `enabled: true` does not require `shared: true`. | | `email` | line above | [test_email.py](../../../../tests/lint/ansible/roles/web-app/integration/test_email.py) | Suppresses the missing-email-integration warning. Pair with `enabled: false` and `shared: false`. | | `logout` | line above | [test_logout_dashboard.py](../../../../tests/lint/ansible/roles/web-app/integration/test_logout_dashboard.py) | Opts a `web-app-*` role out of the universal-logout integration. Marker MUST be directly above `logout:`. Pair with `enabled: false` and `shared: false`. | | `dashboard` | line above | [test_logout_dashboard.py](../../../../tests/lint/ansible/roles/web-app/integration/test_logout_dashboard.py) | Opts a `web-app-*` role out of the dashboard tile integration. Same shape as `logout`. | | `sso` | line above | [test_sso.py](../../../../tests/lint/ansible/roles/web-app/integration/test_sso.py) | Opts the role's unified `services.sso` block out. Declares "no login flow"; paired with `enabled: false` + `shared: false`. | | `file-size` | head (first 30 lines) | [test_python_file_size.py](../../../../tests/lint/repository/structure/test_python_file_size.py) | Opts the entire `.py` file out of the 500-line cap. | | `comments-valid` | head (first 30 lines) | [test_comments_valid.py](../../../../tests/lint/repository/test_comments_valid.py) | Opts the entire file out of the useful-comment check. Reserved for vendored / upstream config templates (e.g. Discourse `app.yml`) whose inline documentation is all intentional. | | `info-media` | head of `meta/main.yml` (first 30 lines) | [test_info_homepage_video.py](../../../../tests/lint/ansible/roles/meta/test_info_homepage_video.py) | Opts an invokable role out of the required `meta/info.yml` `homepage` + `video` entries. Marker lives in `meta/main.yml` (a comment-only `info.yml` would fail the info schema lint). Reserved for fully self-written roles (backups, host plumbing) that have no upstream product page or demo video. | | `project-walk` | same line / span | [test_no_raw_project_walk.py](../../../../tests/lint/filesystem/python/test_no_raw_project_walk.py) | Allows a raw `Path.rglob`, `os.walk`, or `glob.glob` call outside the `utils.cache.files.iter_project_files` contract. | | `cache-read` | same line / span | [test_no_uncached_file_reads.py](../../../../tests/lint/filesystem/python/test_no_uncached_file_reads.py) | Allows a raw `Path.read_text` / `Path.read_bytes` call in `tests/lint/` outside the LRU-cached `utils.cache.files.read_text` contract. | | `lookup-cache-import` | same or above | [test_no_cache_imports_in_lookups.py](../../../../tests/lint/filesystem/python/test_no_cache_imports_in_lookups.py) | Allows a lookup plugin (`plugins/lookup/` or `roles/*/lookup_plugins/`) to import a config-merge function from `utils.cache.applications` / `.domains` / `.users` instead of reaching the SPOT via `lookup_loader.get('applications'/'config'/'domains'/'users')`. Reserved for the SPOT providers (`applications` / `config` / `applications_current_play` / `users` / `domains`) and the raw-volume accessors (`volume` / `nginx`). | | `run-once` | anywhere | [test_run_once_tags.py](../../../../tests/lint/ansible/modules/test_run_once_tags.py), [test_schema.py](../../../../tests/integration/roles/run_once/test_schema.py) | Marks a role's `tasks/main.yml` as intentionally re-runnable. Skips both the run-once tag check and the suffix check. | | `run-once-suffix` | same line | [test_schema.py](../../../../tests/integration/roles/run_once/test_schema.py) | Allows a single `when:` item to reference a `run_once_` flag whose suffix differs from the current role. | | `raw-docker` | same or above; head (first 30 lines) | [test_no_raw_docker.py](../../../../tests/integration/infrastructure/docker/test_no_raw_docker.py) | Marks a single line or a whole file under `roles/` as legitimately calling `docker` / `docker compose` / `docker-compose` directly. | | `hardcoded-dns-resolver` | same or above | [test_no_hardcoded_dns_resolvers.py](../../../../tests/lint/repository/network/test_no_hardcoded_dns_resolvers.py) | Marks a line that needs a literal IP from `NETWORK_PUBLIC_DNS_RESOLVERS` where the substitution point cannot consume the variable (CoreDNS non-Jinja templates, host-bootstrap shell, doc examples). | | `dynamic-flag` | same line OR comment block above key | [test_dynamic_flags.py](../../../../tests/integration/roles/meta/services/test_dynamic_flags.py) | Marks a `roles/*/meta/services.yml` flag whose value stays literal. Per-flag (same line) for databases. Block-level (comment block above) when both flags stay literal. | | `native-metrics` | comment block above | [test_native_metrics_contract.py](../../../../tests/integration/roles/meta/services/prometheus/test_native_metrics_contract.py) | Marks a role whose `services.prometheus.native_metrics.enabled` and `templates/prometheus.yml.j2` presence are intentionally inconsistent. Reserved for prepared-but-default-off scrape fragments (operator opt-in). | | `prometheus-scrape` | same or above | [test_roles_with_service.py](../../../../tests/unit/python/plugins/lookup/test_roles_with_service.py) | Documents a `services.prometheus.scrape: false` opt-out in `roles//meta/services.yml`. The role keeps `services.prometheus.{enabled,shared}: true` (so the role-wiring contract stays satisfied) but `roles_with_service('prometheus')` drops it from `PROMETHEUS_TARGET_ROLES_JSON`. Reserved for 301-redirect-only vhosts that never serve a request through lua-resty-prometheus, so they emit no `app=""` label and have no scrape target. The marker accompanies the `scrape:` data flag the lookup honors. | | `matomo-track` | same or above | [test_roles_with_service.py](../../../../tests/unit/python/plugins/lookup/test_roles_with_service.py) | Documents a `services.matomo.track: false` opt-out in `roles//meta/services.yml`. The role keeps `services.matomo.{enabled,shared}: true` (so the role-wiring contract stays satisfied) but `roles_with_service('matomo')` drops it from `MATOMO_TARGET_ROLES_JSON` and the matomo tracker e2e contract. Reserved for static-file (autoindex) and 301-redirect vhosts that carry no user-facing HTML page worth a `_paq` tracker. The marker accompanies the `track:` data flag the lookup honors. | | `variants-static-override` | same line | [test_variants_no_static_override.py](../../../../tests/integration/roles/meta/services/test_variants_no_static_override.py) | Allows a `roles/*/meta/variants.yml` leaf override of an attribute whose base value in `meta/services.yml` is a static literal. Place on the override line in `variants.yml`. Use only when the consumer chain is provably immune to the variant-merge propagation gap; the default is to make the base value dynamic via `"{{ '' in group_names }}"`. | | `variants-shared-false-once` | same or above | [test_variants_shared_false_once.py](../../../../tests/lint/ansible/services/test_variants_shared_false_once.py) | Exempts one `roles/*/meta/variants.yml` `services..shared: false` pin from the one-local-provider-variant limit for a service whose base `meta/services.yml` uses literal `enabled: true` and dynamic `shared`. Place on the extra `shared: false` line or service key line. Place above the service key in `meta/services.yml` to exempt the service. | | `variants-services-match` | same or above | [test_services_match.py](../../../../tests/integration/roles/meta/variants/test_services_match.py) | Allows a `roles/*/meta/variants.yml` `services.` entry to reference a service key that is NOT declared as a top-level entry in `meta/services.yml`. Reserved for resolver-only matrix hooks (typically on invokable infrastructure roles) whose variant entries pin the round's companion topology via service-key flags the resolver maps to provider roles, with no real consumer contract in the base meta. | | `variants-auth-isolation` | same or above | [test_auth_isolation.py](../../../../tests/integration/roles/meta/variants/test_auth_isolation.py) | Exempts an auth-isolated variant entry in `roles/*/meta/variants.yml` (one that enables exactly one of LDAP / OIDC / OAuth2) from the rule that every non-auth service-key in the role's variant union must be pinned to literal `false`. Place on the leading `- services:` line of the variant or on the line above. Use only when the broader closure is intentional. | | `lookup-config-path` | same or above | [config/](../../../../tests/integration/ansible/lookups/config/) | Skips a single `lookup('config', โ€ฆ)` call from path-validation passes. Use when the call resolves against runtime-only state, typically self-referential roles. | | `unused-var` | same or above | [test_role_and_group_vars_used.py](../../../../tests/lint/ansible/variables/test_role_and_group_vars_used.py) | Exempts a top-level key in `roles//{vars,defaults}/main.yml` or `group_vars/**/*.yml` from the "must be referenced" check. Use when the consumer is non-YAML/Jinja (Python plugins, external tools). | | `project-root-import` | same or above | [test_project_root_import.py](../../../../tests/lint/filesystem/python/test_project_root_import.py) | Permits a local `PROJECT_ROOT` / `parents[N]` / `os.pardir` chain. Reserved for `__main__.py` `sys.path` bootstrap and standalone scripts under `roles//files/`. The marker MUST carry an inline explanation. | | `domain-spot` | same or above | [test_domain_primary_spot.py](../../../../tests/lint/repository/network/test_domain_primary_spot.py) | Marks a line using a `.{{ DOMAIN_PRIMARY }}` host literal outside the meta SPOT. Reserved for legacy domain cleanups that the canonical SPOT cannot represent. | | `literal-protocol-lookup` | same or above | [test_literal_protocol_with_lookup.py](../../../../tests/lint/repository/yaml/test_literal_protocol_with_lookup.py) | Allows a hardcoded `http://` / `https://` literal next to a `lookup(...)` call. Reserved for genuinely fixed protocols (Docker-network upstreams, loopback URLs in CI fixtures). | | `self-path-reference` | same line | [test_no_self_path_reference.py](../../../../tests/lint/filesystem/python/test_no_self_path_reference.py) | Allows a file to contain its own relative path from the repo root as a string literal. Reserved for load-bearing self-references. Repo-root files are exempt without a marker. | | `role-file-spot` | same or above | [test_file_spot.py](../../../../tests/lint/ansible/roles/test_file_spot.py) | Allows a `.py` file to carry a literal role-file path instead of the matching `ROLE_FILE_*` constant from `utils.roles.mapping`. Reserved for tests asserting the constant's value, migration scripts, or doc strings. | | `playwright-service-flag` | comment block above | [test_env_services_match.py](../../../../tests/integration/roles/playwright/test_env_services_match.py) | Exempts a top-level service in `roles//meta/services.yml` from the "must be registered as `_SERVICE_ENABLED=` in `templates/playwright.env.j2`" check. | | `playwright-service-gate` | same or above | [test_spec_env_gates.py](../../../../tests/integration/roles/playwright/test_spec_env_gates.py) | Exempts a `_SERVICE_ENABLED=` line in `roles//templates/playwright.env.j2` from the "must be gated in `files/playwright/playwright.spec.js`" check. | | `pkgmgr-deprecated` | same or above | [test_pkgmgr_deprecated.py](../../../../tests/lint/repository/dependencies/test_pkgmgr_deprecated.py) | Suppresses the warn-only deprecation notice for `include_role` / `import_role` of `pkgmgr` / `pkgmgr-install`. The check emits a `DeprecationWarning` locally and a GitHub Actions `::warning` annotation in CI. Prefer `pip install ` or `pip install git+`. | | `deprecated-http-header` | same or above | [test_no_deprecated_http_security_headers.py](../../../../tests/lint/repository/network/test_no_deprecated_http_security_headers.py) | Exempts a deprecated `add_header` / `Header set/add` line for `X-Frame-Options` / `X-XSS-Protection` / `X-Download-Options` / `X-Permitted-Cross-Domain-Policies`. Prefer Content-Security-Policy via the role's `meta/server.yml` (`csp.flags` / `csp.whitelist`). | | `container-name` | same or above | [test_mode_incompatible_keys.py](../../../../tests/lint/ansible/jinja/test_mode_incompatible_keys.py) | Allows a raw `container_name:` key in a `roles/*/templates/**/*.j2` template. Default path: route through the generic `compose_only` lookup (`{{ lookup('compose_only', 'container_name', NAME) }}`) so swarm-mode replicas do not collide on the static name. | | `pull-policy-key` | same or above | [test_mode_incompatible_keys.py](../../../../tests/lint/ansible/jinja/test_mode_incompatible_keys.py) | Allows a raw `pull_policy:` key in a `roles/*/templates/**/*.j2` template. Default path: route through the generic `compose_only` lookup (`{{ lookup('compose_only', 'pull_policy', 'never') }}`) so swarm does not reject the compose-only extension with "Additional property pull_policy is not allowed". | | `restart-key` | same or above | [test_mode_incompatible_keys.py](../../../../tests/lint/ansible/jinja/test_mode_incompatible_keys.py) | Allows a raw `restart:` key in a `roles/*/templates/**/*.j2` template. Default path: route through the `compose_restart` lookup so swarm-mode does not silently drop the operator's `docker_restart_policy`. | | `compose-structure` | same or above; head (first 30 lines) | [test_compose_template_structure.py](../../../../tests/lint/ansible/jinja/test_compose_template_structure.py) | Exempts a `roles/*/templates/*compose.yml.j2` line, or the whole file (head marker), from the canonical compose skeleton: base-include header, `{{ service_name }}:` service keys each preceded by their `{% set service_name %}`, all per-service `{% set %}` knobs on two-space-indented dash-free lines above the key, `{% include %}` at four spaces inside the service body, and column-0 `compose_volumes` / `compose_networks` at the tail. The layout renders correctly because the `stack_host_template` action plugin sets `lstrip_blocks=True` for `compose.yml.j2`. Reserved for legitimate deviations that genuinely cannot follow the skeleton. | | `seaweedfs-required` | head (first 30 lines) | [test_database_requires_seaweedfs.py](../../../../tests/integration/roles/meta/services/test_database_requires_seaweedfs.py) | Exempts a database-backed `web-app-*` role from the requirement to declare a seaweedfs object-store service. Place in the head of `roles//meta/services.yml`. Use only when the application genuinely needs no object storage. | | `tor-contract` | anywhere in file | [test_tor_contract.py](../../../../tests/lint/ansible/roles/meta/test_tor_contract.py) | Exempts a domain-serving role (`web-`/`svc-db-` prefix or explicit `domains.canonical`) from the "must declare a `tor:` block in `meta/services.yml`" contract. Reserved for roles with no onion surface, e.g. pure redirect helpers. | | `templated-conditional` | same or above | [test_no_templated_conditionals.py](../../../../tests/lint/ansible/test_no_templated_conditionals.py) | Exempts a `when` / `failed_when` / `changed_when` / `until` value that legitimately carries `{{ }}` / `{% %}`. Reserved for genuine edge cases; the default path is a bare expression. Per-item render/apply data guards belong on a `condition:` data field (honored by the sys-svc-compose render helper and `LISTMONK_SETTINGS`), not `when:`. | | `container-address-quote` | same or above | [test_address_never_quoted.py](../../../../tests/lint/ansible/shell/container/test_address_never_quoted.py) | Allows `*_CONTAINER_ADDRESS \| quote` in a role task file. Reserved for sites that never see the swarm `$(...)` fragment (`DEPLOYMENT_MODE == 'compose'`-gated tasks, `compose_mode_force` roles) or consumers that re-evaluate the argument themselves. | | `container-exec-resolver` | same or above; `argv:` target item | [test_exec_uses_resolver.py](../../../../tests/lint/ansible/shell/container/test_exec_uses_resolver.py) | Allows a `container exec` / `container inspect` target that does not route through the `container_address` lookup. Reserved for a container ID already resolved at `delegate_to` runtime (`*_LOCAL_CID`), where the lookup would return a manager-only subshell, and for deliberate bare-name partner probes gated on compose co-location. | | `container-inspect-type` | same or above; `argv:` inspect item | [test_inspect_pins_type.py](../../../../tests/lint/ansible/shell/container/test_inspect_pins_type.py) | Allows an untyped `container inspect` under `roles/`. Default path: pin `--type container`, because a role's overlay network carries the same entity name as its main container, so an untyped inspect can resolve the network and report `map has no entry for key "State"`. Use the typed subcommand (`container volume inspect` etc.) when the target genuinely is not a container. | | `container-healthcheck-unused` | same or above the service key or its `healthcheck:` line | [test_container_healthcheck_declared_is_used.py](../../../../tests/lint/ansible/jinja/test_container_healthcheck_declared_is_used.py) | Allows a `services..healthcheck` that no `lookup('container_healthcheck', โ€ฆ)` call renders. Default path: add the lookup to the service block, because an unrendered declaration reads like the service is watched while the compose file carries no probe. Reserved for a call the static resolver cannot attribute โ€” mastodon renders every service through a macro whose `service_name` is a macro parameter. | | `image-healthcheck` | same or above the service key | [test_image_healthcheck_declared.py](../../../../tests/integration/roles/test_image_healthcheck_declared.py) | Allows a `roles/*/meta/services.yml` entry whose image ships no `HEALTHCHECK` to declare none either. Default path: add `healthcheck:` to the entry, because a container without a probe counts as healthy the moment its process starts โ€” which is how a service that came back empty passes a restore drill. Reserved for containers nothing can probe: a one-shot process that exits, or an image with neither a port nor a shell. | | `csp-unsafe` | same line | [test_csp_unsafe_requires_justification.py](../../../../tests/lint/ansible/roles/meta/test_csp_unsafe_requires_justification.py) | Documents an `unsafe-*: true` flag in `roles/*/meta/csp.yml`. MUST be paired with a `Reason:` on the same line naming what breaks without the relaxation. `unsafe-inline` re-admits the inline execution an XSS needs and `unsafe-eval` re-admits string-to-code, so the flag has to be verified against the running app, not copied from another role. | | `min-storage-headroom` | same line OR comment block above key | [test_min_storage_headroom.py](../../../../tests/external/update/docker/test_min_storage_headroom.py) | Allows a `roles/*/meta/services.yml` `min_storage` to exceed the measured compressed size of its own `image:`/`version:` by more than 1 GB. MUST be paired with a `Reason:` on the same comment line naming what occupies the space. Reserved for services whose data volume genuinely dominates the footprint; the default path is to lower the value, because an over-declared budget makes a host look too small and prunes a cache the deploy did not need to lose. | | `galaxy-git-parity` | same or above | [test_galaxy_entries_have_git_source.py](../../../../tests/lint/repository/dependencies/test_galaxy_entries_have_git_source.py) | Exempts a `requirements/requirements.galaxy.yml` collection from the requirement to also carry a `type: git` entry in `requirements/requirements.git.yml`. Reserved for collections that publish no usable git remote; without the git entry a `galaxy.ansible.com` outage fails `make install`, because the fallback in `scripts/install/ansible.sh` cannot resolve the collection either. | ## Tool-Native `noqa` Codes ๐Ÿงน Some Python files use Ruff-compatible uppercase `# noqa` codes. Ruff and related Python linters handle these, not [suppress.py](../../../../utils/annotations/suppress.py). They MAY appear when the local exception is intentional and clear from context. | Code | Tool meaning | Typical allowed use | | -------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | `BLE001` | Blind exception caught | Narrow command-wrapper boundaries that convert any underlying failure into a domain-specific error. | | `E402` | Module import not at top | Tests that MUST adjust `sys.path` or load fixtures before importing the module under test. | | `E731` | Lambda assigned to variable | Small test-local callbacks or path formatters where a named function would add noise. | | `F401` | Imported but unused | Re-export modules or import-probe tests where import success is the assertion. | | `SLF001` | Private member access | Test-only introspection of parser or object internals when the public surface does not expose the needed state. | ## Adding a new rule ๐Ÿ†• 1. Pick a kebab-case `` identifier. 2. Decide which position semantic from the list above fits the check. 3. Use `is_suppressed_at` / `is_suppressed_in_head` / `is_suppressed_anywhere` from [suppress.py](../../../../utils/annotations/suppress.py) in your test. Do NOT roll a new regex. 4. Add the rule to the catalog table on this page.