|
| 1 | +# FEATURE-ci-v3-runtime-green |
| 2 | + |
| 3 | +Status: Stages 1 and 3 implemented with focused proof; complete CI and remaining supported runtime repairs are pending. Groundwork validation is explicitly prohibited until FULL CI IS GREEN. |
| 4 | +Base: `v3` at `8f3083977f49706e66cefbb3ee8b6f6685469719`. |
| 5 | +Working branch: `task/FEATURE-ci-v3-runtime-green`. User requested integration into `v3` before full CI completion; retain incomplete verification explicitly. |
| 6 | +Plan: primary checkout `.groundwork-plans/FEATURE-ci-v3-runtime-green-plan.md`. |
| 7 | +Journal: primary checkout `.debug/v3-ci-green-VSvXxx/journal.md`. |
| 8 | +Stage evidence: `.debug/v3-ci-green-VSvXxx/runtime-green-stage1/`. |
| 9 | + |
| 10 | +## Stage 1: default Windows timer shutdown |
| 11 | + |
| 12 | +- [x] Compare cached shutdown detection with event substitution and unconditional singleton leakage. |
| 13 | +- [x] Preserve actual native62 RED and reliable LLDB unwind; do not relaunch original captured suites. |
| 14 | +- [x] Add and observe a failing bounded Windows DLL exit regression, with ordinary explicit timer retirement coverage. |
| 15 | +- [x] Cache the documented Windows shutdown query before constructing the default timer thread; abandon that service only during actual process termination. Preserve ordinary cleanup, POSIX behavior and public headers/API/ABI. |
| 16 | +- [x] Register `task_timer_shutdown` in Automake; verify DLL exit, explicit retirement, ordinary static-executable teardown, existing Linux resume/lifetime tests, changed-file lint and diff. |
| 17 | +- [ ] Full exact-source CI on the working branch, including actual MSYS2 package/archive lanes. |
| 18 | +- [ ] Groundwork validation, only after full CI is green; caller owns publication and eventual merge/cleanup. |
| 19 | + |
| 20 | +The actual original CI/local native62 program completes all 734 checks but hangs during DLL process detach. The accepted 24-frame LLDB unwind reaches `timer_queue` condition-variable destruction from `ExitProcess`/`LdrShutdownProcess`. Evidence is retained at `.debug/ci-windows-dump-entry-dbl8orzx/offline-analysis/mac-approved-result.json` and `mac-lldb-session.stdout.txt`; the earlier DbgHelp `.bss` chain is rejected. The original 180-second gate remains FAILED/NOT_RECHECKED. |
| 21 | + |
| 22 | +Microsoft documents that process exit kills the other threads before DLL detach, so even lock acquisition, joining and synchronization-object destruction can deadlock. The private Windows owner resolves `RtlDllShutdownInProgress` before creating its queue/thread, and releases its ownership only when that cached function reports process termination. There is no module lookup, allocation, locking, joining or synchronization destruction on that path. The operating system reclaims this single process-lifetime service. Ordinary destruction still deletes the queue; the POSIX factory is byte-identical. If the documented Windows 10+ query is unavailable, the ordinary cleanup fallback remains; legacy-platform shutdown is not claimed fixed. |
| 23 | + |
| 24 | +Requirements preserved: PRD-V3N-REQ-024/025 and architecture v3 section 3.1 (timeout/cancellation, exactly-once delivery and executor affinity). Public representation, scheduling, cancellation, deadlines, explicit timer ownership and callback delivery are unchanged. No forced application exit, DLL pinning or public shutdown interface is introduced. |
| 25 | + |
| 26 | +## Focused proof and context limits |
| 27 | + |
| 28 | +A C-only consumer of the retained actual CI DLL reaches its default timer factory and prints `DEFAULT_TIMER_READY`, then fails to exit within 9 seconds; its retained handle is retired, with total 9.449 seconds. No C++ standard-library object crosses that ABI boundary. This is a new minimal regression, not another original native62 launch. |
| 29 | + |
| 30 | +The new registered C++ regression runs a matching small three-owner DLL (`resume_signal.cpp`, `task.cpp`, `executor.cpp`) with explicit retirement and default-exit children. The final test against original timer source is RED: exit 1, child wait timeout 258 and destruction-during-shutdown marker, total 9.372 seconds. Against fixed source it is GREEN: exit 0, total 0.491 seconds, no shutdown destruction marker. Each child has a 9-second wait and at most 1 second for owned retirement. An inherited event observes pending-capture destruction during actual process termination, so the assertion also protects runtimes whose condition variable does not itself hang. Static-executable normal CRT destruction is permitted by this test and passes separately. Ordinary explicit retirement joins the worker and releases a capture with an hour-long pending deadline. |
| 31 | + |
| 32 | +Linux focused tests pass: `task_timer_shutdown`; `task_resume_signal` 11 tests/134 checks; `task_resume_signal_lifetime` 3 tests/1816 checks. These use current source compiled with GNU13/C++20/pthreads and only the three owning concurrency translation units. Changed-file cpplint and `git diff --check` pass. `autoreconf -fi` registers the new program and inherited library linkage; existing AC_OUTPUT and .PHONY warnings are recorded without unrelated repair. No full baseline or broad suite was run. |
| 33 | + |
| 34 | +Native Windows context is Windows 11 build26200, cross LLVM-MinGW23.1.4/MinGW15 with its UCRT startup/headers, MSYS2 GCC15.2 standard-library headers/import libraries in an owned cache, and the retained actual CI MSVCRT libstdc++/libgcc/winpthread DLLs. Actual CI uses Windows Server2022 and LLVM23.1.0 with MSYS2 mingw64 throughout. This focused mixed-CRT proof is qualified; it does not replace full actual CI. No provider, SDK or compiler was built or globally installed. A first downloaded UCRT GCC package was unused after original imports identified MSVCRT. |
| 35 | + |
| 36 | +Preserved setup failures: sandboxed WSL native launch was unavailable before normal escalation; initial future-based fixture had unresolved libstdc++ TLS symbols, then a corrected TLS build exposed missing runtime once-call exports (native entry-point status C0000139). That setup failure is not RED. Replacing only test readiness synchronization with an already-supported Win32 event corrected the fixture boundary; the corrected native failure above is the behavioral RED. No production workaround was based on the setup error. Raw commands, logs, receipts, hashes and bounded ownership cleanup are retained in stage evidence. |
| 37 | + |
| 38 | +Darwin PSK failures, Windows host WSAPoll consumer failure and incidental Linux/macOS/BSD assessments retain their previous UNKNOWN/closed-budget states. No unrelated source repair, original diagnostic retry, push, CI dispatch, review agent, Groundwork validation, merge or cleanup occurred in stage 1. |
| 39 | + |
| 40 | +## Related WSAPoll error visibility |
| 41 | + |
| 42 | +- [x] Immediately save `WSAGetLastError()` when the existing `WSAPoll` call fails and include its numeric value in the existing exception message. |
| 43 | +- [x] Preserve interrupted-poll handling and all polling, timing and shutdown semantics. |
| 44 | + |
| 45 | +This caller-authorized message change follows proven timer stage commit `70d0fba7`. It supplies useful error evidence in the next already-required CI run; it does not diagnose or repair the prior consumer exit 6, whose cause remains UNKNOWN and captures remain closed. There are no per-poll traces, socket queries, clocks, locks or error suppression changes. |
| 46 | + |
| 47 | +A bounded Windows test substitutes only the external WSAPoll boundary to return WSAEINVAL through the actual Winsock last-error API. Before the change it returns 2 because the exception omits numeric 10022 (0.310s); after it exits 0 (0.303s), also checking that WSAEINTR still produces no exception. This controlled message regression is not a reproduction of the original consumer failure. Actual Windows compilation, GNU syntax checking of `examples/external_event_loop.cpp`, changed-header cpplint and diff checks pass. Commands, sources and receipts are under stage evidence `host-poll-message/`. |
| 48 | + |
| 49 | +Additional ordinary cleanup proof: a static-linked Windows default service releases its pending callback during normal executable CRT teardown before a later registered atexit observer checks the capture; exit 0 in 0.391s (`ordinary-default-native-test.json`). The default service is therefore not unconditionally immortal. |
| 50 | + |
| 51 | +## Stage 3: FreeBSD evidence transport setup |
| 52 | + |
| 53 | +- [x] Preserve actual current8f native package PASS, redundant automatic-copyback FAIL, and explicit fresh SCP recovery/upload PASS as separate receipts. |
| 54 | +- [x] Set `copyback: 'false'` on the pinned FreeBSD VM action in package validation and release acceptance. |
| 55 | +- [x] Pass the existing 13 focused workflow tests, actionlint and exact source-preservation proof. |
| 56 | +- [ ] Full working-branch CI with the corrected VM setup (not dispatched here). |
| 57 | + |
| 58 | +Current8f package job `121358499066` passed installed native TLS=no at 03:49UTC, TLS=yes and identical installed headers at 04:03UTC. Its later automatic whole-workspace rsync copyback failed with protocol error 12 after receiving 4,049,536,821 bytes. Explicit fresh SCP recovery then succeeded and uploaded artifact `12626459963`, 776,035,888 bytes, producer-reported digest `597ded253263153a8ae4bb617df42defaaceb55c930978e013e4063253532894`. This is retained raw-log/metadata evidence; the artifact was not downloaded for stage3. It does not prove the separate cookie archive translation-unit gate, which remains pending. |
| 59 | + |
| 60 | +The exact pinned action implementation SHA256 is `7f9e5e36ceae15937ec0aabbf7e4ce4ab2855b36aa3dfa0ce8e79e7c0fb9569e`; its post-run step 7 runs only when the lowercased copyback input is not `'false'`. Initial synchronization and guest execution are distinct earlier operations. The input is declared in the [pinned action metadata](https://raw.githubusercontent.com/vmactions/freebsd-vm/c9f815bc7aa0d34c9fdd0619b034a32d6ca7b57e/action.yml). Disabling only this redundant post-run copyback leaves the explicit required SCP transport responsible for retrieving evidence. The underlying rsync connection-loss mechanism is not claimed diagnosed. |
| 61 | + |
| 62 | +Whole-file byte comparison proves that removing the single added scalar from each workflow restores the original file exactly. Guest prepare/run/trap/native commands, initial sync settings, pinned actions/toolchains, source checks, every gate, SCP error propagation, artifact paths and existing fallback handling are therefore unchanged. An existing fallback is preserved if present; automatic copyback is no longer a promised source for it. Failed SCP and missing evidence remain failures. |
| 63 | + |
| 64 | +Focused checks: `python3 scripts/test-v3-ci-workflows.py FreeBSDNodePrerequisites -v` (9 tests), `python3 scripts/test-v3-package-workflow.py -v` (4 tests), cached actionlint on both workflows, and `git diff --check` all pass. No new mirror test, VM, timeout increase, retry, transport framework, baseline suite, CI dispatch, push, merge or Groundwork validation was performed. Stage3 commands, outputs, source hashes and preservation proof are retained at `.debug/v3-ci-green-VSvXxx/runtime-green-stage3/` in the primary checkout. PSK source remains untouched while its fresh native authorization is pending. |
| 65 | + |
| 66 | +## User-directed integration before CI completion |
| 67 | + |
| 68 | +The user requested “merge back to v3, then keep fixing the remaining CI issues.” |
| 69 | +Integrate the focused repairs and ChangeLog update now. Full CI remains incomplete; |
| 70 | +Groundwork validation has not run and stays deferred until full CI is green. |
| 71 | +This integration does not mark the overall CI repair complete or reopen closed |
| 72 | +diagnostic batches. Draft PR #382 carries the original working-branch runs. |
0 commit comments