Wave B1: bump submodule pointers + 5 OPEN_QUESTIONS resolved

generalFunctions f117546 → <new>  B2.3 fireAndWait + P11.1 possibilities
                                    + P11.2 commandRegistry.units + monster schema
  measurement      e6e212a → <new>  B1.3 isStable threshold
  monster          2aa7f88 → <new>  B1.4 cooldown-guard root-cause fix
  machineGroupControl 0e8cab5 → <new>  B2.3 fireAndWait migration

OPEN_QUESTIONS marked RESOLVED in the decisions table:
  isStable tautology, monster cooldown-guard, LatestWinsGate fireAndWait

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
znetsixe
2026-05-11 17:29:23 +02:00
parent 30928ce378
commit 6bf94f4c8a
5 changed files with 55 additions and 15 deletions

View File

@@ -13,7 +13,7 @@ decision during refactor work writes it here rather than guessing.
| Ramp foot for run-zone curve (control/levelBased) | `inflowLevel` (current). startLevel is the 0% minimum, not the curve foot. | | Ramp foot for run-zone curve (control/levelBased) | `inflowLevel` (current). startLevel is the 0% minimum, not the curve foot. |
| `overfillLevel` vs `highVolumeSafetyLevel` | **`highVolumeSafetyLevel` canonical**; drop the legacy alias. | | `overfillLevel` vs `highVolumeSafetyLevel` | **`highVolumeSafetyLevel` canonical**; drop the legacy alias. |
| measurement `isStable` tautology | Fix now with a config-driven absolute threshold (`stabilityThreshold` in scaling-units). Add to schema + editor UI. | | measurement `isStable` tautology | Fix now with a config-driven absolute threshold (`stabilityThreshold` in scaling-units). Add to schema + editor UI. |
| monster cooldown-guard pre-existing fail | Debug + fix the sampling-pulse logic. | | monster cooldown-guard pre-existing fail | **RESOLVED 2026-05-11** — root cause was missing `nominalFlowMin`/`flowMax`/`maxRainRef`/`minSampleIntervalSec` in `monster.json`, stripped by `configUtils.initConfig` before reaching the domain. Added the four keys to the schema. |
| pumpingStation plain child dicts | Migrate to `declareChildGetter`; rewrite affected tests. | | pumpingStation plain child dicts | Migrate to `declareChildGetter`; rewrite affected tests. |
| VGC custom `registerChild` overload | Adopt ChildRouter; rewrite disambiguation tests. | | VGC custom `registerChild` overload | Adopt ChildRouter; rewrite disambiguation tests. |
| MGC inline dispatch gate vs LatestWinsGate | Extend LatestWinsGate with `fireAndWait(value)` returning the per-fire settlement promise. Migrate MGC. | | MGC inline dispatch gate vs LatestWinsGate | Extend LatestWinsGate with `fireAndWait(value)` returning the per-fire settlement promise. Migrate MGC. |
@@ -240,7 +240,26 @@ Tracked; not blocking the refactor.
--- ---
## 2026-05-10 — measurement `isStable` tautology (pre-existing bug) ## 2026-05-10 — measurement `isStable` tautology (pre-existing bug) — RESOLVED
**Resolution (2026-05-11):** Replaced the tautological `stdDev < stdDev*2`
check with a config-driven absolute threshold. New schema field
`calibration.stabilityThreshold` (number, ≥ 0, default `0.01` in
scaling-units) added to `generalFunctions/src/configs/measurement.json` so
all callers see it. `Calibrator.isStable()` now returns `true` when
`stdDev === 0` or `stdDev <= threshold`, falling back to the default when
the config slot is missing or non-numeric. The two BUG-PRESERVED calibrator
tests were rewritten — high-variance buffers now correctly report unstable
under the default and only flip to stable when an explicit relaxed
threshold is supplied. Added edge tests for the relaxed-threshold path,
constant-buffer-with-zero-threshold path, just-above-threshold path, and
missing-config fallback. `nodeClass.buildDomainConfig` and
`measurement.html` (defaults + form field + oneditsave) propagate the UI
value through to the domain. 100/100 measurement tests pass; 70/70
generalFunctions basic tests pass.
### Original entry below
## 2026-05-10 — measurement `isStable` tautology (pre-existing bug) (history)
**Context:** P3.4. The existing `isStable` in `measurement/src/specificClass.js` does: **Context:** P3.4. The existing `isStable` in `measurement/src/specificClass.js` does:
@@ -470,27 +489,48 @@ asserting against the resulting `node._sent` / `node._statuses`.
--- ---
## 2026-05-10 — monster schema strips command-line constraint keys ## 2026-05-10 — monster schema strips command-line constraint keys — RESOLVED 2026-05-11
**Context:** P6.3. The monster JSON schema in `generalFunctions/src/configs/monster.json` defines `samplingtime`, `minVolume`, `maxWeight` and others under `constraints`, but NOT `nominalFlowMin`, `flowMax`, `maxRainRef`, `minSampleIntervalSec`. `configUtils.initConfig` strips these unknown keys with a `Unknown key … Removing it.` warning. The legacy code read them anyway — `Number.isFinite(undefined)` returns false, so guards naturally route into invalid-bounds territory and tests pass via the undefined cascade. **Context:** P6.3. The monster JSON schema in `generalFunctions/src/configs/monster.json` defines `samplingtime`, `minVolume`, `maxWeight` and others under `constraints`, but NOT `nominalFlowMin`, `flowMax`, `maxRainRef`, `minSampleIntervalSec`. `configUtils.initConfig` strips these unknown keys with a `Unknown key … Removing it.` warning. The legacy code read them anyway — `Number.isFinite(undefined)` returns false, so guards naturally route into invalid-bounds territory and tests pass via the undefined cascade.
**Default chosen:** Preserved — refactor reads the same stripped fields the same way. The schema warning is harmless but noisy in test output. **Resolution (2026-05-11, B1.4):** Added the four missing fields (`nominalFlowMin`, `flowMax`, `maxRainRef`, `minSampleIntervalSec`) to the `constraints` section of `generalFunctions/src/configs/monster.json` with sensible defaults (0/0/10/60). The unknown-key warning disappears and user-supplied values now propagate through validation to the domain, restoring the documented sampling behaviour.
**Decision needed by:** Phase 7 (topic-name standardisation) — add the four missing constraint keys to the schema, OR move them into a `samplingControl` section. Either fix removes the warning and lets the values actually pass through.
--- ---
## 2026-05-10 — monster sampling-guards cooldown test fails on development (pre-existing) ## 2026-05-10 — monster sampling-guards cooldown test fails on development (pre-existing) — RESOLVED 2026-05-11
**Context:** P6.3 baseline run. `test/edge/sampling-guards.edge.test.js` "cooldown guard blocks pulses when flow implies oversampling" already fails on `development` BEFORE the refactor (`assert.ok(monster.sumPuls > 0)` — sumPuls stays at 0 across 80 ticks). The legacy in-file equivalent in `test/monster.test.js` (Mocha-style wrapper, not picked up by `node:test`) appears to have passed in an earlier era. **Context:** P6.3 baseline run. `test/edge/sampling-guards.edge.test.js` "cooldown guard blocks pulses when flow implies oversampling" already fails on `development` BEFORE the refactor (`assert.ok(monster.sumPuls > 0)` — sumPuls stays at 0 across 80 ticks). The legacy in-file equivalent in `test/monster.test.js` (Mocha-style wrapper, not picked up by `node:test`) appears to have passed in an earlier era.
**Default chosen:** Refactor preserves behaviour byte-for-byte — same failure remains, same line. Not a refactor regression. **Resolution (2026-05-11, B1.4):** Root cause was the schema-stripping issue documented immediately above — `nominalFlowMin`/`flowMax`/`minSampleIntervalSec` were stripped by `configUtils.initConfig` before reaching the domain, so `validateFlowBounds` saw NaN/NaN and routed every `i_start` into the invalid-bounds early return, which prevented `_beginRun` from ever firing. With the four constraint keys now declared in `monster.json`, the test config propagates intact: `_beginRun` runs, the m3PerTick integrator accumulates ~0.056 m3/tick, `temp_pulse` crosses 1 at tick ~18, the first pulse fires, subsequent pulses are correctly blocked by the 60 s cooldown, and `sumPuls > 0` / `missedSamples > 0` / `bucketVol > 0` / `getSampleCooldownMs() > 0` all hold. Added a guard-site comment in `parameters/parameters.js#validateFlowBounds` pointing back at the schema contract. All 10/10 monster tests green.
**Decision needed by:** Phase 10 (test-suite refactor) — fix the test OR debug the underlying behaviour (likely the interaction between `_beginRun` resetting state inside the same `sampling_program` call that the integrator then runs, leaving the first second's m3PerTick stranded).
--- ---
## 2026-05-10 — MGC handleInput retained inline latest-wins (not DemandDispatcher) ## 2026-05-10 — MGC handleInput retained inline latest-wins (not DemandDispatcher) — RESOLVED
**Resolution (2026-05-11):** Extended `LatestWinsGate` with
`fireAndWait(value)` that returns a per-fire settlement promise. A
parked call superseded by a later fire resolves with the frozen
sentinel `LatestWinsGate.SUPERSEDED = { superseded: true }` (not a
reject) so callers branch on a value without try/catch. Dispatch
errors still resolve the promise (with `undefined`) and surface via
`gate.lastError`.
MGC's `handleInput` now delegates to `DemandDispatcher.fireAndWait`;
the inline `_dispatchInFlight` + `_delayedCall` block is gone.
`turnOffAllMachines` calls `cancelPending()` on the dispatcher
instead of zeroing `_delayedCall`. `LatestWinsGate.js` 75 → 116 lines
(under the 150 cap). MGC `specificClass.js` net 14 lines.
The `turnoff-deadlock` test that pinned `_delayedCall` was rewritten
to assert against the parked `fireAndWait` resolving as superseded.
Other awaiting tests (`ncog-distribution`, `idle-startup-deadlock`,
`demand-cycle-walkthrough`) needed no change since `fireAndWait`
preserves the "await waits for the call's dispatch" shape for
non-superseded calls. All 77/77 MGC tests pass; 12/12 LatestWinsGate
basic tests pass.
### Original entry below
## 2026-05-10 — MGC handleInput retained inline latest-wins (not DemandDispatcher) (history)
**Context:** Wave 1 added `src/dispatch/demandDispatcher.js` wrapping **Context:** Wave 1 added `src/dispatch/demandDispatcher.js` wrapping
`LatestWinsGate`. Tests (`turnoff-deadlock`, `idle-startup-deadlock`, `LatestWinsGate`. Tests (`turnoff-deadlock`, `idle-startup-deadlock`,