Repository navigation
Releases: kaivyy/meshium
Release list
v1.5.0-beta.9 — real database dump/restore
Real database migration (dump → restore)
The database category now moves actual DB data, not just server metadata. Supports PostgreSQL, MySQL/MariaDB, MongoDB, and Redis via a pluggable per-engine adapter.
Pre-release / beta — not production-ready. Downtime = transfer time (dump/restore only; live replication + cutover is Phase 2, deferred).
Added
databasemigration category — real dump/restore for PostgreSQL, MySQL/MariaDB, MongoDB, Redis.- Pluggable per-engine adapter (
DatabaseMigrator) with idempotent restore flags (PG--clean --if-exists, MySQL--add-drop-database, Mongo--drop, Redis RDB replace). - Streamed transfer, no temp file on meshium: MySQL/Mongo pipe
dump|restoreover SSH; PG/Redis use the SFTP file path honestly. - Optional
StreamExecuter/WriteExecuterSSH interfaces — kept off the coreSSHExecuterso ~9 test mocks stay green;DatabaseApplierfalls back to the file path. - Database config block in the wizard (engine/host/port/user/pass/db-name).
- Design doc + live verification guide.
Fixed
- Fresh plan now lands on Discovery (step 0) instead of getting stuck at Compatibility with Next disabled.
- Deleting the last migration row resets the ID counter so the next plan starts from 1 again.
Security
- DB credentials encrypted at rest (same scheme as server SSH passwords); redacted in API; never in step data or logs.
- Injection-safe commands (
ShellQuote,pqIdent/backtickIdent,sqlEscapeSingleQuotes).
Full changelog: see CHANGELOG.md.
v1.5.0-beta.8 — plan-step elapsed timer
[1.5.0-beta.8] — 2026-07-10
UX polish on the create-migration wizard. It is still a pre-release / beta
— not production-ready or enterprise-grade, and no such claim is made.
Added
- Elapsed timer on the wizard Plan step. Step 4 (Review & Create Plan)
showed only a bare "Planning..." spinner while the source-server collection
ran, so a long scan looked like a hang. It now shows amm:sselapsed timer
alongside the spinner, started on "Create Plan" and stopped on
complete/close/error. Not persisted — the create wizard resets on refresh, so
cross-reload doesn't apply (web/src/routes/migrations/new/+page.svelte).
v1.5.0-beta.7 — DB bloat fix, FK cascade, plan recovery
[1.5.0-beta.7] — 2026-07-10
DB bloat + plan-recovery robustness. This release stops the database from
ballooning ~100MB per plan, fixes the root cause that left orphaned rows after
a migration was deleted, and makes interrupted/stale plans surface honestly
instead of stalling or silently dropping the user back. It is still a
pre-release / beta — not production-ready or enterprise-grade, and no such
claim is made.
Fixed — 535MB database bloat
- Config file size capped per file.
ConfigsCollectortarred the whole
/etcwith no per-file limit, so logs, caches, and state DBs in/etc
wrote ~105MB into a singlemigration_stepsrow per plan — 535MB across
five plans. Thefindnow caps at-size -2MandparseTarArchiveskips
any file over 1MiB (maxConfigFileSize), discarding the body so the tar
reader stays aligned. Real config files are well under 1MiB
(internal/mod/migration/configs.go). - Foreign-key cascade now fires on every pool connection (root cause of
orphaned rows).DeleteMigrationrelies onON DELETE CASCADEto clean
upmigration_steps, butPRAGMA foreign_keys = ONwas set via a post-Open
db.Exec— which only configures one connection in the pool, since pragmas
are per-connection, not per-database. Deletes that landed on a FK-off
connection silently skipped the cascade and left orphanedmigration_steps
rows behind (the actual source of the bloat recurring). All pragmas now live
in the DSN via_pragma=…query params, so every connection the driver opens
inherits them. A regression test (TestCascadeDeleteAcrossPool) pins
cascade across multiple pool connections (internal/db/db.go).
Fixed — interrupted / stale / partial plans
- Plan step no longer stalls on root-FS docker-compose scan. The plan step
could hang scanning the root filesystem fordocker-composefiles. The scan
is now bounded so it can't stall the step. - Interrupted plans marked honestly + partial/stale surfaced. Plans
interrupted mid-run are marked with their real state instead of being left
in a misleading in-between state, and partial/stale plans are surfaced to
the user rather than hidden.buildSessiondetects when collected
categories don't cover every requested category and sets an honest error
that drives an incomplete-plan banner. - Unbound SFTP downloads bounded. SFTP downloads had no timeout and could
hang indefinitely. Each download now runs under a FileTransfer timeout in a
goroutine that closes the SFTP file on expiry (ssh/client.go).
Fixed — plan progress + planned-state recovery
- Plan progress streamed per category. Plan collection progress is now
streamed per category over the WebSocket and the collected steps are
persisted, instead of a bare spinner with no indication of how far along
collection is (internal/mod/migration/planner.go). - Compatibility preflight survives a mid-check refresh. The preflight's
context was derived fromr.Context(), so a page refresh mid-check closed
the WebSocket, cancelled the context, and dropped the in-flight work —
landing the user back at Discovery on reload. The preflight now runs under a
background context bounded only by a 5-minute timeout; the WebSocket write
becomes a no-op once the connection is gone, and the results still persist
for the nextloadSession(pipeline_handler.go). - Planned migration recovers to the right step.
recoverStepFromStatehad
no case forcreated(the state-machine name for aplannedmigration,
StatusPlanned ↔ StateCreated), so a freshly planned migration fell through
with no step set and the Next button stayed disabled until the user clicked
rollback.creatednow recovers to step 0 alongsidediscovery/planning. - Rollback button gated to post-apply states. The rollback button showed
for every non-terminal state includingcreated, producing an invalid
created → rollbacktransition. It now requirescurrentStep >= 6
(rollbackAvailable), so it only appears once the pipeline has reached the
apply phase.
v1.5.0-beta.4 (migration-correctness beta)
Meshium v1.5.0-beta.4
Pre-release / beta — migration-correctness candidate. Not a stable release.
Fourth beta on the v1.5.0 line. This is a migration-correctness release: it
does not add migration features. It makes the migration paths stop claiming or
reporting work the live pipeline did not actually perform, and fails closed on
operations that cannot be verified as safe. Every change is a safety or honesty
fix grounded in the Migration Functional Audit.
Meshium is still not production-ready or enterprise-grade at this tag, and
this release makes no such claim. The migration paths are safer and more honest
here — not complete.
Why this release exists
An audit of the migration paths found several places where the code reported
success for work it had not performed, or continued past an operation it could
not verify as safe:
- a traffic-switch cutover that could record success without switching;
- replication lag measurements that returned "caught up" on their error paths,
which could promote a target on un-replicated data; - a MongoDB cutover that reconfigured the live source's replica set before an
inevitable abort; - an "initial sync" stage whose name implied an rsync file transfer it does not
do; - Docker image-pull failures silently downgraded to warnings while the migration
still reported success; - a missing step handler that crashed the process with a nil dereference.
This release addresses each of these by doing the safe thing or refusing with a
clear error, and by making the capability descriptions match what the code
actually does.
What changed since v1.5.0-beta.3
False-success and crash safety
- Traffic switch no longer reports a success it did not achieve. The cutover
traffic-switch path could record a successful switch even when the switch was
not performed. (internal/mod/migration) - Missing step handlers no longer crash the migration. A pipeline step with
no registered handler dereferenced a nil handler and took the process down with
a SIGSEGV; missing handlers are now guarded and surfaced as an error.
Fail closed on unverifiable operations
- Unknown distributions no longer fall back to
apt. An unrecognized source
distro (e.g. Amazon Linux) previously fell through to a Debian-orientedapt
path; the package path now refuses an unknown distro rather than running an
unsafe fallback. - Alpine service migration is gated without OpenRC support. systemd-oriented
service migration is no longer issued against an Alpine/OpenRC host that does
not usesystemctl. - Replication lag paths fail closed. PostgreSQL, MongoDB, and Redis lag
measurements returned0("caught up") on error paths, which could let a
cutover promote on un-replicated data. They now return-1plus an error, and
WaitForCatchUppropagates that error instead of treating a failed measurement
as caught-up. (internal/mod/migration/replication.go) - MongoDB replication cutover is refused up front. There is no real
replica-set lag measurement, so catch-up cannot be verified before promotion.
setupMongoDBnow fails closed before issuingrs.add(), so a cutover that
cannot complete safely never reconfigures the live source's replica set.
Truthful capability reporting
- "Initial sync" stage describes what it actually does. It does not perform a
file-level rsync; it replays the data collected during the collect phase via
each category'sApplier.Apply. The stage name, progress messages, and
comments now say so, and the unusedSyncEngine/InitialSyncpath is
documented as not driven by the live pipeline. (internal/mod/migration/pipeline.go) - Docker image migration documented as registry-only. Image transfer is
docker pullonly; images built locally and never pushed to a reachable
registry cannot be migrated. Pull failures are now counted and reflected in the
completion summary instead of being silently downgraded while success is still
reported. (internal/mod/migration/docker.go,dryrun.go) - Assisted-cutover limitations clarified in the documentation — no implication
of a fully automated zero-downtime cutover where the path is assisted/manual.
Architecture & validation documentation
- Migration orchestrator consolidation plan (
docs/orchestrator-consolidation.md)
records that three orchestrators (Job EngineEngine,Executor/
CompositeRunner, and thePipeline) each drive their own
backup→apply→rollback loop, why that divergence is a correctness risk, and the
decision to designate the Pipeline as the single go-forward path with guard
rails while the others are frozen. - Migration validation matrix and non-destructive scripts
(docs/validation/migration-matrix.md,scripts/validate-fresh-clone.sh,
scripts/validate-migration-lab.sh) — a manual E2E test matrix, a local mirror
of CI's fresh-clone build guard, and a lab bring-up/health-check script. Both
scripts are non-destructive and never trigger a migration themselves
(migrations remain UI/API-driven).
CI
- Fresh-clone build guard — CI builds and tests from a
git archiveofHEAD
(tracked files only) and fails if a tracked source file is swallowed by a
.gitignorerule — the regression that broke the beta.1/beta.2 tags.
Known limitations
- MongoDB replication cutover is unsupported — refused until real replica-set
lag measurement is implemented. - Locally-built Docker images cannot be migrated — image transfer is
registry-pull only; only images present in a registry the target can reach
migrate. - Three migration orchestrators still coexist — consolidation onto the
Pipeline is planned (seedocs/orchestrator-consolidation.md), not yet
performed. A fix to one apply loop does not automatically propagate to the
others. - "Initial sync" is a data replay, not a file-level rsync — the
SyncEngine
is not driven by the live pipeline. - All limitations carried from v1.5.0-beta.3 still apply (pipeline path not
instrumented for observability,Engine.Resumenot instrumented,
staticcheck/govulncheck advisory backlog, bounded idempotency, no SBOM / build
provenance / signing).
Validation checklist (run before trusting a real migration)
-
make buildsucceeds from a fresh clone (builds frontend, then Go), or
runscripts/validate-fresh-clone.sh. -
go build ./...succeeds (after the frontend has been built once). -
go test ./...passes. -
go test -race ./...passes. -
go vet ./...is clean. -
npm run check(svelte-check) is clean andnpm run buildsucceeds. - Manual migration validation matrix on your own hosts — see
docs/validation/migration-matrix.md— across your source→target distro
pair, plus at least one interrupt-and-resume cycle and one rollback.
Upgrade notes
- No schema migration is required by this release.
- No breaking API changes versus v1.5.0-beta.3; no WebSocket or REST contract
consumed by the frontend changed. - Behavior change to be aware of: operations that previously reported success and
continued (unverifiable replication catch-up, MongoDB cutover, unknown-distro
package install, Alpine service migration) now fail closed with a clear error.
This is intentional — a refusal replaces a false success.
Follow-up before a stable release
- Execute the orchestrator consolidation plan: extract a shared
backup→apply→rollback core and route the Executor and Job Engine paths onto it. - Implement real MongoDB replica-set lag measurement, then re-enable the MongoDB
cutover path. - Instrument the pipeline path and
Engine.Resumefor observability. - Clear or explicitly suppress the staticcheck backlog, then promote staticcheck
to a blocking CI gate. - Add SBOM generation and build provenance/signing.
v1.5.0-beta.3 — fresh-clone build fix
Meshium v1.5.0-beta.3
Pre-release / beta — hardening candidate. Not a stable release.
Third beta on the v1.5.0 line. This is a build-fix release: it makes the
tagged source compile from a fresh clone. It carries the same features as
v1.5.0-beta.2 (proxy-aware WebSocket origin check, registered SSH key-management
routes, and the light/dark/system frontend redesign) — nothing new was added.
Meshium is still not production-ready or enterprise-grade at this tag, and
this release makes no such claim.
Why this release exists
v1.5.0-beta.1 and v1.5.0-beta.2 do not build from a fresh clone. Two source
files under internal/mod/server/ were silently excluded from every commit by
an over-broad .gitignore rule, so the tagged trees are missing the
implementation of several sqliteRepo methods. A clean checkout of either tag
fails to compile:
internal/mod/server/repo.go: *sqliteRepo does not implement Repo
(missing method CreateConnectionProfile)
The local development tree always compiled because the files exist on disk —
they just never reached git. This tag fixes that.
What changed since v1.5.0-beta.2
Fresh-clone build fix (the whole point of this release)
.gitignorebinary patterns anchored to the repo root. The bareserver
pattern (intended for the compiled root binary) also matched the
internal/mod/server/package directory, so any new file created there was
ignored.server,bin/, andmeshium-serverare now anchored (/server,
/bin/,/meshium-server) so they only match root-level build artifacts and
never a package directory.- Missing server source files are now tracked.
internal/mod/server/repo_enterprise.go— thesqliteRepoimplementation
ofCreateConnectionProfileand 23 other server-key / connection-profile /
known-host / credential-audit / SSH-agent methods required by theRepo
interface.internal/mod/server/socket_test.go— its accompanying test file.
- README build/test instructions corrected. The docs now state that
cmd/server/web/buildis generated (not committed), thatmake buildbuilds
the frontend before compiling Go, and that a rawgo build ./.../
go test ./...requires the embedded frontend to have been built once
(otherwise it fails withpattern all:web/build: no matching files found).
Features carried over from v1.5.0-beta.2 (unchanged)
Connection fixes
- Proxy-aware WebSocket origin check — WebSocket upgrades no longer return
403 Forbiddenbehind a reverse proxy; the origin hostname is compared against
bothr.Hostand a trustedX-Forwarded-Host, and genuine cross-origin
requests are still rejected. All 7 WebSocket upgraders share the single check. - SSH key-management routes registered —
/api/servers/{id}/test-authand 7
sibling routes no longer return404 NOT_FOUND.
Frontend redesign (light / dark / system)
- Semantic CSS-variable token system; light/dark/system theme toggle; shared UI
primitives restyled on the token layer; all pages swept onto the token system
with layouts preserved; WCAG-oriented tap-target andfocus-visiblehandling.
Inherited from v1.5.0-beta.1
- Concurrency and shutdown correctness across both migration paths (Job Engine
and Pipeline); startup recovery for interrupted migrations. - Fail-closed SSH host-key handling on the credentialed connect paths
(including the AI assistant path). - Idempotent traffic-switch cutover record.
- Pipeline registry + bounded
GracefulDrainon shutdown; resources closed
strictly after graceful shutdown completes. - State-machine engine
Runemits lifecycle observability events. - Honest, code-grounded capability descriptors (Driver SDK, planner strategy
selection, observability seam) with maturity labels rather than overstated
claims. - CI runs vet,
-race, staticcheck, and govulncheck (staticcheck/govulncheck
advisory until the backlog is cleared).
Known limitations
- v1.5.0-beta.1 and v1.5.0-beta.2 tags are non-building — use this tag or
later. The earlier tags are left in place for history but should not be cloned. - Pipeline path is not instrumented for observability — obs events are
emitted from the state-machine engine'sRunonly. Engine.Resumeis not instrumented — no observability events on resume.- Static-analysis backlog — advisory staticcheck findings remain
(unused-symbol backlog and a handful of style findings); non-blocking. - Some future API is intentionally unused — extension points and strategy
descriptors are declared ahead of being wired; deliberate, not dead code. - Full idempotency is not guaranteed for every step — recovery is bounded
by checkpointing; work applied but not yet checkpointed before a crash may be
re-attempted. - Real DNS/LB cutover depends on the available strategy — only implemented
strategies execute; descriptor/future strategies are not orchestrated. - Credential-less SSH wizard probe — the connection wizard's initial probe
dials with host-key verification disabled to read the server banner and
algorithms only; it sends no credentials. Credentialed connect paths (wizard
and AI assistant) fail closed. - Enterprise-grade features are incomplete — no SBOM, no build provenance /
signing.
Validation checklist (run before trusting a real migration)
-
make buildsucceeds from a fresh clone (builds frontend, then Go). -
go build ./...succeeds (after the frontend has been built once). -
go test ./...passes. -
go test -race ./...passes (CI race job runs the full suite unbounded). -
go vet ./...is clean. -
npm run check(svelte-check) is clean andnpm run buildsucceeds. - Manual migration validation matrix on your own hosts:
packages / configs / services / users / docker across your source→target
distro pair, plus at least one interrupt-and-resume cycle and one rollback.
Upgrade notes
- No schema migration is required by this release.
- No breaking API changes versus v1.4.x / earlier v1.5.0 betas in the committed
set. - If you cloned v1.5.0-beta.1 or v1.5.0-beta.2 and could not build, this tag is
the fix — no code changes to features, only the missing files and ignore rule.
Follow-up before a stable release
- Add a CI job that builds and tests from a clean checkout (not the dev
tree) so a missing-tracked-file regression fails the pipeline, not the user. - Instrument the pipeline path and
Engine.Resumefor observability. - Review the no-credential SSH wizard probe and decide whether to keep it as-is,
document it explicitly, or add optional key capture/compare behavior. - Clear or explicitly suppress the staticcheck backlog, then promote staticcheck
to a blocking CI gate. - Extend idempotency guarantees across all pipeline stages.
- Add SBOM generation and build provenance/signing.
v1.5.0-beta.2 — frontend redesign + connection fixes
⚠️ Superseded by v1.5.0-beta.3. This prerelease has a fresh-clone build issue caused by ignored source files. Use v1.5.0-beta.3 or newer.
Meshium v1.5.0-beta.2
Pre-release / beta — hardening candidate. Not a stable release.
Second beta on the v1.5.0 line. It builds on v1.5.0-beta.1 by fixing two
connection-breaking backend bugs and landing a full frontend redesign. It is
still not recommended for production migrations without a manual validation
pass on your own source/target pair (see the Validation Checklist below).
Meshium is not production-ready or enterprise-grade at this tag, and this
release makes no such claim.
What's new since v1.5.0-beta.1
Connection fixes
- WebSocket origin check is now proxy-aware. WebSocket upgrades were
rejected with403 Forbiddenwhenever Meshium was reached through a reverse
proxy (Tailscale serve, nginx) on a public hostname — the origin check
compared the browser'sOriginagainst the internalHost, so Test
Connection / Terminal / Monitoring failed while plain REST kept working. The
origin hostname is now compared against bothr.Hostand a trusted
X-Forwarded-Host; genuine cross-origin requests are still rejected. All 7
WebSocket upgraders were consolidated onto the single shared check (several
previously had no origin protection at all). - SSH key-management routes are now registered.
/api/servers/{id}/test-auth
and 7 sibling routes (install-key,verify-key,rotate-key,clear-key,
auth-status,history,metrics) returned404 NOT_FOUNDbecause the key
handler was never wired into the router. It is now constructed and registered.
Frontend redesign (light / dark / system)
- Semantic CSS-variable token system — colors, surfaces, borders, and
accents are driven by semantic tokens defined once and themed per mode,
replacing hard-coded palette values scattered across pages. - Light / dark / system theme toggle — a persisted theme store with a
three-state top-bar toggle (light / dark / follow-system). - Shared UI primitives restyled on the token layer — Button, Card,
DataTable, DropdownMenu, plus card shadows and focus states. - All pages swept onto the token system — existing page layouts were
preserved; only the styling layer changed. - WCAG-oriented touches — 44px minimum tap targets on mobile and global
focus-visiblehandling; server-detail tab row and mobile terminal overflow
fixes.
Inherited from v1.5.0-beta.1
- Concurrency and shutdown correctness across both migration paths (Job Engine
and Pipeline); startup recovery for interrupted migrations. - Fail-closed SSH host-key handling on the credentialed connect paths
(including the AI assistant path). - Idempotent traffic-switch cutover record.
- Pipeline registry + bounded
GracefulDrainon shutdown; resources closed
strictly after graceful shutdown completes. - State-machine engine
Runemits lifecycle observability events. - Honest, code-grounded capability descriptors (Driver SDK, planner strategy
selection, observability seam) with maturity labels rather than overstated
claims. - CI runs vet,
-race, staticcheck, and govulncheck (staticcheck/govulncheck
advisory until the backlog is cleared).
Known limitations
- Pipeline path is not instrumented for observability — obs events are
emitted from the state-machine engine'sRunonly. Engine.Resumeis not instrumented — no observability events on resume.- Static-analysis backlog — advisory staticcheck findings remain
(unused-symbol backlog and a handful of style findings); non-blocking. - Some future API is intentionally unused — extension points and strategy
descriptors are declared ahead of being wired; deliberate, not dead code. - Full idempotency is not guaranteed for every step — recovery is bounded
by checkpointing; work applied but not yet checkpointed before a crash may be
re-attempted. - Real DNS/LB cutover depends on the available strategy — only implemented
strategies execute; descriptor/future strategies are not orchestrated. - Credential-less SSH wizard probe — the connection wizard's initial probe
dials with host-key verification disabled to read the server banner and
algorithms only; it sends no credentials. Credentialed connect paths (wizard
and AI assistant) fail closed. - Enterprise-grade features are incomplete — no SBOM, no build provenance /
signing.
Validation checklist (run before trusting a real migration)
-
go build ./...succeeds. -
go test ./...passes. -
go test -race ./...passes (CI race job runs the full suite unbounded). -
go vet ./...is clean. -
npm run check(svelte-check) is clean andnpm run buildsucceeds. - Manual migration validation matrix on your own hosts:
packages / configs / services / users / docker across your source→target
distro pair, plus at least one interrupt-and-resume cycle and one rollback.
Upgrade notes
- No schema migration is required by this release.
- No breaking API changes versus v1.4.x / v1.5.0-beta.1 in the committed set.
- The proxy-aware WebSocket origin fix is in this tag (it was uncommitted
WIP at beta.1). If you deploy behind a reverse proxy, this is the release that
fixes the403handshake failures.
Follow-up before a stable release
- Instrument the pipeline path and
Engine.Resumefor observability. - Review the no-credential SSH wizard probe and decide whether to keep it as-is,
document it explicitly, or add optional key capture/compare behavior. - Clear or explicitly suppress the staticcheck backlog, then promote staticcheck
to a blocking CI gate. - Extend idempotency guarantees across all pipeline stages.
- Add SBOM generation and build provenance/signing.
v1.5.0-beta.1 — beta hardening candidate
⚠️ Superseded by v1.5.0-beta.3. This prerelease has a fresh-clone build issue caused by ignored source files. Use v1.5.0-beta.3 or newer.
Meshium v1.5.0-beta.1
Pre-release / beta — hardening candidate. Not a stable release.
This is a beta hardening release focused on runtime safety, crash recovery,
lifecycle correctness, and honest capability documentation. It is not
recommended for production migrations without a manual validation pass on
your own source/target pair (see the Validation Checklist below). Meshium is
not production-ready or enterprise-grade at this tag, and this release makes
no such claim.
Highlights
Concurrency and shutdown correctness across both migration paths (Job Engine and
Pipeline), startup recovery for interrupted migrations, fail-closed SSH host-key
handling, an idempotent traffic-switch cutover record, and a set of honest,
code-grounded capability descriptors (Driver SDK, planner strategy selection,
observability seam) whose maturity is labeled rather than overstated.
Runtime safety
- Job Engine in-memory queue is now concurrency-safe (data race removed).
- Discovery network-step callbacks are serialized (no concurrent callback race).
- SSH stream callback is serialized to prevent a concurrent
onOutputrace. - Security middleware wired; LiveMonitor sockets gated; remote-to-remote rsync
path repaired.
Recovery
- Migrations crashed mid-state-machine (Jalur A) are detected and marked
interrupted on startup, so they become resumable. - Interrupted pipeline migrations (Jalur B) left in a running state are
recovered on startup.
Pipeline lifecycle
- Active pipelines are drained during shutdown via a pipeline registry and a
boundedGracefulDrainwindow before the process exits. - The migration engine is drained before the root context is cancelled.
- Server resources are closed strictly after graceful shutdown completes, so
in-flight steps keep their connections while finishing.
Security
- SSH host-key verification fails closed when no known-hosts store is available
(removes silent insecure-ignore fallbacks on the credentialed connect paths,
including the AI assistant path). - Path-safety guard for remote command paths (rejects NUL/control characters,
opt-in traversal containment). - CSP updated to allow the embedded SvelteKit inline scripts via sha256 hashes
rather than loosening the policy.
Observability
- Vendor-neutral observability abstraction (structured events, metrics,
per-migration timeline, pluggable sink; ships Nop and in-memory sinks — no
external backend mandated). - The state-machine engine's
Runpath emits lifecycle events
(started / stage-completed / stage-started / stage-failed / interrupted /
completed).
Idempotency
- Traffic-switch cutover is idempotent: on resume after a crash between applying
the switch and writing its checkpoint, the config and cutover records are not
duplicated.
Driver SDK
- Standalone, stdlib-only workload driver foundation.
- Honest database-strategy catalog with explicit maturity labels
(implemented / descriptor / future); dump/restore strategies are descriptors,
not executed paths.
Planner
- Capability-grounded, deterministic strategy selector that derives feasibility
from the driver catalog: never selects a non-executable strategy and never
labels a result zero-downtime.
CI / release readiness
- CI expanded to run vet,
-race, staticcheck, and govulncheck; staticcheck and
govulncheck run advisory (non-blocking) until the backlog is cleared. - Safe staticcheck findings cleaned up; two unused internal helpers removed.
RELEASE.mdrelease checklist added.
Documentation
- README claims synced to the code; new
docs/architecture.mdis the honest,
code-grounded reference (descriptor vs implemented, host-key exceptions,
static-analysis backlog).
Known limitations
- Pipeline path is not instrumented for observability — the observ events
are emitted from the state-machine engine'sRunonly. Engine.Resumeis not instrumented — no observability events on the
resume path yet.- Static-analysis backlog — 35 advisory staticcheck findings remain
(27×U1000 unused, 2×SA1019, 2×S1039, 2×S1040, 2×S1016). No new or critical
finding; expected and non-blocking at this tag. - Some future API is intentionally unused — extension points and strategy
descriptors are declared ahead of being wired; these are deliberate, not dead
code. - Full idempotency is not guaranteed for every step — recovery is bounded by
checkpointing; work applied but not yet checkpointed before a crash may be
re-attempted. Steps aim to be idempotent where feasible. - Real DNS/LB cutover depends on the available strategy — only implemented
strategies execute; descriptor/future strategies are not orchestrated. - Credential-less SSH wizard probe — the connection wizard's initial probe
dials with host-key verification disabled to read the server banner and
algorithms only; it sends no credentials. Credentialed connect paths (wizard
and AI assistant) fail closed. - Enterprise-grade features are incomplete — no SBOM, no build provenance/
signing.
Validation checklist (run before trusting a real migration)
-
go build ./...succeeds. -
go test ./...passes. -
go test -race ./...passes (CI race job runs the full suite unbounded). -
go vet ./...is clean. -
staticcheck ./...reviewed — advisory backlog only, no new/critical. - Manual migration validation matrix on your own hosts:
packages / configs / services / users / docker across your source→target
distro pair, plus at least one interrupt-and-resume cycle and one rollback.
Upgrade notes
- No schema migration is required by this release.
- No breaking API changes versus v1.4.x in the committed set.
- If you deploy behind a reverse proxy, the proxy-aware WebSocket origin fix is
not in this tag (it is uncommitted WIP) — plan for it in a later release.
Follow-up before a stable release
- Instrument the pipeline path and
Engine.Resumefor observability. - Review the no-credential SSH wizard probe and decide whether to keep it as-is,
document it explicitly, or add optional key capture/compare behavior. - Clear or explicitly suppress the staticcheck U1000 backlog, then promote
staticcheck to a blocking CI gate. - Extend idempotency guarantees across all pipeline stages.
- Add SBOM generation and build provenance/signing.
v1.4.1 — Zero-Downtime Migration Pipeline & Enterprise SSH
v1.4.1 — 2026-07-03
Patch release building on v1.4.0. This release consolidates all development branches and adds major new capabilities.
🚀 Zero-Downtime Migration Pipeline
- 14-stage pipeline engine — Planning → Discovery → CompatibilityCheck → RiskAssessment → Backup → ProvisionTarget → InstallDependencies → InitialSync → LiveReplication → Verification → PreCutover → TrafficSwitch → PostVerification → Observation → Committed
- 10 specialized engines — Health, Traffic, Replication, Sync, Queue, Provision, Risk, Compatibility, Cutover, Observation
- State machine with 20+ states, checkpoint persistence, LIFO rollback, configurable retry
- 7 traffic providers — Cloudflare, Nginx, Traefik, HAProxy, Caddy, Docker Compose, DNS
- 20+ compatibility checks — architecture, RAM, disk, Docker, kernel, OS, OpenSSL, SELinux, ports, timezone, glibc, etc.
- Real-time WebSocket —
/ws/pipeline/{id}for live progress updates
🔐 Enterprise SSH Authentication
- SSH key management with fingerprint verification
- Connection history tracking
- Secure subprotocol-based WebSocket auth (token via
Sec-WebSocket-Protocol, not URL) - Known hosts management and host key verification
🔍 Enhanced Discovery & Intelligence
- 8 new collectors — CI, Cron, Docker Extended, Monitoring, Runtime, Security, SSL, System
- Intelligence modules — CI pipeline detection, Database analysis, Docker workload profiling
- Workload classifier — automatic server workload categorization
- Planner strategy selector — intelligent migration strategy recommendation with warnings
🛡️ Security & Reliability (Phases 1-4)
- Comprehensive security audit remediation
- WebSocket reliability improvements — reconnect, pause/resume, secret masking
- SSH host verification hardening
- Event bus improvements for real-time updates
🎨 Frontend & UX
- PlannerView UI component
- Forensic UI/UX audit fixes (P0-P3)
- Improved pipeline page with redirect to wizard
- EmptyState, Badge, Button, Card, Modal, PageHeader, ProgressBar, Spinner UI components
📦 Infrastructure
- Docker, CI/CD, structured logging improvements
- 14 new database tables for pipeline state management
- 25+ unit tests for pipeline, health, risk, compatibility engines
v1.4.0 — The Major Management Update
What's New in v1.4.0
The major management update. Adds real interactive PTY terminal, 10 new server management modules, file explorer with in-browser editor, security hardening, and comprehensive bug fixes.
🖥️ Interactive PTY Terminal
- Full interactive SSH terminal powered by xterm.js (FitAddon + WebLinksAddon)
- WebSocket-backed PTY session — real shell, not just command output
- Server selector, connection status badge, reconnect & clear actions
🛠️ 10 New Server Management Modules
- Docker Manager — Start/stop/restart containers, pull images, live log streaming
- Service Manager — Systemd service control (start/stop/restart/enable/disable)
- Process Manager — Live process table, kill/signal by PID, auto-refresh
- Log Viewer — Tail arbitrary log files + journalctl streaming via WebSocket
- Cron Manager — CRUD cron jobs with schedule preset picker and validation
- Firewall Manager — View/add/delete ufw/iptables rules, enable/disable firewall
- Monitoring Dashboard — Real-time CPU/memory/disk/network/load via WebSocket
- System Update Manager — Check/install updates for apt/yum/dnf/pacman
- Drift Detection — Compare server snapshots, detect config drift side-by-side
- AI Assistant — Context-aware chat for command help, log analysis, proactive suggestions
📁 File Explorer
- Browse, read, edit, upload, download, delete, rename files on remote servers — no SSH required
- In-browser file editor with line numbers, Ctrl+S save, unsaved changes indicator
- 9 REST endpoints for full file management
🔒 Security Hardening (Phase 0)
- Shell injection prevention via
ShellQuote()on all new handlers - CSRF protection hardening + 68 new test cases
- Graceful shutdown (SIGINT/SIGTERM) with 30s job drain
- SSH pool invalidation on server credential update/delete
- WebSocket session token validation on all new WS endpoints
- DB indexes for migrations, steps, servers
🐛 Bug Fixes
- Server ID & PID validation on all new handlers
- Process error classification (SSH errors → 500)
- WriteFile mode validation before write
- ls parser field count fix (9→7 for
--time-style=+%s) - Modal
openprop fix in file browser - Svelte 5 reactivity fixes (logs, services, updates pages)
See CHANGELOG.md for the full detailed changelog.
v1.3.0 — Security Hardening, Discovery Engine, Migration Planner, Job Engine, Docker
What's New
The first major update since v1.2.0. Includes Discovery Engine, Migration Planner, Job Engine, security hardening, frontend UX improvements, Docker deployment, and structured logging.
Security Hardening
- Auth middleware fix — Fixed reload loop where the web page would infinitely redirect between / and /login when the app was unlocked but no session token was in the browser
- Frontend 401 handling — API client no longer hard-redirects to /login on 401 responses
- Session-based auth — Bearer token authentication for all API routes
Discovery Engine (Phase 4)
- 8 parallel collectors (OS, hardware, Docker, services, databases, Nginx, disk, ports)
- Dependency graph builder with topological sort
- Compatibility checker (RAM, disk, Docker, port conflicts, OS)
- SQLite-backed snapshot store
Migration Planner (Phase 5)
- Step generators for Docker, Database, File, Nginx, Service workloads
- Risk assessor with configurable thresholds
- Transfer estimator with confidence scoring
- SQLite-backed plan store with WAL mode
- Plan to Engine bridge (MigrationPlan to MigrationStep)
Job Engine (Phase 6)
- SQLite-backed FIFO job queue
- Worker pool with configurable concurrency
- Channel-based progress broadcaster (non-blocking)
- Graceful shutdown (30s timeout)
- Job recovery on restart
Transfer Engine (Phase 3)
- SCP and rsync strategies with resume support
- SHA256 checksum verification
- File and directory transfer steps
State Machine Engine (Phase 2)
- 13-state migration lifecycle with validated transitions
- Crash recovery with checkpoint/resume
- LIFO rollback on failure
Frontend UX
- Login redirect race fix
- Migration error states and loading indicators
- Confirmation dialogs for execute and rollback
- SPA navigation
- WebSocket JSON safety
- Alerts, Terminal, Files, and Dashboard pages
Infrastructure
- Docker — Multi-stage Dockerfile with docker-compose.yml
- Structured logging — JSON logger with configurable log level
- Dependency updates — postcss, sveltejs/kit, svelte, cookie CVE fixes
Bug Fixes
- Migration model fixes (Categories, Plan, RolledBackAt)
- DB schema (rolled_back_at column)
- Executor step selection logic
- Rollback state validation
- Frontend-backend type mismatches
Testing
- 220+ tests pass across 11 packages with -race detector
Full Changelog: v1.2.0...v1.3.0