Changelog

Changelog

What changed in each plugin, newest first.

The changelog text is in English, as in the plugin.

Atom feed

Latest releases

Babbla

Version 0.46.1

Fixed

  • With the chat closed, the unread badge could miss a message for up to two minutes when two arrived within a few seconds of each other. Tabs of one browser share the unread count for eight seconds (0.18.0), and a tab that noticed the second message could take the count another tab had fetched just before it. A shared count is now used only when it is at least as new as the change the tab noticed; otherwise the tab asks the server.
Babbla

Version 0.46.0

Added

  • Settings → Babbla → Diagnostics can turn on lean chat reads. Every time a chat checks for new messages — the conversation list, a conversation's messages, the unread count and the combined check the open chat makes — WordPress normally starts with every plugin and the theme, WooCommerce included, although none of them is needed to answer. With lean reads on, those requests load only Babbla and no theme, so each one holds a PHP worker for a fraction of the time. Sending messages, the assistant and everything else on the site are unchanged. It installs a small must-use plugin, wp-content/mu-plugins/egenverk-babbla-lean.php, and is off until an admin turns it on: a plugin that grants chat access through its own capability rule is not loaded for those requests either, and its users would then be refused — turn lean reads off again in that case. Deactivating Babbla removes the file (on a multisite network only a network-wide deactivation does, since the file serves every site). wp egvb lean on|off|status does the same from WP-CLI. When a Babbla update changes the file, Diagnostics offers to update it.
Babbla

Version 0.45.0

Added

  • Diagnostics now has a Server load card showing Babbla REST requests by route, request rate and response time. It needs a persistent object cache such as Redis; without one it counts nothing. Measurements remain for at most two hours.
Babbla

Version 0.44.0

Changed

  • A new message or an assistant answer now wakes only the chats of the people who can see it, instead of every open wp-admin tab on the site. Each user has their own change signal file: an assistant conversation wakes only its owner, a direct message its two participants, a private room its members. A public room still wakes everyone. Before, every write — including each step of an assistant answer ("Searching the chat…", "Calculating…") in someone's private assistant chat — made every open tab of every user ask WordPress, so one question could cost more than a hundred WordPress starts across the site. The file still says only that something changed; its name is derived from the user id, a random key and the site's secret salt, so no one can work out a colleague's file.
  • Settings → Babbla → Diagnostics tests the admin's own signal file, so opening the tab no longer wakes every other open chat.
  • A wp-admin tab left open across the update reads the old shared file, which is deleted once the first user file is created: it gets three 404s and asks the server on a schedule until it is reloaded. Uninstall (with purge on) removes every user file.
Lagom

Version 0.20.0

Added

  • Database (M5): while switched on, shows (in a section under the settings) the 25 largest site tables (plus any smaller one worth optimizing) and the 20 largest autoloaded options with owner guesses. One table can be optimized per confirmed click only when it is at most 500 MB, has at least 20 MB and 20 % free inside (InnoDB shows a few MB free in almost every small table, which a rebuild does not return), and the database data directory has at least twice its size free. Larger tables get a maintenance-window explanation. Autoload can be stopped per option, never for protected WordPress options, and each change can be undone from the log. Nothing is deleted or changed automatically; the limits keep rebuilds away from large production tables and protect available disk space.
  • tests/database-test.php (wp eval-file).
Lagom

Version 0.19.0

Added

  • Heartbeat, transients and sessions (M4): slows the admin heartbeat and, each night at 03:00 site time (kept across daylight-saving changes), asks WordPress to delete expired transients and removes expired WooCommerce sessions in batches. Core leaves expired transient rows behind when a persistent object cache is active; Lagom forces the database cleanup after showing the counts first. The run keeps 60 measured rows and the card shows the last 10. On dev, 11 363 expired rows took 1 969 ms to remove.
  • tests/housekeeping-test.php (wp eval-file).
Lagom

Version 0.18.0

Added

  • Request watch (M3): with the module on, every wc-ajax call (per endpoint), admin-ajax.php call (per action, Heartbeat labelled), REST call (per route pattern, so /wp/v2/pages/3 and /4 are one row; unknown routes as no-route, and calls refused before they run, such as by a permission check, by their path with numbers as {id}) and wp-cron.php hit adds one short line to a file for that minute under uploads/egenverk-lagom/watch/. No database write and no cache on the request path: about 18 µs per call measured on dev, and files stop growing at 2 MB a minute. A WP-Cron job sums finished minutes every minute into the last hour's counts and deletes the files; the card shows the top 25 endpoints (total, peak per minute, last minute) and warns when WP-Cron has not run, the folder is not writable or a minute hit the cap.
  • When an endpoint passes the threshold in one minute, admins see a notice on every admin screen until they dismiss it, and one email per endpoint per hour goes to the address on the card, or the site's admin email.
  • Nothing about the visitor is stored (no IP, user, cookie, query string or body). Switching the module off stops counting and deletes the files, once at once and once ten minutes later, since a persistent object cache can serve the old setting to the front end for a while. Uninstall removes the counts, alerts, scheduled jobs and the folder.
  • tests/watch-test.php (wp eval-file; run it as the web server user, or chown the folder afterwards).

Fixed

  • tests/scheduler-test.php passes phpcs (multi-item arrays on one line).
Lagom

Version 0.17.0

Added

  • Scheduler cleanup (M2): with the module on, Action Scheduler's own cleaner removes finished and canceled jobs older than "Keep finished jobs for" (default 14 days, Action Scheduler's own is 30) and failed jobs older than "Keep failed jobs for" (default 90 days), with their log rows. "Finished jobs per cleanup run" sets how many finished and canceled jobs go per status each queue run; Action Scheduler 4.0 removes failed ones 20 at a time on its own, by design, so they never crowd out the rest. Lagom sets Action Scheduler's filters and never runs its own delete on its tables. Action Scheduler below 4.0 never removes failed jobs; there Lagom adds one daily job that asks Action Scheduler's cleaner to remove them.
  • The switch saves on only after Show what would be removed has counted, for the values in the form, the finished, canceled and failed jobs and log rows that would go, within the last 10 minutes; lowering a retention while the module is on needs a new count too. The count also shows which Action Scheduler version runs and any log rows that belong to no job (left alone).
  • A log keeps removals per day and source (200 rows); the card shows the last 20 and the total for the last 30 days. Uninstall removes the log, the counts and the daily job.
  • tests/scheduler-test.php (wp eval-file).

Changed

  • "Rows per batch" became "Finished jobs per cleanup run", 20–500, default 100 (was 50–5000 rows, default 500), since it now sets Action Scheduler's batch size and Action Scheduler cleans inside each queue run: on dev one run of 500 per status removed 520 jobs in 9.5 s, about 18 ms each, which would hold up the jobs waiting behind it.
Lagom

Version 0.16.1

Fixed

  • Old bookmarks to tools.php?page=lagom now reach Tools → Lagom instead of "Sorry, you are not allowed to access this page": WordPress refuses the unknown page before admin_init, where the redirect used to run.
  • The zip from bin/package.sh gives every file and folder readable modes, so fonts copied with private modes no longer answer 403 on servers where the web server runs as another user.
Lagom

Version 0.16.0

Added

  • Dashboard widgets (M1): with the module on, the widgets ticked on Tools → Lagom are removed from the dashboard before it is drawn, in every column, so their render code never runs (the Kustom widget calls its API twice per load there). Hiding a widget in Screen Options only hides it. Lagom still records every widget first, so a removed one stays in the list and can be unticked. Work a plugin does while registering its widget, or scripts it enqueues for the dashboard, are not affected; the asset rules handle the latter.
  • tests/dashboard-test.php (wp eval-file).
Babbla

Version 0.41.0

Added

  • Settings → Babbla → Diagnostics has a "Live updates" row. When the tab opens it rewrites the change signal file and fetches it back over HTTP the way a browser does: it says the signal works, that the file is cached or unreachable (with the HTTP status, or "stale content" when an old token comes back), that the test could not run from the server (a blocked loopback, which says nothing about the browser), or that uploads is not writable. The result is kept for five minutes, so reloading the tab does not rewrite the file each time.

Changed

  • The change signal file moved from the uploads root into its own directory, wp-content/uploads/egenverk-babbla-signal/, which carries an .htaccess that sends Cache-Control: no-store, private (Apache with mod_headers) and an empty index.php. The directory and both files are created on activation, on the first write, and again whenever one is missing. The old file in the uploads root is deleted once the new one exists; uninstall (with purge on) removes the directory as well. A wp-admin tab left open across the update still reads the old address: it gets three 404s and falls back to asking the server on a schedule until it is reloaded.
  • A cache that freezes the signal file no longer delays new messages by up to a minute for the rest of the page. When the server has reported a token for more than 30 seconds that the file still has not shown, the page stops reading the file, gives up its place as the browser's reader (0.40.0), falls back to the schedule it uses without a signal (0.38.0/0.39.0) and writes one warning to the browser console naming a cache in front of uploads as the likely cause. A file that lags less than 30 seconds, or a burst of writes, does not trigger it.
Babbla

Version 0.40.0

Changed

  • With several wp-admin tabs open, only one of them reads the change signal file: the visible tab that holds a browser lock (Web Locks) reads it at the pace the fastest visible tab needs and passes every token to the other tabs (BroadcastChannel). Each tab still asks WordPress itself when the token changed, so a new message costs one request per tab as before, and every tab keeps its own safety net and the tab-return rule. A hidden tab never leads; a tab that hears no token for three of its read steps plus two seconds (a frozen or throttled leader) reads the file again itself. Measured in the browser tests: one hour of three visible tabs (one open idle conversation, two closed chats) is 1 826 file reads instead of 3 207, and the same 120 requests to WordPress (60 + 30 + 30). A browser without Web Locks or BroadcastChannel behaves exactly as in 0.39.0.
Babbla

Version 0.39.0

Changed

  • An open chat asks the server about once a minute instead of every 4–16 seconds while nothing happens; new messages still appear within one to two seconds. The open conversation and the conversation list read the small change file every second for a minute after something happens (a message arrives or is sent, the user types, a conversation is opened) and every two seconds otherwise, and ask WordPress only when the file changed, when the tab comes back after more than 30 seconds, or on a one-minute safety net. Measured in the browser tests: one hour of an open conversation with nothing new is 60 requests to WordPress and 1 767 file reads, against 226 requests in 0.38.0. The list is refreshed with every change and on the safety net instead of on every fourth request.
  • The assistant's progress no longer costs a request every 1.5 seconds: while it works the chat reads the file every second, and the assistant's status and answer arrive with the change that carries them.
  • The open chat follows the server's poll_interval and signal_token from GET /poll too (see 0.38.0); a busy site's egvb_poll_interval now also stretches the open chat's safety net. Without the file (uploads not writable, or three failed reads) the open chat keeps the 0.38.0 schedule unchanged.
Babbla

Version 0.38.0

Added

  • GET /unread and GET /poll return poll_interval (seconds) and signal_token (the change signal's current token, read before the answer is built). A new filter, egvb_poll_interval (default 0, clamped to 0–600 seconds), lets a busy site make every closed chat wait longer between its scheduled requests without a release.

Changed

  • An idle wp-admin tab with the chat closed asks the server about once every two minutes instead of every ten seconds; the unread badge still updates within about five seconds of a new message. The closed chat now checks the same small file as the open chat, every five seconds, and asks WordPress for the unread count only when that file changed (at most once per five seconds), when the tab comes back after more than 30 seconds, or on a two-minute safety net. Measured in the browser tests: one hour of a closed chat with nothing new is 30 requests to WordPress and 720 file reads, against 360 requests before.
  • A hidden tab asks every five minutes instead of every 30 seconds, and does not read the file. Without the file (uploads not writable, or three failed reads) the closed chat keeps the 10- and 30-second schedule of 0.37.1. An open conversation and the conversation list are unchanged.
Babbla

Version 0.37.1

Changed

  • Database schema 8: updating converts that one column in place (ALTER TABLE … MODIFY request_id). Existing messages and ids are kept; if the conversion fails, the plugin retries it on the next request.

Fixed

  • A message containing å, ä, ö or any other non-ASCII character was never saved: the chat showed "Send status unknown" and a retry failed the same way. The same fault could stop the assistant's answers and chat searches that contained such characters. Since 0.17.0 the column holding each message's request id used the ascii character set; WordPress then treats the whole messages table as ascii and refuses any query on it that carries other characters. The column now uses the table's own character set, still compared case-sensitively.
Babbla

Version 0.37.0

Added

  • A new route, GET /babbla/v1/poll, answers in one request what an open conversation used to ask for in two: its new messages and, when due, the conversation list (and, on request, the unread count). Each part is exactly what its own route returns. The existing routes are unchanged.

Changed

  • A new message in an open conversation now costs the server one request instead of two: the chat fetches the message and the refreshed conversation list together, so WordPress starts once per update instead of twice. A page loaded before the update keeps working: when the server does not know the new route, the chat goes back to the separate requests.
Lagom

Version 0.15.0

Added

  • PageSpeed Insights as a second opinion (M6f): Tools → Lagom lists every scanned public page type (not wp-admin, not the order endpoints) with a Run PageSpeed button, mobile or desktop. Google opens the page once, logged out, with an empty cart, and reports the score, LCP, TBT and CLS, and how much of each CSS and JS file went unused, matched to the scan's handles where the address is the same. The section is labelled "estimate, public pages only" and only shows results: rules still come from coverage runs and the verification run. A result where Google was redirected to another page (checkout with an empty cart goes to the cart) is refused, not stored.
  • The API key is optional (without one Google allows only a few runs a day). It is stored on the server in a non-autoloaded option, or set as EGENVERK_LAGOM_PSI_KEY in wp-config.php; the page says only whether a key is set, the key is sent only in the server's request to Google, and it is scrubbed from any error message before that is stored or shown. The address sent is always a scanned page of this site, never one from the form. Uninstall removes the key and the results.
  • tests/pagespeed-test.php (wp eval-file; Google is never called, the request is answered by a filter).
Lagom

Version 0.14.0

Added

  • Whole plugins per address (M6e): a plugin rule stops an active plugin from loading at all — its PHP, CSS and JS — on addresses starting with a path (or exactly one address). It needs a small must-use plugin, which Lagom writes only when you click Install the mu-plugin on Tools → Lagom, next to an explanation of what it does and why: a normal plugin loads too late to stop others. Update and remove buttons sit beside it; switching the module off or uninstalling Lagom removes the file.
  • The mu-plugin reads one autoloaded option and does nothing unless a rule matches. It never acts in wp-admin, on AJAX, REST, cron, WP-CLI, XML-RPC, logins, form submissions (only GET and HEAD), WooCommerce API callbacks, post previews or page builders, on cart, checkout and account pages (order endpoints included), or on the addresses in a never-list you keep on the page (payment and shipping callbacks, landing pages). WooCommerce and Lagom itself (by its real folder name) are never switched off. Addresses are compared in one form — decoded, lower case, without index.php, with a trailing slash — so /Cart, /cart and /index.php/cart/ are the same page, and prefixes match whole path segments (/blog/ covers /blog/x/, not /blog-posts/). Plugin rules need pretty permalinks; with plain ones the mu-plugin does nothing and new rules are refused. A preview with the token is kept out of page caches.
  • Plugin rules go through the same steps as file rules: preview, verification, live, log. A plugin rule cannot go live without the current mu-plugin, and a verification counts only if the mu-plugin was installed and current, since without it the rules were not applied. Their page types are the scanned pages the address covers; a rule that covers no scanned page, or lies inside a never-listed address, is refused. Preview links carry a short-lived signed token, since no user is known when the mu-plugin runs; the coverage runner gets one that dies with its run key.
  • tests/plugin-rules-test.php (wp eval-file).

Changed

  • Verification opens each page twice without rules and leaves out whatever moves between those visits (sliders, rotating banners), so only changes caused by the rules count; elements are still compared by identity (tag, id, classes), so a slider whose script stops running still fails the check. Before, a slider on the front page could fail a check at random.
Lagom

Version 0.13.0

Added

  • Rule proposals (M6d): after a coverage run, Tools → Lagom lists per page type the files that are not ruled yet and were unused (CSS, ticked) or only ran their start-up code (JS, left to choose). A file stays out when something used on that page type depends on it. "Add ticked as preview rules" adds them in dependency order.
  • Verification run: bin/lagom-coverage --verify opens every page type that has rules in preview with the rules off and on, at desktop and phone size, runs the same interactions and compares console errors, failed requests, interactions that stopped working and the layout of every visible element (more than 2 % changed fails). --shots dir saves both screenshots per page. Results go to a new REST route egenverk-lagom/v1/coverage/verify.
  • A passed check lets the page type's rules go live without the skip confirmation. A check belongs to the exact set of rules on that page type: adding or removing a rule there makes it stale. Rules verified together go live together (every preview rule sharing a page type with it), so visitors never get a combination that was not checked. The rules table shows per page type "verified", "verification failed" (with the reasons), "rules changed, verify again" or "not verified"; the change log records each outcome.
  • Cart and checkout pass only in a full run with something in the cart: a read-only pass on them is recorded as failed (also when the runner itself was made stricter with --read-only), and an empty cart fails the check. A full verification run adds a simple product from the plan to the cart first. Order-pay and order-received need a real order and never pass a run, so no rule may target them (a rule there would also hold back every rule verified together with it).
  • Console errors are compared with where they came from, so a new error with the same text as an existing one still fails the check; the layout comparison uses every class and the horizontal scroll position.

Changed

  • Coverage runs visit every page at a desktop and a phone size and count a file as used if either used it, so phone-only stylesheets are no longer reported unused.
  • CSS files with @font-face or @keyframes and no matching style rule are shown as "fonts or animations only, check by eye" instead of "unused" and are never proposed: rule usage cannot tell whether a font or an animation is used.
  • The rules option is created with the module's current switch, so a site whose rules option was removed does not ignore previews until the next settings save.
Lagom

Version 0.12.0

Added

  • Coverage runs (M6c, docs/coverage-runner.md): Tools → Lagom lists a plan of one page per page type (scanned pages and suggestions, own addresses can be added), creates a run key, and shows per file and page type what the last run saw: "unused here", "start-up only" or "used", with the share of the file that ran.
  • bin/lagom-coverage (developer tool, not in the zip): a headless browser with a temporary profile that opens each planned page once, records which JS functions are called after load and which CSS rules match, runs standard non-destructive interactions, and uploads a per-file summary.
  • Run keys are shown once, valid for at most 30 minutes, bound to one user and one run, stored only as a hash, logged (created, plan fetched, results uploaded, revoked) and revocable; revoking or replacing a key also ends the login it handed out. A new key retires the user's previous one.
  • Production is read-only, decided by the site: tracking blocked (on by default everywhere), every non-GET request aborted, cart-changing requests aborted, no navigation away from the planned page, and no clicks in wp-admin. Service workers may not start and WebSockets are closed in every run, so nothing reaches the network outside the runner's checks. Full runs on other environments put a simple product in the cart before visiting cart and checkout.
  • REST routes egenverk-lagom/v1/coverage/plan and /results, each needing a valid run key; uploads are kept only for planned pages the scan recorded (a page that redirected is filed under the page type it landed on, if the scan saw it there), and every text is sanitised.
  • Uninstall removes the plan, runs, results and log.
  • tests/coverage-test.php (wp eval-file).
Lagom

Version 0.11.0

Added

  • Asset rules (M6b, docs/BRIEF-assets.md section 3): "Unload…" on a scanned CSS or JS file stops it loading on the page types you tick, front end or admin screens. Rules act on whole handles only.
  • Every new rule starts in preview: it applies only when an administrator opens a page with ?egenverk_lagom_assets=preview, with a note on the page saying how many rules were applied. Preview links per page type sit next to each rule.
  • Going live needs a passed verification run (arrives with the coverage runner). Until then an administrator can make a rule live only by ticking an explicit confirmation that the verification is skipped, which is logged and shown on the rule. Rules on cart, checkout, order-pay or order-received can never skip it.
  • A rule is refused when a file that depends on it would still load on that page type, when the file was not seen there in the last scan, or when it targets Tools → Lagom itself. Because WordPress re-adds a removed file when something still loaded depends on it, a rule only goes live once the rules on its dependants are live, and a dependant's rule cannot leave live (or be deleted) while a rule it depends on is live.
  • ?egenverk_lagom_assets=off turns every rule off for one request; scans ignore rules so the list stays complete. Back to preview and delete per rule; known page caches (WP Rocket, LiteSpeed, W3 Total Cache, WP Super Cache) are emptied after a change, otherwise the page asks you to.
  • Change log of the last 200 rule changes (who, when, what) on Tools → Lagom.
  • The switch and rules live in one small autoloaded option, so the front end reads them without a query; nothing is hooked while the module is off or no rule exists. Uninstall removes rules and log.
  • docs/decisions.md records the decisions behind the asset manager and order search; the brief now describes coverage (runner A plus PageSpeed B), the production safeguards and the PR order.
  • tests/asset-rules-test.php (wp eval-file).
Lagom

Version 0.10.0

Added

  • CSS and JS per page module (off by default), first step of the asset manager (docs/BRIEF-assets.md). While it is on, an administrator opens any front-end page or admin screen with ?egenverk_lagom_assets=scan and Lagom records every CSS and JS file that page printed: handle, the file actually served, whether it is minified and whether the other build (.min or source) is on disk, size, inline code, owner (plugin, theme, core or external host), and what depends on it. Uninstall removes the stored scans. Scans are kept per page type (front page, shop, product, product category, cart, checkout, order received, account, page template, post type, admin screen), at most 40 page types.
  • The module card links one page of each type to scan; the list under the settings groups the files by plugin or theme, largest first, with the page types each file loads on. A small note on the scanned page confirms what was recorded.
  • Read-only: nothing is unloaded yet. Requests without the scan argument add no hook, and a scanned page is kept out of page caches.
  • tests/asset-scan-test.php (wp eval-file).

Changed

  • The header chip on Tools → Lagom names the asset scan among the live modules.
Lagom

Version 0.9.0

Added

  • Lagom's own order search index for orders stored as posts, when no other plugin answers the search filter. A table {prefix}egvl_order_index holds one row per order with the normalised billing email, phone (E.164), postcode, first and last name, company and transaction id, each column indexed. Fast order search uses it once it is complete, so email, phone, postcode, transaction id and name are found fast without HPOS; until then only order numbers are, as before.
  • The index fills in batches of 500 orders through Action Scheduler with a 20-second pause between batches, optionally only between 00 and 06 in the site's time zone. Unticking "Build Lagom's own search index" pauses it and keeps what is built. Any admin page load restarts a fill whose last batch died, until the fill is done. The module card shows how many orders are indexed.
  • Once the table exists, orders are kept in step when they are created or saved (checkout included), and their row is removed when the order is deleted or anonymised by the WooCommerce personal data eraser, also while the fill is paused or the module is off. Uninstall drops the table and its options.
  • readme.txt has a Privacy section.
  • tests/order-index-test.php (wp eval-file).
Conversion Relay

Version 1.4.0

Changed

  • The server reads marketing consent and the ad click from first-party cookies on requests WooCommerce makes anyway, instead of waiting for the browser to send them to ?wc-ajax=egenverk_conversion_relay: every page view and wc-ajax request of a visitor with a WooCommerce session or a login (init priority 20, before Kustom's confirmation completes a payment at 999), a cart addition, the order review, the checkout and the moment before a payment completes. Cookiebot's CookieConsent is parsed by the plugin itself: -1 (a visitor outside a consent region, which Cookiebot's script also reports as a grant) is a grant, 0 a refusal, and otherwise only the marketing flag of the object Cookiebot writes is read, up to 4 kB; anything else is unknown. WP Consent API's wp_consent_marketing cookie is read directly, because wp_has_consent() on the server grants when no consent type is set or, in an opt-out region, when there is no cookie: deny is a refusal, allow a grant only when wp_has_consent() agrees, anything else unknown. The click comes from the pixel SDK's __oppref, which the SDK replaces on every ad landing, then from the plugin's own cookie egenverk_conversion_relay_click, and the browser reference from __obref; each is checked like the endpoint checks them, and must be valid UTF-8.
  • The consent record is written through the same path as the endpoint, so a refusal still withdraws queued purchases at once, but only when consent or the click changed, or when the record has less than two days left; a copy in the WooCommerce session answers every other request without reading the record (a logged-in customer without a session cookie gets no copy, so no session is stored for it). No session is ever opened for this, unknown consent never changes a record, a refusal waits up to five seconds for a record another request holds, and a click the granted record holds is kept when the cookies lack it, as the browser keeps it until a refusal.
  • A cart addition queues its items_added event when the consent cookie in that request grants, instead of requiring a record an earlier request had stored.
  • The response to a granted cart addition hands the session's additions of the last two minutes to the browser in a two-minute cookie, egenverk_conversion_relay_added (host-only, not HttpOnly, SameSite=Lax, Secure on https, path /), each with the event id the server generated, the product and variation, quantity, amount and currency. Carrying every recent addition, rather than the ones the request brought back, keeps an addition whose answer the browser had not read when the next one was posted, and never sets again what the browser sent. The value is at most 1 kB encoded: product names are dropped first, then an addition too large on its own, then the oldest; when nothing fits the cookie is removed. The script reads it on added_to_cart, wc-blocks_added_to_cart and when a page loads, which covers an addition that reloads the page, measures items_added with each event id it has not measured in the last five minutes, and removes the cookie. With refused consent, the pixel off or the event not selected it removes it unmeasured; while consent is unknown, or another script owns the pixel SDK, it leaves it. A refusal the server sees removes it. A refusal also forgets the ids measured, and empties the session's additions, so a later grant does not hand earlier ones over.
  • An order is stamped with the consent in the checkout request's own cookie; an order placed without a readable consent cookie is unknown, whatever an older record says. The session's unpaid order is re-stamped on every order review and consent change, never above what the request's cookie says. Every capture, through the payment or a paid status, now needs that stamp to be a grant as well as the record, and none happens in a request whose consent cookie refuses. A grant that reaches the server only after the payment completed no longer makes the purchase count, as it could through the payment until now: consent is taken as it was when the order was placed and paid.
  • The ad click from the landing URL is kept in the first-party cookie egenverk_conversion_relay_click as <expiry>.<click> (host-only, path /, SameSite=Lax, Secure on https, not HttpOnly), 30 days from the click, instead of in localStorage, which the server cannot read. The script writes it only with a grant and never writes the same click again, so a reload does not extend it; a click 1.3 kept in localStorage moves to the cookie with its expiry. With a grant and a click the server sets the same cookie, since Safari keeps a cookie a script writes for seven days only. The expiry it carries is kept in a new session or for a new account, a click only the pixel SDK's __oppref carries keeps the expiry the session saw before, and a cookie the browser already holds is not sent again. A refusal removes it on both sides.
  • While the server keeps a grant for the browser it sets two marker cookies until the record expires, host-only, SameSite=Lax, Secure on https: egenverk_conversion_relay_record, HttpOnly, which names the record with a signature, and egenverk_conversion_relay_marker, which the script reads and which holds only the expiry, so no script sees a stable identifier. A refusal made on a page, which the next request WooCommerce makes would carry anyway, is sent at once as one small request (client: 4, action: refuse, with keepalive, so it survives the tab being closed) when the server may hold a grant: with a cart, a login or that marker. It is sent once per change to a refusal on that page, and on start-up for a refusal made before the script ran while the marker is there; never for a refusal the page request itself carried, and never in answer to another tab. The HttpOnly marker's signed reference to the record lets the refusal reach it after the WooCommerce session has expired, as it does two days after a guest's last visit; it is signed with a key derived from the auth salt, so rotating the salts invalidates every marker, which is then ignored and removed, and such a late refusal is dropped while the record expires by itself. The endpoint answers the refusal with an empty result, never throttles it, removes both markers, and ignores it when the request's consent cookie grants again; the script then sends a refusal made before it started at most once per marker value in a tab session. The order received, pay-for-order and account pages, where nothing is measured, carry the script in a refusal-only mode: no pixel, no page events and no cart additions, only the refusal and its cleanup.
  • The script no longer sends grants, clicks, cart and login changes, the preparation before the first cart addition, the daily and 30-minute repeats or the forced sync before checkout, and it no longer listens to other tabs. The synchronization state older versions kept in localStorage (egenverk_conversion_relay_synced, egenverk_conversion_relay_granted and their first names) is removed on the first page view. The pixel, the page events, the configuration in the page and the diagnostics are unchanged. A page cached with HTML from before 1.2.1 measures nothing until the page cache is purged.
  • The endpoint still answers scripts from 1.2.x and 1.3.x (client 2 and 3) as before for one version, since pages and browser caches keep them for a while: grants, clicks, refusals, the cart preparation and the throttling. That code goes in 1.5.0.
  • A refusal the record lock kept from being stored is logged as a warning (consent_lock_busy).
  • A guest who logs in or creates an account at checkout takes the consent record and click to the account (WooCommerce 8.8 and later), unless the account holds a newer record.

Fixed

  • The changelog of 1.2.1 and 1.3.2 promised one synchronization before an order is placed, so that a refusal made on the checkout page reaches the server first. The script hooked WooCommerce's checkout_place_order event on the checkout form, but Kustom Checkout posts the order straight to ?wc-ajax=checkout from its own script, so that event never fires and the synchronization never ran for an order placed through Kustom: a refusal made on its checkout page after an earlier grant could leave the order stamped with the grant. The checkout request itself now carries the consent cookie, and the order and the record are both written from it in that request, whichever script posts the order; the hook is gone. A refusal made after the order was placed is read on Kustom's confirmation page before that request captures the payment; if Kustom's server push captured it first, the refusal withdraws the queued purchase if it reaches the server before the purchase is sent, a few seconds after payment.
  • Since 1.0.0 a purchase captured through woocommerce_payment_complete or Kustom's payment callback was decided by the customer's consent record alone, never by the consent recorded on the order when it was placed, so an order placed with consent unknown or refused was still exported when an older grant was on record. Only the paid-status path (1.2.0) checked the order.
Babbla

Version 0.36.0

Added

  • Messages from colleagues appear within about two seconds instead of up to sixteen. The open chat checks a small file in the uploads folder every two seconds (three on the conversation list) and only asks the server for messages when that file says something changed. The file holds a timestamp and nothing else: it reveals that something changed in the chat, never what, where or by whom. It is removed on uninstall when "Purge data on uninstall" is on.
  • The assistant's answer, and its "Searching the chat…"-style status, show sooner: while it works the conversation is checked every one and a half seconds, for up to two minutes; after that the small file wakes the chat when the answer is ready.

Changed

  • Less load on the server: an open chat with nothing new asks WordPress for messages every 16 seconds in a conversation and every 20 seconds on the list, instead of every 4 to 16 seconds. A new message elsewhere also refreshes the conversation list right away, so its unread count shows without waiting.
  • When the uploads folder is not writable, or reading the file fails three times in a row (an error page or something that is not the file; a dropped network connection only skips that check), the chat falls back to exactly the checking schedule of 0.35.2. A CDN that caches the file only slows the chat to the 16- and 20-second checks. A hidden tab or a closed chat is unchanged.
Babbla

Version 0.35.2

Fixed

  • The thin loading stripe at the top of the chat no longer blinks every few seconds on its own. Checking for new messages, unread counts, read markers and the colleague list now run quietly in the background; the stripe shows only while something you did (send, create, search, open) is waiting for the server.
Babbla

Version 0.35.1

Fixed

  • On the full-page chat, the mention picker and the other panels (new message, new room, room info) cover only the conversation, not the whole admin screen.
  • The full-page chat's conversation list is wider (300 px), so room and person names are no longer cut to a few letters.
Babbla

Version 0.35.0

Changed

  • Access, Usage and Diagnostics follow the Egenverk plugin shell like the Settings tab: each section is a card with its heading, tables use the Egenverk table style, and confirmations ("Access saved.", "Babbla ownership claimed.", "The log files were deleted.") are green notices.
  • Access: claiming ownership, finding a user and choosing a user's Babbla role are each a card of rows, label and help on the left and the field and its button on the right.
  • Usage: the period's figures are a row of tiles (questions, failed, tokens in, tokens out, and the estimated cost when prices are set) instead of one sentence. The daily bars use the Babbla colour, and a day over the budget is red.
  • Diagnostics: each status row names its state in a chip ("OK", "Warning", "Error") instead of a coloured dot alone. The log file picker has a visible label, and the log scrolls inside its own box. "Delete all log files" is a red button that shows a loader while it works.
  • On a phone the rows stack and the tables scroll sideways inside their card.
  • Form fields, what each form sends and who may use it are unchanged.
Babbla

Version 0.34.0

Changed

  • Settings → Babbla follows the Egenverk plugin shell. The version sits beside the Babbla name in the header, and each tab's content fades in on load.
  • The Settings tab is one page of cards: Overview, Provider, Behaviour, Limits and cost, and Data. The left section menu is gone. Each setting is a row with its label and help on the left and the field on the right. On a phone the rows stack.
  • The floating bubble, "Purge data on uninstall" and each integration are now on/off switches.
  • Provider is one choice at the top of the Provider card. Only the chosen provider's key and model fields show. The "In use" badge and the second "Use … for the assistant" radio are gone. "Save everything and test the connection" is a secondary button with its description on its own line, and it tests the chosen provider.
  • Saving works the Egenverk way. A save bar slides up from the bottom only when something has changed, and a "Settings saved." toast confirms the save. The always-visible save bar at the top and the second Save button at the bottom are gone. Pressing Enter in a field saves, and it does not run the connection test.
  • Option names, stored values and what is saved are unchanged.
Babbla

Version 0.33.4

Fixed

  • The assistant can be mentioned from the picker again. In a room (public or private) it is the first row of "Mention a colleague or assistant", with its avatar and "Answers once in this room", and it filters with the search like everyone else; the near-invisible "@Agent" button above the list is gone. Direct messages still do not offer it, since the assistant never answers there.
  • The picker's search field is visible in the dark theme: it has a fill, a border and a search icon, and a clear (×) button empties it.
  • Every overlay (mention picker, new DM, new room, room info) has a close (×) button in its header that returns to where you were, like Back and Esc.
  • Selected mentions above the composer are pills with the name and a separate × to remove them.