Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
8fd51b9
feat(goose): add stable multi-source Messages scope and move repeats …
masarray Oct 21, 2026
897c810
feat(goose): add stable multi-source Messages scope and move repeats …
masarray Oct 21, 2026
4db55df
feat(goose): add stable multi-source Messages scope and move repeats …
masarray Oct 21, 2026
f97b610
feat(goose): add stable multi-source Messages scope and move repeats …
masarray Oct 21, 2026
a2547c0
fix(goose): preserve filtered keyed selection and avoid unregistered …
masarray Oct 21, 2026
34b31cd
fix(goose): preserve filtered keyed selection and avoid unregistered …
masarray Oct 21, 2026
bd4b919
test(goose): selected physical publisher keys survive stale and return
masarray Oct 21, 2026
fcc73c8
test(goose): account for the live unselected publisher
masarray Oct 21, 2026
3d09b18
feat(goose): define bounded decoded-value change envelope
masarray Oct 21, 2026
80a58f6
feat(goose): decoder-side bounded verified DataSet change ring and sa…
masarray Oct 21, 2026
6d2a399
feat(goose): keep transient decoded-value change evidence on stable s…
masarray Oct 21, 2026
7d0db02
feat(goose): project bounded decoder value-change evidence into GOOSE…
masarray Oct 21, 2026
6f22f64
feat(goose): understated time-bounded Changed marker on true DataSet …
masarray Oct 21, 2026
f209538
feat(goose): explicit follow state and once-per-batch visible append …
masarray Oct 21, 2026
c589465
feat(goose): compact Messages actions and follow live button; no mous…
masarray Oct 21, 2026
908f544
feat(goose): suspend on real operator interaction; coalesce batch fol…
masarray Oct 21, 2026
2ff9b11
test(goose): parameterize golden GOOSE payload value and revision
masarray Oct 21, 2026
e304501
test(goose): genuine decoded value deltas baseline retrans confRev bu…
masarray Oct 21, 2026
d93f46b
fix(goose): show source scope and transient meaningful event accent; …
masarray Oct 21, 2026
b26971b
feat(goose): limited-time meaningful event accent and visible decoder…
masarray Oct 21, 2026
5b15ec9
fix(goose): distinguish decoder sessions so revision reset cannot sup…
masarray Oct 21, 2026
2da10a5
fix(goose): distinguish decoder sessions so revision reset cannot sup…
masarray Oct 21, 2026
5785e6e
fix(goose): distinguish decoder sessions so revision reset cannot sup…
masarray Oct 21, 2026
ccc8bec
perf(goose): allocation-free per-frame DataSet value comparison with …
masarray Oct 21, 2026
d989507
ci(goose): execute exact-head Windows, stability, architecture, CodeQ…
masarray Oct 21, 2026
44a30c8
test(goose): align source viewport geometry assertion after removing …
masarray Oct 21, 2026
0f3bd7c
fix(goose): bound source change revision to decoder capture session
masarray Oct 21, 2026
7224432
perf(goose): coalesce decoded change notices by physical publisher on…
masarray Oct 21, 2026
74b6385
test(goose): row notices survive decoder-session revision restart
masarray Oct 21, 2026
bea07c4
fix(goose): follow newest visible history on first GOOSE tab activation
masarray Oct 21, 2026
53d50ce
fix(goose): follow newest visible history on first GOOSE tab activation
masarray Oct 21, 2026
2c92328
feat(goose): latch decoded publisher change until explicit per-source…
masarray Oct 21, 2026
dad9632
feat(goose): explicit follow switch state and latched per-message ACK…
masarray Oct 21, 2026
eeb69f1
feat(goose): explicit physical publisher and history row ACK from cli…
masarray Oct 21, 2026
a2af9af
style(goose): paired compact vector switches and acknowledgement-driv…
masarray Oct 21, 2026
4ed73db
test(goose): positive-negative latched publisher ACK, coalescing, rea…
masarray Oct 21, 2026
4f660ad
test(goose): assert paired header switches and explicit ACK without a…
masarray Oct 21, 2026
9d66ac6
fix(goose): follow explicit state without false bottom-offset suspens…
masarray Oct 21, 2026
4400616
fix(goose): use straightforward definitely-assigned follow VM guard
masarray Oct 21, 2026
571070d
feat(goose): preserve exact decoded event frame and changed DataSet e…
masarray Oct 21, 2026
5ec3890
feat(goose): preserve exact decoded event frame and changed DataSet e…
masarray Oct 21, 2026
6e84385
refactor(goose): Sources unread badge is derived from Messages ACK jo…
masarray Oct 21, 2026
f263442
feat(goose): decoder-backed event journal drives Sources+Messages+Ins…
masarray Oct 21, 2026
ffc1567
perf(goose): project unread indicator once per receive batch rather t…
masarray Oct 21, 2026
c755d91
feat(goose): click unread source navigates and pins exact event; ACK …
masarray Oct 21, 2026
eeac75b
feat(goose): inspector shows explicit verified changed-signal count a…
masarray Oct 21, 2026
92d20fc
style(goose): single-line Messages header, remove Clear filter, highl…
masarray Oct 21, 2026
c4709e3
test(goose): verify inherited chevrons and single-row, single-ACK tri…
masarray Oct 21, 2026
62bd30a
test(goose): align Data header contract with signal-change count in s…
masarray Oct 21, 2026
bc03f50
test(goose): decoder journal retains exact timestamp, frame and previ…
masarray Oct 21, 2026
1c7ec6b
test(goose): enforce event-owned ACK instead of obsolete independent …
masarray Oct 21, 2026
7518081
reliability(goose): retain unread decoded events ahead of repeats and…
masarray Oct 21, 2026
1bc4fa9
fix(goose): source-driven historical focus preserves correct publishe…
masarray Oct 21, 2026
6ea7863
fix(goose): derive Inspector value accent from unread selected event;…
masarray Oct 21, 2026
80f192d
style(goose): keep Data rows single-line and natural; put before/afte…
masarray Oct 21, 2026
d8269bf
feat(goose): single workspace click or Enter ACKs currently inspected…
masarray Oct 21, 2026
b25e66e
test(goose): guard one-line value, tooltip, event-gated accent and ce…
masarray Oct 21, 2026
75bcf5c
style(goose): replace noisy Changed label with minimal red unread dot
masarray Oct 21, 2026
27715a9
test(goose): lock minimal red-dot unread notification UX contract
masarray Oct 21, 2026
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: 3 additions & 1 deletion .github/workflows/candidate-package.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
name: Release candidate package

on:
push:
branches: [fix/goose-multisource-filter-20261021]
pull_request:
branches: [main]
paths:
Expand Down Expand Up @@ -45,7 +47,7 @@ env:
jobs:
candidate:
name: Build verified Windows x64 candidate
if: github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'stabilization/') || startsWith(github.head_ref, 'architecture/') || startsWith(github.head_ref, 'legal/') || startsWith(github.head_ref, 'fix/') || startsWith(github.head_ref, 'feat/')
if: github.ref_name == 'fix/goose-multisource-filter-20261021' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'stabilization/') || startsWith(github.head_ref, 'architecture/') || startsWith(github.head_ref, 'legal/') || startsWith(github.head_ref, 'fix/') || startsWith(github.head_ref, 'feat/')
runs-on: windows-latest
timeout-minutes: 50

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI

on:
push:
branches: [main]
branches: [main, fix/goose-multisource-filter-20261021]
pull_request:
branches: [main]
workflow_dispatch:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CodeQL

on:
push:
branches: [main]
branches: [main, fix/goose-multisource-filter-20261021]
pull_request:
branches: [main]
schedule:
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
name: Dependency security review

on:
push:
branches: [fix/goose-multisource-filter-20261021]
pull_request:
branches: [main]

Expand Down Expand Up @@ -58,6 +60,7 @@ jobs:
exit 1

github-dependency-review:
if: github.event_name == 'pull_request'
name: GitHub dependency delta review
runs-on: ubuntu-latest
timeout-minutes: 6
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/runtime-architecture.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
name: Runtime architecture

on:
push:
branches: [fix/goose-multisource-filter-20261021]
pull_request:
branches: [main]
paths:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/runtime-stability.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
name: Runtime stability

on:
push:
branches: [fix/goose-multisource-filter-20261021]
pull_request:
branches: [main]
paths:
Expand Down
61 changes: 57 additions & 4 deletions scripts/verify-workspace-spacing.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,10 @@ foreach ($name in @('WorkspacePanelInset', 'WorkspacePanelGapBelow', 'WorkspaceH
# compact disclosure style; all other workspace layout tokens stay untouched.
$gooseExpanderStyle = $theme.SelectNodes("//w:Style[@x:Key='GooseDatasetExpanderStyle']", $ns)
Assert-True ($gooseExpanderStyle.Count -eq 1) 'GOOSE has one scoped engineer disclosure style'
$gooseExpanderUsage = $window.SelectNodes("//w:Expander[@Style='{StaticResource GooseDatasetExpanderStyle}']", $ns)
Assert-True ($gooseExpanderUsage.Count -eq 1) 'GOOSE typed rows use scoped compact chevrons'
# The event-aware DataSet row is based on the shared GOOSE-only disclosure style,
# preserving its exact compact chevron template while adding conditional value accents.
$gooseExpanderUsage = $window.SelectNodes("//w:Expander/w:Expander.Style/w:Style[@BasedOn='{StaticResource GooseDatasetExpanderStyle}']", $ns)
Assert-True ($gooseExpanderUsage.Count -eq 1) 'GOOSE typed rows retain scoped compact chevrons through BasedOn'
foreach ($binding in @(
'GooseInspectorRows',
'GooseTimelineCountersText',
Expand All @@ -112,7 +114,7 @@ $scrollOffset = $inspector.IndexOf('<ScrollViewer Grid.Row="1"')
Assert-True ($headerOffset -ge 0 -and $scrollOffset -gt $headerOffset) 'Inspector header remains above independently scrolling evidence'
Assert-True ($inspector.Contains('Grid.Row="0" Margin="0,0,0,12"')) 'Inspector header stays in fixed grid row'
Assert-True ($inspector.Contains('Text="Data"')) 'Value group has compact title'
Assert-True ($inspector.Contains('Grid.Column="1" Margin="10,0,3,0"')) 'Value item count uses a separate aligned column'
Assert-True ($inspector.Contains('<StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center" Margin="10,0,3,0">')) 'Value and changed counts share a separate aligned column'
Assert-True ($inspector.Contains('Text="{Binding TypeText}"')) 'Expanded signal kind uses friendly type description'
Assert-True ($inspector.Contains('Text="{Binding ProtocolTypeText}"')) 'Exact original wire type stays available in expanded evidence'
Assert-True ($inspector.Contains('Text="{Binding ConfigurationTypeText}"')) 'Matched configuration type remains available as technical evidence'
Expand Down Expand Up @@ -163,7 +165,9 @@ Assert-True ($gooseLeft.Contains('Command="{Binding GooseClearSearchCommand}"'))
Assert-True ($gooseLeft.Contains('GooseHasSearchText')) 'Clear control visibility responds to actual input'
Assert-True ($gooseLeft.Contains('ScrollViewer.VerticalScrollBarVisibility="Auto"')) 'Source list has an independent scrollbar'
Assert-True ($gooseLeft.Contains('VirtualizingPanel.VirtualizationMode="Recycling"')) 'Source rows remain virtualized'
Assert-True ($gooseLeft.Contains('<Grid Grid.Row="3" MinHeight="0">')) 'Scrollable source viewport is height constrained'
# The obsolete Sources repeat toggle was removed. The bounded source list now
# occupies row 2 rather than row 3; the star-sized viewport is unchanged.
Assert-True ($gooseLeft.Contains('<Grid Grid.Row="2" MinHeight="0">')) 'Scrollable source viewport is height constrained'
Assert-True (-not $gooseLeft.Contains('Text="{Binding GooseFilterSummaryText}"')) 'Redundant source footer removed'

$sectionNodes = $window.SelectNodes("//w:Expander[@Style='{StaticResource GooseInspectorSectionExpanderStyle}']", $ns)
Expand All @@ -178,6 +182,55 @@ Assert-True ($theme.OuterXml.Contains('GooseMaterialExpandCircle')) 'Inspector a
Assert-True (-not $inspector.Contains('Content="Identify these signals in the Configuration tab"')) 'Long textual onboarding removed from signal list'
Assert-True ($inspector.Contains('Content="Identify signals"')) 'Compact signal mapping action retained'
Assert-True ($source.Contains('Text="Messages"')) 'History is available without changing protocol logic'
# GOOSE operator-acknowledged alert contract: UX should never silently expire
# received evidence before the engineer has a chance to inspect it.
Assert-True ($source.Contains('x:Key="GooseHeaderSwitchStyle"')) 'GOOSE header exposes one compact vector switch style'
Assert-True (([regex]::Matches($source, 'Style="\{StaticResource GooseHeaderSwitchStyle\}"')).Count -eq 2) 'Show repeats and Follow live use exactly two adjacent switches'
Assert-True ($source.Contains('IsChecked="{Binding IncludeGooseRetransmission, Mode=TwoWay}"')) 'Repeats switch binds only to message representation'
Assert-True ($source.Contains('IsChecked="{Binding GooseFollowLive, Mode=TwoWay}"')) 'Follow-live switch is a two-way explicit state'
Assert-True (-not $source.Contains('Command="{Binding GooseResumeFollowCommand}"')) 'Old transient Follow live button is removed'
Assert-True ($source.Contains('IsUnacknowledgedEvent') -and $source.Contains('HasUnacknowledgedValueChange')) 'Message and source alert visuals bind to acknowledged state'
Assert-True ($vmSource.Contains('public void Acknowledge()') -and
$vmSource.Contains('public void AcknowledgeGooseHistoryEvent(')) 'ACK belongs to the history event, not an independent source flag'
Assert-True (-not $vmSource.Contains('ExpireEmphasis(') -and
-not $vmSource.Contains('ExpireValueChangeNotice(')) 'Streaming UI does not auto-expire unread engineering evidence'
$messageStart = $source.IndexOf('<!-- Main event timeline: lean, readable, no debug ornaments. -->')
$messageEnd = $source.IndexOf('x:Name="GooseMessageGrid"', $messageStart)
Assert-True ($messageStart -ge 0 -and $messageEnd -gt $messageStart) 'Messages header markup present'
$messageHeader = $source.Substring($messageStart, $messageEnd - $messageStart)
Assert-True (-not $messageHeader.Contains('Clear filter')) 'Messages header has no ugly Clear filter button'
Assert-True (-not $messageHeader.Contains('Grid.Row="1"')) 'Messages header uses exactly one horizontal line'
Assert-True ($messageHeader.Contains('GooseTimelineCountersText')) 'Compact counters remain inline in Messages header'
Assert-True ($vmSource.Contains('InspectNextUnreadGooseSource(') -and
$vmSource.Contains('AcknowledgeGooseHistoryEvent(') -and
$vmSource.Contains('ProjectGooseUnreadIndicators(')) 'Sources and Messages share one unread-event journal'
Assert-True ($inspector.Contains('GooseInspectorChangedCountText') -and
$inspector.Contains('Binding IsChangeHighlighted') -and
$inspector.Contains('ChangeTooltipText')) 'Inspector shows only unread decoded changes and keeps before/after in tooltips'
Assert-True (-not $inspector.Contains('Text="CHANGED"') -and
-not $inspector.Contains('Text="{Binding ChangeText}"')) 'GOOSE Data values remain one line, no stacked change labels'
Assert-True ($vmSource.Contains('public bool AcknowledgeInspectedGooseEvent()') -and
$vmSource.Contains('private bool GooseInspectorAlertActive =>') -and
$vmSource.Contains('ReferenceEquals(_selectedGooseTrafficRow, entry)')) 'One ACK invalidates selected Inspector visual state immediately'
$windowCode = Get-Content -LiteralPath (Join-Path $Root 'src/ProcessBus.App.Wpf/MainWindow.xaml.cs') -Raw
Assert-True ($windowCode.Contains('PreviewMouseDown += GooseWindow_PreviewMouseDown') -and
$windowCode.Contains('PreviewKeyDown += GooseWindow_PreviewKeyDown')) 'Workspace click/Enter acknowledge current inspected event without suppressing controls'
Assert-True ($windowCode.Contains('ReferenceEquals(vm.SelectedGooseTrafficRow, history)')) 'Clicking a different history row never pre-ACKs unread evidence'
Write-Host 'GOOSE tri-pane event contract: PASS (one-line header, decoder evidence, source navigation, single ACK, inspector deltas)'
# Source unread state must be an Android-style minimal dot, never on-card text
# or a second notification border. Tooltip retains the count without noise.
$gooseSourceStart = $source.IndexOf('x:Name="GooseSourceList"')
$gooseSourceEnd = $source.IndexOf('<!-- Main event timeline:', $gooseSourceStart)
Assert-True ($gooseSourceStart -ge 0 -and $gooseSourceEnd -gt $gooseSourceStart) 'GOOSE source notification template found'
$gooseSourceTemplate = $source.Substring($gooseSourceStart, $gooseSourceEnd - $gooseSourceStart)
Assert-True ($gooseSourceTemplate.Contains('<Ellipse Grid.Column="1"') -and
$gooseSourceTemplate.Contains('Fill="#F04E5F"') -and
$gooseSourceTemplate.Contains('ToolTip="{Binding UnreadEventText}"') -and
$gooseSourceTemplate.Contains('Binding HasUnacknowledgedValueChange')) 'Unread status is one unobtrusive red dot, tooltip only'
Assert-True (-not $gooseSourceTemplate.Contains('<TextBlock Text="Changed"') -and
-not $gooseSourceTemplate.Contains('BorderBrush" Value="#A47D49"')) 'No noisy Changed text or redundant amber card outline'
Write-Host 'GOOSE source badge contract: PASS (single red dot, unread tooltip, SSOT ACK)'
Write-Host 'GOOSE acknowledgement UX contract: PASS (paired switches, per-source/event ACK, no timer expiry)'
Write-Host 'GOOSE calm UX contract: PASS (Material icons, searchable scrolling sources, independent Inspector accordions)'
Write-Host 'GOOSE readout contract: PASS (scoped chevron, RX/events, TEST, stable typed rows, live return)'
Write-Host 'WPF workspace spacing contract: PASS (8 DIP columns / 8 DIP panel gaps, named insets)'
Loading
Loading