Skip to content

Commit 644ab14

Browse files
HanSur94claude
andauthored
chore: track GSD planning docs (un-ignore .planning + docs/superpowers) (#168)
PR #61 added `.planning/`, `.superpowers/`, and `docs/superpowers/` to .gitignore as "local workflow artifacts". But git only ignores untracked files — 75 `.planning` files were already tracked and kept getting committed, while every planning doc created afterward was silently swallowed: 408 files (~6.8 MB) sat on disk but never entered the repo. Drop the `.planning/` and `docs/superpowers/` ignore rules and commit the previously-hidden GSD planning docs — PROJECT.md, MILESTONES.md, config.json, REQUIREMENTS/ROADMAP/STATE, codebase/, debug/, milestones/, research/, and the phase/quick directories. `.superpowers/` stays ignored (currently empty). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent c80c932 commit 644ab14

410 files changed

Lines changed: 90148 additions & 2 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
__pycache__/
4343
wiki-gen-summary.md
4444
.claude/worktrees/
45-
.planning/
45+
# .planning/ and docs/superpowers/ are tracked GSD planning docs (un-ignored intentionally).
4646
.superpowers/
47-
docs/superpowers/
4847
.matlab-tests-passed

.planning/MILESTONES.md

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# Milestones
2+
3+
## v2.0 Tag-Based Domain Model (Shipped: 2026-04-17)
4+
5+
**Phases completed:** 10 phases, 37 plans, 26 tasks
6+
7+
**Key accomplishments:**
8+
9+
- FastSenseWidget.refresh() now reuses FastSenseObj via updateData() on sensor-identity match, and getTimeRange() returns O(1) cached CachedXMin/CachedXMax instead of full array scan
10+
- Non-active pages now defer widget realization until first switchPage, with batched drawnow-interleaved realization reducing multi-page startup time proportional to page count.
11+
- One-liner:
12+
- One-liner:
13+
- 1. [Rule 1 - Bug] GaugeWidget.deriveRange had no early return after allVals calculation
14+
- IncrementalEventDetector, LiveEventPipeline, and EventViewer fully migrated from ThresholdRules/addThresholdRule to Thresholds/addThreshold, with zero ThresholdRules references remaining in EventDetection production code
15+
- One-liner:
16+
- Total calls migrated:
17+
- 1. [Rule 2 - Missing Critical Functionality] ThresholdRegistry.clear() added
18+
- Standalone Threshold binding via Threshold property on IconCardWidget, isstruct dispatch in MultiStatusWidget, and per-chip threshold fields in ChipBarWidget resolveChipColor
19+
- One-liner:
20+
- One-liner:
21+
- One-liner:
22+
- One-liner:
23+
- One-liner:
24+
- One-liner:
25+
- One-liner:
26+
- One-liner:
27+
- One-liner:
28+
- One-liner:
29+
- Octave smoke harness + recursive auto-default run_all_examples.m, both with byte-identical skip-list blocks and TagRegistry/EventBinding singleton-cleanup discipline — deterministic per-folder verification gate that every Wave 2 migration plan consumes
30+
- No-op audit pass.
31+
- No-op audit pass.
32+
- InfoColor added to DashboardTheme and IconCardWidget implemented with state-colored circle icon, numeric value display, and three-path data binding
33+
- 1. [Rule 1 - Bug] Fixed testChipColorUpdate using containers.Map for mutable closure
34+
- Sparkline rendering:
35+
- 1. [Rule 3 - Blocking] Wave 1 widget files not yet in worktree
36+
- One-liner:
37+
- One-liner:
38+
39+
---
40+
41+
## v1.0 Dashboard Performance Optimization (Shipped: 2026-04-04)
42+
43+
**Phases completed:** 1 phases, 3 plans, 2 tasks
44+
45+
**Key accomplishments:**
46+
47+
- One-liner:
48+
- Task 1: Consolidated onLiveTick with updateLiveTimeRangeFrom
49+
50+
---
51+
52+
## v1.0 Dashboard Engine Code Review Fixes (Shipped: 2026-04-03)
53+
54+
**Phases completed:** 1 phases, 4 plans, 2 tasks
55+
56+
**Key accomplishments:**
57+
58+
- Four correctness bugs patched in DashboardEngine: multi-page removeWidget, resize reflow, sensor listener parity, and dead removeDetached parameter removed
59+
- One-liner:
60+
- One-liner:
61+
62+
---
63+
64+
## v1.0 FastSense Advanced Dashboard (Shipped: 2026-04-03)
65+
66+
**Phases completed:** 9 phases, 24 plans, 21 tasks
67+
68+
**Key accomplishments:**
69+
70+
- One-liner:
71+
- One-liner:
72+
- DashboardSerializer.save() now correctly emits constructor calls and addChild() for all GroupWidget children in panel, collapsible, and tabbed modes, making .m round-trips reliable for any dashboard using groups
73+
- testTimerContinuesAfterError rewritten to trigger ErrorFcn indirectly via a throwing TimerFcn, giving INFRA-01 runnable automated coverage without calling any private method
74+
- 1. [Pre-existing] TestGroupWidget/testFullDashboardIntegration
75+
- One-liner:
76+
- One-liner:
77+
- One-liner:
78+
- DashboardPage handle class with Name/Widgets/addWidget/toStruct, DashboardEngine.addPage() routing, and 8-method TestDashboardMultiPage scaffold with 3 tests green immediately
79+
- DashboardEngine extended with Pages/ActivePage properties, visible PageBar with themed buttons for multi-page dashboards, switchPage() navigation, and activePageWidgets() scoping for all widget iteration methods
80+
- One-liner:
81+
- testSaveLoadRoundTrip now asserts that ActivePage index 2 is preserved through JSON save/load, closing the LAYOUT-05 coverage gap for DashboardEngine.m lines 1063-1070
82+
- 1. [Rule 1 - Bug] Sensor constructor positional argument
83+
- DetachCallback property + addDetachButton() added to DashboardLayout, injecting a '^' button at [0.82 0.90 0.08 0.08] in every widget panel when callback is wired — DETACH-01 satisfied
84+
- DashboardEngine gains DetachedMirrors registry + detachWidget/removeDetached methods + onLiveTick mirror loop, completing all 7 DETACH tests (DETACH-01 through DETACH-07)
85+
- Multi-page JSON save/load round-trip tests covering SERIAL-01, SERIAL-04, SERIAL-05 with a bug fix for single-named-page save routing to widgetsPagesToConfig
86+
- Multi-page .m export fixed to emit a proper MATLAB function + switchPage routing; 5 new round-trip tests covering SERIAL-02 and SERIAL-03 all pass
87+
- One-liner:
88+
- One-liner:
89+
- One-liner:
90+
- One-liner:
91+
- One-liner:
92+
- One-liner:
93+
94+
---
95+
96+
## v1.0 Advanced Dashboard (Shipped: 2026-04-03)
97+
98+
**Phases completed:** 8 phases, 22 plans, 21 tasks
99+
100+
**Key accomplishments:**
101+
102+
- One-liner:
103+
- One-liner:
104+
- DashboardSerializer.save() now correctly emits constructor calls and addChild() for all GroupWidget children in panel, collapsible, and tabbed modes, making .m round-trips reliable for any dashboard using groups
105+
- testTimerContinuesAfterError rewritten to trigger ErrorFcn indirectly via a throwing TimerFcn, giving INFRA-01 runnable automated coverage without calling any private method
106+
- 1. [Pre-existing] TestGroupWidget/testFullDashboardIntegration
107+
- One-liner:
108+
- One-liner:
109+
- One-liner:
110+
- DashboardPage handle class with Name/Widgets/addWidget/toStruct, DashboardEngine.addPage() routing, and 8-method TestDashboardMultiPage scaffold with 3 tests green immediately
111+
- DashboardEngine extended with Pages/ActivePage properties, visible PageBar with themed buttons for multi-page dashboards, switchPage() navigation, and activePageWidgets() scoping for all widget iteration methods
112+
- One-liner:
113+
- testSaveLoadRoundTrip now asserts that ActivePage index 2 is preserved through JSON save/load, closing the LAYOUT-05 coverage gap for DashboardEngine.m lines 1063-1070
114+
- 1. [Rule 1 - Bug] Sensor constructor positional argument
115+
- DetachCallback property + addDetachButton() added to DashboardLayout, injecting a '^' button at [0.82 0.90 0.08 0.08] in every widget panel when callback is wired — DETACH-01 satisfied
116+
- DashboardEngine gains DetachedMirrors registry + detachWidget/removeDetached methods + onLiveTick mirror loop, completing all 7 DETACH tests (DETACH-01 through DETACH-07)
117+
- Multi-page JSON save/load round-trip tests covering SERIAL-01, SERIAL-04, SERIAL-05 with a bug fix for single-named-page save routing to widgetsPagesToConfig
118+
- Multi-page .m export fixed to emit a proper MATLAB function + switchPage routing; 5 new round-trip tests covering SERIAL-02 and SERIAL-03 all pass
119+
- One-liner:
120+
- One-liner:
121+
- One-liner:
122+
- One-liner:
123+
124+
---
125+
126+
## v1.0 Advanced Dashboard (Shipped: 2026-04-03)
127+
128+
**Phases completed:** 7 phases, 19 plans, 21 tasks
129+
130+
**Key accomplishments:**
131+
132+
- One-liner:
133+
- One-liner:
134+
- DashboardSerializer.save() now correctly emits constructor calls and addChild() for all GroupWidget children in panel, collapsible, and tabbed modes, making .m round-trips reliable for any dashboard using groups
135+
- testTimerContinuesAfterError rewritten to trigger ErrorFcn indirectly via a throwing TimerFcn, giving INFRA-01 runnable automated coverage without calling any private method
136+
- 1. [Pre-existing] TestGroupWidget/testFullDashboardIntegration
137+
- One-liner:
138+
- One-liner:
139+
- One-liner:
140+
- DashboardPage handle class with Name/Widgets/addWidget/toStruct, DashboardEngine.addPage() routing, and 8-method TestDashboardMultiPage scaffold with 3 tests green immediately
141+
- DashboardEngine extended with Pages/ActivePage properties, visible PageBar with themed buttons for multi-page dashboards, switchPage() navigation, and activePageWidgets() scoping for all widget iteration methods
142+
- One-liner:
143+
- testSaveLoadRoundTrip now asserts that ActivePage index 2 is preserved through JSON save/load, closing the LAYOUT-05 coverage gap for DashboardEngine.m lines 1063-1070
144+
- 1. [Rule 1 - Bug] Sensor constructor positional argument
145+
- DetachCallback property + addDetachButton() added to DashboardLayout, injecting a '^' button at [0.82 0.90 0.08 0.08] in every widget panel when callback is wired — DETACH-01 satisfied
146+
- DashboardEngine gains DetachedMirrors registry + detachWidget/removeDetached methods + onLiveTick mirror loop, completing all 7 DETACH tests (DETACH-01 through DETACH-07)
147+
- Multi-page JSON save/load round-trip tests covering SERIAL-01, SERIAL-04, SERIAL-05 with a bug fix for single-named-page save routing to widgetsPagesToConfig
148+
- Multi-page .m export fixed to emit a proper MATLAB function + switchPage routing; 5 new round-trip tests covering SERIAL-02 and SERIAL-03 all pass
149+
- One-liner:
150+
151+
---

.planning/PROJECT.md

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# FastSense Advanced Dashboard
2+
3+
## What This Is
4+
5+
A MATLAB sensor data dashboard engine with nested layout organization (tabs, collapsible groups, multi-page navigation), per-widget info tooltips with Markdown rendering, and detachable live-mirrored widgets that pop out as independent figure windows. Built for MATLAB engineers analyzing sensor data with threshold-based monitoring.
6+
7+
## Core Value
8+
9+
Users can organize complex dashboards into navigable sections and pop out any widget for detailed analysis without losing the dashboard context.
10+
11+
## Requirements
12+
13+
### Validated
14+
15+
- ✓ Widget-based dashboard composition with 20+ widget types — existing
16+
- ✓ 24-column grid layout system — existing
17+
- ✓ Dashboard serialization (JSON/.m export) — existing
18+
- ✓ Theming (light/dark, custom colors) — existing
19+
- ✓ Live data refresh via DashboardEngine timer — existing
20+
- ✓ GroupWidget for basic widget grouping — existing
21+
- ✓ DashboardToolbar with global controls — existing
22+
- ✓ WebBridge for browser-based visualization — existing
23+
- ✓ Timer error recovery (ErrorFcn + auto-restart) — v1.0
24+
- ✓ GroupWidget .m export preserves children — v1.0
25+
- ✓ Shared normalizeToCell helper for jsondecode normalization — v1.0
26+
- ✓ Collapsible sections with grid reflow — v1.0
27+
- ✓ Tab persistence through save/load — v1.0
28+
- ✓ Widget info tooltips with Markdown rendering — v1.0
29+
- ✓ Multi-page dashboards with PageBar navigation — v1.0
30+
- ✓ Active page persistence through save/load — v1.0
31+
- ✓ Detachable live-mirrored widgets — v1.0
32+
- ✓ Independent time axis zoom on detached FastSenseWidget — v1.0
33+
- ✓ Multi-page JSON and .m round-trip serialization — v1.0
34+
- ✓ Collapsed state persistence — v1.0
35+
- ✓ Legacy JSON backward compatibility — v1.0
36+
- ✓ DividerWidget for visual dashboard section separation — v1.0 Phase 8
37+
- ✓ addCollapsible convenience method on DashboardEngine — v1.0 Phase 8
38+
- ✓ Configurable Y-axis limits (YLimits) on FastSenseWidget — v1.0 Phase 8
39+
- ✓ Threshold mini-labels (ShowThresholdLabels) on FastSense and FastSenseWidget — v1.0 Phase 9
40+
41+
### Active
42+
43+
- ✓ Dashboard performance optimization: theme caching, O(1) widget dispatch, single-pass live tick, in-place resize, visibility page switch — v1.0 Performance
44+
- ✓ Tag-based domain model: unified `Tag` foundation, `TagRegistry`, `MonitorTag` derived time-series, `CompositeTag` aggregation — v2.0
45+
- ✓ Events attached to tags with FastSense overlay rendering — v2.0
46+
47+
## Current State
48+
49+
**Shipped:** v2.0 Tag-Based Domain Model (2026-04-17)
50+
51+
The SensorThreshold subsystem has been fully rebooted on a unified `Tag` foundation. Legacy `Sensor`/`Threshold`/`StateChannel`/`CompositeThreshold` classes are deleted. All consumers (FastSenseWidget, dashboard widgets, EventDetection, LiveEventPipeline) operate through the Tag API (`addTag`, `getXY`, `valueAt`). Events bind to tags via `EventBinding` registry and render as toggleable round markers in FastSense. All `examples/` scripts have been migrated to the Tag API and a dedicated 5-script showcase lives under `examples/02-sensors/tags/`.
52+
53+
**Vocabulary:** `SensorTag`, `StateTag`, `MonitorTag`, `CompositeTag`, `TagRegistry`, `EventBinding`. FastSense API: `addTag(t)`.
54+
55+
## Current Milestone: v2.1 Tag-API Tech Debt Cleanup
56+
57+
**Goal:** Close the 4 non-blocking tech debt items surfaced by the v2.0 milestone audit so the Tag-API codebase is free of dead code, test-skip gaps, and stubbed example demos.
58+
59+
**Target items (from `.planning/milestones/v2.0-MILESTONE-AUDIT.md`):**
60+
- Stub or delete `EventDetector.detect(tag, threshold)` dead code referencing the deleted `Threshold` API
61+
- Fix `DashboardSerializer` `.m` script export to handle `source.type='tag'` (currently silently omits Tag-bound widgets; JSON path works)
62+
- Clean up 93 `Threshold(` constructor references across 42 MATLAB-only suite test files (fail on MATLAB, skip on Octave today)
63+
- Rewrite `examples/05-events/example_event_detection_live.m` and `example_event_viewer_from_file.m` as fully-migrated `MonitorTag + EventStore + EventBinding` pipelines (remove deprecation stubs)
64+
65+
**Deferred to future milestones:**
66+
- Asset hierarchy (Asset tree, templates, tag-to-asset binding, browse rollups)
67+
- Custom event GUI (click-drag region selection in FastSense → label dialog)
68+
- Calc tags / formula evaluator for arbitrary derived tags
69+
- Tri-state / continuous severity MonitorTag output
70+
- WebBridge parity for Tag API features
71+
72+
### Out of Scope
73+
74+
- Drag-and-drop visual rearrangement — complexity vs. value for MATLAB-script-driven workflows
75+
- Cross-filtering between widgets — would require a data binding framework
76+
- Interactive controls (dropdowns, sliders) — DashboardEngine is visualization, not control panel
77+
- Browser/WebBridge parity for new features — future milestone
78+
- GroupWidget children individual detach buttons — v1 limitation, top-level only
79+
- Time panel in multi-page mode — works on active page only (known limitation)
80+
81+
## Context
82+
83+
- FastSense is a MATLAB library for high-performance time series visualization with sensor/threshold modeling
84+
- Dashboard engine (`libs/Dashboard/`) has DashboardEngine, DashboardWidget (20+ types), DashboardLayout (24-col grid), DashboardSerializer, DashboardTheme, DashboardBuilder, DashboardPage, DetachedMirror, MarkdownRenderer
85+
- v1.0 shipped: 9 phases, 24 plans, 44 requirements, 2948 lines added across 24 files
86+
- v1.0 code review shipped: 1 phase, 4 plans, 14 bug fixes across DashboardEngine, GroupWidget, DashboardSerializer, DashboardLayout, DashboardWidget, DashboardTheme, HeatmapWidget, BarChartWidget, HistogramWidget
87+
- v1.0 performance shipped: 1 phase, 3 plans — theme caching (getCachedTheme), containers.Map dispatch, single-pass onLiveTick, repositionPanels for resize, visibility toggle for page switch
88+
- New classes added: DashboardPage.m, DetachedMirror.m, DividerWidget.m
89+
- Key patterns established: central injection via realizeWidget(), ReflowCallback for layout updates, DetachCallback for widget pop-out, normalizeToCell for jsondecode safety, markRealized/markUnrealized for lifecycle encapsulation, linesForWidget for shared serialization dispatch, getCachedTheme for theme struct caching, WidgetTypeMap_ for O(1) widget dispatch
90+
- 24,473 LOC MATLAB across libs/ (as of v1.0 completion)
91+
- Known tech debt: 5 items (INFO-03 Markdown downgrade, missing serialization tests, single-page save edge case) — code review tech debt resolved
92+
93+
## Constraints
94+
95+
- **Tech stack**: Pure MATLAB (no external dependencies) — consistent with existing codebase
96+
- **Backward compatibility**: Existing dashboard scripts and serialized dashboards continue to work
97+
- **Widget contract**: Features work through the existing DashboardWidget base class interface
98+
- **Performance**: Detached live-mirrored widgets share the engine timer, no extra timers
99+
100+
## Key Decisions
101+
102+
| Decision | Rationale | Outcome |
103+
|----------|-----------|---------|
104+
| Extend GroupWidget for tabs/collapsible | GroupWidget already handles widget containment | ✓ Good |
105+
| Info tooltip via widget header icon | Minimal UI footprint, consistent placement | ✓ Good |
106+
| Live mirror via DashboardEngine timer | Reuse existing refresh infrastructure | ✓ Good |
107+
| Central injection via realizeWidget() | Single choke-point for all 20+ widget types | ✓ Good |
108+
| DetachedMirror as separate class (not DashboardWidget) | Avoids grid layout interference | ✓ Good |
109+
| Clone via toStruct/fromStruct round-trip | Works for all widget types without per-type dispatch | ✓ Good |
110+
| containers.Map for CloseRequestFcn reference | Solves closure-over-cell-array mutation limitation | ✓ Good |
111+
| Plain text popup (HTML stripped) over javacomponent | Cross-platform safe (Octave compatible) | ✓ Good |
112+
| DividerWidget via uipanel not axes | Simpler, no zoom/pan interaction, cheaper render | ✓ Good |
113+
| addCollapsible on DashboardEngine (not DashboardBuilder) | DashboardEngine owns programmatic API | ✓ Good |
114+
| YLimits=[] for auto, [min max] for fixed | Consistent with MATLAB ylim() convention | ✓ Good |
115+
| ShowThresholdLabels opt-in (default false) | Backward compatible; labels only when explicitly requested | ✓ Good |
116+
| Threshold label at right edge, repositions on zoom/pan | Always visible in view, doesn't move with data | ✓ Good |
117+
| Realized property SetAccess=private with markRealized/markUnrealized | Enforces lifecycle contract, prevents external bypass | ✓ Good |
118+
| linesForWidget shared static helper in DashboardSerializer | Eliminates exportScript/exportScriptPages drift | ✓ Good |
119+
| wireListeners private helper in DashboardEngine | Single listener-wiring call for both page-routed and single-page paths | ✓ Good |
120+
| getCachedTheme with preset invalidation | Eliminates 4 redundant DashboardTheme() calls per render/switch/tick | ✓ Good |
121+
| containers.Map widget dispatch (WidgetTypeMap_) | O(1) type lookup replacing 17-case switch; kpi alias preserved | ✓ Good |
122+
| repositionPanels for onResize | In-place panel repositioning vs destroy+recreate; fallback to rerenderWidgets on missing handles | ✓ Good |
123+
| switchPage visibility toggle | Hide/show panels instead of full rerender; pre-allocate all page panels at render() | ✓ Good |
124+
| Single-pass onLiveTick with updateLiveTimeRangeFrom | One activePageWidgets() call, merged mark-dirty+refresh loop | ✓ Good |
125+
| v2.0 reboot under unified `Tag` root (Option 2) | No-users codebase; preserves design wins from 1001-1003 as concepts; cleanest end state vs. interface-shim approach (Option 3) | Pending v2.0 |
126+
| Vocabulary: `Tag` suffix on all primitives (`SensorTag`, `MonitorTag`, ...) | Trendminer-faithful; uniform mental model; `addTag()` API replaces `addSensor()` | Pending v2.0 |
127+
| Single `TagRegistry` (replaces `SensorRegistry` + `ThresholdRegistry`) | One namespace, one search surface; fewer parallel singletons | Pending v2.0 |
128+
| MonitorTag as full time-series signal (not current-state only) | Plottable, persistable, event-detectable; reuses existing infrastructure | Pending v2.0 |
129+
| Defer asset hierarchy (D), custom event GUI (F), calc tags (G) to later milestones | Ambitious tier (A+B+C+E) is shippable on its own; D/F/G are independent additions | Pending v2.0 |
130+
131+
## Evolution
132+
133+
This document evolves at phase transitions and milestone boundaries.
134+
135+
**After each phase transition** (via `/gsd:transition`):
136+
1. Requirements invalidated? → Move to Out of Scope with reason
137+
2. Requirements validated? → Move to Validated with phase reference
138+
3. New requirements emerged? → Add to Active
139+
4. Decisions to log? → Add to Key Decisions
140+
5. "What This Is" still accurate? → Update if drifted
141+
142+
**After each milestone** (via `/gsd:complete-milestone`):
143+
1. Full review of all sections
144+
2. Core Value check — still the right priority?
145+
3. Audit Out of Scope — reasons still valid?
146+
4. Update Context with current state
147+
148+
---
149+
*Last updated: 2026-04-22 — v2.1 milestone (Tag-API Tech Debt Cleanup) started*

0 commit comments

Comments
 (0)