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
40 changes: 40 additions & 0 deletions evidence/driver-write-completion-20261007/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Driver-owned write completion

Driver.call_after_flush schedules its synchronous callback on the original
Driver App loop after its output flush boundary. Synchronous drivers use their
actual flush; queued Linux and Windows writers use the original WriterThread
FIFO signal. The existing signal now carries and publishes onto that loop.
There is no Toad platform decision or ambient-loop wrapper in this capability.

Headless has no output to wait for. Inline flushes its buffered file. Web waits
for complete framed-packet acceptance at its existing OS write boundary; that
boundary now handles partial os.write results. Neither terminal pixels nor
browser paint are acknowledged. Flush/write failures cannot publish success.

Writer shutdown drains prior signals and clears the original driver's writer
custody; later queued-driver submission is refused outside application mode.
A retired App loop receives no completion. Callback exceptions execute under
the App loop's normal exception handling, not on the terminal writer thread.
WriterThread.call_after_flush now requires the original loop explicitly, and
all native consumers including its original control are migrated.

Qualified native source checks: four focused controls passed in 0.35 seconds,
covering FIFO flush, callback thread/loop, headless scheduling, buffered inline
file flush, closed-loop retirement and joined writer shutdown.

The original WebDriver accepted a 1,100,005-byte framed pipe packet across two
actual OS writes; exact bytes and owner-loop completion passed, and the reader
joined. This proves transport acceptance, not browser paint.

The actual Linux source App rendered through its original writer and delivered
completion on its App loop. Writer and input thread joined. PTY input was used;
output was captured to stderr, not inspected as terminal pixels. The first run
failed only its cleanup oracle: Linux retains the joined input Thread object.
That negative is retained. The corrected Linux-only check passed without
repeating the Web control. Captured stderr includes normal terminal output.

Windows console startup remains unexecuted on this Linux host. Its original
shared WriterThread path is source-reviewed and that writer is exercised above.
No latency improvement is claimed. Native verification used zero inputs and
providers; Parent separately verified and published the paired Linux saved-tab
App. Production remains byte-identical to the delivered 41e8a5319 checkpoint.
26 changes: 26 additions & 0 deletions evidence/driver-write-completion-20261007/app-first.stderr.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[?1049h=[?25l[?1004h[>25u[?2026$p[?2048$p[?2004h[?7l]22;defaultNative driver write completion 
 
 
 
 
 
 
 
 
 [?2004l[?7h>[<u[?1049l[?25h[?1004lTraceback (most recent call last):
File "/home/ts/wt/textual-frame-publication-20261006/tests/driver_write_completion_app.py", line 127, in <module>
asyncio.run(main(Path(sys.argv[1])))
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ts/.local/share/uv/python/cpython-3.14.2-linux-x86_64-gnu/lib/python3.14/asyncio/runners.py", line 204, in run
return runner.run(main)
~~~~~~~~~~^^^^^^
File "/home/ts/.local/share/uv/python/cpython-3.14.2-linux-x86_64-gnu/lib/python3.14/asyncio/runners.py", line 127, in run
return self._loop.run_until_complete(task)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "/home/ts/.local/share/uv/python/cpython-3.14.2-linux-x86_64-gnu/lib/python3.14/asyncio/base_events.py", line 719, in run_until_complete
return future.result()
~~~~~~~~~~~~~^^
File "/home/ts/wt/textual-frame-publication-20261006/tests/driver_write_completion_app.py", line 117, in main
assert app._driver._key_thread is None
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError
Empty file.
10 changes: 10 additions & 0 deletions evidence/driver-write-completion-20261007/app-linux02.stderr.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[?1049h=[?25l[?1004h[>25u[?2026$p[?2048$p[?2004h[?7l]22;defaultNative driver write completion 
 
 
 
 
 
 
 
 
 [?2004l[?7h>[<u[?1049l[?25h[?1004l
Empty file.
2 changes: 2 additions & 0 deletions evidence/driver-write-completion-20261007/controls.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.... [100%]
4 passed in 0.35s
9 changes: 9 additions & 0 deletions evidence/driver-write-completion-20261007/linux-app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"scope": "real source Linux App/PTY writer completion, not pixel presentation",
"driver": "LinuxDriver",
"callback_on_owner_loop": true,
"writer_joined": true,
"input_thread_joined": true,
"inputs": 0,
"providers": 0
}
296 changes: 296 additions & 0 deletions evidence/driver-write-completion-20261007/source-after.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,296 @@
{
"source_head": "55bd8ee71ded2208446f10f1a38458f4a697eefb",
"modules": 723,
"omissions": [],
"sites": [
[
"src/textual/driver.py",
146,
"declaration",
"call_after_flush"
],
[
"src/textual/driver.py",
213,
"declaration",
"close"
],
[
"src/textual/driver.py",
41,
"Store",
"self._loop"
],
[
"src/textual/driver.py",
76,
"Load",
"self._loop"
],
[
"src/textual/driver.py",
156,
"Load",
"self._loop"
],
[
"src/textual/drivers/_input_reader_linux.py",
23,
"declaration",
"close"
],
[
"src/textual/drivers/_input_reader_windows.py",
20,
"declaration",
"close"
],
[
"src/textual/drivers/_writer_thread.py",
19,
"declaration",
"deliver"
],
[
"src/textual/drivers/_writer_thread.py",
44,
"declaration",
"call_after_flush"
],
[
"src/textual/drivers/linux_driver.py",
196,
"declaration",
"call_after_flush"
],
[
"src/textual/drivers/linux_driver.py",
405,
"declaration",
"close"
],
[
"src/textual/drivers/linux_driver.py",
64,
"Store",
"self._writer_thread"
],
[
"src/textual/drivers/linux_driver.py",
248,
"Store",
"self._writer_thread"
],
[
"src/textual/drivers/linux_driver.py",
193,
"Load",
"self._writer_thread"
],
[
"src/textual/drivers/linux_driver.py",
198,
"Load",
"self._writer_thread"
],
[
"src/textual/drivers/linux_driver.py",
199,
"Load",
"self._writer_thread.call_after_flush"
],
[
"src/textual/drivers/linux_driver.py",
199,
"Load",
"self._loop"
],
[
"src/textual/drivers/linux_driver.py",
407,
"Load",
"self._writer_thread"
],
[
"src/textual/drivers/linux_driver.py",
409,
"Store",
"self._writer_thread"
],
[
"src/textual/drivers/linux_driver.py",
194,
"Load",
"self._writer_thread"
],
[
"src/textual/drivers/linux_driver.py",
199,
"Load",
"self._writer_thread"
],
[
"src/textual/drivers/linux_driver.py",
249,
"Load",
"self._writer_thread"
],
[
"src/textual/drivers/linux_driver.py",
408,
"Load",
"self._writer_thread"
],
[
"src/textual/drivers/web_driver.py",
76,
"declaration",
"_write"
],
[
"src/textual/drivers/windows_driver.py",
56,
"declaration",
"call_after_flush"
],
[
"src/textual/drivers/windows_driver.py",
141,
"declaration",
"close"
],
[
"src/textual/drivers/windows_driver.py",
40,
"Store",
"self._writer_thread"
],
[
"src/textual/drivers/windows_driver.py",
97,
"Store",
"self._writer_thread"
],
[
"src/textual/drivers/windows_driver.py",
53,
"Load",
"self._writer_thread"
],
[
"src/textual/drivers/windows_driver.py",
58,
"Load",
"self._writer_thread"
],
[
"src/textual/drivers/windows_driver.py",
59,
"Load",
"self._writer_thread.call_after_flush"
],
[
"src/textual/drivers/windows_driver.py",
59,
"Load",
"self._loop"
],
[
"src/textual/drivers/windows_driver.py",
143,
"Load",
"self._writer_thread"
],
[
"src/textual/drivers/windows_driver.py",
145,
"Store",
"self._writer_thread"
],
[
"src/textual/drivers/windows_driver.py",
54,
"Load",
"self._writer_thread"
],
[
"src/textual/drivers/windows_driver.py",
59,
"Load",
"self._writer_thread"
],
[
"src/textual/drivers/windows_driver.py",
98,
"Load",
"self._writer_thread"
],
[
"src/textual/drivers/windows_driver.py",
144,
"Load",
"self._writer_thread"
],
[
"tests/driver_write_completion_app.py",
116,
"Load",
"app._driver._writer_thread"
],
[
"tests/driver_write_completion_app.py",
35,
"Load",
"self._driver._writer_thread"
],
[
"tests/driver_write_completion_app.py",
40,
"Load",
"self._driver._loop"
],
[
"tests/driver_write_completion_app.py",
84,
"Load",
"driver.call_after_flush"
],
[
"tests/driver_write_completion_app.py",
36,
"Load",
"self._driver.call_after_flush"
],
[
"tests/test_driver_write_completion.py",
23,
"Load",
"app._driver.call_after_flush"
],
[
"tests/test_driver_write_completion.py",
42,
"Load",
"driver.call_after_flush"
],
[
"tests/test_driver_write_completion.py",
60,
"Load",
"writer.call_after_flush"
],
[
"tests/test_driver_write_completion.py",
62,
"Load",
"writer.call_after_flush"
],
[
"tests/test_writer_thread.py",
40,
"Load",
"writer.call_after_flush"
]
],
"dynamic_contract": "Queued external Driver subclasses must override call_after_flush; no arbitrary subclass certification. Windows console startup unexecuted."
}
Loading
Loading