Skip to content
PlantStacks
FeaturesPricingCompareSecuritySupportDocs
Sign inStart free trial

CHANGELOG

Every release, what changed, and why. Updates are Ed25519-signed and your installation verifies the signature before applying — an unsigned or altered package is refused.

Changelog

All notable changes. Releases are signed (Ed25519) and verified against the embedded vendor key before applying — see platformctl update --package.

[1.0.2] — Multi-plant sync could silently drop records (2026-07-31)

Recommended for everyone. Required if you run more than one plant. The fix existed in our source before this build did — 1.0.1 and earlier do not contain it, so upgrading is the only way to get it.

Fixed — silent cross-plant data loss at the sync boundary

  • What went wrong. When one plant pulled changes from another, it recorded how far it had caught up
  • using its own clock at the moment of the pull, while the sending plant only returned records stamped strictly after that point. A record created in the same millisecond as a sync therefore fell into the gap between the two — and because the catch-up marker only ever moves forward, that record was never sent again. No error, no warning, no retry: the record simply existed at one plant and not the other, indefinitely.

  • Who was affected. Only installs running two or more plants with multi_site sync enabled. A
  • single-site install was never at risk. The window is narrow — a record has to be stamped in the exact millisecond of a pull — but a busy plant syncing on a short interval will hit it eventually, and inventory quantities are exactly the kind of record that goes quietly wrong when one is missing.

  • What changed. The catch-up marker is now derived from the data actually received — the newest
  • timestamp in the batch — instead of from the wall clock, and it can never move past what was really seen. The boundary is now inclusive, so a record sharing that timestamp is re-sent rather than skipped; re-sending is safe because applying a record twice is a no-op.

  • Upgrading repairs the damage. The first sync after you upgrade performs a full catch-up pull
  • from each peer plant, so records that were skipped previously are fetched and applied then. You do not need to re-enter anything or re-pair the plants.

Also in this build

  • Everything in 1.0.1 (the zero-IT hardening) plus the above. No settings, licence keys or stored data
  • are changed by upgrading — your existing licence file and your data directory are used as-is.

  • Still unsigned: Windows SmartScreen will warn on first run. Verify the SHA-256 on the Downloads
  • page before installing.

  • Windows portable .zip only (the .exe installer needs Inno Setup; Linux builds need a Linux host).

[1.0.1] — Zero-IT hardening in the shipped build (2026-07-19)

_First rebuild since 1.0.0. The 1.0.0 artifacts predated the zero-IT hardening merge, so the published download did not contain it; this build does._

  • Zero-IT hardening now in the binary: team-connect address + QR (/api/v1/connect-info, /hello),
  • persisted runtime state with sleep-gap and LAN-IP-change detection, extended Health checks (clock plausibility, autostart, disk, off-machine backup), MFA recovery codes, the loopback-gated "Forgot the admin password?" flow, and the "Something's wrong" support export.

  • Still unsigned — Windows SmartScreen will warn on first run. Verify the SHA-256 below before
  • installing; see the Downloads page for the exact click path.

  • Windows portable .zip only in this build (the .exe needs Inno Setup, Linux needs a Linux host).

[1.0.0] — Packaged & launch-ready (built locally; not yet published)

_Prepared 2026-06-29. Everything below is free and non-public: artifacts stay local in dist/, Stripe stays in TEST mode, and the storefront stays gated until the owner decides to launch._

Packaging — 1-click install

  • Self-contained binary (Node SEA): no Node.js, terminal, or config file for the end user —
  • install, open https://localhost:8443/, set an admin password. Pure-Node self-signed TLS cert (no openssl) and per-OS data/config paths with first-run bootstrap.

  • Installers built to dist/installers/ with a dist/SHA256SUMS manifest, all unsigned and
  • local (nothing uploaded): a Windows portable zip (pure-Node ZIP writer — no toolchain, builds on any OS; verified it extracts byte-identical via native Expand-Archive), plus build paths for the Windows Inno-Setup installer, Linux .deb/.rpm/.tar.gz (systemd), and a one-container Docker image.

Commerce — proven in TEST mode, gated OFF

  • Stripe self-serve loop proven end-to-end in test mode (test card → checkout.session.completed
  • webhook → signed WFLIC1 license auto-issued → emailed with a .lic attachment).

  • LAUNCH_MODE gate (default off): public checkout + sign-up return "coming soon" and nothing
  • is purchasable; the webhook + console issuance stay live. New launchmode test; /healthz reports launch_mode + storefront_open. Go-live runbook in sell/GO-LIVE-STRIPE.md.

Marketing site & hosting — deploy-ready, not deployed

  • Static site build (node sell/marketing-site/build.js → dist/site/): all pages, **7 legal pages
  • pre-rendered to static HTML, plus a self-contained coming-soon** holding page (dist/site-coming-soon/). One-command publish documented in sell/PUBLISH-SITE.md. Fixed the brand logo glyph and the contact email.

  • Hosting blueprints validated locally (no deploy): render.yaml/docker-compose.yml parse as YAML,
  • railway.json as JSON; /healthz returns signing_key_matches_build: true. Fixed a real bug in Dockerfile.marketing (it didn't copy sell/shared + legal/, so the server would crash); sell/DEPLOY.md gains a full env reference + launch-gate notes.

Legal & docs

  • Legal pack finalized: product PlantStacks / entity PlantStacks LLC / plantstacks.com;
  • customer-facing contact email moved off a personal address to support@plantstacks.com; business-address + sales-tax placeholders left as marked TODOs (sales-tax later resolved by the CPA — see the [1.1.0] entry). Added the internal legal/NOT-YET-FORMED-NOTICE.md (the LLC is not yet formed — do not represent it as registered).

  • New docs/INSTALL-GUIDE.md (per-OS) and docs/ADMIN-QUICKSTART.md.

Guardrails kept

  • Core stays zero-runtime-dependency (dependencies: {}; the only build tool is postject),
  • offline/no-phone-home, RBAC deny-by-default, WFLIC1 frozen, security-map.md never shipped. Full test suite (20 core suites + vendor backend) green.

[Unreleased] — Rebrand to PlantStacks

  • The product is now PlantStacks (domain plantstacks.com). The brand was applied everywhere
  • the previous product name appeared — including every identifier that carried it: the UI, OpenAPI/docs, PWA manifest, TOTP issuer, seeded help content; Prometheus metrics (plantstacks_); environment variables (PLANTSTACKS_CONFIG, PLANTSTACKS_SECRET_, PLANTSTACKS_LICENSE_PUBKEY, PLANTSTACKS_API_RATE_PER_MIN, PLANTSTACKS__ override prefix); HTTP/webhook headers (X-PlantStacks-*); the plantstacks.log log file; and the npm package name (plantstacks). The bundled trial license re-signed to the same key/format (now "PlantStacks Trial").

  • Compatibility contracts kept (never named after the brand, so nothing to rename): WFLIC1
  • license token format + signing keys, module ids, permission/role keys, store/collection namespaces, event-bus names, the YAML config schema, and the platformctl bin. Existing licenses and data keep working.

  • Legal entity remains PlantStacks LLC (not yet formed — a separate business decision).

[Unreleased] — Support, observability & fleet

  • Data-classification boundary (src/core/diagnostics/): allowlisted diagnostic
  • reports (input shape, never values); local-only verbose log; secret-key drop.

  • Vendor diagnostic KB (/support-kb) + ERR_#### taxonomy + standardized
  • error envelopes. security-map.md is vendor-internal (excluded via .buildignore).

  • On-box support assistant: zero-dep BM25 retrieval over the KB; optional
  • customer-run LOCAL model; cloud LLM endpoints refused; security topics refused.

  • Opt-in support bridge (off by default) via signed webhooks; air-gap file
  • export; vendor-console intake + fleet dedup by error signature.

  • Signed release feed + offline update package; verify-before-apply
  • (ERR_6001/6002/6003); in-app "update available" notification.

  • Observability: structured JSON logging with correlation ids + redaction
  • (values only to the local verbose store), bounded rotation/retention, platformctl doctor, troubleshooting mode + diagnostic bundle.

  • Robustness: circuit breakers + retries with backoff/jitter on optional
  • outbound, bounded queues + backpressure, idempotency; load/chaos tests.

[2.0.0] — Manufacturing MES

  • business_inventory expanded into a full MES: movement ledger, BOM staging,
  • replenishment, traceability, quality holds, counts, costing/WIP, PLC feed.

[1.x] — Platform + enterprise

  • All-features-all-tiers licensing (seats+sites, prorated upgrades), cloud
  • vendor backend, multi_site sync, integration API + OpenAPI, plc_connector, Postgres scale knob.

PlantStacks

Self-hosted operations software for manufacturers. Install once, own your data, run offline.

Product

FeaturesPricingCompareSecurityChangelogAbout

Support

Support centerDocs & installDownloadsSystem requirementsStatusManage subscription

Legal

TermsPrivacyEULARefundsCookiesAcceptable useDPA
© 2026 PlantStacks LLC · Raleigh, NC · Self-hosted on your hardware.No phone-home · Offline-verified licensing
Enlarged PlantStacks product screenshot