Check Reference

Every check from the PR report in detail β€” what is checked, what a finding looks like and what to do about it. The check names in the report link directly here.

Universal (run in every repo)

πŸ›‘οΈ secret-scan universal

Scans the added lines of the diff for plaintext credentials: passwords, API keys, tokens (incl. known prefixes like ghp_, sk-). Once pushed = compromised β€” even if the commit is removed later.

❌ secret-scan β€” 2 possible plaintext secrets
WHAT TO DO

Remove the secret from the code (e.g. !secret/ENV/secret store), and rotate the secret β€” it was public. False positive on example values? Exclude the path via ignore:.

πŸͺ’ conflict-markers universal

Finds leftover git conflict markers (<<<<<<<, =======, >>>>>>>) in added lines β€” the classic result of a hastily resolved merge conflict that instantly breaks configs/code.

❌ conflict-markers β€” conflict markers in automations.yaml:88
WHAT TO DO

Cleanly resolve the conflict at that spot, remove the marker lines, push again.

πŸ—‚οΈ sensitive-files universal

Warns when sensitive files end up in the PR: .env, private keys/certificates, databases, HA .storage files. Such files almost never belong in the repo.

⚠️ sensitive-files β€” .env in the diff β€” does this belong in the repo?
WHAT TO DO

Remove the file from the PR + add it to .gitignore. If it contained real secrets: rotate them.

πŸ” ai-review universal

An LLM (currently Claude) reads the entire diff against the actual project conventions and finds logic errors no linter can see β€” race conditions, restart traps, wrong modes, forgotten edge cases. Findings arrive as line-precise inline comments with reasoning + a fix suggestion.

⚠️ The state trigger on `to: 'off'` fires immediately on the first 'off'. Presence sensors however flicker frequently … Add a `for:` …
WHAT TO DO

Reply directly to the finding β€” the bot justifies itself or retracts (and then resolves the thread). Configurable via ai-review.focus / ai-review.severity in the .codemole.yml.

πŸ“Š diff-size

Measures the size of the PR (lines/files). Warns from +1000 lines or >30 files β€” XXL PRs are hard to review and error-prone.

⚠️ diff-size β€” Large diff: +1240/-80 in 34 files
WHAT TO DO

If possible, split into smaller, thematically separate PRs.

Profile ha-config (Home Assistant configuration)

πŸ“ yamllint

yamllint with HA-friendly rules β€” and only on the lines the PR changes. Cosmetic rules (line-length, on/off truthy, comment style) are off; real errors (parse errors, duplicate keys, trailing spaces) are on. Pre-existing legacy issues in the file don't count.

❌ yamllint β€” 2 new lint errors in changed lines
automations.yaml:34:5: [error] duplication of key "entity_id"
WHAT TO DO

Fix the reported line β€” the message contains file:line:rule.

βœ… ha-validate

Validates the complete HA configuration with a current HA Core (2026.x) β€” schema errors, unknown options, broken automations. Two-pass: base and branch are both checked, only new errors are reported; pre-existing environment errors (e.g. "Unknown device", missing system libs) don't count.

❌ ha-validate β€” 1 new validation error (hass 2026.7.1, 19 pre-existing base errors ignored):
ERROR:…automation:Automation 'X' could not be validated: Service kaputt_ohne_domain does not match format <domain>.<name>
WHAT TO DO

The error text is in the report β€” fix exactly the reported spot.

πŸ”— includes

Checks changed !include/!include_dir_* references: a new reference pointing to a file that doesn't exist makes HA start with a broken config.

❌ includes β€” Missing include files: packages/neu.yaml
WHAT TO DO

Create the file or fix the reference.

πŸ” secret-refs

Checks new !secret name references against secrets.yaml β€” a reference to an undefined secret breaks HA startup.

❌ secret-refs β€” !secret wifi_pw2 is not defined in secrets.yaml
WHAT TO DO

Add the secret to secrets.yaml (on the instance) or fix the name.

β™Š duplicate-ids

Finds duplicate automation ids and aliases. Duplicates silently overwrite each other β€” one of the automations is simply gone, with no error message.

❌ duplicate-ids β€” id "wled_treppe" assigned twice (automations.yaml:120, packages/light.yaml:44)
WHAT TO DO

Rename one of the two (keep id AND alias unique).

⏰ automation-safety

Catches two classic HA traps in changed lines: (1) state triggers with to: but without from: β€” they fire on HA restart, because entities jump from unavailable to their state (a bug that actually happened: sleep mode turned off across the whole house at night). (2) device_id: instead of entity_id: β€” doesn't survive a device replacement.

⚠️ automation-safety β€” automations.yaml:34 state trigger with `to:` without `from:` β€” fires on HA restart (unavailableβ†’on). Add `from:`.
WHAT TO DO

Add from: "off" (or the actual previous state); replace device_id with the entity_id.

πŸ†” entity-exists opt-in

Checks every entity_id referenced in new lines live against your HA instance (/api/states) β€” catches typos, the most common error class of all. Templates and !secret lines are skipped.

⚠️ entity-exists β€” 1 unknown entity:
automations.yaml:12 `binary_sensor.flur_obenn` does not exist in the HA instance
ENABLE

ha_url + encrypted ha_token in the .codemole.yml β€” encrypt the token with the secrets tool in the browser, no server access needed.

Profile ha-component (HA custom component)

🐍 python-syntax

Compiles every changed .py file (py_compile) β€” syntax errors surface immediately, before HA loads the integration.

❌ python-syntax β€” Syntax error in 1 Python file(s)
WHAT TO DO

Run/compile the file locally, fix the error.

🐍 ruff

Ruff lint on the changed Python files β€” style, unused imports, common bugs (e.g. blocking calls that belong in the async loop in HA).

⚠️ ruff β€” 3 finding(s): F401 unused import; E722 bare except …
WHAT TO DO

Run ruff check --fix locally, fix the rest manually.

πŸ“¦ manifest

Checks each component's manifest.json for the HA-required fields (domain, name, version, documentation, issue_tracker, codeowners, requirements, iot_class) + valid JSON.

❌ manifest β€” manifest.json missing: version iot_class
WHAT TO DO

Add the missing fields β€” without version, HA won't load custom components at all.

πŸ“¦ hacs

Checks the hacs.json for the HACS listing (at least the name field). Without it, the integration is hard/impossible to install via HACS.

⚠️ hacs β€” hacs.json missing (HACS listing problematic)
WHAT TO DO

Put a hacs.json with {"name": "…"} in the repo root.

🌐 translations

Ensures that translations/en.json exists (mandatory language) and that all other language files have the same keys β€” missing keys show up in the UI as raw placeholders.

⚠️ translations β€” Translations key mismatch: de(58 vs 62)
WHAT TO DO

Add the missing keys in the reported language (en.json is the reference).

🧾 json-valid

Every changed .json must parse β€” one comma too many in strings.json otherwise breaks the whole integration.

❌ json-valid β€” strings.json: invalid JSON (line 12)
WHAT TO DO

Repair the JSON at the reported spot.

Profile aem-eds (Adobe Edge Delivery / frontend)

πŸ›Ÿ file-guard

Triggers when files are deleted, emptied or shrink suspiciously (>80 % fewer lines) β€” protects against accidentally throwing away code during rebase/merge.

❌ File Guard β€” blocks/teaser/teaser.js: 240 β†’ 3 lines (βˆ’98 %)
WHAT TO DO

Check whether it was intentional; otherwise restore the file. Mark deliberate deletions via PR label/description.

πŸ“‹ pr-vollstΓ€ndigkeit

The PR description needs the mandatory sections: problem, fix, before/after URL β€” otherwise the PR can't be followed in (customer) review.

❌ PR completeness β€” Missing: problem section, before and after URL
WHAT TO DO

Complete the description (use the template); the check runs again on the next push.

🧹 js-lint / css-lint

ESLint + Stylelint on the changed files with the EDS ruleset (e.g. imports with .js extension, no unused variables).

❌ JS Lint β€” In patterns/patterns.js line 1181: Identifier 'telHref' has already been declared
WHAT TO DO

Run npx eslint <file> / npx stylelint locally and fix.

πŸ”€ placeholder-keys

New i18n placeholders in the code must exist in the placeholder sheets (jumo.json …) β€” otherwise the page renders raw keys.

❌ Placeholder keys β€” 2 keys without an entry: teaser.cta.label …
WHAT TO DO

Add the keys to the sheet (or a project-wide exception in testing-rules.json).

πŸ§ͺ unit-tests

Runs the Jest unit tests of the changed blocks (tests/unit/…). No test for a changed block β†’ skip notice.

βšͺ Unit Tests β€” ⏭️ no unit tests created for block(s) contact-overlay-role
WHAT TO DO

Fix failures; create tests for new logic blocks.

πŸ–ΌοΈ visual-tests

Visual regression per block: Playwright screenshots against committed baseline images. Atoms (button, text, image, link) automatically trigger the tests of all organisms that embed them via block-deps.json.

βœ… Visual Tests β€” 2 spec(s) matched [1 block default, 1 transitive consumers] (via contact-overlay-roleβ†’contact-person-portrait)
WHAT TO DO

Inspect the diff: intended change β†’ update the baseline (npm run test:visual:update + commit); unintended β†’ fix the CSS. Create a new spec: guide.

πŸ”„ merge-freshness

Measures how far the branch lags behind its base. >10 commits = warning, >30 = error β€” the older the state, the greater the conflict/regression risk at merge time.

❌ Merge Freshness β€” Branch is 48 commits behind wcms-2777-tokens (please rebase)
WHAT TO DO

git rebase origin/<base> (or merge the base) and push.

🧩 static-scans

Static EDS rules: no framework imports (React/Vue/jQuery), no outline: none (WCAG), JS bundle growth warning (>10 KB) and token compliance β€” hardcoded hex/rgba colors instead of var(--…) in new CSS lines (design token requirement).

⚠️ Static Scans β€” Hardcoded color instead of var(--…) in teaser.css: `color: #e30613;`
WHAT TO DO

Replace the color with the matching design token (token definitions themselves, --x: #abc;, are allowed). Project-wide opt-out: hardcoded-colors exception in testing-rules.json.

Profile wordpress (WordPress theme / plugin)

🐘 php-lint

Runs php -l on every changed .php file to catch syntax errors β€” before WordPress throws a fatal parse error. Reports file & line, also as an inline comment.

❌ php-lint β€” syntax errors in 1 of 2 PHP file(s)
WHAT TO DO

Fix the error at the reported line (missing ;, bracket, etc.).

🧹 phpcs WPCS

Checks the changed .php files with phpcs for security-relevant WPCS rules β€” output escaping, nonce verification, input sanitization/unslashing, prepared SQL. Two-pass: only new/changed lines β€” no style noise, no legacy debt. Issues posted inline (capped at 20).

⚠️ phpcs β€” WPCS-Security: 2 issue(s) on new lines in 1 file(s) β€” 2 flagged inline
WHAT TO DO

Fix the security gap: escape output (esc_html()/esc_attr()), sanitize input + wp_unslash(), verify nonces, use $wpdb->prepare() for SQL. Tune the sniff scope via env PHPCS_SNIFFS (empty = full WPCS).

Opt-in / on-demand (all profiles)

πŸ”Ž page-audit opt-in

Renders the configured pages on both base and branch preview and checks them with axe-core (WCAG 2.1 A/AA + best practice): contrast, button/form labels, landmarks, heading structure, alt texts. Only new findings are reported; timing (DCL/load/KB) is included for information.

πŸ”Ž Page-Audit β€” 2 new finding(s) compared to `main`:
**/de/de/** Β· DCL 126 ms Β· Load 127 ms Β· 6 KB
⚠️ `button-name` (critical): 3 element(s) β€” Buttons must have discernible text. e.g. `button[data-action="call"]`
ENABLE

page-audit.base_url (with {branch} placeholder) + pages in the .codemole.yml β€” example.

⚑ lighthouse on-demand

Full Lighthouse comparison (performance/a11y/best practices/SEO + LCP/CLS) between base and branch preview. Never runs automatically β€” only when you attach the lighthouse label to the PR (re-run: remove the label + set it again). Self-hosted, no Google API.

⚑ Lighthouse β€” βœ… no relevant regression compared to `main`
| /de/de/ | Perf 88 (+11) | A11y 87 | BP 96 (+21) | SEO 61 | LCP 3760 ms Β· CLS 0.004 |
BEST PRACTICE

Once before review/merge on performance-relevant PRs (CSS/JS/images/fonts). Scores fluctuate Β±2–3 points due to CDN. Details.