Repository navigation
Keep slow daemon negotiation on v2 and expose legacy fallback - #870
Merged
Merged
Conversation
coneilen
marked this pull request as ready for review
October 18, 2026 19:39
coneilen
force-pushed
the
coneilen-daemon-negotiation-fallback
branch
from
October 18, 2026 19:40
aae472e to
500b405
Compare
coneilen
force-pushed
the
coneilen-daemon-negotiation-fallback
branch
3 times, most recently
from
October 18, 2026 23:38
0f4cd5d to
e157b4c
Compare
Refs #867. Wait five seconds for hello and retry v2 on timeout; require explicit legacy replies and retain reason/elapsed diagnostics. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: fe0ab659-3c78-4c04-b486-d7e632260386 Signed-off-by: Colin Neilens <coneilen@microsoft.com>
Refs #867. Correct the separate pre-existing overlapped-read byte loss with deterministic real-pipe boundary coverage. Keep production negotiation at five seconds and retain slow-v2, correlation, and genuine-v1 assertions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: fe0ab659-3c78-4c04-b486-d7e632260386 Signed-off-by: Colin Neilens <coneilen@microsoft.com>
Refs #867. Preserve the two-second receipt reader and all validation while recording observed read attempts, held child status, joined teardown, bounded captured streams, and actual peer file state on failure only. Original CI receipt absence remains causally unproven. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: fe0ab659-3c78-4c04-b486-d7e632260386 Signed-off-by: Colin Neilens <coneilen@microsoft.com>
coneilen
force-pushed
the
coneilen-daemon-negotiation-fallback
branch
from
October 19, 2026 01:46
e5a0bc0 to
673343b
Compare
This was referenced Oct 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Keep a slow Windows daemon hello on protocol v2 instead of silently downgrading after 1.5 seconds. Implement the repository-owner decision on #867: allow about 5 seconds, require an explicit legacy/refused reply for fallback, and expose the fallback reason and elapsed time.
Refs #867.
Changes
unsupportedVersionrefusal retain legacy compatibility. Invalid, unrelated, nested, or unsupported selections become visible protocol errors rather than a downgrade.v2 -> v1decision, its specific reason, and measured elapsed milliseconds ingraphcode-windows.logthrough the existing diagnostics writer. Keep the same notice on the existing connection status surface after v1 connects; a later successful v2 hello clears it.DaemonClient.zigtest root, including bounded real named-pipe slow-v2, legacy-command, no-reply, and log checks. Keep the subscription drain's original 1.5-second budget, framing limits, request correlation, and connection-generation behavior.graphcode-windows/src/DaemonClient.zigchanges. No daemon changes, late-reply draining, v1 removal, shared schema changes, desktop tests, or parity-ledger promotion.Test plan
The commands below ran from
graphcode-windowswith bootstrap's pinned Zig 0.15.2 and owned provider checkout. TEMP/TMP, support state, and caches were isolated to this lane. Raw logs remain preserved separately asred-initial.log,green-initial.log,green-final.log, and the regression/build logs in the session artifacts.RED: & $env:GRAPHCODE_ZIG0152 test src\DaemonClient.zig -target x86_64-windows-msvc -lc -ladvapi32 "-I$env:GRAPHCODE_WINGHOSTTY_ROOT\include" --cache-dir D:\depot\copilot-worktrees\GraphCode\coneilen-congenial-goggles.build\lane5\zig-local --global-cache-dir D:\depot\copilot-worktrees\GraphCode\coneilen-congenial-goggles.build\lane5\zig-global --test-filter negotiation -> 7 executed: 1 passed, 6 behavioral failures in 14.800 s; slow v2 expected .negotiating, found .unavailable; no reply expected .v2, found .v1; fallback decision/reason diagnostics absent.
GREEN: & $env:GRAPHCODE_ZIG0152 test src\DaemonClient.zig -target x86_64-windows-msvc -lc -ladvapi32 "-I$env:GRAPHCODE_WINGHOSTTY_ROOT\include" --cache-dir D:\depot\copilot-worktrees\GraphCode\coneilen-congenial-goggles.build\lane5\zig-local --global-cache-dir D:\depot\copilot-worktrees\GraphCode\coneilen-congenial-goggles.build\lane5\zig-global --test-filter negotiation -> 8/8 passed, 0 skipped, 13.785 s; real 2500 ms v2 hello served a correlated request; genuine v1 command round trip and persistent reason/elapsed diagnostic/log passed; bounded no-reply remained v2.
REGRESSION: & $env:GRAPHCODE_ZIG0152 test src\DaemonClient.zig -target x86_64-windows-msvc -lc -ladvapi32 "-I$env:GRAPHCODE_WINGHOSTTY_ROOT\include" --cache-dir D:\depot\copilot-worktrees\GraphCode\coneilen-congenial-goggles.build\lane5\zig-local --global-cache-dir D:\depot\copilot-worktrees\GraphCode\coneilen-congenial-goggles.build\lane5\zig-global -> 215/215 passed, 0 skipped, 149.226 s, including connection generations, coalesced frames, request IDs/correlation, outbound accounting, subscription drain, and imported adjacent contracts.
Additional executed commands, using the same target/link/include/cache arguments as above:
zig test src\FrameBuffer.zigzig test src\DaemonRoundTripTests.zig --test-filter "daemon round-trip support helper"zig build -Demit-win32-host=truein the owned pinned Winghostty checkoutzig build -j1 -Doptimize=ReleaseSafe "-Dwinghostty-dir=$env:GRAPHCODE_WINGHOSTTY_ROOT" --cache-dir D:\depot\copilot-worktrees\GraphCode\coneilen-congenial-goggles\.build\lane5\zig-build-local --global-cache-dir D:\depot\copilot-worktrees\GraphCode\coneilen-congenial-goggles\.build\lane5\zig-build-globalzig-out\bin\graphcode-windows.exe.task/code-review, default model/reasoning/context settingsgit diff --checkPreserved intermediate failures: the first GREEN attempt ran 8 cases, with 7 passing and an owned test-fixture
TestPipeAcceptTimedOuton reconnect (16.667 s). Recreating the owned pipe server before redial corrected the fixture's listen ordering; no assertions were removed or weakened. The initial concurrent ReleaseSafe build failed with LLVM out-of-memory after 350.272 s; the serial-j1retry above passed. The first validation prerequisite check reported the pinned tool environment absent; repository bootstrap then installed the exact pins into this worktree.The tests establish actual named-pipe/component negotiation, legacy command framing, timeout behavior, and the diagnostics file/status text. They do not establish native GUI presentation, desktop/keyboard/UIA behavior, production-daemon persistence, or macOS parity.
make testandmake checkare macOS/Xcode commands and were not run on this Windows host; the full Windows shell/live gate was not run locally. Hosted PR checks are reported separately against the published head, not substituted with a manually dispatched run.Checklist
git commit -s) per the DCOmake test)make check)CI follow-up: separate pre-existing completed-read cancellation defect
Refs #867. This follow-up is on operator-rebased parent
3b4effb62e700cf7978740532ef09372b2e21596, not the original local head. The original implementation evidence and original fresh-eyes review above are historical evidence foraae472e3148fde73a8c3732dc1a5dfd43ab9927b; neither that review nor its 21-success/4-skipped hosted check snapshot is claimed for this repair or a later head.The slow-v2 test failed on the actual rebased PR head in run 39170170880, Windows shell shard 1:
15/215 DaemonClient.test.negotiation slow v2 hello after 2500 ms stays v2 and serves a correlated request...FAIL (TestNegotiationStateTimedOut). The full raw failing job is retained asci-testfix-red-shard1.log.This exposed a separate pre-existing production transport bug, not simply an insufficient test budget. The pending-read timeout path called
CancelIoEx, joinedGetOverlappedResult, then unconditionally discarded any bytes. A read that completed just before cancellation could therefore lose its frame header. A budget-only attempt passed 8/8 focused cases (13.943 s), but failed the full root at 214/215 (73.551 s). A subsequent classified failure showed a reply at 2505 ms inside a 10000 ms test budget, followed byPayloadTooLargeand a reconnect. Those failures and temporary diagnostic runs are preserved separately, not replaced by the passing logs.The operator explicitly approved the transport scope extension within
DaemonClient.zig. The correction cancels and joins non-signaled pending reads before releasing their event, OVERLAPPED, or destination buffer. Successful bytes and aborted completions with bytes reach the existing append path exactly once. Only an aborted completion with zero bytes is no data; terminal read failures and wait failures remain visible. A successful zero-byte read still follows the existing EOF path. No framing limit, fallback policy, correlation check, daemon code, or production timeout changes.The new deterministic real-pipe regression starts a header-only writer only after the client's read is pending. Its injected wait waits for the actual read-completion event, then reports a timeout once, forcing the exact completion-before-cancel boundary through the production read routine. Before the fix, the retained-length assertion failed (
expected 97, found null). After the fix, the header remains pending until its JSON body arrives; the exact 97-byte response is delivered once and completes exactly one correlated request. Separate controls cover aborted zero-byte reads followed by a valid hello, terminal read errors, and cancellation/join before surfacing a wait failure.The original real 2500 ms slow-v2 worker round trip, request-ID matching, final v2/generation assertions, genuine-v1 round trip, and fallback diagnostics assertions remain. Only the slow test receives a 10000 ms deadline and 5000 ms completion/I/O margins; it first asserts that production assigned exactly 5000 ms. That test-only margin is not the root-cause fix and is not a claim of production timeout equivalence. The existing no-reply test still exercises the real default five-second budget.
Commands below use the same pinned target/link/include/cache arguments as the original test commands above, in this owned worktree:
RED: & $env:GRAPHCODE_ZIG0152 test src\DaemonClient.zig -target x86_64-windows-msvc -lc -ladvapi32 "-I$env:GRAPHCODE_WINGHOSTTY_ROOT\include" --cache-dir D:\depot\copilot-worktrees\GraphCode\coneilen-congenial-goggles.build\lane5\zig-local --global-cache-dir D:\depot\copilot-worktrees\GraphCode\coneilen-congenial-goggles.build\lane5\zig-global --test-filter "negotiation cancel boundary" -> 3 executed before the transport correction: 1 passed / 2 behavioral failures, 3.378 s; completed header expected retained length 97, found null; terminal read error silently treated as no data; aborted-zero control passed.
GREEN: & $env:GRAPHCODE_ZIG0152 test src\DaemonClient.zig -target x86_64-windows-msvc -lc -ladvapi32 "-I$env:GRAPHCODE_WINGHOSTTY_ROOT\include" --cache-dir D:\depot\copilot-worktrees\GraphCode\coneilen-congenial-goggles.build\lane5\zig-local --global-cache-dir D:\depot\copilot-worktrees\GraphCode\coneilen-congenial-goggles.build\lane5\zig-global --test-filter negotiation -> final source 12/12 passed, zero skipped, 11.502 s, including four cancellation-boundary cases, slow v2 with correlated request, genuine v1 fallback, diagnostic logging, and bounded no reply.
REGRESSION: & $env:GRAPHCODE_ZIG0152 test src\DaemonClient.zig -target x86_64-windows-msvc -lc -ladvapi32 "-I$env:GRAPHCODE_WINGHOSTTY_ROOT\include" --cache-dir D:\depot\copilot-worktrees\GraphCode\coneilen-congenial-goggles.build\lane5\zig-local --global-cache-dir D:\depot\copilot-worktrees\GraphCode\coneilen-congenial-goggles.build\lane5\zig-global -> final FULL registered root 219/219 passed, zero skipped, 73.440 s.
Final raw evidence:
ci-transport-red.log,ci-transport-final-green.log, andci-transport-final-regression.log. No original assertions or test cases were removed. Production five-second negotiation behavior and explicit-only fallback remain unchanged. This is pipe/component evidence, not native GUI/desktop, production-daemon persistence, or macOS parity. The operator owns readiness, new-head hosted CI, and merge; this repair does not claim any new hosted check result.Repair commit:
c15118c2669c0396f82b0627012d7878b039389a, parent3b4effb62e700cf7978740532ef09372b2e21596. Onlygraphcode-windows/src/DaemonClient.zigchanged in the repair; normal push only, with DCO sign-off and the required App coauthor/session trailers. The earlier local reviewed head is preserved atrefs/lane5-preserved/original-reviewed-head.One fresh-eyes focused
task/code-reviewused default model/reasoning/context settings and covered only this transport correction, seam, regressions, and test timing delta against3b4effb62e700cf7978740532ef09372b2e21596, not the entire original feature. Reviewer agent:bcfcbbf6-569f-4201-9c3e-b59b0cceb168. Final reviewed source blob:08f279bf5ecbec4e82c253c46ae6638d5de44362; no source changes occurred after review launch, and the committed file has that exact blob. Thus the reviewed repair range is3b4effb62e700cf7978740532ef09372b2e21596..c15118c2669c0396f82b0627012d7878b039389a.Full unmodified focused-review verdict:
Integration follow-up: failure-only multiproject classification evidence
Refs #867. Instrumentation commit
e5a0bc0dd47e6db4396e8ab010218e074917a20bis a normal signed commit above the exact operator-held parente157b4c48230522a4e6994e431d5a580706dda93. OnlyTools/windows/uia-live-gate.ps1changes: the receipt reader's observational clocks/counters, a failure-only JSON writer, and the multiproject phase's failure/finally recording. Geometry/Open consumers, outgoing-hover literals, workflow upload rules, typed receipt validation, and the client are untouched. The original review/runtime evidence above remains bound to its named original heads; it is not new-head evidence.CI RED: run 39177391071, original integration job 117822919322 on exact
e157b4c48230522a4e6994e431d5a580706dda93failed atRead-MultiProjectPeer:MULTIPROJECT_PEER: no readable owner/receipt snapshot. No JSON read-retry was logged. Both owned child jobs then exited, became empty, and drained their redirected streams.Read-only classification:
Stub-Daemon.ps1is a v2 peer that immediately sends a flushedselectedVersion:2hello, not a v1-only fixture. The five-second client limit is a maximum, not a mandatory latency. The peer file is written only after the first correlated request response and initial owner publications, not at process launch/hello. The downloaded actualuia-live-gate-diagnosticsartifact contained four JSON files, but no multiproject peer file or child stream logs. That artifact absence does not prove the file was never written or written late. The original stalled stage and original CI cause remain unproven. The operator's successful rerun is a signal, not causal clearance.On a failure only, after the existing owned teardown and joined stream readers, the gate now writes
logs/multiproject-failure.json, which the existinglogs/*.jsonupload already includes. It records the original exception type/message/ID; actual phase/read UTC and elapsed times; calls, attempts, missing-file and parse-failure counts; only actually observed peer counters (otherwise null); actual file existence/length/last-write time; held child identity and pre-teardown exit/status observations; the existing post-teardown proof; and at most 8192 characters of each existing captured stream. Exit codes are null when no exit was observed before teardown, not invented successes. Diagnostic-write failures add exception Data and a loud warning without replacing the original error. No new global process census or desktop probe is added.The reader still performs exactly 40 attempts with 50 ms sleeps; no timeout was widened. Success results and all malformed/missing/foreign-owner/typed receipt rejection rules are unchanged. Production remains v2-first with the original five-second hello budget and the previously reviewed completed-read cancellation repair.
Actual local sequence, with failures preserved separately:
PSScriptRootbefore launching any child (110 ms). Its failure JSON has zero reader calls and no children; this is harness evidence, not a native integration result.2026-10-19T01:42:25.4821840Zto01:42:27.7293050Z. The real peer receipt succeeded in 7 attempts / 403 ms under the unchanged two-second reader, with 2 requests, 2 responses, and 2 publications. The phase then failed because the private loader had omitted the original nestedConvertTo-SketchCanonicalJsondependency. Both owned jobs exited, became empty, and drained their streams (53 ms and 36 ms). The actual new failure diagnostic is retained atD:\g5-870-eaa6520b\logs\multiproject-failure.json. This is not a full integration pass or proof of the old CI cause.2026-10-19T01:44:18.5513069Zto01:44:44.4802139Z(25.927 s): 12 requests / 12 responses, 2 owner graphs, 7 publications, 8 navigation observations, and 2 no-mutation cases. Exactly one complete actual typed receipt was emitted (14380 UTF-8 bytes). Both owned jobs again exited, became empty, and drained their streams, with no teardown failures (69 ms and 12 ms). The outer runner exited 0 with zero stderr bytes. No further local attempts were made.RED: gh api repos/scgopi/GraphCode/actions/jobs/117822919322/logs --allow-escape-sequences -> exact e157 original integration failure: MULTIPROJECT_PEER: no readable owner/receipt snapshot; original failing log retained, causal stage unproven.
GREEN: pwsh -NoProfile -File Test-PeerFailureDiagnostics.ps1 -> 6/6 source-extracted private contracts passed: unchanged absent-file 40x50 ms rejection, successful snapshot return, missing-peer rejection, malformed JSON bounded retry, bounded streams/null unobserved fields, and loud diagnostic-write failure preserving the original exception; initial private warning-capture mistake was corrected in the harness only and retained in its separate failing log.
REGRESSION: pwsh -NoProfile -File Invoke-TargetedMultiProject.ps1 -> operator-approved corrected actual source-extracted multiproject native phase passed in 25.927 s, with exactly one typed receipt, 12/12 correlated requests/responses, all existing native assertions, and both owned jobs empty/exited/streams joined.
The private runner names above refer to retained session-artifact scripts, not newly committed test entry points. Existing source functions/assertions were executed, not reimplemented. Supporting records are
peer-diagnostics-contracts-final.log,peer-targeted-dependency-audit.log,peer-targeted-local-native.log,peer-targeted-local-corrected-summary.json, andpeer-targeted-corrected.stdout.log. The exact local source blob was0749ca7d9a31cbea833afd50fb5bb0ee56dd4117, identical to the committed gate file.git diff --checkand PowerShell parsing passed. Owned pinned provider and exact-head shell builds passed after the documented dependency fetch restored a missing zmx package; the initial missing-package build failure is retained separately.This commit adds observability, not a claimed root-cause fix or a new timing guarantee. The 403 ms observation is one local receipt observation, not a global performance claim. Native/component success does not establish production-daemon persistence or macOS parity. No general review restart was performed for this diagnostics-only change; the earlier original-feature and transport reviews remain historical, separately scoped evidence. New-head hosted CI, readiness, merge, and any follow-up tracking issue are operator-owned; no new-head hosted success is claimed here.