diff --git a/agents/energy-modeler.md b/agents/energy-modeler.md index f467e97..096877b 100644 --- a/agents/energy-modeler.md +++ b/agents/energy-modeler.md @@ -7,11 +7,11 @@ maxTurns: 50 You are an expert building energy modeler with deep knowledge of: -- **EnergyPlus**: All object types, simulation parameters, output reporting, and best practices for versions 8.9 through 25.2 +- **EnergyPlus**: All object types, simulation parameters, output reporting, and best practices for versions 8.9 through the latest supported - **Building thermodynamics**: Heat transfer, thermal mass, solar gains, infiltration, ventilation - **HVAC system design**: Air-side systems (VAV, CAV, DOAS), water-side systems (chillers, boilers, heat pumps), controls, and sizing - **ASHRAE standards**: 90.1 (energy), 62.1 (ventilation), 55 (thermal comfort), 189.1 (high-performance) -- **idfkit tooling**: All 40 MCP tools and 11 resources for schema exploration, model editing, validation, integrity checks, simulation, peak load analysis, weather data, and interactive viewers (geometry, schedules, reports) +- **idfkit tooling**: The full idfkit MCP toolset and `idfkit://…` resources for schema exploration, model editing, validation, integrity checks, simulation, peak load analysis, weather data, version migration, and interactive viewers (geometry, schedules, reports) — consult the live tool list for the authoritative set ## Working Principles diff --git a/commands/quick-sim.md b/commands/quick-sim.md index d15b655..e8872cd 100644 --- a/commands/quick-sim.md +++ b/commands/quick-sim.md @@ -12,13 +12,13 @@ Run a complete simulation workflow for: $ARGUMENTS 1. Load the model with `load_model` 2. Read the `idfkit://model/summary` resource for a brief overview 3. Validate with `validate_model` and `check_model_integrity` — report any issues but continue if non-critical -4. Check for weather data — if no weather file is configured, search for one based on the model's Site:Location -5. Run `run_simulation` with annual=true +4. Check for weather data — if no weather file is configured, `search_weather_stations` based on the model's Site:Location, then `download_weather_file` and pass its EPW path as `weather_file` (a search alone leaves the run with no weather) +5. Run `run_simulation` with `design_day=true, annual=true` (sizing + annual in one pass, so autosized equipment is sized before the annual run) 6. Read the `idfkit://simulation/results` resource and present: - Total energy consumption and intensity (kWh/m2) - Energy breakdown by end-use - Peak loads - - Unmet hours - - Any simulation errors or warnings + - Unmet hours (occupied, heating and cooling separately; ASHRAE 90.1 target ≤ 300 each) + - Any QA flags, simulation errors, or warnings 7. Use `view_simulation_report` to open the interactive report viewer for deeper exploration 8. Ask user if they want to fix any issues and re-run, or if they want to explore specific results in more detail diff --git a/scripts/check-deps.sh b/scripts/check-deps.sh index 794a5bb..9b11781 100755 --- a/scripts/check-deps.sh +++ b/scripts/check-deps.sh @@ -13,14 +13,7 @@ else issues+=("uvx is not installed. Install uv (https://docs.astral.sh/uv/getting-started/installation/) to use the idfkit MCP server and LSP.") fi -# 2. Check idfkit-mcp availability (don't actually install, just check) -if command -v uvx &>/dev/null; then - if uvx --help &>/dev/null 2>&1; then - info+=("idfkit-mcp: will be available via uvx") - fi -fi - -# 3. Look for EnergyPlus installation +# 2. Look for EnergyPlus installation ep_dir="" # Check user config first @@ -37,22 +30,16 @@ if [[ -z "$ep_dir" && -n "${ENERGYPLUS_DIR:-}" ]]; then fi fi -# Auto-detect on macOS -if [[ -z "$ep_dir" ]]; then - for d in /Applications/EnergyPlus-*/; do - if [[ -d "$d" ]]; then - ep_dir="$d" - fi - done -fi - -# Auto-detect on Linux +# Auto-detect (macOS + Linux standard locations). Glob expansion is lexical, so +# EnergyPlus-9.6.0 would sort after EnergyPlus-25.2.0 — pick the highest version +# explicitly with `sort -V`. if [[ -z "$ep_dir" ]]; then - for d in /usr/local/EnergyPlus-*/; do - if [[ -d "$d" ]]; then - ep_dir="$d" - fi - done + shopt -s nullglob + ep_candidates=(/Applications/EnergyPlus-*/ /usr/local/EnergyPlus-*/) + shopt -u nullglob + if (( ${#ep_candidates[@]} > 0 )); then + ep_dir=$(printf '%s\n' "${ep_candidates[@]}" | sort -V | tail -n1) + fi fi if [[ -n "$ep_dir" ]]; then diff --git a/scripts/inject-idf-context.sh b/scripts/inject-idf-context.sh index 92acd8b..6f462a2 100755 --- a/scripts/inject-idf-context.sh +++ b/scripts/inject-idf-context.sh @@ -1,33 +1,53 @@ #!/usr/bin/env bash -# inject-idf-context.sh — Add EnergyPlus context when working with relevant files +# inject-idf-context.sh — Add EnergyPlus context when working with relevant files. +# +# Wired as a PreToolUse hook (Read|Edit|Write). PreToolUse plain stdout is NOT shown to the +# model — context must be returned as JSON via hookSpecificOutput.additionalContext. # Read tool input from stdin input=$(cat) -# Extract file_path from the JSON -file_path=$(echo "$input" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"file_path"[[:space:]]*:[[:space:]]*"//' | sed 's/"$//') +# Extract the target file path. PreToolUse nests it under .tool_input.file_path; fall back to a +# top-level .file_path. Requires jq for robust parsing (handles spaces, quotes, escapes). +if command -v jq &>/dev/null; then + file_path=$(printf '%s' "$input" | jq -r '.tool_input.file_path // .file_path // empty' 2>/dev/null) +else + # Minimal fallback if jq is unavailable. + file_path=$(printf '%s' "$input" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"file_path"[[:space:]]*:[[:space:]]*"//; s/"$//') +fi if [[ -z "$file_path" ]]; then exit 0 fi -# Get the file extension -ext="${file_path##*.}" -ext_lower=$(echo "$ext" | tr '[:upper:]' '[:lower:]') +# Lowercase extension +ext_lower=$(printf '%s' "${file_path##*.}" | tr '[:upper:]' '[:lower:]') case "$ext_lower" in idf) - echo "[idfkit] This is an EnergyPlus Input Data File (.idf). For structured editing, use the idfkit MCP tools (load_model, get_object, update_object, add_object) rather than raw text manipulation. The MCP tools handle reference tracking and validation automatically." + context="This is an EnergyPlus Input Data File (.idf). For structured editing, use the idfkit MCP tools (load_model, list_objects, update_object, add_object) or read the idfkit://model/objects/{type}/{name} resource rather than raw text manipulation. The MCP tools handle reference tracking and validation automatically." ;; epjson) - echo "[idfkit] This is an EnergyPlus JSON input file (.epJSON). For structured editing, use the idfkit MCP tools (load_model, get_object, update_object) which handle schema validation and reference integrity." + context="This is an EnergyPlus JSON input file (.epJSON). For structured editing, use the idfkit MCP tools (load_model, list_objects, update_object) which handle schema validation and reference integrity." ;; epw) - echo "[idfkit] This is an EnergyPlus Weather file (.epw). Use search_weather_stations and download_weather_file MCP tools to find and manage weather data. EPW files should generally not be edited manually." + context="This is an EnergyPlus Weather file (.epw). Use search_weather_stations and download_weather_file MCP tools to find and manage weather data. EPW files should generally not be edited manually." ;; ddy) - echo "[idfkit] This is an EnergyPlus Design Day file (.ddy), typically paired with an EPW weather file. Design day data is used for HVAC sizing calculations." + context="This is an EnergyPlus Design Day file (.ddy), typically paired with an EPW weather file. Design day data drives HVAC autosizing; the design days must be injected into the model as SizingPeriod:DesignDay objects." + ;; + *) + exit 0 ;; esac +# Emit as PreToolUse additionalContext so the model actually sees it. +if command -v jq &>/dev/null; then + jq -n --arg ctx "[idfkit] $context" \ + '{hookSpecificOutput: {hookEventName: "PreToolUse", additionalContext: $ctx}}' +else + # Hand-rolled JSON fallback; context strings above contain no characters needing escaping. + printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":"[idfkit] %s"}}\n' "$context" +fi + exit 0 diff --git a/skills/developing-with-idfkit/SKILL.md b/skills/developing-with-idfkit/SKILL.md index 343f08a..55ff51f 100644 --- a/skills/developing-with-idfkit/SKILL.md +++ b/skills/developing-with-idfkit/SKILL.md @@ -32,9 +32,12 @@ here are about the library API, not the MCP tool surface. Run the discovery script with the user's project directory: ```bash -python /scripts/discover.py --project-dir +python ${CLAUDE_SKILL_DIR}/scripts/discover.py --project-dir ``` +Use the literal `${CLAUDE_SKILL_DIR}` token so the command matches the `allowed-tools` permission +pattern and runs without a prompt. + The script prints either: - **A path on stdout** (exit 0) — the bundled `SKILL.md`. Read it; it routes into @@ -43,7 +46,7 @@ The script prints either: - **An `ERROR:` block on stderr** (non-zero exit). Follow the printed instructions (install or upgrade idfkit, activate the right environment) and re-run. -`` is the directory containing this file; `` is the +`${CLAUDE_SKILL_DIR}` resolves to the directory containing this file; `` is the absolute path to the user's project. Passing `--project-dir` matters because the script resolves `.venv`, `../.venv`, `/.venv`, `Pipfile`, `poetry.lock`, `pdm.lock`, and `uv.lock` relative to it — so it inspects the user's project diff --git a/skills/idf-conventions/SKILL.md b/skills/idf-conventions/SKILL.md index 6225db2..195bfcc 100644 --- a/skills/idf-conventions/SKILL.md +++ b/skills/idf-conventions/SKILL.md @@ -9,24 +9,12 @@ paths: "**/*.idf, **/*.epJSON, **/*.epjson, **/*.py" ## idfkit MCP Tools & Resources -You have access to the idfkit MCP server with 40 tools and 11 resources across 10 categories: +This skill assumes the idfkit MCP server is available. Don't rely on a memorized tool count — consult +the **live tool list** and the server's own startup instructions for the authoritative set. The tools +span schema introspection, model read/write, validation + integrity, simulation + analysis, weather, +documentation, and version migration. -### Tools - -**Schema** (4): `list_object_types`, `describe_object_type`, `search_schema`, `get_available_references` -**Read** (5): `load_model`, `list_objects`, `search_objects`, `convert_osm_to_idf`, `get_change_log` -**Write** (9): `new_model`, `add_object`, `batch_add_objects`, `update_object`, `remove_object`, `rename_object`, `duplicate_object`, `save_model`, `clear_session` -**Validation** (2): `validate_model` (includes reference checking via `check_references` parameter), `check_model_integrity` -**Simulation** (8): `run_simulation`, `list_output_variables`, `query_timeseries`, `query_simulation_table`, `list_simulation_reports`, `view_simulation_report`, `export_timeseries`, `analyze_peak_loads` -**Weather** (2): `search_weather_stations`, `download_weather_file` -**Documentation** (2): `search_docs`, `get_doc_section` -**Zone** (1): `get_zone_properties` -**Geometry** (1): `view_geometry` -**Schedules** (1): `view_schedules` - -### Resources - -Read these via MCP resource URIs for structured data: +Structured state is exposed as read-only `idfkit://…` resources you can read at any time, including: - `idfkit://model/summary` — version, zones, object counts, and groups for the loaded model - `idfkit://model/objects/{object_type}/{name}` — all field values for a specific object @@ -36,6 +24,9 @@ Read these via MCP resource URIs for structured data: - `idfkit://simulation/results` — energy metrics, errors, and tables from the last simulation - `idfkit://simulation/peak-loads` — peak heating/cooling load decomposition with QA flags - `idfkit://simulation/report` — full tabular simulation report organized by section and table +- `idfkit://migration/report` — per-step transition output and structural diff after `migrate_model` + +The server may expose more — treat its live instructions as authoritative rather than this list. ## Key Conventions @@ -47,7 +38,7 @@ Read these via MCP resource URIs for structured data: ### Field Names - idfkit uses snake_case Python field names: `direction_of_relative_north`, `ceiling_height` - The MCP tools accept these snake_case names in the `fields` parameter -- Extensible fields use numbered patterns: `vertex_1_x_coordinate`, `vertex_2_x_coordinate`, etc. +- Extensible groups use a structured array under a wrapper key — e.g. `BuildingSurface:Detailed` takes `vertices: [{vertex_x_coordinate, vertex_y_coordinate, vertex_z_coordinate}, …]`. (Flat numbered keys like `vertex_1_x_coordinate` are a deprecated compat shim that emits warnings — don't use them.) Check `describe_object_type`'s `extensible_group` for the exact key and item fields. ### Workflow Best Practices 1. **Always call `describe_object_type` before creating objects** — know valid fields, constraints, and defaults @@ -60,9 +51,9 @@ Read these via MCP resource URIs for structured data: 8. **Read resources for object data** — use `idfkit://model/objects/{type}/{name}` to inspect objects and `idfkit://model/references/{name}` to check references ### Version Support -- Supported EnergyPlus versions: 8.9.0 through 25.2.0 (16 versions) -- Default version for new models: latest (25.2.0) -- Schemas are bundled — no EnergyPlus installation needed for editing, only for simulation +- Supported EnergyPlus versions: 8.9.0 through the latest supported (currently 26.1.0); idfkit exposes the newest as `LATEST_VERSION` +- Default version for new models: the latest supported version +- Schemas are bundled — no EnergyPlus installation needed for editing or schema validation; only simulation and version migration require an EnergyPlus install ### Common Object Categories - **Simulation Parameters**: SimulationControl, Timestep, RunPeriod, Building diff --git a/skills/new-model/SKILL.md b/skills/new-model/SKILL.md index 2fa77a6..77969cf 100644 --- a/skills/new-model/SKILL.md +++ b/skills/new-model/SKILL.md @@ -19,20 +19,28 @@ Create a new building energy model based on: $ARGUMENTS 2. **Weather data** — Use `search_weather_stations` to find the closest weather station, then `download_weather_file` to get EPW + DDY files -3. **Create model** — Use `new_model` (defaults to latest EnergyPlus version). This seeds Version, Building, SimulationControl, and GlobalGeometryRules automatically. +3. **Create model** — Use `new_model` (defaults to the latest EnergyPlus version). This seeds **only** + Version, Building, SimulationControl, and GlobalGeometryRules. You must still add Timestep, + RunPeriod, and Site:Location yourself (see below) — `check_model_integrity` requires Timestep and + RunPeriod, and Site:Location is needed for solar geometry but is *not* caught by either QA gate. 4. **Build the model** using `batch_add_objects` for efficiency. Add in this order: - - **Schedules**: ScheduleTypeLimits and Schedule:Compact for occupancy, lighting, equipment, HVAC + - **Site & controls**: Site:Location (site lat/long/elevation/time zone), Timestep, RunPeriod + - **Schedules**: ScheduleTypeLimits and Schedule:Compact for occupancy, lighting, equipment, HVAC (every schedule needs a referenced ScheduleTypeLimits) - **Materials and Constructions**: Wall/roof/floor materials and Construction objects - **Zones**: Thermal zones matching the building layout - - **Surfaces**: BuildingSurface:Detailed for walls, floors, roofs with proper vertices + - **Surfaces**: BuildingSurface:Detailed for walls, floors, roofs with proper vertices (use the structured `vertices` array) - **Fenestration**: FenestrationSurface:Detailed for windows/doors - **Internal loads**: People, Lights, ElectricEquipment per zone - - **HVAC**: Zone equipment, air loops, plant loops as needed + - **Infiltration**: ZoneInfiltration:DesignFlowRate per zone (a zero-infiltration model is not credible) + - **HVAC**: Zone equipment, air loops, plant loops as needed — plus ZoneControl:Thermostat + ThermostatSetpoint:DualSetpoint (without thermostats, zones are uncontrolled and unmet-hours are meaningless), and Sizing:Zone / Sizing:System whenever equipment is autosized + - **Sizing periods**: SizingPeriod:DesignDay. There is **no DDY auto-import** — read the downloaded `.ddy` file and hand-author the design-day objects (or copy their values), then ensure SimulationControl enables zone/system sizing - **Output**: Output:Variable and Output:Meter for key metrics - - **Sizing and RunPeriod**: SizingPeriod:DesignDay (from DDY), RunPeriod for annual -5. **Validate** — Run `validate_model` and fix any errors +5. **Validate** — Run `validate_model`, then `check_model_integrity`, and fix any errors. Schema + + integrity passing does **not** guarantee a successful run; for full confidence continue the QA loop: + `save_model` → `run_simulation` → read `idfkit://simulation/results` → fix → repeat until `qa_flags` + is empty. 6. **Save** — Use `save_model` to write the IDF/epJSON file diff --git a/skills/simulate/SKILL.md b/skills/simulate/SKILL.md index dcb62fc..73ddee7 100644 --- a/skills/simulate/SKILL.md +++ b/skills/simulate/SKILL.md @@ -19,30 +19,39 @@ Simulate the model: $ARGUMENTS - Check if the model has a Site:Location or weather file assigned - If not, ask for the building location and use `search_weather_stations` + `download_weather_file` -4. **Run simulation** — Use `run_simulation` with appropriate parameters: - - `weather_file`: path to EPW file - - `design_day`: true for sizing runs - - `annual`: true for full-year simulation +4. **Sizing readiness** — If any equipment is autosized (the common case), the model needs a sizing + run before/with the annual run, or capacities resolve to zero. Confirm `SizingPeriod:DesignDay` + objects exist and `SimulationControl` enables zone/system sizing. (`check_model_integrity` checks + that `SimulationControl` is *present*, not that its sizing flags are *on*.) + +5. **Run simulation** — Use `run_simulation` with appropriate parameters: + - `weather_file`: path to the EPW file + - `design_day`: true to run the sizing (design-day) periods + - `annual`: true for the full-year run + - For an autosized model, run `design_day=true, annual=true` together so sizing feeds the annual run + - `readvars`: true if you want standard ReadVars CSV output (`eplusout.csv`) - Report progress and any warnings during the run -5. **Analyze results** — Read the `idfkit://simulation/results` resource for the overview: +6. **Analyze results** — Read the `idfkit://simulation/results` resource for the overview: - **Energy consumption**: Total site/source energy, by end-use category - **Energy intensity**: kWh/m² (or kBtu/ft²) - **Peak loads**: Heating and cooling design loads - - **Unmet hours**: Hours where setpoints weren't met (target: < 300 heating + cooling) - - **Errors**: Any severe errors or warnings from the simulation + - **Unmet hours**: Occupied hours where setpoints weren't met — reported **separately** for heating + and cooling. ASHRAE 90.1 G3.1.2.3 targets **≤ 300 occupied unmet hours each** (not a heating + + cooling sum); for a baseline/proposed comparison the two models should also differ by ≤ 50 hours. + - **QA flags / errors**: resolve `qa_flags` and any severe errors or warnings from the simulation -6. **Peak load analysis** — Use `analyze_peak_loads` to decompose facility and zone peaks into components and flag QA issues. +7. **Peak load analysis** — Read the `idfkit://simulation/peak-loads` resource and use `analyze_peak_loads` to decompose facility and zone peaks into components and flag QA issues. (This requires the SensibleHeatGainSummary and HVACSizingSummary reports to be requested in the model.) -7. **Detailed analysis** — Use `query_timeseries` and `query_simulation_table` for specific metrics: +8. **Detailed analysis** — Use `query_timeseries` and `query_simulation_table` for specific metrics: - Monthly energy breakdown - Zone temperature profiles - System performance metrics - Use `list_output_variables` to see available time series data - Use `list_simulation_reports` to see available tabular reports -8. **Interactive review** — Use `view_simulation_report` to browse the full tabular report interactively. +9. **Interactive review** — Use `view_simulation_report` to browse the full tabular report interactively. -9. **Export if requested** — Use `export_timeseries` to save results to CSV +10. **Export if requested** — Use `export_timeseries` to save results to CSV Present results in a clear, organized format with the most important metrics highlighted. diff --git a/skills/upgrade-version/SKILL.md b/skills/upgrade-version/SKILL.md index 909ed78..6bcc412 100644 --- a/skills/upgrade-version/SKILL.md +++ b/skills/upgrade-version/SKILL.md @@ -1,6 +1,6 @@ --- name: upgrade-version -description: "Upgrade an EnergyPlus model from one version to another, handling object type changes and deprecated fields" +description: "Forward-migrate an EnergyPlus model to a newer version using the official IDFVersionUpdater transition toolchain (migrate_model). Forward-only." disable-model-invocation: true argument-hint: "[model-path] [target-version]" --- @@ -9,34 +9,50 @@ argument-hint: "[model-path] [target-version]" Upgrade: $ARGUMENTS -## Steps - -1. **Load current model** — Use `load_model` with the source file. Read the `idfkit://model/summary` resource to note the current version. - -2. **Identify target version** — If not specified, default to the latest supported version (25.2.0). Confirm with the user. - -3. **Research changes** — Use `search_docs` and `get_doc_section` to understand what changed between versions. Key areas: - - Renamed or removed object types - - New required fields - - Changed field names or semantics - - Deprecated features - -4. **Create target model** — Use `new_model` with the target version. +> Migration runs the official EnergyPlus **Transition** programs via `migrate_model`. +> It is **forward-only** (target must be >= current) and **requires EnergyPlus installed** +> — the transition binaries ship with it. Do **not** migrate by hand-copying objects into a +> `new_model`: field reorders/renames, split or merged object types, and changed defaults make a +> manual copy silently incorrect (it can still pass schema validation while being physically wrong). -5. **Migrate objects** — For each object type in the source model: - - Use `list_objects` to get all objects of that type - - Use `describe_object_type` on the target version to verify field compatibility - - Use `batch_add_objects` to add compatible objects - - Flag objects that need manual attention (changed schemas, removed types) - -6. **Validate** — Run `validate_model` on the new model and fix any version-specific issues. - -7. **Save** — Use `save_model` to write the upgraded model. - -8. **Report** — Summarize: - - Objects migrated successfully - - Objects that needed modification - - Any objects that could not be migrated (removed types) - - Recommendations for manual review +## Steps -**Supported versions**: 8.9.0, 9.0.1, 9.1.0, 9.2.0, 9.3.0, 9.4.0, 9.5.0, 9.6.0, 22.1.0, 22.2.0, 23.1.0, 23.2.0, 24.1.0, 24.2.0, 25.1.0, 25.2.0 +1. **Load** — Use `load_model` with the source file. Read the `idfkit://model/summary` resource and + note the current version. + +2. **Resolve target** — If `target_version` is not given, default to the latest supported version + (currently 26.1.0) and confirm with the user. `migrate_model` defaults to the installed + EnergyPlus version when `target_version` is omitted. + +3. **Preflight the direction** — Migration is forward-only: + - `target == current`: nothing to do — report and stop. + - `target < current`: **stop**. EnergyPlus Transition has no downgrade path; tell the user and exit. + - `target > current`: proceed. + +4. **Migrate** — Use `migrate_model(target_version=)`. This drives the full IDFVersionUpdater + transition chain (one binary per version step) and replaces the in-memory model on success. + - If it fails because EnergyPlus can't be found, instruct the user to install EnergyPlus or set + `$ENERGYPLUS_DIR` (or pass `energyplus_dir=`). Do **not** fall back to a manual object copy. + +5. **Read the migration report** — Read the `idfkit://migration/report` resource for the per-step + stdout/stderr, the transition audit, and the structural diff (object types added/removed, per-type + field changes). Surface any transition warnings to the user. + +6. **Validate** — Run `validate_model` then `check_model_integrity`. These confirm the migrated model + is well-formed (schema + domain QA). Note that passing them does **not** guarantee a successful + simulation — if EnergyPlus is available, a `run_simulation` smoke test is the definitive check. + +7. **Save** — `migrate_model` leaves `state.file_path` pointing at the original source, so a bare + `save_model` would overwrite it. Save to a new versioned path to preserve the source, e.g. + `save_model(file_path="_v.idf")`. + +8. **Report** — Summarize from authoritative sources, not guesswork: + - source and target versions, and the transition chain that ran (from the report), + - structural diff highlights from `idfkit://migration/report`, + - `validate_model` / `check_model_integrity` results, + - the saved path, + - any transition-emitted warnings that need manual review. + +**Supported range**: 8.9.0 through the latest supported version (currently 26.1.0). EnergyPlus +switched from SemVer to CalVer at 9.6.0 → 22.1.0, so there is no 10.x; the achievable range is +ultimately bounded by the transition binaries shipped with the installed EnergyPlus. diff --git a/skills/validate/SKILL.md b/skills/validate/SKILL.md index 92cf1b3..65c1682 100644 --- a/skills/validate/SKILL.md +++ b/skills/validate/SKILL.md @@ -14,11 +14,18 @@ Validate the currently loaded model. Optional filter: $ARGUMENTS 2. **Check model integrity** — Use `check_model_integrity` for domain-level QA: zones without surfaces, missing required controls, orphan schedules, boundary condition mismatches, fenestration host errors, and HVAC zone reference issues. -3. **Categorize issues** by severity and type: - - **Critical errors**: Missing required fields, invalid field types, unknown object types - - **Reference errors**: Dangling references, circular dependencies - - **Warnings**: Values outside recommended ranges, deprecated fields - - **Info**: Suggestions for improvement +3. **Categorize issues** using the real `ValidationResult` shape. It reports three severities — + **ERROR**, **WARNING**, **INFO** — and `error_count` / `warning_count` / `info_count`. Each item + carries a `severity`, `object_type`, `object_name`, `field`, `message`, and a stable `code`: + - `E001` — required field missing + - `E002` — invalid type + - `E003` — value out of range + - `E004` — unknown reference target (a dangling reference; reported as an ERROR, not a separate tier) + - `E010` — singleton constraint violated (more than one instance of a single-instance type) + - `W001` — schema unavailable (validator skipped) + + `check_model_integrity` items are tagged by `severity` (error/warning/info) and `category` + (geometry / controls / references / hvac / schedules). 4. **Suggest fixes** for each issue: - Missing references → suggest creating the missing object or updating the reference (use `get_available_references` to find valid values) @@ -28,6 +35,10 @@ Validate the currently loaded model. Optional filter: $ARGUMENTS 5. **Offer to auto-fix** simple issues: - Update fields with valid defaults using `update_object` - Create missing referenced objects using `add_object` - - Remove orphaned references + - To fix a renamed reference, prefer `rename_object` (it updates all referrers) over remove+re-add 6. **Re-validate** after fixes to confirm resolution + +7. **Note the limits** — Schema + integrity passing does **not** mean the model is simulation-ready. + For full confidence, `save_model` → `run_simulation` → read the `idfkit://simulation/results` + resource and resolve its `qa_flags`.