Newsletter status: In progress. See
README.mdfor conversion guide.
v2609.09.0 — September 9, 2026
MRs: !2347, !2346, !2345, !2341, !2340, !2339, !2338, !2336, !2335, !2333
Highlights
Editable labor values in the OTR/YMM calculator (!2347, closes #6783) The 2026 OTR/YMM calculator now lets users edit labor values before running the calculation. Labor, travel, storage, insurance, royalties, profitability, revenue splits, and third-party allocations are all computed from the edited values, with warnings for invalid or risky inputs. Partner FP, OTR-Operated, and Third-Party execution modes are supported.
Aegis sign page paginator fixed — documents load in seconds, not 30 (!2335, hotfix) Some Aegis sign-page documents took ~30 seconds to load with the charges table’s zebra rows running off the sheet and price columns missing. The paginator was inflating pinned column widths in an unbounded loop; it now measures the actual room on the page and stops. The sign page loads in under a second for the affected documents.
Jobs tag filter restored, open/closed tabs now actually filter (!2338, !2341, closes #6867) The tag filter removed in the tabs redesign is back in the jobs page header. Restoring it surfaced two latent bugs: the open and closed tabs returned identical results (the filter was rebuilt from the search form, ignoring the route’s state), and the closed tab was slow because it sorted on an unindexed field. Both are fixed — the closed tab now sorts on an indexed field and the tabs respect their state filter.
Multiple VI bugs fixed: schedule time indicator, timeline flexibility label, availability template validation (!2339, closes #6720) The red “now” indicator on the schedule now moves in real time instead of jumping hour to hour. The customer timeline’s flexibility label no longer shows “Not Flexible” when a two-day range is selected. Availability templates with only Monday and Thursday can now be created — typos in the validation were blocking them.
Features
- Infeasible crew assignments now report a structured, human-readable reason (worker labels, task labels, slot labels) instead of a bare “no solution” — the optimizer surfaces exactly which constraint blocked the assignment (!2333)
Fixes
- Calculator execution now reads the job-specific
metadata.calculatorUrlinstead of the wrong metadata key, with a zone-config fallback when no job-specific URL exists (!2346, closes #6876) - Admins can now edit and delete comments from other users — five
PERMISSION_GRAPHrestriction keys were double-prefixed (restriction_restriction_…), making the ownership override silently inert (!2345, closes #6875) - Document slots with no dispatchable identifier are no longer offered in the UI — a slot with an empty
templateIdand noenginekey previously fell back to PandaDoc and failed on every create (!2340) - Sales leaderboard no longer shows future revenue in the current period — events booked for a future month are excluded from the period’s stats, reverting the unwanted behavior introduced in !2316 (!2336)
Other
- Aegis artifact repro gateway added for debugging customer-reported document issues, with a
--rolewarning and tagged URL code fence in the serve script (!2335)
v2609.03.0 — September 3, 2026
MRs: !2334, !2332, !2331, !2330, !2329, !2328, !2327, !2326, !2325, !2321, !2320, !2319
Highlights
BlueSage terminal payments survive long waits and tell operators what is happening (!2334) On the first production day, every terminal push that took longer than 60 seconds was reported as a failure while the device carried on — the ingress cut the request, Apollo retried with the same nonce, and the gateway rejected it. Terminal pushes now return within a second and the panel follows the transaction through to settlement, showing waiting, paid, authorized, declined, cancelled, timeout, or lost states with real next-step messages. The review queue can now complete an open hold from a captured device sale, and pay links can be cancelled. Apollo no longer retries mutations.
Permission system stabilized after multi-role changes (!2320, !2321, !2325, !2328, !2319)
A cascade of regressions from the interstate permission changes took down x-zone requests, admin comment editing, ops dashboard saves, and job imports. The root cause was resolveContext clearing the JWT role when no zone role IDs were found, and roles.list returning a plain array that was being read as { nodes: [...] }. All paths now preserve the JWT single-role fallback, merge in-memory permission graph permissions, and handle the multi-role path correctly.
Performance
Token.isValidnow resolves from the token GraphQL has already loaded instead of re-fetching from Neo4j, eliminating an N+1 that opened 989 concurrent bolt connections and took down the production database for ~10s on a single/business/marketingpage load (!2330)- Charge and price product lookups are now batched through a shared DataLoader keyed by price ID, reducing repeated
products.listrequests (!2332)
Fixes
- Jobs sidebar sub-items (Leads, Estimates, Bookings, etc.) now navigate to the correct child routes instead of query params that were silently dropped by the router redirect (!2329)
- Dispatch crew leader is now auto-promoted when dropping onto a route, with a gold star icon and tooltip for visibility (!2329)
- Add-new-mover defaults to available + all 7 days enabled regardless of name parsing, and toggling available enables all days if none are on (!2329)
- Route table layout restructured to a table-like flex layout with crew on the left, event cards in the middle, and ops summary on the right (!2329)
- Ops summary input now uses a textarea with multi-line support, locks 1.5s after typing stops, and the autosave countdown was removed from the UI (!2329)
- Crew size colors on schedule cards restored by adding minimal charge data back to the
CalendarEventForDispatchfragment (!2326, !2331, !2332) - Auto-assign crew from sibling events disabled due to a Cypher variable scope bug that could assign crew to the wrong event (!2327, closes #6847)
roles.listresponse handling fixed — was readingroles.nodeson a plain array, breaking permissions for every x-zone request (!2328, closes #6852)- Calendar event creation now parses stringified metadata to an object before AJV validation, matching the bulk-edit path (!2319, closes #6808, closes #6812)
- Transaction deletion no longer silently skips records when deleting multiple or when soft-deleted transactions are in the list (!2319, closes #6810, closes #6811, closes #6813)
- Admin users can now edit and delete comments owned by other users — the in-memory permission graph’s
overrideOwnershiprestriction is now merged into the branding query (!2320) - Interstate zone context resolution fixed — users with multiple area roles now context into the job’s owning franchise instead of falling back to the first zone (!2321, closes #6815, closes #6819, closes #6820, closes #6822)
Other
- Codegen rerun for the
CalendarEventForDispatchfragment change and resulting type adjustments across the frontend (!2331)
v2609.02.0 — September 2, 2026
MRs: !2313, !2304, !2318, !2317, !2312, !2314, !2316, !2315, !2308, !2243
Highlights
Dispatch Overhaul — table layout, autosave, and per-event crew (!2313) The dispatch board has been redesigned as a table layout with route rows, crew drop zones, and mini event cards. Crew can now be dragged between routes and assigned to individual events. A push-model save/discard flow with localStorage persistence replaces the old immediate-save pattern, plus an autosave toggle that debounces 5 seconds after the last edit with a visible countdown timer. Dispatch-only events (ops, reserve, admin) are now first-class events instead of comments, and special blocks can be created, edited, and time-adjusted inline.
New Home page with reorderable cards (!2304) A personalized home page replaces the old landing experience. Cards for Quick Links, Dashboards, Help & Support, Recent Jobs, and Latest Releases can be dragged to reorder, toggled on/off via a gear menu, and persist to localStorage. The dashboards directory and business page have also been reworked with a searchable, categorized icon grid and breadcrumb picker.
Dashboards and Take Payment now gated by permissions (!2318, !2317)
Dashboards are now visible based on role permission and zone type — five new permission keys (dashboard.revenue, dashboard.engine, dashboard.salesLeaderboard, dashboard.opsReadiness, dashboard.systemRevenue) control access. The Take Payment button on the job financials tab is now shown only when the zone has a payment processor enabled and the user holds the payment permission.
Features
- Infeasible worker assignments now return a human-readable reason instead of a bare “no solution” — the optimizer surfaces why a crew cannot be assigned (!2243)
Fixes
- Customer billing address and profile edits are now saved correctly when a lead is created — the “Use end location as billing address” checkbox no longer silently drops the address, and subsequent edits to an existing customer are preserved (!2312)
- Interstate jobs that are shared with a user’s zone now resolve the correct context zone instead of falling back to the first zone in the user’s list, fixing “Cannot find job” errors for users with multiple area roles (!2314, closes #6797)
- Sales leaderboard now shows agents with only future/scheduled events in the selected period, instead of excluding them for having zero completed events (!2316)
- MCP reports can now read the 6 Ops Readiness checklist fields (Inventory OK, Ops OK, Truck OK, Crew OK, Labor OK, Welcome OK) via
dataColumnsinstead of always reporting “Ops Readiness Not Complete” (!2315) - Aegis documents now notify the creator (and zone watchers) by email when a document is fully signed, restoring the PandaDoc behaviour that was lost in the migration (!2308)
- Abandoned and answered inbound calls no longer create stray leads in the wrong zone — calls are now routed by their target ID (!6411 routing fix, closes #6411)
Other
- Large backend/frontend cleanup branch merged: removed deprecated scripts (pandadoc-screenshots, es-jobs-load, es-search-test), the
calendarEvents.updateNavigatorservice,Scriptnode model, and dead config defaults (~106k lines removed)
v2609.01.0 — September 1, 2026
MRs: !2303, !2305, !2306, !2307, !2309, !2310, !2311
Highlights
BlueSage terminal payments — Phase A + B (!2303) You Move Me franchises can now take card payments through BlueSage terminals. The full flow is live: a terminal picker and push panel, keyed-in card fields, cards on file, payment and refund dialogs, authorization release, dual-pricing rate display, an event replay sweep for reconciliation, and refund handling with amounts, reasons, and authorisation tracking. The job financials panel re-reads itself while BlueSage settles, so the job always reflects the money that actually moved.
PandaDoc document creation gated behind opt-in config (!2307, hotfix)
PandaDoc’s prepaid $0.12/document plan was not renewed, so creating a document now consumes a $2 API credit the plan grants zero of. Document creation is now blocked by default via a per-zone pandadoc.documentCreationEnabled config (default false); zones that still need PandaDoc for a docType without an Aegis template can toggle it on temporarily. A latent bug that would have turned a receipt-generation failure into a payment-endpoint error was also fixed.
Aegis tables now split to fill the page (!2310) A customer’s Calgary estimate printed the job details on page 1 and left the rest blank because the charges table missed fitting by ~1.6px. Tables now measure the room left on the page and split when they would overflow, so content fills each sheet instead of jumping to the next.
Job summary edits now recorded in history (!2311, closes #6494) Editing a job’s customer, admin, or crew summary left no trace. Summary edits are now diffed server-side against the loaded job state and written as history items, so every summary change is auditable.
Fixes
- Global search no longer shows stale results when a second query’s response arrives out of order — the shared watchQuery/refetch pattern is replaced with a switchMap that drops in-flight requests on new input (!2305)
- AI no longer stops when it calls a non-existent function, and Yembo inventory item names are now visible to AI for complete summaries (!2309, closes #6792)
- NSC calculator now uses max labour hours instead of min for labour charges (!2306, closes #6678)
Other
- PandaDoc receipt generation in
transactions.create/transactions.updateis now guarded so a receipt failure cannot fail the payment itself (!2307)