Files
EVOLV/CONTRACTS.md
Rene De Ren 253ac93896 docs: standards cleanup — single front-door CONTRACTS.md + archive stale plan artifacts
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>
2026-05-18 15:48:46 +02:00

8.4 KiB

EVOLV — Contracts, Rules, and Standards

Front door for humans and agents working in this repo. If you only read one file before touching code, read this one. It maps every contract, rule, and standard in the EVOLV stack and tells you where each lives. Everything else here is a link to a more specific file.

EVOLV is a Node-RED node library for wastewater treatment plant automation, built by Waterschap Brabantse Delta R&D. All work happens on the development branch across 12 submodules; promotion to main is gated by Docker E2E.


1. Where everything lives

Platform-wide (EVOLV root)

What Where Read when
This map CONTRACTS.md (this file) First time, or when orienting
Agent entry-point instructions CLAUDE.md Auto-loaded by Claude Code
Active rules .claude/rules/ (7 files) Triggered by paths: frontmatter or referenced from CLAUDE.md
Platform API contracts .claude/refactor/CONTRACTS.md Before changing generalFunctions exports or any base class
Code conventions .claude/refactor/CONVENTIONS.md Before writing or editing any file
Per-node concern layout .claude/refactor/MODULE_SPLIT.md When adding files to nodes/<n>/src/
Wiki page templates .claude/refactor/WIKI_TEMPLATE.md + WIKI_HOME_TEMPLATE.md When editing a per-node wiki page
Live decisions log .claude/refactor/OPEN_QUESTIONS.md When you spot an ambiguity — append, don't invent
Top-level wiki wiki/ (Home, Architecture, Getting-Started, Telemetry, Topology-Patterns, Topic-Conventions, Glossary, Functional-Overview) When you need a process-level or architecture-level view
Agent skills / routing .agents/AGENTS.md + .agents/skills/ When deciding which specialist to invoke
Improvements backlog .agents/improvements/IMPROVEMENTS_BACKLOG.md When deferring functional work
Repo-memory MCP rule .claude/rules/repo-mem.md Before any concept-search — use repo_search instead of grep

Per-node (nodes/<nodeName>/)

What Where Read when
Node entry instructions for agents nodes/<n>/CLAUDE.md Auto-loaded when touching files in that subtree
Node API contract nodes/<n>/CONTRACT.md Before changing msg.topic inputs/outputs/events
Command registry (source of truth) nodes/<n>/src/commands/index.js When adding/removing an accepted topic
Domain logic nodes/<n>/src/specificClass.js Pure JS; no RED.* allowed
Node-RED adapter nodes/<n>/src/nodeClass.js Bridge to runtime; ≤ 25 lines, extends BaseNodeAdapter
Per-node wiki nodes/<n>/wiki/Home.md, Reference-{Architecture,Contracts,Limitations,Examples}.md Topic-contract + data-model sections autogen via npm run wiki:all
Tests nodes/<n>/test/{basic,integration,edge}/ Required for every change
Example flows nodes/<n>/examples/{basic,integration,edge}.flow.json Required artifact per node

Shared library (nodes/generalFunctions/)

What Where
Library API contract nodes/generalFunctions/CONTRACT.md
Public exports nodes/generalFunctions/index.js (barrel)
Source nodes/generalFunctions/src/{domain,nodered,measurements,convert,configs,…}/

Archives (don't take as authoritative)

What Where Why kept
Pre-refactor wiki pages wiki/Archive/ (20 files) Historical reference; each has ⚠️ ARCHIVED — Do not update
Refactor plan artifacts .claude/refactor/Archive/CONTINUE_HERE.md, TASKS.md The May-2026 refactor plan; phases all done
Old priority lists .agents/improvements/Archive/ Pre-refactor production priorities

2. Discovery chain — how a fresh agent finds the rules

  1. CLAUDE.md auto-loads → points at this file and .claude/rules/repo-mem.md.
  2. .claude/rules/*.md auto-load by paths: frontmatter when editing matching files.
  3. nodes/<n>/CLAUDE.md auto-loads when working under that submodule.
  4. This file (CONTRACTS.md) is the human-facing map of everything in step 1-3.
  5. Concept lookup: use the repo-mem MCP server (repo_search, repo_similar_fixes) — it's faster and more targeted than grep. See .claude/rules/repo-mem.md.

3. The three contracts every node honours

Every EVOLV node is a three-tier sandwich. Each tier has a contract:

Tier Class Contract source Per-node implementation
1 — Entry RED.nodes.registerType .claude/rules/node-architecture.md nodes/<n>/<n>.js
2 — Adapter BaseNodeAdapter (from generalFunctions) .claude/refactor/CONTRACTS.md §2 nodes/<n>/src/nodeClass.js
3 — Domain BaseDomain (from generalFunctions) .claude/refactor/CONTRACTS.md §3 nodes/<n>/src/specificClass.js

Plus the commands registry (nodes/<n>/src/commands/index.js) declares the msg.topic inputs; BaseNodeAdapter dispatches by topic lookup. See .claude/refactor/CONTRACTS.md §4.


4. Output and telemetry contract

Three output ports per node. Source of truth: .claude/refactor/CONTRACTS.md §10 and wiki/Telemetry.md.

Port Carries Formatter
0 Process data (delta-compressed) outputUtils.formatMsg(..., 'process')
1 InfluxDB line protocol outputUtils.formatMsg(..., 'influxdb')
2 Registration / control plumbing hand-shaped on the parent-child handshake

Output-coverage testing (manifest + populated + degraded states) is mandatory for any change touching Port 0/1/2 keys, function-node fan-outs, or dashboard widgets. See .claude/rules/output-coverage.md.


5. When a contract changes — the rule

  1. Update the source file (src/commands/index.js, src/specificClass.js, or generalFunctions/index.js).
  2. Update the per-node CONTRACT.md (Inputs table is partially autogenerated; the rest is hand-maintained).
  3. Run npm run wiki:all inside the submodule to regenerate the topic-contract + data-model sections in wiki/.
  4. If the change touched a platform shape (a base class or shared utility), update .claude/refactor/CONTRACTS.md and nodes/generalFunctions/CONTRACT.md.
  5. If the change introduced a deprecation, add an alias to commands/index.js and a one-line note to the per-node CONTRACT.md.
  6. Append unresolved questions to .claude/refactor/OPEN_QUESTIONS.md. Don't invent answers.

6. Conventions in one paragraph (the rest is in CONVENTIONS.md)

Files ≤ 200 lines (300 hard cap); functions ≤ 30 lines (60 hard cap). Default to no comments — add one only when why is non-obvious. specificClass never imports RED.*. Logger from generalFunctions, never console.log. S88 colour scheme is mandatory in diagrams. Topic prefixes: set.<noun> for idempotent setters, cmd.<verb> for triggers, evt.<noun> for events. Tests live in test/{basic,integration,edge}/. Submodule commits go in the submodule first, then the superproject bumps the pin.


7. Verification checklist before merge

  • Per-node tests green (cd nodes/<n> && node --test test/basic test/integration test/edge).
  • CONTRACT.md updated for any added / removed / renamed topic, port-0 key, or event.
  • npm run wiki:all re-run in the touched submodule(s).
  • Output-coverage manifest + tests updated if any output shape changed.
  • Submodule pin bumped in the superproject.
  • Commit message captures why — load-bearing decisions go in the commit body and PR description.

Last reviewed: 2026-05-18. If something in this map is wrong, fix this file in the same PR as the change that made it wrong.