Files
Dario Gabriel LipicarandClaude Opus 5 3694e85770 fix(ci): run the symbol gate, and fix what it does on Windows
The gate was exposed in `checks` and built by NOTHING. ci.yml names `tests`
specifically, `nix flake check` runs nowhere in this repo, and `ws test` builds
exactly one check per repo -- so the control that mechanically enforces the
one-runtime invariant was dead code here, exactly as it was in logos-basecamp.
The negative control is wired alongside it, always: a gate that has never been
seen to fail is indistinguishable from a broken one.

Three defects in the gate itself, all Windows-only, all inherited from the
logos-basecamp sibling this file was copied from and all found by cross-building
it there:

  * the peer sweep globbed lib/*.{dylib,so}. On Windows every liblogos_* shared
    image is staged into bin/ as a .dll, because the PE loader searches the
    executable's directory -- so it found ZERO owners and the exactly-one
    assertion could not pass on a correct tree.

  * `nm` and `c++filt` were called by their bare names. The cross bintools
    installs ONLY x86_64-w64-mingw32-prefixed ones, so neither was on PATH and
    every measurement read nothing; valid() then refused to assert over it.
    Fail-closed, but the gate could never run. Fixed with targetPrefix, which is
    "" natively and therefore a no-op here.

  * `nm --defined-only` counts PE import THUNKS as definitions: ld synthesizes a
    .text stub AND an __imp_<mangled> IAT slot per imported function. That
    reported images as definers of types they merely import. The paired __imp_
    entry is the discriminator, and it is the right one rather than merely a
    working one -- a genuine second copy statically linked in has no __imp_ slot
    and still counts. (The PE export table also hides the phantom, but it hides
    a real private copy too, trading a false positive for a false NEGATIVE.)

NOT covered: x86_64-windows, which is where a duplicate actually bites. `checks`
is native-only in this flake and Windows artifacts are built in release.yml, so
exposing the gate for that target is a follow-up. The gate itself is now correct
for PE -- verified in logos-basecamp, which does cross-build it.

Verified on aarch64-darwin: SYMBOL GATE PASS (TokenManager 1 definer
liblogos_protocol(35), LogosAPI 1 definer liblogos_qt_host(26), LogosAPIClient 1
definer liblogos_protocol(49); consumers 0) and NEGATIVE CONTROL PASS, rejecting
a planted duplicate at 49 symbols.

Also drops two dangling references to cmake/LogosSharedFromDll.cmake, the
single-provider shim deleted once the runtime became real shared libraries, and
the claim that liblogos_core is the provider -- it is not, which is precisely
why the assertion is exactly-one rather than naming an owner.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 19:56:47 -03:00
..