Skip to content

Releases: GeoffGodwin/sdivi-rust

v0.2.51 — sdivi-rust v0.2.51 — Binaryen-free WASM builds

03 Jun 20:34

Choose a tag to compare

sdivi-rust v0.2.51 — Binaryen-free WASM builds

A small maintenance release (M50) that lets bindings/sdivi-wasm build with
wasm-pack in network-restricted / corporate environments that lack the
binaryen toolchain (wasm-opt). No source or behaviour change; snapshot_version
stays "1.0".

Highlights

  • Disabled wasm-opt post-processing in the wasm-pack release profile. By
    default wasm-pack build runs wasm-opt and, when binaryen isn't on PATH,
    tries to download it — which fails behind a corporate proxy/airgap and breaks
    the build. The size-optimised [profile.release-wasm] Cargo profile
    (opt-level = "z", fat LTO, codegen-units = 1) already provides the primary
    size reduction, so wasm-opt is now disabled via
    [package.metadata.wasm-pack.profile.release] wasm-opt = false. Source builders
    no longer need binaryen.

Size impact

Dropping the wasm-opt pass grows the bundler/node .wasm by ~10%
(≈1,531,484 → ≈1,679,707 bytes) but stays comfortably within the existing
1.75 MB (1,835,008-byte) per-target budget, with ~155 KB of headroom. The trade —
a fragile toolchain dependency for ~10% size — favours the project's primary
audience (corporate / network-restricted builders).

What did not change

  • snapshot_version is still "1.0". Snapshot JSON, the 19-category contract,
    pattern_metrics, and DivergenceSummary are unchanged from v0.2.50.
  • No public-API change, no new .sdivi/config.toml keys, no analysis behaviour change.
  • The published @geoffgodwin/sdivi-wasm exposes the identical wasm-bindgen surface;
    only the codegen post-processing differs.
  • The WASM dependency invariant (Rule 21) holds.

Install

# crates.io
cargo install sdivi-cli

# pre-built binary (Linux x86_64 example)
curl -Lo sdivi https://github.com/GeoffGodwin/sdivi-rust/releases/download/v0.2.51/sdivi-x86_64-unknown-linux-gnu
chmod +x sdivi && mv sdivi ~/.local/bin/

# WASM / npm
npm install @geoffgodwin/sdivi-wasm@0.2.51

Documentation

Released under Apache 2.0.

Full Changelog: v0.2.50...v0.2.51

v0.2.50 — sdivi-rust v0.2.50 — Fix Leiden non-termination on pathological graphs

03 Jun 17:00

Choose a tag to compare

sdivi-rust v0.2.50 — Fix Leiden non-termination on pathological graphs

A correctness/reliability release (M49) that eliminates a non-termination path in
the native Leiden implementation. Certain small graphs with certain seeds could
make run_leiden — and therefore Pipeline::snapshot / detect_boundaries
run for many minutes on inputs as small as 8 nodes. This is fixed, and the
regression is guarded so it cannot silently return.

snapshot_version stays "1.0". No public-API or config change. One caveat:
the fix changes the RNG draw order, so some inputs produce different — but
deterministic and quality-preserving — cluster assignments (see "Impact" below).

Highlights

  • Leiden exponential-blowup fix (M49.2). leiden_recursive previously descended
    into the aggregated graph on every outer-loop iteration in which local moves
    fired, compounding to O(max_iterations^depth) work — on the order of 100^8 for
    an 8-node graph. It is now restructured to match Traag et al. 2019 Algorithm 1:
    local moves run to convergence at each level, then the aggregate is descended into
    at most once per invocation, bounding total work to
    O(max_iterations × n × max_recursion_depth). The minimal reproducer found by
    property testing (a K₁,₅ star, n=6, seed=0) now completes instantly.
  • The hang is now caught in seconds, not 30 minutes (M49.1). proptest's
    fork + timeout features are enabled for the sdivi-detection refinement
    proptests with a per-case timeout, so any future non-terminating case fails fast
    with its minimized input instead of hanging the CI runner to its job timeout. The
    captured case is committed as a regression and guarded by a deterministic
    termination test.

Impact on existing baselines

The category contract, snapshot schema, and config are all unchanged. The only
observable change is in community/cluster assignments for a subset of inputs:

  • Inputs that previously converged in a single local-move sweep are unaffected.
  • Inputs that required multiple sweeps may produce different cluster assignments
    than pre-M49.2 — deterministic for a fixed seed, and within the verify-leiden
    quality tolerance (modularity within 1%, community count within ±10%).
  • If you diff snapshots across the upgrade, re-baseline boundary/cluster fields.
    See MIGRATION_NOTES.md for the full note.

What did not change

  • snapshot_version is still "1.0". Snapshot JSON, pattern_metrics,
    DivergenceSummary, and the 19-category contract are unchanged.
  • No public-API change, no new .sdivi/config.toml keys.
  • Determinism contract holds: same repo state + same seed ⇒ bit-identical Snapshot
    (a different-but-stable output than pre-M49.2 for the affected inputs).
  • WASM dependency invariant (Rule 21) holds; the .wasm stays size-optimised (~1.53 MB).

Install

# crates.io
cargo install sdivi-cli

# pre-built binary (Linux x86_64 example)
curl -Lo sdivi https://github.com/GeoffGodwin/sdivi-rust/releases/download/v0.2.50/sdivi-x86_64-unknown-linux-gnu
chmod +x sdivi && mv sdivi ~/.local/bin/

# WASM / npm
npm install @geoffgodwin/sdivi-wasm@0.2.50

Documentation

Released under Apache 2.0.

Full Changelog: v0.2.48...v0.2.50

v0.2.48 — sdivi-rust v0.2.48 — Smaller WASM artifact and a green CI surface

02 Jun 21:39
a850e8a

Choose a tag to compare

sdivi-rust v0.2.48 — Smaller WASM artifact and a green CI surface

A maintenance release (M48) that follows v0.2.47. It ships a ~25% smaller
@geoffgodwin/sdivi-wasm .wasm and restores a fully green CI surface by fixing
three pre-existing, mutually-masking gate failures that the M34–M47 batch carried.
There are no functional changes: same analysis behaviour, same wasm-bindgen
surface, same snapshot_version "1.0", same public API.

Highlights

  • WASM artifact ~25% smaller. The bundler and node targets now build with the
    size-optimised release-wasm settings (opt-level="z", fat LTO,
    codegen-units=1), driven through wasm-pack via job-scoped
    CARGO_PROFILE_RELEASE_* env overrides (sidestepping the wasm-pack 0.13.x
    --release/--profile conflict). Both targets drop from ~2,062,372 to
    ~1,531,484 bytes. Behaviour is byte-for-byte equivalent.
  • WASM bundle-size gate green again. M34–M47's new pattern-category regex
    tables had pushed the .wasm over the 1.75 MB per-target budget; the optimised
    build lands back under it with ~300 KB headroom — no budget bump needed.
  • M47 consumer-surface typecheck made deterministic. tests/typecheck/tsconfig.json
    now includes "DOM" in lib, so console (used throughout the documented
    examples) resolves on every CI runner instead of depending on an ambient
    @types/node. A self-referential guard comment in negative.ts that began with
    the literal @ts-expect-error token (parsed by TypeScript as a real directive)
    was reworded.
  • Rustdoc fix. classify_hint's documentation linked to the private
    CALL_DISPATCH const, failing cargo doc under RUSTDOCFLAGS="-D warnings".
    The link is now a plain code span.

What did not change

  • snapshot_version is still "1.0". Snapshot JSON, pattern_metrics,
    DivergenceSummary, and the 19-category contract are all unchanged from v0.2.47.
  • No public API change, no new .sdivi/config.toml keys, no new pub items.
  • The WASM dependency invariant (Rule 21) holds; the dependency tree is unchanged
    — only the codegen profile differs.
  • Determinism, atomic-write, retention, and exit-code contracts are unchanged.

Install

# crates.io
cargo install sdivi-cli

# pre-built binary (Linux x86_64 example)
curl -Lo sdivi https://github.com/GeoffGodwin/sdivi-rust/releases/download/v0.2.48/sdivi-x86_64-unknown-linux-gnu
chmod +x sdivi && mv sdivi ~/.local/bin/

# WASM / npm
npm install @geoffgodwin/sdivi-wasm@0.2.48

Documentation

Released under Apache 2.0.

What's Changed

  • ci: green up post-v0.2.47 CI (wasm size + M47 typecheck + rustdoc link) by @GeoffGodwin in #6

Full Changelog: v0.2.47...v0.2.48

v0.2.47 — sdivi-rust v0.2.47 — Eleven new pattern categories and the multi-category dispatch framework

02 Jun 15:00

Choose a tag to compare

sdivi-rust v0.2.47 — Eleven new pattern categories and the multi-category dispatch framework

This release lands the M34–M47 milestone batch, which more than doubles the
pattern measurement surface — from eight categories to nineteen — on the back of
a new multi-category call-dispatch framework. The headline is the CALL_DISPATCH
precedence registry (M34) and the eleven categories it makes possible:
framework_hooks, decorators, null_safety, schema_validation,
state_store, collection_pipelines, http_routing, testing,
serialization, concurrency, and comprehensions. Two existing categories
(resource_management, error_handling) are enriched with cross-language node
kinds, and the WASM consumer surface gains a strict TypeScript typecheck guard.

snapshot_version stays at "1.0". The snapshot JSON shape, pattern_metrics
field shapes, and the DivergenceSummary structure are all unchanged. What
changes is the per-category instance distribution on the next snapshot after
upgrade — see "Impact on existing baselines" below.

Highlights

  • M34 — multi-category call-dispatch framework. classify_hint's
    call_expression/call arm now iterates a const CALL_DISPATCH registry
    instead of a hand-ordered if-chain. Precedence is a first-class, tested
    contract (slots P1–P11); the canonical table lives in
    docs/pattern-categories.md. Behaviour for the pre-existing categories is
    identical — no snapshot diff from this milestone alone.
  • M35 — framework_hooks. TS/JS call_expression callees matching
    ^use[A-Z] (React/Vue/Svelte built-ins plus the custom-hook ecosystem).
  • M36.1 / M36.2 — decorators. TS/JS decorator nodes (M36.1, one instance
    per decorator line) and Python decorated_definition nodes (M36.2,
    wrapper-granularity — one per decorated definition). Node-kind-only; every
    decorator counts regardless of name.
  • M37 — null_safety. TS/JS optional_chain (a?.b, arr?.[0]) and TS
    non_null_expression (el!). Optional calls (fn?.()) emit call_expression
    and are not counted; nullish coalescing (??) is deferred.
  • M38 — schema_validation. Zod / Yup / Valibot / Superstruct
    namespace-anchored calls and the Zod .safeParse( call (TS/JS), plus Pydantic
    field-constraint calls (Field/constr/conint) in Python. Slot P4.
  • M39 — state_store. Redux / RTK, React-Redux hooks, Zustand, Jotai /
    Recoil, MobX, Preact/Angular/Solid signals — ^-anchored at callee start.
    Slot P5. Precedence reassignment: useSelector/useDispatch/useStore
    move from framework_hooks to state_store (more specific wins).
  • M40 — collection_pipelines. .map/.filter/.reduce/.flatMap/
    .forEach/.find/.some/.every/.flat member calls on any receiver.
    Slot P10 (broadest member-call category). Receiver type is indistinguishable
    from callee text — treated as acceptable entropy noise.
  • M41 — http_routing. Server-side route registration on known router
    handles: Express/Koa/Fastify/Hono (TS/JS), net/http + Gin/Echo/Gorilla (Go),
    Flask/FastAPI add_url_rule (Python). Slot P7. Precedence note:
    app.get(...)/router.post(...) move from data_access to http_routing;
    client calls (axios.get, fetch) stay data_access.
  • M42 — testing. BDD globals, lifecycle hooks, expect(...), and the full
    Jest/Vitest helper set (TS/JS); testing.T methods (Go); unittest.TestCase
    assertions (Python). Slot P2. The bucket is empty when test paths are
    scope_excluded.
  • M43 — serialization. JSON.parse/stringify, structuredClone (TS/JS);
    json/pickle load/dump (Python); encoding/json Marshal/Unmarshal/encoder
    (Go). Slot P3. Bare .parse( is excluded (collides with schema validators).
  • M44 — concurrency. Go go_statement / select_statement, plus
    multi-future coordination calls — Promise.all/allSettled/race/any (TS/JS) and
    asyncio.gather/create_task/wait/as_completed/run (Python) at slot P11.
    promise.then/catch/finally chains stay in async_patterns.
  • M45.1 — resource_management enriched. Python with_statement, Go
    defer_statement, Java try_with_resources_statement. Pure node-kind; no new
    category.
  • M45.2 — error_handling enriched. Python except_clause (per arm), Java
    catch_clause (per arm), and throw_statement (per site). Pure node-kind.
    Double-count semantic: a try with 3 except arms yields 1
    try_statement + 3 except_clause = 4 instances (intentional — more arms =
    higher entropy signal).
  • M46 — comprehensions. Python list_comprehension, set_comprehension,
    dictionary_comprehension, and generator_expression. Nested comprehensions
    each emit their own node.
  • M47 — WASM consumer-surface typecheck guard (CI). The WASM workflow now
    tsc --noEmit-typechecks the published examples against the freshly generated
    .d.ts under strict settings, with a self-verifying negative fixture asserting
    that the previously-broken await init() and object-as-Map patterns fail to
    typecheck. Prevents the binding's documented usage from drifting from its types.

list_categories() now returns 19 entries:
async_patterns, class_hierarchy, collection_pipelines, comprehensions,
concurrency, data_access, decorators, error_handling, framework_hooks,
http_routing, logging, null_safety, resource_management,
schema_validation, serialization, state_management, state_store,
testing, type_assertions.

Impact on existing baselines

The category contract grows (additive), but the per-category instance counts and
entropy values shift materially on the first snapshot taken after upgrade:

  • Eleven categories transition from zero to non-zero on repos using the
    relevant idioms (count-introduction events). Per-language details and worked
    before/after examples are in MIGRATION_NOTES.md.
  • Two precedence reassignments move counts between existing buckets:
    useSelector/useDispatch/useStore (framework_hooksstate_store,
    M39) and app.get/router.post-style route registration (data_access
    http_routing, M41).
  • resource_management and error_handling counts grow on Python/Go/Java
    as the newly-routed node kinds enter their buckets (M45.1/M45.2).

Threshold gates (sdivi check) tuned against pre-M34 baseline numbers may trip
on the next snapshot. The escape hatch is unchanged: set
[thresholds.overrides.<category>] with an expires date inside your migration
window to defer recalibration until you have retuned. The M20 cross-architecture
threshold epsilon is far smaller than these instance-count shifts and will not
absorb them.

What did not change

  • snapshot_version is still "1.0". The PatternCatalog JSON shape,
    pattern_metrics field names, and DivergenceSummary structure are unchanged.
  • No new .sdivi/config.toml keys. [thresholds.overrides.<new-category>]
    blocks are legal under the existing category-agnostic override loader and the
    existing expires-required rule.
  • Public API is additive: the eleven new category names, the CALL_DISPATCH
    precedence registry, and the enriched node-kind routing. category_for_node_kind
    and classify_hint signatures are unchanged.
  • Foreign extractors that emit PatternInstanceInput directly are unaffected —
    their inputs determine their outputs.
  • WASM dependency invariant (Rule 21) holds: no tree-sitter/walkdir/ignore/
    rayon/tempfile in the sdivi-core wasm32 dependency tree.
  • Snapshot atomic-write, retention, exit-code, and determinism contracts
    unchanged. Same repo state + same seed still produces bit-identical output
    (a different bit-identical output than pre-M34).

Install

# crates.io
cargo install sdivi-cli

# pre-built binary (Linux x86_64 example)
curl -Lo sdivi https://github.com/GeoffGodwin/sdivi-rust/releases/download/v0.2.47/sdivi-x86_64-unknown-linux-gnu
chmod +x sdivi && mv sdivi ~/.local/bin/

# WASM / npm
npm install @geoffgodwin/sdivi-wasm@0.2.47

Documentation

Released under Apache 2.0.

Full Changelog: v0.2.23...v0.2.47

v0.2.23

30 May 03:30

Choose a tag to compare

sdivi-rust v0.2.23 — Three new pattern categories and callee-text classification

This release lands the M29–M33 milestone batch, which extends the pattern
measurement surface from five categories to eight and promotes classification
from node-kind-only to node-kind + callee-text. The headline additions are the
data_access, logging, and class_hierarchy categories, a new
classify_hint API that inspects the source text of a call to decide its
category, and the native-pipeline switchover that puts classify_hint behind
Pipeline::snapshot.

snapshot_version stays at "1.0". The category set, the pattern_metrics
field shapes, and the DivergenceSummary structure are all unchanged. What
changes is the per-category instance distribution on the next snapshot after
upgrade — see "Impact on existing baselines" below.

Highlights

  • M29 — data_access category. call_expression (TS/JS/Go) and call
    (Python) nodes are now bucketed under data_access. TS/JS/Go already
    collected these as PatternHints; Python's adapter gains "call" in its
    PATTERN_KINDS so every Python call now emits a hint.
  • M30 — logging category (catalog-only at introduction). Added to the
    contract so foreign extractors can emit category: "logging" and round-trip
    through compute_pattern_metrics/compute_delta. category_for_node_kind
    deliberately never returns it — the relevant node kinds overlap with
    data_access and resource_management, and only the callee name
    distinguishes them.
  • M31 — class_hierarchy category. A node-kind-routed category covering
    class_declaration / class_definition / abstract_class_declaration /
    interface_declaration / impl_item across TypeScript, JavaScript, Python,
    Rust, and Java. Go is skipped — it has no class/interface AST shape — so the
    category exists in the catalog but produces zero Go hits.
  • M32 — classify_hint(hint, language) -> Vec<&'static str>. The
    callee-text-aware classifier. Per-language regex tables on data_access,
    logging, and async_patterns (matches_callee) plus an inverted
    resource_management::excludes_callee for Rust macro disambiguation. Exposed
    through sdivi-core and the @geoffgodwin/sdivi-wasm WASM surface alongside
    a new WASM-safe PatternHintInput { node_kind, text } struct. The native
    pipeline is intentionally left on category_for_node_kind in M32 so this
    milestone ships pure-additive (no snapshot diff).
  • M33 — native pipeline switchover. crates/sdivi-patterns/src/catalog.rs
    now classifies hints via classify_hint. logging becomes natively
    populated, data_access narrows to actual data-access callees, TS/JS Promise
    chains (.then()/.catch()/.finally()) route to async_patterns, and Rust
    tracing::*!/log::*!/println!-family macros land in logging instead of
    resource_management. The multi-category return is honoured (a hint can land
    in more than one bucket); v0's per-language regex tables are disjoint so in
    practice each hint lands in at most one.

list_categories() now returns 8 entries:
async_patterns, class_hierarchy, data_access, error_handling,
logging, resource_management, state_management, type_assertions.

Impact on existing baselines

The category contract is unchanged, but the per-category instance counts and
entropy values shift on the first snapshot taken after upgrade:

  • data_access shrinks — only callees matching the per-language regex
    remain; structurally homogeneous non-data calls are dropped.
  • logging becomes non-zero on languages with a logging regex table
    (was catalog-only since M30).
  • async_patterns grows on TS/JS — Promise chains are now counted.
  • resource_management shrinks on Rust — logging macros leave the bucket.

Threshold gates (sdivi check) tuned against pre-M33 baseline numbers may trip
on the next snapshot. The escape hatch is unchanged: set
[thresholds.overrides.<category>] with an expires date inside your migration
window to defer recalibration until you have retuned. The M20 cross-architecture
threshold epsilon is far smaller than these instance-count shifts and will not
absorb them. A side-by-side pre/post worked example is in MIGRATION_NOTES.md.

What did not change

  • snapshot_version is still "1.0". The PatternCatalog JSON shape,
    pattern_metrics field names, and DivergenceSummary structure are
    unchanged.
  • No new .sdivi/config.toml keys. [thresholds.overrides.<new-category>]
    blocks are legal under the existing category-agnostic override loader and the
    existing expires-required rule.
  • Public API is additive: classify_hint, PatternHintInput, the per-category
    matches_callee/excludes_callee helpers, and the three new category names.
    category_for_node_kind is unchanged and preserved for callers that have a
    node kind but no source text.
  • Foreign extractors that emit PatternInstanceInput directly are unaffected —
    their inputs determine their outputs.
  • WASM dependency invariant (Rule 21) holds: regex is the only new entry in
    the sdivi-core wasm32 dependency tree; no tree-sitter/walkdir/ignore/
    rayon/tempfile.
  • Snapshot atomic-write, retention, exit-code, and determinism contracts
    unchanged. Same repo state + same seed still produces bit-identical output
    (a different bit-identical output than pre-M33).

Install

# crates.io
cargo install sdivi-cli

# pre-built binary (Linux x86_64 example)
curl -Lo sdivi https://github.com/GeoffGodwin/sdivi-rust/releases/download/v0.2.23/sdivi-x86_64-unknown-linux-gnu
chmod +x sdivi && mv sdivi ~/.local/bin/

# WASM / npm
npm install @geoffgodwin/sdivi-wasm@0.2.23

Documentation

Released under Apache 2.0.

v0.2.18 — sdivi-rust v0.2.18 — Leiden no longer hangs on large sparse graphs

08 May 14:26
796c519

Choose a tag to compare

sdivi-rust v0.2.18 — Leiden no longer hangs on large sparse graphs

This release lands M28: two performance fixes to the recursive Leiden
implementation in sdivi-detection. Before M28, Pipeline::snapshot could
hang for minutes-to-hours on large sparse weakly-connected graphs (e.g. an
MFE shell with ~1800 files and ~700 import edges) because (1) every call to
refine_community allocated state for the entire graph regardless of how
few nodes were in the coarse community being refined, and (2) recursion
only stopped when an aggregation level produced literally zero merges, so
graphs that compressed by 1–3% per level recursed dozens of times paying
the full setup cost at each level.

After this release, refinement is O(|members| + induced_edges) per
coarse community, recursion stops once compression falls below a
configurable ratio, and a hard recursion-depth cap provides a
belt-and-suspenders safeguard. Snapshots that previously took minutes
complete in seconds.

snapshot_version stays at "1.0". No CLI flag, exit code, or existing
.sdivi/config.toml key changed.

Highlights

  • M28 — Induced-subgraph refinement and recursion cutoff.
    • LeidenGraph::induced_subgraph(members) builds a per-community
      subgraph in O(|members| + induced_edges). refine_community uses
      it instead of walking the full graph on every call.
    • The recursive Leiden driver now exits early when an aggregation
      level would compress the graph by less than
      boundaries.leiden_min_compression_ratio (default 0.1).
    • A hard cap at boundaries.leiden_max_recursion_depth (default 32,
      enough for ~4 billion nodes) guards against pathological inputs.
    • Modularity quality stays inside the existing verify-leiden 1%
      tolerance band. Snapshot determinism is preserved bit-for-bit on the
      same repo state with the same seed.
  • New [boundaries] config keys (additive, both optional):
    • leiden_min_compression_ratio: f64 (default 0.1, range [0.0, 1.0)).
    • leiden_max_recursion_depth: u32 (default 32, must be >= 1).
    • Out-of-range values produce ConfigError::InvalidValue (CLI exit 2).
  • LeidenConfig / LeidenConfigInput gain matching fields so the
    pure-compute (sdivi-core) and WASM callers can tune the cutoffs
    without going through .sdivi/config.toml. WasmLeidenConfigInput
    exposes min_compression_ratio?: number and
    max_recursion_depth?: number to TypeScript.
  • WASM edge-weight hardening. parse_wasm_edge_weights now rejects
    f64::INFINITY and f64::NEG_INFINITY in the same guard as NaN,
    closing a non-blocking finding from the M27 review. Two regression
    tests guard the boundary.

Impact on existing baselines

Modularity values for snapshots taken post-M28 may differ by up to ~1%
from snapshots taken pre-M28 on the same repo state. This is within the
existing verify-leiden 1% tolerance band — the algorithm is
mathematically equivalent; the numerical difference stems from the new
compression-ratio cutoff stopping recursion a level earlier on sparse
graphs. Trend analyses that span the M28 cutover should treat it as a
baseline reset for modularity-sensitive metrics.

coupling_delta, community_count_delta, and boundary_violation_rate
on the same snapshots are unaffected.

What did not change

  • snapshot_version is still "1.0". v0.2.16 snapshots load and diff
    cleanly under v0.2.18.
  • LeidenPartition JSON shape is unchanged. BoundarySpec YAML
    untouched.
  • Public API is additive only: existing callers that omit the new
    LeidenConfigInput / WasmLeidenConfigInput fields receive the
    defaults (0.1 and 32) and behave identically to pre-M28 except
    for the early-exit behaviour described above.
  • Snapshot atomic-write, retention, and exit-code contracts unchanged.
  • Tree-sitter grammars, language adapters, and import resolution are
    untouched.

Install

# crates.io
cargo install sdivi-cli

# pre-built binary (Linux x86_64 example)
curl -Lo sdivi https://github.com/GeoffGodwin/sdivi-rust/releases/download/v0.2.18/sdivi-x86_64-unknown-linux-gnu
chmod +x sdivi && mv sdivi ~/.local/bin/

# WASM / npm
npm install @geoffgodwin/sdivi-wasm@0.2.18

Documentation

Released under Apache 2.0.

What's Changed

Full Changelog: v0.2.16...v0.2.18

v0.2.16 — sdivi-rust v0.2.16 — TS/JS/Python/Go/Java edges actually count

05 May 13:40

Choose a tag to compare

sdivi-rust v0.2.16 — TS/JS/Python/Go/Java edges actually count

This release lands the three-milestone fix for cross-file edge detection in
non-Rust languages. Before v0.2.14, adapters for Python, TypeScript,
JavaScript, Go, and Java pushed whole import-statement text into
FeatureRecord::imports, which dependency_graph::resolve_import silently
dropped. modularity, community_count, and boundary_violation_rate
were therefore computed against a graph with almost no edges and reported
near-zero divergence regardless of what the code did.

After this release, the import graph reflects the actual import graph for
all six supported languages.

snapshot_version stays at "1.0". No CLI flag, exit code, or
.sdivi/config.toml key changed.

Highlights

  • M25 — Adapter extract_imports rewrite. Python, TypeScript,
    JavaScript, Go, and Java adapters now emit bare module specifiers
    (e.g. "./utils", "foo.bar", "github.com/acme/lib") rather than
    whole-statement text. truncate_to_256_bytes and string_content
    consolidated into sdivi-parsing::text (eliminates five-way
    duplication previously flagged in the drift log).
  • M26 — Resolver parent navigation + per-language module conventions.
    dependency_graph::resolve_import now walks parent directories for
    ../ and super:: instead of stripping prefix characters; gained
    per-language dispatch:
    • Python bare dotted specifiers (foo.bar) resolve as path lookups.
    • Go module-path imports resolve via the go.mod module prefix
      (auto-detected by the pipeline).
    • Java dotted imports resolve via standard Maven source roots plus
      auto-discovered module roots; wildcards (com.acme.lib.*) emit one
      edge per class file.
    • New API: build_dependency_graph_with_go_module(records, go_module)
      so WASM / non-pipeline callers can supply the Go module prefix
      without filesystem access.
  • M27 — tsconfig path alias support. TypeScript and JavaScript
    adapters resolve compilerOptions.paths aliases declared in
    tsconfig.json / jsconfig.json. Aliases that point to non-existent
    targets are dropped without warning; standard relative and bare imports
    are unaffected.
  • Non-blocking-note sweep. Six open items in
    .tekhton/NON_BLOCKING_LOG.md resolved or dispositioned: dynamic-import
    docstring softened in crates/sdivi-lang-javascript/src/extract.rs:32
    to match the test's grammar-version-dependent intent; remaining notes
    closed with carry-forward justifications.

Impact on existing baselines

The first snapshot taken on a Python, TypeScript, JavaScript, Go, or Java
project after upgrading from ≤ v0.2.13 will show a large coupling_delta
and community_count_delta against the prior baseline. This is a
correctness fix, not a schema change.

Recommended actions:

  • Re-baseline at the M25+M26 boundary, or
  • Apply a one-time per-category threshold override with expires set
    1–2 weeks out to absorb the cutover. See MIGRATION_NOTES.md for the
    exact override block.

Rust-only projects are unaffected; Rust import resolution did not change.

What did not change

  • snapshot_version is still "1.0". v0.2.13 snapshots load and diff
    cleanly under v0.2.16.
  • Public API additions only: build_dependency_graph_with_go_module is
    additive; the existing build_dependency_graph(records) continues to
    work and dispatches with go_module = None.
  • WASM TypeScript types remain tsify-derived from the same Rust types.
    Existing JS/TS callers using WasmAssembleSnapshotInput need no
    changes.
  • Snapshot atomic-write, retention, and exit-code contracts unchanged.

Install

# crates.io
cargo install sdivi-cli

# pre-built binary (Linux x86_64 example)
curl -Lo sdivi https://github.com/GeoffGodwin/sdivi-rust/releases/download/v0.2.16/sdivi-x86_64-unknown-linux-gnu
chmod +x sdivi && mv sdivi ~/.local/bin/

# WASM / npm
npm install @geoffgodwin/sdivi-wasm@0.2.16

Documentation

Released under Apache 2.0.

What's Changed

Full Changelog: v0.2.13...v0.2.16

v0.2.13

04 May 19:08

Choose a tag to compare

Full Changelog: v0.2.12...v0.2.13

v0.2.12

04 May 17:48

Choose a tag to compare

Full Changelog: v0.2.11...v0.2.12

v0.2.11

04 May 17:23

Choose a tag to compare

Full Changelog: v0.2.10...v0.2.11