Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
28 changes: 28 additions & 0 deletions evidence/dm-initial-publication-20261008/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -907,3 +907,31 @@ This removes48 widget lifetimes, not a broad performance pass. Raw checks and
negatives: /home/ts/.cache/agent-scratch/dm-native-caption-20261008/.
New-launch delivery uses the original reviewed frontend owner; existing user
windows are not restarted.

## Remaining layout cost and completed paint traversal

Native124,6e625590a, removes traversal below foreground widgets after all
requested damage cuts have been painted, using original pending-row bookkeeping.
Reviewed exact decrement/None ownership and affected native paint/held damage
control; actual installed driver workload completes and publishes for new
launches with unchanged Toad21f87a/Core09a. This is not a frame-time pass.

Direct UI-thread CPU spans identify the remaining cost: original full reflow
31calls/479ms total/worst33.7ms and visible reflow71/208ms/worst16.3ms.
Toad prepared-line draw75calls/2.16ms total/worst0.12ms; viewport preparation
326calls/41ms total/worst0.29ms. New native workload has frame p95~103ms,
paint worst5.02ms and full reflow worst38.7ms; single-run variance prevents a
causal latency claim. Raw owner-cpu-complete and native-cuts-wheel are alongside
earlier scratch results. Next work concerns layout admission and invalidation.

Even ordinary Python3.14 cProfile produced impossible own/cumulative timings
and worker-thread calls under UI runcall. Reject timer-attribution pstats;
direct gated thread_time spans above remain distinct valid observations.
The first expanded span recorder touched an absent startup screen; original
failure is retained, the recorder now requires an actual screen stack.

Four unused runtimes were removed after fresh privileged279-process census
without gaps/references and checking default executable symlinks:282680401bytes.
Current, immediate rollback and backend runtimes remain; source, wheels, proof,
publication and raw results are retained. Cleanup original evidence:
disk-cleanup-owner-20261002/Parent-caption-superseded-runtimes-retired-20261008.json.
8 changes: 6 additions & 2 deletions src/toad/widgets/message_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ def show_result(self, notifications: tuple[MessageNotification, ...]) -> None:
summary = " · ".join(f"{state} ({counts[state]})" for state in states[:3])
if len(states) > 3:
summary += f" · {sum(counts[state] for state in states[3:])} others"
self.title = Content(summary or "No recorded notification result")
title = Content(summary or "No recorded notification result")
if not title.is_same(Content.from_text(self.title)):
self.title = title
if not self.collapsed:
_ = self.details
self.set_class(any(item.busy for item in notifications), "-working")
Expand All @@ -78,7 +80,9 @@ def show_error(self, error: Exception) -> None:
if self._error == detail:
return
self._notifications, self._error = None, detail
self.title = Content("Notification status unavailable")
title = Content("Notification status unavailable")
if not title.is_same(Content.from_text(self.title)):
self.title = title
if not self.collapsed:
_ = self.details
self.remove_class("-working")
Expand Down
45 changes: 44 additions & 1 deletion tests/message_notifications_pilot.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,5 +141,48 @@ async def observe():
print("PASS: mounted IRC/Markdown, expanded details, live states without new messages, priority, batch/off-thread/visible bounds, errors/recovery, hidden/inflight guards, native Ready override, no fabricated ACP turn")


async def title_publication():
"""Detail changes retain the original title's native layout admission."""
from dataclasses import replace
from agent_comms.audience_manifest import FrozenRecipient
from textual.app import App

class NotificationApp(App):
def compose(self):
yield MessageNotifications()

app = NotificationApp()
async with app.run_test(size=(90, 20)) as pilot:
feedback = app.query_one(MessageNotifications)
original = MessageNotification(FrozenRecipient("peer", "peer"),
"Responding", "Original outcome", 1, True)
feedback.show_result((original,))
await pilot.pause()
title = feedback.query_one("CollapsibleTitle")
await pilot.click(title)
await pilot.pause()
assert not feedback.collapsed
before = title._layout_updates
feedback.show_result((replace(original, detail="Updated outcome"),))
await pilot.pause()
assert title._layout_updates == before
assert "Updated outcome" in str(feedback.details.render())
assert "Responding (1)" in str(feedback.title) and feedback.has_class("-working")
feedback.show_result((replace(original, state="Responded", busy=False),))
await pilot.pause()
assert "Responded (1)" in str(feedback.title) and not feedback.has_class("-working")
feedback.show_error(OSError("Original read error"))
await pilot.pause()
before = title._layout_updates
feedback.show_error(OSError("Changed read error"))
await pilot.pause()
assert title._layout_updates == before
assert "Changed read error" in str(feedback.details.render())
assert feedback.has_class("-unavailable")
assert app._exception is None
print("PASS: changed details/errors retain title layout; changed summary/activity still publish")


if __name__ == "__main__":
asyncio.run(main())
import sys
asyncio.run(title_publication() if "--title-publication" in sys.argv else main())
Loading