This is the running history of changes we've shipped to ZiplineOS. Each entry leads with the headline changes as quick dot points; open Technical details at the foot of a release for the full breakdown.
Edit forms straight from a workflow tile, safer SSO invites, and more groundwork on contact financials
This release lets you open and edit a form without ever leaving the Workflow Builder, makes inviting a new team member who signs in with Google or Microsoft more reliable, and keeps building toward a unified financial view on the contact profile — still not switched on for any organisation.
Workflows (Input Hub)
- New: edit a form straight from its workflow tile — every form tile in a workflow now has an Edit form button that opens the form builder in a slide-out panel, so you can tweak fields and publish without leaving the workflow page. Closing with unsaved changes prompts you to keep editing or discard.
Admin
- New: choose a sign-in method when inviting a team member — the Add User screen now has a Sign-in Method selector, defaulting to SSO, so a teammate who only ever signs in with Google or Microsoft won't hit an "account already exists" error the first time they log in.
Security and reliability (behind the scenes)
- Hardened the invite sign-in flow so a new account can only be linked to an invited teammate once its email address is verified, closing a narrow window where an unverified sign-up could have inherited someone else's pending invite.
- Continued building the unified financial view on the contact profile — a broker can now add or amend a client's income, assets, liabilities and living expenses by hand from the contact screen, and a new deal can prefill its Fact Find from the client's most recent financial position — still behind the scenes and not yet switched on for any organisation.
- Laid the groundwork for real GCP billing figures on the Kernel Cloud Resources page (still showing the labelled-resource estimate for now).
Technical details
- SSO-first invites: a transient
LoginMethodon the create-user path skips minting a Firebase password account for an SSO invite, returning afirebase-pending-*placeholder UID instead;UserProvisioningMiddlewarerelinks the placeholder to the user's real Firebase UID on their first SSO sign-in (#3054). - New SuperAdmin-only maintenance sweep,
POST /api/v1/admin/maintenance/convert-password-users-to-sso(dry-run by default), converts the existing population of invited-but-never-signed-in password accounts to SSO-first, with per-user error isolation and a re-check immediately before any destructive Firebase credential delete (#3054). - Auth hardening: by-email identity linking in
SessionServiceandUserProvisioningMiddlewarenow requires the token'semail_verifiedclaim (or an already-matching CognitoSub), closing a path where an unverified email/password self-registration could have assumed a pending invite's org membership and role (James review, #3054). - Terraform: provisioned the prod
billing_exportBigQuery dataset andzipline-api-prodservice-account grants for the Cloud Resources real-billing path; fixed a permanent Terraform plan drift on the staging SLO monitoring dashboard (#3054). - Contact 360: new
UpsertContactFinancialItemCommand(POST /api/v1/contacts/{id}/financial/items, Manage-gated) for manual add/amend of a contact's financial items with broker provenance;ContactFactfindPrefillServiceseeds a new deal's Fact Find from the applicant-contact's most recent prior-deal Fact Find, verbatim, behind the dark per-orgdeal_prefill_from_contactflag (#3021). - Input Hub: new
FormEditorPulloutslide-out editor backed by a locked-down/forms/:id/embedroute;FormBuilderPagegained an embedded mode with a save-first publish gate and a postMessage close/publish-close contract with the parent workflow page (#3052).
Bind PDF placeholders straight to your fields, tick checkboxes from an answer, and a faster template editor
This release finishes off the PDF template editor's placeholder workflow: you can now bind a scaffolded placeholder to a field with a click, tick a checkbox automatically from a client's answer, and work through large forms without the lag that used to follow every click. We've also fixed a save-blocking error in the template editor and a display glitch in the "What's New" announcements.
Documents and PDFs (Input Hub)
- Fixed: a placeholder created by auto-detecting fields on a PDF template couldn't be bound to a field from the field picker — you had to delete it and re-add a field by hand instead. Selecting the placeholder and clicking a field in the picker now binds it directly, with a new Rebind option if you need to change it later.
- New: data-bound checkboxes — a checkbox on a PDF template can now be tied to a client's answer (for example, a Purchase / Refinance / Construction pick-one row) and will tick itself automatically when the document is generated, rather than only ever being tickable by hand.
- Fixed: selecting a placeholder in the field picker on a large, shared form (thousands of fields) could take several seconds to respond — collapsed groups no longer render their contents in the background while closed.
- Fixed: saving a PDF template annotation could fail outright with a server error if the bound field's path, type or label was long.
Product-wide
- Fixed: the "What's New" release announcements could show their Later/Previous/Next buttons pushed off-screen, or resize awkwardly between updates, when there were a lot of unread releases.
Security and reliability (behind the scenes)
- Continued building the automations "fire path": the message an automation sends now adjusts what it's allowed to name (deal, product) depending on whether the recipient is inside your organisation or an outside party such as a delegate — still not switched on for any account.
Technical details
- PDF field-picker binding:
handleAddFieldnow routes a picker click to the selected placeholder annotation whilecapturesFieldClick()reports it unresolved, binding FieldPath/Label/DataType; a new "Rebind" clears FieldPath to re-arm capture; fixedbindingStatusForso hand-placed FORM_CONTROLS annotations (Textbox/Checkbox/Signature/Date, which always carry an empty FieldPath) stop being treated as unbound placeholders (#3023). - Data-bound checkboxes: new
CheckedWhenValuecolumn on annotation tables plusCheckboxBindingEvaluator(case-insensitive/trimmed match, MultiSelect-JSON-array membership aware); a blankCheckedWhenValuemeans "tick when truthy" for Checkbox/YesNo answers (#3024). - Field picker perf: MUI Accordion's
Collapseno longer stays mounted for closed groups across the picker's seven accordions, removing thousands of liveListItemButtons from the DOM on large shared forms (#3029). PdfTemplateAnnotations.FieldPath/Type/Labelwidened fromvarchar(100)/varchar(50)/varchar(200)totext, fixing a model/database drift that predated the 2026-07-13 baseline squash and caused a 500 on save (#3038).ReleaseNotesWidget: more than 8 unread notes now render a compact progress bar + "X of N" instead of a 50-dot strip; the footer button group is pinned so it can't be clipped, and the modal uses a fixed height with inner scroll instead of resizing per note (#3041).- Kernel: a new opt-in
BypassCeilingflag on the tenant feature-grant override commands lets a super-admin pilot a feature above an organisation's licence/tier ceiling; fails closed unless the caller is a super-admin (#3041). - Automations: token audience (
{{deal_name}}and similar) is now derived from the resolved recipient's internal/external status rather than authored, backed by a full recipient-resolution, suppression, rendering and transport pipeline; still behind the darkINPUT.automationsflag (#3020).
A new Getting Started checklist, more accurate deal PDFs, and a broad reliability sweep across Input Hub and Collect
This release adds a Getting Started checklist to guide new team members through setup, makes deal PDFs render form answers and discovery card decks accurately, and gives organisations waiting on a dedicated SMS number an honest status instead of a vague "under review". Underneath, we've closed a run of data-loss and completion bugs in Input Hub and Collect, made reinstalling a workflow or form template pack safe to repeat, opened four more apps to every organisation regardless of billing tier, fixed a cross-tenant PDF data leak, and continued laying groundwork for automations and a unified contact financial view — both still switched off for every account.
Deals and workflows (Input Hub)
- A new Getting Started checklist — a progress ring in the navigation rail walks every team member through initial setup (connect your email, add branding, publish a Fact Find, create your first deal), with admin-only steps hidden from regular members and a "don't show again" option.
- Reinstalling or reinstating a previously removed workflow or form template pack no longer creates duplicates or disrupts deals already in progress; setup also gains a new Disclaimer Consent step for editing the privacy wording, checkbox label and scroll-to-accept requirement.
- Fixed: text typed into a field on an inline repeatable form (e.g. Liabilities, Private Health Insurance) could be silently lost if another field's save triggered a background reload before you clicked away.
- Fixed: editing a record through the drawer view could leave the inline list showing stale data until the page was reloaded.
- Fixed: a required form item with no fields of its own (e.g. "Income and Expenses") could never be marked complete, permanently blocking a deal from progressing.
- Fixed: a repeating section could be marked complete even though a newly added entry still had required fields left blank.
- Fixed: the order of questions could drift between the form builder and what was actually submitted, when two questions ended up sharing the same position — drag-to-reorder now reliably sticks.
Client intake (Collect)
- Fixed: Fact Find summary cards could show raw placeholder text instead of the real answer.
- Fixed: a Property asset could ask for its liability type before you'd said whether the property was owner-occupied or rented.
- Fixed: the shortcut that auto-fills a matching liability from an asset (e.g. a car loan appearing after a vehicle) only worked when a broker filled the form on a client's behalf — it now works the same way when applicants fill in Collect themselves.
Documents and PDFs
- Deal PDFs now render form answers faithfully — numbers show thousands separators, dropdown and lookup answers show their real label instead of an internal code, and property/asset-linked questions are grouped together under a clear heading.
- Fixed: a discovery card deck (swipe-style Yes/No questions) still in progress was left out of the PDF entirely; it now appears, captioned with how many cards have been kept so far.
- Fixed: an abandoned card deck could be wrongly marked complete, which then replayed the whole set from the first card the next time it was reopened.
- Fixed: broker-facing card thumbnails that failed to load now retry automatically instead of staying blank until the page was reloaded.
Protocol
- Requesting a dedicated SMS number now shows an honest status — "submitted" while ZiplineOS is preparing it, "pending" once it's with the carrier — instead of a vague "under review" that could sit unchanged for over a week with no visibility.
Admin and billing
- Broadcast, Telemetry, Logic and Protocol are now available to every organisation, regardless of subscription tier — access is controlled purely by your admin's feature-grant settings, not billing.
- Fixed: the admin Users page could wrongly tell an admin that a correctly assigned user "isn't assigned to an organisation yet".
- The catalog packs page in Kernel now shows published template packs alongside drafts.
Security and reliability (behind the scenes)
- Fixed a cross-tenant data leak where a dropdown or lookup answer on a deal PDF could show another organisation's list label.
- Fixed: a Gmail user invited to an organisation under a dotted or aliased address (e.g.
j.smith@gmail.comvsjsmith@gmail.com) could fail to be recognised as invited and end up auto-provisioned into the wrong organisation. - Began building a unified financial view on the contact profile — income, assets, liabilities and living expenses pulled automatically from submitted Fact Finds — not yet switched on for any organisation.
- Continued building the "fire path" for scheduled, rule-driven automations on a deal or workflow — still not switched on for any account.
- Invested in behind-the-scenes reliability monitoring — structured request logging and new service-level uptime checks — with PII kept out of the logs by design.
Technical details
- Form-field/workflow ordering: new
FormFieldOrderNormalizerenforces a dense-uniqueOrderon add/delete/duplicate;(Order, Id)tie-break added to every read path, including the versioning canonical tree (WorkflowSchema.Walk); idempotentNormalizeFormFieldOrdersSuperAdmin backfill command (#3000). - Fact Find/Collect data fidelity:
resolveTilenow resolves merge fields on chip labels viaFieldMeta.options; an AND-of-ORs visibility gate was added toowe_any_money; the asset→liability context-inheritance resolver moved into@zipline/shared-uiso input-portal and Collect share one implementation instead of diverging (#3001). - Deal-PDF fidelity: new
BuildFormItemSectionextraction andRenderRichFallbackraw-JSON safety net;WorkflowItem.IncludeInPdfnow defaults on (migration-backfilled); Subject-member forms grouped under anIsInternalOnly-aware heading; Autocomplete/LookupList resolution now scoped to org-owned or system-managed lists only, closing a cross-tenant label leak (#3005). - Card decks:
DealPdfCardDeckResolverrenders in-progress decks with a newIsCompleteflag;DetermineStatusAsyncgates CardDeck completion onWorkflowItemType.CardDeckrather than payload key-sniffing;CardDeckResponsePanelretries a failed thumbnail load via remount (#3017). - Catalog reinstall idempotency:
InstallTemplatePackHandlerreworked for reuse-in-place — soft-deleted workflow/step/item/role/form rows are revived by matching Name/CatalogPackId, and form fields are reconciled by Key instead of hard-delete-and-rebuild, avoiding a cascade that dropped the field's search index; round-trips 11 previously-lostFormFieldproperties; new dev-timeWorkflowRepoPackExportGeneratorregenerates committed catalog packs from a live org workflow (#2998). - Input Hub QA fixes: FormFiller now tracks a dirty flag and flushes on unmount with an in-flight-save guard; the
initialDatamerge respects that flag;DetermineStatusAsyncdescends into nested-form instances to validate required sub-fields on staff submissions (#3009). - Getting Started checklist: new
GET /api/v1/onboarding/checklistquery;GettingStartedPill/GettingStartedPanelmounted in the shell nav rail with role-aware task filtering (#3010). - Billing:
FeatureGrantService.GetActiveTierSortOrderAsyncshort-circuits theTierUnavailablebranch for a base-platform app allowlist, joining Broadcast/Telemetry/Logic/Protocol to the existing four Basic apps; seat-license and telemetry-source gating are untouched (#3011). - User↔org attribution: shared
HydrateUserOrganizationsAsynchelper ports the existing list-endpoint fix to the singularGET/PUT /users/{id}endpoints; JIT session provisioning gains the same Gmail dot/alias normalization the invite-acceptance path already had (#3019). - Protocol SMS queue: new admin "SMS Numbers" operator page and
ListRegulatoryBundlesQuery; provisioning state split intosubmitted/pending(#3004). - Catalog admin: the admin packs page merges published
CatalogWorkflowPackrows with drafts by slug; the input-portal Template Library drops standalone form browsing now that installing a workflow auto-installs its required forms (#3018). - Contact financial model: new append-only, RLS-policied
ContactFinancialEntryentity and code-ownedFinancialModelCatalog; real-time submit-gated write-through with identity-key dedup/versioning; retires the unused AI "living profile" and legacy flexible financial-position tables; ships behind a darkcontact_financialROLODEX feature flag (Verbs=0 across every role and tier) (#2905). - Automations fire path: new
IAutomationAction/AutomationActionRegistry,AutomationScheduler(claim-before-create dedup), andAutomationFireServicetwo-part re-validation (condition fails open, action liveness check fails closed); gated by a darkINPUT.automationsfeature flag (#2976). - Observability: structured GCP JSON logging, Cloud Trace correlation, and PII-safe request enrichment; new SLO/uptime Terraform modules, staging-wired but not yet applied to production; plus a metric-extractor regex fix and a per-deploy Terraform drift-gate with Mailgun credentials moved to Secret Manager (#3003, #3012, #3013).
Deal emails now send from your own inbox, a friendlier first step, and a workflow reliability sweep
This release changes what a client sees when a deal or input email lands in their inbox — it now comes from the broker's own connected mailbox with their signature, not a generic sender. Signing up now asks for your name so team invites greet people properly, and the admin Users list shows when someone was last active. Underneath, we've closed a long run of reliability fixes across scheduled reminders, workflow automation and Collect's co-applicant flow, plus a batch of NDIS-specific fixes covering phone numbers, PDF text and quote assignment notices.
Deals and workflows (Input Hub)
- Client emails now send from your own inbox — deal and input emails (magic links, co-applicant invites, reminders, delegate invites) now send from the deal owner's own connected mailbox where one exists, with their email signature appended, falling back to your organisation's verified sending domain otherwise.
- New rule-builder date aggregates — a workflow rule can now compare against the "Earliest of" or "Latest of" a set of dates across repeated form instances, e.g. gating on less than three years of address history.
- Fixed: a scheduled reminder anchored to a date a client answered on a form (e.g. "30 days before the policy expires") could fire on a stale date, or keep firing after the client cleared the date entirely, if the answer changed after the reminder was first scheduled.
- Fixed: editing a workflow item's Subject or Summary configuration could silently discard settings like the delegation reminder schedule or PDF pack, even though the page reported a successful save.
- Removed "Update Deal Field" from the workflow action picker — it was never actually implemented by the platform and was recording failures in tenants' activity feeds for authors who used it.
- Fixed: a delegate invited to complete part of a deal could keep receiving chase-up reminders after the deal was actually finished.
Client intake (Collect)
- Fixed: a primary applicant filling in a co-applicant's fact-find on their behalf (or where the invite/proxy choice was left undecided) could get permanently routed through the co-applicant's forms and never reach the finish screen.
- Fixed: a required money-amount slider showed its minimum value as if it were already filled in, so a step could look complete when nothing had actually been chosen — it now prompts "Select an amount" until touched.
- Fixed: a conditional option on a question (e.g. showing older vehicle years once "Used" is selected) could stay hidden if the condition depended on another answer on the same form.
- Fixed: an Australian service number (13xx, 1300, 1800) typed into a phone field was silently rejected and dropped with no error shown; a refused answer is now reported back so nothing is lost quietly.
Account and onboarding
- A friendlier first step — signing up now asks for your name alongside your company name, so team invites you send greet people by name instead of your raw email address.
- Fixed: connecting an Outlook/Microsoft mailbox could report success but silently fail to send any mail.
Admin
- The platform Users list now shows each user's last-active time.
Security and reliability (behind the scenes)
- Closed a crash risk where an oversized phone number submitted through Collect could take down the whole server process.
- Fixed a run of scheduled-reminder bugs: reminders could be dropped or double-sent by the delivery relay, a delegate's reminder could fail to appear on its own deal page, and a reminder could keep firing on a deal that no longer needed it.
- Fixed: generated PDFs (NDIS quotes and deal exports) could contain an invisible corrupted character wherever the letters "ti" appeared together, breaking copy-paste, search and screen readers.
- Began laying groundwork for scheduled, rule-driven automations on a deal or workflow — not yet switched on for any account.
Technical details
- Deal/input sender identity: new
IDealEmailSender/SenderDisplayNamePolicy/DealSenderFallbackAddresschokepoint routes magic-link, co-applicant, reminder, welcome and fill-grant invite emails through the deal owner's OAuth mailbox → org connection → Mailgun fallback chain, appending the owner's signature;CreateDealCommand/UpdateDealCommandnow validateAssignedToUserIdis a member of the deal's org before it can be used as a sender identity (#2987). - Rule builder EARLIEST/LATEST date aggregates:
RuleEvaluatorreduces per-instance date fields to min/max, returning a comparable date for the relative-date operator layer;RuleEngineCatalogand the committeddocs/data/rules-cascade-matrix.mdregenerated to match (#2985). - formField-anchored scheduled delays:
ResolveFormFieldDatenow actually loadsDeal.Submissions(previously always empty, silently falling back toCreatedAt) and resolves viaMergeFieldResolver's scope/instance grammar; a new submit-path guard rebuilds an armed delay when its anchor answer changes, refusing ambiguous matches as a visibleFailedmarker rather than swallowing them (#2972, #2973). - Item editor Subject/Summary config:
decideSubjectConfigSave/decideSummaryConfigSavenow distinguish "nothing authored" (omit), "authored" (persist), and "emptied after being authored" (refuse the save and say why), closing a path where a reminder ladder or PDF pack could be silently dropped or reverted despite a "saved successfully" banner (#2961). WorkflowEngineno longer reports a phantomSuccessfor an item/action type it has no handler for (CarryForward/Checklist/ResultsDisplay/updateDealField); such items are now skipped rather than recorded as failed,Checklistcompletion is driven by its ownDealChecklistItemsrows instead of the removed phantom-success signal, andmovedToStepDatenow anchors onDealStageHistoryinstead ofDeal.ModifiedAt, which moved on any edit to the deal (#2962).DealDelegationLifecyclesplitsIsFinished(suppress unattended reminder chase) fromDelegateAccessIsClosed(revoke the link) — a delegate's own final submit on a Won-stage workflow no longer 404s their remaining co-delegates (#2963).DealComplianceTriggerNotificationrenamed toDealChangedNotificationand moved out ofFeatures/Compliance; carriesWorkflowStageTypeinstead of the never-writtenDealStatus.Won/Lost; adds the missingdocument_finalizedpublish;IsolatedNotificationPublisherreplaces MediatR's default so one failing consumer can no longer silently suppress a compliance evaluation (#2968).DataSyncService(Mystro sync) now publishes this notification on status/step-changing upserts, closing a gap where no org on Mystro sync had ever re-evaluated compliance rules on a synced transition (#2970, #2989).ScheduledEventRelay's promote/retry/dead-letter passes made structurally disjoint (one frozennow, all three pages read before any writes) to stop an overdue reminder being dispatched and dead-lettered in the same cycle, or double-dispatched (#2967). FillGrant/meeting reminder cancellation re-keyed onto the event'sSourcerather than itsContext, so a delegation or meeting reminder now appears on its own deal's scheduled-events feed (#2965). All scheduled-event Cloud Task bodies now route through oneScheduledEventDispatchhelper — the direct-enqueue path had never actually delivered; both reminder ladders only worked because the relay's 60-second sweep silently re-enqueued them (#2897, #2958).- Collect proxy-applicant routing:
primaryNonBlockingApplicantIds()drivespickDestinationand the forward navigator so a co-applicant's proxy/undecided work never blocks the primary;CollectCompletionViewoffers both "complete their details" and "invite them" for proxy/undecided co-applicants (#2996). - MoneySlider gains a "Select an amount" prompt (contrast-checked) and a keyboard-operable tap-to-type editor for the unanswered state (#2983).
- Field-option cross-form/
thisFormshowWhen: theRuleFormReferenceRewriterexport/import pass now walksfield.Optionsas well asRules;RuleEvaluator's option-visibility path is unified with field visibility and madethisForm-aware, so a same-form conditional option is no longer stripped before the client can evaluate it (#2983). - NDIS/phone fix batch:
AuPhoneNumber/AuAnyRegexgain a 13xx/1300/1800 service-number branch mirrored across the C# validator, the TS twin and the CSV-import/backfill SQL;StripPhoneNoise's stack allocation is bounded to a fixed 64-char span with a heap fallback, closing aStackOverflowExceptioncrash reachable from the anonymous Collect submit endpoint;ClientSubmitFormCommandnow returnsrefusedFieldsso a server-side validation refusal is surfaced to the applicant instead of silently reverting the item toInProgress; the bundled PDF font's "ti" ligature was emitting a NULToUnicodemapping that corrupted extracted/copy-pasted/screen-read text in both the NDIS quote and deal-export PDFs, fixed via a sharedTextStyle.ExtractableText()helper; NDIS quote funding-type fields marked required (a quote could otherwise price to $0 with no error); assignment notices (clinician distance, override, preference mismatch) moved into their own PDF panel with corrected labels; the kernel tenant-override matrix no longer disables an override on a zero-ceiling global grant (#2943). - Onboarding:
SubmitOnboardingQuestionnaireCommandcapturesFirstName/LastNameon step 0, which is whatCreateInvitationCommand's inviter-name greeting is read from (#2995). - Admin:
User.LastActiveAtstamped on session create and via a throttledUserActivityHeartbeatMiddleware(SuperAdmin-fenced, impersonation-safe), surfaced as a sortable column on the admin Users table (#2997). - Outlook/Microsoft OAuth scope widened to include
Mail.ReadWrite— Graph's create-then-send flow was being denied at the create-draft step; Gmail/Outlook profile names now backfill a blankUser.FirstName/LastNameon connect (#2986). - Guidance:
UserGuidanceStepEventper-step dwell tracking, aGuidanceEngagementclassifier, and an admin Guides/Onboarding view with reset, plus a spotlight-circle tour option and a shell/input-portal tour copy pass (#2984, #2978). - Automations primitive: new
ITenantScopedAutomations/AutomationRunstables (scope-enum + per-scope FK, SQL-queryable trigger/recipient columns, per-fire outcome/dedup/cap record) — schema and RLS only, no fire path yet (#2974).
A rebuilt AU Mortgage Fact Find, guided onboarding for new teams, and NDIS support quoting
This is a big one. The AU Mortgage Fact Find had started throwing an outright error for some organisations — it's rebuilt from the ground up as a leaner four-stage form that works end to end. New organisations now get a proper guided start: first-visit walkthroughs, a step to invite your team and choose starter workflows during setup, and an automatically generated web address. Nested forms can now inherit an answer from an earlier question instead of asking twice, and organisations running NDIS support coordination get a purpose-built quoting workflow. Underneath all of that is a large batch of reliability fixes across Collect and the form builder, and several tenant-isolation and access-control gaps closed.
Forms
- The AU Mortgage Fact Find is fixed and rebuilt — the form had started returning a hard error for some organisations, making it impossible to complete. It's now a leaner four-stage fact find with plainer wording, the guarantor role removed, household expenses shared across applicants instead of duplicated, and clearer conditional document requests.
- New: AU commercial low-doc / alt-doc fact-find pack — a ready-to-install template for commercial lending fact finds, covering business-purpose declarations, self-certified income with tiered evidence, entity borrowers and ATO-debt disclosure.
- Inherited field values in nested forms — a question inside a nested or repeatable form (for example a liability's asset type) can now automatically pull its value from an earlier answer, either locked (read-only once resolved) or pre-filled (seeded once, never overwriting your own edit), with support for more than one source in a set order.
- Type-aware default values — form authors can now see and set a real default value for a field directly in the builder, instead of an invisible inherited value showing up with no explanation.
- Fixed: a required checkbox question with more than one option could silently lose its answer on save, leaving the step permanently incomplete.
- Fixed: currency fields across the platform now reject negative amounts and cap at $1 trillion, and no longer misbehave while you're typing.
- Fixed: a required repeating group (e.g. "Employment Income") showed a contradictory "Optional" caption even though at least one entry was required to continue.
- Fixed: pasting or fast-typing a whole date into a date field could silently be dropped; a half-entered date now shows a clear hint instead of a mysterious blocked Continue button.
- Fixed: merge-field tokens (like a name or address pulled from another answer) could show up unresolved as raw text on nested-form labels and outstanding-document names.
- Fixed: ABN/ACN/BSB and similar identifier fields displayed thousands-separator commas and could fail validation on submit.
- Fixed: reinstalling or updating a workflow template pack could archive an unrelated form that happened to share a name with one of the pack's own forms.
- Fixed: rule-builder conditions now offer explicit date comparisons (e.g. "years since") computed with real calendar maths, and the picker no longer leaves you on an impossible combination.
- New: platform staff can now turn individual question types on or off per organisation.
- Behind the scenes: laid the groundwork for a new "Lookup" question type that searches an external directory, starting with the Australian Business Register — not yet switched on in any environment.
Account and onboarding
- A better first day — new users get a short guided walkthrough the first time they open ZiplineOS, plus dedicated first-visit tours for Input Hub, the form builder and the workflow builder.
- Invite your team and pick your workflows during setup — the onboarding wizard now lets the first user invite up to four teammates by email and choose which starter workflow templates to install.
- Your web address, sorted automatically — an organisation's URL slug and Collect subdomain are now generated from your company name automatically.
- New: mortgage brokers are now asked to nominate their aggregator during onboarding.
- New: after installing a starter workflow template, a short setup panel walks you through personalising it — privacy wording, roles, and the client invite email, with an AI-drafted starting point rolling out progressively.
- Fixed: choosing starter workflows during onboarding could silently install nothing if you clicked Finish quickly — installs are now confirmed before you're taken into the app.
- Fixed: an organisation created by a ZiplineOS admin no longer gets asked our own "tell us about your organisation" self-serve signup questions.
NDIS support quoting
- New: NDIS support quoting — a purpose-built quoting workflow for organisations coordinating NDIS supports: a client intake form, automatic assignment of the nearest available support clinician (honouring a stated gender preference), a branded PDF quote, and a "Carry Forward" flow that pre-fills a plan renewal from the previous one.
- The quote now tells you when the nearest available clinician is more than 150km away.
- Travel is no longer charged as part of a quote.
- Fixed: a support could be selected without its required funding type, producing a quote with a $0 total and no explanation why.
Deals and workflows (Input Hub)
- First-visit walkthrough for Deals — a guided tour of the Deals kanban board and deal detail page appears the first time you visit.
- Generated deal PDFs now render Summary tiles (the same section/total rollups you already see in Collect), and several answer types that used to show as raw data — who owns an item, a picked date, a delegate's name — now render as plain text.
- Fixed: a delegated form section that had actually been completed kept sending reminder emails and never showed as done; a workflow republish could silently break an active delegation link and wrongly call it "expired" instead of asking for it to be reissued.
- Fixed: on the "who will complete each insurance" step, Continue was allowed once just one product had been assigned instead of all of them.
- Removed the "finish setting up" dashboard nudge now that setup guidance lives inside Input Hub.
- Behind the scenes: an automatic welcome email on deal creation is being built and is not yet switched on for any organisation.
Client intake (Collect)
- Fixed a data-integrity bug: switching between applicants on a shared multi-applicant form could bleed one applicant's in-progress answers into another's.
- Fixed: finishing the final step of a form could fail to show the completion screen or leave step statuses stale; Continue is now disabled while a submission is in flight to stop accidental double-submits.
- Faster perceived load on the multi-applicant details step — the page frame now appears immediately, with only the individual form skeleton-loading.
- Fixed: a required document whose visibility depended on an answer inside a nested sub-form (e.g. a council rates notice) could be silently never requested.
- The public "subscribe for updates" opt-in link now works end to end in production.
- The delegate invite email now names the actual person asking and greets the delegate by name, instead of reading as a generic organisation-to-stranger message.
- Fixed: a public self-registration link containing a "card deck" step showed "this deck has no cards yet."
Admin and integrations
- Registry sections can now be individually granted or revoked per role from the Kernel feature-grants matrix, instead of being all-or-nothing.
- The Template Library now shows only the four core AU lending packs to regular admins; the rest are visible to platform staff only.
- Kernel's Edit User page gained a "Send Welcome Email" action to resend a user's onboarding email on demand.
Security and reliability (behind the scenes)
- Closed a gap in the (not-yet-enabled) deal-creation welcome email config: the save endpoint checked the caller's login but not which organisation the workflow belonged to, which would have let one organisation overwrite another's template.
- Closed several tenant-isolation gaps found while building NDIS quoting: clinician lookups and a quote PDF weren't consistently scoped to the requesting organisation, and an internal-only "staff alerts" field was reachable from an anonymous client link.
- Added server-side enforcement to the setting that turns on the public subscribe link — it was previously guarded only in the browser.
- Magic-link URLs, which carry a live access credential, are no longer written to logs in cleartext.
- Aligned browser tab titles with the ZiplineOS name across every portal, needed for our Google sign-in verification.
Technical details
- AU Mortgage Fact Find:
au-mortgage-factfind-v1catalog item replaced with a faithful 4-stage export (NCCP reasonably-foreseeable-changes section, Credit Guide, credit-check/BID, declaration + signature); a JSON-property-order-sensitive rule-parser bug that 500'd the Employment/Assets stages fixed; guarantor role removed, Living Expenses moved to shared (non-per-applicant) scope, conditional bank-statement/gift-letter/Contract-of-Sale document requests added (#2955, #2969, #2957). - Nested-form context inheritance: field-level
Lock/Prefillmodes with client render-time resolution and server write-path materialisation + reference validation; extended to multi-source precedence with a grouped-by-child-field editor;Lockmode no longer clears a user-typed answer when its parent source becomes unresolved (#2884, #2898, #2901). - Default Value control: type-aware per-field-type editor in the field builder; fixed a Checkbox/Yes-No
Uncheckeddefault coercing to checked across every filler (#2911). - Rule builder: cascading Function → Form → Field → Operator picker; six explicit date functions (
DATE_SPAN_*/*_SINCE) using calendar-unit maths in place of raw day-count subtraction, with legacyDATE_SPAN/DATE_DIFFrule ids normalised losslessly on read (#2883); a locale-sensitive numeric-comparison bug (comma-decimal parsing) and install-time validation of invalid rule-builder operators fixed (#2899). - Money fields: platform-wide floor/ceiling — reject negative, cap the integer portion at 12 digits — enforced in the input sanitizer, client validation and server
FormFieldRule, with a retroactive min-0 default for Money fields with no authored range (#2949). - Multi-option checkbox answers: fixed the write path treating a required multi-option checkbox group as a single boolean consent checkbox and rejecting its array answer (#2981).
- Template-pack install: reinstall/update archival now scoped by the pack's
SourceRefidentity instead of display name, so it can no longer archive an unrelated org-authored form of the same name (#2951). - Lookup field type: new question type + Australian Business Register provider, working in Input Hub and Collect including nested forms; the provider is inert pending the
AbnLookup:Guidsecret, unset in all environments today (#2912). - Per-question-type feature flags: 25 new feature-grant keys, granted by default (#2914).
- Onboarding: new per-user first-visit tracking primitive backing a mandatory shell walkthrough, an Input Hub welcome tour, and embedded Forms/Workflows builder tours using live demo data, guarded against re-firing during impersonation or after a transient network failure (#2902). First self-serve user now provisioned as Owner; up to 4 best-effort teammate invites during onboarding; pick-and-choose starter-workflow install step (#2942). Org slug/Collect-subdomain auto-derivation with a name normaliser and collision retry, plus an admin backfill for orgs with a null subdomain (#2936). New
Organizations.Aggregatorcolumn + onboarding question for the Mortgage Broker role (#2971). Guided post-install setup task plugins (privacy wording, roles, invite-email editor) with an AI-drafted invite email behind theinvite_email_draftgrant, seededVerbs=0and rolling out per-org (#2853). Starter-pack install is now awaited (30s timeout) before the onboarding redirect instead of fire-and-forget (#2950). - NDIS quoting: new pricing/rate-card/decision-table engine, nearest-clinician + travel-distance (Mapbox) + MMM-2023 price-region orchestration, a 7-step/205-field intake workflow, a staff quote-override panel, and a branded paginating quote PDF; new
OrganizationMember.IsSeatExemptlets a contracted clinician be registered without a paid seat or login (#2869). Travel billing removed from the live product; gender-preference-aware clinician matching added; a self-targeting "Carry Forward" plan-renewal flow added; an unrelated formula-engine infinite-loop/OOM bug in comparison-operator parsing fixed along the way (#2896). >150km distance notice added to the quote (#2931). Funding type now required per selected support (#2932). - Deal PDF: Summary-item tiles now render via the same section/total rollup used in Collect; PDF formatters added for ApplicantSelector/EntityReference/Lookup/BookingSlot/SubjectDelegation answer types, closing a leak where an internal-only source form or a delegate's name/email could surface on an externally-visible PDF (#2929).
- FillGrant: delegated sections are now marked
Completedinternally instead of indefinitely re-sending reminders; a workflow republish no longer mis-reports an orphaned delegation link as "expired" rather than "needs reissue"; reminder cadence is now configurable per workflow (#2895). - Deal-creation welcome email: new
WelcomeEmailOnDealCreate-gated (Verbs=0by default in production) automatic send to the primary applicant on API-sourced and opt-in manual deal creation, plus a permanent Initial Email template editor in Workflow Settings; fixed a missing org-ownership check on the template-save endpoint (#2938). - Guidance: first-visit walkthrough for Deals kanban + deal detail, sequenced against the shell/Input Hub tours so they don't stack (#2937).
- QuickCapture edit-view writes now carry applicant/instance identity consistently with sibling components, fixing items that got stuck "outstanding" after an edit (#2947).
- Collect insurance-assignment gate now requires every visible product/subject to have a committed delegation row, not just a non-empty answer array; also fixed a repeatable-instance bypass and a stale warning that never cleared (#2880).
- Collect: per-applicant autosave/render state scoped to stop cross-applicant bleed on shared multi-applicant steps (#2946). Final-submit completion screen and step-status refresh fixed; Continue disabled while a submission is in flight (#2948). Multi-applicant Details step renders its header/switcher immediately with a per-form skeleton instead of a blank-then-spinner sequence (#2956). Nested-sub-form-gated outstanding documents now resolve at the top level; an internal-only File field label no longer leaks to anonymous magic-link clients (#2957). Public subscribe (double opt-in) flow fixed end to end (missing category slug + edge SPA routing) and gated by explicit server-side authorization instead of a frontend-only check (#2882). Delegate invite copy now names the requester and greets the delegate by name (#2878). CardDeck pack forms added to the anonymous-preview workflow-snapshot fallback (#2893).
- Registry: 15 new feature-grant keys for identity-portal nav/settings sections, seeded to mirror existing access ("ships bright"); backend
[RequiresFeature]enforcement is a follow-up (#2913). - Template Library: catalog visibility restricted to 4 core AU lending packs for non-super-admin users; all other packs now require SuperAdmin (#2977).
- Kernel: "Send Welcome Email" action on Edit User, SuperAdmin-only, audit-logged (#2979).
- AU commercial low-doc/alt-doc fact-find catalog pack plus importer fidelity fixes; a dark (
Verbs=0)templates_workflow_updateflat-replace-install capability opened to SuperAdmin preview only; magic-link URLs no longer logged in cleartext (#2910). - Security: cross-tenant template-config overwrite on the welcome-email save endpoint closed (#2938); NDIS clinician-register and quote-PDF tenant-scoping gaps closed (#2869, #2896); internal-only Staff Alerts field closed off from anonymous magic-link access (#2896); Summary-tile PDF leak of internal-only forms and delegate PII closed (#2929); public-subscribe management endpoint given explicit server-side authorization (#2882); document titles aligned with ZiplineOS naming across Shell/Kernel/Rolodex/Ideas for Google OAuth verification (#2857).
Fixed months-silent workflow emails, a broken delegate link, and mail that was landing in spam
This release is a fix pass. The most significant: workflow "send email" reactions had been silently sending nothing for every organisation since late March — they now work again. We've also fixed a delegate invite link that 404'd, a bounce notice that could tag the wrong delegate as unreachable, and client emails that could be flagged as spam because they were sent from a domain that didn't exist. Underneath, we've hardened how session logins are signed and tightened access to and retention of AI request logs.
Deals and workflows (Input Hub)
- Workflow emails are sending again — a "send email" reaction attached to a workflow step had been silently sending nothing since 24 March, for every organisation, because it couldn't understand the newer format the email composer saves recipients in. It now reads both formats, and a misconfigured reaction will show up in the logs instead of failing silently.
- Fixed: the rule builder's "aggregate" dropdown was hiding forms that belonged to a different role (or no role at all) from a per-applicant question's rule sources, even though referencing them was already allowed.
- Fixed: installing a workflow template from the catalog could crash outright, or quietly drop configuration such as step colours and exit rules; re-installing a template no longer overwrites an organisation's own customisations to it.
Client intake (Collect)
- Fixed: the emailed link for a delegated document request could return a "page not found" error.
- Fixed: a bounced email could mark the wrong person as unreachable — if a document request was reassigned to a new delegate right after the previous delegate's invite bounced, the bounce notice could land on the new delegate instead.
Notifications
- Fixed: emails sent to clients (magic links, co-applicant invites, delegate invites) could be flagged as spam because they were sent from a domain that didn't actually exist. They're now sent from one verified ZiplineOS domain, show your organisation's name as the sender (e.g. "Acme Brokers via ZiplineOS"), and reply straight to your broker.
Security and reliability (behind the scenes)
- Hardened how session logins are signed, removing a fallback signing key that could theoretically have been reused across environments.
- Tightened access to AI request logs — reading one now requires an explicit organisation match and is audited — and added a (currently disabled by default) retention window for AI request/response content and other audit logs, plus database-level tenant isolation on the tables that hold them.
Technical details
- Workflow reactions:
ReactionService.ResolveRecipientsAsyncnow accepts both the legacy{type,roleId,email}and composer{sectionKey,id,label}recipient shapes, mirroringWorkflowEngine's existing dual-format resolver; warns on zero resolved recipients; explicitOrganizationIdfilter added to the recipient queries (#2870). - Rule builder:
aggregateSourcesno longer filtered by same-role for aPerApplicantauthor, aligning the picker withRuleScopeReferenceValidator's existing same-role exemption for aggregate references (#2872). - Catalog/versioning: catalog install normalises export-format packs at the deserialize boundary so both pack formats install through one materialisation path; carries full step/role/item config (
Color/IsTerminal/Rules/RulesEnabled/ExitValidationRules,RequiredIf/MinCount/MaxCount,SubjectConfig/CardDeckConfig/MultiInstanceTileConfigand others); re-install now preserves org-customised step/item config instead of clobbering it with an empty pack value; field-level and workflow-level scalar configs (BindsTo,IsExtractable,DealValueField,AllowSelfRegistration, etc.) now carry through export/import/merge andWorkflowPublishermaterialisation (#2875). - Collect edge:
/grant/<token>moved to/g/<token>and added to thecollect-edgeallowlist;/grant/stays live for already-issued invites (#2866). - FillGrants: the Mailgun bounce webhook now matches on the grant's current
GranteeEmailand only acts on aLivegrant, so a stale bounce arriving after a reassignment can no longer mark the new delegate unreachable (#2860). - Email:
RequestMagicLinkCommand,ApplicantMagicLinkSender, andFillGrantInviteServicenow force the global authenticated Mailgun sending domain (matching the visible From header) and set Reply-To to the deal's assigned broker (#2867). - Auth: removed the hard-coded session JWT signing-key fallback; startup now fails in every environment if
Authentication:Session:SigningKeyis unset (SEC-03-F1) (#2834). - Security: the SuperAdmin AI request-log detail read now requires an explicit organisation match and writes an audit record (R1); added a retention sweep for
AiRequestLog/ApiRequestLog/ChangeLog, disabled by default (R2); made AI prompt/response body persistence opt-in and off by default (R3); added row-level-security tenant isolation toAiRequestLogs/ApiRequestLogs/ChangeLogs(R4) (#2874).
Ad-hoc document requests, seamless Collect uploads, and a fix for frozen automated journeys
This release lets a broker ask for an extra document that isn't part of the original form, gives Collect's Documents page a proper drag-and-drop upload surface, and refreshes the sign-in and create-account pages. A new "make this template yours" step helps a brand-new organisation personalise its first workflow before publishing it, and workflow rules can now see answers from the very first "create a deal" screen. Underneath, we've fixed a bug that could freeze an organisation's automated journeys for days.
Client intake (Collect)
- Ad-hoc document requests — a broker can now ask for a document that isn't part of the original form, right from the Deal Documents page, assign it to an applicant (or the whole deal), and group it under an existing or new heading. The applicant uploads it through Collect like any other request.
- Faster, drag-and-drop uploads — each document request row on Collect's Documents page is now its own upload surface: drop or click to add a file, watch it appear instantly with no page flash, add several files to a multi-file request, and remove any one of them individually.
- A co-applicant who's had a section shared with someone else can now hand it back and finish it themselves, with the option to email that person a fresh link straight away.
- Fixed: the applicant picker on fields like "Owner" or "Policy owner" could show no one to choose from when the question sat inside a repeatable section, an edit drawer, or a document-merge drawer.
- Behind the scenes: the groundwork for delegating a single product (such as one insurance policy) to someone else to fill in continues to take shape on our staging environment — not yet switched on for any live account.
Deals and workflows (Input Hub)
- A friendlier first workflow — installing a starter template during onboarding now leaves it as a draft with a short "make this template yours" panel (starting with your logo and brand colour), rather than publishing it immediately with generic defaults. A dashboard hint points a new organisation back to it until it's published.
- Workflow rules can now reference answers given on the very first "create a deal" screen, not only questions asked later in the workflow.
Account and sign-in
- Refreshed login and create-account pages — a cleaner, consistent design across both, and password reset now opens in a focused dialog instead of an inline panel.
Admin and integrations
- Redesigned Integrations page — installed and available integrations are easier to scan, with real provider logos, a one-click setup for the Zipline Form Filler browser extension, and a confirmation step before uninstalling anything.
Security and reliability (behind the scenes)
- Fixed a bug that could freeze an organisation's automated journeys for days: a wait step with an ambiguous time zone got stuck retrying forever and crowded out every other journey's due work behind it.
- Fixed the Help feedback panel so it appears in the right place and no longer leaves the navigation rail in a stuck state.
- Continued closing out the underlying data-governance work: every JSON-shaped column in the database now has a stated, build-checked classification.
Technical details
- Ad-hoc document requests: new
ITenantScopedAdHocDocumentRequestentity + canonical RLS policy; create/edit/cancel commands unioned intoGetOutstandingDocumentsQuery; Collect (anonymous magic-link) upload endpoint scoped toDealIdafter a security review caught it accepting a file from a different deal in the same org; input-portal request/edit modal and Collect upload UI (#2839). - Row-native inline uploads: Documents-tab request rows become drag/click upload surfaces backed by a new scoped magic-link DELETE endpoint for per-chip removal; multi-file accumulation and single-file-slot caps fixed; accessible status icons and contrast pass (#2832).
- Applicant hand-back + cross-applicant documents: the primary applicant can list/download/upload co-applicant documents on Shared items; a new
ClientFacingflag on the outstanding-documents query excludes internal-only submissions from anonymous magic-link responses, closing a gap the widening would otherwise have opened (#2831). - Fixed two defects in the FillGrant submission path reachable only on
ItemScope.Shareditems: the submission unit and submit-lock were both keyed to the grant owner regardless of scope, so a delegate's answers on a Shared item landed in an orphan row invisible to the primary, broker and PDF (#2807). - Per-product ("subject") delegation:
FillGrantgains asubjectscope kind + normalisedScopeKeyslot column (widened live-grant index), grant-scoped form/compute/file endpoints, primary-side delegate/remind/reclaim/reassign UX, broker-side waiting/status surfaces, and aSubjectDelegationfield type; a failed delegation invite now surfaces to the primary instead of silently claiming success, and the delegate-facing surfaces now name the actual product being delegated. Ships behindCollectSubjectDelegationEnabled— turned on for staging only (gated on #2812's three FillGrant migrations already being live), stillfalsein production (#2812, #2851, #2852, #2856, #2859). - Applicant-roster context:
ApplicantSelectorfields inside repeatable/edit/merge-drawer hosts now consume the applicant roster via a React context instead of an ad hoc prop chain, closing the same "empty picker" bug class for good (#2858). - Workflow personalization:
WorkflowPersonalizationTaskentity + RLS, a step-plugin registry, a branding step, and aPersonalizationPanelin the workflow editor; starter-form install no longer auto-publishes (workflow staysDraftuntil personalization is complete and published manually); a bad personalization requirement no longer fails the whole install (#2840). - Manual deal-creation form as a rule source:
RuleScopeReferenceValidatorcarve-out lets a workflow rule reference the deal-creation form from any source scope; both the render and gating rule engines now inject its answers via a sharedManualCreationFormSourceselector so they can't disagree (#2861). - Identity: shared
BrandMarklockup across login and create-account, password reset moved into a dialog, plus accessibility fixes (heading landmark, accessible field names on placeholder-only inputs) (#2841). - Protocol Integrations page rebuilt onto a shared
IntegrationConfigModal; real brand logos for Equifax/Illion/CashDeck/Cotality; Form Filler reduced to a single install action; uninstall now requires confirmation (#2845). - Journeys: an
until_datewait node with no time zone parsed toDateTimeKind.Unspecified, which Npgsql rejected on thetimestamptzWaitingUntilcolumn; the poisoned enrollment then never reachedFailedand re-qualified for the 60-second sweeper every cycle, saturating its cross-org batch and starving every other journey's due waits (root-caused to a 2026-08-11 production incident). Fix parses to UTC and drains a poisoned enrollment via a tracker-independentExecuteUpdatewrite, wrapped in one transaction with the active-enrollment-count decrement (#2862). - Shell: Help feedback panel repositioned and given a
hideFabhost mode so the shell-hosted widget no longer leaves stray nav-rail state (#2850). - ARC-01-F1:
JsonbColumnCatalogGeneratorinventories and classifies all 178 jsonb columns (BusinessQueryable/Config/Snapshot/Payload) with a CI completeness gate, plus additive typedFormAnswerDocument/CustomFieldDocumentcontracts for the business-queryable subset (no write path routed through yet) (#2836).
Working marketing preference topics, a stronger password experience, and a big batch of deal-completion fixes
This release makes marketing email preferences actually do something — recipients can now opt in or out of specific kinds of email, not just unsubscribe from everything — gives every password-set screen a proper strength meter and one consistent policy, and adds two more steps to onboarding so a new organisation leaves the wizard ready to work. Underneath, we've closed out a long run of deal-completion and Collect fixes, and closed a real tenant-isolation gap on four database tables.
Broadcast and marketing preferences
- Preference topics now work — a contact can opt in or out of a specific kind of marketing email (e.g. "Product updates" versus a monthly newsletter) independently, sitting underneath the existing "unsubscribe from everything" switch. Sends and journeys both now check it before mailing.
- Public opt-in page — someone who isn't yet a contact can join an opt-in topic themselves via a shareable link, with a confirmation email required before they're subscribed.
Account and onboarding
- Password strength meter — every password-set screen (sign up, accept invite, change password in Settings) now shows a live strength meter and a requirements checklist, backed by one consistent policy that the server also enforces.
- Onboarding now sets you up to work — after the initial questions, a new organisation can one-click install a starter form (published and ready to use) and apply its logo and brand colour, all before leaving the wizard.
- Fixed: a new signup could get stranded on the Registry dashboard instead of landing back in the main app.
Deals and workflows (Input Hub)
- Forms now have a real publish step, so an in-progress edit no longer leaks into live workflows until it's deliberately published — not yet switched on for any account while we finish the rollout.
- Searchable, grouped pickers for choosing a form now appear everywhere a form is selected, not just the workflow item editor.
- Fixed a run of bugs where a stage, product group, or the whole Summary tab could sit "incomplete" forever because gated-off (not-applicable) questions or optional items were being counted against it — on the staff deal view, the pipeline stepper, and the Subject group badges.
- Fixed: a conditional rule on a multi-select question never fired once someone picked more than one option.
- Fixed: date-rule validation (e.g. an under-18 date of birth) now shows its real error message on Collect, previews and staff deal-fill, instead of a generic "required" message or nothing at all.
- A submission's dropdown options and financial-year labels are now frozen at the moment it's submitted, so a later edit to the form doesn't retroactively change what a past answer looked like.
Client intake (Collect)
- Fixed a data-loss bug: navigating away from a form (e.g. to the Documents page) within two seconds of typing an answer could silently discard it.
- Fixed: switching between applicants on a shared step could snap back to the first question instead of staying on the one you were looking at.
- Fixed: financial-year placeholders in document names (e.g. "FY2026 Tax Return") now resolve properly on the Documents list instead of showing the raw token.
AI and admin
- The AI Services admin area can now filter request logs and break down cost by individual AI process, drillable to a per-organisation view.
Security and reliability (behind the scenes)
- Closed a real gap: four database tables (contact warning flags and their assignments/dismissals, and per-user record-recency tracking) had no tenant-isolation policy at all at the database level. They're now policed, with an automated check that fails the build if any tenant-scoped table ever loses its policy again.
- Locked the CRM messaging page's advanced settings (raw provider credentials, channel routing) down to platform admins only, and fixed a bug where a dedicated SMS number could be silently bypassed in favour of the shared platform number.
- Moved the feedback "?" widget into the global navigation rail.
- Continued laying groundwork for the Chrome extension's shared, self-healing autofill profiles — plumbing only, no profile content yet.
Technical details
- Marketing subscription topics: Phase 1 wires
PreferenceCategory/ContactPreference(already-built admin CRUD + public preference centre) into the actual send path — new-topic default is opt-out (zero behaviour change for existing categories) (#2775). Phase 2 gives the Journey executor the same preference-eligibility check viapreferenceCategoryIdinJourneyNode.Config(#2776). Phase 3 adds an anonymous/api/v1/subscribesurface (PublicSubscribeEndpoints,CollectPublicCORS policy) with mandatory double opt-in and per-email cooldown anti-abuse, reusing existingContactPreferencecolumns rather than a new entity (#2778). - Password policy: shared-ui
PasswordStrengthMeter(5-rule checklist, dark/light variants, a11y labels) wired intoSignUpPage,AcceptInvitePage, andPasswordChangeForm; server-sideSetPasswordCommandValidatornow enforces the same 5-rule policy (#2792). - Onboarding:
POST /api/v1/onboarding/install-starter-formcomposesInstallTemplatePackCommand+PublishFormTemplateCommandviaISenderin one atomic call, dispatched through a trusted path that bypasses the still-darkFormsPublishfeature gate so a brand-new org isn't blocked publishing its own starter form; branding step saves logo/colour toOrganization(#2792).SignUpPagenow honours the shell'sreturnUrl(#2783). - Forms publish lifecycle:
FormTemplategains a publish/draft split;WorkflowDefinitionBuilder.BuildAsyncnow snapshots the published form, not live edits; publish/archive/delete/duplicate are now four separate feature flags, withform_publishseeded dark (Verbs=0) and the other three mirroring the existingformsgrant (no regression) (#2770). SearchableFormPicker(shared-ui) rolled from the workflow item editor (#2777) out to the 9 remaining flat-Selectform-selection surfaces across input-portal and identity-portal (#2790).- Deal-completion parity fixes:
PipelineProgress/staff deal view/Subject group badges no longer countNOT_APPLICABLE(gated-off, zero-instance) or optional items as outstanding (#2784, #2787, #2795); Summary-tab step completion now uses the same required-items-only computation as the Workflow tab (#2793);effectiveCurrentStepIdresolves the next visible step when the server's current step is a hidden summary-only step (#2780); staff deal view now groups a product's pages under its Subject, matching the workflow builder (#2786). - Rule-engine fix:
equals/notEqualson a multi-select answer now mean array-membership rather than exact single-value match, across all four visibility engines (#2806). FormSubmission.FieldsResolvedAsOf(additive column) freezes dynamic option lists and FY label tokens as of submission time (#2799); a follow-up resolved FY tokens on the Collect Documents list and the token picker, which the initial freezing work missed (#2805).- Collect: debounced (2s) autosave now flushes on unmount instead of discarding the pending write, closing a data-loss path when navigating within the debounce window (#2821);
NestedFormunmount now clears its stale entry from the aggregated incomplete-keys ref, releasing a Continue-gate lock left behind after a visibility rule hid the nested form (#2804);selectPersonnow preservesselectedItemIdwhen switching applicant instead of discarding it (#2791); date-rule (V2) validation now drives the inline/gate error onDateFieldacross Collect, preview and deal-fill (#2809);MultiSelectFieldnow handles thegrid-compactdisplay-mode hint, which previously fell through to the plain dropdown (#2782). - Nested frequency-money fields now render inside the multi-instance repeatable-card tile (#2800); tile-mapping regeneration now triggers on form publish rather than every field save (#2796).
- AI Services:
OperationNamefilter added to/admin/ai/logs;byOperation/byOperationOrggroupings added to/admin/ai/usage; embeddings calls reconciled onto the sharedembeddingsprocess key so they're covered by cost-per-process (#2774). - Messaging:
messaging_own_provider/messaging_channelsdark feature flags gate the BYO-Twilio-credential and channel-routing config endpoints to platform admins; fixed a bug where a provisioned dedicated number lost to the shared platform Messaging Service on send (#2781). - SEC-01-F1: a report-only completeness test found four
ITenantScopedtables —ContactWarningFlags,ContactWarningFlagAssignments,ContactWarningFlagDismissals,UserEntityRecencies— with zero RLS policy rows; a migration policies all four using the canonical inlined tenant predicate, and the completeness test flips to a hard CI gate (#2827, #2829); 32 newRlsTestSuiteBasefacts (8 per table) cover per-tenant read isolation, worker cross-tenant visibility, fail-closed on missing/partial tenant stamp, and cross-tenant INSERT/UPDATE rejection (#2830). FeedbackWidgetnow opens via the shell iframe bridge when embedded, anchored to the nav rail rather than floating (#2773).- Extension:
WebsiteFillProfile(platform-scoped) entity + additive-merge loader lands the durability/versioning layer for a global, self-healing Chrome-extension autofill profile; ships with an empty seed — real profile content is a follow-up (#2755). - Seed-data fix: dev/test org seed-clear now walks the full seeded-org subtree instead of direct children only, avoiding an
ON DELETE RESTRICTfailure when a seed child had itself been seeded (#2808).
A redesigned Collect Documents view, self-titling deals, and a reliability sweep for stalled workflows
This release gives Collect's Documents page a clearer, progress-driven redesign with CashDeck income verification built into the flow, has new deals title themselves from applicant names automatically, and closes out a run of bugs where a deal could look finished to a client but stuck to staff (or vice versa). We've also fixed a co-applicant navigation dead-end and hardened a few security-sensitive corners behind the scenes.
Client intake (Collect)
- Redesigned Documents view — the Documents page now shows a clear progress indicator and groups files by status, with the CashDeck income-verification card appearing inline instead of tucked away; once a CashDeck check is done, verifying again is a proper "redo" action rather than a dead end.
- Fixed: some co-applicant workflows could dead-end after finishing one applicant's questions, with no way to reach a shared or proxy-completed section.
- Fixed: after saving, the page now scrolls to your actual next gap instead of jumping back to wherever you happened to tap.
- Fixed: adding another applicant while still typing their name could quietly create duplicates; an empty nested dropdown and a shared-form bug on repeatable sections were also fixed.
Deals and workflows
- Deals now title themselves — a new deal picks up a sensible name from its applicants automatically, and keeps it current as applicants are added, instead of sitting in the pipeline as "Application 48213".
- Smarter card previews on repeatable sections — cards for a repeatable form (multiple vehicles, employers, and so on) now get an AI-generated title, amount and chip summary automatically, instead of needing a broker to configure one by hand.
- Fixed: a deal could show as fully answered to the client ("You're all done") while staff still saw it as incomplete, because sections that legitimately don't apply were still being counted as outstanding work.
- Fixed: a deal could get permanently stuck on a step with nothing to ask, when a whole run of steps in a row turned out not to apply.
- Fixed: a question gated on a co-applicant's answer could wrongly look unanswerable if that answer had been saved but not yet submitted.
- Fixed: purely informational "summary-only" steps no longer clutter the staff deal-detail view.
- Staff completing a deal on a client's behalf now see the same section headings and authored guidance the client sees, and pages where every question is gated off are clearly labelled instead of left blank.
Security and reliability (behind the scenes)
- Closed an XSS/open-redirect gap in the shared sign-in redirect handler.
- Fixed a tenant-isolation gap where moving a file between Drive folders could, under the right conditions, act on another organisation's file record.
- Continued building out SMS as a channel — a Marketing SMS manager (consent, unified inbox, bulk campaigns) and two-way SMS with number provisioning on a CRM contact — all still dark, not yet switched on for any account.
- Patched further vulnerable third-party libraries and hardened a batch of CI/CD pipelines flagged by automated scanning.
Technical details
- Collect Documents redesign: new document status→visual mapping and a redesigned view with progress, grouped rows, and an in-flow CashDeck card; CashDeck fixes found via live sandbox ingest testing — numeric
id/role_idtolerance in response parsing, aIServiceScopeFactoryfix so local-dev background tasks survive their caller's scope, and a sharedAddFolderOrReturnConcurrentWinnerhelper closing a concurrent-insert race that silently dropped 3-of-4 files from a multi-file ingest (#2717). - Multi-applicant proxy selection: a pure
nextProxyAwareTargetturns resolver plus an atomic{stepId, itemId, applicantId?}selection type replaceMultiApplicantSections' localuseState-driven active-applicant logic, fixing the proxy trailing-shared dead-end and item-vs-applicant divergence bugs from PR #2693 (#2697). - Navigation scroll now keys off page completeness (fresh pages open at top; only an in-progress page reveals its first gap) rather than where the user tapped from (#2702).
ContactSelectionautosave dedup fix: a new applicant is only materialized once both first and last name are present, closing a burst-duplicate bug from partial-data autosaves; plus an empty nested-dropdown fix and a shared multi-instance forms fix (#2735).Deal.NameIsAutoGenerated(additive migration) +DealTitleGeneratorcompute an applicant-derived title; a post-commitDealAutoTitleInterceptorkeeps it live as applicants change, while a manual or API-set title is recorded and never overwritten; sync/CSV-import placeholder paths are flagged auto so they still get titled (#2718).- Multi-instance tile mapping: a new structured AI process reads a
FormTemplate's field signatures and proposes a default title/money/chips tile config for repeatable-section cards, regenerated automatically on field add/update/delete via the task queue; landed alongside reasoning-effort plumbing that finally wires the admin AI UI's thinking-budget knob through to Vertex and Bedrock (it was previously stored and displayed but never sent) (#2760). NOT_APPLICABLEitems (gated fully off, zero instances) no longer failisDoneand pin a stage incomplete; input-portal's staff view separately gained aHasNoVisibleQuestionsflag so a gated-off page reads as "does not apply" rather than blank (#2758, #2738).CheckAndAdvanceAsyncnow advances past a full run of empty steps in one pass instead of one step per submission, fixing deals that stalled on an inapplicable category step (#2756).RuleContextBuilder(client-rendered rule externals) andCrossFormDataLoader(server completeness check) disagreed on visibility for a saved-but-InProgresssibling answer; both now agree (#2728).isSummaryOnlyStephides display-only workflow steps from the input-portal deal-detail view (#2769).- Staff deal filler now renders
Displayblocks (section headings, authored guidance) through the same auditedDisplayFieldsanitisation Collect uses, instead of dropping them as client-only (#2715). safeRedirectnow parses the target URL and hands the navigation sink the parsed.href, closing CodeQL alertsjs/xssandjs/client-side-unvalidated-url-redirectionthat an interprocedural boolean guard alone didn't clear (#2743).MoveFileToFolderHandler's placement lookup now filters byOrganizationIdper Ziplock A4 defense-in-depth (#2680).- CRM SMS: Piece B ships two-way SMS on a contact (Twilio send/receive, threaded panel, activity-feed merge, STOP/opt-out) behind the dark
contact_smsgrant (#2719); Piece C ships self-serve AU number provisioning and billing behind a separate dark grant, per-org cap, with RLS-isolatedProvisionedNumbers/OrgRegulatoryBundlestables (#2761). Marketing SMS Manager ships consent/suppression, a unified inbox, and bulk campaigns behind the darkbroadcast_smsgrant (#2736). - Dependency and CI hardening:
undicibumped to 7.29.0 across 7 portals (#2733); the Jira bug-fix agent's workflows had 29 zizmor findings and its credential scoping cleared (#2740, #2741), plus a further pass to zero remaining findings (#2745, #2739);collect-edge/preview-edgeGo toolchain bumped 1.22 → 1.26 (#2709); minimal permissions applied tojira-agent-ci-fix(#2706); dead Cloud SQL Terraform module removed and committed tfplans untracked (#2749); service-account token-creator scoped to the SA with versioning enabled on the two data buckets (#2765).
Self-serve signup, a redesigned contact page, and a round of Collect reliability fixes
This release lets people create their own ZiplineOS account and link Google or Microsoft as a sign-in option, gives Rolodex contact pages a cleaner layout with a unified activity feed, and fixes several issues that could leave a Collect applicant stuck partway through a form. Broadcast also gets a unified custom fields manager, a real-execution journey test mode, and a fix for engagement rates that could read over 100%.
Account and sign-in
- Create your own account — the "Create Account" option on the sign-in page is now live, with a consistent password policy (minimum 12 characters, one uppercase letter, one number) across every signup surface.
- Link Google or Microsoft as a sign-in method — from Settings → Security, a password-first user can now add an SSO provider as an additional way to sign in.
- Fixed: emails sent through a connected Gmail account showed the raw address instead of the sender's name.
- Fixed: connecting Gmail or Outlook could briefly flash the standalone Registry page, or bounce to the wrong address, before returning to the app.
Client intake (Collect)
- Clearer logo and heading sizing — logos can now display larger without distortion, and form titles use a more consistent type scale.
- Fixed: selecting insurances could skip straight past the product step instead of taking the applicant to it.
- Fixed: a form could show a section heading with no questions under it, or a whole page that asked nothing.
- Fixed: in a multi-applicant deal, shared questions (like relationships) could become unreachable for the second applicant.
- Fixed: moving to the second page very quickly after starting a self-registration link could show a "failed to load form" error.
Rolodex (CRM)
- Redesigned contact page — a cleaner header showing last-active time, de-duplicated contact details, and a single unified activity feed replacing the separate history views.
- Richer email view — connected-mailbox emails now show the full conversation thread, with clean sender/recipient formatting instead of raw address lists.
- Fixed: open pipeline value and deal counts were being inflated by deals that were already Won, Lost or Cancelled.
- Fixed: clicking "All activity" from the contact overview could crash the page.
Broadcast and journeys
- Unified custom fields manager — contact and deal custom fields now share one consistent editor, brought over from Rolodex.
- Real journey test runs — testing a journey now executes it for real instead of only simulating it, alongside a polished flow-builder layout.
- Fixed: campaign engagement rate could read above 100%; campaign charts have also been rebuilt with a clearer trend line.
- Fixed: recalculating deal custom fields on a large organisation could run out of memory, and some filter comparisons (greater/less than, "does not contain") were silently computing the wrong values.
Documents
- Discovery cards in the deal PDF — a client's kept discovery-card selections (e.g. chosen policy options) can now be included as an image gallery in the generated deal PDF.
Reporting (Telemetry)
- Reworked standard dashboard — the deals-per-stage funnel now has per-workflow tabs, and breakdown charts fit their space more cleanly.
Security and reliability (behind the scenes)
- Enabled Data Access audit logging across our database, storage and secrets infrastructure, and added rate limiting to the anonymous Collect submission endpoint.
- Added monitoring alerts for unusual database read/write activity.
- Fixed a gap that could let a signed-in user record usage against another organisation, or push a usage counter negative.
- Continued laying groundwork for self-serve trial accounts and per-organisation email sending limits — not yet switched on for any account.
Technical details
- Self-serve signup: identity-portal login page's "Create Account" un-hidden; password policy converged to 12/128 char, 1 uppercase, 1 number across identity-portal and shell, matching the backend
SetPasswordvalidator. SSO linking vialinkWithPopupplus a new identity-portal Settings → Security page; shell/signupnow redirects to the identity hub (#2687). - Trial/quota infrastructure landed dark behind
TrialUsageQuotasEnabled:AddOrganizationSubscriptionTrialFieldsmigration,TrialStatusService,TrialExpiryWorker, and seat-cap trial-awareness (#2687);MailgunDeliveryService.SendSingleEmailAsyncnow gates Marketing-category sends on the trial quota, transactional exempt (#2696). A related tenant-isolation gap inPOST /api/v1/usage/record(org read from request body, unvalidated signed quantity) was fixed on its own branch (#2694). - Gmail sender display name fixed (
DisplayNamenow captured for Google connections); post-OAuth return-to-shell masked with a full-viewport loader (#2661). OAuth callback bounce-port derived fromwindow.location.portinstead of a hardcoded:5176fallback (#2671). - Collect: cross-step navigator now defers to the server-confirmed context instead of the stale pre-submit one before deciding the next step, closing the insurance-select skip (#2653).
EmptyFormPageDetectorsuppresses server-side any page whose every question is rule-gated, andfieldVisibility.tsunifies three previously-triplicated visibility computations to prune section headings with no visible questions (#2647).MultiApplicantSectionsnow rendersItemScope.Shareditems in the same one-form-at-a-time sequence as per-applicant items (#2693). First two form-fetch steps are now pre-warmed from the preview endpoint, closing a race where step 2 could 401 before the deal's real token propagated (#2698). Logo bounds raised (header 180×64, sidebar 150×48, breadcrumb 120×36) and form titles promoted to a shared tier-2 type scale (#2700). - Rolodex contact page: header/sidebar dedup,
isOpenDeal()filters Won/Lost/Cancelled out of pipeline metrics, tab-key alias fix (comms→communications) and a DOM-nesting fix for pinned-tab close buttons (#2686). Email threading via newGET /contacts/{id}/emails/{emailId}/thread, DOMPurify-sanitised HTML in the viewer iframe, and send-path fixes to the timeline's From field and custom-recipient resolution (#2667). - Broadcast:
CustomFieldsManager(shared-ui) replaces the separate contact/deal managers; deal custom-field recompute now batches per-contact to avoid OOM on 100k+ contact orgs, andFormFieldConditionMatcherunifies per-contact/bulk operator matching (#2646, #2663). Journey executor gained an Interactive (no-enqueue) execution mode for live-test;ProcessSendEmailAsync'sMarketingTemplatelookup is now org-scoped, closing a cross-tenant template read on the background worker (#2689, #2690).BroadcastEngagementMathrecomputes engagement rate from flagged, deduplicated events so it can no longer exceed 100% (#2663). - Deal PDF: new kept-card resolver + SSRF-guarded image fetch/resize pipeline renders
CardDeckselections into a gallery section via the existingIncludeInPdftoggle (#2684). - Telemetry: per-workflow funnel stage groups, a v7 dashboard layout (full-width funnel/breakdown + insight row), and a breakdown-donut sizing fix (#2657).
- Security/compliance: Data Access audit logging enabled for AlloyDB, Secret Manager, Cloud Storage and Cloud Run, routed to a dedicated 400-day-retention bucket; Cloud Armor rule 1500 changed from
allowtothrottleon the anonymous Collect endpoint (#2670). Firestore read/write frequency alert policies plus audit-log configuration underdatastore.googleapis.com(#2685, #2699).
Campaign engagement analytics, a consistent Broadcast grid experience, and org-level AI document controls
This release gives Broadcast a proper analytics view for every campaign, brings a consistent, faster-loading table style to every Broadcast list, and lets an organisation's Owner or Admin fine-tune how Drive's AI reads and files documents. We've also fixed a compliance gap in journey unsubscribe footers and closed out a batch of workflow-builder and Collect fixes.
Broadcasts and journeys
- Campaign analytics — a campaign's detail page now has an engagement chart (opens and clicks over time) and an overview tab with device, location and delivery-funnel breakdowns.
- Consistent, faster-loading lists — Campaigns, Templates, Journeys, Contacts, Lists, Segments, Suppression List, Background Jobs and the remaining settings tables now share one grid style, load without a loading-skeleton flash, and (on Contacts) fill the available height so more rows are visible at once.
- Fixed: a journey email sent to a contact who'd never received a broadcast could be missing its mandatory unsubscribe footer.
- Fixed: the Deal Custom Fields manager had gone missing from a contact's detail page — it's back.
- Fixed: the Unsubscribe Footer settings page showed two page headers stacked on top of each other.
Forms and workflows
- Subject grouping in the workflow builder — a product's grouped forms now render inside a visually distinct group so it's obvious at a glance which forms belong together.
- Fixed: opening a large workflow (200+ forms) could make the workflow builder crawl or fail to load, caused by hundreds of simultaneous requests loading form details one at a time.
Client intake (Collect)
- Fixed: the "click a field on the document to fill it" drawer didn't reliably scroll to the right field, had no way to save your answer, and never showed answers you'd already entered.
Reporting (Telemetry)
- Better-behaved breakdown widgets — donut-chart widgets now resize properly at any widget size, with a scrolling list and legend once there's more to show than fits.
Account settings
- AI document settings for Owners and Admins — a new settings page lets an organisation's Owner or Admin adjust the confidence thresholds Drive's AI uses for renaming and data extraction, and manage document categories.
Security and reliability (behind the scenes)
- Continued laying groundwork for AU-resident AI models across multiple providers — still not switched on for any account.
- Trimmed the size of AI responses in the document pipeline to reduce cost and latency, with no change to what brokers see.
Technical details
- Campaign analytics:
BroadcastService.GetAnalyticsAsyncaggregatesBroadcastEventsinto a time series (day/hour granularity by age), link, device, location and funnel breakdown; device/location breakdowns are scoped to opened/clicked events only so bounces/complaints don't flood them with an "Unknown" bucket; newEngagementChart+CampaignOverviewPanelcomponents (#2642). - Broadcast list standardisation (ZipDataGrid programme, Phases 0–4): extracted shared grid styling (
buildZipGridSx),createRowActionsColumn,StatusChipadoption, an automatic pager that avoids MUI Community's 100-row page-size ceiling, auseDelayedFlag/LoadGateno-flash loading pattern, and afillHeightmode — applied across Templates, Segments, Subscription Lists, Preference Categories, Contact Source Data, Suppression List, Background Jobs, Journeys, and the three Contacts-page grids (#2616). - Journey unsubscribe-footer gap: the journey send path now mints a
PreferenceTokenjust-in-time for a tokenless contact before building merge variables; also fixed a malformedList-Unsubscribeheader and added a dry-run-by-default backfill command for the existing tokenless population. A companion change attributes every unsubscribe path (CSV import, one-click, preference-centre, admin, API) with a consistentContactActivity+ source, closing a gap where a CSV-import opt-out left no suppression row or timeline entry (#2639). - Deal Custom Fields manager restored to the contact detail custom-fields tab, reversing an earlier removal that left no UI to manage these fields; Unsubscribe Footer settings page's duplicate header removed and the page registered in settings nav (#2645).
- Workflow builder: new
POST /api/v1/forms/detailsbulk endpoint (GetFormTemplatesBulkQuery) replaces a one-request-per-form fan-out across the builder's three field-context load sites, fixing a request storm that hit thousands of pending requests on a 226-form workflow (#2635). Subject member forms render inside a tinted group box computed fromSubjectConfig.members, order-agnostic and drag-safe (#2637). - Collect merge-field drawer: replaced a one-shot 500ms
querySelectorwith aMutationObserverfor reliable auto-scroll, added a Save footer (the drawer previously suppressed the filler's own Continue with nothing to replace it), and wired existing answers through from the magic-link context so a reopened field shows its prior answer (#2634). - Telemetry:
BreakdownWidgetnow measures itself via a callback-refuseElementSizehook and switches between a responsive donut and a scrolling list/legend; widget expand-button, leaderboard row sizing, and target-member roster UX also polished (#2643). - AI document settings: new org-scoped
GET/PUT /api/v1/org/ai/drive-settings(sessionOrganizationId, Owner/Admin only, merge-write) backing a new identity-portal settings page for rename confidence, extraction confidence, and document categories (#2641). - AI catalog: extended to all 8 AU-resident Bedrock Claude inference profiles and corrected an Opus pricing row that had been charging retired-model rates (a 3x overcharge in the cost-governance ledger); all new models stay
IsDefault=falsepending SOC 2 subprocessor sign-off (#2638, #2644). Drive's AI extract/validate/rename prompts were also slimmed to reduce output tokens with the apply-vs-suggest behaviour unchanged (#2644). - Zipline Meet (native booking, Phase 0): tenant-scoped availability/booking domain, DST-correct slot computation, and anonymous booking/reschedule/cancel endpoints — ships behind a dark feature flag, not yet available to any account (#2632).
- Admin tooling: a new CEDA seeder (admin-portal, SuperAdmin-gated) seeds realistic broadcast demo data — templates, sent campaigns, paused journeys — with send-safety and determinism guarantees, for demos and QA (#2640).
More reliable Collect self-registration, instance-aware document merges, and a reliability sweep
This release makes self-registration links a lot more forgiving — nothing an applicant types is lost, and a visitor who never gets past the first question no longer leaves a stray deal behind. Documents that merge from a repeatable form (like a schedule of vehicles) can now pull a specific instance instead of always the first, and we've closed out a batch of account-settings and dependency fixes.
Client intake (Collect)
- No more throwaway deals — a self-registration link no longer creates a deal in your pipeline until the visitor actually answers their first question, so casual clicks and bots don't clutter your deals list.
- Answers that never get lost — Collect now queues every answer through a durable, offline-aware save queue that retries automatically across dropped connections, rate limits and page reloads, instead of risking silent data loss.
Forms and documents
- Instance-aware document merges — a merge field on a repeatable form (multiple vehicles, multiple employers, and so on) can now be pointed at a specific instance instead of always pulling the first one.
- Grouped product workflows (early access) — we've started rolling out a way to group a workflow's forms under a named "subject" for insurance-style renewal products, shown as a collapsible mini-step in Collect's sidebar. Early access only, not yet available for most accounts.
Reporting (Telemetry)
- Faster dashboard loads — KPI tiles and trend sparklines now run as a handful of grouped database queries instead of dozens per tile, cutting load time on a busy Telemetry dashboard.
Security and reliability (behind the scenes)
- Fixed: saving a brand colour or logo on the email branding page could silently revert on reload, or be wiped entirely by a stale browser tab.
- Fixed: rapidly clicking "Send Reset Email" on the forgot-password page could fire off several reset emails at once; error messages there are also friendlier now.
- Patched further vulnerable third-party libraries flagged by automated dependency scanning.
- Started laying groundwork to keep AI features hosted in Australia across multiple providers, and for an in-app Knowledge Base — both behind the scenes, not yet switched on for any account.
Technical details
- Collect self-registration: deal creation is now deferred to the first server write — anonymous
GET /preview+/preview/form/{id}endpoints render the first step from the publishedConfigurationVersionsnapshot with no deal, applicant, or token; the first answer single-flight mints the deal and the client reconciles onto the real magic-link context viahistory.replaceState(#2509). Follow-up hardening: pre-mint answers were landing in the reservedInstanceNumber == 0sentinel and being orphaned at mint, and the deal-mint remount was blanking in-progress fillers — both fixed, plus a full durable write outbox (sessionStorage-backed queue, transient-retry with backoff, bounded re-mint on a stale/expired token, bounded drop on a hard-rejected payload) so a Collect write is never silently lost (#2610). - Merge fields:
MergeFieldResolvernow carriesInstanceNumberthrough the submission projection, soform.{scope}.{formKey}#{n}.{fieldKey}resolves a specific instance on a repeatable form instead of always the first match; the aggregate grammar ([fn:field]) is unaffected. First-match ordering was made deterministic (ORDER BY InstanceNumber) after live verification surfaced a latent non-determinism (#2606). - Subject item type (early access, gated behind the dark
item_subjectfeature grant): newWorkflowItemType.Subjectgroups existing Form items under a shared config; renders on the Collect client as a nested, collapsible mini-step in the sidebar with an X/Y completion count rather than its own page; builder UI to author it ships in input-portal; cross-environment export/import remaps its workflow-local member/document refs and cross-formrequiredIfrule refs throughFormFieldFkValidator(#2620, #2622, #2623, #2626). - Telemetry:
TrendBucketingfolds Flow-metric (event count/sum) sparklines and Trends-widget series into one grouped-by-day query per family instead of one query per bucket, cutting a ~70–90-query cold-cache dashboard load; Stock and Average metrics are unchanged (#2589). - Fixed the email-branding
PUTwritingbrandColor/logoUrlunconditionally, wiping both on any request body that omitted them (a stale browser tab, or a pre-fix client); the endpoint now does a true partial update (#2602, #2618). - Fixed a double-submit race and unfriendly raw Firebase error strings on the forgot-password form (#2600).
- Dependency security bumps:
brace-expansion,postcss(#2617, #2621), plus a routine Dependabot patch bundle (#2609). - AI gateway: introduced a provider-neutral transport (
IAiProvider) so Vertex AI calls route through a swappable provider abstraction, plus a new AWS Bedrock provider federated via Google OIDC — groundwork to keep AI features AU-resident ahead ofgemini-2.5-flash's October 2026 retirement. Bedrock is provisioned in production but Vertex AI/Gemini stays the default until SOC 2 subprocessor paperwork clears (#2619, #2627, #2631). - Knowledge Base: seeded a new KB system app with five dark (
Verbs=0) view-only space features and a tenant-override/Firestore projection path; ships fully dark, no space is visible yet (#2624).
Sharper Broadcast dashboards and journeys, a refreshed templates list, and the first pieces of configurable dashboards
This release makes the Marketing Hub dashboard and journeys trustworthy at a glance, gives templates a proper sortable list, and fixes a batch of Collect and reporting rough edges. Behind the scenes, we've also started laying the groundwork for fully configurable, role-based dashboards and team targets in Telemetry — not yet switched on for any account.
Broadcasts and journeys
- Accurate dashboard numbers — the Marketing Hub dashboard's active-subscriber count now matches the contacts grid, and engagement/click-through rates now include journey sends as well as one-off broadcasts.
- Journeys on the dashboard — new Active Journeys and Active Enrolments cards, plus a live list of your busiest running journeys.
- Consistent enrolment counts — a journey's enrolled-contact count is now the same everywhere it's shown, and the enrolments table is a proper searchable, sortable, paginated grid instead of quietly stopping at 50 rows.
- Templates get a list view — templates default to a sortable list (name, type, subject, last updated) instead of a cards-only grid, and search now matches template names rather than incidentally matching text buried in the subject line.
- Fixed: sorting the contacts grid by Status or Source didn't actually reorder the rows.
Client intake (Collect)
- Fixed: the new applicant-selector field could show no options at all, regardless of how many applicants were on the deal.
- Fixed: on some workflows, a client could be advanced past the "who'll complete their part?" question for a co-applicant before answering it.
- Fixed: picking a date from the calendar could leave Continue stuck disabled when it was the last question on a page.
- Fixed: organisations using a custom Collect domain could fail to upload documents.
Reporting (Telemetry)
- Fixed a handful of Data Explorer and export rough edges: relative date ranges silently blocking Run, audit-log date filters erroring out, saved-query cards with a blank author, missing form-field columns, exports including hidden columns, and no warning when an export hit the 50,000-row cap.
- Configurable dashboards and team targets (rolling out) — we've started building fully configurable, role-based dashboards with drag-and-drop widgets, plus a targets sheet for setting per-person and team goals that dashboards can track progress against. Still behind the scenes — not yet switched on for any account.
Technical details
- Telemetry dashboards + targets foundation:
DesktopKinddiscriminator,DashboardRoleAssignment+MetricTargetentities (canonical RLS), a code-defined metric catalog across Deals/Funnel/CRM/Team/Forms families, a batch/widget-dataendpoint with per-item error isolation and a 2-minute cache, dashboard CRUD with role-assignment visibility, and aTargetsGridwith per-row advisory locking and optimistic-concurrency conflict resolution. Ships fully dark — every role×tier grant seeded atVerbs=0for both thedashboardsand separately-gatedtargetsfeature keys (#2286); post-merge hardening fixed empty breakdown widgets, gated team-leaderboard metrics off personal dashboards below Admin/Owner, and closed a targets concurrency bug where a stale token could silently clobber a peer's edit (#2551). - Marketing Hub dashboard: subscriber count now derives from
IsGloballyUnsubscribed(matching the contacts grid and list/segment filters) instead of the rawStatuscolumn; added journey KPI cards and a live running-journeys list; engagement/click metrics now spanJourneyEnrollmentLogsalongside sent broadcasts; replaced a fabricated audience-growth chart with a real 30-day cumulative series (#2536). - Journeys: list and detail pages now compute enrolment counts live from
JourneyEnrollmentsinstead of a drift-prone denormalized counter; builder test-run enrolments are excluded via a new first-classIsTestcolumn; the enrolments table moved to the platform's server-modeDataGrid(#2534). - Broadcast templates: default sortable
ZipDataGridlist view (Name/Type/Subject/Updated/Created) with a purerankTemplatessearch helper scoped to template name only; contacts-grid Status/Source column sorting fixed to use the same effective-status derivation as the dashboard (#2572, #2536). - Collect fixes:
ItemSection's inline Form branch now forwards the deal's applicant roster toApplicantSelectorFieldSlot(#2521); the co-applicant invite/proxy choice now commits atomically with the contact entry, via a newonCommitfield-renderer prop for date pickers (#2535, #2572); aBucketCorsPlannerworker reconciles GCS bucket CORS against active Collect custom domains every 60s (#2572); redundant token validation dropped from the anonymous/computeendpoint (#2515). - Data integrity: a
ReconcileOrganizationHierarchyDepthmigration repairs staleOrganization.HierarchyDepthrows found by a staging diagnostic, fixing mis-indented entries in the telemetry org-scope selector (#2573). - Telemetry fixes: relative date presets (7D/30D/etc.) now commit an explicit end date so Data Explorer's Run button unblocks correctly (#2556); starred queries refresh live in the sidebar on toggle (#2557); the audit-logs date filter no longer 500s under staging/prod's strict timestamp handling (#2568); saved-query cards fall back to "Unknown" for an author with no name set (#2569); form-field columns now render when customised, CSV export is scoped to visible columns, and exports over 50,000 rows show a capped-export warning (#2567).
Faster Collect card loads and a tenant-isolation hardening sweep
Collect's swipe-card questionnaire loads noticeably faster now, and we've closed out a further round of defense-in-depth tenant-isolation hardening behind the scenes.
Client intake (Collect)
- Faster card loads — the swipe-card questionnaire now loads its images and workflow data in parallel instead of one at a time, cutting several seconds off the load for image-heavy forms.
Security and reliability (behind the scenes)
- A further tenant-isolation hardening pass tightened cross-organisation guards on several deal, document and annotation lookups. No live data exposure was found — these are defense-in-depth fixes that make the checks explicit rather than implicit.
Technical details
- Collect performance:
FormFieldImageUrlResolvernow fans its per-imageGetDownloadUrlcalls out withTask.WhenAllinstead of a serial loop (#2513); workflow snapshots are now cached perConfigurationVersion, andGetDealFormTemplateQuery's deal lookups gained guardedOrganizationIdfilters plus a token-resolved org threaded through the Collect dispatch path (#2503). - Org-isolation audit remediation (Findings 2, 3, 4, 5, 7): added explicit
OrganizationId/DealIdguards toComputeFormFieldsQuery,ClientGetLiveDocumentStateQuery,ClientSaveLiveDocumentCommand, andDealAnnotationCommands's snapshot resolution, with new discriminating regression tests inOrgIsolationAuditTests(#2508).
An applicant-picker field for forms, richer Collect summaries, and broadcast targeting fixes
This release adds a way to point a form question straight at one of the deal's applicants, gives Collect's summary steps more control over ordering and filtering, and fixes a handful of issues affecting who broadcasts reach and how workflow steps complete.
Forms
- Applicant selector field — a new field type lets a form question reference one of the deal's applicants directly, instead of re-entering their details by hand.
- Fixed: a per-applicant step summarising totals or counts from a shared, deal-wide form could wrongly show as unanswered, sometimes blocking the step from completing until the applicant re-entered data that was already there.
Client intake (Collect)
- Reorder summary sections — drag summary sections into the order you want them shown to the client.
- Filter what appears in a summary rollup — set a rule so a repeated-item summary only lists the instances that match, such as just the primary applicant's answers.
- Fill in missing forms from the summary — an empty "add" slot in a summary can now link and create the missing form in place, rather than sending the client elsewhere first.
- Fixed: navigating back could skip past a summary step you'd already acknowledged instead of returning to it.
Broadcasts
- Fixed: broadcast filters and saved segments now agree with the contacts grid on who's unsubscribed, so an unsubscribed contact is reliably excluded from sends regardless of how they were unsubscribed — CSV import, a merged contact, or a broadcast unsubscribe link.
- Fixed a data-visibility gap where workflow-preview and not-yet-completed self-registration contacts could appear in Broadcast audiences when they shouldn't have.
Security and reliability (behind the scenes)
- Patched several vulnerable third-party libraries flagged by automated dependency scanning across ZiplineOS's portals.
- Fixed: submitting a malformed organisation ID returned a raw technical error instead of a clean error response.
Technical details
- ApplicantSelector field type (forms enum #23): backend round-trip, an
ApplicantPickerwidget in shared-ui (slot-backed canonical field), form-builder + FormFiller (input-portal) + magic-link filler (Collect) rendering, and applicant-name(s) formatting in review/summary (#2494). - Collect/Input summary work: drag-to-reorder summary sections; per-section instance-filter authoring, validation (same-form field references only) and evaluation; an add-slot that materializes a hosted item atomically with the summary item on the same step, with a sibling-order fix so display order stays deterministic; a summary-editor remount keyed by item id to avoid stale drag-reorder state; a back-nav fix for returning to an acknowledged summary; and a cross-org export/import fix stripping a redundant
formTemplateIdleft inside serialized instance filters (#2497). - Workflow aggregate fix:
GatherFormInstancesno longer skips Shared (null-ApplicantId) submissions when resolving a PerApplicant item's aggregate rule over a Shared form, aligning it withResolveFormElement's scalar-fallback behaviour (#2491). - Broadcast contact-visibility fix: the raw-SQL
ContactVisibilitySqlfragment now matches the LINQApplyContactVisibilityhelper'sDealApplicant.IsDeletedhandling, closing a leak where a contact with a soft-deleted applicant link to a live deal was hidden in CRM but visible in Broadcast segments (#2479, #2480, #2486). - Broadcast status-filter fix: list/segment filters and the contacts grid now derive contact status through a shared
ContactStatusFilterSql.EffectiveStatusExpressionthat folds inIsGloballyUnsubscribed, instead of comparing the rawStatuscolumn; removed the non-functional bounced/complained filter options (that state lives inSuppressionEntries) and short-circuited stale saved filters referencing them (#2492). - Dependency security sweep: a semver-safe lockfile refresh across 18 manifests (axios, websocket-driver, brace-expansion, js-yaml, protobufjs and others), plus a follow-up
immutablebump in ideas-portal (#2484, #2489). - Malformed
organizationIdroute/query values now return a 400 instead of an unhandled 500 (#2483).
An in-app AI assistant (early access), smarter broadcast campaigns and step-level form rules
Two big themes in this release. Broadcasts and journeys gained a proper set of campaign controls — cleaner unsubscribe handling, pause-safe timing and one-click duplication — while forms gained rules that can hide or skip whole steps, not just individual questions. Underneath, we've begun rolling out an in-app AI assistant and a document autofill that reads an uploaded file and pre-fills a client's form. Several of these are being switched on gradually, so they won't all be visible in every account yet.
Broadcasts and journeys
- Campaign-ops tools for journeys — journeys now show clear status badges on each step, honour a suppression list so exited or unsubscribed contacts stop receiving messages, keep scheduled delays safe across a pause, and can be duplicated in one click to reuse as a template.
- Cleaner unsubscribe handling — an unsubscribe now records where it came from, and its links open in your own Collect portal (with custom-domain support) rather than a generic page.
- More reliable sends — broadcast templates now keep their title and subject through an edit, the contacts filter's Clear applies straight away, and message-delivery tracking was made robust across environments.
Client intake (Collect)
- AI document autofill (rolling out) — a client can upload a document and have the matching form fields read out and pre-filled for them to check, instead of retyping. Being switched on progressively.
- A brand-asset library so your logos and images are kept in one place for reuse across intake.
- Summary steps now roll up repeated sub-forms into one tidy review, and a deal's logo is now placed automatically — one less setting to manage.
Forms and workflows
- Step-level rules (rolling out) — a rule can now hide or skip an entire step, not only individual fields, so a workflow adapts to each applicant's answers. Rolling out gradually.
- Rules are now applied per applicant on shared forms, and conditional fields cascade correctly as answers change during a live fill.
- A batch of form-editor fixes — clearer validation messages, help text now flows through to AI extraction, and several display and accessibility fixes.
Contacts
- Contact import (rolling out) — import a contact list from a spreadsheet, with new custom fields created automatically from the columns and subscription status carried across. Being granted to accounts progressively.
AI assistant (early access)
- An in-app AI assistant has started rolling out behind the scenes — read-only to begin with, and off by default until it's enabled for an account. It isn't switched on in general accounts yet.
Technical details
- Journey campaign-ops: suppression-list exits, per-node status badges, pause-safe delay recomputation and a journey-duplicate action; read-only builder nodes (xyflow draggable/connectable disabled) and a shared
ActivateJourneyAsyncpath behind both/activateand/resume(#2453, #2409, #2396). Deliverability fixes: register Mailgun webhooks at the request's env host (not a hardcoded staging URL), use the global Mailgun signing key, and Cloud Armor bypass rules for send + inbound campaign webhooks (#2414, #2417, #2416, #2415). Broadcast template Title/Subject retention and immediate contacts-filter Clear (#2472, #2430). - Collect AI document autofill:
/statusfilename surfacing, a replace-clobber value-drift fix and a merge path that never overwrites user input, plus a tenant-scoped brand-asset library (#2401). Summary item rolls up selectable nested forms flattened, automatic logo placement retiring thelogoPositiondropdown, and broker merge-token rendering in client copy (#2474, #2467, #2435). - Workflow step-level rules shipped in two slices — Slice A author + persist (behaviour-neutral) and Slice B runtime hide + skip-for-advancement — with scope-aware rule references (per-applicant selectable, Shared→PerApplicant guard) and per-applicant resolution at the completion gate;
containstreated as element membership for array answers, any-instance gating over repeatable nested forms with fail-open on unresolvable sources, and cascade of conditional visibility on live-fill (#2454, #2461, #2463, #2473, #2434, #2432, #2464). Form-editor fixes: blank-label validation, Toggle visibility-rule guidance, accessible dropdown labels, background-error on page load, help text into AI extract (#2413, #2350, #2349, #2348, #2469). - Contact import: typed custom-field auto-creation with an import migration seeded
IsActive=true, Verbs=0(dark by default, granted via the kernel feature-grants matrix), per-ObjectTypeRequireAsyncendpoint gating authorised by grant rather thanPlatformRole.SuperAdmin, and subscription-status import (#2428, #2451, #2476). - AI copilot Phase 0 + Phase 1: a gated read-only copilot with two-phase writes/planner behind a three-nested-gate access model (an
AiCopilotEnabledkill switch, anai-copilotkernel feature-grant, per-tool gating), served from a separate Cloud Run service with SSE-safe LB routing — all dark by default (#2425, #2424).
Bring-your-own domain for client intake, portable Card Packs and a security-hardening sweep
Client intake took a big step this release: you can now serve Collect on your own domain, and the discovery-card questionnaires can be packaged up and shared between accounts or reviewed by the broker back in the deal. Alongside the new features, a broad security-hardening pass landed behind the scenes.
Client intake (Collect)
- Bring your own domain — run the client-facing Collect portal on your own web address rather than a shared one, so the whole intake looks like your brand. Being configured per account.
- Discovery-card viewer for brokers — the swipe-card answers a client gives now appear back in the deal workspace for the broker to review at a glance.
- Card Packs are portable — export a set of discovery cards as a single file and import it into another account, so a good questionnaire can be reused.
- A cleaner fill experience — a read-only summary review with a link straight to the item to change, tidier navigation between steps, and swipe-only cards on mobile.
Broadcasts and journeys
- Verified sender identity — broadcasts now send from a verified domain with aligned DKIM, which improves deliverability and trust.
- Pause, edit, resume — pausing a journey lets you edit it, and pressing Resume publishes your edited version rather than the old one.
- Steadier automation — fixes to journey triggers, wait timing, conditions and the events view, so enrolments aren't dropped when several contacts are added at once.
Security and reliability (behind the scenes)
- A security-hardening sweep — stronger sign-in and access checks, safer handling of user-supplied content, HTTP hardening headers, and stored credentials moved into managed secret storage.
- An accessibility pass across the CRM and intake portals.
Technical details
- Collect bring-your-own custom domain (host-first resolution + frontend, Phases 1–2) with follow-up fixes (auto-poll, 503, self-registration domain picker), env/IAM for a scoped Cert Manager, edge URL-map matching all hosts, and CORS admitting the bare Collect apex origin (#2352, #2378, #2371, #2386, #2389, #2385, #2394, #2392). Discovery Cards broker-side response viewer in the deal workspace, Card Pack export/import as a portable zip with a temp-zip lifecycle rule, Summary-item read-only review (navigate-to-source + inline add slot), and mobile swipe-only discovery cards (#2370, #2379, #2382, #2372, #2395).
- Broadcast sender-identity gating (verified-domain From + DKIM-aligned send), journey pause-then-edit resume publishing the edited draft, a fix for journey triggers dropping enrolments on multi-contact list/segment adds (shared-DbContext race), a broadcast + journey fixes bundle (webhooks, waits, conditions, events UI), and a journey email bot-engagement filter (#2298, #2302, #2318, #2338, #2383). A telemetry Data Explorer (source-registry engine, goal-named data sources, sub-tenant scoping, full feature-gating) began rolling out behind a grant (#2303, #2321).
- Ziplock security hardening: verify Google OIDC token on the internal task endpoint (auth-bypass), validate
returnUrlbefore the SSO-token redirect (zero-click token exfil), an access-control / XSS / SQLi / rate-limit batch, HTTP hardening headers (ZAP baseline), rotate committed credentials + Slack webhooks into Secret Manager, aSanitizedHtmlsink enforcing adangerouslySetInnerHTMLban, an ESLint ban on rawfetch(), and chrome-extension regex-metacharacter escaping (#2295, #2311, #2304, #2290, #2300, #2313, #2315, #2312). Portal-local accessibility sweeps for the CRM and input portals (#2316, #2317).
Security hotfix — stronger sign-in verification
A small, security-focused release. It strengthens the way a sign-in session is verified before it's issued, so every session is confirmed against the identity provider first.
Security and reliability (behind the scenes)
- Hardened sign-in — a session is now verified against the identity provider before it's issued, closing a gap in how sign-in tokens were checked.
- Added an automated security-scanning step to our release pipeline, so new builds are checked for common issues before they ship.
Technical details
- Verify the Firebase ID token before minting a session (critical auth-bypass fix) and an advisory ZAP DAST baseline scan added to CI (Ziplock E15) (#2293, #2287).
Rolled-up form summaries, a smarter auto-fill extension, and an email-security sweep
Repeated form data — applicants, properties, income sources — is now far easier to read at a glance: it's collated into tidy, labelled tiles with running totals instead of a long repeated list. The browser extension can now be taught brand-new fields rather than only corrected on ones it already knows, and a broad email-safety pass landed underneath. Behind the scenes we've also laid the groundwork for branded deal PDFs, a new client-intake summary step and billing safeguards, all rolling out progressively.
Form summaries and rollups
- Multi-instance summary tiles — where a form is filled out more than once, the deal view now gathers every entry into clean, owner-labelled tiles with a group total, so a set of applicants or properties reads as an at-a-glance summary rather than a long list.
- A new Summary field you can drop into a form — a read-only rollup that totals every entry of a chosen form into one table, with a link straight to each underlying entry to edit it.
Browser extension
- The extension can now be taught brand-new fields, not just corrected on the ones it already knows — point it at a field on the page, preview what it captured, and confirm to save it. Its mapping self-heals as sites change, so auto-fill keeps working without a rebuild.
Security and reliability (behind the scenes)
- A sweep of email-safety fixes — contact names, custom fields, email signatures and invitation, welcome and secure-link text are now safely encoded everywhere they're placed into an outgoing email, so stored content can't run in a recipient's inbox.
- Tightened access checks on shared idea boards, so a private board can no longer be read, overwritten or copied by someone who isn't a member.
- Fixed a bug where publishing a workflow could drop newer item settings (such as delays, card decks and summary tiles) while merging changes.
On the way (rolling out progressively)
- Deal PDF export — generate a branded PDF of a deal's collected information, with named templates and separate internal and client-facing versions. Being switched on gradually, so it isn't visible in every account yet.
- A Summary step in client intake (Collect) that rolls several forms up into review tiles with an acknowledge-to-continue gate.
- A payment-method safeguard that asks for a saved card before an organisation adds billable users.
- Bank-statement retrieval in Collect, so a client can share their statements straight into their file.
Technical details
- Input-portal multi-instance rollups: a
MultiInstanceTileConfigjsonb onWorkflowItemdrives adaptive fact-chip tiles with owner labels and a group total in the deal view; the config is validated (field-key + money-type, cross-organisation keys rejected), round-tripped through the portable workflow document, and surfaced on everyWorkflowItemDtoprojection so it renders after a save (#2257,AddMultiInstanceTileConfig). - A new display-only
FormFieldType.Summaryrollup field (FormField.SummaryConfigJson) totals every already-collected instance of a source form viaGET /api/v1/deals/{id}/form-summary(organisation- and deal-scoped,InstanceNumber > 0) with a deep-link-to-edit seam; the embeddedsource.formTemplateIdis FK-validated on every FormField write path and threaded through portable export/import and the frozen snapshot (#2249,AddFormFieldSummaryConfigJson). - Browser extension Teach→Profile: an additive
POST /platform-profiles/{id}/fieldsmerge endpoint plus a field-scoped value-mapPUT(retiring the clobber-prone full-blob replace), DevExtreme-aware target/type derivation, and a capture → preview → confirm flow so maintainers can add brand-new field mappings, not just edit existing ones. Requires anextension:writetoken; the extension is published out of band and version-coupled to this backend (#2237). - Email stored-XSS hardening (four sibling sinks outside
MergeFieldService): an opt-inhtmlEncodeon merge-field substitution wired to the HTML send paths;EmailRenderingServicenow sanitises the user-authored email signature it previously embedded raw; invitation, welcome and magic-link builders HTML-encode their free-text fields; and the identity-portal signature preview runs through DOMPurify (#2262, #2264, #2266, #2261). - Reliability:
WorkflowPublisher.ApplyItemFieldsno longer strips the five newerPortableItemfields (ExecutionTrigger, AppliesToSources, DelayConfig, CardDeckConfig, MultiInstanceTileConfig) on RC publish / merge materialise, now guarded by a reflection parity test; Ideas-board snapshot load / save / duplicate enforce board membership (private boards no longer leak to non-members) and snapshots are pruned to the newest 20 per board (#2271, #2274). - Dark-launched foundations, all seeded with
Verbs=0so no organisation sees them yet: deal PDF export behind thedeal_pdfINPUT grant — a QuestPDF assembler, an asyncDealPdfExportpipeline, per-workflowWorkflowPdfTemplatepacks with Internal/External audience filtering and anIncludeInPdfper-item eligibility gate (#2282,AddIncludeInPdfToWorkflowItem,AddDealPdfExport,AddWorkflowPdfTemplate,AddSuppressEmptySectionsToPdfTemplate); a Collect Summary workflow item behinditem_summary(WorkflowItemType.Summary+SummaryConfig, with DB-backed reference validation) (#2272,AddWorkflowItemSummaryConfig,AddInputItemSummaryFeature); a payment-method gate (BillingPaymentMethodRequired, default off) returning HTTP 402 at the seat-consuming entry points (#2273); and CashDeck organisation-scoped bank-statement retrieval with webhook ingestion into Drive (#2247). - Platform and admin: SuperAdmin-only manual Airwallex customer linking from the kernel organisation page (link / re-link / unlink with orphan-subscription guards, every change audited); the feature-grants Phase 2 tenant-overrides matrix and batch endpoint plus the Phase 3 grant-history restyle; and the dead
AllowExternalFillworkflow-item flag was retired (#2270, #2259, #2260, #2253,DropWorkflowItemAllowExternalFill).
Redesigned Deals workspace, sharper AI summaries and a security-hardening sweep
The Deals page has been rebuilt around the way you actually work a pipeline — one place to switch between board, table, timeline and calendar views, filter by referrer, and focus on just your favourites. Alongside it, the AI deal summary now reads your uploaded documents, the browser extension tells you exactly what it filled, and a broad security-and-reliability pass landed underneath.
Deals workspace
- A redesigned Deals page — cleaner header, toolbar and deal cards.
- Four ways to see your pipeline — Board, Table, Timeline and Calendar — switchable from a single control, with a board minimap for navigating large pipelines at a glance.
- Filter by referrer and "Show favourites only", now applied on the server so they stay fast and consistent as you page through deals.
- The view switcher is fully keyboard accessible.
AI deal summary
- The AI deal summary now also draws on data AI has extracted from uploaded documents, not just typed form answers — so the summary reflects what's actually in the client's paperwork.
Browser extension
- Per-field feedback when auto-filling — see at a glance which fields were filled, skipped or failed.
- An advisory warning when the applicant you're filling for doesn't match the deal's active applicant, so you catch a mismatch before it lands.
- Smarter dropdown matching — option lists and value mappings are reconciled and normalised, so more fields populate correctly the first time.
Fixes and polish
- Fixed a bug where a saved delay setting on a workflow item could abort saving a form submission.
- Client-intake (Collect) magic links and the browser-extension API stay reliable now that tenant isolation is enforced end to end.
Security and reliability (behind the scenes)
- Personal information and secrets are now automatically masked in every server log through a single central safeguard, rather than relying on each log line to sanitise itself.
- Resolved a batch of code-scanning findings — regular-expression denial-of-service and cross-site-scripting hardening, including rendering footer links and logo previews through normalised URLs.
- The admin/kernel console is now restricted to platform super-admins.
- Continued supply-chain and CI hardening across the build pipeline.
Technical details
- Input-portal Deals redesign: a rebuilt Deals page (header, toolbar, card cleanup) with a SegmentedViewSwitch across Board / Table / Timeline / Calendar, a Kanban minimap, a referrer filter, and a server-side
starredOnlyfavourites filter; the UpdateDeal response now populates PrimaryApplicantName, CurrentStepStageType and CreationSource so cards render fully after an edit; deal-card initials were consolidated into a shared avatar util (#2199, #2203, #2211, #2212, #2213, #2214). - A new Card Deck / SwipeDeck system (shared-ui, input and client portals) ships dark behind the
item_card_deckINPUT feature grant — the backing migration seeds the feature and role grants with no verbs, so no organisation sees it yet; it is foundation work rolling out progressively (AddInputCardDeckFeature). - The AI deal summary prompt now includes AI-extracted document data in addition to completed-form answers, and refreshes stay current as those inputs change (#2219).
- Chrome extension: per-field populate feedback (filled / skipped / failed), an advisory active-applicant reconcile warning, and dropdown-vocabulary reconcile with value-map match normalisation; multi-instance sections drop the legacy " #N" suffix in favour of underlying instanceNumber / dealApplicantId fields. The extension is published out of band and is version-coupled to this backend; existing tokens must be re-minted for the tightened
extension:writescope (#2230, #2231, #2232). - Ziplock D1 safe-logging chokepoint: a LogScrubbingEnricher runs on every Serilog event to strip control characters and mask PII/secrets centrally, on both logging pipelines (#2114).
- Security hardening: ReDoS and cleartext-log CodeQL alerts resolved, footer-link and logo-preview DOM sinks fed normalised/parsed URLs, an eslint no-unsanitized rule added, plus Trivy (IaC + image) scanning and a zizmor GitHub Actions static-analysis gate (#2233, #2215, #2234, #2227, #2218).
- Access control and tenant isolation: the kernel/admin portal is restricted to
PlatformRole=SuperAdminvia a new guard plus an/app-productsfilter; API-token principals now stamp tenant by GUID id so extension requests work under row-level security; Collect magic-link loads stamp the token's org and re-assert the soft-delete filter so links resolve when RLS is on (#2182, #2210, #2098, #2108). - Form templates gained a
Kindclassifier (Form=0 preserves existing semantics) as groundwork for distinct template types; the migration is additive and backward-compatible (AddFormTemplateKind). - Further fixes: a JSONB DelayConfig filter no longer aborts form-submission saves; per-session port offsets are applied to portal iframe URLs for multi-session local dev; and an admin tenant-overrides matrix UI with a batch endpoint plus a grant-history restyle landed (#2207, #2200, #2206, #1698, #1699).
- Platform / CI: GitHub PRs sync to Jira with draft-aware status, deploys treat an idempotent Firebase no-op release as success, and dependency/action bumps (actions/checkout v7, cache v6, setup-go v6) landed alongside a production-deployment runbook for the
prod-released..mainrange (#2226, #2252, #2255).
Multi-applicant client intake
When a deal has more than one applicant, client intake (Collect) now guides each person through their own part — organised into clear, sequential sections, with the option to invite a co-applicant to complete their details themselves while everyone else keeps moving.
Multi-applicant intake (Collect)
- Intake now splits into ordered sections — shared (joint) sections plus a section for each applicant — instead of one long interleaved form, with each section unlocking once the one before it is complete.
- For each co-applicant's section the primary can choose "I'll do it" and fill it in themselves, or invite the co-applicant to complete their own part through their own secure link — so two people can work on the same deal at the same time.
- An invited section shows live progress (for example, "Waiting on Jane — 1/3") and can be reclaimed at any time, keeping anything already entered.
- A completion review before submitting confirms every applicant's required sections are done.
- Each applicant's section pages through one question at a time, the same focused flow single-applicant deals already get.
Forms and workflows
- The workflow Documents tab now supports drag-and-drop and multi-file upload, with a single dialog to bulk-apply a category, description and "required" flag across the files — or edit each one before uploading them in a batch.
- A cleaner default form builder and workflow editor: advanced and power-user controls (field key, indexed and searchable toggles, JSON export, default entry steps, manual-creation form) can now be switched on per organisation rather than shown to everyone.
Deals
- The AI deal summary now refreshes automatically when something it reads has changed — form answers, stage, applicants or item progress — so the summary on the Summary tab stays current without a manual regenerate. It updates quietly in the background and never blanks the card.
Fixes and polish
- Form questions with both a minimum and a maximum now enforce both — previously a value over the maximum could slip through — and validation messages no longer show a stray "null".
- Desktop and sign-in background images are now served by ZiplineOS itself instead of a third party, so they load faster and reliably, with automatic recovery if a saved background ever goes missing.
Technical details
- Multi-applicant Collect renders as sequential, per-step sections computed from the deal's applicants: consecutive shared items stay in place as a shared section, and per-applicant runs expand to one section per applicant (primary first). Sections hard-lock until the prior blocking sections are complete; an invited (delegated) section is non-blocking and shows live progress derived from the fill context, with a reclaim affordance. Each applicant section reuses the single-applicant one-item-per-page pagination, and the single-applicant flow is unchanged.
- Co-applicant invites use the existing per-applicant magic link, so both parties write to the same deal in parallel (last-write-wins per item). Underneath, a hardened FillGrant primitive landed across seven phases — a tenant-scoped entity with its own row-level-security policy, SHA-256-hashed scoped tokens and an anonymous fill endpoint behind a single scope guard, an explicit lifecycle (issue / revoke fence / reclaim / decline / lock-on-submit), completion gating with per-applicant progress, email invites with reminders and bounce handling plus landing-page consent, and per-section delegation for non-applicant helpers (for example an accountant). It is rolling out progressively behind the scenes.
- Workflow template documents gained a drop-anywhere upload zone and multi-select, a unified Add Documents dialog with a tri-state bulk "required" control, partial-failure-safe batch upload through the shared file pipeline, and an extracted dropzone hook.
- Form-builder question advanced options and workflow-editor power-user controls were placed behind dark INPUT feature flags (advanced field options, field-key edit, indexed and searchable; workflow entry steps, manual-creation form, and JSON export), each registered in the capability provider so platform staff can enable them per tier × role from the kernel feature-grants matrix; JSON export is also enforced server-side.
- The AI deal summary auto-refreshes on landing when its source fingerprint (form answers, stage, applicants, item progress — not notes or emails) changes; refreshes run in the background, keep the stale text on screen with an "Updating…" hint and cross-fade the new text in, and fail quietly so a transient error never blanks the card.
- Validation: every numeric bound (length, range, selections, nested-cardinality, file constraints) now coerces through the same number / numeric-string handling as submitted values, restoring backend ⇄ front-end parity so minimum and maximum both enforce; unset (null) bounds are treated as unset, so messages no longer read "null"; sub-form-within-a-sub-form nesting is suppressed with a warning when linking.
- Security and maintenance: cross-organisation form-template references inside form and workflow visibility rules are now validated before saving; the deprecated marketing-site app was removed; dependency security updates were applied across portals (undici, dompurify, axios, vite, react-router and others); and SOC 2 / Vanta evidence, a disaster-recovery tabletop template and an over-privileged service-account split landed as part of ongoing security hardening.
- Desktop and sign-in backgrounds moved to ten self-hosted, same-origin images with a stable per-day rotation, a blob cache that now actually populates, and self-healing for dead or stale background URLs; legacy third-party URLs saved in settings fall through to the stock set.
Form archiving and new display formats
Quality-of-life updates to forms — tidy up your form list, show answers in more useful formats, and build richer conditional logic.
- Archive forms you no longer use, and restore them later, to keep your active form list clean.
- New display formats for questions — amount with a frequency (e.g. "$X per month") and a number with a unit.
- More conditional-logic operators for form rules, including "does not contain" and additional numeric comparisons.
Technical details
- Forms list gains Archive / Unarchive actions. Archived forms drop out of the active list and out of the form pickers used when assembling a deal, so they can't be attached by mistake — they stay fully restorable, and any submissions already captured against them are left untouched.
- Two new display formats: an amount paired with a frequency (e.g. "$X per month") and a number paired with a fixed unit. Both are presentation-only — the underlying stored value doesn't change — so existing answers re-render in the new format automatically, and the format is identical across the form-builder preview, the client intake (Collect) and the deal view.
- Form-rule evaluation gained a
notContainsoperator plus additional numeric comparisons. They're available both in a form's show/hide visibility rules and in the rule builder, and the builder preview now matches live form evaluation exactly, so what you see while authoring is what the client gets. - Ongoing behind-the-scenes work on reliability, security and deployment monitoring.
Self-service billing and unified Contact Profiles
Two major additions: a self-service billing area with secure card payments and invoices, plus Contact Profiles that build a single, up-to-date picture of each client across all of their deals.
Billing
- A new Billing area with a clear account overview.
- View and download invoices as PDFs, including one-off invoices.
- Pay securely by saved card.
- Automated payment reminders and access handling for overdue accounts.
Contact Profiles
- A Contact Profile that consolidates a client's details gathered across multiple deals.
- Suggested profile updates are routed to a broker for review before they're applied — nothing changes automatically.
- Cross-deal matching keeps a client's information consistent everywhere it appears.
Forms and intake
- Live, as-you-type formatting for number, money and phone fields.
- Type-aware formatting of values across both the intake and deal views.
- A new Entity Reference question type that links a question to another form submission.
- Nested-form history coverage — keep adding entries (such as address or employment history) until a required number of years is covered.
- Mark forms and fields as internal-only.
- Client intake (Collect) layout fixes: removed unwanted horizontal scrolling, and validation errors now appear inline.
Technical details
- Billing redesigned into a ledger-style hub; invoice list and PDFs read from the live payment provider; saved-card capture via embedded secure card elements; one-off / ad-hoc invoices and proration on signup; dunning and access-restriction policy for overdue accounts (rolling out progressively).
- Contact Profile: a profile-core data model, a promotion pipeline that draws from deal data, cross-deal item matching with delta routing, and a broker review / apply / remove surface in the CRM portal.
- Number, money and phone fields format live as you type and according to their type across portals; compact option grids size dynamically so option text is never clipped.
- New Entity Reference field type (targets a form submission); nested-form temporal coverage; internal-only toggle for forms and fields; surfacing of all field-value validation errors inline.
Deal Workspace, AI management and Document Intelligence
A redesigned Deal Workspace, a central control plane for AI features (including spend controls), and AI-assisted document analysis.
Deal Workspace
- A redesigned deal view with a Summary tab and an AI Deal Summary.
- New workflow views — Detailed, Checklist and Board — plus Focus and Compare modes.
AI management and cost controls
- A central place to manage AI processes and tailor them per organisation.
- Prompt management with versioning and promotion.
- An audit trail, dashboards and alerts for AI activity.
- Cost controls — spend estimates and configurable spend limits.
Document Intelligence
- AI-assisted document analysis, with an extraction preview built into the deal's Documents area.
Forms and intake
- Modern calendar date and date-time pickers for date questions.
- Validation improvements — ABN format checks, numeric minimums and maximums, and cleaner number entry (no spinner arrows or accidental scroll-to-change).
- "Required later" file requests are gathered in the Documents section.
- A new comprehensive Australian mortgage fact-find form template.
- Transactional emails now read as plain, personal messages.
Technical details
- Deal Workspace Phase 1 (Summary tab plus an AI Deal Summary that includes completed-form answers) and Phase 2 (workflow redesign — Detailed / Checklist / Board with Focus and Compare).
- AI control plane: a process registry, per-organisation overrides and matrix, a unified prompt subsystem with versioning and promotion, an audit trail with dashboards and alerts, and a cost-limit admin UI backed by spend estimation and real-time enforcement.
- Document Intelligence: a category registry with CRUD, gateway infrastructure, an extraction pipeline with live analysis, and an AI preview drawer in deal Documents.
- Form questions use calendar date/time pickers; ABN and numeric min/max validation; "required later" file handling; contact-selection questions can be tied to an applicant role; new comprehensive AU mortgage fact-find template.
AI Fact-Find and smarter intake forms
Introduces AI Fact-Find — automatically draft answers from uploaded documents — alongside a wave of client-intake form improvements.
AI Fact-Find
- AI Fact-Find reads uploaded documents and drafts answers to your fact-find, which you review and apply before anything is saved.
- Configurable per organisation (enable or disable, and set a confidence threshold) from Admin settings.
Intake forms
- Richer question display modes, including grid layouts for dropdown and multi-select questions, shown consistently across the builder preview, intake and nested forms.
- Automatic page breaks between forms for a cleaner, step-by-step flow.
- A Back button alongside Continue in the form filler.
- The Add button moved below the cards in multi-instance and nested forms, with instant add and delete.
- Stronger completeness checks for nested and multi-instance forms.
- Answers are only flagged invalid once you leave a field, and clear the instant they become valid.
Deals
- The Lead-stage swim lane is hidden from deal views unless it's been granted.
Technical details
- AI Fact-Find delivered across five phases — foundations, ingest / digest / orchestration, a per-form guard-railed extraction loop, review-and-apply, and the input-portal front end — with an Admin settings card (enable, confidence, model) and a progressive rollout behind a kill-switch.
- Forms: all display modes render in builder preview, intake and nested forms; dropdown and multi-select default to grid display; implicit, mandatory page breaks between intake forms; a back button; the add button below cards; optimistic multi-instance add and delete; nested and multi-instance completeness enforcement; answers validated on blur and cleared when valid; step auto-advance skips items hidden by visibility rules.
- Security: dependency security updates applied across portals.
Form presentation controls and intake polish
More control over how each question is presented, plus visual polish in the client-intake (Collect) experience.
- Per-field presentation controls now live in the form builder, so you decide how each question looks.
- A slider option for money questions.
- Visibility rules are now fully portable — a form's show/hide logic behaves the same wherever the form runs.
- Collect polish — cleaner header and footer spacing, and the organisation name is hidden when a logo is shown.
Technical details
- Per-field question presentation options moved into the form builder, so the look of each question is set where the question is authored rather than configured globally; money questions can additionally render as a draggable slider instead of a typed amount.
- Visibility (show-when) rules made portable across environments by keying them to stable field identifiers rather than positions, so a form's show/hide logic behaves the same wherever the form runs; stale display-hint overrides are recovered by unique field key during backfill.
- Collect (client intake) reserves the top and bottom spacing even when the header or footer is hidden, so the layout no longer jumps; the organisation name is suppressed when a logo is present to avoid showing both at once.
Smarter validation and a rebuilt mobile intake
A new validation engine that checks answers consistently as they're entered, plus a ground-up rebuild of the form-filling experience on phones and tablets.
Validation
- A new validation engine checks each answer against its question type — text, number, email, phone, date, selection, file and nested forms — consistently across the form-builder preview, client intake and deal views.
- Built-in checks for Australian postcodes, valid phone numbers, and required acceptances (such as ticking a consent box), plus contact-role rules.
- Errors show in a live preview while you build the form, so what you author is what the client sees.
Mobile and tablet intake
- A rebuilt mobile form-filler — the Continue button stays docked to the bottom of the screen, the page no longer jumps on load, and sizing is correct on iOS.
- Smoother paging between forms and steps on small screens.
Technical details
- InputValidationV2 shipped across phases — engine scaffolding and editor shell, a workflow-merge lift and read-DTO surface, then the parity-tested engine with submit-path and renderer migration, followed by per-cluster authoring UIs (text / numeric / email / phone, dates, selection, files and nested forms) each with a live preview.
- Rollout was gated end to end: registered as a capability, enabled per organisation behind a runtime gate, then flipped on globally behind a kill switch once parity tests passed.
- Validation additions: AU postcode and phone-number format checks, a "must be true" acceptance type for consent, contact-role validation, and type guards for computed defaults and bound fields.
- The mobile form-filler was rebuilt around the visual viewport — a sticky Continue dock pinned to the keyboard-aware height, document-scroll lock, each next page opening at the top, and iOS / tablet sizing fixes. Collect also moved to SEO-correct edge routing.
Formulas, merge fields and repeatable forms
Forms can now calculate values, reuse answers across repeated sections, and render the right number of copies automatically.
- A new Formula field — a read-only, calculated value derived from other answers that you can drop into merge fields and documents.
- Formula values on PDFs — calculated figures can be stamped onto generated documents.
- Aggregate merge fields for repeatable forms (for example, totalling across every entry), with the merge-field picker now finding fields across nested forms.
- Repeatable forms by cardinality — intake renders the right number of form copies automatically, such as one per applicant.
- A read-only Display (Message) question for adding instructions or notes inside a form.
- Per-document sending for signing, with reactions and clearer invalidation when something changes.
- A refreshed disclaimer checkbox.
Technical details
- Formula form-field type — numeric, read-only, with merge-field interpolation — plus a Formula PDF-annotation type that replaces the old form-field formula and stamps computed values onto generated PDFs.
- Aggregate merge fields for repeatable forms, with recursive form discovery and de-duplication in the merge-field picker.
- Cardinality-driven multi-instance rendering, per-card Continue, final-form completion and a branded done view.
- Read-only Display (Message) question type for the collect portal; per-document send for signing with reactions and directional invalidation operators; disclaimer-checkbox redesign.
Collect polish, quote estimates and rule-builder fixes
A wave of polish across the client-intake experience, improvements to quote estimates, and fixes to the form rule builder.
Quote estimates
- An Include Residual toggle wired through to the calculation engine.
- A clearer finance disclaimer in place of the old comparison-rate note.
- A manual-continuation Continue button for quote integrations.
Intake polish
- Consistent branding and theme across the documents and completion views.
- Responsive width on tablet and mobile.
- Faster completion — the round-trips after submitting a form were collapsed.
Rule builder
- The field picker now shows fields from the selected form, and no longer renders blank for valid rules.
- Cross-form visibility rules preserve answers when forms are partitioned.
- Signatures are now applied to the finalised document.
Technical details
- Quote Estimate: Include Residual toggle wired to the calc engine, a finance disclaimer replacing the comparison-rate note, a manual-continuation Continue for integrations, and onItemView trigger-timing fixes.
- Presentation chrome applied consistently across collect documents and complete views with theme tokens honored; responsive collect form width on tablet and mobile.
- Rule builder reads from the selected form's source partition; the cross-form visibility evaluator preserves user answers; "This Form" links are kept after source partitioning.
- Performance: the post-submit GET cascade collapsed from many round-trips to one, and magic-link validation was pre-compiled and instrumented.
Inventory and Invoicing portals (early access)
Two new portals begin rolling out — an Inventory portal for tracking stock, and the foundations of an Invoicing portal.
Inventory (early access)
- Items with locations, stock levels and movements, and a per-item activity feed.
- Per-tenant tags to organise items, replacing the single category.
- Server-side search and pagination on the items list, inline on-hand editing, and a primary image per item.
- Scan-to-accumulate for fast stock-takes, and printable labels for registered machine codes.
Invoicing (foundations)
- An Invoicing portal scaffold, with per-tenant invoice numbers and SKUs.
Both portals are dark-launched behind access flags while they're built out.
Technical details
- Inventory: an InventoryItem entity with create / update / get / list and list-and-detail UI, InventoryLocation, stock levels + movements + an adjust UI, a per-item activity feed, per-tenant many-to-many Tags under Settings, server-side search and pagination, inline on-hand editing, a scan-to-accumulate MVP, printable machine-code labels, and a primary (denormalised) image per item.
- Invoicing: a portal scaffold with a placeholder dashboard, plus a per-tenant SequenceGenerator for invoice numbers and SKUs.
- Shared groundwork: a Money value object, a QuestPDF + IPdfRenderer skeleton, inventory / invoicing seeds, and dark-launched access features with shell icons for the new portals.
Faster intake, lead forms and presentation defaults
A big performance pass on the client-intake experience, per-source lead forms for capturing enquiries, and cleaner default form presentation.
Performance
- The client-intake (Collect) experience loads noticeably faster — routes are code-split, the PDF stack loads only when needed, and pages stream in without long freezes.
Lead forms
- Per-source lead forms — capture different information depending on where an enquiry came from.
- A broker Lead section on the deal page, with anonymous enquiries hidden until they convert.
Forms
- A cleaner default presentation: inline, borderless, one question at a time.
- Image display fields — add images to forms with upload, size presets and a live preview.
- "0 = unlimited" repetitions for forms and workflow items.
Technical details
- Collect performance phases 1–5: bundle analysis and TipTap removal, route code-splitting with a lazy-loaded PDF stack, CDN origin headers and @mui de-duplication, a deferred pdfjs worker and latin-only fonts, long-task chunking with web-vitals RUM, and a lazy CollectPage with eager self-register.
- Lead capture: per-source lead forms (backend foundation, admin picker UI, and a broker Lead section on the deal-detail page), source-aware steps and forms, anonymous workflows hidden until conversion, and path-based slug routing for self-registration.
- Forms: presentation defaults to inline, borderless and one-question-at-a-time; Image (Display) fields with environment upload, size presets and a live preview; FormField and WorkflowItem repetition switched to "0 = unlimited".
- Security hardening: user input sanitised before logging, DOMPurify with a URL-scheme allowlist in the client portal, and logo-URL scheme validation before preview.
One unified navigation, a new Flows connector, and a faster CRM
This release brings every part of ZiplineOS under one consistent side navigation, introduces Flows for connecting outside tools straight into your CRM, and makes the CRM noticeably faster. You can also now install ZiplineOS as an app. Behind the scenes, we began rolling out a safer draft-and-merge way to edit form workflows, which is starting to reach tenants gradually.
Navigation & app experience
- One unified navigation rail now spans every part of ZiplineOS. The new collapsible side rail remembers whether you've pinned it open or tucked it away, auto-expands on hover, and keeps your icons in place as it slides — so jumping between your forms, Drive, Broadcast, CRM and the other portals feels like one product instead of many.
- Folder trees and in-context menus are built in: Drive shows its folder structure right in the rail, form workflows can be starred for quick access, and row actions are a click away without leaving the page.
- Install ZiplineOS as an app. You can now add ZiplineOS to your desktop or phone home screen and launch it in its own window like any other app.
Flows (connect your other tools)
- New Flows connector lets outside tools push data straight into ZiplineOS. A flow can create a contact in your CRM automatically — mapping names, email, phone, tags and custom fields from whatever sent the data.
- Clearer setup and safer duplicate handling. Each flow now has an endpoint panel showing its web address, keys and a ready-to-copy example, plus an always-visible field picker for mapping incoming data. Contacts are only treated as duplicates on an exact first-name, last-name, email and phone match.
CRM
- A noticeably faster CRM. Contact lists, dashboards and search have been reworked to load quicker, especially for larger organisations with deep contact hierarchies.
- More accurate billing — practice and test deals are now kept out of your usage and billing figures so your numbers reflect real client work.
Forms & workflows
- Safer workflow editing is on the way. We've started rolling out a new draft-and-merge way to edit form workflows — edit a working copy, review every change side by side, and merge it in only when you're happy, with a version history you can roll back to and deals that stay pinned to the version they were created on. It's being switched on gradually, so it may not be visible in your account yet.
- Cleaner editing throughout — friendlier in-app dialogs replace abrupt browser pop-ups, edits to form items save reliably even when you rename them, and new workflow-creation forms make starting a workflow from scratch quicker.
Admin & distribution
- Central catalog for sharing workflow packs. Admins can now version, review and publish reusable workflow packs from a central catalog and push updates out to tenants, with new admin screens to manage it all.
Technical details
- The integrated shell nav is a phased rollout: an embedded portal mode with a nested sub-nav protocol and a row-actions protocol, with input, broadcast, drive and the remaining seven portals opting in, plus iframe absolute-positioning to remove the loading gap, and a PWA manifest/service worker/install button for app install (#1198-#1217, #1264).
- Workflow versioning is built on a new draft/release-candidate model: WorkflowDraft and WorkflowReleaseCandidate entities, a diff/merge type system and schema contract, a three-way merge algorithm with an auto-resolver, MergeSession persistence with JSON endpoints, and merge-aware promote plus refresh-from-Published flows, with Deal version-pinning columns and a test-deal picker (#1224, #1226-#1243, #1260-#1268).
- An entity-resolution and conflict-projection layer surfaces every change for explicit acceptance, including cross-path move detection for items, a MovedToDifferentParents conflict variant and a merge audit page; it also fixed an inverted KeepCurrent/KeepOther mapping, stale-base-snapshot fallbacks and projector root-path prefixes. Stable Id keying for items and annotations prevents renames from duplicating entries (#1277, #1281, #1283, #1284, #1286, #1289, #1290, #1291, #1299, #1300, #1301, #1302).
- The workflow_drafts capability ships dark behind a kernel feature grant, gated on both backend commands and the UI, with RC terminology hidden from ungranted users — which is why the draft/merge editing experience is not yet generally available (#1304, #1305, #1306, #1308, #1345, #1379).
- Catalog distribution adds pack-version drafts/RCs, an admin UI, promote-to-catalog, a prod seeder and distribution evaluator, tenant-side seed-from-update, and git sync that opens a GitHub PR on catalog publish (#1247-#1256).
- Flows (the protocol portal) authenticate through the unified ApiToken system, write audit-log entries for flow and key lifecycle events, surface draft graph validation in the editor, and fixed a bug that persisted an empty graph; CreateContact targets were expanded to tags, CRM entity, external ids and dynamic tenant custom fields (#1407, #1416, #1417, #1421, #1422, #1426-#1430).
- Performance: forced custom plans on request connections fixed a 78x dashboard regression, the RLS tenant predicate was rewritten to IN(unnest()) for O(1) per-row hashing, omni-search Pass-1 moved to a dedicated reader role for sub-millisecond results (debounce also raised 50ms->150ms), and the /forms/breakdown telemetry query dropped a Deal JOIN in favour of composite indexes; CRM also batches contact counts/fuzzy lookups and lazy-loads dashboards (#1219, #1220, #1222, #1223, #1230, #1246, #1253, #1270, #1278, #1280, #1282).
- Test/security hardening: the A4 org-isolation kit (Ring 0/1/1b plus Phase C drains across Registry, Drive, Marketing, Organizations, Catalog and Forms) builds out tenant-isolation convention coverage, and a Collect endpoint moved its INPUT.deals gate off shared queries onto an authed endpoint (#1272, #1273, #1275, #1287, #1311, #1420).
- Plumbing fixes: EF Core 10 PendingModelChangesWarning suppression at startup migration, restoration of Referrer ModelSnapshot entries lost in the #1407 merge, env-aware dashboard URLs after login, a marketing-site TS6 peer-conflict fix added to the CI matrix, and a SuperAdmin license bypass via synthetic AppProduct rows (#1271, #1381, #1382, #1383, #1413, #1414).
Flows begins rolling out, plus a sharper Quote Tool
This release begins the rollout of Flows — a new way to capture data from anywhere and run it through your own automated steps, starting with an early pilot — and gives the Quote Tool a sharper, more reliable foundation for gathering client details and reusing your setups.
Flows (early rollout)
- Visual flow builder — design your own automations on a canvas: add steps, configure each one, and run a test before going live. This first version is rolling out in phases, starting with a pilot, so it won't appear for every account yet.
- Capture data from anywhere — a new secure intake link lets outside systems and forms send information straight into your flows, so nothing has to be re-keyed by hand.
- See every run at a glance — each flow keeps an execution log and live KPI tiles, so you can confirm work happened and track the numbers that matter.
Quote Tool
- Refreshed qualifying questions — the questionnaire now uses a single, consistent 36-field set, so you capture the right client details every time without duplicate or missing fields.
- Reuse your setups in one step — quote configurations can now be exported and imported as a file, making it easy to copy a working setup between environments or roll out an update.
- Smoother end-to-end quoting — runtime fixes and a more reliable two-phase save mean importing a published sheet and producing a quote now works cleanly from start to finish.
- Simpler calculation setup — the standalone calculation picker has been removed in favour of one clear scope selector, so there's only one place to choose how a quote is worked out.
Dashboard & access
- See the apps you're entitled to — your dashboard now shows the apps available to you based on your access rather than your subscription, so the right tools appear where they should.
- Sign-in and invitation fixes — Gmail-style email addresses (with dots and aliases) are now matched correctly at sign-in, and previously removed users can be re-invited and restored without getting stuck.
Technical details
- The new Flows engine ships as a full 9-part build: data model and feature grant (#1177), a flow executor with individual node executors (#1182), a public ingest endpoint secured with bearer auth plus idempotency and an async worker (#1186), the builder UI — list, canvas editor, node configs and test panel (#1187), and execution logging with KPI cells (#1188). It is rolled out in a launch phase behind the flows_manage capability (#1190) and piloted with a first customer (Stratton, #1188) — not yet generally available.
- Tenant isolation hardening: TenantRls is now enabled in production so row-level-security policies see the stamped GUCs (#1164), SuperAdmin organisation reads (Members/Subscriptions) are routed through worker context (#1157), and accessible_org_ids was widened for SuperAdmin in the user-context middleware (#1161).
- Provisioning robustness: default app subscriptions are now seeded on root-org creation and /me self-lookups are RLS-safe (#1153), live User rows are preferred when a ghost record shares a Cognito sub or email (#1174), and invitation handling stamps DeletedAt for clean user resurrection (#1172).
- Dashboard app visibility was decoupled from subscription and the legacy RequiredRole gate deprecated (#1175).
- Code-quality tooling: a new A3 Roslyn analyzer (ZIP001/002/003) landed alongside a 56-site cleanup (#1193), plus a fix to memoize the flows API hook to stop an infinite render loop (#1191), and assorted compliance-hosting, sandbox-spacing and dashboard-flicker fixes (#1176).
OmniSearch, a built-in Quote Tool, and a smarter Contact view
This release introduces OmniSearch — a single, fast search box that finds contacts, referrers and records from anywhere — alongside an early Quote Tool for client intake forms and a redesigned Contact 360 view in the CRM. Plenty of behind-the-scenes hardening rounds it out.
Search
- OmniSearch is here — one search box to find contacts, referrers and records across the app. It opens with your recent items, then fills in matches as you type, with typo-tolerant fuzzy matching so near-misses still surface what you meant.
- Filter as you search — entity-type chips and inline filter tokens let you narrow to just the entity you want (for example, only contacts) without leaving the keyboard.
- Searches your custom fields too — results can reach into custom fields on contacts and referrers, and you choose which fields are indexed for search. Items you open often rise to the top automatically, based on your own recent activity.
Collect (client intake)
- New Quote Tool step (early access) — intake forms can include a live quoting step that runs your calculation engine inline, takes over the screen for a focused quote experience, and maps answers into your quote logic. It is dark-launched behind a feature flag to start, so it rolls out gradually rather than being switched on for everyone.
CRM
- Contact 360 redesign — a cleaner contact view that pulls everything together in one place, including a new Rolodex dashboard. It rolls out behind feature gates.
- Linked form answers on the contact — values from a contact's linked intake forms now appear directly in the Contact Details sidebar, so you can see what the client told you without digging.
- Custom fields for referrers — add, edit and manage your own fields on referrer records to track the details that matter to your business.
Quoting
- Easier rule building — rule editors now offer schema-aware autocomplete, plain-English explainer cards for how figures are combined, and a clear summary of what changed each time you publish.
- Change safety — new drift detection flags when published quote logic has diverged from its source, helping you catch surprises before clients do.
Technical details
- Tenant-isolation (RLS) hardening sweep across roughly fifteen write endpoints: they now validate cross-tenant foreign keys and caller membership before writes, stamp OrganizationId on inserts, and block cross-tenant tree pollution on organization create/move — closing a batch of tracked isolation gaps. PRs: #1090, #1108, #1109, #1110, #1111, #1112, #1113, #1114, #1116, #1117, #1118, #1123, #1124, #1125, #1126, plus admin-portal cross-tenant writes routed through worker context (#1054).
- Auth tightening: /users endpoints gate mutations to the caller's org tree and drop a join-first-org footgun, system-updates mutations are restricted to SuperAdmin, /collect file downloads are scoped by applicant, and a new SuperAdmin endpoint can set a user's Firebase password (#1127, #1119, #1123, #1037).
- OmniSearch search architecture: scored results with a two-pass endpoint split (fast /search plus deep /search/deep), providers emitting ScoredSearchResult sorted by score, ExternalId Tier-1 matching, and per-user recency scoring (#1034, #1038, #1041, #1053, #1092).
- Performance and DB-context plumbing: keyword providers routed through background/read-only DbContexts with Pass 1 latency restored by serialising them and RLS Layer 2 reinstated, tenant predicates inlined per policy, a new IX_Contacts_OrgSource index for the Rolodex dashboard, raw telemetry queries routed through the EF connection, and feature-grant audit-log inserts moved to background context (#1122, #1115, #1135, #1133, #1134, #1027, #1024, #1137).
- Hardening of input handling: smuggled widget IDs rejected on desktop widget PUTs, field-access-preset validation mapped to 4xx instead of 500, and the webhook auth-type whitelist tightened to stop leaking values in 500s (#1093, #1094, #1095).
- Test-data seeder made RLS-safe and re-runnable on any org with orphan test-user cleanup, quoting tool primitives and CSS extracted into shared UI, a deploy fix to set the Firebase ProjectId in the Cloud Run env, and the ContactSearchProvider perf p95 threshold raised to 250ms (#1102, #1103, #1139, #1144, #1048, #1128).
Lender matching and pricing in a quoting sandbox, plus contact, deal, and team controls
This release brings the first preview of a new quoting engine that matches your clients to suitable lenders and works out indicative pricing — all built inside a safe sandbox you can test against sample applicants before anything goes live. It launches as a pilot with a small group of lenders. We've also added contact warning flags, automatic emails when a deal changes hands, and easier control over team roles and access.
Quoting & lender matching (early preview)
- Introducing lender matching — set up your lender offerings and tiers, then shortlist the lenders that fit each client's situation, with an AI assistant that can suggest policy rules and read them straight from a lender's PDF.
- A new pricing engine calculates an indicative final rate for each matched lender offering, so a shortlist comes with pricing attached rather than a manual lookup.
- All of this lives in a new quoting sandbox where you build and test lender policies against sample applicants before publishing — compare your changes against what's live, try live overrides, and import or export your policy collections and groups. It launches as a 10-lender pilot, with Pepper and Metro among the first.
CRM & contacts
- Added contact warning flags so you can flag a contact with a banner, pick from a catalogue of warnings, and dismiss or remove them as situations change.
Deals
- When a deal is reassigned, the new owner is now emailed automatically, so nothing slips through the cracks during a hand-off.
Team & access
- You can now deactivate and reactivate team members directly from the user edit screen, keeping access tidy when people join or leave.
- Introduced the first version of a roles and permissions matrix, letting admins create custom roles and set what each role can do.
Technical details
- The quoting engine moved to its own logic portal under /api/v1/logic/quoting/* and is built in rings — policy authoring, a matching service with a lender-shortlist preset, applicant fixtures with diff-against-published, a pricing service bridged into rate enrichment (finalRate), and live-override recompute in the sandbox. Includes a guard against zero-rate tiers crashing the match endpoint.
- Multi-tenant isolation hardening (the 'ziplock' workstream): the CalculationEngine is now tenant-scoped (ITenantScoped) with row-level security, worker/shared services use separate DbContexts, and RLS-aware seeding plus foreign-key fixes resolve Ring 1 backfill issues under FORCE RLS on child organisations.
- Security: SegmentEvaluationService hardened against SQL-injection regressions; startup/auth fixes for CalcEngine dependency injection and pre-tenant DbContext use in SessionService and AuditService.
- Platform plumbing: role-capability grants v1 (with custom roles, LISTEN/NOTIFY, and a health-check interface), a result-card preset option for workflow integration items, shared EndpointHelpers for org-ID lookup, and the compliance portal wired up alongside a telemetry GroupBy fix.
- User deactivate/reactivate is synced across both Firebase auth and the database.
Smarter documents, quoting foundations, and a more polished Deal Workspace
This release brings a redesigned document experience with thumbnails and bulk upload, the first building blocks of in-app quoting, and a smarter AI pipeline that sorts and names client files automatically. It also delivers a sweep of usability, accuracy, and accessibility improvements across the Deal workspace, CRM, client intake, and reporting dashboards.
Documents & Drive
- Redesigned Documents tab — files now appear as visual thumbnails, with one-click bulk upload and the ability to download everything at once as a single ZIP.
- Automatic file sorting — uploaded client documents are now classified, checked, and renamed automatically by AI, so files land in the right place with sensible names without manual tidying.
- Safer file handling — deleting a document now asks for confirmation first, and document cards can be operated entirely by keyboard.
Quoting (new)
- Quoting groundwork — the first version of the in-app quoting experience is now in place, laying the presentation layer and provider connections that future quote features will build on.
Deals & workflows
- A more reliable Deal workspace — the back button now returns you to the Kanban board with your tabs intact, deal titles can no longer be left blank, deal cards show tidy compact currency, and deleting notes asks for confirmation first.
- Manage applicants on a deal — you can now remove an applicant from a deal directly, with sensible per-role limits on how many applicants a deal can hold.
- Clearer progress tracking — the stage navigator now counts only the items that are actually required, so the "complete" tally reflects what genuinely needs doing.
- Cleaner Kanban views — irrelevant stage columns hide based on your status filter, table sorting handles empty values gracefully, and workflow status labels read in plain English.
Collect (client intake) & forms
- Smoother client intake — forms now auto-advance correctly end to end, hidden fields no longer leave awkward blank gaps, and step visuals and completion indicators were polished throughout.
- More dependable form logic — visibility rules now handle unanswered and outstanding-document fields correctly, and form templates must have unique names within each organisation.
- Safer portal links — revoking a client portal link now asks for confirmation first, so access can't be cut off by accident.
CRM
- Better contact search — you can now find contacts by phone number, including matches across different number formats.
- Quick Actions that work — the Log Call and Add Note buttons on a contact now do what they say, and the Add Contact dialog lays out cleanly on every screen size.
Broadcast & marketing
- Flexible email starts — the broadcast wizard now offers both a visual builder and an HTML start-from-scratch path, with clearer labelling that the email body is markdown.
- Safer sending — the Send Email button stays disabled until a subject, body, and recipients are all present.
Dashboards & reporting
- More accurate Telemetry charts — deal statuses (including On Hold) now show as their own slices, monthly trends no longer drop recent months, currency and dates display in correct Australian formatting, and "new this month" counts reflect the actual calendar month.
- Clearer audit logs — action filters are complete, details render as readable text instead of raw code, and custom date ranges are validated.
Everywhere
- Navigation and polish across the board — proper 404 pages for unknown links, working deep-links and breadcrumbs, the sidebar auto-collapsing on tablets, and dozens of small accessibility, layout, and wording fixes throughout the app.
Technical details
- Security hardening: cross-tenant
dealIdis now rejected on/upload-url, deal notes are sanitised server-side with a TipTap allowlist, session-scoped list endpoints reject anorganizationIdquery param, and thumbnail/ZIP fetches skip credentials for external URLs (#850, #891, #791, #887). - API correctness:
GET /api/v1/contactsreturns a realtotalCountand honourspageSize;PATCH /deals/{id}rejects unknown fields and normalisesexpectedCloseDateto UTC; settings endpoints return200 nullinstead of erroring when no config exists; empty note content returns 400 rather than 500 (#648, #902, #904, #782, #892). - Engine/Logic builder: per-parameter Required toggles, Test Panel JSON generated from engine parameters, output-schema placeholder fixes, and graceful empty/not-found states for missing engines (#693, #692, #694, #696, #792).
- Infrastructure and integration:
X-Api-Keyallowed in CORS for Engine webhooks,X-Forwarded-Protohonoured when building external URLs, webhook request/response payloads captured on error paths, and a Magick.NET migration for image handling (#664, #695, #787, #750). - CI: the AI-review jq pipeline now coerces object-shape items to strings (#909).
- Carry-forward refactor: form-list scoping with exclusion handling, plus removal of dead
formTemplateMatchMapcode from the execute handler (#788, #789).
AI fills forms from documents, plus referrer tracking
This release lets AI read a client's uploaded documents and fill in their form answers automatically, and introduces referrer records so you can start tracking who's sending you business. Forms also got tidier, clearing away answers that no longer apply.
Collect (client intake)
- AI document data extraction — upload a document and let AI read it and fill the matching form fields for you, so clients and your team spend less time re-typing details that are already on the page.
- Cleaner forms — when a question is hidden because it no longer applies, its answer is now cleared on save, so saved forms only keep the answers that actually matter.
- Various small fixes and polish across the form-filling experience.
CRM
- Referrer records (early access) — a first phase of referrer tracking lands, with a dedicated portal screen to create, view, and manage referrers so you can start keeping track of who is referring clients to you. More referrer functionality is on the way.
Technical details
- The AI extraction feature required teaching the document pipeline to load the underlying file bytes whenever auto-extraction runs (AutoExtract is now included in the needsVision check), so vision-based reading has the full document to work from (#500).
- Behind the CRM referrer work, the dormant legacy Contact.ReferrerId field was retired to keep the data model clean as the new Referrer entity takes over (#502).
- Cloud Tasks callbacks on staging now accept a Google OIDC token, fixing background-job authentication in that environment (#501).
- Security and maintenance hardening: resolved critical and high npm audit vulnerabilities, and bumped Terraform to 1.6.6 to work around an expired GPG key blocking infrastructure runs (#525, #526).
A richer client intake experience in Collect
This release gives your client intake forms a proper documents workflow, lets clients defer non-urgent information, and supports filling out repeatable sections inline — so clients can get started faster and you collect everything in one place.
Collect (client intake)
- Documents in Collect — clients can now see a dedicated Documents section and act on their files inline (upload, view and manage) without leaving the form.
- "Required Later" toggle — mark information as needed down the track rather than blocking submission, so clients can get started straight away and finish the rest when they're ready.
- Repeatable sections inline — forms that need more than one of something (multiple applicants, properties or income sources) can now be filled out as inline multi-instance forms, right where you are.
Technical details
- Security hardening across the platform: tightened token expiry handling, a Content-Security-Policy header, and signature verification on inbound Twilio webhooks (#462).
- Email connections now deactivate automatically when a token refresh fails, preventing silent send/receive failures from a stale connection (#461).
- Telemetry test coverage expanded with several new tests to close gaps, plus stabilisation of flaky end-to-end tests (#456, #473).
