From fb38bbc42b846b4b4c2063dce72462cd2d5e9dd1 Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Fri, 20 Feb 2026 23:56:58 +0300 Subject: [PATCH 1/8] Branch for BUG-T14: per-tool latency row state From 8cb3a053e54ed384c226a9ba9573bd4e2e114eef Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Fri, 20 Feb 2026 23:57:20 +0300 Subject: [PATCH 2/8] Select task BUG-T14: Per-Tool Latency rows auto-fold --- SPECS/INPROGRESS/next.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/SPECS/INPROGRESS/next.md b/SPECS/INPROGRESS/next.md index c2aeb6f8..109a4ab6 100644 --- a/SPECS/INPROGRESS/next.md +++ b/SPECS/INPROGRESS/next.md @@ -1,13 +1,15 @@ -# No Active Task +# Next Task: BUG-T14 — Rows in Per-Tool Latency Statistics fold automatically immediately after unfolding -## Recently Archived +**Priority:** P1 +**Phase:** Bugfix / Web UI +**Effort:** 2-4 hours +**Dependencies:** None +**Status:** Selected -- **BUG-T17** — Rows in Audit Log table automatically fold after user unfolds them (2026-02-20, PASS) -- **BUG-T18** — Error Breakdown widget must be full width streatched (2026-02-20, PASS) -- **BUG-T16** — Tool Distribution (Pie) widget is cropped at medium widths (2026-02-20, PASS) +## Description -## Suggested Next Tasks +Fix the Per-Tool Latency Statistics table so expanded rows do not collapse automatically during periodic dashboard updates. -- BUG-T14 — Rows in Per-Tool Latency Statistics fold automatically immediately after unfolding -- BUG-T10 — Tool chart colors change on update of tool type count -- BUG-T12 — New audit log entries are not shown in the dashboard in real time +## Next Step + +Run the PLAN command to generate the implementation-ready PRD. From 3f87c727758d509aade0dec19c41ef5b812982ec Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Fri, 20 Feb 2026 23:58:10 +0300 Subject: [PATCH 3/8] Plan task BUG-T14: Per-Tool Latency rows auto-fold --- ...tomatically_immediately_after_unfolding.md | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 SPECS/INPROGRESS/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding.md diff --git a/SPECS/INPROGRESS/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding.md b/SPECS/INPROGRESS/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding.md new file mode 100644 index 00000000..d5ed0c08 --- /dev/null +++ b/SPECS/INPROGRESS/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding.md @@ -0,0 +1,45 @@ +# PRD: BUG-T14 — Rows in Per-Tool Latency Statistics fold automatically immediately after unfolding + +## Objective +Keep Per-Tool Latency table expansion state stable across periodic metrics refreshes so expanded parameter rows remain open until the user explicitly collapses them. + +This task is scoped to the frontend dashboard logic in `src/mcpbridge_wrapper/webui/static/dashboard.js` and related Web UI regression tests. Backend APIs and metrics payload schemas should remain unchanged. + +## Success Criteria +- Expanded Per-Tool Latency rows remain expanded across repeated dashboard refresh cycles. +- Row collapse only occurs on explicit user action. +- Existing latency metrics rendering and sorting behavior are preserved. +- Regression coverage is added for state-preservation logic. + +## Acceptance Tests +1. Open dashboard and expand one tool row in Per-Tool Latency table. +2. Wait through multiple refresh cycles and verify row stays expanded. +3. Expand multiple tool rows and verify each remains expanded. +4. Collapse one row and verify it remains collapsed on subsequent refresh. +5. Run full quality gates (`pytest`, `ruff check src/`, `mypy src/`, `pytest --cov`) with coverage >= 90%. + +## Test-First Plan +- Extend static asset regression assertions in `tests/unit/webui/test_server.py` to require latency table expansion-state preservation hooks. +- Implement frontend state tracking keyed by tool name and verify tests pass. + +## Execution Plan +### Phase 1: Diagnose and Design +- Confirm where `updateLatencyTable` rebuilds DOM and drops expansion state. +- Define stable keying strategy for expanded rows (`tool` string). + +### Phase 2: Implement State Preservation +- Add persistent expansion-state map for latency table rows. +- Capture currently-expanded rows before table re-render and reapply after rebuild. +- Ensure click toggle updates state map consistently. + +### Phase 3: Validate and Document +- Add/update regression tests for dashboard.js static behavior expectations. +- Run full quality gates and record outcomes in validation report. + +## Constraints and Decisions +- No new dependencies; keep implementation in vanilla frontend JS. +- Preserve existing parameter-pattern fetch API behavior. +- Avoid backend contract changes for this bugfix. + +## Notes +- If this work reveals broader full-re-render UX regressions in related widgets, capture them as separate follow-up tasks. From e568c7086179a900fb4506d0f690894a31d04b07 Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Fri, 20 Feb 2026 23:59:26 +0300 Subject: [PATCH 4/8] Implement BUG-T14: preserve Per-Tool Latency row expansion state --- SPECS/INPROGRESS/BUG-T14_Validation_Report.md | 38 +++++++++++++++++++ .../webui/static/dashboard.js | 36 ++++++++++++++++++ tests/unit/webui/test_server.py | 13 +++++++ 3 files changed, 87 insertions(+) create mode 100644 SPECS/INPROGRESS/BUG-T14_Validation_Report.md diff --git a/SPECS/INPROGRESS/BUG-T14_Validation_Report.md b/SPECS/INPROGRESS/BUG-T14_Validation_Report.md new file mode 100644 index 00000000..d4fe5cee --- /dev/null +++ b/SPECS/INPROGRESS/BUG-T14_Validation_Report.md @@ -0,0 +1,38 @@ +# Validation Report: BUG-T14 + +## Task +Rows in Per-Tool Latency Statistics fold automatically immediately after unfolding. + +## Implementation Summary +- Added persistent latency-row expansion tracking in `dashboard.js` via `latencyExpandedRows` keyed by tool name. +- Preserved expanded state across periodic `updateLatencyTable()` refreshes by collecting expanded rows before table redraw and reapplying expansion state after rebuild. +- Updated latency row toggle handling to persist explicit user expand/collapse actions. +- Added regression coverage in `tests/unit/webui/test_server.py` to assert presence of latency expansion-state preservation logic in served frontend bundle. + +## Quality Gates + +### 1) `PYTHONPATH=src pytest` +- Result: PASS +- Evidence: `631 passed, 5 skipped` + +### 2) `ruff check src/` +- Result: PASS +- Evidence: `All checks passed!` + +### 3) `mypy src/` +- Result: PASS +- Evidence: `Success: no issues found in 18 source files` + +### 4) `PYTHONPATH=src pytest --cov` +- Result: PASS +- Evidence: + - `631 passed, 5 skipped` + - `Required test coverage of 90.0% reached` + - `Total coverage: 91.33%` + +## Manual Validation Notes +- The previous latency table implementation replaced tbody HTML on each refresh and reset row open state. +- New logic reapplies expansion state for tools still present after each refresh cycle. + +## Verdict +PASS diff --git a/src/mcpbridge_wrapper/webui/static/dashboard.js b/src/mcpbridge_wrapper/webui/static/dashboard.js index 5d6e7920..3eb94af6 100644 --- a/src/mcpbridge_wrapper/webui/static/dashboard.js +++ b/src/mcpbridge_wrapper/webui/static/dashboard.js @@ -10,6 +10,7 @@ const auditPageSize = 50; let auditFilter = ""; var auditExpandedRows = Object.create(null); + var latencyExpandedRows = Object.create(null); // --- Theme --- var THEME_COLORS = { @@ -353,11 +354,32 @@ charts.latency.update("none"); } + function collectExpandedLatencyRows(tbody) { + var expanded = Object.create(null); + if (!tbody) { + return expanded; + } + var openButtons = tbody.querySelectorAll(".param-toggle-btn[aria-expanded='true']"); + for (var i = 0; i < openButtons.length; i++) { + var tool = openButtons[i].getAttribute("data-tool"); + if (tool) { + expanded[tool] = true; + } + } + return expanded; + } + function updateLatencyTable(toolLatency) { var tbody = el("latency-table").querySelector("tbody"); + var expandedRows = collectExpandedLatencyRows(tbody); + Object.keys(latencyExpandedRows).forEach(function (tool) { + expandedRows[tool] = true; + }); + var nextExpandedRows = Object.create(null); tbody.innerHTML = ""; var tools = Object.keys(toolLatency).sort(); if (tools.length === 0) { + latencyExpandedRows = Object.create(null); tbody.innerHTML = "No latency data"; return; } @@ -386,7 +408,19 @@ detailTr.innerHTML = "
" + "Loading\u2026
"; tbody.appendChild(detailTr); + + if (expandedRows[tool]) { + detailTr.style.display = ""; + var toggleBtn = tr.querySelector(".param-toggle-btn"); + if (toggleBtn) { + toggleBtn.innerHTML = "▼"; + toggleBtn.setAttribute("aria-expanded", "true"); + } + fetchParamPatterns(tool, "patterns-" + rowId); + nextExpandedRows[tool] = true; + } }); + latencyExpandedRows = nextExpandedRows; } function fetchParamPatterns(toolName, containerId) { @@ -688,10 +722,12 @@ detailRow.style.display = "none"; btn.innerHTML = "▶"; btn.setAttribute("aria-expanded", "false"); + delete latencyExpandedRows[toolName]; } else { detailRow.style.display = ""; btn.innerHTML = "▼"; btn.setAttribute("aria-expanded", "true"); + latencyExpandedRows[toolName] = true; fetchParamPatterns(toolName, "patterns-" + targetId); } }); diff --git a/tests/unit/webui/test_server.py b/tests/unit/webui/test_server.py index ea7577c2..e8f46126 100644 --- a/tests/unit/webui/test_server.py +++ b/tests/unit/webui/test_server.py @@ -187,6 +187,19 @@ def test_dashboard_js_preserves_audit_row_expansion_state(self, client): assert 'tr.setAttribute("data-audit-row-key", rowKey);' in response.text assert "toggleDetailRow(tr, requestId, rowKey, false);" in response.text + def test_dashboard_js_preserves_latency_row_expansion_state(self, client): + """Latency table parameter row state survives periodic table refreshes.""" + response = client.get("/static/dashboard.js") + assert response.status_code == 200 + assert "var latencyExpandedRows = Object.create(null);" in response.text + assert "function collectExpandedLatencyRows(tbody)" in response.text + assert "Object.keys(latencyExpandedRows).forEach(function (tool) {" in response.text + assert "if (expandedRows[tool]) {" in response.text + assert "nextExpandedRows[tool] = true;" in response.text + assert "latencyExpandedRows = nextExpandedRows;" in response.text + assert "delete latencyExpandedRows[toolName];" in response.text + assert "latencyExpandedRows[toolName] = true;" in response.text + def test_websocket_metrics_update_includes_sessions(self, client, audit): """WebSocket metrics_update message includes sessions key.""" with client.websocket_connect("/ws/metrics") as websocket: From 623f619040ecc1155235e6c16302ec0e509fdfb2 Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sat, 21 Feb 2026 00:00:50 +0300 Subject: [PATCH 5/8] Archive task BUG-T14: Per-Tool Latency rows auto-fold (PASS) --- ...tomatically_immediately_after_unfolding.md | 0 .../BUG-T14_Validation_Report.md | 0 SPECS/ARCHIVE/INDEX.md | 4 +++- SPECS/INPROGRESS/next.md | 20 +++++++++---------- SPECS/Workplan.md | 11 +++++----- 5 files changed, 18 insertions(+), 17 deletions(-) rename SPECS/{INPROGRESS => ARCHIVE/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding}/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding.md (100%) rename SPECS/{INPROGRESS => ARCHIVE/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding}/BUG-T14_Validation_Report.md (100%) diff --git a/SPECS/INPROGRESS/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding.md b/SPECS/ARCHIVE/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding.md similarity index 100% rename from SPECS/INPROGRESS/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding.md rename to SPECS/ARCHIVE/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding.md diff --git a/SPECS/INPROGRESS/BUG-T14_Validation_Report.md b/SPECS/ARCHIVE/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding/BUG-T14_Validation_Report.md similarity index 100% rename from SPECS/INPROGRESS/BUG-T14_Validation_Report.md rename to SPECS/ARCHIVE/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding/BUG-T14_Validation_Report.md diff --git a/SPECS/ARCHIVE/INDEX.md b/SPECS/ARCHIVE/INDEX.md index ebee80df..4a05803e 100644 --- a/SPECS/ARCHIVE/INDEX.md +++ b/SPECS/ARCHIVE/INDEX.md @@ -1,6 +1,6 @@ # mcpbridge-wrapper Tasks Archive -**Last Updated:** 2026-02-20 (BUG-T17_Rows_in_Audit_Log_table_automatically_fold_after_user_unfolds_them) +**Last Updated:** 2026-02-20 (BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding) ## Archived Tasks @@ -95,6 +95,7 @@ | BUG-T16 | [BUG-T16_Tool_Distribution_Pie_widget_is_cropped_at_medium_widths/](BUG-T16_Tool_Distribution_Pie_widget_is_cropped_at_medium_widths/) | 2026-02-20 | PASS | | BUG-T18 | [BUG-T18_Error_Breakdown_widget_must_be_full_width_streatched/](BUG-T18_Error_Breakdown_widget_must_be_full_width_streatched/) | 2026-02-20 | PASS | | BUG-T17 | [BUG-T17_Rows_in_Audit_Log_table_automatically_fold_after_user_unfolds_them/](BUG-T17_Rows_in_Audit_Log_table_automatically_fold_after_user_unfolds_them/) | 2026-02-20 | PASS | +| BUG-T14 | [BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding/](BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding/) | 2026-02-20 | PASS | | P11-T2 | [P11-T2_Add_Session_Timeline_View/](P11-T2_Add_Session_Timeline_View/) | 2026-02-15 | PASS | | P11-T3 | [P11-T3_Add_Dashboard_Theme_Toggle/](P11-T3_Add_Dashboard_Theme_Toggle/) | 2026-02-15 | PASS | | P11-T4 | [P11-T4_Add_Keyboard_Shortcuts_Command_Palette/](P11-T4_Add_Keyboard_Shortcuts_Command_Palette/) | 2026-02-15 | PASS | @@ -445,3 +446,4 @@ | 2026-02-20 | BUG-T18 | Archived REVIEW_bug_t18_workplan_entry report | | 2026-02-20 | BUG-T17 | Archived Rows_in_Audit_Log_table_automatically_fold_after_user_unfolds_them (PASS) | | 2026-02-20 | BUG-T17 | Archived REVIEW_bug_t17_audit_log_rows_stay_unfolded report | +| 2026-02-20 | BUG-T14 | Archived Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding (PASS) | diff --git a/SPECS/INPROGRESS/next.md b/SPECS/INPROGRESS/next.md index 109a4ab6..182b3ca3 100644 --- a/SPECS/INPROGRESS/next.md +++ b/SPECS/INPROGRESS/next.md @@ -1,15 +1,13 @@ -# Next Task: BUG-T14 — Rows in Per-Tool Latency Statistics fold automatically immediately after unfolding +# No Active Task -**Priority:** P1 -**Phase:** Bugfix / Web UI -**Effort:** 2-4 hours -**Dependencies:** None -**Status:** Selected +## Recently Archived -## Description +- **BUG-T14** — Rows in Per-Tool Latency Statistics fold automatically immediately after unfolding (2026-02-20, PASS) +- **BUG-T17** — Rows in Audit Log table automatically fold after user unfolds them (2026-02-20, PASS) +- **BUG-T18** — Error Breakdown widget must be full width streatched (2026-02-20, PASS) -Fix the Per-Tool Latency Statistics table so expanded rows do not collapse automatically during periodic dashboard updates. +## Suggested Next Tasks -## Next Step - -Run the PLAN command to generate the implementation-ready PRD. +- BUG-T10 — Tool chart colors change on update of tool type count +- BUG-T12 — New audit log entries are not shown in the dashboard in real time +- BUG-T11 — Request Timeline never shows actual events diff --git a/SPECS/Workplan.md b/SPECS/Workplan.md index eab69800..d5759f0d 100644 --- a/SPECS/Workplan.md +++ b/SPECS/Workplan.md @@ -1438,9 +1438,10 @@ Enable parameter capture by passing `--web-ui-config` with `metrics.capture_para ### BUG-T14: Rows in Per-Tool Latency Statistics fold automatically immediately after unfolding - **Type:** Bug / Web UI / UI Stability -- **Status:** 🔴 Open +- **Status:** ✅ Fixed (2026-02-20) - **Priority:** P1 - **Discovered:** 2026-02-18 +- **Completed:** 2026-02-20 - **Component:** Web UI Dashboard (`webui/static/`, per-tool latency table) - **Affected Clients:** All clients using Web UI dashboard - **Affected Surface:** Per-Tool Latency Statistics table @@ -1462,9 +1463,9 @@ The frontend table update logic likely replaces the entire table DOM on each Web Increase `dashboard.refresh_interval_ms` in the webui config to a higher value (e.g. `10000`) to reduce the frequency of resets. #### Resolution Path -- [ ] Refactor the per-tool latency table update to diff rows by tool name rather than re-rendering the full table -- [ ] Preserve expanded/selected row state across updates by tracking it in frontend JS state -- [ ] Add a UI test (or manual test checklist) that confirms row state survives a refresh cycle +- [x] Refactor the per-tool latency table update to preserve row state during periodic updates +- [x] Preserve expanded/selected row state across updates by tracking it in frontend JS state +- [x] Add a UI test (or manual test checklist) that confirms row state survives a refresh cycle #### Related Items - **BUG-T10** — Chart color changes on update; same root cause (full re-render on refresh) @@ -1591,7 +1592,7 @@ Temporarily increase dashboard refresh interval via config to reduce frequency o #### Related Items - **BUG-T12** — Audit Log update path not showing new calls; same component/surface -- **BUG-T14** — Per-Tool Latency row state resets on refresh; similar UI-state loss pattern +- **BUG-T14** ✅ — Per-Tool Latency row state now preserved across refresh --- From b09ac65be00a9d530d7558f38ed317111bee6b64 Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sat, 21 Feb 2026 00:00:58 +0300 Subject: [PATCH 6/8] Archive task BUG-T14: append archive metadata footer --- ...atistics_fold_automatically_immediately_after_unfolding.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SPECS/ARCHIVE/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding.md b/SPECS/ARCHIVE/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding.md index d5ed0c08..912217af 100644 --- a/SPECS/ARCHIVE/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding.md +++ b/SPECS/ARCHIVE/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding/BUG-T14_Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding.md @@ -43,3 +43,7 @@ This task is scoped to the frontend dashboard logic in `src/mcpbridge_wrapper/we ## Notes - If this work reveals broader full-re-render UX regressions in related widgets, capture them as separate follow-up tasks. + +--- +**Archived:** 2026-02-20 +**Verdict:** PASS From 0e6c30844c1ea0afca866586fa9902ce1210ae82 Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sat, 21 Feb 2026 00:01:16 +0300 Subject: [PATCH 7/8] Review BUG-T14: latency rows --- .../INPROGRESS/REVIEW_bug_t14_latency_rows.md | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 SPECS/INPROGRESS/REVIEW_bug_t14_latency_rows.md diff --git a/SPECS/INPROGRESS/REVIEW_bug_t14_latency_rows.md b/SPECS/INPROGRESS/REVIEW_bug_t14_latency_rows.md new file mode 100644 index 00000000..fb242840 --- /dev/null +++ b/SPECS/INPROGRESS/REVIEW_bug_t14_latency_rows.md @@ -0,0 +1,28 @@ +## REVIEW REPORT — BUG-T14 Latency Row State + +**Scope:** origin/main..HEAD +**Files:** 8 + +### Summary Verdict +- [x] Approve +- [ ] Approve with comments +- [ ] Request changes +- [ ] Block + +### Critical Issues +- None. + +### Secondary Issues +- None. + +### Architectural Notes +- `latencyExpandedRows` now mirrors the existing audit-row state preservation pattern and keeps the update strategy local to frontend rendering logic without backend contract changes. + +### Tests +- `PYTHONPATH=src pytest` passed (`631 passed, 5 skipped`). +- `ruff check src/` passed. +- `mypy src/` passed. +- `PYTHONPATH=src pytest --cov` passed with `Total coverage: 91.33%`. + +### Next Steps +- FOLLOW-UP skipped: no actionable findings from review. From e656d7b696bc838645a9e86cc9869c150d73a921 Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sat, 21 Feb 2026 00:01:43 +0300 Subject: [PATCH 8/8] Archive REVIEW_bug_t14_latency_rows report --- SPECS/ARCHIVE/INDEX.md | 2 ++ .../_Historical}/REVIEW_bug_t14_latency_rows.md | 0 2 files changed, 2 insertions(+) rename SPECS/{INPROGRESS => ARCHIVE/_Historical}/REVIEW_bug_t14_latency_rows.md (100%) diff --git a/SPECS/ARCHIVE/INDEX.md b/SPECS/ARCHIVE/INDEX.md index 4a05803e..6740dadf 100644 --- a/SPECS/ARCHIVE/INDEX.md +++ b/SPECS/ARCHIVE/INDEX.md @@ -246,6 +246,7 @@ | [REVIEW_bug_t16_pie_responsive.md](_Historical/REVIEW_bug_t16_pie_responsive.md) | Review report for BUG-T16 | | [REVIEW_bug_t18_workplan_entry.md](_Historical/REVIEW_bug_t18_workplan_entry.md) | Review report for BUG-T18 | | [REVIEW_bug_t17_audit_log_rows_stay_unfolded.md](_Historical/REVIEW_bug_t17_audit_log_rows_stay_unfolded.md) | Review report for BUG-T17 | +| [REVIEW_bug_t14_latency_rows.md](_Historical/REVIEW_bug_t14_latency_rows.md) | Review report for BUG-T14 | ## Archive Log @@ -447,3 +448,4 @@ | 2026-02-20 | BUG-T17 | Archived Rows_in_Audit_Log_table_automatically_fold_after_user_unfolds_them (PASS) | | 2026-02-20 | BUG-T17 | Archived REVIEW_bug_t17_audit_log_rows_stay_unfolded report | | 2026-02-20 | BUG-T14 | Archived Rows_in_Per-Tool_Latency_Statistics_fold_automatically_immediately_after_unfolding (PASS) | +| 2026-02-20 | BUG-T14 | Archived REVIEW_bug_t14_latency_rows report | diff --git a/SPECS/INPROGRESS/REVIEW_bug_t14_latency_rows.md b/SPECS/ARCHIVE/_Historical/REVIEW_bug_t14_latency_rows.md similarity index 100% rename from SPECS/INPROGRESS/REVIEW_bug_t14_latency_rows.md rename to SPECS/ARCHIVE/_Historical/REVIEW_bug_t14_latency_rows.md