Skip to content

feat: add deterministic operating-point security validation - #86

Merged
qian-harvard merged 6 commits into
Power-Agent:mainfrom
BurhanAbdullah:feat/operating-point-validation-clean
Sep 24, 2026
Merged

qian-harvard merged 6 commits into
Power-Agent:mainfrom
BurhanAbdullah:feat/operating-point-validation-clean

Conversation

@BurhanAbdullah

@BurhanAbdullah BurhanAbdullah commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Adds a deterministic, solver-independent operating-point security validation layer for the pandapower MCP server.

Changes
Add operating_point.py for validation of an existing converged power-flow result.
Check bus voltage limits and line/transformer loading limits.
Report operating-point extrema, active/reactive losses, near-limit conditions, and deterministic violations.
Expose validate_operating_point as an MCP tool.
Return stable machine-readable statuses: ok, warning, error, and failed.
Ensure validation does not rerun a solver or mutate the network.
Add focused regression tests covering clean operation, voltage violations, line overloads, near-limit conditions, unsolved networks, invalid criteria, and non-mutation

Scope: This PR intentionally contains only the operating-point validation implementation, MCP exposure, and focused tests.

@BurhanAbdullah BurhanAbdullah changed the title Feat/operating point validation clean feat: add deterministic operating-point security validation Sep 23, 2026
qian-harvard and others added 2 commits September 23, 2026 21:57
operating_point.py sat at the repository root, which the wheel does not
ship: it packages powermcp/ plus the force-included server directories.
From a source checkout the import worked, so CI passed; from an
installed wheel, `powermcp run pandapower` died with
"ModuleNotFoundError: No module named 'operating_point'" -- taking down
the whole pandapower server, a core, default-installed tool, not just
the new one. It now lives beside audit.py in pandapower/, ships as
powermcp/_servers/pandapower/operating_point.py, and imports through
the server's own directory the same way audit does. Verified from a
fresh venv with the built wheel installed: both tools register and run.

The tool reports like its siblings and like audit_network: status
"success" when the validation ran, "error" with a message when it could
not (no network, no converged power flow, invalid limits), with the
verdict in validation_status (ok, warning or error). The library keeps
its own return shape; the tool translates at the boundary.

Validator fixes:
- Near-limit warnings are raised only for elements inside the band. The
  old margin/band < 0.05 test was also true for negative margins, so an
  element already violating was reported as near a limit too.
- Out-of-service buses are skipped; pandapower gives them NaN by design.
- 3-winding transformers are checked for loading and counted in losses.
- Non-finite values serialize as null instead of a bare NaN token,
  which is not valid JSON.
- The tool docstring states the prerequisite, the global-limit
  semantics and the envelope.

Tests load the module by path and cover the fixes plus the tool itself:
the no-network and could-not-run paths, the success envelope, limits
reaching the validator, and registration. Reverting the envelope fails
them. 19 pass; full suite with current main 495 passed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@qian-harvard

Copy link
Copy Markdown
Contributor

I pushed a round of changes as 36d45e2 (maintainer edit) on top of a merge of current main, and am merging. One of them fixes a blocker that CI structurally could not catch, so here is the detail.

Packaging blocker. operating_point.py sat at the repository root. The wheel ships powermcp/ plus the force-included server directories, and nothing else. From a source checkout the import worked, so CI passed. From an installed wheel, powermcp run pandapower died with ModuleNotFoundError: No module named 'operating_point'. That took down the entire pandapower server — a core, default-installed tool — not just this new one. The module now sits beside audit.py in pandapower/, ships as powermcp/_servers/pandapower/operating_point.py, and imports through the server's own directory the same way audit does. I verified from a fresh venv with the built wheel installed: both tools register and run.

Envelope. Same change as on #79, so the two validators speak one dialect with the rest of the server. status is "success" when validation ran, or "error" with a message when it couldn't (no network, no converged power flow, invalid limits). The verdict is in validation_status (ok | warning | error). validate_operating_point() in the module keeps its own return shape; the tool translates at the boundary.

Validator fixes:

  • Near-limit warnings are raised only for elements inside the band. The old margin / band < 0.05 test was also true for negative margins, so an element already violating was reported as "near" its limit as well.
  • Out-of-service buses are skipped; pandapower gives them NaN voltages by design.
  • 3-winding transformers are checked for loading and counted in losses.
  • Non-finite values serialize as null instead of a bare NaN token, which isn't valid JSON.
  • The tool docstring now states the prerequisite (run run_power_flow first), that the limits are global and per-element network limits are ignored, and the envelope.

Tests now load the module by path and cover the fixes plus the tool itself: no-network and could-not-run paths, the success envelope, limits reaching the validator, and registration. I checked that reverting the envelope fails them. 19 pass; the full suite with current main is 495 passed, green on all four interpreters.

Follow-ups, none blocking: an opt-in flag to honour per-element limits (min_vm_pu, max_loading_percent) instead of the global band; stable reason codes on the error paths; and a CI job that builds the wheel and starts each default server from it. That last one would have caught the blocker here, and it's the kind of thing only a wheel install exercises.

Thanks for two solid validation tools in a row.

@qian-harvard
qian-harvard merged commit 3d58126 into Power-Agent:main Sep 24, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants