From 2d62e1808b6f4110e253dcf6dc2951ed9da217d5 Mon Sep 17 00:00:00 2001 From: Martino Ferrari Date: Thu, 27 Aug 2026 17:07:08 +0200 Subject: [PATCH] docs: fix six cross-task defects found in the UDPScope plan pre-flight Each of these would have surfaced as a compile/link failure or a reviewer rejection mid-execution, when the implementer holding the task has no view of the neighbouring task that contradicts it. Co-Authored-By: Claude Opus 4.6 --- docs/superpowers/plans/2026-08-27-udpscope.md | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/docs/superpowers/plans/2026-08-27-udpscope.md b/docs/superpowers/plans/2026-08-27-udpscope.md index b843ee7..75f8d2a 100644 --- a/docs/superpowers/plans/2026-08-27-udpscope.md +++ b/docs/superpowers/plans/2026-08-27-udpscope.md @@ -2899,7 +2899,19 @@ TEST(SignalStore, ConcurrentPushAndReadDoNotCrash) { } stop.store(true); writer.join(); - SUCCEED(); + + /* Not just "it did not crash": the store must still be coherent after the + race. The window is 0.05 s at 1 MHz, so the ring spans at most + 0.05 * kRingMargin seconds, and readLast was capped at 4096 points. */ + double oldest = 0.0, newest = 0.0; + ASSERT_TRUE(s.span("a", oldest, newest)); + EXPECT_GE(newest, oldest); + EXPECT_LE(newest - oldest, 0.05 * SignalStore::kRingMargin * 1.5); + EXPECT_LE(out.size(), 4096u); + EXPECT_EQ(out.t.size(), out.v.size()); + for (size_t i = 1; i < out.size(); ++i) { + EXPECT_GE(out.t[i], out.t[i - 1]) << "timestamps went backwards at " << i; + } } ``` @@ -4138,7 +4150,7 @@ TEST(ReceiverLink, StopIsSafeWhenNeverStarted) { Receiver rx(store); rx.stop(); EXPECT_FALSE(rx.running()); - SUCCEED(); + EXPECT_FALSE(rx.link().running); } ``` @@ -5138,10 +5150,6 @@ void App::drawMenuBar() { } ImGui::EndMenu(); } - if (ImGui::BeginMenu("View")) { - ImGui::MenuItem("(cursors land in Task 13)", nullptr, false, false); - ImGui::EndMenu(); - } if (ImGui::BeginMenu("Help")) { ImGui::MenuItem("UDPScope — direct UDPS oscilloscope", nullptr, false, false); ImGui::EndMenu(); @@ -5974,8 +5982,9 @@ In `Client/udpscope/App.h`, add `#include "PaneView.h"` and the members: double xSpanSec_ = 1.0; /**< live window width, Task 12 makes it settable */ ``` -In `Client/udpscope/App.cpp`, make the signal list a drag source by replacing -the `ImGui::Selectable(m.name.c_str());` line with: +In `Client/udpscope/SignalList.cpp` — that is where Task 9 put +`App::drawSignalList()`, not `App.cpp` — make the signal list a drag source by +replacing the `ImGui::Selectable(m.name.c_str());` line with: ```cpp ImGui::Selectable(m.name.c_str()); @@ -6035,10 +6044,14 @@ set(CORE_SOURCES set(APP_SOURCES main.cpp App.cpp + SignalList.cpp PaneView.cpp ) ``` +`SignalList.cpp` stays in the list — it holds `App::drawSignalList()` and +dropping it is a link error, not a warning. + `PaneView.cpp` needs ImGui headers, so it belongs to the executable, not the core library — that is what keeps `udpscope_tests` free of a GUI dependency. @@ -6977,7 +6990,8 @@ and after `paneView_.drawTree(...)`: } ``` -Add the live control to the View menu in `drawMenuBar()`: +There is no View menu yet — Task 9 built only File and Help. Add one to +`drawMenuBar()`, between the File and Help blocks: ```cpp if (ImGui::BeginMenu("View")) { @@ -9169,7 +9183,8 @@ TEST(PaneTree, CloneIsADeepCopy) { - [ ] **Step 8: Add the File menu and save on exit** -In `App::drawMenuBar()`, before the View menu: +In `App::drawMenuBar()`, **replace** the File menu block Task 9 wrote (the one +whose only item is Quit) — do not add a second one: ```cpp if (ImGui::BeginMenu("File")) {