Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Added

- Allow the exact operator-declared Third Series Expert 2K-FA firmware values `Rel.26_03_24_A` and `Rel.08_06_26_A` on the existing model-, topology-, and STANDBY/RX-bound production fan path. Empty, mistyped, case-variant, or other firmware values advertise no modes and send no amplifier commands; the newer firmware evidence is limited to a read-only confirmation of unchanged setup and FAN NOISE topology.

### Fixed

- Preserve explicit `false` values for `serialAssertDTR` and `serialAssertRTS` across settings responses, config rewrites, unrelated settings saves, and restarts while retaining the existing `true` default for absent fields.
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ If no serial port is configured, the app starts in setup/fixture mode and the Se

The advanced `serialAssertDTR` and `serialAssertRTS` settings default to `true` when absent. Set them to `false` for transports such as PTYs or network serial bridges that do not support modem-control ioctls; explicit `false` values remain preserved across settings saves and restarts.

Third Series Expert 2K-FA production fan control additionally requires the operator-declared actual `fanPolicyFirmwareVersion` setting to equal `Rel.26_03_24_A` or `Rel.08_06_26_A` exactly. Status polling does not attest firmware, so empty, mistyped, case-variant, or other values advertise no supported modes and remain blocked before any amplifier command.

## API highlights

Canonical API routes live under `/api/v1/...`.
Expand Down Expand Up @@ -92,7 +94,7 @@ The app also serves:

Manual Fan Boost, Fan Normal, Fan Auto, and Verify controls use a display-verified transaction instead of a blind button macro. The controller temporarily enters STANDBY when necessary, pauses all menu writes during TX, verifies each expected LCD screen, saves the setting, and restores OPERATE only when it owned that transition. A timed Fan Boost begins its timer only after CONTEST mode is verified.

Production fan control is hardware-confirmed on the First Series Expert 1.3K-FA and CONFIG-first Second Series Expert 1.5K-FA. The API advertises `supportedModes` per promoted model; both profiles report `normal` and `contest`. Unsupported models report no modes and stop before SET; an unexpected screen stops the transaction rather than continuing.
Production fan control is hardware-confirmed on the First Series Expert 1.3K-FA, CONFIG-first Second Series Expert 1.5K-FA, and the exact firmware-bound Third Series Expert 2K-FA topology. The API advertises `supportedModes` per promoted model; these profiles report `normal` and `contest`. For Third Series, hardware QUIET maps to logical Normal and hardware NORMAL maps to logical high cooling (`contest`). That profile starts only from verified STANDBY/RX and never sends DISPLAY or an OPERATE/STANDBY command. Unsupported model or firmware combinations report no modes and stop before SET; an unexpected screen stops the transaction rather than continuing.

Unattended startup verification has one narrowly reviewed recovery capability for the First Series 1.3K-FA and Second Series 1.5K-FA: after a mismatch or timeout while actively traversing that profile's exact setup-grid waypoint, it may send DISPLAY once and retain ownership until a newer checksum-valid STANDBY/RX home frame arrives. It never runs from a submenu, stale or cross-family screen, TX or unknown RX state, another model, or a manual/API transaction. Recovery does not make verification successful; the failed transaction remains latched until explicitly cleared.

Expand All @@ -108,7 +110,7 @@ The advanced Menu Debug wizard is disabled by default and intended for supervise

The reviewed First Series Expert 1.3K-FA profile may propose reversible fan and two-bank A/B tests. The Expert 1.5K-FA Second Series fan profile follows its captured CONFIG-first topology; both fan profiles have physically verified apply and restoration evidence and are eligible for production fan control. Unknown models and F-KFA NORMAL/QUIET layouts remain topology-only; QUIET is never treated as high cooling. TX is latched immediately. TX, stale evidence, an unexpected screen, timeout, abort, transport failure, or safety preemption stops the session fail-closed; the wizard never retries blindly, restores OPERATE, or performs blind menu recovery.

The reporting wizard has one candidate-only Expert 2K-FA Third Series transaction bound to the exact model, setup topology, and firmware `Rel.26_03_24_A`. From verified STANDBY/RX it records a reversible hardware NORMAL (high cooling) → QUIET (low cooling) → NORMAL test, never sends DISPLAY, and remains separate from production fan control until the resulting apply/restore report and missing raw fixtures are reviewed. Second Series setup recognition accepts either input number.
The reporting wizard retains the Expert 2K-FA Third Series reversible evidence path on `Rel.26_03_24_A`. Production promotion is separately bound to exact model, topology, an exact operator-declared actual firmware allowlist (`Rel.26_03_24_A` or `Rel.08_06_26_A`), and STANDBY/RX. The original firmware has the complete reversible D1 report; the newer firmware has Justin's separate read-only confirmation of the unchanged top setup grid and FAN NOISE page/cursor topology, not a second complete apply/restore report. Second Series setup recognition accepts either input number.

For unfamiliar layouts, discovery may enter an exact highlighted fan candidate only when the live legend says `[SET]:CONFIRM`; `[SET]:CHANGE` stops before SET because it may write immediately. Once a candidate fan page is captured, the wizard sends no selector, SAVE, or DISPLAY command and retains exclusive actuation ownership until the operator physically returns the amplifier to a newer checksum-valid STANDBY home screen.

Expand Down
12 changes: 9 additions & 3 deletions cmd/server/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1711,7 +1711,7 @@ <h3 class="settings-card-title">Safety Monitoring</h3>
<!-- Automatic Fan Policy -->
<div class="settings-card">
<h3 class="settings-card-title">Automatic Fan Cooling</h3>
<p class="needs-restart-note">Experimental and disabled by default. Automatic fan cooling requires a promoted hardware profile and supports the verified First Series Expert 1.3K-FA and CONFIG-first Second Series Expert 1.5K-FA paths. Unsupported models are blocked before SET; use Menu Debug to capture candidate profiles. During a transaction the server verifies the model, first menu topology, and every later waypoint, waits for RX, temporarily changes OPERATE to STANDBY when necessary, and restores OPERATE only when it owned that change.</p>
<p class="needs-restart-note">Experimental and disabled by default. Automatic fan cooling supports the verified First Series Expert 1.3K-FA, CONFIG-first Second Series Expert 1.5K-FA, and firmware-bound Third Series Expert 2K-FA paths. Third Series requires the amplifier's actual firmware to be exactly Rel.26_03_24_A or Rel.08_06_26_A and is STANDBY/RX-only; it never sends DISPLAY or changes OPERATE/STANDBY. Unsupported model, firmware, or topology combinations are blocked before selector movement.</p>

<div class="settings-section" style="margin-top:14px;">
<div class="settings-checkbox-row">
Expand All @@ -1722,6 +1722,10 @@ <h3 class="settings-card-title">Automatic Fan Cooling</h3>
<input type="checkbox" id="s-verify-fan-mode-on-startup">
<label class="settings-checkbox-label" for="s-verify-fan-mode-on-startup">Verify saved fan mode after server startup</label>
</div>
<div class="settings-row">
<label class="settings-label" for="s-fan-policy-firmware">Amplifier firmware binding</label>
<input id="s-fan-policy-firmware" class="settings-input" type="text" maxlength="64" placeholder="Actual Third Series firmware, exactly as shown">
</div>
<div class="settings-row">
<label class="settings-label" for="s-fan-boost-duration">Fan Boost duration</label>
<select id="s-fan-boost-duration" class="settings-input">
Expand Down Expand Up @@ -1761,7 +1765,7 @@ <h3 class="settings-card-title">
<div id="menu-debug-body">
<div class="settings-section">
<p class="settings-hint">One guarded start automatically discovers and runs the frozen fan transaction. Every individual command still requires newer matching display evidence before the next command. The wizard pauses only for physical candidate and restored confirmation.</p>
<p class="settings-hint">Expert 2K-FA Third Series firmware <code>Rel.26_03_24_A</code> is candidate testing only: hardware NORMAL means high cooling and QUIET means low cooling. The test remains in STANDBY/RX, never sends DISPLAY, and does not enable production fan control.</p>
<p class="settings-hint">Expert 2K-FA Third Series Menu Debug remains the evidence workflow for unpromoted firmware and topologies. Production accepts only an actual firmware value of <code>Rel.26_03_24_A</code> or <code>Rel.08_06_26_A</code>, configured separately above, and remains STANDBY/RX-only.</p>
<ol class="menu-debug-plan">
<li>Discover and temporarily change the fan setting; you verify it; the server restores the original.</li>
</ol>
Expand Down Expand Up @@ -3265,6 +3269,7 @@ <h3 class="settings-card-title">
document.getElementById('s-fan-high-temperature').value = s.fanHighTemperatureC || 50;
document.getElementById('s-fan-normal-temperature').value = s.fanNormalTemperatureC || 42;
document.getElementById('s-fan-boost-duration').value = String(s.fanBoostDurationMinutes || 0);
document.getElementById('s-fan-policy-firmware').value = s.fanPolicyFirmwareVersion || '';
}

function populateMenuDebugSetting(settings) {
Expand Down Expand Up @@ -3588,6 +3593,7 @@ <h3 class="settings-card-title">
fanHighTemperatureC: numberOrZero('s-fan-high-temperature'),
fanNormalTemperatureC: numberOrZero('s-fan-normal-temperature'),
fanBoostDurationMinutes: Number(document.getElementById('s-fan-boost-duration').value || 0),
fanPolicyFirmwareVersion: document.getElementById('s-fan-policy-firmware').value.trim(),
};
try {
const res = await fetch('/api/v1/settings', {
Expand All @@ -3600,7 +3606,7 @@ <h3 class="settings-card-title">
setStatus('fan-policy-status', body.error || 'Save failed', 'err');
return;
}
setStatus('fan-policy-status', payload.automaticFanPolicyEnabled ? 'Saved; automatic fan policy enabled with verified temporary-STANDBY navigation' : 'Saved; automatic fan policy disabled', 'ok');
setStatus('fan-policy-status', payload.automaticFanPolicyEnabled ? 'Saved; automatic fan policy enabled with model, firmware, topology, and STANDBY gates' : 'Saved; automatic fan policy disabled', 'ok');
if (body.data) applySettingsFromResponse(body.data);
loadFanPolicyStatus();
} catch (err) {
Expand Down
1 change: 1 addition & 0 deletions cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ func newServerWithUploader(cfg *config.Manager, pollInterval time.Duration, stop
HighTemperatureC: settings.FanHighTemperatureC,
NormalTemperatureC: settings.FanNormalTemperatureC,
DisplayProfile: settings.FanDisplayProfile,
FirmwareVersion: settings.FanPolicyFirmwareVersion,
SafetyStandbyArmed: settings.SafetyMonitoringEnabled && settings.OvertemperatureStandbyArmed,
SafetyStandbyTripC: settings.TemperatureTripC,
}
Expand Down
2 changes: 1 addition & 1 deletion docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,4 +228,4 @@ fixtures/*.bin ──► protocol.LoadFixtureState ──► display.State/runti
- **Every feature needs tests.** Decoder changes need regression tests against fixture files.
- **Automatic standby is narrow and one-way.** It may send the documented OPERATE toggle once per latched overtemperature episode only with fresh protocol-native OPERATE and RX evidence. It never acts during TX, retries, powers off, or auto-wakes.
- **Fan navigation is one verified transaction.** Production writes require a promoted profile and support the model- and topology-bound First Series Expert 1.3K-FA and CONFIG-first Second Series Expert 1.5K-FA paths. Automatic, manual, and verification requests share the same temporary-STANDBY path, pause every write during TX, stop on unexpected screens, and restore OPERATE only after verified SAVE/home completion when the controller owned the transition.
- **Third Series 2K-FA testing remains in Menu Debug, outside production fan navigation.** The candidate grammar is bound to `EXPERT 2K-FA`, `expert-2k-fa-third-series-setup-v1`, and `Rel.26_03_24_A`. It runs only from verified STANDBY/RX, treats physical NORMAL as high cooling and QUIET as low cooling, records exact raw LCD grids for every receipt, requires physical apply and restore confirmation, never sends DISPLAY, and never enters or restores OPERATE. Promotion requires a separately reviewed complete hardware report.
- **Third Series 2K-FA production control is narrower than First/Second Series.** It is bound to `EXPERT 2K-FA`, the exact Third Series topology, and an explicit exact allowlist of operator-declared actual firmware values (`Rel.26_03_24_A` and `Rel.08_06_26_A`) because status polling does not expose firmware. Empty, mistyped, case-variant, or other firmware values fail closed. It maps hardware QUIET to logical Normal cooling and hardware NORMAL to logical high cooling, starts only from verified STANDBY/RX, and never sends DISPLAY or an OPERATE/STANDBY command. The original firmware's exact 23-state reversible D1 report is retained as regression evidence; the newer firmware has a separate read-only re-capture of the unchanged top setup grid and FAN NOISE page/cursor topology, not a claimed second reversible report. Menu Debug remains the guarded evidence path for other firmware or topology combinations.
6 changes: 4 additions & 2 deletions docs/PROTOCOL.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,11 @@ Controlled testing on the First Series Expert 1.3K-FA established that serial DI

Menu Debug & Reporting is a separate disabled-by-default discovery boundary. Arming requires the exact acknowledgement, fresh protocol STANDBY/RX, a recent checksum-valid STANDBY home display, inactive fan control, disarmed overtemperature standby, and an exclusive actuation lease. Its token is memory-only and short-lived; each mutation consumes the latest revision so stale tabs cannot replay commands. The built-in wizard requests only the fan capability; bank topology remains available only when an API client explicitly requests it, so completed fan validation cannot silently continue into unrelated bank discovery. One guarded start runs discovery and the frozen apply plan automatically, but every SET, RIGHT, or model-specific no-save exit still receives one authorization and waits for a newer matching checksum-valid screen before the next authorization. Apply pauses for physical candidate confirmation; a positive answer starts automatic restore, followed by physical restored confirmation. Protocol status, LCD evidence, discovery and planned authorizations are bound to the observed amplifier model and the serial-session generation that produced them. The live transport atomically requires that same model, STANDBY, and known RX under its write lock before sending. Opening a replacement port or observing a different identified model within the same port session immediately invalidates the entire active session and discards all report evidence, preventing different hardware from continuing or relabeling prior evidence; the transport also captures the verified port under its write lock so a reconnect cannot redirect a command.

Reviewed reversible fan-test profiles cover the First Series Expert 1.3K-FA and the CONFIG-first Expert 1.5K-FA Second Series topology. Both profiles have physically verified apply and restoration evidence and are eligible for production fan control. One additional candidate-only grammar covers the exact Expert 2K-FA Third Series model/topology/firmware combination for a single STANDBY/RX NORMAL→QUIETNORMAL evidence run; it is not a production fan-policy profile. Unknown models and F-KFA NORMAL/QUIET layouts remain topology-only; QUIET is never interpreted as high cooling.
Reviewed reversible fan-test grammars cover the First Series Expert 1.3K-FA, CONFIG-first Expert 1.5K-FA Second Series, and exact Expert 2K-FA Third Series topologies. Third Series production is narrower: it requires model `EXPERT 2K-FA`, exact captured topology, and an operator-declared actual firmware value exactly equal to `Rel.26_03_24_A` or `Rel.08_06_26_A` because status polling does not expose firmware. Empty, mistyped, case-variant, and all other firmware values fail closed. It is STANDBY/RX-only, maps hardware QUIET to logical Normal and hardware NORMAL to logical high cooling, and never sends DISPLAY or an OPERATE/STANDBY command. Unknown models and F-KFA NORMAL/QUIET layouts remain topology-only; QUIET is never interpreted as high cooling.

An August 2026 Third Series Expert 2K-FA field report established a separate menu family. Its home header has `CAT` where bank-capable models have `BNK`, its setup grid separates `TEMP.` from `FAN NOISE`, and its fan page is a NORMAL/QUIET radio group headed `POWER-SUPPLY FAN`. The raw `0xAE` glyph marks the active radio value and is read from the exact character grid rather than inferred from decoded text. The reporting wizard accepts one candidate test only when the model is `EXPERT 2K-FA`, firmware is exactly `Rel.26_03_24_A`, every setup waypoint retains the exact Third Series topology and `[SET]:CONFIRM` legend, and the fan page begins NORMAL-active/NORMAL-selected. The frozen plan applies QUIET, requires a newer saved STANDBY/RX home receipt and positive physical confirmation, then re-enters and restores NORMAL with the same gates. It never sends DISPLAY and does not inherit First/Second Series production fan control or OPERATE transitions. Production remains blocked until the complete reversible report and missing raw hardware fixtures are reviewed.
An August 2026 Third Series Expert 2K-FA field report established a separate menu family. Its home header has `CAT` where bank-capable models have `BNK`, its setup grid separates `TEMP.` from `FAN NOISE`, and its fan page is a NORMAL/QUIET radio group headed `POWER-SUPPLY FAN`. The raw `0xAE` glyph marks the active radio value and is read from the exact character grid rather than inferred from decoded text. Production D1 report `00acd5279f994baf497f58cf607f9efea6b770fbf3679beae301a88ce177b715` completed the guarded NORMAL→QUIET→NORMAL apply/restore run with newer SAVE/home receipts and positive physical verification. Its 23 distinct exact raw states are checked in as regression fixtures. No report evidence authorizes OPERATE-to-STANDBY automation.

After upgrading to `Rel.08_06_26_A`, the same operator separately re-captured the top setup grid and FAN NOISE page/cursor topology read-only and reported them exactly unchanged. That narrower evidence supports the same exact production recognizer on the newer firmware, but it is not represented as another complete NORMAL→QUIET→NORMAL report and does not replace or relabel the original D1 provenance.

The same field report disproved a broader no-save assumption. On that firmware, top-level items whose legend says `[SET]:CHANGE` write immediately; DISPLAY cannot undo the change. Sub-pages with an explicit SAVE stage their edits, but that does not make DISPLAY a globally safe recovery key. Per-page legends and model-scoped capture evidence therefore remain authoritative before SET, and DISPLAY recovery remains explicitly allowlisted by model and screen.

Expand Down
Loading