All releases
August 2026 August 2026

August 2026 Updates

Aegis gains a MoveBuddha inventory document, intake forms support late-mounted SPA containers, and a new 3001.5 calendar-events report adds the Estimator column.

Newsletter status: In progress. See README.md for conversion guide.

v2608.14.0 — August 14, 2026

MRs: !2255, !2254, !2252, !2251, !2250, !2249, !2246, !2245

Highlights

Rule-triggered emails now go only to the roles the rule specifies (!2246) Previously, send-email-to-job rules were emailing every user on the job — customer, estimator, sales agent, and crew — regardless of the rule’s to field. Staff were receiving customer-facing emails (addressed to the customer), and unsubscribing, which also dropped their internal job notifications. Emails now respect the to recipients the rule names. This affected 452 rules across 27 zones, with 50–74% of daily rule-email volume going to staff addresses.

Charge values are now saved as whole cents, preventing job page load failures (!2245, closes #6647) Certain price/quantity combinations produced fractional-cent values (e.g. 100.00000000001) that violated the GraphQL integer schema, making jobs inaccessible and breaking job lists. Rounding is now applied consistently on charge creation, updates, and expense-total serialization, including a read-side fix for jobs saved before this change.

Performance

  • Archive job queue query rewritten to eliminate a CartesianProduct that caused 20M+ dbhits and 5+ minute queries in production — now ~140ms total across two split queries, with Bull stalledInterval raised to 10min to prevent duplicate execution across pods (!2252)

Features

  • Flat-price jobs can now select from different flat-price types, with calculator behaviour adapting to the chosen FP type (!2254, closes #6620)
  • Invoice numbers are now included on YMM invoices (!2255, closes #6666)
  • Snoball Zapier payload now includes customer zip code and sales rep name; estimator name is used as the sales rep (!2244)
  • mr scripts CLI commands added — list, inspect, create, update, run, delete, and view execution logs; script code limit raised to 250,000 characters (!2249)

Fixes

  • Script fetch() host function was failing with HTTP 0 Invalid IP address: undefined on Node.js 20+ — pinned DNS agent lookup callback now handles the { all: true } option (!2250)
  • QuickJS pending jobs were not pumped after async hook callbacks, causing await fetch() in hooks to silently never complete — runner now drains pending jobs before VM disposal (!2249)
  • Script zone matching now uses neoFilterObjectByZonesV2 (parents array) instead of the stale children array; tag service calls corrected to use the right service name and parameters (!2251)

Other

  • functions/version.txt set to 2608.14.0 to ship updated calculator scripts and Snoball payload changes to Cloudflare R2 via deploy-functions (!2254, !2244)

v2608.11.0 — August 11, 2026

MRs: !2244, !2241, !2238, !2236, !2235, !2233

Highlights

Snoball referral integration is live for the YMM-Toledo pilot (!2244) Completed moves now automatically post to Snoball’s Zapier webhook so Snoball can trigger referral outreach (SMS/email asking past customers to refer friends). When a Snoball-referred job is invoiced, a payout event is sent so Snoball can pay the referrer. Both flows are idempotent — a reserve-then-confirm tag pattern and a deterministic event ID prevent double-posts from concurrent or replayed executions. The webhook URL is configured per zone via snoball.webhookUrl (no hardcoded default).

Features

  • New S-One moving calculator with full quote generation, packing services, valuation options, and storage calculations (!2238)
  • S-One estimate template for Aegis document rendering (!2238)
  • Standard moving contract template for Aegis — a signable contract document for booked moves (!2236)
  • Weight and volume per item now displayed in the inventory standard template (!2233)

Fixes

  • Rule-triggered emails were sending to all roles on the job instead of only the roles named in the rule action — emails now go only to the specified recipients (!2241)
  • Charge calculations were producing broken floating-point numbers (e.g. 100.00000000001) due to missing rounding in create/update paths — rounding is now applied consistently across charge creation, updates, and expense-total calculations (!2235)

Other

  • functions/version.txt set to 2608.11.0 to ship the Snoball script, S-One calculator, and new templates to Cloudflare R2 via deploy-functions (!2244, !2238, !2236)

v2608.06.0 — August 6, 2026

MRs: !2234, !2235, !2231, !2227

Highlights

Aegis invoices no longer overlap signature fields when the charges table is long (!2234) Generating an invoice for a job with many events and charges produced a PDF where the charges table ran past the page edge and painted over the signature fields below it. The shared paginator now splits oversized tables at row boundaries, so a table that doesn’t fit on one sheet flows onto the next page instead of overflowing. The fix applies to all 7 Aegis invoice templates that have both a charges table and signature fields.

Fixes

  • Yembo inventory was not syncing to Move Right when yemboMoveCreatorId was missing (common for VOSE booked from intake at the moment the Yembo event arrives, before employees are assigned) — the early return is removed so artifacts upload with system as the author and inventory updates proceed regardless (!2235, closes #6628)
  • intake.virtualEstimators set to an empty [] was doing two contradictory jobs: the availability endpoint read it as “no filter → every estimator” while the intake form read it as “skip VOSE entirely,” so zones with no estimators configured still got virtual estimates booked against arbitrary Estimator assets — the layers now agree and VOSE is skipped when no estimators are configured (!2231, closes #6619)
  • Vancouver OBE leads were being misrouted to Lehigh Valley because area-code casing wasn’t normalized before the service-area lookup — area codes are now lower-cased, and address parsing for Canadian postal codes, US ZIP codes, highways, and civic numbers is improved (!2227, closes #6602, closes #6608)

Other

  • Aegis bumped to 0.1.18 (row-level table pagination in the shared paginator) — published via the hotfix merge (!2234)

v2608.05.0 — August 5, 2026

MRs: !2226, !2229, !2232

Highlights

MoveBuddha inventory documents now render in Aegis (!2226) Aegis can produce a branded, paginated inventory document from job data — itemized by room with job details, locations, totals, and free-text notes. Large rooms flow to continuation blocks so nothing overflows the page, empty inventories show a fallback message, and blank dates fall back to YYYY-MM-DD instead of printing a raw ISO string. The new inventory doc type resolves without a PandaDoc template ID, so franchises that never configured PandaDoc inventory can still generate one. A __name shim in the render harness lets esbuild-paginated PDF checks run in the browser without errors.

Intake form now supports late-mounted SPA containers (!2232) Sites that mount the MoveRight intake container after the script loads (e.g. single-page apps that render the form on navigation) previously got a silent no-op. The loader now exposes MoveRightIntake.init() for explicit initialization after late mounting while preserving automatic init on normal page loads, and calling init() repeatedly is safe — no duplicate forms. A standalone test page documents and verifies the late-mount/duplicate-prevention sequence.

Features

  • New system report 3001.5 Calendar Events With Sales Agent and Estimator — a variation of 3001.4 that adds an Estimator column next to Sales Agent, using the same estimator-resolution logic and the same filters/period/aggregations (!2229)
  • inventory Aegis document type with zone-configurable activation, metadata, validation, and accent colors; the documents modal keys template lookups on the config key so Aegis-only doc types resolve without a PandaDoc templateId (!2226)
  • MoveRightIntake.init() browser global for explicit intake initialization after late mounting, with repeatable/duplicate-safe invocation (!2232)

Fixes

  • documents-modal template lookup keyed on templateId failed to resolve Aegis-only doc types (no PandaDoc template) — now keyed on the config key (!2226)
  • Aegis documents printed a raw ISO string when a date field was blank; blank dates now fall back to YYYY-MM-DD (!2226)
  • esbuild’s __name helper threw in the browser-rendered PDF pagination harness; a shim restores it so serialized pagination runs cleanly (!2226)
  • 3001.5’s Event Type Summary aggregation keyed on a non-existent createdAt, producing an empty summary; corrected to eventCreatedAt so buckets populate (!2229)
  • Inventory document dropped the internal-use line and consolidated the customer name rendering (!2226)

Other

  • Aegis bumped to 0.1.17 (new inventory template + render-harness __name shim) (!2226)
  • Intake bumped to 2608.05.0 (SPA init() support, test page, vite config for the MoveRightIntake global) (!2232)
  • functions/version.txt set to 2608.05.0 to ship the inventory template to Cloudflare R2 via deploy-functions (!2226)
  • hotfix: deploy functions 2607.31 to R2 (!2225) shipped the prior release’s R2 functions after the 2607.31.0 release commit skipped functions/version.txt; superseded by this release’s functions bump