diff --git a/evidence/dm-initial-publication-20261008/README.md b/evidence/dm-initial-publication-20261008/README.md index 14cbdef0d..26ad41b8e 100644 --- a/evidence/dm-initial-publication-20261008/README.md +++ b/evidence/dm-initial-publication-20261008/README.md @@ -708,3 +708,55 @@ Raw/source control files are under unmeasured. The next required installed observation also retains Layout.widget identity and original node/layout source epochs in the existing recorder so native work can distinguish real changed extents from repeated late requests. + + +## Row-resource frontend delivered + +Toad572 merged. Built exact Toad31fe7bd25 with unchanged nativec330/Core09a. +Full954 assets/69packages/2857RECORD entries/native package matched. Installed +real wire/Toad resource control passed for compact and Markdown: composition +owns children, recomposition replaces retired instances, removed bodies cannot +authorize reads. Source partial-paint control passed with original durable reads. + +Installed original burst:160 ordered wheel packets/20incoming/16recipients, +provider0. Median4.72ms/p95220.87/max259.54 input, final backlog10.48ms; frame +p95109.43/max212.56; loop max124.10ms. No reliable speed gain established. +Repeated queries are removed, but pacing still FAIL. + +New diagnostic identifies253 Layout sources:48CommsRow,43CollapsibleTitle, +40MessageNotifications,40Contents,40IRCMessage,11IRCMessageText,10Window, +remaining navigation widgets17. No identical identity+node/layout-epoch repeats. +Four CommsRow instances each submitted12requests with layout epochs increasing +by2. Their original paint_thread_frame already calls update(Content,layout=False); +source declarations match native Static measurement/rendering and original box +hooks. The exact producer of those epoch changes still needs proof. Native owner +received actual source-bearing raw; requests are not being silently discarded. + +The original reviewed frontend publisher selected this runtime for new launches, +preserving backend defaults, active route, original native and running owners. +Receipt: `.artifacts/dm-owned-resources-delivery-20261008/live-publication.json`. +Source/build/installed/publication raw are retained in +`/home/ts/.cache/agent-scratch/dm-owned-resources-20261008/`. Existing user windows +keep imported modules. Goal remains open for frame pacing and full user workflows. + + +## Channel header has one presentation owner + +Source trace proves the paired channel-row layout epochs: SidebarProjection +first wrote pin/name without counts, then ChannelGroup.present wrote name/counts +without pin. Even identical final sources therefore changed the displayed text +twice. The second write also erased the visible pin marker. + +Deleted the first writer. Existing ChannelGroup.present now supplies pin/name/ +active/registered counts once under original member custody. Its row's original +Static content equality handles unchanged text. No new state/cache or suppressed +layout request. Actual source changes still use native update/layout. + +Before/after AST705 source/test modules parsed with zero omissions; all channel +header label publication now comes from ChannelGroup.present. Existing real +private-store/native-App activity-order control extended in place and passed: +pinned channel label/counts survive, rebuilding an unchanged snapshot leaves +the header layout epoch unchanged, changed activity still reorders members, +original widget identities/pins and unchanged prepared resource preserved. +Raw: `/home/ts/.cache/agent-scratch/channel-label-owner-20261008/source-app.log`. +Installed latency remains to be measured; no broad pacing pass claimed. diff --git a/src/toad/sidebar_projection.py b/src/toad/sidebar_projection.py index c6fe89990..e7d23e67f 100644 --- a/src/toad/sidebar_projection.py +++ b/src/toad/sidebar_projection.py @@ -177,7 +177,6 @@ def measure_width() -> int: for view in snapshot.wire.channels: channel_row = channels[view.channel.name] unread = snapshot.wire.channel_unread.get(view.channel.name, 0) - channel_row.set_label(f"{'* ' if view.channel.pinned else ''}{view.channel.name}") group = channel_row.query_ancestor(ChannelGroup) group.update_unread(unread) group.update_activity(view, row_inputs) diff --git a/src/toad/widgets/comms_sidebar.py b/src/toad/widgets/comms_sidebar.py index c86cfab33..ffb063e44 100644 --- a/src/toad/widgets/comms_sidebar.py +++ b/src/toad/widgets/comms_sidebar.py @@ -180,7 +180,8 @@ def present(self, view: ChannelView) -> None: row = self.row sidebar = self.query_ancestor(CommsSidebar) if row.is_attached: - row.set_label(f"{view.channel.name} {view.active_agents}/{view.registered_agents}") + row.set_label(f"{'* ' if view.channel.pinned else ''}{view.channel.name} " + f"{view.active_agents}/{view.registered_agents}") row.tooltip = (f"{view.active_agents} running or idle / {view.registered_agents} registered agents" f" ยท tags: {', '.join(sorted(view.channel.tags)) or 'all'}") self.expanded = sidebar.navigation.state.expanded.get( diff --git a/tests/sidebar_activity_order_pilot.py b/tests/sidebar_activity_order_pilot.py index 300e71b3e..4a4107c9a 100644 --- a/tests/sidebar_activity_order_pilot.py +++ b/tests/sidebar_activity_order_pilot.py @@ -26,6 +26,7 @@ async def main(): comms.registry.declare(Thread(name, frozenset({'team'}), str(root), process_identity=ProcessIdentity.capture(os.getpid()))) comms.channels.set_thread_pinned('#team', 'pinned', True) + comms.channels.set_channel_pinned('#team', True) comms.channels.set_channel_sort('#team', ThreadSort.LAST_ACTIVITY) comms.agents.set_activity('recent', ActivityState.IDLE) comms.agents.set_activity('older', ActivityState.IDLE) @@ -37,6 +38,15 @@ async def main(): if group.row.target_name == '#team') await group.reveal_members() await pilot.pause() + channel_view = next(view for view in sidebar.projection.snapshot.wire.channels + if view.channel.name == '#team') + expected_label = f"* #team {channel_view.active_agents}/{channel_view.registered_agents}" + assert str(group.row.content) == expected_label + epoch = group.row._layout_updates + await sidebar.projection.rebuild(sidebar.projection.snapshot) + await pilot.pause() + assert str(group.row.content) == expected_label + assert group.row._layout_updates == epoch, "Unchanged channel label requested layout" original = dict(group._members) unchanged = original['older']._thread_presentation assert tuple(row.target_name for row in group.member_container.children) == ( @@ -55,6 +65,9 @@ async def main(): assert group._members == original assert original['older']._thread_presentation is unchanged assert original['recent']._thread_presentation.source.busy + channel_view = next(view for view in sidebar.projection.snapshot.wire.channels + if view.channel.name == '#team') + assert str(group.row.content) == f"* #team {channel_view.active_agents}/{channel_view.registered_agents}" assert app._exception is None print('Actual activity moved the changed native row ahead of the retained row; ' 'pin, widget identity and unchanged paint resource preserved.', flush=True)