Files
EVOLV/CONTRACTS.md
znetsixe d4e72f280e docs: retire repo-mem MCP, migrate skills to .claude/skills, audit fixes
- Delete .mcp.json + .claude/rules/repo-mem.md; drop .repo-mem from .gitignore
- Remove repo-mem / substrate_score / repo_search references from all .md
- Move 15 EVOLV skills from .agents/skills/ to .claude/skills/ so they are
  auto-discovered by the Claude Code harness and invokable via the Skill tool
- Retire .agents/skills/evolv-orchestrator (duplicate of the subagent at
  .claude/agents/evolv-orchestrator.md); orchestrator lives as a subagent only
- Drop OpenAI-format agent yaml metadata from each skill (not needed for CC)
- Update CLAUDE.md, CONTRACTS.md, AGENTS.md to point at the new locations and
  disambiguate skills (.claude/skills/) vs subagents (.claude/agents/)
- Fix CLAUDE.md tick-loop wording (opt-in per-node, not a fixed 1000ms)
- Widen .claude/rules/ paths frontmatter so node-architecture and telemetry
  rules trigger on more relevant files; add frontmatter to flow-layout rule
- Bump CONTRACTS.md review date to 2026-05-19; add step 7 to the contract-
  change workflow (review example flows when topic usage changes)
- Bump nodes/generalFunctions pin (Home.md substrate_score reference removed)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 09:30:49 +02:00

8.6 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 .claude/skills/ (15 domain skills, auto-discovered, invokable via Skill tool) When you need domain reasoning
Spawnable subagents .claude/agents/ (10 Claude Code subagents) When you want to delegate independent work
Routing table .agents/AGENTS.md When deciding which specialist to invoke
Improvements backlog .agents/improvements/IMPROVEMENTS_BACKLOG.md When deferring functional work

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.
  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 grep / find or the Explore subagent — anchor on the canonical sources listed in §1 (commands registry, CONTRACT.md, base classes in generalFunctions/).

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.
  7. If topic usage in an example flow changed, regenerate or review the per-node wiki/Reference-Examples.md and the examples/*.flow.json set.

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-19. If something in this map is wrong, fix this file in the same PR as the change that made it wrong.