- A new Insights area that reads our own conversations and tells us what is going wrong in them. Until now, knowing whether Mira handled a hundred conversations well meant a person opening a hundred conversations. Insights is a report you run on demand: it reads recent client conversations, checks each one against a list of questions, and stores every hit as a finding with the quote from the conversation that proves it, so the console shows the answer and the evidence side by side. It runs on whatever environment you open it in, reading only that environment's own conversations, and it is its own permission, granted deliberately like every other tab, with reading past reports and paying for a new one being two separate levels of access. The sweep runs in the background on the cheapest model tier and is bounded, so a report costs cents rather than being an open tap.
- The list of questions became something a teammate writes, not something an engineer ships. The starter list was written into the code, which makes every new question a code change. It is now a registry an admin edits from the console: add a tag or a question, say which agent it applies to, switch it on or off. Nothing is ever deleted, only deactivated, because past findings point back at it. Each question declares the shape of the answer it wants, yes or no, one of a set of named options, or free text, and the model is held to exactly that shape rather than asked politely for it, so answers can be counted and charted instead of read. Each one can also name a condition for running at all, so a question whose evidence cannot possibly exist in a two-message conversation costs nothing on that conversation. And every set of named options quietly gains an "other" bucket, so a conversation that fits none of the listed choices lands somewhere real and findable instead of being forced into the nearest wrong one.
- Every agent became something you can ask questions about, not just the two that talk to people. The first version could only read the client conversation. But every one of our agents is having a conversation, with the model and its own tools, and all of it is already recorded, so any of them can be examined the same way. The talent-side agent is now read per talent thread, with its own six starter questions about price mismatches, how the talent reacted, and whether they were cut off early. Every other agent is read through its own recorded working, and it wires itself up: define a question for the search agent and the next report tags the search agent, define none and it costs nothing. Each report also ends with a short set of written lessons per agent, grounded in what that run actually found.
- The report became a table you can work, then a set of charts, then a history. The findings started as a flat list that repeated the same conversation once per question, which made counting anything by eye. It is now a grid: one row per conversation or talent thread, one column per question, the answer in the cell, with the whole conversation sliding in from the side when you click a row rather than being dumped into the page under your feet. Every column carries its own filter over the answers that column actually contains, including an explicit bucket for the ones with no answer; any column or agent tab can be hidden, and those choices are remembered per person. Above the table, a card per question draws the distribution of its answers. And because the findings accumulate, there is now a trend view: each question's rate plotted across every past report, so "is this getting better" is a line rather than a memory.
- And then the report grew an assistant you can ask about itself. A floating chat sits on the report and answers questions about the run already on the screen. It has no access to the database and cannot run anything: it only sees that run's stored findings, which is what makes it safe to leave open. It can point at specific rows and put a "show these rows" button under its answer that pins the table to exactly them, it can suggest a filter and apply it for you, and when it thinks a question is missing it can offer to add it to the registry as a new check, which you confirm and rerun. It sees every agent's findings joined by project rather than only the tab you are looking at, so it can say things like "this share of talent threads that failed had this upstream tag", and say plainly when a question was never run rather than guessing.
- Production alerts had never once reached Slack, for nine days, and nothing said so. The channel that every one of production's sixty-eight alarms routed through was pointed straight at a Slack address that cannot accept the shape of message the monitoring system sends; Slack answered "no" to every one, and delivery failures are reported precisely nowhere, so the channel read as healthy and connected while delivering nothing at all. It had been that way since it was created on 28 July. Inside that window the admin console sat at zero percent uptime for four days with its alarm firing correctly the entire time and nobody hearing it. Alerts now go through a small translator that re-posts them in the shape Slack actually accepts, production gets its own room, and the build now refuses outright if anyone ever points the channel at a raw Slack address again. All sixty-eight alarms were then reviewed against a fortnight of real data, and the two that cried wolf were retuned.
- Alerts also stopped being triggered by people clicking around a preview. Every pull request gets its own disposable copy of the site, running in the same place as the shared development environment and logging the same events, and none of the alarm counters could tell them apart. Measured over a week, of forty-four request-timeout events, thirty-eight came from a single preview and opened nine separate incidents; several of the preview stacks still emitting were orphans of long-closed pull requests. The exclusion was put on the counters themselves rather than on the twenty-odd alarms that read them, so it cannot be forgotten by the next alarm somebody writes.
- We can now see whether talent replies are actually arriving. A talent's reply reaches us over three different routes, and the two that do the real delivering had no measurement on either end, only log lines; the only measured one was the half-hourly safety net that exists to catch what the others miss. So the main route could have stopped delivering every reply and the only visible sign would have been a quiet warning up to thirty minutes later. Each inbound message is now counted with the route that carried it, along with how long the talent actually waited between sending and us storing it, so a deploy can be watched rather than reconstructed afterwards. There is a new dashboard whose top row answers "is it flowing right now, and by which route", and the launch wall board gained a Talent replies tile and chart.
- The funnel board went from taking eight and a half seconds to a quarter of one. The board that draws every project's journey and where it stops measured 8.5 seconds in production against a hard 10-second ceiling, and 19 seconds for the all-time view on a large dataset, which is a defect twice over: slow work sitting on a page request, and slow work that gets slower as we grow. Three things were wrong. A piece of the query was being silently re-run for every project row, forty-six times over, so one window alone took 6.4 seconds; a single keyword took it to 9.7 milliseconds and named the cause. Twelve per-project lookups became seven grouped passes. And four separate time windows that each recomputed everything now come from one pass, sharing one clock, so the seven-day view can no longer contain a project the ninety-day view has not caught up to. Then the whole thing moved off the page request into a background refresh every five minutes, with the page honestly stamping how old the number is. Measured on 38,000 projects: 42.8 seconds for all four windows became 265 milliseconds, and the result was proved identical by running both versions against one database with the clock held still.
- Three smaller things that were each quietly wrong. The virus scanner for uploads was configured so that every simultaneous scan needed its own machine, and each machine spends five minutes loading its signature database on startup, so a normal burst of uploads cold-started six of them and the scans that landed on a not-yet-ready one failed and were silently retried, fifty to seventy times a day. One warm machine now absorbs a burst. The command our own documentation gave for rotating an alert channel could never work, in six places, because it destroyed the channel before repointing the alarms and the platform refuses that; the documented command is now true rather than rewritten around the defect. And the standard pre-push check on a developer machine was silently running the live behavioural test suite against the real model, which costs about fifty-five dollars a time, from a check the house rules explicitly forbid from triggering it.
- Signing back into the console now returns you to the link you clicked. An operator opens a project link from an alert, finds their session expired, signs in, and lands on the console home page with nothing to click but "go back and find the link again". The console now remembers where you were trying to go and puts you there, with four rules that keep a remembered link from becoming a trap of its own: only a link back into the console itself is ever stored, a second tab cannot inherit it, it expires after ten minutes, and it is used once.
- The talent search got its judgement back, without going back to guesswork. The previous day made the search a fixed pipeline, which made it reproducible but also stubborn: it ran once, with whatever it started with. The agent now sets the search up, the pipeline runs it, and then the agent reads the result and decides what happens next, up to three times: finish, or search again with broader wording, a different budget or one constraint dropped, or say plainly that nothing here fits. That last one matters, because an honest "no good match" is a real answer and it never had a way of being said. Budget is the agent's own call within the run, which kills the case where a twenty dollar job was hunted at five thousand. Alongside it, the one model call that opens the search was the only one with no safety net: when it failed after its retries it handed back an empty list that looked exactly like an honest "nobody here does this". Re-running two hundred briefs hard enough to trip the provider's rate limit produced fifty of those silent empties on ordinary briefs like a logo or a product video. That call now fails loudly, and the client is told the search hit a hiccup rather than being told the marketplace is empty. And grading candidates, about sixty model calls a search, stopped paying full price for the same instructions every time: a rearrangement that changes no wording pushes the repeated part over the size at which the provider will cache it, at roughly a quarter of the price.
38 commits, and two clear halves. One is a brand new Insights area that reads our own conversations back to us: run a report, and every conversation is checked against a list of questions a teammate writes from the console, with each answer stored beside the quote that proves it. Over the day that grew a proper answer shape so results can be counted, a second surface for the talent-side agent read per thread, then every agent through its own recorded working, then charts, then a history across past reports, and finally a floating assistant that answers questions about the run on screen, points at the exact rows it means, and offers to add the question it thinks is missing. The other half is production telling the truth: the channel that all sixty-eight production alarms routed through had never delivered a single one since it was created nine days earlier, silently, including four days of the admin console being completely down; previews stopped setting off the shared environment's alarms; talent replies became measurable end to end instead of only reconstructable; and the funnel board went from 8.5 seconds on a page request to 265 milliseconds off it.