diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5334e26..a2bf17e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
* `color_mode` is replaced by `clustering` (`color-cluster` | `bw` | `watershed`) across the CLI (`--clustering`), Rust (`Config::clustering`, enum `Clustering`), Python, and Node — the field selects the region-forming algorithm, not a color space.
+### Fixed
+
+* Spline fitting no longer swings far away from the outline around thin strands (a long-standing defect, via visioncortex 0.9.1): a sparse splice slice — a few-pixel jog followed by a long straight leg — could be fitted by a single cubic that interpolated every sample while ballooning up to ~30 px sideways between them, visibly crossing narrow gaps. Slices are now densified before fitting and multi-cubic fits are kept in full, in both stacked mode and the mosaic's shared-boundary fitter.
+
## 1.0.0-alpha.1 - 2026-07-24
Ground-up rewrite of VTracer into a **vectorization framework** with pluggable stages.
diff --git a/Cargo.toml b/Cargo.toml
index 726d629..4188256 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -26,7 +26,4 @@ homepage = "http://www.visioncortex.org/vtracer"
repository = "https://github.com/visioncortex/vtracer/"
[workspace.dependencies]
-visioncortex = "0.9"
-# For local development against an unreleased visioncortex, add a patch:
-# [patch.crates-io]
-# visioncortex = { path = "../visioncortex" }
+visioncortex = "0.9.1"
diff --git a/crates/vtracer/Cargo.toml b/crates/vtracer/Cargo.toml
index c1819b5..14d66d4 100644
--- a/crates/vtracer/Cargo.toml
+++ b/crates/vtracer/Cargo.toml
@@ -22,3 +22,5 @@ visioncortex.workspace = true
# Rasterize-and-diff equivalence tests (stacked vs mosaic). Test-only; not
# compiled for wasm targets, so the library stays wasm-safe.
resvg = "0.45"
+# Decode the sample photo for the spline-fitting regression test. Test-only.
+image = { version = "0.25", default-features = false, features = ["jpeg"] }
diff --git a/crates/vtracer/src/mosaic/fit.rs b/crates/vtracer/src/mosaic/fit.rs
index 56fe335..13b21ef 100644
--- a/crates/vtracer/src/mosaic/fit.rs
+++ b/crates/vtracer/src/mosaic/fit.rs
@@ -98,7 +98,7 @@ impl SegmentFitter for PolygonSegmentFitter {
/// gapless. A distance-based DP can't do this: near the √2/2 threshold it
/// can't separate staircase noise from real curvature. Smoothing and per-slice
/// cubic fitting then reuse the same visioncortex machinery stacked mode uses
-/// (open-path variants of the smoothing primitives + `fit_points_with_bezier`),
+/// (open-path variants of the smoothing primitives + `fit_points_with_beziers`),
/// so the curve character matches stacked.
#[derive(Debug, Clone)]
pub struct SplineSegmentFitter {
@@ -146,14 +146,15 @@ fn straight_cubic(a: PointF64, b: PointF64) -> [PointF64; 4] {
/// uses in `Spline::from_path_f64`, so mosaic curves have the same character.
const FIT_ERROR: f64 = 10.0;
-/// Fit one splice slice into a single cubic, exactly as stacked mode does
-/// (`fit_points_with_bezier`: one retract-handled cubic per slice, endpoints
-/// pinned to the slice ends).
+/// Fit one splice slice, exactly as stacked mode does
+/// (`fit_points_with_beziers`: the full retract-handled cubic chain per slice,
+/// outer endpoints pinned to the slice ends — a sparse or multi-curve slice is
+/// kept faithful instead of being collapsed onto one ballooning cubic).
fn fit_slice(slice: &[PointF64], out: &mut Vec<[PointF64; 4]>) {
match slice.len() {
0 | 1 => {}
2 => out.push(straight_cubic(slice[0], slice[1])),
- _ => out.push(SubdivideSmooth::fit_points_with_bezier(slice, FIT_ERROR)),
+ _ => out.extend(SubdivideSmooth::fit_points_with_beziers(slice, FIT_ERROR)),
}
}
diff --git a/crates/vtracer/tests/goldens/bands_palette.svg b/crates/vtracer/tests/goldens/bands_palette.svg
index dd12864..ac9301f 100644
--- a/crates/vtracer/tests/goldens/bands_palette.svg
+++ b/crates/vtracer/tests/goldens/bands_palette.svg
@@ -1,7 +1,7 @@
diff --git a/crates/vtracer/tests/goldens/bands_spline.svg b/crates/vtracer/tests/goldens/bands_spline.svg
index 5b12122..0e35e32 100644
--- a/crates/vtracer/tests/goldens/bands_spline.svg
+++ b/crates/vtracer/tests/goldens/bands_spline.svg
@@ -1,8 +1,8 @@
diff --git a/crates/vtracer/tests/goldens/checker_mosaic_polygon.svg b/crates/vtracer/tests/goldens/checker_mosaic_polygon.svg
index 03e70ed..75873ab 100644
--- a/crates/vtracer/tests/goldens/checker_mosaic_polygon.svg
+++ b/crates/vtracer/tests/goldens/checker_mosaic_polygon.svg
@@ -1,52 +1,50 @@
diff --git a/crates/vtracer/tests/goldens/checker_spline.svg b/crates/vtracer/tests/goldens/checker_spline.svg
index 475e174..900c1cc 100644
--- a/crates/vtracer/tests/goldens/checker_spline.svg
+++ b/crates/vtracer/tests/goldens/checker_spline.svg
@@ -1,7 +1,7 @@