In swarm mode the container_address lookup returns a $(/usr/bin/resolve-container-id ...) fragment that must expand at exec time; piping it through Jinja quote hands docker the literal string and every exec fails with 'No such container' (broke all three snipe-it CI variants). Remove the quote at the seven snipe-it sites and the live matrix/openproject sites, convert openproject's argv exec to shell so the fragment can expand, split the matrix bridge restart per deployment mode with a manager gate, and mark the compose-only or eval-contract sites with nocheck. A new lint (container-address-quote) bans the pattern repo-wide. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
31 KiB
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:
<comment-prefix> (noqa|nocheck): <rule>(, <rule>)*
noqa and nocheck are case-insensitive synonyms in the parser. Every project rule MUST use nocheck: because # noqa: <code> 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 hard-rejects # noqa: <code> whose codes do not match [A-Z]+\d+.
<rule> 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.
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 | 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, 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, test_semver_pinning.py | Skips both the live ref-update warning and the non-semver-pin lint for that entity's ref: key. |
direct-yaml |
same line / span | 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 | Allows a bare curl invocation without the curl filter or inline --max-time. |
redundant-bool-ternary |
same line | 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 | 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 | Marks a service whose enabled: true does not require shared: true. |
email |
line above | test_email.py | Suppresses the missing-email-integration warning. Pair with enabled: false and shared: false. |
logout |
line above | 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 | Opts a web-app-* role out of the dashboard tile integration. Same shape as logout. |
sso |
line above | 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 | Opts the entire .py file out of the 500-line cap. |
comments-valid |
head (first 30 lines) | 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. |
project-walk |
same line / span | 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 | 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 | 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, 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 | Allows a single when: item to reference a run_once_<other> flag whose suffix differs from the current role. |
raw-docker |
same or above; head (first 30 lines) | 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 | 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 | 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 | 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 | Documents a services.prometheus.scrape: false opt-out in roles/<role>/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="<role>" 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 | Documents a services.matomo.track: false opt-out in roles/<role>/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 | 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 "{{ '<role>' in group_names }}". |
variants-shared-false-once |
same or above | test_variants_shared_false_once.py | Exempts one roles/*/meta/variants.yml services.<key>.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 | Allows a roles/*/meta/variants.yml services.<key> 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 | 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/ | 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 | Exempts a top-level key in roles/<role>/{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 | Permits a local PROJECT_ROOT / parents[N] / os.pardir chain. Reserved for __main__.py sys.path bootstrap and standalone scripts under roles/<role>/files/. The marker MUST carry an inline explanation. |
domain-spot |
same or above | test_domain_primary_spot.py | Marks a line using a <word>.{{ 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 | 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 | 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 | 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 | Exempts a top-level service in roles/<role>/meta/services.yml from the "must be registered as <NAME>_SERVICE_ENABLED= in templates/playwright.env.j2" check. |
playwright-service-gate |
same or above | test_spec_env_gates.py | Exempts a <NAME>_SERVICE_ENABLED= line in roles/<role>/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 | 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 <name> or pip install git+<repo>. |
deprecated-http-header |
same or above | 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 | 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 | 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 | 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 | 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 | Exempts a database-backed web-app-* role from the requirement to declare a seaweedfs object-store service. Place in the head of roles/<role>/meta/services.yml. Use only when the application genuinely needs no object storage. |
templated-conditional |
same or above | 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_container_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. |
Tool-Native noqa Codes 🧹
Some Python files use Ruff-compatible uppercase # noqa codes. Ruff and related Python linters handle these, not 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 🆕
- Pick a kebab-case
<rule>identifier. - Decide which position semantic from the list above fits the check.
- Use
is_suppressed_at/is_suppressed_in_head/is_suppressed_anywherefrom suppress.py in your test. Do NOT roll a new regex. - Add the rule to the catalog table on this page.