Skip to content

Host integrations must consume released rivet packages, never compile rivet sources into downstream executables #238

Closed

Description

@turinglambdaai

New project constraint (owner decision, 2026-10-13)

Downstream products must not include or compile rivet source files
directly. Every integration surface consumes rivet as a released
package
, so downstream upgrades are version bumps and upstream file
additions require zero downstream coordination.

Current state per surface (taskly as the reference product)

Surface Today Verdict under the constraint
Racket backend raco pkg install '…rivet.git#vX.Y.Z' (git-tag package) acceptable package form; catalog publication is the higher standard
macOS host SwiftPM .package(path: <rivet checkout>/platform/macos) — proper product boundaries (RivetRuntime/RivetEmbedding/RivetSystem), but a source-checkout path, not a released package gray zone: package boundary exists, release form missing
Windows host .vcxproj <ClCompile Include="$(RIVET_ROOT)\platform\windows\runtime\backend.cpp"> etc. — rivet .cpp files compiled straight into RivetHost.exe violates
Linux host downstream CMakeLists copies the ${RIVET_ROOT}/platform/linux/system/*.cpp list into its own add_executable violates (the fragility is on record: taskly's CI went red when #211 added a file; 0.9.0 adds two more)

Note: #234's includable rivet_linux_sources.cmake fragment unifies the
list but still compiles rivet sources into the downstream executable —
under the new constraint it is a transitional step, not the end state.

What "released package" means per surface

  1. macOS: a SwiftPM-resolvable package at a tag — manifest at the
    repository root (or a dedicated package repo/release artifact) so
    downstreams declare .package(url: …rivet.git, from: "0.9.0").
  2. Windows: rivet builds rivet_host.lib (or an umbrella static
    lib) + headers as a releaseable unit; downstreams consume it via
    find_package(rivet CONFIG) / NuGet / a release-asset layout, never
    <ClCompile> of rivet sources.
  3. Linux: the same static-library + CMake package config, or a
    FetchContent/tag-based add_subdirectory with a declared target
    (rivet::host-platform), so downstreams link a target instead of
    listing sources.
  4. Racket: publish releases to the package catalog so the git-URL
    pin becomes raco pkg install rivet with a version constraint.

Sequencing suggestion

The host library packaging is the enabling work; once any surface ships
a package form, taskly migrates that surface to it (it is the reference
product and should be the first mover, as it was for RivetUpdate).

Activity

  1. turinglambdaai commented on Oct 13, 2026

    @turinglambdaai
    OwnerAuthor

    Windows package-smoke CRT diagnosis (three CI rounds, empirical)

    While migrating taskly onto the package surfaces I chased the Windows smoke through three LNK2038 shapes; root causes are now fully identified so whoever lands the final fix can skip the rediscovery:

    1. HybridCRT.props ships in the template but nothing imports it. The stock smoke exe compiles MD/MDd (stock MSVC defaults) because Directory.Build.props importing HybridCRT is a product-side artifact (taskly carries its own), not part of the scaffold. Any fix that assumes the template exe is MT will mismatch.
    2. C++/WinRT headers have two sources. The template exe references Microsoft.Windows.CppWinRT 3.0.260818.1 explicitly — that package, not WindowsAppSDK, provides winrt/ headers. If rivet-host.vcxproj (or rivet-chart) does not carry the same PackageReference, the library compiles against the toolchain-default 2.0 projection and the exe against 3.0 → LNK2038 on "C++/WinRT version" (and on _COROUTINE_ABI, which differs between projections). 156c69b added Microsoft.Windows.CppWinRT (default overridable via RivetCppWinRTVersion) to both libraries — that part is the load-bearing fix; msbuild /restore (already in raco rivet build) restores ProjectReference closures, so it does take effect.
    3. The CRT forwarding contract: RivetRuntimeLibrary (forwarded through the ProjectReference's Properties=) must reflect the consumer's actual CRT. The stock template must not hard-code MT (that's what 156c69b removed); hybrid products define it themselves (taskly/taskboard do). If the smoke flow imports HybridCRT into the generated exe (67aa594's smoke-source-package.sh touches this area), the template must forward MT/MTd accordingly — the invariant is "library CRT == consuming exe CRT", never a fixed value.

    Suggested end state: keep the library CRT neutral by default (MD/MDd), forward via RivetRuntimeLibrary only from consumers that deviate, and add a smoke matrix leg that builds the hybrid variant once so both paths stay green. Happy to hand this over — the parallel work on #235/#236 is deeper in this code than my session.

  2. turinglambdaai commented on Oct 13, 2026

    @turinglambdaai
    OwnerAuthor

    Shipped in Rivet 0.11.0.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions