Companion Compatibility Matrix

View Source

This guide is the single source of truth for one question: what core version and which engine do I need to add a first-party companion package? Each companion is published as its own Hex package and versions independently of crosswake core.

For how to register a companion and what mix crosswake.doctor reports when a dependency is missing, read Companion Integrations. For the forward-looking compatibility contract (manifest, bridge, and runtime axes), read Compatibility Boundaries. This matrix does not restate either guide — it pins the per-package version facts the drift test keeps honest.

The Requires crosswake cell below is the verbatim Hex requirement extracted from each package's mix.exs; a merge-blocking drift test (test/crosswake/proof/phase132_compat_matrix_drift_test.exs) fails the build if a cell drifts from the package source in either direction.

Hex PackageCompanion IDCurrent VersionRequires crosswakeEngine Dependencyhexdocs
crosswake_rulestead:rulestead0.1.0~> 0.2{:rulestead, "~> 0.1", optional: true}hexdocs.pm/crosswake_rulestead
crosswake_rindle:rindleunpublished~> 0.2{:rindle, "~> 0.1", optional: true}not yet on hexdocs
crosswake_sigra:sigra0.1.3~> 0.2none (pure-Elixir auth machinery)hexdocs.pm/crosswake_sigra
crosswake_chimeway:chimeway0.1.0~> 0.2none (pure-Elixir notification machinery)hexdocs.pm/crosswake_chimeway
crosswake_threadlineN/A (observer — not a :companions registrant)0.1.0~> 0.2none (optional :plug + :phoenix_live_view for surface modules)hexdocs.pm/crosswake_threadline

The Current Version column reflects published Hex truth. A cell reading unpublished means the package is extracted and wired into the release graph in this repository but has never been published to hex.pm — it cannot be added to a project yet, and it has no hexdocs page. crosswake_rindle is in that state today. crosswake_rulestead 0.1.0 is published and has current HexDocs.

For public registry truth, run mix crosswake.release.status --live; that command is allowed to report a package version as configured locally while still warning that Hex, Maven Central, or the SwiftPM mirror has not propagated it yet.

Threadline wiring

Threadline is the one companion that is not a :companions registrant — its Companion ID cell reads N/A (observer) for that reason. Instead of registering in :companions config, Threadline is wired into a host application through two Phoenix integration points: the Crosswake.Plug.Threadline plug (added to the endpoint or a router pipeline) and on_mount: Crosswake.Live.Threadline (added to a LiveView or live_session). As a pure-OTP audit/correlation observer it has no engine dependency; :plug and :phoenix_live_view are optional and needed only for those surface modules.

Independent Versioning

These are first-party companion packages, each with its own SemVer line — the version numbers do not move in lockstep with core or with each other. The Requires crosswake cell declares a minimum, not a ceiling. Every current companion declares ~> 0.2 and will not resolve against a 0.1.x core. Each companion still owns that floor independently and can raise it without moving its package version or any sibling companion in lockstep.

Reading the Requirement Syntax

The current requirement form is ~> 0.2, meaning >= 0.2.0 and < 1.0.0. It excludes the entire 0.1.x line, so every current companion requires core 0.2.0 or newer. If a companion ever needs a tighter floor it will name a fuller version, and the drift test will require that exact literal in this doc.

Release Integrity Boundaries

Release integrity work keeps the train honest without changing these compatibility floors: Release Please Release PR merge is the human approval boundary, CI owns happy-path Hex publishing, and manual dispatch is exact-ref Hex recovery only. Clean-room exactness, SwiftPM/Maven recovery, and iOS mirror backfill are separate release-ops evidence surfaces. mix crosswake.release.status is the current text/JSON status surface for local graph truth and optional live registry presence. This guide remains the floor contract; live registry presence is a separate status concern and does not couple independent companion version lines.

Engine Dependencies

crosswake_sigra is the exception to the engine-dependency pattern: version 0.1.3 has no dependency on the sigra Hex package. It supplies Crosswake's pure-Elixir auth projection seam, while the host projects its verified Sigra session into that seam. Consequently it does not constrain Sigra's package version: a host on Sigra 1.4.x, or on a separately sourced 1.5.0, has no Mix-solver conflict with crosswake_sigra. This is version decoupling, not a claim that the companion replaces or directly exercises every Sigra release.

Companions that do declare an engine use optional: true. An optional dependency is not pulled transitively into an adopter's project — adding crosswake_rindle does not install rindle. You add the engine yourself only when you want the engine-present behavior; absent it, the companion fails closed and mix crosswake.doctor reports companion.dependency_missing.

Name the friction honestly. Because ~> 0.1 admits every 0.x (>= 0.1.0 and < 1.0.0), a companion only hits the cap when its engine reaches 1.0.0. rulestead is at 1.0.0 — outside ~> 0.1 — so to run it engine-present you must pin the engine to its 0.1.x line rather than taking the latest release; widening past the next major is deferred until the contract is proven against it. rindle is at 0.3.0, which is still within ~> 0.1, so it resolves engine-present without pinning.

Verifying Companion Health

After adding a companion package, run:

mix crosswake.doctor

The doctor closes the loop on the two ways a companion goes quietly wrong: you added the package but never registered it in :companions config, or you registered it but never added (or pinned) its engine. In the second case the doctor emits companion.dependency_missing as an :error — the live check that this static matrix cannot perform for you.