Changelog
New features, improvements, fixes, and security updates — shipped to every workspace automatically.
334 entries
Week of November 2, 2026
Nov 2 – Nov 8 · 4 updates
Mostly Security & trust, AI, Integrations & API
- ImprovedIntegrations & APIVoice & calls
Voice commands sent through the API now wait for your confirmation
A spoken command sent to Pact's voice command API now answers with what it is about to change and a one-time confirmation, and changes nothing until the same person confirms.
What changed
Pact's phone line already reads a change back before making it. Voice commands sent through the API now work the same way.
- The voice command API answers with a read-back, such as "I'll move Acme to negotiation and add a note to Acme", and a one-time confirmation that expires.
- Nothing changes in your CRM until the same person confirms. A confirmation from anyone else, a repeat, or one that arrives late changes nothing.
- A command that is missing something it needs is answered straight away and never waits for a confirmation.
- If your own tools call this API, add the confirm step. Until you do, commands are read back but not applied.
Try it
Open /api-reference and find the voice command confirm step: send a command, then confirm it with the token it returns.
#2026-11-03-voice-commands-through-the-api-wait-for-confirmationTechnical details
4777PR #4777 — voice commands through the API are read back and wait for a confirm
- SecurityAISecurity & trust
Your own AI model gets the same safety controls as Pact's
A workspace that connects its own AI model now gets every safety control Pact's own AI has: the kill switch, data-sharing settings, injection screening, redaction, the answer filter and a calls-per-minute limit.
What changed
Until now, a workspace that brought its own AI model skipped most of Pact's AI safety controls. Every request to your model now passes the same checks, in the same order, as Pact's own AI.
- The kill switch and your data-sharing settings apply. When either says no, nothing is sent to your model.
- A calls-per-minute limit stops a runaway loop from flooding your model.
- Instructions hidden in your CRM data are screened out before a request leaves Pact.
- Personal details and secrets are redacted according to your data-sharing setting.
- Answers pass the same filter before anyone sees them.
Try it
Open /admin/ai/features, where a workspace's own model is set up: the same safety controls now cover it.
#2026-11-03-your-own-ai-model-gets-the-same-safety-controlsTechnical details
4776PR #4776 — a workspace's own AI model passes Pact's AI safety controls
- SecuritySecurity & trust
Pact support needs a passkey or code to open your workspace
Before a member of Pact's staff can open your workspace as one of your users, they now have to confirm with a passkey or an authenticator code. A password alone is refused.
What changed
Support sometimes needs to see your workspace the way one of your users sees it. Starting that now takes a fresh, strong second step.
- Pact staff confirm with a passkey or an authenticator app every time they open your workspace as one of your users.
- A password alone is refused, so a stolen staff password or session can't be used to reach your data this way.
- Your workspace owner still gets an email each time it happens.
Try it
Set up the same protection for your own account: add a passkey or an authenticator app under /settings/mfa.
#2026-11-03-pact-support-needs-a-passkey-to-open-your-workspaceTechnical details
4756PR #4756 — Pact staff need a passkey or authenticator code to open a workspace
- FixedSecurity & trust
pact.place stores nothing about your visit until you agree
The pact.place website no longer saves a visitor id before you accept tracking, never saves one with Global Privacy Control on, and removes one saved earlier when you say no.
What changed
Viewing pricing or clicking a sign-up button on pact.place used to save a visitor id in your browser, whatever you had chosen about tracking. That's fixed.
- Nothing is saved until you say yes to tracking.
- With Global Privacy Control turned on in your browser, nothing is saved at all.
- If you say no, an id saved on an earlier visit is removed.
Try it
Turn on Global Privacy Control in your browser and open /pricing: nothing about your visit is saved.
#2026-11-03-pact-place-stores-nothing-about-your-visit-until-you-agreeTechnical details
4757PR #4757 — the website saves no visitor id before consent
Week of October 26, 2026
Oct 26 – Nov 1 · 5 updates
Mostly AI, Sales & CRM, Data & analytics
- FixedAIVoice & calls
AI stays on through busy calls and stray sentences
A busy phone call no longer runs into the AI limit after a few sentences, and neither a burst of limited requests nor one sentence that looks like an instruction to the AI switches AI off for your whole workspace.
What changed
What changed
On 1 November one busy phone call switched AI off for a whole workspace. Three fixes make sure that can't happen again.
- One thing you say on a call counts once against your AI limit, however many steps it takes Pact to answer it. Before, a caller could hit the limit after about four sentences.
- A burst of rate-limited AI requests now raises an alert for Pact's team instead of switching AI off for everyone. Any workspace the old rule switched off was switched back on by this release.
- One ordinary sentence that happens to look like an instruction to the AI, such as "so you are now the owner of the Acme deal", is refused on its own and no longer switches AI off for the workspace. Repeated real attempts still do.
Try it
Make a longer call to your Pact line and keep asking questions: it keeps answering. Your line's settings are under /settings/voice.
#2026-11-01-ai-stays-on-through-busy-callsTechnical details
4797PR #4797 — one thing a caller says counts once against the AI limit4793PR #4793 — a rate-limit burst alerts and never switches AI off4803PR #4803 — one flagged sentence no longer switches AI off
- FixedSales & CRMData & analytics
A rep's forecast and search match their own book
A rep's pipeline forecast and search now show the same deals and accounts as their own lists. The contacts export includes everyone on the Contacts page, and overdue cases and privacy requests surface first.
What changed
What changed
Pact's numbers now agree with what each person can see.
- A rep's pipeline forecast adds up their own deals, and a manager's adds up their team's. Before, a rep could see a forecast for the whole company above an empty board. Owners and admins see the same totals as before.
- Search shows a rep the accounts and deals in their own book.
- The contacts export includes every person on the Contacts page, not just a header row.
- A support case past its due time with no first response shows as SLA-breached straight away, in lists, filters and reports.
- Consent Today lists overdue privacy requests first and says how many are overdue.
Try it
Sign in as a rep and open /sales/forecast: the total matches the deals on your own board.
#2026-11-01-forecast-and-search-match-a-reps-bookTechnical details
4747PR #4747 — reps' forecast and search match their book
- ImprovedExperience
Requesting a workspace confirms your email first
A request for a new Pact workspace now starts by confirming your email with a branded message, then asks a few questions about your company so the workspace can open set up for your industry.
What changed
What changed
Asking for a Pact workspace is quicker to review and safer to send.
- Your request starts with a sign-in link to your inbox, so we know the address works before anyone reviews it.
- The form asks a few short questions about your company: website, size, industry, country, the CRM you use today and what you want Pact for. Your workspace can then open set up for your industry.
- The confirmation email is branded, reads well in dark mode and in Outlook, and can't be used up by a company's link scanner before you click it.
Try it
Invite a colleague to try /signup: they get a branded email to confirm their address before the short company questions.
#2026-11-01-requesting-a-workspace-confirms-your-email-firstTechnical details
4711PR #4711 — workspace requests confirm email first and ask about the company4710PR #4710 — a branded verification email that link scanners can't use up4759PR #4759 — the sign-in link goes out through the branded email
- FixedSales & CRM
Know when a prospect first opens your shared demo
Sales engineers now get a notification the first time a prospect opens a demo sandbox they shared, so you can follow up while the demo is fresh.
What changed
What changed
Sharing a demo sandbox was meant to tell you when the prospect opened it. That notification never arrived. It does now.
- The first time someone opens a demo sandbox link you shared, you get a notification, so you can follow up while the demo is fresh.
- Nothing changes for the prospect: the link opens the same demo as before.
Try it
Share a demo from /se/sandbox, open the link in a private window, and check /notifications.
#2026-11-01-know-when-a-prospect-opens-your-demoTechnical details
4734PR #4734 — notify the sales engineer when a shared demo is first opened
- SecurityAISecurity & trust
Hidden instructions to the AI are caught in any spelling
Pact's AI safety checks now catch instructions hidden in emails, leads, call transcripts and uploaded documents however they're spelled, and withhold an email read during a call if it carries one.
What changed
What changed
Someone can try to slip instructions to Pact's AI inside an email, a lead, a call transcript or a document you upload. Pact now catches more of those attempts.
- Instructions disguised with invisible characters, look-alike letters, wide characters or quoting are checked the same way as plain text. In Pact's own test suite of 120 planted instructions, 36 used to get past the check because of how they were spelled; each is now checked the way the AI would read it.
- Text hidden inside structured data is unpacked and checked before the AI reads it.
- When the AI reads an email for you during a call and that email carries a hidden instruction, the email is withheld and the call carries on.
Try it
Admins can see what was blocked, and why, under /admin/security/ai-defense.
#2026-11-01-planted-instructions-caught-in-any-spellingTechnical details
4733PR #4733 — every spelling of a planted instruction is scored, hostile results withheld
Week of October 19, 2026
Oct 19 – Oct 25 · 43 updates
Mostly Sales & CRM, Experience, Data & analytics
- @mentions work in every workspace, and every alert opens its record
- Home's cards name every person and record, and open it
- A won deal makes the account a customer everywhere
- The next best action card shows at once
- The phone line answers questions, and finishes what you missed
- Changing your call voice shows what each choice costs
- Imports, uploads and daily limits fit real use
- Switch from HubSpot or Salesforce with every deal on its stage
- Home's approvals card names the deal, who asked, and opens it
- Reps can reassign owners, move close dates, and add, follow up on and finish tasks by phone
- A deploy no longer ends a phone call to your Pact line
- Tasks and hot leads load reliably, and Home waits out a slow load
- Phone answers about a named account arrive sooner
- Log a call from any account, contact or deal
- Every deal on the board, and stage moves your manager can see
- The Pact phone line gets to the point and finds your own accounts
- Support cases follow the conversation, in your own time zone
- A slipping renewal can start its own save play
- A lead shows the consent it gave, and forms embed anywhere
- A live SPF, DKIM and DMARC checklist for your sending domain
- Every module says what it needs to run, and members can come back
- The status and trust pages say exactly what is measured
- A calm first day for every new teammate
- Your calendar stays connected, and a broken one says how to fix it
- Numbers that say when they are missing, and AI text that ends cleanly
- Fast and fair as your workspace grows
- Ask Pact now says how sure it is, and why
- The Pact phone line learns the names you correct, and shows you what it learned
- One lifecycle stage per account, everywhere, and where accounts stall
- Forecast Commit, close dates and at-risk lists that add up
- Managers open on their team's board, and a rep's pages read as theirs
- Your week on the calendar page, and an attendee picker by name
- Campaigns get credit for the deals their forms start
- Sign-in asks for your authenticator, and admins can require MFA by role
- Workspace settings show what each one enforces, and AI spending caps hold
- See every question asked of your workspace in the Ask trail
- Scheduled data exports that run, with a receipt for every run
- Support SLA clocks are right in every time zone, and open cases count toward health
- Field reps see when each account was last visited, and a scorecard that adds up
- When something can't load, Pact says what in plain words, and the rest keeps working
- Pact on a phone: clear of the home indicator, with labels that stay whole
- Help for every screen, navigation in your language, and a first day in your own module
- Watch the guided tour without sound, and every hands-on moment fits the screen
- NewFixedSales & CRMExperience
@mentions work in every workspace, and every alert opens its record
Type @ in a comment to bring a teammate in, in any workspace. Home's Mentions & comments card now holds only mentions and comments, names who wrote each one, and opens the record at the comment.
What changed
What changed
@mentions used to work only in Pact's demo workspace. They now work in every workspace: type @ in a comment, pick a teammate, and they see it on Home and in the notification bell.
- Home's Mentions & comments card shows only mentions and comments. Alerts stay in the bell.
- Every row names who wrote it and what they did, such as "replied to you" or "reacted to your comment".
- A row opens the record, scrolled to the comment. A row with nowhere to go says why instead of opening a missing page.
- Notifications in the bell, on Home, in email, in push and in Slack open the right record and name the person who acted. Eight kinds that used to open a missing page now open the right one.
Try it
Open any deal, type @ in a comment and pick a teammate, then check /notifications as them: the row names you and opens the comment.
#2026-10-25-mentions-in-every-workspace-and-alerts-open-their-recordTechnical details
4610PR #4610 — @mentions work in every workspace4558PR #4558 — Home's mentions card shows mentions and names who wrote them4612PR #4612 — every notification opens its record and names who acted
- FixedExperience
Home's cards name every person and record, and open it
Home's deals, signals, tasks and recently viewed cards now show the name of every record and person and open the record itself. A missing value says so instead of showing a zero.
What changed
What changed
Home's cards read like a list of people and deals again, not identifiers.
- The deals, signals, tasks and recently viewed cards name each record and the person behind it, and selecting a row opens that record.
- A person always shows as a name, or "A teammate" when the name can't be read, never as an email address.
- The customer success and marketing Today pages no longer show account numbers or invented zeros. An account with no score reads "No score".
- After someone else signs in on the same browser, What's new no longer flashes the previous person's unread count, and a release you haven't seen always shows as unread.
Try it
Open /home and select a row on the deals or tasks card: it names the record and opens it.
#2026-10-25-home-cards-name-people-and-recordsTechnical details
4589PR #4589 — every Home card names its people and records4542PR #4542 — What's new keeps the right unread count after a switch
- FixedSales & CRM
A won deal makes the account a customer everywhere
Once an account has a won deal it reads as a customer on every page, and a won renewal moves it to Renewed. Deal boards with more than 200 deals now show every deal.
What changed
What changed
An account whose renewal had closed won could still read "In pipeline" because a new expansion or renewal was open. That's fixed.
- Once an account has a closed-won deal, it is a customer until it's marked lost or churned. An open renewal or expansion shows as "renewal in progress", never as a step back to pipeline.
- A renewal deal that closes won moves the account to Renewed.
- The lifecycle strip, the accounts filter, the report builder, the account page and Do next now agree on every account's stage.
- Do next shows a health score as the number with its band, such as "9 (critical)".
- Deal boards with more than 200 deals now load every deal instead of stopping at the first 200.
Try it
Open /sales/accounts, filter by Customer, and open an account with a won renewal: it reads Renewed on the list and on the page.
#2026-10-25-a-won-deal-makes-the-account-a-customerTechnical details
4534PR #4534 — a won deal makes the account a customer everywhere
- PerformanceAISales & CRM
The next best action card shows at once
An account's next best action now appears the moment the page opens: the last AI suggestion, or a rule-based one marked Rules, with a fresh AI answer filling in as it's written.
What changed
What changed
The next best action card used to sit empty for several seconds while the AI worked. It now shows something useful straight away.
- The card opens with the last AI suggestion and how old it is, or with the top rule-based suggestion, labelled Rules.
- A fresh AI suggestion fills in as it is written, then its buttons appear, without the card jumping.
- Opening an unchanged account again keeps the AI suggestion it already has instead of falling back to rules.
- A workspace that has reached its AI limit gets the rule-based suggestion instead of a broken card.
Try it
Open an account from /sales/accounts and watch the next best action card: it shows a suggestion at once and updates as the AI answers.
#2026-10-25-next-best-action-shows-at-onceTechnical details
4564PR #4564 — the next best action card shows at once
- ImprovedFixedVoice & callsAI
The phone line answers questions, and finishes what you missed
Ask Pact's phone line a question and you get an answer, never an offer to change your data. Say "what?" after an answer is cut off and you hear the rest, and four new questions about change over time now work.
What changed
What changed
Questions on your Pact phone line now get answers, and fewer answers get lost.
- A question is answered, never treated as a change. "How many deals have we lost on Acme?" used to be read as "mark Acme as lost"; now you hear the count.
- If an answer is cut off and you say "what?", the line gives you the rest of it.
- New questions: which reps drove a change, how accurate your forecast was, what actually moved this quarter, and whether your sales cycle is getting longer.
- A second, different question about the same name keeps the account you already picked.
- "How is my team doing?" now says how many reps it covers, for example "56 of 108 reps with deals", instead of counting only the reps with deals.
Try it
Call your Pact line and ask "how accurate was our forecast this quarter?". Voice settings are under /settings/voice.
#2026-10-25-the-phone-line-answers-questions-and-repeats-what-you-missedTechnical details
4602PR #4602 — a question on the phone line is answered, never opened as a change4609PR #4609 — a caller who says "what?" gets the rest of the answer4574PR #4574 — four change-over-time questions reach a live call4615PR #4615 — "the company" says how many reps it covers4595PR #4595 — a follow-up question keeps its account, and a failed purge is retried
- NewVoice & calls
Changing your call voice shows what each choice costs
Switching your workspace's Pro or Premium call voice now asks whether to prepare the new voice right away, prices both choices before anything is saved, and shows the actual cost afterwards.
What changed
What changed
Picking a new Pro or Premium call voice now opens a confirm step with two priced choices.
- Warm the new voice now records your call lines and quick replies in the new voice, shows its progress, then shows the actual cost beside the estimate.
- Skip saves without recording anything. It shows what recording the same replies during calls will cost, and how long your first line currently takes to start.
- If some lines fail to record, the card now says how many are missing and offers a retry, instead of saying the voice is ready.
Try it
Open /admin/voice-mcp/settings/voice-quality, pick a different Pro or Premium voice, and compare the two priced choices before you save.
#2026-10-25-changing-call-voice-shows-what-it-costsTechnical details
4601PR #4601 — changing a call voice asks to warm it now and shows the cost4624PR #4624 — a voice warm that recorded nothing no longer reads as ready
- FixedPlatformIntegrations & API
Imports, uploads and daily limits fit real use
The import wizard no longer loses your file between steps, a failed import can be retried at once, and a workspace gets its own plan's daily limits even before billing is set up.
What changed
What changed
A handful of limits were getting in the way of ordinary work. They now match how Pact is used.
- The import wizard keeps your uploaded file from one step to the next, so a preview never asks you to upload a file you just uploaded.
- A save that's retried after a dropped connection is applied once, not twice.
- A failed import no longer counts against the one-import-per-hour limit, so you can fix it and run it again straight away.
- A workspace gets its own plan's daily limits even before billing is set up, instead of the free plan's.
- Call recordings up to 120 MB can be uploaded, so an hour-long call fits.
- Busy pages like search no longer share one rate limit, so heavy use of one doesn't block another.
- If removing a deleted workspace's data fails, it is retried at least twice before day 30, so a deletion still finishes within the 30 days Pact promises.
Try it
Open /settings/data-import, upload a file and go through the preview: it keeps your file across every step.
#2026-10-25-imports-uploads-and-daily-limits-fit-real-useTechnical details
4516PR #4516 — the import wizard and retried saves work across machines4642PR #4642 — plan-aware daily limits, per-page rate limits and bigger uploads
- FixedIntegrations & APISales & CRM
Switch from HubSpot or Salesforce with every deal on its stage
Switching from HubSpot or Salesforce now brings every deal onto your board with its real owner and stage, imports activities and notes with their text, and ends with a report of exactly what came across and why anything didn't.
What changed
What changed
Switching from HubSpot or Salesforce now brings every deal onto your board with its real owner and stage, so your pipeline looks the way it did in your old system.
- Activities and notes arrive with their text, attached to the right record.
- Consent comes across only where your old system recorded it.
- The import ends with a report of exactly what came across and, for anything that didn't, why.
Try it
Open /settings/integrations, connect HubSpot or Salesforce, run an import, and read the report it ends with.
#2026-10-22-switch-from-hubspot-or-salesforce-with-every-dealTechnical details
4529PR #4529 — a HubSpot or Salesforce switch lands every deal
- FixedSales & CRMExperience
Home's approvals card names the deal, who asked, and opens it
Each row on Home's Awaiting your approval card now says what is asked, on which deal, who asked and how long it has waited, and opens the approval when you select it.
What changed
What changed
Each row on Home's Awaiting your approval card now says what is being asked, on which deal, who asked, and how long it has waited. Selecting a row opens the approval.
- The card lists the requests you can decide. If you can't decide any, it shows the status of your own requests under a caption that says so.
- A request whose deal is no longer available shows a plain reason instead of a broken link.
Try it
Open /home and look at the Awaiting your approval card: each row names the deal and the person who asked, and opens the approval.
#2026-10-22-approvals-card-says-what-is-asked-on-which-dealTechnical details
4581PR #4581 — approvals card names the deal and opens it
- NewVoice & callsSales & CRM
Reps can reassign owners, move close dates, and add, follow up on and finish tasks by phone
The phone line can now reassign a deal or account owner, move a close date, change a deal amount, add a task, schedule a follow-up, and mark a task done — each read back in words before anything is saved.
What changed
What changed
Your Pact phone line can now make these changes for you, read each one back in words, and save it only after you confirm.
- Reassign a deal or account owner.
- Move a close date or change a deal amount.
- Add a task, schedule a follow-up, or mark a task done.
Try it
Call your Pact line, ask it to move a deal's close date, confirm when it reads the change back, then check the deal under /deals.
#2026-10-22-reps-can-reassign-owners-move-close-dates-and-adTechnical details
4572PR #4572 — owners, close dates and tasks by phone
- FixedVoice & calls
A deploy no longer ends a phone call to your Pact line
A call in progress stays up while Pact updates, and if the line drops it picks back up with "Sorry, I lost you for a second." and the question you were answering.
What changed
What changed
A deploy no longer ends a phone call to your Pact line. A call in progress stays up while Pact updates.
- If the line drops for any other reason, the call reopens with its context and the caller hears "Sorry, I lost you for a second." followed by the question they were answering.
- A change the caller already confirmed is not made a second time after the call resumes.
Try it
Call your Pact line and ask about an account; the line's settings are under /settings/voice.
#2026-10-22-a-deploy-no-longer-ends-a-phone-callTechnical details
4577PR #4577 — a deploy never drops a live call
- FixedExperienceSales & CRM
Tasks and hot leads load reliably, and Home waits out a slow load
The tasks page and hot leads now load every time, and a slow first load on Home keeps its skeleton and says it is still loading instead of reporting a failure.
What changed
What changed
The tasks page and the hot leads list now load every time, instead of showing "Something went wrong".
- Completing a task from the list works the same way.
- When Home or the module switcher is slow to answer, it keeps its placeholder, says it is still loading, and asks once more. An error appears only when a request really failed, and it says what failed.
Try it
Open /home after a while away: a slow load shows that it is still loading, then fills in.
#2026-10-22-tasks-and-hot-leads-load-reliablyTechnical details
4562PR #4562 — tasks and hot leads load, Home waits out slow loads
- PerformanceVoice & calls
Phone answers about a named account arrive sooner
When you ask your Pact line about an account by name, it reads that account first, so the first spoken word comes about two seconds sooner at the median in our timed replay.
What changed
What changed
When you ask your Pact line about an account by name, for example "what's been going on with Acme Corp?", it now reads that account first and answers in one step instead of two.
- In our timed replay, the first spoken word at the median moved from about 6.0 seconds to 3.8 seconds.
- Questions that name no account, or two, behave as before.
Try it
Call your Pact line and ask what's been going on with one of your accounts; review its settings under /settings/voice.
#2026-10-22-phone-answers-about-a-named-account-arrive-soonerTechnical details
4571PR #4571 — named-account phone answers arrive sooner
- NewSales & CRMVoice & callsMobile
Log a call from any account, contact or deal
Log call now sits next to Add Note on every account, contact and deal, and on Today. The call page shows what a voice call changed, names who called, and plays its recording on a phone.
What changed
One form, everywhere you work. Log call opens the same short form from an account, a contact, a deal or Today. The outcome is required and never preselected, a no-answer takes two taps, minutes are asked only for a connected call, and the start time can be changed for end-of-day logging. The form previews the exact line your call will add to the timeline.
It lands where people look. A logged call is written to the account's timeline, which every record's Timeline tab reads. A contact or deal from a different account is refused rather than filed in the wrong place, and a contact with no account still gets its call, with a note saying why there is no timeline line.
The call page says what a call did. "What this call did" links each record a voice call changed and names the action that changed it, every action is listed with its outcome (Done, Refused or Failed), and the lookups it ran are listed too. The call is titled by the person caller ID matched, with the number beneath.
Recordings on a phone. Call recordings now play on phones, and you can reveal a caller's full number when you need it. Each reveal is logged.
Try it
Open any account on /accounts, press Log call next to Add Note, pick an outcome, and see the line it adds to the account's Timeline tab.
#2026-10-21-log-a-call-from-any-recordTechnical details
4475PR #4475 — log a call from an account, a contact, a deal or Today4474PR #4474 — the call page links what a voice call did and names who called4532PR #4532 — recordings play on a phone, and a number can be shown
- ImprovedSales & CRMData & analytics
Every deal on the board, and stage moves your manager can see
Board columns load 50 deals at a time with exact totals, a stage change on a deal page reaches its Timeline and the team feed, and imported deals arrive with an owner and reach Today when overdue.
What changed
Every deal is reachable. Each pipeline column shows its first 50 deals, says how many of its deals are shown out of the exact total, and loads the next 50 when you ask. A "Show more" that fails says so on its own line.
Stage moves everyone can see. On a deal page, Stage is now a choice of that pipeline's stages and moves the deal through the same checks as the board. The move appears on the deal's Timeline tab beside its calls and notes, and in the manager's activity feed, which now opens on work and leaves sign-ins behind a labeled toggle.
At-risk deals stay visible. Today's at-risk list keeps an open deal whose stage happens to share its name with another pipeline's won or lost stage.
Imports that finish the job. An import with no owner column gives its deals and accounts to the person who ran it, open deals past their close date reach that rep's Today, undoing an import also removes the accounts it created (and says which it kept and why), and a run that stopped making progress reads as failed instead of running forever.
Contacts on their account. A contact added by hand is linked to its account, so it shows on the account page, its roster and in Ask Pact.
Try it
Open /sales/pipeline, scroll a long column to its foot and press Show more; then change a deal's Stage on its page and open its Timeline tab.
#2026-10-21-every-deal-on-the-boardTechnical details
4522PR #4522 — columns load 50 at a time with exact totals4478PR #4478 — a stage move shows where the rep and the manager look4512PR #4512 — an open deal that shares a closed stage's name stays on Today4477PR #4477 — after an import: owners, overdue deals on Today, undo, failed runs4462PR #4462 — a contact added by hand is linked to its account
- ImprovedVoice & callsAI
The Pact phone line gets to the point and finds your own accounts
Answers lead with the point in a sentence or two, misheard names are matched by sound against your own accounts, and the line says people's names instead of reading out their email addresses.
What changed
Short answers first. The line answers the question you asked in a sentence or two and offers the rest only when there is more. Repeating yourself is treated as a correction, never answered with the same sentence twice, and when your workspace has used its AI allowance the line tells you plainly.
Your names, heard right. The line looks among your own accounts first, matches a misheard name by how it sounds, and asks one clear question instead of guessing between two similar accounts. It only ever chooses among records that exist.
Spoken like a person. People are named, never read out as email addresses, an account's industry is said once rather than repeated after a name that already says it, and "the contacts at" replaces an awkward possessive.
Fewer interruptions. A rep calling from their own number can make 30 calls an hour, blocked attempts no longer count toward the limit, and the line never offers a follow-up while it is still waiting on your answer.
The screen keeps up. A live call's view in the browser updates as the call happens, whichever of Pact's servers handled the moment, instead of waiting for the next reconnect.
Try it
Call your Pact line and ask about one of your accounts by name; then open /settings/voice to see the line's settings.
#2026-10-21-the-phone-line-gets-to-the-pointTechnical details
4536PR #4536 — answers lead with the point, and a repeat is a correction4537PR #4537 — the line hears and finds the caller's own names4472PR #4472 — names, not email addresses; an industry said once4471PR #4471 — 30 calls an hour from a rep's own number; no offer mid-flow4514PR #4514 — the live call view keeps up across servers
- ImprovedDocs & supportExperience
Support cases follow the conversation, in your own time zone
A customer's reply and your answer each move the case, emailed cases open on the right customer, a reply that could not be delivered says why, and every case time reads correctly wherever you are.
What changed
Status that follows the thread. A customer's reply and your answer each move the case, so the queue shows who is waiting on whom. A case that arrives by email opens on the sender's contact and account, and replies thread back into the same case.
Chat visitors are recognized. A chat visitor who gives their email address is matched to their contact.
A reply that was not sent says so. When a reply cannot be delivered, the inbox shows a warning with the reason and an Open settings button instead of a success message. Admins can set the address replies come from in Support settings, under Outbound.
Times you can trust. Every support time, from the SLA countdown to triage, participants and the renewals board, is sent as an exact moment, so it reads correctly in every time zone and the triage time says it is UTC.
Try it
Open /support/inbox, answer a case, and watch its status move; admins set the reply address under Support settings › Outbound.
#2026-10-21-support-cases-follow-the-conversationTechnical details
4468PR #4468 — a reply moves the case, and a chat visitor's email finds their contact4498PR #4498 — a reply that never reached the customer says why4463PR #4463 — every support timestamp is an exact moment4502PR #4502 — the triage time says it is UTC
- NewSales & CRMData & analytics
A slipping renewal can start its own save play
Turn it on and a health drop before a renewal starts the Renewal at risk play for the account owner. Account health now has its own CSAT signal and counts open support cases.
What changed
Off until you turn it on. On the Saves page, an admin switches on the Renewal at risk play and first sees how many accounts would have started it today.
What it does. When an account's health band drops and it has an open renewal due within 90 days, or already overdue, the play starts for the account owner: one task per step, each due by the renewal date, and one in-app notification saying why. It emails no one, and it never starts a second copy of a play already running.
CSAT counts on its own. Account health gains a CSAT signal from the 1 to 5 ratings an account gave in the last 180 days. An account nobody has rated is left out of that signal rather than scored as neutral, so turning it on moves no unrated account.
Support is part of the picture. Open support cases count as open tickets in account health, and support activity counts as activity on the account.
Try it
Open /cs-app/saves to see how many accounts the Renewal at risk play would start for today, and switch it on.
#2026-10-21-renewals-start-their-own-save-playTechnical details
4465PR #4465 — a health-band drop before a renewal starts the save play4464PR #4464 — CSAT is its own health signal; support counts as activity
- ImprovedMarketingSales & CRM
A lead shows the consent it gave, and forms embed anywhere
Every lead page answers whether you may email that person, with the form, date and boxes they ticked as proof. Converted leads land on your pipeline's first stage, and hosted forms embed on any website.
What changed
Consent on the lead. A Consent card on each lead says whether you may send them marketing email: granted, pending, withdrawn, expired or none, with the form, the date and the boxes they ticked. It is the first card on a phone, and the lead's header carries a badge. A consent record that could not be read says so instead of showing none.
Converted leads land on the board. Converting a lead puts the new deal on your default pipeline's first open stage, or the stage you choose, instead of a stage no pipeline has.
Embed anywhere. Hosted forms can now be embedded on any website.
Try it
Open a lead from /leads and read its Consent card; convert it and find the deal on your pipeline's first stage.
#2026-10-21-a-lead-shows-the-consent-it-gaveTechnical details
4470PR #4470 — a form lead shows its consent, converts onto the board, embeds anywhere
- ImprovedMarketingIntegrations & API
A live SPF, DKIM and DMARC checklist for your sending domain
Email settings check each sending domain live and show the exact record to publish. Bounces, complaints and text-message receipts are recorded once and never dropped, and inbox placement says Not measured.
What changed
A checklist that checks. For each sending domain, email settings now read SPF, DKIM, DMARC and alignment live and show the exact record to publish for anything missing.
Honest placement. Inbox placement shows "Not measured" until it has been measured, instead of an estimate.
Nothing lost on the way in. Bounces and complaints from your email provider are verified the way each provider signs them, and if saving one fails the provider is asked to send it again. Text-message delivery receipts and STOP replies work the same way, and each is recorded once.
Try it
Admins: open /admin/email/domains and read the checklist for a sending domain, with the record to publish for any line that is not yet green.
#2026-10-21-a-live-checklist-for-your-sending-domainTechnical details
4528PR #4528 — a live domain checklist; bounces verified and retried4567PR #4567 — text-message receipts and STOP replies are stored or retried
- NewPlatformSecurity & trust
Every module says what it needs to run, and members can come back
The Modules page shows, for each module you bought, whether everything it depends on is in place. Win/loss opens for Sales and CS seats, a suspended member can be re-activated, and company sign-in starts from the login page.
What changed
Ready to run. A Ready to run panel on the Modules page lists, for each module, the background jobs, settings and keys it depends on and whether each is in place, by name only. A check that could not be read says unknown, with the reason.
A module reaches its own pages. Sales seats open the win/loss deal feed behind Sales, and CS seats open the win/loss reports behind Customer Success, so neither page refuses the people who bought it.
Re-activate a member. The Users page offers Re-activate on a suspended member, on desktop and on a phone card. It takes back a plan seat and each module seat, and it refuses members managed by your identity provider.
Company sign-in from the login page. A workspace that uses OIDC single sign-on can start sign-in from Pact's login page, and admins configure it with one redirect address.
Try it
Admins: open /admin/modules and read the Ready to run panel for each module you have bought.
#2026-10-21-every-module-says-what-it-needsTechnical details
4508PR #4508 — every module says what it needs to run4509PR #4509 — a bought module reaches its pages; a member can come back4500PR #4500 — OIDC sign-in starts from the web login
- ImprovedSecurity & trustPlatform
The status and trust pages say exactly what is measured
The status page shows only what was checked, one sub-processor list stands behind the trust page and the DPA, and privacy requests name any step that failed instead of reporting zero.
What changed
Status you can believe. Each component on the status page is either measured, with how recently, or marked unknown. Uptime is shown over real checks only, with the number of days behind it, and a summary says how many components are monitored right now.
One sub-processor list. The trust page, the data processing agreement and the admin list read from one register. Each vendor says when it is engaged, and vendors Pact does not use are listed as not sub-processors.
Erasure keeps proof, not the person. A completed erasure keeps a record that the request was fulfilled, without a copy of the person's data.
Privacy requests that cannot fail quietly. If any step of an access or erasure request cannot be read, it is named on the result and the request stays open, and the impact preview says Not counted instead of zero.
Try it
Open /trust and read the sub-processor list, then open /status and see which components are measured and since when.
#2026-10-21-status-and-trust-say-what-is-measuredTechnical details
4504PR #4504 — the status page reports what was measured4505PR #4505 — one sub-processor register behind trust, DPA and admin4483PR #4483 — a completed erasure keeps proof it happened4507PR #4507 — a failed privacy-request step is named, never read as zero
- ImprovedExperienceDocs & support
A calm first day for every new teammate
A new teammate's first page is one Start here card that asks what they do and points to three places worth their first ten minutes. Nothing opens by itself, and owners see the setup wizard once.
What changed
One place to start. A new seat lands on a single Start here card that asks what they do and points to three places worth their first ten minutes.
Nothing loud before they have done anything. No tours open by themselves, there is no role picker, there are no points before any work, and What's new starts at zero.
Owners set up once. Workspace owners get the setup wizard once, not twice.
A real health number. "Avg account health" on Home now reads your accounts' real health.
Try it
Sign in as a newly invited teammate and open /home to see the Start here card.
#2026-10-21-a-calm-first-dayTechnical details
4527PR #4527 — every new seat gets one first-run surface
- FixedIntegrations & APISales & CRM
Your calendar stays connected, and a broken one says how to fix it
Pact renews calendar and mailbox connections before they expire. One that stops working says why on the calendar page, on Home and on each record's email, with a link to reconnect your own.
What changed
Connections that stay alive. Pact refreshes each connected calendar's and mailbox's sign-in before it expires, and an Outlook connection's update subscription is renewed a day ahead.
When one breaks, it says why. A connection the provider has rejected is marked as needing a reconnect, and the calendar page, Home and each record's email tab say what went wrong.
Reconnect your own. Connect and Reconnect take you to your own calendar page, not an admin screen.
Try it
Open /calendar to see your connection's state, and reconnect from there if it asks you to.
#2026-10-21-your-calendar-stays-connectedTechnical details
4496PR #4496 — calendar and mailbox connections stay connected and say why
- FixedData & analyticsAIMarketing
Numbers that say when they are missing, and AI text that ends cleanly
Marketing Today counts active journeys again, key results read account health correctly, a count that cannot be read is marked missing instead of 0, and no AI sentence stops mid-word.
What changed
Missing is not zero. Marketing Today counts your active journeys again, and a count it cannot read is marked as missing rather than shown as 0. Account-health and engagement key results read the right figures and say so when a read fails.
Whole windows. NPS averages and the tracking, social and data snapshots on Today count everything in their window, including its first day and the hours before midnight UTC.
Duplicates found again. Data-quality scans detect duplicate contacts that share an email address.
AI text ends cleanly. Every AI sentence is kept within its space on a word boundary, so none stops mid-word, and the next-best-action card shows its whole sentence and names the record it is about.
Try it
Open /marketing/today and read the active journeys count; a figure that cannot be read now says so.
#2026-10-21-numbers-that-say-when-they-are-missingTechnical details
4523PR #4523 — Marketing Today counts active journeys; a failed read says so4552PR #4552 — account-health and engagement key results read correctly4550PR #4550 — Today snapshots and NPS windows count the whole window4524PR #4524 — duplicate contacts that share an email are found again4548PR #4548 — no AI sentence stops mid-word
- PerformancePlatformData & analytics
Fast and fair as your workspace grows
The activity feed, the support queue and the dashboard funnel stay quick in large workspaces, and background work is shared fairly so one workspace's import never holds up another's.
What changed
Quick at size. The activity feed reads its newest items first, the support queue ranks cases with one read instead of one per case, and the dashboard funnel reads deals once. Each stays quick as a workspace grows.
Fair background work. Background jobs are served workspace by workspace, so one workspace's large import or backlog no longer delays everyone else's jobs or webhooks.
Try it
Open /activity in a busy workspace and page back through the feed.
#2026-10-21-fast-and-fair-as-you-growTechnical details
4521PR #4521 — the activity feed, support queue and dashboard funnel stay fast4510PR #4510 — workspaces share background work fairly
- NewAISales & CRM
Ask Pact now says how sure it is, and why
Every Ask Pact answer carries a confidence word with its weakest reason first, counts that match the lists you can open, and a line saying whose book the numbers cover. It answers about more of your workspace, and applies the filters you name.
What changed
How sure, in words. Each answer shows a confidence band with what it means (never a bare percentage), leads with the weakest reason, and adds a "how I know" line. A question Pact declined or redirected says it is not an answer, and one that could not be answered says "Not answered" instead of guessing. On a phone you see the band and one line, with the reasons a tap away.
The same numbers as your lists. Counts and lists of accounts, deals, contacts and cases now match what you see when you open the matching list, and every answer says whose book it covers: yours, your team's or the whole workspace. When the daily question limit is reached or something fails, Ask explains what happened rather than showing an error.
More of your workspace. Ask can now answer about tasks, quotes, contracts, portal tickets, NPS, onboarding, win/loss, field visits and identified website visitors. Filters you name, such as an industry, state, country or region, are applied using your workspace's own values, and "how many" questions come back as a number.
Sharper routing. Questions about invoices, recent consent changes, lead counts, why you lose and to whom, and quiet deals over a named window each reach the right answer. "How many reps hit quota" is counted for the period you name, and a forecast explanation uses the period you asked about and says whether it came in above or below plan.
Deal questions, answered from your records. Asking which deals are at risk, or "which are my largest open deals?", answers from your deal records even in a workspace with no AI model connected, with open deals listed largest first. When Ask names the "largest" at-risk accounts, they are the three with the most ARR, largest first.
Try it
On /dashboard, press the sparkle in the top bar (More › Ask Pact on a phone) and ask "which of my deals are at risk?": the answer shows how sure it is and whose book it counted.
#2026-10-20-ask-pact-says-how-sure-it-isTechnical details
4352PR #4352 — every answer shows how sure it is, in words4348PR #4348 — answers match the asker's own lists and name whose book4358PR #4358 — more modules, and the filters you name4373PR #4373 — questions reach the right answer; forecasts read the period4421PR #4421 — at-risk deals answered from records without a model4425PR #4425 — the largest at-risk accounts are the largest by ARR4497PR #4497 — your largest open deals, listed without a model
- NewVoice & callsAI
The Pact phone line learns the names you correct, and shows you what it learned
After each call the Pact line learns the names you correct it on and tunes how much it says. A What Pact learned page lists every change with the calls behind it, and lets you undo it or turn learning off.
What changed
It learns from your calls. After every finished call, the line picks up the names you correct ("no, I meant …"), and uses a name once two calls agree on it. Learned names belong to your workspace. It also tunes how much it says: more detail when you often ask it to repeat, shorter answers when you often cut it off.
You can see and undo all of it. Settings › Voice › What Pact learned shows each change, the calls that caused it by date and time (linked to each call's page) and when it happened. Undo or delete anything, or switch learning off.
Admins can review the whole workspace. Owners and admins get a Workspace names page listing every learned name: what the line heard, the account it maps to, who taught it and the calls that confirmed it. Removing a name is logged under the admin's name, and erasing a contact's data removes learned names that match them.
Better conversations. Ask two questions in one breath ("What accounts do I have? Which are at risk?") and both are answered, in order. When the line talks with a caller in another supported language, its greeting says it is an AI in that language. The first call after Pact restarts answers as quickly as every call after it.
More you can do by phone. "Tell me about" an account includes its deals. Log a call and correct the account mid-sentence ("no, I meant …"), or give the account and the summary in one breath; the note lands on the account you meant, with its time, in the activity timeline. Saying goodbye simply ends the call.
Honest when a source is missing. If a deal timeline cannot read one of its sources, such as calls, the line says so out loud instead of implying nobody called. The weekly review counts the deals that moved stage from the full activity history, and says so when every one of those moves comes from imported history.
Every insight on the call page. A call's page now shows every insight Pact extracted. Workspaces that use MEDDPICC get a tab for each MEDDPICC area with findings, anything else collects under Other, and the page opens on the first tab with content.
Try it
After a call on the Pact line, open /settings/voice/learned to see what changed and which call taught it.
#2026-10-20-the-phone-line-learns-and-shows-youTechnical details
4391PR #4391 — the phone line learns from every finished call4401PR #4401 — owners and admins review every learned name4405PR #4405 — Workspace names shows each confirming call's time4396PR #4396 — What Pact learned links each call by date and time4422PR #4422 — plain-words messages on the learning pages4338PR #4338 — two questions in one breath are both answered4337PR #4337 — the AI disclosure in the caller's language4416PR #4416 — the first call answers as fast as the hundredth4419PR #4419 — a missing timeline source is said aloud4159PR #4159 — the weekly review counts every stage move4363PR #4363 — every AI insight on the call page4435PR #4435 — an account brief reads the account's deals4438PR #4438 — log-a-call keeps your correction and timestamps the note4437PR #4437 — goodbye ends the call
- ImprovedSales & CRMData & analytics
One lifecycle stage per account, everywhere, and where accounts stall
An account's stage now reads the same on its page, in lists, segments, reports, search, voice and Ask. Analytics shows where accounts stall between stages, and Customer Success sees a newly won customer the day it is won.
What changed
One stage line. The account page shows one stage: the one Pact derives from your records, or a stage someone set by hand when it is further along, with who set it, when and why. Changing it asks for a reason, and the change is kept in the account's history.
The same stage everywhere. The Accounts list filter (now with a Customer option covering every customer stage), segments, custom reports, plain-language reports, playbooks, search, Ask and voice all read that one stage. A stage your pipeline marks as won counts as won whatever it is called, and saved views and old links keep working.
Where accounts stall. Analytics › Funnels opens with conversion and time spent in each lifecycle stage. Stage history is recorded as accounts are opened and worked, so counts are shown as minimums and the page says so.
Customer Success, from day one. A just-won customer appears on the CS boards and accounts list straight away, marked Not scored yet, with a Stage column and a Not scored filter. The CS Journey board's columns are real customer stages (Just won, Onboarding, Supported, Renewed) with risk on each card and an At risk only filter. The CS home shows each CSM their own book, and managers their team's.
Reasons in sentences. The reason beside each customer-health score now reads as a plain sentence instead of a raw count.
Marketing and phone homes. The Marketing home shows the lifecycle lane for the accounts your campaigns and journeys reached, and how many records could not be matched to an account. On a phone, a module home's lifecycle lane opens on its top three next actions, each with its reason. Converting a lead now carries its source, owner and notes onto the new account, contact and deal.
Try it
Open /analytics-app/funnels to see where accounts stall, then an account page to see its one stage line and who set it.
#2026-10-20-one-lifecycle-stage-and-where-accounts-stallTechnical details
4349PR #4349 — one stage vocabulary for every reader and writer4354PR #4354 — one stage line, the CS journey, where accounts stall4376PR #4376 — CS sees a just-won customer before it is scored4382PR #4382 — search, Ask, voice and reports read one stage; lead fields carry over4407PR #4407 — reports, segments and playbooks read one stage4353PR #4353 — the Marketing lane, the CSM's book, next actions on a phone4366PR #4366 — customer-health reasons read as sentences
- FixedSales & CRMData & analytics
Forecast Commit, close dates and at-risk lists that add up
Commit adds up the deals reps called Commit, the forecast strip weights open deals only, close dates show the day the rep picked in every time zone, and at-risk lists leave out deals that are already won or lost.
What changed
Commit means Commit. Analytics › Forecasts adds up the open deals your reps called Commit, the same figure the sales Forecast page shows, and says how many deals it covers.
One forecast strip. The pipeline's forecast strip folds different spellings of a category into one ("COMMIT" and "Commit"), and its total is Open, weighted: open deals only, each at its own probability, so it matches the dashboard. Workspaces with closed-won deals will see this total come down, because won deals no longer count in it.
The day the rep picked. Close dates on the board, the deals list and the deal page show the date that was chosen, west of UTC too, so a January 1 close stays in its quarter.
At-risk lists you can act on. Each deal's risk level comes from its current score, and won or lost deals drop out of the at-risk lists on Today, the dashboard and the risk feed.
Every stage move, recorded the same way. Whether a deal moves on its page, by voice, from chat or through the API, it records the same stage history, close date and forecast update, with who or what moved it. A stage that does not exist in that deal's pipeline is refused with the list of valid stages.
Cycle time and coverage. Average sales cycle measures won deals from creation to close, and says so when no won deal has a close date yet rather than showing 0. The pipeline-coverage figure that the API and connected AI assistants read counts only the period's won deals toward its goal.
Try it
Open /analytics-app/forecasts and compare Commit with the sales forecast, then the forecast strip on /pipeline.
#2026-10-20-forecast-numbers-that-add-upTechnical details
4430PR #4430 — forecast Commit reads what reps called Commit4431PR #4431 — the forecast strip folds spellings and weights open deals4449PR #4449 — a close date reads as the day the rep picked2736PR #2736 — risk level from score; closed deals leave at-risk lists4374PR #4374 — every stage move writes the same history4427PR #4427 — average sales cycle measures won deals4426PR #4426 — coverage counts the period's won deals
- ImprovedSales & CRM
Managers open on their team's board, and a rep's pages read as theirs
A manager's pipeline opens on their team's deals with a switch to their own, leader Today pages work like every other home, and a rep sees open pipeline, the forecast and Radar cards that name the record they are about.
What changed
The team's board, first. A manager with direct reports opens the pipeline board on the team's deals, titled Team pipeline, and can switch between Team and Mine. Opening a report's board shows that person's deals. Reps still open on their own book, and a new workspace's sample deals belong to its real people. Manager Today and the manager forecast show each rep's real open deals and pipeline value, including deals created in the app.
Leader homes that hold together. Sales manager and director Today pages have a title in every state, the lifecycle lane for the team's book, waiting chips and a Try again that reloads. On desktop, the "whose data" picker sits in the page header, and a link to a CSM's Today opens that CSM's book.
A rep's pages. When no deal value has been typed in, the account header shows the account's open pipeline. Open forecast on Today opens the forecast. Members no longer see admin-only setup links on AI cards, and at-risk deals scored on deal records appear in Today and open the deal's own page.
Radar names the record. Each Radar suggestion names the account, contact or deal it is about, filter chips show how many of each kind are waiting, and Do it on a deal card opens that deal on the board. A reply draft without a connected mailbox says Connect your Gmail and links to your own connection page.
Try it
As a manager, open /sales/pipeline: it opens on your team's deals, with Team and Mine above the board.
#2026-10-20-managers-open-on-their-teams-boardTechnical details
4320PR #4320 — managers open on their team's board; sample deals have owners4347PR #4347 — leader Todays on the frame, the scope picker in the header4482PR #4482 — a rep's pages read as a rep's4403PR #4403 — deal-keyed risk reaches Today; reply draft says your Gmail2668PR #2668 — Radar names the record and shows the breadth4447PR #4447 — a rep's deals count on Manager Today
- NewSales & CRMExperience
Your week on the calendar page, and an attendee picker by name
The calendar page shows your next seven days with each meeting's account and deal, managers see who on the team has a connected calendar, and attendees are picked by name. Schedule meeting says what is missing and lets you keep working.
What changed
Your next seven days. The calendar page lays out your week: each meeting with its account, and its open deal when there is exactly one. Free time in working hours is marked as unverified when Pact cannot see your calendar, and your connection state sits on the page with the step that fixes it.
For managers. The team view shows each rep's calendar connection, read-only, and coverage counts only the reps whose calendar Pact can see.
Attendees by name. When scheduling or editing a meeting, pick attendees from your workspace's people and the account's contacts, or type an email.
Connect from where you are. Connect calendar, Reconnect and Check calendar settings open your own connection page, as does Connect Gmail on a reply draft. Last synced always reads as a past time.
Schedule meeting says what it needs. On an account or contact, the dialog tells apart a calendar that is not connected (with a one-click Add a task to schedule it), a calendar with no booking links yet, and a read that failed (with Try again).
Try it
Open /calendar to see your week with each meeting's account and deal, and your connection state.
#2026-10-20-your-week-on-the-calendarTechnical details
4388PR #4388 — each rep's calendar state, their week, an attendee picker4360PR #4360 — connect and reconnect open your own calendar page4451PR #4451 — Schedule meeting says your calendar isn't connected4393PR #4393 — last synced is always in the past
- FixedMarketingData & analytics
Campaigns get credit for the deals their forms start
When a form fill becomes a lead and the lead becomes a won deal, attribution credits that form's campaign. Campaign sends count toward their account the moment they go out, and interest alerts say why an account surged.
What changed
Forms that win deals get the credit. Attribution now follows a won deal back to the lead it was converted from and the form touches on that lead. Web visits and lead touches are ordered by time, so first-touch, last-touch and U-shaped models weigh them correctly, and a deal converted without a company is credited too.
Sends count right away. Each campaign send is linked to its account as it goes out, so the Marketing home's account lane includes it immediately.
Alerts that explain themselves. When reading from an account surges on your website, the owner's alert says why in plain words, names the pricing page when that is what drew the visits, and links to the account. An account with no earlier activity is described as new interest.
Try it
Open /marketing/attribution and switch between first-touch and U-shaped: deals that began with a form fill now carry their campaign.
#2026-10-20-campaigns-get-credit-for-their-dealsTechnical details
4432PR #4432 — a deal won from a campaign's form is credited to it4381PR #4381 — campaign sends resolve to their account when written4359PR #4359 — a surge alert tells the owner why
- SecurityNewSecurity & trust
Sign-in asks for your authenticator, and admins can require MFA by role
Set up an authenticator app and sign-in asks for its code after your password. Admins can require multi-factor sign-in for a role, see who a rule affects before saving, and role changes from your identity provider follow group membership.
What changed
A code after your password. Once you add an authenticator app under Settings › MFA, sign-in asks for its 6-digit code, or one of your recovery codes. Passkey and single sign-on sign-ins rely on the passkey or your identity provider instead.
MFA by role. Admins can require multi-factor sign-in for any role on the IAM policies page, which explains who a rule will affect. When the grace period ends, someone who has not enrolled gets a setup-only sign-in that lets them add an authenticator and save recovery codes before going any further.
Rules that apply to open sessions. Turning on MFA required for a role first lists everyone it would sign out, people with no passkey or authenticator, and signs them out only after you confirm. You cannot sign yourself out this way, and nobody is signed out during a grace window.
Groups decide roles. When your identity provider grants a role through a group, removing someone from that group, unmapping it or deleting it returns them to their own role in Pact and refreshes their session. A role set by hand on the Team page counts as their own.
Immediate. Signing out, ending a session, deactivating someone or changing their role takes effect on the very next request.
Try it
Open /settings/mfa to add an authenticator app; admins set per-role rules on the IAM policies page.
#2026-10-20-sign-in-asks-for-your-authenticatorTechnical details
4325PR #4325 — sign-in asks for an enrolled authenticator; per-role MFA applies4332PR #4332 — MFA required names, then signs out, the sessions it disallows4333PR #4333 — leaving an IdP group takes away the role it gave4357PR #4357 — sign-outs and role changes hold on every app machine
- ImprovedPlatformSecurity & trustIntegrations & API
Workspace settings show what each one enforces, and AI spending caps hold
Organization settings now say whether each setting is enforced, applied, report-only or stored only, with your workspace's real thresholds. The monthly AI spending caps refuse requests once reached, and more admin changes reach the audit log.
What changed
Every setting says what it does. Organization settings shows, for each field, whether it is enforced, applied, report-only or stored only, with this workspace's actual thresholds and AI spend, in plain words.
AI spending caps are enforced. The monthly caps for the whole workspace and for each person now refuse further AI requests once reached, with a message pointing to the setting. Unless an owner changes them, the caps are $5,000 a month for the workspace and $200 a month per person, so a heavy user can reach theirs. Spend on your own model key is shown as not enforced.
More in the audit log. Role changes made by an identity-provider group sync, every change to the AI spending cap, and team role changes, invites and removals all appear in the audit log with who made them.
Webhooks you can de-duplicate. Each event reaches a subscription once, with the same event ID on every retry, and re-enabling a paused subscription no longer replays everything it missed. Website events identify the account by its public ID, as documented.
Schema exports. The schema explorer exports your data model as a Prisma schema, an OpenAPI fragment or the migration history, with tables above your access level redacted.
Try it
Open /admin/settings to see which settings are enforced and your workspace's AI caps.
#2026-10-20-settings-show-what-they-enforceTechnical details
4377PR #4377 — settings show what each one enforces4380PR #4380 — the settings map in plain words4367PR #4367 — the monthly AI caps refuse the call4328PR #4328 — group syncs, AI cap edits and team changes are audited4408PR #4408 — each webhook event once, under one stable event ID4369PR #4369 — schema explorer exports work
- NewAISecurity & trust
See every question asked of your workspace in the Ask trail
Owners and admins can review every question asked of the workspace's data, with personal details redacted before storage and how sure each answer was. Ask also declines an answer that would cost more than 5¢, before spending anything.
What changed
A trail you can audit. AI governance gains the Ask trail: every question asked of your workspace's data, with personal details redacted before anything is stored, how sure each answer was, and totals for the period. Members never see colleagues' questions.
Kept briefly, erased with the person. Questions are kept for 90 days by default, and a question that cites a person is deleted when that person's data is erased.
Limits stated, and checked first. Ask estimates what an answer will cost before calling a model and declines, with the reason, if it is over the per-answer limit of 5¢. The AI budget page's Ask limits card states the daily question limit, where it comes from, today's use and the per-person-per-minute ceiling.
Try it
Open /admin/security/ask-trail to review the questions asked this week and how sure each answer was.
#2026-10-20-the-ask-trailTechnical details
4404PR #4404 — every Ask question leaves a redacted, erasable trail4410PR #4410 — decline an answer before paying for it4378PR #4378 — the AI budget page shows the Ask daily limit and its use
- NewData & analyticsSecurity & trust
Scheduled data exports that run, with a receipt for every run
Owners and admins can export accounts, contacts, deals and more with the filters they choose, schedule it to recur, and get a signed download link by email. Each schedule shows what its last run did, whether the email went out and when the link expires.
What changed
Build it once, get it on your schedule. Choose what to export (accounts, contacts, deals and more) and filter it, then schedule it to recur or press Run now. Each run produces a signed download link, sent by email, that expires after seven days.
A receipt for every run. Each schedule shows the last run's result, whether the email went out (and, if it was held, the reason in plain words), how often the link was opened, when it expires and when the next run is due.
What left, on the record. Export history lists the fields that left your workspace in each run. Sending to an address outside your workspace follows your email safety settings.
Try it
Open /admin/export, build an export, then schedule it or press Run now to get its receipt.
#2026-10-20-scheduled-exports-with-a-receiptTechnical details
4428PR #4428 — scheduled exports that fire, and a receipt per run
- FixedDocs & supportSales & CRM
Support SLA clocks are right in every time zone, and open cases count toward health
A case's due time and SLA countdown now read the same real moment wherever the viewer is. An account's open support cases count toward its health score and appear on its health card.
What changed
The real deadline, everywhere. Due times and SLA countdowns on the case page, the case list and its events, the at-risk board and the support queue count down from the actual deadline, whether you work east or west of UTC, so a case never looks safer or later than it is.
Open cases count toward health. An account's health score now includes its open support cases, and its health card shows how many there are. Accounts with open cases may score lower once their health is recalculated, which is the point: the score now reflects them.
The Support workspace is part of enterprise plans.
Try it
Open /support/queue and compare a case's countdown with its due time; then an account's health card for its open cases.
#2026-10-20-support-sla-clocks-in-every-time-zoneTechnical details
4439PR #4439 — the SLA clock counts down from the real instant4444PR #4444 — open support cases count as open support tickets
- ImprovedMobileSales & CRM
Field reps see when each account was last visited, and a scorecard that adds up
Every account in a field rep's territory shows its last visit, and accounts untouched for 30 days or more are flagged with how long it has been. The scorecard's visit counts add up to the visits planned.
What changed
Last visited, at a glance. Each account in a territory reads "Visited" with the day of its last visit, or "Not visited yet", and an account untouched for 30 days or more is flagged with how long it has been. If visits cannot be read, the page says so rather than showing "Not visited yet".
A scorecard that adds up. The Visits card shows done, skipped, no-show and still-open visits, and the four add up to the visits planned. New opportunities count deals opened within a week of a completed visit.
The same Today. Field's home now uses the standard Today layout, leading with the next stop.
Field is part of enterprise plans.
Try it
Open /field/territory to see each account's last visit, then the scorecard to check that the visit counts add up.
#2026-10-20-field-territory-and-scorecardTechnical details
4323PR #4323 — territory shows the last visit; the scorecard adds up
- ImprovedExperienceData & analytics
When something can't load, Pact says what in plain words, and the rest keeps working
A chart or list that cannot load now says what happened in plain words, with the technical detail behind Details and a Copy for support button. One failed panel no longer blanks the Analytics home, and several pages that showed an error now load.
What changed
Plain words, details on request. Error messages and notices across Pact say what happened in a sentence. The request, status and a support reference sit behind Details with a Copy button, on dashboard charts, Analytics, data profiles and sources, consent rules, billing usage and voice setup.
One panel, not the page. On the Analytics home, Win/Loss and Support analytics, a section that cannot load shows its own Couldn't load with Try again while the rest of the page works. Win/Loss leaves its totals blank rather than undercounting when some reasons cannot be read, and the dashboard's consent mix no longer reports "no records" when it simply failed to load.
The same Today for Analytics. The Analytics home uses the standard Today layout: alarms and moves first, the range picker above every panel, and full-width charts. The alarm panel waits for its comparison before saying anything is calm.
Pages that load again. The at-risk cases list, perks, the admin transparency snapshot, the list of installed OAuth apps and the related-records panel on account pages load as they should, and the cards on a contact's page find the contact they belong to.
Past tense for the past. Times for things that already happened, such as updated or last run, always read in the past tense, and voice diagnostics name each call by its date and time.
Try it
Open /analytics-app/today: if a panel cannot load, it says so on its own and the rest of the page keeps working.
#2026-10-20-plain-words-when-something-cannot-loadTechnical details
4370PR #4370 — a partial answer costs one panel, never the Analytics home4386PR #4386 — the rest of the panels survive bad data4383PR #4383 — Analytics and Field get the same Today4390PR #4390 — failures in plain words, details behind Details4397PR #4397 — the consent block and Analytics say a failed read plainly4415PR #4415 — server text out of the sentence; past events in the past tense4318PR #4318 — ten endpoints that errored now answer2439PR #2439 — contact cards find records that exist
- ImprovedMobileExperience
Pact on a phone: clear of the home indicator, with labels that stay whole
On iPhone the tab bar sits above the home indicator and every page scrolls clear of it. Buttons keep their whole label, crowded rows wrap, and what you just saved appears in the list straight away.
What changed
Room at the bottom. The tab bar's labels sit above the iPhone home indicator, the end of every page scrolls fully clear of the bar, and the voice dock, floating buttons and sheets line up with it. Pages no longer end in a band of blank space.
Labels stay whole. Buttons on phones and tablets are never squeezed below their own label, and crowded rows of actions wrap instead of cutting words.
What you saved, right away. Something you just saved appears in the list you are looking at, such as a task added on an account's Tasks tab.
One comment box. Coaching reviews, support resolution and close notes, and field-visit notes use the same comment box as the rest of Pact, and a draft you come back to is restored in the box.
Try it
On an iPhone, open /sales/today and scroll to the end: the last card clears the tab bar and the home indicator.
#2026-10-20-pact-on-a-phone-clears-the-home-indicatorTechnical details
4371PR #4371 — the iPhone tab bar clears the home indicator4457PR #4457 — tap-target floors stop squeezing labels4448PR #4448 — a list refetched after your save shows it4389PR #4389 — one composer for coaching, support and visit notes
- ImprovedDocs & supportExperience
Help for every screen, navigation in your language, and a first day in your own module
Every screen in the navigation has a Help entry saying what it is for and where its data comes from. Navigation labels are translated in every supported language, invitees land in their own module, and notifications work in a new workspace.
What changed
Help on every screen. The Help panel now covers every screen in the navigation: what it is for, what people do there and where its data comes from. 71 screens gained an entry, and five admin entries were corrected to say exactly what their screen does.
Your language, all the way down. 49 sidebar and mobile navigation labels, such as Calls, Voice and Dialer, are translated in all 14 supported languages besides English.
Tours that open the page. Each role's tour includes the new screen that matters to it, every step describes what the product does, and seven Try it links open the page the step is about.
A first day that fits. Accepting an invitation lands you on your own module's home, shaped by the role your inviter chose. Someone who opens an admin page without admin rights is told who the page is for and offered a way back, and the Pick your role prompt opens on its own only on the home page.
Migrations that arrive whole. Deals brought over from your previous CRM appear on the deals page, the account page, Today and in Ask. The first-run tip no longer covers the setup wizard's buttons, and the docs helper in the navigation is now called Help & how-to, so it is never mistaken for Ask Pact, which answers from your data.
Notifications from the start. In a new workspace, the bell and the Notifications page show your notifications. An empty page explains what will arrive there and links to notification settings, and a failed load offers a retry.
Try it
Open /notifications, then the Help panel from the top bar: every screen in the navigation now has an entry.
#2026-10-20-help-for-every-screenTechnical details
4385PR #4385 — every nav screen has help4411PR #4411 — five help lines say what the code does4339PR #4339 — 49 nav labels in 15 languages4402PR #4402 — role tours show the new screens4406PR #4406 — every role-tour step says what the product does4424PR #4424 — an invitee lands in their own module4481PR #4481 — an admin page tells a rep who it is for4364PR #4364 — a new workspace's notification page works4455PR #4455 — a migrated deal shows up as a deal; Help & how-to
- ImprovedMarketingExperience
Watch the guided tour without sound, and every hands-on moment fits the screen
The guided Pact tour can be watched muted with captions, has a clearly labeled way out, and fits each hands-on moment on screen without scrolling on desktop and iPad. On a phone, the first screen of a moment holds the instruction, the control and Close.
What changed
Watch it anywhere. Mute the narration and follow the captions. A labeled exit is always in view, and focus returns to where you were when a moment closes.
Moments that fit. On desktop and iPad, every hands-on moment fits under the film with no inner scrolling. On a phone, the first screen holds the instruction, the control and Close, and a More below cue appears when there is more.
Chapters at a glance. Chapter pills are never cut mid-word, and the field moment says what to do.
The tour opens after a quick request for access.
Try it
Request access at /demo/access, press Play, then mute: the captions carry the tour.
#2026-10-20-watch-the-tour-without-soundTechnical details
4365PR #4365 — watch it without sound, a labeled way out4412PR #4412 — every live moment fits under the film
Week of October 12, 2026
Oct 12 – Oct 18 · 16 updates
Mostly Sales & CRM, Marketing, Voice & calls
- See which companies visit your website, matched to your accounts
- Know when an account gets interested, and who should hear about it
- Voice: every call, voicemail and meeting in one list to search and replay
- Pact answers in your customer's language, in twelve languages
- Pact line calls record from the first word, once recording is on
- The Pact line holds for hard questions and asks before it changes anything
- Every record page opens with one customer header, and edits never collide
- Contacts, deals, leads, cases and campaigns search and count your whole book
- Today starts with what to do, and every page is easier to find again
- Pact on a phone: faster pages, thumb-sized buttons, a step-by-step dialer
- Choose who sees each dashboard, and each rep's book holds their own deals
- A new workspace says what it lacks, and imports keep going past a bad row
- Stronger sign-in, single sign-on and export controls for every workspace
- The guided Pact tour waits while you try it yourself
- Managers get a team calendar: who has no customer meetings, and the week ahead
- pact.place reads cleanly on every phone and screen
- NewMarketingSales & CRMData & analytics
See which companies visit your website, matched to your accounts
Paste one line on your website and Pact shows which companies are reading it, what they read, and which of them are already your accounts. Home, mobile and VPN traffic is labeled as such and never matched to a company.
What changed
One line, and a live check. The Install page under Tracking gives your workspace the line to paste into your site, and shows the first visit the moment it arrives. Owners and admins create and rotate site keys. A new workspace's setup wizard ends on this page.
Consent decides what is collected. A browser that sends Global Privacy Control is never tracked. Outside the US, and wherever the country is unknown, nothing is stored until the visitor accepts; US visitors get notice and a way to opt out, unless your banner is set to opt-in everywhere. Raw IP addresses are never stored.
Companies, never guesses about people. Each visit is labeled as a home, mobile or company network. Visits from a company network are matched to your accounts, and a company you don't have yet can be added as an account in one step. Pact never names a person from an IP address.
Where it shows up. Accounts on your site lists each company with what it read and how interested it looks; Visitors lists the people Pact has recognized and how it knows them. Every account page gets an On your site card, the first visit becomes the first entry on its timeline, and the Sales and Marketing Today pages show the top five.
Tracking is a module: its pages need Tracking switched on, and the accounts list also works with Sales or Marketing.
Try it
Open /tracking-app/install to get your line, then /tracking-app/accounts once the first visits arrive.
#2026-10-16-see-which-companies-visit-your-siteTechnical details
4098PR #4098 — one line on any website, consent first, live from the first visitor4096PR #4096 — accounts and visitors on your site4092PR #4092 — visits matched to your accounts, home/mobile/VPN filtered out4103PR #4103 — every visit labeled home, mobile or company network4146PR #4146 — tracking on account pages and in the setup wizard
- NewSales & CRMMarketing
Know when an account gets interested, and who should hear about it
Every account on your site gets an interest level with the pages behind it, refreshed every six hours. Its owner hears the day an ideal-fit account reads your pricing page, and a website visit can start a journey.
What changed
Interest you can read. Each account visiting your site carries an interest level with page-by-page reasons, refreshed every six hours.
Alerts that reach someone. The account owner is notified the day an ideal-fit account reads your pricing page or its interest surges. An account with no owner, or whose owner has left the workspace, alerts the workspace owner instead, with a note saying why.
Journeys that start from a visit. Write a trigger in plain words, such as "when an ideal-fit account reads your pricing page twice in a week", and it starts a journey or alerts the owner, once per event. Every send still goes through consent and your workspace's email safety settings.
History that follows the person. When a visitor signs in, submits a form that matches a contact, clicks a link in an email you sent them, or a teammate attaches their chat to a contact, their earlier visits join that contact's record. A shared browser never hands one person's history to the next, and erasing a contact erases their visits with them. Converting a lead links the new contact to its company.
Webhooks and the activity feed. Six website events (visits, page views, forms started, visitors recognized, accounts recognized and interest surges) are available to webhooks, without IP addresses, and read as plain sentences in the activity feed.
Try it
Open /journeys/triggers and start a journey from a website visit, or open an account in /tracking-app/accounts to see its interest and the pages behind it.
#2026-10-16-know-when-an-account-gets-interestedTechnical details
4101PR #4101 — interest bands, reasons and pricing-page alerts from live traffic4093PR #4093 — web visits and interest surges start journeys and alert owners4094PR #4094 — earlier visits join the record at the first trusted moment4156PR #4156 — an account with nobody to tell reaches the workspace owner4091PR #4091 — six website-visit events for webhooks and the activity feed4229PR #4229 — a converted lead's contact is linked to its company
- NewVoice & calls
Voice: every call, voicemail and meeting in one list to search and replay
A new Voice page holds every conversation with Pact: phone calls, voicemails, meetings and voice notes, recorded or not. Search the words that were said, filter by person, language, outcome or length, and open any one to listen and read it.
What changed
One list for every voice conversation. Calls on your Pact line and from the dialer, voicemails, meetings, voice notes and in-app voice all land in Voice. Save a view, export it, or open a row to play the recording beside its transcript. A teammate's private conversation stays private.
It says what happened. Each conversation shows how it went (answered, partial, or ended by Pact), and when Pact ended a call, why. A conversation that was not recorded says why not, in plain words.
Read it in English. On a conversation in another language, Show in English translates the whole call at once and marks any line it could not translate.
Where it lives. Voice is in the main navigation, and the old call log and voice hub links open it. Voice comes with the Sales module; turning recording on is for admins.
Try it
Open /voice/interactions, search for a word a customer said, and open the conversation to listen.
#2026-10-16-voice-every-conversation-in-one-listTechnical details
4084PR #4084 — Voice: every voice conversation in one list4078PR #4078 — one searchable list over every voice source4090PR #4090 — Voice says why a call wasn't recorded, and how it ended4088PR #4088 — translate a whole call in one step; untranslated lines marked
- NewAIVoice & calls
Pact answers in your customer's language, in twelve languages
Pact recognizes which language a customer speaks or writes and answers in it: on the phone, and in the drafts and summaries it writes for you. Your team can read an English translation alongside.
What changed
Twelve languages. English, Spanish, French, German, Portuguese, Italian, Dutch, Japanese, Chinese (Simplified and Traditional), Korean, Arabic and Hindi, in sixteen regional versions. All are on by default, and an admin can narrow the list under Conversation language.
On the phone. The Pact line answers callers in their language and changes language only when the caller does, never on a single stray word; a caller can also just ask ("en español, por favor"). A caller whose contact record names a preferred language is asked for recording consent in that language.
In what Pact writes. Voicemail reply drafts, call and meeting summaries, voice-note summaries, email reply drafts, case reply suggestions, survey summaries and social inbox drafts are written in the customer's language.
Remembered, and erasable. A contact's preferred language is saved on their record, and erasing a contact erases their saved translations too.
Try it
Open /voice/interactions and filter by language; admins choose which languages the workspace answers in under Admin, Conversation language.
#2026-10-16-pact-answers-in-your-customers-languageTechnical details
4081PR #4081 — twelve languages, one language layer4080PR #4080 — answers in the customer's language on the phone and in every draft4089PR #4089 — the line changes language only when the caller does
- ImprovedVoice & callsSecurity & trust
Pact line calls record from the first word, once recording is on
Turn recording on and every call on your Pact line is recorded from the first word, after one consent question in the caller's language. The recording page says whether the next call will record and, if not, the one thing in the way.
What changed
On when you say so. Recording stays off until an owner or admin turns it on. From then on every call on your Pact line is recorded from the first word, whichever way it reached you.
One consent question. The caller is asked once, in any of twelve languages. A "no" carries on with the call, unrecorded.
A page that tells you. The recording page says whether the next call will record and, if it won't, the one thing in the way, with counts for the last 24 hours.
One recap per call. When the phone carrier reports the end of a call twice, the call still gets exactly one recap, one CRM update and one team alert, and keeps its real length.
Try it
Open /admin/voice-recordings to see whether your next call will record.
#2026-10-16-calls-record-from-the-first-wordTechnical details
4079PR #4079 — calls recorded on every path, consent asked once2669PR #2669 — a repeated live event cannot break the call's record2673PR #2673 — the end-of-call notice claims each side effect once
- ImprovedVoice & calls
The Pact line holds for hard questions and asks before it changes anything
When a question takes a moment, the Pact line says so and comes back with the answer. It finds the account you meant with one question, answers who owns an account with a name, and asks you to verify before it creates, edits or closes a record.
What changed
It holds, then answers. A question that takes longer gets "one moment" and then the answer. Answers arrive without long silences, and the line is yours again as soon as Pact finishes speaking.
It finds what you meant. When one account is clearly the one you meant, it asks one quick question instead of reading out a menu of names. "Who owns Acme?" gets the owner's name. A command like "tell me about my risks" is heard as a command, not as a company.
It checks before it changes. Before the line creates, edits or closes a record, it asks the caller to verify, and a code from your authenticator app works. On a line set not to ask for a code, changes are made in the app instead.
Calls end well. A call where the caller has gone silent is ended rather than left open, and the per-call spending limit counts the carrier's minutes. A caller who is abusive gets one polite boundary and then a polite close; admins can set how strict that is.
Try it
Add an authenticator app at /settings/mfa, then call your Pact line, ask who owns one of your accounts, and make a change to it.
#2026-10-16-the-pact-line-holds-finds-and-checksTechnical details
4203PR #4203 — hold and deliver, instead of discarding the answer4230PR #4230 — the hold wired into every call4235PR #4235 — a question no longer waits behind a write4232PR #4232 — a clear match is one question, not a three-name menu4236PR #4236 — a command never reaches the company-name matcher4163PR #4163 — "who owns X" answered with the person4143PR #4143 — the line opens as soon as the answer ends4132PR #4132 — a silent call ends; the spend limit counts carrier minutes4082PR #4082 — an abusive call ends politely4148PR #4148 — changes by phone ask the caller to verify4213PR #4213 — an authenticator code works as the second step
- ImprovedSales & CRMExperience
Every record page opens with one customer header, and edits never collide
Accounts, contacts, leads, deals, cases and renewal briefs open the same way: who the customer is, where they stand in plain words, and the same four quick actions. When a colleague changed the field you are editing, you see both values and choose.
What changed
One header on every record. Each record page opens with who the customer is, a standing line in words (for example "In pipeline — Health 43 · at risk"), and links to the same customer in your other modules. Every record type has one tab row and the same four quick actions: Note, Task, Timeline and Files.
Edits that say what happened. An inline edit says Saved, or Didn't save with a Retry. If a colleague changed the same field first, you see both values and pick one, so nobody's edit is silently overwritten.
Rates that add up. Open and delivery rates on accounts, contacts and sequences always sit between 0 and 100%, show the counts behind them ("3 of 4 delivered"), and change in points. A window that sent nothing says so.
An activity feed that reads like notes. The activity page and every account's Activity tab show who did what to which record, in plain words, grouped by day, and a filtered feed can be shared as a link.
Try it
Open any account from /accounts, edit a field from the header, then open its Activity tab.
#2026-10-16-one-customer-header-on-every-recordTechnical details
4058PR #4058 — one customer header on every record page4068PR #4068 — one tab row, equal quick actions, a standing line in words4073PR #4073 — Sales and CS workspaces carry the same header4065PR #4065 — every rate is a per-send funnel, changes in points4074PR #4074 — one activity timeline that reads like a colleague's notes
- ImprovedSales & CRMMarketing
Contacts, deals, leads, cases and campaigns search and count your whole book
Every main list searches, sorts, filters and counts across everything you can see, not just the rows on screen. The view lives in the link, you choose the columns, and export takes the view you are looking at.
What changed
Whole-book answers. Contacts, Deals, Leads, Cases and Campaigns search, sort, filter and count across your whole book, and the count is the real total.
Your view, kept. The view stays in the link so you can share it. Pick and order your columns, and export the current view, up to 10,000 rows. On Deals you can change the amount, close date and owner right in the table.
At a keyboard, and on a phone. j and k move, x selects, Enter opens and / searches. On a phone each list becomes cards with a filter sheet, and filter rows scroll on one line. A cut-off name or amount shows in full on hover.
Try it
Open /contacts, filter it, copy the link and open it in a new tab: the same view comes back.
#2026-10-16-lists-search-the-whole-bookTechnical details
4062PR #4062 — Contacts and Deals sort, filter and count across the whole book4072PR #4072 — Leads, Cases and Campaigns do the same4069PR #4069 — one rhythm at phone and desk widths
- ImprovedExperience
Today starts with what to do, and every page is easier to find again
Every role's Today page opens on what is waiting for you and your top three next steps. Breadcrumbs, pins and recent records sit on every page, and two keys switch module.
What changed
Today, in order. Waiting on you comes first, as chips with counts, then Start here with your top three actions, then context you can collapse or reorder. Your layout is saved for you, and on a desktop Today uses two columns.
Find your way back. Every page has breadcrumbs. Pin any page, filters included, to the command palette (⌘K), the sidebar and the phone's More menu; your recent records show there too. Press m and a letter to switch module, or g then i for the inbox.
Pages that open the same way. Title first, then filters, then content, starting at the same height on every page, with one back control on record pages. Loading, error and not-found pages say what happened, and dashboard tiles in a row are the same height.
Try it
Open /home, then pin a filtered list and find it again under ⌘K.
#2026-10-16-today-starts-with-what-to-doTechnical details
4060PR #4060 — every role's Today leads with the thing to do4061PR #4061 — breadcrumbs, pins and recents, and one loading/error standard4059PR #4059 — every page opens title, filters, then content4066PR #4066 — every page starts at the same height, one back control
- ImprovedPerformanceMobile
Pact on a phone: faster pages, thumb-sized buttons, a step-by-step dialer
Phones download only what they show, every button is sized for a thumb, and the dialer takes you through a call one step at a time. Settings, Notifications can turn on browser notifications for the kinds you choose.
What changed
Faster. Charts load as you reach them, and the Ask panel starts loading as your finger reaches the button. On a slow connection a thin line shows the page is still arriving, and a page an update has replaced reloads itself once.
Sized for a thumb. On a touch screen every button and row is at least 44 pixels, and a button is never squeezed narrower than its label. Toasts sit at the bottom, and the inbox shows each conversation on two clean lines.
Calls from your pocket. On a phone the dialer goes one step at a time: pick from your queue or search for a person, call, log, back. Placing calls needs a connected phone provider. Sales account, deliverability and forecast tables become cards, and KPI tiles read "up from 16", or "No quota set" where there is none.
Notifications. Settings, Notifications has a control to turn on browser notifications, and you choose which kinds of notification may use it.
Try it
On a phone, open /calls/dialer and work a call from your queue.
#2026-10-16-pact-on-a-phoneTechnical details
4070PR #4070 — a phone downloads only what it shows4071PR #4071 — thumb-sized buttons; the inbox reads like a mail client4290PR #4290 — a button on a touch screen never shrinks below its label4247PR #4247 — a rep can prepare for and place a call on a phone4261PR #4261 — first loads say they are arriving; the push control4227PR #4227 — the browser notification sender
- NewImprovedData & analyticsSales & CRM
Choose who sees each dashboard, and each rep's book holds their own deals
A dashboard's owner, or an admin, picks who can see it: everyone, managers and above, admins only, or only themselves and admins. Deal lists and the pipeline board show each person the deals that are theirs to work.
What changed
Who can see this. On any dashboard its owner or an admin opens Who can see this and picks one of four audiences: Everyone in the workspace (the default), Managers and above, Admins only, or Only me and admins. It opens as a side sheet at a desk and a bottom sheet on a phone, and each card on the dashboards list shows its audience.
Who can change it. Only a dashboard's owner and workspace admins can edit, share or delete it, and sharing never gives anyone edit rights. Everyone else sees a View only badge.
Each book is its own. A record you create without naming an owner is yours. A rep's deal list and pipeline board show the deals they own, a manager's show the team's, and owners and admins see everything. If your reps worked from one shared board, each of them now sees their own deals.
Forecasts and reviews. Reps and managers submit their own forecast commit, and only their own; admins can still submit for a rep. Managers can add deals to the deal review queue.
Try it
Open /dashboards, open a dashboard you own and choose Who can see this.
#2026-10-16-choose-who-sees-each-dashboardTechnical details
4309PR #4309 — the owner sets who can see each dashboard4308PR #4308 — only the owner or an admin can change a dashboard4296PR #4296 — a rep's book holds what they create and the deals they own4293PR #4293 — a rep submits their own forecast commit
- ImprovedPlatformData & analytics
A new workspace says what it lacks, and imports keep going past a bad row
Empty pages name what is missing and the first step to fill it. The setup wizard does what it says, invited teammates land where they were headed, and a bad cell in a CSV import fails only its own row.
What changed
Empty, and honest about it. A new workspace names what it lacks and the first step, such as "No leads yet — Leads arrive from forms…", rather than calling empty data healthy. The welcome banner is a short toast.
A wizard that keeps its word. The modules you choose are switched on, sample data loads only when you ask for it, and the last step reports what actually happened. Only owners and admins run setup; invited teammates land on the page they opened. A product tour you finish stays finished on every device.
Imports that keep going. In a CSV import a bad cell fails only its own row and the rest import. A country written out in full is stored correctly, deals without a currency take your workspace default, and imported contacts are linked to their account.
Contact details, everywhere. The browser extension recognizes your contacts, the duplicate warning appears when you create one, audiences carry addresses and {{first_name}} fields fill in, logged calls and WhatsApp messages find their contact, and the customer portal finds the right person.
Try it
Open /admin/import and import a CSV that has one bad row: the rest import.
#2026-10-16-a-new-workspace-starts-straightTechnical details
4136PR #4136 — the empty workspace stops congratulating itself4237PR #4237 — an empty workspace names what it lacks4294PR #4294 — an invited rep lands on Today, not the setup wizard4268PR #4268 — finished tours stay finished4287PR #4287 — a CSV import keeps going past a bad cell4288PR #4288 — captured addresses are stored4300PR #4300 — calls, WhatsApp and the social inbox find contacts4301PR #4301 — audiences, personalization and the portal read contacts4302PR #4302 — the extension, dedupe and imports read contacts
- SecuritySecurity & trust
Stronger sign-in, single sign-on and export controls for every workspace
Sign-in attempts are limited, common passwords are refused with the reason shown, single sign-on routes only to a workspace that has verified its domain, and only owners and admins can export the whole workspace or create API keys.
What changed
Every workspace has these today, with nothing to switch on:
- Every Pact page and API response carries standard browser security headers.
- Repeated failed sign-in, step-up and sign-up attempts are limited, and the link that returns you after signing in always stays on Pact.
- Common passwords are refused at sign-up, invite and reset, and the form says why. A password reset reaches every workspace you belong to, in one email.
- A passkey counts when Pact asks you to confirm it's you, and someone who signs in only with a passkey can add an authenticator app.
- Single sign-on by email domain routes only to a workspace that has verified that domain in DNS, and a domain belongs to one workspace. The SSO page shows how each of your domains routes.
- Deactivating someone in Microsoft Entra ID ends their Pact sessions and stops their API keys.
- Only owners and admins can export the whole workspace, create API keys or make someone an owner, and nobody can change their own role. Everyone can still export their own data from Settings, Privacy.
- A workflow's database step, an OKR custom query and a rollup read only your own workspace; a step that does not say so is refused, with the table named.
- Connecting an AI tool to Pact over MCP lands on Pact's own consent page.
Try it
Open /settings/mfa to add a passkey or an authenticator app; admins can see how each email domain routes at /admin/sso.
#2026-10-16-sign-in-sso-and-export-controlsTechnical details
4050PR #4050 — headers, one redirect rule, attempt limits, role and key rules4272PR #4272 — SSO domain routing on verified ownership; Entra deactivation4275PR #4275 — every sign-up attempt counts toward its limit4284PR #4284 — workflow, OKR and rollup queries read their own workspace4295PR #4295 — only an owner or admin exports the whole workspace4303PR #4303 — password reset and policy, billing, OAuth4215PR #4215 — a passkey satisfies the step-up check
- NewMarketingExperience
The guided Pact tour waits while you try it yourself
The narrated tour of a working day in Pact has nine hands-on moments on real Pact screens. It waits while you use them, pauses and resumes exactly where you left it, plays offline, and its captions come in six languages.
What changed
A working day, narrated. One narrator takes you through a day in Pact, chapter by chapter, following one fictional client from deal to quote, invoice, call and consent. Pause anywhere and resume exactly where you left off, jump by chapter, or present it with speaker notes. Nothing plays until you press Play.
Try it yourself. Nine hands-on moments run on the real Pact screens with no network: ask Pact a question, drag a deal into Commit, turn a consent preference off, build a website alert in three taps, plan a field rep's day on a map, and more. Each opens under the film with Close and Skip in view, and on a phone it gets most of the screen.
It waits for you. Start using a moment and the tour says "Take your time. The tour waits for you." Every timer stops while you type, drag or play a call, and only your Continue, on screen from the first frame, moves it on. When you've finished and gone quiet, it says "Moving on shortly…" before it does.
Share it, keep it. Send a colleague one exact moment, print a one-page recap of what you watched, put a click-to-play poster on your own page, or download the whole tour as one file that plays offline. Buttons and captions come in English, Spanish, Brazilian Portuguese, French, German and Japanese, and the narration is in English; switch language mid-step and you keep your place.
The tour opens after a quick request for access.
Try it
Request access at /demo/access, then open a hands-on moment and start typing: the tour waits.
#2026-10-16-the-guided-tour-waits-while-you-try-itTechnical details
4110PR #4110 — live moments on the real components, no network4112PR #4112 — pause anywhere, resume exactly, sound on the first tap4114PR #4114 — the tour looks like pact.place on every phone and browser4115PR #4115 — the live moments fit a phone4117PR #4117 — share a moment, a one-page recap, a script-free embed4118PR #4118 — captions and controls in five more languages4120PR #4120 — keeps playing offline; downloads as one file4124PR #4124 — the embed poster fits an upright phone4125PR #4125 — the English narration4128PR #4128 — the what-if answers itself; the player speaks your language4131PR #4131 — one day in order; every moment asks for the tap4139PR #4139 — nothing plays until you press Play4149PR #4149 — one client through every chapter4240PR #4240 — a tap, not a cursor; fresh narration4264PR #4264 — on a phone an open moment gets the room4269PR #4269 — Escape closes a moment; the tablet top bar fits4306PR #4306 — a live moment waits while you are using it
- NewSales & CRM
Managers get a team calendar: who has no customer meetings, and the week ahead
The Team view of the calendar shows a manager's own reports: who has no customer meeting in the window, each rep's meeting load against the team median, and the week ahead for each person.
What changed
Three panels. Who on your team has no customer meeting in the window, each rep's meeting load against the team median, and the week ahead for each of your reports.
Private by default. An event that is not linked to a customer record shows only as busy, and the page says how many are hidden.
Your team, and only your team. The view covers your own reporting line. Someone with no reports sees a plain "no reports" state, and the team calendar needs connected calendars to fill.
Try it
Open /calendar/team, or use the Team button on /calendar.
#2026-10-16-a-team-calendar-for-managersTechnical details
4175PR #4175 — the leader roll-up, on the existing reporting line
- FixedMarketingMobile
pact.place reads cleanly on every phone and screen
The public site opens in its light, moving look unless you chose dark inside Pact, the iPhone menu sits right under the announcement bar, and public pages carry no install sheet or sign-in redirects.
What changed
One look. pact.place always opens in its light aurora look, even on a computer set to dark mode; only someone who chose dark inside Pact sees it dark.
Phones and tablets. On a notched iPhone the menu sits right under the announcement bar. Public pages show no install sheet and send no visitor through a sign-in redirect.
Links that land, and a clean badge. Links from the product guides, the MCP marketplace and the comparison pages go where they say, and the Most popular badge on pricing is solid, with the card's border running around it.
Try it
Open /pricing on a phone and compare the plans.
#2026-10-16-pact-place-reads-cleanly-everywhereTechnical details
4087PR #4087 — the public site is light aurora unless you chose dark in Pact4099PR #4099 — the iPhone logo sits under the announcement bar4246PR #4246 — the Most popular badge is solid4260PR #4260 — no install sheet on public pages; dead links fixed
Week of September 28, 2026
Sep 28 – Oct 4 · 22 updates
Mostly Security & trust, Sales & CRM, AI
- SSO you can see working, and offboarding that ends access at once
- SOC 2: one auditor-ready evidence package, with every gap named
- Responsible disclosure, and a penetration test being scheduled
- Won deals, escalations and next steps reach the right person
- Every account, contact and case shows where the customer stands — risk included
- Stage history: every move a customer makes, dated, with the reason
- Every AI phone-agent reply shows where it came from
- Ask answers what-ifs and multi-part questions, and says why when it won't
- Sales Today leads with what you promised on calls, and Open prep opens a meeting brief
- Quotes and invoices say whether they went out, and their PDFs open
- Website chat lands in your support queue, and the case co-pilot always loads
- Post images and video to X and YouTube, and share one Social library
- Run Pact's AI on your own OpenAI key or AWS Bedrock account
- The phone agent answers about the account you name, and suggests only phrases that work
- CS Today opens on your at-risk accounts, and phones name the section you're in
- Old deal-room links open the right deal, and past QBRs open as they were saved
- Your audit log shows every time Pact staff access your workspace, and why
- Confirming it's you works on any connection, and sample data needs two steps to remove
- Tapping a notification opens the call, rule, dashboard or record it's about
- API requests stay fast as your usage grows, and the API reference opens instantly
- Pipeline and health history show only what was actually measured
- A new homepage, with pricing side by side and a path into the guided tour
- NewImprovedSecurity & trustPlatform
SSO you can see working, and offboarding that ends access at once
Single sign-on now gives each workspace the exact values to paste into Okta, Microsoft Entra ID or any SAML provider, and shows whether each connection has worked: the last sign-in and who, the last refusal and why. Deactivating someone ends their sessions and holds the API keys they created, in the same moment.
What changed
Values computed for your workspace. The SAML setup step shows the four values your identity provider asks for — the sign-in (ACS) URL that ends in your workspace's ID, the entity ID, the single logout URL and the metadata URL — each with a note on what it is for, so the usual mix-ups ("reply URL does not match", a wrong audience) are hard to make. If your provider was configured with a different sign-in URL, update it to the one shown on the page.
A status that says what happened. Each connection reads Verified, Not yet verified, Unknown or Disabled, with the last sign-in (when, and who) and the last refusal with its reason in plain words. If the sign-in history cannot be read, the page says Unknown — "not the same as never" — rather than guessing. One line shows provisioning from your identity provider: its last call, and how many provisioned people are active.
Offboarding ends access everywhere at once. Whether someone is deactivated from your identity provider through SCIM or in Settings → Team, their signed-in sessions end and the API keys they created stop working in the same step, and your audit log records how many of each. Re-enabling the person restores their keys, so create integration keys under an account that stays.
Sign-out at your identity provider reaches Pact. A signed sign-out request from Okta or Entra ID ends the Pact session, including over the redirect binding both use by default. Sign-in assertions that are replayed, altered, unsigned, expired or issued for a different workspace are refused, recorded, and never create a user.
On a phone the status is one card per connection, state first; on a desktop it is a grid you can compare at a glance.
Try it
Open /admin/sso to see each connection's status and the values to paste into your identity provider.
#2026-10-03-sso-you-can-see-workingTechnical details
4048PR #4048 — SAML sign-in for every workspace end to end; deactivation ends sessions and API keys4049PR #4049 — the SSO page shows verified, last sign-in, last refusal and provisioning
- ImprovedSecurity & trust
SOC 2: one auditor-ready evidence package, with every gap named
Pact's SOC 2 evidence now exports as one package an auditor can work from: every control with the policy that governs it, the evidence behind it and its last test — or the gap, named. The audit itself has not started, and the Trust Center says so in the same words.
What changed
One export, the whole chain. Each of the 61 Trust Services criteria lists its owner, its governing policies and whether they are current, its evidence source, the steps for any evidence collected by hand, its last test and when the next is due. Anything missing is written into a gaps column rather than left blank.
The policies travel with the evidence. The package carries every governing policy word for word, each with its fingerprint in an index, a record of who acknowledged which policy, and an index of every evidence source with its own last result. The bundled verifier re-checks each of them against the package's signed digest.
No green that has not been earned. Evidence from a source that could not be reached is marked "Source unreachable" and does not count toward readiness. A policy past its review date is a finding that names the date. A policy acknowledged only by its owner is reported as an exception, not as communicated. When coverage cannot be read, the control sheet says "Policy coverage unknown" — never "no policy".
Where Pact stands, in plain words. The SOC 2 Type II audit has not started. The Trust Center lists it as "In preparation · not yet audited", and the security documentation says no independent audit has started. Customers who need the evidence package for their own vendor review can request it under NDA.
Admins collect evidence and download the package from Admin → SOC 2 Type II.
Try it
Open /trust to see the SOC 2 status, or, as an admin, open /admin/compliance/soc2 to collect evidence and download the auditor package.
#2026-10-03-soc2-auditor-package-every-gap-namedTechnical details
4045PR #4045 — one auditor package with every control, its policy, its evidence and every gap named
- NewSecurity & trust
Responsible disclosure, and a penetration test being scheduled
Security researchers now have one page that says how to report a vulnerability, what Pact commits to in return and the safe harbor for good-faith research. The security page and the Trust Center say exactly where the external penetration test stands: being scheduled, with the preparation done.
What changed
How to report, and what you get back. The new disclosure page lists what to include in a report, then the commitments: acknowledgement within 2 business days, updates through triage, fix and release, and a 90-day window before publication unless agreed otherwise. It sets out what is in scope and out of scope, and the safe harbor for research done in good faith.
One set of terms, everywhere. The disclosure page, the security page, the Trust Center and the machine-readable security.txt state the same contact and the same commitments, and security.txt now points to the full policy.
The penetration test, stated exactly. The external test is being scheduled: an independent firm will test the application and API by hand, signed in, across roles and across workspaces. What is ready now is listed beside it — the scope and rules of engagement, an inventory of every API route and how it authenticates generated from the code, and one-command test workspaces that hold sample data only.
No external test has run yet. Once the test and its fixes are complete, a summary and the firm's attestation letter will be published on the security page, and enterprise customers will be able to request the full report under NDA.
Try it
Open /security/disclosure for the policy and safe harbor, and /security for where the external test stands.
#2026-10-03-responsible-disclosure-and-where-the-test-standsTechnical details
4046PR #4046 — responsible-disclosure page; pen-test status stated as being scheduled
- NewImprovedSales & CRMVoice & calls
Won deals, escalations and next steps reach the right person
Work handed between teams no longer waits for someone to retype it. A won deal opens onboarding and hands the kickoff to the engagement manager, an escalated case reaches delivery, and a call's agreed next step becomes a task for the person who ran the call — each saying why it is theirs.
What changed
A won deal starts onboarding. Winning a deal on the board, on the deal page or through a paid order opens the onboarding plan and hands the kickoff task to the engagement manager, with the deal and its amount. Nothing is retyped.
Escalations and site follow-ups land with an owner. Manual and SLA escalations reach the engagement manager as a task, a notification and an entry on the account timeline. A consultant on site can send confirmed follow-ups as assigned tasks with one tap, and the card names who will receive them.
What a call agreed becomes a task. After a call is analyzed, its agreed next step becomes a task for the person who ran the call and is added to the account timeline. The due date comes only from the call's own words — "by Thursday", "within 3 days", "next week" — counted from the day of the call. Pact never invents one.
Leads and expansions reach their owner. A lead routed by a rule, assigned by a teammate or arriving through a form notifies its new owner with the source and why it is theirs. Promoting an expansion signal or play opens a deal owned by the account owner and tells both the owner and the engagement manager.
Every hand-off says why you. A "Handed to you" panel leads CS Today, and each account's Overview now has "Hand-offs on this account": what was handed over, from which team, to whom, and why that person — "owns the onboarding plan", for example. When nobody owns the account yet it says "nobody yet" instead of guessing.
Renewals read the latest health. At-risk on the renewals board follows the most recent health score, and a renewal with no score yet says "No health score yet · stage only". Solutions engineers can also pin evidence to a deal room; a customer quote without consent is refused.
Hand-off notices arrive in-app, and by email or push for people who have turned those on in Settings → Notifications.
Try it
Open /cs-app/today to see the “Handed to you” panel, or open any account at /accounts and find “Hand-offs on this account” on its Overview.
#2026-10-02-handoffs-reach-the-right-personTechnical details
3946PR #3946 — a won deal, an escalated case and a site follow-up reach the engagement manager3973PR #3973 — the account page shows what was handed off, who has it and why them3975PR #3975 — a call's next step, a routed lead and an expansion reach their owner
- NewImprovedSales & CRMData & analytics
Every account, contact and case shows where the customer stands — risk included
Account, contact and case pages now show the customer's whole lifecycle in seven steps, from lead to renewal, with what is happening at each and the next step to take. When health says a customer is leaving, the stage says so in the same sentence, and lifecycle views count your whole book.
What changed
One customer, seven steps, on every page that shows them. Lead, nurtured, in pipeline, won, onboarded, supported and renewed are always drawn, with the current step highlighted. The same view appears from the account, from any of its contacts and from any of its cases, and each step says what feeds it and links to the area that owns it.
A stage never reads as good news when the customer is at risk. "Supported", "Onboarding", "Just won", "In pipeline" and "Renewed" now carry health or churn risk in the same sentence, a critical score shows in red, and risk leads the account's highlight ahead of an expansion suggestion. A renewal set to cancel says so on its row. When risk cannot be determined, the page says "risk not established" rather than implying all is well.
Contradictions are shown, not resolved by hiding one. A customer that renewed and is also set to cancel shows both facts. A step you do not have access to is labeled as such, and a step that could not be loaded is named as a gap — never shown as an empty or a zero.
Lifecycle views count every account. The lifecycle lane on module homes now reads your whole book in pages, so its stage counts are your true totals rather than the first 50. A progress line shows while the rest load, and if a later page fails, what was read stays on screen with Try again.
The account page, the lifecycle lane and the CS journey board use the same risk rules, so they agree. On a phone, name, stage and next step sit on one row.
Try it
Open any account at /accounts and look at its lifecycle panel, or open /cs-app/journey to see the same risk rules across your portfolio.
#2026-10-02-every-record-shows-where-the-customer-standsTechnical details
3572PR #3572 — one customer, seven rungs, on every page that shows them4025PR #4025 — the lifecycle standing reconciles with at-risk health4043PR #4043 — the module lane reads every account, paged and complete
- NewSales & CRMData & analytics
Stage history: every move a customer makes, dated, with the reason
Account, contact and case pages now carry a Stage history: where the customer stands, how long they have been there, and every stage change since the account was first opened, each with its reason and the team whose activity caused it.
What changed
Every move says why. Each change names its reason — a deal opened, a deal was won, onboarding started, a case opened, a subscription renewed — and which team's activity caused it. Moves backward and skipped stages are labeled as such.
Time in stage, measured. Each stage shows how long the customer stayed there, drawn as a bar against the longest stay, so a slow stretch stands out at a glance.
Dates you can trust. A date comes from the record itself where one exists, such as the day a deal closed, and is otherwise marked as the day the change was seen. History begins the first time an account is opened after this release: that view records a starting point, and the card ends with "Not recorded before …". Pact never fills in or backdates what it did not see.
Readable from every seat. Sales, Customer Success and Support all see the same history. Deal names, amounts and health scores stay visible only to seats that have the area that owns them; everyone else sees that the move happened and where to find the detail.
It works on desktop and on phones, and a compact version sits beside the case on case pages.
Try it
Open any account at /accounts and scroll to “Stage history”. The same card is on a contact's page and beside a case, for any contact or case linked to an account.
#2026-10-02-stage-history-dated-with-its-reasonTechnical details
3863PR #3863 — stage history on the account page, desktop and phone4042PR #4042 — the journey has dates: every move says why, whose signal, and how long
- NewImprovedVoice & callsAISecurity & trust
Every AI phone-agent reply shows where it came from
A call with Pact's AI phone agent now shows, under each reply, where that answer came from, and opens on a one-line verdict: did the agent tell anyone something that wasn't true? A reply claiming something was sent, booked or saved is checked against what Pact actually did before the caller hears it.
What changed
A source under every reply. The call record labels each AI reply with where it came from — "From your CRM · deals", "Computed from pipeline totals", or "Not established" when nothing backed it.
A verdict at the top. One line answers whether the agent told the caller anything untrue, with the counts beside it: replies traced, confirmed, stopped, unconfirmed and unrecorded.
Claims are checked before they are spoken. When the agent tries to say something was sent, booked or saved and no action backs it up, those words are stopped and the caller never hears them; the record shows what was stopped. Answers that read no data cannot speak a figure, and answers from your data name their source out loud.
No added cost or delay. The checks are rule-based, run on every turn, and make no extra AI call.
Calls recorded before this release show a note in place of per-reply sources.
Try it
Open an AI phone-agent call from /calls to see the source under each reply, or review one in /coach.
#2026-10-02-ai-phone-answers-show-their-sourceTechnical details
3858PR #3858 — every spoken answer carries its source, and no call promises an action that didn't happen3859PR #3859 — every AI-agent reply shows where it came from on the call record
- ImprovedPerformanceAIData & analyticsIntegrations & API
Ask answers what-ifs and multi-part questions, and says why when it won't
Ask Pact now answers what-if questions with the exact arithmetic and your own history, returns the records that match every condition when a question spans several parts of Pact, and gives a direct reading for “How are we doing?”.
What changed
What-ifs, worked out. "What would a 10% discount do to our pipeline?" returns the arithmetic plus your own quote acceptance with and without a discount, labeled as an observation from your history rather than a prediction.
Questions that span modules. Ask for "accounts with an open case and an open deal", or "accounts with an open P1 case, a renewal this quarter and no nurture touch in 30 days", and you get the accounts that match every condition — answered from your records directly, without an AI model call.
A straight answer to a broad question. "How are we doing?" now gives a direct reading of your team's open pipeline, with one-tap follow-ups.
Declines are rare, and explained. Ask declines only a small set of requests — classifying people by health or faith, for example, or exporting everything — and each decline says why and offers questions it can answer, ready to tap.
Faster, and honest about confidence on the phone. Answers drawn from your records start arriving about a quarter of a second sooner. On a call, an answer the agent is unsure of ends with "I'm not confident in that one." AI assistants connected through Pact's MCP server receive a confidence level and its reasons with every workspace answer.
Try it
Open Ask Pact from the command palette and ask “What would a 10% discount do to our pipeline?”, then “accounts with an open case and an open deal”.
#2026-10-02-ask-answers-what-ifs-and-multi-part-questionsTechnical details
3857PR #3857 — what-ifs, cross-module answers and narrow, explained declines4039PR #4039 — confidence on the phone and in MCP; “How are we doing?” and cross-module fixes
- NewImprovedSales & CRMVoice & callsAI
Sales Today leads with what you promised on calls, and Open prep opens a meeting brief
Follow-ups you owe from your calls now lead “Deals waiting on you”, with the call's own deadline words. “Open prep” lands on a meeting-prep brief for the account, recaps can be copied or shared to the deal room, and sales managers land on their own desk.
What changed
Your promises come first. Overdue follow-ups from your calls, the ones due today or tomorrow, and recent undated ones now lead "Deals waiting on you" on Sales Today. Dates come only from what was said on the call; Pact never makes one up.
Open prep opens a brief. On Sales Today, "Open prep" now lands on the account's meeting-prep card. With a meeting on your calendar you get talking points, watch-outs and Join, Reschedule or Draft follow-up. With nothing scheduled, prep on demand draws on the account, its open deal and the last 14 days of activity. If your calendar could not be read, the card says so rather than claiming nothing is scheduled, and it only ever shows your own meetings.
Recaps travel. Every call recap has "Copy recap" and "Share to deal room", and the shared text says whether AI wrote it. Both fit on a phone.
Managers land on their desk. Sales managers now open on the manager's Today when they sign in, and the first-run tour follows your role instead of asking you to pick one.
Try it
Open /sales/today and look at “Deals waiting on you”, then tap “Open prep” on an account card. On any call at /calls, try Copy recap.
#2026-10-02-sales-today-leads-with-what-you-promisedTechnical details
3948PR #3948 — call promises on Sales Today, managers on their own desk, recaps that leave the call3979PR #3979 — Open prep reaches a meeting brief, or prep on demand
- ImprovedFixedSales & CRMSecurity & trust
Quotes and invoices say whether they went out, and their PDFs open
Sending a quote now tells you whether the email went out and records the result on the quote. New invoices start as drafts until you send them or mark them sent, quote and invoice PDFs open in a new tab, and the audit log credits a client's signature to the client.
What changed
You know what was sent. Sending a quote shows the outcome in the confirmation and on the quote's activity: sent, blocked with the reason, or email not set up. Quote emails carry a full link that opens from any mail client.
Invoices start as drafts. A new invoice has Send invoice and Mark as sent, and becomes Sent only when the email is accepted or a person records delivery. Existing invoices are unchanged.
PDFs open. Preview PDF on a quote and the PDF button on an invoice open the document in a new tab, popup blockers included. Quotes created from a deal download under their real name, accents and other non-English characters intact, and if a PDF cannot be produced the page says why instead of opening a blank tab.
Ownership follows the deal. A quote created from a deal is owned by the deal's owner, and conversion reporting credits that person.
An audit trail that names the client. The audit log records a client's accept, decline and signature — credited to the client, with one consistent identifier you can filter on — along with the order it creates and each privacy request opened and evidenced. Invitation entries name who invited and no longer show the invitee's full address.
Try it
Open a quote under /sales/quotes and use Preview PDF, or open a new invoice under /sales/invoices to see Send invoice and Mark as sent.
#2026-10-02-quotes-and-invoices-say-what-happenedTechnical details
3945PR #3945 — quotes, invoices and the audit log say what actually happened3915PR #3915 — quote and invoice PDFs open, for any quote name3971PR #3971 — a client's signature is credited to the client in the audit log
- NewFixedExperienceIntegrations & APIAI
Website chat lands in your support queue, and the case co-pilot always loads
Paste one script tag on your site and visitor chats arrive in the support queue as cases, with agents replying from the case. On every case, the co-pilot's panels load independently, agents can draft a knowledge-base article from a resolved case, and macros fill in for the open case.
What changed
A chat window for your website. Only the launcher button loads with your page; nothing is fetched or stored until a visitor opens the chat. It follows your cookie-banner rules, does no page tracking, works under a strict website security policy with two allow-list entries, and becomes a full-height sheet on phones.
Built for the queue, not the inbox. Visitor chats arrive as chat cases. Agent replies appear in the visitor's window and internal notes never do. Visitor-given names are labeled unverified and never matched to a contact. Per-visitor and per-workspace limits, a per-site allow-list and bot traps keep spam out, and the settings page shows the real limits. Each visitor message is triaged by AI and counts toward your workspace's AI budget.
A co-pilot that always shows up. Reply drafts, escalation risk, similar cases and deflection each load and retry on their own, so one slow panel no longer hides the rest, and a missing signal is named inside its panel. "Escalation not computed" replaces a misleading 0%.
From resolved case to article. "Draft article from this case" saves a review-pending knowledge-base draft with a Review draft link, or says why it cannot — the case isn't resolved, or the knowledge base already covers it.
Macros, filled in. Insert macro fills a saved macro for the open case, and a customer reply cannot go out while a field is still unfilled. Case pages use a single column on phones.
Try it
Open /support/settings/chat-widget to copy your chat script tag, then open any support case to see the co-pilot panels and Insert macro.
#2026-10-02-website-chat-and-a-steadier-case-copilotTechnical details
3934PR #3934 — website chat widget: visitor chats land in the support queue3942PR #3942 — the case co-pilot loads per panel; KB drafts from a case; macros filled in
- NewAIIntegrations & APISecurity & trust
Run Pact's AI on your own OpenAI key or AWS Bedrock account
Admins can choose a stored OpenAI key or AWS Bedrock credential to serve the workspace's AI features. A Model provider card shows what is active, tests it with one real call, and shows which model serves each tier.
What changed
Nothing switches on its own. A stored key serves AI only after an admin chooses it, and the confirmation says where your data will go and who will be billed.
Test before you trust. "Test" makes one real, tiny AI call through all the usual safeguards and reports the model, the latency and the cost — or a concrete next step if it fails.
Your region stays your region. With Bedrock, AI calls stay in the credential's region by default and never fall back to global routing; global is an explicit opt-in.
Fails closed. If Pact cannot confirm where an AI call will be routed, the call stops rather than quietly using a different provider. Usage on your own key is billed to your account and shown, at list prices, in your AI spend.
Try it
Open /admin/ai/features and find the Model provider card; credentials are stored under Integrations.
#2026-10-02-run-pacts-ai-on-your-own-providerTechnical details
3926PR #3926 — a workspace's own OpenAI key or AWS Bedrock credentials serve its AI features
- ImprovedFixedVoice & callsExperience
The phone agent answers about the account you name, and suggests only phrases that work
“What are my risks with” an account now answers about that account alone. Short names heard as a time get a “did you mean” from your own accounts, a turn that can't be answered names its reason, and every phrase Pact suggests is one it can act on.
What changed
Risk, for the account you asked about. "What are my risks with" a named account is answered for that account only, and "nothing flagged" is said only after checking that account against the full risk list. A name said as words or digits, with or without punctuation, finds the same account, and a short name finds the full company name.
Misheard names are recovered. A short account name that speech recognition hears as a time is offered back as a "did you mean" from your own accounts, while real times still mean times when you are scheduling.
A specific reason, not a menu. When a turn cannot be answered, the agent names what went wrong and a next step instead of repeating the same generic help line.
Every suggestion works. Each phrase suggested in the voice hub, the "try saying" pill, the help panel and a first call's greeting is now checked automatically against what the agent actually handles; eight that went nowhere were removed and three quick-starts replaced. "What can you do?" now names six kinds of task in about 8 seconds, where it used to name three in about 17.
Try it
Open /voice-hub to see the suggested phrases, or on a call ask “What are my risks with” one of your accounts, then “What can you do?”.
#2026-10-02-phone-agent-understands-named-accountsTechnical details
2888PR #2888 — the risk feed is scoped to the account you name2907PR #2907 — names misheard as times are recovered; dead ends name their reason3259PR #3259 — the guidance no longer names phrases that do nothing4014PR #4014 — two more suggested voice phrases that nothing answered are gone
- ImprovedExperienceMobile
CS Today opens on your at-risk accounts, and phones name the section you're in
Customer Success Today opens on its title with your action buckets first; each can be minimized, hidden or reordered, and your layout is saved. On a phone, every module now shows a row naming the section you're in that opens the module's menu.
What changed
The work first. CS Today opens on its title with the action buckets straight after it; on a phone the first at-risk account now sits near the top of the screen. The day summary and the daily goal moved below the buckets, and the summary can be moved back up with one tap.
Arrange it your way. From Customize, minimize a bucket (it keeps its count), hide it, or reorder it. Your layout is saved, and CSMs and CS leads each keep their own.
Know where you are on a phone. Inside any of the ten modules, a row under the top bar names the section and module — "My accounts · Sales", for example. Tapping it opens the module's menu, which closes when you pick a page. It never names a section your role cannot open, and desktop is unchanged.
Try it
Open /cs-app/today and press Customize; on a phone, open /sales/accounts to see the section row.
#2026-10-02-cs-today-you-arrange-and-module-rows-on-phonesTechnical details
3854PR #3854 — CS Today opens on its own title; every bucket a panel you arrange4041PR #4041 — every module names its section on a phone, in one row
- FixedImprovedSales & CRMSecurity & trust
Old deal-room links open the right deal, and past QBRs open as they were saved
A bookmarked deal link ending in /room or /voice-room opens that deal's own room and switches to its permanent link. A past quarter's QBR opens as the deck that was saved, never regenerated with today's numbers.
What changed
Links that land. Bookmarked and pasted room links open the right deal and update the address to the deal's permanent link. A link to a deal that doesn't exist says so instead of offering to set up a room, and the Voice Room tells "no deal matches this link" apart from "no room yet".
A QBR is a record, not a recalculation. A past quarter opens as a saved snapshot — "Saved snapshot · composed …" — offers Export only, and cannot be overwritten. A quarter with nothing saved says "No QBR was saved for" that period and links to the account.
Only ever your own. Deal rooms, voice rooms, renewal briefs and QBRs open only for records in your own workspace.
Try it
Open a deal under /sales/deals and its Room, or open a past quarter's QBR from an account in /cs-app.
#2026-10-02-deal-links-and-past-qbrs-open-as-they-shouldTechnical details
4038PR #4038 — old deal links open their room; a past QBR opens as it was saved
- NewSecuritySecurity & trust
Your audit log shows every time Pact staff access your workspace, and why
When Pact staff view, change, suspend or sign in to your workspace, a matching entry now appears in your own audit log with what they did, when, and the reason they gave. Microsoft 365 add-in sign-in and imports were tightened at the same time.
What changed
Staff access, in your own log. Each staff action that targets your workspace adds an entry attributed to Pact staff, including the reason given — for a suspension, or a sign-in on your behalf. When staff change a setting for someone in your workspace, that is recorded in your history too. Entries never include another workspace's users or the staff member's address, device or session, and timestamps carry an explicit time zone.
Sign-in and imports, tightened. Microsoft 365 add-in sign-in now relies only on a verified identity, and a workspace that is suspended or being closed cannot gain a new one. Imported files only ever add to your own workspace's records.
Entries begin with this release; earlier staff access is not back-filled.
Try it
Open /admin/security/audit-log and filter for entries attributed to Pact staff.
#2026-10-02-your-audit-log-shows-staff-accessTechnical details
3871PR #3871 — each workspace sees staff access to it in its own audit log3682PR #3682 — workspace isolation tightened across imports, admin tools and Microsoft 365 sign-in
- FixedImprovedSecuritySecurity & trustMobile
Confirming it's you works on any connection, and sample data needs two steps to remove
The “confirm it's you” sheet can always be cancelled, even while a slow connection is still starting it. Authenticator status in Settings is always accurate, and removing sample data now takes typing your workspace name and confirming it's you — and can be undone for 30 days.
What changed
Never stuck behind the sheet. When Pact asks you to confirm it's you before a sensitive action, Cancel and the password field work straight away; only Confirm waits, labeled "Starting…". The server still verifies every confirmation.
Authenticator status you can rely on. If Pact ever cannot check your authenticator app's codes, Settings says "Needs setup again" instead of "On", with "Remove to set up again" as the first action, and codes entered in that state never count toward a lockout. Recovery codes and your password keep working throughout, and the two-factor help page lists exactly the confirmation methods that work.
Sample data comes out on purpose. Removing sample data takes two separate actions: typing your workspace's name, then confirming it's you. A mistyped name removes nothing. Only records tagged as sample are removed — your own records are never touched — and the page now correctly says the removal can be undone for 30 days.
Try it
Open /settings/mfa to see your authenticator status, or /admin/data-management to see the sample-data removal steps.
#2026-10-02-confirming-its-you-and-removing-sample-dataTechnical details
4022PR #4022 — the confirm-it's-you sheet stays cancellable while it starts4033PR #4033 — authenticator status is accurate and a server-side fault never counts toward lockout3851PR #3851 — removing sample data takes two deliberate actions
- ImprovedExperience
Tapping a notification opens the call, rule, dashboard or record it's about
Notifications that used to open nowhere, or only a general page, now take you straight to what they are about — including notifications already in your inbox.
What changed
Straight to the thing. A parked call or a failed transfer opens that call. An alert from an automation rule opens Rules with that rule highlighted, and says so if the rule was deleted. Dashboard alerts open the dashboard, enrichment budget alerts open the budgets page, and enrichment job updates open the account.
People, too. Access requests and sign-in security alerts open the person's admin page.
Older ones work as well. Notifications already in your inbox open their item wherever the original link or record can still be found.
Try it
Open /inbox/notifications and tap any notification.
#2026-10-02-notifications-open-what-they-are-aboutTechnical details
4010PR #4010 — every notification opens what it is about
- PerformanceIntegrations & APIPlatform
API requests stay fast as your usage grows, and the API reference opens instantly
Pact checks your monthly API usage on every request. That check now reads a running total instead of re-adding the month, so it no longer slows down as usage grows, and the API reference opens immediately right after an update.
What changed
Usage checks that don't grow with usage. On a copy of real data, the monthly usage read went from about 130 milliseconds to under a tenth of a millisecond. When many requests arrive at once, one refresh serves them all: 20 simultaneous requests now cause one usage query instead of 40.
What is kept. Monthly usage totals are kept permanently. Per-request usage detail is rolled up into daily totals after 90 days, so older months still show their usage.
The API reference, ready on arrival. Right after an update, the API reference now opens immediately instead of taking up to about 18 seconds to build.
Try it
Open /settings/billing/usage to see your API usage, or /api-reference for the reference.
#2026-10-02-api-stays-fast-as-usage-growsTechnical details
3693PR #3693 — the per-request usage check reads a running total, refreshed once4007PR #4007 — the API reference is served prebuilt right after an update
- FixedData & analytics
Pipeline and health history show only what was actually measured
Data pipeline pages now list only runs that really happened and point a connected CRM source to its own Sync now, which reports measured counts. Customer-health trend lines draw only recorded scores.
What changed
Measured, or marked. For a Salesforce, HubSpot or Pipedrive source, the pipeline page links straight to that source's Sync now, which reports measured counts. Run says plainly when nothing ran rather than recording a run.
Nothing deleted. Runs from earlier builds are kept, badged Not measured, and left out of the success rate. Sample pipelines stay labeled Sample.
Health trends you can trust. Health sparklines draw only scores that were recorded, and say so when there is no history yet.
Try it
Open a pipeline under /data/pipelines, or the health page at /cs-app/health.
#2026-10-02-pipeline-history-shows-only-measured-runsTechnical details
4035PR #4035 — a pipeline Run never records a run that did not happen
- NewExperienceDocs & support
A new homepage, with pricing side by side and a path into the guided tour
The homepage is rebuilt around a CRM that shows its work: every capability card links to the release that shipped it, the price comparison sits side by side, and there is a clear path from the live voice agent into the full guided tour.
What changed
Every claim cites its release. Each capability card on the homepage links to the feature's own page and to the changelog entry that made it true.
Try before you talk to anyone. Visitors can call the live voice agent with no signup, then request access to a narrated guided tour of a sample workspace.
Pricing in context. The price comparison sits side by side with what the same coverage costs elsewhere, with a pricing explainer.
Setup guides that open. The Setup docs button on each public integration page now opens a real setup guide, or does not appear when there is none. The homepage reads well in light and dark, from a phone to an ultrawide screen.
Try it
Open the homepage at pact.place, or go straight to /pricing or an integration page under /integrations.
#2026-10-02-a-new-homepageTechnical details
4026PR #4026 — the evidence redesign: new homepage, pricing and demo path4030PR #4030 — the guided-tour button lands on the tour's access screen4034PR #4034 — every integration page's Setup docs button opens a real guide
Week of September 21, 2026
Sep 21 – Sep 27 · 38 updates
Mostly Data & analytics, Sales & CRM, Experience
- Accounts search your whole book, and each account opens on one sourced record
- The phone agent remembers your calls, preps your meetings and searches your mail
- Make Sales Today yours: minimise, hide and reorder every panel
- Sales managers open on the deals that need them
- Every dashboard chart shows where its numbers come from
- Five more sources sync, and you can migrate from Close and Apollo
- Confirm sensitive changes with an authenticator app, and a caller known only by their number confirms a texted code before Pact acts
- Every outbound call checks do-not-call and consent first, and every person's consent state shows where it came from
- Calls with the phone agent feel like a conversation: no dead air, plain words, and the numbers you actually said
- My pipeline is yours, new deals appear where you made them, and reps price quotes from the catalog
- Ask Pact answers questions that cross marketing, sales and support, and says plainly when two parts can't be joined
- Scheduled social posts publish themselves, campaigns reach their segment's real members, and a segment keeps every condition you asked for
- Customer Success: every save sticks, QBR decks generate and export cleanly, and a case opens from its number
- Field Rep joins the module switcher and keeps working when signal drops; solutions engineers get their calendar and quick RFP uploads
- Enrichment pays only for what's missing, shows what it can fill, and checks your provider key before saving it
- A Finance role reads revenue recognition and records payments, and proposals and invoices carry your firm's name
- Sequence and playbook builders save a real Branch with both paths, and the workflow builder names the steps that can't run yet
- Every daily page is reachable from the module you work in, a workspace switch sticks, and pages open with their own name
- On a phone, nothing floats over your work, titles are never cut, and Hey Pact fits on screen
- Steadier and lighter: updates don't interrupt you, idle tabs stay quiet, and exports, push and call playback work
- Developers: agents asking the workspace over MCP get the answer a person gets, and the iOS SDK ships Combine publishers
- The sample workspace tells one connected story across Sales, Customer Success, Marketing, Consent and Analytics
- A workspace can go live: sample data is labeled, kept out of exports, and purged without touching a real row
- Every data-subject request does what it says: access, portability, rectification, restriction, objection and erasure
- A page that could not read your data now says so, instead of showing a zero or “nothing here yet”
- Five surfaces that showed invented numbers now show your data, or nothing
- Ask Pact and Hey Pact find the record you said out loud, and admit it when a lookup could not run
- The notification bell counts what it is going to show, and the inbox folds a repeating condition into one row
- The customer lifecycle is a timeline: seven stages, one account on a dated line, and a portfolio sorted by urgency
- Dashboards show open pipeline from deals, with every closed and lost stage excluded from every money figure
- Every AI voice-agent call can be opened from Calls, and the inbound screen-pop works again
- On the phone, Pact stops interrogating you for optional details, hears names it used to mishear, and no longer reports a change failed while it commits
- Cross-workspace reads are closed, unsigned callbacks are refused, and report share links finally expire
- On a phone, every drag handle works under a thumb, the top bar fits at 1024, and a scrolled-away filter says so
- Field Rep loads for every rep, keeps visits logged with no signal, and shows each rep only their own day
- Accounts loads 46 kB lighter on first open
- Sidebar groups can be put away, and the choice sticks
- Fifteen integration pages said “Not connected” about integrations that were wired, and journey attribution always read $0
- NewImprovedSales & CRMData & analytics
Accounts search your whole book, and each account opens on one sourced record
Search and filters on Accounts used to cover only the first 6,000 accounts loaded. They now run over every account with true totals. The account page opens on a single customer record with each field's source beside it, and merging duplicates moves the whole customer.
What changed
On a large book, Accounts loaded the first 6,000 records and searched only those, so a search could answer “0 of 18,311” for a name that matched thousands further down. Search, every filter and every sort now run over your whole book, and the count line shows true totals such as “2,289 matching of 18,311”. Filter counts in the side rail cover every account and say so when they could not be loaded, instead of showing zeros. The list loads more as you scroll, and phones load 200 cards at a time.
One customer record. An account's Overview now opens on the record itself. Each field sits beside where its value came from. A provider that disagrees is shown next to your value, never over it, stale values are marked, and you can see what was merged into the account and what each module holds for this customer. Support-only and CS-only seats can open the record too, and a section that fails to load says so rather than showing 0.
Merging duplicates moves the whole customer. Merging two accounts now moves the duplicate's contacts, opportunities and other linked records onto the surviving account, and a link to the merged-away account lands on the survivor and says so. Merges completed before this release are not re-run.
Try it
Open /accounts and search for a name you know sits deep in the book: the count line shows matches out of your true total. Open any account to see each field's source on its Overview.
#2026-09-27-accounts-search-the-whole-bookTechnical details
3841PR #3841 — search, filters and sort run on the server over every account3861PR #3861 — one customer profile with every field's source; a merge moves the whole customer
- NewVoice & callsAI
The phone agent remembers your calls, preps your meetings and searches your mail
Ask where you left things with an account and it quotes what you said on your own recent calls, or says it found nothing. “Prep me for my three o'clock” briefs the meeting, your own mailbox and Drive are searchable by voice, and five more requests now get done instead of declined.
What changed
It remembers, with receipts. The agent can recall what you discussed on your own calls from the last 30 days, quoting your words and when you said them, or tell you plainly that it found nothing about that topic. It never paraphrases a memory, never draws on another user's calls, and never counts something you interrupted as discussed.
Meeting prep by voice. “Prep me for my three o'clock”, “prep me for my next meeting” or just “prep me” gives who and when first, then the attendees, the related deal, the last meeting and recent activity, one thing to watch for and a suggested opener. It works for in-person and dial-in meetings as well as video calls, and says what is missing rather than skipping it.
“Tell me about” an account is a real brief. You hear its open deals, contacts on file, any risk or slippage, the last 14 days of team activity and one recommended next step, all scoped to the account you named. Say yes to the offer that follows and it opens the battle card or meeting prep.
Your own mail and files. “Search my Gmail for the renewal” searches the caller's own connected Gmail, Outlook or Google Drive, never a colleague's, and merges the matches with CRM results, each with where it came from. A source that can't be searched gets its own reason: not connected, missing permission, expired or timed out. Nothing from your mailbox is copied into Pact. Drive search depends on your Google connection being current, and Slack, Teams and Notion aren't searchable yet; the agent says so when asked.
Five more requests get done. Over the phone you can now create an account, prep a one-on-one with a direct report, pull evidence from a deal, set up a demo sandbox and save a dictated playbook. Each is read back before it is committed, and “done” is said only after the result is confirmed. The agent also answers questions about Pact itself and your team, and opens a support ticket once you say yes.
Try it
Call 1-424-PACT-MCP and say “prep me for my next meeting”, or “search my Gmail for the renewal”. Ask where you left things with an account and it quotes your own recent calls, or tells you it found nothing.
#2026-09-27-phone-agent-remembers-preps-and-searchesTechnical details
2910PR #2910 — the agent remembers previous calls, sourced, or says nothing2911PR #2911 — “prep me for my three o'clock” joins the resolver and the brief2901PR #2901 — “tell me about” an account is a scoped brief3932PR #3932 — voice search reaches the caller's own Gmail, Outlook and Drive3873PR #3873 — five more things a caller asks for actually happen2840PR #2840 — questions about Pact and your team, and support tickets, reach live calls
- NewExperienceSales & CRM
Make Sales Today yours: minimise, hide and reorder every panel
A Customize button beside the Today title opens a side panel on desktop and a bottom sheet on phones. Minimise a panel to a one-line summary, hide it, reorder it by touch, buttons or Alt+↑/↓, or reset the page — and the layout is kept for you.
What changed
Sales Today is the first page where every panel is yours to arrange. Customize, next to the page title, lists the page's panels; on a phone it opens as a bottom sheet with thumb-sized controls. Minimise a panel and it keeps a one-line summary, such as “Coaching tips · 6 tips”, so the signal stays on screen without the bulk. Hide one and a single line remains, “Day summary is hidden · Show”, so nothing disappears without a way back.
Reorder by touch, with the arrow buttons, or with Alt+↑ and Alt+↓ from the keyboard, and Reset returns the page to its default. The layout is saved to your account for that page, and if it can only be kept on this device the sheet says so. Sales Today also now opens with its own “Today” title.
Try it
Open /sales/today and click Customize beside the title. Minimise “Coaching tips” to its one-line summary, move a panel up, and reload: your layout is still there.
#2026-09-27-customize-sales-todayTechnical details
3853PR #3853 — per-user page panels, Sales Today first
- NewFixedSales & CRMData & analytics
Sales managers open on the deals that need them
Manager Today leads with “Deals needing you”: overdue promised next steps and stalled late-stage deals, each with its reason. Moving a deal's stage now updates its forecast category, the manager forecast shows each rep's real pipeline, and the Team scorecard counts every deal a rep owns.
What changed
Deals needing you. Manager Today now opens on your team's open deals that need you this morning, each with its reason: a next step promised on a call that is overdue or due soon, or a late-stage deal that has stalled or passed its close date. A stall is measured against your own team's usual time in that stage, as in “26 days in Negotiation · team usually 11 days”. The list covers your whole reporting line and can be narrowed to a sub-team. A read that failed says “Not checked”, never “Nothing needs you”.
The forecast follows the board. Moving a deal to a new stage, whether by dragging it, from the action palette or in a bulk move, now sets its forecast category to match, so a deal dragged to Closed Won counts as won and a reopened deal leaves Won. A category you set explicitly still wins, and deals moved before this release keep the category they had. When the quarter's quota is already made, Forecast says so and treats the rest as upside.
Each rep's real numbers. Manager Forecast now shows each rep's real Commit, Best case and Pipeline, where it had read $0 for every rep, and Gap analysis loads instead of spinning. The Team scorecard counts deals recorded under a rep's email as well as their name and dates wins and losses by their close date, so some managers will see corrected figures.
Try it
Open /sales/manager/today: “Deals needing you” comes first, each row with its reason. Then open /sales/manager/forecast for each rep's Commit, Best case and Pipeline.
#2026-09-27-managers-open-on-the-deals-that-need-themTechnical details
3980PR #3980 — which of the team's deals need the manager, and why3910PR #3910 — a stage move carries the forecast category; a made quota says so3964PR #3964 — the manager forecast shows each rep's real pipeline3898PR #3898 — the Team scorecard counts deals by owner email and close date
- NewFixedData & analyticsMarketing
Every dashboard chart shows where its numbers come from
The four dashboard charts now show their unit, record count, load time and a link to the records, with a table view and CSV on each. Sequence open and reply rates are computed from real sends, and a failed or unmeasured figure is labelled rather than shown as zero.
What changed
Charts with receipts. The pipeline funnel, velocity, open-rate and top-accounts charts on the dashboard each show their unit, how many records they read, when they loaded and a link to those records, with a table view and a CSV download that keeps raw numbers. On a phone, bar charts become a ranked list with full names and tappable rows, so no value needs a hover. A day with no sends is a gap rather than 0%, the current week is drawn dashed as “so far”, and a failed load names the request that failed instead of saying “No pipeline yet”.
Rates that are computed. A sequence's Open rate and Reply rate now show the evidence behind them, such as “212 of 501 email sends opened”, counting each email once and a click as an open, or “Not measured” with the reason when your email provider hasn't reported. Journey A/B variant reports count only messages the provider accepted and each open once. Some of these figures will read lower than before, because they now count only what happened.
One at-risk ARR. “What's our at-risk ARR?” gets one answer across Ask and CS Today, and it now covers every at-risk account in your book rather than the eight shown on cards. Ask says when it could not compute a number instead of calling it zero, the report builder offers Deals directly, and exported reports keep their report's name.
Zero only when it's zero. Attribution now counts consent violations and journey touches, which had never been computed, so those numbers may change. Attribution, Forecasts, the SE scorecard, Data pipelines and the Analytics Today sequence heatmap show “Couldn't load” with a retry when a read fails. Saved reports built on the older opportunities data now read deals, like every other surface.
Try it
Open /dashboard and switch any chart to its table view or download its CSV; the footer shows the record count and when it loaded. A sequence's Open and Reply rate tiles are on its page under /sequences.
#2026-09-27-dashboard-charts-show-their-sourceTechnical details
3865PR #3865 — one chart system: every dashboard number shows its source3815PR #3815 — sequence open and reply rates are computed, or “not measured”3955PR #3955 — journey variant reports count what the provider reported3944PR #3944 — one at-risk ARR across Ask and CS Today; reports on deals3791PR #3791 — a failed read is a failure: no stored zeros3870PR #3870 — a failed sequence-heatmap read says so3972PR #3972 — saved opportunity reports read deals
- NewIntegrations & APIData & analytics
Five more sources sync, and you can migrate from Close and Apollo
A pipeline-first CRM, ActiveCampaign, Mailchimp, Klaviyo and Kit now sync read-only on your schedule or on Sync now, with record counts and failures on every run. Close and Apollo join the migration wizard with dry run and rollback, and a connector that only stores a credential says so first.
What changed
Five connectors that sync. Connect a pipeline-first CRM or ActiveCampaign to bring in accounts, contacts and deals, or connect Mailchimp (every audience), Klaviyo or Kit to bring in contacts. Syncs are read-only and incremental: nothing is written back, a person on two audiences stays one contact, a blank vendor field never overwrites good data, and fields a rep has edited are kept. Each run shows “N in · N failed” with the first error, and a rejected key shows as a red run with a sentence on how to fix it. Runs start once you choose a schedule or press Sync now. Vendor unsubscribes are counted but not yet turned into Pact consent.
Migrate from Close and Apollo with the same wizard as the other supported CRMs: paste an API key, review the inventory and field mapping, preview a dry run, import, and roll back if you need to. Close brings accounts, contacts, deals and activity history, including notes, calls, meetings, texts and email subjects. From Apollo, contacts marked unsubscribed arrive as withdrawn and everyone else as consent unknown, never granted. Anything the source would not let Pact read is listed as a named gap, a run with gaps says “Imported — with gaps”, and re-running a migration never imports a record twice.
Counts that were measured. A data source now shows a record count only when a connector actually measured it. Salesforce and HubSpot sources run the real connector on Sync now and show what it imported, and a source type with no connector says sync isn't available yet and points to the import wizard. The integrations directory leads with “Credential storage only” for connectors that store a key but don't move data yet, and no longer undersells Resend, SendGrid, Zoom, Teams and Google Meet, which already work.
Try it
Open /admin/migrate and pick Close or Apollo to see the dry-run preview before anything is imported. Syncing connectors are under /admin/integrations, each showing its last run.
#2026-09-27-connectors-sync-and-migrationsTechnical details
3927PR #3927 — five marketplace connectors sync, read-only and incremental3936PR #3936 — migrate from Close and Apollo like every other source3816PR #3816 — Sync now never writes a record count it did not measure3817PR #3817 — the connector catalog says “credential storage only” first
- NewSecuritySecurity & trust
Confirm sensitive changes with an authenticator app, and a caller known only by their number confirms a texted code before Pact acts
Set up Google Authenticator, 1Password, Microsoft Authenticator or Authy in Settings to confirm sensitive changes, with ten recovery codes. On the phone, a caller recognized only by caller ID confirms a texted code before an email, text, meeting, campaign or merge. Several workspace boundaries were tightened.
What changed
An authenticator app for sensitive changes. Settings now sets up an authenticator app from a QR code, and nothing turns on until one code checks out. You get ten one-time recovery codes, and the dialog can't be closed until you confirm you've saved them. Settings shows whether it's on, when it was last used and how many recovery codes remain, with a warning at three. After five wrong codes in a row it locks for a stated time, and you can still confirm with your password or a recovery code. It confirms sensitive changes; it is not asked for at sign-in.
Stricter confirmation. Confirming a sensitive action now always requires a real proof, such as your password or an authenticator code, and every confirmation attempt, successful or not, is recorded in the audit log. Passkey confirmation for sensitive actions is paused until a fully verified check is in place.
A texted code for phone callers. When a caller is recognized only by their number, Pact texts a six-digit code to the phone on that user's own profile before it sends an email or text, books a meeting, launches a campaign or merges records. It asks at most once per call and never for reads, and three wrong codes lock the check. If a code can't be sent, the action is refused and the reason is spoken. It's on by default, and admins can see exactly what it guards under Admin → Voice → Security.
Tighter workspace boundaries. Account, contact, related-record and consent views read only your own workspace's records, and a request whose sign-in can't be confirmed is refused rather than guessed. Customer-success figures, win/loss, the dashboard's win rate, closed-won and top-owner revenue, and per-rep closed-won count only your workspace's records, so some of those tiles may move to their true values. An IP allowlist is always checked against the workspace you're signed into, and background enrichment updates only companies in the workspace that asked for it.
Shared links that behave. Shared report links now open for the people you send them to, revoking one really revokes it, and a shared link no longer exposes internal identifiers. Links created before this release were never saved, so share the report again to get a working link.
Try it
Open /settings/mfa to set up an authenticator app and save your recovery codes. Admins can review the phone-caller code under /admin/voice-mcp/settings/security.
#2026-09-27-authenticator-app-and-tighter-boundariesTechnical details
3826PR #3826 — an authenticator app confirms sensitive changes3837PR #3837 — sensitive-action confirmation requires a real proof3872PR #3872 — a texted code guards what caller ID alone must not authorize3608PR #3608 — record reads bound to your workspace; sign-in failures refuse3694PR #3694 — customer-success and win/loss figures count only your workspace3829PR #3829 — dashboard win rate and closed-won count only your workspace3636PR #3636 — the IP allowlist checks the workspace you're signed into3607PR #3607 — background enrichment writes only to the requesting workspace3868PR #3868 — shared report links open, and revoking one revokes it
- FixedSecuritySecurity & trustVoice & calls
Every outbound call checks do-not-call and consent first, and every person's consent state shows where it came from
Campaigns, transfers, callbacks, briefings and calls started from Slack or a deal room now all check your do-not-call list and withdrawn consent before the phone rings. Contacts show consented, withdrawn, expired or no record, and privacy requests can be verified and fulfilled from their page again.
What changed
Consent before the phone rings. Every outbound call Pact places, including campaigns, transfers, callbacks, briefings and alerts, calls started from Slack, deal rooms, conference and huddle calls, now checks your do-not-call and suppression list and withdrawn consent before dialing, plus prior express consent when your workspace requires it. Previously most of these paths skipped the check. A refused dial never rings and gives a one-sentence reason where you started it, and a blocked warm transfer takes the customer off hold. Queued callback requests now actually dial.
Consent state on every person. Contacts, the contact card, the Sales people list and the contact header now show consented, withdrawn, expired or no record, each badge saying when the answer was recorded and where it came from, where every person used to read “unknown”. “No record” is stated plainly as not permission, and a failed read shows “Unavailable”. Imports can carry an email-marketing consent column; a bare yes/no column is refused because it can't say which way it points, and an import never overturns a withdrawal. Records imported before this release are not re-evaluated.
Privacy requests that finish. A request can be verified and fulfilled from its page again, either by an emailed link the requester opens or by an ID hashed in your browser plus a reviewer's sign-off, and the email route shows the real delivery result. An erasure that could not remove all of a person's stored contact details is no longer marked complete; it stays open with the reason, and running it again finishes the job.
Clearer records. Preference-center purposes now show their names and legal basis, with a badge for those that need double opt-in, and account pages describe recent activity in plain words instead of system event codes.
Try it
Open /contacts: every person carries a consent badge naming when and where the answer was recorded. Privacy requests are under /consent-app/dsar.
#2026-09-27-consent-before-every-dialTechnical details
3786PR #3786 — every outbound dial passes the pre-dial do-not-call and consent check3838PR #3838 — a person's consent state is read from the consent ledger3914PR #3914 — a privacy request can be verified and fulfilled from its page3839PR #3839 — an incomplete erasure is never reported complete3969PR #3969 — preference-center purposes named; account activity in plain words
- ImprovedFixedVoice & callsAI
Calls with the phone agent feel like a conversation: no dead air, plain words, and the numbers you actually said
You hear the start of an answer within about five seconds, or an honest offer to try again. Everyday asks answer instantly, a spoken deal update keeps every value you said, and a question about a named account is answered about that account.
What changed
No dead air. Some answers used to leave callers in 4 to 17 seconds of silence. There is now a firm limit: you hear the start of the answer within about five seconds, or “I couldn't pull that in time. Want me to try again?”, and “yes” retries. A save already in progress is never cut off, and a slow lookup is never reported as “nothing found”. “Can you hear me?” mid-answer gets “Yes, I can hear you” and the answer still arrives, and on speakerphone the agent ignores its own voice.
Instant everyday asks. “Tell me my top five”, “actually, never mind, cancel that”, “tell me about yourself” and “how did July go?” right after a scorecard now answer immediately. “How did I do in Q2?” is a short headline you can follow with “what about Q3?”, and a quarter that has ended is reported as finished, hit or missed and by how much, in your fiscal quarter if your year doesn't start in January.
The numbers you said. A deal update said in one breath reads back the stage, amount, probability and owner you gave: “seven fifty thousand” is $750,000 and “one point five million” is $1,500,000. An update that names both a stage and an amount saves both after you confirm. Amounts are spoken the way a person says them, as in “12 dollars and 50 cents”.
Answers about what you asked. Asking why a named account is stalled or at risk gets an answer about that account, with the reasons behind the flag, instead of the whole at-risk list, and a cause-and-effect question gets that question answered or a plain statement of what's missing. “Yes” and “hello?” are never taken as account names, picking from a “which one?” menu opens the one you picked, and replies are plain words, with no on-screen labels and no talk of tools.
Callers who aren't your team. An outside caller asking for a teammate is told they have reached an AI assistant and can leave a message, which lands in your voicemail inbox, addressed to that person when the name matches one teammate. Only an explicit goodbye ends a call. The recording question is now 13 words and never re-asks, and an unclear answer continues without recording.
Mail and mornings. “Read my email” says right away why it can't and how to fix it, such as reconnecting Gmail in Settings. The spoken morning standup reads your account signals as plain sentences and ends with the one account to reach out to first.
Try it
Call 1-424-PACT-MCP and update a deal to negotiation at “seven fifty thousand”: the read-back says $750,000. Or ask “how did I do in Q2?” and follow with “what about Q3?”.
#2026-09-27-phone-calls-feel-like-a-conversationTechnical details
3902PR #3902 — no caller waits in silence: an answer or an honest line by 5 s3899PR #3899 — every caller turn gets an answer; the consent prompt is shorter3903PR #3903 — top five, cancel, “about yourself” and “how did July go” answer at once3986PR #3986 — a short Q2 headline, and “what about Q3?” follows it3901PR #3901 — “read my email” says why it can't; a past quarter is closed3985PR #3985 — a spoken deal update reads back the numbers the caller said3896PR #3896 — a spoken update naming a stage and an amount writes both3883PR #3883 — cents as cents, and a menu pick opens the account picked3895PR #3895 — a question about a named account is answered about it3635PR #3635 — “how did X affect Y” is answered, not met with the risk feed3906PR #3906 — “yes” is never an account, and replies are plain words3900PR #3900 — outside callers reach a front desk and leave a message3909PR #3909 — the morning standup reads the signal in plain sentences
- FixedImprovedSales & CRM
My pipeline is yours, new deals appear where you made them, and reps price quotes from the catalog
My pipeline shows only the deals you own, and a deal created there appears at once. The New deal dialog keeps what you type, reps can add catalog products to quotes and generate decks, every deal links to its rooms and briefs, and quote PDFs export whatever the title.
What changed
My pipeline means yours. Owners, admins and managers opening My pipeline saw every deal in the workspace under a “My” title; it now shows the deals you own, and the whole team stays on Pipeline. A deal created from My pipeline now appears on it right away, through the same Add deal dialog as the main board. The New deal dialog no longer wipes what you typed while it finishes loading, and an untouched currency uses your workspace default. Sales Win/Loss shows the closed deals you recorded, rather than one teammate's for everyone. The API reference for creating opportunities now names the deals endpoint whose records appear on the board.
Quotes and decks for every rep. A rep's “Add from catalog” list was empty, so rep-built quotes carried only custom $0 lines. Reps now see your active, published products with list prices, while the catalog stays admin-edited, and members can generate, regenerate and edit decks; templates and deleting decks stay with admins. A quote whose title contains an em dash, an accent or a non-Latin character now exports its PDF, named after the quote.
Every deal links to its rooms. A deal page now has a strip linking to its Deal Room, Voice Room and call brief, plus a renewal brief for renewal deals, and each Customer Success account has a quarterly-review picker listing the quarters with a saved deck. Account links from My accounts, a deal page and Win/Loss open the account again. Deal rooms where someone reacted to a message load their messages and threads again.
Try it
Open /sales/pipeline and add a deal: it appears on the board at once. Open any deal from there to find its Deal Room, Voice Room and call brief in one strip.
#2026-09-27-deals-quotes-and-deal-roomsTechnical details
3892PR #3892 — My pipeline shows only your deals; the API names the board's endpoint3882PR #3882 — a deal created from My pipeline appears on My pipeline3891PR #3891 — the New deal dialog never wipes what you typed3912PR #3912 — Win/Loss “mine” is the signed-in person3947PR #3947 — a rep can price a quote from the catalog and generate a deck3908PR #3908 — account links open the account; any quote title exports its PDF3827PR #3827 — deal, renewal and QBR pages get links that open the right record3960PR #3960 — deal rooms with reactions load again
- NewFixedAIData & analytics
Ask Pact answers questions that cross marketing, sales and support, and says plainly when two parts can't be joined
Ask which accounts marketing nurtured that sales never called, or how many lost deals had an open support case, and get one filtered answer that shows how the records were linked. Win rate, closing-this-quarter and overdue questions answer again, and event influence is a real answer.
What changed
Questions that cross the business. A question that spans marketing, sales, outbound, support and customer health is now answered as one filtered result, and the answer shows how the records were linked, flagging weaker links such as a match by email address. When two parts of the business aren't connected, the answer says so in one line, with what would close the gap, instead of returning a silently partial answer. “What happened to the leads from…” returns a status breakdown of those leads.
Everyday pipeline questions answer. “What is our win rate this quarter?”, “deals closing this quarter”, “overdue deals”, “trend of deals closing by month” and “accounts with a follow-up due this month” now return correct counts, where they had answered that the read failed.
Influence you can see. “Which pursuits did our events influence?” gets a real answer, using first-touch or any-touch logic over tracking events, form submissions and email clicks and replies, and says how many touches it could place on an account, or “not established” rather than 0. New website and form touches from a known contact now attach to that contact's account as they arrive; earlier touches are not back-filled.
Suggestions with context. Next-best-action suggestions and buyer-persona insights now draw on your actual deals, account details, recent activity, support tickets and notes, and if one piece can't be read the others still reach the AI.
Try it
Open /ai/ask-pact and ask “Of the deals we lost last quarter, how many had an open support case?”: the answer shows how deals and cases were linked.
#2026-09-27-ask-pact-crosses-the-businessTechnical details
3543PR #3543 — a question can cross the business, and names the gap when it cannot3963PR #3963 — win rate, closing-this-quarter, overdue and follow-up questions answer3976PR #3976 — “which pursuits did our events influence?” gets a real answer3886PR #3886 — next-best-action and buyer-persona context read your real deals
- NewFixedMarketing
Scheduled social posts publish themselves, campaigns reach their segment's real members, and a segment keeps every condition you asked for
Scheduled posts now go out at their time, exactly once, with a link to the live post or the network's reason and a retry. A campaign sent to a contacts segment reaches its members, plain-language segments apply or refuse every condition by name, and form cards show real submissions.
What changed
Social posts on schedule. A scheduled post now publishes on its own at its time, exactly once, and links to the live post. The list shows each state: Scheduled, Publishing, Retrying with the attempt count, Published, or Failed with the network's reason and Try again. A post more than a day late is not published on its own; it fails and says how late it is. The composer marks channels that can't publish yet, such as TikTok and YouTube, as drafts only, refuses an X post over 280 characters instead of cutting it off, and shows scheduled times in your own time zone. Publishing to LinkedIn company pages isn't supported yet and is refused with a reason.
Campaigns reach their segment. A campaign sent to a contacts segment now reaches the segment's real members, and the pre-send check counts the same people the send reaches; consent and email-safety checks still decide every recipient. Re-routing a lead that matches no routing rule now keeps its current owner and says “No rule matched”.
Segments keep what you asked for. Describe a segment in plain language and every condition is either applied or refused by name on its chip, so a segment is never saved broader than you asked. New conditions include not-equal, between, is empty, starts or ends with, and “no activity in N days, including never”. Facebook Page, Instagram, Messenger and WhatsApp steps preview as the recipient will see them, with merge tags filled and any reason Meta would refuse the send. The Forms gallery shows each form's real submissions, and its Edit button opens the builder.
Try it
Open /social/composer, schedule a post a few minutes out, and watch it move to Published with a link in /social. Build a segment in plain language at /builder to see each condition applied or refused.
#2026-09-27-marketing-posts-campaigns-segmentsTechnical details
3828PR #3828 — scheduled posts publish at their time, once3939PR #3939 — a campaign reaches its segment's members; no-rule re-route keeps the owner3878PR #3878 — segments keep every condition or refuse by name; Meta steps preview as sent3913PR #3913 — the forms gallery shows real submissions and working Edit links
- FixedSales & CRM
Customer Success: every save sticks, QBR decks generate and export cleanly, and a case opens from its number
Onboarding plans, save plays, expansion triage, quotas and QBR edits in the CS workspace now stay saved after you save them. QBR decks generate again and export to PowerPoint with real formatting, a case opens from its case number, and the at-risk page explains when churn predictions are off.
What changed
Saves that stick. In the CS workspace, “Create plan” could report success while the list still read “No active onboarding plans”, and the same was true of every CS write. All fifteen write actions, covering onboarding plans and milestones, save-play runs, expansion triage and promote, quotas, and QBR slide edits and reorders, now save before they confirm. Changes that did not save before this release are not recovered, so a plan that never appeared needs to be entered again.
QBR decks for every account. Opening a QBR deck failed on some accounts, a deck that did compose wasn't kept, and Export PPTX couldn't download. Decks now compose with seven slides, are saved, and export as a real PowerPoint file. Exported slides render bold and italic properly with no stray formatting symbols or internal source notes, including decks created earlier, and the editor previews each slide as your client will see it.
Cases and at-risk. Open a support case from the number customers quote, such as CASE-1014, and every co-pilot panel on the case loads, always within your own workspace. When churn predictions are off for a workspace, the At-risk page says so and points to CS Today instead of showing “Not Found”. The customer lifecycle panel now opens on SE Today, Support Today and every module home for anyone who can open that page.
Try it
Open /cs-app/onboarding and create a plan: it is in the list when the dialog closes. QBR decks open from an account's quarterly-review picker in /cs-app/accounts.
#2026-09-27-customer-success-saves-and-qbrsTechnical details
3961PR #3961 — onboarding plans, save plays, quotas and triage stay saved3920PR #3920 — QBR decks compose, save and export3967PR #3967 — a QBR slide reads as prose in the exported deck3962PR #3962 — a case opens from its case number, in your own workspace3965PR #3965 — the at-risk page says churn predictions are off3968PR #3968 — the lifecycle panel opens wherever its module home opens
- NewFixedSales & CRMMobile
Field Rep joins the module switcher and keeps working when signal drops; solutions engineers get their calendar and quick RFP uploads
Field Rep now appears in the module switcher, and Plan a visit starts a visit from any account. A visit keeps your note when signal drops and takes photos on site. SE Today shows today's meetings, and an RFP upload returns as soon as the file is saved.
What changed
Field Rep in the switcher. Field Rep now appears in the module switcher for workspaces whose plan includes it, and opens on Today at phone and desktop widths. “Plan a visit” on any account opens Today with the stop filled in and linked to that account, and a precise on-site check-in pins an account that has no location yet, never moving an existing pin.
Visits that survive the field. Field visit pages open again, with a pre-visit brief built from your open deals on that account. Losing signal keeps the visit on screen with a dated “No signal” notice and Retry, and your draft note survives a reload in that tab. “Add photo” opens the rear camera and attaches the picture to your note; photos need a signal, and the button says so. The main action, “I've arrived”, now sits above the phone's tab bar where a thumb can reach it, and the visit note can be saved while still on site. Consulting workspaces get consulting outcomes when they depart, such as Workshop held or Decision needed from client.
For solutions engineers. SE Today's calendar panel shows your meetings for today, where it had shown “Couldn't load” for everyone. Uploading an RFP now returns as soon as the file is saved; the page shows “Reading questions…” and updates itself when they're ready, or says it couldn't read them and asks for a re-upload. Battlecards and the RFP list tell “couldn't load” apart from “nothing here”, and a slow upload no longer shows a failure that invites a duplicate.
Try it
Open /field/today from the module switcher, or open an account and choose Plan a visit. Solutions engineers can upload an RFP at /se/rfps/new and watch the page follow the question read.
#2026-09-27-field-reps-and-solutions-engineersTechnical details
3803PR #3803 — Field Rep in the module switcher, one tap from any account3917PR #3917 — every field visit page opens again3982PR #3982 — a lost signal costs nothing; photos on site; consulting outcomes3918PR #3918 — the phone's primary action sits above the tab bar3919PR #3919 — SE Today's calendar shows today's meetings3981PR #3981 — an RFP upload returns once the file is saved3940PR #3940 — SE pages tell a failed read from an empty one
- ImprovedIntegrations & APIData & analytics
Enrichment pays only for what's missing, shows what it can fill, and checks your provider key before saving it
Enrich from vendors reuses values that are still current at no cost and says why any field stayed unknown. The Enrich sheet shows how many fields can be filled now, and a provider key is checked with the provider before anything is stored.
What changed
Reuse before you buy. Each enriched field now has a shelf life, such as 30 days for a job title, 90 for revenue and a year for headquarters. A repeat lookup inside it calls no vendor and costs nothing, so only missing or out-of-date fields are bought. The result leads with what you spent, then lists each field as New, Reused (“checked 2 days ago · good until Oct 22”) or Unknown with its reason. A value someone on your team entered is never re-bought, “Re-check current values too” forces a fresh lookup, and if your enrichment budget can't be read, nothing is bought and the dialog says so.
What can be filled, before you ask. The Enrich sheet on an account shows only the fields an account can actually get, with a line such as “9 of 23 fields can be filled now” and the provider connection that would unlock the rest. Person-only lookups are no longer run against an account, so you aren't charged for lookups that could never match. Data sources Pact can't sync yet, such as Stripe, Marketo and Mixpanel, appear under “Not built yet” with a request link and the CSV import path instead of asking for a secret key.
A key is checked before it's stored. Connecting Apollo, Cognism, Lusha, RocketReach or ZoomInfo with your own key now checks it with the provider first. A key the provider refuses is not saved, and the sheet says “Nothing was stored” with the provider's reason. Each provider card shows connected, needs attention or unverified, the published per-lookup price or “Not published”, and a Disconnect button.
Try it
Open an account from /accounts and choose Enrich from vendors: fields that are still current are marked Reused at no cost. Provider keys live under /settings/integrations/enrichment.
#2026-09-27-enrichment-pays-only-for-what-is-missingTechnical details
3867PR #3867 — vendor lookups reuse current values at $0 and say why a field is unknown3935PR #3935 — Enrich shows real coverage; no card asks for a key it cannot use2744PR #2744 — a provider key is checked before it is stored
- NewFixedSales & CRMPlatform
A Finance role reads revenue recognition and records payments, and proposals and invoices carry your firm's name
Finance users can read revenue recognition without being admins and record a wire, ACH or check payment against an invoice. Invites say what the new teammate will work as, and client-facing proposals, quote PDFs and invoices use your firm's name instead of Pact's.
What changed
A Finance role. A finance lead can now read revenue recognition without being a workspace admin, while running the sweep and closing a month stay with owners and admins. Anyone allowed can record a wire, ACH or check payment against an invoice, and recording never moves money. Partial payments add up and the invoice turns Paid only when the balance reaches zero. The dialog shows what's still owed, refuses an over-payment, a repeated bank reference or a closed invoice, and flags a reference that doesn't match the invoice's wire reference.
Invites say where people land. All three invite dialogs gain a “Works as” field with a line explaining what that role can do, the role picker accepts Compliance and Finance, and an invite can no longer grant more access than the person sending it has.
Your name on what clients see. Proposals, quote PDFs and invoice PDFs now carry the sender name set in your branding, or your workspace name, instead of “Pact”, and a custom domain in the quote PDF footer no longer loses its first letters. In the consent app, the privacy-request shortcut now shows where identity verification stands and links to the request page to finish it.
Try it
Open an invoice from /sales/invoices and choose Record payment to log a wire against it. Invite a teammate from /settings/team to see the new “Works as” field.
#2026-09-27-finance-role-and-client-documentsTechnical details
3952PR #3952 — a Finance role, recorded payments, and invites that say where people land3953PR #3953 — client documents carry your firm's name; the privacy shortcut shows status
- ImprovedMarketingPlatform
Sequence and playbook builders save a real Branch with both paths, and the workflow builder names the steps that can't run yet
The sequence builder's Branch step is no longer “coming soon”: draw a Yes and a No path and choose which engagement counts. A playbook Branch keeps its condition and both paths, and a test run shows which path a record takes. The workflow builder won't save six step types that can't run yet.
What changed
Branch in sequences. The sequence builder's Branch step is now a real step: draw a Yes and a No path, choose which engagement counts (replied, clicked a link or opened), and both paths save together. Opens are off by default, and the inspector explains why: mail-privacy proxies open messages automatically. The builder refuses routing it can't follow, such as a loop, and warns when a path ends the sequence. On a phone, the sequence reads as an outline with each path indented under Yes or No.
Branch in playbooks. A playbook Branch now has a structured condition, with field, operator and value including “is one of”, and saves both its Then and Else paths, where the builder used to keep only Then and drop the condition. The inspector says which path a record with a missing field takes, and a test run shows which path a given record would follow.
Workflows say what can't run. Six step types with nothing to run them yet, namely incoming email, cost cap hit, assign owner, voice call, generate RFP and run report, are marked unavailable with the reason, and a workflow that uses one won't save until it's removed. Existing workflows are not changed, and the dry run says how many steps would do nothing.
These are builder changes: what you design now saves exactly as drawn, and test runs show the path it takes.
Try it
Open a sequence under /sequences and its builder to add a Branch with Yes and No paths. In /playbooks, a Branch's test run shows which path a record follows.
#2026-09-27-branch-steps-in-buildersTechnical details
3831PR #3831 — a sequence Branch step with a Yes and a No path3840PR #3840 — a playbook Branch keeps its condition and both arms3845PR #3845 — a workflow step nothing can run is refused at save and named
- ImprovedExperiencePlatform
Every daily page is reachable from the module you work in, a workspace switch sticks, and pages open with their own name
Sales gains Tasks, Meetings, AI Radar, Calls and Power calling in its rail, Support gains Cases, and eight working pages that no link reached now have one. Switching from Support to Sales stays switched, a page error keeps the module's navigation, and the 90-second tour can be dismissed.
What changed
A way in to every page. The Sales rail now includes Tasks, Meetings, AI Radar, Calls and Power calling, plus Approvals for managers; Support gains Cases, and Admin gains Workflows. Eight pages you could only reach by typing an address now have a link: My contacts and Win/Loss in the Sales rail, a Meetings card in Settings, Currency & FX in admin settings, inbound webhook receivers, 24-hour slow-query trends, and a Live monitor on sent campaigns. Support agents, sales engineers, field reps and compliance users now land in their own module when your plan includes it, and SSO groups such as “Customer Support” or “Field Sales” map to them.
A switch that sticks. After switching from Support to Sales, opening Inbox or Home used to bring Support back. The module you choose now stays chosen on phone and desktop, and tapping Home on your module's home scrolls to the top. In sections with their own tab strip, such as IAM and Social, the strip keeps its place as you move between pages.
Pages that start with themselves. Marketing, Analytics, Data, Consent, Settings, Home, onboarding and admin pages now open with their own title, and module homes put their own content above the customer lifecycle, which now reads in plain language with its sources behind “How we know”. Several “coming soon” notes became the working feature: an email draft sends straight into a new campaign, billing usage shows what you're billed and how much of each allowance you've used, and the HubSpot and Pipedrive cards connect through Data sources.
Errors that don't take the page. If a page inside a module hits an error, the module's navigation stays usable, with Try again and a Report that includes a reference for support. The “Watch the 90-second tour” button can now be dismissed, and every tour stays one click away under Help → Tours.
Try it
Open /sales/today and look at the rail: Tasks sits under Today, with Meetings, AI Radar and Calls below it. Press ? to find every tour under Help → Tours.
#2026-09-27-every-page-has-a-way-inTechnical details
3814PR #3814 — every daily surface is reachable from the module you work in3810PR #3810 — eight working pages that no link reached get an entry point3844PR #3844 — a workspace switch sticks3823PR #3823 — a section's own navigation stays put between its pages3804PR #3804 — marketing, analytics, data and consent pages open with their own name3805PR #3805 — core surfaces lead with their own title; placeholders became features3800PR #3800 — module homes lead with their own content; the lifecycle reads plainly3846PR #3846 — a crash inside a module keeps its navigation and gets reported3842PR #3842 — the 90-second tour button is dismissible and lives in Help → Tours
- FixedMobileExperience
On a phone, nothing floats over your work, titles are never cut, and Hey Pact fits on screen
The quick-actions button is now an Actions tab in the bottom bar, Home and the Dashboard reach your work sooner, and the Dashboard title is whole at every width. Hey Pact fits above the keyboard, small labels render at their designed size, and warning notes are readable in light mode.
What changed
Nothing rests over content. The floating corner button that covered Dashboard activity rows is now a sixth tab, Actions, in the bottom bar, with its count badge. Stacked notices take a single row and disappear once dismissed. Dashboard Recent activity shows business activity with readable headlines such as “Email · Logged” and names instead of ids, and leaves out sign-ins and automated calls.
Your work sooner. On a phone, the Home greeting is one line instead of a large card, so today's deals are on the first screen, and dashboard KPI tiles drop their decorative icons. The Dashboard title is never cut to “Dash…” at any width from 320 to 1920 pixels; when the header is tight, the Sample label moves to a small line beneath it.
Hey Pact fits. The Hey Pact panel stays on screen with its close button and your question visible, only the conversation scrolls, the text box stays above the keyboard, and swiping to dismiss no longer fires while you scroll.
Readable details. Small labels, including phone tab names, sidebar badges and changelog tags, render at their designed size and color, so “Records” no longer truncates on a small phone. Warning notes on call recaps, deal decisions, the email composer, lead scoring, and support, customer success and admin pages were white on pale amber and are now readable in the light theme.
Try it
Open /dashboard on a phone: the Actions tab sits in the bottom bar and the title is whole. Open Hey Pact from any page and start typing; the composer stays above the keyboard.
#2026-09-27-phone-screens-show-your-workTechnical details
3794PR #3794 — nothing on the phone rests over content; Recent activity reads plainly3774PR #3774 — the phone screen spends itself on your work3797PR #3797 — the page title is never cut, from 320 to 19203628PR #3628 — Hey Pact is usable on a phone again3798PR #3798 — small labels render at their designed 10 px3911PR #3911 — warning notes on partner and marketer pages are readable3950PR #3950 — every warning callout in the app is readable
- PerformanceFixedPlatformExperience
Steadier and lighter: updates don't interrupt you, idle tabs stay quiet, and exports, push and call playback work
Pages mid-load, live updates and clicks keep working while a new version rolls out. An idle tab no longer keeps loading pages in the background, the incoming-call overlay and live pipeline updates connect again, and report CSVs, audit exports, browser push and AI-call playback work.
What changed
Releases you don't notice. When a new version rolls out, each server now finishes the requests it's handling before it stops, so pages that are loading, live updates and clicks keep working, and live views such as notifications and activity reconnect right away.
Lighter tabs. A page-preloading hint was chaining endlessly, so every open tab kept re-requesting pages for as long as it stayed open; a page load now preloads its few likely next pages once. App sounds load the first time they play, and never for someone with sound turned off.
Live again. The incoming-call overlay appears again when a call comes in, and the Pipeline and My pipeline boards update live when a teammate moves a deal. Snoozing the setup checklist now sticks across devices, and snoozing the daily goal works.
Things that now do what they say. A saved report's CSV and the audit-log export buttons download the file, with a reason if a download fails. Browser push registers your browser and says what will arrive, with a real test send; AI-agent calls with a recording play it; data sources list their full run history; contacts show when each person was last touched; and sequences and journeys can be shared by link. On SSO settings, Show SP metadata displays your service-provider metadata. Records created through the public booking page, forms, surveys, campaigns, segments, journeys and templates come back with their real identity, so a new booking links to its calendar event.
Held, not dropped. If a workspace is suspended, incoming email events, Slack messages and calls are kept and processed when it resumes; once a workspace is scheduled for deletion, new inbound data is refused.
Try it
Open a saved report under /analytics-app/reports and click its CSV button: the file downloads. An AI-agent call with a recording now plays from its page under /calls.
#2026-09-27-steadier-and-lighterTechnical details
3843PR #3843 — releases no longer cut requests mid-flight3888PR #3888 — idle tabs stop re-requesting pages3889PR #3889 — app sounds load on first play3881PR #3881 — the ring overlay and pipeline live updates connect3890PR #3890 — checklist and daily-goal snoozes save3966PR #3966 — a saved report's CSV and the audit-log export download3876PR #3876 — push that registers, call playback, run history, last activity, share links3847PR #3847 — Show SP metadata works on SSO settings3593PR #3593 — created records come back with their real identity3802PR #3802 — inbound events for a suspended workspace are held, not dropped
- ImprovedIntegrations & API
Developers: agents asking the workspace over MCP get the answer a person gets, and the iOS SDK ships Combine publishers
The ask_workspace MCP tool now returns the same answer, confidence and gaps as Ask in the app. That changes its payload, so an integration reading the old keys should read gaps. The iOS SDK's PactSDKCombine product now exists, and the SDK builds cleanly under Swift 6 strict concurrency.
What changed
ask_workspace answers like Ask. Agents connected over MCP that call ask_workspace used to get answers from a different engine with no confidence information. They now get the same answer a person gets in Ask: a counted answer arrives with its measured confidence, an unmeasured one says “not established” instead of giving a number, and conversation threads continue.
This changes the payload. The response now carries answer_tier, confidence, kpis, gaps and steps, and ai_powered, sources_searched and retrieval_unavailable are no longer top-level fields. An integration that read those keys should read gaps instead.
iOS SDK. The PactSDKCombine product the package listed now has code behind it: its publishers start on first demand, can be cancelled, and pass Pact errors through unchanged. The SDK builds under Swift 6 strict concurrency with no errors, and every Swift sample on the iOS SDK page compiles, including corrected quickstart and offline-queue samples.
Try it
Open /docs/developers/mobile-sdk/ios for the Combine samples. MCP clients see the new ask_workspace fields on their next call.
#2026-09-27-developers-mcp-and-iosTechnical details
3974PR #3974 — ask_workspace returns the answer, tier and confidence a person gets3957PR #3957 — the PactSDKCombine product exists; the SDK is Swift 6 clean
- ImprovedData & analyticsExperience
The sample workspace tells one connected story across Sales, Customer Success, Marketing, Consent and Analytics
Accounts, deals, calls, health scores, deal rooms, quotas, win/loss, forms and activity in the sample workspace now describe the same accounts, with real forecast numbers on the manager pages. Support's knowledge-base search finds articles again for every workspace.
What changed
The sample workspace is how most people first see Pact, and it used to be a set of disconnected rows. Account stages, deals, calls, health scores, deal rooms, buying committees, quotas, win/loss, battlecards, forms, templates and the activity feed now describe the same eight accounts, so a story you start on Sales Today continues on CS Today and in Analytics. Sample pipeline boards have their columns, Manager Today and Forecast show a real Commit instead of $0, and dates stay relative to today.
Every sample row is still labelled as sample, and removing it still takes two deliberate steps that leave your own records untouched.
The same release fixes two things for every workspace: Support's knowledge-base search returns articles again, and a WhatsApp or Messenger mention can no longer blank the unified inbox.
Try it
Open /sales/manager/today in the sample workspace, where Commit shows a real figure, then follow the same account from /cs-app/today.
#2026-09-27-sample-workspace-one-storyTechnical details
3875PR #3875 — one coherent sample world across every module
- NewData & analyticsSecurity & trust
A workspace can go live: sample data is labeled, kept out of exports, and purged without touching a real row
Seeded sample rows now carry a lifecycle of their own — labeled where you see them, left out of every data export with a count of what was left out, and cleared at go-live by one action that can only remove rows belonging to your workspace.
What changed
Every new workspace starts with sample data so the product is not empty on day one. Until now that data had no lifecycle: it looked like yours, it went out in your exports, and clearing it meant trusting a script.
Labeled. One rule decides what is sample — a seed marker, or a row older than the workspace's go-live moment on a table that carries a watermark. Nothing is inferred at render time. On the dashboard the label is now a compact ✦ Sample tag beside the title instead of a widget in the way of your own numbers; tap it to see the seeded record counts by entity.
Kept out of exports, with a count. A data-subject access answer, a GDPR export and a portability bundle all leave sample rows out and say how many were left out and why. Before this, a customer's "here is everything we hold about you" bundle silently mixed our demo rows into their evidence.
Purged without touching a real row. The go-live purge builds every statement on the same engine that deletes a whole workspace, so every delete carries a workspace predicate, and it proves real rows survived independently of its own predicate. Demo usage no longer counts toward a real meter, and seeded users no longer receive credentials that can be derived from the seed.
Deleting a whole workspace is now provable, too. A relation map of every table in the schema classifies each one — deleted by workspace id, deleted through a parent, retained with a written reason, anonymized, or rebuilt — and a statement guard fails if any emitted delete lacks a workspace predicate. Suppression and audit rows are never plain-deleted; an address becomes a hashed tombstone so a person who asked not to be contacted stays not-contacted after their data is gone. A customer who asks for their workspace to be deleted can be answered with evidence instead of a promise.
Try it
Open /dashboard. The ✦ Sample tag sits beside the title; tap it for the seeded record counts by entity and the typed-DELETE clear, which keeps a 30-day undo.
#2026-09-23-a-workspace-can-go-liveTechnical details
3737PR #3737 — sample data labeled, excluded from exports, purged at go-live3793PR #3793 — the sample-data label moves beside the dashboard title3736PR #3736 — delete a whole workspace, provably, and prove real rows survived
- NewSecuritySecurity & trust
Every data-subject request does what it says: access, portability, rectification, restriction, objection and erasure
Fulfilling a request used to change nothing unless it was a deletion. Now an access request delivers a download link to the subject, rectification applies the change, restriction adds a suppression every gate honors, and a missed deadline is escalated every hour.
What changed
Of the four request types the DPO console offered, only delete did anything when a request was marked fulfilled. Access collected evidence nobody sent, rectify marked the request done and left the record unchanged, and portability produced nothing. There were no request types for restriction or objection, nothing checked that the requester was the data subject, and nothing chased a missed deadline.
Access now emails the subject a single-request download link, and the answer says what was searched and what was not. Portability produces a versioned bundle — profile, consent ledger, form submissions, identities. Rectification applies the requested changes, re-encrypts and re-hashes the record, and keeps a per-field before/after with identifiers masked. Restriction adds a suppression that every gate honors — sends, retrieval into a model's context, agent memory, enrichment — while storage is untouched. Objection lands as withdrawals on the consent ledger. Erasure worked before and is unchanged, plus a guard for shared addresses.
Identity is verified before fulfillment, and an overdue request is escalated hourly instead of aging quietly.
Underneath, a privacy drill against a copy of production found the paths that did not survive contact and fixed them: an erasure used to *unsuppress* a person by deleting their suppression row, so mail could resume; the retained list now keeps a hashed tombstone. A suspended, pending-deletion or deleted workspace is now refused on sessions, API keys, webhooks, scheduled jobs, AI jobs, billing, inbound voice and sequence sends — and an unreadable status fails closed.
Try it
Open /consent-app/dsar, open a request and fulfill it. An access request emails the subject a single-use download link; a restriction request adds a suppression you can see honored on the next send attempt.
#2026-09-23-every-data-subject-right-does-somethingTechnical details
3718PR #3718 — every data-subject right does something when it is fulfilled3735PR #3735 — tenants.status enforced across the product; erasure, DSAR and cross-tenant gaps from the privacy drill
- FixedData & analyticsExperience
A page that could not read your data now says so, instead of showing a zero or “nothing here yet”
Not allowed, could not read, and nothing there are three different answers. Analytics, Marketing, Support, coaching and the notification bell used to render the second as the third — a failed read looked exactly like an empty workspace.
What changed
A read can end three ways, and each needs its own answer. Ok, nothing there gets the page's own empty state, and a real zero is a zero. Failed gets one named failure with a request reference and a Try again. Refused gets a lock, the module named, whether the workspace or the seat lacks it, who can grant it, and a working link.
Before this, Analytics tiles printed $0 in pipeline over a 0% win rate while the read was in flight or after it failed — byte-identical to a workspace with no pipeline. Support Today printed "Inbox zero — nice" over a cases table the server could not read. The manager coaching page printed "the team is moving deals at expected dwell" over a query that had never once executed, beside a skill rubric that scored a rep 100 on discovery from an empty result. Two privacy-portal reads told a data subject they had no consent records when the read had raised.
The top bar had the same shape in the one place nobody checked: the notification bell disappeared entirely on any failed count — a 502 during a deploy looked like a workspace that had never bought notifications. It now stays, in the same footprint, and says what failed.
The primitive underneath was fixed as well. The read-isolation helper recorded a gap only when a read *raised*; a helper that swallowed its own failure and returned an empty list exited cleanly, and on Postgres left the shared transaction aborted for the next query. It now records the failure that does not raise, so the surfaces above cannot be lied to by the layer below them.
Try it
Open /analytics-app/today or /support/today. A failed read renders one compact Couldn't load line with its reference and a Try again; a refused module names who can grant it; a true zero is a zero.
#2026-09-23-a-failed-read-is-not-an-empty-workspaceTechnical details
3551PR #3551 — not allowed, could not read, and nothing there are three answers: Analytics and Marketing3555PR #3555 — Support Today and Phone said "no recent calls" when they meant "I could not look"3558PR #3558 — a notification count that failed to load renders as a bell that says so3560PR #3560 — a read that swallowed its own failure now records the gap3569PR #3569 — two support reads answered "absent" to a question they could not ask3570PR #3570 — three surfaces said 'nothing there' about reads that never ran3770PR #3770 — the coaching page stops rendering a failed read as a clean team
- FixedMarketingVoice & callsExperience
Five surfaces that showed invented numbers now show your data, or nothing
A scripted live call, an A/B split that bucketed untagged sends by id parity, a hardcoded send-time window, five invented playbooks and a fake mail-domain settings page are gone. Each surface now shows a real read, an honest empty state, or is removed.
What changed
The standing rule is no shell pages: real data, no placeholders, no dead links. A code read and a sweep found the places still breaking it, and every one is now either real, honestly empty, or gone. Nothing unreal was made to look more real.
The live voice page played a timer-driven scripted call with invented tools and sentiment; it now opens the real Live tab over your actual calls, and the scripted view is deleted. A campaign's A/B tab split untagged sends into variants by the parity of their id and spread opens across them; untagged sends are now counted as untagged and never bucketed, rates are null unless opens are variant-tagged, and a campaign with no variants says it is not a test. The send-time tab printed a hardcoded "9:30–11:00, +18% open"; it now shows the optimizer's recommendation for the campaign's segment, or the reason there is none. Customer-success playbooks listed five invented auto-enroll plays with activity counts and outcome claims; they are removed and the real expansion plays kept. The marketing settings page printed a made-up mail domain, caps and DMARC status; it is now an index of the real configuration pages that says what is not configurable.
Alongside them, toast-only controls that confirmed actions they never performed, test harnesses reachable from production, and links to pages that did not exist were removed or wired to the thing they named.
Try it
Open a campaign under /marketing/campaigns and look at the A/B tab: sends without a variant tag are counted as untagged rather than split by an invented rule. /voice-live now lands on the real Live tab of /calls.
#2026-09-23-invented-numbers-removedTechnical details
3589PR #3589 — no shell pages: fabricated data, toast-only controls, prod-reachable harnesses and 404 links removed
- FixedPerformanceAI
Ask Pact and Hey Pact find the record you said out loud, and admit it when a lookup could not run
Speech-to-text spells names out — “three m” for 3M, “a t and t” for AT&T — and Pact used to answer that the workspace held nothing. Now the name resolves, the answer is scoped to that record, a failed retrieval is shown as a named gap, and the interactive path has a 15-second budget.
What changed
Asked out loud on a phone, "What caused the 3M stall?" arrived as "What caused the three m stall?" and Pact replied that it could not find anything matching that in the workspace — about a workspace that holds an account named 3M. The spoken form now resolves to the record, and it resolves on the structured branches too, so a question about one account is answered about that account rather than tenant-wide. A near miss never narrows the answer, and an ambiguous name is left ambiguous and logged.
When there is genuinely no match, the suggestions under the answer are the closest records on file instead of the three most recently added — and the gap sentence no longer points at "the suggestions below" on a surface, or a phone line, that has none.
A retrieval that could not run is no longer rendered as a workspace that holds nothing. The engine learned the difference two weeks ago; every consumer dropped the flag on the floor. It now reaches all six — the panel, the thread, the phone, the widget, the API payload and the extractive fallback — and a seventh engine the review never named. On screen, retrieval failed, matched nothing, not entitled and has results are four distinct states.
Time is bounded and accounted for. The interactive path inherited a batch retry policy that could take 92 seconds to give up; it now spends a 15-second wall-clock budget and, when that expires, degrades to the record list and says so. Every answer carries a request total and a per-stage ledger, so a slow answer can say where the seconds went instead of leaving a mystery. Time nothing names is reported as unaccounted, never dropped.
In the AI usage ledger, an error is now filed under its exception class instead of "unknown", and three ordinary words containing "rate" no longer file a failure as a rate limit.
Try it
Open /ai/ask-pact and ask about an account by a name speech-to-text would spell out. The answer is scoped to that record; ask about one that does not exist and the closest records on file are offered, with no sentence claiming the workspace is empty.
#2026-09-23-ask-pact-finds-the-record-you-saidTechnical details
3576PR #3576 — the workspace holds 3M, and Pact said it held nothing3578PR #3578 — the structured branches scope to the record the question names3755PR #3755 — a retrieval that could not run never reads as an empty workspace, on all six consumers3556PR #3556 — the gap no longer points at suggestions that are not there3564PR #3564 — a 54-second answer now says where the 54 seconds went3728PR #3728 — a 15 s deadline on the interactive path; the panel body loads on open3279PR #3279 — an AI error is filed under its exception class, never "unknown"
- FixedImprovedExperience
The notification bell counts what it is going to show, and the inbox folds a repeating condition into one row
A bell reading 285 over a list of forty was one unfinished passkey enrollment reported 140 times. A burst of one standing condition is now one item and counts as one, dismissing it clears every row it stands for, and a test-send can no longer answer OK while sending nothing.
What changed
The bell said 285 unread over a dropdown holding roughly forty items, because 140 of those rows were one unfinished passkey enrollment reported 140 times and forty more were one usage threshold reported forty times. The twenty mentions and nine access requests that actually needed a person were underneath them.
A burst of one standing condition now renders as one item and counts as one. Two mentions two hours apart still count as two, and two different threshold conditions never collapse into one line — the earlier grouping key was coarser than the condition it named, so an abandoned enrollment and a failed one shared a row and could re-raise each other's payload. Muting a kind moves the badge. Clicking a collapsed row clears the whole group, and a row with no destination can still be dismissed.
The unified inbox — the one surface built to be "everything that needs you, triaged" — asked for the uncollapsed feed and was the last place still rendering a condition as 140 rows. It now asks for groups, dismissing a grouped row archives every id it stands for, opening one marks them all read, and a standing condition is badged as a volume while an event kind is badged as updates.
The notification test-send in settings answered 200 and sent nothing; it now either produces a notification or says why it could not.
Try it
Open /notifications. A repeated condition is one row with a volume badge; dismiss it and every row it stands for is archived, and the bell's number matches the list.
#2026-09-23-the-bell-counts-what-it-showsTechnical details
3565PR #3565 — the bell counts the things it is going to show3741PR #3741 — a dedup key coarser than its condition merged two conditions into one line3742PR #3742 — the unified inbox asks for the collapsed feed; every action reaches the group3761PR #3761 — a test-send that answered 200 and sent nothing
- NewSales & CRMData & analytics
The customer lifecycle is a timeline: seven stages, one account on a dated line, and a portfolio sorted by urgency
The lifecycle lane used to stop at Won and resume at Supported, drawing the stretch where customers are actually lost as nothing. It now has seven rungs, and the view is a timeline — one account's dated journey with today marked and the next SLA ceiling and renewal decision below it — or a portfolio with one attention cell per row.
What changed
The lifecycle lane stopped at Won and resumed at Supported. The stretch between the signature and the second invoice — implementation, and the renewal decision — was drawn as the absence of anything, and that is where customers are actually lost. It was never a data problem: onboarding plans, subscriptions and expansion signals have carried an account id for months. The lane simply never reached them.
The lane now has seven rungs, each with a written map of what it can and cannot count. Onboarded and renewed are real counts from real ledgers, scoped to your workspace. A rung whose ledger did not answer is a named reason, never a zero.
The view itself was rebuilt at both widths, replacing a rung strip over a table that named the same accounts twice. Journey draws one account on a vertical, dated line, newest at the bottom, a today marker, and the future below it — an SLA ceiling in five days, a renewal decision in nineteen. Portfolio is five columns — account, lifecycle, needs attention, health, open — with one attention cell per row on three levels, the rung strip folded into the row as a seven-segment bar, sorted by urgency.
Open cases and expansion signals were undated on the wire, which is why a timeline was not possible before. Both now carry the dates their tables have always held, so the line can show causality: an expansion converted on the 2nd, four P1 cases on the 8th, health down 22 points, a ceiling in five days, a decision in nineteen — readable in one screen on a phone.
Try it
Open /cs-app/accounts and switch between Journey and Portfolio. Journey draws one account on a dated line with today marked and the next SLA ceiling and renewal decision below it; Portfolio sorts every account by urgency with one attention cell per row.
#2026-09-23-the-lifecycle-is-a-timelineTechnical details
3567PR #3567 — the lane grows the two rungs where customers are actually lost3577PR #3577 — the lifecycle view is a timeline: journey and portfolio, at 390 and 1920
- FixedSales & CRMData & analytics
Dashboards show open pipeline from deals, with every closed and lost stage excluded from every money figure
Dashboard readers now read the deals ledger with an explicit stage predicate on every aggregate, so a lost renewal is closed rather than counted as live. Five dead figures went with it, including a pipeline total that had summed a nonexistent column on every snapshot ever taken.
What changed
Dashboards now show open pipeline from the deals ledger, with an explicit stage predicate on every money aggregate. The match is by substring, so a stage such as "Renewal — Lost" is closed and excluded, not counted as a live renewal.
Five figures that were never right went with it. The pipeline-value total on every stored snapshot summed a column that did not exist, so it had been 0.0 on every snapshot ever taken. The My Day widget returned a server error on Postgres. Two readers filtered on a status column that was not there. A customer-success renewal read was not scoped to the workspace. And the inbound caller's open pipeline — the number that decides whether a known caller is bumped up the queue — had read $0 on every call because the query raised and the failure was swallowed.
Try it
Open /dashboard. Open pipeline and open renewals count deals in open stages only; a stage containing “Lost” or “Closed” is out of both, whatever its spelling.
#2026-09-23-dashboards-show-open-pipeline-from-dealsTechnical details
3337PR #3337 — dashboards show open pipeline from deals, with an explicit stage predicate
- FixedNewVoice & calls
Every AI voice-agent call can be opened from Calls, and the inbound screen-pop works again
384 of one workspace's 420 voice-agent calls could not be opened from any page — their turns were stored the whole time. They open now. The screen-pop for a recognized inbound caller returned a server error on every match; it now shows a caller context pack, and a transfer carries a handoff pack.
What changed
A voice-agent call's turns were in the database and already served by two working endpoints, but the call page only knew how to resolve a call-log id or a recording id and dead-ended on everything else. Measured on one workspace: calls a person could open from Calls went from 167 of 551 to 551 of 551. Another workspace's call is refused with the same answer as a missing one, so an id cannot be probed.
The inbound screen-pop — the card that appears when a known contact calls in — returned a server error for every caller it matched, and the transfer whisper went silent with it. It is fixed, and it now serves a caller context pack: who is calling, their open deals and cases, and the last conversation. A transfer carries a handoff evidence pack so the next person is not starting from nothing.
The relay could also lose a turn the caller had already heard answered, or store it twice stamped as an interruption that never happened, when the socket tore down at the wrong instant. Exactly one row per answered turn is now written whatever the teardown does, and no interruption is fabricated — which also stops those phantom rows polluting the cut-rate analysis.
The custom media transport's admit gate had imported a module deleted two weeks earlier, so every call that reached it raised a server error instead of speaking its refusal; the import is fixed and the whole admit path now fails closed with spoken TwiML.
Try it
Open /calls. A voice-agent call opens on its own page with every turn. When a known contact calls in, the screen-pop shows the caller context pack; transfer the call and the handoff pack goes with it.
#2026-09-23-every-voice-agent-call-opensTechnical details
3766PR #3766 — open the 384 AI voice-agent calls no tenant route could reach3705PR #3705 — the inbound screen-pop 500'd for every caller it matched; caller context and handoff packs3763PR #3763 — the relay no longer loses a turn at teardown or stores it twice as a barge-in3676PR #3676 — the media-streams admit gate imported a deleted module and 500'd instead of refusing
- FixedVoice & calls
On the phone, Pact stops interrogating you for optional details, hears names it used to mishear, and no longer reports a change failed while it commits
Nine fixes measured on real calls: an update no longer walks you through every optional field, a filtered zero no longer claims the pipeline is empty, a timed-out write is reported as what it did, amounts are read in full, and the recognizer finally receives the vocabulary that was built for it.
What changed
Every fix here was measured on real calls, not on a fixture. Say "update that" followed by a stage and Pact applies it; it no longer asks "anything for the deal amount? … anything for the close date? … you can say skip" for every optional field before doing what you asked.
A filtered search that returned zero used to be spoken as "you have no open deals right now" — on a call that had just counted 27. The call now remembers what it resolved, and a zero from a filter is spoken as a zero from that filter. When the workspace holds the account you named, "tell me about three m" reaches 3M instead of an invented account built from a filler word.
A voice-CRM write that ran past the turn's timeout was narrated backwards: "sorry, that took too long," followed by an invitation to retry — while the deal was updated anyway. The write is idempotent and its receipt is durable, so after a timeout Pact reads the receipt and tells you what actually happened.
"Of course —" and "No problem —" no longer open a sentence that goes on to report a miss. Amounts are spoken in full — "four hundred and eighty thousand dollars", not "$480k". A capability menu is no longer recited on every failure.
The recognizer's vocabulary bias — the list of your accounts and contacts that helps speech-to-text hear them — was built and cached on every call and then never sent on the transport that serves most of them. It is sent now, under a byte bound that is raised one rung at a time only after a real call connects on the rung below. A misheard tool phrase is recovered by sound against phrases already seen, with zero wrong claims on 522 real turns. Chained requests — "open a deal with 3M and progress it to prospecting" — are split where they should be and left whole where splitting would be harmful.
Try it
Call 1-424-PACT-MCP, say “update that” and then a stage. Pact applies it without asking about every optional field, and reads a deal amount back in full when you give one.
#2026-09-23-the-phone-agent-stops-interrogatingTechnical details
2784PR #2784 — an update stops interrogating: the optional-slot treadmill2788PR #2788 — the call remembers what it resolved; a filtered zero stops claiming the pipeline is empty2809PR #2809 — the caller stops being told a change failed while it commits2811PR #2811 — no "Of course —" in front of a miss; numbers are said out loud2833PR #2833 — draft-a-reply routing fixed; voice-capability census2871PR #2871 — a misheard tool invocation is recovered by sound, 0 wrong claims on 522 real turns2872PR #2872 — the recognizer bias was built, cached, and thrown away on 92% of calls2876PR #2876 — chaining fires on the clauses it should, and only those2902PR #2902 — relay biasing relanded behind a byte bound
- SecuritySecurity & trustIntegrations & API
Cross-workspace reads are closed, unsigned callbacks are refused, and report share links finally expire
An anonymous request could read any workspace's deals through a link-unfurl endpoint; any workspace admin could delete the feature flag that gates every other workspace; a workspace's own AI-cost page listed the platform's five biggest spenders. Each is closed, with the probe that found it kept as a test.
What changed
This is the batch's security work, stated plainly. Everything below is live; nothing here is a switch waiting to be thrown.
Reads across workspaces. A link-unfurl endpoint took its workspace from a request header and carried no authentication, so an anonymous request could read any workspace's deals, accounts and contacts by naming the workspace and guessing an id. A workspace's AI-cost overview grouped by workspace with no predicate, so any customer's admin saw the platform's five biggest workspaces and their exact spend. A company that belonged to no workspace was readable by every workspace across eight routes. Event and collaboration WebSockets authenticated only when a variable production never set was set, and a signed-in user could stream another workspace's events by naming it. All closed, and a static gate now runs in CI so a new one-sided join fails the build.
Writes across workspaces. Feature flags are global — one row per flag for the whole fleet — and every route that could create, retarget or delete one was gated on a workspace-level permission, so any workspace admin could remove the gate governing everyone else. Those routes are now Pact-staff surfaces; the per-workspace path is untouched. An erasure in one workspace deleted matching notifications in every workspace. A suspended workspace could un-suspend itself and any owner could self-upgrade their plan. A share link for a report never wrote its expiry, so every share link ever issued was permanent; they expire now.
Callbacks. Twelve inbound webhook routes accepted an unsigned POST from outside. Email-provider webhooks, e-signature callbacks, calendar and social callbacks, and the Twilio voice-room routes now verify a signature or refuse in production, and a signature-bypass flag is ignored when the app runs as production. An unauthenticated media socket is closed after fifteen seconds instead of being held open for half an hour. The bounce-and-complaint webhook that verified nothing — so an anonymous caller could suppress any workspace's mail to any address — verifies now.
Underneath. Every production transaction now runs bound to its workspace or on an explicitly elevated, named path, and the isolation checks in CI evaluate each table's policy as a non-bypass role rather than only checking that a policy exists. The database role switch that makes Postgres enforce those policies is still staged, as the runbook records; this batch makes the day it is thrown a smaller one.
Try it
Open /reports, share one, and open the share dialog again: the link carries an expiry. From outside, an unsigned POST to an inbound webhook route answers 401 instead of 200.
#2026-09-23-cross-workspace-reads-closedTechnical details
3571PR #3571 — an anonymous request could read any workspace's deals; the scanner that found it3738PR #3738 — four live cross-workspace leaks, a structural role fix, and a predicate gate that runs3630PR #3630 — a company with no workspace is reachable by no workspace3591PR #3591 — event and collab WebSockets authenticate on every deployment3768PR #3768 — any workspace admin could delete the feature flag that gates every other workspace3611PR #3611 — six lifecycle gaps: erasure scoped, plan and status changes staff-only, SSO and SCIM first-create fixed3568PR #3568 — report share links never expired; three real fences3617PR #3617 — inbound webhook signatures and backing-service TLS3623PR #3623 — the inbound callbacks that answered unsigned callers are closed3747PR #3747 — the last two inbound routes that accepted unsigned requests now refuse3574PR #3574 — the one email webhook that verified nothing now verifies3599PR #3599 — media-socket pre-auth deadline; production ignores bypass flags3590PR #3590 — the tenant-isolation checks evaluate policies instead of counting them3598PR #3598 — every unbound production transaction is bound or explicitly routed
- FixedMobileExperience
On a phone, every drag handle works under a thumb, the top bar fits at 1024, and a scrolled-away filter says so
Six of eight reorderable lists could not be moved by touch. The bell and account menu ran up to 230 px off the right edge at laptop widths. The analytics range rail hid the selected range off-screen. The tracking page was a narrowed table. Each is a phone design now, and a gate performs the gesture.
What changed
Every mobile defect reported in the week to the 15th was found by a person looking at their own phone, while six mobile gates ran green every night. The gates measured boxes; none of them put a finger on anything. Three things changed.
Drag handles. One grip — 44 by 44 pixels below the laptop breakpoint, with touch-action none — replaced seven hand-rolled ones. Six of the eight reorderable lists in the product could not be moved by a thumb; they can now, and a gate drives real touch events at 390 by 844 and fails if the list does not move.
The top bar at 1024–1279 px. The sidebar takes 260 px and the right-hand cluster could not shrink, so on 31 routes the bell and account menu ran 50–230 px past the edge. In that band the view-as label goes icon-only, the tier and Hey Pact pills wait for a wider screen, and the account name hides. Every control stays reachable.
The analytics range rail at 390 px. The rail's port was 138 px against 315 px of chips, so four of seven ranges were off-screen with nothing saying so — and on the year-to-date range the active chip sat entirely out of view, so the page rendered "7d 14d 30d" with nothing highlighted above figures scoped by that selection. The rail now scrolls the active chip into view and says when more is hidden. The same page also took its whole route into its error boundary whenever the summary arrived without KPIs; it degrades per-tile now.
Tracking on a phone is its own design rather than the desktop table narrowed, with a paging count that no longer lies while the browser-side source filter is on, and an empty table that says which kind of empty it is. And an announcement banner that overflowed both edges at 360 px — the one real defect behind eleven of the layout backlog's failures — is fixed.
Try it
On a phone, open /analytics-app/today?range=ytd: the active range chip is scrolled into view and highlighted. Open /pipeline and hold a card's grip to reorder it with a thumb.
#2026-09-23-the-phone-gets-its-screen-backTechnical details
3566PR #3566 — six of eight drag surfaces could not be used by a thumb; the gesture gate3615PR #3615 — the top bar fits at 1024px3772PR #3772 — the analytics range rail hid the selected range at 3903534PR #3534 — the tracking page gets a phone design and two honesty fixes2829PR #2829 — the layout backlog was 6 causes, not 103 bugs; the banner overflow at 360px
- FixedMobileSales & CRM
Field Rep loads for every rep, keeps visits logged with no signal, and shows each rep only their own day
Every Field Rep page landed in its error state for every rep, because its client bypassed the app's API path and sent no credentials. It is on the standard client now, and what that exposed is fixed too: other reps' visits were open to any rep, a long outcome crashed the save, and offline replay could jam for good.
What changed
Today, Route, Territory, Scorecard and Visit all opened on an error for every rep. The module's client was the only one in the product on a raw fetch with no API prefix and no authorization header, and the browser proxies only the prefixed paths. It now uses the standard client, and a contract test covers every request it can make.
Once the pages were reachable, reading them turned up three more defects. A visit or territory belonging to another rep in the same workspace was open to any rep; it now answers not-found, identical to a missing record, on all seven visit routes and on territory read and archive. An outcome, objective or check-in method wider than its database column crashed the save with a server error; each now gets a validation error naming the field. And the offline outbox never actually worked offline — a queued visit is now kept with no signal and replayed, in its own savepoint, when the connection returns, and each queued action can only touch the queuing rep's own visit.
Every module root now lands on that module's Today.
Try it
On your phone open /field/today. Log a visit with no signal and it is kept and replayed when you are back online; another rep's visit answers not-found.
#2026-09-23-field-rep-loads-for-every-repTechnical details
3785PR #3785 — Field Rep loads for every rep, keeps visits logged with no signal, and each rep's day is their own
- PerformanceSales & CRM
Accounts loads 46 kB lighter on first open
The account list's first-load script went from 279 kB to 233 kB. Four things nobody runs before a click — the bulk-action bar, the guided tour, the right-click Ask Pact dialog and a browser fallback no browser takes — now load at the moment they are asked for.
What changed
The account list is the page a rep opens most, often on a phone, and it had sat on its script budget through three bumps. Its first load now carries 46 kB less JavaScript to download, parse and run before the list is interactive — 279 kB to 233 kB, exact gzip sums, with the budget left where it was.
Nothing looks different. The bulk-action bar loads on the first row selection, the guided tour on the first "Take the tour" click, the right-click Ask Pact dialog and its voice stack on the first open, and a base64 fallback that no browser takes is no longer bundled at all. Each deferred surface is fixed-position or absent until opened, so nothing shifts, and a guard test fails if any of the four static imports comes back.
Try it
Open /accounts on a phone. The list is interactive sooner; select a row and the bulk-action bar appears on demand, exactly as before.
#2026-09-23-accounts-loads-lighterTechnical details
3790PR #3790 — /accounts first load 279 → 233 kB without raising a budget
- FixedIntegrations & APIMarketing
Fifteen integration pages said “Not connected” about integrations that were wired, and journey attribution always read $0
A wildcard route on the video-meetings integration answered for e-signature, Salesforce, HubSpot, Pipedrive, Resend and Discord before their own routers were reached. Journey attribution joined a column dropped months ago, so every journey showed $0 attributed pipeline. Both are fixed, and /health now names the deployed commit.
What changed
The video-meetings integration's route matched any provider segment, so the app answered "unknown provider" for fifteen endpoints across five other integrations before the router that owned them was ever reached — and the settings pages rendered that as Not connected or Not configured for integrations that were wired correctly. The route now declines anything that is not a video provider and lets the request fall through, whatever the router order.
Journey attribution joined enrolled subjects to contacts on a plaintext email column that a migration dropped months ago. The query failed on every database, the failure was swallowed, and every journey showed $0 attributed pipeline on the list and on detail. Enrolled subjects are now matched through the workspace-salted email hash, the same way segments already match, and opportunities are filtered to the workspace rather than matched by company name across all of them.
For anyone integrating against the API, /health now returns the deployed commit, so a support conversation can start from what is actually running.
Try it
Open /admin/integrations: e-signature, Salesforce, HubSpot, Pipedrive, Resend and Discord show their real status. Open a journey under /marketing/journeys — attributed pipeline is computed against your contacts instead of reading $0.
#2026-09-23-integrations-said-not-connectedTechnical details
3633PR #3633 — the video-meetings wildcard 404'd 15 routes on 5 other routers3632PR #3632 — journey attribution always read $0 because it joined a dropped column3702PR #3702 — /health names the deployed commit
Week of September 14, 2026
Sep 14 – Sep 20 · 32 updates
Mostly Data & analytics, Platform, Mobile
- Ask Pact now shows where every part of an answer came from
- Passkeys work on a phone, and no sign-in control is ever inert
- Ten module homes, and all of them work on a phone
- A number we could not read no longer renders as zero
- Hey Pact stopped reciting, stopped interrupting, and started saying what it is doing
- Five reads that could cross a workspace boundary were found and closed
- Hey Pact hears the name you say, not the one your CRM stores
- Pact says what it is before it asks a stranger a legal question
- More of Pact can be asked for out loud — and the ones that cannot say why
- On a phone, Pact never covers its own content
- A call record now says which of three empty things happened
- Consent, DSAR and the audit log say true things about themselves
- Pipeline, forecast and health all read the same table now
- Sample data has a history now — and it still deletes completely
- Asking for a workspace now tells someone, and tells you
- One dead webhook no longer stalls everything behind it
- Hey Pact's audio plays in order, and a price is not cut at the decimal point
- A call that is interrupted says so, on the record and to the caller
- The marketing site fits a 320px phone, and its navigation goes where it says
- Radar says why a finding is first — and never says "all caught up" when a check died
- Objectives and key results you can actually work from
- What Pact costs to run is visible, including the parts that cannot be measured yet
- Six invented numbers removed from Pact Data, and the vault page describes what exists
- Health scores are no longer computed for accounts that belong to no workspace
- Health and churn carry their age, so a stale score cannot read as current
- Marketing activity now reaches the account: the lifecycle's nurtured stage fills with a real count
- A notification names who did what, and where to go
- The DPO console no longer reports a clean audit log when the read failed
- The cross-module table no longer cuts off on the right, at any window narrower than 1920
- Three sales pages said “nothing here yet” when the read failed, and one listed the wrong records
- The collapsed sidebar can be searched, and the phone's rail gets a filter
- The consent overview stated a lower bar than the send gate enforces, and its switches saved nothing
- NewAIData & analytics
Ask Pact now shows where every part of an answer came from
Every element of an answer carries a provenance tier — measured, derived, estimated, or a labelled gap — so you can see which half of a sentence to trust.
What changed
An assistant that answers in one confident voice makes you trust the weakest sentence as much as the strongest. Ask Pact no longer does that.
Every element of an answer now carries a provenance tier. A number read straight out of your workspace is marked as measured. A number computed from those is marked as derived. A model's judgement is marked as such. And when a piece of the answer could not be obtained at all, that is its own tier — a labelled gap that names what failed, rather than a zero, a blank, or a plausible-sounding sentence covering the hole.
The answer also arrives differently. It decomposes first: you see the question broken into the parts it will answer, then each part fills in, with live progress and an honest estimate of what is left. The spinner that used to run forever when a step died now resolves into the gap that killed it.
Asking about something your workspace has no row for used to produce a confident answer about nothing. Now the premise is corrected first — "there is no account by that name; here are the three closest" — and then the question is answered against what does exist. Pivots to the adjacent question sit one tap away.
The same ladder is spoken. Ask over the phone on 1-424-PACT-MCP or through Hey Pact and you get the reading first, the gap as an answer rather than as silence, and consent enforced fail-closed on every path.
Underneath it is a catalog, a planner and an executor over a measured cube — exercised against a 151-question breadth corpus with zero refusals.
Try it
Open Ask Pact (/ai/ask-pact) and ask something that spans two sources — "how did pipeline move this quarter, and which reps drove it?" Watch the answer decompose, then look at the tier chip on each element. Then ask about an account that does not exist and watch it correct the premise instead of inventing one.
#2026-09-15-ask-pact-shows-its-workTechnical details
3355PR #3355 — provenance tiers on every element + decomposition-first stream3343PR #3343 — the panel parses the stream, renders the tiers, stops the endless spinner3357PR #3357 — no wrong questions: pivots, labelled gaps, premise correction, routing3388PR #3388 — confidence, live progress and honest estimates while the answer assembles3406PR #3406 — the ladder speaks: 1-424-PACT-MCP and Hey Pact, consent fail-closed3426PR #3426 — the Hey Pact thread renders the ladder; pivots one tap away3423PR #3423 — catalog, planner, executor and a 151-question breadth corpus, refused 03477PR #3477 — a question about a record with no row corrects the premise, then answers3469PR #3469 — a fuzzy fallback no longer takes the whole answer down with it3472PR #3472 — the deals context query used the old opportunities column names3376PR #3376 — the hand-off card pointed at two routes that do not exist
- FixedSecuritySecurity & trustMobile
Passkeys work on a phone, and no sign-in control is ever inert
Every passkey ceremony now completes or says exactly what happened — including the cross-device scan, which had lost the transport hints that make it appear at all.
What changed
Passkeys were the sign-in path most likely to leave you stuck with a button that did nothing.
Three separate faults are fixed. Cross-device sign-in — scan the QR code with your phone to sign in on a laptop — had lost its transport hints and its ceremony timeout, so the browser often never offered the option. A credential identifier longer than 32 characters hit a column that could not hold it, and every passkey login turned into a 500 because the failure was caught by code whose own docstring promised it was harmless, leaving the transaction aborted for whatever ran next.
The third is the rule rather than the bug: no control in the sign-in flow is inert now. Every ceremony either completes or tells you exactly what happened — cancelled, timed out, no credential on this device, wrong domain — instead of failing silently and leaving you to guess which.
Issuing a login challenge is a state change, so it writes an audit row. It did not before, which meant the most security-relevant moment in the product was the one with no record of it.
Separately, sign-in stopped sharing its connection pool with everything else. The isolated pool exists so that a busy workspace can never make sign-in slow; collaboration and the two live-update transports were sitting in it and have been moved out. SAML assertion replay protection now survives across processes, so a replayed assertion is rejected by any server that sees it, not only by the one that saw the original.
Try it
Sign out, then sign in with a passkey from a device that is not the one holding it — pick Use a phone or tablet and scan the code. Then try cancelling mid-ceremony: you should get a specific message, not a button that quietly stops working.
#2026-09-15-passkeys-on-a-phoneTechnical details
3418PR #3418 — passkeys on a phone; every ceremony completes or says what happened3415PR #3415 — restore transports and the ceremony timeout for cross-device3452PR #3452 — a 32-char column must not turn every passkey login into a 5003456PR #3456 — a login challenge is a state change, so it writes an audit row3397PR #3397 — the isolated auth pool is for sign-in only3353PR #3353 — SAML assertion replay protection survives more than one process
- NewImprovedExperienceMobile
Ten module homes, and all of them work on a phone
Each module now opens on a Today page built from its own lifecycle, and eight of them rendered nothing at all at phone width until this week.
What changed
Every module — Sales, SE, Analytics, Data, Consent and the rest — now opens on a Today page assembled from that module's own declared lifecycle, rather than from a layout copied between them.
The lane was proven on one module first and nine more now declare their own, which is the part that matters for what comes next: a module gets its home by describing its lifecycle, not by someone hand-building another page.
The phone half was a genuine defect, not a polish item. Eight module homes rendered nothing at 390px — the lifecycle lane was a desktop grid with no mobile expression, so the page loaded, occupied the viewport, and showed no content. Both widths are now designed deliberately: at desktop the lane is scanned across, at phone width it is read down, and what earns a row differs between them because the reading differs.
A Home card that is empty and a Home card that could not load are no longer the same picture — the second one now says which read failed.
The Sales module home also stopped inventing a pipeline. It previously rendered plausible-looking rows whenever the API returned anything short of a server error, which included a permission refusal — so a workspace without the module could see a convincing pipeline that was not theirs. It now performs the cross-module read it was always missing, and renders a labelled gap when that read fails.
Try it
On a phone, open /sales/today and scroll the lifecycle lane — then compare the same page on a laptop. Both should be full; before this week the phone view was empty.
#2026-09-15-module-homes-on-a-phoneTechnical details
3528PR #3528 — eight module homes rendered nothing on a phone; the 390 half of the lane3524PR #3524 — the lane was proven on one module, nine more declare their own3517PR #3517 — an empty Home card and a Home card that could not look, distinguished3492PR #3492 — the sales module home stops inventing a pipeline3529PR #3529 (9a3fcae7) — two module homes stop printing numbers nobody read, and the grid stops leaving a hole
- FixedData & analyticsPlatform
A number we could not read no longer renders as zero
Dashboards, cost lines and KPI tiles that fail a read now say which read failed, instead of showing a confident 0 that looks like an answer.
What changed
A zero is an answer. "I could not read this" is a different answer. For a long time Pact rendered the second as the first, across a lot of surfaces at once.
The general fix is a contract: a metric whose read failed renders as a labelled gap naming what failed — never as a number, never as an empty row that looks like "you have none of these".
Where it bit hardest: one broken widget was aborting the transaction it shared with five others, so a single failure made the whole dashboard invent reasons. A swallowed query was reporting 0 open deals against 350. The tenant AI spend line was reading a column that does not exist and showing the result as
$0. Cost dimensions with no ledger behind them were rendering as though they had measured zero.KPI tiles got the same treatment from the other direction: a tile with no honest history now says so, and a flat line drawn from a single point is no longer presented as a trend.
Metrics now declare themselves — what they measure, from where — so that when one of them does report zero, the zero can be trusted. There is a health surface that will not print a number it did not measure.
Lists learned the same manners. A result that was silently cut off now carries a visible banner saying it was cut off, and the entity picker says what its eight rows are eight *of*.
Try it
Open /dashboard and look at any tile that has no data. It should name the reason — no history yet, or a read that failed — rather than showing a bare 0. The same is true of the cost lines under /admin/costs.
#2026-09-15-a-number-that-failed-is-not-a-zeroTechnical details
3372PR #3372 — a metric that failed must not render as zero3506PR #3506 — one broken widget aborted the shared transaction; the other five invented a reason3295PR #3295 — a swallowed query was returning 0 open deals against 3503462PR #3462 — tenant AI spend was reading a column that does not exist3461PR #3461 — a cost dimension that cannot measure must not render as one measuring zero3374PR #3374 — a widget says which empty it is3375PR #3375 — a KPI tile with no honest history says so; a flat line is not a trend3507PR #3507 — a metric that declares itself, so its zero can be trusted3509PR #3509 — a metric health surface that never prints a zero it did not measure3354PR #3354 — silent truncation becomes a visible banner3440PR #3440 — the entity picker searches the server and says what the eight rows are eight of
- ImprovedVoice & calls
Hey Pact stopped reciting, stopped interrupting, and started saying what it is doing
Options are asked as a question rather than counted off, a long answer says what it is working on instead of going quiet, and a briefing starts speaking while it is still being composed.
What changed
Twenty-five separate repairs, all of them about the same thing: what it is like to be on the other end of the call.
Menus are questions now, not recitations. "First, X. Second, Y. Third, Z" was interrupted by the caller in roughly three quarters of the cases where it was used; "X, Y, or Z?" almost never is. Four renderers were still counting options off and have been converted.
Silence has been removed from the long path. "Got it —" followed by twelve seconds of nothing was the worst version. Pact now says what it is doing rather than that it is still doing it, at every cue, and a briefing starts speaking while it is still being composed instead of after. A question with a constant answer — "top deals" — no longer pays a model to work it out.
Repeating yourself gets a different reply. Saying it again used to get the same sentence back, word for word.
A declined request says which condition declined it. A briefing that will not run names the reason rather than failing into a generic apology, and a request Pact cannot complete no longer promises a callback that was never going to be sent.
An offer Pact makes, it can accept. Several replies ended with an offer that nothing downstream could act on; where two offers appeared in one reply, the answer bound to the wrong one. The layer that makes an offer now records what it offered, and the deal list closes on a question that actually narrows — and can then answer it.
A confirmation left pending no longer swallows the rest of the call.
Try it
Start a Hey Pact call and ask "what should I do today?" — you should hear it working, out loud, rather than nothing. Then ask for something with several matches and answer with the option rather than a number; the menu should have asked you a question, not counted at you.
#2026-09-15-hey-pact-holds-a-conversationTechnical details
2947PR #2947 — a menu is a question: "X, Y, or Z?" not "First, X. Second, Y."2967PR #2967 — three more renderers were still counting options off2795PR #2795 — the regexes are a correction list; compose it3012PR #3012 — when he says it again, stop saying the same thing back2966PR #2966 — she says "Got it —" and then goes silent for twelve seconds2970PR #2970 — make the call state legible; the one it never showed was "working"3025PR #3025 — say what she is doing, instead of that she is still doing it3064PR #3064 — say what she is doing at every cue, and answer "anything hot"3010PR #3010 — speak the briefing while composing it, not after3018PR #3018 — "top deals" is a constant; stop paying a model to say so3020PR #3020 — a briefing that declines now says which condition fired2983PR #2983 — a feature that only logs its own failure reads as broken forever2993PR #2993 — stop promising a callback that was never sent3192PR #3192 — a pending confirmation no longer swallows the rest of the call3233PR #3233 — the deal list closes on a question that narrows, and can answer it3265PR #3265 — every offer Pact makes, it can accept3247PR #3247 — two offers in one reply bound to the wrong one; scope the kind3211PR #3211 — the layer that makes an offer now records what it offered
- SecuritySecurity & trustPlatform
Five reads that could cross a workspace boundary were found and closed
Five cross-workspace reads closed, an unauthenticated cross-workspace endpoint deleted, and isolation policies now cover every workspace-scoped table — with the switch that makes the database enforce them staged, not yet thrown.
What changed
Pact scopes every query to the workspace that asked, in the application. Five places where that scoping was missing or wrong were found and closed: the accounts list and its count were running without a workspace filter; stage history resolved its company reference across workspaces; an automatic merge could read and overwrite another workspace's row; customer-health had four cross-workspace reads; and pipeline reads were re-bound after the deals migration.
Underneath that, the rule is being moved down into the database itself, so a query that forgets is refused rather than answered. Isolation policies now cover every workspace-scoped table — 783 of 783 — with the workspace identity bound on every transaction rather than on a connection a pooler might hand to someone else, a row with no workspace on it no longer readable by every workspace, and three background jobs that were bypassing the policy on the serving connection routed onto their own.
The switch that makes those policies bind is staged and has not been thrown. It went live once on 14 September and was reverted the same afternoon after it locked every device out for 2 h 20 m; the app therefore still connects as a role the policies do not apply to. We would rather say that than let a policy count be read as a guarantee, and this entry will change on the day it changes.
Separately, an unauthenticated live ticker that could return data across workspaces was deleted rather than fixed. It had no owner and no customer depending on it, and the safest version of that endpoint is the one that does not exist.
Outbound traffic got the same treatment from the other side: SMS, voice, calendar, Slack, webhooks, social posting and CRM write-back now transmit only through the egress guard, so there is one place that decides whether Pact is allowed to talk to the outside world on your behalf.
Try it
Open /admin/audit and filter to today. Sign-in challenges and policy decisions land there now; before this batch the challenge step wrote nothing at all.
#2026-09-15-tenant-isolation-in-the-databaseTechnical details
3359PR #3359 — database-enforced tenant isolation: role runbook, hooks, RLS on 518 tables3405PR #3405 — measure the enforcement preconditions on production and stage the role switch3468PR #3468 — the tenant GUCs bind on every transaction3481PR #3481 — a row with no tenant must not be a row every tenant can read3498PR #3498 — three cross-tenant jobs were bypassing on the serving connection3352PR #3352 — the accounts list and its count were tenant-less3053PR #3053 — stage_history resolved its company FK across tenants3158PR #3158 — auto-merge could read and overwrite another tenant's row3128PR #3128 — four cross-tenant reads in customer health3438PR #3438 — pipeline reads under ADR-0026 are tenant-bound3291PR #3291 — delete the unauthenticated cross-tenant live ticker3404PR #3404 — SMS, voice and calendar transmit only through the egress guard3412PR #3412 — Slack, webhooks, social and CRM write-back through the egress guard
- FixedVoice & calls
Hey Pact hears the name you say, not the one your CRM stores
Speech recognition is now biased toward how people actually say a name, and thirty phrases a rep uses about their own work stopped being read as company names.
What changed
A perfect transcription can still reach the wrong record, and that was the largest single class of voice failure.
Recognition is now biased toward the name a caller says, rather than the string the CRM stores — "three am" resolving to nothing appeared nine times in the corpus and is now understood as 3M. Being polite was another one: a courteous phrasing wrapped around an account name made the account unreachable.
Thirty ways a rep describes their own work — the vocabulary of the job, not of a customer — were being read as company names and searched for. They are now swept out of account search before it runs. So is the caller's own filler.
Where a name is genuinely ambiguous, the fix was to narrow the ask, not the book: Pact asks a question that distinguishes the candidates instead of quietly picking one or widening the search until something matches. The deal menu was labelling accounts while speaking deal names, which is why it never trimmed correctly.
Try it
On a Hey Pact call, say a company name inside a polite sentence — "could you pull up 3M for me, please?" It should find the account. Before this it searched for the sentence.
#2026-09-15-hey-pact-hears-the-name-you-sayTechnical details
2941PR #2941 — bias the decoder on the name the caller says, not the one the CRM stores3023PR #3023 — "three am" is 3M, nine times in the corpus, and resolved to nothing3090PR #3090 — a perfect transcription reached the wrong company; narrow the ask3217PR #3217 — sweep the caller's own vocabulary out of account search3230PR #3230 — 30 ways a rep describes their own work were read as company names3027PR #3027 — being polite made an account unreachable3174PR #3174 — the deal menu labels accounts but speaks deal names
- FixedSecurityVoice & callsSecurity & trust
Pact says what it is before it asks a stranger a legal question
AI disclosure now rides inside the greeting in Pact's own register, on every call it places — and a caller ID is treated as a hint, never as an identity.
What changed
Two things a voice product must never get wrong: who it is, and who it is talking to.
Disclosure. Pact identifies itself as an AI assistant before it asks anyone a question with legal weight. That was compliant before this batch and sounded like a warranty notice, because the disclaimer was prepended as a separate sentence — "Hi, this is Pact, an AI assistant. Hey Dean, what's up?", two introductions where one is a disclaimer. The clause now rides inside the identification each greeting already made, in Pact's own register, and it is present on every call Pact places, not only on the authenticated ones.
Identity. A recognized caller ID is a hint, not a credential. Pact now steps up to a real check exactly where the caller ID is not enough, rather than trusting it everywhere or challenging everyone.
Writes. A command that was misheard must not execute a write. Confirmation is now by consequence — Pact repeats what it is about to change, not the words it thinks it heard.
Register. On a call Pact was on, it may not describe itself as a person. That had to be enforced rather than requested.
An unknown caller also gets a better first impression rather than a deliberately equal one: the greeting no longer offers two words that reached nothing, and no longer asks for a term that nothing on the other side handles. If you need one, "get me a human" now reaches an escalation hotline — which is off until a workspace configures a number, so it says so rather than pretending to transfer.
Try it
Have Pact place a call to yourself from /calls/dialer and listen to the first sentence — the AI disclosure should be part of how it introduces itself, not a separate notice bolted in front. Then say "get me a human".
#2026-09-15-voice-says-what-it-is-before-it-asksTechnical details
3219PR #3219 — say it in her own register, and on every call Pact places2995PR #2995 — Pact says what it is before it asks a stranger a legal question3066PR #3066 — caller ID is not an identity; step up only where it is not enough3182PR #3182 — a write must not execute on a misheard command3228PR #3228 — a call Pact was on may not describe Pact as a person2988PR #2988 — the unknown caller gets the better first impression2976PR #2976 — the unknown caller's first impression asked for a word nothing handles3052PR #3052 — "get me a human" reaches a human: an escalation hotline, off by default
- NewVoice & callsAI
More of Pact can be asked for out loud — and the ones that cannot say why
Voice eligibility is derived from what a tool is rather than kept as a list, and a tool you can say but cannot run no longer looks identical to one that does not exist.
What changed
What Pact can do out loud is no longer maintained as a list somebody has to remember to update.
Two failure shapes were behind most of the "it just didn't understand me" reports. The first: a tool you can say and cannot run is worse than one you cannot say, because the failure looks exactly like not being understood. Those are now either bound properly or declined with a spoken reason. Binding them also surfaced a mis-mapping that had been shipped and was invisible while the tool was unreachable.
The second: the feature flags that gate voice capabilities could not be read from the table they lived in, so they evaluated against a default rather than against the workspace's actual configuration. They are evaluated now.
Discoverability is on for everyone, honestly — the capability menu used to take 42 seconds to speak, which is the right taxonomy delivered the wrong way. It is now a short menu that leads somewhere, and the number of things you can actually say and have happen went up rather than the number of things it claims.
Follow-ups work across turns: ask Pact to make a battle card and then say "read it to me", and it finds the one it just made. Asking about risk gets a risk answer rather than an account search.
Try it
On a Hey Pact call, ask "what can you do?" — the menu should be short and lead somewhere. Then make a battle card and immediately say "read it to me".
#2026-09-15-more-of-pact-is-sayableTechnical details
2943PR #2943 — the flag table cannot be read, so evaluate it instead2964PR #2964 — a tool you can say and cannot run is worse than one you cannot say2991PR #2991 — bind two, decline two with reasons; the binding found a mis-mapping3194PR #3194 — discoverability on for everyone, honestly: 14 sayable becomes 163183PR #3183 — the capability menu was 42 seconds: right taxonomy, wrong delivery3236PR #3236 — she made the battlecard, so "read it to me" now finds it3204PR #3204 — "tell me about my risks" was answered with an account search3008PR #3008 — the greeting offered two words that reached nothing2954PR #2954 — the grade could not see a turn the caller heard nothing back from2909PR #2909 — the inbox publishes a typed pickable list
- FixedMobileExperience
On a phone, Pact never covers its own content
One floating affordance and one notice at a time, chrome held to a budget, and a tap on a deal card is a tap at any duration.
What changed
Four separate things were competing for the bottom of a phone screen, and the content lost.
There is now one floating affordance and one notice at phone width, with everything else moved into the flow. Chrome — bars, headers, banners — had grown to about 40% of the screen on the dashboard; it now has a budget, and the budget is enforced rather than reviewed.
The deal board had a touch bug worth naming on its own: a tap was only registered if it was short enough, so a deliberate press read as nothing, and a drag also fired as a swipe. A tap is a tap at any duration now, and a drag is only a drag.
Try it
On a phone, open /pipeline and press and hold a deal card for a full second before lifting. It should open the deal. Then scroll the board and count how much of the screen is chrome.
#2026-09-15-phone-app-never-covers-its-own-contentTechnical details
3442PR #3442 — at phone width the app never covers its own content3511PR #3511 — on a phone, chrome was 40% of the screen; give it a budget and gate it3491PR #3491 — a tap on a deal card is a tap at any duration, and a drag is not also a swipe
- NewImprovedVoice & callsData & analytics
A call record now says which of three empty things happened
The post-call pipeline runs, and when a panel is empty it distinguishes never ran, ran and found nothing, and failed — instead of showing the same blank for all three.
What changed
Open a call and four panels used to be blank. All four blanks meant "we found nothing", and none of them were true — the extraction had never run at all.
The post-call pipeline now runs as a pipeline, with a stage ledger, and every empty state on the call record says which empty it is: not started, ran and found nothing, or failed with the reason. Those are three different answers and they were rendering as one.
Two rendering faults went with it. A stored recap containing a placeholder was being displayed as six single-character bullets. The insights card opened on whichever tab came first, which was frequently an empty one, and its chips wrapped onto a second row that pushed the content out of view — it now opens on a tab that has something in it.
Exports keep their promise: the call export contains what its own description says it contains, and the timeline's total is a total rather than the count of the page you are looking at.
Try it
Open /calls, pick any call, and look at the panels that have nothing in them — each should name its own reason. Then export the call and check the export against the description above the button.
#2026-09-15-calls-that-explain-themselvesTechnical details
3304PR #3304 — build the post-call pipeline, and make every empty state say which empty it is3305PR #3305 — an empty call-detail panel now says which of three things happened3309PR #3309 — a stored recap rendered "<item>" as six single-character bullets3315PR #3315 — keep the call AI-insights chips on one row3317PR #3317 — open the call insights card on a tab that has something in it3348PR #3348 — the export exports what it promises, and the timeline's total is a total
- FixedSecuritySecurity & trustData & analytics
Consent, DSAR and the audit log say true things about themselves
A data-subject request fulfilled early was shown as 107 days overdue, the read-only consent preview queried the wrong subject type, and the export path had never completed once.
What changed
The compliance surfaces are the ones where a wrong number is not a cosmetic problem, and several of them were confidently wrong.
The DSAR clock. A request that had been fulfilled 21 days early was displayed as *"Overdue by 107 days"*. The service-level calculation ran against the wrong pair of dates.
The consent preview. The read-only preview looked its subject up by the wrong subject type, so it reported nothing for people who had a full consent history.
The export. A data-subject export could never have completed — six separate bugs, found by the simple expedient of running it rather than reading it.
The audit log. Ninety-six rows claimed a digest had been sent when none ever was. Audit rows are not editable by design; these were corrected through a recorded migration, with the correction itself in the record.
The proof-of-capture text that sits under a consent record was on the wire and never rendered, so the evidence existed and no one could see it. The insight tabs on the same card were left in a state where no panel was active — a 143-pixel empty shell sitting on top of the data it was supposed to show.
Try it
Open /dsar and check a request that was completed before its deadline — the status should say so. Then open /consent, pick a contact, and look for the proof-of-capture line under the record.
#2026-09-15-consent-and-dsar-surfaces-read-trueTechnical details
3323PR #3323 — consent ledger, DSAR SLA, proof of capture3327PR #3327 — live-tail bouncing, duplicates, coaching headline, phone approval3351PR #3351 — the read-only preview looked up the wrong subject type3097PR #3097 — the export could never have run: six bugs, found by running it3061PR #3061 — correct 96 rows that claimed a digest was sent when none ever was
- FixedSales & CRMData & analytics
Pipeline, forecast and health all read the same table now
Opportunities and deals were two tables telling two stories; everything that reports on pipeline has been repointed to one, with the value checked on both sides.
What changed
Pact had opportunities and it had deals, and different parts of the product read different ones. The forecast read two tables, not one. Customer health read the older. Pipeline read the newer. The numbers disagreed, quietly, for anyone who compared two screens.
Deals is the target, the decision is recorded, and the readers have been moved across a tranche at a time with the value compared on both sides of each move rather than assumed.
Two specific wrong numbers fell out of it. A decorated stage name was hiding a closed deal inside open pipeline. And the forecast bucket named "pipeline" was not the pipeline — it was a different slice with the same label.
The reconciliation that was supposed to prove the two tables agreed was copying zero rows, and the check on it was written so that it could not fail. Both were replaced; the remaining rows without a workspace were assigned where that was provable and refused where it was not, rather than written as null.
Duplicate review is legible at laptop resolution now and shows survivorship — which record won each field, and why. The demo-data purge no longer destroys the source records of a merge.
Try it
Open /pipeline and then /sales/forecast and compare the open-pipeline totals. They should agree; before this batch they were reading different tables.
#2026-09-15-pipeline-reads-one-tableTechnical details
3051PR #3051 — merge opportunities into deals; ADR-0026 decided, target is deals3130PR #3130 — repoint tranche 2 to deals: 10 readers, value-checked3164PR #3164 — the forecast read two tables, not one3264PR #3264 — the bucket named pipeline is not the pipeline3293PR #3293 — a decorated stage name hid a closed deal in open pipeline3292PR #3292 — replace the opportunities to deals check that cannot fail3299PR #3299 — the reconciliation copied zero rows3334PR #3334 — assign the 10 provable NULL-tenant rows3137PR #3137 — refuse the two accountless opportunities instead of writing NULL3311PR #3311 — duplicate-cluster review legible at 1080p, with survivorship3312PR #3312 — stop the demo-data purge from destroying merged source records
- ImprovedData & analyticsPlatform
Sample data has a history now — and it still deletes completely
Seeded accounts come with contacts, activity and a past that hangs together across eleven more tables, all of it in the same purgeable cohort.
What changed
A sample account used to be a name and a logo. Evaluating anything against it meant imagining the rest.
Seeded data now carries a history: eleven more tables joined the purgeable cohort, so a sample account arrives with the contacts, activity and past that make a pipeline view, a forecast or a call record worth looking at.
The constraint that makes this safe is unchanged and was re-proved rather than assumed: purge still takes nothing but the seeded rows. Every seeded row is marked as seeded, the purge selects on that mark alone, and the test asserts that a workspace's real records survive it untouched.
The contact book behind it was repaired at the same time: every demo contact has a reachable address, contacts link to a real company rather than to a name that happened to match, six duplicate accounts were converged, and the tombstones left by an earlier convergence run were cleaned up. Name-based joins are a debt rather than a mechanism now, and the remaining count says which debt it is.
Try it
Open /pact-admin/demo-data, seed a sample workspace, then open one of its accounts — it should have contacts, activity and history, not an empty shell. Purge it afterwards and confirm your own records are untouched.
#2026-09-15-sample-data-has-a-historyTechnical details
3504PR #3504 — sample data gets a history: 11 more tables in the purgeable cohort2802PR #2802 — a clear you can undo, a flag that means one thing, the demo book refilled2921PR #2921 — give all 1,749 demo contacts a reachable address, and name the class2962PR #2962 — give contacts a real company link, and converge six duplicate accounts3007PR #3007 — repair tombstones left by the earlier convergence run3047PR #3047 — 72 to 67 name joins, and the remaining number says which debt it is
- FixedPlatformExperience
Asking for a workspace now tells someone, and tells you
A tenant request notifies the founder loudly, the applicant is told what happened, and the approver can see the request they are approving.
What changed
The signup chain ended in silence in both directions. A request for a workspace notified nobody, and the person who made it heard nothing back.
It notifies now, loudly, and the approver can see what they are approving. The applicant is told — the response that carries the notification was being swallowed, so the email never sent even though everything upstream of it worked.
A newly approved workspace is seeded before its first sign-in, so the first screen has something in it. The fast path had also been skipping the revenue-leader setup entirely, and a seed that failed did so invisibly.
Try it
Request a workspace from the marketing site with an address you can read, then check /pact-admin/internal-ops/tenants/pending — the request should be visible with its details, and the confirmation should arrive.
#2026-09-15-signing-up-tells-someoneTechnical details
3319PR #3319 — a tenant request must notify the founder, loudly3321PR #3321 — return the 202 so the founder email actually sends3324PR #3324 — seed a new tenant, let the applicant be told, let the approver see3168PR #3168 — the fast path missed the CRO, and a failed seed was invisible
- FixedIntegrations & APIPlatform
One dead webhook no longer stalls everything behind it
A single unreachable endpoint was holding up every background tick; sequence delivery no longer claims a send before it happens, and the email digest counts its own failures.
What changed
Background work was running behind a single point of failure that nobody had noticed, because the symptom was slowness rather than an error.
One dead webhook endpoint was stalling every background tick. A subscriber that stopped answering held the queue for everything else. It no longer does.
Sequence delivery stopped lying about itself. The drain was marking a message as delivered before it had been sent, so a send that failed afterwards still read as delivered.
Background work has one leader. Scheduled jobs elect a leader at the seam the scheduler already named, rather than relying on there being exactly one worker.
The email digest counts its own failures. It now tracks a run of failed deliveries and records what would unblock them, instead of failing weekly in a way that looked identical to having nothing to send.
Try it
Open /settings/webhooks, point one endpoint at a URL that does not answer, and watch the others keep delivering. The failing one should report its own state rather than silently holding the queue.
#2026-09-15-delivery-that-does-not-stallTechnical details
3344PR #3344 — one dead endpoint no longer stalls every background tick3422PR #3422 — the drain claims a delivery before it sends it3427PR #3427 — leader election at the seam the scheduler named3092PR #3092 — count the run of failed deliveries, and record what unblocks them
- FixedPerformanceVoice & calls
Hey Pact's audio plays in order, and a price is not cut at the decimal point
Speech ordering is now enforced rather than incidental, a clause boundary on a digit is treated as provisional, and hold music sounds like a company rather than a horror film.
What changed
Spoken output had two distinct ways of coming out wrong, and one of them was self-inflicted.
Ordering is enforced now. Playback order used to be a property of how the pieces happened to arrive rather than of anything guaranteeing it, and an attempt to improve throughput made it worse — a sentence would play two words, jump to the end, and come back to the middle. That attempt was reverted the same day, and the speech channel is now serialized by construction: each piece is scheduled at a time that can only advance, so two pieces cannot swap.
A clause boundary on a digit is provisional. Pact was ending a phrase at the decimal point, so "$310.1M" was spoken as "$310" and then a fragment. Numbers are now held until it is clear the number has ended.
Hold music no longer sounds haunted. The default is a warm, telephony-safe synth that survives the codec, replacing something that a caller on hold experienced as unsettling rather than neutral.
Try it
Ask Hey Pact for a number with a decimal — "what is total open pipeline?" — and listen to whether the figure is spoken whole. Then ask for a long summary and listen through to the end for anything out of sequence.
#2026-09-15-hey-pact-audio-plays-in-orderTechnical details
3084PR #3084 — serialize the speech channel; ordering was incidental, now enforced2893PR #2893 — a clause boundary on a digit is provisional; "$310.1M" was cut at the decimal2632PR #2632 — warm, telephony-safe hold music: free synth default + de-spooked prompts
- FixedVoice & callsPlatform
A call that is interrupted says so, on the record and to the caller
A deploy used to hang up on a live call with no explanation and no trace; now the caller is told and the call record says what happened.
What changed
A deploy landing in the middle of a live call used to end it. From the caller's side that is indistinguishable from Pact hanging up on them, and from ours it left nothing behind to find.
The caller is told now, in the call, rather than being dropped into silence. And the call record carries the reason — a deploy-dropped call says so on the record, not only in a log file nobody reads after the fact.
Underneath, each relay connection has exactly one writer. Six senders were sharing a socket with no lock between them, which is the kind of thing that works until it does not. The single-utterance failure class — a call where the caller says one thing and never hears back — was hunted down to a second inbound connection and a counter that was being incremented into nothing.
Try it
Open /calls and look at any call that ended unexpectedly. The record should name the reason it ended rather than simply stopping.
#2026-09-15-a-call-survives-a-deployTechnical details
3103PR #3103 — a deploy hung up on a live call; tell the caller instead3170PR #3170 — a deploy-dropped call now says so on the record, not just in a log3109PR #3109 — one writer per relay socket: six senders, zero locks3099PR #3099 — hunt the one-utterance class: a second inbound call, a counter with no sink
- FixedMarketingMobile
The marketing site fits a 320px phone, and its navigation goes where it says
The hero call to action clears the fold on the smallest phone still in use, the mobile navigation's primary item scrolls to a section that exists, and display type has a chosen line height.
What changed
The public site was measured on a 320×568 viewport — the smallest phone still in meaningful use — and it did not fit.
The hero's primary call to action sat below the fold by a margin that took several attempts to close honestly: the first two moved it with margins, which a centered grid absorbs, and only the third — padding rather than margins — actually moved it. It clears the fold outright now, and the fold got 36px back on top of that.
The mobile navigation's primary item scrolled to a section that was hidden, so the most prominent control on a phone did nothing.
Display type had no chosen line height on any route. It was inheriting whatever the cascade produced, which is why large headings touched each other at some widths and not others. Three components carried it, not one.
Two smaller honesty repairs went with it: no named reference on the site points at something that does not exist, no bracket is left unfilled, and the outcome statistics on the role pages are sized like the claims they are rather than like measured results.
Try it
Open pact.place on a phone — or a 320px-wide browser window — and check that the primary button is visible without scrolling. Then use the first item in the mobile navigation.
#2026-09-15-the-homepage-fits-a-small-phoneTechnical details
3035PR #3035 — the mobile nav's primary item scrolled to a hidden section3068PR #3068 — close the last 22px so the hero CTA clears a 320x568 fold3074PR #3074 — the last 6px: hero CTA clears the 320x568 fold outright3078PR #3078 — move the CTA with padding, not margins3267PR #3267 — give the mobile fold back 36px, and stop the hero lines touching3281PR #3281 — display type had no chosen line-height on any route3288PR #3288 — finish the display-leading pass: 3 components, not 13062PR #3062 — the skip link stops painting over the What's New bar; the hero fits 320px3386PR #3386 — no named reference that does not exist, and no unfilled bracket3399PR #3399 — role-page outcome stats are sized like what they are
- NewAISales & CRM
Radar says why a finding is first — and never says "all caught up" when a check died
Each suggestion carries the reason it ranked where it did, and a detector that could not run is reported as a detector that could not run.
What changed
Radar ranks what deserves your attention. Two things were missing from that: why, and what it could not see.
Every finding now carries the reason it is first — the signal that put it there, not merely a score. A ranking you cannot interrogate is a ranking you have to take on faith, and the first time it is wrong you stop using it.
The second is the more serious one. When a detector failed to run, Radar reported "all caught up" — the same message it shows when it ran everything and found nothing. Those are opposite states. A detector that could not run now says so, by name, and the health of the checks themselves is visible next to their output.
Try it
Open /radar and look at the top finding — it should tell you why it ranked first. Then check the detector health panel: any check that could not run is named there rather than folded into a clean bill of health.
#2026-09-15-radar-says-why-a-finding-is-firstTechnical details
3459PR #3459 (754bafdd) — a detector that could not run must never read as "all caught up"
- NewSales & CRMPlatform
Objectives and key results you can actually work from
Objectives, key results, workstreams and tasks can be created, measured and worked from the same page, rather than living in a spreadsheet next to the CRM.
What changed
Planning has been the thing that happens in a spreadsheet beside the CRM, and then stops matching it within a fortnight.
Objectives, key results, workstreams and tasks are now first-class: they can be created, measured and worked from the page itself. A key result reads its own measure rather than waiting for someone to type the current number in, and the work that moves it hangs off it directly.
The point is not the artifact. It is that the plan and the pipeline are the same data, so the plan cannot quietly go stale while the numbers move.
Try it
Open /plan/okrs, create an objective with one key result, and attach a workstream to it. The key result should show its own current measure without anyone updating it by hand.
#2026-09-15-okrs-you-can-work-fromTechnical details
2727PR #2727 — OKRs can be created, measured, and worked from the page
- NewPlatformData & analytics
What Pact costs to run is visible, including the parts that cannot be measured yet
Scale economics, which spending caps can actually bind, and an explicit list of the blind spots — with metrics that were being collected and never written now wired up.
What changed
A cost surface that shows a number for everything is more dangerous than one that admits a gap, because you plan against it.
The cost-to-serve view now carries three things: the scale economics — what a workspace costs as it grows — the bindability of each spending cap, meaning whether the cap can actually stop the spend it names, and an explicit blind-spot list of the dimensions that have no ledger behind them and therefore cannot be measured at all.
The dimensions that cannot measure render as such rather than as a confident zero, which was the previous behavior and the reason a cap could look enforced while enforcing nothing.
Underneath, a set of metrics that the code appeared to collect were never actually written anywhere. Those are wired up, and the code paths that had never once executed were deleted rather than left to look like coverage.
Try it
Open /admin/costs and look for a dimension marked as not measured. It should name what is missing rather than showing $0 — and the caps list should say which caps can bind.
#2026-09-15-cost-to-serve-is-visibleTechnical details
3083PR #3083 — scale economics, cap bindability, and the blind-spot list2989PR #2989 — wire the metrics that were never written, delete the code that never ran
- FixedData & analytics
Six invented numbers removed from Pact Data, and the vault page describes what exists
The profiles and vault pages printed the same six figures for every workspace — 14,231 profiles, an 89% match rate, 2.3M records, AES-256 per-tenant keys — including workspaces that had connected nothing. Each is now a read that can decline to answer, with its formula beside it.
What changed
Six numbers on the Data module were string literals in the page source: 14,231 profiles, an 89% match rate and 42 pending merges on the profiles page; 2.3M records across 14 tables, 365-day retention and AES-256 per-tenant encryption on the vault page. They were identical for every workspace, including ones that had connected nothing.
The vault tiles were the worse of the two. A fabricated volume misleads; a fabricated security guarantee is the kind of sentence that gets copied into a customer's security questionnaire. And the page's own description — an append-only raw store for every event and record — described a system that does not exist here. The vault is reverse-ETL and change-data-capture: destinations, signed export manifests, subscriptions with measured lag. Twenty-two endpoints, of which the page exposed none.
Every tile is now a read with its formula shown, and a real zero, a gap and a refused read are three different pictures. The identity graph reports its own health instead of a literal.
Try it
Open /data-app/vault and /data-app/profiles. Every figure carries its formula; a read that could not run says so instead of printing a number.
#2026-09-15-six-invented-numbers-removed-from-pact-data-and-Technical details
b5e0f4ffPR #3554
- FixedSales & CRMSecurity & trust
Health scores are no longer computed for accounts that belong to no workspace
The health refresher picked up every company with no workspace of its own and wrote each one a health snapshot and a churn prediction under every workspace's identity. It now refreshes only the accounts your workspace owns, and the at-risk queue cannot show another workspace's company name.
What changed
The customer-health refresher selected every company that either belonged to the workspace being refreshed or belonged to no workspace at all. That second clause is the wildcard this codebase has closed several times in read paths; this loop wrote. Every workspace with health scoring on picked up the same ownerless company and stored it a health snapshot, a churn prediction and possibly a follow-up task, each stamped with that workspace's id — one company, many workspaces, each claiming it, with the signal context read under a workspace that did not own the account.
The refresh loop now never picks up a company no workspace owns, a failed refresh is logged with its exception class and the tick still completes, and the at-risk queue cannot render another workspace's company name. A test fails if the wildcard is reintroduced anywhere in the package.
Try it
Open /cs-app/at-risk. Every account listed belongs to your workspace; a health score's age is shown beside it (see the next entry).
#2026-09-15-the-health-refresher-stops-writing-snapshots-forTechnical details
4250743dPR #3553
- NewSales & CRM
Health and churn carry their age, so a stale score cannot read as current
Health scores and churn predictions now show how old they are. A score nobody has recomputed in months no longer looks like this morning's, and a stale score never keeps a confident tone.
What changed
The as-of time has been on the lifecycle payload since the dimension was written, and no consumer rendered it. A health snapshot computed in March and one computed this morning arrived on a rep's phone as the identical chip.
The age is now part of the number. Health and churn risk carry an age in whole days and a stale flag computed on the server, with the threshold declared once and named in the payload's own formula so a reader can check it. The chip prints the age when it changes the reading and always in the accessible name; a stale number never keeps a confident warning tone and never loses its value. An unreadable timestamp is reported as unknown age, never as fresh.
Try it
Open /cs-app/accounts and look at the health chip on any account. A score older than the threshold shows its age in days and drops the confident tone.
#2026-09-15-health-and-churn-carry-their-age-so-a-stale-scorTechnical details
975cb2c9PR #3552
- NewMarketingSales & CRM
Marketing activity now reaches the account: the lifecycle's nurtured stage fills with a real count
“Marketing cannot be joined to accounts” was documented as a limitation and was never true. A journey enrollment now resolves to its contact and account through the workspace-salted email hash, so the nurtured rung of the lifecycle lane shows a real number for the first time.
What changed
Contacts already carried both ends of the bridge: a salted hash of the email, indexed, and the company they belong to. A marketing subject reaches an account in two hops with no schema change and no plaintext column. What was missing was not a join but a single place that performs it and says why when it cannot.
One canonical resolver now takes a workspace and a subject — email, phone, contact id or company name — and returns the contact and the account, or a named reason it could not, in the same gap shape the surfaces already read. The answer is materialized on the three marketing ledgers so the read is per page rather than per workspace, with a dry-run by default and a reversal receipt, and it is maintained on the write path.
The lifecycle lane's nurtured rung, which used to be the void, fills with a real count — and still renders the honest hole where the backfill has not been run.
Try it
Open /cs-app/accounts and look at the lifecycle lane: the nurtured rung shows a count drawn from journey enrollments resolved to your accounts, or names why it could not.
#2026-09-15-the-join-everyone-documented-as-impossible-is-onTechnical details
1418487fPR #3547
- FixedExperienceMobile
A notification names who did what, and where to go
A mention used to arrive as “Someone sent you a notification” with no way to find out who or what. The list now carries the actor, a sentence for every kind producers emit, a link to the record, and the destination the producer already attached.
What changed
The mention pipeline was healthy. Three independent layers were each dropping one of the four things a notification owes its reader, and the row that reached a phone was the sum of all three.
Who did it was stored on every row and never selected by the list route, so it read "Someone". What happened had no copy template for 28 of the kinds producers actually emit, so it read "sent you a notification". Which record was routed for ten kinds while producers emit quotes, calls, notes, meetings, workflows and approvals whose pages all exist. Where to go was written by 23 producers into a field no reader ever looked at.
All four now reach the list, on the phone and on the desktop, and the link a notification already carried is the link it opens.
Try it
Mention a teammate in a note. Their bell shows who mentioned them, on which record, and opens that record on tap — on /notifications and in the top-bar bell.
#2026-09-15-a-notification-names-who-what-and-where-and-the-Technical details
51a2641cPR #3545
- FixedSecurity & trust
The DPO console no longer reports a clean audit log when the read failed
Eleven reads on the consent and solutions-engineering day-flow pages swallowed every failure and rendered a zero with reassuring copy: “Audit log clean — quiet day for the audit queue.” Each read now runs in its own savepoint, records its failure, and the page says which read did not run.
What changed
Eleven optional database reads across the consent and solutions-engineering surfaces caught every exception and substituted a zero or an empty list, with no log line anywhere. Both pages render those empties with reassuring copy, so a database the server could not read was answered with "Audit log clean — no high-severity events to review", "Consent rates steady", "Suppression list quiet", "No sends blocked today", and — for the scorecard — advice to run a report that could not have worked.
The consent hero narrated the same fabricated zeros in prose, and in its AI-written variant a model turned them into fluent, confident good news. On the most regulator-facing surface in the product, that is the wrong direction to fail.
Each read now runs inside its own savepoint so one failure is not eleven, records the failure on the result so the page can say which read did not run, and logs at error with the exception class.
Try it
Open /consent-app/today. Every tile that could not be read says so by name; a quiet audit queue is reported only when the audit log was actually read.
#2026-09-15-a-failed-read-told-a-dpo-the-audit-log-was-cleanTechnical details
c477aac5PR #3544
- FixedExperienceMobile
The cross-module table no longer cuts off on the right, at any window narrower than 1920
Inside the module shell the table had 750 px at a 1440 window and wanted 899 — the whole Moved (30d) column sat behind a scrollbar nobody had reason to look for, on nine module homes. Hidden pixels at 1440 went from 149 to 0, and phones get a lane of their own.
What changed
Measured inside the module shell rather than full-bleed, the cross-module table's scroll container had 750 px at a 1440 window and wanted 899 — 149 px, the entire Moved (30d) column, past the right edge behind a scrollbar a reader has no reason to look for. At 1280 it was 256 px. At 768 it was 421 px, and four elements inside the lane's stage columns spilled out of their own boxes. That was nine module homes, not one, because the same composition sits on every non-sales Today page.
The page never scrolls sideways now at any of seven widths from 1920 down to 390. When the table does scroll it says so and keeps the account column fixed, so a row never loses its identity. The phone is its own design: a lifecycle lane built for 390 px rather than the desktop table narrowed.
Try it
Open /cs-app/today at a laptop width. The table fits with no sideways scroll; narrow the window and the account column stays put while the rest scrolls, with a hint that it does.
#2026-09-15-the-cross-module-table-was-cut-off-on-the-right-Technical details
9a779217PR #3533
- FixedSales & CRM
Three sales pages said “nothing here yet” when the read failed, and one listed the wrong records
A page headed My contacts listed the workspace's accounts. A page headed My calls listed everyone's calls. Win/Loss fetched three outcomes and rendered two. And a failed read on any of them rendered as an empty list. Each page's scope now matches the query it sends, and a failure is a failure.
What changed
Three pages in the sales module — contacts, calls and win/loss — told a rep things that were not true. A failed read rendered as "nothing here yet". A page headed My contacts listed the workspace's accounts. A page headed My calls listed everyone's calls. The win/loss page fetched three outcomes and rendered two.
The reason they survived is the more useful finding: the repo already had a lint rule against exactly this, on these very files, and it could not see the shape the code was written in. The rule now catches the React form of the swallow, no failed read on these pages renders as an empty list, each page's scope claim matches the query it sends, and every number traces to a handle or says it is not established.
Try it
Open /sales/contacts and /sales/calls. Each lists exactly what its heading says — your contacts, your calls — and a read that fails says so rather than showing an empty list.
#2026-09-15-three-pages-said-nothing-here-yet-when-the-read-Technical details
5c143874PR #3532
- NewExperienceMobile
The collapsed sidebar can be searched, and the phone's rail gets a filter
With the sidebar collapsed to icons the filter was gone and its keyboard shortcut silently did nothing; on a phone the rail had no filter at all. Both now open a filter that searches the rail you are actually looking at, which under admin is a different rail from the main one.
What changed
A 64 px icon rail cannot hold a text field, and it still does not. What it can do is open one: the filter's own keyboard chord had been silently dead when collapsed, because the input it looked for was never rendered. The command palette is a real page-finder, but the rail is not always the main navigation — under admin it swaps for the admin rail — and "where is the thing in this rail" and "every page in the product" are different questions.
Collapsed, the rail now opens a filter on demand that searches the rail you are looking at. On a phone, where the drawer had no filter at all, the same control is at the top of the drawer.
Try it
Collapse the sidebar and press its filter shortcut, or tap the search icon in the rail. On a phone, open the navigation drawer and use the filter at the top.
#2026-09-15-the-collapsed-rail-can-be-searched-and-the-phoneTechnical details
064db4c2PR #3531
- FixedSecurity & trustData & analytics
The consent overview stated a lower bar than the send gate enforces, and its switches saved nothing
The consent overview listed four jurisdictions of the eight the engine evaluates, described CASL email as opt-in when the gate requires double opt-in, folded expired and unknown consent into pending, and rendered three tracking switches and two export buttons that were wired to nothing. All of it now reads from, and writes to, the real configuration.
What changed
On a compliance surface the direction of a wrong statement matters. The consent overview said CASL email required opt-in; the send gate requires double opt-in, so the page stated a bar lower than the one enforced. It listed four jurisdictions; the engine evaluates eight, and UK GDPR, PIPEDA, LGPD and PIPL were invisible. Its posture tiles folded expired and unknown consent into pending so the cards would sum cleanly — lapsed consent read as not yet asked.
On the tracking tab, three switches including "Honour Global Privacy Control" and a Save button were local state; nothing was stored, while the endpoint that stores it had existed the whole time. Two header buttons, export audit log and import suppression list, had no handler.
The overview now reads its defaults from the same rules the send gate enforces, lists every jurisdiction the engine evaluates, keeps expired and unknown as their own states, and the tracking switches read and write the real cookie-consent configuration. On the Data module's Today page, an identity-graph tile that printed two string literals now reads its own health.
Try it
Open /consent and compare the jurisdictional defaults with a real send: the bar shown is the bar enforced. Flip a switch on the Tracking tab, reload, and it is still flipped.
#2026-09-15-two-surfaces-that-were-telling-the-operator-thinTechnical details
588e29a7PR #3530
Week of August 31, 2026
Aug 31 – Sep 6 · 11 updates
Mostly Voice & calls, AI, Platform
- Ask Pact out loud for far more than it used to answer
- Voice lets you finish your sentence
- Hey Pact cards dock again, and a dismissal can be undone
- Links that led nowhere now lead somewhere
- A buzz in spoken replies, halved
- Play the recording, not just its transcript
- Answers lead with structure, and say so when the answer is no
- The scorecard is spoken as it's written
- On a phone, a tapped deal opens and a held deal drags
- Pages stop getting slower the longer the server runs
- Loading, empty, failed and no-access finally look different
- NewVoice & calls
Ask Pact out loud for far more than it used to answer
Voice used to reach seven named actions. It now reaches fifty-two, chosen by what a tool actually is rather than by a hand-kept list — battle cards among them.
What changed
What voice could do was governed by an allowlist of seven tool names. Anything not on that list was unreachable out loud, however well it worked everywhere else, and adding a capability meant remembering to add its name in a second place. Mostly nobody did.
The allowlist is gone. A tool is now offered by voice when it qualifies on its own properties — it returns quickly enough to hold a conversation, it needs few enough details to ask for out loud, it describes itself well enough to be matched, and it is not a heavyweight generation job. Tools that should never be spoken are excluded by name, with the reason recorded next to the exclusion.
Fifty-two actions are reachable by voice today, counted from the running catalog, up from seven. Generating a competitor battle card is one of them — previously it existed, worked, and simply could not be asked for.
Because eligibility is derived rather than listed, a new tool that qualifies is reachable the day it ships, without anyone remembering a second file.
Try it
Open Hey Pact and say "make me a battle card for Salesforce". Before this it fell through to a generic answer, because the action was not on the list of seven.
#2026-09-06-voice-reaches-the-whole-productTechnical details
2841PR #2841 (630128a) — eligibility policy replaces the 7-name catalog allowlist
- ImprovedVoice & calls
Voice lets you finish your sentence
The agent stopped answering thoughts you had not finished, stopped treating a plain "yes" as a cue to keep talking, and will now let you pick an option it just read out.
What changed
Three separate ways a spoken conversation used to go wrong, all repaired in this batch.
It cut you off mid-word. The endpointer decided you had stopped talking on timing alone, without reading what had been said, so roughly half of all turn-ends landed inside a word. The agent then answered a sentence you were still in the middle of.
"Yes" was not treated as an answer. Asked a direct question, a bare "yes" was read as a filler noise rather than a reply, and the agent asked again.
A menu it read aloud could not be answered. When it offered three candidates, saying which one you wanted did not select it — the options were spoken but not bindable, so the only way through was to start over.
Try it
Start a Hey Pact call, ask something that returns several matches — "open the Acme deal" when more than one Acme exists — and answer with just "the second one". It should pick, not re-ask.
#2026-09-06-voice-lets-you-finishTechnical details
2796PR #2796 (2028991) — the endpointer reads the words, not only the clock2830PR #2830 (21b9481) — a bare "yes" is an answerd7a360cd7a360c — the menu will let you pick the option it just read
- FixedVoice & calls
Hey Pact cards dock again, and a dismissal can be undone
Deal cards stopped docking when deals moved to public IDs, which quietly took "Dismiss all" with them. Both work again, and a dismissal is now recoverable.
What changed
When deals moved to public identifiers, the card surface kept matching on the old one. Deal cards became undockable, and because "Dismiss all" walked the same set, it stopped clearing anything — a button that looked live and did nothing.
Cards dock again and "Dismiss all" clears again. A card that fails to dock for any other reason now says so instead of vanishing, and a dismissal can be brought back rather than being final.
Try it
Ask Hey Pact about a deal, dock the card it returns, then use Dismiss all — the stack should actually clear, and the dismissal should be recoverable.
#2026-09-06-hey-pact-cards-come-backTechnical details
2800PR #2800 (39b266e) — deal cards became undockable, taking "Dismiss all" with them28a9f4028a9f40 — a card that fails to dock stops being invisible; dismissals are recoverable
- FixedMarketing
Links that led nowhere now lead somewhere
Twelve links pointed at hosts that do not exist, a customer-stories anchor never resolved, and the contact-sales form promised a reply nobody would have received.
What changed
A sweep of every internal link and call to action found several that could not work.
Twelve pointed at hostnames that do not resolve. An anchor to the customer-stories section never matched anything on the page, so the link scrolled nowhere. And the contact-sales form accepted a submission and told the visitor to expect a reply, without a path that would deliver one.
All are repaired, and a gate now checks internal anchors and links on every change — the anchor case in particular had never been checked by anything.
Try it
On the marketing site, use the Customer stories link in the navigation — it should scroll to the section instead of doing nothing.
#2026-09-06-links-that-go-somewhereTechnical details
8ca83698ca8369 — twelve dead links, and a sales form that promised a reply nobody receives857ab06857ab06 — #customer-stories never resolved, and no gate had ever checked an anchor
- FixedVoice & calls
A buzz in spoken replies, halved
Spoken answers carried an audible buzz. One of its two causes — a fresh audio device opened for every phrase batch instead of once per answer — is fixed.
What changed
Longer spoken answers carried a repeating artifact, regular enough to sound like a buzz rather than noise. It was a render quantum repeating: playback opened a new audio device for each batch of phrases within a single answer, and every open re-paid a small startup cost that landed inside the audio.
Playback now opens one device per answer. Long replies are noticeably cleaner.
This is one of two causes, and the other is still open. A thin opening buffer is also being paid once per phrase batch rather than once per answer. Until that lands, a residual artifact can remain on some replies — so this entry claims a reduction, not silence.
Try it
Ask Hey Pact something with a long spoken answer — "summarize my pipeline" — and listen through to the end. Compare with a short reply.
#2026-09-06-quieter-voice-playbackTechnical details
2805PR #2805 (10986be) — stop opening an audio device per phrase batch
- NewVoice & calls
Play the recording, not just its transcript
Call recordings now play in the product — a real waveform, a scrubber, and a download — with each row telling you plainly whether it actually has audio behind it.
What changed
A recording row used to be a promise the product could not keep: it showed a
status and a transcript, and there was no way to hear the call.
Now there is a player. It streams the stored audio, draws a waveform you can
scrub, and offers a download. Playback is one authorization decision on the
server, scoped to your tenant, and every read is written to the audit log — so
"who listened to this call" is a question with an answer.
Each row tells the truth about itself. Recordings that carry stored audio
are the ones that offer playback; rows that only ever had a transcript say so
instead of handing you a dead play button. On a workspace seeded with demo
data, most rows are the second kind, and the list now shows that rather than
hiding it.
A separate repair stopped the upload-retention purge from deleting captured
call audio it was never meant to touch.
#2026-09-04-play-the-recordingTechnical details
2740PR #2740 — tenant playback, audio truth per row, audited reads2746PR #2746 — the retention purge can no longer delete captured audio
- ImprovedAI
Answers lead with structure, and say so when the answer is no
Ask Pact something and the numbers arrive as tiles, the records as chips you can open, and the evidence as a row you can check — instead of a paragraph you have to read twice.
What changed
Every surface that answers a question — Hey Pact, search, the scorecard — used
to reply in prose, with the figures buried mid-sentence and the records named
but not linked. Formatting the model emitted was sometimes printed literally,
asterisks and all.
Answers now put structure first:
- Metric tiles for the numbers, so a figure is a figure and not a clause.
- Record chips for anything Pact named, each one a link to the record.
- An evidence row under the answer, so you can see what it was derived from.
- Markup is rendered, not dumped.
A "no" is now an answer with proof. When there is nothing matching what you
asked, Pact says what it looked at and why the result is empty, instead of
returning a blank panel that reads like a failure.
#2026-09-04-answers-show-their-structureTechnical details
2707PR #2707 — structure above prose on every answer surface
- PerformanceVoice & callsAI
The scorecard is spoken as it's written
Asking for a call scorecard out loud no longer means waiting in silence for the whole thing to be composed — it starts speaking as the first sentence exists.
What changed
The spoken scorecard used to be generated in full, then read aloud. The wait
before the first word was the entire composition time, and on a phone that
silence is indistinguishable from a call that has dropped.
It now streams: narration begins as soon as there is a sentence to say and
continues while the rest is written. Two other repairs ride along — a
classifier that was being consulted and then ignored on every request is gone,
and an answer cut short by echo on the line resumes instead of ending there.
#2026-09-04-scorecard-spoken-as-writtenTechnical details
2688PR #2688 — speak the scorecard as it is written, drop the ignored classifier
- FixedMobileSales & CRM
On a phone, a tapped deal opens and a held deal drags
Touching a card on the pipeline board did two things at once. A tap now opens the deal; a press-and-hold picks it up to move it.
What changed
On the mobile pipeline board a touch-and-hold armed two different gestures on
two different timers — a drag at 250ms and a detail sheet at 500ms — so the
same finger movement could open a sheet you did not ask for, or start dragging
a card you meant to read.
The two are now separated by intent: **tap to open the deal, press and hold to
pick it up.** The board header, the floating action button's slot, the record
action rail and the inbox chip filters were straightened out in the same pass.
#2026-09-04-hold-to-drag-tap-to-openTechnical details
2741PR #2741 — a held deal is a drag, a tapped deal is the sheet
- PerformancePlatform
Pages stop getting slower the longer the server runs
A leak that made the web tier steadily slower between deploys is closed, and pages are no longer served uncompressed from the edge.
What changed
Two independent things were making Pact slower than it should have been:
- A leak in the web tier. Every server-rendered request armed a 30-minute
cleanup timer that outlived the request. Under steady traffic those
accumulated for hours, so the site got heavier the longer it went between
deploys. Server rendering now uses a per-request cache that is released with
the request.
- Uncompressed HTML at the edge. A caching rule let the CDN store and serve
the homepage without compression — roughly half a megabyte of HTML where
75 KB would do. Fixed, and verified on production.
#2026-09-04-pages-stop-getting-slowerTechnical details
2724PR #2724 — stop SSR requests arming 30-min GC timers; never cache uncompressed HTML
- FixedPlatform
Loading, empty, failed and no-access finally look different
A surface that failed to load used to render as an empty one. Every data-backed panel in Pact now distinguishes still-loading, genuinely empty, actually broken, and not-yours.
What changed
The worst failure mode in a CRM is a panel that shows nothing and means four
different things. "You have no deals at risk" and "we could not reach the
service that computes deals at risk" looked identical, and the second one is
the one you need to know about.
Every data-backed surface now separates the four states and says which one it
is in — including "you do not have access to this", which previously rendered
as absence too.
#2026-09-04-surfaces-tell-the-truthTechnical details
2706PR #2706 — every data-backed surface tells the truth about its state
Week of August 17, 2026
Aug 17 – Aug 23 · 6 updates
Mostly Voice & calls, Integrations & API, AI
- Calls stop cutting off mid-sentence, and play the voice you picked
- A flaky calendar sync no longer disconnects you for good
- Ask the voice agent to do something — now it does it
- Calls answer at conversational speed — and sound like a person
- The audit log can't be rewritten — and you can watch it live
- Reliability: calls keep their thread, pages stop failing whole
- FixedVoice & calls
Calls stop cutting off mid-sentence, and play the voice you picked
A bookkeeping gap that could truncate the agent's reply when a caller talked over the tail end of it is closed, and the custom voice you choose in Settings now reaches every live call instead of a pinned default.
What changed
Two related repairs to how a call sounds:
- No more mid-phrase cutoffs. On a live call, generated text finishes fast but keeps playing out loud for several seconds after. If a caller talked over that tail, the record of what they'd actually heard was sometimes wrong — occasionally chopping the agent's own reply short. The turn-tracking now arms before the reply starts playing, not after, and covers a cancelled-mid-generation turn the same way as one that already finished.
- Your chosen voice is the one that speaks.
/settings/voicesaved a selection that a lower-level relay setting silently overrode on every inbound call, so the picker looked like it worked but never took effect. It's wired through now — pick a voice, hear that voice.
#2026-08-21-voice-stops-cutting-offTechnical details
2521PR #2521 — record the turn Twilio cut off after we stopped generating2522PR #2522 — stop assuming a cancelled turn was heard in full2523PR #2523 — arm the playback tracker before the persist, not after2519PR #2519 — the voice picker was writing to a column the live call never read
- FixedIntegrations & API
A flaky calendar sync no longer disconnects you for good
One transient sync failure used to drop your calendar and email connection out of rotation permanently, with no notice; a blip now stays a blip.
What changed
Calendar and Gmail ingestion ride the same connection row, and any sync failure — even one caused by a momentary hiccup on Google's side — flipped that row to an error state that the recurring sync job then skipped forever. The only way back was reconnecting by hand, which is why "calendar and email are disconnected again" kept coming back. The sync job now gives a failed connection another chance instead of permanently benching it.
#2026-08-21-calendar-sync-no-longer-a-trapdoorTechnical details
2515PR #2515 — stop a failed sync from permanently disconnecting calendar + email
- NewImprovedVoice & callsAI
Ask the voice agent to do something — now it does it
The phone agent now executes the things callers most often ask for — logging a note, creating a task, moving a deal — instead of describing what it would do. It hands off to a human when it is failing, and voicemails come back with the next action already extracted.
What changed
The voice agent used to be better at narrating work than doing it. This batch closes that gap:
- Actions execute. Ask it to log a note, create a follow-up task, or move a deal's stage and it performs the write — through the same consent check and audit trail as a write made by hand — then confirms what it did, instead of telling you what it would have done.
- A yes means the thing you said yes to. Accept the agent's offer to look at your high-risk deals and it reads the at-risk feed — those deals, not the whole pipeline.
- It knows when to give up. When the agent is failing a caller — repeated misunderstandings, or the app explicitly asks — it hands the call off to a human instead of looping.
- Voicemail comes back with the next action. Each voicemail is analyzed for what the caller actually needs — a callback, a document, a meeting — and high-confidence next actions are extracted and queued rather than left buried in a transcript.
#2026-08-21-voice-agent-does-the-thingTechnical details
2480PR #2480 — execute the top requested actions instead of narrating them2483PR #2483 — count an FSM commit as a real tool call2476PR #2476 — hand off to a human when Pact is failing, or when the app asks2496PR #2496 — a yes to the high-risk-deals offer reads those deals2500PR #2500 — a yes advances, a repeat forks, a risk ask reads the risk feed2423PR #2423 — voicemail next-action extraction + confidence-gated auto-actions
- PerformanceImprovedVoice & calls
Calls answer at conversational speed — and sound like a person
The first words of the agent's reply now start in roughly a quarter of a second instead of over a second and a half, the delivery adapts to what is being said, and markup never leaks into speech.
What changed
Three changes to how a call feels:
- Answers start fast. The slow first-response path — routing before speaking — is now covered by an immediate spoken prefix, so the agent's reply begins in roughly a quarter of a second instead of over a second and a half of dead air.
- Delivery follows content. Bad news slows down, lists get list rhythm, numbers are spoken like a person says numbers — prosody is derived from what is being said rather than one flat voice for everything.
- Words, not markup. Display formatting (symbols, emphasis marks, layout characters) is normalized away at the text-to-speech boundary, so the agent can never read "asterisk asterisk" at you again. Voice selection was also consolidated into one canonical resolver, so every surface speaks with the voice you actually picked.
#2026-08-21-calls-answer-fast-and-sound-humanTechnical details
2467PR #2467 — cover the routing prefix so a call answers in ~250ms, not 1.6s2468PR #2468 — contextual prosody: what is being said colors how it is spoken2494PR #2494 — speak words, not markup: normalize display text at the TTS boundary2474PR #2474 — one canonical TTS resolver across four disagreeing surfaces2485PR #2485 — the voice pick actually reaches synthesis
- NewSecuritySecurity & trustPlatform
The audit log can't be rewritten — and you can watch it live
Audit events now carry full forensic context, immutability is enforced by the database itself rather than by convention, and a live tail view streams events as they happen.
What changed
The audit trail grew three properties a security reviewer will actually ask about:
- Forensic context on every event — who acted, from where, through what — captured at write time, so an investigation doesn't have to reconstruct the request after the fact.
- Immutability the database enforces. Audit rows can no longer be updated or deleted by the application at all — the constraint lives in the database, not in code review.
- A live tail. Watch audit events stream in as they happen from the admin audit view, instead of refreshing a filtered list.
#2026-08-21-audit-log-immutable-and-liveTechnical details
2442PR #2442 — forensic context, DB-enforced immutability, live tail
- FixedVoice & callsSales & CRMIntegrations & API
Reliability: calls keep their thread, pages stop failing whole
A large repair pass from live-call audits: booking understands spoken times and escapes dead ends, deal counts agree across every voice path, one failing card no longer takes down an account page, and integration status reads the same on every surface.
What changed
Most of this window was repair work driven by call-by-call audits of real conversations. The customer-visible fixes:
On calls
- Booking a meeting now understands spoken times ("Tuesday at three"), escapes a slot-fill that keeps failing instead of re-asking forever, and yields when you change the subject mid-flow.
- Deal counts agree across every voice path — one caller, one scope, whether you ask the simple way or the complex way.
- The agent hears *your* company's name correctly instead of rescuing it into a CRM record's name, and no longer overwrites fields with placeholder values.
- A call's final turn survives an immediate hangup, so the last thing you said still lands in the record.
- Inbound calls no longer risk a slow pickup: the heavy contact lookup was moved off the answer path.
In the app
- On an account page, one failing card now costs you that card — not the whole route. Two crash classes on account and health surfaces are fixed.
- Ten contact endpoints that could 500 on PII reads are repaired.
- The onboarding activation card no longer renders an error for a widget the workspace switched off.
Integrations and storage
- Twilio's connection status now reads the same on every surface — the verifier was fixed and the duplicated status rail removed.
- A misconfigured BYOK storage bucket can no longer fail every file write in the workspace; it fails only the tenant that misconfigured it, with a clear error.
#2026-08-21-reliability-roundupTechnical details
2504PR #2504 — booking hears spoken times, escapes failed slot-fills, yields to new intents2497PR #2497 — one caller, one scope: deal counts agree across every voice path2464PR #2464 — rep-scoped scorecard reads the right deal table2486PR #2486 — stop placeholder slot writes, hear the caller's own company2484PR #2484 — entity rescue must not re-fire inside a correctly-heard name2491PR #2491 — a call's final turn survives an immediate hangup2440PR #2440 — inbound webhook 504s: decrypt-scan off the pickup path2437PR #2437 — sub_scores shape no longer takes down account pages2444PR #2444 — one failing card costs the card, not the route2463PR #2463 — contact PII reads through contact_ops: 10 live 500s fixed2451PR #2451 — activation card respects a switched-off widget2449PR #2449 — Twilio status agrees across surfaces; IAM rail deduped2466PR #2466 — a broken BYOK bucket can't 500 every blob write
Week of August 10, 2026
Aug 10 – Aug 16 · 20 updates
Mostly Platform, Experience, Sales & CRM
- Ask gives you sourced answers, not just search results
- A SOC 2 Type II console that an auditor can actually use
- Support triage suggests, and the SLA clock tells the truth
- Deal health scores, per-field enrichment routing, and RFP round-trip
- A visual workflow builder, and five ways to look at a list
- The calls list, the spend dashboard, and alerts that respect quiet hours
- Cards read as surfaces, headers stop clipping, and the timeline has a spine
- Behind the scenes: an email safety gate, guarded routes, and fewer 500s
- A redesigned CRM — records, lists, accounts, and pipeline
- Build, view, export, and schedule your own reports
- Notifications Center 2.0 and a triage Inbox
- A sharper home dashboard
- Find anything with ⌘K — plus faster navigation
- A live activity feed with a full audit trail
- Fixes: meetings, calling, and a cleaner failure path
- In-app calling that just works, call after call
- A guided first day — with one-click sample data
- Bring your whole CRM in — hardened data import
- Faster forms, lists, and navigation
- Sign-in, iOS, and mobile fixes
- NewImprovedAI
Ask gives you sourced answers, not just search results
One Ask panel now answers questions about your CRM data and your docs together. It chains several lookups to reach an answer, cites the records it used, remembers the last few turns so follow-ups work, and asks you which record you meant when a name is ambiguous.
What changed
Ask used to be a search box that handed back a list. It now works through a question:
- Multi-hop retrieval — a question that needs two or three lookups to answer gets them. "Which deals in my pipeline have gone quiet since the last QBR?" reads the pipeline, then the activity, then joins them, instead of pattern-matching the sentence against deal names.
- Real citations — every answer links the records it drew from, so you can click straight through and check the work.
- Session memory — the panel keeps the last few turns, so "what about the ones in EMEA?" resolves against the question you just asked.
- Clickable ambiguity — when a name matches more than one record, Ask asks which one you meant and gives you the choices as buttons rather than guessing.
- An empty result is an answer — if there genuinely is no activity to report, Ask says so and records why each lookup came back empty, instead of showing a failure.
Several sharp edges went with it: the panel no longer matches your whole question against deal names as a single LIKE, no longer returns cards with no content in them, and fits inside a 375px viewport.
Open Ask from the top bar on any page.
#2026-08-15-ask-panel-multi-hop-citationsTechnical details
2230PR #2230 — consolidated Ask panel: CRM data + docs Q&A in one surface2379PR #2379 — multi-hop retrieval, real citations, session memory, clickable ambiguity2382PR #2382 — apply the quality layer before the router's tool choice, not after2383PR #2383 — an empty activity ledger is an answer, not a failure2384PR #2384 — stop LIKE-matching the whole question against deal names2325PR #2325 — "give me deals" no longer returns dead cards with no way to clear them2234PR #2234 — P0: Postgres 500, dead mobile launcher, three wrong-key UI bugs2239PR #2239 — Ask panel content no longer overflows the viewport at 375px
- NewSecurity & trustPlatform
A SOC 2 Type II console that an auditor can actually use
All 61 AICPA Trust Services criteria are catalogued, evidence collects itself for a growing share of them, 17 policies are published and acknowledgeable, and the auditor package exports as a real deliverable — control matrix, remediation plan, and a signed archive.
What changed
Compliance work in Pact was a spreadsheet exercise. It is now a console:
- The full controls catalog — all 61 AICPA Trust Services criteria, with the Common Criteria, Availability, Confidentiality, Processing Integrity, and Privacy series each broken out and tracked separately.
- Evidence that collects itself — a set of automated collectors replaced manual evidence gathering for a growing share of controls. Where a control is still manual or still deficient, the console says so rather than showing a green tick it has not earned.
- A real policy library — 17 auditor-grade policies, published, versioned, and acknowledgeable by staff, with acknowledgement state tracked per person.
- An auditor package that downloads — the export produces a control matrix, a remediation plan, and a signed archive. It previously 403'd with "could not generate package"; that is fixed.
- The sub-processor register is populated with the vendors that actually process data, rather than the handful it previously named.
- An honest vendor register — the attestations Pact does *not* yet hold are tracked as open requests rather than quietly omitted, so the gap is visible to you before it is visible to an auditor.
- Usable on a phone — the console, the gap tracker, and the timeline all work at 375px, so you can clear an acknowledgement away from your desk.
Admins: find it under Admin → SOC 2.
#2026-08-15-soc2-type-ii-consoleTechnical details
2341PR #2341 — auditor-grade SOC 2 Type II console: control matrix, gap tracker, timeline2340PR #2340 — controls catalog: all 61 AICPA Trust Services criteria2344PR #2344 — auditor package as a real deliverable: control matrix, remediation plan, signed archive2337PR #2337 — fix the auditor package download 4032346PR #2346 — five manual evidence gaps become automated collectors2358PR #2358 — automated tests for the 33 Common Criteria2359PR #2359 — Availability / Confidentiality / Processing Integrity collectors and policies2361PR #2361 — Privacy P1–P8: real notice, evidence collectors, honest deficiencies2362PR #2362 — policy library: 17 auditor-grade policies, published + acknowledged2363PR #2363 — make the SOC 2 console operational on mobile2364PR #2364 — populate the sub-processor register2369PR #2369 — vendor register: track the attestations we do not yet hold
- NewImprovedDocs & supportAI
Support triage suggests, and the SLA clock tells the truth
Incoming cases get a consolidated triage card — likely duplicates, the owner who handled similar cases before, and a suggested route you can accept or override. The SLA clock now stops while you are waiting on the customer and honors your holiday calendar, and the submit form deflects answerable questions to the knowledge base first.
What changed
Two changes to how support work gets picked up:
- Consolidated AI triage — a new case arrives with one card that shows likely duplicates, the owner who has handled similar cases before, and a suggested category and route. Every suggestion is accept-or-override; nothing is applied to a case without a person agreeing to it.
- An SLA clock that stops for customer-wait — time spent waiting on a customer reply no longer counts against your response target, so the breach numbers reflect work you could actually have done. The clock also honors your configured holiday calendar.
- SLA reporting by owner and category — breach and attainment now break down by who owned the case and what kind of case it was, instead of a single tenant-wide number.
- Deflection before the ticket exists — the customer-side submit form now suggests relevant knowledge-base articles as someone types their problem, so the answerable questions get answered without becoming a case at all.
The triage card also got meaningfully lighter — dropping a heavy popover dependency cut the route's payload after it had grown 16.2%.
#2026-08-15-support-triage-and-slaTechnical details
2347PR #2347 — S-1 consolidated AI triage: duplicates, owner history, accept/override2349PR #2349 — SLA stops for customer-wait, honors holidays, reports by owner/category2354PR #2354 — drop Radix Popover from the triage card (16.2% route growth)
- NewSales & CRMAI
Deal health scores, per-field enrichment routing, and RFP round-trip
Deals carry a health score with a 30-day drop-risk read and suggested next actions. Enrichment routes each field to the vendor that is best at it, with a hard budget stop. And RFP work now round-trips: export a response, keep the answers as a reusable knowledge base.
What changed
Three revenue surfaces got real depth:
- Deal health — each deal now carries a health score, a 30-day drop-risk read, and suggested next-best actions drawn from what actually moved comparable deals. The score shows its inputs, so you can disagree with it.
- Per-field enrichment routing — instead of one vendor per record, each field routes to the vendor that is strongest for that field, with a waterfall fallback when the first choice has nothing. A hard budget stop halts spend at your cap rather than running past it, and you can trigger a specific vendor from the record itself.
- RFP round-trip for sales engineers — export an RFP response, and the answers you wrote are kept as a searchable answer library with reuse tracking, so the next RFP starts from what you have already said. Architecture diagrams generate from the stack you actually recorded.
#2026-08-15-deal-health-enrichment-rfpTechnical details
2378PR #2378 — deal health score, 30-day drop-risk, AI next-best actions2376PR #2376 — per-field waterfall routing, budget hard stop, record-level vendor action2388PR #2388 — RFP round-trip export, answer KB with reuse, stack-driven architecture
- NewMarketingSales & CRMMobile
A visual workflow builder, and five ways to look at a list
Build automations on a canvas with run history and starter templates. Every list surface gained a view switcher — List, Cards, Board, Calendar, Table — and duplicate management got a review queue with a 30-day undo.
What changed
- Visual workflow builder — /workflows lists your automations, a canvas editor builds them, and each run is recorded so you can see what fired and what it did. Templates cover the common shapes so you are not starting from an empty canvas.
- View switcher across list surfaces — the same records, shown as a List, Cards, a Board, a Calendar, or a Table, switchable per surface and remembered.
- Duplicate management — a cluster review queue groups likely duplicates, merging rewires foreign keys properly rather than orphaning related records, and every merge has a 30-day undo.
- Multi-action swipe trays on mobile — swipe a row in any CRM list for its common actions, or long-press for the full action sheet.
#2026-08-15-workflow-builder-and-list-viewsTechnical details
2241PR #2241 — visual workflow builder: /workflows list, canvas editor, run history, templates2242PR #2242 — view switcher (List/Cards/Board/Calendar/Table) across list surfaces2222PR #2222 — duplicate management: cluster review queue, FK-rewiring merge + 30-day undo2218PR #2218 — multi-action swipe trays + long-press action sheet for CRM lists2232PR #2232 — bulk panel: Assign owner + Merge, 44px targets, scroll clearance
- NewImprovedVoice & callsPlatformExperience
The calls list, the spend dashboard, and alerts that respect quiet hours
/calls gained filters, cross-call transcript search, bulk actions, and analytics, and each call page shows cost, an AI recap, and a waveform. The spend dashboard grew anomaly detection, provider mix, unit economics, and cap simulation. Proactive alerts now honor real quiet hours.
What changed
- A calls list worth opening — filters, search across call transcripts rather than just titles, bulk actions, and analytics over the set you have filtered to.
- A call page with context — per-call cost in the header, an AI recap, a waveform you can scrub, and the playbook the call matched.
- Spend dashboard 2.0 — anomaly detection on unusual spend, provider mix so you can see where the money goes, unit economics per call and per seat, a forecast, and a cap simulation that shows what a proposed cap would have done to last month.
- Proactive alerts — spend, coaching, and missed-call alerts, with quiet hours that are actually enforced rather than advisory.
- Mobile parity — the spend table scrolls properly at 375px instead of clipping its own columns.
#2026-08-15-calls-spend-and-alertsTechnical details
2304PR #2304 — overhaul /calls: filters, cross-call transcript search, bulk actions, analytics2300PR #2300 — overhaul /calls/[id]: cost header, AI recap, waveform, playbook match2295PR #2295 — cost dashboard 2.0: anomalies, provider mix, unit economics, forecast, cap simulation2294PR #2294 — proactive alerts for spend, coaching, missed calls + real quiet hours2303PR #2303 — /admin/budget mobile parity at 375px
- ImprovedFixedExperienceSales & CRM
Cards read as surfaces, headers stop clipping, and the timeline has a spine
Card surfaces gained an edge and a lit top so they stop reading as flat squares. Panel headers no longer clip their own titles. The record timeline groups by day, and the account header stops starving its own title when there are several actions.
What changed
A pass over the surfaces you look at all day:
- Cards read as surfaces — a defined edge and a lit top edge, so a card is distinguishable from the page behind it instead of reading as a flat square.
- Panel headers stop clipping — a sheet header no longer cuts off its own title. "Vonage" was rendering as "/onage".
- The account header keeps its title — when a record has several actions in the header, the actions no longer squeeze the record name down to nothing.
- A day spine on the record timeline — timeline events group under the day they happened, so a busy record reads as a sequence rather than a wall.
- Create and edit forms — consistent spacing, validation, and keyboard behavior across every create/edit form in the product.
- Record detail chrome — underline tabs, tag and territory chips, consistent padding, and clearance so the floating action button stops covering content.
#2026-08-15-interface-polish-and-record-detailTechnical details
2334PR #2334 — card surfaces read as flat squares: give them an edge and a lit top2333PR #2333 — P0: sheet headers clipped by their own panel ("Vonage" → "/onage")2386PR #2386 — the account header starved its own title2391PR #2391 — give the record timeline a day spine2221PR #2221 — global create/edit form polish (U2-FORMS)2233PR #2233 — record-detail chrome: underline tabs, TAGS + Territory, padding, FAB clearance
- SecurityFixedPerformanceSecurity & trustPlatform
Behind the scenes: an email safety gate, guarded routes, and fewer 500s
Every outbound email now passes a single safety gate before it leaves. Fifteen routes gained authorization guards. And a set of 500s — Account 360, the contact dedupe scan, the flag loader — are fixed.
What changed
Work you should not have to notice, but which matters:
- One email safety gate — every outbound email in the product now passes a single decision point before it is sent, and bulk sends go out one gated request per recipient rather than exposing the whole recipient list in a shared header. No email reaches someone who should not receive it because a code path forgot to check.
- Fifteen routes gained authorization guards, seven mutations gained audit records, and an unauthenticated call-diagnostics read was closed.
- One malformed flag row no longer takes down the product — a single bad
metadata_jsonvalue used to return 500 from every flag-gated route in the app. It is now isolated to the flag that is broken. - Fixed 500s — Account 360 on every account page, the contact dedupe scan against the encrypted contacts schema, and the tracking/calls signal reads.
- Faster pages — a repaired bundle-size gate cut nine oversized routes down to one and stopped the baseline drifting, and four N+1 query patterns were batched (coaching lists, spaces collaborators, per-contact tracking events, campaign send polling).
#2026-08-15-security-and-reliabilityTechnical details
2335PR #2335 — email safety gate: no email reaches a stranger by accident2356PR #2356 — close Family 4: every send goes through the safety gate2278PR #2278 — guard 15 routes + audit 7 mutations; close unauthenticated call-diagnostics read2394PR #2394 — one malformed metadata_json row no longer 500s every flag-gated route2281PR #2281 — P0: Account 360 500s on every account page2373PR #2373 — contact dedupe scan 500'd on the encrypted contacts schema2360PR #2360 — bundle gate 9 failures → 1, and stop the baseline going stale
- ImprovedNewSales & CRMExperience
A redesigned CRM — records, lists, accounts, and pipeline
The surfaces you live in every day got rebuilt: Account, Contact, and Deal pages share one clean layout, /contacts and /deals are fast virtualized lists, Accounts is a tiled card grid with filters and presets, and the pipeline board gained WIP limits, days-in-stage, and keyboard control.
What changed
The daily-driver screens are now consistent, dense, and fast:
- One shared record layout — Account, Contact, and Deal detail pages were rebuilt on a single shell: a consistent header, tabbed sections, and a right-hand insight rail. The rail is now bounded, so long records stay a normal page instead of stretching three or four screens tall.
- Virtualized lists — /contacts and /deals render as tiled list views that stay smooth at thousands of rows.
- Accounts as a tiled grid — a card grid with compact / comfortable density modes, a filter rail, and saved view presets so you can jump straight to the slice you work from.
- A sharper pipeline board — the kanban view gained per-column WIP limits, average days-in-stage, spring-loaded drag, grouping, and full keyboard navigation.
Open any account, contact, or deal, or switch to the board on your pipeline, to see it.
#2026-08-11-crm-redesign-records-lists-pipelineTechnical details
2193PR #2193 — redesign Account/Contact/Deal detail pages onto a shared shell2208PR #2208 — bound the record-detail insight rail (stop the 3–4× page + dead gradient)2202PR #2202 — virtualized tiled list views for /contacts and /deals2203PR #2203 — Accounts tiled card grid: density modes, filter rail, presets2200PR #2200 — pipeline kanban polish: WIP limits, days-in-stage, spring drag, keyboard nav
- NewData & analytics
Build, view, export, and schedule your own reports
A real report builder: pick an entity, drag in dimensions, add AND/OR filters, and choose a chart or table. View results in fast, sortable tables, export to CSV, Excel, or PDF, schedule a report to arrive by email, and share a read-only link.
What changed
Reports is now a full build-view-share loop instead of a set of canned charts:
- Build visually — start from an entity (accounts, contacts, opportunities, sequence activity, timeline, or consent), drag in the dimensions you want, and combine filters with nested AND/OR logic.
- View fast — results render in a sortable, virtualized table that stays responsive at thousands of rows, with a chart preview alongside.
- Export for real — download any report as CSV, Excel, or PDF.
- Schedule delivery — set a report to run on a recurring cadence and email itself to the people who need it.
- Share read-only — hand out a signed link to a live report without giving someone a seat.
Find it under Reports in the sidebar.
#2026-08-11-reports-builder-exports-schedulesTechnical details
2209PR #2209 — real custom report builder, viewer, exports + scheduled delivery
- NewImprovedExperienceSales & CRM
Notifications Center 2.0 and a triage Inbox
Notifications got a proper home: a grouped, filterable center that updates in real time with a sidebar badge, plus a new triage Inbox that pulls notifications and call/voice action items into one feed so you can clear everything in one place.
What changed
Everything that needs your attention now lands somewhere sensible:
- Notifications Center 2.0 — the /notifications page groups and filters your notifications, updates live over the existing stream, and drives a numeric badge in the sidebar so you can see what's waiting at a glance.
- A triage Inbox — a new /inbox/triage brings notifications together with call and voice action items in a single feed, each tagged by source, so a morning sweep clears calls, follow-ups, and alerts without hopping between screens.
Open the bell in the top bar, or head to your Inbox.
#2026-08-11-notifications-inbox-2Technical details
2205PR #2205 — notifications center 2.0 + inbox 2.0 triage
- ImprovedData & analytics
A sharper home dashboard
The home dashboard charts were rebuilt on shared primitives: a richer tooltip with exact values, matched-shape empty states that tell you what to do next, a proper stepped pipeline funnel with de-duplicated stages, and a density toggle to fit more or less on screen.
What changed
The dashboard reads like one considered analytics surface now:
- Better charts — velocity, open-rate, top-accounts, and consent charts share a single set of primitives: one tooltip with a title, colored series dots, and exact values.
- Empty states with a next step — a blank chart now shows a matched-shape placeholder and a clear call to action instead of an empty box.
- A real pipeline funnel — the pipeline block is a proper stepped funnel with duplicate stages removed and conversion math clamped so the numbers stay honest.
- Density toggle — switch between compact, comfortable, and spacious to scale chart heights to your screen.
- Reduced-motion aware — chart entrance animations respect the system reduced-motion setting.
It's the first thing you see after signing in.
#2026-08-11-sharper-dashboardTechnical details
2197PR #2197 — dashboard data-viz upgrade on shared chart primitives2199PR #2199 — pipeline funnel: dedupe stages, clamp conversion, compact layout
- NewData & analyticsSecurity & trustPlatform
A live activity feed with a full audit trail
The Activity page is now a live, filterable record of what happened across your workspace — who did what, and when — backed by an audit trail. Admin “view as” impersonation is fully audited with dual-actor records and clear start/stop.
What changed
For admins who need to know exactly what's going on:
- A live activity feed — the Activity page projects a curated slice of your workspace's events into one searchable, filterable timeline: who acted, on what, and when.
- A real audit trail — the feed is backed by the same audited event stream the platform records, so it's a record you can trust, not a best-effort log.
- Impersonation you can account for — admin “view as / impersonate” now writes dual-actor audit records with clear start and stop, closing the compliance gaps around acting on another user's behalf.
Open Activity from the sidebar.
#2026-08-11-activity-feed-audit-trailTechnical details
2196PR #2196 — live activity feed + impersonation compliance (dual-actor audit)
- FixedPlatform
Fixes: meetings, calling, and a cleaner failure path
A round of fixes: Meetings and Calls lists no longer error on records missing expected columns, in-app calling reads the right CORS setting on every configured domain, and a few backend 500s now fail with clear, referenceable errors instead of dead ends.
What changed
The important fixes from this window:
- Meetings and Calls lists stay up — both stopped 500-ing when a contact record was missing columns the list expected.
- Calling connects on every domain — the softphone now reads
CORS_ALLOWED_ORIGINS(not only the older variable), so in-app calling connects on all of a workspace's configured origins. - Honest failures — a subject-line generation 500, a spin-off queue backlog, and a dead end when voice is turned off were all fixed, and now surface real, referenceable errors instead of failing silently.
- No double-fired commands — Ask Pact no longer runs a command twice when you both speak and click it.
- First admin never locked out — new workspaces create the owner's membership atomically, so provisioning can't leave the first admin without access.
#2026-08-11-reliability-fixesTechnical details
2206PR #2206 — Meetings/Calls lists 500 on non-existent contact columns2207PR #2207 — read CORS_ALLOWED_ORIGINS (not just ALLOWED_ORIGINS) for the softphone2194PR #2194 — subject-gen 500, spin-off queue clog, voice-off dead-end + real error refs2188PR #2188 — guard Ask-Pact voice+click path against double-fire2189PR #2189 — create owner membership atomically (unbreaks new-tenant access)
- FixedImprovedVoice & callsPlatform
In-app calling that just works, call after call
A wave of softphone fixes: your second, third, and tenth call now connect as reliably as the first, calls stop hanging in “Connecting…”, Android audio works, and the installed app updates itself so nobody's stuck on a stale build.
What changed
The in-app dialer got a hardening pass so calling stays out of your way:
- Every call, not just the first — the softphone now keeps a persistent connection, so the “first call works, second call hangs” problem is gone.
- No more stuck “Connecting…” — a connect watchdog and clean teardown mean a call that can't go through fails fast and clearly instead of spinning forever.
- Audio on Android — fixed the error that left Android callers with a connected call but no sound, by unlocking audio inside the tap that starts the call.
- Always up to date — installed Pact apps now auto-update on deploy, and the dialer runs a microphone pre-check so a blocked mic tells you exactly what's wrong instead of failing silently mid-call.
This applies wherever your workspace has voice set up. Open the dialer from the bottom-right of the app to place a call.
#2026-08-10-reliable-in-app-callingTechnical details
2163PR #2163 — persistent softphone Device: fix “first call works, second hangs”2160PR #2160 — stop the softphone hanging in “Connecting…” (teardown + watchdog)2170PR #2170 — Android softphone audio: unlock audio in the click gesture2161PR #2161 — auto-update installed PWAs on deploy + mic preflight & honest failure UX
- NewImprovedDocs & support
A guided first day — with one-click sample data
New workspaces now open to a clear activation path: a dashboard “get started” card, purposeful empty states that tell you what to do next, a repaired first-run tour, and a one-click “Load sample data” so you can explore a populated CRM before importing your own.
What changed
Day one in Pact used to drop you into a set of empty screens. Now it guides you:
- An activation card on the dashboard — a short checklist of the highest-value first steps, right where you land after signing in.
- Empty states that do something — each blank list explains what belongs there and links straight to the action that fills it, instead of just showing “no data.”
- Load sample data in one click — from any empty state or the activation card, seed a realistic sample workspace so you can click around a full CRM before committing your real data. Clear it whenever you want.
- A first-run tour that lands on real anchors — the guided tour was repaired end-to-end and now covers import, calling, and voice, so it points at things that actually exist.
Sign in to a fresh workspace, or find the activation card on your dashboard.
#2026-08-10-a-stronger-first-dayTechnical details
2173PR #2173 — day-1 polish: dashboard activation card, fix dead links, purposeful empty states2177PR #2177 — “Load sample data” from empty states + activation card2176PR #2176 — repair first-run tour anchors + cover import/softphone/voice
- ImprovedData & analytics
Bring your whole CRM in — hardened data import
The import pipeline was rebuilt to ingest a full corporate export — accounts, contacts, contracts, and their relationships — instead of choking on the messy, wide files real CRMs actually produce.
What changed
Getting your data into Pact shouldn't be the hard part of switching. This pass makes import handle the real thing:
- Full corporate exports — the pipeline now ingests wide, multi-object exports (accounts, contacts, contracts and their links) rather than one clean object at a time.
- More resilient to messy files — better handling of the inconsistent columns, encodings, and partial rows that show up in exports from other systems.
- A clearer import screen — the admin import surface was reworked so you can see what mapped, what didn't, and what landed.
Try it under Settings → Admin → Import.
#2026-08-10-import-your-whole-crmTechnical details
2174PR #2174 — harden import pipeline for full corporate-export ingestion
- FixedPlatformSecurity & trustMobile
Sign-in, iOS, and mobile fixes
A round of fixes to things that should never trip you up: a sign-in edge case that could lock a workspace owner out, a close button hidden under the iPhone's Dynamic Island, and the schema explorer's toolbar on phones.
What changed
The important fixes from this window:
- No owner lockout — sign-in now resolves an account from its email deterministically, closing an edge case where a duplicate workspace row could lock the real owner out of their own workspace.
- Reachable close button on iPhone — the “X” on full-screen mobile sheets was slipping under the Dynamic Island; it now sits inside the safe area on every full-screen surface.
- Schema explorer on phones — the explorer's layout, filter, and lock controls are now reachable on mobile instead of being cut off, anchored to the top of the screen.
#2026-08-10-sign-in-and-mobile-fixesTechnical details
2181PR #2181 — deterministic email→user resolution (fixes owner lockout via duplicate tenant row)2155PR #2155 — iOS safe-area: close X trapped under the Dynamic Island on full-screen mobile2157PR #2157 — schema explorer: full toolbar on mobile, top-anchored
Week of August 3, 2026
Aug 3 – Aug 9 · 9 updates
Mostly Voice & calls, Platform, Experience
- Talk to Pact right from the homepage
- Place and review calls inside Pact
- A faster dashboard and a faster app
- Filter any module's navigation instantly
- A more natural voice on the demo line
- The mobile homepage, rebuilt for portrait
- Interaction and accessibility polish across the app
- New on the blog: What is MCP?
- Reliability fixes: microphone, phone line, and billing
- NewVoice & callsMarketing
Talk to Pact right from the homepage
The Pact homepage now has a live voice demo: tap the mic (or read the guided walkthrough) and ask a real Pact agent about a sample pipeline — no signup, no phone call required.
What changed
You no longer have to dial a number to hear what a voice-native CRM sounds like:
- Live, in the browser — the hero widget talks to a real Pact agent over the public demo endpoint, using a seeded sample workspace so you can ask about deals, accounts, and next steps.
- Guided, not a dead mic — a short scripted walkthrough introduces what to ask, narrates each answer, and signs off gracefully, so the demo works even with the microphone blocked.
- Its own experience on mobile — phones get a tap-first version tuned for portrait, below the hero.
Try it at the top of the homepage, or call the demo line at +1 (424) 722-8627.
#2026-08-07-talk-to-pact-on-the-homepageTechnical details
2051PR #2051 — voice-first homepage: live agent hero2071PR #2071 — guided homepage demo: intro, narration, sign-off2055PR #2055 — resolve demo availability on the server, not the browser
- NewVoice & calls
Place and review calls inside Pact
Where your workspace has voice set up, Pact now has an in-app dialer, a call log with per-call detail, and a live call canvas — so calling and reviewing calls happens inside the CRM instead of a separate app.
What changed
Calling is now a first-class surface in the app:
- A dialer — a click-to-call softphone for placing calls without leaving Pact, on desktop and mobile.
- A call log — a feed of recent calls with a detail view for each one, so call history lives next to the records it belongs to.
- A live call canvas — a companion view that follows an in-progress call turn by turn.
This rolls out where a workspace has voice configured; the surfaces degrade cleanly and stay out of the way when calling isn't set up.
#2026-08-07-in-app-callingTechnical details
2016PR #2016 — in-app call UI: /call-log feed, detail, /voice-live canvas1952PR #1952 — call feed + durable dialer recordings2128PR #2128 — outbound softphone TwiML so the dialer dials out
- PerformancePlatform
A faster dashboard and a faster app
We moved per-request work off the hot path and cached repeated auth lookups, so the dashboard and the rest of the app respond noticeably faster — especially the first load after signing in.
What changed
A set of backend performance fixes targeting the slowest common path — loading the dashboard:
- Less work per request — per-request logging, metering, and Redis I/O that used to block each API call now run off the event loop.
- Fewer repeated lookups — bearer-token-to-tenant resolution and negative API-key checks are cached instead of hitting the database every request, and the connection pool was enlarged.
Together these removed the redundant per-request database round-trips that were making the dashboard feel sluggish under load.
#2026-08-07-faster-dashboard-and-appTechnical details
1842PR #1842 — off-load per-request middleware I/O1844PR #1844 — drop metering middleware's per-request DB from the hot path1864PR #1864 — cache bearer→tenant lookups + bump the DB pool
- ImprovedVoice & calls
A more natural voice on the demo line
The Pact demo line now speaks with a noticeably more natural, human-sounding voice, and reads at a calmer pace so answers are easier to follow.
What changed
The demo experience got a real voice upgrade:
- A warmer, more natural voice — the demo line's streaming voice was moved to a higher-quality speech engine.
- A calmer pace — playback was slowed slightly so numbers and names are easier to catch on the first pass.
- No stray markup — pause and emphasis hints are handled internally instead of ever being read aloud.
This is the voice you'll hear on the homepage demo and the demo line today.
#2026-08-07-natural-demo-voiceTechnical details
1930PR #1930 — flip the demo line's streaming voice to a natural TTS voice2005PR #2005 — slow the demo voice pace2001PR #2001 — stop speech markup from being spoken literally
- ImprovedMarketingMobile
The mobile homepage, rebuilt for portrait
The marketing homepage on phones was redesigned for portrait screens instead of being a shrunk-down desktop layout — tighter spacing, no dead bands, and a tap-first voice demo.
What changed
The phone homepage is now designed for the device, not squeezed to fit it:
- Built for portrait — sections, spacing, and type were reworked for a narrow screen.
- No wasted space — we removed the empty gaps above the headline and the space that used to be held open for a microphone prompt that wasn't coming.
- A tap-first voice moment — the mobile hero gets its own tap-to-talk demo beat instead of the desktop widget.
#2026-08-07-mobile-homepage-rebuiltTechnical details
2054PR #2054 — mobile homepage designed for portrait2059PR #2059 — remove the dead band above the mobile headline2065PR #2065 — stop repeating the hero headline verbatim
- ImprovedExperience
Interaction and accessibility polish across the app
A wave of small interaction fixes: visible keyboard focus rings, clearer hover feedback on tabs and table rows, accessible chart gradients and progress bars, and toasts instead of raw browser alerts.
What changed
Dozens of small rough edges, smoothed:
- Keyboard focus you can see — focus rings on filter chips and interactive controls, so keyboard and screen-reader users can tell where they are.
- Clearer hover feedback — tabs, tooltips, and table rows now respond visibly to the pointer, with an opt-in sticky table header.
- Accessible charts and progress — chart gradients get unique IDs so they render correctly when several charts share a page, and progress bars carry accessible names.
- Toasts, not alerts — failed actions (like a Spaces invite) now surface a toast instead of a jarring browser alert.
- Faster, quieter navigation — the module rail no longer fires a burst of prefetch requests on load.
#2026-08-07-interaction-accessibility-polishTechnical details
2121PR #2121 — tab hover + tooltip feedback2122PR #2122 — keyboard focus rings + accessible progress2123PR #2123 — perceptible table row hover2124PR #2124 — unique per-instance chart gradient ids2125PR #2125 — stop the module-rail prefetch storm2126PR #2126 — toast instead of alert() on invite failure
- NewPlatform
New on the blog: What is MCP?
Pact now has a blog, and the first article explains the Model Context Protocol (MCP) — the open standard behind Pact's tool integrations — in plain language.
What changed
We started publishing:
- A blog at /blog — a home for product thinking and explainers.
- First up: “What is MCP?” — a plain-language introduction to the Model Context Protocol, the open standard Pact uses to connect the CRM to tools and assistants.
#2026-08-07-blog-what-is-mcpTechnical details
1724PR #1724 — /blog route + first article: What is MCP?
- FixedPlatformVoice & calls
Reliability fixes: microphone, phone line, and billing
A round of fixes to things that should just work: the in-app microphone, the inbound phone line, browser-based dialing, and the billing guard that could wall off the app.
What changed
The important fixes from this window:
- Microphone restored app-wide — a permissions policy was blocking the microphone across the whole app; voice input works again.
- Inbound phone line kept up — a couple of database issues that could take the main phone line down (a type mismatch on caller lookup, a reserved word in a query) were fixed.
- Browser dialing unblocked — the security policy now allows the voice signaling the in-app softphone needs to place a call.
- No more accidental lockout — when usage limits are hit, Pact warns instead of walling off the app, and the client no longer retries a hard "limit reached" response in a storm.
#2026-08-07-reliability-fixesTechnical details
2052PR #2052 — grant microphone=(self); Permissions-Policy had killed the mic2039PR #2039 — fix boolean/integer mismatch that poisoned the inbound webhook2049PR #2049 — quote the reserved word in a voice-reminders query2142PR #2142 — allow Twilio Voice SDK signaling in CSP so the softphone can dial1619PR #1619 — stop the metering-wall retry storm1626PR #1626 — warn-only global allowance instead of a hard lockout
Week of July 13, 2026
Jul 13 – Jul 19 · 18 updates
Mostly Voice & calls, Integrations & API, AI
- Call your CRM — Pact Voice is live on +1 (424) 722-8627
- Do things on a call — text, note, email, book, transfer
- Voice now answers the questions it used to drop
- Ask loosely — the intent router figures out what you meant
- A hard daily cap on voice spend, with a graceful wind-down
- Watch a call in the app while it happens
- Voice can now close and update records on the call
- See every voice call — cost, duration, and transcript
- Voice you can run in a regulated business
- MCP recipes — ready-made tool chains you can install
- One place to connect your own providers — 51 of them
- Call alerts in Slack and Teams, and the live call on your phone
- See a feature work before you connect anything — and always know which is which
- Inbound calling — routing per number, queues, and callbacks
- Voice setup in about a minute — with a preview when a provider isn't connected
- Translated transcripts, weekly call topics, and Zoho call sync
- The MCP tool catalog is now browsable — and its badges tell the truth
- Hardening after an outage
- NewVoice & calls
Call your CRM — Pact Voice is live on +1 (424) 722-8627
Pick up a phone, call +1 (424) 722-8627, and talk to your workspace: ask about your deals, your accounts, and your pipeline out loud and hear the answer back from live data. This is Pact's flagship channel.
#2026-07-19-voice-mcp-liveWhat changed
Pact Voice is the fastest way into your CRM — your voice, no screen:
- Call the demo line — dial [+1 (424) 722-8627](tel:+14247228627) and start talking. Ask "what are my open deals?", "show me my accounts", "how's my pipeline looking?" and hear a short answer read back.
- Answers come from live workspace data — the agent routes each question to the same in-process MCP tools the app uses, so consent, cost, and audit apply exactly as they do everywhere else. It is not a scripted demo bot.
- Kept short on purpose — replies are capped so a phone call doesn't turn into a monologue.
The public demo line is live now. Turning Voice on for your own workspace is a guided setup step — pick a provider, get a number, set your compliance posture, and place a test call.
- NewVoice & calls
Do things on a call — text, note, email, book, transfer
Voice went from read-only to hands-on: ask Pact to text you the details or log a note and it does it on the call, wired to real tools — with email, meeting booking, and warm transfer wired the same way and degrading honestly when a provider isn't connected.
What changed
Voice can now act, not just answer — every action writes a durable ledger row and a call is capped at five actions:
- Text me the details — Pact sends an SMS to your own number on file through your connected messaging provider, respecting the opt-out list. This and note-taking are the verified-working pair.
- Add a note — "note on Acme that budget approved" logs against the account then and there.
- Email me / book a meeting / transfer me — each is wired to a real handler. When the mail provider or calendar isn't connected, Pact says so plainly instead of pretending; a transfer runs the compliance gate before it dials.
- Guardrails built in — a per-call action cap and a per-action cost ceiling stop an ASR mis-hear from fanning out texts or dials.
#2026-07-19-voice-actionsTechnical details
1782PR #1782 — voice interactive actions: text/email/note/book/transfer1787PR #1787 — action-ledger UUID/JSON dialect fix
- FixedVoice & calls
Voice now answers the questions it used to drop
"What are my opportunities?" and "show me my accounts" used to fall through to the generic answer engine and come back with nothing useful. Both now route to the right CRM tool and list your records.
What changed
A pass over the voice router closed the "every question returns nothing" gap:
- "Opportunities" is a deal — reps say "opportunities" and "opps" far more than "deals". Those phrasings now route to your deals instead of dropping into the generic fallback.
- "My accounts" lists your accounts — "my accounts" / "show me my accounts" / a bare "accounts" now returns your account list rather than answering with segment analytics.
- Named look-ups land — asking for a specific account by name resolves to that record instead of a cold, contextless search.
#2026-07-19-voice-answer-qualityTechnical details
1788PR #1788 — route opportunities/my-accounts to the right CRM tool1790PR #1790 — answer-quality routing follow-up (prod-verified)
- NewVoice & callsAI
Ask loosely — the intent router figures out what you meant
Loose, conversational questions like "who's about to close?" now resolve to the right tool via a small language model that runs only when the fast keyword match misses — and asks a clarifying question when it genuinely can't tell.
What changed
The keyword router still runs first — it's free and instant. When it can't place an utterance, one small model call takes over instead of dumping to a generic search:
- Paraphrases resolve — "how's my pipeline looking?", "anything hot?", "who's about to close?" map to the right tool plus a filter/sort spec, so you don't have to hit a magic phrase.
- It asks when unsure — below a confidence threshold, Pact asks a short clarifying question rather than guessing wrong.
- It never breaks the call — if no model is configured or the call times out, the turn falls back to the previous behavior. The router is opt-in per tenant and only runs on the fall-through, so the cheap path stays cheap.
#2026-07-19-voice-intent-routerTechnical details
1791PR #1791 — Haiku intent router on regex fall-through1792PR #1792 — intent-router clarify threshold + fail-open
- NewVoice & calls
A hard daily cap on voice spend, with a graceful wind-down
Voice is Pact's most expensive channel, so it ships with a server-side per-tenant daily cap, a tighter cap on the public demo line, and a polite wind-down when a call reaches the limit instead of a silent overrun.
#2026-07-19-voice-cost-capWhat changed
The cap is enforced on the server, not trusted to the caller:
- Per-tenant daily cap — a default daily ceiling per workspace, configurable, checked at call start and before each turn.
- A tighter cap on the demo line — the public number is clamped to a low daily budget so a runaway test can't bleed the budget.
- Graceful degradation — when the next turn would cross the cap, Pact says "I've hit your daily cap, let's continue via Pact's dashboard" and ends cleanly, rather than dropping the call or overspending.
- NewVoice & callsMobile
Watch a call in the app while it happens
When a routed call comes in, your installed app can ring and open a live companion view that follows the conversation in real time over a streaming connection — the transcript arrives as it's spoken.
#2026-07-19-voice-live-companionWhat changed
The call and the app are two views of the same moment:
- Incoming ring — a routed inbound call fires a push to the assigned user's installed app so it rings and offers to open the call. This is strictly additive: it never changes how the call itself is handled.
- Live companion — open the call and the companion view follows it over a streaming (SSE) connection, with the transcript filling in as the conversation happens.
- Deep-linked — the ring opens straight to that specific call, not a generic inbox.
- ImprovedVoice & calls
Voice can now close and update records on the call
The conversational action executor is now wired into every voice turn, so the things Pact says it will do actually run on the call — and the set of record actions grew: close a deal won or lost, and create or update a contact or account, all by voice.
What changed
Voice actions went from "wired" to "runs on the call", and the record surface widened:
- Close a deal — "mark the Acme renewal closed won" updates the opportunity's stage on the call, with a spoken confirmation before the write.
- Create or update a contact or account — "add a contact named Jordan Lee at Acme" or "update Acme's website" writes the record then and there.
- It actually executes — the action executor is now wired into every turn, so a confirmed action is carried out rather than just acknowledged.
- Same guardrails — each call is capped at five actions, every write is confirmed first, and when a provider or calendar isn't connected Pact says so instead of pretending. Every action still writes a durable ledger row.
#2026-07-19-voice-actions-executeTechnical details
1808PR #1808 — more bound actions: close-won/lost, create/update contact & account1812PR #1812 — wire the action executor + meta-query fallback into /turn
- NewVoice & calls
See every voice call — cost, duration, and transcript
The admin console now has a Voice observability view: every call with its duration and cost, today's spend against the daily cap, and a full openable transcript for each conversation.
What changed
Voice is Pact's most expensive channel, so it comes with the visibility to run it:
- Every call, listed — see recent calls with duration and per-call cost in the admin console.
- Spend against the cap — today's voice spend and the remaining daily budget, so you know where you stand before the cap kicks in.
- Full transcripts — open any call to read exactly what was asked and answered, alongside the consent and audit trail.
Find it under Settings → Voice in the admin console at /admin/voice-mcp.
#2026-07-19-voice-observability-dashboardTechnical details
1810PR #1810 — observability + admin dashboard (calls, cost, transcripts)
- NewSecurityVoice & callsSecurity & trust
Voice you can run in a regulated business
Calling gained the controls a compliance team asks for first: a per-tenant calling mode, a TCPA time-of-day gate, do-not-call lists, automatic detection and redaction of personal, health, and card data, and encrypted originals for teams working under a BAA.
What changed
The compliance layer under Pact Voice — configured once, enforced on every call:
- Calling mode + TCPA gate — pick the calling posture for your tenant and let Pact refuse outbound attempts that fall outside permitted contact hours, instead of trusting a rep to check the clock.
- Do-not-call lists — maintained per tenant and checked before a number is dialed.
- Sensitive-data redaction — transcripts are scanned for personal, health, and card data and redacted automatically.
- Compliance vault — the unredacted originals are encrypted at rest for teams operating under a BAA, with access recorded on an audit trail.
- Recording consent — playback stays gated on the consent ledger, and state two-party-consent rules are applied from a maintained registry rather than a hand-copied list.
Set it up under
/admin/voice-mcp.#2026-07-17-voice-complianceTechnical details
1697PR #1697 — V-9: mode selector, TCPA gate, DNC lists, PHI redaction1730PR #1730 — V-25: PII/PHI/PCI detection, redaction, encrypted BAA-tier originals1706PR #1706 — V-9 follow-up: compliance audit endpoint column fix
- NewAIIntegrations & API
MCP recipes — ready-made tool chains you can install
Install a multi-step MCP tool chain into your workspace in one step — five starter recipes cover renewals, cold calling, support escalation, RFP autofill, and post-call deal updates.
What changed
Instead of assembling tools call by call, start from a recipe:
- Five starter recipes — SaaS renewal playbook, real-estate cold call, support escalation auto-route, RFP autofill from your won library, and post-call deal update.
- One-step install — a recipe lands in your workspace as an inspectable multi-step chain rather than a black box.
- Preview before you wire anything — steps whose provider isn't connected run as clearly-labeled emulated previews, so you can walk a whole recipe before committing an account.
#2026-07-17-mcp-recipesTechnical details
1740PR #1740 — recipe marketplace: installable multi-step MCP tool chains
- NewPlatformIntegrations & APIData & analytics
One place to connect your own providers — 51 of them
A unified provider catalog at /admin/integrations: browse 51 providers across voice, language models, speech, messaging, CRM, warehouses, enrichment, and storage, connect one from a single sheet, and preview what it does before you hand over a key.
What changed
Bring-your-own-key was spread across a dozen screens; it now has one home — at
/admin/integrations:- 51 providers in one catalog, spanning voice, language models, speech-to-text and text-to-speech, voice agents, messaging, CRM, warehouses, enrichment, and storage.
- One connect sheet — the same flow regardless of which provider you're wiring.
- Preview before you connect — see what a provider would do for you as a labeled emulated preview, so the decision to hand over a key is informed.
#2026-07-17-byok-catalogTechnical details
1741PR #1741 — unified BYOK provider catalog: 51 providers, connect sheet, previews
- NewVoice & callsMobileIntegrations & API
Call alerts in Slack and Teams, and the live call on your phone
Post-call and missed-call alerts land in Slack or Teams with one-tap buttons that log the click and take you straight to the right place in Pact, and the installed mobile app rings on an incoming call and opens the live companion with the transcript and running cost.
What changed
- Slack and Teams alerts — a post-call or missed-call summary arrives in the channel you choose, with buttons for View call, Book meeting, Mark won, and Escalate. Each button records who clicked it and opens the matching surface in Pact — the booking screen, the opportunity, the escalation inbox — so the click is a fast route to the work, not a silent state change.
- Mobile — the installed app rings on an incoming routed call and opens the live-call companion (transcript and running cost) while you talk. The audio itself stays on the carrier leg today; the app surfaces the call rather than accepting the audio, so the primary action is Open call. Browser-native answering is a tracked follow-up.
- Hardware handling, a live waveform, and the incoming ring are all in place on the mobile softphone.
#2026-07-17-voice-alerts-mobileTechnical details
1729PR #1729 — V-10: post-call + missed-call alerts to Slack + Teams1731PR #1731 — V-12: mobile PWA softphone — hardware, waveform, incoming ring
- NewPlatformSecurity & trust
See a feature work before you connect anything — and always know which is which
A shared emulation layer lets provider-backed features render a realistic preview when you haven't connected that provider yet — and every previewed value carries a visible provenance marker so emulated output is never mistaken for live data.
What changed
Evaluating a feature used to mean wiring an account first. Now it doesn't:
- Full-fidelity previews — provider-backed surfaces render a realistic preview when the provider isn't connected, so you can judge the feature on its merits.
- Provenance you can see — a marker on the value and a banner on the surface state plainly that what you're looking at is emulated, not live. The rule is simple: an emulated value never appears without saying so.
- Real beats emulated, always — connect the provider and live data supersedes the preview.
This is deliberately conservative: it is a preview layer for provider-backed features, not a simulation of your data.
#2026-07-17-emulation-coreTechnical details
1738PR #1738 — emulation core framework: previews with explicit provenance
- NewVoice & calls
Inbound calling — routing per number, queues, and callbacks
Route each of your numbers to the right team, hold callers in a real queue with hold music, let them press 1 for a callback instead of waiting, and move your priority accounts to the front of the line.
What changed
Inbound calls now behave like a phone system, not a single ringing endpoint:
- Routing per phone number — each number gets its own routing rules, so support and sales lines land with the right people.
- Queues with hold music — callers wait in an actual queue rather than hearing a busy tone.
- Press 1 for a callback — a caller can drop out of the queue and keep their place as a callback instead of holding.
- VIP priority — the accounts you flag jump the queue.
#2026-07-17-voice-routing-queuesTechnical details
1694PR #1694 — V-7: tenant call routing per phone number1699PR #1699 — V-8: inbound queues, hold music, press-1 callback, VIP priority
- NewImprovedVoice & callsDocs & support
Voice setup in about a minute — with a preview when a provider isn't connected
A guided wizard takes you from nothing to a verified call: pick a provider, get a number, set your compliance posture, and place a test call — and any step whose provider isn't connected yet runs as a clearly-labeled preview so you can still see the whole flow.
What changed
- Zero to a verified call — a step-by-step wizard covering provider choice, number, compliance posture, and a test call, with one canonical guide behind it.
- Multi-provider — the wizard works across the supported voice providers rather than assuming one.
- Preview instead of a dead end — if a step's provider isn't connected, it runs as an emulated preview marked with its provenance, so evaluating Pact Voice doesn't require wiring an account first. Previews are labeled as previews everywhere they appear.
- Compliance is part of setup, not an afterthought — the wizard walks you through the calling mode and consent posture before the first call.
#2026-07-17-voice-setup-wizardTechnical details
1715PR #1715 — zero-to-verified-call setup wizard + canonical guide1739PR #1739 — wizard v2: multi-provider, emulation provenance, compliance step
- NewVoice & callsAIIntegrations & API
Translated transcripts, weekly call topics, and Zoho call sync
Read any call transcript translated into your language with your own key, see what your calls were actually about each week as clustered topics with trends, and sync call activity to and from Zoho.
What changed
- Multi-language transcripts — translate a call transcript using your own translation key, so a team reading in a different language than the customer spoke is no longer stuck.
- Weekly call topics — calls are clustered into topics each week with a trend chart and drill-down, so "what are customers calling about" has a real answer instead of an anecdote.
- Zoho CRM sync — call activity writes back to Zoho and syncs bidirectionally, joining the existing CRM connectors.
#2026-07-17-voice-languages-topics-crmTechnical details
1728PR #1728 — V-22: multi-language transcript translation (BYOK)1725PR #1725 — V-17: weekly call-topic clustering + trend chart + drill-down1727PR #1727 — V-11: Zoho + bidirectional call-activity write-back
- ImprovedPlatform
Hardening after an outage
Following a production outage, the web tier gained an explicit restart contract, real health checks, an independent external uptime probe, and the ability to recycle itself when it stops responding promptly — plus a documented rollback path.
What changed
An outage is only useful if it changes the system. What changed:
- Restart contract — the process now restarts on failure by policy rather than by luck, and the watchdog's shutdown path is bounded so it can't hang on the way out.
- Health checks are back on, with the lag watchdog behind its own startup gate so a slow cold start can't trigger a recycle loop.
- Self-recycle on event-loop lag — if the app stops responding promptly it recycles itself instead of serving a hanging page, with concurrency limits set to what the machine can actually handle.
- An external uptime probe that watches from outside our own infrastructure, so we don't depend on the failing system to tell us it's failing.
- A documented rollback path, plus fleet checks before and after a deploy and a blocking login smoke test, so a bad release is caught and reversed quickly.
The demo environment was also moved to larger machines with a warm minimum, so it stops falling over under burst traffic.
#2026-07-17-resilienceTechnical details
1735PR #1735 — watchdog restart contract, health checks back, uptime probe1736PR #1736 — event-loop-lag self-recycle + realistic concurrency limits1737PR #1737 — lag watchdog gets its own 120s uptime gate1743PR #1743 — pact-demo shared-cpu-2x/2GB + warm minimum
Week of July 6, 2026
Jul 6 – Jul 12 · 15 updates
Mostly Platform, AI, Sales & CRM
- Architecture diagrams actually render, plus SE team analytics
- Pages for every role, a Solutions menu, and no more dead ends
- Pact's accent color is now a real indigo
- Fixes: microphone prompts, SE demo pages, compliance audit
- Voice — make and take calls without leaving Pact
- A Support module — one inbox, AI triage, SLAs, and CSAT
- A Sales Engineering module — RFPs, proposals, demos, and a win library
- Enrichment — your providers, your budgets, and live buying signals
- Warehouse sync — a governed analytics feed with auto-pause
- A visible Edit button on every record
- MCP tool results render as tables and charts
- A quieter, faster app shell
- Errors tell you what actually went wrong
- Reliability: module switcher, journeys, seats, and a batch of 500s
- Durable object storage and a steadier web tier
- FixedNewSales & CRM
Architecture diagrams actually render, plus SE team analytics
The architecture proposal designer now draws a real diagram instead of falling back to raw source, proposals export as a Pact-branded PDF, and a team analytics dashboard shows how the SE function is actually spending its time.
What changed
- Live diagrams render — the architecture designer's diagram was falling back to raw source; it now draws properly, using a bundled renderer that works under our content-security policy.
- SE team analytics — a dashboard for the solutions function, with real period-over-period deltas rather than placeholder numbers.
- Polish across the module — the RFP drafter, architecture designer, playbook library, win library, and analytics got a sweep: real KPI deltas, your-own-key embeddings for search, a Pact-branded PDF export, and honest empty states that tell you what to do next.
#2026-07-17-se-diagrams-analyticsTechnical details
1726PR #1726 — bundle mermaid so the Live Diagram actually renders (P0)1695PR #1695 — SE-6: team analytics dashboard1734PR #1734 — SE polish sweep: KPI deltas, BYOK embeddings, branded PDF, empty states
- ImprovedExperienceMarketing
Pact's accent color is now a real indigo
The placeholder purple that had been standing in across the site and app was replaced with Pact's actual indigo, applied consistently everywhere.
What changed
- The sitewide accent moved to Pact's real indigo (
#3A4690), retiring the purple placeholder that had been shipping in its place. - Applied consistently across the marketing site and the app, along with the wax-seal motif, so the brand reads as one thing rather than two.
- Mobile pipeline views went full-bleed in the same pass.
#2026-07-17-brand-accentTechnical details
1718PR #1718 — sitewide accent → indigo #3A4690 + wax seals1713PR #1713 — brand accent, mobile pipeline full-bleed, MCP leads
- The sitewide accent moved to Pact's real indigo (
- FixedVoice & callsPlatformSales & CRM
Fixes: microphone prompts, SE demo pages, compliance audit
Pact no longer asks you to enable a microphone you've already granted, SE demo pages stopped failing to load under rapid navigation, and the voice compliance audit view queries the right data.
What changed
- Microphone — the softphone was telling reps to grant a microphone permission they had already granted; it now reads the real permission state.
- SE demo pages — a canceled request could poison the page and leave it stuck; navigating quickly between demo pages now works.
- Compliance audit — the voice compliance audit view was querying the wrong columns and returning nothing useful; it now reads the real audit trail.
#2026-07-17-fixesTechnical details
1710PR #1710 — stop prompting for an already-granted microphone1705PR #1705 — SE demo page abort-poisoning fix + 6-viewport proof1706PR #1706 — compliance audit endpoint queries the right columns
- NewVoice & callsSales & CRMAI
Voice — make and take calls without leaving Pact
A built-in softphone with auto-provisioned numbers, outbound call campaigns, voicemail transcription with drafted replies, recording with retention and consent-gated playback, and post-call action items — on the provider of your choice.
What changed
Calling is now a first-class surface, not a bolt-on:
- In-app softphone — place and receive calls in the browser over WebRTC, with numbers auto-provisioned so you can dial on day one.
- Outbound call campaigns — sequenced dialing with voicemail drop and automatic retries, so a call list works itself instead of living on a sticky note.
- Voicemail intelligence — missed voicemails are captured, transcribed with your own transcription key, and come back with a drafted reply you can send or edit.
- Recording, retention, and consent — record calls with per-tenant retention windows and legal hold, and playback is gated on the same consent ledger the rest of Pact enforces.
- Post-call action items — every call can extract its own action items into a review inbox afterward.
- Missed-call auto-triage — an unknown inbound number can auto-create a contact and a follow-up task and drop a card in your inbox, so nothing slips.
- AI voice agents — configure a bot to handle a call flow and rehearse it with a simulated test call before it ever talks to a customer.
- Your provider — connect SignalWire, Plivo, or Vonage, or bring your own SIP trunk, behind one voice interface.
Voicemail lives at
/inbox/voicemail; number, agent, recording, and provider settings are under/admin/voice-mcp.#2026-07-10-voiceTechnical details
1615PR #1615 — plug-and-play voice: auto-provisioned numbers + softphone1632PR #1632 — V-1: outbound call campaign orchestrator1631PR #1631 — V-2: voicemail capture, BYOK transcription, AI reply drafts1633PR #1633 — V-3: recording retention, legal hold, consent-gated playback1641PR #1641 — V-4: AI voice agents + simulated test call1637PR #1637 — V-6: post-call action items + review inbox1646PR #1646 — V-15: missed-call auto-triage1686PR #1686 — CPaaS provider adapters: SignalWire, Plivo, Vonage, BYO SIP
- NewDocs & supportAI
A Support module — one inbox, AI triage, SLAs, and CSAT
A full support workspace at /support: email, chat, Slack, WhatsApp, and voice in one threaded inbox, AI triage that classifies and routes tickets, sentiment-driven escalation, SLA policies with live countdowns, and a satisfaction loop.
What changed
Support is now its own module, not a repurposed CRM view — at
/support:- Unified inbox — email, chat, Slack, WhatsApp, and voice land in one thread per customer, so the conversation follows the person across channels.
- AI ticket triage — incoming tickets are classified, routed to the right queue, and the right people are notified, without a human sorting the pile first.
- Ticket sentiment — a rolling sentiment score per ticket auto-escalates the ones turning sour and floats them onto an at-risk dashboard.
- SLA management — set response and resolution policies, watch live countdowns, get an 80%-of-budget warning before a breach, and read a weekly SLA report.
- Support analytics + CSAT — a completed satisfaction loop: send a survey, collect the score, and see volume, resolution time, and satisfaction trends on one dashboard.
- Knowledge-base suggestions — as an agent drafts a reply, relevant KB articles surface right in the composer; helpfulness votes (anonymous for customers) boost the best articles in search, and the KB stays readable offline.
#2026-07-10-support-moduleTechnical details
1655PR #1655 — S-5: unified inbox (email + chat + Slack + WhatsApp + voice)1647PR #1647 — S-1: AI ticket triage — classify, route, notify1665PR #1665 — S-2: ticket sentiment + auto-escalation + at-risk dashboard1678PR #1678 — S-3: SLA policies, live countdowns, 80% warnings, weekly report1687PR #1687 — S-6: support analytics dashboard + completed CSAT loop1668PR #1668 — S-4: KB suggestions in the reply composer + vote-boosted search + offline KB
- NewSales & CRMAI
A Sales Engineering module — RFPs, proposals, demos, and a win library
A workspace for solutions teams at /se: draft RFP responses from your own win library with citations, design architecture proposals with live diagrams and PDF export, provision demo sandboxes from vertical templates, and reuse evidence from won deals.
What changed
The pre-sales side of the house gets its own module — at
/se:- RFP drafter — upload an RFP, extract the questions, and get draft answers pulled from your win library, each with a confidence level and citations back to the source.
- Architecture proposal designer — compose a proposal with cost bands and a live Mermaid diagram, then export it to PDF for the customer.
- Demo sandboxes — provision a demo environment from a vertical seed template and share a prospect link, with a lifecycle so stale sandboxes clean themselves up.
- Playbook library — curated playbooks with hybrid search, versioning, and usage analytics, so what works gets reused.
- Win library — extract reusable evidence from won deals (consent-gated), so the next proposal starts from proof, not a blank page.
#2026-07-10-sales-engineering-moduleTechnical details
1652PR #1652 — SE-1: RFP drafter — extract, draft, cite1667PR #1667 — SE-2: architecture proposal designer + live Mermaid + PDF1669PR #1669 — SE-3: demo sandbox provisioning + prospect share links1677PR #1677 — SE-4: playbook library — curated, searchable, versioned1656PR #1656 — SE-5: win library — won-deal evidence extraction + reuse
- NewAIData & analyticsPlatform
Enrichment — your providers, your budgets, and live buying signals
Connect your own enrichment providers behind a consent-gated waterfall, cap spend with per-team budgets that can alert, throttle, or block at a threshold, and turn live signals into automatic actions.
What changed
Enrichment now runs on your terms — at
/enrichment:- Bring your own providers — a provider-adapter framework runs your enrichment sources in a waterfall (fall through to the next source when one comes up empty), with a consent gate on every lookup.
- Budget guardrails — set per-team budgets and choose what happens at the threshold: alert, throttle, or block. See a cost preview before a run and a threshold alert when you're close.
- Live signal detection — define rules that watch for buying signals and fire an action when one lands, so a change in an account becomes a task instead of a missed moment.
#2026-07-10-enrichment-byok-budgetsTechnical details
1679PR #1679 — E-1: BYOK provider adapter framework + consent gate + waterfall1676PR #1676 — E-3: budget guardrails — alert / throttle / block, team scope, cost preview1684PR #1684 — E-4: live signal detection + action rules
- NewData & analyticsPlatform
Warehouse sync — a governed analytics feed with auto-pause
Register the entities you want in your warehouse and sync them out, with a budget that auto-pauses the feed before it overruns — configurable from admin and drivable over MCP.
What changed
Get Pact's data into your warehouse without a fragile export script — at
/admin/warehouse:- Analytics entity registry — pick exactly which entities sync, so you own the shape of what lands downstream.
- Budget auto-pause — the sync pauses itself before it blows a spend budget instead of running up a surprise bill.
- MCP tools — configure and inspect the sync from an AI client over MCP, alongside the admin surface.
#2026-07-10-warehouse-syncTechnical details
1664PR #1664 — Wave AR activation: entity registry, budget auto-pause, MCP tools
- ImprovedSales & CRMExperience
A visible Edit button on every record
Contact, account, lead, case, and campaign detail pages now carry a clear Edit button, so changing a record no longer means hunting for a hidden menu.
What changed
- One canonical Edit button now sits on contact, account, lead, case, and campaign detail pages.
- No more guessing whether a field is editable inline or which overflow menu hides the edit action — the affordance is where you expect it.
#2026-07-10-edit-affordanceTechnical details
1675PR #1675 — visible Edit on contact, account, lead, case + campaign detail
- ImprovedAIIntegrations & API
MCP tool results render as tables and charts
In the MCP tool sandbox, a tool's output now renders as a type-aware table or chart with clear guardrail states, instead of a wall of raw JSON.
What changed
- The MCP tool sandbox now shows results as type-aware tables and charts, so you can read what a tool returned at a glance.
- Guardrail states — consent-filtered rows, rate-limit and cost signals — render inline instead of hiding in the payload.
#2026-07-10-mcp-result-viewsTechnical details
1614PR #1614 — result-view primitives: type-aware tables, charts, guardrail states
- FixedPlatformData & analytics
Errors tell you what actually went wrong
A widget that fails now shows the real reason instead of a generic message, calendar and seat-cap actions surface honest errors, and a malformed limits payload can no longer break the upgrade nudge.
What changed
- Widgets now report the real reason they couldn't load, so a failure is diagnosable instead of a shrug.
- Calendar and seat-cap actions (on
/meetingsand module assignment) show what went wrong — a full seat pool, a disconnected calendar — instead of a silent no-op. - The cap nudge banner is guarded against a malformed limits payload, so bad data can't blank the upgrade prompt.
#2026-07-10-honest-errorsTechnical details
1642PR #1642 — show the real reason when widgets fail to load1660PR #1660 — honest calendar and seat-cap errors1673PR #1673 — guard cap nudge banner against malformed caps payload
- FixedPlatformData & analytics
Reliability: module switcher, journeys, seats, and a batch of 500s
The module switcher no longer disappears and gained search and a keyboard shortcut, journeys with a terminal wait now complete instead of looping, seat counts reflect only live users, and a batch of Postgres-only 500s across cases, meetings, and the new modules is fixed.
What changed
- Module switcher — it no longer vanishes when a fetch fails; it now shows an honest zero-state, a retry, a search box, and a
Cmd+Shift+Mshortcut, and caches the module list so it stops flickering. A ghost-module bug that shrank owners' and admins' module coverage is also fixed. - Journeys — an enrollment that reaches a terminal wait step now completes instead of looping indefinitely.
- Seats — seat counts reflect only live users, orphaned seat assignments are purged with a proper cascade, and Pact-internal tenants are exempt from seat caps and metering.
- Postgres 500s — a batch of database-only errors is fixed across case and routing-rule creation, meeting contact resolution, the SE scorecard and
/se/today, and module assignment, so the new Support and SE modules behave the same on production as in test.
#2026-07-10-reliability-fixesTechnical details
1650PR #1650 — module switcher: honest zero-state, search, Cmd+Shift+M, cache1645PR #1645 — ghost Support/SE modules no longer shrink owner/admin coverage1659PR #1659 — journeys terminal wait completes the enrollment1657PR #1657 — count only live users + bypass caps for internal tenants1661PR #1661 — purge orphaned seat assignments + FK cascade1648PR #1648 — RETURNING id on Postgres for case + routing-rule create1649PR #1649 — Support Today 500 + SE workspace auth on Postgres1674PR #1674 — Postgres flags-bind + meetings contact resolver 500s
- Module switcher — it no longer vanishes when a fetch fails; it now shows an honest zero-state, a retry, a search box, and a
- ImprovedPlatform
Durable object storage and a steadier web tier
File and attachment storage moved to a managed object store with a backfill worker so nothing is stranded on a single machine, and the web tier was hardened so instances can't recycle together and stay warm for fast first loads.
What changed
Internal work you feel as a more durable, steadier platform:
- Object storage — the blob layer moved behind an object-store seam with the writer cut over and a backfill worker, so files and attachments no longer depend on a single machine's disk.
- Steadier web tier — the reliability watchdog was tuned and clamped below the memory cliff it guards, sibling instances are prevented from recycling at the same moment, and both machines stay warm so you don't hit a cold "try again" load.
- Honest cost reporting — the internal cost rollup retired a stale line item and now stamps the source of every figure, so the numbers we run the business on are trustworthy.
#2026-07-10-behind-the-scenesTechnical details
1666PR #1666 — blob layer → object store: seam, writer cutover, backfill worker1685PR #1685 — clamp the web-tier watchdog below the GC-pause cliff1682PR #1682 — recycle slots so sibling instances never go down together1688PR #1688 — cost rollup honesty: retire the stale line, stamp every figure
Week of June 29, 2026
Jun 29 – Jul 5 · 13 updates
Mostly Platform, Experience, Data & analytics
- MCP goes read-write — 115 tools, per-client keys, and a sandbox
- Search now covers tasks, notes, emails, and custom objects
- Seven more languages, including full right-to-left support
- Pipeline board controls, a two-rail deal page, and favorite dashboards
- pact.place redesigned — story-first on desktop and mobile
- Large contact lists load in under a second
- Dashboards fail honestly — real errors, per-widget, with retry
- App-wide polish — consistent empty states, safer destructive actions
- "Report a problem" now carries the context support needs
- Installed-app sign-in no longer breaks right after we ship an update
- Language switching is now trustworthy end to end
- Fixes: schema explorer, real-time notifications, offline banner
- Tighter tenant scoping on enrichment lookups
- NewAIIntegrations & APIPlatform
MCP goes read-write — 115 tools, per-client keys, and a sandbox
AI clients connected over MCP can now create and update records — not just read them — with per-client MCP-only keys, tier-aware limits, a full call audit, a prompt library, and a sandbox to try tools safely.
What changed
The MCP server grew from a read-only window into a working surface:
- Entity write tools — create and update accounts, contacts, and deals, and add notes, from Claude, Cursor, or any MCP client, alongside the existing read tools. The catalog now spans 115 tools. Writes require explicit
write:*scopes, run on a tighter rate limit, and the consent gate refuses contact writes targeting suppressed or withdrawn subjects. - A prompt library and pact:// resources — reusable, parameterized prompts and addressable records, so a client can pull the exact context it needs instead of pasting.
- Per-client MCP-only keys — issue a key that works over MCP and nowhere else, scoped by plan tier, with per-key limits.
- Call audit — every tool call is logged with who, what, and when, visible in admin.
- Tool sandbox + client guides — try any tool with synthetic data before pointing it at real records, and follow per-client setup guides for the popular MCP clients.
Why it matters: your AI assistant stops being a reporter and starts being an operator — under keys, limits, and an audit trail you control.
#2026-07-05-mcp-writesTechnical details
1578PR #1578 — entity write tools + prompt library + pact:// resources1579PR #1579 — per-client MCP-only keys, tier-aware limits, call audit + tool catalog1580PR #1580 — tool sandbox + per-client integration guides
- Entity write tools — create and update accounts, contacts, and deals, and add notes, from Claude, Cursor, or any MCP client, alongside the existing read tools. The catalog now spans 115 tools. Writes require explicit
- NewImprovedAIExperience
Search now covers tasks, notes, emails, and custom objects
Global search (and Cmd+K) now reaches tasks, notes, logged emails, and custom-object records in one query, alongside accounts, contacts, and deals.
What changed
- One search box, the whole workspace: tasks, notes, logged emails, and custom-object groups now come back from the same query as accounts, contacts, and deals.
- Results stay tenant-scoped and permission-checked per entity type.
Why it matters: "I know it's in here somewhere" now has one answer box instead of four.
#2026-07-05-unified-searchTechnical details
1574PR #1574 — unified search: tasks, notes, emails, custom-object groups in /v1/search
- NewExperience
Seven more languages, including full right-to-left support
Arabic, Hebrew, Hindi, Indonesian, Turkish, Polish, and Dutch join the six languages shipped in June — 14 languages total, with true RTL layouts for Arabic and Hebrew and locale-aware formatting throughout.
What changed
- Seven new locales — Arabic, Hebrew, Hindi, Indonesian, Turkish, Polish, and Dutch — bringing the app to 14 languages including English.
- Real right-to-left layouts for Arabic and Hebrew: mirrored navigation, correctly-ordered controls, and RTL-aware components, not just translated strings.
- Locale-aware date, number, and currency formatting extends to every new locale.
#2026-07-05-i18n-wave-2Technical details
1549PR #1549 — Wave AM: 7 new locales + RTL + locale formatters
- NewImprovedSales & CRMData & analytics
Pipeline board controls, a two-rail deal page, and favorite dashboards
The pipeline board gained collapse-stage and density controls, deal detail moved to a two-rail layout with an inline header, and dashboards you star now float to the top of the hub.
What changed
Three upgrades to the surfaces sales teams live in:
- Pipeline board controls — collapse the stages you're not working (folded stages stay drop targets, so drag-to-move still works) and pick a card density — comfortable, compact, or spacious. The board remembers both per device.
- Deal detail, two-rail — the deal page now puts activity and detail side by side under an inline header, so updating a deal doesn't mean pogo-sticking between tabs.
- Favorite dashboards — star the boards you check daily and they float to the top of the dashboards hub.
#2026-07-05-crm-working-surfacesTechnical details
1567PR #1567 — board view controls: collapse stages + density toggle1568PR #1568 — deal detail two-rail layout + inline header1566PR #1566 — favorite boards float to the top of the hub
- ImprovedMarketing
pact.place redesigned — story-first on desktop and mobile
The marketing homepage was rebuilt as a story on both trees: a liquid-glass hero and eight-beat arc on desktop, and a lean six-beat, thumb-first story on phones that cut the scroll by two-thirds.
What changed
- Desktop — a two-column liquid-glass hero, a problem → solution → proof arc, and an interactive tour of the live product as the centerpiece. Claims on the page are limited to what's actually shipped.
- Mobile — a dedicated six-beat story tree: the scroll dropped from ~34 phone screens to ~13, and the primary calls to action sit in the thumb zone.
- Both trees share one live product demo — touch it, no login.
#2026-07-05-homepage-redesignTechnical details
1589PR #1589 — desktop homepage redesign, story-first1585PR #1585 — mobile homepage major redesign, story-first
- PerformanceSales & CRMPlatform
Large contact lists load in under a second
Contact and people reads no longer run per-row permission and key lookups — on large workspaces, list pages that took tens of seconds now render in under a second.
What changed
- Contact reads now resolve feature flags and decryption keys once per request instead of once per row.
- On workspaces with tens of thousands of contacts, the people list went from tens of seconds to under a second.
- The same fix applies to every surface that reads contacts in bulk — lists, search results, and exports.
#2026-07-05-contact-reads-performanceTechnical details
1608PR #1608 — request-scoped flag+DEK cache kills per-row lookups in contact reads
- ImprovedData & analyticsPlatform
Dashboards fail honestly — real errors, per-widget, with retry
A widget that can't load now says what went wrong and offers a retry — instead of a blank card or a bare "Failed to load." — and one broken widget can no longer blank the whole dashboard.
What changed
- Per-widget error states — each dashboard widget renders its own readable error with a retry button; the rest of the page keeps working.
- Section boundaries — an error in one dashboard section is contained there instead of taking down the route.
- The AI "What's happening" summary moved off the request path: the dashboard renders immediately and the summary streams in when ready, instead of blocking or showing "Couldn't generate a summary."
#2026-07-05-dashboard-resilienceTechnical details
1588PR #1588 — route widget load errors through <WidgetError>1603PR #1603 — dashboard section boundaries1570PR #1570 — move the AI summary off the request path
- ImprovedExperience
App-wide polish — consistent empty states, safer destructive actions
Empty and loading states now share one visual language across the app, destructive actions get a real confirmation dialog instead of a browser popup, and hover and focus motion was unified and calmed.
What changed
- Empty and loading states across the app now use the same primitives — no more mystery blank panels while data loads.
- Destructive actions (delete, revoke, disconnect) use a proper in-app confirmation dialog with a typed danger zone where it matters — the raw browser
confirm()popup is gone. - Motion polish — hover-lift and focus-ring behavior is consistent everywhere, and toasts arrive top-right with a spring instead of jumping.
#2026-07-05-app-polishTechnical details
1565PR #1565 — unify empty + loading states on shared primitives1564PR #1564 — ConfirmDialog + DangerZone primitives1562PR #1562 — hover-lift + focus-ring consolidation, toast spring
- ImprovedDocs & supportPlatform
"Report a problem" now carries the context support needs
Problem reports now attach the error ID, build version, timestamp, and your user and workspace context automatically, plus a one-click "Copy diagnostics" button — so support can act on the first message.
What changed
- Reports automatically include the error ID, build ID, and timestamp of what you hit, plus your user and workspace identifiers.
- A Copy diagnostics button puts the same bundle on your clipboard for tickets filed elsewhere.
- No more "can you tell us roughly when it happened?" round-trips.
#2026-07-05-support-diagnosticsTechnical details
1601PR #1601 — reports carry Sentry event ID, build id, timestamp1605PR #1605 — reports carry user email + tenant slug, Copy diagnostics
- FixedMobilePlatform
Installed-app sign-in no longer breaks right after we ship an update
If you use Pact as an installed app, a fresh deploy could strand you on an error screen at sign-in. The app now detects a stale build and reloads itself once, and the edge cache can no longer serve pages that reference removed files.
What changed
We ship many times a day, and the installed (PWA) app could get caught mid-update:
- The app now detects a stale-build load failure and reloads itself once, automatically — no more error screen where retrying just re-broke the same way.
- Edge caching was tightened so a cached page can no longer reference files a newer deploy removed, and the service worker itself is never cached by the CDN.
If you saw "something didn't work" right after opening the installed app, this was it.
#2026-07-05-pwa-stale-deployTechnical details
1595PR #1595 — auto-reload on stale-deploy chunk error1596PR #1596 — bound prerendered HTML TTL at the edge1597PR #1597 — stale-edge HTML guard1598PR #1598 — sw.js must be no-store at the CDN
- FixedExperience
Language switching is now trustworthy end to end
The language picker now only appears where translations actually exist, your choice survives sign-in and cold starts, the switch applies instantly, and the menu closes properly on select.
What changed
A batch of fixes that make the language switcher behave like it should:
- The picker is hidden on pages that aren't translated yet instead of offering a switch that half-works.
- Your language survives sign-in — it no longer snaps back to English after the post-login navigation.
- The UI flips immediately when you switch; saving the preference happens in the background, so a cold backend can't make the switch look dead.
- Saving your language no longer errors for workspace accounts, and the menu closes on select instead of blocking clicks.
#2026-07-05-language-switchingTechnical details
1584PR #1584 — hide the switcher where translations don't exist1600PR #1600 — language survives the post-login navigation1606PR #1606 — flip the UI before the locale save1599PR #1599 — locale preference 500 fix1610PR #1610 — close the language menu on select
- FixedPlatformData & analyticsMobile
Fixes: schema explorer, real-time notifications, offline banner
The schema explorer got its desktop diagram back and a legible mobile grid (and no longer crashes on iOS pinch-zoom), real-time notifications reconnected, the offline banner stopped lying, and AI status checks no longer count against usage.
What changed
- Schema explorer — the desktop entity diagram is back (the growing schema had tripped a clustering threshold and turned it into thumbnails), mobile gets a legible module grid, and pinch-zoom on iOS no longer crashes the page.
- Real-time notifications — the live notification stream reconnected for all sessions; it had been failing authentication since a recent auth change.
- Offline banner — the "you're offline" banner now confirms connectivity with a real probe before showing, instead of sticking on-screen while you're clearly online.
- Contact detail rail — side panels no longer wrap awkwardly at narrow widths.
- AI status checks — availability probes from dashboards no longer count as AI agent calls, which had made AI features look rate-limited or erroring when they weren't.
#2026-07-05-fixesTechnical details
1594PR #1594 — restore desktop ERD + legible mobile module grid1246PR #1246 — root-cause the iOS pinch crash1607PR #1607 — unbreak the notifications stream auth1572PR #1572 — offline banner probe-confirms connectivity1561PR #1561 — contact rail panels stop wrapping1604PR #1604 — AI availability probes are not agent calls
- SecuritySecurity & trust
Tighter tenant scoping on enrichment lookups
Enrichment lookups are now explicitly tenant-scoped at the query layer, and the migration-safety CI gate was raised to cover the full current schema.
What changed
- Enrichment lookups now carry explicit tenant scoping at the query layer, closing a class of cross-tenant read risk before it could be reached.
- The migration-safety gate in CI was raised to cover every migration through the current head, so schema changes keep getting checked against the same bar.
#2026-07-05-tenant-scopingTechnical details
1586PR #1586 — tenant-scope enrichment lookups + raise migration gate
Week of June 22, 2026
Jun 22 – Jun 28 · 11 updates
Mostly Integrations & API, Platform, Security & trust
- Always-free data portability — export and import, on every plan
- Browser extension — Chrome, Edge, and Firefox
- Six languages — Spanish, French, German, Portuguese, Japanese, and Simplified Chinese
- Self-serve billing — Stripe Checkout, Customer Portal, and a no-dark-patterns upgrade flow
- Trust Center — security log, bug bounty, and self-serve export
- Customer Health 2.0 — explainable scores on every account
- Talk to your CRM, and an AI deal-room brief
- HubSpot and Pipedrive migration, and a native Discord app
- Workflow triggers, save-as-template, and a real-time editing safety net
- Per-call API metering, webhook replay, and mobile deep links
- Tenant-isolation hardening and step-up on sensitive actions
- NewData & analyticsSecurity & trust
Always-free data portability — export and import, on every plan
Export your full tenant — records, activity, consent state, and inline attachments — as a signed archive, and import one back, on every plan including Free. No paywall on your own data.
What changed
Your data is yours, and getting it out is never a paid feature:
- Full export of accounts, contacts, opportunities, activity, sequences, and the consent ledger, with inline attachments and a signed manifest so the archive is verifiable end to end.
- Import a previously-exported archive back into a tenant. The format is versioned (v1.1), and minor version bumps are accepted under a family rule so an export never expires the moment we ship an improvement.
- One-shot download tokens with a short audit window, so a link you hand to your data team can't be replayed later.
- Available on every plan, including Free — data portability is a right, not an add-on.
Why it matters: there's no lock-in tax. You can leave with everything, or move a workspace between environments, whenever you want.
#2026-06-27-data-portabilityTechnical details
1480PR #1480 — Wave BG: always-free tenant data export1483PR #1483 — Wave BG Phase 2A: always-free tenant data import1482PR #1482 — Wave BG Phase 2B: inline attachments + one-shot tokens + audit window
- NewIntegrations & APIExperience
Browser extension — Chrome, Edge, and Firefox
A cross-browser MV3 extension: sign in with PKCE, open the command palette anywhere with Cmd+K, and see the calendar context for the person or company on the page you're viewing.
What changed
Bring Pact to the tab you're already on:
- Cross-browser (Chrome, Edge, Firefox) on Manifest V3, with a shared polyfill so behavior matches across engines.
- PKCE sign-in — the OAuth flow never exposes a client secret in the extension.
- Cmd+K everywhere — the same command palette you use in the app, on any page.
- Calendar context for the account or contact in view, so you walk into a meeting already briefed.
Why it matters: the CRM meets you where the work happens instead of asking you to switch tabs.
#2026-06-27-browser-extensionTechnical details
1486PR #1486 — Wave BJ: PKCE auth, Calendar, Cmd+K, cross-browser polyfill1491PR #1491 — Wave BJ: artifact workflow + deploy runbook
- NewExperienceMarketing
Six languages — Spanish, French, German, Portuguese, Japanese, and Simplified Chinese
The product and the marketing site now speak six languages, with locale-aware dates, numbers, and currency, and localized system email templates. A coverage dashboard keeps translations honest.
What changed
Global by default, not as a bolt-on:
- Six locales — Spanish, French, German, Portuguese, Japanese, and Simplified Chinese — across the app and the marketing pages.
- Locale-aware formatters for dates, numbers, and currency, plus localized system email templates.
- A coverage dashboard at
/pact-admin/i18n/coveragewith a freshness analyzer, so a stale string shows up as a gap instead of shipping silently in English.
Why it matters: international teams see Pact in their own language, down to how a date or an amount is written.
#2026-06-27-i18nTechnical details
1487PR #1487 — Wave BK Phase 1: regional locale split + formatters + email templates1454PR #1454 — /pact-admin/i18n/coverage dashboard + freshness analyzer
- NewPlatform
Self-serve billing — Stripe Checkout, Customer Portal, and a no-dark-patterns upgrade flow
Upgrade, change plan, and manage your subscription yourself through Stripe Checkout and the Customer Portal, with a reverse-trial that starts you on a paid experience and a one-click upgrade the moment you hit a cap.
What changed
Everything you need to go from Free to paid without talking to sales:
- Stripe Checkout + Customer Portal — start, change, or cancel a subscription and manage payment methods yourself.
- Reverse trial — new workspaces begin on the full paid experience and settle onto the right plan when the trial ends, so you evaluate the real thing.
- Cap-aware upgrade — when a workspace reaches a plan limit, the upgrade is one click, with the affected limit named plainly and no manufactured urgency.
- Usage metering + a usage dashboard so you can see consumption ahead of any usage-based line item.
- Admin surfaces show a clear "configure Stripe keys" banner and disable checkout CTAs until the keys are in place — no half-wired states.
Why it matters: buying and managing Pact is self-serve and honest, with the limits and prices stated plainly.
#2026-06-27-self-serve-billingTechnical details
1489PR #1489 — Wave BE: self-serve Stripe Checkout + Customer Portal1518PR #1518 — Wave BD: reverse-trial flow on the platform-plan path1522PR #1522 — Wave BH: cap-aware upgrade UX — one-click, no dark patterns1520PR #1520 — Wave BF: pay-as-you-go metering + usage dashboard1485PR #1485 — Wave BC: soft + hard cap enforcement on plan limits
- NewSecuritySecurity & trust
Trust Center — security log, bug bounty, and self-serve export
A customer-facing Trust Center with a running security log, a bug-bounty program, live uptime, and a self-serve data export — plus a machine-readable security.txt at the web apex.
What changed
The evidence a security reviewer asks for, without a sales call:
- Security log and a bug-bounty page, so the security posture and how to report an issue are public.
- Uptime gates wired into the homepage and PWA, so status is honest and visible.
- Self-serve export from the same surface — see the always-free portability above.
- security.txt (RFC 9116) at the apex for coordinated disclosure.
Why it matters: a prospect's security team can self-serve most of their diligence from one place.
#2026-06-27-trust-centerTechnical details
1524PR #1524 — Wave BI: Trust Center — security log, bug bounty, export1476PR #1476 — customer-facing trust + transparency UX layer1477PR #1477 — post-incident homepage + PWA uptime gates1542PR #1542 — RFC 9116 security.txt at the web apex
- NewSales & CRMAI
Customer Health 2.0 — explainable scores on every account
The health and churn-risk model now ships every score with its grade, severity, trend, and per-signal contributions, framed by a new HealthScoreWidget and stacked into the account rail.
What changed
Health that shows its work:
- A held-out evaluation on the churn model, plus deal-lifecycle sentiment folded into the score, on a real scheduler.
- A HealthScoreWidget that frames the raw score as a grade, a severity, a trend, and the per-signal (SHAP) contributions behind it.
- Health and risk cards stacked in the account rail, so "why is this account red" has an answer on the call, not in a notebook.
Why it matters: a CSM can defend a renewal number with the specific signals that moved it.
#2026-06-27-customer-health-2Technical details
1533PR #1533 — activate Customer Health 2.0: held-out churn eval, sentiment, scheduler1554PR #1554 — HealthScoreWidget: grade · severity · trend · SHAP1547PR #1547 — stack health + risk cards in the account rail
- NewAISales & CRM
Talk to your CRM, and an AI deal-room brief
Filter more lists in plain language, and open a deal room to an AI brief that rolls up sentiment shifts, competitor mentions, and decision-maker changes across the thread.
What changed
Two AI surfaces grounded in your own records:
- Natural-language search on more lists — opt in and narrow a list by typing what you want instead of building a query.
- AI deal-room brief — a per-deal summary with the sentiment delta, a competitor rollup, and any decision-maker changes, so you catch a shift before it costs you the deal.
Both cite the records behind their claims and run on the same consent-filtered, cost-attributed loop as the rest of Pact's AI.
#2026-06-27-natural-language-and-deal-aiTechnical details
1538PR #1538 — Wave AY: opt-in natural language search on more lists1540PR #1540 — Wave AO: AI deal-room brief (sentiment, competitor rollup, decision-makers)
- NewIntegrations & APIData & analytics
HubSpot and Pipedrive migration, and a native Discord app
Import from HubSpot or Pipedrive with schema discovery and editable field mapping, and run deals from a Discord channel with native chat actions and deal rooms.
What changed
More ways in, and more places to work:
- HubSpot + Pipedrive importers with schema discovery, field-history handling, and an editable mapping step — so a switch keeps your structure instead of flattening it.
- Native Discord app with chat actions and deal rooms — turn a channel into a CRM record and advance a deal without leaving the conversation.
Why it matters: moving to Pact is guided, and the team keeps collaborating where it already does.
#2026-06-27-migration-and-chat-nativeTechnical details
1537PR #1537 — Wave AG: HubSpot + Pipedrive connectors, schema discovery, editable mapping1544PR #1544 — Wave AU: Discord native app + chat actions + deal rooms
- NewMarketingIntegrations & API
Workflow triggers, save-as-template, and a real-time editing safety net
Workflows can now fire on events and be saved as reusable templates, and collaborative editing gained a conflict/undo banner plus an offline retry queue so concurrent edits never lose work.
What changed
- Automation gap-fill — event triggers, a delete-record action, and save-as-template, so a workflow you tuned once becomes a starting point for the next.
- Real-time editing safety net — an opt-in conflict-and-undo banner and an offline retry queue, so two people on the same record (or a dropped connection) never silently lose an edit.
#2026-06-27-workflow-automation-and-collabTechnical details
1531PR #1531 — Wave AC: event triggers, crm_delete, save-as-template1530PR #1530 — inline-edit safety net: conflict/undo banner, offline retry queue (opt-in)
- NewPlatformIntegrations & API
Per-call API metering, webhook replay, and mobile deep links
The public API meters per call with tier enforcement, webhooks gained a replay window for missed deliveries, and native deep-link association files are served so app links resolve on iOS and Android.
What changed
Platform depth for teams building on Pact:
- Per-call API metering with tier enforcement, so usage is measured and limits are honest.
- Webhook replay window — re-deliver events a consumer missed instead of losing them.
- Deep-link association files at the web apex so links open the native apps.
- Vertical custom fields seeded per industry template, so a new workspace starts with the fields its vertical actually uses.
#2026-06-27-api-metering-and-platformTechnical details
1539PR #1539 — Wave AN: per-call metering + tier enforcement1535PR #1535 — webhook replay window + native deep-link association files1541PR #1541 — seed industry custom fields per vertical template
- SecuritySecurity & trustPlatform
Tenant-isolation hardening and step-up on sensitive actions
Row-level tenant isolation was hardened with CI coverage gates and cross-tenant deny-path tests, a staff-bypass audit surface was added, and sensitive operations can require a step-up (default off).
What changed
Defense in depth on the thing that matters most — your data staying yours:
- Row-level security hardening across the data plane, with CI gates that fail a PR lacking isolation coverage and Postgres regression tests that assert cross-tenant reads are denied.
- Staff-bypass audit — any support access is logged and visible on an admin surface.
- Step-up policy — sensitive operations can require re-verification. It ships off by default, so nothing changes until an admin opts in.
#2026-06-27-tenant-isolationTechnical details
1441PR #1441 — RLS Phase 1: tenant-isolation hardening infrastructure1448PR #1448 — RLS Phase 3: Postgres cross-tenant deny-path tests1453PR #1453 — RLS Phase 4: staff-bypass audit log + admin surface1545PR #1545 — default-OFF step-up policy for sensitive operations
Week of June 15, 2026
Jun 15 – Jun 21 · 5 updates
Mostly Marketing, Platform, Data & analytics
- NewMarketingExperience
A living backdrop — atmosphere on auth and an in-app toggle
A depth-and-light backdrop warms the sign-in and sign-up screens, and an opt-in Settings → Appearance toggle brings a subtle lit atmosphere to the whole app — off by default, motion-safe.
What changed
- Warm auth surfaces — a gentle mesh-and-grain backdrop on sign-in and sign-up.
- In-app surface atmosphere — an opt-in toggle in Settings → Appearance layers subtle depth beneath the glass surfaces across the app. Off by default, per-browser, and it honors reduced-motion, reduced-transparency, and forced-colors.
The system is CSS-only where it counts and composes with the existing ambient theme, so it stays within the homepage performance budget.
#2026-06-27-atmosphereTechnical details
1525PR #1525 — atmosphere: depth/light/grain backdrop + warm auth surfaces1529PR #1529 — opt-in global in-app surface atmosphere (Settings toggle)
- NewDocs & supportMarketing
A 30-second signup funnel and interactive role demos
Signup now runs a 30-second path to a first meaningful action, and the marketing site added interactive, role-specific demos for sales, marketing, and customer success.
What changed
- Activation funnel — a 30-second signup-to-first-action path, so a new user does something real fast.
- Role demos at
/for/sales,/for/marketing, and/for/cs— touch the product for your role, no login, with an honest "what's illustrative" footer. - The pricing page moved to a clean four-tier structure with plain-language limits.
#2026-06-27-activation-and-marketingTechnical details
1460PR #1460 — 30-second signup → first AHA-moment funnel1468PR #1468 — /for/{sales,marketing,cs} interactive demos + audit footer1450PR #1450 — /pricing rebuild: 5 tiers → 4 canonical
- PerformancePlatformMarketing
Faster marketing pages and per-route performance budgets
The marketing tree now renders statically behind a route-aware content-security policy so the edge cache stays hot, and every route carries a per-route performance budget with an observability dashboard.
What changed
- Static marketing render + route-aware CSP — public pages serve from the edge cache instead of re-rendering per request.
- Per-route perf budgets with a dashboard at
/pact-admin/observability/perf, plus an interaction-responsiveness (INP) gate, so a regression fails CI instead of reaching users. - Design tokens moved to 11-stop, WCAG-verified color scales with status, elevation, type, and surface tokens — one source of truth for contrast.
#2026-06-27-perfTechnical details
1532PR #1532 — static-render marketing tree to unblock edge cache1528PR #1528 — route-aware CSP for the marketing tree1488PR #1488 — Wave BN: per-route web perf budgets + observability1515PR #1515 — 11-stop WCAG-verified color scales + status/elevation/type/surface tokens
- FixedPlatformData & analyticsMarketing
Reliability and accessibility fixes across the app and marketing site
The analytics dashboard now surfaces a clear error state instead of a blank crash, the language selector no longer silently fails in production, a landing-page SSR crash is fixed, and sign-in / sign-up / pricing gained accessibility fixes.
What changed
A batch of correctness and access fixes:
- Analytics — an error boundary surfaces a readable state instead of an unhandled crash, and an owner leaderboard renders an em-dash for a null win rate instead of a broken cell.
- i18n — the language selector no longer 401s silently in production, and it now works across all marketing pages.
- Marketing — a stale pricing slug that crashed server rendering on the landing page is fixed.
- Accessibility — real headings, skip links, correct input types, and labeled controls on sign-up, sign-in, and the pricing calculator, plus a sweep of route aliases and redirects so old links resolve.
#2026-06-27-fixesTechnical details
1514PR #1514 — analytics error boundary1517PR #1517 — language selector prod 401 fix + all marketing pages1474PR #1474 — landing SSR crash from stale pricing slug1465PR #1465 — a11y on /signup and /login
- ImprovedPlatform
Faster, self-healing infrastructure
Deploys moved to a managed native runner for faster, more predictable releases, and the platform gained runtime self-healing with auto-restart, rollback, circuit breakers, and a SHA-rollout gate.
What changed
Internal work customers feel as a faster, steadier platform:
- Managed CI runner — the heaviest build/deploy jobs run on a native (no-emulation) runner, so releases are faster and less likely to stall in a queue.
- Runtime self-healing — auto-restart and rollback, circuit breakers, tenant-throttling, and a SHA-rollout gate that verifies a deploy actually reached the running app before calling it done.
- Declarative alerting and additional smoke gates (signup flow, chunk-404, auth non-5xx) so a regression pages on-call before it reaches you.
#2026-06-27-behind-the-scenesTechnical details
1459PR #1459 — runtime auto-restart/rollback + circuit breakers + SHA-rollout gate1527PR #1527 — route bundle-size build to the managed runner1504PR #1504 — self-hosted-runner docs for the managed-runner migration
Week of June 8, 2026
Jun 8 – Jun 14 · 9 updates
Mostly Platform, AI, Data & analytics
- Pact speaks MCP — connect Claude, Cursor, or any AI client to your CRM
- Agent Orchestrator — multi-agent workflows with explicit handoffs
- White-label embedded analytics — your dashboards on your customers' pages
- A steadier, faster app shell
- Visual workflow automation builder — with a consent gate on every send
- Live Salesforce migration — guided, schema-aware, in-product
- Public Trust Center — compliance status verified from code
- Ask your workspace anything — answers with citations, filtered by consent
- Customer health 2.0 — an ML risk model that shows its work
- NewAIIntegrations & APIPlatform
Pact speaks MCP — connect Claude, Cursor, or any AI client to your CRM
A native Model Context Protocol server: external AI agents can query accounts, contacts, deals, and pipeline — and fire Pact's AI agents — with consent filtering, audit, and cost attribution enforced on every call.
#2026-06-11-mcp-serverWhat changed
Your AI assistant can now work your CRM directly — at
https://api.pact.place/mcp/:- Nine tools, live today —
query_accounts,query_contacts,query_deals,query_pipeline_health,get_metric_explanation,ask_workspace,list_agents,fire_agent, andread_briefing. - Consent-native — every record passes the same consent gate the product enforces; suppressed or withdrawn subjects are filtered out and the hidden count is reported back to the agent.
- BYOK-respecting — contact PII is read through your tenant's encryption keys, never around them.
- An audit row per call — tool, client, argument digest, latency, result count, and what the consent gate hid.
- Cost-attributed and rate-limited — AI tool spend lands in your usage ledger and is echoed in the response; per-tenant and per-tool limits stop runaway agent loops.
- Native OAuth — standard discovery metadata plus Dynamic Client Registration, so MCP-native clients connect with no pre-shared keys. Scoped
pact_live_*API keys work too.
Setup guides for Claude, Cursor, and custom clients: [/integrations/mcp](/integrations/mcp).
- Nine tools, live today —
- NewAIMarketing
Agent Orchestrator — multi-agent workflows with explicit handoffs
Compose Pact's agent roster into multi-step orchestrations: one agent's structured output feeds the next through a declared handoff contract, with gates and forks between steps — and consent + cost enforcement on every one.
#2026-06-11-agent-orchestratorWhat changed
One agent is useful; a chain of them is a process — at
/admin/agents → Orchestrator:- Five prebuilt orchestrations — lead → qualified, stalled-deal rescue, account 360 brief, inbox → action (with branched routing), and inbound funnel health.
- Explicit handoff contracts — each step declares exactly which fields of the previous agent's output it consumes; no prompt-soup between agents.
- Gates and forks — a qualification gate stops the chain on a non-fit; a fork routes an inbox item to support or sales by intent.
- Three new roster agents — account qualification (ICP fit from firmographics + engagement), site optimization (first-party tracking stream), and data validation (a measured SQL profile of your data — null rates, duplicates, out-of-range values — not guesses).
- Yours to edit — installing an orchestration materializes a normal workflow, fully editable in the visual builder. Every step stays consent-gated, cost-attributed, and audit-trailed.
- NewData & analyticsPlatform
White-label embedded analytics — your dashboards on your customers' pages
Embed live, white-labeled Pact dashboards in your own product or customer portal with a signed token — viewers need no Pact login, and consent filtering plus per-view audit hold outside your walls.
#2026-06-11-embedded-analyticsWhat changed
Pact's dashboards can now live anywhere you need them:
- Signed-token embeds — each embed is authorized by a short-lived signed JWT minted by your backend; no Pact accounts for your viewers.
- White-label — your branding on the embedded surface, not ours.
- The guarantees travel with the data — rows are consent-filtered and every view is audited and metered, exactly as in-app.
- Five starter templates and an in-app configurator at
/admin/embedto compose, brand, and preview an embed before you ship it.
- ImprovedPerformancePlatform
A steadier, faster app shell
The post-login dashboard no longer shifts layout while it loads, and a server-side stability fix keeps long-running sessions fast.
#2026-06-11-dashboard-performanceWhat changed
- Layout shift on the dashboard is gone — the welcome hero and KPI strip no longer jump as data arrives; cumulative layout shift on the home and dashboard routes dropped from 0.62 to 0.02 in production measurement.
- Steadier under load — fixed a server-side memory growth pattern that could slow the web app during long sessions, plus a structural watchdog so it can't recur silently.
- NewMarketingSecurity & trustPlatform
Visual workflow automation builder — with a consent gate on every send
Build multi-step automations on a visual canvas — triggers, real branching, test runs, and versioning — and every outbound action checks the consent ledger at execution time.
#2026-06-11-workflow-automation-builderWhat changed
Zapier-class automation, native to your CRM data — at
/admin/workflows:- Visual canvas with real branching — conditions actually fork execution paths, not just filter a list.
- 4 trigger types and 12 actions spanning records, sequences, notifications, and webhooks.
- Test-run mode — execute a workflow against a sample record and read every step's outcome before you arm it.
- Versioning — published workflows are immutable snapshots; edit a draft, compare, then promote.
- Consent-gated by construction — any step that touches a contact checks the consent ledger at execution time and records a
consent_blockedoutcome instead of silently sending. Automation a DPO can sign off on.
- NewData & analyticsPlatformIntegrations & API
Live Salesforce migration — guided, schema-aware, in-product
Connect Salesforce at /admin/migrate and run a guided import that maps accounts, contacts, deals, owners, and consent state — with a dry-run report before anything is written.
#2026-06-11-salesforce-migratorWhat changed
Switching CRMs is the moment vendors fear and we optimize for — at
/admin/migrate:- Schema-aware mapping — Salesforce Accounts, Contacts, and Opportunities map to Pact's model with owner assignment and field history preserved.
- Dry-run first — a full reconciliation report (counts, collisions, unmapped fields) before a single record is written.
- Consent state carries over — opt-in/opt-out status lands in the consent ledger with provenance, so day-one sends are as compliant as day-100 sends.
- Deduplication built in — existing records match on identity, not blind inserts.
HubSpot, Pipedrive, Close, and Apollo importers are next on the roadmap; the CSV importer covers them today.
- NewSecuritySecurity & trust
Public Trust Center — compliance status verified from code
A public /trust page where every framework claim (SOC 2, ISO 27001, HIPAA, GDPR, CCPA) is rendered from the live compliance registry — including the ISO 27001 program's 93 Annex-A controls.
#2026-06-11-trust-centerWhat changed
Procurement teams shouldn't have to take a marketing page's word for it —
/trustrenders from the same compliance registry the product enforces:- Code-backed status — each framework's state (compliant / in progress / available) comes from the live trust-center payload, not hand-edited copy.
- ISO 27001:2022 program — 93 Annex-A controls tracked in-product with a risk register and Statement of Applicability.
- SIG-Lite auto-fill — generate vendor-questionnaire answers from the same control data.
- DSAR, BAA, and sub-processor documentation linked from one place.
- NewAI
Ask your workspace anything — answers with citations, filtered by consent
The workspace answer engine takes a plain-English question and answers from your tenant's data — every claim cited back to its source records, consent-filtered, and logged to the audit trail.
#2026-06-11-workspace-answer-engineWhat changed
Conversational answers over your own CRM data, built the Pact way:
- Citations on every answer — each claim links back to the source records it was derived from; no unsourced assertions.
- Consent-filtered retrieval — records you're not permitted to use never enter the context window.
- Resistant to prompt injection in your data — retrieved content is treated as data, not instructions.
- Audited — every question, answer, and citation set lands in the audit trail.
- Threads: ask a follow-up and the engine keeps the conversation's context.
- NewImprovedSales & CRMAIData & analytics
Customer health 2.0 — an ML risk model that shows its work
Health scoring adds an ML churn-risk layer with per-signal contributions — read exactly which signals moved an account's risk, on a gauge built for the renewal call.
#2026-06-11-customer-health-explainable-riskWhat changed
The transparent weighted health score now has an ML sibling:
- Churn-risk model with per-signal explanations — every score ships with the contribution of each input signal, so "why did this account turn red" has a real answer.
- Risk gauge on account pages and the CS at-risk view — the explanation renders next to the number, not in a data team's notebook.
- The weighted baseline stays — weights you can see and tune live — and both layers are auditable back to source events.
Week of June 1, 2026
Jun 1 – Jun 7 · 16 updates
Mostly Platform, AI, Data & analytics
- Voice notes on every record + Magic Compose
- AI Agents that learn from your corrections
- 73-connector integration marketplace + connection platform
- First-class invoices, refunds, and ASC 606 revenue recognition
- CRM depth — leads, multi-pipeline, cases, approvals, team selling, forecasting
- E-invoice formats, automated tax, ACH and wire reconciliation, polished quote PDF
- Today and Coach now run on real Claude, plus a Campaign Builder agent
- Enterprise SSO and SCIM hardening, signed webhooks, per-tenant rate limits
- Mobile polish — contact view, pipeline, visual builders, and more
- Behind-the-scenes reliability work
- In-context help and inline AI on every control
- AI feature marketplace — public catalogue and admin cost browser
- Eight one-tap sales-velocity dashboard templates
- SOC 2 Type II evidence automation and self-serve HIPAA BAA
- One-click purge of demo data, including seeded emails
- Behind-the-scenes reliability work
- NewAIExperienceMobile
Voice notes on every record + Magic Compose
Dictate a note on any record and Pact transcribes, cleans, and files it — and Magic Compose rewrites any text field in your brand voice with a reviewable diff before anything is saved.
What changed
Two ways to type less and capture more:
- Voice notes — tap the mic on any contact, company, or deal, talk, and Pact transcribes the audio, tidies the filler words, and attaches a clean note to the timeline. Works hands-free in the field on the mobile app.
- Magic Compose — an Apple-Intelligence-style menu on any text field: rewrite, shorten, expand, or change the tone, always in your tenant's brand voice. Changes land as a side-by-side diff you approve or reject — nothing is auto-saved.
Both run on a live model call and respect your AI cost controls.
#2026-06-04-voice-notes-magic-composeTechnical details
1143PR #1143 — voice notes on records + Magic Compose v2
- NewAI
AI Agents that learn from your corrections
Accept, override, or reject what an AI agent proposes — and the agent remembers. A new /agents browser shows every agent, what it did, and how often you trusted it.
What changed
The nine-agent framework now closes the loop:
- Override-and-learn — every agent suggestion can be accepted, edited, or rejected, and that feedback is stored per tenant so the agent's next pass reflects how your team actually works.
- Agent browser at
/agents— a directory of every available agent with a detail page showing recent runs, accept/override/reject rates, and where each agent plugs into your workflow. - Admins get an aggregate trust view to spot which agents are pulling their weight and which need tuning.
No black boxes: you can always see what an agent proposed and why before it touches a record.
#2026-06-04-ai-agents-trust-loopTechnical details
1133PR #1133 — agent trust loop (accept/override/reject + learning)1139PR #1139 — tenant /agents browser + detail
- NewIntegrations & APIData & analyticsPlatform
73-connector integration marketplace + connection platform
A public /integrations directory of 73 connectors, plus an admin connection platform with per-connection field mapping, sync schedules, health, and signed custom webhooks.
What changed
Connect Pact to the rest of your stack without a services engagement:
- Public marketplace at
/integrations— browse 73 connectors across CRM, marketing, data, billing, and support, each with what it syncs and how to set it up. - Connection platform at
/admin/integrations/connections— configure each connection's field mapping, sync schedule, and direction, and watch its health from one place. - Custom webhooks with HMAC-signed delivery for anything not in the catalogue, reusing the same encrypted credential store as the first-party connectors.
#2026-06-04-integration-marketplaceTechnical details
1173PR #1173 — Integrations Wave H: 73 connectors + connection platform
- Public marketplace at
- NewPlatform
First-class invoices, refunds, and ASC 606 revenue recognition
Pact now issues branded invoices and hosted pay pages, handles refunds and chargebacks, and runs an ASC 606 revenue-recognition engine with a CFO month-close and a balanced journal export.
What changed
The quote-to-cash chain now runs all the way through the books:
- Invoices — a first-class invoice object with a branded PDF, a hosted
/p/invoicepay page, and a/sales/invoicesboard. Pay routes to Stripe; Pact never auto-debits. - Refunds & chargebacks — issue a refund with contra-revenue and deferred-revenue reversal handled correctly.
- ASC 606 revenue recognition — point-in-time vs. ratable schedules, a CFO month-close, and a balanced double-entry journal CSV your accounting team can import.
Built on the existing CPQ and order lifecycle — order fulfillment is decoupled from financial status, with an append-only order-events ledger.
#2026-06-04-invoices-revenue-recognitionTechnical details
1146PR #1146 — order lifecycle + ASC 606 rev-rec engine1153PR #1153 — first-class invoice object + hosted pay page1155PR #1155 — refunds & chargebacks + reverse recognition
- Invoices — a first-class invoice object with a branded PDF, a hosted
- NewSales & CRM
CRM depth — leads, multi-pipeline, cases, approvals, team selling, forecasting
A deep wave across the core CRM: a first-class Leads object with scoring and conversion, multi-pipeline deals with configurable stages and gated advance, Cases with SLAs and auto-routing, multi-step approvals, team selling with compensation and record-level sharing, a forecast command center, and a visual behavioral segment builder with real A/B significance.
What changed
Every piece is live and tenant-scoped:
- Leads at
/leads— a first-classLeadobject with lifecycle states, scoring, conversion to account + contact, web-form capture, and round-robin / weighted routing. - Multi-pipeline at
/pipeline— deals are no longer single-pipeline. Define your own pipelines with configurable stages, mandatory entry / exit criteria, gated advance with explicit override audit, per-stage automations, and multi-currency forecast rollup. - Cases (support tickets) at
/cases— case lifecycle with SLAs, auto-routing rules, knowledge-base deflection, and conversion to deal. - Multi-step approvals at
/admin/approvals— branching, multi-step approval processes for discounts, refunds, and any custom object. Builds on the existing single-step framework. - Team selling, compensation, and sharing rules — multi-rep deal participation with per-rep splits, compensation plans (quota and commission), and record-level sharing layered on top of RBAC.
- Forecast command center at
/forecasting— rollup, commit / most-likely / best-case overrides, quota and commission, accuracy tracking, cohort trends, and velocity. - Visual behavioral segment builder at
/segments— live count preview, behavioral predicates (page view, form submit) correlated by contact ID, and campaign A/B tests scored with a real chi-square test (p-value, lift, confidence — tri-state, not a thumbs-up). - Contact 360 — Relationship Strength — a per-contact score on
/accounts/[id]summarizing interaction frequency, recency, and reciprocation across email, calls, meetings, and replies.
Why it matters: the full sales motion now lives in one product — from first lead through close, approvals, support handoff, and forecast — without bolt-on tools.
#2026-06-04-crm-depthTechnical details
1210PR #1210 — Lead management: entity, lifecycle, scoring, conversion, capture, routing1207PR #1207 — Multi-pipeline + configurable stages + gated advance + stage automation1209PR #1209 — Cases + multi-step approval processes1208PR #1208 — RevOps Wave 5: team selling, compensation, sharing rules1206PR #1206 — Forecast command center: rollup, override, quota, commission, accuracy1205PR #1205 — Visual behavioral segment builder + real chi-square A/B significance1201PR #1201 — per-contact Relationship Strength on Contact 360
- Leads at
- NewPlatform
E-invoice formats, automated tax, ACH and wire reconciliation, polished quote PDF
Closes the remaining gaps in quote-to-cash: e-invoice generation in Peppol BIS 3.0, UBL 2.1, and CFDI 4.0; automated tax via Avalara and TaxJar; Plaid ACH and wire reconciliation; and a polished quote PDF with archivable filename and audit certificate.
What changed
- E-invoice formats — Peppol BIS 3.0, UBL 2.1, and CFDI 4.0 generation with a validation oracle. Submission to AP and PAC providers is human-gated.
- Automated tax — pluggable engine with Avalara and TaxJar adapters, exemption support, and a flat-rate fallback when no provider is configured.
- Plaid ACH and wire reconciliation — encrypted Plaid token storage, an exact-match wire matcher on reference + amount (auto-reconcile when both match, manual queue otherwise), and buyer-initiated Stripe ACH.
- Polished quote PDF — branded header, repeat thead on long quotes, signature block, accept / draft watermark, page numbering, archivable filename, and a print stylesheet that matches the on-screen surface.
#2026-06-04-money-path-completionTechnical details
1164PR #1164 — e-invoice: Peppol BIS 3.0 / UBL 2.1 / CFDI 4.01170PR #1170 — automated tax (Avalara/TaxJar) + Plaid ACH and wire reconciliation1138PR #1138 — polished quote PDF with print-stylesheet parity
- ImprovedNewAI
Today and Coach now run on real Claude, plus a Campaign Builder agent
The daily summary on /home is now a live Claude call, three feature classifications were corrected, the brand-voice retrieval that Magic Compose depends on was rewired, and a new Campaign Builder AI agent drafts and optimizes marketing campaigns end-to-end.
What changed
- Today / Coach summary on real Claude — the daily summary on
/homeis a live model call grounded in your own data, not a templated string. Three features that were misclassified as Hybrid were corrected on the public catalogue at/ai-features, which now shows 37 Real, 22 Hybrid, and 0 Not yet AI. - Magic Compose brand-voice retrieval — hoisted into a leaf module so the brand-voice path that was silently dead in Magic Compose is now wired end-to-end. Existing Magic Compose flows benefit automatically.
- Campaign Builder agent — drafts a multi-step campaign (subject lines, body, sends, follow-ups) from a brief and lets you optimize before sending. Lives in
/admin/automationsand on the campaign editor.
Why it matters: every AI feature classified as "Real" actually runs a live model call on every request — and the catalogue is the same registry that powers the in-app honesty badges and a CI gate that blocks any feature shipped as "AI" without a real model call.
#2026-06-04-ai-catalogue-and-todayTechnical details
1136PR #1136 — Today / Coach summary on real Claude + 3 dishonest HYBRID corrections1149PR #1149 — hoist brand-voice retrieval + fix dead path in Magic Compose1163PR #1163 — Campaign Builder AI agent: draft and optimize campaigns
- Today / Coach summary on real Claude — the daily summary on
- NewSecuritySecurity & trustPlatform
Enterprise SSO and SCIM hardening, signed webhooks, per-tenant rate limits
Break-glass admin recovery, SAML group to role JIT, SP-side request signing, the SCIM enterprise user extension, IdP metadata-URL setup with a Workday-tested guide, HMAC-signed webhooks with secret rotation, per-tenant inbound credentials, and a quota-usage dashboard.
What changed
- Break-glass admin recovery — a sealed, audit-logged path back into your tenant when SSO is misconfigured, so you can never lock yourself out.
- SAML group → role JIT — first-time sign-in maps SAML groups to Pact roles automatically.
- SP-side request signing — Pact signs its SAML AuthnRequests so identity providers can verify them.
- SCIM enterprise extension — supports employee number, department, manager, and cost center.
- Metadata-URL setup + Workday-tested guide — paste your IdP's metadata URL and Pact configures the rest. End-to-end tested with Workday.
- HMAC-signed webhooks with rotation — every outbound webhook carries a signature; admins can rotate the signing secret with a grace window so subscribers never miss a beat.
- Per-tenant inbound credentials and quota usage — see exactly which integration is sending what, with rate-limit headroom at a glance.
Why it matters: enterprise admins can stand up SSO, SCIM, and signed webhooks without filing a support ticket, and have full visibility into who's authenticated and what's hitting their tenant.
#2026-06-04-sso-scim-webhooksTechnical details
1137PR #1137 — Enterprise SSO/SCIM hardening: break-glass, SAML JIT, SP signing, Workday1141PR #1141 — merge parallel alembic heads (SSO/SCIM + agent feedback)1144PR #1144 — signed webhooks + secret rotation + per-tenant creds + quota dashboard
- FixedImprovedMobile
Mobile polish — contact view, pipeline, visual builders, and more
Contact view lays out cleanly at 320 px and stops blanking after refresh, the pipeline kanban no longer overlaps cards on tall stages, every visual builder accepts drag-from-palette without crashing, Buyer Lens fits the 4-column channel grid, and pull-to-refresh waits for an intentional gesture.
What changed
- Contact detail page — grid columns constrained so long identifiers no longer overflow at 320 px; the What's-happening card body no longer goes blank after refresh;
$5,000kcurrency rollup formats correctly. - Pipeline kanban virtualization —
measureElementis wired correctly, so deal cards no longer overlap on tall stages. - Visual builder drag-from-palette — every visual builder (sequences, journeys, workflows, custom workflows) now accepts a drag without crashing the canvas. Hardened against WebKit, mobile gestures, agent-built canvases, and empty canvases.
- Buyer Lens — pill wrap and a properly responsive 4-column channel grid that no longer cramps at 320 px.
- Pull-to-refresh — gated on scroll position so accidental pulls during reading don't trigger a refetch.
#2026-06-04-mobile-polishTechnical details
1192PR #1192 — contact detail page grid columns constrained1193PR #1193 — contact identifier values no longer overflow at 320 px1190PR #1190 — What's-happening blank body + $5000k currency rollup1204PR #1204 — pipeline deal cards no longer overlap (virtualizer measureElement)1142PR #1142 — P0: drag-from-palette no longer crashes the canvas1145PR #1145 — harden the drag guard: WebKit + mobile + agents + empty canvas1194PR #1194 — Buyer Lens tab layout: pill wrap + 4-col grid1200PR #1200 — scroll-aware pull-to-refresh gate
- Contact detail page — grid columns constrained so long identifiers no longer overflow at 320 px; the What's-happening card body no longer goes blank after refresh;
- ImprovedPlatform
Behind-the-scenes reliability work
Faster, more predictable deploys: Vercel builds get the headroom they need, and our deploy wrapper refuses unmerged code and pre-flights database migrations. Corrected 2026-08-23: this entry originally also claimed a security-CI improvement that was not one — see the correction below.
What changed
Internal improvements that customers don't see directly but feel as fewer deploy delays and tighter release safety:
- Vercel build headroom — Node heap and twitter-image runtime literals tuned so Vercel builds don't run out of memory partway through.
- Deploy guards — our
deploy.shwrapper refuses to deploy unmergedHEADand pre-flights every pending Postgres migration before the cutover, so a botched release is caught before any user-visible change. - ~~Tighter security CI — the auth-hygiene scanner now recognizes
require_moduleas a valid authorization guard, so the gate flags real issues without false positives that previously blocked unrelated PRs.~~
> Correction — 2026-08-23. The struck-through claim above was wrong, and we are leaving it visible rather than deleting it.
>
>
require_moduleis not an authorization guard. It returns early forowner,adminandapicallers before any check; it no-ops when a tenant'sMODULES_ENABLEDflag is false; and it fails open on any flag-store error. That flag has zero rows in production, so in practice it admitted every caller on every tenant.>
> Teaching the scanner to accept it did not remove false positives — it credited 717 routes as authorization-guarded when they had no authorization check at all, and hid them behind a green summary that has been cited as access-control evidence.
>
> The scanner has since been reworked to classify
require_moduleas fail-open rather than as a guard, and to separate "authenticated" from "authorized" instead of collapsing both into one boolean. Nothing about the product's actual access control changed on 2026-06-04 in either direction; only the reporting was wrong.#2026-06-04-reliabilityTechnical details
1214PR #1214 — unblock Vercel builds: raise Node heap + inline twitter-image literals1213PR #1213 — deploy.sh guards: refuse unmerged HEAD + pre-flight Postgres migrations1212PR #1212 — auth_hygiene scanner recognizes require_module as an authz guard (superseded; see the 2026-08-23 correction above)
- NewDocs & supportAI
In-context help and inline AI on every control
Hover the ⓘ icon next to a control for a plain-language explanation, a Learn more link, and an inline AI answer — without leaving the page.
What changed
A new help layer that sits on top of the existing help bubble:
- Hover, click, or keyboard-focus the ⓘ icon to open a glass tooltip with a short description and a deep link to the relevant docs.
- Ask AI inline — the answer streams back in under two seconds, grounded in the specific control you asked about. If the AI doesn't have enough context, it says so instead of guessing.
- Wired into ten real controls today across API keys, notifications, appearance, and the dashboard, and rolling out to more surfaces every week.
- Touch devices get a full-width bottom sheet so the content never clips a screen edge; the controls without a help entry stay clean — no clutter where there's nothing to say.
#2026-06-03-in-context-helpTechnical details
1121PR #1121 — HelpHover primitive + inline AI Q&A on UI controls
- NewAIPlatform
AI feature marketplace — public catalogue and admin cost browser
A public /ai-features catalogue with honest REAL / HYBRID / not-yet-AI classification, and an admin browser at /admin/ai/features with 30-day spend, per-feature detail, and cost-optimization recommendations.
What changed
Two surfaces, one source of truth:
- Public catalogue at
/ai-features— every AI feature Pact ships, classified as REAL (a live model call on every request), HYBRID (model plus deterministic logic), or NOT YET AI, with the provider, surfaces, and what it does. No marketing fluff; the same registry powers the in-app honesty badges and a CI gate that blocks any feature shipped as "AI" without a live model call. - Admin browser at
/admin/ai/features— card grid with classification chips, search, filters, and sorts; a tenant-wide 30-day spend hero; and a cost-optimization panel with concrete recommendations (model efficiency, large-context warnings, low-usage flags, cache health). - Per-feature detail page with a curated sample input/output, the last 20 anonymized runs, the system-prompt overlay (and whether you've overridden it), where the feature is used in the product, and tailored recommendations for that feature only.
Why it matters: admins can see exactly what every AI feature does, what it costs, and where to tune it — without filing a ticket or reading code.
#2026-06-03-ai-feature-marketplaceTechnical details
1124PR #1124 — AI feature marketplace: classification, cost, per-feature detail
- Public catalogue at
- NewData & analyticsSales & CRM
Eight one-tap sales-velocity dashboard templates
Browse a new gallery at /dashboards/new and clone any of eight pre-built dashboards covering sales velocity, deal aging, win rate, rep ramp, activity, customer success, attribution, and the executive scorecard.
What changed
A new gallery at /dashboards/new with eight category-grouped templates, each composed over real tenant-scoped data and clonable with one tap:
- Sales velocity — weighted pipeline, win rate, time-to-close trend, win rate by source, forecast by category.
- Deal aging — stale deals (>30 days idle), slipped close dates, aging buckets, average age by stage.
- Win rate by source — by source, industry, deal size, rep, and quarter.
- Rep ramp — deals and activity per rep, win rate by rep, tenure.
- Activity intelligence — activity mix, daily volume, per-rep load, sequence engagement.
- Customer success scorecard — health distribution, NPS trend, at-risk accounts, renewals.
- Marketing attribution — first-touch source pipeline and revenue, channel mix, engagement.
- Executive scorecard — ARR, bookings QTD, win rate, coverage, health, NPS plus trends.
Every template inherits the existing dashboard builder's anomaly badges, AI insight summaries, and threshold alerts.
#2026-06-03-velocity-dashboardsTechnical details
1125PR #1125 — 8 sales-velocity templates + /dashboards/new gallery1126PR #1126 — live prod proof against Fly v648
- NewSecuritySecurity & trustPlatform
SOC 2 Type II evidence automation and self-serve HIPAA BAA
A new compliance center at /admin/compliance — a SOC 2 readiness scorecard with automated, tamper-evident evidence bundles for auditors, and a self-serve HIPAA Business Associate Addendum at /admin/compliance/baa.
What changed
Turns Pact's existing controls — tenant isolation, RBAC, append-only audit log, GDPR deletion, sub-processor management, encryption — into systematic, auditor-ingestible evidence:
- SOC 2 readiness scorecard at
/admin/compliance/soc2— per-criterion coverage across all five SOC 2 Trust Services Criteria, with per-evidence-type freshness. - Automated nightly evidence collection for six evidence types (access review, audit-log retention, vendor/sub-processor schedule, customer data deletion, encryption posture, processing-integrity controls). Manual evidence (change management, vulnerability scans, backup-restore test, incident response, tenant-isolation CI gate) is surfaced as an honest gap list with collection instructions — never fabricated.
- Tamper-evident bundles — SHA-256 hashes over every artifact's exact bytes, a manifest hash over the sorted set, and an optional HMAC-SHA256 signature. Verifiable end-to-end; any byte-level edit is detected.
- One-click monthly bundle + multi-period auditor package, each with an auditor-facing index PDF.
- Self-serve HIPAA BAA at
/admin/compliance/baa— preview the addendum with your covered-entity name pre-filled, download a signed PDF with a matching document hash.
Why it matters: enterprise prospects' auditors can be handed a polished evidence ZIP covering every SOC 2 criterion on the spot — and HIPAA-covered customers can self-serve a BAA without going through legal back-and-forth.
#2026-06-03-soc2-hipaa-evidenceTechnical details
1116PR #1116 — SOC 2 Type II evidence automation + HIPAA BAA generator
- SOC 2 readiness scorecard at
- ImprovedPlatformData & analytics
One-click purge of demo data, including seeded emails
Admin → Data management at /admin/seed-data now includes a 'Purge seeded emails' button so you can wipe demo contact emails in one click before going live.
What changed
Every seeded record now carries an
is_seed_dataflag, and the Admin → Data management surface gained a "Seeded emails" card with a DEMO badge and a one-click purge button (with a type-DELETE confirm and an audit-log entry). Use it as part of your go-live checklist to clear the demo emails the workspace shipped with — your real, customer-entered contact emails are never touched.#2026-06-03-seed-data-purgeTechnical details
1122PR #1122 — seed encrypted contact emails + is_seed_data flag + purge switch
- ImprovedPlatform
Behind-the-scenes reliability work
Recurring cleanup of stale preview environments and a daily branch-hygiene sweep — quietly keeping the underlying infrastructure tidy so deploys stay fast and predictable.
What changed
Two internal improvements that customers don't see directly but feel as a faster, more reliable platform:
- Recurring preview-environment cleanup — a unified engine reaps closed-PR preview databases, branches, and deploys on a nightly schedule and after every release, with safety rails that never touch open PRs, protected branches, or anything labeled
keep-preview. - Daily branch-hygiene sweep — automated audit of long-stale branches with a rolling tracking issue, so engineering work stays focused and the deploy surface stays clean.
#2026-06-03-reliabilityTechnical details
1119PR #1119 — unified recurring preview-resource cleanup engine1120PR #1120 — preview-cleanup observability tile + control1123PR #1123 — branch + worktree sweep + daily hygiene cron
- Recurring preview-environment cleanup — a unified engine reaps closed-PR preview databases, branches, and deploys on a nightly schedule and after every release, with safety rails that never touch open PRs, protected branches, or anything labeled
Week of May 25, 2026
May 25 – May 31 · 28 updates
Mostly Platform, Integrations & API, Experience
- Personalized onboarding tours per role
- Smarter search and context-aware navigation
- AI agents you can run on demand or on a schedule
- AI answers honestly, with untrusted-input fencing
- Enterprise security and compliance hardening
- Security hardening and a tenant-isolation gate
- Analytics and dashboards served from a read replica
- Developer hub at /developers
- Microsoft 365 calendar setup wizard
- Calendar credentials read from the right place
- Two-way calendar sync and public booking pages
- Choose your ambient background
- Working light and dark variants for every ambient theme
- Liquid-glass interface, with real blur on iOS Safari
- Redesigned mobile interface
- No surprise keyboard on mobile
- Dashboards that animate, ship with demo data, and clean up
- Lead routing, click-to-call, power dialer, and threaded SMS
- Admin: AI feature inventory and per-feature cost breakdown
- Enterprise controls: audit log, GDPR export, and rate-limit visibility
- Public form sites — drag-and-drop builder with custom-field mapping
- Pact Internal Ops console — card layout, visible actions, mobile-clean
- Customizable page layouts with cascading scopes
- Rate-limit outage hardening: fail-open + visible API reference errors
- Interactive schema explorer for admins
- Schema explorer — intelligent compact toolbar
- Live system status at /status
- Unified API reference at /api-reference
- NewDocs & support
Personalized onboarding tours per role
Guided onboarding tours tailored to your role — CRM, Customer Success, Marketing, or Admin — that start automatically on first sign-in and pick up where you left off.
What changed
Each persona gets its own walk-through of the surfaces it uses daily, anchored to real screens:
- CRM — accounts, contacts, deals, follow-ups, pipeline.
- Customer Success — health, at-risk accounts, playbooks, workload.
- Marketing — sequences, templates, AI steps, forms, attribution.
- Admin — users, integrations, audit log, AI usage, health.
Tours auto-start on first sign-in, resume if you leave mid-way, and can be replayed any time.
#2026-05-30-persona-toursTechnical details
1034PR #1034 — four-persona first-run tours1035PR #1035 — tour resume + replay1037PR #1037 — persona detection + picker
- ImprovedFixedAIExperience
Smarter search and context-aware navigation
Search returns rich, ranked results across every entity, calendar links resolve gracefully, and moving between modules keeps your place.
What changed
- Hybrid search — results are ranked across all entities using keyword and semantic matching together, so the right account, contact, or deal surfaces first.
- Graceful calendar links — calendar URLs redirect sensibly instead of dead-ending in a 404.
- Cross-module navigation — jumping from one module to another preserves your context, with a breadcrumb back to where you came from.
#2026-05-30-graceful-uxTechnical details
1036PR #1036 — hybrid search, calendar redirects, return breadcrumb
- NewAI
AI agents you can run on demand or on a schedule
Four AI agents are live — inbox triage, deal coach, customer-success save, and sequence personalizer. Run them ad-hoc or set them to run automatically on a schedule.
What changed
- Inbox triage — sorts and prioritizes incoming messages.
- Deal coach — suggests the next best move on an open deal.
- Customer-success save — flags at-risk accounts and drafts a save play.
- Sequence personalizer — tailors outbound steps to each recipient.
Trigger an agent yourself, or schedule it to run on its own.
#2026-05-30-ai-agentsTechnical details
1030PR #1030 — AI agent framework + scheduled runs
- ImprovedSecurityAISecurity & trust
AI answers honestly, with untrusted-input fencing
Every AI feature now declines clearly when it lacks enough context instead of fabricating an answer, and untrusted input is fenced off everywhere.
What changed
- AI features return an honest "not enough information" rather than inventing details when context is thin.
- Untrusted input (record content, email bodies, uploads) is fenced from instructions across every AI surface, hardening against prompt injection.
#2026-05-30-ai-honestyTechnical details
998PR #998 — AI prompt-engineering standard + input fencing
- SecurityNewFixedSecurity & trust
Enterprise security and compliance hardening
SSO-required enforcement now actually blocks password sign-in, plus audit-log retention pruning, a downloadable DPA, a cookie consent banner, and a tenant-aware sub-processor list.
What changed
- SSO required is now enforced at sign-in — closing a real gap where password login still worked when SSO was mandated.
- Audit log retention prunes on a schedule per your policy.
- Downloadable DPA — generate and download your Data Processing Addendum as a PDF.
- Cookie consent banner for public surfaces.
- Sub-processor list is tenant-aware and kept current.
#2026-05-30-enterprise-hardeningTechnical details
1032PR #1032 — SSO enforcement, DPA PDF, consent banner, sub-processors
- SecuritySecurity & trust
Security hardening and a tenant-isolation gate
Three critical and three high-severity issues fixed, with a new tenant-isolation check baked into the test suite to prevent regressions.
What changed
- Three CRITICAL and three HIGH severity fixes shipped, including cross-tenant access paths.
- A new tenant-isolation gate runs in the test suite, so a route that derives a record from a request body instead of the auth context fails the build.
#2026-05-30-security-hardeningTechnical details
1001PR #1001 — security fixes + tenant-isolation CI gate
- PerformancePlatformData & analytics
Analytics and dashboards served from a read replica
Analytics and dashboard reads now route to a dedicated read replica, so heavy reporting no longer competes with your day-to-day work.
What changed
Read-heavy analytics and dashboard queries are served from a separate database replica. The result is faster reports and a snappier app everywhere, because reporting load no longer contends with interactive reads and writes.
#2026-05-30-replica-readsTechnical details
1031PR #1031 — replica routing for analytics/dashboard reads1033PR #1033 — replica middleware repair
- NewIntegrations & API
Developer hub at /developers
A new developer hub with quick-starts, SDK code examples, an integration cookbook, and a redesigned webhook subscription console.
What changed
The new /developers hub gathers everything you need to build on Pact:
- Quick-starts for API keys, your first call, OAuth, and webhooks.
- Copy-paste SDK examples in curl, TypeScript, and Python.
- An integration cookbook with end-to-end recipes.
- A redesigned webhook console with delivery health and per-subscription stats.
#2026-05-30-developer-hubTechnical details
1029PR #1029 — /developers hub, SDK examples, webhook console
- NewImprovedIntegrations & API
Microsoft 365 calendar setup wizard
Microsoft 365 calendar sync is now configurable through an admin wizard that mirrors the Google setup flow.
What changed
Connect Microsoft 365 calendars through a guided admin wizard — the same step-by-step flow already used for Google, so there's one consistent way to set up either provider.
#2026-05-30-ms365-calendar-wizardTechnical details
1028PR #1028 — Microsoft 365 calendar admin wizard
- FixedIntegrations & API
Calendar credentials read from the right place
Calendar OAuth credentials are now read from the correct store — no more dead-end asking you to configure them somewhere inaccessible.
What changed
Calendar OAuth credentials now resolve from your workspace's integration credentials, fixing a dead end where setup pointed at a platform store you couldn't reach.
#2026-05-30-calendar-credentials-fixTechnical details
1024PR #1024 — calendar OAuth credential resolver fix
- NewIntegrations & API
Two-way calendar sync and public booking pages
Two-way Google and Microsoft sync, public booking pages at /book/your-slug, round-robin team booking, and automatic confirmation emails.
What changed
- Two-way sync with Google and Microsoft calendars.
- Public booking pages at
/book/<your-slug>so anyone can grab time with you. - Round-robin team booking distributes meetings across a team.
- Confirmation emails are sent automatically on booking.
#2026-05-30-calendar-sync-bookingTechnical details
1002PR #1002 — calendar sync + booking foundation1025PR #1025 — booking seed + not-found handling1026PR #1026 — booking routing1027PR #1027 — public scheduler proxy
- NewExperience
Choose your ambient background
Pick an ambient theme at /settings/appearance — Aurora, Ocean, Rainfall, Fireplace, Forest, Snowfall, Cosmos, or Minimal — with a mobile override that works.
What changed
Set the mood of your workspace from Settings → Appearance. Eight ambient themes — Aurora, Ocean, Rainfall, Fireplace, Forest, Snowfall, Cosmos, and Minimal — each tuned for performance, with a mobile override that actually takes effect on phones.
#2026-05-30-ambient-backgroundsTechnical details
1008PR #1008 — ambient background system + picker1009PR #1009 — mobile override + performance caps
- FixedExperience
Working light and dark variants for every ambient theme
All eight ambient backgrounds now render correctly in both light and dark mode, instead of washing out or going blank.
What changed
Every ambient theme now has a proper light and dark variant. Previously some were eye-searing in light mode or blank in dark mode; each is now tuned for both.
#2026-05-30-light-dark-variantsTechnical details
1020PR #1020 — light/dark variants for all ambient themes
- NewFixedExperience
Liquid-glass interface, with real blur on iOS Safari
A liquid-glass surface system across the app, and a fix so iOS Safari 17 and earlier get real blur instead of a flat panel.
What changed
- A consistent liquid-glass surface system across the app's panels and sheets.
- Fixed a build step that was dropping the
-webkit-blur prefix, so iOS Safari 17 and earlier now get true frosted blur rather than a flat fallback.
#2026-05-30-liquid-glassTechnical details
1003PR #1003 — liquid-glass surface system1006PR #1006 — preserve -webkit-backdrop-filter in built CSS
- ImprovedMobileExperience
Redesigned mobile interface
Mobile gets a transparency-led redesign — tinted glass cards, a soft veil for legibility, and a coordinated action-button stack so Help and AI no longer overlap.
What changed
- Tinted glass cards and a gaussian veil keep content legible over ambient backgrounds.
- The floating action buttons (Help and AI) are now coordinated into one stack instead of colliding.
#2026-05-30-mobile-glassTechnical details
1014PR #1014 — mobile glass cards1018PR #1018 — tinted glass + veil1019PR #1019 — coordinated FAB stack
- FixedMobile
No surprise keyboard on mobile
Mobile pages no longer pop the on-screen keyboard the moment they load — only when you explicitly tap a search field.
What changed
Inputs no longer steal focus on page load on touch devices, so the keyboard stays down until you actually tap a field. The command palette still opens the keyboard, because there you asked for it.
#2026-05-30-mobile-no-autofocusTechnical details
1009PR #1009 — disable autofocus on touch1011PR #1011 — keyboard only on explicit tap
- NewImprovedData & analytics
Dashboards that animate, ship with demo data, and clean up
Dashboards animate on load, new workspaces start with pre-populated demo dashboards, and admins can wipe the demo data when they're ready.
What changed
- Dashboards animate on load — staggered cards, count-up metrics, an anomaly pulse, and a fade-in for insights.
- New workspaces get pre-populated demo dashboards so the product looks alive on day one.
- Admins can wipe demo data from Admin → Data management whenever they like.
#2026-05-30-dashboardsTechnical details
1013PR #1013 — dashboard load animations1016PR #1016 — demo dashboard seeder + is_seed_data flag1017PR #1017 — admin demo-data off-switch
- NewSales & CRM
Lead routing, click-to-call, power dialer, and threaded SMS
A sales-operations suite: lead routing, click-to-call and a power dialer, threaded SMS, AI call transcripts, and a mobile dialer.
What changed
- Lead routing assigns inbound leads to the right rep.
- Click-to-call and a power dialer for working a list fast.
- Threaded SMS keeps text conversations in one place.
- AI call transcripts capture and summarize calls.
- A mobile dialer for selling on the go.
#2026-05-30-sales-opsTechnical details
999PR #999 — lead routing, dialer, SMS, call transcripts
- NewPlatformAI
Admin: AI feature inventory and per-feature cost breakdown
Two new admin pages — one for auditing every AI feature in Pact (real vs. hybrid vs. not-yet-AI), and one for breaking AI spend down by feature and by user with a 1/7/30/90-day window.
What changed
/admin/ai/inventory
A sortable, color-coded table of all 32 audited AI features Pact ships. For each feature: the feature ID, display name, classification (REAL 14 · HYBRID 17 · NOT YET AI 1), provider, endpoint, and the UI surfaces it appears on. The same registry powers the public "Powered by Claude" honesty badges and a CI gate that fails any PR which lets a feature ship as "AI" without a live model call.
/admin/ai/cost-breakdown
Per-feature AI spend with a nested per-user drill-down. Filter by user and by time window — last 1, 7, 30, 90 days, or all-time. The view reads the raw AI usage ledger directly, so feature totals reconcile exactly with their per-user rows; no rounding, no double counting.
Why it matters: admins can answer two questions on the spot — *"which of my users is driving AI cost?"* and *"how real is each of the AI features we're paying for?"* Both pages are admin-only and recover work from two earlier chips that died mid-merge.
#2026-05-28-admin-ai-inventory-and-costTechnical details
41a264f5PR #935 — AI inventory + per-feature/per-user cost dashboard (recovery)
- NewPlatformSecurity & trust
Enterprise controls: audit log, GDPR export, and rate-limit visibility
A pass over the enterprise hardening surface to close the remaining gaps in the admin audit log, the GDPR self-service export, and the per-tenant rate-limit dashboard.
What changed
What's now in admin
This release closes the last small gaps in three enterprise controls that already shipped most of their functionality earlier in the quarter:
- Audit log at
/admin/audit-logand/admin/security/audit-log— searchable, cursor-paginated, with before/after diffs on edited rows, source IP, and CSV / JSONL / XLSX export. A watch subscription will notify you when a row matching your filter lands. - GDPR self-service export — your end users can request a copy of their data from
/v1/me/privacy/export; admins manage requests at/admin/privacy. Each export is delivered as a signed-URL ZIP. Deletions carry a 30-day grace period with an email cancellation token, so a tap of a wrong button doesn't permanently lose someone's data. - Rate-limit visibility at
/admin/security/rate-limits— per-tenant policies, per-API-key sliding-window counters, and the choice ofblock,log_only, orthrottlemode per route, with sampled audit events. Plan-tier defaults are pre-loaded.
Why it matters: customers on enterprise plans now have one admin surface that answers *"who did what?"*, *"can my users get their data?"*, and *"what's hitting my API right now?"* — without needing to file a support ticket.
#2026-05-28-enterprise-controlsTechnical details
a5f2e3d4PR #937 — gap-close on audit log / GDPR export / rate-limit visibility
- Audit log at
- NewMarketingSales & CRM
Public form sites — drag-and-drop builder with custom-field mapping
Build a hosted lead-capture form in minutes — drag-and-drop builder, starter templates, and one-click mapping from form fields onto custom contact and account fields. Submissions land in your CRM with full consent.
What changed
What changed
A new admin surface —
/admin/forms— replaces the old "embed this iframe and pray" workflow.- Drag-and-drop builder — every field type you'd expect (text, email, phone, dropdown, radio, multi-select, consent checkbox, hidden tracking fields) drags onto a live preview. Reorder, duplicate, or delete with a single click.
- Custom-field mapping — fields you've defined under Admin → Custom fields show up directly in the builder. A new lead-capture field can be wired into the form, mapped to the contact column, and live within the same minute.
- Starter templates — common shapes (Contact us, Demo request, Newsletter signup, Event RSVP, Beta access) come pre-built so you don't draw from a blank page.
- Hosted form sites — every form gets a public URL on
pact.place, mobile-first, your branding, no iframe required. Embed it as a link, drop it in a marketing email, or share it on social.
Why it matters
Forms are where customers tell you they want to talk to you. Until this PR, you needed an engineer to ship a form change. Now any marketer can build, publish, and edit a form without leaving Pact — and every submission lands as a contact with consent recorded, so the marketing engine can take it from there.
#2026-05-28-form-sitesTechnical details
ed2c9ed1PR #952 — feat(forms): public form sites with drag-drop builder + custom field mapping + templates
- ImprovedPlatformMobile
Pact Internal Ops console — card layout, visible actions, mobile-clean
The internal staff console at /pact-admin got a polish pass: mobile-friendly card layout for tenants, action buttons that are actually visible, meaningful empty states instead of blank panels, and a relative-time bug fix that was making rows look stale.
What changed
What changed
The Pact Internal Ops console (
/pact-admin, gated tois_pact_staff) was a feature-complete but rough surface. This change makes it usable on the phone and honest in its empty states.- Tenants page (
/pact-admin/tenants) — switched from a too-wide table to a mobile-first card layout. Each tenant card shows the things ops actually scans for (plan, status, last activity, support flag) without horizontal scrolling at 375px. - Visible actions — "Impersonate", "Suspend", and "Open billing" used to hide behind a triple-dot menu that nobody discovered. Primary actions are now buttons; the rare ones stay in the menu.
- Meaningful empty states — Trials, Backups, and Health used to render a blank panel when the underlying list was empty. Each now says what the panel is for and how to add something to it.
- Relative-time fix — the "Last active 2 hours ago" string was misreading the timestamp on
/pact-admin/tenantsand/pact-admin/trials, making every row look stale. The sharedfmtRelative/formatRelativehelper has been fixed and the call sites unified.
Why it matters
The Internal Ops console is the surface our team reaches for during an incident — usually from a phone, away from a desk. A console that requires a laptop is a console that nobody uses.
#2026-05-28-pact-internal-opsTechnical details
7e168d9bPR #955 — fix(staff): Pact Internal Ops + staff surfaces — card layout mobile, visible actions, meaningful empty states, relative-time bug
- Tenants page (
- NewPlatformData & analytics
Customizable page layouts with cascading scopes
Rearrange the dashboard for the whole tenant, a single role, a group, or one user — with a clean cascade, a one-click reset per scope, and a full audit trail for every change.
What changed
What changed
The dashboard now follows a layout owned by you, not Pact.
- Editor at `/admin/page-layouts` — pick the page, pick the scope (default, role, group, user), drag the blocks into the order you want, then save.
- Cascading scopes — when Pact renders the dashboard it walks
user > group > role > tenant > defaultand uses the first layout it finds. Power users can override the org-wide default for themselves; everyone else inherits the layout admins set for them. - Graceful fallback — if your custom layout points at a block that no longer ships (e.g. a removed module), the renderer silently falls back to the next layer instead of throwing.
- Audit log — every layout change is recorded with who, when, and what changed. Roll back from the audit trail without losing other in-flight edits.
What's editable today
Dashboard v1 is the first page on the cascade. More pages (account detail, pipeline, inbox) will follow as we extend the block registry. The contract for adding a new editable page is one entry in
web/src/lib/page-layouts/registry.tsx.Why it matters
Sales leaders, customer-success leads, and product marketers each want a different dashboard. Until now they all looked at the same one and complained. Page layouts ship a real answer instead of "we'll add a toggle eventually."
#2026-05-28-page-layoutsTechnical details
9cb4eefePR #954 — feat(layouts): customizable page layouts cascading scopes + graceful fallback + audit
- SecurityFixedPlatformSecurity & trustIntegrations & API
Rate-limit outage hardening: fail-open + visible API reference errors
Two changes shipped together after the 2026-05-28 outage: the rate-limit backend now fails open instead of taking auth down, and the API reference surfaces fetch errors loudly instead of spinning forever.
What changed
What happened on 2026-05-28
Our Upstash Redis instance hit its monthly request quota at 03:34 UTC. Every Redis command started returning a quota error. The rate-limit dependency propagated that error to FastAPI — which meant every authenticated request, including
/v1/auth/login, returned an HTTP 500. Users were locked out of the app for about fifteen minutes until we switched the counter to an in-memory backend.Fail-open rate limiting
The rate-limit code now wraps every backend call in a guard. If the counter backend errors for any reason — quota, network, missing instance — the request is allowed through (rather than 500-ing), and a degraded-counter metric increments. A WARN line is logged with the error class, count, and route; Sentry tags the request
rate_limit.degraded=true. The next time the counter is unhealthy, on-call gets a notification at the alarm threshold, not an outage at the quota.Normal behavior is unchanged: when Redis is healthy, no warning fires and the counter stays at zero. When the backend genuinely denies a request, callers still get an honest 429.
Loud errors on the API reference
During the outage, the staff and authenticated tier tabs on
/api-referenceshowed an infinite loading spinner instead of an error, because the spec-fetch effect had no timeout or error UI. The fix:- 15-second timeout on the fetch, then a structured error state.
- Four error kinds —
timeout,auth,network,http— each with the right call to action and a "Try again" button that re-runs the fetch without a page refresh. - 401 / 403 prompts you to re-authenticate instead of looking like the docs are broken.
Why it matters: the next time a downstream dependency hiccups, auth stays up and the docs don't lie about it. A full postmortem lives at
docs/incidents/2026-05-28-auth-outage.md.#2026-05-28-rate-limit-resilienceTechnical details
8298ac9aPR #936 — fail-open on Redis errors so quota/network failures don't 500 authb78524efPR #938 — surface API-reference fetch errors visibly instead of infinite spinner
- NewPlatformIntegrations & API
Interactive schema explorer for admins
A live ERD of every Pact table — 185 nodes, 241 edges — with auto-layout, a side drawer per table, tier filtering, and pinch-zoom on mobile. Sits under Admin → Schema explorer.
What changed
What changed
/admin/schema-exploreris a new interactive map of the entire Pact data model.- Auto-layout ERD — every ORM table renders as a card, every foreign key as an edge. The graph (185 nodes, 241 edges in the current snapshot) is computed server-side from
Base.metadata.tablesand served byGET /v1/admin/system/schema-graph. - Side drawer per table — click a node to see its columns, their types, nullability, and the foreign keys leaving and entering the table.
- Tier filtering — toggle the tier chips to focus on just the public surface, the authenticated tier, or the staff/internal tables. Makes it tractable to answer "what does a customer actually see?" in one screen.
- Mobile pinch-zoom — the canvas pans and zooms on touch, so on-call engineers can reason about the model from a phone during an incident.
Why it matters
Until now the schema lived in
models/*.pyand a couple of out-of-date diagrams. Onboarding engineers and customer-facing teams now have a single, always-current ground truth for "what data does Pact actually store, and how is it connected."#2026-05-28-schema-explorerTechnical details
622d9b79PR #947 — feat(admin): interactive schema explorer — auto-layout ERD + drawer + tier filtering + mobile pinch-zoom
- Auto-layout ERD — every ORM table renders as a card, every foreign key as an edge. The graph (185 nodes, 241 edges in the current snapshot) is computed server-side from
- ImprovedPlatformIntegrations & API
Schema explorer — intelligent compact toolbar
Replaced the schema explorer's corner button grid with a single floating pill that holds search, layout picker, multi-select filters, saved views, minimap toggle, zoom cluster, and an export menu. Mobile gets a bottom-sheet variant with safe-area-aware spacing.
#2026-05-28-schema-explorer-toolbarWhat changed
What changed
/admin/schema-explorernow ships a unified intelligent toolbar in place of the previous corner-button grid.- One pill, every control — search (with ranked dropdown), layout (Tree / Force / Grid), filter (tier + multi-select modules with count badges), minimap toggle, zoom cluster, saved views, and export (PNG / SVG / Mermaid / JSON) all sit in a single ≤56 px pill on desktop.
- Search dropdown — fuzzy matcher ranks exact > prefix > fuzzy > column matches, surfaces the module dot and column count next to each hit, and arrow-keys + Enter let you jump-to-node without ever touching the mouse.
- Saved views — name a filter + layout combo ("Sales schema", "Internal admin") and recall it with one click; per-tenant in localStorage with URL deep-linking for shareable views.
- Color-coded modules + edges — each module group gets a stable hue from a deterministic palette so CRM / Marketing / Integrations are visually distinct, and edges color by relation kind (FK = blue, M2M = purple, soft-link = grey).
- PII badge — node cards flag tables whose columns name-match common PII (email, phone, SSN, address) so compliance triage is one glance away.
- Mobile bottom-sheet — the toolbar collapses to a thin bottom pill above the iOS safe-area; tap to expand the full controls in a Sheet that auto-hides the minimap so the controls have room.
- Pinned nodes — long-press / right-click a node to pin it; pinned tables stay visible even when filters would otherwise hide them.
- Visited-node breadcrumb — top-left chip remembers the last three tables you opened so a "where did I come from?" tap is one click.
Why it matters
The corner-grid toolbar from PR #947 was functional but cramped — six controls fighting for space, no search dropdown, no module multi-select, no saved views, no edge color cues. The polish pass aligns the surface with Linear's graph view and Hex lineage — tight on desktop, native on mobile, and intelligent enough that "find a table" or "save my Sales view" is one obvious gesture instead of a workflow.
- NewPlatform
Live system status at /status
A public status page with component health, 90-day uptime, an active and historical incident log, and email + RSS subscriptions — plus an admin console for posting and managing incidents.
What changed
Public /status
The new
/statuspage shows, for everyone, with no sign-in required:- An overall status banner — operational, degraded, or major outage.
- Seven component health rows (API, Web app, Auth, Marketing engine, Sequence engine, Webhooks, Background workers), each with a 90-day uptime sparkline.
- A live list of active incidents and the rolling 90-day incident history.
- A one-field email subscription, plus an RSS feed for IT or status-monitoring tools.
A background health probe runs every minute, records a row per component, and feeds the sparklines without sitting on a shared web connection.
Admin /admin/status
Pact admins and owners get an incident-management console at
/admin/status:- Report a new incident — name, impact, affected components, opening update.
- Post updates as the incident progresses; mark it resolved when it's over.
- Every mutation writes an audit log entry, and the page is gated by the same role checks the rest of
/adminuses.
Why it matters: customers can stop pinging support to ask "is it just me?" — they can see the truth on
/status. And the next incident gets a clean public timeline instead of a Slack thread no one outside Pact can read.#2026-05-28-status-pageTechnical details
96844146PR #934 — /status + /admin/status — recover from chip crash, ship for real
- NewIntegrations & APIDocs & supportExperience
Unified API reference at /api-reference
Three scattered API doc surfaces collapsed into a single in-app page that auto-detects your highest accessible tier and lets you flip between Public, Authenticated, and Pact staff specs.
What changed
One place for the API surface
We had three different ways to browse the API — anonymous
/docs/api, an authenticated/devpage with a staff toggle, and a staff-only/internal-docs/api. Customers had no idea which was which.The new `/api-reference` page lives inside the signed-in shell, replaces all three, and:
- Detects the highest tier your role is cleared for from your session and renders that by default.
- Shows a pill toggle for Public / Authenticated / Pact staff. Pills you can't access stay visible but disabled, with a lock icon and a tooltip explaining what would unlock them — so customers can see that a higher tier exists without being able to peek.
- Honors a
?tier=URL parameter for deep-linking, silently clamped to what your role is allowed to see. - Is wired into the existing Developer nav group: API Reference, API keys, Webhooks.
The old
/devand/internal-docspaths now redirect to the unified surface. The authoritative gate is still server-side: even if someone fabricates the tier param, the OpenAPI proxy returns 401/403 unless the caller is actually cleared for that tier.Why it matters: discoverability. The API reference is now reachable from the in-app sidebar like every other Pact surface, and it always opens at the right depth of detail for who's looking at it.
#2026-05-28-unified-api-referenceTechnical details
73d41a82PR #933 — unified /api-reference with auto-tier + nav entry + sunset /dev and /internal-docs
Week of May 18, 2026
May 18 – May 24 · 13 updates
Mostly Marketing, Mobile, AI
- Powered by Claude badges across AI surfaces
- API reference now renders reliably on every visit
- Marketing surfaces no longer crash when there's nothing to show yet
- PWA: working in-app links, and a 404 no longer looks like a logout
- Sign in works correctly on every phone
- Three-tier API documentation: Public, Authenticated, and Pact staff
- Cleaner top bars on iPhone and Android
- Personalization and send-time windows now run on real AI
- AI agents for research and draft generation
- Bulk operations for accounts and contacts
- Public REST API with API key authentication
- Stripe Checkout, billing portal, and operator billing panel
- White-label branding for agency tenants
- NewAIExperience
Powered by Claude badges across AI surfaces
Every AI feature now wears a small honesty label so you can tell at a glance whether it's calling Claude live, blending Claude with a rule-based fallback, or not yet AI-backed.
What changed
You should know what's actually AI
Three label variants, driven by a single feature registry on the backend:
- Powered by Claude (green) — always calls Claude; errors loudly if the model isn't configured.
- Hybrid: Claude + rules (blue) — calls Claude when configured, falls back to rule-based logic otherwise.
- Not yet AI (red) — surfaces marketed as AI that don't yet make a model call. We're calling that out as honesty debt instead of hiding it.
Each badge has a tooltip with the provider and endpoint, plus a link to "How AI works in Pact" for the longer explanation.
Why it matters: when a screen says "AI", you can now confirm — without reading a docs page — whether that's a real model call or a smart-looking heuristic. No AI feature can over-claim how real it is, because the badge is generated from the same registry the backend uses to enforce live model calls.
#2026-05-24-ai-honesty-badgesTechnical details
d834c2dePR #923 — Powered by Claude / Hybrid badges across AI surfaces
- FixedDocs & supportIntegrations & API
API reference now renders reliably on every visit
Two separate bugs were leaving the API reference panel blank — once on first load, once after navigating inside the app. Both are fixed and proved out under the strict Content Security Policy.
What changed
Two blank-panel bugs, one solved surface
The
/docs/apireference is rendered by Redoc inside a CSP-strict iframe. Two bugs were making it disappear:1. Cross-origin spec fetch. The page tried to load its OpenAPI spec from
app.pact.placewhile sitting onwww.pact.place. The strictconnect-src 'self'blocked the request and Redoc rendered an empty pane.2. Stale Content Security Policy nonce on client-side navigation. When you reached
/docs/apivia an in-app link (rather than a hard refresh), the iframe inherited a CSP nonce minted at the parent's original load — different from the one stamped on the freshly rendered Redoc script. The script was blocked and the panel went blank until you hit refresh.What changed
- The OpenAPI spec is now proxied same-origin from
/api/openapi-public, so the fetch is matched byconnect-src 'self'and triggers no CORS preflight. - The Redoc iframe now lives at
/docs/api/redoc, a dedicated route that mints a fresh per-request nonce on every load — hard refresh and SPA navigation alike.
Why it matters: the API reference is now load-stable. You can click into it from the docs sidebar, refresh, or open it cold from a bookmark — it renders every time, no white pages.
#2026-05-24-docs-api-stable-renderTechnical details
6869e85bPR #922 — serve the OpenAPI spec same-origind74e3793PR #929 — fix stale CSP nonce on client-side nav
- The OpenAPI spec is now proxied same-origin from
- FixedMarketingPlatform
Marketing surfaces no longer crash when there's nothing to show yet
Personalization and Send-time windows could throw a runtime error on fresh tenants when an honest empty response came back from the API. Both now render the empty state cleanly.
What changed
What was happening
When a tenant didn't yet have enough sends or audience signal, the API correctly returned an empty body — and two shared layout components, the module-permissions provider and the "viewing as" header, tried to read array properties off that empty object. The exception bubbled into a render crash that looked like an outage on the Personalize and Send-time windows surfaces.
What changed
Both components now treat an empty payload as "no data yet" instead of dereferencing into it. The genuinely empty states the marketing surfaces already shipped (
No audience yet,Add more sends before we can recommend a window) now render cleanly instead of being masked by a runtime error.Why it matters: new tenants and any segment lacking signal will see the intended empty state from now on, not a blank screen. Existing tenants with data are unaffected.
#2026-05-24-empty-data-crash-fixTechnical details
8f882fd4PR #925 — empty-data crash cascade in ModuleProvider + ViewingAsHeader
- FixedSecurity & trustMarketingMobile
Sign in works correctly on every phone
Two mobile sign-in problems closed: the /login form now centers properly on iPhone and Android, and the Sign in button on the marketing landing is now visible and tap-friendly inside the iOS PWA.
What changed
/login: actually centered now
The sign-in form used
min-h-screen(which resolves to100vh) for vertical centering. On mobile,100vhis the height with the address bar hidden — so when the URL bar is showing, a "centered" card sits noticeably below the visible middle of the screen, and its bottom can clip off-screen. Swapped to100dvh(dynamic viewport height), which tracks the current visible viewport and re-centers as the URL bar shows or hides. Verified on a Pixel 7 (Chromium) and an iPhone 14 Pro (WebKit) emulator.Landing page: Sign in is now discoverable
In the installed iOS PWA, the marketing landing's "Sign in" was rendered as a faint ghost link, crammed against the system status icons because the header had no safe-area inset. Two changes:
- The header now respects the device's top safe area, so the logo and the Sign in button clear the notch and Dynamic Island.
- "Sign in" is now a solid primary button — high contrast, clearly tappable, harder to lose against the status bar.
Why it matters: if someone has the PWA installed and lands on the marketing page, getting back into the app is now an obvious one-tap action. And the sign-in form itself is correctly positioned the first time on every device profile we tested.
#2026-05-24-sign-in-on-every-phoneTechnical details
bd9b54e5PR #930 — /login form dead-centered on all mobile viewports512b71d5PR #931 — discoverable, safe-area-aware Sign in on the landing nav
- NewSecurityIntegrations & APIDocs & supportSecurity & trust
Three-tier API documentation: Public, Authenticated, and Pact staff
The API reference and developer docs are now split into three audience-scoped tiers, so signed-out visitors only see the public surface while customers and Pact staff each see exactly what they're cleared for.
What changed
Why this matters
Until this week, the auto-generated FastAPI spec was served anonymously and exposed every internal route — admin, impersonation, replay-cost — alongside the genuinely public endpoints. The MDX guides on
/docshad the same problem: a single sidebar listed staff-only Self-hosting pages next to the public quickstart.This release closes that gap end to end. Every API route and every docs page is now classified into one of three tiers:
- Public — what anyone on the internet can see.
- Authenticated — what a signed-in customer of your tier sees.
- Pact staff — internal surfaces, only visible to Pact employees.
What you'll notice
- The full
/openapi.jsonand/docs//redocendpoints on the API origin are gone. Three filtered specs replace them:/api/openapi-public,/api/openapi-authenticated,/api/openapi-staff. /docsonly renders public articles to anonymous visitors. Signing in unlocks the authenticated tier; staff additionally see the Administration section.- Search is tier-aware — anonymous search never returns titles or excerpts from gated pages.
- A CI guard blocks any PR that would publish a staff or authenticated MDX snippet through a public surface.
For customers building integrations: if a route disappeared from your reference, it was never meant to be public. Use the in-app API Reference (
/api-reference) to see the routes your role actually has access to.#2026-05-24-tier-aware-api-docsTechnical details
740ce1a6PR #920 — close anonymous full-OpenAPI leak + strip pact-dev CLI pageba604478PR #924 — per-route visibility tags + 3 tier-aware OpenAPI specs4cc98042PR #926 — tier-routed MDX content + tier-aware search + CI leak guard
- FixedMobile
Cleaner top bars on iPhone and Android
Fixed two opposite mobile glitches: the status bar overlapping the menu on iPhone, and a white gap above the icon bar on Android.
What changed
One fix, two symptoms
The top navigation bar handled the device "safe area" (the strip behind the notch, Dynamic Island, and status bar) inconsistently across layouts. That produced two opposite problems on phones:
- On iPhone, the docs header sat *under* the status bar, so the "Menu" label was partly hidden behind the clock.
- On Android, the installed app reserved iOS-only spacing it never needed, leaving a large white gutter above the icon bar.
Both are now resolved with a single rule applied to every sticky top bar — the in-app bar and the docs header alike. The safe-area reservation only kicks in on Apple touch devices that actually need it, so iPhone and iPad PWAs get the right padding while Android and desktop are left untouched.
Why it matters: if you use Pact installed to your home screen, the top bar now lines up correctly on every device — nothing clipped behind the status bar on iOS, no wasted space on Android.
#2026-05-23-mobile-safe-areaTechnical details
bb7dbd8fPR #909 — unified iOS safe-area handling (Android leak + iOS docs underlap)71d6b343PR #908 — Android top-padding regression (iOS safe-area gate leaked)
- ImprovedMarketingAI
Personalization and send-time windows now run on real AI
The Personalization and Send-time windows surfaces now generate every recommendation with live AI — and show an honest empty state instead of placeholder copy when there isn't enough signal yet.
What changed
Real AI, or nothing
Two marketing surfaces used to show stand-in content: Personalization was a "ships next" placeholder, and Send-time windows quietly fell back to a hardcoded "9:30–11am Tue/Wed/Thu" when a segment didn't have much send history. Both are now wired to the same production AI optimizers the rest of Pact uses.
Personalization
Enter a base subject line and Claude rewrites it for each audience segment's dominant role and industry — the exact optimizer that already runs inside journeys. Each suggestion is generated live, and segments that don't change are clearly marked "No change" rather than padded with invented variants.
Send-time windows
Every segment is now routed through the real send-time optimizer (engagement history → tenant default → AI inference). Recommendations are labeled Engagement-backed or AI-inferred so you can see where each window came from. Applying a window rewrites the hour-of-day on every scheduled campaign for that segment.
Honest empty states
When a segment lacks the signal to ground a recommendation — no audience yet, or fewer than 100 delivered emails — you'll see a clear "add more data" prompt instead of a confident-looking number that isn't real.
Why it matters: you can trust what these screens tell you. Every subject line and send-time window is now produced by the same AI that powers the rest of your workspace, and when the data isn't there yet, Pact says so plainly instead of guessing.
#2026-05-23-real-ai-marketingTechnical details
6734650aPR #910 — wire personalize + send-time surfaces to real AIClient
- New
AI agents for research and draft generation
Click the sparkle icon in the top bar to ask AI to research an account, draft a follow-up email, or summarize a contact's history.
#2026-05-22-ai-agentsWhat changed
AI agents
The Ask AI panel (⌘K → "Ask AI", or the ✨ button in the top bar) now supports agentic tasks that go beyond simple Q&A.
Try asking:
- *"Research Acme Corp and summarize their recent news"* — pulls public data and returns a brief
- *"Draft a follow-up email for my last call with Jordan Smith"* — uses call notes and contact history
- *"Which accounts in my book are most likely to churn?"* — scores your pipeline using engagement signals
How it works:
Agents run in the background and stream results token by token. You can keep working while they run. Results are copied to the clipboard or inserted into the editor.
All agent activity is logged in Activity → AI for audit purposes.
- New
Bulk operations for accounts and contacts
Select multiple records in any list view and apply tags, add to sequences, update fields, or export in one step.
#2026-05-22-bulk-opsWhat changed
Bulk operations
List views now support row-level multi-select. Use the checkbox in the table header to select all visible rows, or click individual rows to build a selection.
Available bulk actions:
- Tag — apply one or more tags to all selected records
- Add to sequence — enroll the selection into any active sequence
- Update field — set owner, status, lifecycle stage, or any custom field
- Export — download as CSV in the background; a toast links to the file when ready
- Delete — moves records to the trash (restoreable for 30 days)
Actions run server-side in batches of 100. A progress banner keeps you updated.
- New
Public REST API with API key authentication
Generate API keys from Settings → Integrations to access your Pact data from any external tool or automation.
#2026-05-22-public-apiWhat changed
Public REST API
Your Pact account now has a stable public REST API, secured with per-tenant API keys.
Get started:
1. Go to Settings → Integrations → API Keys
2. Generate a key and store it securely (shown only once)
3. Pass
Authorization: Bearer <key>on every requestFull reference docs at
/docs/api. The same OpenAPI spec powers the built-in API explorer.What's available
- Accounts and contacts — read, create, patch
- Sequences — list, trigger, pause
- Segments and tags — read
- Webhook events for real-time push
Rate limit: 1 000 req/min per key. Raise limits from the API Keys page.
- New
Stripe Checkout, billing portal, and operator billing panel
Pact now ships a full Stripe billing flow: plan picker, Stripe-hosted checkout, Stripe Customer Portal redirect, and a real-time operator billing overview with MRR/ARR and a failed-payment queue.
#2026-05-22-stripe-checkoutWhat changed
What shipped
Plan picker & checkout (/billing/upgrade)
Choose from Starter, Pro, or Enterprise tiers. Clicking "Start Starter" or "Start Pro" opens a Stripe-hosted checkout session and returns you to the billing admin page on success. Enterprise routes to the sales team.
Stripe Customer Portal (/billing/portal)
Tenants can now update their card, download invoices, or cancel their subscription directly from the Pact billing admin page. Clicking "Manage billing" launches the Stripe Customer Portal in-tab.
Operator billing panel (/pact-admin/billing)
Pact staff get a live view of:
- Stripe mode — live / test / unconfigured / no-op
- MRR & ARR — summed from active + trialing subscriptions
- Subscription counts by status (active, trialing, past_due, canceled…)
- Failed-payment queue — tenants in past_due / grace_period / soft_lock with links to their tenant detail page
Anti-abuse guards
Tenants with a
hard_lockdunning state receive HTTP 402 on checkout. Attempting to start a second active subscription for the same plan returns HTTP 409.Go-live runbook
Full step-by-step instructions in
docs/ops/stripe-go-live.md. Set Stripe keys via Admin → Platform secrets — never viafly secrets set. - New
White-label branding for agency tenants
Agency plan tenants can now replace the Pact logo, app name, and sender domain with their own brand across all client-facing surfaces.
#2026-05-22-white-labelWhat changed
White-label branding
Agency tenants on the Agency plan can now configure a fully custom brand identity applied across all client-facing surfaces.
Configurable in Settings → Brand:
- App name shown in the browser tab and email footers
- Primary logo (SVG or PNG, shown in the top bar and sidebar)
- Favicon
- Custom sender domain for outbound sequences (requires DNS verification)
- Accent color for the UI
Branding changes take effect immediately for all sub-tenants managed under your agency account.
Contact your account manager to enable the Agency plan.
Subscribe via RSS · Weekly email digest, if you opt in · Sign in