Repository navigation
Add CLAUDE.md documentation for ExpertAssist project - #2
Merged
Merged
Conversation
Document the codebase structure, tech stack, development workflows, API endpoints, key patterns, and conventions for AI assistants working with this power grid contingency analysis application. https://claude.ai/code/session_01Y9w9cky5CKAqLnfXneCpon
marota
added a commit
that referenced
this pull request
Apr 18, 2026
After the network_service<->recommender_service mutualisation (docs/perf-shared-network.md, commit f4184d6), the .xiidm file was still being parsed TWICE by pypowsybl during /api/config: 1. network_service.load_network() (already mutualised) 2. setup_environment_configs_pypowsybl() via grid2op backend On large grids this 2nd parse costs ~1-5 s of redundant CPU. This commit (paired with upstream commit 58fe2e44 in expert_op4grid_recommender 0.2.0.post1) eliminates load #2 by injecting the already-loaded Network instance into the upstream helper: setup_environment_configs_pypowsybl(network=self._base_network) SimulationEnvironment and NetworkManager already supported the `network=` branch — only the top-level convenience function needed the signature extension (see upstream patch). Thread-safety: three holders now reference the same Network, but the variant-mutating operations (grid2op LF in analysis/simulation, recommender variant switching) don't overlap with /api/config's NAD worker — confirmed by the v9 trace showing the NAD prefetch completes before /api/config returns. Expected impact (v10 trace pending): - /api/config: ~16.6 s -> ~13-14 s (-3 s) - /api/network-diagram: ~380 ms (unchanged, cache still warm) - Total critical path: ~18 s -> ~15 s (-3 s vs v9, -6 s vs v7) Requires expert_op4grid_recommender >= 0.2.0.post1. See docs/perf-grid2op-shared-network.md.
marota
pushed a commit
that referenced
this pull request
Apr 20, 2026
Three user-facing session-reload regressions fixed in one pass:
1. **N-1 diagram not refetched on reload** — the N-1 effect in
`App.tsx:724-775` used `hasAnalysisState()` as part of its
early-return short-circuit. After a session reload actions are
already rehydrated, so `hasAnalysisState() === true` while
`n1Diagram === null` — the effect would return early and leave
the N-1 tab blank, the N-1 Overloads panel empty and the user
with a dangling "Select a contingency element" placeholder.
Fix: the early-return now also checks `!restoringSessionRef.current`
so a just-restored session always proceeds to the fetch.
`useSession::handleRestoreSession` already flipped the ref to
`true` before `setSelectedBranch` — a new regression test in
`useSession.test.ts` locks that ordering in place.
2. **State wiped by `clearContingencyState()`** — once the early
return is relaxed, the effect reached the `clearContingencyState()`
+ `setN1Diagram(null)` + `setActiveTab('n-1')` block, which would
wipe the just-restored result / selectedActionIds / overflow PDF
URL / action diagram. Fix: capture the flag in a local `isRestoring`
BEFORE resetting `restoringSessionRef.current`, then skip the
clear + tab switch when restoring.
3. **Overflow PDF appeared unreloaded** — was a downstream symptom
of #2: `result.pdf_url` got nuked alongside the rest of the
analysis state. The same skip now preserves it.
Legacy standalone decommissioned:
- `standalone_interface.html` → renamed to
`standalone_interface_legacy.html`, untracked via `.gitignore`,
kept on disk for reference only. The canonical single-file
distribution is now `frontend/dist-standalone/standalone.html`
produced by `npm run build:standalone`. No more manual mirroring.
- CLAUDE.md (root + frontend) + `docs/save-results.md` updated.
- Four parity scripts default-target the auto-generated bundle and
fall back to the legacy file when the auto-gen is not built. The
invariants script maps the legacy `"file_hint"` transparently to
whichever artifact is on disk.
- Deleted `cssRegression.test.ts` and `standaloneInterface.test.ts`
(both tested properties of the decommissioned legacy file; the
React source covers the same invariants and the auto-gen bundle
inherits them).
New regression tests:
- `useSession.test.ts`: verifies `restoringSessionRef.current` flips
to `true` BEFORE `setSelectedBranch` fires, locking the ordering
that makes the N-1 fetch work on restore.
- `SldOverlay.test.tsx` (4 new specs):
- LS load cell highlighted via `load_shedding_details` fallback
when `action_topology` is empty
- Curtailed generator highlighted via `curtailment_details` fallback
- PST highlighted via `pst_details` fallback
- Signature cache invalidates when `shedded_mw` bumps in-place
(re-simulation) — forces clone re-plant on fresh magnitude
Test suite: 936/936 passing (43 files; the 54-test drop vs. last
commit is the two deleted legacy-file tests).
Parity layers: L2 + L4 exit 0; L1 + L3a report the 3 pre-existing
false positives (config_loaded / settings_applied bare-identifier
paths; `reactExports.useCallback` anchor limit) documented in the
CLAUDE.md audit delta.
https://claude.ai/code/session_014N3uuxctcVVocMwxp4EcNL
marota
pushed a commit
that referenced
this pull request
May 2, 2026
Adds two layers of regression guards covering all five
recommendations from `docs/proposals/ui-design-critique.md`:
1. Seven new static invariants in `scripts/check_invariants.py`
(Layer 4):
- notices_panel_in_sidebar — AppSidebar mounts <NoticesPanel>
- action_feed_no_dismissable_warning_state — ActionFeed lost
setShowActionDictWarning / setShowRecommenderWarning
- overload_panel_uses_monitoring_hint — OverloadPanel exposes
`monitoringHint`, not the legacy banner props
- diagram_legend_on_each_diagram_tab — VisualizationPanel wires
<DiagramLegend tabId="n|n-1|action">
- nad_overload_halo_capped_at_zoom — App.css caps overload halo
stroke at 24px on detail-zoom via vector-effect: non-scaling-
stroke
- design_token_gate_blocks_inline_hex — FRONTEND_HEX_LITERAL_MAX
stays at 0
- action_card_progressive_disclosure_gated_by_isViewing —
ActionCard renders the disclosure subtree under {isViewing &&
Total: 10 → 17 invariants. All green.
2. New `frontend/src/uxConsistency.test.tsx` (19 specs) — runtime
contract checks rendering the real components rather than
mocks. One describe block per recommendation:
- #1 design tokens: scans inline `style` attributes for raw hex
literals and asserts none leak from OverloadPanel / AppSidebar
- #2 progressive disclosure: ActionCard at-rest hides the
disclosure subtree; isViewing=true reveals it
- #3 halo cap: re-asserts the App.css rule (cheaper feedback
loop than the static script)
- #4 warning tier: OverloadPanel without monitoringHint shows
no inline yellow banner; ActionFeed at default state has no
warning-styled descendant; AppSidebar surfaces the
<NoticesPanel> pill iff notices.length > 0
- #5 diagram legend: each tab in VisualizationPanel mounts a
legend pill when its SVG is loaded, omits it when absent
- source-text invariants: cross-checks the file-level
contracts so a refactor that drops a recommendation fails
this file too
1182 → 1201 specs. All passing; ESLint clean; code-quality
gate clean.
https://claude.ai/code/session_01EYXsLY6hKRncRxj3KTHERk
marota
pushed a commit
that referenced
this pull request
May 7, 2026
Two parity scripts referenced the legacy single-string contingency event / tab id and started failing once the N-K refactor renamed them: - ``check_invariants.py`` — invariant ``diagram_legend_on_each_diagram_tab`` regex looked for ``tabId="n-1"`` but the contingency tab id is now ``"contingency"``. Rewriting the chained pattern restores the 17/17 score. - ``check_gesture_sequence.py`` — gesture #2 (Select contingency) expected the legacy ``contingency_selected`` event. The new flow splits the gesture into ``contingency_element_added`` / ``contingency_element_removed`` (per-chip toggle) plus ``contingency_applied`` when the user clicks the Trigger button to commit the pending list. The COMMIT is what drives the diagram fetch, so the spec now expects ``contingency_applied`` on the React side; ``contingency_selected`` stays as the standalone-side primary handler with ``contingency_applied`` as a fallback so the freshly-built ``dist-standalone/standalone.html`` (carrying the new event) wins on CI. Layer 1 (static parity) needs no script change — the auto-generated ``frontend/dist-standalone/standalone.html`` regenerated by ``npm run build:standalone`` in the CI workflow inherits the new ``/api/contingency-*`` paths and the new InteractionType events straight from the React source tree. Verified locally: all five gates (Layer 1 / 3a / 4 + session- fidelity Layer 2 + code-quality) exit 0. https://claude.ai/code/session_01CtPJf8fEJAts2tbxBA7cSF
marota
pushed a commit
that referenced
this pull request
Jun 18, 2026
Targets #1 + #2 from the code-quality review. The three mixins (Diagram/Analysis/Simulation) operate on the composed RecommenderService `self`, so per-class mypy checking false-positived on every cross-mixin `self._x` (~63 of 69 errors). Declare that shared surface once in services/_recommender_state.py — a TYPE_CHECKING-only base the mixins inherit at type-check time and `object` at runtime, so there is no MRO or behaviour change (confirmed: offline backend suite is byte-identical stashed vs not — 624 passed either way). Fixes the 3 real latent type bugs the noise was hiding (#2): - run_analysis_step2: `list[str]` params defaulting to None → `| None` - _cached_obs_n1_elements Optional/non-Optional mismatch (resolved by the shared declaration) and scope-disables `method-assign` for the by-design model-integration method swaps in recommenders/_service_integration.py (rather than adding `# type: ignore`, which would breach the suppression ratchet). mypy is now 0 and GATES the build (was advisory); pinned mypy==1.19.* for CI reproducibility. ruff clean. https://claude.ai/code/session_0185GQf52QDpMM4zRDmGVN8X
marota
added a commit
that referenced
this pull request
Jul 3, 2026
Add 2026-07 full-repository review to docs/architecture
marota
added a commit
that referenced
this pull request
Jul 3, 2026
Add 2026-07 full-repository review to docs/architecture
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds comprehensive project documentation in the form of a
CLAUDE.mdfile, providing a complete reference guide for the ExpertAssist power grid contingency analysis application.Changes
CLAUDE.md: A 160-line documentation file covering:Purpose
This documentation serves as a single source of truth for understanding the ExpertAssist codebase, enabling faster onboarding and providing clear guidance on:
The document is structured to be useful for both human developers and AI assistants working with the codebase.
https://claude.ai/code/session_01Y9w9cky5CKAqLnfXneCpon