[BUG] Serial host fixture applies receive-poll timeout to output writes #41

Open
opened 2026-09-13 03:59:39 +02:00 by erikinkinen · 0 comments
Owner

Summary

A native-utility host fixture fails in Integration CI 1588, before the VM catalog starts. The serial success case reports EOF after its Python socket guest times out while writing output. The fixture uses the same socket's 50-millisecond receive-poll timeout for those writes. The actual reason that individual write did not complete inside that interval remains unknown.

Reproduction

This is one retained CI observation, not a new reproduction. At original Integration e67e4d3ad9596b435bdc44fd5ee716210cddb601, the host-check workflow runs:

python3 tests/native_utility_fixture_test.py

The failing case is UtilityFixtureTests.test_actual_serial_dispatch_complete_sequence_and_separate_consents. It invokes the real runner and native-utility observer against local COM1/QMP sockets supplied by a generated Python process. The disk and firmware files are explicitly nonbootable fixture bytes; this case does not execute a guest OS. Frequency and a deterministic minimal trigger for the observed timeout are not established. No unchanged retry of this original failure was performed. The later corrected-source validation is recorded below.

Expected and actual behavior

The valid serial fixture should complete its command sequence and separate consent exchanges, satisfy the existing literal event/status assertions, and retire its socket threads. Receive polling should remain distinct from the bounded allowance for writing fixture output; a real output failure must still fail the case.

Instead, the observer completed command 5 and reported command 6 injected at relative time 4.320718 seconds, then reported that the serial character device closed. The runner returned 1 where the valid case expected 0. The generated fixture process's traceback identifies TimeoutError in serial_connection.sendall(value), reached while echoing a non-newline input character. Its thread guard stores the error and signals stop; joining the fixture rethrows the retained error.

The accepted socket receives a timeout of 0.05 seconds for polling in the shared powerbox fixture. The inherited output publisher calls sendall on that same socket without a separate write contract. The source coupling and failing write are established; host scheduling, socket backpressure and a shared cause with any real-VM failure are not established.

Environment and identity

The exact source is e67e4d3ad9596b435bdc44fd5ee716210cddb601, pull-request run 1588/API9096, main job 19569, attempt 1. The utility fixture selects the serial native-utility route with 60-second hard, 15-second stall and 3-second command limits. Its outer subprocess has a 65-second timeout and its fake process uses the authored 60-second lifecycle wait. No deadline or assertion was changed during this investigation.

The workflow, runner, observer and inherited Python fixture sources are bound to ten original published Git blobs. This failure concerns host test transport ownership; it is not evidence of a kernel, filesystem, physical COM1 device or booted utility defect.

Evidence and prior checks

The five-case fixture file reports one failure after 36.101 seconds. The traceback and failing assertion appear at 01:40:02 UTC on 2026-09-13; the API records terminal failure at 01:40:07 UTC. The complete main log has 192,931 bytes and SHA-256 9062b815f6498714e5e14859b26f37dd508a4146ea7209749b8a3c8814ff2a08.

All three complete job logs are retained, totaling 297,622 bytes, with no observer warning candidates. The Rust and Markdown jobs pass. Earlier host groups, including the 21 console-progress cases, pass; no worker-scoped catalog scenario success is reached in this failed main job. Later real-VM checks are not reached. A separate push run remains independent evidence.

The signed correction is fe8c8103719af9c127dd769f4427d2a346e1ffd9. It separates nonblocking receive polling from a single absolute three-second write deadline, preserves partial-progress, stop, disconnect and timeout failures, and attempts all owned thread joins while retaining the original error. The powerbox and editor serial overrides follow the same contract. No production command, stall or VM threshold changes.

All 88 relevant host cases pass, including nine actual-socket and cleanup controls. The initial setup retained four readiness failures under an overlong temporary path; a shorter exclusive path allowed the remaining 79 cases to pass with unchanged source and reused prior positive controls. All 116 Markdown files and 71 workflow shell bodies pass. CI 1593 and CI 1594 remain queued. A separately reported startup ownership defect is tracked in #42.

Tracking

Keep this host fixture failure distinct from the real-VM serial-input observation #30, the release physical utility stall #38, and the console-progress host timing fixture #25. Similar error words do not establish a common cause. Coordination remains in Integration PR #12.

The signed correction and local controls establish independent receive polling, bounded write completion, stop handling and first-error preservation. Keep this issue open for the corrected checkpoint’s CI result. Preserve production observer deadlines, the literal command/consent oracle and existing negative cases; ignoring write failures or increasing production thresholds is not a correction.

## Summary A native-utility host fixture fails in [Integration CI 1588](https://git.erikinkinen.fi/erix/integration/actions/runs/1588), before the VM catalog starts. The serial success case reports EOF after its Python socket guest times out while writing output. The fixture uses the same socket's 50-millisecond receive-poll timeout for those writes. The actual reason that individual write did not complete inside that interval remains unknown. ## Reproduction This is one retained CI observation, not a new reproduction. At original Integration `e67e4d3ad9596b435bdc44fd5ee716210cddb601`, the [host-check workflow](https://git.erikinkinen.fi/erix/integration/src/commit/e67e4d3ad9596b435bdc44fd5ee716210cddb601/.github/workflows/ci.yml#L518) runs: ```sh python3 tests/native_utility_fixture_test.py ``` The failing case is `UtilityFixtureTests.test_actual_serial_dispatch_complete_sequence_and_separate_consents`. It invokes the real runner and native-utility observer against local COM1/QMP sockets supplied by a generated Python process. The disk and firmware files are explicitly nonbootable fixture bytes; this case does not execute a guest OS. Frequency and a deterministic minimal trigger for the observed timeout are not established. No unchanged retry of this original failure was performed. The later corrected-source validation is recorded below. ## Expected and actual behavior The valid serial fixture should complete its command sequence and separate consent exchanges, satisfy the existing literal event/status assertions, and retire its socket threads. Receive polling should remain distinct from the bounded allowance for writing fixture output; a real output failure must still fail the case. Instead, the observer completed command 5 and reported command 6 injected at relative time 4.320718 seconds, then reported that the serial character device closed. The runner returned 1 where the valid case expected 0. The generated fixture process's traceback identifies `TimeoutError` in `serial_connection.sendall(value)`, reached while echoing a non-newline input character. Its thread guard stores the error and signals stop; joining the fixture rethrows the retained error. The accepted socket receives a timeout of 0.05 seconds for polling in [the shared powerbox fixture](https://git.erikinkinen.fi/erix/integration/src/commit/e67e4d3ad9596b435bdc44fd5ee716210cddb601/tests/powerbox_prompt_fixture_test.py#L129). The inherited [output publisher](https://git.erikinkinen.fi/erix/integration/src/commit/e67e4d3ad9596b435bdc44fd5ee716210cddb601/tests/interactive_shell_transport_test.py#L46) calls `sendall` on that same socket without a separate write contract. The source coupling and failing write are established; host scheduling, socket backpressure and a shared cause with any real-VM failure are not established. ## Environment and identity The exact source is `e67e4d3ad9596b435bdc44fd5ee716210cddb601`, pull-request run 1588/API9096, main job 19569, attempt 1. The utility fixture selects the serial `native-utility` route with 60-second hard, 15-second stall and 3-second command limits. Its outer subprocess has a 65-second timeout and its fake process uses the authored 60-second lifecycle wait. No deadline or assertion was changed during this investigation. The workflow, runner, observer and inherited Python fixture sources are bound to ten original published Git blobs. This failure concerns host test transport ownership; it is not evidence of a kernel, filesystem, physical COM1 device or booted utility defect. ## Evidence and prior checks The five-case fixture file reports one failure after 36.101 seconds. The traceback and failing assertion appear at 01:40:02 UTC on 2026-09-13; the API records terminal failure at 01:40:07 UTC. The complete main log has 192,931 bytes and SHA-256 `9062b815f6498714e5e14859b26f37dd508a4146ea7209749b8a3c8814ff2a08`. All three complete job logs are retained, totaling 297,622 bytes, with no observer warning candidates. The Rust and Markdown jobs pass. Earlier host groups, including the 21 console-progress cases, pass; no worker-scoped catalog scenario success is reached in this failed main job. Later real-VM checks are not reached. A separate push run remains independent evidence. The signed correction is `fe8c8103719af9c127dd769f4427d2a346e1ffd9`. It separates nonblocking receive polling from a single absolute three-second write deadline, preserves partial-progress, stop, disconnect and timeout failures, and attempts all owned thread joins while retaining the original error. The powerbox and editor serial overrides follow the same contract. No production command, stall or VM threshold changes. All 88 relevant host cases pass, including nine actual-socket and cleanup controls. The initial setup retained four readiness failures under an overlong temporary path; a shorter exclusive path allowed the remaining 79 cases to pass with unchanged source and reused prior positive controls. All 116 Markdown files and 71 workflow shell bodies pass. [CI 1593](https://git.erikinkinen.fi/erix/integration/actions/runs/1593) and [CI 1594](https://git.erikinkinen.fi/erix/integration/actions/runs/1594) remain queued. A separately reported startup ownership defect is tracked in [#42](https://git.erikinkinen.fi/erix/integration/issues/42). ## Tracking Keep this host fixture failure distinct from [the real-VM serial-input observation #30](https://git.erikinkinen.fi/erix/integration/issues/30), [the release physical utility stall #38](https://git.erikinkinen.fi/erix/integration/issues/38), and [the console-progress host timing fixture #25](https://git.erikinkinen.fi/erix/integration/issues/25). Similar error words do not establish a common cause. Coordination remains in [Integration PR #12](https://git.erikinkinen.fi/erix/integration/pulls/12). The signed correction and local controls establish independent receive polling, bounded write completion, stop handling and first-error preservation. Keep this issue open for the corrected checkpoint’s CI result. Preserve production observer deadlines, the literal command/consent oracle and existing negative cases; ignoring write failures or increasing production thresholds is not a correction.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
erix/integration#41
No description provided.