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.
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.
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:.
Finds leftover git conflict markers (<<<<<<<, =======, >>>>>>>) in added lines β the classic result of a hastily resolved merge conflict that instantly breaks configs/code.
Cleanly resolve the conflict at that spot, remove the marker lines, push again.
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.
Remove the file from the PR + add it to .gitignore. If it contained real secrets: rotate them.
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.
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.
Measures the size of the PR (lines/files). Warns from +1000 lines or >30 files β XXL PRs are hard to review and error-prone.
If possible, split into smaller, thematically separate PRs.
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.
Fix the reported line β the message contains file:line:rule.
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.
The error text is in the report β fix exactly the reported spot.
Checks changed !include/!include_dir_* references: a new reference pointing to a file that doesn't exist makes HA start with a broken config.
Create the file or fix the reference.
Checks new !secret name references against secrets.yaml β a reference to an undefined secret breaks HA startup.
Add the secret to secrets.yaml (on the instance) or fix the name.
Finds duplicate automation ids and aliases. Duplicates silently overwrite each other β one of the automations is simply gone, with no error message.
Rename one of the two (keep id AND alias unique).
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.
Add from: "off" (or the actual previous state); replace device_id with the entity_id.
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.
ha_url + encrypted ha_token in the .codemole.yml β encrypt the token with the secrets tool in the browser, no server access needed.
Compiles every changed .py file (py_compile) β syntax errors surface immediately, before HA loads the integration.
Run/compile the file locally, fix the error.
Ruff lint on the changed Python files β style, unused imports, common bugs (e.g. blocking calls that belong in the async loop in HA).
Run ruff check --fix locally, fix the rest manually.
Checks each component's manifest.json for the HA-required fields (domain, name, version, documentation, issue_tracker, codeowners, requirements, iot_class) + valid JSON.
Add the missing fields β without version, HA won't load custom components at all.
Checks the hacs.json for the HACS listing (at least the name field). Without it, the integration is hard/impossible to install via HACS.
Put a hacs.json with {"name": "β¦"} in the repo root.
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.
Add the missing keys in the reported language (en.json is the reference).
Every changed .json must parse β one comma too many in strings.json otherwise breaks the whole integration.
Repair the JSON at the reported spot.
Triggers when files are deleted, emptied or shrink suspiciously (>80 % fewer lines) β protects against accidentally throwing away code during rebase/merge.
Check whether it was intentional; otherwise restore the file. Mark deliberate deletions via PR label/description.
The PR description needs the mandatory sections: problem, fix, before/after URL β otherwise the PR can't be followed in (customer) review.
Complete the description (use the template); the check runs again on the next push.
ESLint + Stylelint on the changed files with the EDS ruleset (e.g. imports with .js extension, no unused variables).
Run npx eslint <file> / npx stylelint locally and fix.
New i18n placeholders in the code must exist in the placeholder sheets (jumo.json β¦) β otherwise the page renders raw keys.
Add the keys to the sheet (or a project-wide exception in testing-rules.json).
Runs the Jest unit tests of the changed blocks (tests/unit/β¦). No test for a changed block β skip notice.
Fix failures; create tests for new logic blocks.
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.
Inspect the diff: intended change β update the baseline (npm run test:visual:update + commit); unintended β fix the CSS. Create a new spec: guide.
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.
git rebase origin/<base> (or merge the base) and push.
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).
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.
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.
Fix the error at the reported line (missing ;, bracket, etc.).
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).
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).
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.base_url (with {branch} placeholder) + pages in the .codemole.yml β example.
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.
Once before review/merge on performance-relevant PRs (CSS/JS/images/fonts). Scores fluctuate Β±2β3 points due to CDN. Details.