Skip to content
Merged
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
13 changes: 13 additions & 0 deletions .agents/session-log.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Session Log - QuantLab

## 2026-04-10 — Snapshot Status Contract Alignment (Issue #361)
- **Session Focus**: Align the desktop snapshot-status renderer semantics with the shared `desktop/shared/models/snapshot.ts` contract.
- **Tasks Completed**:
- Updated `desktop/renderer/modules/tab-renderers.js` so snapshot refresh labels now branch on `ok`, `degraded`, `error`, and `idle` instead of stale `ready` / `loading` values.
- Kept healthy snapshots mapped to `Live`, degraded snapshots mapped to warning semantics, and explicit error snapshots mapped to negative/unavailable semantics.
- Added a small `node:test` regression file to lock the snapshot label/tone mapping against the current shared contract.
- **Key Decisions**:
- The shared snapshot contract remains the source of truth; the renderer adapts to it rather than expanding the contract back to old status names.
- `degraded` and `error` remain separate operator states so local fallback or partial data does not look identical to a hard runtime failure.
- **Validation Notes**:
- Validate with `npm run typecheck`, `node --check renderer/app.js`, `node --check renderer/modules/tab-renderers.js`, and `node --test tests/snapshot-status.test.mjs` from `desktop/`.
- Keep desktop smoke coverage in place to ensure the slice does not regress the current shell path.

## 2026-04-10 — Real-Path Desktop Validation and Smoke Semantics (Issue #275)
- **Session Focus**: Restore an honest distinction between fallback desktop smoke and real-path desktop validation.
- **Tasks Completed**:
Expand Down
14 changes: 7 additions & 7 deletions desktop/renderer/modules/tab-renderers.js
Original file line number Diff line number Diff line change
Expand Up @@ -1792,25 +1792,25 @@ function renderOpsChipRow(label, counts) {
`;
}

function describeSnapshotRefresh(snapshotStatus) {
if (snapshotStatus?.status === "ready") {
export function describeSnapshotRefresh(snapshotStatus) {
if (snapshotStatus?.status === "ok") {
return {
label: snapshotStatus.refreshPaused ? "Paused" : "Live",
tone: snapshotStatus.refreshPaused ? "tone-warning" : "tone-positive",
lastSuccessAt: snapshotStatus.lastSuccessAt ? formatDateTime(snapshotStatus.lastSuccessAt) : "Never",
};
}
if (snapshotStatus?.status === "error") {
if (snapshotStatus?.status === "degraded") {
return {
label: snapshotStatus.refreshPaused ? "Review required" : "Degraded",
tone: "tone-negative",
tone: "tone-warning",
lastSuccessAt: snapshotStatus.lastSuccessAt ? formatDateTime(snapshotStatus.lastSuccessAt) : "Never",
};
}
if (snapshotStatus?.status === "loading") {
if (snapshotStatus?.status === "error") {
return {
label: "Refreshing",
tone: "tone-warning",
label: snapshotStatus.refreshPaused ? "Review required" : "Unavailable",
tone: "tone-negative",
lastSuccessAt: snapshotStatus.lastSuccessAt ? formatDateTime(snapshotStatus.lastSuccessAt) : "Never",
};
}
Expand Down
52 changes: 52 additions & 0 deletions desktop/tests/snapshot-status.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import test from "node:test";
import assert from "node:assert/strict";

import { describeSnapshotRefresh } from "../renderer/modules/tab-renderers.js";

const ISO_TIME = "2026-04-10T14:00:00.000Z";

test("ok snapshots render as live", () => {
const result = describeSnapshotRefresh({
status: "ok",
refreshPaused: false,
lastSuccessAt: ISO_TIME,
});

assert.equal(result.label, "Live");
assert.equal(result.tone, "tone-positive");
assert.notEqual(result.lastSuccessAt, "Never");
});

test("degraded snapshots stay warning-toned and do not fall back to waiting", () => {
const result = describeSnapshotRefresh({
status: "degraded",
refreshPaused: false,
lastSuccessAt: ISO_TIME,
});

assert.equal(result.label, "Degraded");
assert.equal(result.tone, "tone-warning");
});

test("error snapshots remain negative and explicitly unavailable", () => {
const result = describeSnapshotRefresh({
status: "error",
refreshPaused: false,
lastSuccessAt: ISO_TIME,
});

assert.equal(result.label, "Unavailable");
assert.equal(result.tone, "tone-negative");
});

test("idle snapshots remain waiting", () => {
const result = describeSnapshotRefresh({
status: "idle",
refreshPaused: false,
lastSuccessAt: null,
});

assert.equal(result.label, "Waiting");
assert.equal(result.tone, "tone-warning");
assert.equal(result.lastSuccessAt, "Never");
});
Loading