development now = slice/43 (latest real work, 31 commits incl. full
dashboardAPI body de957cb) + the bits ONLY dev-lzm had:
- .npmrc (npm supply-chain hardening: ignore-scripts, min-release-age)
- YAML frontmatter on .claude/agents/*.md
- measurement node -> d7f6613 (editor JS modularization)
- pumpingStation docs (2fb083d) carried under fc6491d
Submodule pointers resolved to the NEWER side (auto-merge had regressed
coresync->aefec90 and pumpingStation->2fb083d):
coresync=21d77a8 (slice/43) dashboardAPI=de957cb (slice/43)
measurement=d7f6613 (dev-lzm) pumpingStation=fc6491d (dev-lzm+m³/s)
package version set to 1.0.35.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bring dev-lzm in sync with origin/development for generalFunctions,
machineGroupControl, pumpingStation and rotatingMachine (clean
fast-forwards, no divergence).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add name/description frontmatter to all 10 .claude/agents/*.md files so
they are discoverable and routable as Claude Code subagents.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Promotes the pumpingStation development tip into the superproject. On top of the
ef07f2a already pinned by the 5-node bump, this adds the contract/docs work:
- docs(contract): close output-contract gaps — mode/manualDemand, Port-2 topic,
output manifest (4889fda)
- docs(contract): worked msg examples for every input topic + output port (2fb083d)
- fix(ps): persist stopLevel/holdLevel as numbers; flow output in m³/h; etc.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Submodule a83a85e: editor was storing numeric inputs as strings via
Node-RED's auto-form-bind, causing the stopLevel/holdLevel fields to
blank out on Done → reopen. oneditsave now explicitly parseFloats them,
and the reader helpers coerce strings for backward compatibility with
already-saved flows.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bumps dashboardAPI submodule pointer to include the runtime datasource-uid
resolver. Templates no longer have to ship with the right uid baked in; any
Grafana instance with an influxdb datasource will now render the dashboards
correctly. Fixes the "Datasource <uid> not found" exclamation marks observed
when pushing to a fresh Grafana (e.g. the VPS).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Larger margins ensure the size-14 rim and floor captions never overlap
the topmost or bottommost threshold line in the tank.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lines now have a minimum 3.7% gap so labels never collide with adjacent
threshold lines, regardless of how close the underlying levels are.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Canvas elements now use 'constraint: { horizontal: scale, vertical: scale }'
with percentage-based margin placement so the tank fills the card edge to
edge and stays centered as the panel resizes. Threshold labels split
left/right with a gap and at font size 14 for readability.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tank vertically centered in canvas frame. Labels for thresholds at the
very bottom of the tank (small dryRunThresholdPercent) no longer extend
below the visible card area.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Threshold labels now sit above or below their lines (never on top) and
are centered horizontally inside the tank.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds .claude/settings.json with CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1
so every contributor gets the `team` keyword + TeamCreate tool on clone,
without each person having to set the env var locally.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Canvas frame stretched vertically to match the card's aspect ratio so
the tank visual fills the entire card height with no letterboxing below.
Redundant in-canvas readouts dropped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tank Layout visual now fills the Canvas card edge-to-edge. Each
threshold's name + value live INSIDE the tank near its line instead of
in external label columns.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Canvas card shrunk to w:6 and frame to 400 px so the basin visual fills
the card edge-to-edge. Level/Volume timeseries widen to w:14 to absorb
the freed columns. Right value labels and bottom readouts no longer clip.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tank Layout canvas + bar gauge + Level/Volume timeseries grow to h:20
so the basin visual occupies more vertical space and reads at a glance.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces Heights/Volume-Limits/Fill% stats with an integrated basin visual:
vertical bar gauge bound to live level + threshold markers, plus Canvas
showing tank zones, threshold lines, named labels, and live readouts.
Level + Volume timeseries reflow next to the basin in the renamed Basin row.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- machineGroupControl f18f3cc: fn_chart_pump_a/b/c emit -1 OFF sentinel on the
per-pump % control chart when state is off/idle/maintenance; ui_chart_pumps_ctrl
ymin=-5; new per-pump-ctrl-fanout output-coverage test + manifest update.
- pumpingStation e041877: revert canonical flow to m³/s (platform convention),
keep output m³/h for dashboard parity. No demand smoothing/hysteresis — that
belongs in a dedicated intermediate node per design review.
Also cleaned stale InfluxDB series (out-of-tree): dropped "MGC Isolated" and
"MGC — Pump Group" measurements and the category="undefined" rows in
"Machine Group" (135,416 stale rows; live untagged data preserved).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
machineGroupControl 2af6c90, generalFunctions 5c091cd. Rendezvous lock verified
live on the isolated rig: clean monotonic 1→2 pump staging, no wait/hunt.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Bumps nodes/dashboardAPI submodule to slice/34-walking-skeleton@7fdab73
(credentials block for bearer token, folderUid config field, basic tests).
- Pins grafana/grafana to 11.3.0 — legacy /api/dashboards/db is the
generator target; G12 K8s-style API is out of scope (PRD constraint).
Refs #34
Bumps machineGroupControl (e1e1977) and pumpingStation (ef07f2a) — example
dashboard JSON tweaks committed on each submodule's development branch.
Adds docs/research/ and docs/prd/ for the dashboardAPI v2 graph-aware Grafana
generator workflow (Gitea issues #32-#43). Ignores .prototypes/ — throwaway
spike code lives there per the /prototype skill.
Bumps:
- rotatingMachine 455f15d refactor: route unit conversions through UnitPolicy.convert
- pumpingStation 2d68a4f refactor + fix(level): UnitPolicy adoption, level-rate timestamp fix, integration test rewire
- machineGroupControl ddf2b07 refactor: _canonicalToOutputFlow + setDemand via UnitPolicy.convert, structure test rewire
- generalFunctions bc79de1 fix(influx): accept tagCode camelCase + emit positionVsParent tag
- measurement 36eaa2f test(edge): align with object-payload accept behaviour
The UnitPolicy bump finishes the §6 contract migration the refactor
plan named (drop _convertUnitValue / hardcoded m3/h<->m3/s scalars in
favour of policy.convert at every site).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the old 3-panel coresync-frost-demo.json with a 13-panel dashboard
designed for at-a-glance verification of CoreSync's compression behaviour.
Dashboard rebuild (docker/grafana/provisioning/dashboards/coresync-frost-demo.json):
- Header "How to read" text panel: definitions table + sanity checks so
every metric is line-of-sight to its Flux source.
- Scoreboard row (4 stats): raw samples / CoreSync knots / reduction % /
approx. bytes saved over the selected time range.
- Per-stream verification table: one row per CoreSync stream with raw,
knots, and reductionPct (gradient-coloured). Each line's math is
mentally checkable: raw × (1 − reductionPct/100) = knots.
- Signal-reconstruction overlays: flow (m³/h) and pressure (mbar)
rendered as a thin raw line plus fat red knot points so you can see
knots snap to the raw signal at direction changes. Fixes the previous
panels which mislabelled both as `flowm3h` regardless of units.
- Diagnostics row: per-stream knot-interarrival timeseries and a
full-math compression-health table (raw, knots, kept fraction with
gradient bar, savedPct with colour background).
Bumps coresync submodule to 21d77a8 which lands the FROST demo flow plus
the burst-window reducer fix that was driving cog/efficiency/SEC to ~0%
compression. Verified end-to-end on the live stack: headline reduction
went from 33% to 83%, broken streams from 0.6%-14% to 78%-93%.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Front-loads gap discovery before /grill-me by adding two skills:
research MOSTLY fans out Explore + WebSearch agents in parallel,
synthesizes findings into a brief, names open
unknowns explicitly (which become /prototype targets)
prototype MOSTLY builds a throwaway spike to test ONE falsifiable
assumption; code lives in .prototypes/ (gitignored),
never promoted; output is evidence — verdict, numbers,
observed behavior — that feeds /prd
Full chain now:
/research → /prototype → /grill-me → /prd → /prd-to-issues → /ship-it
Chain rationale: /research and /prototype surface knowledge gaps and falsify
risky assumptions while the cost of changing direction is still cheap; the
TOGETHER phases (grill-me, prd) lock down the contract; the AFK phase
(ship-it) only executes against contracts already on paper.
The chain is a default, not a mandate — README covers when to skip
upstream skills for small or stack-familiar work.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Four workflow skills that take a feature from fuzzy idea to merged code.
Two human-in-the-loop phases (grill-me, prd), one mostly-together (prd-to-issues
files only on explicit 'create'), and one AFK (ship-it).
grill-me TOGETHER pressure-test the idea with hard interview questions
prd TOGETHER synthesize PRD; gaps stay explicit, not papered over
prd-to-issues MOSTLY thin vertical-slice issues with coverage matrix +
per-issue Slice check; self-audits before showing
ship-it AFK shell loop ships each slice end-to-end with one
commit per issue, status streams to terminal,
Ctrl-C-able, survives session close
Vertical-slice principle throughout: every issue cuts end-to-end through every
integration layer (no horizontal "do all the DB work first" issues). The
AFK loop only ships against acceptance criteria already locked in by the PRD
phase — autonomous code never runs against undefined contracts.
ship-it tracker support: gh (GitHub) and tea (Gitea). For this repo, set
SHIP_IT_TRUNK=development to override the main default.
See .claude/skills/README.md for the full how-to and a worked example.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PALETTE REDESIGN (2026-05-21)
Sidebar swatches switched from S88 level (all blue) to domain-hue per node.
Family hue = function (rotating=orange, valves=teal, biology=green/olive,
sampling=violet, sensor=amber, aeration=sky-blue, infrastructure=slate);
within a family, darker = higher S88 / "more controller-ish."
Editor-group rectangles in flow.json still follow S88 — only the
registerType colour changed.
Submodule bumps for palette: rotatingMachine, machineGroupControl,
pumpingStation, valve, valveGroupControl, reactor, settler, monster,
measurement, diffuser, dashboardAPI.
Docs touched:
- CLAUDE.md: palette swatch vs. editor-group bullets split out.
- .claude/rules/node-red-flow-layout.md: new §10.0 introduces the two
color systems, full 12-row palette table, and explicit warning not to
mix the two hexes.
- .claude/refactor/MODULE_SPLIT.md: per-node headers annotated with
both `group #XXX` and `palette #XXX`.
- .claude/refactor/WIKI_HOME_TEMPLATE.md + WIKI_TEMPLATE.md: clarify
Mermaid classDefs visualize hierarchy, not palette swatches.
- .claude/refactor/OPEN_QUESTIONS.md: dated decision entry with
rationale, file list, and follow-ups.
CORESYNC SUBMODULE (new)
nodes/coresync added pointing at https://gitea.wbd-rd.nl/RnD/coresync.
FROST/SensorThings handoff path — first version forwards FROST-ready HTTP
request messages on the dbase output; a downstream http-request node
performs the POST and feeds responses back on msg.topic = "frost.response".
Lazy stream resolver, latest-wins queue (keep first + latest, drop middle),
knot-emit on slope change, provenance preserved in Observation parameters.
- .gitmodules: add nodes/coresync entry.
- package.json: register coresync as a Node-RED node.
- generalFunctions bump: new frostFormatter + 4 node config schemas
expose the dbase format option.
- measurement bump: "frost" option added to dbaseOutputFormat dropdown
(plus the in-flight data.measurement unit-handling work).
- machineGroupControl bump: small editor compact-fields tweak alongside
the palette change.
- CORESYNC_FROST_INTERVIEW_HANDOFF.md added at root with interview state
(Q20 open: slope angle vs. relative delta comparison).
DASHBOARDAPI MODULE_NOT_FOUND FIX
package.json: dashboardapi entry path corrected to
nodes/dashboardAPI/dashboardAPI.js. Commit e04c4a1 renamed the files to
camelCase but missed package.json; on case-sensitive filesystems
(Linux/Docker, where the tarball lands) the require resolved to nothing
and the node showed MODULE_NOT_FOUND in the Node-RED palette.
MISC CLEANUP
- examples/README.md + examples/pumpingstation-complete-example/ removal
(build_flow.py, flow.json, README.md superseded by per-node examples).
- jest.config.js: in-progress tweak.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Submodule pointer:
- rotatingMachine @ 8c5822c
style(editor): drop fixed max-width on rotor SVG — let it fill the panel
Repo hygiene:
- Add .repo-mem/, .codex, CLAUDE.local.md to .gitignore. These are
per-developer Claude Code state (memory store, IDE marker, per-machine
conventions) that shouldn't ever land in the repo. .repo-mem alone is
hundreds of MB on disk.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The root EVOLV package was 175.8 MB because npm pack at the parent walks
the full file tree and IGNORES per-submodule .npmignore files. The
.gitignore fallback wasn't enough — it left .repo-mem/ (838 MB on disk),
.claude/, .agents/, .codex, every submodule's wiki + tests + simulation
harness, and the per-submodule CLAUDE.md files in the tarball.
This .npmignore mirrors .gitignore for the dev-artifact baseline and then
adds two more layers:
1. Repo-level dev tooling that .gitignore doesn't cover (tools/,
docker/, scripts/, test/, wiki/, .repo-mem/, .claude/, …).
2. Per-submodule dev-only trees under nodes/*/ — necessary because npm
pack at the root doesn't honour the submodule's own .npmignore.
After: 1.6 MB tarball, 498 files, runtime content only (entry .js + .html,
src/, package.json, examples/, generalFunctions datasets + coolprop.wasm,
per-node README/LICENSE/CONTRACT). Removes the
"npm warn gitignore-fallback" warning.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Submodule pointer updates:
- generalFunctions @ ae30cef
feat(pumpingStation schema): add holdLevel + deadZoneKeepAlivePercent;
slim npm pack
- machineGroupControl @ aeb938c
feat(setDemand): surface specificClass.setDemand(value, unit='%')
+ slim npm pack
- pumpingStation @ 2e4ad8d
fix(levelBased): drop hold zone, route through MGC.setDemand, add
holdLevel + integrator variant pick; slim npm pack
Cross-submodule summary:
- pumpingStation level-based control now sends percent demand to MGC via
the new MGC.setDemand entry point — was calling handleInput with a raw
percent, which the dispatcher interpreted as canonical m³/s and pegged
the group at 100 %.
- Ramp foot is no longer pinned at inflowLevel. Default is startLevel
(0 % at startLevel = MGC flow.min, matching operator mental model). New
optional holdLevel raises the 0 %-foot for an explicit hold band.
- Predicted-volume integrator now picks the best-available variant per
side (measured first, then predicted) so a real upstream sensor +
predicted pump outflow both feed the basin balance.
- Each submodule grew a .npmignore mirroring its .gitignore plus the
dev-only trees (test/, wiki/, .claude/, …). Per-submodule pack sizes
dropped — pumpingStation went 1.5 MB → 57 kB.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two trailing items the prior commits missed:
- .mcp.json was rm'd from the working tree in commit d4e72f2 (repo-mem
cleanup) but never staged for deletion; git status kept showing
' D .mcp.json' as a result. Properly removed now.
- nodes/pumpingStation pin bumps to pull in the wiki-gen regen commit
that kept Reference-Contracts.md in sync with the tool's canonical
output.
User WIP intentionally not touched: examples/README.md zeroed-out,
examples/pumpingstation-complete-example/* removed, and
nodes/rotatingMachine working-tree change to rotatingMachine.html.
Those belong to the user; the harness only re-flagged them.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Superproject:
- CLAUDE.md: legacy-drift table loses the dashboardAPI row (migrated);
drift section notes the type-id-preservation strategy for the
remaining mgc / vgc renames.
- CONTRACTS.md: canonical-unit rule explicitly carves out reactor as
an approved ASM-textbook exception with the conversion boundary.
Submodules:
- nodes/valve @ 167b102: CONTRACT documents valve's lack of an FSM
maintenance state (schema mode enum accepts `maintenance` but no
enter/exit sequences exist). Limits made explicit instead of being
hidden as a wiki TODO.
- nodes/reactor @ 75d0413: CONTRACT now declares the approved ASM-unit
divergence (mg/L, m³/d, °C, 1/h) with the conversion boundary spelled
out. Closes the canonical-unit drift surfaced by the wiki audit.
- nodes/dashboardAPI @ ......: file rename (preserves type id).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>