Conversation
Adds report-only Maintenance Review Queue parsing and rendering to the issue triage helper. Documents the official proposal and maintainer-facing usage while preserving no GitHub mutation, no runtime authority, no entity semantics changes, and no generated dashboard impact. Validation: python3 -m unittest 'tests 2/test_issue_triage.py'; python3 scripts/check_proposal_links.py; python3 -m unittest 'tests 2/test_proposal_links.py'; python3 scripts/check_version_governance.py; python3 -m py_compile scripts/issue_triage.py; git diff --check.
Preserve manifest version at 2.0.7 pending explicit beta adoption gate. Includes default-safe V2 dashboard updates, admin-gated pause/resume services, sanitized diagnostics/reporting, fail-closed tracked secret scanning, and targeted regression coverage.
Bump manifest to 2.0.8-beta.1 and extend the existing v205_release_check contract to cover the v2.0.8 beta/rc/stable line.
Match the generated V2 Stability Score badge outer frame to the passive Ready/Zone/AQ badge treatment while keeping the inner 2.1 gauge and 10 BPM shimmer unchanged. Validation: runtime card sanity, diff check, py_compile, version governance, and tracked secret scan.
This reverts commit 6e77d98.
Scope: update the GitHub Pages intro heading and environmental context copy only. Reason: make the public project page more human, current, and clear about why humidity stability matters without changing runtime behavior. Validation: git diff --check -- site/index.html; python3 -m unittest "tests 2/test_pages_site.py".
Sync main into develop before v2.0.8 release candidate
Prepare v2.0.8 release candidate
Scope: correct release-facing wording now that PR #76 has merged and develop is the v2.0.8 release-review source. Rationale: remove stale senyo888-patch-1-to-develop language before the later develop-to-main handoff. Validation: git diff --check; VERSION_GOVERNANCE_BRANCH=develop python3 scripts/check_version_governance.py; python3 scripts/check_proposal_links.py.
|
Thanks for opening your first Humidity Intelligence pull request. Contributions help improve the project, and your time here is appreciated. Humidity Intelligence values deterministic behaviour, runtime truthfulness, stability over time, and maintainable changes. Review will focus on preserving those principles as much as on the code itself. A strong PR usually:
Community discussion, proposal submissions, and constructive feedback are welcome, especially when a change touches runtime semantics, generated UI truth, diagnostics, or long-term project direction. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (7)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (6)
📝 WalkthroughWalkthroughThis PR ships v2.0.8: Setup Assist onboarding and telemetry flow changes, sanitized diagnostics and services output with admin-gated pause/resume, Stability Score dashboard cards replacing Pause tiles, an advisory maintenance queue for issue triage, and broad documentation and release-metadata updates. ChangesDocumentation, Governance, and Release Metadata
Setup Assist Onboarding Feature
Diagnostics and Services Sanitization
Dashboard Stability Score UI Update
Issue Triage Advisory Queue and Secret Scan Hardening
Estimated code review effort: 4 (Complex) | ~75 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant ConfigFlow
participant SetupAssist as helpers/setup_assist.py
participant HARegistries
User->>ConfigFlow: Add telemetry sensor
ConfigFlow->>SetupAssist: setup_assist_suggestion(hass, entity_id)
SetupAssist->>HARegistries: async_get(entity/area/device/label)
HARegistries-->>SetupAssist: metadata or failure
SetupAssist-->>ConfigFlow: SetupAssistSuggestion(room, level, labels, warnings)
ConfigFlow-->>User: Show advisory defaults (Save/Preview/Cancel)
User->>ConfigFlow: Save
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (7)
scripts/issue_triage.py (3)
1428-1456: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win
main()only catchesOSError, not theValueErrorraised by_resolve_report_path.If
--outputresolves outside the repo,_write_reportraisesValueError, which propagates uncaught out ofmain()(onlyOSErroris handled around the call), producing a raw traceback instead of the clean error path used for other write failures.♻️ Proposed fix
try: _write_report(output_path, report) - except OSError as exc: + except (OSError, ValueError) as exc: print(f"Could not write triage report: {exc}", file=sys.stderr) return 1🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/issue_triage.py` around lines 1428 - 1456, The report write path validation in _resolve_report_path can raise ValueError for paths outside the repository, but main() only handles OSError around _write_report. Update the error handling at the call site in main() so the same clean failure path is used for both OSError and ValueError, or normalize the exception type raised by _resolve_report_path/_write_report so invalid --output paths are reported without a raw traceback.
405-483: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winNo duplicate-id detection across queue files.
_action_from_datavalidatesidformat per-file butload_maintenance_action_queuenever checks for duplicateids across multiple files in the directory, so two files with the sameHI-MRQ-...id would both render as separate actions with no warning.♻️ Proposed fix
actions: list[MaintenanceAction] = [] warnings: list[str] = [] + seen_ids: set[str] = set() action_files = sorted({*queue_dir.glob("*.yaml"), *queue_dir.glob("*.yml")}) for path in action_files: try: data = _parse_simple_action_yaml(path.read_text(encoding="utf-8")) action, action_warnings = _action_from_data(path, data) except (OSError, ValueError) as exc: warnings.append(f"{path.name}: could not parse action file: {exc}") continue warnings.extend(action_warnings) - if action is not None: + if action is not None and action.id in seen_ids: + warnings.append(f"{path.name}: duplicate action id: {action.id}") + elif action is not None: + seen_ids.add(action.id) actions.append(action)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/issue_triage.py` around lines 405 - 483, Add cross-file duplicate ID detection to the maintenance queue loading flow: `_action_from_data` only validates the per-file `id` format, so extend `load_maintenance_action_queue` to track seen `MaintenanceAction.id` values while iterating files and emit a warning when the same `HI-MRQ-...` id appears more than once. Keep the existing `_action_from_data` validation as-is, but ensure duplicate IDs are rejected or warned before returning the final queue so only one action per id is accepted.
301-317: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueInline list parsing splits naively on
,and won't handle quoted values containing commas.
_parse_yaml_scalar's[...]branch doesinner.split(","), so a value like["a, b", "c"]would be incorrectly split into three items. Given this is a documented minimal YAML subset for maintainer-authored files, low risk, but worth a comment noting the limitation.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/issue_triage.py` around lines 301 - 317, The inline-list parsing in _parse_yaml_scalar currently splits on commas with inner.split(",") and cannot handle quoted items containing commas. Update the [..] branch to either implement proper tokenization for quoted list items or, if you keep the current minimal parser, add an explicit comment/documentation near _parse_yaml_scalar explaining that quoted commas are unsupported; reference _parse_yaml_scalar and its inline-list handling so the limitation is clear.diagnostics.py (2)
246-276: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueMinor DRY nit:
active_alert_resolutionis recomputed instead of reused fromdiagnostics_summary.
_runtime_summaryrecomputes_alert_resolution_summary(runtime_data.get("alert_telemetry", []))on Line 262 even though the identical value is already available atdiagnostics_summary["active_alert_resolution"](computed in_diagnostics_summary, Line 451) and is already reused forunavailable_or_unknown_entitiesa few lines below. Pulling fromdiagnostics_summaryhere would remove the duplicate computation.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@diagnostics.py` around lines 246 - 276, In _runtime_summary, active_alert_resolution is being recomputed from runtime_data instead of reusing the value already assembled in diagnostics_summary. Update the _runtime_summary return payload to read active_alert_resolution from diagnostics_summary["active_alert_resolution"] the same way unavailable_or_unknown_entities and warnings are reused, so the summary stays DRY and uses the existing _diagnostics_summary output.
578-583: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove the unused
_lane_outputshelper
_output_statesand_lane_output_summarynow cover this path, and_lane_outputsno longer has any callers. Dropping it keeps the module smaller and avoids dead helper drift.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@diagnostics.py` around lines 578 - 583, Remove the dead `_lane_outputs` helper from `diagnostics.py` since it has no remaining callers and is now superseded by `_output_states` and `_lane_output_summary`. Delete the `_lane_outputs` function definition and ensure any lingering references are updated or removed so the module only keeps the active output-summary path.services.py (1)
1000-1005: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueDuplicate of diagnostics.py's
_count_by.
_count_config_rowsis functionally identical todiagnostics.py's_count_by(same key-counting logic). Worth consolidating into a shared helper module alongside the zone-duplicate summarizers to avoid drift between the two counting implementations.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@services.py` around lines 1000 - 1005, The `_count_config_rows` helper duplicates the key-counting logic already implemented in `diagnostics.py`’s `_count_by`, so consolidate both into a shared helper used by `services.py` and the diagnostics code. Move the counting logic into the existing shared helper module alongside the zone-duplicate summarizers, then update `_count_config_rows` to delegate to that shared function instead of reimplementing the loop. Keep the external behavior the same, and use the existing `_count_by` symbol as the source of truth for this counting behavior.helpers/zone_validation.py (1)
34-43: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove the unused raw zone-duplicate formatter.
summarize_zone_mapping_duplicateshas no remaining call sites, so keeping it around only preserves a raw entity-ID string builder with no current use.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@helpers/zone_validation.py` around lines 34 - 43, summarize_zone_mapping_duplicates is unused and should be removed from helpers/zone_validation.py. Delete the function entirely and also remove any now-unused typing imports or related references so the module stays clean; if any callers exist elsewhere, update them to stop relying on this raw duplicate formatter and use the remaining zone validation flow instead.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@diagnostics.py`:
- Around line 597-609: The empty-state handling in _entity_status_summary is
inconsistent with _entity_status_bucket, causing blank state strings to be
counted as available instead of unknown. Update _entity_status_summary to treat
empty or whitespace-only state_text the same way as _entity_status_bucket does,
and apply the same normalization in _support_state_summary so the diagnostics
and support summaries classify entity states consistently.
In `@docs/runtime-simulation-validation.md`:
- Around line 4-6: The description in this section overstates the harness as
“production validation infrastructure,” which conflicts with its local/test-only
scope. Update the wording in the runtime-simulation validation text to use a
local-validation label or similarly narrow phrasing, and keep the surrounding
references to deterministic fake telemetry, V2.1 display fixtures, HA Lab
evidence, and live Home Assistant runtime validation clearly separated from this
local surface.
In `@scripts/issue_triage.py`:
- Around line 27-29: The triage report currently renders queue.source_dir
directly, which can leak local absolute paths even though _public_safety_issue
only checks parsed queue actions. Update the source_dir handling in
issue_triage.py so the value is normalized relative to REPO_ROOT or otherwise
sanitized before it is used in the report rendering path that builds the
“Source:” line. Make the fix in the queue/report flow around the queue object
and the rendering logic that references queue.source_dir, and ensure the
resulting output cannot contain a local absolute path.
In `@services.py`:
- Around line 911-927: _update `_support_state_summary` to treat an empty
`state.state` the same as `"unknown"` instead of counting it as available; the
current logic in `services.py` only checks for `"unknown"` and `"unavailable"`,
so add the empty-string case in the same branch. Since this duplicates
`diagnostics.py`’s `_entity_status_summary`, consider moving both summaries to a
shared helper (for example in `zone_validation.py`) and have
`_support_state_summary` call that shared function so the fix is centralized.
In `@tests` 2/test_issue_triage.py:
- Around line 250-258: The
`test_public_safety_rejects_cross_platform_local_paths` loop is not fully
wrapped by the `subTest` context because the `assertEqual` call sits outside it,
so move the assertion inside the `with self.subTest(local_path=local_path)`
block. This keeps each `local_path` case isolated and ensures failures are
reported per subtest while preserving the existing
`self.triage._public_safety_issue` check.
---
Nitpick comments:
In `@diagnostics.py`:
- Around line 246-276: In _runtime_summary, active_alert_resolution is being
recomputed from runtime_data instead of reusing the value already assembled in
diagnostics_summary. Update the _runtime_summary return payload to read
active_alert_resolution from diagnostics_summary["active_alert_resolution"] the
same way unavailable_or_unknown_entities and warnings are reused, so the summary
stays DRY and uses the existing _diagnostics_summary output.
- Around line 578-583: Remove the dead `_lane_outputs` helper from
`diagnostics.py` since it has no remaining callers and is now superseded by
`_output_states` and `_lane_output_summary`. Delete the `_lane_outputs` function
definition and ensure any lingering references are updated or removed so the
module only keeps the active output-summary path.
In `@helpers/zone_validation.py`:
- Around line 34-43: summarize_zone_mapping_duplicates is unused and should be
removed from helpers/zone_validation.py. Delete the function entirely and also
remove any now-unused typing imports or related references so the module stays
clean; if any callers exist elsewhere, update them to stop relying on this raw
duplicate formatter and use the remaining zone validation flow instead.
In `@scripts/issue_triage.py`:
- Around line 1428-1456: The report write path validation in
_resolve_report_path can raise ValueError for paths outside the repository, but
main() only handles OSError around _write_report. Update the error handling at
the call site in main() so the same clean failure path is used for both OSError
and ValueError, or normalize the exception type raised by
_resolve_report_path/_write_report so invalid --output paths are reported
without a raw traceback.
- Around line 405-483: Add cross-file duplicate ID detection to the maintenance
queue loading flow: `_action_from_data` only validates the per-file `id` format,
so extend `load_maintenance_action_queue` to track seen `MaintenanceAction.id`
values while iterating files and emit a warning when the same `HI-MRQ-...` id
appears more than once. Keep the existing `_action_from_data` validation as-is,
but ensure duplicate IDs are rejected or warned before returning the final queue
so only one action per id is accepted.
- Around line 301-317: The inline-list parsing in _parse_yaml_scalar currently
splits on commas with inner.split(",") and cannot handle quoted items containing
commas. Update the [..] branch to either implement proper tokenization for
quoted list items or, if you keep the current minimal parser, add an explicit
comment/documentation near _parse_yaml_scalar explaining that quoted commas are
unsupported; reference _parse_yaml_scalar and its inline-list handling so the
limitation is clear.
In `@services.py`:
- Around line 1000-1005: The `_count_config_rows` helper duplicates the
key-counting logic already implemented in `diagnostics.py`’s `_count_by`, so
consolidate both into a shared helper used by `services.py` and the diagnostics
code. Move the counting logic into the existing shared helper module alongside
the zone-duplicate summarizers, then update `_count_config_rows` to delegate to
that shared function instead of reimplementing the loop. Keep the external
behavior the same, and use the existing `_count_by` symbol as the source of
truth for this counting behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: b50f4869-53df-4a28-81cb-7700d48bdbe4
📒 Files selected for processing (36)
.github/pull_request_template.mdARCHITECTURE.mdCHANGELOG.mdCONTRIBUTING.mdREADME.mdconfig_flow.pyconst.pydiagnostics.pydocs/issue-triage.mddocs/proposals/2026-06-08-v207-degraded-alert-ui-truth-separation.mddocs/release-governance.mddocs/runtime-simulation-validation.mddocs/support.mdhelpers/setup_assist.pyhelpers/zone_validation.pylegacy/README.mdmanifest.jsonscripts/issue_triage.pyscripts/security/scan_secrets.shsensor.pyservices.pyservices.yamlstrings.jsontests 2/test_config_flow_sanity.pytests 2/test_diagnostics.pytests 2/test_issue_triage.pytests 2/test_runtime_card_sanity.pytests 2/test_setup_assist.pytests 2/test_workflows.pytranslations/en.jsonui-gallery/default-v2-mobile-aq/card.yamlui-gallery/default-v2-tablet-zone-2/card.yamlui/README.mdui/cards/v2_mobile.yamlui/cards/v2_tablet.yamlui/cards/view_cards_button.yaml
Scope: fix validated CodeRabbit actionable findings for diagnostics/support state summaries, advisory queue source redaction, runtime simulation wording, and issue-triage subTest isolation. Runtime impact: no lane ordering, entity semantics, output writer, service contract, or migration change; diagnostics/support summaries now classify blank HA states as unknown. Validation: python3 tests 2/test_diagnostics.py; python3 tests 2/test_issue_triage.py; python3 tests 2/test_runtime_card_sanity.py; git diff --check; python3 -m py_compile diagnostics.py services.py scripts/issue_triage.py; VERSION_GOVERNANCE_BRANCH=develop python3 scripts/check_version_governance.py; python3 scripts/check_proposal_links.py; scripts/security/scan_secrets.sh tracked.

Summary
Promotes Humidity Intelligence v2.0.8 release-candidate work from
developtowardmain, including Bella’s final release-state wording correction after PR #76 merged.Scope
Release-promotion PR covering the already-reviewed v2.0.8 candidate on
develop: setup guidance, generated dashboard hardening, diagnostics/support sanitization, setup-assist diagnostics, service-boundary hardening, UI Gallery/card updates, tests, and release documentation.Reason
developnow contains the v2.0.8 candidate and the stalesenyo888-patch-1 -> developrelease wording has been corrected. This PR prepares the stable release source formainreview without publishing a tag or GitHub Release.Files affected
config_flow.py,sensor.py,services.py,diagnostics.py,const.py,helpers/manifest.json,services.yaml,strings.json,translations/en.jsonREADME.md,CHANGELOG.md,ARCHITECTURE.md,docs/ui/cards/,ui-gallery/tests 2/,scripts/Runtime impact
Deterministic lane ordering is preserved. Entity semantics, output-writer boundaries, AQ priority, CO emergency priority, humidifier independence, and migration shape remain aligned with the existing backend contract.
Global all-entry pause/resume now requires admin context; scoped
entry_idcalls remain available.UI impact
Generated V2 dashboards are safer default status/review surfaces. Pause/resume and standalone View Cards workflows remain explicit service/admin paths. The passive Stability preview badge is display-only and does not create sensors, calculate scores, select lanes, or write outputs.
Generated cards and UI Gallery examples were updated.
Migration impact
No breaking migration.
Users should restart Home Assistant after updating package code, then refresh/re-export generated cards or update pasted Manual-card YAML if they use generated V2 card surfaces.
Rollback safety
Rollback is a normal revert to the previous stable release source. No hidden automation path, new output writer, or entity semantic migration is introduced.
Validation performed
develop; CI/checks were green.develop:016685fgit diff --checkpython3 -m py_compile config_flow.py sensor.py diagnostics.py services.py helpers/setup_assist.py helpers/zone_validation.py scripts/issue_triage.pypython3 -m compileall -q .bash -n scripts/security/scan_secrets.shscripts/security/scan_secrets.sh trackedVERSION_GOVERNANCE_BRANCH=develop python3 scripts/check_version_governance.pypython3 scripts/check_proposal_links.pypython3 -m unittest "tests 2/test_proposal_links.py"python3 "tests 2/test_diagnostics.py"python3 "tests 2/test_issue_triage.py"python3 "tests 2/test_workflows.py"python3 "tests 2/test_runtime_card_sanity.py"python3 "tests 2/test_config_flow_sanity.py"python3 "tests 2/test_setup_assist.py"ui/cards/, andui-gallery/HA Lab advisory evidence
Pass with notes.
Sanitized HA/export evidence showed
self_checkpassing,v205_release_checkpassing, generated-card entity availability passing with no missing or unknown/unavailable generated entities, diagnostics warnings empty, setup-assist diagnostics available, and diagnostics continuity stable apart from normal telemetry value drift.HA Lab evidence is advisory only. It does not replace Bella, Aetherwing, AetherCore, Aetherbite, maintainer approval,
mainpromotion review, tag approval, or GitHub Release approval.Type
Checks
main: this is adevelop->mainrelease-promotion PR.humidity_intelligence.refresh_uior refreshed dashboards where UI output changed. Not performed by Codex; users should refresh/re-export generated cards after update.updated,no-op, orblockedwhere public support/manual guidance is affected.not applicable.UI Gallery submissions
/ui-gallery/<card-id>/.README.md,preview.png, andcard.yamlordashboard.yaml.ui-gallery/README.mdis updated.ui-gallery/reference.txtformat.Summary by CodeRabbit