# Home Assistant OpenCode Rules You are working directly inside a live Home Assistant installation (`/homeassistant`). ## Critical Mandates & Approval Rules 1. **Read-Only by Default**: Only read files and query APIs when investigating. Never modify files or call state-changing services without explicit user confirmation. 2. **Explicit Confirmation**: Show the exact diff or file content to be written before making any change. Wait for user approval ("yes", "go ahead"). 3. **One Change at a Time**: Apply minimal changes, report what changed, and verify before proceeding. 4. **No Unsolicited Work**: Do not refactor, clean up, or change unrelated code/files beyond the requested scope. 5. **Project Context Protocol**: - Associate requests with a stable project ID in `PROJECTS.md` (e.g. `P013`). - Read `PROJECTS.md` before starting work. Record durable context under the project ID. - Never mark a project `Complete` unless the user explicitly confirms completion. Ask: "Should I close Pxxx?" ## Off-Limits & Restricted Paths Never read, write, or access: - `.storage/`, `.cloud/`, `deps/`, `tts/` - `home-assistant_v2.db*`, `home-assistant.log*` - `secrets.yaml` (never expose or log secret contents) Use MCP tools (`get_devices`, `get_areas`, `get_entity_details`, `get_history`) or CLI tools (`hab`) instead of accessing internal storage or database files. ## Configuration & Architecture Gotchas - **Directory Includes in `configuration.yaml`**: - `automation`: Uses `!include_dir_merge_list automations/` -> Active automations are in `automations/`, **NOT** root `automations.yaml` (which is legacy/inactive). - `script`: Uses `!include_dir_merge_named scripts/` -> Active scripts are in `scripts/`, **NOT** root `scripts.yaml`. - `group`: Uses `!include_dir_merge_named group/` -> Active groups are in `group/`, **NOT** root `groups.yaml`. - `packages`: Uses `!include_dir_named packages/`. - `template`: Uses `!include_dir_merge_list templates/`. - `sensor`: Uses `!include_dir_merge_list sensor/`. ## CLI & Tooling Reference ### Shell YAML Queries (`yq`) - **Always use `yq`** (mikefarah/Go version) for CLI YAML processing. PyYAML and Ruby YAML crash on HA tags (`!include`, `!secret`). - Example: `yq '.homeassistant.latitude' configuration.yaml` ### Home Assistant Admin (`hab` CLI) - Pre-authenticated CLI tool for managing HA via terminal (`hab --json`). - Common commands: - Entities & Devices: `hab entity list --domain light --json`, `hab device list --json` - Automations/Scripts: `hab automation list --json`, `hab script list --json` - Dashboards: `hab dashboard list --json`, `hab dashboard get --json` - Operations: `hab system health --json`, `hab backup create` ### Zigbee Toolkit (`zigporter` CLI) - Handles cascade renames across automations, scripts, scenes, and Lovelace dashboards. - Command: `zigporter rename-entity light.old light.new --apply` (Defaults to dry-run if `--apply` omitted). - Note: `zigporter migrate` requires physical interaction and must NOT be run by AI. ### Safe Configuration Writing (MCP) - Prefer `write_config_safe(file_path, content, dry_run=true)` to pre-validate before writing. - Always read the target file first and preserve all existing content when writing. ## Mandatory YAML Style Rules - **Indentation**: 2 spaces (no tabs). - **Strings**: Double quotes (`"..."`). Exceptions: entity IDs, action names, area IDs, device classes, modes. - **Booleans**: Lowercase `true`/`false` only. Never `on`/`off`/`yes`/`no` as YAML booleans. - **Lists & Maps**: Block style only. Never flow style `[1, 2]` or `{key: val}`. - **Action Targets**: Always use `target:` block (`target: entity_id: light.room`). Do not put `entity_id` inside `data:` or at root action level. - **Templates**: Use `states('sensor.x')` and `is_state(...)` helpers. Never use direct state object access (`states.sensor.x.state`).