Per discussion: "test" and "eval" overlap in meaning; "simulations"
is more honest about what's actually happening — scripted plant
inputs driving a physics sim, then recorded for analysis.
Rename scope:
- eval/ → simulations/ (tracked as git renames)
- Internal references in run.js and README.md updated
- wiki/modes/mpc.md link updated
Also fixes a log-write bug noticed during the rename:
- run.js didn't mkdir simulations/logs/ before createWriteStream,
so the stream opened into a potentially non-existent dir and the
file never materialised. Added fs.mkdirSync(..., recursive:true).
- end() wasn't awaited, so the process could exit before the stream
flushed. Now awaits the 'finish' event. Confirmed: 1200 records
actually land in simulations/logs/<scenario>.jsonl.
- Added simulations/logs/.gitignore so future JSONL artefacts stay
out of the repo but the dir remains tracked.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
### eval/ (scenario-based evaluation)
Complements the unit tests under test/basic. Scenarios fluctuate inputs
over simulated time, record every tick to JSONL, print a summary
table + event log, and check expectations. Complementary to unit
tests — these answer "how does the system respond to this input
profile" rather than "is this function correct".
- eval/run.js — driver; monkey-patches Date.now so the
volume integrator ticks at 1 s/iter
regardless of wall-clock
- eval/scenarios/ — one file per scenario
- levelbased-steady.js — constant inflow, demand converges
- levelbased-storm.js — inflow surge, demand saturates
- safety-dry-run-trip.js — manual mode, empty basin, safety trips
- eval/formatters/table.js — ASCII summary of sampled ticks
- eval/logs/ — per-scenario JSONL output (one line per tick)
- eval/README.md — usage + scenario file shape + how to pipe
into InfluxDB/Grafana
All three starter scenarios PASS with their expectations.
### wiki/modes/ (tier template pages)
The levelbased page templated Tier-1 modes (static transfer function).
Added worked examples for the other two tiers so all mode pages share
a common skeleton and new modes have something concrete to imitate:
- flowbased.md — Tier 2 (PID on measured outflow)
- powerbased.md — Tier 2 (levelbased curve clipped by grid power budget)
- mpc.md — Tier 3 (optimisation + forecast; block diagram +
scenario time-series instead of a fixed curve)
- modes/README.md — updated with the three-tier classification table
and diagram-type-per-tier guidance
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Introduces the pattern: basin model is the shared canvas (mode-agnostic
physics); each control mode is its own page under wiki/modes/ plus a
demand-vs-level transfer-function diagram under wiki/diagrams/modes/.
- wiki/modes/README.md — index + per-mode page template (inputs,
threshold policy, demand formula, edge cases, related)
- wiki/modes/levelbased.md — first worked example using the new naming
convention (dryRunLevel / minLevel / startLevel / maxLevel /
overflowLevel). Forward-looking — the code still uses the old names
until the pending rename refactor.
- wiki/diagrams/modes/levelbased.drawio.svg — transfer-function plot
(zones: STOP / DEAD ZONE / RAMP / SATURATE, safety trips outside the
plot). Round-trippable via embedded drawio XML.
- functional-description.md — replaced the inline levelbased/manual
subsection with a table pointing at the modes/ pages. Removed the
old control-zones ASCII diagram reference (superseded by the
per-mode transfer function).
- wiki/README.md — added Control modes entry + diagrams/modes/ pointer.
The remaining placeholder modes (flowbased, pressureBased,
percentageBased, powerBased, hybrid, manual) can each fill in the
template independently.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>