Mark the softphone guardrails plan executed
Real commit SHAs in place of the placeholder, and 47 steps ticked. A finished plan showing all-unchecked boxes misreads as abandoned work.
A checkbox click should not re-render the folder sidebar
Six call sites read the email store with a bare `useEmailStore()`. In zustand that subscribes to the WHOLE store, so any change anywhere in it re-renders the co...
The drop beacon reports which path ICE actually chose
The beacon shipped iceCandidateType as a permanently-null field. That is worse than omitting it: it makes the telemetry look more informative than it is, and th...
Memoize the app-wide unread value, fix a self-retriggering effect
UnreadContext published a fourteen-member object literal as its context value, so React saw the context change on every render of the provider and woke every co...
Stop polling for badges nobody is looking at, and stop waking every consumer
Two always-mounted providers ran a one-minute poll with no visibility gate. LegalPackageCount had none at all; TrainingPendingCount had a visibilitychange re-re...
A phone-less org should not open a call socket
The softphone opened its SockJS/STOMP connection to media.<domain> unconditionally at boot. getCapabilities() is awaited a few lines above and is the backend's ...
One day picker, shared by the calendar and the settings tab
The two surfaces had each grown their own answer to "which days?". The settings tab put Workweek Days, Weekend Days and Every Day behind a dropdown; the calenda...
Stop re-merging the whole catalogue on every request
getRequestConfig runs per request, and for any non-English member it called mergeWithFallback over the entire 23,252-key catalogue every time — rebuilding a res...
Badge a minimized window with its server unread count
The one component that sees both the window list and the unread maps — the engine knows nothing about conversations and the unread context knows nothing about w...
Set an absolute unread count from the server
Replaces hexhead:incoming, which nothing ever dispatched. Its +1 would have counted a re-delivered snapshot as a new message, and its spawn-if-missing branch wo...
Messages and calls, on the existing timeline component
CommunicationsTimeline and EmailEntry take an optional endpointBase and keep the lead path as the default, so every existing call site is byte-for- does not car...
Stop losing calls to session expiry, teardown and stale devices
Four guardrails that share two files, so they share a commit. A live call now counts as session activity. ClientActivityTracker equated presence with input eve...
Read-fence SMS/AI mark-reads, fold sessionType into sameSessions
Three review findings against Task 21, all plan-mandated: - markSmsRead/markAiRead had no read fence: a refresh or an inbound push resolving between the opti...
One arriving message should not re-render the whole history
Batch 5 of the client-side performance audit. MessageList maps every loaded message to a MessageBubble, and MessageBubble was not memoized. With 300 messages o...
Take AG Grid's 187 KB of CSS off the critical path of every route
Batch 4 of the client-side performance audit, and the last of the big ones. app/globals.css opened with two @imports of ag-grid's stylesheets, and the root lay...
SMS and AI counts, and a per-surface split
One MediaService snapshot covers three surfaces that belong on two different nav indicators, so the totals are separated from the server's declared sessionType ...
A thrown hexhead can no longer end a live call
SoftphoneTool never listened for the cancelable tool:requestClose that MessageTool uses to protect unsent text, so scoring the remove goal on a minimized softph...
Stop sending the whole message catalogue to the sign-in handoff
Batch 3 of the client-side performance audit. The root layout passed every message to NextIntlClientProvider on every route. The catalogue is 1.05 MB compact —...
Confirm before a refresh takes a live call
The SIP session lives in the document and nothing on the server holds a handle to it, so a reload ends the call outright — with no BYE, leaving the far end on s...
Rebuild the availability editor around the day it describes
The editor was a stack of form rows that never showed what it was making. It now opens with the thing itself: a 24-hour rail with the block painted on it, in th...
Split the tool windows out of the shell, stop the idle timer storm
Batch 2 of the client-side performance audit. As with batch 1, nothing a member can see or do changes. The tool registry imported all ten tool windows eagerly,...
One address for a conversation on any of five surfaces
chat/support/social share the chat: namespace because they share one unread snapshot; SMS and AI get their own, because a VoipConversation UUID and a media sess...
A refresh mid-call no longer re-dials the customer
The tool-window snapshot replayed props verbatim, which is right for state and wrong for an instruction. `autoDial: true` survived into the restored window and ...
Routes for the notification spine's counts and mark-reads
The PUT routes answer 204 and must not call .json() on it — that turns a successful mark-read into a 500.
Set up RingCentral with a JWT, and assign members their own number
Three screens, one change. The phone server's overview tab replaces "Connect with RingCentral" with the credential form the JWT flow actually needs — client id...
Implementation plans for the softphone line window
Two plans, because the spec covers two subsystems and the first ships working software on its own. The guardrails plan is seven tasks that need no new browsing...
@kamo/tool-core 0.1.2
Brings raisedBy: 'incoming' and the quietRaise event, so an arriving message can be absorbed by a minimized window's hexhead instead of re-opening it.
Stop shipping the shell code no route can reach
Batch 1 of the client-side performance audit. Every change is behaviour-preserving; nothing a member can see or do is different afterwards. I18nProviders impor...
Design the softphone line window
A call cannot be moved into a window after it starts — an RTCPeerConnection and its MediaStream are not transferable between browsing contexts, and there is no ...
Rebuild the console on the house design language
The first pass was wrong and it was wrong in a way that should have been obvious before a line was written: I built Tailwind divs, MUI Tabs and hardcoded rgba c...
Availability for presenters only, and a way to understand it
Three things, all about the same layer. WHO SEES IT. The availability toggle was shown to everybody. Declaring hours is only meaningful for somebody a webinar ...
The new organization opens in its own tab
Creating one signed THIS tab into it, so a member who created an organization on someone's behalf was silently moved out of the one they were working in — and h...
Apply the branding the wizard just collected
Colours, logos and backgrounds chosen while creating an organization were not reaching it. The member opened their new workspace on default branding and had to ...
Write, sign and amend a visit note
The composer changes shape once a note is signed, and that is the whole design. Before signature it is a text area that autosaves. After signature the text area...
Convert any logo to vector, and say what the scan found per step
Three things, all reported from the wizard itself. THE COMPACT LOGO NO LONGER DEMANDS AN SVG. The slot can only store a vector -- the backend writes it to a fi...
Workweek Days, Weekend Days and Every Day in the Day field
Declaring the same hours five times over was the only way to say 'I present on weekdays'. The Day field now offers the three groups above the individual days. ...
Commit the Dispatch/Service Work program design and its evidence corpus
Both program specs and all 56 research files were untracked and existed only on one disk, while HANDOFF.md tells the next session to read them first. Also reco...
Plan webhook hardening and idempotency across BillingService, shared-library and APIService
Ten tasks, TDD throughout, with the severity restated to what was actually verified: the Stripe fail-open is latent (the secret is present in prod, 38 bytes) an...
A healthcare market's commerce surface is its revenue cycle
The other verticals show orders and agreements because that is where their money is. A medical practice's money is in claims — and specifically in the ones noth...
Give bugs and enhancements their own support section
The two report entries were sitting under "Online Support" beside Contact Support and View Active Tickets, which is a different errand: those two are asking a p...
Member-level availability, with sub-tabs and a calendar layer
**************** now has two sub-tabs. "Webinar Types" is what an administrator configures — the offering, its presenters, its reminders. "Scheduled Availabilit...
The Patient Records surface — day, safety, search and chart
A nav entry, four panels and a chart. The design decisions worth reading are the ones where the screen is a control rather than a view. The chart's allergy ban...
Tighten the screenshot drop hint
"Drag images here, paste from your clipboard, or click to browse" becomes "Drop image, paste from clipboard, or click to browse" — the three things you can do, ...
Close the dead space under the lead grid's pager
The pager sits at the bottom of the grid Card's CardContent, and CardContent ships `&:last-child { padding-bottom: 24px }` of its own. That selector carries a c...
Fit the report form in the window without scrolling
The form was about 120px taller than the 460x690 window's content area, so every new report opened on a scrollbar. Six changes, each of which also reads better ...
Implementation plan for quiet hexheads and the notification spine
33 tasks across five phases whose order is load-bearing: the schema must be run before any service maps a column, the library published before the services buil...
Say plainly what the domain field is for
The hint explained the field in terms of the hosts it produces — internal.<domain> for the workspace, login.<domain> for sign-in — which means nothing to somebo...
A domain is no longer required to create an org
Requiring it here was the wizard's half of the rule this effort removed: a customer could not finish creating an org without naming a domain, and then could not...
Design for quiet hexheads and the per-surface notification spine
A minimized chat window re-opens itself on every arriving message. The hexhead should absorb it instead — count, thump, stay put — and only a conversation with ...
Close five gaps in the website brand suggestions
Five things found reading the first cut back, all of them real. The "Added below" badge lied. It tracked only which card had been clicked, so hitting Remove on...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.