Skip to main content

Give feedback

Back to all releases
Changelog

3.0.0

Released 2026-09-29

Fixed

  • The native app's Expo Updates patch dependency now matches Expo SDK 55's required version, restoring the Android native release gate.

  • Administrator-created member, broker and administrator invitations, assisted onboarding with a real email address, and new community administrator welcomes now email a one-hour set-password link instead of a lasting password. Password-reset requests made through the accessible frontend now link back to that frontend when the community has a registered accessible domain.

  • Public contact submissions now escape submitted markup in the email sent to community staff and use only the validated address in Reply-To, preventing injected links or headers in that message.

  • Broker and coordinator Help Centre guide corrected in 20 articles after checking each against the code, including: starting hours are given by default on approval, a rejection reason appears under Broker Notes, the insurance check always applies to the member who posted the listing, message review shows only the messages up to the copied one, what risk tags really change, which actions Recent Activity shows, and that edited messages return to Unreviewed. A new article explains that the Match Approvals list currently receives nothing. The group activities guide now also needs the Groups feature, which those pages depend on. All eleven languages, AI-translated and not yet native-reviewed.

  • Members' Help Centre guide corrected in 13 articles after checking each against the code: sign-in offers Google and Facebook (not Apple); brokers and coordinators, not only admins, can see a member's phone number; matches include upcoming events; event attendance rewards explain self check-in, the monthly limit and reversals; showcased badges appear in the members directory; volunteer hours explain the per-entry and 24-hours-a-day limits; job lists include jobs with no closing date; marketplace orders explain paying with time credits and the Disputed status. Ten new articles cover saved items, muting, the AI assistant allowance, job and marketplace listing limits, venue visit points and four Caring Community pages. Pages that do not work as their screens describe were deliberately left out. All eleven languages; the ten non-English versions were drafted by AI and have not been reviewed by native speakers.

  • Help Centre: searching the community's own questions no longer matches the hidden formatting inside an answer (for example "strong" or "href"); only the words a reader can see are searched. Search now lists every matching guide instead of stopping at 30, Broker Panel guide pages show the article's title in the browser tab, and the "Go to this page" buttons use an in-app arrow instead of the "opens another site" arrow.

  • Search backfills now wait for Meilisearch to finish each document task and report rejected writes as failures; writes explicitly use the document ID as the primary key.

  • Database recovery now rebuilds all four legacy views against the restored database, and a migration repairs their missing-definer access in the live schema. The schema export omits environment-specific view creators. A differently named restore still requires the documented post-import view rebuild.

  • Updated the React test runner and coverage package to patched Vitest 4.1.11, retaining isolated test files and the existing CI worker limit.

  • Fixed Android Play bundles silently retaining an already-used version code after Expo regenerated an existing native project; the guarded build now reapplies the Gradle override and verifies the compiled version code before archiving.

Added

  • Sales enquiry emails from POST /v2/sales/orders now list everything the visitor selected in the quote builder, including the choices that cost nothing, in a table above the priced lines, with the buying route and the member count entered. Billing, pricing mode and each line's cadence read in plain words ("Annual prepay", "Custom: a written all-in quote is required", "Per month") instead of codes. The new contract_route, active_members and selections quote fields are optional, so existing callers get the same email as before.

  • npm run check:help-staleness lists Help Centre articles whose underlying code has changed since the article was last checked against it, using a record of each article's source files and the commit it was verified at (react-frontend/src/pages/help/guides/data/sources.json). It fails only on new, unreviewed drift. Not yet part of CI.

  • Help Centre label check: an automated test that every bold on-screen label quoted in a guide exists in the app's own text for that language, so a guide cannot silently name a button the reader will not find. Labels already known to be missing are listed per language and may only go down.

  • Admin Help Centre guide: a new "Privacy, records and data" topic (Activity Log, GDPR dashboard, consent records, GDPR audit log, data retention) and an article on message translation settings, each checked against the code; settings on those pages that currently have no effect are not described. All eleven languages, AI-translated and not yet native-reviewed.

  • A new automatic check stops translations whose letters have been replaced by question marks. When text passes through a step that cannot carry accented or non-Latin characters, every such character becomes "?" — Arabic and Japanese turn into "????" and "ausgewählt" into "ausgew?hlt" — yet the file still looks valid and every existing translation check stays green. This has now had to be repaired by hand twice. scripts/check-i18n-question-mark-damage.mjs scans the website, the mobile app and the server's language files (both JSON and PHP) and fails with a list of every damaged value. It runs as BLOCKING in CI's Translation Drift Detection job (which now also wakes on mobile/locales/**), in scripts/preflight.mjs, and as npm run check:i18n:question-marks within npm run check:i18n; its rules are pinned by scripts/test/check-i18n-question-mark-damage.test.mjs. It cannot see a letter lost at the very end of a value of more than one word (such as "Non activ?"), because that looks exactly like a real question; run against the damage repaired earlier today, it would have caught 213 of the 230 values.

  • Group members can now control group-specific notification frequency, email delivery and push delivery from the native app. Failed reads do not expose guessed defaults, and failed saves keep edited choices available for retry.

  • Group pages in the mobile app now include their own Feed, with member-only, paginated posts and polls plus group-bound post and poll creation.

  • Group members can now use configured group channels in the mobile app, including paginated messages and exact-channel notification links. Managers can create and delete channels and pin messages. Interrupted channel or message creation is stored encrypted and can be retried without duplicates. Available in all seven app languages.

  • Group members can now follow configured group challenges and their progress in the mobile app. Managers can create bounded challenges and cancel active ones; interrupted creation is stored encrypted and an exact retry returns the original challenge without duplicating progress or audit records. Available in all seven app languages.

  • Group members can now open configured subgroups from the mobile group page. Managers can search the groups they are authorised to manage and place a new or existing group beneath one; the app excludes the edited group and its known descendants, preserves refused selections, and relies on the server's tenant, authority and cycle checks. Available in all seven app languages.

  • Group managers can now schedule discussions and announcements and configure new-member welcome messages from the mobile app. Scheduling follows the group's enabled content tabs, preserves unfinished work encrypted on the device, and safely reuses the original server result after a lost response instead of creating duplicates. Cancellation and welcome-message saves use authoritative readback when the response is uncertain. Available in all seven app languages.

  • The mobile app's Help centre now includes the full step-by-step members' guides, read inside the app rather than in a browser. Topics for features a community has switched off are hidden, search covers the guides as well as the community's own questions, and links to a members' guide on the website open the same guide in the app. The guide text comes from the website, so it is in the member's language (English where a translation is missing) and stays up to date without an app release. A short note explains that the guides describe the website, where some buttons sit in different places. Needs an app release to reach members.

  • A complete Help Centre is now built into the app, written in plain English: three guides with 295 step-by-step articles, for members (31 topics), for brokers and coordinators (8 topics) and for community admins (10 topics). Guides for features a community has switched off are hidden, search works in every language (including Japanese, which is written without spaces), and each article links straight to the page it describes. The Broker Panel's help page now shows the broker guide, replacing the old page, which wrongly said that every view of a member's messages is logged; the admin panel's help page now links to the admin guide. Available in all eleven languages. The ten non-English versions were drafted by AI and have not yet been reviewed by a native speaker; where the app's own button labels are mistranslated, the guides quote them as they appear on screen so readers can find them.

  • Event organisers can now manage event safety in the mobile app: set the participation policy (minimum age and code of conduct), save it as a draft, publish or archive it, and record, update or withdraw participation review decisions with controlled reasons and effective dates. Interrupted changes stay saved on the device and are only resent when the organiser chooses to. If someone else changed the policy first, the screen reloads the current values; an archived policy is shown as final and cannot be edited. Available in all seven app languages.

  • Added encrypted, account-scoped recovery for native organiser Safety requests, preserving exact changes across interrupted responses and preventing uncertain decisions from being replaced. The organiser screen is still being completed.

  • Added validated native API support for organiser event safety drafts, publication, archiving and paginated participation reviews, preserving revision checks and request identities. The native organiser Safety workspace is still being completed.

  • Native event organisers can search members, assign permitted team roles with optional expiry, revoke access and review assignment history in a dedicated Team screen. Saved requests preserve their identity after interrupted responses; explicit recovery and confirmed discard protect unresolved changes.

  • Native event organisers can review partner sharing status, delivery counts and safe diagnostic codes in a dedicated read-only federation screen, with refresh recovery and protected account/community changes.

  • Native event organisers can now create and edit agenda sessions, manage speakers and secure resources, cancel sessions with reasons, and reorder the programme from a dedicated screen. Requests are saved encrypted before sending; interrupted requests retain their retry identity, and rejected edits retain their input for review against current versions.

  • Native course learners can share their completion certificate from the course player, with authenticated retrieval, account-change protection and retry after a failed export.

  • Group members can upload validated files from the native app, with translated size/type feedback and file-owner deletion controls matching the server permissions.

Changed

  • Security-assurance guidance now distinguishes the contracted independent penetration test from a test that has actually begun or produced a report.

  • Android release metadata now records the verified live Play build 20 / 1.8.1, published on 27 September 2026 at 7:31 PM from exact source commit 86adbf3391972f5c6b6cf863adda734bcfb6eda0, after internal testing, zero supported-device losses, Play quick checks and production submission 15.

  • New blog posts now start as Published and visible to search engines, so a post goes live and can be found unless an admin chooses otherwise. The search-engine setting on the blog form is now a plain "Show in search engines" switch, on by default, with a line underneath saying in words whether search engines may list the post. Available in all eleven languages.

  • The "Get the app" page now labels the Android app as an early release that is still in development, with that notice placed directly under its heading and before the download button, and says plainly that the core features are solid but some less common situations may not work yet. A new "Most stable" section above the one-tap install button recommends the browser version on phones: it is the same as the full website, always current, and fully maintained, with the Apple home-screen limitation restated. Available in all eleven languages.

  • Security assurance now tracks small, journey-based reviews against versioned OWASP ASVS 5.0.0 requirements, with explicit proof and environment states. The full checklist remains a reference rather than an active whole-platform audit. The scanning guide now distinguishes dependency-review job failure, merge protection and the non-blocking Semgrep step.

  • Every Android build is now filed in one folder, mobile/releases/android/, by the build scripts themselves: Play bundles as play/timebank-global-<version>-build<code>.aab and test APKs under sideload/, each with its SHA-256, and INDEX.tsv recording the source commit of every build. Bundles were previously copied by hand into mobile/ under two naming styles with no commit recorded; the thirteen existing files were moved into the folder (mobile/scripts/archive-android-build.sh, mobile/docs/PLAY_RELEASE_PROCEDURE.md).

Fixed

  • The database-column CI gate now recognizes new tables declared by pending Laravel migrations while the production-derived schema dump has not yet been refreshed.

  • The Android device-test workflow now runs its full Maestro journey suite on a stable Android 15 image and disables the irrelevant spellchecker service. Android 16's Google APIs emulator left a system starting_reveal transition permanently active, delaying each typed character until Maestro's two-minute device-control request expired even though the app had reached the login screen and the independent launch check passed. The app now opens a newly created saved-items collection directly, avoiding a moving-list tap while its refreshed row is inserted.

  • The admin Deliverables list now shows every deliverable, with a page control. It only ever asked for the first 20, so anything beyond that was hidden.

  • The grant history on the admin Starting Balances page now lists the time credits that admins have granted. It looked for the list and for each grant's details under names the server never uses, so it always showed an empty history, even after a successful grant.

  • Five more admin list pages now let you reach every record, not just the first page. Like the newsletter activity page, they read the page count from the wrong part of the server's response. The GDPR audit log showed no entries at all. The error log stopped at its first 50 entries, and the GDPR requests list, the newsletter list and the smart-match results each stopped at their first 20. None of them offered a page control. The error log also now works out its pages from the 50 entries per page the server actually sends. The automated tests for about thirty admin and broker pages now use the reply shape the server really sends, so this kind of fault can no longer pass them unnoticed.

  • The admin newsletter activity page now shows every open and click. It read the page count from the wrong part of the server's response, so it always believed there was one page: anything past the first 50 events was hidden with no page control, and the header count stopped at 50. The Opened and Clicked badges on the same page no longer break mid-word in the narrow Event column.

  • The mobile event-communications recovery test now waits for the retry read from secure storage before checking that the recovery panel closes. Under the complete 6,959-test CI run, the asynchronous update occasionally crossed the test library's one-second default even though the same focused test passed locally.

  • The Android device-test workflow now allows the full thirteen-flow Maestro suite and screenshot tour up to 90 minutes. The former 60-minute whole-job limit cancelled two build 19 verification runs while Maestro was still active, after the API checks and Android build had passed. The longer run exposed the underlying shared failure: Android API 36 left the app behind the launcher while its starting_reveal animation never completed, so every journey after launch smoke timed out against the home screen. CI now disables emulator animations for deterministic launches; the E2E build already suppresses the reduced-motion LogBox warning, while ordinary local debug runs still restore animations before testing.

  • The admin Safeguarding screen now describes three safeguarding options correctly, in all eleven languages. It said "Require coordinator approval" and "Monitor messaging" copy the member's messages for review, and that "Restrict matching" holds matches for approval. In fact coordinator approval holds matches and exchanges for sign-off without copying messages, "Monitor messaging" stops other members contacting that member directly, and "Restrict matching" currently only records the member's choice.

  • Made Docker build verification wait for the production PHP container's real health endpoint and fail when it never becomes ready, instead of emitting a non-blocking warning after a fixed five-second delay.

  • Corrected Irish Help Centre wording across the shared page, member, broker and admin guides. The changes clarify search results, blocking and reporting, photo ID, wallet payments, partner-community choices and safeguarding contact, and fix several awkward titles and summaries. Further member-guide claims were corrected in all eleven guide languages: the Broker Panel does not offer a control to settle or cancel disputed exchanges, "Match approval" currently records a preference without changing match suggestions, and "Broker review" routes exchanges through approval without promising approval of matches. The same safeguarding corrections now appear in web and mobile onboarding confirmations; the web confirmation shows the "Match approval" explanation only when that preference was selected. The guide labels quoted from the app remain as shown on screen; native-speaker review is still outstanding.

  • Fifteen Help Centre articles that told people something the platform does not do have been corrected in all eleven languages, after a check of every guide against the code. The admin guide said two safeguarding options copy a member's messages for review; they do not. "Monitor messaging" actually stops other members contacting that member directly, and "Restrict matching" currently changes nothing, and the guide now says both. The broker guide now says that only admins can pin, edit or delete member notes, that a broker can still adjust another broker's or an admin's balance, that a monitoring period does not switch messaging back on when it runs out, that Recent Activity shows only some kinds of action, and when "Broker approval required" on a risk tag actually takes effect. The member guide no longer says you can block someone from a feed post (that menu only mutes), describes goal buddies as offers the owner must accept, and explains that the wallet export includes only the entries loaded on screen. Guides are now also hidden whenever a page they send people to is switched off: 27 articles gained the missing switch (most of them the Settings page), and the Exchanges guides are hidden when members cannot request exchanges, on the website and in the phone app. A new test fails if an article links to a page with an on/off switch without carrying the same switch. The corrected translations were written by AI and have not been reviewed by native speakers.

  • Group content creation in the mobile app now refreshes group membership and management rights after the server refuses a stale request. Discussion, announcement, Q&A, wiki and gallery controls disappear immediately when access has changed, preventing repeated attempts from an outdated composer.

  • Group invitation emails can now be sent from the mobile app when the optional message is left blank. Laravel previously converted the empty field to null and then rejected it. Results also distinguish a durable invitation whose email delivery failed from one that was actually sent, instead of reporting both as “Sent”, and malformed delivery results fail closed.

  • When a group manager loses management authority while the mobile Automation screen is open, a refused manager-only read or write now refreshes the group immediately. Stale scheduling and welcome-message controls disappear, the screen returns to Overview, and a definitively refused schedule is not retained for retry or created on the server.

  • A scheduled group post refused by safeguarding or another definite client-side rule now releases its encrypted retry lock while keeping the manager's entered text available to correct. Connection failures still retain the protected request for an exact retry, and the app explains safeguarding refusals in all seven mobile languages instead of claiming the post is waiting for a connection.

  • Scheduled group posts in the mobile app now keep the local time selected by the manager after refresh, and links to the manager-only Automation tab now wait for group permissions to load instead of reopening the Overview tab.

  • Members can now pull down to refresh a Help Centre guide after reconnecting, without leaving the article or replacing already loaded text with a full-page spinner.

  • Many on-screen labels in the ten non-English versions of the website were machine-translation errors and have been corrected, together with every Help Centre guide that quoted them. Examples: "Safeguarding" shown as the word for "backup" (French) or "IT security" (Dutch), "Sign in" shown as "Registration" (Italian), "Passkey" shown as "password" (Dutch), "Dismissed" shown as "fired from a job", "30 seconds" shown as "30 years", safeguarding notices written in Latin letters instead of Arabic script, and admin buttons written as verbs. Exchange statuses such as "Awaiting Provider" were fixed English text in the code and are now translated. The corrections were made by AI translators and have not been reviewed by native speakers.

  • About 190 more translations that showed question marks in place of letters, found by the new check, are readable again. They are in the emails and notifications sent when a safeguarding certification is due for review or has expired (which reached admins in Arabic and Japanese as "????" and with letters missing in seven other languages), in the payment-tier error messages, in the "United Kingdom — national policy package" safeguarding label, in two coordinator nudges, and in the mobile app's verification badges and event attendance labels (such as "Tel?fono verificado" and "Asisti?"). Each was rewritten by hand; the Arabic and Japanese safeguarding emails were translated afresh from the current English (lang/*/{emails,svc_notifications,svc_notifications_2,caring_community}.json, lang/*/{api,safeguarding}.php, mobile/locales/*/{common,events,resources}.json).

  • About 230 translated labels and messages that showed question marks in place of letters are readable again. In Arabic and Japanese, whole labels on the admin member-edit page, the event attendee list, the blog image settings and parts of the admin menu had become "????"; other languages had lost single letters, such as German "Verlauf f?r", French "Activ?", Polish "wyr??niony" and Portuguese "N?o". Each was rewritten by hand in the style that language's file already uses. In German, Spanish, Arabic and Japanese the Google Places cost warning had been turned into a question by the same damage and now reads as a statement again. The strings had been saved at various times between May and July 2026 by a step that could not carry non-English characters; the existing check for garbled text only looks for other kinds of damage, so nothing flagged it (react-frontend/public/locales/*/{admin_blog,admin_config,admin_content,admin_dashboard,admin_nav,admin_resources,admin_system,admin_users,broker,emails,emails_notifications,errors,events,help_admins,kb}.json).

  • Switches that are turned off are visible again everywhere on the platform. An off switch drew a white track and a white knob on a white card, so it looked as if there was no switch at all (the blog form's search-engine setting and the cookie preferences were two examples). Off switches now have a grey track with an outline in both light and dark mode (react-frontend/src/components/ui/Switch.tsx).

  • The blog form now shows the featured-image limits at all times — up to 10 MB, and no larger than 24 megapixels or 6000 pixels on the longest side — and checks a chosen image against them before uploading. An image that is too large now gets a message beside the image saying which limit it broke and by how much, instead of only a brief "upload failed" notice; when the server refuses an image, its reason is shown.

  • Turning a blog post's search-engine visibility back on now saves. The form left the setting out of the request when it was switched on, and the server only updates that setting when it is sent, so a post once hidden from search engines stayed hidden unless a meta title or description was also filled in.

  • The blog form's featured-image messages showed as rows of question marks in Arabic, Japanese and Polish, and with missing letters in German, Dutch and Portuguese. They have been rewritten in all six languages.

  • Creating a feed post in the mobile app now preserves the exact account, community, group and text across a lost response or app restart. An exact retry returns the original post instead of creating a duplicate, while changed content under the same protected request is rejected.

  • Starting a group discussion in the mobile app now stores the exact draft and protected request in encrypted device storage before sending. After a lost response or app restart, the member must explicitly retry the restored discussion; changed content cannot replace the unresolved request, and unavailable recovery blocks a new post.

  • Creating a group announcement in the mobile app now preserves the exact title, message, pin choice and protected request across a lost response or app restart. A restored announcement stays locked for explicit retry; definite validation rejection releases it for correction, and unavailable recovery blocks new work.

  • Asking a group question in the mobile app now preserves its exact title, context and protected request across a lost response or app restart. Restored questions remain locked for explicit retry, and unavailable recovery blocks a replacement question.

  • Posting an answer in group Q&A now preserves the exact answer and protected request across a lost response or app restart. The recovery card remains usable even when the original question is outside the first loaded page.

  • Creating a group wiki page in the mobile app now preserves the exact title, content and protected request across a lost response or app restart. Restored pages remain locked for explicit retry, and unavailable recovery blocks replacement work.

  • Uploading a group gallery photo or video now keeps an app-owned copy plus its protected request across a lost response or app restart. Recovery verifies the same file bytes before explicit retry and blocks selecting replacement media while the original result is uncertain.

  • Pending group invitations in the mobile app now show their expiry date in the language chosen in the app, rather than US English. The committed database schema snapshot now includes the group-exchange, federation-message and group join-decision retry tables, the contact-form retry columns and the quiz-attempt retry columns, so the schema-reference check passes again.

  • Deleting a group announcement, wiki page, question or answer now removes its creation-replay receipt in the same transaction, so a later retry cannot resolve to content that has already been deleted.

  • The mobile app's "Create group exchange" screen now offers "Add yourself as" Provider or Receiver, matching the website, so an organiser who is also taking part can include themselves. The member search never lists the person searching, so this was impossible in the app before. Available in all seven app languages.

  • Signing in on a local development machine works again. The browser-origin check added with the move of refresh credentials out of browser storage allowed plain http://localhost only when the environment was named local or testing, but the documented local stack runs as development, so every local browser sign-in was refused with AUTH_BROWSER_ORIGIN_INVALID before the password was checked. development is now included, matching the other loopback allowances; production and staging are unchanged.

  • The AI assistant now describes group exchanges correctly: Providers and Receivers, the three ways to share hours, and how everyone confirms. Its built-in text described a "beneficiary", payment "from a community pool" and per-person actual hours, none of which exist. Communities already using the old default text are updated by a migration; a community whose admin edited that text keeps their own version.

  • The group exchange setup screen now offers "Add yourself as" Provider or Receiver, so an organiser who is also taking part, such as a workshop leader, can include themselves. The member search never lists the person searching, so this was impossible on the website before. Available in all eleven languages.

  • Completing a group exchange now records who paid whom. Each receiver's wallet history shows the hours they gave, paid to the providers who earned them, and every participant's records now add up to their balance change. Previously only providers got a record, and it named the organiser as the payer even though the organiser's balance never moved, so receivers could not see what they had given and the organiser's totals in admin reports were inflated. Exchanges completed before this change keep their old records (GroupExchangeService::complete()).

  • Group discussion replies in the mobile app now preserve the exact draft and protected request across a lost response or app restart. Retrying returns the original reply without creating another post or repeating its server-side effects, while changed text under the same request is rejected.

  • Group join-request decisions in the mobile app are now stored before sending and can be retried safely after a lost response or app restart. The server replays the original accept or reject result without repeating XP or in-app notifications, rejects changed intent, and prevents a second manager from overwriting a completed decision.

  • Group managers can now create and share expiring invitation links, send validated email invitations, review pending invitations and revoke them from the mobile app. Interrupted requests refresh authoritative pending state before another mutation is allowed, and refused email work remains editable.

  • Group-task creation in the mobile app now preserves the exact draft and protected request across an interrupted response or app restart. Retrying returns the original task instead of creating a duplicate; invalid submissions remain editable, and deleting a task removes its replay receipt so it can be created again safely.

  • Group tasks now offer every loaded member and a searchable, paginated assignee picker for creation and reassignment, preserving an off-page current assignee and ignoring obsolete or failed searches.

  • Group-exchange member search now keeps the newest query's result when an earlier request finishes later, and ignores obsolete failures instead of replacing current results with a stale error.

  • Native group member and task actions now follow the server's per-record permissions, hiding refused controls while preserving the task creator's edit/delete access and an assignee's status-only access.

  • Native group pages now honour each community's configured sections: disabled tabs are hidden, their guarded endpoints are not read or refreshed, and a disabled deep link safely opens the group overview.

  • Group file uploads from the mobile app now keep the same protected request after an interrupted response or app restart. Retrying the same selected file returns the original upload instead of storing a duplicate, while changed content under that request is rejected.

  • Contact messages sent from the mobile app now keep the same protected request after an interrupted response or app restart. Retrying preserves one stored submission and does not repeat the organiser email attempt; reusing the key for changed content is rejected.

  • Federated messages sent between communities from the mobile app now keep the same protected request after an interrupted response or app restart. Retrying returns the original message and does not repeat email, realtime, in-app or push delivery; reusing the key for changed content is rejected.

  • Creating a group exchange in the mobile app now keeps the same protected request after an interrupted response or app restart, so an explicit retry returns the original exchange instead of creating a duplicate. Reusing the request after changing its title, hours, split or participants is rejected.

  • Creating a group in the mobile app now reuses the same protected request after an interrupted response or app restart, so retrying cannot create a second group. Reusing that request for changed group details is rejected instead of applying the wrong result.

  • Native event Safety saves now preserve unfinished edits in the other form: saving a participation review keeps policy edits, and saving a policy keeps the review draft. Pending recovery also keeps the navigation warning for unrelated unsaved work, and accepted changes release their busy state before the screen refreshes.

  • The scheduler and queue workers now use the same prerender snapshot volume as the web app, so drift detection and cache invalidation work after workers drop root privileges.

  • The post-deploy Sentry watch now shortens an explicitly pinned full commit to the 12-character release used by the running services, so it counts errors from that release correctly.

  • Prerender drift detection now identifies active jobs by tenant ID, allowing the platform master tenant's null slug without aborting scheduled sweeps.

  • Newsletter subscriber activity tables now ignore malformed rows without an email instead of crashing when a row has no stable key. The API also excludes blank emails before counting and paging these lists, so totals match the rows shown.

  • Production's blue/green browser gate now tests the exact candidate release over local HTTPS, so its sign-in checks use the same secure-cookie rules as the live site.

  • The Swiss AI consent notice now appears only after sign-in, when its consent choices can be saved, and dismissing it applies only to the current member and community.

  • Prepare Android 1.8.0 (build 18) for Internal testing: the organiser Safety screen, the iPhone lock, photo, date and location fixes, and the reconnect and large-text fixes from the mobile finish work.

  • In the mobile app, if location access has been refused for good (always the case on an iPhone after one refusal), the Listings "Near me" filter and the nearby marketplace map now offer an "Open settings" button, so the member can turn location back on. Before, they only saw a message with no way forward.

  • On an iPhone, the event Team screen (access expiry) and the event Safety screen (review end date) now keep the date shown on the picker when the organiser taps Done without scrolling it. Before, nothing was saved in that case, although a date was on screen.

  • In the mobile app, adding a photo (profile picture, group media, marketplace listings and shop profile, onboarding, podcasts and message attachments) now opens the phone's photo picker straight away. The app used to ask for access to the whole photo library first; on an iPhone, anyone who once said no could never add a photo again, because the question is never asked a second time.

  • In the mobile app, the agenda change comparison now shows dates and times in the language chosen in the app, like every other screen, instead of the device's language setting.

  • With very large text in the mobile app, the Listings title no longer breaks in the middle of the word and the Home feed header wraps instead of being cut off.

  • On a member's profile in the mobile app, the action buttons (Connect, Send credits, Send message, Say thanks) now sit two to a row, so their labels are no longer cut off.

  • The Volunteering page in the mobile app shows a dash instead of "0" for opportunities, applications and verified hours until they have loaded.

  • When the phone loses its connection and gets it back, screens in the mobile app that could not load now load again by themselves instead of waiting for you to press Retry. While a list cannot load, the Listings, Events and Search pages no longer show a false "0 results".

  • The Organisations page in the mobile app no longer shows "0 partners, 0 volunteers" while the list is still loading or has failed to load.

  • An open conversation in the mobile app now catches up when you come back to the app, so messages sent while it was in the background appear straight away instead of waiting for a pull to refresh.

  • Creating or editing a time-bank listing in the mobile app: pressing Post with something missing now scrolls to the first problem, such as "Please choose a category". Before, the message appeared off-screen and the button seemed to do nothing.

  • Marketplace in the mobile app: changing a filter or searching somewhere else while results are loading no longer shows the older results; opening one collection and then another quickly shows the right items; and collections now load past their first 50 items with a Load more button.

  • The legal document screen in the mobile app no longer shows the previous document's text when a link opens a different document.

  • In the mobile app, a quick double tap can no longer send a federated message or reply twice, send the contact form twice, or create two saved collections.

  • In the mobile app, withdrawing an idea and then leaving the screen before it finished no longer pulls you back to the ideas list from wherever you had gone.

  • Creating an event from a template in the mobile app can no longer make two draft events: a retry after a lost connection reuses the original request, and a double tap sends only one.

  • The automated test data for the mobile app now creates its sample event the same way the app does, so the event safety, registration and check-in sections open for it instead of showing "Registration workspace could not be loaded". Real events were not affected.

  • Native agenda conflicts now persist their rejected state reliably on the first Android attempt. Recovery snapshots the validated refusal code before queued storage work, preserving the saved change for review instead of leaving it pending after a runtime error.

  • Native agenda conflict review now compares current session details with the live proposed edit, including exact times and expandable speaker/resource changes. Restored linked speakers retain their available display names without changing member identity.

  • Native agenda organisers can explicitly discard a definitively rejected change after confirmation, including when its session has been cancelled or removed. Obsolete editors close during review; uncertain operations and failed local discards remain protected.

  • Native agenda recovery now permits review of an interrupted edit, cancellation or reorder when the API proves its saved version is obsolete and the operation never applied. Accepted retries still return their original receipt; other uncertain outcomes remain protected.

  • Native agenda editing preserves exact original times when minute-based inputs are unchanged, avoiding false event-boundary errors. Failed saves now bring the recovery notice into view on long forms, and sessions spanning multiple days show both start and end dates.

  • Native offline attendance now restores the previous state when undoing an action, permits a valid later scan of the same badge, and avoids counting synced actions again after refreshing the roster. An opt-in history snapshot preserves compatibility with existing clients; uncertain pending actions remain saved for reconciliation.

  • Native event check-in now translates conflict attendance states and scanner refusal messages in all seven app languages, and accurately describes the saved read-only queue after a refused sync without promising retention after confirmed device revocation.

  • Native event check-in queues now recover the latest conflict decisions after organiser resolution and reopening, including older saved queues, without resubmitting attendance or discarding pending scans.

  • Plain native message drafts now follow the member across inbox and deep-link entry. Existing drafts are recovered without copying or deleting them; distinct legacy drafts and listing-specific drafts remain preserved.

  • Native messaging now refreshes unread counts after realtime resubscription and reloads missed messages when the conversation is visible, deferring read-affecting recovery while it is covered or backgrounded.

  • Native message threads now follow delayed message layout when opening a conversation, while preserving the position of members who deliberately scroll into older history.

  • Message attachment persistence failures now roll back the complete send instead of reporting success with missing files. Retrying can save the full message, and failed sends clean up staged uploads.

  • Native course quizzes now let learners review and edit their answers after selecting Try again, rather than immediately consuming another attempt with unchanged answers. Recovery of an uncertain submission continues to reuse its original attempt.

Security

  • Granting or removing community top-admin rights now requires outranking the account being changed, as other account-security actions already do, so one platform admin can no longer demote another or a platform owner (F-255).

  • Identity verification now applies the adults-only rule: when a passed ID check shows the holder is under 18, the account is not approved or activated, gets no "ID verified" badge, and cannot sign in (F-240).

  • Podcast audio can now be stored only on private server storage or the configured cloud storage. Community admins can no longer choose a shared public folder or the website's own folder, where audio would have bypassed signed links and members-only checks (F-266).

  • A regional network admin can no longer switch hub mode on or off, or reactivate, their own root community (which could remove a fellow network admin's rights); that is for platform admins. They still manage their sub-communities as before (F-251).

  • A broker or coordinator can no longer lift an admin's ban by suspending the member and then reactivating them; single and bulk suspension leave banned members unchanged for them (F-250).

  • Deleting an account now also removes the member's stored display name, username, date of birth, organisation name, CV details and availability, and deletes their comments, so their real name no longer appears to other members afterwards (F-243).

  • On the accessible site's sign-up safeguarding step, a help link is now shown only when it is a secure https web address (F-253).

  • A broker or coordinator can no longer reverse, or settle a dispute on, an exchange involving another broker or an admin; this needs an admin, as balance corrections already do. Exchanges between ordinary members are unchanged (F-254).

  • Installing a community's caring role presets no longer takes over a role that another community created under the same name (F-267).

  • A member's activity timeline, shown on their profile to other members, now contains only posts, comments and events the viewer could open themselves, and shows connections by first name only. It is also withheld when the profile is visible to connections only or either member has blocked the other, as the profile itself is. Supporters with "view activity" permission see the same filtered timeline (F-239).

  • Confirming a paper sign-up form now applies the adults-only rule: a form with a date of birth under 18, or an invalid one, does not create an account (F-249).

  • Adding a new advert to an approved local-advertising campaign now sends the campaign back for admin review, so members never see an advert an admin has not reviewed (F-260).

  • A member removed from a group can no longer edit the posts and comments they left in it (F-265).

  • A member's profile no longer shows them as online to other members when they have switched on "Hide my presence" (F-264).

  • The web server now refuses the old public folders that message attachments and voice messages used before they moved to private storage (F-262).

  • Cross-community credit transfers now require the wallet to be switched on, onboarding to be complete and the current terms to be accepted, like ordinary transfers. Creating a group exchange now also requires the current terms to be accepted (F-259).

  • Group webhook deliveries now always connect to the address the platform checked, instead of looking the address up a second time (F-258).

  • Server-side web requests the platform makes (link previews, webhooks, partner connections) now also refuse the cloud host's internal service address and other non-public network ranges (F-257).

  • Admins can now attach item attributes only to categories in their own community, and the attribute list never shows another community's category name (F-256).

  • The API now accepts sign-in credentials only in the Authorization header. A browser cookie that no Project NEXUS app sets was also accepted as a credential (F-247).

  • A member's availability, skills, endorsements, appreciations, public collections, verification badges and rating now follow the same privacy rules as their profile: hidden from non-connections when the profile is visible to connections only, and from anyone either side has blocked. The "who is available" list now also respects search opt-out, connections-only profiles and blocks, and shows first names only (F-246).

  • Event organisers who are not community admins can now name at most 50 members in one invitation campaign. Larger lists are for admins, like the other community-wide invitation types (F-241).

  • Saving a community's settings no longer restarts page rendering for every other community unless the community's maintenance mode really changes. Re-sending the current maintenance setting used to trigger a full platform re-render each time (F-245, partly fixed: a real switch into or out of maintenance still re-renders every community).

  • Only admins can now turn on review copies of every private message. A broker could reach the same setting through the message-sampling rate; brokers can still choose a sampling rate below 100% (F-242).

  • Group chatroom notifications now go only to active members of the group. People who had asked to join, had been invited or had been removed from a group could receive message previews from its chatroom (F-238).

  • Strengthened authorization and privacy controls for safeguarding case changes, message review archives, message translation and marketplace discovery. Supported transfer approvals now show the amount and exact beneficiary, and paid course enrolments keep separate payment identities.

  • BREAKING: Regional-point member transfer responses no longer include recipient_balance; recipients can continue to read their own balance through their account summary.

  • Safeguarding report assignments and alerts now require current, tenant-scoped report access, excluding report subjects and expired or revoked permissions. The report route and recipient checks use consistent administrator authority.

  • BREAKING: External Credit Commons and Komunitin transfers now require the local payer's approval for each specific debit. Partner-requested completion stays pending until approval; settlement and Credit Commons reversals recheck the approved terms, expiry, balance, and replay state. Komunitin transfer creation now requires a stable partner request ID or Idempotency-Key.

  • Coordinators, and admins whose rights come from account settings rather than the "admin" role, now receive every safeguarding alert the Broker Panel is built around: copies of messages for review, requests for coordinator help, safeguarding disclosures at sign-up, blocked contact attempts, changes to a member's safeguarding preferences, incident reports, overdue-review escalations and vetting renewals. Eleven alerts each had their own hard-coded list of roles, and none included coordinators, so a community run by coordinators was never told. They now share one rule, and a test fails if a hand-written list comes back. This was an original gap, not a regression (F-221).

  • "Hide Comment" in comment moderation now hides the comment from every member. It used to hide the comment only from the moderator who pressed it, so everyone else could still read it. A hidden comment is now removed the same way the content-moderation queue removes a rejected one (F-220).

  • Admins can now record a data breach from the GDPR pages. "Report breach" failed every time, so no breach could be recorded where the dashboard tells admins to record it. Reports now get their reference number and start as "detected", and the number of affected members is kept. The breach page's "Mark investigating" and "Mark contained" actions now appear for a new report, and the dashboard's active-breach count includes it (F-223).

  • A broker or coordinator can no longer add or remove hours on another broker's or an admin's balance; they can still correct an ordinary member's balance, with a reason, as before. Only a broker's own balance was blocked, although the broker guide said brokers cannot change another broker's or an admin's account. The check is the same rank rule member-management actions already use. Admins are unchanged. The broker guide's "one exception" note is removed in all eleven languages (F-219).

  • A broker can no longer close a member's report about content the broker owns, including posts, listings, comments, events, goals, polls, volunteering opportunities, challenges, resources, jobs, blog posts and discussions, or about a review they wrote or received. The earlier F-218 fix missed several reportable feed types; a broker could still dismiss a complaint about their own public goal, even after deleting it. Reports whose content owner can no longer be identified now require an admin to close them. Admins keep full latitude. The broker guide says so in all eleven languages (F-218).

  • When a broker's monitoring period runs out, a member whose messaging was switched off can now send messages again, and is told their restrictions have been lifted. Until now the nightly clean-up ended the monitoring but left messaging switched off for good, while the member dropped out of the brokers' monitoring list, so nobody could see or undo it. The same clean-up frees members already left in that state, the automatic end is recorded in the activity log, and the message-sending check no longer honours a switch-off whose period has passed. The broker guide now describes this in all eleven languages instead of warning brokers to end monitoring by hand (F-217).

  • Retire the prior member's browser push subscription when a session expires or is replaced, including cross-tab account switches, and give each push endpoint one current member owner when a new account subscribes (F-108 follow-up).

  • Bind member GDPR data requests, consent changes and account-erasure requests, plus administrator consent views and account-created consents, to the authenticated community after tenant resolution. These operations could otherwise use the platform default community when their controllers were constructed early (F-216).

  • The job-moderation administrator switch now governs job publication and review. A saved choice takes precedence over older tenant configuration, so enabling review in settings actually holds new and edited job ads for approval (F-215).

  • Job ads now return to moderation when an employer changes approved content. An open ad is removed from public view pending review; changes to a closed or draft ad invalidate its old approval before reopening. Resubmitting unchanged content leaves the approval intact (F-214).

  • F-004 (E-038): a goal buddy must be accepted by the goal owner. Any member could appoint themselves buddy of another member's public goal with one request. POST /v2/goals/{id}/buddy now creates a pending request (new table goal_buddy_requests, additive migration) and changes nothing on the goal; the owner accepts or declines it through the new owner-only GET /v2/goals/{id}/buddy-requests and POST /v2/goals/{id}/buddy-requests/{requestId}/accept|decline. Accepting keeps the F-143 row lock and the F-097 public-identity projection, re-checks the safeguarding policy and closes competing offers; a declined member cannot re-offer on the same goal. React and the accessible site show pending offers to the owner with accept/decline controls, and "offer sent" to the member who offered. Regression test: tests/Laravel/Feature/Security/E038/GoalBuddyConsentTest.php; GoalBuddyConcurrencyTest now races two owner accepts. The accessible site's generated route matrix and API consumer ledger are refreshed for the new route and its three API calls.

  • F-002 (E-038): another member's exchange history is no longer visible. GET /v2/users/{id}/activity/dashboard returned, to any signed-in member of the same community, every completed exchange with the other party's name and hours, monthly hours and a net balance — shown on every member page of the accessible site. Exchange entries, hours_summary and monthly_hours are now returned only to the member themselves and to that community's admins, brokers and coordinators; other members still see public posts, skills, connection and engagement counts, and the profile's hours-given and hours-received totals are unchanged. Regression test: tests/Laravel/Feature/Security/E038/MemberActivityDashboardPrivacyTest.php.

  • F-035 (E-038): unrecognised hostnames are now refused. An API request arriving on a hostname that is not a community's domain, a community's accessible domain, a configured platform host or an internal address now gets a plain 404 instead of being answered as the master community. Extra platform hostnames go in TENANT_PLATFORM_HOSTS; TENANT_REFUSE_UNKNOWN_HOSTS=false restores the old behaviour in an emergency. Regression test: tests/Laravel/Feature/Security/E038/UnrecognisedHostRefusalTest.php.

  • O-068 (E-038): the pen-test staging mail viewer receives platform email again. Since 17 September the platform refused every recipient on a reserved domain such as .local, so password resets, invitations and notifications to the staging test accounts (@pentest.project-nexus.local) never reached the capture inbox. A non-production server can now name its capture domains in MAIL_CAPTURE_RECIPIENT_DOMAINS; production ignores the setting, and a bare suffix or anonymized.local is never exempted. Regression tests in tests/Laravel/Unit/Services/EmailDispatchServiceTest.php.

  • "Report a Concern" (Caring Community) now tells members truthfully who reads their report: the community's coordinators, brokers and administrators, who can see the reporter's name. It previously said reports went only to designated safeguarding coordinators. Critical reports now alert those staff (they used to reach almost nobody, because only people with a rarely granted individual permission were alerted), overdue reports of any urgency are escalated to them, and nobody can see or be alerted about a report made about themselves (F-213).

  • When a broker or coordinator opens a copied message for review, they now see only the conversation up to that message (the latest 50 messages before it), and every opening is recorded in the audit log. Previously opening one copy showed the first 200 messages the two members had ever exchanged, including everything written afterwards that was never copied or flagged, and only review decisions were recorded (F-212).

  • When a community reviews job ads before they appear, a job saved as a draft and then published now goes to review instead of straight onto the public jobs list. Previously "save as draft, then publish" skipped the review step. Jobs that were already approved can still be reopened without a second review, and admins can publish directly (F-211).

  • Only the person who sent a message can now delete it for everyone. Either participant could previously choose "Delete for everyone" on the other person's message, which replaced it with "[Message deleted]" for both people, so a member could erase what someone else had written to them. The other person can still remove a message from their own view, and the website no longer offers the option on other people's messages. The messaging guide and service comment now state the same sender-only rule (F-210).

  • Browser sign-in now keeps the 15-minute access credential in memory and the rotating refresh credential in a secure, host-only HttpOnly cookie. Existing readable browser token records are removed on startup, and the native app's token response remains available. Same-origin API routing, session continuity checks, and recoverable retry screens across protected panels protect custom communities and account switches. Browser gates now use distinct cookie sessions, test Safari's engine over HTTPS, and isolate synthetic MFA and accessibility runs under the existing rate limits. The mobile API route inventory is checked against the running Laravel build (F-149 / CodeQL #1778).

  • Community boundaries: an admin can no longer look up another community's members through data-protection requests, CRM tasks or deliverables; a federation partnership can no longer be made active without the other community agreeing; switching federation off now takes a community out of federation completely; secret groups and private-group events are no longer shared with partner communities; either side can no longer reactivate a credit agreement the other suspended; and the partner API respects each community's own switch.

  • Sign-up and sign-in: a community's identity-verification and waiting-list rules now apply to email sign-ups too; switching off "new members need approval" needs a platform administrator; turning on two-step sign-in asks you to confirm it is you; resending a verification email to the same address is rate-limited; and the test identity provider is no longer available on shared test servers.

  • Admin powers: a broker can no longer undo an admin's ban; a network super-admin can no longer impersonate an equal; community-deactivation safeguards apply on every edit path; and audit, activity and safeguarding records have minimum retention periods.

  • Outbound requests and push: the server can no longer be pointed at its own internal addresses through unusual address formats; web-push subscriptions must point at a recognised push service; a phone's push registration can no longer be moved to another account or community; and group-webhook replies are size-limited.

  • Credits and billing: donations and community-fund movements refuse amounts smaller than a cent, and exchanges round agreed hours once so both balances move by exactly the same amount; anonymous clicks and repeated views no longer spend an advertiser's budget; new group exchanges always start as drafts; subscription billing now follows Stripe for plan changes made in the billing portal, unpaid or failed payments, cancellations and delayed bank payments; and a paid push campaign can no longer change after it is submitted for review.

  • Safeguarding, events, groups and volunteering: the person who reports a volunteering safeguarding incident no longer sees the investigators' notes; guardian consent refuses the young person's own email address; only community admins can send event invitations to email lists, CSV uploads or the whole community, and other organisers no longer see those options; a member removed from a private group can no longer rejoin with an older invite; draft ideation challenges no longer appear in campaign lists, outcome dashboards or favourites; and the daily 24-hour volunteering limit holds even for simultaneous submissions.

  • Feed, stories, polls and courses: reviews that are hidden, flagged or deleted leave the feed; blocking someone also stops their likes, story reactions, shares and poll votes; stories shared with a limited audience can no longer be reacted to or answered by others; course cards follow the course's visibility and status; republishing no longer undoes an admin's rejection of a course or podcast, and changes to an approved course or its lessons go back for review where the community reviews courses; course prerequisites no longer reveal hidden courses; the older post endpoint applies the current checks; sidebar suggestions hide listings awaiting moderation and blocked members; and posts can no longer embed images hosted elsewhere.

  • Uploads and messages: uploaded SVG images are fully cleaned and uploaded files are served under a strict content policy; photos no longer keep hidden location data; editing a message that a broker reviews sends it back for review, marked as edited; and a voice message deleted for everyone no longer shows its transcript in the conversation list.

  • AI features outside the assistant chat (voice-message transcripts, message and content translation, AI-written listing, marketplace and job descriptions, and marketplace suggested replies) now respect the community's AI switch and each member's AI allowance. The assistant's "generate" buttons, which had stopped working, work again.

  • Videos and links: job videos and course embed lessons accept only YouTube and Vimeo links and play in a locked-down frame; idea attachment links accept only ordinary web addresses; and the sign-in error page no longer shows text taken from the link.

  • React app: profile preview cards no longer show the previous person's view of other members after someone else signs in on the same browser tab.

  • Accessible site: sign-in limits apply to each visitor instead of to shared Cloudflare addresses; file uploads keep the visitor's address and language; and sign-in and session cookies are locked to the site's own address. Existing sign-ins keep working through this release.

  • Mobile app: the appreciations and collections screens name members only from the server, and accepted-offer checkout shows the price the server holds rather than one taken from a link; and iPhone builds now pin the platform's certificates, as Android builds already do. The app no longer accepts over-the-air code updates: every change now arrives as a new version from the app store. The app no longer contains any guardian-consent screens or under-18 event settings, and if an account is recorded as under 18 it explains, in the member's language, that the platform is for adults.

  • Adults only everywhere: the platform is for adults aged 18 and over on every surface. Guardian consent for volunteering and events has been switched off, an account recorded as under 18 can no longer sign in or keep an existing session, and nobody can enter a date of birth under 18. The guardian-consent screens have been removed from the website, the accessible site and the app, organisers can no longer require guardian consent on an event, and the public features page no longer offers it. Date-of-birth pickers stop at 18 years ago, and the optional identity step, which used to accept 16, now requires 18. An admin who tries to switch guardian consent back on sees a translated explanation.

  • A member's data export includes their recorded sign-in history again.

  • Deployment and backups: a production deploy now builds exactly the commit its pre-deploy check approved; backups are created readable by their owner only; database passwords no longer appear in the server's process list, and the manual backup and migration scripts never handle the password at all; deploy state no longer lives in a shared temporary folder; and a deleted community's old web address is removed from the cross-site allow-list. The background job and scheduler processes no longer run with full system rights, and the platform's own code can no longer be changed by the web server's user.

  • Keep external Partner API and partner federation traffic closed by default on new rollouts, even if database switches are enabled. Caring Community's disabled state now blocks its API routes and invite lookup, external Caring data paths and the React invite page (F-150).

  • Patched development dependencies used by the root, React and accessible frontends, including the SVG optimizer. Unused accessibility and HeroUI command-line packages were removed. The React test runner and Lighthouse CI archive dependency still need compatible upstream fixes.

  • Hardened legacy community-link redirects on custom accessible domains with path and origin validation while preserving safe local paths and their query strings.

  • Link previews now retain cURL DNS pinning and stop downloading as soon as the decoded response exceeds 500 KB. Authenticated members can no longer make a preview worker load an unbounded response into memory or bypass the pinned address through the PHP stream handler (F-148 / E-025 R21).

  • External federation transfer cancellations now lock and recheck the completed transfer before reversing credits. Two simultaneous authenticated partner cancellations can no longer deduct the same transfer twice (F-147 / E-025 R14).

  • React sessions now bind requests, retries, sign-in completions, tenant changes, logout, impersonation and offline event check-in data to one immutable account generation. Delayed work from account A can no longer refresh, resend, overwrite, clear or retarget account B after a same-browser account switch. Regression coverage now exercises the exact browser-storage mutation boundaries, and the test-type ratchet locks in the corrected biometric response fixtures (F-020 / E-025 R04).

  • Super-panel user moves now lock and recheck the destination community before changing an account. A simultaneous hierarchy, active-state, or hub-capability change can no longer make a previously valid destination stale; hierarchy moves use the same tenant-before-user lock order (F-144).

  • The message inbox no longer returns other members' last-active time (F-088).

  • BREAKING: The old GET /api/members, GET /api/listings and GET /api/groups endpoints have been removed. They ignored member privacy settings and returned other members' email addresses, unapproved listings and private groups. No Project NEXUS app used them; use /api/v2/users, /api/v2/listings and /api/v2/groups (F-145).

  • Members taking part in a group exchange no longer receive each other's email addresses (F-146).

  • Members now see other members by first name only (organisations by their name) in event attendee lists, message and group-chat lists, review lists, reaction lists, exchanges, endorsements, ideation, a group's recent members and story viewers; anonymous reviews no longer reveal who wrote them in review lists. Administrators still see full names (F-084).

  • Removed or rejected reviews can no longer be opened by other members, and a single review no longer shows members' surnames or an anonymous reviewer's name (F-073).

  • The feed sidebar no longer advertises draft events or events from private groups you are not in (F-074).

  • Posts, comments and profiles can no longer borrow the app's own styling to draw fake "sign in again" screens (F-075).

  • Sending a connection request no longer shows you the other member's surname, private bio, location or when they were last online (F-083).

  • The connections list, group member lists and the leaderboard now show first names only to non-admins, as profiles already did (F-084).

  • Members can no longer look up which groups another member belongs to (F-096).

  • Private group chatrooms are now actually private: only their creator, the group's admins and community admins can open them (F-098).

  • "Hide my presence" now also applies to suggested members and friends in the feed sidebar, which no longer return members' last-active time (F-088).

  • Group chats now respect blocks and "messaging disabled" restrictions, need the same completed setup and accepted terms as one-to-one messages, and copy monitored members' messages for broker review (F-086).

  • Deleting a conversation through the older app route now hides it only for you, instead of erasing the other person's messages and the broker's safeguarding copies (F-087).

  • "Hide my presence" now stays in effect, including on message screens (F-088).

  • Messages can no longer carry forged attachment details; attachments come only from real uploads (F-089).

  • A blocked member can no longer see the safeguarding notice of the member who blocked them (F-092).

  • Deactivating several communities at once now has the same safeguards as deactivating one: a network admin cannot deactivate their own network, and a community that still has active sub-communities is refused (F-060).

  • Simultaneous offers to become a public goal's buddy now have one atomic winner. The selected buddy and its history records are committed together; later contenders receive the existing conflict response and no duplicate notification is created (F-143).

  • Ratings left on an exchange can now only be seen by the people in that exchange, its assigned broker and community admins (F-103).

  • Members viewing the community fund no longer see who received a grant or the reason an admin gave (F-104).

  • Time-credit donations can no longer be sent to suspended or banned accounts, and every way of sending credits now needs the same completed setup and accepted terms (F-105).

  • An admin grant from the community fund to a member who doesn't exist or can't receive credits is now refused and the fund is left untouched (F-106).

  • A delayed 'payment failed' notice can no longer cancel an identity-check fee that was already paid, and the fee is shown in the community's own currency (F-107).

  • Public job feeds can no longer be altered by text inside a job post (F-076).

  • The image thumbnail service can no longer be used to view files from the protected vetting-documents folder (F-090).

  • Only community admins can upload to or browse the admin image library (F-091).

  • Regional super-panel administrators can no longer revoke, move, or move-and-promote peer and higher-tier accounts in their tenant subtree. These mutations now recheck both account hierarchy and regional access under database locks; bulk moves reject protected targets individually while continuing eligible lower-tier moves (F-142).

  • The AI assistant's event search and semantic search no longer show events from private or secret groups to members who are not in them (F-079).

  • Compose drafts and recent searches now belong to one member of one community and are cleared on sign-out, so the next person on a shared browser can't see or publish them (F-109).

  • Opening a link to another community on the shared accessible site no longer signs the member out; the session is refreshed with the community it was issued for (F-112).

  • Every numeric id in the accessible site's routes is now digits-only and every value placed into an API path is encoded, so a crafted link can't point a member's authenticated request at another endpoint (F-113).

  • The accessible site's CSRF token is now tied to the session and uses a __Host- cookie in production (F-114).

  • Opening the two-step verification page on the accessible site no longer generates a new setup secret; setup starts only from its button (F-115).

  • A link's name can no longer set the title of a message thread, profile or federated message in the app; only the name the server gives is shown (F-118).

  • The app's fingerprint or face lock now locks again when the app returns after more than five minutes in the background (F-119).

  • Wallet CSV exports from the app now neutralise cells that spreadsheet apps would run as formulas (F-120).

  • Exported wallet statements and downloaded message attachments are removed from the phone on sign-out, and a failed or out-of-session attachment download is no longer offered as the file (F-121).

  • Hidden or deleted messages no longer expose retained attachments, voice recordings or transcripts to the affected participant; delete-for-everyone tombstones also omit private media metadata (F-046).

  • Link previews now reject credential-bearing URLs, isolate non-default ports and fragments in cache identity, quarantine unsafe legacy rows across direct, post, message and feed reads, and migrate the global cache without breaking valid associations (F-052).

  • Brokers and coordinators must now use two-factor authentication, like administrators (F-057).

  • Brokers can no longer edit administrators' or other brokers' profiles, or change the name of an ID-verified member (F-058).

  • Only platform super-admins can clear the cache for every community (F-059).

  • Admin SEO redirects now only accept pages on the same site and no longer apply to API routes (F-061).

  • A community's SMTP server must now be a public mail server; private and internal network addresses are refused (F-062).

  • Emails sent over direct SMTP are no longer cut short or altered when a line begins with a full stop (F-063).

  • Platform-wide scheduled job logs, which can mention members of any community, are now visible only to platform super-admins (F-064).

  • Guardian-consent requests for events now authorize the minor against the event's current audience before creating consent history, notification outbox, or encrypted delivery state. A minor outside a private group's audience remains unable to trigger guardian email, including when an event manager submits the request on their behalf (F-051).

  • Members who chose not to appear in member search no longer show up in suggested members, "People you may know", @mention suggestions or members-by-skill, and these lists no longer show surnames (F-080).

  • Members whose profile is visible to connections only are no longer listed in the member directory or nearby members for anyone else, and their listings and reviews are no longer readable by other members (F-081).

  • Other members now see a member's location, and the location of their listings, only to about 1 km, and nearby-search distances can no longer be used to pinpoint someone (F-082).

  • AI member searches now enforce each member's profile visibility and bilateral blocks at database hydration time. Connections-only profiles are returned only to accepted connections, blocked pairs are excluded in either direction, and semantic-search hits are rechecked against current settings before any profile fields reach the model or the response (F-049).

  • Members no longer see draft or unpublished KISS meetings, or the notes coordinators write about them (F-134).

  • Cover-care suggestions now respect members' "don't list me" and connections-only privacy settings, and no longer show their location or verification status (F-135).

  • Once a coordinator has reported or settled a member's hour estate, the member can no longer change it or its beneficiary, and members no longer see coordinator notes on their estate (F-136).

  • The caring Marktplatz no longer shows listings that are still awaiting or have failed moderation (F-137).

  • Voice help requests now respect the community's AI on/off switch and each member's AI usage allowance (F-138).

  • Anonymous municipality feedback now stays anonymous in the admin triage list and detail view, matching the CSV export (F-139).

  • Hour gifts and legacy-hour estate settlements now appear in wallet history, so balances and the transaction ledger agree (F-140).

  • The global API rate limit now treats a bearer credential as a member identity only after validating the current signed access token. Rotating malformed, expired or revoked bearer strings can no longer create fresh anonymous request budgets, while verified members behind one shared address retain separate per-account allowances (F-036 residual).

  • Mobile EAS build uploads now exclude the local signing-credentials file, so keystore passwords are no longer sent to Expo build workers with the project (F-125).

  • The local development stack now exposes its keyless search engine and root-login phpMyAdmin on this machine only, not the local network (F-124).

  • The deploy-drift watchdog workflow no longer pastes the latest commit subject or production response values into a shell script, closing a CI command-injection route to its alert-bot token (F-122).

  • Search no longer shows events from private groups to people who aren't in the group, never includes an event's online meeting or video link, and no longer lists private groups or listings still awaiting moderation when the search engine is unavailable (F-078).

  • Signing out everywhere, a password reset, an administrator password or two-factor reset, and suspending or banning a member now also remove that member's registered phone and browser push destinations, so a lost or stolen device stops receiving their notifications (F-117).

  • Polls can now only be posted into a group by people allowed to post there, polls made inside a group stay in that group, and people outside a private group can no longer see its polls (F-069).

  • Comments and reactions on private goals, drafts and items still awaiting moderation can no longer be read or added by other members (F-071).

  • Connecting a Google or Facebook login to your account now needs a fresh confirmation (silently after a recent strong sign-in, otherwise your password, authenticator code or backup code), so a stolen session can't add a permanent way in (F-056).

  • The admin settings and system configuration screens now lock email verification and member approval for anyone but a platform super-admin and leave those settings out of their saves, so ordinary admins no longer get an error when saving other settings (F-054).

  • Municipal survey answers are now checked against the question's options, each member can respond once per survey, and anonymous responses can no longer be linked back to members (F-127).

  • The public lead sign-up form can no longer wipe or push out existing leads, and it no longer reveals whether an email is already on the list (F-131).

  • Caring hours can now only be sent to a partner cooperative that has Caring Community turned on, and error messages no longer reveal which cooperatives or member emails exist (F-132).

  • Community admins can no longer switch off email verification or member approval, turn on maintenance mode, or disable passkeys and two-factor sign-in through the enterprise config screen, and resetting that screen no longer wipes other settings (F-054).

  • Brokers can no longer lift a messaging restriction placed on themselves, and nobody can restrict or release a member of equal or higher rank (F-055).

  • The accessible frontend now sends each visitor's address to the API in the standard forwarded-address header, which the production API server already trusts from its own network, so one visitor's failed sign-ins, reset or registration attempts can no longer lock out every accessible-frontend user (F-110).

  • Club member import no longer returns passwords or account ids, no longer enrols or re-activates existing members, always adds plain members, follows the community's approval rule, and sends new members a password-setup email (F-126).

  • The emergency alert banner no longer shows members push-delivery details or who else an alert was sent to, and delivery results no longer store device tokens (F-128).

  • The civic digest no longer shows members events from private groups they don't belong to, or safety alerts meant for other people (F-129).

  • Caregiver link requests now respect blocks and safeguarding contact rules, can't be re-sent within 7 days of being declined or withdrawn, and notes are limited to 1,000 characters (F-130).

  • The caring "download my data" export no longer includes staff investigation notes, assignees or escalation notes (F-133).

  • Files uploaded to the accessible frontend are now deleted even when the request is refused before it reaches the page, so anonymous uploads can no longer fill the server's disk (F-111).

  • The accessible frontend now tells members honestly when a password-reset or verification email was refused for too many attempts, instead of saying it was sent, and passes each visitor's address to the API so per-visitor limits can apply (F-110, accessible-frontend half).

  • Signing out of the mobile app now revokes its refresh token on the server, so a copied token stops working immediately (F-116).

  • Signing out of the web app now removes that browser's push subscription, so the next person to use the browser no longer receives the previous member's notifications (F-108).

  • Blocking a member now also stops them commenting on or reacting to your content, replying to your comments, @mentioning you, finding you in mention search, reviewing you, endorsing your skills or sending you appreciations, in either direction (F-070).

  • Story highlights can now only contain your own stories, and a highlight shows each story only to people its audience allows, so close-friends and connections-only stories can no longer be read through someone else's highlight (F-067).

  • Volunteer hours can now only be logged for the last 90 days, and no single day can hold more than 24 hours in total across all organisations, so hours can no longer be backdated for years to create credits (F-101, F-141).

  • Tenant administrator AI master and chat switches now stop both the general member assistant and job-specific AI chat before conversation persistence, context/tool preparation, or primary/fallback provider dispatch. Retained provider keys and malformed legacy switch values can no longer keep chat active after an administrator disables it (F-048).

  • Member AI chat now enforces each person's tenant-configured daily and monthly budget atomically across general chat, job chat, provider fallbacks, tool-loop calls and paid semantic-search embeddings. Concurrent requests cannot both consume the final slot, and a mid-conversation limit produces a visible localized assistant response instead of leaving an incomplete thread (F-044).

  • Becoming a buddy for another member's public goal now returns only the goal owner's and buddy's public identity fields, instead of serializing their complete account rows with contact, birth, location, login, privacy, role, and payment-provider metadata (F-097).

  • Group owners and admins can no longer download members' email addresses or the names of pending and banned members from group exports; tenant admins still get the full export (F-093).

  • Group owners can no longer point their group at, or delete, another group's picture: image paths now come only from uploads, and a shared file is kept while any group still uses it (F-094).

  • Group challenges are now limited to 10 live at a time per group, and each member can earn at most 300 challenge XP per day (F-095).

  • Message send responses now restrict embedded sender and recipient objects to public identity fields. Text, attachment, voice, story-reply, and idempotent replay paths no longer return contact details, date of birth, precise location, login/account metadata, privacy settings, or payment-provider identifiers from the users table (F-085).

  • Timebank job offers can no longer create time credits from nothing: the employer must have enough credits to pay when an offer is accepted, and job credit amounts are limited to the same cap and precision as wallet transfers (F-100).

  • Blind hiring now also hides candidates' names and emails in the applications CSV export, the job's activity history, the interview list and AI candidate ranking (F-102).

  • The old social feed endpoint now follows the same privacy rules as the main feed, so it no longer shows private or secret group posts to non-members, other members' private goals, draft or cancelled events, or hidden, draft or deleted posts (F-065).

  • The old like and "who liked this" endpoints now refuse items you are not allowed to see, such as posts in a private group you are not in (F-072).

  • Ideation idea lists now verify the tenant-scoped parent challenge and hide draft, withdrawn, and unpublished content from unauthorised members. Direct idea, comment, and media reads apply the same lifecycle rules, preventing a member from naming another community's challenge or a hidden idea to retrieve its contents (F-077).

  • An event organiser's decision now holds. A member the organiser declined or removed can still ask for a place again, but the request waits as "pending" for the organiser instead of confirming itself; a member already awaiting approval can no longer confirm themselves; "Require organiser approval" now puts self-registrations in pending; and published registration open/close dates are enforced (F-099).

  • A revoked "Peer Endorsed" verification badge now stays revoked: further peer endorsements can no longer restore a badge an administrator took away, and automatically granted badges no longer name the endorsing member as the verifier (F-068).

  • Regional network administrators can no longer turn themselves or another branch account into a platform administrator through the generic user create/edit API, or alter accounts at their own or a higher security tier. Platform authority remains available only through the dedicated god-only grant route. User changes are re-authorized under database locks and now write an atomic old/new audit record (F-053).

  • Bookmarks and saved collections no longer reveal an item the viewer is not allowed to see. Saving or bookmarking now requires that the member can see the item (private-group posts, draft or unapproved listings and jobs, unpublished pages and events outside their audience are refused), and bookmark titles and collection previews are withheld for anything the viewer cannot see — including items in another member's public collection (F-066).

  • Membership badges no longer disclose another member's dues amounts, currencies, due dates, payment dates or prior-year history. The member and authorized club administrators retain full dues detail, while other signed-in members receive only the current status needed to render the badge (F-050).

  • Course detail now returns a syllabus rather than paid or scheduled lesson content to members who have not enrolled. Explicit free-preview lessons remain readable; enrolled learners receive content only after its drip schedule unlocks, while course authors and administrators retain full editing access (F-047).

  • Members with an active identity-verification badge can no longer clear their verified name or date of birth by sending JSON null, including while a platform administrator is viewing another community. Where guardian consent is enabled for volunteering, missing, invalid or future dates of birth now stop participation until age can be established; consent is rechecked at application, shift signup, waitlist entry and promotion, and group-reservation placement (F-045).

  • Club event sharing now accepts only a public event that belongs to the authorized source club and that the authenticated administrator has event-management authority over. Both clubs must have non-empty matching municipality codes. Incoming and outgoing share lists also recheck the owner relationship, public visibility, both current consents and municipality before returning event details, so old or later-restricted shares no longer disclose them (F-043).

  • The public municipality calendar now applies the same group audience boundary as anonymous event discovery. Events linked to private, secret, missing or inactive groups are omitted, while ungrouped events and events in active public groups remain visible (F-042).

  • Club administrators can no longer waive another club's membership dues or send reminders for them by combining the club they manage with a dues-record ID from another club. Waiver and reminder lookups and updates now bind the dues record to both the authenticated tenant and the already-authorized club (F-041).

  • On iPhones, the mobile app's fingerprint / Face ID lock now always stays on top. Before, a screen opened from a notification or a link while the app was locked could appear above the lock (F-040). Android was not affected.

  • The platform-wide API request-rate ceiling can no longer be multiplied by changing a request header. Its bucket was keyed partly on the X-Tenant-ID / X-Tenant-Slug headers the caller supplies, so sending a different community value on each request minted a fresh allowance every time and the ceiling never engaged. It is now keyed on the community the platform actually resolved, so an unrecognised value no longer creates a new allowance. Ordinary use is unaffected, and each community keeps its own separate allowance as before.

  • Member search results now honour the member's own "show my profile in member search results" setting everywhere it is offered. Global search, search autocomplete and the AI assistant's member lookups previously ignored it and returned members who had switched it off, together with their name, avatar, location, skills and profile link; the member directory, Explore and member ranking always honoured it. The rule now lives in one place (App\Support\Members\MemberDirectoryVisibility) so a new discovery surface cannot miss it, and it covers the tenant's own directory listing requirements as well. Search-engine results are revalidated against the database, so a member who changes the setting takes effect immediately rather than at the next index sync.

  • The profile update endpoint (PUT /api/v2/users/me) no longer changes a member's email address. It accepted a new address with no password, sent no confirmation to that address, and left the account marked as verified, so anyone holding a signed-in session could move the account to another mailbox and then reset its password, and a member could claim somebody else's address in a way that Google sign-in trusted. A request carrying a different address is now refused with EMAIL_CHANGE_NOT_AVAILABLE and nothing is saved; sending back the current address, as clients that post the whole profile do, still works. No app offered email changes through this route, so nothing members use has changed.

  • Text a member chooses can no longer put a working link into an email the platform sends to someone else. Display names were placed into several emails as raw HTML — the "liked your post", "commented", "replied", "shared", thank-you, connection-request/accepted/declined, donation and ideas emails among them — so a member who put a link in their own name could have it delivered, clickable, from the platform's own address to anyone whose post they liked. The email builder now keeps only simple formatting (bold, italics, line breaks, styled text, and links back to the community's own site) in paragraph, highlight and list text and shows any other markup as plain text. The instant email queue now also escapes plain notification snippets before converting line breaks, closing the fallback used by connection and other notifications that do not supply a prepared HTML body (F-038).

  • A failed profile, privacy, avatar or account-deletion write no longer shows the member the raw database error, which included the internal database host, port and name and the SQL statement. The detail is still logged; the member now sees "Something went wrong. Please try again." Photo upload messages a member can act on ("File too large", "Invalid file type" and similar) are still shown. A stale error from an earlier request can also no longer be reported against a later one.


Back to all releases