Log pumpingStation architectural decisions; bump submodule pointers
Some checks failed
CI / lint-and-test (push) Has been cancelled
Some checks failed
CI / lint-and-test (push) Has been cancelled
Four decisions recorded under .agents/decisions/ per project convention (DECISION-YYYYMMDD-slug.md) to close the loop on today's pumpingStation refactor + eval + docs work: - wiki-in-code-repo — why docs+diagrams+code now live in one package - 5-threshold-naming — old/new field mapping + breaking-change rationale - mode-tier-template — Tier 1/2/3 classification for mode pages - eval-harness — why eval/ exists alongside test/ Also bumps nodes/pumpingStation to 66fd3fe (eval harness + Tier 2/3 template pages). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,54 @@
|
|||||||
|
# DECISION-20260422-pumpingstation-5-threshold-naming
|
||||||
|
|
||||||
|
## Context
|
||||||
|
- Task/request: Re-draw the pumpingStation basin model and rename the configuration fields so they match the conceptual model used in the wiki.
|
||||||
|
- Impacted files/contracts:
|
||||||
|
- `generalFunctions/src/configs/pumpingStation.json` (schema keys)
|
||||||
|
- `nodes/pumpingStation/src/specificClass.js` (internal state + comments)
|
||||||
|
- `nodes/pumpingStation/src/nodeClass.js` (config ingestion mapping)
|
||||||
|
- `nodes/pumpingStation/pumpingStation.html` (editor field IDs + labels)
|
||||||
|
- `nodes/pumpingStation/test/*` (test fixtures)
|
||||||
|
- `examples/pumpingstation-3pumps-dashboard/{build_flow.py, flow.json, README.md}`
|
||||||
|
- saved production flows that reference the old field names (breaking change)
|
||||||
|
- Why a decision is required now: The old names (`stopLevel`, `maxFlowLevel`, `minFlowLevel`, `heightInlet/Outlet/Overflow`) conflated geometry with control thresholds and had a redundant field (`minFlowLevel` always had to equal `startLevel`).
|
||||||
|
|
||||||
|
## Options
|
||||||
|
1. Keep old names; just document them better
|
||||||
|
- Benefits: Zero breaking change.
|
||||||
|
- Risks: Naming keeps confusing new contributors; docs continue drifting from code.
|
||||||
|
|
||||||
|
2. Adopt the 5-threshold naming from the wiki basin diagram (selected)
|
||||||
|
- Benefits: Clear semantic split — two safety thresholds (`dryRunLevel`, `overflowLevel`), three control thresholds (`minLevel`, `startLevel`, `maxLevel`) — plus three physical pipe heights (`inflowLevel`, `outflowLevel`, basin `height`). Drops the redundant `minFlowLevel`. Matches the diagram in the functional description.
|
||||||
|
- Risks: Breaking change for saved flows; node editor fields must be re-entered.
|
||||||
|
- Rollout notes: RnD/trial node — no compat shim. Breaking change documented in commit bodies and wiki.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
- Selected option: Option 2.
|
||||||
|
- Decision owner: User
|
||||||
|
- Date: 2026-04-22
|
||||||
|
- Rationale: The names should reflect the model. The diagram came first; the code should match the diagram, not the other way around. Compat posture is "controlled" (per DECISION-20260216) — breaking changes are permitted with migration notes.
|
||||||
|
|
||||||
|
## Mapping
|
||||||
|
| Old | New |
|
||||||
|
|---|---|
|
||||||
|
| `heightInlet` | `inflowLevel` |
|
||||||
|
| `heightOutlet` | `outflowLevel` |
|
||||||
|
| `heightOverflow` | `overflowLevel` |
|
||||||
|
| `stopLevel` | `minLevel` |
|
||||||
|
| `maxFlowLevel` | `maxLevel` |
|
||||||
|
| `minFlowLevel` | removed (collapsed into `startLevel`) |
|
||||||
|
| `minVolIn/Out` (internal) | `minVolAtInflow/Outflow` |
|
||||||
|
| `maxVolOverflow` (internal) | `maxVolAtOverflow` |
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
- Compatibility impact: Existing flows break; editor fields must be re-entered.
|
||||||
|
- Safety/security impact: Safety thresholds (`dryRunLevel`, `overflowLevel`) now have first-class names — guardrail validation can reason about them explicitly.
|
||||||
|
- Data/operations impact: InfluxDB payload field names change (`maxVolOverflow` → `maxVolAtOverflow` etc.). Downstream Grafana dashboards referencing the old names must update.
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- Required code/doc updates: Done in commits pumpingStation@a218945, generalFunctions@4252292, EVOLV@b885f29.
|
||||||
|
- Validation evidence required: Unit tests (`node --test test/basic/*.test.js`) pass; `grep -r` confirms zero residual old names in pumpingStation/ + generalFunctions/pumpingStation.json + examples/.
|
||||||
|
|
||||||
|
## Rollback / Migration
|
||||||
|
- Rollback strategy: revert the three commits; the renames are isolated.
|
||||||
|
- Migration/deprecation plan: None — RnD node, breaking change is acceptable.
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
# DECISION-20260422-pumpingstation-eval-harness
|
||||||
|
|
||||||
|
## Context
|
||||||
|
- Task/request: Provide a way to fluctuate inputs to the pumpingStation and observe the system's response over time, in a readable form suitable for post-hoc analysis (operator review, Grafana, or ad-hoc debugging).
|
||||||
|
- Impacted files/contracts: `nodes/pumpingStation/eval/*`, `test/basic/*`.
|
||||||
|
- Why a decision is required now: Unit tests (`node --test`) verify individual functions in isolation. They can't ergonomically show "what does the level look like over 20 minutes of storm surge". That's a different artefact.
|
||||||
|
|
||||||
|
## Options
|
||||||
|
1. Extend unit tests to cover scenarios
|
||||||
|
- Benefits: Single testing surface.
|
||||||
|
- Risks: Unit tests are assertion-heavy and slow to read; scenario output (tables, events) gets lost in TAP.
|
||||||
|
|
||||||
|
2. Separate `eval/` folder with a scenario runner (selected)
|
||||||
|
- Benefits: Scenarios read as narratives ("steady state", "storm surge", "safety dry-run"); output is human-friendly (ASCII table + events + expectation checks); JSONL per-tick log enables Grafana streaming or offline analysis.
|
||||||
|
- Risks: Second test surface to maintain.
|
||||||
|
|
||||||
|
3. Real-time Node-RED deployment + observe
|
||||||
|
- Benefits: Closest to production.
|
||||||
|
- Risks: Slow, requires infrastructure, irreproducible.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
- Selected option: Option 2.
|
||||||
|
- Decision owner: User
|
||||||
|
- Date: 2026-04-22
|
||||||
|
- Rationale: Unit tests answer "is this function correct?"; evals answer "how does the system behave under this input profile?". Two distinct questions — two distinct tools. The split also matches the .claude/rules/testing.md 3-tier convention (basic/integration/edge) which is for asserted behaviours, not scenario replay.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
test/
|
||||||
|
basic/ integration/ edge/ — node:test + assertions
|
||||||
|
eval/
|
||||||
|
run.js — scenario driver
|
||||||
|
scenarios/*.js — each exports { name, config, setup, inputs(t,ps), expectations }
|
||||||
|
formatters/table.js — ASCII summary
|
||||||
|
logs/*.jsonl — one-line-per-tick output
|
||||||
|
README.md — usage + how to pipe into Grafana
|
||||||
|
```
|
||||||
|
|
||||||
|
Driver monkey-patches `Date.now()` so the volume integrator sees 1 second per tick regardless of wall-clock. Every tick records a state snapshot (level, volume, direction, netFlow, flowSource, demand, mode, safetyActive) to JSONL for streaming.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
- Compatibility impact: None.
|
||||||
|
- Safety/security impact: None — read-only simulation.
|
||||||
|
- Data/operations impact: Running `node eval/run.js --all` produces artefacts that can be checked into CI for regression (e.g. "did the storm scenario's max level rise compared to last release?"). The JSONL format is friendly to InfluxDB/Grafana for interactive review.
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- Required code/doc updates: Driver + three starter scenarios (`levelbased-steady`, `levelbased-storm`, `safety-dry-run-trip`) + README in `eval/`.
|
||||||
|
- Validation evidence required: `node eval/run.js --all` exits 0; manual inspection of JSONL confirms per-tick records make physical sense.
|
||||||
|
|
||||||
|
## Rollback / Migration
|
||||||
|
- Rollback strategy: Delete `eval/`. Unit tests continue to work.
|
||||||
|
- Migration/deprecation plan: N/A.
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
# DECISION-20260422-pumpingstation-mode-tier-template
|
||||||
|
|
||||||
|
## Context
|
||||||
|
- Task/request: Document each pumpingStation control mode uniformly so operators can compare them and contributors can add new ones from a template.
|
||||||
|
- Impacted files/contracts: `wiki/modes/*.md`, `wiki/diagrams/modes/*.drawio.svg`.
|
||||||
|
- Why a decision is required now: The initial `levelbased.md` used a 2D `demand-vs-level` transfer-function plot. That plot form works for static memoryless control but misleads for modes whose curve shape changes at runtime (e.g. `powerBased`) or where there is no curve at all (`mpc`). We need one template that stretches to cover all cases.
|
||||||
|
|
||||||
|
## Options
|
||||||
|
1. One template, transfer-function only
|
||||||
|
- Benefits: Uniformity.
|
||||||
|
- Risks: Silently misleading for Tier-2/Tier-3 modes where the "curve" is not well-defined.
|
||||||
|
|
||||||
|
2. Per-mode ad-hoc diagrams
|
||||||
|
- Benefits: Each mode gets the best visual for itself.
|
||||||
|
- Risks: No common vocabulary — comparing modes becomes harder.
|
||||||
|
|
||||||
|
3. Three-tier template (selected)
|
||||||
|
- Benefits: Classifies every mode into one of three buckets, each with a dedicated diagram type. Still one template — only the diagram section branches.
|
||||||
|
- Risks: Some modes don't fit cleanly; will need judgement.
|
||||||
|
|
||||||
|
## Tier definitions
|
||||||
|
|
||||||
|
| Tier | Control surface | Example modes | Diagrams |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 1 | Static: `demand = f(x)` memoryless | `levelbased`, `manual` | Single-curve transfer function |
|
||||||
|
| 2 | Parameterised: shape fixed, curve moves with `θ(t)` | `flowbased` (PID), `pressureBased`, `percentageBased`, `powerBased` | Transfer function + parameter-overlay / family-of-curves |
|
||||||
|
| 3 | Optimisation / horizon: no fixed curve | `hybrid-optimal`, `mpc`, weather-aware | Block diagram of signal flow + scenario time-series |
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
- Selected option: Option 3 — three-tier classification with diagram type per tier.
|
||||||
|
- Decision owner: User
|
||||||
|
- Date: 2026-04-22
|
||||||
|
- Rationale: Keeps the mode pages comparable (same six sections) while being honest about what's actually drawable. Tier-3 modes get scenario-based analysis (via the `eval/` harness) instead of a fictitious static curve.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
- Compatibility impact: None — this is doc-level.
|
||||||
|
- Safety/security impact: None.
|
||||||
|
- Data/operations impact: New modes get a template to follow; reviews have a shared vocabulary.
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- Required code/doc updates: `wiki/modes/README.md` lists the tiers and template; `wiki/modes/{flowbased, powerbased, mpc}.md` are worked templates covering Tier 2 (×2) and Tier 3 (×1) respectively.
|
||||||
|
- Validation evidence required: A reviewer reading a mode page can identify which tier it is within 10 seconds without scrolling.
|
||||||
|
|
||||||
|
## Rollback / Migration
|
||||||
|
- Rollback strategy: Delete `wiki/modes/`; revert the table in `wiki/README.md`.
|
||||||
|
- Migration/deprecation plan: N/A — adding a tier later (e.g. Tier 4 — RL-based) is trivially additive.
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
# DECISION-20260422-pumpingstation-wiki-in-code-repo
|
||||||
|
|
||||||
|
## Context
|
||||||
|
- Task/request: Document pumpingStation functional behaviour (basin model, control modes, safety). Initial draft went into the Gitea wiki repo (`pumpingStation.wiki.git`).
|
||||||
|
- Impacted files/contracts: location of all pumpingStation documentation; how docs, diagrams, and code stay in sync; wiki UI vs repo browsing UX.
|
||||||
|
- Why a decision is required now: Wiki repo + code repo diverge silently. When `specificClass.js` renames a field, nothing forces the wiki to follow. User preference is "single package" — clone once, edit together, review together.
|
||||||
|
|
||||||
|
## Options
|
||||||
|
1. Keep docs in `pumpingStation.wiki.git` (Gitea's native wiki)
|
||||||
|
- Benefits: Gitea wiki UI (Pages dropdown, `?edit=1`, dedicated URL).
|
||||||
|
- Risks: Two separate repos; code and doc drift silently.
|
||||||
|
- Rollout notes: Status quo as of 2026-04-22.
|
||||||
|
|
||||||
|
2. Move docs + diagrams into `pumpingStation.git/wiki/` (selected)
|
||||||
|
- Benefits: Single package — `git clone pumpingStation` gets code + docs + diagrams. Atomic commits can change code + doc + diagram together. Diagrams version-lock with the class they describe.
|
||||||
|
- Risks: Lose the Gitea wiki Pages dropdown. Browsing is via the repo tree.
|
||||||
|
- Rollout notes: Shrink the `.wiki.git` to a pointer at the new location.
|
||||||
|
|
||||||
|
3. Hybrid — diagrams only in code repo, Markdown pages in `.wiki.git`
|
||||||
|
- Benefits: Keep Gitea wiki UI.
|
||||||
|
- Risks: Image URLs break silently on rename; still two repos to sync.
|
||||||
|
- Rollout notes: Not pursued.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
- Selected option: Option 2 — everything under `pumpingStation/wiki/`.
|
||||||
|
- Decision owner: User (r.de.ren@brabantsedelta.nl)
|
||||||
|
- Date: 2026-04-22
|
||||||
|
- Rationale: Single package > Gitea wiki UI convenience. Review-as-one-PR pattern is worth more than the Pages dropdown. `wiki/README.md` acts as the index instead.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
- Compatibility impact: Anyone bookmarking `RnD/pumpingStation/wiki/Functional-Description` lands on a one-line pointer. Breaking but low-impact.
|
||||||
|
- Safety/security impact: None.
|
||||||
|
- Data/operations impact: Future contributors must know to edit `wiki/` inside the code repo, not the wiki repo. Pointer page on the Gitea wiki explains.
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- Required code/doc updates: `pumpingStation/wiki/{functional-description.md, README.md, modes/, diagrams/}` populated; `.wiki.git` Home shrunk.
|
||||||
|
- Validation evidence required: Raw Gitea URLs resolve; `https://gitea.wbd-rd.nl/RnD/pumpingStation/src/branch/main/wiki/` browses cleanly.
|
||||||
|
|
||||||
|
## Rollback / Migration
|
||||||
|
- Rollback strategy: Reverse — copy `pumpingStation/wiki/*.md` back into `.wiki.git`, update `.wiki.git` Home to point at itself.
|
||||||
|
- Migration/deprecation plan: The pointer page stays indefinitely.
|
||||||
Submodule nodes/pumpingStation updated: a2189457f6...66fd3feff8
Reference in New Issue
Block a user