Skip to content

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 22 Sep 07:39
· 21 commits to main since this release
2f2f3a2

The production-readiness release. It ships the correctness fix main had
been sitting on for twelve days, and closes the gaps between "the analysis is
correct and published" and "a team can depend on this in their CI": the
supply chain, the release, the platform coverage, and the semver rule that
decides what a field addition costs.

Added

  • Windows is gated in CI, and the README says which platforms are
    supported.
    The word did not appear anywhere in this repository — not a
    support statement, not an exclusion, not a job — while the README said the
    analysis "runs anywhere". A Windows user had no way to tell whether a
    failure was worth reporting.

    It mostly does run anywhere: the job found three bugs, two of which are
    below and one of which made learn panic outright. The analysis, check,
    the artifact round-trip, the schemas and the CLI contract are gated on
    Windows now.

    The four terminal views are not, and that is stated rather than
    skipped: under ConPTY the PTY suites time out waiting for a frame boundary
    while the screen they print is the right screen, fully painted — two
    different suites show it, so it is about how that console delivers what an
    application wrote rather than about what these views render. #162 holds the
    root cause, which needs a Windows machine to reduce. .gitattributes pins
    the working tree to LF, which is the other half of the learn fix.

    Components are named explicitly in that job rather than left to
    rust-toolchain.toml: the channel installed on the runner and its
    components did not, and the failure surfaced three crates later as the
    driver's build script reporting a missing rustc-dev — the right message
    from the wrong layer.

Fixed

  • cargo reconverge learn panicked on Windows, for all four lessons.
    The prose arrives through include_str!, which embeds the working tree's
    bytes. A checkout with core.autocrlf=true — the default on Windows —
    gives \r\n---\r\n, so the page split found no separator, every lesson
    collapsed to one page, and the page-metadata assertion fired. A surviving
    \r would have rendered as a glyph too. Line endings are normalized before
    the split now, and the regression test is written against the bytes rather
    than the platform, because a Linux clone of a repository whose files were
    committed with CRLF has the same problem. .gitattributes pins the tree to
    LF as well, for the golden files the PTY suites compare byte-for-byte.

  • reconverge-driver refused to build on Windows with rustc-dev
    installed.
    The build script that turns a missing component into one
    actionable line looked in <sysroot>/lib for librustc_driver*, which is
    the Unix layout — windows-msvc puts rustc_driver-<hash>.dll under
    <sysroot>/bin, so a correct toolchain was reported as missing the
    component and the build stopped. That is exactly what the script's own
    documentation promises not to do.

    The same check was also a false negative everywhere:
    librustc_driver-<hash>.so is in <sysroot>/lib on any toolchain, because
    it is the shared library rustc itself links — measured against a stable
    1.98.0 with no rustc-dev, one match there and zero in
    lib/rustlib/<host>/lib. It now looks for the component's .rmeta in
    <sysroot>/lib/rustlib/<host>/lib, which is where rustc-dev installs on
    every platform, so the guard fires when it should and only then.

Added

  • Releases carry binaries, and the action has a version to pin. Two gaps
    that were really one: release.yml compiled cargo-reconverge,
    reconverge-driver and reconverge-tui for Linux and macOS on every
    release and then left them in workflow artifacts, which expire and need a
    GitHub login to reach — v0.6.1 shipped with zero assets. So the only
    supported install was cargo install, which compiles a rustc-driver, and
    the GitHub Action pays that on every consumer's run because it deliberately
    never caches.

    github-release now creates the release from this version's CHANGELOG.md
    section — not from generated commit subjects — and attaches one
    reconverge-<tag>-<host-triple>.tar.gz per platform with a .sha256
    beside it. float-major-tag then repoints v0 through the API, after the
    publish, so the floating tag can never name a release that did not reach
    crates.io.

    README.md and action/README.md document @v0 instead of @main. That
    was the sharper half of the problem: the ref decides which analyzer version
    the action installs, so @main re-decided it on every run of a consumer's
    CI, and a merge here changed the gate in somebody else's pull request with
    no notice and nothing to pin.

  • --cc takes the CUDA spellings. sm_86 is what nvcc -arch takes,
    what ptxas prints and what a PTX .target directive says; 86 is the
    same thing without the prefix. Both now normalize to 8.6, as do sm_120
    and 100 — a capability is one or two major digits and exactly one minor
    digit, so the last digit of a run is always the minor.

    launchbound has accepted these two spellings since 2.0 and passes this
    flag straight through to this parser, so the pair disagreed about the
    spelling of their shared argument. Nothing else moved: normalization
    rewrites the text and hands it to the same parser, so 8.x is still
    non-numeric and 999.9 still lands on the table message.

    One test changed its example rather than its assertion:
    a_bad_value_answers_in_one_line_… used --cc 80, which now means 8.0.

Changed

  • termlens 0.11 in both PTY suites (reconverge-tui and
    cargo-reconverge), and the vendored skill with it. 0.11 is termlens's
    stability candidate: from it no promised item changes incompatibly before
    its 1.0, so this requirement should hold for a while.

    Its one breaking change lands here as a simplification.
    Screen::unsupported() returns a view instead of a slice of Arc<str>,
    and unsupported_overflow() folds into it — so the pinned list and "the
    record is not truncated" are now one assertion, because the view
    compares equal to a slice only when the retained shapes match and
    nothing overflowed the bound. tests/emulation.rs loses its
    Vec<String> helper, and the three flow tests lose a separate overflow
    assertion each.

    The comment in tests/emulation.rs warning that termlens#320 reported
    blink and strikethrough as unsupported when the shadow parser implements
    them is gone: that was fixed upstream in 0.10.2, so an entry in this
    list is now a real gap in every case.

  • Uniformity is scoped now, and a barrier is checked against its own
    participants
    (#133). A guard uniform within a block settles
    sync_threads and settles nothing wider: blockIdx and
    cluster::block_rank() are constant on every thread of a block and
    different on the next one, so

    #[cluster_launch(2, 1, 1)]
    pub fn only_rank_zero() {
        if cluster::block_rank() == 0 { cluster::cluster_sync(); }
    }

    is entered by one block of the cluster and skipped by the other, and 0.6.x
    reported nothing at all — exit 0, no findings, zero opaque. The same
    shape one scope up (grid::sync() under a blockIdx guard) was equally
    silent, which is how the report widened from a cluster quirk to the
    general statement.

    The engine now carries a second lattice beside lane uniformity:
    LaunchScope — Block ⊑ Cluster ⊑ Grid — recording how far each value is
    actually constant, and the dialect answers barrier_scope for how far
    each barrier reaches. A finding is raised when the guard's scope does not
    cover the barrier's.

    Always warning, never promoted. The witness interpreter replays the
    lanes of one block and cannot execute the second block this needs, so
    there is no concrete hang to confirm; calling it confirmed would be a
    claim the evidence does not support.

    The precision half matters as much and is pinned by its own samples:
    everything starts grid-constant and is narrowed only by what it reads, so
    a kernel argument, blockDim, and arithmetic over either still decide a
    grid-wide barrier, and cluster::cluster_idx() still decides a
    cluster-wide one. blockDim/gridDim/nsmid/gridid/nwarpid/the
    launch environment registers and the cluster's shape moved from
    BlockUniform to the new GridUniform; smid, block_rank and the
    cluster coordinates stayed block-scoped, which is what makes the check
    fire where it should.

Breaking

  • reconverge-core: Callee, BarrierSite and Analysis gain fields
    (Callee::scope, BarrierSite::{scope, cross_block_cause},
    Analysis::{local_scopes, block_guard_scope}), and CallKind gains
    ClusterUniform and GridUniform beside BlockUniform. SimtDialect
    gains barrier_scope, with a Block default, so an existing dialect
    keeps compiling and keeps the narrow answer.

  • reconverge-artifacts: the four artifact roots, ToolInfo and
    ReadError are #[non_exhaustive].
    "Schemas are additive-only" and
    "adding a field is not a breaking change" turned out to be different
    promises, and only the first one held: a new key in findings.v1 is
    additive in JSON and a major break here, because a struct with public
    fields can be built with a struct expression from anywhere. The Breaking
    entry above is that, twice, for three reconverge-core records.

    Which types close is decided by who builds the value, and the split was
    measured rather than assumed. Marking all twenty-two records broke 42
    construction sites inside this workspace alone, across cargo-reconverge,
    reconverge-tui and the driver — a downstream front-end that writes
    artifacts would pay the same, so the leaf records (Finding, SourceSpan,
    Step, Entry and the rest) stay plain deliberately. The roots do not:
    a reader deserializes one rather than assembling it, a top-level key is the
    likeliest thing a schema gains, and three of the four already had a new.
    WitnessArtifact now has one too, matching FindingsArtifact::new.

    The vocabulary enums — Confidence, LaneState, VerdictKind,
    Uniformity, ValueSource — stay exhaustive on purpose: a _ arm
    over confidence tiers or lane states is a wrong answer that compiles, and
    adding a variant is meant to make every reader decide. The rule is written
    down in CONTRIBUTING §8 and in the crate docs, so the next reader does not
    file the inconsistency as a bug.

Install

cargo install cargo-reconverge
cargo reconverge setup

Or take a prebuilt archive below and put the three binaries
on your PATH in the same directory -- cargo-reconverge
finds the driver and the views as siblings of its own
executable. Verify it first:

shasum -a 256 -c reconverge-v0.7.0-<triple>.tar.gz.sha256