Everything shipped in the last fortnight is now written down, and the deploy guide explains the step that was being skipped.
Added
The feature list covers this release - reviews with rounds, formats and captions, mindmaps, note sharing and find-in-note, the WhatsApp inbox, the affiliate programme, imports from Airtable and Google Sheets, bulk task archiving, and the indexing rules that keep customer data out of every search engine. Every section count is now reconciled against its own bullets, so the numbers cannot drift from the content again.
The deploy guide explains the schema step, which it never did. It now says plainly that the host's start command must be npm start, what a skipped migration looks like from outside (several unrelated features breaking at once), the three ways to find out in seconds, and how to confirm for yourself that a release cannot lose data before running it.
The troubleshooting tables name the real symptoms - a 500 in the platform console, "Couldn't load your reviews", "Some things didn't load", saved keys showing blank, a broken agency logo - and point all of them at the one cause, with a warning not to press Save on a settings page that is showing blanks.
Every one of these is readable inside the product at Platform Admin - Docs, which renders each markdown file in the repository.
Platform settings showed every saved key as blank when the read failed. It was one Save away from writing those blanks back.
Fixed
The platform settings page showed the Resend key, the Razorpay ids, the R2 bucket and the analytics fields as unset when they were not. The page read the whole settings row; the row could not be read; every field rendered empty, exactly as if nothing had ever been configured. Secrets were never at risk - they are only written when non-empty - but the plain fields were one Save away from being overwritten with those blanks. The page now reads the fields it displays, so it can show a real value or a real error, and never a false empty.
The platform dashboard and the Agencies tab both went down while every other page worked, because both read every column on an agency and one of those columns was new. They ask for what they show now, and fall back when the extra columns are absent.
The Agency tab in Settings did the same thing with the agency's own settings row. It keeps the name, logo, timezone and invoice prefix working even when the newer fields are not there yet.
Reviews was only half-fixed last time. The fallback narrowed the review OPTIONS and left the review itself reading every column, so a database missing the two fields added alongside them still failed before the fallback could help. Both halves drop back together now.
One cause behind five apparently unrelated failures, and a boot check so it can never be silent again.
Fixed
Reviews, Settings, the platform console and Mindmaps all failed after a deploy, for one reason. The database had not received the last release. Every page reading a new column threw, so it looked like four separate features breaking at once - which is the worst way for this to present, because nobody looks for one cause. Reproduced each symptom against a deliberately out-of-date database to confirm it.
The same whole-row read was in nine other places, so it was a class of bug rather than one. Storage, email, payments, AI, platform settings, invoice numbering, workspace signup and two platform actions all fetched every column when they wanted a handful. Each now names what it uses, so a column added by a future release cannot break a reader that does not want it - and npm run verify:schema-safety fails the build if one comes back. The check was tested by reintroducing the original bug and confirming it is caught.
The schema check now runs on every boot, whatever started the app. It was in the start npm script, which a host set to run next start directly skips entirely - and nothing then says the migration was missed. It runs from the framework's own startup hook now, prints exactly which tables and columns are missing and which release added each, and can apply them itself with AUTO_MIGRATE_ON_BOOT=1.
The daily briefing printed raw URLs at you. "1 overdue task - /admin/tasks" - the path was being concatenated onto the end of the sentence. The actions are now links you can click, with the destination attached properly rather than pasted into the text.
The agency logo went blank for a reason that had nothing to do with the image. Five config readers - storage, email, payments, AI and the platform settings - fetched their settings row without naming any columns, so they asked for every column in the model including one this release added. On a database that had not had the migration applied that query threw, the catch swallowed it, and the config read back as unset. Storage therefore looked unconfigured and every uploaded image 404'd. One missing column, and nothing in the chain mentioned a schema. They now ask for exactly the columns they use, so a column added tomorrow cannot break a reader that does not want it.
The agency logo in the header was also skipping the shared image resolver, so it never got the flag the image proxy needs. Every other surface - the portal, intake forms, emails - already used it.
Notes and Reviews stayed blank after a deploy whose schema had not applied. Nothing was ever deleted.
Fixed
Notes appeared to be gone, and Reviews would not load. Neither was true of the data. A deploy had come up serving new code against a database that had not received the new tables - so the note list, which now also reads who a note is shared with, failed as a whole; and the reviews list, which selects every column on a review option, failed on columns added the week before. Both queries now fall back: the sharing badge and the artwork caption go missing instead of the screen.
The reviews query named its columns instead of selecting the whole row. Selecting everything meant every future column silently joined the list of things that could take the page down.
A new check at /api/health/schema says exactly which tables and columns this database is missing, and which release added them. A deploy whose schema did not apply is invisible from outside - the site loads, sessions work, and only the pages touching new columns fail - so the fastest honest answer to "is the database behind" is now one request.
Seven public pages had no header or footer at all. They do now - and finished tasks can be cleared off the list in one go.
Added
Clear finished tasks in one go. The Completed and Archived tabs now have a selection: tick the ones you want, or Select all, and move them together. Archiving one at a time is fine for three tasks and unusable for eighty, which is what a quarter of a busy board looks like. Nothing is deleted - the tasks, their comments and their history are kept, and anything archived can be restored the same way.
Deliberately not on the Active tab. A select-all there is a way to sweep live work off a board by accident, and no screen anywhere answers "where did my sprint go". The API refuses to bulk-archive anything that is not Done, whatever it is asked.
Fixed
The site was running two different designs, and seven pages were running neither. Most pages used one shell; /handover and /project-knowledge used a second one with a different header, button and type scale; and the blog, /security, /privacy, /terms, /roadmap and /updates had no header or footer whatsoever - just a bare column with a "Back to WorkTogethr" text link. Every public page now wears the same chrome, and the second shell has been deleted rather than left to be picked by mistake again.
The blog is the one that mattered commercially. Search traffic lands there first, and it was landing on a page with no navigation at all - nothing to click, no way into the product. It now carries the site header, the footer and the same heading treatment as everything else.
Blog is in the footer, which it never was. It is indexed, canonical, in the sitemap and in llms.txt, and every published post is added to the sitemap on its own.
The affiliate page's questions ran outside the page container and its Apply button was rendering without the primary style. Both were one missing class.
A new check counts the header and footer on every public page, because chrome going missing is invisible in a diff and the first thing a visitor sees. That check is what found the seven.
A partner programme that actually tracks and pays, and a confirmation in front of every delete.
Added
Affiliate and referral programme, at /affiliates. 30% of every payment for the first 12 months on each agency an affiliate brings, a 90-day attribution window, monthly payouts from $50. A separate referral track for existing customers pays a free month per agency instead of cash, so there is no invoicing or tax paperwork for somebody just recommending it. People referred get 20% off their first three months. The numbers are on the page rather than behind the form - a page you have to apply to before learning the commission loses to every page that does not.
The attribution and commission engine behind it. A ?ref link sets a 90-day cookie; a signup made while it is set stamps the workspace with that affiliate, once and permanently; every payment inside the earning window records a commission at the rate it was earned at. First touch wins, so two affiliates can never claim one sale. A commission sits in a 30-day hold before it becomes payable, which covers refunds - so nothing is ever clawed back after it has been paid, and a commission already paid out is never reversed silently.
Applications land in Platform admin as well as by email, with what each affiliate has actually earned: customers brought, payable now, still in the hold, and paid out. Approving an application mints their referral code.
Affiliates is in the header, the footer, and a band on the home page, because a recruitment page nobody can find recruits nobody.
The referral link is emailed automatically the moment somebody is approved. Approving used to mint a code and stop, leaving whoever approved them to copy it into an email by hand - a promise made on the public page and kept only by somebody remembering. The affiliate and referral tracks get different letters, because they are paid differently and one letter hedging both tells each of them half a thing that is not true of them.
npm run verify:affiliates - 32 checks over the whole money path, including the two failures that cost real money: a webhook delivered twice paying twice, and a forged code earning anything.
Fixed
The affiliate page looked like a different website. It was built on the light page shell that /handover and /project-knowledge use, while every page anybody actually arrives on - the home page, pricing, product, features, the solution pages - is on the dark one. So it had a different header, a different button, a different type scale and a different footer to whatever the visitor had just been reading. Rebuilt on the shell the rest of the site uses.
Every delete now asks first, in a real dialog. Eighteen screens used the browser's grey confirm box, which cannot be styled, is unreadable in dark mode and has room for one sentence - so all it could ever say was "this cannot be undone", never what is kept or what the reversible alternative is.
Three deletes asked nothing at all and now do: a pinned review comment, a checklist item on a task, and an idea on a mindmap. The review comment is the one that mattered - it is feedback somebody took the trouble to leave, and the button sits one row from Resolve.
Mindmaps had no visible delete. It faded in only on hover, so it flickered on a trackpad and did not exist on a touch screen, and it was hidden from everyone but the map's author even though the server has always allowed any teammate to remove one, exactly as Notes does.
Who can read a note is now one dropdown, the way Google Docs does it.
Fixed
Sharing is one control instead of three. The visibility picker, the project link and a separate Share button all looked like answers to "who can see this", so all three got used wrong. There is now a single dropdown - Only me / My team / My team and the client / Specific people... - and the last one opens the people picker. Nothing under it needs explaining, because there is nothing left to explain.
The people dialog looks like the one everybody already knows. Search at the top, the people who have access underneath, a small Viewer/Editor dropdown on each row, and a Done button. The three paragraphs about how visibility and sharing interact are gone; a control that needs a paragraph is a control that needed changing.
Viewer is not offered where it would do nothing. On a note your team can already read, adding somebody as a viewer granted no access at all - it only told them. That option is simply absent now, so the only thing on offer is the one that changes something.
Notes and mindmaps use the same four words for the same setting, instead of "Team - my agency" on one screen and "My workspace" on the other.
Seven things that were wrong, including a delete button that has never once worked.
Added
The platform console can delete an agency. Any agency, with its people, clients, projects, files and messages. It asks for the agency's name to be typed first - the server checks that too, not just the dialog - and it shows how many people, clients and projects will go, because from a list of agencies there is otherwise no way to tell an abandoned trial from a live customer. It sits under its own separator, away from Suspend: one of those is reversible and the other is not.
You can close your workspace yourself. Settings → Agency → Danger zone used to end at "please contact support". It now actually does it: type the workspace name, confirm with your password, and the workspace and everything in it is removed - people, clients, projects, tasks, files, invoices and messages - in one transaction, along with the stored files behind them. Before you confirm you are shown exactly what will go, counted, so an empty trial and a live agency do not look the same at the moment of deciding.
Google and Microsoft sign-in can be switched on from Platform → Settings. Paste a client ID and secret and the "Continue with" button appears on sign-in and signup; leave them blank and nothing changes. An environment variable still wins where one is set. The redirect URL you need is shown next to each field.
Files sent in a message can be opened instead of downloaded. Click the name to view a PDF, image or Markdown file in the browser; the arrow beside it still downloads. Previously every attachment went straight to your downloads folder whether you wanted it there or not.
Improved
Your plan's limit is now exactly the number on the pricing page. There used to be a one-time pass: the first time you reached a ceiling, that action was let through anyway. It was meant kindly and it read as a bug - on the Free plan it meant three clients quietly became four, and the refusal turned up on the fifth, so the pricing page, the usage meter and the product itself gave three different answers. Now the third client is the third client. When you reach it you are told what you have used, that nothing you already have is affected, and one specific thing to archive - or the plan that has more room.
Roadmap statuses say what they mean. "Awaiting triage" was showing on requests that had already shipped or been closed, because it described whether an item had been put on the public roadmap rather than what had happened to it. Shipped and closed items now read as shipped and closed, and the separate question - whether it is publicly listed - is its own quiet label.
Fixed
A suspended agency now shows as suspended. The platform console read the subscription's status and ignored the agency's own, so an account you had just suspended still said "Active". Both are shown, and a suspension is what you see first. The same action had a second fault behind it: after writing the change it read back every column of the agency, so on a database a release behind, the suspension would take effect and still report "Failed to update status".
Markdown and text files can be attached to messages..md, .txt, .csv and similar were refused with a generic error because the browser reports no type for them and the check only looked at type. It now falls back to the file extension. Attachments are stored in object storage (Cloudflare R2) and not in the database, so this has no bearing on how large your database gets - the one exception is a workspace with no object storage configured, where they fall back to being held inline.
Deleting an agency works at all. Six foreign keys point at the people table in a way that stops a delete rather than following it, so the platform console's delete has been failing with a database error for any agency with activity in it - reported only as "Failed to delete agency". Those rows are now cleared first, in one transaction, and a check that runs against a real database proves the deleted tenant goes and every other tenant is left byte-for-byte as it was.
Uptime monitoring loads again. The panel was asking the database for two columns that were never added, and failed before it could draw anything.
Draw the shape of a thing before writing it down, find a line in a long note, and let trusted messages become tasks on their own.
Added
Mindmaps. A new screen beside Notes, because a note is bad at the one thing a map is for. Prose records what was decided; a map records what the parts are and how they hang together, and a bulleted outline flattens exactly the shape that is the point. Branches arrange themselves into a tidy tree as you add them, so you are never laying out a diagram when you meant to be thinking. Click a node and press Tab for a child, Enter to rename, Delete to remove; fold a branch away when it is in the way, colour the ones that matter. Switch to Free positioning on a map you want to lay out deliberately, and it keeps the arrangement it had rather than jumping. Filed against a project or a task, the same way a note is, with the same three visibility words - nothing new to learn about who can see it.
Find in a note. Ctrl+F inside a note, or the magnifier in its corner. Highlights every hit, tells you "3 of 17", Enter and Shift+Enter step through, Escape closes. It exists because the browser's own find cannot reliably reach a nested scroller - on exactly the long notes this is for, it would highlight something you could not see. Nothing is edited: the matches are drawn over the text, so searching cannot dirty a note or fire an autosave.
WhatsApp can create tasks without a click. Off by default, and staying that way: the inbox exists because most forwarded messages are not tasks, and a board that fills itself with "thanks!" is one people stop reading. When you have watched the suggestions for a week and trust them, turn it on, set how sure the AI has to be, and say where a task goes when the sender does not match a client. Anything less sure than your threshold still waits for you, exactly as it does now. Everything a rule creates says so on the task, so "why did this appear" always has an answer.
Fixed
Note sharing was findable only by accident. The Share control was an unlabelled icon sitting next to a labelled Private/Team/Client dropdown, so people read the dropdown, concluded that was all the sharing there was, and never found it. It is now a button that says Share, with a count of who has it. The two answer different questions - one is who can see this at all, the other is hand it to a named person - and both now say which.
The people list in that dialog only appeared once you typed. Opening it showed an empty search box and no colleagues. Search is for narrowing a list, not for revealing that one exists.
Every one of these was reproduced against a copy of production and re-run on the same rows after the migration. The migration itself adds nine tables and twenty-six columns and removes nothing - 2,539 rows across 74 tables were untouched by it.
Fixed
Approve & sign-off did nothing and locked the screen. Two separate faults wearing one symptom. The overlay sat above the confirmation dialog, so the dialog opened behind it while its backdrop kept swallowing clicks; and behind that, signing off read back four columns the database did not have yet, which rolled the sign-off back with it. Both fixed - and the sign-off itself was confirmed working against a real production review.
"New round" had the same pair of faults, and the same fix. When the columns rounds needs genuinely are not there, it now says so by name instead of failing silently.
Your client's team list would not load at all. It asked for a sign-in timestamp that only exists after this release, and losing that one field took the whole roster with it. The names come back now whether or not the column is there.
The buttons on a review comment stopped working, including Resolve, which has nothing to do with the feature that broke it. Numbering and assignment are newer than resolving; asking for them unconditionally meant a database without them failed before Resolve could run.
Mindmaps and the WhatsApp inbox returned a bare error. Both now name the table they are waiting on, so the answer is "this site's database is behind" rather than a number.
Meeting notes returned three tasks from an hour-long meeting. The reply was hitting its size limit and arriving cut mid-list, which made the whole thing unreadable - so instead of forty tasks you got a failure, and instead of a failure you got three. A reply that runs out of room is now trimmed back to its last complete task and kept, and the screen tells you the end of your notes may not be in the list.
A WhatsApp connection that could not be read was indistinguishable from one that was never set up. Both showed "not connected". The first is now logged.
Improved
You can see whether a client's team members have ever signed in. Adding somebody to a client's team creates an account with a temporary password, so the account existing has never proved anybody used it. The roster now shows when each person last signed in, or that they never have.
The check that guards against this whole class of bug was itself only looking at two of the twenty-six columns this release adds, and only when a column began its line - so the read that broke the client team list, which was one long line, went straight past it. It now covers every added column wherever it appears, and it was tested by putting the original bug back and confirming it is caught.
Fixed - signup
Nobody could create a workspace from the "Start free" buttons. Every one of them - the site header, the mobile menu, the features page, the link under the login form - goes to /signup with no plan named, and the form then asked the API for a plan called starter, which is not one of ours. Two separate faults turned that into a dead end: the form's built-in default named a plan that does not exist, and the code resolving it treated "that slug is unknown" as "there are no plans at all" - plan?.isPublic !== false is TRUE when there is no plan - so every fallback beneath it was unreachable. The answer was "No plans configured. Contact support." on a database holding eight plans, one of them free and public. Only people arriving from a pricing-page link, which carries a real plan, could get through.
An unrecognised plan now simply means "no preference" and lands on the entry plan. A private plan is never granted by signing up, and the founding lifetime plan is still bought inside the app rather than at signup - both re-tested. npm run verify:plans now fails if the form's default stops naming a real plan, or if that null test comes back.
Signup errors say what happened. A refused signup and a broken one both produced "Something went wrong", because the response was parsed without a guard and the failure to parse it was caught by the same handler. They are now told apart: the server's own reason, a status code, or plainly that the request never reached the server.
Improved
The gap between sections is the same on every screen. It had drifted on four surfaces - notifications, tables, a team member's profile and the platform docs reader - which is exactly the number that never gets fixed, because each one on its own looks deliberate. All 69 page-level surfaces now sit on one rhythm, and npm run verify:spacing fails if one drifts. Deliberately not applied to things that are not stacks of sections: a folder tree still spaces its nodes tightly, and a comment list still reads as a list.
Fixed - the front door
Password reset had stopped working, and said it had worked. The lookup asked for every column on a user, including one this release added, so on a database that had not had the migration applied it threw - and the catch returns the same "if an account exists, a link has been sent" as the success path. Anyone locked out was told a link was coming and none was ever sent. There was no error to see, nothing to report, and no way to tell it from a mail that went to spam.
Signing up failed for three separate reasons, not one. The form's default plan slug named a plan that no longer exists (it was the old name for Studio, renamed without the form being updated); an unknown slug was then treated as "there are no plans at all"; and the writes that create the workspace read their new rows back, including two columns the database did not have. All three are fixed, and signing up was re-run end to end against a copy of the real database.
Forty-five more places had the same fault. Every create, update and delete reads the whole new row back unless told otherwise, so adding a client, inviting a team member, inviting a client's team member, changing a password, completing a password reset and finishing onboarding were all broken in the same way and for the same reason. Each now names the columns it actually uses, defined once so the next added column cannot repeat this.
An affiliate application is no longer lost when it cannot be filed. The table it writes to arrives with this release, so on a database that is behind, somebody who had just written three paragraphs about their audience was told "Could not send that. Try again in a moment." The application is now emailed regardless, marked as not filed, and that email is exempted from the alert dedupe - because when the row did not save it is the only copy.
Added
Leads: who started, and who finished. Signup and the affiliate application now record anyone who got as far as entering an email, whether or not they completed it, under Platform Admin → Leads. Each row carries how many times that person tried and, when the form refused them, exactly what it said - so several people turned away by the same sentence is visible as a warning at the top of the screen rather than something to notice by reading down a column.
This exists because the failures above produced no evidence at all. A form that has stopped working and a form nobody wants look identical from the outside: no new customers, no error reports, no complaints. The password is never sent by the browser and never accepted by the server - an allow-list at both ends, and npm run verify:leads fails the build if either changes.
Changed
Any email provider can create a workspace now. Signup used to reject Gmail, Outlook, Yahoo, iCloud, Zoho, Fastmail, GMX and a dozen others as "not a work email" - which turned away exactly the small agencies this product is for, a lot of whom run on Gmail. It was also not doing the job it appeared to: nothing verified that a domain existed or belonged to an agency, so alex@madeupdomain.xyz was accepted while a real agency on Gmail was not. Whether somebody is an agency is answered by what they do in their first week, not by their mail provider. Throwaway addresses are still refused, because nothing we send can reach one.
The same restriction is off your client intake form. A prospect asking your studio for a quote from a Gmail address was being turned away, and that was your lead, not ours. A personal mailbox is harder to qualify; it is still an enquiry, and a refused one is nothing.
Added
Microsoft Clarity and Hotjar, on the public website only. Paste a project id under Platform Admin → Settings and session replay and heatmaps run on the marketing site. They do not run inside anyone's signed-in workspace, and that is enforced in code rather than left to configuration: a recording of a workspace would be a recording of a customer's own client list, invoices and private notes. A recorder already running when somebody signs in is stopped explicitly, because signing in is a page change and a recorder does not stop by itself. npm run verify:analytics checks the boundary route by route.
Added
You can see where signups come from, including the ones no UTM can catch. Platform Admin → Leads now shows every workspace grouped by the channel that brought it in - and answer engines are highlighted, because that traffic arrives with no utm_source at all. Somebody who asks ChatGPT or Claude for agency software and clicks through used to be filed as "direct", next to people typing the address off a business card, so the channel that might be growing fastest looked like nothing.
Campaign links work as you would expect (?utm_source=, utm_medium, utm_campaign), and where there is no campaign the referring site is recognised and grouped: chatgpt.com and chat.openai.com are one channel, not two, and regional Google domains are one, not nine. A referrer we do not recognise keeps its own name rather than disappearing into "other" - a podcast's show notes sending you traffic is worth seeing.
First touch wins, on a 90-day window, matching the affiliate rule. Somebody found through Claude who returns a week later via a search for your name was found by Claude; crediting the search instead is how a channel that is working gets switched off for looking like it isn't.
Fixed
Affiliate links only counted on five pages. The middleware that sets the ?ref= cookie ran on the homepage, signup, pricing, product and affiliates - and nowhere else. A link to a feature page, a blog post or a solutions page set nothing at all, so the affiliate got no credit and no source was recorded, silently, for exactly the pages worth linking to. It now runs on every page, and new pages are covered on the day they are added rather than when somebody remembers to extend a list.
Added
Sign in with Google or Microsoft. One click instead of a password, on both the sign-in and signup screens. Somebody who already has an account - including one they have only ever used a password with - is signed straight into it, keeping their role, their agency and the display name their colleagues see. Somebody new is asked one question, "what is your agency called", because that is the single thing a login provider can never tell us, and the workspace is created from there.
Both are off until configured, and each button appears only when its credentials are set - so an unconfigured deployment shows the password form alone rather than a button that fails with "client_id is required". Setup is in the deploy guide; it is an ordinary OAuth client, not Google's paid Identity Platform.
The workspace it creates is identical to a password signup's: the same free-forever plan, the same reserved-URL rules, the same affiliate credit, and the same first-touch attribution - so somebody who arrived from Claude a week earlier still counts as having come from Claude.
Fixed
"Failed to create review" said nothing about why. The cause was a database that had not had the current release applied: rounds and formats add columns that a review row cannot be written without, so the insert itself was refused. It now names the missing column and says plainly that it is a pending update rather than a broken button - and the read after the write asks for the columns it uses, so a column added later cannot break creating a review again.
Improved
A development review now asks for a URL, not for pictures of one. Choosing "Development" and then being shown a file picker meant screenshotting the very page the review can load live - so the address was demoted to a secondary field on each row. Paste a staging URL, press Add page, repeat. Each page is rendered at seven widths from 1920 down to 360, and comments pin to the exact spot with the browser, OS and viewport recorded.
Placement and post copy are no longer asked for on a development review. They are design questions - a staging page is not shot for a feed and has no caption to sign off.
A localhost address is called out as you type it. The page is loaded by whoever opens the review, in their browser, so http://localhost:3000 shows them their own machine or nothing at all - and it fails silently, which is how a review gets sent and then reported as broken. The form says so, and suggests a deployed staging URL or a tunnel. Private network addresses get the same warning, and an http:// page is allowed but flagged, because a secure page cannot frame an insecure one.
Fixed
Ten screens answered "Failed to create…" when a required field was empty. Creating a task without a title, a contract without a client, a time entry without a project - each spent a database round trip discovering something the form already knew, then returned a 500 with four words. They now say which field is missing, as a 400. Confirmed by asking every one of them to create something from an empty form.
Logging time without picking a date failed outright. The date defaults to today, which is what somebody logging two hours means; a date that cannot be read is refused with a message instead of a stack trace.
A project created without a description failed, because the column cannot be empty. It now saves, exactly as the form always assumed it would.
Seventy-six places threw away the reason a request failed.catch with no error bound discards the stack, the database error code and the field name - so "Failed to create project" was the entire record of what went wrong, and every one of these had to be reproduced by hand before it could be read. All of them now log. Nothing else changed: same messages, same status codes. Adding the first of them turned a failure that had resisted diagnosis into a one-line answer.
The platform console said "undefined is now on the Studio plan" after an upgrade, and the same on granting unlimited access - two agency lookups had been narrowed to just an id while the code below still read the name and the status. Both now read what they use.
Fixed
A deploy could fail with the wrong explanation. When the host unpacks Prisma's schema-engine binary without its execute bit, the schema step cannot start at all - and the build reported "SCHEMA WAS REFUSED", sending the diagnosis towards database grants and table locks when the database had never been contacted. The three cases are now told apart: the engine could not run, the database could not be reached, and the database refused. Only the last fails the build, which is what it is for.
The engine's permissions are repaired automatically - on install, and again with one retry if the schema step still cannot start. A build that hit this once should not need a human with SSH access the next time.
Every page that names an agency, a client or a project is now unlistable, and a development comment carries the browser it was seen in.
Added
Development reviews record the environment. A pinned comment on a live build now carries the reviewer's browser, operating system, viewport and the exact page, captured automatically at the moment they click. "The header wraps" reaching a developer without any of that is a comment they answer with "works for me", and the thread stalls for two days until somebody mentions Safari. The page URL is pre-filled and editable, because a reviewer who clicked through to another page is the case it exists for. All of it appears in the shared report the developer receives.
Fixed
The app can no longer be indexed by a search engine, on any page. Every authenticated route already redirected a stranger before serving any HTML; now /admin, /team, /client, /platform and everything the API returns - including client files - also carry an explicit noindex header. A page made public by mistake stays unlisted.
Your workspace login pages are unlistable./<your-agency> and its intake form named a customer of ours on a page Google was free to index, and agencies link their own branded login from their own websites, which is exactly how it gets found. Both are now noindex. So are the testimonial walls and embeds, which name clients, and the tokenised review links, which point at unreleased work.
Login, register, setup, password and error screens are out of the index too. They answer to anybody and are not pages anyone should arrive on from a search.
A robots.txt mistake that made three pages permanently un-hideable.Disallow stops a crawler fetching a page - it does not stop the URL being listed, and because the page can never be fetched, a noindex on it can never be read either. Setup and the two password screens were in that state. They are now crawlable and carry a real noindex, which is the instruction that actually removes them.
Marketing pages are unaffected and asserted to stay that way: the suite now checks in both directions, so neither a leak nor an over-broad rule that de-indexes the public site can ship quietly.
The sitemap stopped publishing the customer list, every public page now names itself properly, and the browser is told what it may do with the site.
Added
IndexNow, from the admin panel. Settings now generates the key, shows it, and submits every public page and blog post in one click, so a batch of marketing edits reaches Bing, Yandex and Seznam in minutes instead of waiting to be crawled. The card says plainly that Google does not take part in IndexNow, because a button that means "everyone except the one you care about" is a thing people find out about three months later.
Security headers on every response. HSTS, nosniff, a referrer policy, a permissions policy, and clickjacking protection. The testimonial widget and the public wall keep their exemption, because they are meant to be embedded on your clients' own sites and a security header that breaks a shipped feature is a security header that gets reverted.
llms.txt now indexes the whole public site, not eight pages of it, grouped so an answer engine can tell a product page from a policy page. An assistant that never sees a page cannot cite it.
`npm run verify:seo`. 95 checks against what a crawler actually receives: one h1, a canonical on every public page, valid JSON-LD, the right things in the sitemap and, more to the point, the wrong things out of it. Two audits disagreed about what this site does; nothing about the served HTML had ever been asserted, so every claim had to be checked by hand. Now it is checked on every run.
Fixed
The sitemap published every active workspace. One URL per agency meant the platform's customer list was readable by anyone who opened sitemap.xml, and it put tenant login screens in the search index. Neither was something a customer agreed to. Workspace slugs are gone from it entirely.
The sitemap listed login and register, and left out the product. Eight URLs, two of which were forms nobody should arrive on from a search, while the product, client portal, reviews, AI, features and every solution and trust page were invisible to anything that discovers URLs from a sitemap. All twenty public pages are there now, with real change dates.
Two URLs for the same page./for/marketing-agencies and /solutions/marketing-agencies shipped identical content under identical title tags, which makes the two compete with each other in search. The /for/* pages now redirect permanently to /solutions/*, so links to them still work and only one URL is ranked.
Headlines read as one word to a machine. A line break inside a heading joined the halves together, so "One project.Everything connected." is what a crawler and an AI summariser saw. Fixed across the marketing pages.
Analytics could count every visit twice when Google Tag Manager and GA4 were both configured, which quietly inflates every number you make decisions on. Only one now loads, and Settings says which and why.
Pages without their own title. Signup, handover, project knowledge, privacy, security and terms inherited a generic one and had no canonical.
Approve a story creative in the shape it ships in, compare v1 against v2, and turn forwarded client messages into work.
Added
Reviews know what shape the work is. Every asset was rendered in one wide box, which is right for a website mock and wrong for almost everything else an agency gets approved. Square feed posts, 4:5 portrait, 9:16 stories and reels, 16:9, banners and print now render at their real proportions, so a story is reviewed as a story rather than letterboxed into a desktop frame. The placement is guessed from the file's own pixels when you upload, shown, and changeable in one click.
The caption is approved with the artwork. On a social post the copy is half the deliverable and it was being signed off in a separate email or not at all. It now sits with the creative, on the card and in the review.
PDFs are reviewed page by page. A twelve-page brochure had to be exported to twelve PNGs first, because there was nowhere to record which page a comment belonged to. Pin a comment on page 4 and it comes back on page 4, with the pagination everybody actually thinks in.
Compare two rounds side by side, overlaid, or with a swipe. Rounds made the history keepable; this makes it checkable. "The header is fixed" no longer has to be taken on trust - overlay shows anything that moved as a double edge, and the swipe handle works for a change that covers the whole frame.
WhatsApp forwarding inbox. Connect your own WhatsApp Business number, forward a client message to it, and AI proposes a task with a due date and a priority - which you check and accept, or throw away. The original message is kept on the task, so "who asked for this, in what words" is still answerable six weeks later. Nothing is ever created without a click: the AI says how confident it is and why, because a board that fills with "haha nice one" is a board people stop trusting.
Platform admin can remove a message from the inbox for noise and test forwards. Dismissing keeps the record that it was read and judged; deleting is for clutter.
Fixed
Agency settings no longer return secrets to the browser. The settings API returned the whole row, which was harmless until that row started holding a WhatsApp access token and app secret. It now returns whether each is set and never the value.
Delete your own comment, hear about a review you are on, and find out why an email never arrived.
Fixed
You can remove your own pinned comment. The API always allowed it and there was no button anywhere, so somebody who pinned the wrong thing on the wrong screen could only resolve it - which says "this was dealt with", and it was not. Only ever your own, and the dialog offers resolving instead where that is what you meant. Your own replies can be removed the same way.
Opening a review now tells the agency, not only the client. A team member could put work up for approval and the owner, the manager and everybody else on the project would find out by being told in a meeting.
Responding to a review notifies the person who opened it. This only ever fired when a CLIENT responded, so a designer who put three directions up and had their manager pick one was told nothing - the author was the single person not on the recipient list.
A pinned comment reaches everyone on the review, at a link that works. It went to whoever opened the review and nobody else, at /admin/projects/...?review=... - a path a team member, manager, HR lead or salesperson cannot open, carrying a parameter no screen has ever read. So the one person who did get it landed on the Overview tab and went looking. Recipients are now everyone connected to the work, and each gets a link into their own workspace, on the Reviews tab.
Sign-off tells the people who did the work, not just accounts with the Owner role.
Added
Platform admin can see whether email is actually arriving. Every send, suppression and provider rejection has been recorded since the ledger was built, and nothing had ever read it - so a rejected email left a line in a server log and no trace in the product. Settings now shows what went out today and this month, and the last refusals with the provider's own words. The commonest one is a Resend sending domain that was never verified, which silently refuses every message to anybody except the account holder: exactly the situation that reads as "notifications do not work" when the in-app half is working fine.
Reply to a pinned comment, hand it to someone, refer to it by number, and put up v2 without destroying v1.
Added
Replies on a pinned comment. A pin was one remark with nowhere to answer it, so everything after it - "fixed, try now", "still off on mobile", "that was deliberate, here is why" - happened in email, which is the thing putting the review in the product was meant to end. Guests on the share link can reply too, under the same rule as leaving a pin: a name is required. Resolving still belongs to the agency alone.
Pins are numbered. Every comment gets a number within its round, so "see #3" means something in a call or an email. The number is the pin's own, not its position in the list, so hiding resolved comments never renumbers the rest - #7 is still #7 tomorrow.
A comment can be assigned to someone on the team. A review with twenty pins is a pile until each one has an owner; now it is a work list, and being handed one sends a notification. Client contacts cannot be assigned - they are not the ones fixing it.
Rounds: v1, v2, v3 of the same review. Put up a revision without overwriting the screens the last round's feedback was pointing at. A new round only ever adds: the previous round and every comment on it stay readable forever, and you can switch back to them. Each round carries a note saying what changed, and putting one up tells you how many comments are still open on the one you are leaving - they stay there rather than being moved onto screens they were never about. A signed-off review cannot gain a round, because that would put work after the signature.
Fixed
Nobody can delete or edit somebody else's message, owners included. Deleting another person's message in a project thread was briefly possible for an agency owner. It should not be: a conversation is what people said to each other, not a record the agency owns, and being able to quietly remove a colleague's message changes what people are willing to say. Direct messages were never exposed to admins at all - that is now asserted in the test suite rather than assumed.
Improved
Note sharing asks which kind of access you mean. Picking a person now offers "Can view" and "Can edit" as two buttons rather than a silent default you have to notice and change afterwards, and the existing list says which one each person has. Read-only genuinely means read-only: the note opens with the editor disabled and the API refuses the write.
Notes go to individuals, messages can carry files and be corrected, and a review stops asking you to vote on one thing.
Added
Share a note with one person. Notes could be private (nobody), team (everybody) or client - there was no way to say "just Priya", so showing a draft to one colleague meant publishing it to the whole company. Now you can hand a note to somebody by name, as read-only or with edit access, and they are notified. A share only ever grants access: it can never hide a note from anyone who could already see it, and only the author can share - a note given to a colleague in confidence is not forwardable by them.
Attachments in messages. The paperclip was an icon with nothing behind it - it looked live and did nothing when clicked. It now opens a file picker, takes several files at once, shows what is queued before you send, and a message may be nothing but files. Pictures arrive as thumbnails, everything else as a chip you can download.
Edit and delete your own messages. Fix a typo instead of sending a correction after it. Every edited message is permanently marked "edited" with the time on hover - that mark is what makes editing safe to allow, and it is not optional. You can only ever edit your own words; an admin can delete a message but never change what somebody said.
Day dividers and full timestamps in chat. Every message already showed a clock time, so a thread spanning a week showed four identical "09:14"s with nothing to separate them. Runs of messages are now broken by Today / Yesterday / the date, and hovering any message gives the full date and time.
Improved
A review can hold twelve items, not four. The form assumed one shape - here are a few directions, pick one - and a set of ten screens to comment on hit the cap immediately. You can now attach many images in one go, one item per file, named from the filenames.
Reviews can ask for comments instead of a vote. A new switch on the review says whether it is a decision or a set of work to look at. Where it is not a decision, the vote buttons and tallies are gone entirely, and the card counts comments rather than votes.
Fixed
Pressing Enter in a review comment box now sends the comment. The box had no key handler and no submit button, and the only way to send anything was the Vote button - which needed an option. So on a review with one option there was no way to comment at all: the box accepted the text and had nowhere to send it. Enter sends, there is a visible Comment button beside it, and a comment no longer requires a vote.
A single-option review no longer asks you to vote. It offered "Vote", and once clicked, "Your pick" - a pick among one. Signing off on the one thing on the table is still offered, because approving it is a real decision; voting on it was not.
Airtable and Google Sheets import, paste that keeps its shape, and reviews out of hiding.
Added
Import your CRM leads. The importer now takes a fourth thing: leads, straight into the pipeline. Contact, company, stage, deal value, source, follow-up date and the rest, with the same preview-before-anything-happens and the same one-click undo as clients and projects. A lead with no email yet is matched on name and company instead, so re-importing a conference list does not double your pipeline.
Import from Airtable. Paste a personal access token, pick a base, pick a table, and it arrives - as CRM leads, or as a table of its own with Airtable's own field types carried across. The token is used for that one import and never stored: reload the page and it is gone.
Import from Google Sheets. Paste the link to a sheet shared with "anyone with the link", and the tab comes across. No Google account to connect, no consent screen, nothing held afterwards - turn the sharing back off when you are done.
Paste a block of cells into a table. Copy a selection out of Excel, Numbers or Sheets, click a cell and paste. It says how many rows and columns arrived and what will happen to them before it does anything, adds any columns the paste is wider than the table, and works out each new column's type from the values in it. "Add to the end" is the default, because it is the only option that cannot overwrite anything.
Reviews are in the sidebar. Every approval you have asked for, across every project, with what is still waiting on a decision at the top. They were only ever reachable from a tab inside a project, which is a reasonable place to raise one and a hopeless place to chase one.
Improved
Notes keep the formatting when you paste from Google Docs, Google Sheets or Word. Headings, bold, italic, underline, lists, links and tables now survive; the source document's fonts, point sizes and background colours do not, so a paste looks like the note it landed in rather than like the document it came from. A grid of cells pasted as plain text arrives as a table instead of one run-on line per row.
Em dashes are gone. Every one of them, across the product and these notes, is now an ordinary hyphen.
Fixed
Feedback updates actually reach the person who raised them. Three things were wrong at once. The report status - the column that answers "did you fix my bug" - could not be changed from the platform admin at all, and was never announced. The roadmap stage was announced, but the email went out under a catch-all category that suppresses a second one to the same person within twelve hours, so an update was routinely dropped behind unrelated mail. And the Feedback screen showed only the status, never the roadmap stage, the timing or the note written about it - so a request could be planned, built and shipped without one thing changing on the screen of the person who asked for it. All three are fixed, and the triage screen now says who will be notified before you save.
Finished work stops disappearing, nothing deletes without asking, and notes can hold notes.
Added
Every client now has a History. Notes, links, files, tables, credentials, reviews, contracts and invoices gathered for a client, across every project of theirs, grouped by the phase they came from - with finished phases labelled rather than hidden. Agencies find it on the client record; clients get their own Project history page, filtered to what is genuinely theirs. It is the answer to "what do we already know about them" when a second project starts a year later.
Notes can hold notes. File a page inside another page, up to five levels - a spec with a page per section, a runbook with a page per service. The sidebar becomes a tree you can expand and collapse, an open sub-note shows the trail back up, and you can move a note somewhere else at any time. Deleting a page never deletes what is filed underneath it: sub-notes move up a level, and the dialog says so before you agree.
Images in notes. Paste a screenshot straight from the snipping tool, drag a file in, or use the toolbar. Images are stored with the note rather than linked from somewhere that will stop resolving. Several at once arrive as small thumbnails you can scan - click one for the full size.
Bug reports and support queries now email whoever runs the platform, instead of waiting in a table for somebody to think to look. A screenshot attached to a report is finally shown - it was being uploaded and stored, and displayed on no screen at all.
A "stuck? tell us" form on the login screen. Somebody who cannot get past the login page has no account, so every in-app help route is closed to them. This was built and then rendered on no page, which is why the support inbox was always empty.
Files list shows which project each file belongs to without opening it, and can be sorted newest, oldest, by name or by size - with or without a project filter applied.
The roadmap can be filtered by stage in the platform admin, including "not triaged yet".
Completed to-dos can be cleared in one go rather than one at a time.
Improved
Nothing is deleted without being asked first. Fifteen places used to delete on a single click with no confirmation at all - a table and every row in it, a file, a saved link, a portfolio piece, a testimonial, a leave request, a whole repeating calendar series. Every one of them now asks, in the product's own dialog rather than the browser's grey box, and the wording distinguishes archiving (reversible) from deleting (not). Permanent deletions ask you to type the name.
Clients can no longer be permanently deleted at all. Archiving already does everything "delete" was wanted for and is reversible in one click. A client who comes back after five years is worth more than a tidy list, and the record of what was built for them is what makes the return worth anything.
A finished phase is genuinely finished. Archived projects are now read-only, and say so. Before, everything on them stayed editable - and anything you saved was filtered straight back out of the task list and the briefing, so the work succeeded and vanished. Their notes and tables also leave the working lists, while staying in the client's history.
Restoring a project brings its client back too. Bringing back a project whose client was archived used to leave the project live and the client invisible in every list and picker.
The archive shows what is inside it. Each archived project or client expands to list what it holds, split into what survives a permanent delete and what does not - rather than asking you to take "nothing was lost" on trust.
The formatting toolbar stays put while you scroll a long note, instead of scrolling away exactly when you need it.
Fixed
Links that sent a project manager to "access denied". Several links were hardcoded to the admin workspace - the client name on every project page, the archive, the client history, and the "c" keyboard shortcut. Anyone who is not an admin or a client works in a different workspace, so those links denied access to exactly the people running the projects.
`/team/testimonials` returned 404. The menu offered it to project managers and sales - who are the people meant to collect testimonials - and the page only existed for admins.
Adding several images to a note at once kept only one or two. Each new image replaced the one before it instead of following it.
The share-with-client switch on a table could not be switched on when the table had no client attached, and did not say why. It now explains itself, and a table created on a client's project is attached to that client automatically.
The plans screen listed features per plan, which contradicts how the product is sold - every feature is on every plan and only the capacity differs.
Handbook links that went missing after a deploy are back. None of them were ever deleted: a query started asking for entries with no client attached, so every entry anyone had tagged to a client silently fell out of the list. The tag and the ownership are now separate things, and a repair runs on deploy.
Creating a note from the picker now closes the dialog and opens the note. It was being created correctly and then hidden behind the dialog that should have closed.
A blank page after a deploy now recovers itself. A browser holding the previous build's files could land on an empty page showing only a "Skip to content" link. It reloads once and repairs itself.
The dashboard no longer shows two cards counting the same overdue tasks, and meeting notes sit under the daily briefing where they get used.
Notes, tables and links from an archived project or client now carry an Archived label, so a note from a finished phase reads as one.
The current page is underlined in the site header rather than overlined.
Standups, focus afternoons, the Friday you never work - set them once.
Added
Blocked time can repeat. Daily, weekdays only, weekly, fortnightly or monthly, up to an end date you pick. The dialog tells you how many dates it will book *before* it books them, and each entry says which pattern it came from, so a run of identical days in your calendar reads as deliberate rather than as a bug.
Removing a repeating block asks what you mean. Just this date, this one and everything after it, or the whole series. Cancelling a standing commitment used to mean deleting forty entries one at a time - which nobody does, so the calendar kept showing people as busy for months after the thing had ended.
Repeat times hold across daylight-saving changes: a 9am block stays at 9am, rather than quietly sliding an hour for half the year.
No standing instruction on your card. A reminder, a link, a payment - and only when you decide.
Changed
Subscriptions renew manually. We don’t store your card and nothing is ever auto-debited. A few days before your plan ends you get a reminder with a link; you pay, and the period extends. Renewing early adds time rather than resetting it, so paying ahead never costs you days you had already bought.
Paying for a year costs ten months - and means doing this once instead of twelve times.
Every feature is on every plan, and now there is no mechanism left that could take one away. The product still carried the machinery from when tiers differed by module: the menu hid links your plan didn't cover, ten APIs could answer "Not on your plan", and reaching one of those areas showed an upgrade page. All of it was dormant - every plan already carried every module - but dormant is not gone, and one edit in a settings screen could have switched it on for a paying customer. The menu is now decided by your role alone, and what a plan limits is only how much you can run. White-label is the single exception, and it says so wherever it appears.
Fixed
The plan cards still described a feature ladder. Every feature has been on every plan for a while, but the pricing cards read “Everything in Studio, plus…” and listed the CRM, contracts, invoices, HR and hiring only from Agency upwards. Nothing said those were excluded from cheaper plans - but anyone reading the Free card would have concluded exactly that, at the one moment it matters most. Each card now states plainly that every feature is included, and differs only on how much you can run.
Cancelling on the free plan started a countdown to losing your workspace. It set the subscription to cancelled, which the product read as “access until the period ends, then lock” - so an agency who pressed Cancel on a plan that costs nothing would have lost access about five weeks later, having never paid us. There is now nothing to cancel on a free plan, and it says so.
Checkout could refuse the payment at the last step. A five-minute window had crept into how subscriptions were created, so anyone who took longer than that at the card form - entering contact details, waiting for an OTP - was turned away after doing everything right.
Somewhere to look before you commit, an explanation on every menu item, and a downgrade that tells you what it means first.
Added
A finished project to look at, from day one. New workspaces get Northwind - a sample client and project with tasks part-done, references filled in, and the portal a client would actually see. It is obviously ours, it does not count towards your plan, and one click removes it and everything under it. An empty product cannot show you the part that matters most, which is what happens once a client replies.
Every menu item explains itself. Hover any sidebar entry and it says what it is and why you would bother, a line each. Now that every module is on every plan, a two-person studio meets Handover, Hiring and the Partner Vault on day one - and a label is not an explanation.
Pin the parts you use. Any sidebar item can be pinned to the top. Saved to you rather than to your browser, so it follows you to another machine - an account manager and a designer want different four things.
Downgrade preview. Before moving to a smaller plan you see exactly which allowances you are above, with your own numbers, and we state plainly that nothing is deleted, hidden or archived. Everything keeps working; you simply cannot add more of those until you are back under.
You are told when we let one through. The first time your workspace passes a ceiling it did not know was there, the action still goes through and the owners get a note saying so. The person publishing the thirty-first review this month is rarely the person who can change the plan.
Changed
Moving to a cheaper plan no longer sends you through checkout. It moves your existing billing across instead, so you are not re-entering a card in order to spend less.
The pricing page publishes every allowance now, not four headline numbers - review cycles, tables, rows, prospects, contracts sent, testimonial requests, published reviews and candidates, across all four plans. The table is generated from the same catalogue the product enforces, so the page cannot advertise one number while the button refuses at another.
Fixed
Two claims on the pricing page were simply untrue. It answered a question about "when my 14-day trial ends" - there is no trial and never has been. And it said the Partner Vault was part of Scaled and the lifetime deal, when it is on every plan including Free. Both are now checked by the build.
A check of our own that had never once run. An invisible character had got into one of our tests, so a rule about how we are allowed to describe invoicing was silently testing nothing. Every source file is now scanned for that class of mistake - it had happened twice, and both times looked perfectly correct on screen.
No feature is behind a tier any more. What a plan buys is capacity - and now you can see exactly how much of it you are using.
Changed
Every feature is now on every plan, including Free. CRM, contracts and e-signatures, invoices, hiring, 360° reviews, time off, HR documents, handover packs, analytics, tables, AI - all of it, on every tier. You should be able to find out whether the thing works on your own clients before deciding whether to pay for it, and a locked button tells you nothing. What a plan changes is how much you can run, not what you are allowed to open. White-label branding remains the one paid exception.
A ceiling now reads as a milestone, not a failure. When you reach one, we say what you achieved - "you have used 25 of 25 active clients" - and promise the part that actually matters: everything you already have keeps working exactly as it is. Nothing is hidden, locked or deleted. Where you can free up room without paying, we say how.
Added
A Usage page, in Settings. Everything your workspace is running against everything it is allowed: people, clients, projects, storage, AI actions, review cycles, tables and rows, prospects, contracts sent, testimonial requests, published reviews and candidates. Monthly allowances say when they reset. Everyone on your team can see the numbers; only an owner sees the route to change the plan - being stopped without being able to see why is the worst version of a limit.
Warnings before the wall. Meters turn amber at 90%, and the last stretch of a cap is shown where the work happens rather than only on the billing page.
One free pass per limit. The first time your workspace meets a ceiling it did not know was there, the action goes through anyway. A client-facing workflow should not stop dead on a number nobody had seen.
Fixed
The founding lifetime plan was about to be given away. An internal change would have granted every lifetime buyer unlimited clients and 5,000 AI actions a month - on a plan sold on exactly the opposite promise. The bounds it was sold with (40 clients, 400 projects, 50 GB, AI on your own key) are now asserted by the build.
The billing page and the create buttons could disagree. Usage meters were built from a different query than the limits actually enforced, so a page could show room while the button refused. There is now one source for every allowance, and a check that fails the build if a meter and a limit ever drift apart.
Running out of allowance no longer looks like being denied access. It used to render with the same padlock as "you don't have permission", which sent people hunting for a setting or asking an admin for access that would not have helped.
A clearer front door for clients, project templates, and invitations that no longer email a password.
Added
Clients now land on what needs them. A client was emailed because somebody needs something - a review looked at, a contract signed, work approved. That request now sits at the top of their portal with the reason it matters, in the order of what it costs to leave: contracts block everything, reviews block the work, approvals are the smallest ask. When nothing is waiting it says “You’re done for now” and stops.
Project templates. SaaS product design, website design, website development, SaaS development, design system, monthly retainer - or start empty. Each adds the first five or six tasks that genuinely come first, not forty you have to delete.
Changed
Invitations no longer email a password. Your client gets a one-time link and chooses their own, and the link expires after a week. A password sent by email sits in an inbox for years, never expires, and is usually reused from somewhere else - none of which is true of a link that is spent the moment it is used.
Import from whatever you use now, see exactly what will happen first, and undo it if it was wrong.
Added
Import and migration. Clients, projects and tasks from a CSV. Download our template, paste your export into it, upload. We recognise the usual column names other tools use - “Company Name”, “Task Name”, “Due” - so you rarely need to rename anything.
You see exactly what will happen before anything is created. How many rows will import, which are already in your workspace, and which need fixing and why. The preview and the import run the same checks, so what it promises is what you get.
Every import can be undone, and undoing removes only what that import created - anything you have added since is untouched.
The rows that did not work come back as a spreadsheet with the reason attached, so you can fix them and re-upload rather than hunting for them yourself.
How it deliberately behaves
Columns we have nowhere to put are left out, and we say which. We do not invent a field to hold another tool’s data or quietly stuff it into your notes.
Duplicates are skipped, never merged. Merging would mean deciding whose version of a phone number wins, and getting that wrong overwrites something you typed.
Dates like 03/04/2026 are refused rather than guessed - that is two different days depending where you live, and guessing puts work in the wrong month.
A menu that leads with the work, a checklist that gets a real project in, and honest wording on invoices.
Changed
The menu now leads with the work. Home, Projects, Tasks, Clients and Messages sit at the top; everything else is grouped underneath as Project knowledge, Agency growth, Agency operations and Administration. It used to be Overview / Work / People / Finance, which told you how we had organised our code rather than how you run an agency.
Invoices are described honestly. The screen now says what it is: a record of what you invoiced and what was paid. It does not collect money and it is not accounting or tax software - an agency that assumed otherwise would find out at the worst possible moment. The word "invoicing" is gone from the landing page for the same reason.
Added
A first-project checklist on the dashboard. Six steps, each explaining *why* rather than just what: add a client, create a project, put something in it, invite someone, do something real, come back this week. It disappears once you have done all six, and you can dismiss it at any point.
Conversations are now a project tab, so all eleven parts of a project live in the project.
Overview, Files, Time and Activity join the project tabs, behind a header that stays put.
Added
A project header that follows you. Name, client, status, progress, project manager, what is due next - pinned to the top whatever tab you are on. It also shows what is sitting with the client, which was previously invisible unless you went looking. A review waiting a fortnight for an answer is the most expensive thing that can quietly happen to a project.
Projects now open on Overview, which leads with *what needs you on this project*: overdue first, then what is waiting on the client, then work in review, then anything nobody is assigned to. The old landing card showed budget and dates - true, and not what anyone opens a project to find out.
Files, Time and Activity are now project tabs. Everything on a project can be reached from the project, rather than from a global list you have to filter. They are the same screens as the global ones, locked to the project, so the two can never disagree about what a file is.
A project's own history. Activity records now remember which project they happened on, so a project can show its own timeline instead of you reading the whole agency's.
Handover notes were arriving as one run-on line. So were twenty-six other things.
Fixed
Anything you type across several lines now reads the way you wrote it. Handover notes were the reported case, and the worst one - credentials, logins and “2FA is on Priya’s phone”, all run together into a single paragraph for whoever picks the project up months later. The line breaks were always saved; they were being thrown away on the way to the screen.
The same fault was in twenty-six other places, all now fixed: client addresses, team bios, HR document notes, company policies, performance reviews, the reason on a time-off request, client briefs, feedback, roadmap notes, testimonials, project and task descriptions, AI summaries and the daily briefing.
Where text is deliberately clipped to one line - a compact feed, a card preview - it still is. That is a design choice, not the same bug.
We were hiding our best arguments behind the purchase they were supposed to cause.
Changed
The CRM, contracts, invoices, HR, reviews and hiring are now on every plan - including free. They used to start on Agency or Scaled. The reasoning was ordinary and, on reflection, wrong: a feature nobody can try is a feature nobody can miss. An agency on the free plan never discovered the thing also did contracts, so contracts never became a reason to pay for anything.
Plans now differ by size, and nothing else. Three active clients on free, 25 on Studio, 100 on Agency, unlimited on Scaled. That is the whole difference. "Pay when you win your fourth client" needs no explaining; "pay to unlock the CRM" always did.
The one exception is full white-label. Your portal carries your logo on every plan; Scaled removes our name from the emails, the login page and the intake forms too. Nobody needs to *try* having their branding removed to know whether they want it, which is exactly why it is a fair thing to charge for and the CRM was not.
The message when you reach a limit used to read "Your current plan allows up to 3 teammembers." It now says what you achieved before it says what to do.
Added
Test accounts arrive with real work in them - three projects, ten tasks, a prospect, assigned across the personas. An empty workspace looks identical whether a role is working or being silently refused, which made it useless for checking exactly the thing it existed to check.
Fixed
You can file a document against someone's record again. The People → Documents tab listed documents and offered no way to add one - the feature was finished on the server and missing from the screen.
The Notes page called itself Documents in six places, including the search box, left over from the rename.
The landing page claimed four different numbers for the same thing - ten tools, six subscriptions, four logins, eight tools - depending which section you read. It is four subscriptions everywhere now, which is the one with the arithmetic behind it.
Seven review widths, screenshots pasted into comments, and a shareable write-up of the lot.
Added
A feedback report you can send someone. Every pinned comment, beside a picture of what it is about, with the marker on it - numbered, grouped by screen and by device, and printable to PDF. It opens from a link with no account, so the developer who has to fix the header never needs a login. Works for design and development reviews alike.
Paste a screenshot straight into a comment. Ctrl+V while you are writing it. This is the only way a live staging page can carry pictures into the report: a page loaded from another server is sealed off from us by the browser, deliberately, so we cannot photograph it for you.
Seven screen widths instead of three - 1920, 1440, 1280, 1024, 768, 390 and 360. Chosen for where layouts actually break rather than for named devices; 360 is where text wrapping fails first, and 1920 is the one nobody checks.
Where no screenshot was attached, the report says so and gives you the URL, the width and the position, rather than showing an empty frame.
Fixed
Comments left on the new narrow widths were being filed as desktop comments. The screen picker offered seven, the server only recognised the original three and quietly rewrote the rest - so "this only breaks on a small phone", the single most useful thing in the comment, was lost on the way to the database. Nothing errored; the comment simply described the wrong screen.
We walked all ten roles through every screen in their sidebar. Sixty-odd doors were locked from the inside.
Fixed
HR and Sales were shut out of ordinary staff tools. Neither could open the calendar, files, the handbook, time tracking or messages, and Sales could not open analytics - all things they are plainly meant to use. The links were right there; the pages just came back empty, because the permission lists behind them were written before those two roles existed.
Your HR lead could not book their own holiday. They could open the time-off page and see the button. Submitting was refused. In the HR tool.
Clients were being offered pages that were never theirs - the agency's internal handbook, its time tracking and its testimonial pipeline. The link appeared and then led nowhere, which reads as something broken rather than as an area that was never for them.
62 more permission lists across 45 files had the same gap and have been widened. Deliberately narrow ones - billing, settings, anything for owners only - were left exactly as they are.
Added
A check that walks every role through every screen and fails the build if the product offers someone a link that answers nothing. It signs in as all ten roles for real, opens each page their menu offers, and tries the things they need to actually do - like blocking out time or requesting leave - rather than only checking the page loads.
One renamed role, 138 stale permission checks, and a pile of bugs that all turned out to be the same bug.
Fixed
Your project manager, HR lead and salespeople were missing from places they belong. When we split the old “manager” role into Project Manager, HR and Sales, 138 permission checks across 86 files went on naming the role that no longer existed - so those three roles were silently refused. It never threw an error; the screen simply came back empty. Reported separately as: the assignee dropdown missing your PM, three roles unable to delete their own time-off request, and most of the agency unable to open the Portfolio. All one cause, all fixed, and a check now fails the build if the dead name comes back.
Assigning someone a task now puts them on the project. It used to do only half of that, so a new starter could hold three tasks and still see an empty Projects tab - including the project their own tasks were on. Existing assignments are repaired automatically. Removing someone from a task does *not* remove them from the project; they may be on other work there.
The Portfolio is now open to everyone on staff, not just admins. It is the work they did.
Profile pictures came out blurry. Avatars were being shrunk with settings meant for bulk file uploads - too small, then cropped to a circle, then shown on a high-resolution screen. They are now sharp, and still tiny to store.
Your blocked time list scrolls. It grew with every entry, pushing the rest of the page down and putting the older entries out of reach.
Time off can be deleted, not only withdrawn. Withdrawing keeps the record, which is right once someone has seen it. A request nobody has acted on yet is a typo, and can now just be removed.
The performance review year is no longer capped at this year. You can set one up for next year, and on 1 January the review everyone was mid-way through stays selectable.
Pinned comments on designs and live staging sites, heatmap tools, and a fix for new starters seeing an empty app.
Added
Comment on the exact spot. Click anywhere on a design or a live staging page and leave a comment pinned to that point. No more “the spacing under the header, on the second one, on mobile” - the comment is attached to the place it is about, and the person fixing it sees exactly where you meant.
Development reviews open your staging link at three screen sizes - desktop, tablet and mobile - and remember which one each comment was left on, because “the header wraps” is usually only true at one of them.
People you share the link with can pin comments too, without an account. They type their name, so feedback is never anonymous. Only your team can mark a comment resolved - a reviewer can’t quietly close their own request, and resolved comments stay on the record rather than disappearing.
You are notified the moment someone pins a comment on a review you asked for.
Hotjar, Microsoft Clarity and PostHog can be switched on in Platform → Settings to see heatmaps and session replays. Each is off until you enter an id - with the box empty no script is loaded at all, because tools that record what people type should not default to on.
Fixed
New team members saw an empty Tasks page with no explanation. You see tasks assigned to you plus everything on projects you are a member of - so somebody not yet added to a project saw nothing, and the page said “No tasks found”, which reads as “your team has no work”. It now says what is actually going on and what to ask for.
Test logins were never created on a deployed server. They needed an environment variable that a managed host gives you no obvious way to set, so the deploy skipped them silently and the only symptom was logins that did not work. They are now created automatically, with a strong password generated at deploy time and shown in Platform → Settings.
Every feature, every role, in one place - generated from the product so it cannot go stale.
Added
A full feature inventory you can actually read. 190 features across 17 areas, with a plain-language table of what each of the ten roles can and cannot reach, and what comes with which plan. It is generated from the product itself rather than typed up by hand, so it stays true as things change - which is the opposite of how the pricing page had quietly drifted.
A sweep of every number and promise on the landing page, the pricing page and the plans themselves.
Fixed
The pricing page promised things some plans don't include. A panel headed "the full platform - no feature paywalls" listed the CRM, contracts, e-signatures and hiring, none of which are on Free or Studio, and an FAQ said the Partner Vault "unlocks immediately upon signing up" when it starts on Scaled. It now lists only what genuinely ships on every tier, and says plainly where the commercial and people sides begin.
The landing page understated the plans. It advertised 15 clients on Studio and 50 on Agency when they actually allow 25 and 100, and its prices were fixed dollars - so an Indian visitor saw dollars there and rupees one click later. Every figure now comes from the same place as the checkout.
Signing up still offered a 14-day free trial. There hasn't been one since the move to free-forever; the plan you actually got was the free plan. The signup, login and register pages now say so.
The free plan described a limit it no longer had, calling itself "one active client" months after the cap became three.
Tables were missing from every plan's feature list - on every tier, advertised on none of them.
Found by testing the whole subscription lifecycle against the payment provider rather than just the checkout screen.
Fixed
Downgrading changed your plan but not your billing. Moving to a cheaper plan updated what you saw in the product and left the old, more expensive mandate running at the payment provider - so you would have kept paying the higher price indefinitely, with nothing anywhere in the app to contradict it. Downgrades now move or stop the mandate, and if that cannot be done we refuse the change rather than let you believe you are paying less than you are.
Upgrading could have billed you for both plans. Upgrading creates a new mandate; the old one was never cancelled, and we overwrote the only reference that could have stopped it. The previous mandate is now retired the moment the new one activates.
Cancelling twice said cancelling had failed. The second attempt reported an error to people whose subscription was, in fact, already cancelled - the check was looking for wording the provider does not use. It now reads the real message.
Changing a price in the admin panel updated the site but not the payment provider. The new figure appeared on the pricing page immediately while checkout still charged the old one. Editing a price now republishes it to the provider in the same action, and says so if it cannot.
Security
The payment webhook accepted unsigned events when no signing secret was configured. That endpoint is what grants a paid plan, so without the secret anyone who knew its address could have granted themselves the top tier - permanently, and indistinguishably from a real payment in our records. It now refuses to process anything unsigned in production, and the signature comparison is constant-time.
A missing plan could drop a real customer into the developer payment simulator. If a plan was unavailable in the customer's currency, checkout fell back to the internal testing panel that grants plans without charging. Customers now get a clear "we can't do this right now, and you haven't been charged" instead.
International cards are live, and the price you see is now the price that reaches your card.
Added
Prices in USD and INR, and you pick which. Where you are decides the opening currency - India sees rupees, everywhere else sees dollars - and a toggle beside the price lets you change it. Your choice follows you from the pricing page to checkout, so nobody picks dollars and gets quoted rupees at the last step.
Fixed
A customer outside India was shown "$29" and charged ₹2,499. Every plan on the payment account was in rupees, so the dollar figure was a label rather than a price; the real debit arrived in a foreign currency, converted at the bank's own rate, usually with a foreign-transaction fee on top. There are now real dollar plans, and an American subscribing to Studio is charged $29.
The billing page quoted the annual price at 85×. It carried its own conversion left over from the old plan names, so on annual billing a plan costing $290 a year was displayed as "$24650/yr" - a rupee number behind a dollar sign, on the screen where you decide whether to upgrade.
A rounding rule turned $0 into ₹-1 on the one plan every visitor sees first.
Fixed
The Free plan showed ₹-1 to visitors in India. Rupee prices are rounded to end in 99 - ₹2,499, ₹6,699 - which is what makes them read as prices rather than currency conversions. Applied to ₹0 it produced minus one. It was on the first tier anyone looks at, where it reads as a broken product before you have used anything.
One login per role, seedable into staging - without publishing a password.
Added
Test personas can now be seeded on a deployed environment, so you and your team can check what each role actually sees on the real thing rather than only on a laptop. Eleven accounts - owner, project manager, HR, sales, team member, five client roles, and an admin on the Free plan for testing the caps.
It only runs when you ask for it (SEED_PERSONAS=1) and the password comes from your own environment variable, never from the code. A password committed to the repository would be a published one, and one of those accounts can reach billing. Short or obvious passwords are refused, and the password never appears in the deploy log.
npm run seed:personas -- --remove takes them all away again when you're finished.
Review responses reach the agency, failed saves say so instead of pretending, and Playbook is now Handbook.
Fixed
When a client responded to a design or dev review, nobody at the agency was told. You shared three directions, they picked one and explained why, and it sat there unnoticed - which is the exact thing putting reviews in the product instead of email was supposed to prevent. Owners and project managers are now notified, with the option they chose and their comment.
Failed saves no longer look like successful ones. Ticking a checklist item, deleting a handover credential, moving a deal down the pipeline - each updated the screen immediately and, if the save failed, said nothing. The change reverted on your next reload and it looked like the product was losing your work at random. These now tell you plainly and put the screen back to match, so what you see is always what's actually saved.
A list that fails to load no longer says "nothing here yet". That's the most misleading message we had: indistinguishable from the truth, so people concluded their data was gone. Tables and the Archive now show what went wrong with a Try again button. The Archive additionally says "nothing has been deleted", because that's the reassurance that matters on that screen.
Changed
Playbook is now Handbook. "Playbook" was jargon; "Notebook" would have sat confusingly next to Notes. Handbook is what agencies already call this, and it's honest about what's inside - a curated set of links to how your team works, not another place to write.
The People page explains itself. It does two different jobs - your own time off and documents, and administering everyone else's - and five unlabelled tabs gave no clue which was which. Every tab now opens with a line saying what's in it and who can see it. The one that matters most: your HR documents are visible to you and the workspace owner, and not to your manager.
One was too tight to be useful. Three is enough to actually run your agency on.
Changed
The Free plan covers three active clients, not one (and 15 projects instead of 5). One client read as a demo rather than a free plan - your second arrives within weeks, so the limit bit before you'd built anything worth keeping. Three is enough to genuinely run the business through it, and the project allowance was lifted with it so you reach the client limit first: "you've got three clients" is a sign you're growing, "you've run out of projects" just feels arbitrary.
Archiving instead of destroying, a project-first flow for tables and notes, AI on the free plan, and plan names that finally match everywhere.
Fixed
"Delete project" was destroying far more than the project. It cascaded through fourteen linked things - tasks, notes, documents, files, references, reviews, time entries, invoices, contracts, tables and the handover pack - permanently, from one button behind "Are you sure?". Deleting a *client* did that to every project of theirs first. The handover pack exists so knowledge survives a project ending, and it was the first thing destroyed when one did. Delete now archives: it disappears from your lists, everything attached stays exactly where it is, and one click brings it all back.
Permanent deletion now tells you what it will destroy before you agree to it - "43 tasks, 12 documents, 8 files and the handover pack" - and you have to type the name to confirm. It's only reachable from the Archive, and only by an owner.
Plan names are the same everywhere now. Internally the plans were called starter, pro and business while showing you Studio, Agency and Scaled. That mismatch is exactly how a payment plan named after one tier got reused by another. Same names in the app, the database and Razorpay.
Added
An Archive view on Projects and Clients. Finished with something? Archive it. Your list stays short and nothing is lost - search it, restore it, or (deliberately, with the counts in front of you) delete it for good.
Tables now work like Notes: search, a project filter, a New button and a flat list - in the sidebar for every persona, and as a Tables tab inside each project.
Creating a table starts by asking which project it's for. That's the whole point of tables over a spreadsheet: a row that knows it belongs to the Acme retainer. Agency-wide tables are still possible, but now as a choice rather than the default.
Creating a note asks the same question. Notes written from the sidebar used to be silently detached from the work they described, and nobody ever went back to attach them.
Changed
AI is on every plan, including Free. 50 actions a month on Free, 300 on Studio, 1,500 on Agency, 5,000 on Scaled - or unlimited on your own API key, on any plan. Locking AI away meant nobody could ever see what it does.
The AI limit message now speaks to the right person. If you're the owner it tells you how to fix it; if you're not, it tells you to ask your owner to add an AI key - because sending someone to a Settings page they can't open is a dead end that reads like a bug.
No more countdown. Start free and stay free for one client, upgrade when you win the second - plus typed tables that finally get the content calendar out of Drive.
Changed
The 14-day trial is gone. There's a Free plan instead, and it never expires. Two weeks was never enough to see what this does: a client has to log in, a contract has to come back signed, an invoice has to get paid. The trial kept running out before any of that happened, and took the agency's workspace with it. Free gives you one active client with everything switched on - the branded portal, tasks, chat, approvals, files, time tracking, unlimited people - for as long as you like. When you win a second client you'll know it's time, and that's a much better moment than a date on a calendar.
If your trial had already started or lapsed, you're now on Free. Nothing was deleted and nobody was locked out. Your workspace is exactly where you left it.
Added
Tables - the spreadsheets your agency runs on, inside the product. The content calendar, the ad-spend tracker, the asset register: typed columns (text, number, currency, date, select, checkbox, link, person, client, project), sorting, search, CSV export. Start from a template rather than a blank grid. The part Sheets can't do: a row can point at a real client or a real project, and you can share one table with one client - they fill in their own rows and see nothing else. Available on every plan, including Free.
Tables are deliberately not a spreadsheet engine - no formulas, no pivots. That's what Sheets is good at, and it isn't the problem.
Fixed
The new prices weren't actually reaching checkout. Razorpay keeps its own copy of each plan with its own amount, and ours still held the old figures - so the site advertised one price while checkout charged another, and the top tier had no plan at all, meaning an upgrade to Scaled would simply have failed. They're now generated from our catalogue automatically on every deploy, and there's a test that talks to Razorpay and refuses to pass if any tier is missing, mispriced, or named after the wrong plan on the receipt.
Indian customers were shown dollars and charged rupees. The lifetime deal displayed "$399" and would have taken ₹33,915 - a number that appeared nowhere on the site. Every price now comes from one place, so what you see is what you're charged.
Signing in from several devices no longer looks like an attack. The login throttle counts failed attempts only, and a correct password clears the count.
100 lifetime seats for the agencies willing to bet early, contracts both sides actually sign, and a briefing every morning on what needs you.
Added
Founding Lifetime - $399 once, 100 seats, 60 days. Everything in Scaled, forever, including whatever we build next. AI runs on your own API key, which is exactly how we can offer a one-time price while everyone else charges $9-28 per user per month for theirs. Start free, then buy it from your billing page in a single Razorpay payment - no card stored with us and nothing recurring to cancel. "Lifetime" means the lifetime of the product, and we'd rather say that here than bury it in terms.
The counter on the pricing page is real. When it says 88 left, 12 have sold. When they're gone the offer disappears rather than lingering as decoration.
Changed
AI is the headline now, not a feature in a list. The daily briefing is the first thing on every dashboard; proposals, client updates and meeting-notes-to-tasks sit behind it. Included in the plan from Agency upward, with a monthly fair-use allowance you can see on the billing page - and a one-click "use your own key" for no limit at all.
Signing in is more forgiving and more secure at the same time. The login throttle now counts only *failed* attempts, and a correct password clears the count. Signing in from your phone, your laptop and the office no longer looks like an attack.
Fixed
The new prices now actually apply to existing workspaces. Plans were seeded once and never updated, so an older workspace still showed the old names, prices and seat caps. They're migrated automatically on deploy - and if you were already subscribed, you keep the exact price and limits you signed up on, moved onto a private founding-price plan of your own. Nobody's bill changes.
White-label was gated by two different rules that had quietly diverged, so the middle tier could reach a Scaled-only feature. There's now one source of truth, and a test that keeps it that way.
Team roles on the marketing site grew past the colour palette built for them, which blanked the section. Fixed.
Three plans that map to three real problems, unlimited people on every one of them, and a founding price locked for life.
Changed
Unlimited people on every plan. Bringing in a freelancer for one project should never involve a conversation about the bill. Every other tool in this category charges per seat, which bills you for hiring - the one thing that should never cost you more.
Plans are now three jobs, not three quotas.Studio $29 - "my clients keep asking where things are": a branded portal, projects, tasks, notes, files, chat and time tracking. Agency $79 - "I'm winning work but chasing money": adds the pipeline, contracts with real e-signatures, invoices, analytics and AI. Scaled $199 - "I have a team now and nothing is written down": adds handover packs, 360° reviews, time off, HR documents, policies, hiring, the extra roles and full white-label. *(Superseded on 2026-08-06: every feature listed here is now on every plan, including Free. Only the allowances differ.)*
Every tier is a complete answer, not a crippled version of the next one. Studio isn't "the one without invoicing" - it's a finished job you can stay on for good. You move up when you have a new problem, never because we removed something.
Your price never rises. Sign up during beta and you keep today's price for as long as you stay, including every feature added later.
Added
AI has a fair-use allowance (1,500 actions a month on Agency, 5,000 on Scaled) instead of being quietly unbounded. Running out never blocks the product - everything still works without AI, and you can paste your own API key in Settings for unlimited use at any time.
Anything not on your plan is simply not in your menu, and if you reach it by an old link you get a plain explanation of what it does and what it's part of - never a permission error. Access and plan are two different questions and the app now answers them separately: you'll never be quoted a price for something your role wouldn't let you use anyway. *(Superseded on 2026-08-06: nothing is off-plan any more, so this page no longer exists. The menu is decided by your role alone.)*
Project manager, HR and Sales roles built on a permission system that can't leak; roles inside your clients' own teams; an AI briefing each morning built from only what you're allowed to see; and a whole class of "I changed it but it still shows the old one" bugs gone.
Added
Real e-signatures on contracts - the DocuSign kind, not a button. Sign by typing your name or drawing it, confirm you intend it to be binding, and both sides sign: the client to accept, the agency to counter-sign and execute. A contract only becomes *Signed* when both have. Every signature records who signed, their email, job title, the time, their IP address, the exact consent wording they agreed to, and a fingerprint of the document itself - all read from the session, never from the browser, so nobody can sign as someone else.
A certificate of completion on every contract. Both signature marks, the full history - sent, first opened, commented, changes requested, revised, signed - and a live integrity check. If anyone edits the contract after it was signed, the certificate says so in red, and flags exactly which signatures predate the change. That check can fail, which is what makes it worth trusting.
An AI daily briefing, on your dashboard every morning. One paragraph on what today actually looks like, then the specific actions - overdue work, a contract where the client asked for changes, time off waiting on your approval, a prospect nobody has touched in a week. It is assembled per person from only the facts your role entitles you to see: HR is never told about the pipeline, Sales is never told who's off sick. On a clear day it says so in one line. It's a card on your dashboard and never an email - close it and it stays closed until tomorrow.
Project manager, HR and Sales roles. HR gets people, reviews, time off, hiring, documents and policies - and no client work or money. Sales gets prospects, proposals, contracts and invoices - and no team records or HR. The old Manager role is now Project manager; existing accounts migrate automatically and keep everything they had.
Your clients get roles too. A client company can now give their own people an access level - Owner, Manager, HR, Sales or Team member - inside their own portal. Their owner sees contracts and invoices; their teammate sees the work. Because the client's roles are a separate system from the agency's, a client's HR person and yours can never be confused for each other.
A permission model with one source of truth. Access is now decided by *capabilities* rather than by listing role names at every screen. A new role starts with nothing and is granted explicitly, so it cannot inherit access by accident. There's a test that walks the entire matrix, so "what can Sales see?" has a pinned answer rather than a remembered one.
Improved
Nothing is offered that you can't open. Menu items you don't have access to are simply not shown. If you arrive by an old link or a bookmark anyway, you no longer get a bare "403 Access denied" - you keep your sidebar, and the page tells you what the area is and who looks after it ("Contracts is looked after by Owner, Project manager and Sales"), so you know who to ask. The menu and the block page read from the same table, so they can never disagree.
A role change now takes effect immediately. Previously your role was read once at sign-in and trusted for up to 30 days - so a promotion didn't arrive, and a demotion didn't take. Your account details and access level are now re-checked continuously.
Fixed
Changing a team member's email now actually changes it. It used to update the team card while Settings kept showing the old address - and, worse, the person could still only sign in with the old one, because the login was never updated. Both are now the same thing. Changing it to an address already in use gives a clear message instead of a failure.
The same bug, pointing the other way. Renaming yourself or changing your photo in Settings updated your account but left your card in the team directory showing the old one. Names, emails, photos and phone numbers now stay in step wherever they appear.
HR can manage policies again. The People screen was checking for the Owner role specifically, which quietly excluded the HR role from publishing policies it was supposed to own.
Monthly reviews with real peer feedback, project progress you never type in again, a visible author on everything, sharper AI, and a calmer inbox.
Added
360° performance reviews, for everyone - monthly, structured 1-on-1 reviews with the eight sections teams actually use (what went well, what didn't, what needs improvement, actions, career plan, upward feedback, peer input, manager's note), a 1-5 star rating and a month-over-month comparison. Save as a private draft, then publish - the person gets it in the app *and* as a complete email they can keep. Every persona has the page: admins and managers write them, and every single person - team member or client - sees their own monthly performance in one place.
Your review is yours - a review is visible to exactly three parties: the person it's about (once published), whoever wrote it, and an admin. Not your teammates, not your project manager, nobody else. Private manager notes are never emailed and never shown to you, and a draft is invisible until it's published.
Clients get the same tool for their own team - a client's primary contact runs reviews for their own staff inside their own portal. That's their private HR data: the agency can't see it, and no other client can either.
Peer feedback that's actually 360° - invite teammates and they write their own input, optionally anonymous to the person being reviewed. No more transcribing hearsay into a textarea. A peer only ever sees their own contribution - never the review itself.
Read receipts on reviews - the person confirms they've read it, so you can tell "we're aligned" from "it's been sitting unopened for three weeks".
A lot more for managers - the delivery lead now gets a read-only Team directory with full profiles, a read-only Clients directory, Requests so they can qualify incoming client work and turn it into a project, Analytics for delivery health, and the Activity Log. Creating and removing people and clients, billing and settings still belong to admins - enforced on the API, not just hidden from the menu.
Every item shows who created it - projects, tasks and the rest now carry a visible author, so "where did this come from?" has an answer.
Reporting lines. Each person now has a manager, set on their profile. It's not decoration: it decides who can write your performance review and who approves your time off. A manager sees only the people who report to them; admins still see everyone.
A People area for everyone - time off, joining and leaving checklists, your own documents and the company policies, in one place.
Time off, requested and approved in the app. Ask for days, your manager gets it in an approvals inbox, and once approved it appears on the team calendar automatically. Nobody can approve their own leave, including admins. Overlapping requests are caught when you file them, not by whoever is approving.
Joining & leaving checklists. Reusable templates (two sensible ones are there from the start) so the dozen things that happen every time someone starts or leaves are already written down. Items are copied when a checklist starts, so editing a template never rewrites someone's live run.
Company policies with acknowledgement. Publish your handbook or expenses policy, everyone is notified, and you can see exactly who has accepted it. Editing a published policy creates a new version - so an old acknowledgement never quietly comes to cover words nobody read.
Personal HR documents - contracts, offer letters, appraisal records. Visible to the person and to an admin, and deliberately not to their manager: running a 1-on-1 needs the performance review, not somebody's passport scan. Records can also be marked admin-only.
Improved
Project progress calculates itself - a project's percentage now tracks completed tasks automatically instead of sitting at 0% until someone remembers to type a number. Cards show the working ("12/20 tasks"), and you can still pin a manual number per project when you'd rather set it by hand.
Sharper AI everywhere - tighter house rules across every AI surface (no preamble, no filler, never an invented date or figure), proper JSON mode with an automatic retry so extraction stops failing with "not in the expected format", and richer grounding for each feature.
Notes → tasks is far more accurate - it now sees the project's description, dates and the whole team roster, so names in your notes resolve to real people even on a project nobody is formally staffed on. Deadlines the notes actually stated ("by Friday", "end of month") arrive as real dates instead of a badge you retype.
Creating a task suggests the right people - the assignee list now starts with the project's own team, with the full agency one click away.
A calmer inbox - moving ten deliverables into review sends one "3 items need your approval" email instead of ten. Password resets, invitations, invoices and contracts are never affected.
The agency portal matches the rest of the product - /your-agency now wears the same clean sign-in design, carrying your logo and name with WorkTogethr stepping back to a quiet "powered by".
Dead ends now tell you what happened and where to go - every "no access", "not found" and "couldn't load" screen in the app names the thing you were reaching for, explains whether it's a permissions problem or a missing record, and gives you a button that goes somewhere useful. Land on the wrong workspace and it says which one you tried, which one is yours, and takes you there in one click.
A failed request no longer looks like an empty page - a list whose data didn't load used to say "No tasks found", which reads as "you have no work". It now says it couldn't load, and offers to retry.
Tasks now open on YOUR work. Every persona lands on "My tasks" instead of the whole agency's board, with a one-click switch to Everyone that's remembered for next time. With five people the old behaviour was liveable; with fifty it meant filtering your own question back out of a wall of other people's work every single visit. For a client, "mine" also includes anything waiting on their approval - that's their real queue. The narrowing happens on the server, so a big agency no longer ships thousands of tasks the browser would immediately hide.
Completed tasks tidy themselves away. A task that's been done for a week moves to Archived automatically. Nothing is deleted - it's the same soft archive as the button, still listed under Archived and restorable in one click. Set the window (or switch it off) per agency in Settings; the default is 7 days.
Fixed
Invitation links no longer 403 - a site URL saved with a trailing slash produced //login, which the CDN treated as a different (blocked) path. Every email link is now built through one normaliser.
Invitation emails say who invited you, and where - the real inviter's name and your actual workspace name, instead of "The Admin has invited you to join WorkTogethr on WorkTogethr".
Invitations include a temporary password - the "Accept invitation" button now actually gets you in, rather than dropping you on a sign-in form with no credentials.
Two logos in the header in dark mode - on desktop the WorkTogethr wordmark refused to hide and sat next to your agency logo. A dark-mode style was outranking the rule meant to hide it; the two now can't fight.
Client emails wear your brand, not ours - the portal welcome and the approval nudges were going out with the WorkTogethr header and telling your client they'd been added "on WorkTogethr". They now carry your name, logo and colour, with a quiet "powered by" in the footer where it belongs.
The portal welcome email names the address to sign in with, instead of "sign in with this email".
A crash inside the workspace keeps your sidebar - you can carry on somewhere else instead of being thrown out to a full-page error.
Opening a client or team member you can't see no longer bounces you silently back to the list with no explanation.
Safety caps on a few lists that could grow without limit (portfolio, testimonial walls, the public roadmap), so one request can never try to load an entire table.
Adding a team member no longer throws away half the form - the employee code, job title, portfolio links and résumé you filled in were being dropped on create and only saved if you went back and edited the person afterwards. Their profile page now shows all of it, plus their access level.
The status badge on a team member's profile was stretching into a full-width black bar.
Profile photos were being squashed. Any photo that wasn't already square got stretched to fit the circle, so faces came out visibly distorted. Every avatar in the app now crops to centre instead. (Your uploaded file was always fine - only the display was wrong, so nothing needs re-uploading.)
"Failed to save profile" - once you'd uploaded a profile photo, you could never save your profile again. Photos moved to cloud storage but the check that validates them didn't follow, so it rejected the app's own uploads. Saving works now whether your photo is stored, inline or a link.
Errors now say what actually went wrong. A few screens replaced the server's own message with a generic one, which is why the profile bug needed a screenshot to find.
Design & development review images were being thrown away. Same root cause as the profile photo: the check that validates an uploaded image never learned about cloud storage, so it silently discarded every review image - no error, the review just saved without its artwork.
Your logo now actually appears where it matters most. On the /your-agency sign-in page, the public intake form, the testimonial request page and in every client email, an uploaded logo was loading as a broken image. Review images on a public share link had the same problem.
Security
A manager could write a performance review of anyone in the agency - including their own boss and other managers' people - because "who do you manage" wasn't recorded anywhere. Reviews now follow the reporting line.
Closed a hole in the public image route. Brand assets are served without a login so your logo can appear on public pages - but that exemption applied to *any* file, so anyone holding a storage link could read any uploaded file, including résumés and client deliverables, across workspaces. It's now limited to images actually published as a logo, and it fails closed.
A premium light redesign of the whole public site, a one-step trial signup, real recurring subscriptions with reminders you can trust, and a WhatsApp lifeline when you're stuck.
Added
A completely redesigned public site - landing, sign-in, sign-up, pricing and the shared client-facing link pages, all in a clean, light, premium look with animated product previews.
Recurring subscriptions via Razorpay - pick a plan and it auto-renews monthly or yearly, with UPI, netbanking and Indian + international cards. A friendly pre-charge reminder email lands ~3 days before every renewal, so you're never surprised.
Reliable cancellation - cancelling in-app now truly stops future charges on the payment provider (not just in our records), and you keep access until the end of the period you paid for.
Uptime monitoring - a health check the platform admin can point a free monitor (e.g. UptimeRobot) at, plus live status right in the admin, so you know the moment anything is down.
A WhatsApp help button on the landing and sign-in pages, and a "submit a query" box on signup - reach a human instantly if anything goes wrong.
GST-aware Indian pricing - prices shown in INR with GST clearly noted.
Improved
Signup is now a single, simple step - since the trial is free with no card, we no longer ask you to choose a plan first; just create your workspace and you're in.
Clearer pricing - every plan includes the full platform (no feature paywalls); plans differ by size (team, clients, projects), with full white-label reserved for Scaled Agency.
Sharper, honest marketing copy focused on running an agency end to end - CRM, contracts, reviews, handover, hiring, playbook, testimonials and more.
The header "What's new" now tracks the changelog - recent updates show automatically, in a compact, scannable list.
Fixed
Global search results are clickable again - clicking a result navigates just like pressing Enter, and the search dialog is now screen-reader accessible.
Team member form - removed the duplicate "job title" field; role/position is the single source and shows on the profile.
Fuller people records, install WorkTogethr as an app, dark-mode branding, and a stack of workspace polish.
Added
Install WorkTogethr as an app - a one-tap install button now appears in the header on supported browsers, so the workspace runs like a native app with its own window and icon.
Employee codes, job titles, portfolios, résumés and profile pictures on team members - admins can now set a teammate's HR code, public job title, portfolio links, résumé and photo right from the team form, and the team cards show them at a glance.
Profile pictures for client teammates too - clients can add a photo, role, department and phone for each of their team members.
Client display pictures - upload a photo or company logo for each client instead of a plain initial; it shows across the workspace.
A dark-mode logo for your agency - upload a separate light-coloured logo that automatically swaps in when a viewer is in dark mode, so a dark logo never disappears against the dark header.
Collapse the sidebar to an icon-only rail to reclaim screen space - your choice is remembered.
Newsletter sign-up on the homepage and a marketing opt-in at signup, both feeding a new Marketing list in the platform admin (with CSV export).
A featured-post blog layout with a hero for the latest article, tag chips and estimated read time - now with rich search-engine and AI-crawler metadata so posts rank and get discovered.
A "what's new" button in the header - a gift icon with an unread dot shows each release's features for your role (AI features in their own section); click it anytime, and we can also email the announcement to everyone.
A WhatsApp help button on the landing and sign-in pages, plus a "submit a query" box on agency signup, so anyone who gets stuck can reach a human instantly.
Improved
Refreshed, premium emails - a cleaner black-and-white design across every message we send.
A more useful dashboard - appreciation and kudos now sit right at the top, and (where AI is set up) you can turn meeting notes into assigned tasks straight from the dashboard by picking the project.
A more prominent AI assistant in the header, so it's easier to find.
Documents now filter by project and sharing level, not just search - find any document across every project from one place.
Feedback / testimonial requests now show their shareable link with copy, open, resend and delete actions on each pending request - no more lost links.
Client team members are labelled "Client team" in the platform user directory, distinct from primary client contacts.
Agency signup now expects a work email - a personal Gmail/Yahoo/Outlook address is no longer accepted for a new agency account (your team and clients can still use any email).
Fixed
Editing a team member from their profile now opens the editor instead of bouncing back to the team list.
The department badge on team cards no longer stretches awkwardly across the card.
Uploads work without any R2 setup, AI failures now tell you what's wrong, and your own logo is free on every plan.
Fixed
Uploads no longer fail with "failed to fetch." Files, profile pictures and handover deliverables now upload through the app instead of straight to storage, so no bucket CORS configuration is needed - this is why storage showed "Connected" but uploads still failed.
Editing a client's email now updates their login too, not just the displayed record.
The references page no longer overflows the window on wide screens.
Improved
AI errors now say what actually went wrong - a rejected key, a wrong model name, a rate limit or a network block - instead of a generic "unavailable", so it's fixable in seconds.
Premium email design - a branded dark header with your mark, an accent rule and a cleaner footer across every email.
A richer intake form - website, service needed, timeline and "how did you hear about us", all captured straight into the CRM record.
Added
Use your own agency logo on any plan. Your brand in the workspace header, your login page and your emails is no longer a paid feature - only per-client portal white-labelling is.
"Test connection" for AI in both platform and agency settings - one click does a real round-trip and tells you exactly what's wrong (bad key, wrong provider, model, or the Google key needing the Generative Language API), so setup never fails silently.
Full contract-grade AI proposals - every generated proposal now follows a fixed structure: Client, Client POC, Project, Agency, Agency POC, Executive Summary, Roadblocks, Mission, Scope of Work, Deliverables, Timeline, Pricing, Support, Guarantee and Terms of Payment. Missing values are left as clear placeholders rather than guessed.
Automatic recovery from stale pages after a deploy - if an open tab holds an out-of-date page, it now refreshes itself instead of showing a blank screen.
Improved
Cleaner homepage feature grid - the bento layout now tiles evenly with equal-height cards instead of leaving gaps.
A big one: your customers can now see what you're building, invoices bill line by line, and the CRM keeps a real history.
Added
Public roadmap at /roadmap - anyone can see what's being considered, planned, in progress and shipped, and vote on what matters to them.
Feature requests from everywhere - the public form, and the in-portal feedback box for agency admins, managers, team members and clients, all feed the same pipeline.
Voting on roadmap items, with one vote per person whether they're signed in or not.
What's new page at /updates - this changelog, rendered, and updated automatically with every deployment.
Invoice line items - bill line by line with quantity, unit, rate and per-line totals, plus subtotal, discount, tax rate and payable total.
Invoice PO number, payment terms, tax label and terms & conditions, so invoices survive a client's finance department.
Prospect detail view - a real CRM record with a contact panel, deal panel, and a full activity timeline of calls, emails, meetings and notes.
Prospect activity logging with outcome and an agreed next step, which drives the follow-up reminder.
Deal source, industry, company size, expected close date, probability, deal owner, competitor and lost reason on every prospect.
Convert prospect to client in one click, carrying the details across.
Rich text editor for contracts and proposals, replacing the plain textarea - headings, lists, bold, links, the lot.
Intake link dialog with the live URL, a copy button, an embeddable snippet, a QR code and a preview, instead of a silent clipboard copy.
Improved
Time tracking - log time against a specific task, not just a project; the running timer now survives a page refresh and counts real elapsed time instead of drifting in a background tab.
Time tracking summary cards now respect the filters you've applied, instead of always showing the all-time total.
Time entries are editable, not just deletable.
The logo now shows on mobile in the admin, team and client headers, instead of the plain word "WorkTogethr".
Fixed
Discarding a running timer now asks for confirmation first, instead of silently throwing away hours of tracked work.
Time entry minutes are validated, so an entry can no longer be saved as "0h 90m".
Turn a rough brief into a proposal, and a messy call recap into assigned tasks.
Added
AI proposal generator - feed a title, rough scope, budget and timeline, and get a full proposal written in your agency's own format, saved as a draft contract ready to send for signature.
Per-agency proposal template, so generated proposals match your house style.
AI meeting notes → tasks - paste raw notes or a transcript and get the actions, owners, decisions and open questions extracted, with every line reviewable before anything is created.
AI assistant in the header - ask anything about your projects and tasks and get a structured written summary back.
Bring your own AI key at the agency level, which overrides the platform key.
Improved
Every AI feature is hidden completely when no key is configured - no broken buttons, no cost.
Files moved off the database, agency branding arrived, and billing stopped locking people out.
Added
Cloudflare R2 file storage with direct-to-bucket uploads and short-lived signed download links.
Automatic image compression in the browser before upload, typically 70-90% smaller.
Agency branding - logo, brand colour and name applied across the portal, login page and emails.
Invoice payment recording with running received and outstanding totals.
Weekly digest emails for projects, tasks, billing and trial status.
Premium branded email templates across every notification the platform sends.
Improved
Billing never locks you out of billing - the billing and settings pages stay reachable when a subscription lapses, and clients and team members are never locked out by their agency's billing state.
Seven-day grace period with full access after a trial ends, with reminders before and during.
Fixed
Analytics counted planning-stage projects as completed.
Invoices lost their project link on save.
Testimonial submissions failed when the link carried no agency identifier.
A cleaner notification center, instant badges, and a batch of quality-of-life fixes.
Improved
A redesigned notification center - colour-coded icons per event, grouped into Today / Yesterday / Earlier, an All/Unread filter, and whole-row click-through to the item.
Unread badges clear the moment you read something, instead of waiting for the next refresh.
Admins and managers can be assigned to tasks and projects - the owner is now part of the assignable directory, with role labels shown.
Navigation tidy-up: Playbook and References moved next to Documents and Files.
Fixed
The partner vault is now readable in light mode.
The to-do list no longer runs edge-to-edge - proper padding and rounded rows.
Where WorkTogethr started: one workspace to run an agency and its clients.
Added
The first WorkTogethr build - projects, tasks, clients and team, with the client relationship at the centre. Everything since has been built on this foundation: one shared, role-gated workspace rather than separate tools bolted together.