Skip to content

fix(mcp): prevent detached Windows venv workers from opening a console window - #2523

Open
zittenyetten wants to merge 2 commits into
Q00:mainfrom
zittenyetten:codex/windows-worker-no-console
Open

zittenyetten wants to merge 2 commits into
Q00:mainfrom
zittenyetten:codex/windows-worker-no-console

Conversation

@zittenyetten

@zittenyetten zittenyetten commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Background work launched through ooo run can open an empty Windows console when _spawn_worker() uses a CPython venv redirector. Replace DETACHED_PROCESS with CREATE_NO_WINDOW, retaining CREATE_NEW_PROCESS_GROUP and the configured venv interpreter.

The product change remains the same as the reviewed six-file patch. The seven-file submission adds calibrated console/visible-window checks and a targeted Windows CI step. The latest follow-up changes one test-local type annotation to resolve its expanded MyPy diagnostic; it makes no further product or CI change. This PR is ready for formal review, with the unresolved failures and approval decisions disclosed below; it is not a merge-ready or all-tests-passing claim. The earlier matched comparison remains original: 274 passed / 11 failed; modified: 276 passed / 9 failed.

Review boundary

  • User problem: an unintended empty console appears while accepting a durable background job through a Windows venv.
  • Conditions: the existing MCP _spawn_worker() path; locally verified on Windows build 26200 with CPython 3.12.12 venv, redirected streams and model-free durable probe jobs. Other runner/session/Python combinations require their own capability result.
  • Contract: suppress the worker console in the affected environment while preserving sys.executable, arguments, cwd/env, DEVNULL streams, process-group flag and reaper. Preserve actual worker startup, work after normal/forced accepting-parent exit, nested handoff, and cooperative cancellation followed by launcher/worker exit. Preserve the POSIX launch branch. Evidence and unverified portions are stated below.
  • Boundary and owner: existing MCP spawning, related test helpers and the existing Windows CI job. One production file, five test/helper files and one workflow. The PR author owns the proposed changes; review belongs to MCP/test-infrastructure maintainers. No new backend, persistence format, user setting or CI privilege.
  • Non-goals: lifecycle event-ordering repair, arbitrary descendant-tree cancellation, Codex/dashboard/TUI changes or unrelated refactoring. These exclusions do not waive the existing failing tests or repository contracts.
  • Evidence: prior single matched Windows A/B, version-qualified local Windows/Linux evidence and remote CI for the first submitted head, plus bounded before/after validation of the latest test annotation correction. Results are tied to their revisions below. Temporary network/model guards and raw diagnostics are outside the patch.

Cause and minimal change

The affected chain includes a Windows venv redirector and the native Python worker. Under the original flags, the real worker acquires a console despite stream redirection. The earlier comparison recorded nonzero versus zero GetConsoleWindow() handles while both workers completed the model-free job.

The current real-process positive control restores only the original creation flags inside the accepting test child; it still invokes the genuine worker entrypoint. It reproduced both console association and a visible, uniquely titled window. The proposed flags produced a completed venv worker with no console association and no matching visible window observed.

CREATE_NO_WINDOW is ignored when combined with DETACHED_PROCESS or CREATE_NEW_CONSOLE, so the flag is replaced, not combined. The POSIX product code is unchanged. Microsoft process-creation flags.

Changes

  • src/ouroboros/mcp/detached_jobs.py: existing one-flag fix and explanatory comment; no further product edits in this revision.
  • tests/unit/mcp/test_detached_jobs.py: preserve Windows/POSIX Popen contracts.
  • tests/integration/mcp/detached_probe_process.py: real accepting-parent handshake and identity/handle-based cleanup; add an opt-in legacy-flag positive control. The default candidate launch is unmodified by the control.
  • tests/integration/mcp/test_detached_probe_process.py: five helper safety/error-handling cases. Explicit creationflags preserves the existing default while resolving the helper's typing ambiguity.
  • tests/integration/mcp/test_detached_job_worker.py: normal/forced parent, nested handoff, cancellation and isolation improvements; the latest follow-up additionally narrows one test-local state annotation from dict[str, object] to dict[str, int | bool]. Operations, waiting conditions and assertions are unchanged.
  • tests/integration/mcp/test_detached_worker_window.py: separate console-association and visible-window tests, each requiring its own legacy positive control. Unique title/visible-window polling begins before launch and continues through exit. Evidence is saved to JSON and JUnit properties.
  • .github/workflows/test.yml: after the existing Windows checks, install the frozen dev/MCP test profile and run the same targeted 13 cases serially with isolated HOME/USERPROFILE/AppData/temp. Keep existing tests, permissions, runner and timeout. Save JUnit, scope summary and probe observations.

Reproduction and upstream status

During the earlier 2026-10-04 KST validation, main and latest release v0.55.4 both resolved to 5fc67bb2e3131cca56d8cdc9a1b7534252aa5301. At publication preflight, main had advanced one commit to dfc5307 through #2517; its twelve changed files do not overlap this seven-file patch. Latest release v0.55.4 still resolves to the validated baseline. The branch retains the validated base without rebase. The earlier local runs were on that base; subsequent CI for head 7937aaf used PR merge commit 63d4c4e, including main dfc5307, as detailed below. The latest-release reproduction requirement is supported by that matching revision. Relevant issue/PR searches and a refreshed open-PR check found no exact duplicate within the recorded scope.

With the supplied regression tests in an isolated Windows venv, after installing the dev/MCP test dependencies:

uv run --python 3.12 --no-sync pytest tests/integration/mcp/test_detached_worker_window.py -n 0 -q -rs

This reviewer command selects the two window tests included in the recorded 13-case run; it was not executed as an additional standalone run. They run a legacy-flag control followed by the candidate using actual workers and the built-in model-free probe. The older 285-case comparison used identical tests/diagnostics and ordered IDs with only the product flag difference; its results are below.

GetConsoleWindow() establishes console association, not desktop visibility. A pseudoconsole can have a non-displayed handle. Visibility uses EnumWindows, IsWindowVisible and a unique worker-set title, sampled every 50 ms. It does not prove the absence of shorter transients, unrelated windows or windows on inaccessible desktops. Microsoft GetConsoleWindow.

If a legacy control is not detected, the relevant test is UNSUPPORTED / NOT VERIFIED, not a zero-window pass. Missing observations/assertion failures fail the tests. CI reports console association and visibility separately; a generally green job with a visibility skip does not establish visibility coverage on that runner. A calibrated interactive Windows run remains the separate visibility evidence when hosted CI cannot observe it.

Latest follow-up: test-local MyPy correction

Current head: ddfc17c0905a522b1ef19adab8472232e4f22ec0. Compared with 7937aaf1062b1a91251ca8a0f61e3f382047d213, this follow-up changes one line in tests/integration/mcp/test_detached_job_worker.py: state: dict[str, object] becomes state: dict[str, int | bool]. The dictionary stores a runner-call count and Boolean state; object was too broad for the existing int(state["runner_calls"]) expression. No cast, ignore, assertion, wait condition, runtime operation, product file or workflow is changed in this follow-up.

Bounded local validation used CPython 3.12.12, MyPy 2.3.1 and the same dependency versions in isolated source/profile/cache copies:

  • Expanded MyPy, same six files before/after: head 7937aaf reproduced 1 call-overload error / 6 checked files at test_detached_job_worker.py:432 (exit 1, 13.48 s). The one-line candidate passed 6 checked files with no issues (exit 0, 12.32 s). This is an actual test-inclusive before/after result, separate from the earlier source-only CI gate.
  • Existing parameterized test: test_worker_preserves_live_job_after_postaccept_receipt_failure[exception-1] and [structured_error-0] both passed in the focused native-Windows diagnostic (pytest 9.1.1; 2 passed, 0 failed, 0 skipped, 4.53 s pytest time; natural process exit in 6.31 s).
  • Initial focused-test attempt: the sandboxed invocation collected those two cases but reached the diagnostic controller's 180-second timeout without a completed case or JUnit result. Its owned launcher was forcibly cleaned up; the later ownership check could not open the recorded guard process (Windows error 87), so no additional process was terminated. The timeout is retained as an unsuccessful attempt; its precise cause was not established. A single subsequent native-Windows invocation used the same two cases with verbose output and a 45-second faulthandler diagnostic; no assertion or wait condition was changed. This was a bounded diagnostic retry, not a rerun of the historical 285-case A/B.
  • Ruff: check and format check passed for the changed test file. Source-file manifests remained unchanged through validation. No whole-suite result or new Linux run is claimed for this annotation follow-up.

Before this correction, a separate 2026-10-04 isolated check reproduced the same int(object) diagnostic once on each of main dfc530775fa0c1a3cd560708ee5e0a0f9cb2f5ce and release v0.55.4 / original PR base 5fc67bb2e3131cca56d8cdc9a1b7534252aa5301: 1 error in 1 checked file at line 473, using Python 3.12.12 and MyPy 2.3.1 with --follow-imports=silent. Those runs establish a pre-patch reproduction under that toolchain, not a historical six-file baseline run. They reused the installed dependency set and one generated version-metadata file; source copies, profiles and caches were isolated, rather than claiming a wholly new dependency installation.

New-head remote CI snapshot (2026-10-03 22:33 UTC): 10 checks succeeded, 2 were in progress, 1 conditional check was skipped, all associated with ddfc17c0905a522b1ef19adab8472232e4f22ec0. The pending checks were Runtime sandbox (Windows) and Test Python 3.12. Source-only MyPy, Ruff and Bridge TypeScript had succeeded; Performance budget (advisory) was skipped. This is a time-bounded snapshot, not a claim that all current-head CI or Windows visibility checks passed; subsequent status is available in the PR Checks tab.

The broader Windows comparison was not rerun for this annotation-only change. Its nine candidate failures remain disclosed below; a successful bounded MyPy/test check or source-only CI does not resolve them. The earlier bot approval covered 7937aaf, not this new head, so updated review is requested.

Historical local verification: seven-file head 7937aaf

Base: 5fc67bb2e3131cca56d8cdc9a1b7534252aa5301. Earlier submitted head: 7937aaf1062b1a91251ca8a0f61e3f382047d213. These results predate the latest annotation correction. Patch SHA-256: 9c570a2ea94bfde9817278ee2edd0799b7ab02a985c5d23b9075d1a3662a88a4. The working copy and isolated test source were matched by all seven file hashes before/after verification.

  • Local Windows, 13 selected cases: 13 passed, 0 skipped, 161.43 seconds of pytest time. Selection: helper safety 5, platform options 2, real lifecycle 4, console association 1, visible window 1.
  • Console association: legacy handle nonzero; candidate handle zero. Both real workers completed and retained the venv interpreter/owner identity assertions.
  • Visible windows: legacy positive control detected 1 unique visible window over 267 samples; candidate detected 0 over 244 samples; no enumeration errors. Both ran the genuine worker and completed the model-free job.
  • Process cleanup: controller fallback terminations 0, retained owned processes remaining alive 0. One deliberate forced-parent case and one deliberate helper-cleanup termination in the database-failure safety test were recorded separately. Lifecycle/window passes were not manufactured by controller cleanup. This is not an all-descendants guarantee.
  • Local Linux supplemented revision: WSL2, CPython 3.12.12; the same selection finished 11 passed / 2 Windows-only skipped, 143.70 seconds. All seven source hashes matched before/after. The skips are not Windows detection evidence. A temporary guard produced one assertion-rewrite warning, without a product/test failure. An initial diagnostic-controller capability error stopped before any tests; it was corrected only in the temporary controller and its original logs were preserved. Retained owned processes exited with zero controller fallback; the immediate helper-owned sleep child is verified by its original Popen poll/wait rather than the controller ledger.
  • Ruff: check and format check passed for all six Python files in the patch.
  • Expanded targeted MyPy at 7937aaf: mypy --follow-imports=silent on those six Python files reported 1 error in test_detached_job_worker.py:432, int(state["runner_calls"]) (object argument). Two helper Popen typing ambiguities had already been corrected without changing behavior. A baseline run had not been performed at submission; later isolated main/release reproduction and the latest before/after correction are reported separately above. This historical six-file result is a failure, not the successful source-only CI gate.
  • Workflow locally checked: YAML parsed; PowerShell step parsed; Python reporting step compiled. Controlled missing-report/missing-window/failure inputs fail the reporter, while an unsupported visibility input is explicitly reported as unverified. Actual local JUnit was also reported correctly. These checks do not execute GitHub Actions or validate every hosted-runner behavior.
  • Isolation: fresh profiles/SQLite databases and real model-free probes; guarded diagnostic Python spawns and external network/model CLI blocking. Installed packages and live MCP services were not modified. Existing assertions and CI checks were retained.

Historical remote verification: head 7937aaf

Snapshot: 2026-10-04 03:27 KST. All seven workflow runs associated with 7937aaf1062b1a91251ca8a0f61e3f382047d213 succeeded on attempt 1; check runs were 12 success, 0 failure/pending, 2 skipped. The conditional skips were Performance budget (advisory) and Upload coverage. Actions checked out PR merge commit 63d4c4eb126ba9fcf6a5aacfa73edd49e356caad, combining that head with base dfc530775fa0c1a3cd560708ee5e0a0f9cb2f5ce. These are results for the earlier head, not proof of the latest head's CI or review status.

Windows job · uploaded JUnit and observations

Runner: Windows Server 2025 build 26100, windows-2025-vs2026 image, CPython 3.12.10 venv.

Evidence Observed result
Selected worker regressions 13 passed, 0 failed/error, 0 skipped, 83.35 seconds; logs, JUnit and uploaded summary agree
Selection Helper safety 5, launch options 2, real lifecycle 4, console association 1, visible window 1
Console association Legacy control handle 262510, candidate 0; genuine venv workers completed and identity assertions passed
Visible windows Legacy 1 uniquely titled visible window / 136 samples; candidate 0 / 135 samples; 50 ms interval, no enumeration errors
Capability Both positive controls observed; no unsupported/unverified result in these 13 cases on this execution

The lifecycle cases cover normal/forced accepting-parent exit, cancellation followed by worker/launcher exit, and nested handoff. Evidence is finite sampling on one runner session, not a guarantee for every desktop, sub-50-ms transient or arbitrary descendant. The same job separately recorded 65 plugin-hook passes and 67 sandbox passes / 19 sandbox skips; the latter skips are not skips in the selected worker cases.

Ubuntu Python 3.12 recorded 25,631 passed / 191 skipped / 1 xfailed, 8 warnings, with Python 3.12.14 and four workers on the non-performance tests/ selection. Source-only MyPy ran uv run mypy src/ouroboros and passed 686 source files; it did not cover the separate expanded test-file diagnostic. Ruff, Bridge TypeScript, Native TUI, MCP 1 SDK, issue-link and associated policy checks also succeeded for that earlier head.

None of the nine failing IDs from the historical Windows comparison is in this Windows 13-case selection. Neither this result nor Ubuntu's different platform/selection establishes that those failures were fixed, unrelated or unchanged in frequency.

Historical six-file evidence — not rerun for either later revision

Previous patch SHA-256: 09fe9ea372fc2064882c3006ac04d52e39319a10e4adbb9b260213171074c347.

Selection, one Windows execution per version Original Modified
Same ordered 285 IDs 274 passed, 11 failed 276 passed, 9 failed
Common 281 cases, excluding four new cases 272 passed, 9 failed 272 passed, 9 failed
New Windows flag and venv console regressions 2 intended failures 2 passed
New POSIX flag and forced-parent parameter 2 passed 2 passed

All nine modified-version failures below are existing tests. The two 9-failure totals differ in membership: in-flight-pause failed only in the candidate; transient-resume failed only in the original without an event snapshot. No frequency or no-regression conclusion follows from one pair. Clocks, UUIDs, scheduling and sequential cache effects were uncontrolled.

The frozen six-file selected Windows run was 12 passed. Its selected Linux run was 11 passed / 1 Windows-only skip, WSL2 Linux 6.6.87.2, glibc 2.35, CPython 3.12.12; all six file hashes match that revision. An earlier Linux broad run was 284 passed / 1 Windows-only skip on eight related modules, before the final helper review; it lacks a complete source fingerprint and is not verification of either latest revision. Its historical MyPy 686-file result is also not a current-head CI result.

Remaining modified-version failures from the earlier pair

All names below are existing tests. Repeated symptoms are not sufficient to establish repeated causes.

Test Original / modified Established evidence and uncertainty
test_cancel_job_preserves_signal_when_runner_starts_during_cancel fail / fail Cleanup unlink raises Windows sharing violation (WinError 32). Exact lock holder was not instrumented.
test_cancel_job_stops_task_when_linked_session_inspection_fails fail / fail Cancellation marker assertion sees False. The clearing/liveness branch responsible remains unconfirmed.
test_spawn_initializes_concrete_event_store_before_emitting fail / fail Pending-emit wait helper exhausts its checks. The cause of the incomplete emission was not captured in this pair.
test_replay_during_in_flight_pause_append_uses_last_durable_status pass / fail Modified failure is directly traced to tied timestamps and reversed ID ordering after append completed; pending=0, replay running/live paused.
test_replay_after_completed_returns_completed_snapshot fail / fail Pending-emit wait failure; direct delay/unfinished-emission cause unconfirmed in this pair.
test_replay_after_cancel_returns_cancelled_snapshot fail / fail Pending-emit wait failure; direct delay/unfinished-emission cause unconfirmed in this pair.
test_agent_process_snapshot_ignores_other_processes_and_malformed_rows fail / fail Expected completed, observed running. No event snapshot for this case, so a timestamp-tie cause is unconfirmed.
test_cancelled_durable_resume_preserves_pause_when_append_fails_pre_commit fail / fail Both failures directly show tied timestamps and reversed ID ordering; pending=0, replay running/live paused.
test_production_detached_evolve_rejects_malformed_seed_before_job_acceptance fail / fail Rejection validation reports an unexpected worker PID. This pair did not capture the compared PID values, so it does not independently confirm the detailed launcher/worker explanation.

The two directly observed ordering failures use identical agent_process.py and test code and do not call _spawn_worker(). They are proposed for a separate lifecycle-ordering issue. That does not classify every other failure as pre-existing or unrelated; the malformed-seed case traverses the actual changed launch path and remains a disclosed follow-up.

Review status and remaining decisions

The Windows workflow explicitly selects the new option, real-worker, console-association and visibility checks; existing Ubuntu and Windows checks remain. The results for the current head are reported in the latest-follow-up section. Earlier results above are historical evidence and do not become current-head results automatically.

The bot approval of 7937aaf found no demonstrated blocker within the declared review boundary and requested disposition of the nine failures before merge. It is not approval of the annotation follow-up. Its review environment lacked pytest; the executed Actions results are identified separately.

The existing protected-workflow approval request in #2522 remains outstanding. The issue's needs-approval status concerns the protected CI change; successful Actions runs and the previous bot's code-review approval do not independently resolve it. Formal review is requested without waiving that decision or the existing test contracts.

  • Latest-main/release reproduction and public duplicate checks recorded for the window issue and separate MyPy diagnostic.
  • Historical calibrated Windows 13-case and Linux 11-pass/2-skip evidence recorded, with exact revision scope.
  • Historical remote Windows association and visibility results reviewed; both positive controls were observed.
  • Existing nine failures, source-only versus expanded MyPy scopes, and historical revisions disclosed.
  • Maintainer disposition of the remaining Windows failures and explicit follow-up ownership where appropriate.
  • Explicit resolution of the protected CI-change approval request.
  • Review of the latest head and all applicable merge requirements. Current branch-protection requirements are not independently established by the historical checks.

Related issues

Refs #2522

The lifecycle event-ordering issue remains a separate follow-up draft and is not fixed or closed by this PR. It has not been published as part of this submission.

Replace DETACHED_PROCESS with CREATE_NO_WINDOW while retaining the
configured interpreter and process-group flag. Add calibrated real-worker
regressions and targeted Windows CI coverage.

Refs Q00#2522
ouroboros-agent[bot]
ouroboros-agent Bot previously approved these changes Oct 3, 2026

@ouroboros-agent ouroboros-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — ouroboros-agent[bot]

Verdict: APPROVE

Metadata

Field Value
PR #2523
HEAD checked 7937aaf1062b1a91251ca8a0f61e3f382047d213
Request ID req_1791050741_67
Review record b1e5af9c-9535-443e-b7b2-3b2d1bbe70d1

What Improved

  • Replaces DETACHED_PROCESS with CREATE_NO_WINDOW for Windows durable workers while retaining the venv interpreter, process-group flag, redirected streams, reaper, and POSIX branch. Adds real-worker Windows console and visibility checks with a legacy positive control.

Issue Requirements

Requirement Status
#2522: reproduce the original console and verify its absence on an affected Windows venv Covered by legacy-control and candidate tests; PR reports a passing local run
Preserve worker startup, accepting-parent exit survival, nested handoff, cancellation, and worker exit Covered by changed integration tests; PR reports a passing targeted run
Include Windows regressions in CI and distinguish unsupported visibility Implemented in the Windows workflow and reporter
Preserve the non-Windows launch branch and assess unresolved failures without claiming no regression POSIX branch is unchanged; failures and evidence limits are disclosed

Prior Findings Status

No prior ouroboros-agent review rounds or human review comments were supplied. No prior blocker required reconciliation.

Blockers

No in-scope blocking findings remained after policy filtering.

Follow-up Findings

# File:Line Priority Confidence Suggestion
1 PR body: Verification Medium High MCP and test-infrastructure maintainers should disposition the nine disclosed failures and review the required remote gates before merge. The single historical comparison does not establish whether every failure is unrelated to this change.

Non-blocking Suggestions

None.

Test Coverage Notes

  • Reviewed the changed unit, lifecycle, console, visibility, and Windows CI tests. The six changed Python files compiled successfully. Local pytest could not start because the snapshot environment lacks pytest. The PR reports 13 passing targeted Windows cases; remote CI and repository-wide gates remain unverified.

Design Notes

The change stays within the existing MCP spawn and test boundaries. No blocking root-cause class or new subsystem is established by current source.

Design / Roadmap Gate

The declared problem is an empty console during Windows CPython 3.12 venv background-job acceptance. The flag change targets that spawn path without changing persistence or the POSIX launch branch. Tests exercise genuine workers and separate console association from visible-window observation. The disclosed broad failures and pending remote gates limit merge readiness but do not establish a current, in-boundary contract violation.

Directional Notes

Maintainer-memory cues prompted inspection of process identity, cleanup, and incomplete preflight evidence. The verdict rests on the current source and declared #2522 contract, not those cues.

Convergence Gate

  • Decision: CONTINUE

  • Review round: 1

  • Subsystem budget: 4 — github/workflows, src/ouroboros/mcp, tests/integration/mcp, tests/unit/mcp

  • Blocking findings: 0 (0 repeated)

  • Root-cause hypothesis: No blocking root cause

  • Minimal reproduction: N/A

  • Subsystem budget: MCP detached spawning, MCP test infrastructure, Windows CI

  • Scope expansion: none

  • Blocker classification: none

  • Stagnation decision: CONTINUE

  • Reset success condition: N/A

  • Reset prohibition: N/A

  • Reset verification command: N/A

  • Effect owner: MCP detached spawning

Test Coverage

  • Reviewed the changed unit, lifecycle, console, visibility, and Windows CI tests. The six changed Python files compiled successfully. Local pytest could not start because the snapshot environment lacks pytest. The PR reports 13 passing targeted Windows cases; remote CI and repository-wide gates remain unverified.

Merge Recommendation

Approve this review: no in-boundary violation is proven from the current snapshot. Resolve the disclosed failures and required CI gates before merge.

Review-Metadata:
verdict: APPROVE
head_sha: 7937aaf
request_id: req_1791050741_67
review_profile: memory-aware-zero-trust-v2
advisory_memory_only: true


Reviewed by ouroboros-agent[bot] via Codex deep analysis

@zittenyetten
zittenyetten marked this pull request as ready for review October 3, 2026 22:35
@zittenyetten

Copy link
Copy Markdown
Contributor Author

Updated in ddfc17c0905a522b1ef19adab8472232e4f22ec0: one test-local annotation is now dict[str, int | bool] instead of dict[str, object], matching the values used by the existing int(state["runner_calls"]) expression. Runtime operations, assertions and waits are unchanged; there are no further product or workflow edits.

Bounded local verification: the same six-file expanded MyPy check changed from 1 reproduced error on 7937aaf to no issues in 6 files after the annotation correction. Both existing receipt-failure parameter cases passed in the focused native-Windows run (2 passed, 4.53 s), and the changed file's Ruff check/format check passed. An initial sandboxed attempt timed out after 180 seconds without completed case/JUnit results; that unsuccessful attempt is retained, with the precise cause unconfirmed. Only the same two cases were retried once; assertions and waits were unchanged.

For this new head, the 22:33 UTC CI snapshot shows 10 success, 2 in progress, 1 conditional skip. Windows and Python 3.12 tests were still running; the earlier head's green results are not substituted for them.

The body now separates this head's checks from 7937aaf's earlier Windows 13-pass calibrated run and the historical Windows comparison's nine unresolved candidate failures. The protected-CI approval request and nine-failure disposition request remain open; this update does not waive those decisions.

This PR is ready for formal review. Please re-review the latest head; the earlier approval covered 7937aaf.

@ouroboros-agent ouroboros-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — ouroboros-agent[bot]

Verdict: APPROVE

Metadata

Field Value
PR #2523
HEAD checked ddfc17c0905a522b1ef19adab8472232e4f22ec0
Request ID req_1791066925_69
Review record f59427ea-76fd-4d4c-bff5-b7f1d0ddd0d5

What Improved

  • Replaces the Windows detached-worker launch flag with CREATE_NO_WINDOW while retaining the configured venv interpreter, process-group flag, and existing launch arguments.
  • Adds real-worker checks for console association, visible windows, parent exit, cancellation, and nested handoff.

Issue Requirements

Requirement Status
Suppress the Windows CPython 3.12 venv worker console on the existing MCP spawn path Implemented; calibrated evidence is reported for the earlier head
Preserve interpreter, arguments, cwd/env, redirected streams, process group, reaper, and POSIX branch Preserved in the current source and covered by launch-contract tests
Preserve worker startup, parent-exit survival, nested handoff, and cooperative cancellation Covered by targeted real-worker tests; current-head Windows CI result was pending in the supplied body
Add targeted Windows CI observations for console association and visibility Implemented; visibility remains conditional on detecting its legacy positive control
Linked issue #2522 requirements beyond those stated in the PR body Not independently available in the supplied review inputs

Prior Findings Status

The prior approval’s classification is maintained. The current snapshot shows the same production flag change; the later annotation change alters no runtime operation or assertion. No previously discussed concern is independently proven as an in-boundary blocker at this head.

Blockers

No in-scope blocking findings remained after policy filtering.

Follow-up Findings

# File:Line Priority Confidence Suggestion
1 PR body:122 Medium High MCP and test-infrastructure maintainers should disposition the nine disclosed Windows comparison failures separately. The supplied evidence does not establish that this flag change caused or resolved them.

Non-blocking Suggestions

None.

Test Coverage Notes

  • Reviewed the selected test paths and Windows CI step. The PR body reports 13 passing targeted Windows cases on the earlier head and a passing expanded MyPy check plus two focused cases after the annotation change. Those historical results are not current-head CI results.
  • Local execution was unavailable: uv run --python 3.12 --no-sync pytest ... could not start because pytest is absent from this source snapshot’s environment.

Design Notes

The change stays within MCP worker spawning and its existing test and CI surfaces. No new subsystem or ownership boundary is needed.

Design / Roadmap Gate

The declared contract is limited to the Windows venv launch path under the stated conditions. Current source retains the POSIX branch and existing worker launch inputs. The new tests distinguish console association from desktop visibility and mark an undetected legacy control as unverified. Disclosed broader failures and pending merge gates require maintainer disposition, but do not demonstrate that this PR breaks its promised behavior.

Directional Notes

Prior review reasoning and maintainer memory guided inspection of process identity, cleanup, and verification scope. The verdict rests on the current source and diff. The PR body separately identifies a pending protected-workflow approval decision.

Convergence Gate

  • Decision: CONTINUE

  • Review round: 2

  • Subsystem budget: 4 — github/workflows, src/ouroboros/mcp, tests/integration/mcp, tests/unit/mcp

  • Blocking findings: 0 (0 repeated)

  • Root-cause hypothesis: No blocking root cause

  • Minimal reproduction: N/A

  • Subsystem budget: MCP worker spawning, MCP tests, Windows test workflow

  • Scope expansion: none

  • Blocker classification: none

  • Stagnation decision: CONTINUE

  • Reset success condition: N/A

  • Reset prohibition: N/A

  • Reset verification command: N/A

  • Effect owner: MCP worker spawning

Test Coverage

  • Reviewed the selected test paths and Windows CI step. The PR body reports 13 passing targeted Windows cases on the earlier head and a passing expanded MyPy check plus two focused cases after the annotation change. Those historical results are not current-head CI results.
  • Local execution was unavailable: uv run --python 3.12 --no-sync pytest ... could not start because pytest is absent from this source snapshot’s environment.

Merge Recommendation

Approve this code review: no current-head, in-boundary violation is proven. Maintainers still need to disposition the disclosed Windows failures, protected-workflow approval, and applicable current-head merge checks.

Review-Metadata:
verdict: APPROVE
head_sha: ddfc17c
request_id: req_1791066925_69
review_profile: memory-aware-zero-trust-v2
advisory_memory_only: true


Reviewed by ouroboros-agent[bot] via Codex deep analysis

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant