Files
EVOLV/.claude/refactor/Archive/TASKS.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

16 KiB
Raw Permalink Blame History

Task list — ARCHIVED

Warning

ARCHIVED — Phases 111 landed on development in May 2026. This file is the original phased plan and is retained for history. For deferred / open work, see ../OPEN_QUESTIONS.md. For current standards, start at ../../../CONTRACTS.md (EVOLV root).

Phased and ordered. The TaskCreate tracker mirrors this list and is the active, mutable view; this file is the durable plan.

A task is done when:

  • The code matches the contracts in CONTRACTS.md.
  • All the affected node's tests are green (node --test test/basic test/integration test/edge).
  • A short note is appended in the task tracker if anything was deferred to OPEN_QUESTIONS.md.

Phase 1 — generalFunctions additive infra

Goal: add the new platform pieces. Nothing is removed; nothing existing changes shape. All existing nodes continue to work unchanged.

# Task Notes
1.1 Add src/domain/UnitPolicy.js + tests Extracted from rotatingMachine._buildUnitPolicy.
1.2 Add src/domain/ChildRouter.js + tests Built on existing childRegistrationUtils.
1.3 Add src/domain/LatestWinsGate.js + tests Extracted from MGC _dispatchInFlight/_delayedCall.
1.4 Add src/domain/HealthStatus.js + tests Standardise the {level, flags, message, source} shape.
1.5 Add src/domain/BaseDomain.js + tests Constructor boilerplate; calls subclass configure()/_init().
1.6 Add src/nodered/commandRegistry.js + tests Topic dispatch + alias warnings.
1.7 Add src/nodered/statusBadge.js + tests compose, error, idle, byState helpers.
1.8 Add src/nodered/statusUpdater.js + tests 1 Hz poller calling source.getStatusBadge().
1.9 Add src/nodered/BaseNodeAdapter.js + tests The thing every nodeClass extends.
1.10 Add src/stats/index.js + tests Promote mean/stdDev/median/mad/lerp from measurement.
1.11 Update generalFunctions/index.js (additive) New exports under existing pattern.
1.12 Run all 12 nodes' tests against the bumped generalFunctions Sanity gate before phase 2.

Phase-1 commit cadence: one commit per task on the development branch of generalFunctions. Submodule pointer in parent EVOLV bumps once at end of phase.

Phase 2 — pumpingStation pilot

Goal: prove the new infrastructure end-to-end. Pumping station is a mid-complexity node — bigger than measurement, smaller than the curve-driven nodes.

# Task Notes
2.1 Move standalone demo from specificClass.js to examples/standalone-demo.js Pure deletion + move; tests unchanged.
2.2 Extract basin/ (BasinGeometry + thresholdValidator) Pure functions.
2.3 Extract measurement/flowAggregator.js (incl. _updatePredictedVolume) Centerpiece of the tick loop.
2.4 Extract measurement/measurementRouter.js + measurement/calibration.js
2.5 Extract control/ strategies + dispatcher levelBased, flowBased (stub), manual.
2.6 Extract safety/safetyController.js dryRunRule + overfillRule split internally.
2.7 Add getStatusBadge() on PumpingStation; remove badge logic from nodeClass
2.8 Convert nodeClass.js to extend BaseNodeAdapter
2.9 Convert specificClass.js to extend BaseDomain Use ChildRouter, UnitPolicy.
2.10 Extract commands/ registry + handlers Old topic names become aliases.
2.11 Extract editor.js from pumpingStation.html (the SVG redraw logic) Served via a /pumpingStation/editor.js admin endpoint.
2.12 Generate CONTRACT.md from commands/ + handwritten events section
2.13 Tests: 3-tier per extracted module + the existing suite still green Add edge tests for any regression discovered.
2.14 Docker E2E (deploy 01-basic/02-integration/03-dashboard flows on a running Node-RED) Required for "trial-ready" claim.

Phase 3 — measurement

# Task Notes
3.1 Promote stats helpers to generalFunctions/src/stats/ (already done in 1.10)
3.2 Convert analog mode to use Channel internally (with key=null) Removes the ~400-line inline pipeline duplication.
3.3 Extract simulation/simulator.js
3.4 Extract calibration/calibrator.js
3.5 Add getStatusBadge() on Measurement
3.6 Convert nodeClass.js to BaseNodeAdapter; specificClass.js to BaseDomain
3.7 Extract commands/
3.8 CONTRACT.md
3.9 Tests + Docker E2E

Phase 4 — machineGroupControl

# Task Notes
4.1 Extract groupOps/ (groupOperatingPoint + groupCurves) The cluster of _group* helpers.
4.2 Extract totals/totalsCalculator.js
4.3 Extract combinatorics/pumpCombinations.js
4.4 Extract optimizer/bestCombination.js + optimizer/bepGravitation.js
4.5 Extract efficiency/groupEfficiency.js
4.6 Extract dispatch/demandDispatcher.js using LatestWinsGate Replaces _dispatchInFlight/_delayedCall directly.
4.7 Add getStatusBadge()
4.8 Convert nodeClass + specificClass to base classes; use ChildRouter
4.9 commands/ + CONTRACT.md
4.10 Tests + Docker E2E

Phase 5 — rotatingMachine

# Task Notes
5.1 Extract curves/ (loader + normalizer + reverseCurve)
5.2 Extract prediction/ (predictors + groupPredictors + operatingPoint)
5.3 Extract drift/ using HealthStatus
5.4 Extract pressure/ (virtual children + initialization + router)
5.5 Extract state/stateBindings.js (adapter to existing generalFunctions/state)
5.6 Extract measurement/measurementHandlers.js
5.7 Extract flow/flowController.js
5.8 Extract display/workingCurves.js
5.9 Add getStatusBadge() (replaces the 100-line nodeClass version)
5.10 Convert nodeClass + specificClass
5.11 commands/ + CONTRACT.md
5.12 Tests + Docker E2E

Phase 6 — remaining nodes

For each: skeleton refactor only — extend BaseNodeAdapter + BaseDomain, use ChildRouter, move the input switch to commands/, add getStatusBadge(). Domain-specific module split only if specificClass > 300 lines after the platform refactor.

# Task
6.1 valve
6.2 valveGroupControl
6.3 diffuser
6.4 monster
6.5 settler
6.6 reactor
6.7 dashboardAPI (special — likely no BaseDomain, it's a passive HTTP server)

These are parallelisable — each can be its own agent.

Phase 7 — remove legacy topic aliases

Note: canonical names (set.*, cmd.*, data.*, child.*, query.*, evt.*) are used from Phase 1 onwards — see CONTRACTS.md §1. Each commands/index.js declares the canonical name as topic and lists pre-refactor names in aliases. So Phase 7 is just the deprecation-window sweep.

# Task Notes
7.1 Audit aliases across all commands/ files; confirm one release cycle has elapsed If any alias was added recently, defer that node's removal another cycle.
7.2 Remove aliases entries; canonical name only Each removal is a single PR.
7.3 Update example flows that still used legacy names Should already have been updated in their phase.
7.4 Document the removal in each CONTRACT.md "Removed legacy topic X (replaced by canonical Y) on YYYY-MM-DD".

Phase 8 — promotion to main

When every node is on the new infra and Docker E2E green:

  1. Bump submodule pointers in parent EVOLV development.
  2. Open a PR per submodule (developmentmain).
  3. Open the parent EVOLV PR last (developmentmain).
  4. Merge in dependency order (generalFunctions first, then nodes that depend on it, finally EVOLV).

Phase 8.5 — generalFunctions deprecated path cleanup

Removes the deprecated paths flagged in OPEN_QUESTIONS.md. Runs after promotion to main (so callers have stopped depending on the old paths via the platform's own consumers).

Targets to remove

Path Replaced by First flagged
src/helper/menuUtils_DEPRECATED.js src/menu/ (the active menu manager) pre-refactor
loadCurve export (in index.js + datasets/assetData/curves/) loadModel pre-refactor
Any *_DEPRECATED.* file added during the refactor (per-file note) refactor

Tasks

# Task Notes
8.5.1 Audit consumers of loadCurve across all nodes Should be zero after Phase 5 (rotatingMachine) — verify.
8.5.2 Remove loadCurve export + the underlying file Single PR. Test all nodes.
8.5.3 Remove menuUtils_DEPRECATED.js Verify zero imports first.
8.5.4 Sweep generalFunctions/src/ for _DEPRECATED.* files; remove with consumer audit One PR per file.
8.5.5 Update generalFunctions README to drop deprecated references

Phase 9 — wiki cleanup (post-refactor)

Goal: each node's gitea wiki becomes visual-first, scannable, and follows one shared template. Today's wiki has lots of prose and varies per node — once the platform is uniform, the wiki should be too.

Don't start phase 9 until phase 8 is done (the wiki documents the post-refactor shape, not the in-flight transition).

Standard wiki template (one file per node, this is the spec)

1. One-paragraph "what is this node" (≤ 60 words).
2. Position in the platform — a Mermaid block showing the node and its
   typical neighbours (parent + child types, with arrows for
   data direction).
3. Capability matrix — small table of "what this node can do" with
   ✅ / ❌ / partial.
4. Topic contract — auto-generated from src/commands/index.js
   (set.* / cmd.* / evt.* / data.* — payload schema and example).
5. Output payload — a Mermaid sequence-diagram of a typical tick
   (parent → child → measurement → tick → port-0 emit).
6. Configuration — a Mermaid block diagram of the editor form sections
   plus a table mapping each form field to the config key it lands at.
7. Examples — links to examples/01-basic, 02-integration, 03-dashboard
   with one screenshot each.
8. State / mode chart — Mermaid stateDiagram for any node with
   non-trivial states (rotatingMachine, pumpingStation, MGC).
9. "When you would NOT use this node" — explicit non-goals.
10. Issues / known limitations — single-line items with links to
    repo issues.

Tasks

# Task Notes
9.1 Author the canonical wiki template at .claude/refactor/WIKI_TEMPLATE.md Source of truth.
9.2 Build the auto-generator: commands/index.js → "Topic contract" markdown section Run via a small npm run wiki:contract script per node.
9.3 Pilot on pumpingStation wiki: replace existing pages with the new template Visual-first, prune prose.
9.4 Apply to other 3 core nodes (measurement, MGC, rotatingMachine)
9.5 Apply to remaining nodes (one per repo)
9.6 Update parent EVOLV wiki: top-level platform overview with a Mermaid block of all 13 nodes and how they connect (S88 hierarchy + data direction)
9.7 Add a wiki style guide (max prose per section, where Mermaid is required, screenshot conventions)
9.8 Audit pass: every page renders, every Mermaid block compiles, every link resolves

Visual primitives we'll lean on (Mermaid)

  • flowchart LR — node connections (parent ↔ child, data direction).
  • sequenceDiagram — tick-to-port-0 lifecycle.
  • stateDiagram-v2 — rotatingMachine / pumpingStation state machines.
  • erDiagram — only if a node has a complex internal data model worth visualising.

Skip: classDiagram (we don't expose classes to users); gantt (no schedules in a node's docs).

Hard rules

  • Every page leads with the Mermaid platform-position block. No "intro paragraph then later a diagram" — diagram first.
  • Each section opens with the diagram or table; prose annotates the visual, not the other way round.
  • No more than 60 words of unbroken prose anywhere on a page.
  • One canonical source of truth for the topic contract: commands/index.js. The wiki page is generated from it. No hand-written drift.

Phase 10 — test-suite refactor (post-wiki)

Goal: bring every node's test layout in line with CONVENTIONS.md §Testing now that the platform is uniform. Pre-existing test debt logged in OPEN_QUESTIONS.md gets cleaned up here.

Tasks

# Task Notes
10.1 Audit each node: basic / integration / edge split, naming, helpers One pass; produce a per-node punch list.
10.2 Convert any Mocha-style tests (describe/it) to node:test Specifically dashboardAPI/test/basic/structure-module-load.basic.test.js.
10.3 Address reactor mathjs load (per OPEN_QUESTIONS): tree-shake or hoist If hoisted, document the pattern as a CONVENTION addition.
10.4 Promote shared test helpers to generalFunctions/test/helpers/ Common fakes: fake Node-RED node, fake child, fake RED.
10.5 Add missing edge tests for each refactored module flagged during P2-P5 Edge cases discovered during refactor land here.
10.6 Make every basic-test runner exit cleanly in batch (node --test test/basic/) No leaked timers, no real setInterval outliving the assertions. Mirrors the BaseNodeAdapter test fix.
10.7 Standard CI shape: each node has npm run test:basic, test:integration, test:edge (consistent across nodes) Allows uniform CI invocation.
10.8 Audit pass: every node's test suite green in batch under one wall-clock budget (≤ 60 s for basic) The new platform-wide gate.

Phase 11 — unit-aware commands

Goal: every numeric setter / data topic carries an explicit unit; the user can supply any compatible unit and the commandRegistry normalises before the handler runs. Unknown units warn + list accepted alternatives.

Tasks

# Task Notes
11.1 generalFunctions/src/convert/: add possibilities(measure) helper Returns the list of accepted unit names for a measure (volumeFlowRate, pressure, etc.).
11.2 generalFunctions/src/nodered/commandRegistry.js: handle descriptor.units Normalisation pipeline: extract value+unit from msg, validate against units.measure, convert to units.default, warn + fall back on bad input. Tests for all 4 paths (no-unit / valid / wrong-measure / unknown).
11.3 generalFunctions/src/nodered/BaseNodeAdapter.js: auto-wire query.units topic Returns { topic → { measure, default, accepted: [...] } } from the registry. No per-node wiring needed.
11.4 generalFunctions/scripts/wikiGen.js: render units column Topic-contract auto-gen table grows a Unit column showing measure (default <unit>).
11.5 Per-node src/commands/index.js: declare units on every numeric setter ~10 nodes. See proposed default-units table in interview reply.
11.6 Regenerate every CONTRACT.md + wiki Home.md via npm run wiki:all Automated.
11.7 Tests: commandRegistry unit-handling paths 4 scenarios per the validation table.

Default units per topic (proposed)

Topic Default Why
pumpingStation set.inflow m3/h Operator-friendly scale
pumpingStation set.demand m3/h same
pumpingStation set.outflow m3/h symmetric
pumpingStation cmd.calibrate.volume m3 basin volume
pumpingStation cmd.calibrate.level m basin height
MGC set.demand m3/h matches PS
rotatingMachine set.setpoint % control%
rotatingMachine set.flow-setpoint m3/h flow target
rotatingMachine data.simulate-measurement per payload.type dispatch by sensor type
valve set.position % valve open-%
measurement data.measurement mode-dependent analog → Channel scaling; digital → per-channel cfg
monster data.flow m3/h already enforced
reactor data.influent flow=m3/h, concentrations=mg/L engine internals
settler data.influent flow=m3/h, concentrations=mg/L matches reactor
diffuser data.flow m3/h air flow scale