Establish CONTRACTS.md at the EVOLV root as the canonical map of where every
contract, rule, and standard lives. Surface it from CLAUDE.md so every fresh
agent or colleague lands there first.
Reshape .claude/refactor/ to reflect that the platform refactor is done:
live standards stay at the top level; the plan artifacts (CONTINUE_HERE.md,
TASKS.md) move into Archive/ with WARNING banners.
Drop content that drifted out of date or duplicated the new standards stack:
- docs/DEVELOPER_GUIDE.md (pre-refactor walkthrough; superseded by
wiki/Architecture, wiki/Getting-Started, .claude/rules/node-architecture,
.claude/refactor/MODULE_SPLIT + per-node CONTRACT.md + src/commands/).
- .agents/decisions/ (15 DECISION files): load-bearing decisions belong in
commit messages and PR descriptions; live open items in OPEN_QUESTIONS.md.
- .agents/improvements/TOP10_*.md: moved to Archive/.
Bump generalFunctions to 49c77f2 — adds CONTRACT.md inside the library:
different shape from per-node CONTRACT.md files (library API, not msg.topic),
with stability tags and pointers to .claude/refactor/CONTRACTS.md §N.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* generalFunctions @ 34a4ef0 — new iconHelpers module + initVisuals
step on logger/position menus; asset selector rebuilt as a chip
wizard with per-stage type-to-filter combobox and node-aware curve
mini-chart (rotatingMachine Q-H, valve Cv, diffuser SOTE).
* machineGroupControl @ 6833e9f — consumes the shared visuals;
strategy/rendezvous cards keep their MGC-local SVGs; maintenance
switched to FA fa-wrench. Output-format pickers now use the shared
.evolv-icon-picker classes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- machineGroupControl @ 472402c — rendezvous planner extracted into
src/movement/. Every dispatch (both optimalControl and priorityControl)
routes through a shared _dispatchFlowDistribution helper so all pumps
reach their setpoint at t* = max(eta_i) regardless of per-pump speed.
New "Same-time landing" toggle in the editor (planner.useRendezvous,
default true) for operators who want the legacy fire-and-forget.
- generalFunctions @ af02d36 — new planner.useRendezvous schema field
and stateManager.getRemainingTransitionS() that the planner reads to
compute exact eta for children mid-ladder.
- rotatingMachine @ 5ea0b0b — sequenceController honors the new
sequenceAbortToken so a pre-empted sequence (e.g. shutdown caught
mid-ramp by a fresh demand) cleanly breaks out instead of barging
through to its terminal state.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- generalFunctions f8f71a4: schema additions (output.process/dbase,
functionality.distance, drop prioritypercentagecontrol), measurement
position.x nullable, asset-data file renamed machine.json ->
rotatingmachine.json so AssetMenu lookup matches, menu re-derives
supplier/assetType from saved model id on reopen.
- pumpingStation 2c7fe17: setDemand reads unit-normalised payload from
commandRegistry (mirrors today's MGC change to unit-self-describing
demand commands). Pre-existing test failure (stale path to
basic-dashboard.flow.json, renamed to 02-Dashboard.json in fe5fa35) is
unrelated to this commit.
- rotatingMachine 394a972: η = (Q·ΔP)/P_shaft replaces the legacy Q/P
formula — gives a real BEP peak so NCog stops collapsing to 0 and the
MGC dashboard's BEP-position metric actually moves. Asset-registry
lookup renamed machine -> rotatingmachine (matches generalFunctions
rename). Constructor stateConfig pass-through fixed (default-param was
clobbering BaseNodeAdapter's pre-set extras). + 2 new tests.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
MGC submodule lands the 2026-05-14 governance review fixes plus rolled-up
session work: _output-manifest.md per the new output-coverage rule,
computeEqualFlowDistribution extracted as a pure function (testable without
MGC), groupEfficiency degenerate-case fix, unit-self-describing set.demand,
eta = (Q*dP)/P formula correction, and dashboard fan-out hardening
(auto-init, NCog normalization, Q-H trim, null-trap closure). Suite 108/108.
Superproject adds:
- .claude/rules/output-coverage.md: every-output-every-state testing rule
prompted by the eta-null crash earlier in the session.
- CLAUDE.md: pointer to the new rule under Conventions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Follow-up to the AssetResolver landing. All five diffuser supplier
curves now share one X-axis convention; diffuser specificClass
computes specific flux from total flow + membrane area and queries the
curves at that flux. Each curve file carries its own
_meta.membraneArea_m2_per_element so the node defaults are correct
without any per-node overrides.
Supplier naming fixed: Sulzer (PIK300/PRK300), Aquaconsult-Entec
(Aerostrip Phoenix).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Coordinated cutover across five submodules to the generalFunctions
asset registry. Highlights:
- generalFunctions: AssetResolver namespace + FileBackend, with new
diffuser supplier curves (GVA migrated, Jäger JetFlex EPDM-1000,
Aerostrip Phoenix multi-coverage, PIK300/PRK300 multi-coverage).
Diffuser config schema corrected: density was always meant to be
bottom-coverage %, not elements/m².
- diffuser: _loadSpecs reads from the registry; editor wired with the
shared asset cascade (supplier → type → model → unit).
- rotatingMachine + valve: derive supplier/type/units from the model
id via resolveAssetMetadata; reject saved legacy fields with a clear
re-save prompt.
- machineGroupControl: integration fixtures use the trimmed asset
shape.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Surfaces mode/scaling in the editor, fixes the camelCase-vs-lowercase
mismatch that silently disabled dispatch on default config, compacts the
status badge, extends getOutput with capacity / machine-count fields, and
replaces the pre-refactor example stubs with 01-Basic.json (MGC + 3
pumps + setup) and 02-Dashboard.json (FlowFuse dashboard with charts).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Fixes MGC child-registration id collision and rotatingMachine
curve-lookup failure caused by the shallow Object.assign in
ConfigManager.buildConfig wiping general.id and asset.model.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Includes 285fd01 (drop 52 MB 01-basic-demo.gif) and 6e89e49 (restore GIF
"needed" placeholders in Home and Reference-Examples so the dropped media
is tracked instead of leaving a broken image link).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Submodule pointers
- pumpingStation: realistic basin defaults, ramp-foot visual fix, manual-mode
observability, new 02-Dashboard.json (charts + raw-output table), wiki
Home/Reference-Examples with screenshots + demo GIF.
- generalFunctions: pumpingStation config schema defaults aligned with the
new editor drag-in values; startLevel description corrected (ramp foot is
inflowLevel, not startLevel).
- monster: examples cleanup — drop pre-refactor flows, ship single
02-integrated-e2e.json.
Wiki
- New wiki/Functional-Overview.md: companion to Architecture covering the
process side — what each node physically represents and which control
objective it serves.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pilot pass for the per-node Home redesign. pumpingStation's wiki/
now has a short, intuitive Home.md plus four Reference-* sibling
pages (Contracts / Architecture / Examples / Limitations). Asset
placeholders created under wiki/_partial-{screenshots,gifs,flows}/
with explicit "screenshot needed" / "GIF needed" callouts where
the user will record assets.
Abandoned content: wiki/functional-description.md and wiki/modes/*
were removed from source per user direction (example-driven over
prose).
Once this pattern is validated on the live pumpingStation wiki,
the same split will be applied to the other 10 nodes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
All 11 nodes' wiki/Home.md regenerated with the Unit column +
per-topic descriptions. rotatingMachine + reactor private-method
test files rewritten to the public BaseNodeAdapter surface.
OPEN_QUESTIONS: rotatingMachine + reactor private-test entries
marked RESOLVED.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
scripts/test-platform.js iterates each submodule, runs npm test, shows
a per-node pass/fail summary, exits non-zero if any node fails.
Wired as `npm run test:platform` in the parent package.json.
Submodule pointer bumps:
dashboardAPI 2874608 → 92d7eba (Mocha → node:test conversion for edge+integration)
diffuser 0ec9dd1 → 15cfb22 (P10.7a test script fix)
generalFunctions 8ebf31d → 95c5e68 (P10.7a test script fix + remove 5 broken Mocha dupes)
pumpingStation 52d3889 → d2384b1 (P10.7a test script fix)
Current platform-wide gate: 729 pass / 5 fail across 12 submodules
(5 failures are all pre-existing AssertionErrors logged in
OPEN_QUESTIONS.md for Phase 10.5).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pump-shutdown deadlock fix split across two submodules:
- rotatingMachine@8f9150e: shutdown sequence clears state.delayedMove
so the abort-and-return-to-operational path doesn't auto-pickup the
queued setpoint and re-engage the pump.
- machineGroupControl@ea2857f: turnOffAllMachines clears MGC's
_delayedCall and serializes per-pump shutdown so PS's 2 s tick loop
can't interrupt an in-flight shutdown.
Live verification on pumpingstation-complete-example demo: basin now
shuts pumps off at stopLevel cleanly, reverses to fill, completes the
hysteresis cycle.
Also disable the trends page in the demo flow (build_flow.py + regen
flow.json). FlowFuse ui-chart's per-series server-side history buffer
(7 charts × ~20 series × 3600-point retention) was saturating the
Node-RED event loop at 129% CPU, making the dashboard freeze on every
click. Trends remain available — just disabled by default; flip the
ui_page_trends "d" key to false to re-enable.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
WARN now fires only when force-aborting an actually in-flight pump
movement (gate-bypass safety net), not on every no-op tick.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the _dispatchInFlight gate that mirrors rotatingMachine
state.delayedMove. Before this, PS at 1 Hz overran in-flight pump
ramps via concurrent handleInput entries, producing the live thrash:
120 aborts / 2 min, pump_b clamped at minFlow.
Includes regression test:
test/mgc-overactive-demand-serialization.integration.test.js
covering concurrent-burst serialization (30 calls → ≤ 5 aborts) and
latest-wins semantic.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- nodes/machineGroupControl@69bdf11 makes DOWNSTREAM single-writer
(handlePressureChange = live aggregate; optimizer target moved to
AT_EQUIPMENT). Closes the ps-mgc-flow-contract failure.
- test/inflow-overcapacity-stability now starts the basin at maxLevel
so PS percControl is immediately 100 % (the actual storm condition)
and uses real-time waits between ticks so movementManager intervals
fire — the previous setImmediate yield was too fast for moves to
progress, making pumps look perma-parked even when behaviour was OK.
Park observations dropped from 83 to 3 across the sim window; final
ctrl converges to ~88 % across all 3 pumps.
All 82 cross-node + node integration tests now pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Submodule bumps land the deadlock fix (state.js residue unpark + MGC
optimalControl dispatch reorder) and pumpingStation stopLevel hysteresis.
- Renames examples/pumpingstation-3pumps-dashboard →
pumpingstation-complete-example with regenerated flow.json. New
dashboard groups, demand-broadcast wiring, S88 placement rule
applied, ui-chart trend-split and link-channel naming follow
.claude/rules/node-red-flow-layout.md.
- New cross-node test harness under test/: end-to-end-pumpingstation
drives PS + MGC + 3 pumps + physics simulator end-to-end and
verifies the ~5/15 min cycle.
- Adds Grafana provisioning dashboards (pumping-station.json) and a
helper sync-example.sh script for export/import to live Node-RED.
- Docker entrypoint + settings + compose tweaks for the persistent
user dir layout used by the demo.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- package.json: remove @tensorflow/tfjs and @tensorflow/tfjs-node.
Monster's TF code was already stripped; the deps were stale and kept
pulling a heavy native binary back into every install.
- .gitignore: ignore .repo-mem/ regenerable indexes and per-session
.claude/*.lock runtime files.
- CLAUDE.md: prepend READ-FIRST pointer to .claude/rules/repo-mem.md;
collapse the 'three outputs' bullet to a pointer at node-architecture.
- .claude/rules/telemetry.md: drop Port 0/1/2 duplication; reference
node-architecture.md.
- .claude/rules/testing.md: stop requiring a separate test/edge tier and
the basic/integration/edge example flow trio. Reflects what nodes
actually do.
- .claude/rules/repo-mem.md (new): when-to-call-which guide for the
per-repo memory MCP, anti-patterns, refresh model.
- .mcp.json (new): wire repo-mem stdio server.
- docs/DEVELOPER_GUIDE.md (new): step-by-step guide for adding a new
EVOLV node under the three-layer pattern.
- Bump nodes/pumpingStation to 6ab585b (docs + simulations refresh,
spill-flow path renames consistent with d8490aa).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pumpingStation: predicted-volume hard-floor at 0; spill flow refactored
from flow.predicted.out.<child=overflow> to its own position
flow.predicted.overflow. Drops the spillPrev self-subtraction. New
underflowVolume diagnostic for flow-balance errors. 70/70 tests pass.
generalFunctions: MeasurementContainer.get() strict-resolves explicit
.child(name) — missing named child now returns null instead of falling
through to a sibling. Persistent setChildId remains a hint (no
behavioural change for registered children).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Integrator now clamps predicted volume to [dryRunSafetyVol,
maxVolAtOverflow], records cumulative spill as overflowVolume and
exposes a synthetic flow.predicted.out.overflow rate so net flow
balances to ~0 while pinned. _selectBestNetFlow holds the last
level-rate net flow during overflow so dashboards keep a usable
reading. Top-level predictedOverflowVolume / predictedOverflowRate
fields added to getOutput.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- bounds.js sets HTML5 min/max on every level + percent input so the
spinner can't push values past the basin hierarchy.
- Basin-level violations now surface in a visible ribbon above the
basin diagram and block Deploy via oneditsave.
- Layout polish: widened side panel, tightened basin viewBox, dropped
mode-preview axis labels, moved datum below the tank.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- pumpingStation: hold-then-ramp shift hysteresis driven by
shiftArmPercent (% output threshold for arming) instead of by level.
New e2e integration test exercises the full fill→arm→hold→ramp-down
cycle. Editor preview gains the arming-% horizontal line.
- generalFunctions: add shiftArmPercent to the pumpingStation schema;
add prominent doc block on MeasurementContainer documenting the
`${type}.${variant}.${position}.${childId}` flatten format and the
implicit 'default' childId convention so dashboards don't drop it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>