diff --git a/CONTRACT.md b/CONTRACT.md new file mode 100644 index 0000000..d395318 --- /dev/null +++ b/CONTRACT.md @@ -0,0 +1,116 @@ +# generalFunctions — Library Contract + +> The public API surface that every EVOLV node depends on. Different shape from +> per-node `CONTRACT.md` files: nodes contract on `msg.topic`, this library +> contracts on **what `require('generalFunctions')` exports**. + +For deep contracts on the post-refactor platform shapes (`BaseDomain`, +`BaseNodeAdapter`, command registry, `UnitPolicy`, `ChildRouter`, +`LatestWinsGate`, `HealthStatus`, `statusBadge`), see the platform-level +[`.claude/refactor/CONTRACTS.md`](../../.claude/refactor/CONTRACTS.md) in the +EVOLV superproject. This file is the index and stability tag per export. + +**Stability tags:** +- `stable` — API change requires a deprecation cycle and a CONTRACT update here. +- `experimental` — may change without warning; do not depend on the exact shape in production code paths. +- `deprecated` — kept for backwards compatibility, slated for removal. + +--- + +## Platform base classes (post-refactor) + +| Export | Kind | Stability | Source | Spec | +|---|---|---|---|---| +| `BaseDomain` | class | stable | `src/domain/BaseDomain.js` | [.claude/refactor/CONTRACTS.md §3](../../.claude/refactor/CONTRACTS.md) — extend for all specific domain classes | +| `BaseNodeAdapter` | class | stable | `src/nodered/BaseNodeAdapter.js` | [.claude/refactor/CONTRACTS.md §2](../../.claude/refactor/CONTRACTS.md) — extend for all nodeClass adapters | +| `CommandRegistry` / `createRegistry` | class / factory | stable | `src/nodered/commandRegistry.js` | [.claude/refactor/CONTRACTS.md §4](../../.claude/refactor/CONTRACTS.md) — builds `Map` | +| `ChildRouter` | class | stable | `src/domain/ChildRouter.js` | [.claude/refactor/CONTRACTS.md §5](../../.claude/refactor/CONTRACTS.md) — declarative parent-side child routing | +| `UnitPolicy` | class | stable | `src/domain/UnitPolicy.js` | [.claude/refactor/CONTRACTS.md §6](../../.claude/refactor/CONTRACTS.md) — canonical-unit declaration + render | +| `statusBadge` | function | stable | `src/nodered/statusBadge.js` | [.claude/refactor/CONTRACTS.md §7](../../.claude/refactor/CONTRACTS.md) — Node-RED status text/colour | +| `StatusUpdater` | class | stable | `src/nodered/statusUpdater.js` | Drives `node.status()` every tick | +| `HealthStatus` | class | stable | `src/domain/HealthStatus.js` | [.claude/refactor/CONTRACTS.md §9](../../.claude/refactor/CONTRACTS.md) — prediction-quality / drift state | +| `LatestWinsGate` | class | stable | `src/domain/LatestWinsGate.js` | Idempotent-setter gate; prevents redundant dispatches | + +## Output formatting + +| Export | Kind | Stability | Source | Notes | +|---|---|---|---|---| +| `outputUtils` | object | stable | `src/helper/` (re-export) | `.formatMsg(payload, mode)`; `mode ∈ {'process','influxdb'}`; delta compression on `'process'` | +| `logger` | object | stable | `src/helper/` (re-export) | Structured logger — use instead of `console.log` | + +## Measurements + +| Export | Kind | Stability | Source | Notes | +|---|---|---|---|---| +| `MeasurementContainer` | class | stable | `src/measurements/` | Chainable `.type().variant().position(childId)` store; emits `..` on its `emitter` | +| `POSITIONS`, `POSITION_VALUES`, `isValidPosition` | const + helper | stable | `src/constants/positions.js` | Canonical position labels (`upstream`/`downstream`/`atequipment`/…) | + +## Configuration + +| Export | Kind | Stability | Source | Notes | +|---|---|---|---|---| +| `configManager` | class | stable | `src/configs/` | Loads node-specific JSON schemas from `src/configs/.json`; serves admin endpoint | +| `configUtils` | object | stable | `src/helper/` | Schema helpers used by `configManager` | +| `assetApiConfig` | object | stable | `src/configs/assetApiConfig.js` | Asset-registry HTTP backend config | +| `validation`, `assertions` | object | stable | `src/helper/` | Runtime validation primitives | +| `MenuManager` | class | stable | `src/menu/` | Dynamic editor dropdown endpoints | + +## Child registration + +| Export | Kind | Stability | Source | Notes | +|---|---|---|---|---| +| `childRegistrationUtils` | object | stable | `src/helper/` | The handshake utilities `BaseNodeAdapter` uses for parent-child wiring | + +## Conversion & physics + +| Export | Kind | Stability | Source | Notes | +|---|---|---|---|---| +| `convert` | object | stable | `src/convert/` | Unit conversions (used by `UnitPolicy`) | +| `Fysics` | class | stable | `src/convert/fysics.js` | Fluid/hydraulic helpers | +| `coolprop` | object | stable | `src/coolprop-node/src/index.js` | Thermodynamic property calculations | +| `gravity` | object | stable | `src/helper/` | Gravity constants and helpers | + +## Control & prediction + +| Export | Kind | Stability | Source | Notes | +|---|---|---|---|---| +| `PIDController` | class | stable | `src/pid/` | Standard PID; positional and velocity forms | +| `CascadePIDController` | class | stable | `src/pid/` | Cascaded outer/inner PID | +| `createPidController`, `createCascadePidController` | factory | stable | `src/pid/` | Convenience builders from config | +| `predict` | object | stable | `src/predict/` | Series prediction / smoothing | +| `interpolation` | object | stable | `src/predict/` | 1-D and 3-D interpolation primitives | +| `nrmse` | function | stable | `src/nrmse/` | Normalised RMSE metric (with profile variants) | +| `stats` | object | stable | `src/stats/` | Mean/variance/quantile helpers | +| `state` | object | stable | `src/state/` | Generic state-machine helpers | + +## Asset registry + +| Export | Kind | Stability | Source | Notes | +|---|---|---|---|---| +| `assetResolver` | singleton | stable | `src/registry/` | `.resolve(category, modelId)` — sync, case-insensitive, returns `null` on miss | +| `AssetResolver` | class | stable | `src/registry/` | Resolver type (for testing / alt backends) | +| `FileBackend`, `HttpBackend` | class | stable | `src/registry/` | Resolver backends | +| `loadCurve` | function | **deprecated** | `index.js` (shim) | Thin shim over `assetResolver.resolve('curves', ...)`. New code uses the resolver directly. | + +--- + +## Adding a new export + +1. Implement the module under `src//`. +2. Re-export it from `index.js` (alphabetical within the concern block). +3. Add a row to the appropriate table above with the stability tag. +4. If the export is a new platform shape (a new base class or cross-node protocol), + add a section to [.claude/refactor/CONTRACTS.md](../../.claude/refactor/CONTRACTS.md) in the superproject. +5. Add a test under `test/`. + +## Removing an export + +1. Mark it **deprecated** in this file (keep the row, change the tag, add a "removed-in" line). +2. Update every consumer in `nodes/*` to use the replacement. +3. Bump submodule pin in the superproject for each touched node. +4. After one release on `development` with no consumers, remove the export and its row. + +--- + +*Source of truth for the export list: `index.js` (barrel). If this file and the +barrel disagree, the barrel wins — fix this file in the same PR.*