Skip to content

docs: describe the Windows client that exists now, not the one authored blind - #2

Merged
Ryanmello07 merged 1 commit into
urnetwork:mainfrom
Ryanmello07:docs/readme-current-state-upstream
Aug 13, 2026
Merged

docs: describe the Windows client that exists now, not the one authored blind#2
Ryanmello07 merged 1 commit into
urnetwork:mainfrom
Ryanmello07:docs/readme-current-state-upstream

Conversation

@Ryanmello07

Copy link
Copy Markdown
Contributor

The README still described this repo as macOS-authored code that had never been compiled on Windows — "not compiled on the authoring host", "expect one iteration pass on a real Windows box". Both architectures now build in CI on every push, and the client has been run and exercised on real hardware, so that framing misleads anyone evaluating the repo.

Everything below was checked against the tree rather than written from memory.

Corrections

Claim in the old README Reality
"not compiled on the authoring host" build-and-test.yml builds x64 + ARM64 green on every push
R6/R7 DNS + IPv6 leak guards listed as remaining app/src/Service/WfpPolicy.cpp implements them, plus the kill switch
Updater not mentioned UpdateChecker exists, and is load-bearing since the Store cannot push EXE/MSI updates
Advanced Mode / developer screen not mentioned present across ConnectPage, DeveloperPage, SettingsPage, MainWindow, SdkHost

Also adds the CI workflow, build-local.ps1, and the app log path.

Two SDK-binding traps worth recording

Both produce silently wrong output instead of an error, which is what makes them expensive:

  • make generate is pure Go and runs on any host. It is not macOS-only — only make build_windows is host-sensitive, because of the cross-toolchains (llvm-mingw / zig). An earlier belief that generation required macOS cost real time.
  • The generator must run with GOOS=linux in the environment. On a Windows host it drops every !windows-tagged declaration — IoLoop among them — and emits bindings that are wrong with no warning. Note also that GOOS=linux go run ./gen cross-builds and then cannot execute the result; build first, then run.

The RPC return-value constraint is noted for the same reason: because the UI and the tunnel are in different processes, anything the UI must report rather than merely trigger has to return its value across the RPC. That is the shape behind MigrateExit and ProbeAllExits returning counts (urnetwork/sdk#141).

Kept honest

Known gaps stay listed as gaps — Store submission, attestation signing, driver loopback fixup and Verifier hardening, localization — including the note that the split-tunnel driver is the least-exercised component here, with the process-based bind-redirect path having had considerably more real use than the rest.

Docs only; no code changes.

🤖 Generated with Claude Code

https://claude.ai/code/session_01USz3ouFAdiioTWHnjo1815

The README still described this as macOS-authored code that had never been
compiled on Windows ("not compiled on the authoring host", "expect one
iteration pass on a real Windows box"). Both architectures now build in CI
on every push, and the client has been run on real hardware, so that framing
was actively misleading to anyone evaluating the repo.

Corrected, all against the tree rather than from memory:

- Drop the never-compiled/authored-on-macOS caveats and the IDE-errors note.
- R6/R7 DNS and IPv6 leak guards were listed as REMAINING work; WfpPolicy
  implements them, along with the kill switch. Moved to implemented.
- The updater (UpdateChecker) was not mentioned at all, though the Store
  cannot push EXE/MSI updates and it is therefore load-bearing.
- Add Advanced Mode and the developer/reliability screen.
- Add the CI workflow, build-local.ps1, and the app log path.

Also record two SDK-binding traps that cost real time and produce silent
wrong output rather than errors: `make generate` is pure Go and NOT
macOS-only (only the cross-toolchain build is host-sensitive), and the
generator must run with GOOS=linux or it drops every !windows-tagged
declaration. Note the RPC return-value constraint for the same reason —
it is the shape behind MigrateExit and ProbeAllExits returning counts.

Known gaps are kept as gaps, including that the split-tunnel driver is the
least-exercised component here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01USz3ouFAdiioTWHnjo1815
@Ryanmello07
Ryanmello07 merged commit cc9c682 into urnetwork:main Aug 13, 2026
3 checks passed
Ryanmello07 added a commit to Ryanmello07/urnetwork-windows that referenced this pull request Aug 14, 2026
…t, not incidentally

Fix round 3 for Task 2a. The controller's frame-capture gate caught a
real runtime regression, not a diff-review finding: launch signed-out
wide (art card left, form right -- correct, captured), then move the
window narrow. The form re-centers correctly but the carousel art card
is gone entirely -- not for one frame, permanently; waiting 700ms does
not heal it. This is the Task 2a reviewer's Important finding urnetwork#2
(reparent relies on the SizeChanged cascade) manifesting for real.

Root cause: ApplyBreakpoint's login block reparents LoginCarouselHost
between LoginPanel and LoginArtPane but never asks LoginPage to resync
the host's Visibility/Height for its new parent -- it relied entirely
on LoginPanel's/LoginRoot's own SizeChanged firing afterward to call
ApplyLoginLayout again. On the repro that never happened for this
resize (or happened before the reparent, while the host was still
under its old parent), so the host was left with whatever Visibility/
Height ApplyLoginLayout had last computed for the OLD slot, and once
nothing else's size was still changing, nothing was left to trigger a
second look. A layout switch this important cannot depend on an
event that isn't guaranteed to land after the state it needs to see.

Fix: LoginPage::ApplyLoginLayout moves from private to public (LoginPage.h)
and MainWindow::ApplyBreakpoint calls it explicitly, once, right after
the if/else that does the reparenting -- covering both directions of the
crossing from one call site rather than duplicating it per branch.
ApplyLoginLayout stays the single writer of the host's Visibility/Height;
ApplyBreakpoint stays the single writer of LoginArtColumn/LoginFormColumn/
LoginArtPane. Nothing about the two owners' boundaries changed, only
who reliably asks the owner to re-run after moving what it owns.

The existing LoginRoot/LoginPanel SizeChanged hooks are untouched and
still do real work (a same-layout resize that does not cross the
breakpoint still needs the elastic-height arithmetic to re-run); this
adds a THIRD, deterministic call site rather than replacing the other
two.

Line endings: MainWindow.xaml.cpp was already correct LF+BOM on disk,
matching git HEAD, and was edited in place. LoginPage.h was byte-wise
CRLF on disk (git's autocrlf silently hid this from `git status`/`git
diff`, the same trap prior rounds hit) despite being genuinely LF in
history -- confirmed identical to `git show HEAD:LoginPage.h` after
normalizing. Read as raw bytes, normalized to LF, edited by exact
string replacement, written back in LF with no BOM.

Verified by running: & .\tools\build-local.ps1 from app\, 0 errors, 1
warning (the pre-existing unrelated XamlTypeInfo.g.cpp C4651). Build
only, per task scope -- the controller re-runs the frame capture.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01USz3ouFAdiioTWHnjo1815
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