[{"slug":"ZV-2026-1961","server_name":"hydrata.com","severity":"breaking","title":"hydrata.com: Field result was removed from attach_input_layer output; consumers reading it will break.","summary":"[safe] Tool list_inputs was added. [safe] Tool list_time_series was added. [breaking] Field result was removed from attach_input_layer output; consumers reading it will break. [safe] Description of build_scenario changed (16% word delta). [breaking] Field result was removed from build_scenario output; consumers reading it will break. [breaking] Field result was removed from cancel_run output; consumers reading it will break. [safe] Description of create_project changed (22% word delta). [breaking] Field result was removed from create_project output; consumers reading it will break. [risky] Description of create_scenario changed (28% word delta). [breaking] Field result was removed from create_scenario output; consumers reading it will break. [breaking] Field result was removed from create_time_series output; consumers reading it will break. [breaking] Field result was removed from finalize_terrain_upload output; consumers reading it will break. [risky] Description of get_project changed (72% word delta). [breaking] Field result was removed from get_project output; consumers reading it will break. [risky] Description of get_run changed (42% word delta). [breaking] Field result was removed from get_run output; consumers reading it will break. [risky] Description of get_run_status changed (43% word delta). [breaking] Field result was removed from get_run_status output; consumers reading it will break. [risky] Description of get_scenario changed (61% word delta). [breaking] Field result was removed from get_scenario output; consumers reading it will break. [safe] Description of get_terrain changed (2% word delta). [breaking] Field result was removed from get_terrain output; consumers reading it will break. [breaking] Field result was removed from list_projects output; consumers reading it will break. [risky] Description of list_runs changed (37% word delta). [breaking] Field result was removed from list_runs output; consumers reading it will break. [breaking] Field resu","changes":[{"kind":"tool_added","tool":"list_inputs","detail":"Tool `list_inputs` was added.","severity":"safe"},{"kind":"tool_added","tool":"list_time_series","detail":"Tool `list_time_series` was added.","severity":"safe"},{"kind":"output_property_removed","path":"outputSchema.properties.result","tool":"attach_input_layer","before":{"type":"string"},"detail":"Field `result` was removed from `attach_input_layer` output; consumers reading it will break.","severity":"breaking"},{"kind":"description_changed","tool":"build_scenario","after":"Build a scenario's package (mesh + inputs) after showing what it will cost, and poll until built.\n\nOrder of operations, so the number is shown before anything is spent:\n\n1. GET the scenario detail. A record with no `boundary`/`computed_status`\n   keys is a non-member's read of a public project → refused: a build\n   needs the EDITOR role.\n2. Re-call checks on `latest_run` (a re-POST is NOT deduplicated after\n   `built`/`complete` — it would dispatch a duplicate build): no run →\n   proceed; run `created`/`building` → resume polling, no POST; run\n   `built`/`queued`/`computing`/`processing`/`complete` with\n   `latest_run_is_valid` not false → return that state, no POST unless\n   rebuild=true; run `error`/`cancelled`, or `latest_run_is_valid` false\n   (the scenario was edited since the build) → proceed.\n3. Spend gates, each a refusal with `outcome: \"refused\"` and no POST: the\n   scenario has no boundary or its boundary row has no features (the\n   server would admit the build and fail it in make_package); the\n   estimate is None (resolution is 0/unset); the estimate is above\n   100,000 triangles and confirm is not true — the refusal states the\n   number; re-call with confirm=true to proceed. An estimate of 0 over a\n   boundary WITH features is buildable and is reported, not refused.\n4. POST /projects/<id>/scenarios/<pk>/build/. Every 4xx comes back\n   verbatim as a normal result with `http_status`: 422 MESH_TOO_LARGE\n   (`error_code`, `estimate`, `ceiling`, `detail` — the server's hard\n   ceiling; coarsen `resolution` or shrink the boundary; no run was\n   created), 409 COMPUTE_TARGET_UNAVAILABLE, 400/403/404. A 409 WITHOUT\n   an error_code is the dedup body ({status, run_id, detail}: a build is\n   already in flight) — the tool resumes polling that run.\n5. On 202 poll the detail's `computed_status` (created → building →\n   built | error), bounded by timeout_seconds.\n\nReturns a COMPACT state, never the whole detail: `outcome` (built, error,\ncancelled, complete/queued/computing/processing for a run past the build,\ntimed_out, or refused), `computed_status`, `mesh_triangle_count_estimate`,\n`posted`, the POST's `build` body + `http_status` when one was made, and\nthe latest run's `run_id`, `run_status`, `error_message`, `user_message`,\n`mesh_triangle_count`. `timed_out` is normal (make_package re-downloads\nthe terrain from S3 every build; minutes): call again with the same\narguments — step 2 resumes polling the same run, it never POSTs twice —\nor cancel_run(run_id) if the run is stuck in `created` with no worker.\n`error` is terminal: `error_message` says why (fix the inputs, then call\nagain — an errored latest run is rebuilt).\n\nUnits: `resolution` — on the SCENARIO and on every MeshRegion FEATURE — is\na LENGTH in metres; ANUGA maximum_triangle_area = resolution²/2 (FloatField\ndefault 100, not nullable; 0 makes the estimate None), and the estimate\nprices both the same way (TASK-3186). The smallest value becomes the raster\ncell size. A MeshRegion feature must carry `resolution_units = m` (features\ndrawn in the map are marked automatically); an unmarked one makes the build\nanswer 422 MESH_REGION_UNITS_UNMARKED, naming the conversion an operator runs.","before":"Build a scenario's package (mesh + inputs) after showing what it will cost, and poll until built.\n\nOrder of operations, so the number is shown before anything is spent:\n\n1. GET the scenario detail. A record with no `boundary`/`computed_status`\n   keys is a non-member's read of a public project → refused: a build\n   needs the EDITOR role.\n2. Re-call checks on `latest_run` (a re-POST is NOT deduplicated after\n   `built`/`complete` — it would dispatch a duplicate build): no run →\n   proceed; run `created`/`building` → resume polling, no POST; run\n   `built`/`queued`/`computing`/`processing`/`complete` with\n   `latest_run_is_valid` not false → return that state, no POST unless\n   rebuild=true; run `error`/`cancelled`, or `latest_run_is_valid` false\n   (the scenario was edited since the build) → proceed.\n3. Spend gates, each a refusal with `outcome: \"refused\"` and no POST: the\n   scenario has no boundary or its boundary row has no features (the\n   server would admit the build and fail it in make_package); the\n   estimate is None (resolution is 0/unset); the estimate is above\n   100,000 triangles and confirm is not true — the refusal states the\n   number; re-call with confirm=true to proceed. An estimate of 0 over a\n   boundary WITH features is buildable and is reported, not refused.\n4. POST /projects/<id>/scenarios/<pk>/build/. Every 4xx comes back\n   verbatim as a normal result with `http_status`: 422 MESH_TOO_LARGE\n   (`error_code`, `estimate`, `ceiling`, `detail` — the server's hard\n   ceiling; coarsen `resolution` or shrink the boundary; no run was\n   created), 409 COMPUTE_TARGET_UNAVAILABLE, 400/403/404. A 409 WITHOUT\n   an error_code is the dedup body ({status, run_id, detail}: a build is\n   already in flight) — the tool resumes polling that run.\n5. On 202 poll the detail's `computed_status` (created → building →\n   built | error), bounded by timeout_seconds.\n\nReturns a COMPACT state, never the whole detail: `outcome` (built, error,\ncancelled, complete/queued/computing/processing for a run past the build,\ntimed_out, or refused), `computed_status`, `mesh_triangle_count_estimate`,\n`posted`, the POST's `build` body + `http_status` when one was made, and\nthe latest run's `run_id`, `run_status`, `error_message`, `user_message`,\n`mesh_triangle_count`. `timed_out` is normal (make_package re-downloads\nthe terrain from S3 every build; minutes): call again with the same\narguments — step 2 resumes polling the same run, it never POSTs twice —\nor cancel_run(run_id) if the run is stuck in `created` with no worker.\n`error` is terminal: `error_message` says why (fix the inputs, then call\nagain — an errored latest run is rebuilt).\n\nUnits: `resolution` on the SCENARIO is a LENGTH in metres — ANUGA\nmaximum_triangle_area = resolution²/2 (run_utils.py:227/:290; FloatField\ndefault 100, not nullable; 0 makes the estimate None) and the same value\nbecomes the raster cell size; a MeshRegion FEATURE's `resolution` is\nconsumed by the mesher as an AREA (max_triangle_area, m²) while the\nestimate prices it as a length, so attached regions mesh ~15x more than\nestimated (Towradgi 100/36/8 m² regions: estimate ~18k, mesh ~283k); the\nsmallest MeshRegion value becomes the raster cell size.","detail":"Description of `build_scenario` changed (16% word delta).","severity":"safe","descriptionDelta":0.15600000000000003},{"kind":"output_property_removed","path":"outputSchema.properties.result","tool":"build_scenario","before":{"type":"string"},"detail":"Field `result` was removed from `build_scenario` output; consumers reading it will break.","severity":"breaking"},{"kind":"output_property_removed","path":"outputSchema.properties.result","tool":"cancel_run","before":{"type":"string"},"detail":"Field `result` was removed from `cancel_run` output; consumers reading it will break.","severity":"breaking"},{"kind":"description_changed","tool":"create_project","after":"Create a new ANUGA project. Returns the project record including its id, base_map and ui_url.\n\nThe caller's own account becomes the owner. `projection` is the projected\nCRS every scenario in the project is meshed and run in — pick the UTM zone\ncovering the site. The project's map is created alongside it; `ui_url`\nopens it — give it to the user. Next step for a new project:\npresign_terrain_upload.","before":"Create a new ANUGA project. Returns the project record including its id.\n\nThe caller's own account becomes the owner. `projection` is the projected\nCRS every scenario in the project is meshed and run in — pick the UTM zone\ncovering the site. Next step for a new project: presign_terrain_upload.","detail":"Description of `create_project` changed (22% word delta).","severity":"safe","descriptionDelta":0.21739130434782605},{"kind":"output_property_removed","path":"outputSchema.properties.result","tool":"create_project","before":{"type":"string"},"detail":"Field `result` was removed from `create_project` output; consumers reading it will break.","severity":"breaking"},{"kind":"description_changed","tool":"create_scenario","after":"Create a DRAFT scenario (no build, no run) and report its mesh-triangle estimate.\n\nPOSTs /projects/<id>/scenarios/ with the write fields, then GETs the\nscenario detail — the create response carries NO estimate; the detail's\n`mesh_triangle_count_estimate` (+ `_breakdown`) does. Returns a compact\nrecord (the same fields get_scenario answers with): id, name, the FK ids\nas stored, resolution, duration, `computed_status` (`created` = no run\nyet), the estimate and its breakdown, the price (`compute_cost_estimate`\nin USD, `vcpu_hours_estimate`), `inflow_anchor_mismatch`, and\nhttp_status. Next step: build_scenario (which asks for\nconfirm=true above 100,000 triangles). Nothing is meshed or queued here.\n\nUnits: `resolution` — on the SCENARIO and on every MeshRegion FEATURE — is\na LENGTH in metres; ANUGA maximum_triangle_area = resolution²/2 (FloatField\ndefault 100, not nullable; 0 makes the estimate None), and the estimate\nprices both the same way (TASK-3186). The smallest value becomes the raster\ncell size. A MeshRegion feature must carry `resolution_units = m` (features\ndrawn in the map are marked automatically); an unmarked one makes the build\nanswer 422 MESH_REGION_UNITS_UNMARKED, naming the conversion an operator runs.\n\nThe server does NOT validate that the FK ids belong to `project_id` —\npass the row ids attach_input_layer / get_terrain returned for THIS\nproject. Every FK is nullable at create time, and the build fails later\non a scenario with no terrain, or with neither an inflow nor a rainfall.\nA `boundary` whose row has no features (the default 'Boundary 01' before\nattach_input_layer) is accepted here and refused by build_scenario. The\nestimate is None when resolution is 0; an estimate of 0 with a real\nboundary is a very coarse mesh, not an error.","before":"Create a DRAFT scenario (no build, no run) and report its mesh-triangle estimate.\n\nPOSTs /projects/<id>/scenarios/ with the write fields, then GETs the\nscenario detail — the create response carries NO estimate; the detail's\n`mesh_triangle_count_estimate` (+ `_breakdown`) does. Returns a compact\nrecord: id, name, the FK ids as stored, resolution, duration,\n`computed_status` (`created` = no run yet), the estimate and its\nbreakdown, and http_status. Next step: build_scenario (which asks for\nconfirm=true above 100,000 triangles). Nothing is meshed or queued here.\n\nUnits: `resolution` on the SCENARIO is a LENGTH in metres — ANUGA\nmaximum_triangle_area = resolution²/2 (run_utils.py:227/:290; FloatField\ndefault 100, not nullable; 0 makes the estimate None) and the same value\nbecomes the raster cell size; a MeshRegion FEATURE's `resolution` is\nconsumed by the mesher as an AREA (max_triangle_area, m²) while the\nestimate prices it as a length, so attached regions mesh ~15x more than\nestimated (Towradgi 100/36/8 m² regions: estimate ~18k, mesh ~283k); the\nsmallest MeshRegion value becomes the raster cell size.\n\nThe server does NOT validate that the FK ids belong to `project_id` —\npass the row ids attach_input_layer / get_terrain returned for THIS\nproject. Every FK is nullable at create time, and the build fails later\non a scenario with no terrain, or with neither an inflow nor a rainfall.\nA `boundary` whose row has no features (the default 'Boundary 01' before\nattach_input_layer) is accepted here and refused by build_scenario. The\nestimate is None when resolution is 0; an estimate of 0 with a real\nboundary is a very coarse mesh, not an error.","detail":"Description of `create_scenario` changed (28% word delta).","severity":"risky","descriptionDelta":0.2808988764044944},{"kind":"output_property_removed","path":"outputSchema.properties.result","tool":"create_scenario","before":{"type":"string"},"detail":"Field `result` was removed from `create_scenario` output; consumers reading it will break.","severity":"breaking"},{"kind":"output_property_removed","path":"outputSchema.properties.result","tool":"create_time_series","before":{"type":"string"},"detail":"Field `result` was removed from `create_time_series` output; consumers reading it will break.","severity":"breaking"},{"kind":"output_property_removed","path":"outputSchema.properties.result","tool":"finalize_terrain_upload","before":{"type":"string"},"detail":"Field `result` was removed from `finalize_terrain_upload` output; consumers reading it will break.","severity":"breaking"},{"kind":"description_changed","tool":"get_project","after":"Get one ANUGA project: id, name, projection, visibility, your role, its base map — and the link to it.\n\nReturns the project record (`id`, `name`, `projection` (EPSG code),\n`simple_view_config`, `visibility`, `owner_username`, `my_role`,\n`base_map`) plus `ui_url`: the link that opens the project's map, for the\nuser (`<site>/catalogue/#/map/<base_map>`; null while a new project's map\nis still being created). Scenarios are NOT listed here — use get_scenario\nwith a scenario id.","before":"Get details of a specific ANUGA project including its scenarios.\n\nReturns the project name, projection (EPSG code), base map ID,\nand configuration.","detail":"Description of `get_project` changed (72% word delta).","severity":"risky","descriptionDelta":0.7192982456140351},{"kind":"output_property_removed","path":"outputSchema.properties.result","tool":"get_project","before":{"type":"string"},"detail":"Field `result` was removed from `get_project` output; consumers reading it will break.","severity":"breaking"},{"kind":"description_changed","tool":"get_run","after":"Get full details of a simulation run including timing and results.\n\nReturns the complete run record: status, progress, timing (start/end\ntimestamps, duration), compute details (backend, instance type, cost),\nmesh info, error messages, and result log. Use get_run_status for\nlightweight polling; use this for final results.\n\nThe presigned `s3_*_url` download links are ELIDED — each is a 6-hour\ncapability and no tool relays one. The results stay viewable through the\n`gn_layer_*` entries (published WMS layers on the project's map).","before":"Get full details of a simulation run including timing and results.\n\nReturns the complete run record: status, progress, timing (start/end\ntimestamps, duration), compute details (backend, instance type, cost),\nmesh info, error messages, and result log. Use get_run_status for\nlightweight polling; use this for final results.","detail":"Description of `get_run` changed (42% word delta).","severity":"risky","descriptionDelta":0.417910447761194},{"kind":"output_property_removed","path":"outputSchema.properties.result","tool":"get_run","before":{"type":"string"},"detail":"Field `result` was removed from `get_run` output; consumers reading it will break.","severity":"breaking"},{"kind":"description_changed","tool":"get_run_status","after":"Lightweight status check for a simulation run (fast, <50ms).\n\nUse this for polling instead of get_run. Returns only: id, status,\n`phase`, progress_pct (0-100), eta_seconds, error_message, and\ncompute_backend.\n\n`phase` is never empty: it is `status`, except `preparing_inputs` while a\n`computing` run has no progress yet (it is downloading its input package\nand building the domain — minutes on a big model; this is NOT a stall).\nPoll every 5-10 seconds. Terminal states: complete, error, cancelled.","before":"Lightweight status check for a simulation run (fast, <50ms).\n\nUse this for polling instead of get_run. Returns only: id, status,\nprogress_pct (0-100), eta_seconds, error_message, and compute_backend.\n\nPoll every 5-10 seconds. Terminal states: complete, error, cancelled.","detail":"Description of `get_run_status` changed (43% word delta).","severity":"risky","descriptionDelta":0.42622950819672134},{"kind":"output_property_removed","path":"outputSchema.properties.result","tool":"get_run_status","before":{"type":"string"},"detail":"Field `result` was removed from `get_run_status` output; consumers reading it will break.","severity":"breaking"},{"kind":"description_changed","tool":"get_scenario","after":"Get a scenario's COMPACT state: its `computed_status`, inputs, estimate and price.\n\nReturns a compact record, never the raw ~50 KB detail: `scenario_id`,\n`computed_status`, `mesh_triangle_count_estimate` and its `_breakdown`,\n`latest_run_is_valid`, the latest run's `run_id`, `run_status`,\n`error_message`, `user_message`, `status_detail` and `mesh_triangle_count`\n— plus what the scenario IS and what it will cost: `name`, `description`,\n`project`, `resolution`, `duration`, the input row ids (`terrain`,\n`boundary`, `friction`, `inflow`, `rainfall`, `structure`, `mesh_region`),\n`compute_cost_estimate` (USD), `vcpu_hours_estimate`, and\n`inflow_anchor_mismatch` (null unless an inflow series starts after the\nmodel does, whose first value is then held backwards).\n\nThe `computed_status` field (there is NO `status` key on a scenario) is\nderived from the latest run and will be one of: created, building, built,\nqueued, computing, processing, complete, error, or cancelled — `created`\nalso means no run exists yet. A scenario must be `built` before it can be\nrun. `latest_run_is_valid` is false after any edit since the last build.\nA non-member reading a public project's scenario gets a reduced record:\nthe fields the server withholds (the input ids, the price,\n`inflow_anchor_mismatch`) are ABSENT here rather than reported as null —\n\"withheld\" is not \"no terrain, no cost\" — while the run-state keys,\n`computed_status` among them, read null.\n\nNo presigned S3 URL is returned by any read tool (each is a 6-hour\ncapability): results stay viewable through a run's `gn_layer_*` WMS\nentries — use get_run for the full run record.","before":"Get scenario details including its `computed_status` and latest run.\n\nThe `computed_status` field (there is NO `status` key on a scenario) is\nderived from the latest run and will be one of: created, building, built,\nqueued, computing, processing, complete, error, or cancelled — `created`\nalso means no run exists yet. A scenario must be `built` before it can be\nrun. The detail also carries `mesh_triangle_count_estimate` (+ its\n`_breakdown`) and `latest_run_is_valid` (false after any edit since the\nlast build). A non-member reading a public project's scenario gets a\nreduced record with no `computed_status`.","detail":"Description of `get_scenario` changed (61% word delta).","severity":"risky","descriptionDelta":0.607843137254902},{"kind":"output_property_removed","path":"outputSchema.properties.result","tool":"get_scenario","before":{"type":"string"},"detail":"Field `result` was removed from `get_scenario` output; consumers reading it will break.","severity":"breaking"},{"kind":"description_changed","tool":"get_terrain","after":"Poll a terrain's import until it is `ready` (or `error`), bounded by timeout_seconds.\n\nReturns `outcome` — exactly one of `ready`, `error`, `timed_out`, `not_found`\n(the project has no terrain yet; an unknown terrain_id is an API 404 error\ninstead) — plus the last `status` seen (creating → styling → ready | error)\nand `phase` (that status, or `not_found`; never empty),\n`polls`, `elapsed_seconds` and the full `terrain` record (its `gn_layer` is\nthe published elevation dataset pk once ready). An import takes minutes to\ntens of minutes (the SAME 32 MB 1 m DEM measured 4.5 min once and 26 min\nonce — the worker's S3 download speed dominates), so `timed_out` is normal\nand NOT a failure: keep calling with the same arguments while `status` is\nstill `creating`/`styling`; several calls in a row is expected. `error` is\nterminal — the import failed and no default input rows were seeded; upload\na corrected GeoTIFF as a new terrain.\n\n`ready` is written by the import task; the project's default input rows\n(Boundary 01, Friction 01, Inflow 01, Rainfall 01, Structure 01,\nMeshRegion 01, one GeoNode layer each) are seeded by the NEXT task in the\nchain and appear over the following ~30 s. Poll the input-layer list until\nit is non-empty before attaching your own layer to a default row.","before":"Poll a terrain's import until it is `ready` (or `error`), bounded by timeout_seconds.\n\nReturns `outcome` — exactly one of `ready`, `error`, `timed_out`, `not_found`\n(the project has no terrain yet; an unknown terrain_id is an API 404 error\ninstead) — plus the last `status` seen (creating → styling → ready | error),\n`polls`, `elapsed_seconds` and the full `terrain` record (its `gn_layer` is\nthe published elevation dataset pk once ready). An import takes minutes to\ntens of minutes (the SAME 32 MB 1 m DEM measured 4.5 min once and 26 min\nonce — the worker's S3 download speed dominates), so `timed_out` is normal\nand NOT a failure: keep calling with the same arguments while `status` is\nstill `creating`/`styling`; several calls in a row is expected. `error` is\nterminal — the import failed and no default input rows were seeded; upload\na corrected GeoTIFF as a new terrain.\n\n`ready` is written by the import task; the project's default input rows\n(Boundary 01, Friction 01, Inflow 01, Rainfall 01, Structure 01,\nMeshRegion 01, one GeoNode layer each) are seeded by the NEXT task in the\nchain and appear over the following ~30 s. Poll the input-layer list until\nit is non-empty before attaching your own layer to a default row.","detail":"Description of `get_terrain` changed (2% word delta).","severity":"safe","descriptionDelta":0.023809523809523836},{"kind":"output_property_removed","path":"outputSchema.properties.result","tool":"get_terrain","before":{"type":"string"},"detail":"Field `result` was removed from `get_terrain` output; consumers reading it will break.","severity":"breaking"},{"kind":"output_property_removed","path":"outputSchema.properties.result","tool":"list_projects","before":{"type":"string"},"detail":"Field `result` was removed from `list_projects` output; consumers reading it will break.","severity":"breaking"},{"kind":"description_changed","tool":"list_runs","after":"List all simulation runs across all scenarios in a project.\n\nReturns a paginated list of runs. Optionally filter by status\nto find active, completed, or failed runs. Each row's presigned\n`s3_*_url` download links are elided (6-hour capabilities).","before":"List all simulation runs across all scenarios in a project.\n\nReturns a paginated list of runs. Optionally filter by status\nto find active, completed, or failed runs.","detail":"Description of `list_runs` changed (37% word delta).","severity":"risky","descriptionDelta":0.37142857142857144},{"kind":"output_property_removed","path":"outputSchema.properties.result","tool":"list_runs","before":{"type":"string"},"detail":"Field `result` was removed from `list_runs` output; consumers reading it will break.","severity":"breaking"},{"kind":"output_property_removed","path":"outputSchema.properties.result","tool":"presign_terrain_upload","before":{"type":"string"},"detail":"Field `result` was removed from `presign_terrain_upload` output; consumers reading it will break.","severity":"breaking"},{"kind":"output_property_removed","path":"outputSchema.properties.result","tool":"retry_run","before":{"type":"string"},"detail":"Field `result` was removed from `retry_run` output; consumers reading it will break.","severity":"breaking"},{"kind":"description_changed","tool":"start_simulation","after":"Start a flood simulation run for a built scenario.\n\nThe scenario must be in 'built' status. Returns 202 with the new run.\nThe run transitions through: built → queued → computing → processing → complete.\n\nAfter starting, poll get_run_status to track progress. Returns 409\nif the scenario is not in the correct state. The returned run record has\nits presigned `s3_*_url` links elided (6-hour capabilities).","before":"Start a flood simulation run for a built scenario.\n\nThe scenario must be in 'built' status. Returns 202 with the new run.\nThe run transitions through: built → queued → computing → processing → complete.\n\nAfter starting, poll get_run_status to track progress. Returns 409\nif the scenario is not in the correct state.","detail":"Description of `start_simulation` changed (25% word delta).","severity":"risky","descriptionDelta":0.25},{"kind":"output_property_removed","path":"outputSchema.properties.result","tool":"start_simulation","before":{"type":"string"},"detail":"Field `result` was removed from `start_simulation` output; consumers reading it will break.","severity":"breaking"}],"published_at":"2026-10-08T10:11:13.856Z"}]