Files
Dario Gabriel LipicarandClaude Opus 5 9a92fe860e 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 smoke-test
and integration-test 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, the same way it
was in logos-basecamp and logos-logoscore-cli. The negative control is wired
alongside it, always: an absence assertion that has never been seen to fail is
indistinguishable from a broken one.

Three defects in the gate itself, inherited from the logos-basecamp sibling this
file was copied from, and found by cross-building it THERE. They are latent
here -- this flake has no x86_64-windows target -- but a copy that is wrong on
the platform it is copied to is worth fixing before it is needed, not after:

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

  * `nm` and `c++filt` were called by their bare names. A cross bintools
    installs ONLY the x86_64-w64-mingw32-prefixed ones, so neither is on PATH
    and every measurement reads nothing; valid() then refuses to assert over it.
    Fixed with targetPrefix, which is "" natively -- a no-op on every platform
    this repo currently builds.

  * `nm --defined-only` counts PE import THUNKS as definitions: ld synthesizes a
    .text stub AND an __imp_<mangled> IAT slot per imported function. That
    reports 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.)

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), and the app itself defines 0 -- with NEGATIVE
CONTROL PASS rejecting a planted duplicate at 2 definers for LogosAPIClient.

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