Changelog

Release history

Every published release, written for users. The full technical detail lives in the source repository.

  1. 3.11.12Latest

    Reboot without false alerts, an Inbox that goes to the point

    A planned reboot no longer opens alerts

    Rebooting a machine used to open “Container unhealthy” or “Service failed” alerts: the agent was capturing the shutdown itself. Agent 1.3.22 announces the shutdown and only sends what it measured before. Alerts left open by a reboot now close on their own as soon as the machine is healthy.

    An unexpected reboot is reported

    Conversely, a machine that restarts without a clean shutdown (hard reset, crash, power loss) now opens an “Unexpected reboot” alert, at low priority.

    The Inbox goes to the point

    By default, the Inbox only shows P0 and P1 alerts. When there are none, it also shows P2. You can leave a server or an app out of it: a banner reminds you what is left out, and notifications are unchanged. The server name now has its own line in the list.

    “I’m on it” rather than “Acknowledge”

    In French, the button now reads « Je m’en occupe ». The gesture is the same: it stops reminders. The alert stays open until things are back to normal, which closes it on its own.

    Log errors show up

    A server whose logs contain errors shows it in the catalogue and on its page, with the error count over the last 24 hours and a link to its logs.

    Demos stay under “Demo”

    On the phone, the “All” scope no longer shows demonstration machines, as on the website.

  2. 3.11.11Docker vulnerabilities spotted sooner, groups to file your machines

    Docker and containerd vulnerabilities, as soon as they are published

    StatHall now reads, every night, the security advisories that Docker and containerd publish on their own repositories. An update that fixes a vulnerability in the Docker engine, its command line, Compose, buildx or containerd is flagged as soon as it ships, without waiting for the public databases to pick it up, which can take more than a week.

    Medium vulnerabilities count too

    A medium-severity vulnerability that an available update fixes now opens an alert, at low priority (P2). A high one raises it to P1, a critical one to P0. Its name becomes “Fixable vulnerability not patched”.

    File a machine without sharing it

    You can file a machine you don’t co-own into your groups, to find your way in your catalogue. It is filing only: it grants the group’s other members no right on the machine and applies no group rule or alert to it. The group marks it “Filed only”.

  3. 3.11.10Roadmap: editing for those who can edit

    Buttons only when they work

    An app’s roadmap only shows its editing buttons (version, milestone, settings) to the people who can change it: the owner and co-owners. Other members read it without buttons that would be refused.

    An abandoned version is put away

    A version marked “skipped” will not ship: it joins the history, hidden by default, with the versions already released.

  4. 3.11.9Roadmap: create a version, hide the history

    App owners edit their roadmap

    An app’s owner and co-owners can again add a version or a milestone, or set the roadmap cadence: the buttons were only shown to the instance administrator. When a change is refused, the cockpit says why.

    The form opens where you can see it

    “Add a version” opens its form at the top of the roadmap, no longer below a long history. A version number that already exists is reported.

    History folds away

    Versions already released and past milestones are hidden by default: the roadmap shows what is coming. “Show history” brings them back.

  5. 3.11.8“To handle” no longer shows what is fixed

    A list that says what is left to do

    The inbox default filter, “To handle”, no longer keeps fixed alerts: a vulnerability patched overnight is gone from it in the morning. What was fixed in the last 24 hours is still listed under “To handle + acknowledged + settled”, in the cockpit and on the phone.

    An agent that survives a restart of the StatHall server

    If a server restarts while the cockpit itself is unavailable, the agent (1.3.21) starts anyway and retries, instead of stopping until someone restarts it by hand.

    An alert that follows the fix

    A container image or a package updated during the day leaves its alert’s details at once, instead of staying there until the next day.

  6. 3.11.7Built on Node 24

    An up-to-date foundation

    The cockpit and this site are now built with Node 24, the long-term supported Node release. Nothing changes in use: the build tooling simply stays within its support window.

  7. 3.11.6A fixed vulnerability closes within minutes

    No more waiting for the hour

    After a package update, the agent (1.3.20) sends the machine’s inventory within minutes instead of waiting for the hourly scan: a fixed vulnerability leaves the cockpit almost at once. The cost for the machine stays negligible.

  8. 3.11.5A health score that explains itself

    The score says why

    Each overview card names what lowers its health score (“−60 Unpatched critical vulnerability”), and the “Mean health” card opens the list sorted from lowest to highest. A target with an undated component is capped at 90 instead of showing 100, and the card says which one.

    No more silent vulnerability

    A vulnerability whose fix has been published for more than a day now raises an alert even if the machine does not see it yet: its package index is out of date, and the alert tells you to refresh it.

    PHP and Laravel dated, a cleaner Inbox

    A Docker image built on your machine is dated by what it contains: the PHP, Node.js, Python, Go or Ruby version it ships, and Laravel, Symfony, Drupal or CakePHP read from the project’s composer.lock (agent 1.3.19). The inbox now hides acknowledged alerts by default; a filter brings them back, on the cockpit and on the phone. In a server’s logs, a refusal by the firewall, the web server or an SSH scanner is now labelled “defence” instead of the red of an error.

  9. 3.11.4More accurate container memory alerts

    Fewer false alerts

    A container’s memory no longer counts the disk cache that the system frees on demand. A database keeping its files in cache no longer looks “almost full”: only memory actually in use and shared memory count. Update the agent (1.3.18) to benefit.

  10. 3.11.3One container failure, one alert

    Less noise

    A container stuck in a restart loop no longer raises an alert on every cycle: the failure stays one open alert until the container actually holds, instead of closing and reopening every few minutes — with a notification each time.

  11. 3.11.2Excel exports twice as fast

    Faster

    The Excel workbook is now prepared about twice as fast, including the full workbook of your whole fleet, without weighing on the server.

    What changes in the file

    Each sheet is now a range with filters and a frozen header, rather than a formatted Excel “table”. Pivot tables work exactly as before: click inside the data, then Insert › PivotTable. Ctrl+T formats the range as a table if you wish.

  12. 3.11.1Reliable Excel exports across a whole fleet

    Fixes

    • An Excel workbook containing an issue whose title carries invisible characters (binary bytes reported by an app) now exports normally instead of failing.
    • Preparing a large workbook no longer slows down the rest of the cockpit while it runs.
  13. 3.11.0Your data in Excel or CSV, ready for a pivot table

    What StatHall keeps, now exportable

    Sentry keeps only 90 days of statistics: your month-by-month quota consumption no longer exists there. StatHall collects it daily and keeps it, along with the monthly issue trend, crash-free rate release by release, store metrics or, for a server, 400 days of system metrics. The new Exports screen hands them back as a file.

    • An Exports tab on every app and server, and an Exports screen for the whole fleet, under My targets.
    • Thirteen datasets: monthly issue and Sentry quota trend, quota by day or month, issues, events per issue, sessions and crash-free by release, store metrics and reviews, versions, server system metrics, probe availability, agent events, end of support, anomalies.
    • Period and granularity of your choice: 3, 6 or 12 whole months, since the beginning, or custom dates; by day or month.

    Ready for Excel

    • Excel: one sheet per dataset, as a real Excel table (filters, direct pivot table source), typed dates and numbers, and an “About” sheet that dates the extraction and defines every column. One button gathers every dataset into a single workbook.
    • CSV: comma separator and decimal point in English; semicolon and decimal comma in French.
    • Every row carries the target name: a fleet export compares your apps or servers as is.

    Security

    You only export targets whose data you can see. Every export is recorded in the audit log, a review’s author is never exported, and text coming from a third-party service can never turn into a formula in your spreadsheet.

  14. 3.10.4Fewer false alerts on logs

    Alerts

    A bot requesting files that don’t exist on your site no longer opens an “error burst” alert: nginx logs these requests as errors, but the visitor is wrong, not your server. The lines remain available in the logs, and the alert still states how many lines it set aside.

  15. 3.10.3Strengthened security posture

    Security

    Strengthened security posture of the service. No action is needed on your part.

  16. 3.10.2Stronger account security

    Security

    Strengthened security posture of the sign-in flow. No action is needed on your part.

  17. 3.10.1Stronger account security

    Security

    Strengthened security posture of the sign-in, sign-up and account recovery flows, on the cockpit and in the mobile app. No action is needed on your part.

  18. 3.10.0Read-only API access, for the screens you trust

    Your urgent anomalies, on a screen of your own

    A wall dashboard, a monitoring script, a screen in the workshop: a trusted client can now read the number of urgent anomalies (P0 and P1) of your targets, and the names of the targets involved, without opening a browser session. The count follows your Inbox exactly: an alert you acknowledge, snooze or resolve disappears from the screen on its own.

    Read-only service tokens

    Access goes through a service token, created in Settings › API access. A token reads one specific aggregate and nothing else: it opens no screen and no other part of the API, and cannot change anything.

    • Creating one asks for your password and a two-factor code; the token is shown only once.
    • Every token expires after 90 days at most. You are warned a week and then a day before, and you regenerate it with no downtime: the previous one stays valid while you deploy the new one.
    • You can restrict a token to your network’s address, in one click.
    • You are notified on Telegram and by email on creation, on first use from a new address, and on any abnormal use. A token used suspiciously is suspended automatically.
    • Revocation takes effect immediately.

    Security

    Strengthened security posture.

  19. 3.9.0End of support, on a scale of its own

    Every component now has its end of support

    StatHall dates everything your targets run: the distribution, databases and languages installed from a third-party repository, running Docker images, the frameworks in your SBOMs, Google Play and App Store requirements for your apps, the StatHall agent and the PostgreSQL database of a Supabase project. The calendar comes from endoflife.date and is refreshed daily. No data about your fleet leaves in the process: the whole calendar is downloaded, and no single product is ever looked up.

    A package shipped by your distribution follows the distribution’s end of support: Debian keeps fixing its Python to the end, whatever python.org says. Only what comes from a third-party repository follows its vendor’s calendar. Extended support (Ubuntu Pro, Debian ELTS) counts as soon as it is active.

    A “Support” badge, less severe than a vulnerability

    Each component sits on a seven-level scale: three before the deadline (end announced, plan it, imminent), three after (out of support, long out of support, abandoned), and “not covered” when the date is unknown. Not knowing is never shown as up to date.

    The badge appears on the target list, the header, the overview, the Security tab and each app’s page, and on your phone. An end of support opens a single alert per target, never critical: it does not count on the app icon badge. You are notified when a component goes out of support, and the alert closes by itself once it is upgraded.

    A “Lifecycle” screen

    Every deadline across your fleet in one place, sorted by severity then date, filterable by level and origin. For an app, enter its Android targetSdk and iOS SDK in its configuration: StatHall warns you before the stores refuse your updates.

    Fixes

    • Push notifications: without any setting on your side, P0 and P1 alerts are now sent to your phone, as the settings screen already showed. Emails remain opt-in.
    • Online help: the article index is refreshed daily again.
    • Google Play sync: a transient Google outage no longer fails the stability data sync.
    • SBOM: several SBOMs on one target (API, front end) now coexist instead of overwriting each other.
  20. 3.8.32No beta version suggested as a fix

    Vulnerabilities only recommend stable versions

    When a security vulnerability is fixed, StatHall tells you which version to install. An alpha, beta or release-candidate version is never suggested anymore: if only a pre-release fixes a vulnerability in an image’s software or an application dependency, no “fixable” alert opens until a stable version ships.

  21. 3.8.31The server now reports every change to a critical alert to the app

    Getting ready for an always-accurate app icon

    The server now tells the mobile app about every change to a P0 alert — opened, acknowledged, snoozed, closed — even when that change sends you no notification (a metric back to normal, at night during your quiet hours). This signal is never displayed: it will let the app keep the number on its icon accurate, starting with its next version.

  22. 3.8.30A fixed vulnerability closes its alert the same day

    Fixes are recognised within minutes

    Security vulnerabilities and outdated container images were only re-assessed once a night: an update made in the morning left its alert open until the next day. Now, as soon as the agent reports a change on a server — updated packages, a container recreated on a new image — that server is re-assessed and the alert closes by itself if the fix is real. The nightly pass stays in place.

    Filtering the inbox by level

    The inbox can return only the alerts of a given level — the basis of the new “P0” chip in the mobile app.

  23. 3.8.29Accurate image alerts, and SBOMs that alert

    An identically rebuilt image is no longer reported as outdated

    With recent Docker versions, rebuilding an image without changing anything gives it a new identifier. StatHall now compares the content actually running, as Docker Compose does: only an image whose content changed is reported. Requires agent 1.3.15.

    Vulnerabilities in your application dependencies finally alert

    A fixed vulnerability in a dependency declared by an SBOM now opens the server’s vulnerability alert, with the version that fixes it on your branch.

    Known security fixes within the hour

    The agent re-reads the package list every hour: an available security fix shows up in the cockpit within the hour, instead of up to a day later.

  24. 3.8.28One vulnerability, one line

    Your containers’ vulnerabilities no longer count twice

    A vulnerability published by two security databases now appears once in a server’s Security tab, with its severity score.

  25. 3.8.27Vulnerabilities of your containers and Docker packages

    Known vulnerabilities beyond the distribution’s packages

    A server’s vulnerability watch only looked at its distribution’s packages. It now also follows:

    • packages installed from Docker’s repository (containerd.io, Compose and Buildx plugins);
    • the software of some running images: Traefik, Caddy and Gitea pulled from their official repository.

    A vulnerability fixed by the vendor is shown with the nearest version that fixes it, in the Security tab and in the server’s alert. An up-to-date version never inherits another branch’s vulnerabilities.

  26. 3.8.26The right version in image alerts

    The running version is the tag’s

    When a patch release is out for a pinned image, the alert now shows the version of the running tag, not a version inherited from the base image.

  27. 3.8.25Outdated images: no alert during a deployment

    An image alert no longer fires during a deployment

    A freshly rebuilt or pulled image is only reported if the lag lasts: the moment a deployment replaces its containers no longer triggers anything. The alert also says more precisely what happened (image pulled, rebuilt on the machine, or of unknown origin) and no longer shows a version inherited from the base image. Requires agent 1.3.14 for exact versions.

  28. 3.8.24Outdated container images are now reported

    An alert when a container is not running the up-to-date image

    A server’s page now reports lagging containers, with the step that catches them up:

    • image already pulled but not applied — the new version is waiting on the machine, only recreating the container is missing;
    • image rebuilt but not applied — the restart that does not reload the code;
    • patch release out — a pinned tag such as v3.7.5 while v3.7.13 has shipped;
    • newer image at the registry under the same tag.

    One alert per server, listing the images involved and their versions. It requires agent 1.3.13, read-only as always.

  29. 3.8.23Ready-to-copy commands, on the right service

    Diagnostic leads name the service at fault

    When a server alert suggested a command to run on the machine, it read “journalctl -u <unit>” and left you to find the service. It now fills it in: the failed service, the one producing the burst of errors, or the program that crashed. The command can be copied and run as is.

  30. 3.8.22The right version from the first visit

    The cockpit opens straight on the latest version

    After an update, the cockpit could first show its previous version, kept by the browser, before reloading on its own. The sign-in page then announced a different version number than this site. The page is now always requested from the server: the version shown is the one running, everywhere. Offline, the cockpit still opens.

  31. 3.8.21One group per series of crashes

    Grouped crashes no longer repeat

    The same series of crashes could still appear two or three times among incidents, as views computed on different days. Only the most recent one now stays open.

    A group that no longer crashes closes

    When none of the crashes in a group has occurred for two weeks, or they are all resolved or ignored, the incident closes on its own. If it comes back, it reopens. An incident you closed yourself stays closed.

  32. 3.8.20Incidents that close, a faster vulnerability watch

    A settled incident no longer waits for you

    When every alert of an incident has been closed for a day, the incident closes on its own. It no longer asks you to decide on a problem solved long ago. An incident you confirmed or rejected keeps your decision.

    No more duplicate crash groups

    The same group of crashes could appear several times in the incident list, one new copy per day. Only one remains, updated as days go by.

    A faster, lighter vulnerability watch

    The daily security check of your servers now runs once per night and no longer reads the same security advisories several times: it finishes much sooner and spares your database.

    Agent 1.3.11

    A service repaired while the agent or the machine was restarting is now reported as recovered, instead of leaving its alert open.

  33. 3.8.19Fewer false alerts on containers

    A container that has recovered is no longer reported as unhealthy

    When the system runs out of memory, it may stop a process inside a container; Docker then remembers it until the container restarts, even if the service resumed normally within seconds. A running, healthy container is no longer reported for that reason. The out-of-memory event itself is still reported by its own alert, and a container that actually stopped or became unhealthy after such an event keeps alerting you.

  34. 3.8.18The agent reports where each package comes from

    Vulnerabilities compared against the right version number

    Security fixes are released for a package’s original software, which does not always carry the same version number as the installed package. Agent 1.3.10 now reports both, as the system knows them: StatHall no longer has to work them out, and each vulnerability is compared against the right number.

    Update the agent on your servers (apt upgrade) to benefit from it; an older agent keeps working as before.

  35. 3.8.17Vulnerabilities finally have a severity, and one alert per server

    Every vulnerability has a severity

    The Security screen now shows the severity of each known vulnerability (critical, high, medium or low) and its CVSS score, computed from the information published by the distributions.

    One alert per server, when there is something to do

    When serious vulnerabilities affect a server and the update that fixes them is available, you get a single alert for that server: the most serious vulnerability first, then the list of packages to update. A vulnerability that no available update fixes, or that the distribution rates as negligible, stays visible on the Security screen without alerting you.

    Fewer imaginary vulnerabilities

    Some libraries carry a version number different from the software they come from. StatHall sometimes compared them to the wrong number and reported vulnerabilities fixed long ago. The right version is now worked out.

  36. 3.8.16Vulnerabilities on your servers, counted precisely

    Only the running kernel counts

    After an update, Debian and Ubuntu keep previous kernels on disk. Their vulnerabilities were counted as the machine’s own, even though they are not running and their fix is already installed: it is the running kernel. They are now left out of the scan.

    Each vulnerability belongs to its version

    When several versions of the same software coexist, each one now carries only its own vulnerabilities. A server’s count of fixable vulnerabilities is once again the list of updates actually available.

  37. 3.8.15Vulnerabilities on Ubuntu servers finally counted, and upcoming releases already covered

    What can be fixed on an Ubuntu server

    On an Ubuntu server, the Security screen never showed a fixable vulnerability, even when an update was available. Each known vulnerability is now linked to the version that fixes it: the headline figure finally says what an update would solve.

    Ubuntu’s verdict is taken into account

    As with Debian, the vulnerabilities Ubuntu rates as negligible (theoretical, no fix planned) are counted separately, among those that need no action. A negligible vulnerability that an update fixes stays on the to-do list.

    Ready for upcoming releases

    Upcoming Ubuntu and Debian releases will be recognised as soon as they come out, without waiting for a StatHall update. The end-of-support date of a recent Ubuntu release is now known, or derived from Ubuntu’s release calendar: you are warned in time, never too early.

    More complete scans

    A brief outage of the known-vulnerabilities database no longer leaves servers unscanned until the next day, and a vulnerability is no longer reported as fixed just because it could not be re-read.

  38. 3.8.14A service that stays up all night, and fewer false alerts

    No more early-morning interruptions

    The daily update of the known-vulnerabilities database needed too much memory at once and could interrupt the service for a few moments, early in the morning. It now processes that data in small batches and keeps only what concerns your software: the service stays available, and the reported vulnerabilities are exactly the same.

    Fewer false alerts on containers

    A one-off command run in a temporary container (a migration, an admin script) is no longer reported as an unhealthy container: like continuous integration jobs, it is recognised as ephemeral and set aside.

  39. 3.8.13The cockpit stays responsive, even with many tabs open

    No more slowdowns when the cockpit stays open

    Every open cockpit tab kept server resources reserved for as long as its real-time connection lasted. With many tabs open at once, the cockpit could slow down and then show errors for everyone. Those resources are now released right away: opening the cockpit in several tabs no longer weighs on the service.

  40. 3.8.12A complete privacy policy, and account deletion explained

    The privacy policy covers the mobile app

    It now says what the iPhone, iPad and Android app sends and to whom: device registration to alert you, the notes you write, crash reports (which you can turn off in the app). Hosting providers and processors are named.

    Deleting your account, step by step

    A new documentation page, Delete your account, describes the steps from the cockpit or the app, what is erased and the cancellation window. That window is 14 days: the terms and the privacy policy said 30 days, they are corrected.

    Legal pages opened from the cockpit or the app now lead to the website, which holds the only up-to-date version.

  41. 3.8.11Security pass ahead of the app's arrival on the stores

    Strengthened security posture

    Before the mobile app goes on sale, a security review of the API and the app led to several hardening changes: fairer rate limits, quieter logs, and a protected store demo account. Nothing changes in how you use StatHall.

  42. 3.8.10The public site reads better, for you and for search engines

    Every page also exists as plain text

    Every page of the site — documentation, product pages, changelog, legal pages — is available as Markdown at the same address with a .md suffix (for example /en/docs/incidents.md): handy to paste a page into an assistant or read it outside a browser. The content is the same as the page, without the menu or the layout. A /llms.txt file lists the main pages.

    The language button no longer leads to a page that does not exist: when a page has no English version yet, it opens the closest section. The Unix servers, Agent and Super-dashboard pages are reachable from the Product menu. An unknown address now shows the site’s own error page, in the right language.

    Dates and releases you can follow

    Every documentation article shows when it was last updated, and so do the legal pages, in a consistent format. The changelog has an Atom feed (/en/changelog/feed.xml) to hear about new releases, and every release has its own anchor (/en/changelog/#v3.8.10). The home page now says that Docker container supervision is available — it has been since agent 1.1.

    The cockpit stays yours

    The application (the cockpit) now asks search engines and crawlers not to crawl or index it: only the public site is meant to show up in results.

    Lighter

    Pages are served compressed, and a font file that did not exist is no longer requested on every visit.

  43. 3.8.9Target lists load everywhere again

    Targets, health and apps show up without waiting

    In the mobile app, the Targets and Health screens and the app list could hang and then show “The server is taking too long to respond” when the fleet included an app with a very large crash history. Data access control is now computed once per request: these screens answer in a few tenths of a second, with no change to what anyone is allowed to see.

  44. 3.8.8Your collapsed groups follow you everywhere

    Catalogue folding is saved in your account

    The groups you collapse in the catalogue stay collapsed on all your browsers and devices: the state is saved in your account, not just in the open tab.

    A collapsed group flags its alerts

    A collapsed group shows how many of its servers and apps are alerting, subgroups included: collapsing a group no longer hides a problem.

  45. 3.8.7The catalogue remembers your collapsed groups

    Your groups stay the way you left them

    In the catalogue, the groups you collapse stay collapsed when you open a server or an app and come back, even after a reload. Each grouping mode keeps its own state. A search shows all its results, including inside a collapsed group, and the collapsed state returns when you clear the search.

  46. 3.8.6“Back” takes you where you came from

    A back button that knows where you came from

    The back arrow of a server, an app or a group now takes you to the page you came from: the inbox, the catalogue, a server’s team… It doesn’t step back tab by tab, and the button says where it goes. If you arrived through a direct link, it takes you to the catalogue or the group list.

  47. 3.8.5Duplicate access shows up

    Duplicate access is flagged

    When someone has access to a server or an app and the same access through a group, the Team tab flags it: “Duplicate of group”, with a button to remove the duplicate without changing their rights. The group’s Access tab also flags the access granted on its targets that the group already covers.

  48. 3.8.4A counter counts what the screen shows

    The anomaly count matches the inbox

    A target’s badge, the catalogue, the overview and the mobile app now count anomalies the way the inbox shows them: seven crashes of the same kind make one anomaly, “7 occurrences”. A target’s badge spells it out: “2 anomalies · 6 occurrences”.

    See who has access, and where it comes from

    A server’s or an app’s Team tab shows every person with their role and where their access comes from: granted on the target, or from a group. Group access is managed in the group, one click away from the target. A group’s Access tab shows how many targets it covers, what comes down from parent groups and the access granted target by target. These screens could also show up empty while access existed: that is fixed.

    A separate /home partition is finally measured

    On a machine whose /home lives on its own partition, the agent reported 0 % usage whatever the real fill level. Agent 1.3.6 measures every disk the way df does. Update it with sudo apt update && sudo apt install stathall-agent.

  49. 3.8.3Alerts calibrated type by type

    A disk at 90 % is no longer an emergency

    A disk 90 % full now opens an alert to handle within the day, not an “Act now” alert: that one comes at 95 %. When a disk fills up fast, the fill forecast warns you in time.

    App alerts are back to their own tuning

    Four rules installed by default were throwing off app detection: a rise in crashes could go unnoticed, and a passing dip in the rating raised an alert too easily. They are disabled: each alert type follows its own tuning again.

    The Rules screen explains what applies

    Without an active rule, StatHall’s calibrated thresholds apply. The rules remain available as templates, to adjust and preview before enabling them. A rule you had edited stays as it is.

  50. 3.8.2A machine's profile wins over a general rule

    The “CI runner” profile has the last word

    An alert rule defined for every server could still wake up the CPU alerts of a machine marked “CI runner”. The profile now takes precedence over that kind of general rule. A rule you wrote for that machine or its group still applies.

  51. 3.8.1The “CI runner” profile silences the CPU

    A runner no longer wakes anyone up on every build

    A default rule added a CPU alert at 85 % on every server, including those with the “CI runner” profile: a continuous-integration machine kept alerting during its builds. That rule is now disabled; the usual CPU thresholds apply, and the profile silences them as promised.

    Default rules that actually apply

    A “less than 200 MB” memory rule was displayed without ever watching anything: it is disabled, and the standard memory threshold covers that case. A rule you had edited stays as it is. The “Re-seed default rules” button on the Rules screen works again.

  52. 3.8.0Every alert says what and how much

    What, and how much

    An alert used to read “System metric high”. It now reads “Disk /: threshold exceeded” and shows the disk at 90.6% on a gauge with the 90% threshold marked. Every alert follows: a certificate shows its days left, a predicted saturation its deadline (“Full in 38 h”), an error burst its count against the usual, a failed service its name. Each alert carries the icon of what it concerns, in the list and in the detail, on the cockpit and on the phone.

    Leads about the right resource

    On a full disk, the suggested commands were the CPU’s. Each resource now has its own: what takes the space on that very disk, the memory actually available, processes killed for lack of memory. The next step shows right under the explanation.

    Continuous integration machines

    A runner maxes out its CPU on every job. Tick CI runner in the server’s Alerts tab: CPU and load alerts go quiet, everything else stays monitored. The cockpit suggests it when it sees GitLab Runner running. And the ephemeral containers of jobs no longer raise alerts, anywhere.

  53. 3.7.3Links also open the Android APK

    A StatHall link received by email opens the Android app when it is installed. That held for the Play Store version, not for the APK installed directly: Android did not recognise it and the link went to the browser. Both are now recognised.

  54. 3.7.2Filtering the inbox

    The right server, not the whole fleet

    On a server’s page, the “10 anomalies” badge opened the inbox on the anomalies of all your servers. It now leads to that server’s open anomalies, whatever their date: exactly what the badge counts.

    Type, group, target

    The inbox can be filtered by type (applications or servers), by group — sub-groups included — and by target. The target list follows your choice: under “Servers”, you will not be offered an application. It all lives in the page address, so a filtered view can be shared and pinned.

    On the phone, the same filters sit in the picker at the top of the inbox.

    Switching accounts on a phone

    Signing in to a second account on a phone already registered under another one failed at every sign-in — and the first account kept receiving its alerts on that phone. The phone now follows the signed-in account, and only that one.

  55. 3.7.0The third-party services nobody was watching

    A quota, a function, a shared project

    An app does not only fall over because of its own code. It falls because the email sending quota ran out — and the password reset is the one that did not go through. Because a server function is no longer deployed. Because the Supabase project two of your targets share went to sleep.

    Three signals the cockpit did not have. It has them now.

    Brevo: the wall ahead

    The new connector reads the sending credits you have left, once an hour, and warns twice: below 100 credits, then below 25. A single threshold would force a choice between warning too early and warning once it has already happened. When credits come back, the alert closes by itself.

    Supabase: your functions, and their errors

    The connector now watches each Edge Function — a failing function breaks a whole journey without the project’s health moving an inch — and counts the past hour’s error responses. No log content leaves your project: StatHall brings back a number, nothing else.

    One service, several targets

    Your app and its back-office live on the same Supabase project? Configure it once, then share it. The token stays in one place, collection runs once, and the alert opens on both sides — because it is on their own page that each person should read “the backend is paused”. The share grants no access: it shows the state of the common service, nothing more.

    On the mobile app

    A server outage no longer counts as an app crash. Those errors were already handled on screen by a banner and a retry; counting them as crashes skewed the crash-free rate — the very measure a release decision rests on.

  56. 3.6.0Forty alerts, three incidents

    The cockpit connects your alerts

    A filling disk makes a container unhealthy, which fails a probe, which floods the logs with errors. Until now that meant four alerts side by side, and it was up to you to work out which came first.

    StatHall does it for you. The new Incidents screen groups what belongs to one story, names the fact that most likely set it off, and tells you what that naming is worth: likely root, plausible root, or needs a call when several starting points are possible.

    “This crash — who is it hitting?”

    A crash almost never hits everyone. The cockpit now reads the breakdown by OS version, device model and app release, and compares it to what each value actually weighs. The table spells the gap out in words — “six times more” — and always says what it compares against: measured sessions, or the target’s other crashes.

    A minimum count applies: two events on a rare device are not enough to claim anything.

    Across targets

    When an app depends on a server — you declared it in its links — an app symptom and a server anomaly overlapping in time are brought together. The symptom is in the app, the cause is on the other side: the link nothing carried before.

    Your verdict counts, and it is kept

    Confirm the root, dismiss it, detach a fact that does not belong. The calculation runs every twenty minutes; it refreshes the evidence and never your decision.

    On the alert list, the Roots only checkbox hides what an incident already explains — and leaves everything it does not.

    The screen exists on the cockpit and on the phone: it is on call, at 2 a.m., that “which one started?” matters most.

  57. 3.5.0Detection now looks at the right measurement

    Ten weeks of crashes, not one alert

    An app monitored by the cockpit dropped from 89% to 58% crash-free sessions overnight, and stayed there for ten weeks across four releases. Over that period StatHall ingested 78 million events for that app — and opened no technical alert at all. The only alerts it raised were about the store rating.

    The reason fits in one sentence: the cockpit was watching the crash rate published by the store, not the one measured by Sentry. On a cross-platform app, the store figure covers Android only, and it read 99% while the real measurement sat at 58%.

    The crash rate is now read per release

    The cockpit now ingests Sentry’s measurement as Sentry produces it: day by day, and release by release. That was the missing dimension, because it is the one you act on — you fix a release, or you pull a release.

    A lasting degradation now raises an alert

    Detection used to look for spikes: a sudden gap against the previous days. A degradation that settles in produces none — after two weeks, it is the new normal.

    A new rule watches the level: below 95% crash-free sessions on a seven-day average, the alert stays open for as long as it lasts, at P0, and names the release involved. It only fires for releases that carry real weight in the fleet: an old version used by a handful of devices raises nothing.

    Review alerts stop crying wolf

    A dropping rating could open a P0 alert — the highest severity — on a single day’s average. Three changes:

    • it now caps at P1: a store rating plays out on acquisition, not on service;
    • a day with fewer than five reviews is no longer a measurement;
    • only reviews that talk about the app count. On a commerce app, reviews about stock, delivery or customer service are excluded: an engineering team cannot act on them.

    A release without a measurement is no longer called “healthy”

    When no crash data is available for a release, its card reads unknown instead of “healthy”. The cockpit no longer states what it has not verified.

    The detection rules on screen actually apply

    The rules screen listed thresholds that were never applied: a threshold written “95 %” was not readable by the engine, and five rules named detectors that did not exist. Rules now carry an executable value, the screen shows what is really applied — or flags a threshold that is not — and an unknown type is rejected on save.

  58. 3.4.0An alert now says when it was measured

    A resolved alert no longer reads like a live incident

    A “Security updates pending” alert opened at midnight, resolved by the machine at 6:55 am when it applied the fix on its own — and read back at 9:40 pm as if it were still open, severity and urgency included.

    The card now states its state: resolved or not, how long ago, and by what (“fixes applied”, “service back up”…). The “open for” duration freezes at closing time instead of growing on its own.

    The figures attached to an alert come from the right moment

    Under the heading “Other series at the same moment”, the cockpit showed the readings from now, even on yesterday’s alert. You read a swap at 99.88% next to a package measured 21 hours earlier, and looked for a link that did not exist.

    Those series are now looked up around the moment of the measurement, with their timestamp in the machine’s own timezone. When they do not come from there, the gap is spelled out.

    Tonight’s security fix no longer wakes anyone

    A machine that applies its own security fixes deserves its night. An alert is no longer opened for a fix published a few hours ago: what matters is the age of the oldest unapplied fix, not the number of packages. And successful runs of automatic patching are no longer counted as relapses — three successes in a row used to show up as “already seen 3 times this month”.

    Clicking a notification opened the machine’s screen without pointing at anything. If the alert had closed in the meantime, there was no way left to find it. The link now opens the alert itself, closed or not. Alerts that fade out on their own are announced as resolved, instead of leaving a notification with no follow-up.

    The phone shows what the cockpit shows

    Same account, two screens, two truths: the phone’s inbox ignored acknowledged alerts and those resolved in the last 24 hours. It now shows the same scope as the cockpit, with a “Resolved” badge on what is already behind you.

    Less noise in logs, and a vulnerability counter that means something

    A packet blocked by the firewall and a request refused by a web server are defences that worked: they no longer count as errors in the excerpts attached to an alert — they took nine lines out of ten there.

    As for the Security screen, it announced “945 open vulnerabilities” on an up-to-date machine. Those were advisories the distribution vendor reviewed and decided not to fix — every Debian machine carries about a thousand. The counter now shows what is left to handle; the rest is still stated, in its place.

  59. 3.3.0The bottom of lists, sessions that last, and AI that names itself

    Scrolling finally reaches the bottom

    On the phone, the last item in a list hid under the tab bar. Not always: depending on the screen, the iPhone model, the orientation. Often enough that a “Retry” button sat out of reach whenever a list failed to load.

    The bar is translucent and content passes beneath it — that is deliberate, you should sense what is scrolling behind the glass. In exchange, every list has to clear the height it gives up. It now measures that height instead of assuming it: the value follows the bar, whether an iPhone adds its home indicator, a full-screen sheet has no bar at all, or an Android device has neither.

    The cockpit no longer logs you out mid-sentence

    A session lasted seven days from sign-in, then stopped — in the middle of a sentence, with no warning. It now extends itself for as long as you keep using it, up to a month. Past that, you sign in again: a session should not live forever.

    The app stops asking for your credentials for no reason

    It also works in the background, refreshing your inbox before you open the screen. That background work and the visible app could renew their access in the same second — and the server, which guards against token theft, read the coincidence as an attack. It can now tell two hands on the same door from a break-in.

    You will always know what the AI wrote

    AI is one of StatHall’s strengths, and it was invisible: a summary written by a model and a computed figure looked alike. Every text that comes from an AI now carries its mark, and says where it drew its material from.

    Three distinct marks, because a single one would lie. AI when a model wrote the text. AI search when the machine understands your question without writing anything. For your AI on the text you copy into the assistant of your choice. And no mark where there is no AI — an alert’s “Understand and act” block is written by hand, once, and will stay that way.

    When the assistant cannot write — provider unavailable, monthly budget reached — it hands you the documentation passages as they are, and says so. No “AI” mark on text nobody generated.

    The documentation answers inside ⌘K

    Quick search looked word for word through your targets. Typing “ANR” returned nothing unless an app was named that. It now queries the documentation too, by meaning: the same question finds the article on stability, and “ask the assistant” is one key away.

    Your data stays put: only the public documentation is indexed this way. Your targets and alerts keep their instant search, on your machine.

  60. 3.2.0The phone no longer just reports

    Understanding an alert without opening your laptop

    A notification arrives at two in the morning: container_unhealthy. The app could show it, acknowledge it, snooze it, resolve it. It could not say what it meant.

    The cockpit’s “Understand and act” block is now on the phone, whole: what the alert means, where to start, the measured facts, the diagnostic leads with the read-only command that checks each one — and the complete text to paste into the assistant of your choice, carrying the machine’s context and the recent logs that everyone forgets when copying an alert by hand.

    The suggested commands only read. StatHall observes; it runs nothing on your machines, and the app only lets you copy them.

    Leaving a word from the field

    Acknowledging an alert without writing anything left the team with an incident marked “handled” without knowing by whom or why. Notes now exist in the app: “looking into it, it’s the 3 a.m. backup running” is written from a train platform and read from the office, in the same anomaly record. Everyone can delete their own notes, and only their own.

    Choosing what the lists show

    For several versions the cockpit has separated “what I own”, “shared with me”, “everything”, the demos and the whole estate. The phone mixed them all. The target scope is now in the app, on the inbox and on the target list.

    A scope stays what it has always been: a display filter. It grants no permission and removes none, and the choices offered are the ones the server announces — not a guess made on the phone.

    A resolved alert finally says what resolved it

    Since the previous version the inbox keeps what resolved itself over the last twenty-four hours. The app showed those rows, but not the reason: “updates applied”, “container recovered”, “timer ran”. It shows it now, as the cockpit does.

    And in English

    Alert explanations came from the monitoring’s type catalogue, which existed only in French: an English cockpit displayed French sentences. Both languages are now in it, and the reader decides — on the web as on the phone.

  61. 3.1.3What fixed itself is still there to see

    An alert settled overnight no longer vanishes

    At 3:30 this morning an alert went out by e-mail: “security updates pending”. At 6:08 the server applied the packages on its own, and the alert closed two minutes later. By 9:00 the inbox showed nothing at all: the e-mail pointed to an alert that could not be found, and nothing said it had been dealt with.

    The inbox now shows, by default, what needs action and what settled in the last twenty-four hours. Settled rows carry a “Settled” pill and say what fixed the incident — “updates applied”, “container recovered”, “back to normal”. A finished incident has no urgency, so the red pill steps aside. The “Open” filter is still one click away for anyone who wants the to-do list alone.

    A full swap is not a saturation

    An alert reported that a server had filled its swap space. It stayed open for thirty-eight hours without telling anyone anything: the machine had no swapping in flight, no memory pressure, and nearly ten gigabytes of RAM available. It could not close on its own either — swap does not empty by itself.

    That alert no longer fires by default. What hurts is the swap rate, which keeps its thresholds and did speak up on the days the machine genuinely struggled. The measurement stays visible in the charts, and can be turned back on per server.

    Less noise on continuous integration machines

    A build server logs as an error that an image layer is already being written — then retries and succeeds. A single build produces dozens of those per minute, which opened an alert every time: seven in six days, with no outage behind them. Those lines join the known noise, kept out of error-burst counting while remaining visible in the logs.

  62. 3.1.2One alert per incident, and nothing left from the previous account

    One incident, one alert

    A container that crashes on startup restarts in a loop — and between two crashes it is “running” for a handful of seconds. StatHall took that instant for a recovery: it closed the alert, reopened it on the next restart, and started over. A single overnight outage produced fifty-four alerts, as many e-mails, and an empty inbox by the time you looked — the alert the message pointed to had just been closed.

    Now, as long as the restart counter keeps climbing, the incident stays open. Recovery is established over time: the container has to run, healthy, for ten minutes. A service whose health check goes green without restarting still closes its alert immediately, as before.

    A defence that works is not an outage

    Bots probing /.env or /.git on a public site are turned away by the web server’s configuration — which logs an error line for every refusal. StatHall counted those lines as application errors and opened an alert: fourteen in four days, on a site that was perfectly healthy.

    Deliberate refusals no longer count towards error bursts. They remain visible in the logs, still count as volume — a flood of scans is still a flood — and the alert now states how many lines were set aside: a silent filter ends up being accused of lying.

    Switching accounts no longer exposes the previous one

    The cockpit cleared its data on sign-out — the one moment that is never guaranteed. An expired session, a closed tab, a lost connection, and the next account found the previous one’s targets, favourites and history still on screen until a manual refresh.

    The cleanup now happens on both sides: when a session ends, and when another one opens for someone else. Theme, language and layout stay — those are your device preferences, not account data.

  63. 3.1.1An alert you can read without squinting

    The detail gets its space back

    In the inbox, the list and the detail panel split the screen the wrong way round: the list, which carries little more than a title and a date, took up three quarters; the detail — what the measurement means, the facts, the diagnostic leads and their commands — was squeezed into a narrow column where labels overlapped values.

    The proportions are now reversed. The detail panel scrolls on its own, and the three actions — acknowledge, snooze, resolve — sit next to the title instead of at the bottom of a long page.

    Facts written to be read

    The “Understand and act” block still showed leftovers from the database: a braced dictionary for a threshold, a full technical timestamp, flags that only the engine cares about. It now reads “Threshold: P2 ≥ 90”, “Last seen alive: 07/09/2026 21:52”, lists the packages concerned and translates states. What teaches a reader nothing — the statistical parameters — is gone.

    Help

    The keyboard-shortcuts dialog opened behind the help panel. The assistant’s wait, meanwhile, was invisible: it now occupies the place of the answer. And the search field waits a fraction of a second before searching, instead of querying the engine on every keystroke.

  64. 3.1.0The assistant's configuration is now set from the cockpit

    No more touching the server

    The key that powers the documentation assistant is now set in Administration → System, along with its provider, model and monthly cap. Until now this required server access, a file editor and a redeployment — for a value that takes ten seconds to change.

    Once saved, the key is never shown again: the screen displays only its last four characters, enough to recognise it without reading it. It is stored encrypted, like your connector credentials.

    Restricted to instance administrators. Every change is recorded in the audit log — which key, never its value.

    For those self-hosting StatHall, configuration through environment variables keeps working: it is the default when nothing is set in the cockpit.

  65. 3.0.1Help, revised after your first feedback

    One question mark, not two

    There were two, side by side, for two different things: help and keyboard shortcuts. Only one remains, bottom right — where help is looked for. Shortcuts are now an entry in the panel, and the ? key still opens them.

    The assistant first, not behind a third tab

    The panel now opens on the question field, cursor inside, with three suggested questions. The article for the screen you are on, and the rest of the documentation, follow for those who prefer reading. The same field filters articles as you type and asks the assistant when you submit.

    Answers that no longer stop halfway

    Asked “how do I add a target?”, the assistant answered for an application and said nothing about Unix servers — even though it had found the passage. It now returns the three most relevant excerpts, each kept short.

    Also: waiting is now named instead of showing an empty list, and scrollbars no longer clash with the dark background.

  66. 3.0.0Your cloud backends, an app that hands over to the cockpit, and help that answers

    Supervising a backend that runs on none of your machines

    StatHall now watches Supabase and Cloudflare, alongside your applications and servers.

    The alert that was missing most: a Supabase project on the free tier is paused after a period without traffic. The application living on it goes down, and until now nothing told you. That is now a P1 alert. Add to it service-by-service health (database, auth, API, storage, realtime), the state of the latest Cloudflare Pages deployment, zone traffic, and the validity of the token itself — an expired token stops collection silently.

    Both connectors install on an application as well as on a server. That is new: until this release, a server target could carry no connector at all.

    Documentation online, and help inside the cockpit

    Documentation now lives on the site, at stathall.com/docs: creating a target, installing the agent, wiring each connector, choosing and configuring an AI, receiving the right alerts.

    In the cockpit, a ? button opens the help for the screen you are on. The same panel searches the whole documentation, and answers a question in plain language: “how do I create a target?”, “where do I find my Sentry token?”. Answers cite their sources, and the assistant says when it does not know rather than inventing. It reads none of your data — only the documentation.

    Configuring a target, without the maze

    The configuration screen stacked two navigation bars, repeated the target name and offered a way back to the page you were already on. Configuration is now a tab of the target, with its settings grouped into named sections: the target, data, artificial intelligence, access, and what cannot be undone.

    From the mobile app

    The app stays deliberately concise. It now knows how to hand over: from a target, a link opens the cockpit on the same page, and a server’s card names what the cockpit shows in addition — vulnerabilities and fixes, filterable logs, configuration.

    Along the way, a fix for those who host StatHall themselves: links to the cockpit and to the legal pages were refused without a word. They work.

  67. v2.9.1An alert that tells the truth

    Fixed

    • A busy core no longer raises an alert. We were getting four “CPU at 92 %” alerts for a single event, on a machine that was doing fine: each one was about one core of a sixteen-core server. A saturated core is a task doing its job — a build, a backup — not an incident. StatHall now looks at the machine, and keeps the cores for charts.
    • A one-minute spike no longer wakes anyone. A single reading above the threshold used to open an alert that lived for a quarter of an hour. The breach must now hold for a few minutes — except for a disk fault, which alerts immediately.
    • The alert finally says whether it is a spike or a sustained problem, along with the machine’s core count.
    • Mobile app: the bottom of lists is no longer hidden by the tab bar, and a snoozed anomaly can be found again — the “Snoozed” and “Resolved” filters were missing.

    Added

    • “Understand and act”, on every anomaly. The screen explains what the alert means, suggests where to look with the read-only command that checks it, and gives you a ready-to-copy prompt for the AI assistant of your choice — with the context already in it: the machine, the measurements, how long the threshold was crossed, recent logs. Those logs are scrubbed before being attached: no credential leaves with them.

    StatHall observes, it does not administer: the suggested commands are reads, for you to run yourself. Nothing is ever executed remotely.

  68. v2.9.0One menu, and nothing hiding any more

    Added

    • A single, labelled menu. The icon rail, the admin menu and the mobile menu are now one collapsible sidebar, with words instead of pictograms to guess at. Administration is a section within it, marked by a purple rule.
    • You can create your own targets. Adding an app or putting a machine under supervision no longer requires an admin account. A fair-use cap applies, shown plainly, and the screen tells you where you stand — instead of greying out a button without explanation. A brand-new account is no longer stuck in a dead end: it starts by creating its first target.
    • All your AI keys in one place. A “Settings → Artificial intelligence” screen shows which targets are covered, by which provider, with this month’s usage — and lets you apply a key to several targets at once. Fine-grained configuration stays within each target.
    • A “Scope” filter, at the foot of the menu. Owned, Team, Everything — plus Demo and Instance for administrators. It replaces an admin-only filter that sorted targets by the role of their owner: a machine shared with you could end up appearing nowhere. By default you now see what you own and what has been shared with you, and when a screen is empty it tells you which filter is emptying it.
    • A site map. It lists every screen, including those your permissions hide — with the reason. A missing feature no longer reads as “it’s gone”.
    • Screens that were missing: deployment history, license status, catch-up jobs, the failed-task queue, account creation, changing your password without going through “forgot password”, and push notification settings without having installed the mobile app.

    Changed

    • “Account” becomes “Settings”, split into eight screens instead of one long page: profile, security, notifications, AI, privacy, targets, groups, plan. Three screens that could only be reached by knowing their address (plan, usage, access code) now have a place in the menu.
    • The fair-use cap moves from 3 to 10 targets, and no longer applies at all to a self-hosted install. Three was a leftover from a pricing grid that no longer exists: a mini-server, a VPS and two apps already make four. When you host StatHall yourself, no cap applies — it is your hardware.
    • An account with no target keeps its menu. It used to be confined to four pages. It still lands on a welcome screen offering to create a first target, but everything else stays open to it.
    • Every screen has one address, and only one. Four pages existed twice. Your bookmarks on the old addresses keep working.
    • ⌘K search opens over the page instead of sitting in the top bar, and now knows every screen rather than six fixed shortcuts.
    • The addresses of your working pages — inbox, overview, activity, AI summary, a target’s pages — have not changed.

    Fixed

    • Saving an AI key failed in some configurations.
    • The alert rules page showed for everyone, while only administration can change them.
    • Signing out from the two-factor enrolment screen led to a page not found.
    • An account created from the administration screen could not sign in. It was asked for an e-mail verification that had never been sent. An account created by an administrator, with its password, is now valid straight away.
    • The overview ignored the scope filter: its grid emptied while the counters above it kept counting the whole fleet.
    • A server’s monitoring rules are now checked as you type. A misspelled task name or an inconsistent threshold used to silently disable an alert; it is now refused, with the reason.
  69. v2.8.7Sharing a group now shares what's inside it

    Fixed

    • Being a group co-owner gave no access to its servers. The group showed up in the list, but its contents stayed empty — not in the catalogue, not in the group filter. Sharing covered the folder and stopped there, when the contents are exactly what you mean to share. Access granted on a group now opens its member targets, and flows down to sub-groups wherever inheritance is enabled. Read access stays read-only; only co-ownership allows changes. Ownership of a target is never passed on through a group: deleting or transferring one remains the owner’s call.
    • You couldn’t see who a group was shared with. The list showed numbers (“#1”, “#6”) instead of addresses, and the menu for granting access stayed empty: it relied on the full account directory, which is admin-only. Addresses now show for everyone, and the menu offers the people you already work with — without ever exposing the directory.
    • A group co-owner could do nothing with it. They saw the group but couldn’t rename it, file a target into it, or see who it was shared with. Co-ownership now allows those; deleting the group stays with its owner.
    • Filing a target into a group now requires the right to manage it. Read access alone no longer lets you share it that way.
    • Automatic sharing of a new group is read-only. Creating a group still shares it with the co-owners of your targets, but as readers: you decide who gets to change it.
    • The admin filter no longer hides your own targets. The “Team” scope only showed targets owned by an administrator account: a machine you personally co-own dropped out of it, disappearing from the catalogue, the overview and its group. An admin filter now never removes what you hold a named right on. And when a screen genuinely is emptied by that filter, it says so and offers to widen it in one click.
  70. v2.8.6Creating a group now works for everyone

    Fixed

    • Creating a group failed with an error for every non-admin account. The screen returned a technical error with no explanation. The permission had been opened on the application side in the previous release, but the database’s tenant-isolation rule still refused the write — a check that looked for the very row being created. Administrators were unaffected, which is what kept the defect invisible until a user tried. Organising targets into groups now works for everyone, and nobody can create a group on someone else’s behalf or file it under another person’s tree.
    • A group’s URL slug only filled in on the first letter. Typing “Sebastien” suggested just s. It now follows what you type, handles accents (“Sébastien” gives sebastien), and hands control back if you clear the field after editing it.

    Added

    • A group is now shared with the co-owners of its machines. Until now a co-owner could see the machines but not the groups organising them, so co-ownership stopped half-way. Read-only access is unaffected — it grants access to a machine, not to its owner’s filing.
  71. v2.8.5No more alert noise on build servers

    Fixed

    • A continuous-integration server no longer raises an alert for every finished job. Each build job runs in a throwaway container, created for the occasion and destroyed afterwards. StatHall treated its disappearance as a service outage, so it opened a high-severity alert — which could never close, since the container was gone. On a build machine that meant one more permanent alert every day. StatHall now tells a service, meant to stay alive, from a throwaway container that simply finished its work, and no longer counts a requested shutdown as an incident.
    • An alert whose container is gone now closes. Including when it disappeared while the agent was stopped: StatHall reconciles open alerts against the actual list of containers. It deliberately closes nothing without a fresh list — a silent machine must not have its incidents quietly evaporate.

    Added

    • Bulk declaration of availability probes. Probes check, from the outside, that a site answers the expected status code and how many days are left on its certificate. They had to be created one at a time; a single command now declares them all, leaving existing ones untouched. The expected status is explicit per domain: a probe that accepts “any valid response” would let an unexpected redirect or an error page through.
  72. v2.8.4Gauges that move, a Security tab in English, a “reclaimable” that says where

    Fixed

    • A machine’s gauges now refresh on their own. On a server page, the gauges (CPU, memory, disk, network) stayed frozen on the values loaded when the page was opened: the available memory shown could be hours old. They now follow the agent’s reporting rhythm, once a minute. The timestamp of the most recent data point is shown above the gauges, in amber when it gets old.
    • A server’s “Security” tab now displays in English (and French). It showed its internal technical identifiers instead of the labels.
    • A freshly created server no longer claims “0 vulnerabilities”. Until the software inventory arrives, the counters show ”—”: nobody has looked yet, which is not the same as “nothing to report”.

    Added

    • “Reclaimable Docker space” now says where. Clicking the tile opens the detail: how much per family (images, containers, volumes, build cache), the matching cleanup command, and the largest unused objects with their size. The figure itself was wrong: it only counted the build cache and ignored images with no container, orphaned volumes and stopped containers — most of what a cleanup actually frees. The per-object list requires agent 1.3.2.
    • Memory shows the total. “36.8 GiB available of 55.0 GiB” instead of a lone value that could not be checked against the percentage right above it.
  73. v2.8.3Three screens that refused to open

    Fixed

    • A server’s AI diagnosis, the Notifications screen and the Security tab were unusable. The six tables added in 2.8.0 were protected by the database’s multi-tenant isolation — but without the rule that says who may see what. A protected table with no rule denies everything: the diagnosis returned an error behind a “Diagnosis unavailable” message. No data was ever exposed — the fault closes, it does not open.
    • A server’s AI key can finally be entered from the console. A server’s AI tab only set the analysis frequency: there was no field for the key, so no analysis was possible. Keys stay per target, so a client application never pays for a server’s analysis.
    • The Security tab was showing its technical identifier instead of its name.
  74. v2.8.2Vulnerability watch finally gets its data

    What changes for you

    • Your machines’ software inventory now actually reaches StatHall. The agent was building its package inventory just fine — and sending it to a route it never called, because of a ceiling in its protocol version negotiation. The Security tab therefore stayed empty, with an active agent, normal telemetry and no error message at all — the worst kind of failure: a feature that believes it shipped. Found while putting three real machines under supervision.

    Update the agent to benefit:

    sudo apt update && sudo apt install stathall-agent
    
  75. v2.8.1Alerts you can understand without opening the cockpit

    What changes for you

    • Your alerts now answer the four questions you actually ask. Who is affected — “Server CMJ Test Systems”, no longer “this app” for a Unix machine. How urgent — act now, act today, or schedule it. How much effort — quick fix, needs diagnosis, or depends on someone else. And is this new — “already happened 3 times in the last 30 days, open for 5 h”. All of it before any measured value: the numbers are evidence, not the message.
    • Urgency is no longer confused with severity. A distribution past end of life is critical and is fixed by a planned migration; a disk filling up within twelve hours is fixed right now. The two are stated separately, so a critical alert doesn’t wake you when it needn’t.
    • Every alert type explains what it means and what to do, one sentence each — “a scheduled job has not run for too long, typically a backup that stopped working”, followed by the command to check it. Commands are shown, never executed: StatHall watches, it does not administer.
    • The email subject is enough to triage your inbox: [P0] vps-cmj · Disk filling up — /mnt/data · Act now. Before, every subject looked alike, whether it was a full disk, an expired certificate or a dead backup.
    • The grouped digest puts what needs immediate action first, flagged with a bolt — a critical but schedulable issue no longer buries a major one that needs handling within the hour.
    • Telegram gets to the point: what and where on the first line, which is all you read on a lock screen.
    • Putting a machine under supervision can now be done from the command line, with its monitoring rules (backup freshness, machine-specific thresholds) set in the same step — useful for a fleet, and for self-hosting.

    Fixed

    • The daily health snapshot had been failing every night since it shipped, with nothing to report it.
  76. v2.8.0Your servers warn you before they break

    What changes for you

    • StatHall now forecasts saturation instead of reporting it. A disk, inode table or memory pool that keeps filling up raises an alert before it is full, with a figure you can act on (“full in about 38 hours”) and enough detail to judge the forecast. The method is robust to spikes: a build cache that swells then drops raises nothing.
    • A backup that stops running is finally detected. Until now a scheduled job that failed raised an alert; a job that stopped firing altogether — disabled, broken schedule, machine off at the time — went unnoticed. That is the case you discover on the day you need the backup.
    • Alerts reach you on Telegram or your own webhook. A new “Notifications” screen in your account: you enter your bot token or your URL, pick the scope (all my targets, all my servers, a group, a single target), the minimum severity, your quiet hours — plus an automatic follow-up if a critical alert stays unacknowledged. A “Test” button sends a real message, right away. This works for every target, mobile apps included.
    • A Security tab per server. Known vulnerabilities in your installed packages, named, with severity and the version that fixes them; pending updates; distribution end of life; outdated container images. And because a server always carries vulnerabilities with no fix available, what is actionable comes first — the rest is dismissed explicitly, with a written reason. A CI pipeline can also push its application dependency inventory (SBOM) and have it tracked in the same place.
    • The AI diagnosis actually looks at the machine. It now receives its identity, anomalies, forecasts, the week’s metrics, scheduled jobs, logs and vulnerabilities — where it used to see only an anomaly counter. The commands it suggests are displayed, never executed: StatHall watches, it does not administer. And a machine where nothing changed costs nothing to analyse again.
    • The Unix agent 1.3 sees far more. Disk space in gigabytes rather than percentages alone, drive temperatures and SMART health, per-core CPU, hypervisor steal time on virtualised servers, per-container Docker usage and the space taken by images and build caches, the full list of available updates, and a filter to drop repetitive log noise.
    • Thirty days of history, visible. A server’s charts were locked to 24 hours while the data is kept far longer: a 24 h / 7 days / 30 days selector arrives.

    Fixed

    • A server with an open disk error showed a technical score of 100 out of 100.
    • The log-derived alerts shipped in early September — disk error, SSH brute-force, process crash — were never pushed to mobile. Now they are.
    • An application’s AI key could be consumed, and its quota billed, to analyse a server.
    • A server’s logs and AI diagnosis were unreachable from the sidebar.

    The agent updates through apt upgrade stathall-agent once the new version is published to the repository.

  77. v2.7.8The overview finally opens from mobile

    What changes for you

    • The overview is reachable from the mobile app. The screen that gathers all your targets, their health and their “hosted on” links refused to open on a phone: it expected a browser session, which the app does not have. It showed an “unavailable” message instead — on the one screen that gives you the whole picture.
    • The iOS “Update” button no longer leads nowhere. When a version of the app becomes too old to talk to the server, the update screen offered an App Store link that did not exist. It now offers nothing until the iOS listing is published, rather than opening a dead page.

    No app update is needed: these fixes take effect on your next session.

  78. v2.7.7The mobile app finally gets the right numbers

    What changes for you

    • Quiet hours in your own time zone: the “do not disturb” window for your notifications was evaluated in UTC, never in your local time. A “22:00 → 07:00” set from France actually ran from midnight to nine in the morning. It now follows your device’s time.
    • The “Anomaly” filter in the notification log only showed alerts: acknowledgements and resolutions, though duly received, vanished from it. All three now appear.
    • Your target list carries its health status — it was the only view in the product that would not tell you the state of what it listed — and the number of users hit by a crash is no longer always zero.
    • Weekly summary history is in the right order: the most recent one comes first, including when several weeks were generated in one go.
    • The activity feed is translated: its labels were composed in French on the server and shown as-is in the English app. It can also be read over 7 or 30 days, instead of a fixed week.

    No app update is needed: these fixes take effect on your next session.

  79. v2.7.6Much sharper review categories

    What changes for you

    • Review categories are now decided by the language model configured on your app — the very one already writing your weekly summaries. On our reference corpus, wrong labels drop from 22 to 6 and missed categories from 103 to 40; two categories, “performance” and “UX”, were previously never detected at all.
    • Far faster catch-up: analysing one review used to take a dozen seconds, it now takes a fraction of a second. A backlog of several thousand reviews is cleared in about an hour instead of several days.
    • No key, no change: an app with no language model configured — or whose monthly budget is spent — keeps being analysed by the local classifier, with no interruption and nothing lost.
  80. v2.7.5Sharper review tagging

    What changes for you

    • Review labels: automatic classification used to keep labels on thin evidence — a review reporting a crash also came back tagged “pricing” or “delivery”. The confidence threshold has been raised: about two labels per review now instead of four, with far less off-topic noise. Reviews already analysed were updated to the new threshold.
    • Some reviews now carry no label at all: that is intended. When no category stands out clearly, showing nothing beats showing a misleading label — and the filters on the Reviews page get more trustworthy.
    • Under the hood: reviews for which the model kept no category were re-analysed on every cycle, endlessly. Fixed — which also clears the analysis backlog faster.
  81. v2.7.4Refreshed demo workspace

    What changes for you

    • Demo apps and servers: the demo dataset can now be regenerated on demand for a given date. It tells a complete four-month story — a regression shipped in an update, the wave of negative reviews that follows, the fix, then the return to normal — with multilingual reviews, crashes, anomalies, versions and server logs that all line up.
    • Demo AI summaries: demo reviews go through the very same processing as your real apps — review and crash embeddings, automatic tagging, matching a crash with the reviews describing it, and weekly summaries generated by the configured language model.
    • Crashes reported by several sources: merging the same crash seen by two tools (say Sentry and Crashlytics) failed silently once both reports had been embedded. Fixed.
  82. v2.7.3Reliable Agent tab, readable server cards

    What changes for you

    • Servers › Settings › Agent: once an agent had connected, the tab wrongly showed “No active token” and offered to generate a new one — which would have cut off the running agent. The active token shows again (last seen, host, IP address, agent version), and a read error is now reported as such, with a Retry button.
    • Servers › Overview: on mid-width screens, the “System” and “Agent status” cards no longer overlap their labels — columns adapt to the card width and the hostname stays readable.
  83. v2.7.2Clearer log filters

    What changes for you

    • Servers › Logs: an enabled filter is now obvious at a glance, including the INFO and DEBUG levels — check mark, solid border and tinted background on every active chip. The Events page filters get the same treatment.
    • Interface: tinted backgrounds and borders on badges, banners and button hovers now render as intended, in light and dark mode (the style engine was silently dropping them).
  84. v2.7.1Technical fix on server ingestion state

    What changes for you

    • Servers: internal fix to how the ingestion state is recorded (no visible change; self-diagnostic data is now stored cleanly).
  85. v2.7.0Reliable server logs: Docker, files, and a page that explains what it shows

    What changes for you

    • Server Logs page: it no longer loads forever. When the list is empty it tells you why — agent offline or not installed yet, agent to update, reporting threshold too high, collection in trouble, or simply filters that are too narrow — and offers the useful action. An error shows as an error with a Retry button; a slow request can be cancelled; a long list continues with “Load more” instead of being cut silently.
    • More log sources (Unix agent 1.2.0): besides journald, logs from Docker containers and application files under /var/log (nginx, PostgreSQL, MySQL, Redis, MongoDB, PHP-FPM, fail2ban, unattended upgrades…) now reach the cockpit, filterable by source. The agent reports what it cannot read instead of staying silent.
    • New alerts derived from logs: error burst on a service, abnormal log volume, kernel disk errors, repeated sudo failures, massive SSH attempts, process crash, degraded log collection. They close on their own once the situation is back to normal.
    • Unix agent 1.2.0: leaner and sturdier journald reading (bounded memory, progressive catch-up after an outage, no more logs missed because of the time zone or long messages), finer grouping of similar lines, diagnostics visible in the cockpit. Update with apt upgrade, no configuration change; 1.1 agents keep working.
    • Cockpit: a tab left open for days now updates itself to the next version, and server pages no longer get stuck loading when a piece of data is missing.
  86. v2.6.5No more false “no worker” alert during an update

    What changes for you

    • System alerts: updating the instance recreates its workers in under a minute; the “no worker responds” alert is now raised only if the outage lasts at least three minutes.
    • Agents: Unix agent 1.1.1 is announced (configurable log threshold, detailed units).
  87. v2.6.4Manage an app's or server's groups from its own page

    What changes for you

    • Groups from the target: every application and server header now shows its groups and lets you add or remove them directly, without opening the groups administration. Only groups you can manage are offered.
  88. v2.6.3Fix: the server Logs page was stuck in a request loop

    What changes for you

    • Server logs: the page kept re-issuing the same request and stayed on its loading indicator, as if logs had stopped arriving. Fixed: the requested period is pinned to the minute and the page renders immediately.
  89. v2.6.2Reliable, monitored backups, an alert for chronic ANR rates, an up-to-date home page

    What changes for you

    • Backups: the hosted instance’s nightly backup only produced empty files. The script is rewritten (the file is written only after success, rotation is guaranteed) and StatHall now watches itself: a missing, failed, empty or too-old backup raises a system alert by e-mail and in the app.
    • Chronic ANR: a new anomaly flags an Android app whose user-perceived ANR rate stays above Google Play’s “bad behaviour” threshold (0.47%), even without a spike. Play figures delivered five days late are now taken into account.
    • Website: the home page reflects what is actually available (Unix servers, websites) and no longer stays cached after an update.
  90. v2.6.1Fix: server agents were rejected (HTTP 500) by the rate limiter

    What changes for you

    • Server agents report their metrics again. An incompatibility between our rate limiter and the ingestion API returned a 500 error on every agent push, even after the data had been stored, so the agent kept replaying the same batch forever. Fixed, with a test that now exercises the API with the rate limiter enabled so it cannot regress silently.
    • The same defect affected password change, e-mail verification, account deletion cancellation, rule preview and probe actions: all fixed.

    Nothing to do on your side: the fix is server-side.

  91. v2.6.0End-to-end server monitoring, reliable detection, a real-time cockpit and an offline-capable mobile app

    What changes for you

    This release bundles three streams: detection (Android ANR increases are now tracked and notified, like crash-free drops, even when Google publishes its figures two days late), end-to-end server monitoring, and a real-time cockpit.

    Your servers, actually monitored

    • Agent 1.1: twenty-plus metrics (CPU, iowait, memory, swap, load, disk and inodes per mount point, network, I/O, system pressure), Docker container state, systemd timers (your backups), reboot required, out-of-memory kills, top 5 processes. Same installation, transparent upgrade.
    • HTTP / TCP / TLS probes run from the cockpit: is your site up, how fast, and in how many days does its certificate expire? A failing probe or an expiring certificate becomes an anomaly notified by email and on mobile.
    • Silent agent = alert: a server that stops reporting is flagged (P1 then P0) instead of merely changing colour.
    • Per-server alert thresholds, push cadence driven by the cockpit, bounded data retention.

    A cockpit that updates itself

    • Overview: every target, apps and servers, sorted by priority, with the “hosted on” topology.
    • Anomalies, notifications and summaries show up in real time (no more 30-second polling); the inbox loads page by page and stays smooth past 200 tiles.
    • Initial load is four times lighter, and the cockpit installs like an app (home screen on mobile and desktop).
    • StatHall monitors itself: scheduler, workers, connectors and data freshness raise system alerts.

    Mobile app 2.5

    • Offline: reads from the cache, actions (acknowledge, resolve, snooze) are queued and replayed when the network is back.
    • Background refresh and a badge for critical anomalies.
    • Richer notifications (title, body, “Acknowledge” straight from the notification), overview, app ↔ server links, server target creation with an install QR code, alert thresholds, probes and containers on the server page.
  92. v2.4.0StatHall goes free and open-source — no subscription, donations and self-hosting

    What’s changing for you

    StatHall takes an important turn: there is no pricing and no subscription anymore. The project fully embraces what it is: a useful tool, offered simply, without a binding service relationship.

    Three paths, no commitment

    • Free hosted instance — app.stathall.com stays free, within reasonable usage limits (“fair-use”) that protect the shared infrastructure. The service is provided “as-is”, with no availability guarantee and no contractual support.
    • Open-source self-hosting — StatHall’s code is released as open-source (AGPL-3.0 license). If you need more than fair-use, or prefer to keep your data on your own infra, run your own instance with Docker Compose — no limits, no dependency.
    • Donations — funding the project is now voluntary: Buy Me A Coffee and GitHub Sponsors. No strings attached.

    What about the Pro tier / payments?

    The paid Pro tier and card payments are removed. No more “upgrade to Pro”, no monthly subscription, no sales contract (the terms of sale are gone). Instead, a “How it works” page simply explains the model.

    Need a higher quota, a specific connector, or a hand? Get in touch — we look at it case by case, with no commitment.

    Founding supporters

    Early Buy Me A Coffee supporters keep lifetime recognition and an extended quota profile. Thank you.

    Under the hood

    • Removal of the payment integration and related data.
    • Existing quota limits become fair-use guardrails, with no pricing attached.
  93. v2.3.0Grouped Inbox by type + Team / All / Demo filter for admins

    What’s new for you

    Two major additions to declutter the cockpit when you track many targets, plus a long-awaited keyboard detail.

    The Inbox now groups items intelligently

    Until now every entry showed separately: a release shipped on iOS and Android meant 2 rows, and a recurring anomaly flooded the feed. The Inbox now applies a grouping rule tailored to each type:

    • New versions — a single tile per version, listing the impacted OS with their release date (e.g. v1.2.1 · iOS 05/17 · Android 05/18). Sorting uses the most recent date.
    • AI summaries — a single tile per target per day (the Apple / Google / Global scopes are merged, the most complete one is shown).
    • Anomalies — when the same anomaly recurs for a target, a single tile shows an occurrence counter (N×) and the date of the last occurrence, with the highest severity. Expandable to act on each occurrence; a one-off anomaly stays a regular actionable card.

    Team / All / Demo filter, everywhere (admin accounts)

    An administrator overseeing several accounts was flooded by other teams’ feeds and by demo targets. A new global selector now appears at the top of the screen for admin accounts, with three modes:

    • Team — only your internal team’s targets (default).
    • All — all real targets, excluding demos.
    • Demo — demo targets only (debug / showcase).

    The filter starts on Team at every new session, then your choice is remembered for the current session and applies everywhere: Inbox, catalogue, applications, servers, dashboards, the rail’s alert counter and the target picker. Demos no longer pollute the standard view.

    Keyboard shortcut on Windows / Linux

    The shortcut to open search already worked with Ctrl+K on Windows and Linux, but the interface only showed the macOS version (⌘K). The keyboard hint now adapts to your system: ⌘K on Mac, Ctrl+K elsewhere.

    On mobile

    The mobile app aligns its Inbox with these rules: anomalies grouped by type (counter + last occurrence) and summaries grouped by day. Versions were already grouped by OS.

    Under the hood

    • No database migration.
    • Grouping rules centralised server-side for the web cockpit.
  94. v2.2.3Polymorphic favorites + in-app inbox — your custom cockpit

    What changes for you

    This release turns the left rail into a real personal cockpit: pin your apps, servers, favorite pages, and receive notifications in a centralized in-app inbox.

    Pin any screen

    The ⭐ button now appears in every page header: on app pages, server pages, target tabs (Reviews, Crashes, AI…), and global pages (Activity, Catalogue, AI Digest, Rules). One click pins the screen to your rail; one more click unpins it.

    Glanceable pastilles

    Rail vignettes (40×40 px) carry two visual cues:

    • Type icon top-left (rocket for app, server for server, shield for admin view, filter for Inbox filter…)
    • Purpose icon centered (MessageSquare for Reviews, AlertOctagon for Crashes, Sparkles for AI digest, etc.)
    • Initials at the bottom to distinguish multiple favorites of the same type (DF, AS, PW…)

    On hover, a rich popover shows the full label, category, target tab and three actions (Open / Rename / Unpin).

    In-app inbox

    The bell at the bottom of the rail becomes functional: an unread count badge (polling every 30 s), one click opens a side drawer with all your workspace notifications.

    Sources at launch:

    • Anomalies opened (P0/P1) — notify owners and co-owners
    • Anomalies acknowledged by another user — notify watchers
    • Anomalies resolved by another user — notify watchers

    For each notification you can: mark as read (click), delete (✕), mark all read, clear all read. Clicking opens the target page directly.

    Live counter sync

    When you mark an anomaly notification as read, the bell badge decrements immediately. When you acknowledge an anomaly in Inbox, the ⚠ P0 badge syncs. Both counters stay consistent via automatic cache invalidation.

    Under the hood

    • New alembic migration c1f7e2b8d4a6 (polymorphic favorites: kind, target_url, target_id, target_section)
    • New alembic migration c1f7e2b8d4a7 (user_notifications table with own-user RLS + partial index on unread)
    • 6 REST endpoints for the inbox (list, unread-count, read, mark-all-read, delete, clear-read)
    • insert_notification hooks in services/anomalies.py (dedicated session, isolated from main transaction)
    • 18 additional backend tests — 506 tests passing total

    This release is backward-compatible: your existing pinned views (Inbox filter) stay intact (default kind=inbox_filter).

  95. v2.0.0-mobile-rc.10Mobile rc.10 — notifications settings rebuilt + alignment with SPA

    What changes for you (mobile)

    Mobile iteration 2.0.0-rc.10 completes the UX/UI rebuild aligned with the “Lecteur Mobile” design and the SPA V2.2.x. Two crashes are fixed, the notifications settings screen becomes functional, and the vocabulary is aligned with the SPA (“AI Summary” → “Pulse”).

    2 Sentry crashes fixed

    • Tap on “Notification settings” in Account crashed the app at page open (XamlParseException on a missing resource key). Three internal references fixed, the screen now opens cleanly.
    • 30-day trend on an app’s detail view crashed at chart render in some contexts (25 Sentry events). Root cause: uninitialised X axis labels passed to the charts library. Array now properly seeded with empty strings, no more crash.

    Notification settings now usable

    The granular “Settings per event type” screen is now openable from Account → dedicated row. It exposes a 6 types × 3 channels grid (P0/P1/P2/AI summaries/Versions/System × Push/Mail/Quiet), a quiet hours section (DND with time range, P0 always allowed) and a test push button with immediate toast feedback. Icons per type (red/amber/ indigo alerts, purple sparkles for Pulse, etc.) now render correctly.

    AppPickerSheet: apps vs servers + anomaly badge

    The “Choose a target” sheet now visually distinguishes applications (rocket icon, indigo soft background) from servers (server icon, grey soft background). The bare “0” to the right of each target is replaced by a red “N anom.” badge, visible only when the target has open anomalies — nothing otherwise (readability). Labels go from “Choose an app / All apps” to “Choose a target / All targets” to reflect the polymorphic (apps + servers) list since V2 LOT 2.

    Vocabulary aligned with the SPA — “Pulse”

    The SPA V2.2.1 renamed “AI Summary” to “Pulse” (Pulse reviews, Pulse app, Pulse server). The mobile app follows in rc.10: Inbox filter “Summaries” → “Pulses”, teaser card ”✦ AI Summary” → ”✦ Pulse”, page title “AI Summary” → “Pulse”, “Summary history” → “Pulses history”. Consistent across SPA Inbox and mobile.

    Activity timeline backed by richer history

    The mobile Activity screen previously showed only release 2.0.0-rc.7 (the last one recorded in DB). The backend now seeds 72 deployment history entries (12 backend versions × 6 services: api, frontend, marketing, worker-default, worker-sync, beat) covering the past 22 days (V2.0.0-rc.8 → V2.2.9). The mobile Activity screen now shows a realistic history alongside the store releases of demo apps.

    Under the hood

    • Backend adds the kind field (application | server) to the mobile AppCard schema, propagated from SupervisedTarget.kind. Lets the mobile app distinguish polymorphic targets.
    • New CLI seed-demo-release-events (idempotent, skipped when ≥ 30 rows already in DB) to enrich the Activity history.
    • Mobile bumped to 2.0.0-rc.10 / build 41. Android build = 0 errors, 455 xUnit tests green.
    • No DB migration.
  96. v2.2.9Inbox — server anomalies visible + tighter rail + denser cards

    What changes for you

    Three user feedback items handled in one pass to perfect the cockpit’s visual consistency.

    Server anomalies are back in the Inbox

    Since the Inbox redesign in v2.2.7, only app anomalies (crashes, ratings, negative reviews) appeared in the feed. Server anomalies (CPU/RAM/disk/load over thresholds) were invisible, creating a mismatch with the rail’s 5 P0 badge that still counted them.

    Now the rail counter matches the Inbox “critical” counter, and server anomalies appear as “Système metric élevée — Server name”. Click → server overview.

    Better-anchored notification pill + larger rail icons

    The red badge on the Inbox icon was positioned relative to the button (40×40 px), so it “floated” away from the actual icon. It is now anchored directly on the icon corner, with a ring that detaches it from the background.

    The main rail icons (Inbox / Activity / Catalogue / AI Summary / Rules / Admin / Bell) go from 18 to 20 px with a thicker stroke. More readable on every screen.

    More contrasted target tile health dots

    The status dots on catalogue tiles (8×8 px) are scaled up to 10×10 px and surrounded by a colored halo. The 4 states (red disconnected, amber stale, green connected, gray pending) are finally distinguishable at a glance.

    Consistent LED on the server header

    The colored dot in a server header (next to the name) now matches the actual state — it used to stay green regardless of situation, which could falsely suggest a healthy server while it was actually “pending” or “disconnected”. The rendering is now identical between the header and the catalogue tile.

    Agent update available — dedicated purple color

    New visual signal: a connected server running on an agent version strictly older than the latest one observed across your portfolio shows a purple LED (instead of green). The color is dedicated — distinct from orange (silent server) and blue (pending status) — to avoid any confusion.

    Example: if your Runner-Seb-Nuc and others run v1.0.5 while demo-prod-debian stays on v1.0.0, the latter shows purple in the catalogue.

    On the server detail (overview), the Agent version field shows a small purple ↑ v1.0.5 badge next to the version number, with a tooltip recalling the target version.

    Dedicated blue LED for “Pending”

    Servers in pending state (never connected) used to show a gray LED on the catalogue while the detail page showed a blue pill (Pending). The two representations are now aligned on the same blue color (brand-blue), distinct from purple (agent update) and indigo (CTA).

    Color legend in the catalogue

    An inline legend was added below the catalogue filter bar to remind what each dot means:

    • Connected · healthy (green)
    • Silent · watch (orange)
    • Agent update available (purple)
    • Disconnected · critical (red)
    • Pending · never connected (blue)
    • Unknown · no data (solid gray, visible like a true dot)

    The counters at the top of the page (small colored dots next to “N targets”) also get a hover tooltip for the same info. The Health filter in the toolbar adds a new “Pending” option to narrow down to never-connected servers (useful during pre-deployment).

    More tiles per row

    The catalogue grid gains +1 column per screen size: on very wide screens you now see 6 tiles per row instead of 5, on medium screens 3 instead of 2, etc. Roughly 17% width gain per tile.

    Under the hood

    • server_metric_high anomaly type now accepted by the SPA Inbox endpoint.
    • Tile dot: h-2.5 w-2.5 + colored ring-2, no clipping in truncated names (fix for the overflow reported by user).
    • No DB migration.

    19/05 patch — user feedback batch

    A second batch of fixes shipped same day on 2.2.9 (no version bump).

    Reviews — search + version filter actually work

    The reviews search bar only searched within review content; typing 28.3.1 or a username never matched anything. It now also looks through the title, author and version string. The Version filter dropdown was visual-only — the selection was never sent to the server. Picking 28.3.1 now actually filters the list.

    The version picker has been rebuilt: multi-select combobox with inline search, semver-descending order (newest releases on top), and we dropped the · iOS / · Android suffix (the version string is universal, the adjacent Platform selector does the OS targeting). You can tick several versions and the list becomes the union.

    All Reviews filters now live in the URL (?q=…&version=…&platform=… &rating=…): bookmark a view, share a link, or land here pre-filtered when coming from the Versions page.

    Versions → Reviews in one click

    On an app’s Versions page, each row’s review counter is now a direct link to /apps/:slug/reviews?version=X&platform=Y. No more copying the version into the filter manually.

    Bonus: opening a “Version published” card from the Inbox now opens the app’s Versions page pre-filtered and auto-expanded on the matching version (already shipped earlier in 2.2.9, repeat for clarity).

    Inbox — same-day summaries deduplicated

    AI summaries (Apple, Google, Global review scopes) generated on the same date showed up as three side-by-side rows for the same app. We now keep the Global summary (it covers Apple+Google) ; the individual scopes are still reachable from Reviews pulse.

    Reviews pulse (app) — screen no longer blank

    The 3-column view (Global / iOS / Android) was looking for a summary whose dates matched exactly the last 30 days. Since archived summaries cover fixed windows (7d, 30d ending on a fixed date…), the match almost always failed and every column rendered “No summary available”. It now picks the latest successful summary per scope and shows the actual period covered (“Period: DD/MM → DD/MM”).

    Global AI digest — date range + richer chips

    The Global AI digest header now shows the date range covered (from DD/MM to DD/MM) on top of the “This week / Previous week / Month” label.

    The target chips at the bottom were thin (just a name + an icon). They now show the open P0/P1 anomaly count (red ⚠ N badge when

    0, red-bordered chip) and the latest known version. Sorted descending: targets with the most open critical anomalies come first.

    Groups accessible to owners

    App/server owners can now browse and manage their groups from /groups (new entry in the “Global views” sidebar). Creating a root group is still super-admin-only (backend returns 403 otherwise), but creating sub-groups, editing, deleting, and managing members no longer requires going through the admin panel.

    Anomaly rules — clearer message when table is empty

    The Anomaly rules page used to flatly say “0 rules · 0 active” when the table was empty, with no hint as to why (the 9 default rules should have been seeded by the V2.2 migration). It now shows an explanatory banner with the CLI command to run on the API container: python -m app.cli seed-anomaly-rules (idempotent thanks to a unique index on the natural key).

    Ownership transfer email — Outlook + button polish

    The square logo in the email header rendered blank on Outlook (the semi-transparent white tint is ignored → falls back to solid white, so the white “S” was invisible). We added a dark indigo Outlook fallback ; non-Outlook clients still get the original translucent overlay.

    The “View the app” button in the ownership-transfer email has been rebuilt as a bulletproof button (table + mso-padding-alt) so it keeps its padding on Outlook 2007-2019. Added a → arrow for intent clarity.

    Under the hood

    • Backend GET /apps/{id}/reviews now accepts repeated ?version= (multi-values). The q param searches across content + title + author + version_string.
    • AIDigest payload exposes period_from + period_to. Target chips enriched with open_critical + last_version.
    • app/services/inbox.py deduplicates summaries by (target_id, date(generated_at)) with priority global > apple > google.
    • New CLI seed-anomaly-rules (idempotent via a partial unique index uq_anomaly_rules_natural_key).
    • 0 DB migration; no new secret nor new dependency.

    19-20/05 patch 2 — super-admin confidentiality + co-owner delete + mobile icons

    Break-glass is now mandatory for super-admins

    Before: a super-admin could browse and configure any application or server without asking for access, including ones they aren’t part of the team for. The “Request temporary access” button was there but purely cosmetic.

    Now: a super-admin who isn’t either the owner or a co-owner of a target must request a temporary access (break-glass) to browse it just as much as to edit it. Without an active grant, the URL /apps/:slug or /servers/:slug returns 404. The owner gets an email every time a request is made, and every action taken by the super-admin is audited.

    The admin pages (users, plans, audit log, system) stay freely accessible — the restriction only applies to per-target screens.

    Co-owners cannot delete an app or server

    The backend already blocked deletion (owner-only), but the UI left the “Delete” button active for co-owners — the click failed with a silent error. The button is now disabled for co-owners, with an explanatory note: “Owner-only action”. To delete an app where you are a co-owner, ask the owner or request a transfer first.

    Mobile — icons aligned with the SPA

    The target picker on mobile showed a rocket for apps and a server rack for servers. The SPA already uses the 📱 + 🖥 emojis for the same distinction. Both now align on 📱 (application) + 🖥 (server), with the Aurora-colored square kept to differentiate visually.

    To roll out on iPhone via ./scripts/deploy-ios-device.sh when ready — mobile version 2.0.0-rc.12 (build 43).

  97. v2.2.8Catalogue tree — VS Code style path coalescing

    What changes for you

    Small ergonomic pass on the catalogue tree view: chains of empty ancestors are now coalesced into a single breadcrumb line, à la VS Code rendering src/components/layouts/ as one row when no intermediate folder has a direct file.

    Before / After

    On a hierarchy Client > Solution > Env > debian/ubuntu where only the leaf groups (debian, ubuntu) have direct targets, you now see:

    ▾ Client › Solution › Env    8 included  ⚙
       ▾ debian                  4 targets   ⚙
         [cards × 4]
       ▾ ubuntu                  4 targets   ⚙
         [cards × 4]
    

    instead of 6 chained structural rows.

    Dynamic cases

    • If you add a target directly to “Client”, Client stops coalescing and gets its own row with cards.
    • If a new group appears at the same level as Solution, the parent Client becomes a divergence point again (its row appears, the subtrees keep coalescing).
    • Groups fully empty (no direct member, no descendant with content) are hidden from the catalogue. They remain visible in /admin/groups if you want to configure them.

    ⚙ Configure button

    The Configure icon keeps pointing to the last segment of the breadcrumb (the group actually represented by the row). To configure a coalesced ancestor, go through /admin/groups.

    Under the hood

    • buildTreeSections algorithm rewritten in 2 passes (prune + emit).
    • Cascading collapse is preserved.
    • No DB migration, frontend-only.
  98. v2.2.7Web Inbox — anomalies + summaries + versions in one stream

    What changes for you

    The SPA Inbox now mirrors the mobile app: a unified chronological stream mixing anomalies, AI summaries and newly detected versions. Each row opens the relevant tab on the target directly.

    4 sorting tabs at the top

    • All — full chronological feed (default).
    • Anomalies — anomalies only (status + severity filters available).
    • Summaries — weekly AI summaries only.
    • Versions — newly detected releases only.

    The active tab is persisted in the URL (?kind=).

    Easy to scan at a glance

    Each feed card carries:

    • A left color stripe: red P0, amber P1, indigo Summary, purple Version.
    • A badge: severity for anomalies, ✨ Summary for AI, 🏷 Version for releases.
    • A pre-formatted title (“Crashes en hausse — Demo Travel App”, “Weekly AI summary”, “v1.2.1 published”).
    • A context subtitle: platform/version for anomaly, themes for summary, platform for version.

    The detail panel on the right shows kind-specific content and a button that routes to the right target tab:

    • App anomaly → app’s Anomalies page
    • Server anomaly → server overview
    • Summary → app’s Pulse Reviews tab (/ia-reviews)
    • Version → app’s Versions page

    For anomalies, the Acknowledge / Snooze / Resolve actions stay available.

    Filters and tabs

    When you pick Anomalies (or All), a Status selector appears in the filter bar (Open / Acknowledged / Snoozed / Resolved / All) — the status option was moved from tabs to the filter row, for parity with mobile.

    The Period filter (24h / 3d / 7d / 30d) stays visible at all times.

    Under the hood

    • New GET /api/v1/inbox endpoint — cross-source feed with kinds, anomaly_status, window_days, limit parameters.
    • The backend service aggregates 3 sources into a single response sorted DESC by occurrence date.
    • The mobile BFF keeps its separate endpoint unchanged (cursor pagination, etc.).
    • 60 s auto-polling on the SPA.
  99. v2.2.6Catalogue grouped by default + collapsible tree + group admin for its owners

    What changes for you

    Three improvements that make day-to-day group usage feel natural.

    Catalogue opens straight in “Grouped by group”

    If you can see at least one group, the catalogue defaults to the Group by: Group mode. If you prefer another mode (Type / Health), your choice is persisted in the URL (?gb=type) and takes precedence over the auto default.

    Tree view expanded by default

    Group sections are rendered with indentation and a collapsible chevron. The whole tree is expanded on first render. You can collapse each branch individually, or use the “Expand all / Collapse all” buttons in the toolbar.

    Collapsing is cascading: collapsing a parent automatically hides its descendants.

    Own a group? You can administer it

    The ⚙ Configure button appears in each group section header where you have write access (owner, direct co-owner, or owner of an ancestor group with inheritance enabled). One click opens the group config page (General · Members · Access · AI Summary) — without going through super-admin admin.

    Super-admin group admin stays available at /admin/groups for cross-account operations.

    Under the hood

    • A can_write field is added to each group node in the API (single batch SQL query for all visible groups).
    • New /groups/:id/config route not gated by RequireAdmin — Postgres RLS guarantees server-side access control.
    • No DB migration.
  100. v2.2.5Group-by-group — actually works now

    What changes for you

    The catalogue’s “Group by: Group” mode finally renders one section per group with the matching targets. Until now the toggle collapsed everything into a single “All” section — the feature was inert since V2.2.0-rc.1.

    Sections per group + Ungrouped

    In /catalogue, pick Group in the “Group by” selector. You now see:

    • One section per group you administer or have access to, with the matching target cards inside.
    • A final “Ungrouped” section for orphan targets (not attached to any group).

    A target belonging to multiple groups appears in each matching section (standard “group-by” semantics).

    Under the hood

    • The GET /groups endpoint now exposes the direct member list for each node (single aggregated SQL query, RLS-aware).
    • No DB migration, no breaking change: API payload is additive.
  101. v2.2.4App owners can finally edit their own apps + filterable Apps/Servers admin

    What changes for you

    This release fixes a bug that prevented non-super-admin app owners from editing their own apps, and overhauls the Apps/Servers admin console with a per-user filter for clarity when a workspace hosts several teams.

    Own an app? The “Configure” button works at last

    If you are owner or co-owner of an app, the Configure button in the app header now opens the proper options page: data sources, health settings, team, AI summary, danger zone. No more silent redirect to the home — the trap hit every click on Configure before.

    Same fix for servers: the Configure button correctly routes owners to the server config page without going through global admin.

    Apps / Servers admin overhaul

    The Admin › Apps and Admin › Servers pages gain:

    • An owner filter bar Team / All / User. By default you only see apps and servers owned by the StatHall team (super-admins). Pick a user to switch to their apps/servers.
    • A search field on name or slug.
    • A sortable Owner column with the owner’s email + a TEAM (indigo) or CLIENT (purple) badge computed automatically.
    • A live “N results” counter on the right.

    The filter state is persisted in the URL: share /admin/apps?owner=42 to point straight to a user’s apps.

    “Viewer” label renamed to “User”

    On the Admin › Users page, the global user role displayed as “Viewer”. The label was misleading: a user can be owner of their apps and have full rights on them. The new label User is more neutral.

    Inbox: each anomaly now shows its target

    Every Inbox row now shows Application · App name or Server · Server name under the type. The “Open context” button correctly routes to the app Anomalies page or the server overview (no more broken link for servers).

    Group Members panel overhaul

    On a group page, the Members tab now only shows effective members (no more mixing with the full list of visible targets). A ”+ Add targets” button opens a modal with search, app/server filters, multi-select and “Select all visible results” bulk action.

    Under the hood

    • 0 DB migration, purely frontend fix + backend permissions preserved (Postgres RLS unchanged).
    • New reusable UserPickerCombobox component (keyboard-first: arrows, Enter, Esc).
    • New useGroup(id) hook for group members resolution.
    • 58 frontend tests green.
  102. v2.2.2Inbox + Scope finish line — cross-source AI summaries, live anomaly rules, mobile responsive

    What changes for you

    The V2.2 “Inbox + Scope” redesign ships in its final form: this release adds everything that was still missing to make the version production-stable and usable on the go.

    Cross-source AI summaries

    Four new AI endpoints power the UI:

    • Weekly AI digest (cross-scope): automatic brief every Monday morning with TLDR, hotspots and watch-list across all your supervised targets.
    • App pulse — global view: per-app health digest (strengths, weaknesses, top recommendation).
    • Reviews pulse: 3 adaptive columns Global / iOS / Android depending on the app’s platforms, each with sentiment, positives, negatives, bugs reported, feature requests, tags and verbatims.
    • Server pulse: 7-day activity summary (incidents, highlights, operational recommendation).

    All summaries are cached server-side for 1 hour. Without an LLM provider configured, the UI shows a structured fallback (no blank page).

    Anomaly rules applied in real time

    The anomaly rules you edit from /rules are now read directly by the detection engine (cascade target > group > type > all). A new Preview button lets you simulate “how many anomalies would this rule have raised over the past 30 days” before saving — calibrate your thresholds with confidence.

    Enriched / command bar

    • Member targets: in path mode /lab/lab-debian/, the menu now lists targets that are members of the group, not just sub-groups.
    • Inline group editing: press ⌘+. on a group node to rename, move or delete the group without leaving the command bar.

    Polished Catalogue & Activity

    • Catalogue: each card now shows the latest released version of the app (Apple or Play, whichever is most recent).
    • Activity: new 5-column strip above the feed (Events 7d · Anomalies · Releases · System · today-by-hour sparkline).
    • AI summary: last-generated timestamp shown in relative format (“2h ago”) with a live indicator during regeneration.

    Shared pinned views

    You can now share a pinned view with the rest of your workspace: tick “Share this view” when pinning. A small 👁 icon distinguishes public views in the rail. Read-only for other members.

    Mobile responsive

    The interface is now usable comfortably below 1024 px: a slide-over drawer replaces the side rails, accessible via the hamburger in the top-left. Tablet and mobile no longer lose any functionality.

    Under the hood

    • New alembic migration c1f7e2b8d4a5 (pinned_views.is_public column + extended RLS policy for public reads).
    • Cross-source LLM generation via the providers you’ve already configured (DeepSeek / OpenAI), no hidden cost.
    • Beat job Monday 06:00 UTC: email.send_global_ai_digests enriched with actual content (tldr, hotspots, watch list) instead of a placeholder.
    • Refactored global scope to React Context (memoization + cross-page consistency).
    • Test suite: 488 backend tests + 58 frontend tests + Playwright e2e scaffolding. No regression on V2.1 screens.

    This release stabilizes V2.2 in its final form; we recommend updating as soon as possible.

  103. v2.2.0-rc.1« Inbox + Scope » UX overhaul — Inbox is home, hierarchical groups, « / » shell mode

    What changes for you

    After four rapid cockpit iterations in 24 hours (V2.1.0), StatHall ships a deep UX overhaul driven by an external ergonomic audit. The « Inbox + Scope » pattern rests on three pillars: triage first, keyboard command, scope by group.

    Inbox = home (replaces Global overview)

    The landing screen is now the Inbox: a triage list of open anomalies. You know in 5 seconds what deserves your attention this morning — no need to scroll a dashboard to spot reds.

    • Enriched statuses: open / acknowledged / snoozed / resolved. You can snooze an anomaly until tomorrow and it automatically pops back into the Inbox when the window expires.
    • Empty = « All quiet »: if nothing’s pending, the Inbox says so plainly instead of rendering a dashboard to scan.

    /portfolio redirects to /inbox — your bookmarks keep working.

    Unified combobox with « / » shell mode

    The target picker in the topbar becomes a central combobox combining three modes:

    1. Idle display = « you are here » (current target, active scope, or current view).
    2. Free mode (⌘K or click) = favorites, recent, scopes, groups, actions, fuzzy multi-token search.
    3. Shell mode (starts with /) = Unix-like path grammar. /demo-fitness/cra + Tab + Enter → you land on Demo Fitness, Crashes tab. /lab/lab-debian/ → catalogue scoped to Lab Debian. Tab completes the longest common prefix or cycles through matches.

    The ? shortcut opens the full cheat sheet. Stop click-clicking to navigate — type the path.

    Hierarchical target groups

    You can now group targets in a tree: Client > Solution / Environment > targets. Free semantics — client account, product line, env prod/staging/dev, whatever.

    • A target can belong to multiple groups (product × environment matrix supported).
    • Access rights are inherited automatically to descendant groups and their members (on by default; opt-out per group).
    • All main views (Inbox, Catalogue, Activity, AI digest, Rules) are filtered by the global scope — pick « Acme » in the combobox and everything narrows down to that client.
    • The scope lives in the URL (?scope=group:acme), so a link preserves the full context.

    5 main views

    • Inbox (/inbox): anomaly triage, statuses, filters, detail drawer.
    • Activity (/activity): unified timeline of releases, anomaly transitions, system events, grouped by day.
    • Catalogue (/catalogue): targets grid with groupBy = group / type / health, replaces /apps + /servers.
    • Global AI digest (/ai): weekly cross-scope digest aggregating everything you can see — critical anomalies, releases, app sentiment, server patterns.
    • Rules (/rules): 9 default anomaly rules editable by admins. Inherit along the group tree.

    Per-target AI summary — Reviews AND Activity

    The « AI summary » tab on an app now has a Reviews / Activity sub-toggle:

    • Reviews = store review summary (sentiment, pros/cons, reported bugs) — like before, migrated from the old Summaries tab.
    • Activity = new: textual summary of events, crashes, anomalies, recurring patterns of the target.

    Servers get an equivalent « AI summary — Activity » tab (systemd / apt events, reboots).

    Email opt-in: a new block in /account/email-subscriptions lets you opt in to receive the global digest and per-target summaries by email at your chosen cadence (never / weekly / monthly). The generation cadence target-side stays in the hands of the target’s owner (admin panel of the app / server / group).

    Admin mode clearly separated

    When you enter the admin panel, a purple banner « Admin mode » appears in the topbar and a dedicated 3-group sidebar (Management / Product / System) takes the main navigation slot. A dedicated button lets you exit back to your daily supervision. No more confusion between the two spaces.

    Personal pinned views

    You can pin a filtered Inbox view (e.g. « P0 from Acme client ») and recall it with one click from the rail. Pinned views are persisted in the database, available across all your devices.

    Under the hood

    • The 5-item rail replaces V2.1’s 4 entries (Overview, All apps, All servers, Anomalies). Overview views are reachable via the combobox.
    • The « Read-only » banner becomes a discreet, dismissible note (per session).
    • The version number in the topbar opens an integrated changelog drawer.

    Nothing to do on your end — the new ergonomics applies on your next sign-in. Legacy /portfolio /apps /servers /apps/.../summaries redirect to the new routes.

  104. v2.1.0-rc.2Sidebar overhaul — persistent Rail + contextual Panel

    What’s new for you

    A redesigned left sidebar

    The left sidebar of the web cockpit is fully redesigned with two columns:

    • Persistent thin rail (56px) with global navigation icons: Overview, All apps, All servers. Always visible — switch views in one click from anywhere.
    • Contextual panel (200px) to the right of the rail that adapts to the route automatically:
      • inside an app → app sub-nav (Dashboard, Reviews, Crashes, Versions, Roadmap, Anomalies, AI summary)
      • inside a server → server sub-nav (Overview, Events)
      • in admin panel → 3 groups (Management / Product / System)
      • on overview routes → Portfolio / Apps / Servers shortcuts
      • on profile → Account, Feedback, Donate

    No need to use the top target picker to navigate between supervised targets anymore — one click on a rail icon does it.

    Critical anomalies badge

    A new ⚠️ button in the rail shows a red badge with the count of open P0 anomalies across all your targets. Click → jumps to the cross-target view to ack them.

    Permanent admin shortcut

    For administrators, a dedicated ⚙️ button in the rail leads to /admin in one click from anywhere.

    Ergonomic improvements (shipped same day)

    • More compact cards on “All apps” and “All servers” views: denser grid (up to 5 cards per row on wide screens).
    • Clickable KPI tiles on those views: click “Connected” to filter the grid to only show connected servers. Same for “Anomalies”, “Demo”, “Pinned”.
    • Clickable Portfolio KPIs: “Applications” → /apps, “Servers” → /servers, “Open anomalies” → Anomalies view.

    Under the hood

    • A single shell replaces the 5 previous layouts (app, server, admin, global views, profile) — simpler to maintain.
    • The menu stays keyboard-accessible and screen-reader compatible (navigation role, tooltips, visible focus).

    No action required — the new ergonomics applies automatically on your next sign-in.

  105. v2.1.0-rc.1Universal cockpit — ergonomic overhaul

    What’s new for you

    Three overview dashboards to supervise everything

    The web cockpit gains three new user dashboards, accessible directly from the target picker at the top:

    • Overview (/portfolio) — a glance at everything: aggregated KPIs, top critical anomalies, your apps and servers side by side.
    • All apps (/apps) — the complete list of your mobile apps with search, stats, and quick access to cross-app reviews and cross-app anomalies as secondary tabs.
    • All servers (/servers) — the complete list of your Unix servers with Connected / Silent / Disconnected stats.

    Each card is clickable and takes you straight to the relevant app or server dashboard.

    A smarter target picker

    The top picker (“Pick a target”) gets four new features:

    • Global views at the top of the menu: one-click to the three global dashboards.
    • Favorites — pin your most-used targets via the star on hover, they always stay at the top of the menu.
    • Recent — your 5 most recently visited targets are remembered automatically.
    • Health dot on each target: green if all is well, orange for caution, red for critical anomaly. Plus a discreet grey dot when data hasn’t been synchronized for more than 24h.

    The menu stays readable even if you supervise dozens of targets, thanks to cmdk search + pinning.

    Reorganized admin sidebar

    For administrators, the admin panel (/admin) is now organized in three clear thematic groups:

    • Management: Apps, Servers, Users, Approvals.
    • Product: Pricing plans, Access codes.
    • System: System, Audit, Push diagnostics.

    No more duplication between the sidebar and the top-right user menu — the latter now only keeps a single Admin panel shortcut.

    Admin screens up to visual standard

    The Pricing plans, Access codes, and Push diagnostics pages finally adopt the Aurora Valhalla design that’s consistent with the rest of the SPA: tables inside cards, standardized inputs and buttons, illustrated empty states.

    Under the hood

    • An Agent tab in the server sidebar (user view) had no actual purpose (token management is admin-only) and has been removed.
    • A broken visual token (bg-surface-card) that made some cards invisible has been fixed throughout the application.

    No action required on your side — the new ergonomics applies automatically on your next sign-in.

  106. v2.0.0-rc.8Mobile app — new 5-tab cockpit and design system refresh

    What’s new for you

    A more cohesive mobile app

    The StatHall Mobile app (iOS + Android) receives a full visual refresh. Navigation between screens is smoother, titles and cards now share a common style (Inter Tight type, Aurora palette), and the native iOS navigation bar is finally aligned with the rest of the app.

    A 5-tab cockpit

    The navigation bar goes from 3 to 5 tabs: Inbox · Targets · Health · Activity · Account. The “Apps” tab reverts to its generic name “Targets” and shows all your applications and servers by default — you can filter afterwards if needed.

    New “Health” tab

    At a glance, see the global health score of your portfolio, broken down into three dimensions (tech / business / adoption), and the list of targets that need attention first (score under 70).

    New “Activity” tab

    A real-time timeline combines deployments, store version detections (iOS / Android), and agent events (systemd, APT security updates…) into a single feed. Filter by type to focus on what matters.

    On an application page, a “Linked servers” section lists the servers hosting it (hosted_on relationship). Conversely, the server page shows a shortcut to the parent app. Tap any card to jump straight to its details.

    Under the hood

    A few new backend touch-points feed these screens (health overview, activity feed, target links) with no impact on your existing data. The aggregation runs entirely within your tenant — nothing leaves your perimeter.


    No action required — this version reaches the mobile app automatically on your next open.

  107. v2.0.0-rc.7StatHall V2 — universal cockpit, Pro plan, and super-dashboard

    What’s new for you

    A Pro plan to support the project

    This release introduces the Pro tier at €12/month (VAT not applicable, art. 293 B of the French Tax Code), positioned as participation in infrastructure costs rather than a commercial product with an SLA. The Free tier stays unchanged for standard usage. Founding supporters automatically receive 6 months Pro free.

    The super-dashboard

    A new view brings all your supervised targets — applications and servers — together on a single board. You can now link an app to a server (hosted_on, depends_on, related relationships) to see the overall health of a group of interdependent services at a glance.

    Consumption tracking and access codes

    A new Usage page details your daily consumption (API calls, ingest events, emails) and quota status. A new Access Code page lets you redeem a promo or grant — handy for early adopters and ambassadors.

    Zero-downtime deployments

    Under the hood, StatHall updates now deploy via rolling restart (new container starts before the old one stops), with automatic rollback on failure. A new Release History page in the admin traces each deployment.

    Expanded documentation

    Three new product pages detail Unix servers, the super-dashboard and the push-only agent. Quickstart guides target mobile devs, DevOps and freelancers. The Security page is updated with agent principles.

    Strengthened security posture

    Daily off-site encrypted backups (weekly / monthly rotation over 3 months), a Traefik maintenance page displayed during downtime, and traceable deployment history to ease diagnosis.


    As always, these changes roll out gradually and remain backward compatible with your existing data. No action required.

  108. v2.0.0-rc.6StatHall now supervises your Unix servers too

    What changes for you

    A new target type: Unix server

    StatHall is no longer limited to mobile applications: you can now add your Unix servers to your cockpit. A lightweight agent, installed in a single command, pushes your system metrics (CPU, RAM, disk), events (systemd services, APT security updates) and aggregated journald logs to the cockpit — without ever opening an inbound port on your server.

    A dedicated server dashboard

    For each connected server:

    • Agent state in real time — connected, stale, or offline.
    • System identity declared by the agent (hostname, distribution, kernel, CPU, RAM, timezone).
    • System metrics over 24 hours, pre-aggregated per-minute on the agent side to stay lightweight.
    • Recent events (service stops, restarts, available security updates).
    • Logs from journald grouped by template with occurrence counter.

    Mobile app: new “Targets” tab

    The companion mobile app now displays your applications and your servers side by side in a unified “Targets” tab. You can view the server dashboard in read-only mode from your phone — useful for a quick check when you’re away from your desk.

    For whom this changes

    • Everyone: new “Targets” tab replaces “Apps” in the mobile app (the filter lets you find the app-only view).
    • Administrators: ability to add server targets from the SPA console (Admin → Servers).
    • No action required on existing applications — your mobile-app supervision continues exactly as before.

    Under the hood

    • Agent auth via opaque Fernet token, encrypted at rest, strictly bound to a single server (hostname binding).
    • TimescaleDB storage + continuous aggregates 1 min / 5 min / 1 h to keep history lightweight.
    • Mobile API now v2 (clean cutover, no parallel coexistence).
    • Over 500 automated tests added in this release.
  109. v2.0.0-rc.5Clear labels on review themes

    What changes for you

    No more technical identifiers in the “Top themes” card

    Right after it was fixed, the “Top review themes” card was showing the technical identifiers of the themes (praise, bug, ux, pricing…) instead of readable labels.

    This is corrected: themes now display with clear, translated labels — “positive”, “performance”, “feature request”… — in both French and English.

    Who’s affected

    Every app-dashboard user. A display change only — nothing to do on your end.

  110. v2.0.0-rc.4A real adoption score + the "Top review themes" card fixed

    What changes for you

    An adoption score based on the active-users trend

    The dashboard’s adoption gauge showed “no data”. It now relies on a real measure: the trend in daily active users over the last 7 days, compared to the previous 7 days. Steady, rising or falling — you see at a glance whether the app is gaining or losing ground.

    It’s an independent signal: it sits next to the health score without changing it. When the history is too short to compare two periods, the gauge stays empty rather than inventing a number.

    The “Top review themes” card surfaces data again

    The card that summarises the recurring themes in your reviews — bugs, pricing, usability, feature requests… — was empty for every app. It’s fixed and once again shows the dominant themes with their average rating.

    Who’s affected

    Every app-dashboard user. The data appears automatically.

  111. v2.0.0-rc.3A consistent health score everywhere — dashboard, list and mobile

    What changes for you

    The same score, wherever you look at it

    An app’s dashboard could show a different health score than the one in your app list or in the mobile app — sometimes off by a factor of two. The reason: the dashboard was recomputing its own formula on its side.

    From now on, the health score has a single source of truth. The number shown on an app’s dashboard is exactly the same as in the portfolio list and on mobile.

    The score respects your app’s profile

    If you’ve set a health profile for an app (e-commerce, game, utility…), the score now takes the relevant-reviews filter into account: only reviews that actually talk about the app count, not off-topic ones. An app can thus go from a raw rating of 3.5★ to a relevant rating of 4.5★.

    A slightly less harsh crash scale

    The way the crash-free session rate is scored has been softened: roughly 1 % of crashing sessions no longer tips an app into the red.

    Who’s affected

    Every web and mobile user. The recalculation is automatic.

  112. v2.0.0-rc.2The health score better reflects the reality of your apps

    What changes for you

    A fairer health score for long-running apps

    An app’s health score was unfairly penalising applications that have been running for months. Two of its components counted raw volumes — the total number of known crashes, the number of negative reviews — against fixed caps. An app with a naturally large history ended up in the red even though it was doing fine.

    From now on:

    • the “crash” signal relies solely on the crash-free session rate — a percentage, which doesn’t depend on the app’s age;
    • negative reviews are counted as a proportion of recent reviews, not as an absolute number.

    The result: a healthy app shows a healthy score, regardless of how long it’s been around.

    The status of older issues reconciles more faithfully

    Along the way, issues marked as resolved in the crash-tracking tool are now better reconciled inside StatHall — the displayed status reflects reality more faithfully.

    Who’s affected

    Every web and mobile user. The score recalculates automatically — nothing to do on your end.

  113. v2.0.0-rc.1The V2 foundations: a base ready to supervise far more than your apps

    What changes for you

    Nothing — and that’s on purpose.

    This release lays the technical foundations of StatHall V2. Behind the scenes, the tool has been rebuilt so it can soon supervise far more than mobile applications: Unix servers first, then databases, websites and containers — all in the same cockpit.

    Your apps, exactly as before

    Every application, connector, review, crash, AI summary and history is unchanged. Nothing to do on your end, nothing to reconfigure: the web interface and the mobile app work identically. The work in this release is entirely internal.

    What it sets up

    StatHall is moving from “the unified cockpit for your mobile apps” to the universal supervision cockpit. The next step, already underway: a Unix server target type, with a lightweight agent you install in a single command.

    Who’s affected

    Nobody, today. This release is a foundation step: it ships no visible new feature — it makes the ones coming next possible.

  114. v1.0.0-rc.27Ownership transfer, scoped super-administrator access, more respectful emails and login

    Highlights

    A sprint driven by a single question: how do we best respect users and their data? Three complementary tracks:

    1. you can now transfer ownership of an app without going through the account-deletion wizard;
    2. the access scope of StatHall super-administrators is framed to match our GDPR commitments (data minimization, traceability, immediate notification);
    3. small day-to-day respect tweaks: leaner email footer, clear login message when your account is pending approval, refreshed Terms and Privacy Policy reflecting it all.

    Transfer app ownership

    When you no longer want to be the principal owner of an app:

    • Go to App · Team, then click Transfer ownership.
    • Pick a recipient among the app’s co-owners or active super-administrators.
    • The recipient becomes principal owner and you keep a co-owner access so you don’t lose sight of the app during the handover. You and the new owner receive a confirmation email.

    The legacy flow for transferring ownership before account deletion is unchanged — the action is just available standalone from the Team tab now.

    Super-administrator access scope

    To match our privacy commitments, StatHall super-administrators now only see the technical metadata of an app they are not a member of: name, slug, configured connectors, sync status. Business data — user reviews, AI summaries, anomalies, crashes, detailed metrics — is only accessible to them under one of these conditions:

    • they are the owner of the app;
    • they were added as a co-owner or viewer by a team member;
    • they grant themselves temporary access (1 to 72 hours) for technical work. In that case, you receive an immediate email with the saved reason and the expiration date, and you can revoke it in one click from your app’s page.

    All temporary accesses are recorded in the app’s audit trail: you know who connected, when, why, and for how long.

    Forced transfer on third-party request (death, dismissal…)

    When StatHall must transfer an app at the request of a third party — an heir, an HR department after the owner has left, official support — the super-administrator can now attach a supporting document (PDF, PNG or JPEG, 5 MB max) at the moment of the forced transfer: death certificate, HR attestation, power of attorney, etc.

    The supporting document is:

    • optional but strongly recommended to materialize the proof of the request;
    • kept encrypted at rest for 3 years, aligned with the retention of other sensitive events;
    • identified by an SHA-256 hash recorded in the audit log, guaranteeing it cannot be tampered with after the fact without detection;
    • accessible to super-administrators for audit. The previous owner can request a copy at any time by writing to contact@stathall.com — this is the official contestation channel.

    Legal basis: legitimate interest (proof of operation, anti-fraud), documented in the Privacy Policy §2.4.

    More respectful, more polished emails

    • Full design refresh: every StatHall email now ships with an Aurora-coloured hero (indigo → purple gradient) carrying the wordmark and a contextual subtitle (“Security”, “Weekly summary”, “GDPR · Article 15”…). A thin multi-tone accent line bridges the hero to the content, the CTA stays on the brand primary colour. Immediate visual identity in any mail client (Gmail, Outlook, Apple Mail, Proton, etc.).
    • Leaner footer: we removed the name + address + SIRET block from the bottom of all our emails. The only legal link that remains is Privacy (so you can always reach the data-protection policy from your inbox). The individual-publisher disclosure remains available on the legal pages of the site.
    • “Buy me a coffee” block removed from emails: we’re preparing a premium tier and don’t want to mix the “support the project” and “service being monetized” signals in the same inbox. The support button stays available in the web app sidebar and on the dedicated page of the site.

    More respectful login

    • Dedicated message for pending-approval accounts: if you try to log in with an account whose public signup request has not yet been approved by an administrator, you now see a clear message (“Your account is pending approval”) instead of “Invalid credentials”. The message is only revealed once your password is correct — no extra information is exposed to an attacker who would be probing.
    • Terms of Service (section 3): new access-role breakdown reflecting the super-administrator restriction, plus a dedicated section on ownership transfer and one on temporary “break-glass” access.
    • Privacy Policy (section 2): explicit mention of the minimization principle applied to super-administrators, plus dedicated sections on ownership transfers and temporary accesses (with immediate notification to the owner and 30-day audit retention).

    Behind the scenes

    • New audit entries for every transfer (standalone or forced) and for every temporary super-administrator access.
    • The audit log keeps the history of temporary accesses for 30 days after expiration.
    • No action required for existing owners: your apps keep their configuration, members, and business data intact.
  115. v1.0.0-rc.26AI history, mobile Inbox reliability, email redesign, publisher info

    What’s new

    A UX sprint on the AI history tab on the web, a reliability fix for the Summaries card in the mobile Inbox, a visual redesign of transactional emails, alignment of the mobile AI Summary tab order with the web, and an update to the legal pages.

    For users — web

    • Regenerate button on every row of the AI history table. It opens the generation dialog with the period and scope already filled in. Run the summary again as-is, or switch the scope (iOS, Android, Global) before confirming.
    • Delete button on every row, with an explicit confirmation dialog. The summary is permanently removed but can be regenerated later (the underlying reviews stay in the database).
    • “Generate missing report” dialog: the dark overlay now covers the entire page (previously a band stayed visible at the top). The dialog also gains full keyboard navigation (Tab, Esc to close).
    • Clearer error messages: if you pick a period with no reviews for the requested scope, the message explains the case instead of a cryptic “HTTP 404”.

    For users — mobile

    • More reliable Inbox: only summaries that actually have content appear under the “Summaries” tab. Attempts that produced no content (for example because no reviews came in that week) no longer surface as blank cards.
    • Clearer Summary card: the exact generation date and time now appears in plain text under the app name (“May 11 · 02:00”), in addition to the relative counter already shown top-right (“20h”). No more mental math.
    • Title fallback: if a summary has no generated title, the card shows “New weekly summary” instead of an empty area.
    • AI Summary tabs: now ordered Global · Apple · Google, matching the web. Global remains the default selected scope.
    • Summaries stack in the Inbox: a single card per week now — summarising the scopes available (“Apr 30 · Global · iOS · Android”). A tap opens the AI Summary screen where you can switch scopes via the tabs, just like on the web. No more three identical-looking cards sharing the same date.
    • Versions stack in the Inbox: same treatment applied to version releases. A cross-platform version (iOS + Android) now shows as one card “v1.1.0” with two lines “iOS · May 15” + “Android · May 18”. A single-OS version still shows with one line. A tap opens the app’s Versions timeline.
    • ASC/DESC sort in the Inbox: new pill button in the header (”↓ Newest” / ”↑ Oldest”). You can now reverse the feed order to bring the oldest items to the top. Infinite scroll remains smooth in both directions. For merged stacks (Summaries by week, Versions by release), the card sits at the group’s most recent date regardless of the chosen direction.
    • Smoother Inbox reading:
      • Versions are now positioned in the feed at their actual release date (the one shown on the card), not their ingestion date. A release shipped 2 months ago but backfilled recently no longer incorrectly jumps to the top.
      • Scrolling down (loading older entries) no longer interrupts your position: new entries are appended at the tail instead of rebuilding the whole list.
    • Fix “pull-to-refresh” spinning forever: on the Inbox and 5 other lists (Anomalies, Reviews, Crashes, Apps, Notifications), the spinner never stopped after a pull. Fixed — it now disappears as soon as the list is refreshed.

    Emails — visual redesign

    • All emails now share the same look: StatHall header, signature, a link to support the project, and legal details in the footer. For optional emails (anomaly alerts, weekly digest), a “Manage my preferences” link appears at the bottom — it does not show on essential emails (signup verification, password reset, etc.).
    • Signup:
      • The activation link still expires after 24 hours.
      • Administrators now receive the notification of a new request after the person has verified their email (no longer the moment they submit the form). Less noise in the admin inbox, focus on accounts actually waiting.
      • An automated email alerts the team when a wave of unverified signups is detected.

    Added to both the Terms of Service and Privacy Policy:

    • Publisher: Sébastien Soulier, individual entrepreneur (French micro-entrepreneur regime)
    • Address: 12 Rue Georges Brassens, 32600 Lias, France
    • SIRET: 10483848700015

    Last updated: May 11, 2026.

    For organisations

    No data-schema impact. Summary-deletion actions are recorded in the audit log like every sensitive action.

  116. v1.0.0-rc.25Security posture hardening

    What’s in this release

    A technical pass: no new feature, but a full alignment on the 2026 cybersecurity standards across the web, mobile and infrastructure layers.

    The work focused on foundations that must remain invisible at use: transport protocols, browser headers, cache policies, session handling, logs and telemetry. All of this stays transparent for you — the posture is simply more robust.

    For end users

    No action required. Your existing sessions, preferences and configurations keep working as before. A transparent update of your account credentials parameters is applied on your next sign-in.

    For organizations

    For on-premise customers and security officers, a detailed audit is kept in our internal documentation. The cybersecurity standards applicable to all future changes are formalized and enforced continuously.

  117. v1.0.0-rc.24Account deletion — full GDPR overhaul (app transfer, anonymization, 2FA)

    What changes for you

    The Delete my account flow (Account page → Privacy section) has been fully redesigned. This release ships 6 improvements on security and GDPR compliance.

    New choice: permanent deletion or anonymization

    You can now pick between:

    • Permanent deletion: everything is wiped (profile, preferences, connector credentials, notes, sessions). Historical behavior. Your account vanishes completely from StatHall.
    • Anonymization: your email, name, password and preferences are wiped, but your contributions (notes attached to apps, anomalies you acknowledged, tagged reviews) stay on the platform — no longer attributable to you. Useful if you contributed and don’t want to erase the useful traces.

    App ownership transfer before deletion

    If you own one or several apps, the wizard now offers to transfer ownership to an existing co-owner or super-admin before closing your account. No more need to delete each app manually: pick a recipient in a dropdown and one click does it.

    Two-factor authentication required to delete

    If TOTP 2FA is enabled on your account, the wizard requires the 6-digit code from your authenticator app (or a recovery code) on top of your password. Prevents an attacker who has your password but not your 2FA device from initiating a deletion.

    14-day retraction window (down from 30)

    The window during which you can cancel a deletion is reduced from 30 to 14 days. Aligns with current practice (Apple Account Deletion, GitHub) while staying within French CNIL recommendations (7-30 days).

    Account locked during retraction + cancel via email

    During those 14 days you can no longer log into your account (login returns a dedicated error). Cancellation is done only via the link sent by email when you scheduled the deletion. Click the “Cancel request” button in that email — you land on a confirmation page, that’s it.

    Confirmation email after effective wipe

    Once the 14 days elapse and the wipe is effective, you receive a final confirmation email matching the chosen mode:

    • “Your StatHall account has been deleted”
    • “Your StatHall account has been anonymized”

    Not mandated by GDPR but a courtesy — you have certainty the request was honored.

    Under the hood

    • 1 Alembic migration adding two columns to the users table: delete_mode (NULL/'delete'/'anonymize') and delete_cancel_token (random 256-bit token for the email link).
    • 4 new API endpoints: list transfer candidates, execute transfer, delete with mode + TOTP, public cancel-by-token. The historical auth-required cancel endpoint is preserved for special accounts.
    • Server-side login guard: dedicated 403 account_pending_deletion during the grace period, exception for the Apple/Google review technical account.
    • Structured audit log: new actions account.anonymize.executed, account.delete.cancel_by_token, account.delete.transfer_ownership, all retained 3 years (proof of right-to-be-forgotten exercise).
    • Frontend 3-step wizard (Mode → Transfer → Confirm), new public page /account/cancel-deletion?token=..., FR and EN translations.
    • Mobile: no change (mobile redirects to web for deletion since rc.19). Aligned versions: mobile + backend + SPA + marketing all bump to 1.0.0-rc.24.

    No action required from you. If you had a scheduled deletion before this release, it keeps running normally with the historical behavior (permanent deletion, 30-day window preserved for those cases).

  118. v1.0.0-rc.23Share buttons — proper LinkedIn + X official logos

    What changes for you

    On the Donate pages (on the website, in the web app, and in the mobile app), the « Share on LinkedIn » and « Share on X » buttons looked a bit dull — either plain text, or a generic monochrome icon. Fixed: the buttons now sport the real official logos of both platforms, with their exact brand colors:

    • LinkedIn: LinkedIn-blue button (#0A66C2) with the official logo.
    • X: black button with the official X logo (inverted to white on the website’s dark themes, to keep contrast).

    The mobile button also said « X / Twitter »: we dropped the legacy « Twitter » mention, it now simply says « X » (aligned with the platform’s official rebrand).

    No other feature changes — this is a purely visual release.

    Under the hood

    • SPA: using the simple-icons package (already installed for connector logos since V3.S10), no new dependency. Internal <BrandIcon> component that renders the SVG path with fill-current to automatically follow the button’s text color.
    • Marketing: SVG paths inlined directly in the Astro markup (no dependency added — static site, minimal bundle).
    • Mobile MAUI: 2 new vector SVG files in Resources/Images/ (official Simple Icons logos under CC0 license), compiled to multi-density MauiImage by the build.
    • Consistency renames: the mobile ShareTwitterCommand becomes ShareXCommand, the intent URL switches to https://x.com/intent/post (canonical X URL since 2024 — the old URL was already redirecting, but using the right one is cleaner).
    • Aligned versions: mobile + backend + SPA frontend + marketing all bump to 1.0.0-rc.23.

    Note that the <meta name="twitter:card"> tag stays as-is in the site <head> — it’s the standard Open Graph convention for share previews, X still documents it under that name (renaming it would break the preview rendering inside feeds).

  119. v1.0.0-rc.22Security hardening — stronger browser protections

    What changes for you

    This release is exclusively focused on security hardening of the website and web app, following an external penetration test performed on 2026-05-10. No new feature, no visible change in the interface — you won’t notice anything in your daily use.

    Why it matters

    When your browser opens stathall.com, it receives a series of technical instructions that define what it is allowed to load: which scripts, which images, which servers it can connect to. Without those guard-rails, a vulnerability in one of the libraries used by the site could let an attacker inject malicious code.

    We tightened all those protections, on both the app (stathall.com) and the marketing site (www.stathall.com).

    Concretely

    • Strict resource loading policy: the browser now refuses to execute any script, load any font, or connect to any server that isn’t explicitly allowlisted. Only Cloudflare Turnstile (the anti-bot challenge on signup and reset-password forms) is allowed on top of our own domain.
    • Strengthened cross-site isolation: your StatHall tab can no longer be spied on by another tab opened on a third-party site.
    • The server version is no longer disclosed — an attacker can’t target a vulnerability tied to a specific version number anymore.

    Under the hood

    • Traefik reverse-proxy config (serving stathall.com + www.stathall.com) extended: Content-Security-Policy, Cross-Origin-Opener-Policy, Cross-Origin-Resource-Policy, and the upstream Server header is now stripped.
    • server_tokens off added to the nginx configs of both the app container and the marketing container.
    • Caddy config (used by on-premise deployments and local dev) aligned with the same cross-site protections.
    • COEP require-corp not enabled: would break the Cloudflare Turnstile iframe on authentication forms.
    • Aligned versions: mobile + backend + SPA frontend + marketing all bump to 1.0.0-rc.22.

    Alongside this sprint, three DNS actions remain to be performed on the Infomaniak side (DKIM configuration, cleanup of obsolete TXT records) — with no user-visible impact.

  120. v1.0.0-rc.21Fix « Delete my account » crash in the app + immediate mobile sign-out on web deletion

    What changes for you

    « Delete my account » no longer crashes

    In the mobile app, tapping Account → Delete my account was raising a navigation error. The cause: the internal route name collided with the Account tab. Fixed — the redirect page now opens cleanly, and its « Continue on stathall.com » button opens your browser as expected.

    Server list on login: back to swipe-only

    The icon to the right of each environment in the login screen was rendering as a red question mark on some phones — the icon font didn’t always map the trash glyph. We removed that explicit icon: deleting an environment is now done only via left swipe (Edit · Delete), like on iOS Settings or Mail. The hint under the list reminds you: « Swipe a server left to edit or delete it ».

    Tapping the row switches to that server, with no ambiguity.

    Account deletion: immediate sign-out across all your devices

    When you delete your account from the website, all your active mobile sessions are now invalidated in the same operation. Before: a device that still held a refresh token could theoretically keep refreshing its access for the 30-day grace window. Now: all mobile refresh tokens and all push devices are revoked at the same time the deletion is scheduled. Your mobile apps will require fresh authentication immediately, even during the grace period.

    This logic lives in a single place server-side — any deletion (web today, future channels if any) triggers the same behaviour.

    Under the hood

    • Mobile: route account-delete (flat) instead of account/delete (which was being interpreted as the Account section → Shell error). User-visible XAML unchanged.
    • Backend: revocation of MobileRefreshToken on deletion was moved from the caller to the schedule_deletion service itself. Centralisation: one code path to audit.
    • Dedicated pytest covering the device + refresh tokens cascade on SPA deletion.
    • Aligned versions: mobile + backend + SPA frontend + marketing all bump to 1.0.0-rc.21.
  121. v1.0.0-rc.20Explicit « Support » button in headers, and mobile deletion endpoints retired from the backend

    What changes for you

    The « Support » button is now explicit

    On the Inbox and Apps headers of the mobile app, the gradient circle with the coffee icon has become a wider pill with the word « Support » next to the cup. No more guessing what the button does — the intent is spelled out.

    It’s the same wording as the button in the website’s sidebar.

    Account deletion no longer exposed by the mobile app (server side)

    Following the rc.19 decision to redirect account deletion to the web browser, the corresponding server endpoints have been removed from the mobile backend:

    • POST /api/mobile/v1/me/delete → removed.
    • POST /api/mobile/v1/me/export-request → removed.

    This is more than cosmetic cleanup: the attack surface is genuinely reduced. The mobile app can no longer, even with a compromised token, trigger an account deletion or an export. Both sensitive operations are only reachable through the SPA web (/api/v1/account/delete, /api/v1/account/export) where the dedicated path is in place with step-up auth + grace period.

    The associated rate limits and schemas have also been removed. The personal audit console (GET /me/audit, read-only) remains available for the mobile A13 screen.

    Under the hood

    • Backend: 2 endpoints removed, ~250 lines of dead code dropped in me.py, schemas MobileDeleteAccountBody + MobileExportRequestResponse removed, related rate limits removed, 6 corresponding pytest tests removed.
    • Mobile: IApiClient.DeleteMeAsync + RequestDataExportAsync
      • record AccountDeleteRequest removed.
    • SPA web: no change — the deletion flow remains intact under My Account → Privacy & GDPR.
    • Aligned versions: mobile + backend + SPA frontend + marketing all bump to 1.0.0-rc.20.
  122. v1.0.0-rc.19Account deletion: web redirect from the mobile app

    What changes for you

    Account deletion happens on stathall.com

    The mobile app no longer offers account deletion directly inside the app. When you tap Delete my account on the Account screen, the app shows a short explanation page then redirects you to stathall.com → My account in your browser. The actual deletion is finalised there.

    It’s a security decision, not a regression:

    • Account deletion is irreversible (with a 30-day grace period, but ultimately: irreversible).
    • An action this critical deserves a dedicated path in the browser, where you have your usual environment to verify, export your data, re-authenticate your identity.
    • The mobile app still covers everything else: profile, preferences, sessions, sign-out. Only the final deletion is moved out.

    Concretely, on the web page you’ll be able to:

    1. Export your data if you wish (GDPR article 15 — a full copy of everything related to you).
    2. Confirm your identity (password + 2FA if enabled).
    3. Trigger the deletion — a 30-day grace period applies before complete erasure, during which you can still change your mind.

    Compliance

    This design has been explicitly accepted since 2022 under the Apple App Store Review Guidelines 5.1.1(v) and the Play Store requirements: a clearly indicated link to a web deletion page replaces in-app delete.

    Under the hood

    • The mobile app no longer reaches a backend deletion endpoint from the mobile API: that attack surface is removed.
    • Aligned versions: mobile + backend + SPA frontend + marketing all bump to 1.0.0-rc.19.
  123. v1.0.0-rc.18Support StatHall always one tap away, email pre-filled at login, and public changelog tidied up

    What changes for you

    Support StatHall directly from Inbox and Apps

    A coffee icon in a purple-gradient circle now appears at the top of the Inbox and Apps tabs in the mobile app, right next to the search magnifier. A tap takes you to the Support page, exactly like the dedicated button in the website’s sidebar. No need to dig into Account to find it — it’s right where you naturally look when using the app.

    The icon now uses the standard ☕ emoji for identical rendering on iOS and Android, with no dependency on an icon font.

    Email pre-filled when you switch environments

    When you tap a saved environment from the Setup or Login screen and that profile is tied to an email (format Production - your@email.com), the app automatically pre-fills the email field on the login screen. You only have to type your password — one less step.

    If you start typing in the field before the app has had time to pre-fill it, your input is preserved — the app never overwrites you.

    Public changelog tidied up

    The public history at www.stathall.com/changelog now only lists release-candidate versions (rc.1 to rc.18). Earlier development versions (alpha, pre-1.0) have been removed: they documented internal steps before the first public deployment and brought nothing to an end user.

    The result: a clean chronological history that starts at the first public stathall.com deployment and moves forward release by release without breaks.

    Under the hood

    • No backend or database changes.
    • Mobile: new Support icon with handler in the Inbox and Apps views. No embedded WebView — external links always open in the system browser.
    • Marketing: changelog sort logic stays as in rc.15 (descending date then release number). 26 files removed from the repo, 0 file added.
    • Aligned versions: mobile + backend + SPA frontend + marketing all bump to 1.0.0-rc.18.
  124. v1.0.0-rc.17Support StatHall directly from the mobile app + public changelog review

    What changes for you

    Support StatHall from the mobile app

    The mobile app gains a Support StatHall page in the Account tab, right above the sign-out button. A subtle purple gradient card with a coffee icon — discreet but visible. You can’t miss it when you open your settings, without it interrupting your usage.

    Tap it, and you land on a dedicated page that explains:

    • What your support funds (infra & hosting, AI model costs for weekly summaries, development time).
    • The transparency commitment: no « premium » feature tier. Every StatHall feature stays free and identical whether you donate or not. Your support funds the service’s existence, not a privileged access.
    • An alternative for those who can’t donate: spreading the word to other devs or product managers via LinkedIn or X / Twitter is just as valuable.

    Donations go through Buy Me a Coffee like on the website — one-off or recurring, starting at a few euros. The button opens your system browser; the app never touches your payment method directly.

    Public changelog tightened

    This release also includes a full pass over this page’s entries (rc.1 → rc.16) to remove internal details that didn’t belong in public — server file paths, module or migration names, precise validation parameters, tooling identifiers. The user-facing content stays intact; only the technical specifics that could have guided an attack were removed.

    For self-hosted teams

    The VITE_DONATE_BMC option you configure on the SPA still works exactly as before. The new mobile page hard-codes the official StatHall BMC handle — it’s not per-instance configurable for now (rationale: if you self-host, there’s no reason to surface a donate button for StatHall to your users). If that’s a problem for your deployment, please open an issue.

    Under the hood

    • No backend or database changes.
    • Mobile: new Support page + entry card in the Account tab. The main tap delegates to the system browser to preserve your privacy (no embedded WebView).
    • Aligned versions: mobile + backend + SPA frontend + marketing all bump to 1.0.0-rc.17.
  125. v1.0.0-rc.16Connected devices management is now on the web app — revoke your mobile sessions from My Account

    What changes for you

    Manage your mobile devices from the browser too

    Until rc.15, the « Connected devices » list was only reachable from the mobile app (Account → Devices). If you lost your phone, or wanted to check your open sessions from your workstation, you had to grab your device — slightly paradoxical.

    Now, app.stathall.com → My Account → Security displays the exact same list, with:

    • The Apple or Smartphone icon depending on platform.
    • The user-given device name (« Sebastien’s iPhone »).
    • A combined OS · model subtitle (« iOS 26.4 · iPhone16,1 »).
    • Relative time since last activity (« Seen 2 min ago », « Seen yesterday », « Seen 3 d »…).
    • A Revoke button per device, with inline confirmation (title + risk description + Confirm/Cancel buttons).

    When you revoke a device, its session becomes invalid immediately, no more notifications can reach it, and the user must sign back in to access data.

    It’s the exact same flow as mobile, now available from both sides.

    Security group description expanded

    The Security group in My Account now reads « Two-factor authentication (2FA), backup codes and connected devices » instead of « Two-factor authentication (2FA) and backup codes », to reflect the new screen.

  126. v1.0.0-rc.15Public changelog sort fix — the latest release now correctly sits at the top

    What changes for you

    The latest release is back at the top

    On the /changelog page, multiple releases shipped on the same day (rc.6 through rc.15, all dated 2026-05-10) could appear in the wrong order — rc.9 surfaced above rc.14.

    Now the sort considers the release-candidate number whenever several entries share the same release date. The latest release is always on top, no matter how many ship on a single day.

  127. v1.0.0-rc.14Redesigned « Connected devices » card: platform icon, combined OS + model, and relative time (« seen 2 min ago »)

    What changes for you

    The « Connected devices » list becomes readable

    Before rc.14, each device in Account → Connected devices displayed its name followed by three raw lines: a lowercase platform (« ios »), a 10/05/2026 12:22 date, and a red « Revoke » link with no framing. Hard to spot your iPhone at a glance when you have multiple sessions.

    Now each card shows:

    • A 44 × 44 pt indigo capsule with the Apple or Smartphone icon depending on platform — immediate visual cue.
    • The device name as a bold title.
    • A combined « OS · model » subtitle (e.g. « iOS 26.4 · iPhone16,1 ») — see the platform and exact model in one glance.
    • Relative time (« Seen 2 min », « Seen yesterday », « Seen 3 d »…) instead of an absolute date to decode.
    • The « This device » badge clearly positioned top-right when it’s the current session.
    • A framed Revoke button in red rather than a plain link — destructive action is visually recognisable.

    Spacing between cards bumps to 10 pt to breathe, and the empty state message is updated to reflect rc.12 (the app now registers the device at login automatically — no need to grant push first for it to appear).

  128. v1.0.0-rc.13Defensive validation on stored sessions + changelog gap-fill

    What changes for you

    Stored sessions: defensive validation

    The app uses your locally-stored session credentials to automatically rename your server profiles with your email. Before rc.13, the reader didn’t check the consistency of the data — safe in practice but not robust against storage corruption or edge cases.

    Now several structural checks are applied before any use: if any fails, the app keeps the historical profile name rather than altering it with invalid data.

    Changelog gap-fill rc.7 → rc.11

    The marketing site previously only displayed rc.6 and rc.12 — every intermediate iteration (rc.7 through rc.11) has now been added to the public changelog, in both French and English. You can now follow the full history of the mobile app, from the expandable Inbox stacks (rc.7) to the full server management refactor (rc.11).

  129. v1.0.0-rc.12Your iPhone now shows up in 'Connected devices' even without push + security hardening + version alignment across the stack

    What changes for you

    Your iPhone shows up under « Connected devices » even without push

    Before rc.12, your device only appeared under Account → Devices after you had granted iOS / Android push permission. If you refused it or simply hadn’t gotten to the prompt yet, the list stayed empty even though you were logged in. Now the app registers your device at login with or without push permission — your install is always visible, and notifications turn on automatically the day you grant the permission.

    The current device is also recognised as such — useful for multi-device management and to avoid accidentally signing out the very device you’re cleaning up from.

    Hardened security

    • Link validation: a link opening the app is now only accepted if it points at a known domain (the SaaS or a registered self-hosted environment).
    • Clean device revocation on logout: your mobile session is invalidated server-side at the same time you sign out — no more notifications can reach a device you’ve signed out from.
    • Diagnostics sent to Sentry: emails and technical identifiers present in traces are automatically masked before upload.

    Stability

    • Several UI handlers that could silently die on error are now traced without interrupting the app.
    • Components that subscribe to global events now unsubscribe cleanly on teardown → no more memory leak after navigating Inbox / Apps / Account back-and-forth.

    iOS HIG / Material 3 standards

    • Tap targets bumped to 48 dp on Android (vs 44 pt iOS, unchanged) per Material Design 3.
    • Safe-area insets applied to the missing detail screens — content no longer slips under the Dynamic Island / Android notch.
    • Semantic heading hierarchy added (Inbox, Apps, Account) so VoiceOver / TalkBack announce page structure correctly.

    Versions aligned across the stack

    This release realigns mobile + backend + SPA frontend + marketing site on the same 1.0.0-rc.12. No more version drift between the app and the service.

  130. v1.0.0-rc.11Delete servers from the Setup screen, polished swipe in the server list, and automatic rename of existing profiles

    What changes for you

    Delete from the pre-auth Setup screen

    Before rc.11, deleting an environment was only possible from the login (with an active account) or from Account → Servers (post-auth). If you landed on the initial Setup screen with several existing profiles, you couldn’t clean up before signing in.

    Now the « Continue with an existing server » list on the Setup screen exposes the same swipe-to-delete as the other screens — swipe left to reveal the red Delete button with confirmation. If it’s the last profile remaining, the app offers a Reset everything action that wipes everything and sends you back to the empty Setup screen.

    Polished server list (iOS Settings-style)

    The Account → Servers screen is reworked to look like native iOS Settings: single rounded container, flat rows with separators, comfortable minimum row height. Left-swipe reveals Edit (indigo) and Delete (red) in standard slide-over mode (no auto-execute on full swipe). No more colour bleed or rounded corners clipping awkwardly during the drag.

    Automatic rename of existing profiles

    If you had several profiles created before rc.9 (without an email suffix in their name), they were stuck with their historical name. Now every time you open the login screen, the app detects the account linked to each profile and automatically renames it to "{base} - {email}".

    It works for stathall.com as well as for any custom server (« Test » on localhost, on-premise environments, etc.). The rename is idempotent: if the suffix is already present, the app does nothing.

  131. v1.0.0-rc.10The Delete button becomes explicit — no more guessing you had to swipe

    What changes for you

    A visible 🗑 icon on each server

    The swipe-to-delete shipped in rc.9 worked, but many users didn’t realise they had to swipe to reveal the action. Now every non-active profile in the « Switch to another server » list shows a red trash icon of 44 × 44 pt on the right — tap to confirm and delete. The swipe is still available as a bonus, but the action is immediately visible for everyone.

    « Manage servers » as the main entry point

    The « Edit server » button under the active block becomes « Manage servers » — its action sheet now contains:

    • Continue with stathall.com (when not yet configured)
    • Edit current server
    • Add an environment
    • Manage servers (new) → opens the full Account → Servers page with full CRUD, ability to delete the active profile after switching, or reset everything.

    The hint under the list is rewritten to spell out the three paths: « Tap a row to switch · 🗑 to delete · Edit server → Manage servers for the full list ».

  132. v1.0.0-rc.9Anti-duplicate on the server list: one profile per (URL × email) pair, even if you sign in multiple times

    What changes for you

    No more « Production » profiles piling up

    If you tapped Continue with stathall.com several times from the login screen (e.g. after reinstalling the app), a new « Production » profile would appear each time, all with the same URL — eventually the « Switch to another server » list became unreadable.

    Now, after every successful login, your active profile is automatically renamed « Production - your@email.com », and any profile with the same URL and email is consolidated. If you sign in again with the same email, the existing profile is reused instead of creating a new one.

    If another person signs into the same server from the same device (rare in practice, common in QA), they get their own separate profile — no collision.

    Swipe-to-delete on the server list from login

    The « Switch to another server » list on the login screen now exposes the same actions as Account → Servers: swipe left on a row to reveal Edit (indigo) and Delete (red) with confirmation. No need to go into Settings to clean up.

  133. v1.0.0-rc.8Robust back navigation, accessibility up to Apple HIG standards, and an Inbox that no longer jumps while loading

    What changes for you

    The back button always works

    Before rc.8, some back paths could leave the app stuck on an error screen — typically when you came in from a push notification or a deep-link into an anomaly detail. This release makes back navigation robust across the whole app, with an explicit fallback to the source tab. No more freeze, no more dead screen.

    Inbox: no more scroll jump while loading

    When you scrolled the Inbox while pagination was loading new items, your scroll position could jump back to the top. Now your position stays stable even if the source changes while you read.

    Accessibility — Apple HIG / Material Design standards

    • Icon buttons (search, settings, back) bump to the minimum recommended by Apple (« Touch Targets ») and Material 3 (« Accessibility »).
    • Semantic labels and descriptions are enriched so VoiceOver / TalkBack announce each action correctly.

    Roadmap: the Gantt rendering lands

    The Roadmap screen for an app now shows DEV / TNR / REL phases as proportional colored bars, with a vertical red line marking the current instant — see at a glance where each version stands.

    Settings: Servers and Devices get dedicated pages

    Before, Account → Settings mixed everything. Now Servers (stathall.com / on-prem environment management) and Connected devices (devices with push) each have a dedicated page, with swipe-to-delete and native confirmation.

    Versions: platform auto-detection

    On the Versions screen of an app, if you’ve only configured iOS or only Android, the app automatically detects which platform has data and switches to it on open. The unused platform’s toggle is greyed out.

    AI Summary: navigable history

    The AI Summary screen of an app now shows a horizontal row of past summaries at the bottom — tap to re-read any of the recent summaries. No more digging in the web app.

  134. v1.0.0-rc.7Inbox is easier to read — your summaries and new versions are now grouped automatically by app

    What changes for you

    Expandable stacks in the Inbox

    When you track several apps, the Inbox could get noisy — each app emits its weekly summary and declares its new versions, drowning out the actual anomalies. From now on, summaries and versions for the same app collapse automatically into a single « 3 updates · App X » row you tap to expand.

    Anomalies are never collapsed: they stay individually visible because those are the ones you need to act on quickly.

    UX cleanup

    The Apps tab drops the « Portfolio » segmented control that didn’t add value on small screens: we list your apps directly, with their health badge, no extra tab to pick.

    This release also includes internal fixes to smooth iOS deploys on recent system versions.

  135. v1.0.0-rc.6Mobile app redesign: a unified Inbox, links that open the app, and at-a-glance health scores

    What changes for you

    A mobile app rebuilt around your Inbox

    The StatHall app for iOS and Android moves from five tabs to three: Inbox · Apps · Account. The Inbox becomes the landing screen and aggregates everything that needs your attention across all your apps in a single feed: anomalies, AI summaries and detected releases. Filter by type with a chip row, swipe to acknowledge in two taps, switch scope (all apps / one app) through a bottom sheet with search.

    The Account tab finally groups profile, preferences, security & GDPR and support into four clear cards.

    When you get a StatHall URL via email, Slack or SMS — like https://app.stathall.com/apps/my-app/anomalies/123 — your phone opens the native app directly on the right anomaly if it’s installed, without bouncing through the browser. Otherwise the web page loads as usual.

    This is what Apple calls Universal Links and Google calls App Links. Nothing to do on your end — it works as soon as the rc.6 app is installed on your device.

    A visual health score per app

    The app detail screen now shows a circular HealthGauge that summarises overall health, broken down into three progress-bar sub-scores: technical (crashes, ANRs, performance), business (ratings, reviews, revenue for paid apps), adoption (downloads, MAU, retention). You spot in two seconds what’s dragging an app’s score down.

    Releases timeline and roadmap, on mobile

    Two new screens accessible from an app’s detail:

    • Versions — iOS/Android timeline with release dates and crash-free deltas between consecutive versions.
    • Roadmap — Gantt swimlane (DEV / TNR / REL) in read-only mode to follow upcoming milestones without opening the web app.

    Better push notification management

    A new Notifications screen lists every push received with timestamp and read / unread state. If system notifications are disabled at the OS level, an inline banner reminds you to open Settings — you no longer miss a critical alert because permission was accidentally denied.

    Who’s affected

    Every StatHall mobile user on iOS and Android will receive the rc.6 update through TestFlight (iOS) and Internal Testing (Play Store). No server-side migration on your end — the new screens populate automatically.

    On the web, nothing visibly changes this time: rc.6 is a 100 % mobile sprint.

    Known limitations

    • The Roadmap screen on mobile is read-only — to add or edit a release, open the web app.
    • Universal Links activate on the server side as soon as the iOS and Android signing identifiers are configured. If you see a link open in Safari/Chrome instead of the app, the device hasn’t re-fetched the association file yet (Apple refreshes it every 24 h).
  136. v1.0.0-rc.5Android store crashes, deep-links to your tools, « new / regression / spike » badges on every issue

    What changes for you

    Your Android crashes, even without Crashlytics

    StatHall now ingests Android crashes directly from Play Vitals (the console that feeds your Play Store listing). Every user with an active Google Play connector sees error clusters (crash + ANR + non-fatal) appear automatically under the Crashes tab, with nothing to add or configure.

    On iOS, Apple doesn’t offer an equivalent public API — you stay on Sentry or Crashlytics for iOS details.

    One click to open the source console

    Every crash issue now sports an external icon to the right of its title. A click takes you straight to the issue page in Sentry, Firebase Console or Play Console — the exact same issue, opened in the tool you use to fix it.

    The URL is built from the information already saved on the connector. For Play Console, a new optional field « Play developer ID » appears on the Google form: it’s the numeric ID visible in your console URL. Without it, everything else works — we just hide the Play icon.

    Crashlytics + Play Vitals: a single line per crash

    When the same Android crash is reported by both Crashlytics and Play Vitals, StatHall automatically merges the two rows into one. The canonical row is the one with the most occurrences; you see both external icons side-by-side to jump between tools, plus a small « Correlated » badge to explain the match.

    Matching uses two steps: an exact match on the normalised title, then a fallback on semantic similarity for cases where labels diverge.

    Four badges to skim faster

    Every crash issue can now carry up to four visual badges:

    • New — issue first seen in the last 7 days.
    • Regression — issue that had been resolved then resurfaced. Reported directly by Sentry.
    • Spike — recent occurrence volume meaningfully above the 14-day baseline. Auto-detection with hysteresis to avoid false flicker.
    • First seen in vX.Y.Z — issue that appeared in your latest release. First signal of a potential regression tied to the release.

    The badges are designed so you can spot, at a glance, what deserves attention in a long crash list.

    Small UI cleanups

    • The old « Access » tab in app settings was removed: it duplicated « Team », which covers everything (members, invitations, viewer / co-owner roles) in a single view.
    • The « Add version » button appeared three times on the roadmap (header, Gantt toolbar, empty state). The Gantt-toolbar duplicate was removed — only one occurrence is visible now.

    Who this changes things for

    Any team with an active Google Play connector. Play Vitals crashes appear automatically on the next sync. Badges and deep-links are visible from the first refresh of the Crashes tab.

    To enable the direct link to Play Console on crashes, open Sources → Google → Play developer ID and paste the numeric ID from your console URL.

    Known limits

    • iOS remains asymmetric: Apple doesn’t expose a stable public API for detailed crash issues. For iOS crashes, we rely on Sentry or Crashlytics.
    • The Play Vitals API doesn’t expose the « regression » concept on Google’s side. The « Regression » badge therefore only lights up on issues sourced from Sentry for now.
  137. v1.0.0-rc.4AI Summary rethought: token at the app level, configurable auto-generation, clearer reading experience

    Same-day patches

    A handful of follow-ups went to prod on May 6th right after the initial rc.4 tag — they all still carry the rc.4 tag:

    • Editing just the monthly quota or preferred model without re-typing the API key now works. Before: saving was impossible unless the key was re-entered. After: the key stays optional in edit mode; the server keeps the encrypted key it already has.
    • Simplified LLM Key card: removed the now-redundant “Edit” button, the reveal eye only appears once at least one character is typed, richer placeholder.
    • Weekly summary toggle now persists across refreshes. Older accounts (with a legacy frequency field) stay active automatically.
    • Default auto-pregeneration moved to Sunday 23:59 UTC (instead of Monday 00:00 UTC) — more consistent semantics: the report is generated right before midnight Sunday and covers the week that just ended (Mon→Sun).
    • « How it works » caption rewritten to spell out the covered window with two concrete examples, no more vague reference to the “default config”.
    • « Saved » visual confirmation on every user-facing Save button — a green pill that auto-hides after 2.5s.

    What actually changes

    AI Summary — per-app configurable auto-generation

    • The LLM token now belongs to the app, not the user. Before: every user had to drop their own DeepSeek or OpenAI API key in their account; in practice, in a team, either nobody did it or one person carried it individually. Now: the key is configured once by the app owner, in the app settings → AI tab. It’s masked behind asterisks (you’ll never see the key in clear again after entering it), with a « Test connection » button to validate authentication before the first cycle.
    • Weekly auto-pregeneration configurable at the app level: on/off toggle, day-of-week + UTC time, plus checkboxes for generated scopes (Global, iOS, Android — pick any combination). The covered window is the 7 fully elapsed days before generation (default: Monday 00:00 UTC to Sunday 23:59 UTC). No more relying on someone clicking « Generate » every Monday.
    • Estimated cost displayed right in the auto-generation configuration screen: number of LLM calls per cycle + this month’s running total against the declared quota.
    • No more manual generation for users. The summary screen becomes a pure reading view: you navigate previously pre-generated reports, you don’t trigger them.

    Reading summaries — clearer UX

    • Explicit day counter on the period selector: « From 20/04/2026 to 26/04/2026 inclusive = 7 days ». The inclusivity of the end date is materialised in the text to avoid the ambiguity that made people think a 20→26 range covered only 6 days.
    • Auto-snap to the closest pre-generated report. When you pick a range that doesn’t exactly match any pre-generated report, a « Go to closest report » button appears with a clear message — no silent surprise.
    • Better empty states: weeks with no reviews render as « No reviews this week » instead of a blank page.

    Email preferences — simplified toggle

    • The user no longer picks the send day of the weekly summary. The day is imposed by each app’s pregen configuration — it’s consistent: the digest goes out as soon as the report is ready. Users keep a yes/no toggle to subscribe / unsubscribe per app.
    • Old account-level API keys are marked as deprecated via an explicit warning banner. You can delete them in one click from your account; they no longer have any effect on summaries.

    AI history for admins

    • New « AI History » tab in app settings (super-admin only). Paginated table of every generation attempt — successes, empty weeks, missing keys, provider errors or quota exhaustion. Each row shows the date, covered period, scope, origin (auto / admin manual), status, review count and actual cost.
    • « Generate missing report » button: lets an admin fill a gap (LLM outage, quota exceeded one week, key absent at cycle time) without replaying an already-published report. The generated report is tagged « admin manual » in the history for traceability.

    Performance — Faster Dashboard and app list

    • App dashboard: the « Top themes 30d » widget loads significantly faster on high-review-volume apps. Expected gain: -40 to -60 % on dashboard load latency.
    • Admin app list: the « earliest sync date » query is now aggregated in a single pass instead of one per app. Gain: -20 to -30 % on list latency, proportional to app count.
    • Navigation cache: dashboard and portfolio screens keep their data cached for 60 seconds (instead of 30) and 5 minutes in memory after switching screens. No more redundant refetch when navigating between tabs.

    Migration

    • No automatic copy of existing user-level LLM keys to the app level. Project decision: we want to force an explicit gesture from the owner to confirm which key is used for which app. Apps without an app-level key won’t get a pre-generated summary until reconfiguration.
    • Admin audit tool to list, per app, its owner and the state of key configuration. Lets an admin notify the right owners post-deploy in minutes.

    Who this matters to

    Any team that was using AI Summary so far. Before rc.4, the LLM cost depended on one person’s key in the team, and generation had to be triggered manually every week. After: cost is managed at the app level, generation runs by itself on the configured day, and the team discovers the report by opening the screen.

    What’s next

    • Effective removal of legacy user-level keys: shipped same day in rc.4.1.
    • Configurable cadence beyond weekly (bi-weekly / monthly) if users ask for it on review volumes that justify it.
    • On-demand generation for owners (not just super-admins).
  138. v1.0.0-rc.3App dashboard redesign, Play Store scraper bumped to 16 markets, fairer tagging and faster dashboard

    What actually shipped

    App dashboard — noticeably faster

    • An app’s dashboard no longer loads KPIs for every other app in the workspace just to keep one. Before: opening the dashboard ran several useless queries per workspace app, then filtered in application code — latency grew linearly with app count. Now: the filter is applied at the data layer, only the relevant app is computed.

    Play Store scraper — 5 markets → 16 (Americas, Europe, French overseas)

    • More Play Store markets queried at each backfill to capture reviews exclusive to regional storefronts (a review posted from Brazil doesn’t necessarily surface in the French or US feed). Coverage now: Europe (FR, GB, DE, ES, IT, NL, PL, PT) + Americas (US, CA, BR, MX) + French overseas (Guadeloupe, Martinique, Réunion, Guyane). Oceania intentionally excluded.
    • No depth gain in time : Google caps the public feed at about 6 weeks regardless of market. That’s why we don’t have full Android history like we do on Apple.
    • No duplicates despite multiple markets: a review seen first in one market isn’t reprocessed when the scraper moves to the next.
    • Backfill counter fixed: the « Recent jobs » card used to display fetch counts (inflated by cross-market re-runs of the same review). It now reflects reviews actually added to the database — consistent with the « Android reviews » dashboard card.

    Review tagging — no more bogus « bug » on stock complaints

    • The tagger no longer confuses real-world and the app. Before: a review like « out of stock for days » got labelled bug + perf + UX. After: if the text isn’t about the app, the bug / ux pills don’t light up.
    • Three new business labels for retail / delivery / restaurant apps: stock (out of stock, unavailable), delivery (delay, driver, store pickup), customer_service (support, call center, in-store welcome). Shown in a separate « Off-app » family, visually distinct (slate pill).
    • Contextual suppression of remaining false positives: if a business label clearly dominates app labels, low-scored app pills are auto-removed.
    • Hardened e-commerce health profile: reviews tagged stock / delivery / customer_service are now explicitly excluded from the business health score.
    • Retag of existing reviews: an admin can reapply the new rules to history with a single command.

    App dashboard — denser first view, faster to read

    • Beefed-up « Average rating » card: the big 7d number is now flanked by two baselines on the right — the 30d average and the global average across all reviews in the database. Below each number, the review count (n=…) makes the statistical fragility of the 7d number explicit on low-volume apps — fewer than 5 reviews and the 7d value greys out.
    • Four new widgets on the dashboard:
      • Replies 30d — share of reviews that received a reply from the support team.
      • Last release — relative date per iOS / Android platform, with a ⚠ badge if more than 90 days without a release.
      • Open anomalies — compact P0 / P1 / P2 grid of anomalies still in flight.
      • Top review themes (30d) — the 8 most recurring themes with the average rating per theme. See at a glance that « payment » sits at 4.2★ while « crash login » sits at 1.8★.
    • Layout reorganised by reading order: health → ratings → adoption proxy → review quality → tech / ops. ~40 % less scroll.

    Coming next sprint

    • Active users per version × OS with impact weighting (a regression on a 1 % adoption release matters less than one on the dominant release). Deferred to validate each source in a dedicated window.

    Google Play backfill — bucket dropped

    • The Google Cloud Storage bucket disappears from the Google Play connector. Before: you had to provision and authorise a bucket via Play Console, copy its name into the connector form — in practice almost nobody got past that step. Now: no bucket to configure.
    • Historical reviews: pulled from the public Play Store listing across five markets (FR, US, DE, ES, IT) in parallel, with auto-deduplication. On repeated backfills we stop as soon as we hit a review already in the database.
    • Historical downloads: pulled from Google’s official API, with about a year of history available. Same service account, zero new permission to grant.
    • Connector docs rewritten. The Google install guide now fits in three steps instead of five.

    Who this matters to

    Anyone trying to backfill an Android app’s history in StatHall. Before rc.3, the « GCS bucket » screen literally blocked onboarding. Now, as soon as the service account validates, the historical imports are available under Synchronisation with no extra config.

    Owned limits

    • Public review scraping fetches what the Play Store exposes publicly (typically a few thousand recent reviews per market). For apps with a very long history, the older tail can no longer be backfilled.
    • Install history is capped at about a year by the official API. Earlier than that is impossible on Google’s side.
    • Scraping is a best-effort mechanism — Google can shut it down without notice. The official API remains the only guaranteed source for ≤ 7-day reviews.
  139. v1.0.0-rc.2Connector chain UX fix — visible feedback, no more silent failures

    What actually shipped

    • Fix « Never signed in » on invitation-created accounts. When a new user accepted an invitation and set their password inline, their account showed up in the admin list but with « Never signed in » in the last-login column — even though they had just completed onboarding with an active session. The acceptance date is now recorded as the first sign-in, consistent with the regular login flow.
    • Connector test now responds. When you tapped Test connection on a connector (Sentry, Apple, Google, Firebase) and it failed, the screen stayed blank — no message, no sign the request had even been sent. A red banner now systematically appears with the cause: invalid credentials, network down, server error, or rate-limit.
    • The Install button no longer closes silently. If saving credentials fails, the form stays open with an explicit error banner.
    • No more bogus « Android package missing » warning. The Google Play form showed this message wrongly, even when the package was filled in at the previous step.
    • Silent rate-limit hotfix. An uncaught exception was returning silent 500s on some rate-limited calls. Fixed.
    • Sources > Advanced tab clarified. The two cards (Google Play and Apple App Store Connect) were indistinguishable. Each card now shows its official logo + the connector name, and the historical-import title spells out the source. The Apple card only appears once the vendor number is filled in (without it, Sales Reports backfills failed silently).
    • Translation key display bug: some strings on the Sources tab rendered as raw untranslated keys. Fixed.
    • GitHub logo now visible in dark mode (Sentry too): the icon was near-black on dark grey, contrast ratio too low. The logo square background is now permanently white — App Store / Play Store convention, preserves brand recognition in dark mode.
    • Google Play GCS bucket merged into the Google card. Before: separate card under Sources > Advanced. Now: integrated field on the Google form, like Apple’s vendor number. « Install » persists credentials + bucket in a single click.
    • Historical imports moved under Synchronisation. Google + Apple backfill tools aren’t really « config » — they’re one-shot syncs. They now live at the bottom of the Synchronisation tab, visible only when the source is ready to backfill.

    Who this matters to

    Anyone trying to wire a Sentry, Apple App Store Connect, Google Play or Firebase connector to an app — roughly 100 % of the onboarding path. The silent bug made the experience kafkaesque: you clicked, nothing happened, you didn’t know what to do. rc.2 fixes that upstream (bundle ID propagation) and downstream (errors surface in the UI).

  140. v1.0.0-rc.1First public deployment — app.stathall.com + www.stathall.com

    What actually shipped

    • StatHall is live. The product now runs at app.stathall.com (SPA + API) and the marketing site — the one you’re reading — at www.stathall.com. No functional change compared to the last alpha: this RC marks the move from staging to production.
    • Deployment tooling hardened. A fresh install now goes through without manual intervention, even on a host that already runs other sites.
    • Marketing site bundled in the deploy. The site is built and served on every release, fully static, with no tracker injected.
    • No database schema change this sprint. Pure go-live and consolidation.

    What’s next

    • Production soak to watch the real-world behaviour of connectors on live apps.
    • Stable v1.0.0 tag once the security checklist clears.