Skip to content

Changelog

What’s new in Xentr.

Improvements, fixes and updates — in plain language, newest first. Subscribe via RSS.

August 6, 2026Latest

Working security contact, and a documentation accuracy pass

Our published security contact no longer goes to a dead mailbox. SECURITY.md and .well-known/security.txt advertised security@xentr.ai, but the xentr.ai domain has no inbound mail configured — any vulnerability report sent there was silently lost. Both files now point at a monitored address. We also corrected the repository documentation that had drifted away from the actual codebase, so that anyone (or any coding agent) reading it is pointed at code that still exists.

Technical details

Security contact. dig MX xentr.ai returns nothing — only send.xentr.ai has an MX record, and that is outbound-only (SES/Resend). Every address at the apex domain, including security@ and support@, was undeliverable. SECURITY.md and .well-known/security.txt now use victorlee@vigordigital.org, which is on live Lark MX and is already the destination the consultation endpoint mails to. SECURITY.md also promised advisories under a docs/security-advisories/ directory that was never created; it now points at GitHub Security Advisories. Documentation accuracy. - apps/web/CLAUDE.md routed dashboard and auth work to apps/app, an app deleted on 2026-05-17. Now points at apps/mimos. - README.md listed apps/app/ as a live directory while a later section described it as deleted, and hard-coded migration counts that were wrong (29 vs 80 Drizzle files, 3 vs 7 TimescaleDB). The repository tree is now accurate and no longer quotes counts that go stale on every migration. Its duplicate "Project layout" section was folded into the tree above it. - VIGOR-DEVIATIONS.md had three deviations whose quarterly review lapsed on 2026-07-18. Each was re-verified as still accurate (Supabase Auth in use with no BetterAuth, Drizzle with no Prisma, no GraphQL dependencies or source tree) and re-dated. - Rule 39's wording claimed AuditService is injected into every mutating *controller*; in practice it is injected at the service layer in 26 services versus 9 of 45 controllers. The two mutating-looking endpoints with no audit write — consultation/submit and device-types/match — were confirmed to be POST-shaped non-mutations and are correctly exempt. - docs/plan-edge-mtls.md cited .planning/p6-cutover-runbook.md, a path that does not exist; repointed at edge/xentr-fanuc/docs/CLOUD-CUTOVER-RUNBOOK.md. - The aidesigner skill instructions existed as two byte-identical copies; .agents/skills/… is now a symlink to the .claude/skills/… original, matching the existing AGENTS.md → CLAUDE.md pattern.

August 6, 2026

If your downtime report showed hundreds of stoppages "awaiting reason" even though your operators had cleared every item in their inbox, they were right and the report was wrong. Those counts were almost entirely auto-detected blips under a minute — the kind a machine produces dozens of times an hour — which the operator inbox deliberately rolls up rather than asking anyone to categorise one by one. The report was still counting them as outstanding work, so the number could never reach zero. On one plant this showed 596 "awaiting" when the real figure was 7. Micro-stops now get their own line in the Pareto. Their minutes still count toward your downtime totals — a machine stopping 600 times is worth knowing about — but they no longer pose as a to-do list. We also fixed a date-range bug in the same area: picking a custom range on any report excluded the final day you selected. "1 June to 31 July" was really querying up to 31 July at midnight, so the whole of the 31st was missing from your numbers. Presets ("Last 7 days" and friends) were never affected.

Technical details

Pareto bucketing (oee.service.ts, downtime-pareto). The query bucketed every row with categorized_at IS NULL into "Awaiting reason". The operator inbox (downtime.service.ts, microStopFilter) excludes categorized_at IS NULL AND ended_at IS NOT NULL AND duration_minutes <= 1 from its listed rows, surfacing them only as an aggregate — so no UI path exists to ever set categorized_at on one. scanWindow emits an event on every entry into a non-RUNNING state and stores Math.max(1, round(sec/60)), so a 30s blip off a 30s-sampled machine_states feed lands as duration_minutes = 1 and is swallowed by that filter. The CASE is now three-way, routing micro-stops to their own bucket; category stays unplanned, so OEE and planned-share arithmetic are unchanged. Date range (date-range-picker.tsx). getPresetRange() correctly wrapped to in endOfDay(); the custom two-click path in handleDayClick passed react-day-picker's raw local-midnight Date. Consumers filter started_at < to, making the selected end date exclusive. Range normalisation is extracted to lib/date-range.ts (resolveCustomRange) with unit tests covering end-of-day inclusivity, click-order independence, and single-day picks. detectPreset() compares with isSameDay(), so preset matching is unaffected. Banner (downtime-by-category/page.tsx). The data-quality banner tested totalMinutes === 0, which only holds while an event is still open — a closed-but-unconfirmed stoppage carries its full duration, so the banner stayed silent precisely when there was real unreconciled downtime. It now keys off the bucket name.

July 13, 2026

The ink‑and‑signal duotone look now covers the entire marketing site, not just the homepage and pricing. Solutions, Resources, Compare, Integrations, Trust, the changelog and the blog all share the same dark surfaces, one violet accent, and yellow reserved strictly for the numbers that matter — so the site reads as one system end to end. We also removed the old pre‑revamp homepage sections that were no longer used.

Technical details

.theme-ink is now applied once on the marketing <main> (in conditional-chrome.tsx), so every non‑fullscreen page renders in the dark scope by default; semantic tokens adapt automatically. A token sweep converted the remaining hardcoded light surfaces (bg-paper/bg-paper-2/bg-whitebg-background/bg-card, Panel tone="paper"tone="ink") and light‑violet chips (bg-violet-50/100 + text-violet-600/700bg-violet-500/15 + text-violet-300) across Solutions, Resources, Compare, Integrations, Trust, and the changelog. Shared DataTable status/violet colors already clear WCAG AA on ink via the earlier .theme-ink remap. Eight orphaned pre‑revamp homepage section components were deleted.

The marketing site now speaks to the person signing the cheque. It opens with the money question every owner asks — "how much capacity am I paying for but not using?" — and answers it live: drag your machine count and margin, and the recoverable-dollars figure and payback period update in front of you. From there it walks through the wins that matter to an SME (recovered capacity, faster cash, accurate quoting, keeping customers) and the compliance path to winning MNC program business. The look is a dark "ink and signal" duotone where a single yellow highlight is reserved for the numbers that matter.

Technical details

apps/web revamp across the Homepage, Pricing, and Book-consultation pages. New Tailwind v4 tokens in globals.css: a signal (yellow) scale plus a scoped .theme-ink dark surface the three pages opt into (global default stays light until remaining pages are converted). The hero mounts an interactive capacity-ROI widget backed by a pure, unit-tested computeRecovery() (lib/marketing/capacity.ts) with URL-synced inputs. Cinematic scroll reveals use the existing GSAP+Lenis provider and motion/react, all reduced-motion aware. Exposed specifics (location, machine counts) were removed in favour of capability language. .theme-ink remaps light-paper-calibrated status/violet colors to their ink-calibrated siblings so shared components (DataTable, also used on the light /compare page) clear WCAG AA on both surfaces.

July 7, 2026

The edge agent can now reshape data before it leaves the box: rename cryptic tag names to meaningful ones, map raw enum codes to readable states, stamp static context like line or area onto every reading, drop noisy channels, and suppress sub-deadband jitter. Rules are plain configuration — no code, uniform across every protocol the agent speaks.

Technical details

New src/transform/ stage (RFC P2) inserted at the single driver→publisher channel seam: TransformStage::spawn(rx, rules) returns the original receiver untouched when no rules exist (golden wire test enforces byte-identical default behavior). Steps: rename / enum_map (with drop_unmapped) / enrich / drop / deadband (numeric widening of the in-driver exact-match DeltaFilter, keyed per machine+category on last-emitted). Rules live in the transforms: config list (v1: config.yaml; registry delivery follows with fleet config). Payload parsed lazily once, re-serialised only when dirty; non-JSON payloads pass payload-shaped steps untouched. Runs before the write-ahead buffer, so only post-transform data is persisted/published.

A new Explorer view charts the raw data stream from your connected machines — pick a machine, browse every tag its edge agent reports (OPC UA nodes, Modbus registers), and watch any of them chart live over windows from 15 minutes to 7 days. No dashboard setup required. It rolls out with the first OPC UA / Modbus connections; FANUC-only factories will see it appear alongside those integrations.

Technical details

Three pieces (RFC P3): gateway-core now subscribes the edge tag/{name} topics (legacy + tenant-prefixed) and lands Good-quality numeric/boolean samples in the existing sensor_readings hypertable (sensor_type='tag') through the same WAL/batch/idempotency path — no schema change. Two new factory-scoped endpoints (monitoring/tags — distinct tags with last(value,time) over 7d; monitoring/tags/seriestime_bucket avg/min/max, whitelisted buckets). New (dashboard)/explorer page (recharts, 5s polling, range presets) + sidebar entry. Explorer reads live once an edge with OPC UA/Modbus machines streams; FANUC state/production continue on their existing paths.

The edge agent gains its third protocol: Modbus TCP. Chillers, dryers, hot-runner controllers, energy meters and thousands of other shop-floor devices expose Modbus — now they stream into Xentr through the same agent that already handles FANUC and OPC UA machines, with per-device register maps (data types, byte orders, scaling) configured from the cloud. RTU devices connect through a Modbus-TCP gateway.

Technical details

New in-process driver family (protocol: "modbus", tokio-modbus/TCP) following the OPC UA pattern: ClientLike seam with mock + real, run-loop FSM with the shared backoff/tolerance policy, per-tag emits on tag/{name} with delta suppression. modbus: config block per machine (unit_id + tags: kind/address/type/word_order/scale/offset/unit; raw 0-based addresses); contiguous reads are batch-planned (≤120 regs, gap-merge ≤8). Pure decode/planner cores are unit-tested (all word orders, i16/u32/i64/f32/f64, window splits); golden wire test confirms FANUC/OPC UA output stays byte-identical. Fleet store gains a modbus_json column via the ALTER-on-open pattern. Note: dashboards render Modbus tags fully once the cloud generic-tag ingestion (RFC P3) lands — the driver ships first so field provisioning can start.

July 5, 2026

Connecting a factory box to Xentr is becoming a download: the new Xentr Edge desktop app walks you through pasting a claim code from the dashboard, checks the FANUC runtime, starts the streaming agent, and shows live "you're streaming" status — machine list included. First release targets Windows; the installer is built on every change.

Technical details

New firewalled Tauri v2 project at edge/xentr-edge-desktop (own pnpm workspace + Cargo project, out of the monorepo lockstep, own path-filtered CI producing the NSIS installer artifact). Strict shell-only boundary per the 2026-07-04 architecture verdict: the app writes the agent's config.yaml (claim block; claim-issued credentials override placeholders), spawns/supervises the xentr-fanuc agent process, and polls its localhost :9180 /healthz · /readyz · /machines — drivers/OTA/MQTT stay in the agent. Wizard: claim → FANUC DLL gate (detect-and-guide, part A02B-0207-K737) → start → live checklist. Phase B tracked: bootstrapper download+verify, windows-service install replacing nssm, Trusted Signing, WebView2 offline variant.

A new Trust & Compliance page lays out how Xentr protects manufacturing data and audit evidence: the append-only audit trail, tenant isolation, invitation-only access, consent-first analytics, and the records the platform keeps for audit day. It also covers the standards the numbers themselves are built to — OEE per ISO 22400, machine data over open protocols (OPC UA, MQTT) — and states our own posture plainly: an ISO 27001-aligned program working toward certification, nothing claimed that we don't hold. The homepage gains a matching trust strip before the closing section, and the fox makes another appearance, leaving a trail of recorded pawprints.

Technical details

New static /trust route on the marketing site (in the sitemap; canonical/OG inherit from the layout), a TrustStrip band between the FAQ and the final CTA, a footer link, and a pointer from the /legal/security policy. Every fact card maps to shipped enforcement: the audit_logs_no_modify trigger, OrgMembershipGuard + RLS with tenant-isolation.spec.ts in CI, CodeQL + full-history gitleaks workflows, and consent-gated PostHog with PII-shaped keys redacted. Compliance profiles (ISO 9001 / ISO 13485 / IATF 16949) are explicitly labeled "in development". One new duotone asset (fox-trust.webp, 1:1).

Visiting xentr.ai no longer rewrites your address bar with calculator numbers. The OEE calculator used to push its default inputs into the URL the moment the page loaded — now the address only changes once you actually edit a value, the Reset button restores a clean URL, and "Copy link" still produces a complete shareable link either way.

Technical details

The calculator's mount-time "seed the URL" effect (router.replace with default params + #oee-calculator) ran on every homepage visit because the calculator is embedded there — polluting analytics with fake params and causing refreshes to jump to the anchor. Removed; copyLink now builds the query from current values instead of the address bar, and reset replaces to the bare pathname (inputs fall back to defaults via the existing parsers). Audited the rest of apps/web for mount-time URL writers: none.

The Learn course now feels like a course: a cover with time-to-complete up front, a you-are-here strip showing where each chapter sits in the model → plan → run → close → staff loop, big next-chapter cards, chapter outcomes stated up front, and the course remembers your progress in this browser — come back and pick up where you left off. Finish everything and the fox celebrates with you.

Technical details

Course cover + chips on the Introduction, per-chapter loop strip, localStorage progress (no account, no tracking — stays in your browser), next-chapter cards from the course order, outcome callouts per chapter, and a completion block with the celebrating fox.

The developer portal landing page now gets you to a first API call faster: the quickstart code sits in the hero with a clear fork between building integrations and learning the product, the page shows the real spec version and endpoint count it was generated from, a primitives index replaces the capability wall, and the three newest changelog entries surface right on the page.

Technical details

Hero fork panels (quickstart vs Learn), live openapi.json stats read at build, hairline primitives grid with verified links, a what's-new strip parsed from the changelog entry files, and a Learn promo band with the fox. No new dependencies.

The changelog page got a redesign: the newest release leads the page with its own visual, entries can be filtered by area (product, website, docs, edge, copilot), major entries carry artwork, and the fox now sleeps at the end of the list — nothing newer to see. Under the hood each release is now its own file, which keeps this page fast to change.

Technical details

Source restructured from one changelog.mdx to one MDX file per entry under apps/docs/content/changelog/ (filename-ordered, frontmatter title/date/tags/image). The marketing page, RSS feed and the per-PR CI gate all follow the new location; old anchors keep their slugs.

The app at app.xentr.ai finally has a real 404 page — the fox tracking paw prints toward the page that got away, in all six languages. One mascot, one style: the same ink-and-violet duotone used everywhere else.

Technical details

apps/mimos gains a root not-found.tsx following the design-system mascot rules (one fox, ≤140px, aria-hidden, no live numbers nearby) with notFound.* strings seeded in all six locales. A briefly-explored light-mode treatment was dropped same-day in favor of a single duotone style — all mascot art (app 404, changelog sign-off, Learn finale) now uses the dark duotone masters, framed on light surfaces like the developer-portal 404.

The fox comes alive

Website · Docs

The homepage's closing section now plays a short film: the fox takes off from his walkway and runs the production floor, past machines and glowing andon lights. If your system prefers reduced motion you keep the still image. He's also started helping on the developer portal — the 404 page now shows him tracking paw prints, hunting for the page that isn't there.

Technical details

12s Seedance 2.0 clip in the house duotone grade, first frame matching the existing FinalCta still (seamless poster → video). Shipped as 1.0&nbsp;MB WebM + 1.6&nbsp;MB MP4 + WebP poster, motion-reduce CSS gate, lg-only frame — same pattern as the HomeHero film. Docs portal not-found.tsx gains the fox-search illustration. Mascot asset library trimmed to the approved duotone set.

Learn is restructured as a guided course rather than a list of tutorials: it opens on an Introduction chapter that tells you exactly what you'll build, the sidebar groups chapters into Get started → The basics → Your team → Wrap up, every chapter has previous/next navigation, and two new chapters bookend the path — Set up your access (including how invitation-only access works) and Next steps.

Technical details

/learn becomes an optional catch-all serving the course tree (index.mdx is the Introduction — the old card-list landing page is retired), with section separators in content/learn/meta.json and fumadocs' built-in neighbour navigation. New chapters: setup.mdx, next-steps.mdx. Structure modeled on docs.medusajs.com/learn.

Xentr has a mascot: a small violet fox who watches the shop floor. He makes his first appearances on the homepage — watching over a running floor in the closing section — and on the 404 page, where he's found the unplugged cable. Same ink-and-violet illustration style as the rest of the site.

Technical details

Two new duotone assets (fox-hero.webp, fox-404.webp) generated in the house GPT Image 2 recipe with a fixed character reference. FinalCta gains a framed 16:9 visual column (same grid pattern as the 404 band); the 404 page swaps the andon image for the fox, and the andon shot remains in use in FloorStory.

July 4, 2026

Tutorials now live entirely under Learn with their own focused sidebar, and the docs sidebar no longer lists Tutorials or Changelog. Old links keep working — /docs/tutorials/… forwards to /learn/… and the old in-docs changelog forwards to xentr.ai/changelog.

Technical details

Second fumadocs collection (content/learn) served at /learn/[...slug] with its own page tree; the four tutorial pages moved via git mv (history preserved). Permanent redirects cover /docs/tutorials, /docs/tutorials/:slug and /docs/changelog. Search indexes both trees; the sitemap lists /learn/* and drops the redirecting URLs. The changelog source file stays in place as the single source for the marketing page, RSS feed, and the CI changelog gate.

A deep redundancy audit removed the leftovers of the retired MIMOS i4TAP pilot (old demo seeds, sales decks, proposal PDFs), 80+ completed one-off scripts, an unused FOCAS driver package superseded by the Rust edge runtime, and broken release tooling. Duplicated dashboard and marketing pages were consolidated into shared components, so future fixes land once instead of twice. No customer-facing behavior changes.

Technical details

118 files deleted (~9k lines): retired-customer collateral, historical apply-NNNN migration runners, pre-Drizzle setup scripts, packages/drivers/driver-focas, Changesets machinery (broken by org policy — see VIGOR-DEVIATIONS.md #4), Mender compose stack, and the Lark tracking integration (deviation #5). Consolidations: reports/mimos + mimos-savings into one parameterized component, shared OEE bar chart, audience/legal page components, invalidateOrderSurfaces, useReflowAccept, canonical ['production-methods', factoryId] query (fixes a stale-cache invalidation bug), staff-role checks via isXentrStaff. Dead exports stripped from method-throughput, gateway-core, protocols, mqtt-protocol. Docs truth pass: staging architecture, edge runbooks, Mender references, sub-processors, README. Magma Grafana origin is now env-overridable (MAGMA_GRAFANA_ORIGIN / NEXT_PUBLIC_MAGMA_GRAFANA_ORIGIN, in-source fallback unchanged).

This changelog now has a dedicated page on the main site at xentr.ai/changelog, and the learning journey has its own home at developer.xentr.ai/learn — five steps from an empty account to a running, staffed factory. The Developers menu now points at Docs, Learn, API Reference and Changelog as four distinct destinations, and the Compare page has been removed from the site navigation.

Technical details

xentr.ai/changelog is statically rendered from this same MDX file at build time (single source; the per-PR changelog CI gate covers it for free), with per-entry anchors and the RSS link. /learn is a dedicated page on the developer portal linking the quickstart + four tutorials in order. The in-app "What's new" banner now points to the marketing changelog. Compare routes still exist (SEO); they're just delinked from the header, footer and mobile menu.

The xentr.ai homepage now opens on film: a slow dolly through a dark machine hall behind a bolder headline, in the same ink-and-violet grade as the rest of the brand. And the site header gains a Developers menu — Documentation, API Reference, Changelog, and a step-by-step Learning journey — so the developer path is one click from anywhere.

Technical details

Hero footage generated with Seedance 2.0 (unbranded prompt, frame-checked), 0.8&nbsp;MB WebM / 2.2&nbsp;MB MP4, first frame as WebP poster; phones and prefers-reduced-motion get the still. Copy-legibility scrims layered left + vertical; headline scale raised. New DevelopersMenu mega-menu (desktop + mobile drawer) pointing at developer.xentr.ai's docs, API reference, changelog, and tutorials; the old standalone "Docs" link and Resources "API Docs" entry are folded into it.

The "A day on a floor you can't see" narrative is rewritten for the people who sign: each moment now names its cost — payroll spent finding out what ran, paid machine-hours producing nothing, overtime and expedited freight, quotes priced on capacity the floor never had — and closes with the four P&L lines a blind floor bleeds into, linking straight to the OEE calculator so you can put your own numbers on it.

Technical details

FloorStory copy rewrite (CEO/CFO framing) + a "bleed lines" strip and an anchor link to #oee-calculator. Cost *mechanisms* only — no invented figures, per the truth rules; the calculator computes the visitor's own numbers.

The xentr.ai homepage now opens with the problem before the product: a new "A day on a floor you can't see" section walks through the real cost of running blind — the morning walk, the silent stop, the quiet slip, the month-end post-mortem — before the rest of the page answers it. Behind the hero, the machine-hall backdrop now moves: a subtle ambient loop of light trails drifting across the floor. It stays a still image on phones and for anyone with reduced motion enabled.

Technical details

New FloorStory section (ink band, mono-timestamp narrative beats, truth-rule copy) between the hero and "Your floor. In plain sight.", so the existing ink→light rhythm reads as blind→seen. Hero loop generated from the existing duotone still with Seedance 2.0 (start frame = end frame → seamless 10s loop), encoded to 0.29&nbsp;MB WebM + 0.70&nbsp;MB MP4, autoplay muted loop playsinline at 30% opacity with the WebP still as poster; hidden below sm and under prefers-reduced-motion via CSS so those users keep the still.

A more visual website

Website · Docs

The xentr.ai site now shows the factory, not just describes it: sector vignettes in the "Already on the floor in Penang" section, device-in-context scenes on the operator app / wallboard / copilot cards, a wire-it-to-see-it schematic in the deployment story, per-industry artwork on all six industry pages, and backdrops on the homepage hero, booking page, and 404. The developer portal front page gets a matching illustration. All artwork is generated in one duotone ink-and-violet grade — no real plants or customers are shown.

Technical details

17 generated duotone assets (unbranded, no readable text, individually reviewed) served as WebP under public/duotone/ (14-100&nbsp;KB each, ~760&nbsp;KB total) via next/image with explicit sizes; backdrops are aria-hidden with gradient scrims to keep text contrast; the industry template maps slug → image with a graceful no-image fallback.

The xentr.ai website and this developer portal got a structural tune-up. Search engines now see each page's own address and shared links show the right page titles; both sites have proper branded "page not found" screens; the developer portal gained a favicon, social-share cards, and a sitemap; and this changelog now has shareable links per entry plus an RSS feed. Contact buttons that silently went nowhere now route to the booking form.

Technical details

Marketing: per-route canonicals, per-page OpenGraph/Twitter inheritance, Organization/WebSite/FAQPage JSON-LD, blog posts added to the sitemap, not-found.tsx/error.tsx, www→apex 308 redirect, skip-to-content link, nav current-page indication, mobile pricing-table overflow fix, and dead mailto: CTAs replaced with the booking form. Developer portal: /docs/api-reference index page (was a 404), corrected dashboard host in quickstart/auth docs, favicon + OG image + robots + sitemap, Space Grotesk display headings aligned with the marketing brand, a custom 404, and this changelog restructured with per-entry heading anchors and an RSS route.

Sensor readings can no longer be double-counted after an edge reconnects, so axis/spindle/temperature aggregations stay correct.

Technical details

sensor_readings had no unique key, so a gateway WAL replay inserted duplicate rows (unlike machine_states/production_counts, which already dedupe). Migration 007 de-duplicates existing rows and adds UNIQUE (time, factory_id, machine_id, sensor_type, sensor_name); the batch writer now uses ON CONFLICT DO NOTHING. The index is already applied to the prod TimescaleDB.

Two production orders created at the same instant in the same factory can no longer be assigned the same order number.

Technical details

generateOrderNumber was read-max-then-increment with no lock. Order creation (and cloning) now allocate the number under a per-factory advisory lock, and migration 0083 adds a UNIQUE (factory_id, order_number) index as the hard backstop. The migration self-guards: it fails loudly if pre-existing duplicates exist so they can be resolved first.

Switching the active factory now starts Copilot fresh for the new site — its conversation, thread, and suggestion chips no longer carry over from the previous factory.

Technical details

Proactive suggestions were fetched once behind a boolean ref, so Factory A's chips (embedding A's order numbers / action tokens) survived a switch to Factory B. Suggestions are now keyed by factoryId (refetch on change), and a factory switch resets the conversation id, message thread, and chips.

When you log a past production run, Xentr now blocks an end time that's before the start, or times in the future, instead of silently saving a broken window.

Technical details

The validateBackfillTiming guard existed but was never called. It's now enforced on both backfill paths (scheduleSplit and applyTimingToOrder), throwing a 400 on inverted / future windows that previously corrupted part-count and pace math.

Account managers now see edge and device inventory only for the organizations they're assigned to — never the whole fleet, and never another tenant's.

Technical details

Fleet endpoints (GET /api/fleet/stats, /api/fleet/edges) previously treated xentr_account_manager as full-fleet staff: it could omit organizationId for a global view and pass any organizationId unverified. Now only xentr_platform_owner gets the global (null) scope; every other role is confined to listReadableOrgIds, and a supplied organizationId is verified with assertCanReadOrg.

If you keep a tab open (a wallboard, a planning screen) and we ship an update, a banner now appears at the top: refresh with one click, or follow the What's new link to this changelog. Dismiss it to keep working — it won't nag again until the next update.

Technical details

New UpdateBanner in the app root layout compares the app version baked into the client bundle at build time (NEXT_PUBLIC_APP_VERSION) against GET /api/version (force-dynamic, no-store), polled every 5 minutes and on tab re-focus. Every release bumps the version, so any mismatch means a newer deployment is live. The banner keys off the lockstep app version rather than a deployment commit SHA.

A new desktop app for on-site setup scans your factory network for FANUC machines, adds them in a click, and shows live connection status — no config files or command-line steps.

Technical details

New edge/xentr-connector Electron wizard that wraps the xentr-fanuc collector and its :9180 control plane (subnet FOCAS scan, hot-reload machine add, health/readiness view, one-click Windows service install). Out of the pnpm/turbo workspace and version-lockstep, like the collector. Also removed the unused gsap dependency from the product app.

Xentr now publishes a user-facing changelog — every product change ships with a plain-language entry on this page.

Technical details

PR #352/#353. The changelog is part of the developer docs at developer.xentr.ai — each entry pairs a plain-language headline with an optional technical note like this one, newest first.

June 30, 2026

The downtime window on a workstation now states exactly what period it covers, the order list is searchable, and the production chart no longer projects past today.

Technical details

PR #351. Downtime window labeling, order search on the workstation detail view, and the production chart's x-axis is bounded to the current day instead of extending into future hours.

June 25, 2026

After each answer, Copilot now offers context-aware follow-up suggestions — one click to drill into a machine, an order, or a report it just mentioned.

Technical details

PR #344 (Slice 2). Suggestions are generated per-turn by the LLM engine from the conversation state and rendered as chips under the reply.

Copilot vision Q&A

Product · Copilot

You can now attach an image, PDF, or CSV to a Copilot question — snap a defect photo or drop in a spec sheet and ask about it directly.

Technical details

PR #347 (Slice 5). Vision Q&A: attachments are passed to the multimodal model alongside the prompt; CSVs are parsed and summarized before inclusion.

Saved Copilot conversations

Product · Copilot

A sidebar lists your past Copilot conversations — start a new one, switch back to an old one, rename, or delete.

Technical details

PR #346 (Slice 4). Conversation persistence with list/new/switch/rename/delete, scoped per user and organization.

Richer Copilot answers

Product · Copilot

Copilot replies now render formatted text, tables, and charts, and can produce a downloadable PDF report.

Technical details

PRs #342/#343/#345. The rule-based engine was replaced by an LLM engine (Slice 1 wired the UI to it); rich output renders markdown + recharts and exports PDF via the report pipeline.

June 22, 2026

On the order cockpit, batch number, ship date, and assigned machine are now edited directly in the new properties side panel — no separate dialog, and the header stays focused on live production status.

Technical details

PRs #340 (58f9b2d9) + b7346708. New order-properties-panel.tsx right rail; edits go through the existing PATCH /production-orders/:id. Header reduced to an identity line (product · qty).

The Xentr fox curled up asleep

You’re all caught up. Nothing newer to see.

Subscribe via RSS