- Mira inside Claude and inside ChatGPT went from a skeleton that answered to something you would recognise as her, over eight passes in one day. The first and biggest was speed. The chat tool was waiting for the WHOLE turn to finish, both lanes, the brief rewrite included, while the browser app shows her reply the moment her fast lane streams. It now returns on the first persisted reply, widget or error, and the slow lanes keep running behind it and drain into the card, so a state of still working WITH a reply already on screen is the normal shape rather than a spinner. The card also stopped looking like a generic panel and took Mira's own design tokens verbatim, her exact green ramp and her surface sets, with the host only choosing dark or light. Then a live run through it as a real user, brief to search, found the rest. The status poll was stacking its own instructions into the visible thread, so every quiet tick appended another sentence of guidance as though Mira had said it, and after a minute a phone showed six identical copies of one paragraph; those replies are marked for the host only now, and the fold guards on CONTAINMENT rather than exact equality, because the old check only suppressed a repeat while the entry held that one sentence and nothing else. The recommendation blurb was echoing a frozen summary that named the wrong top talent, so it is recomposed from the cards actually returned. Decision options had lost their explanations to a key name that live payloads never use. Finalist cards were reading field names the payload never carried, so every finalist rendered as the literal word Finalist with no craft, no photo and no reasoning, and price and timeline landed below the buttons because they were being spliced in before an element that did not exist. Talent avatars were letter discs and could never have been anything else, since the real photo URL was dropped from the payload AND the card frame refuses every outside domain by default; the field rides through now and the frame declares the one image host it is allowed, with the photo layered over the initial disc so a dead link degrades to letters rather than to a hole. The card never said who was speaking either, and now leads with the Mira by fiverr lockup, rebuilt as inline drawing because no asset URL survives that locked frame, painting in the host's own text colour so it inverts with the theme.
- The chat surface could never open a second project, and every new hiring need was quietly overwriting the last one. Omitting the project id does not start fresh: the worker's fallback attaches the turn to the user's NEWEST project, which is the right answer for a dropped thread and exactly the wrong one for a new role. The tool's own description promised the opposite in as many words. So a client who had finished a logo brief and then asked for a developer landed in the logo project and overwrote it, proven on a live probe. There is an explicit new-project flag now, and it creates the row BEFORE the turn is claimed, the same order the browser app's own New project control uses, with the id derived from the same content key the claim already dedupes on so a host retrying the call re-creates the SAME row and converges rather than forking. The per-user project cap applies, and the instructions to the host now say the true thing: omitting the id attaches to the most recent project, a different role needs the flag. Five more tools landed the same day, each reusing the browser app's own seam rather than a second implementation: the brief WHOLE rather than the four-hundred-character glance, a PDF that calls the real export handler as a function and returns a link that works with no session because the route signs a scoped token onto it, telling Mira who you are once and having it remembered across every project, and two destructive ones built as rituals rather than sentences. Deleting a project does nothing at all unless a separate confirm flag is passed, and it reports what the project holds first, because a model reading a conversation is one misreading of clear that out away from destroying a brief. Erasing the whole account goes through the same core the web privacy page and the admin console call, and it acts only on the literal word DELETE, so yes, go ahead and delete it are all refused by construction.
- Five talents were told their boundary was saved and nothing was saved, and the reason was a column that is allowed to be empty. A QA thread stated nine boundaries and got nine warm replies, every one ending noted, with no tool fired and no row written. From the talent's seat that is indistinguishable from success, which makes it the worst failure this feature can have. Two separate causes, found a few hours apart. The first was the prompt and the tool list disagreeing about the same turn: the tools were there the whole time, and the prose said reply only on a closed conversation, so the model obeyed the prose. A standing preference is about the TALENT and not about this project, so no state of this project may drop it, and both halves now read ONE predicate. The closed-thread carve-out is unconditional, because the moment somebody says stop sending me work under a thousand dollars is usually the moment they were just passed over. The second cause was the key. Every read and write keyed on the talent's numeric marketplace id, which is nullable and empty by design for rows predating it and for the whole hand-picked shortlist flow that never touches the service supplying the number. Two threads out of three had none, so five captures went on the floor while the reply had already promised otherwise. The number was never the right key: it was added for a reporting join and enforcement inherited an analytics requirement, while both ends of enforcement already carry the username and always have, and a username cannot change. It is keyed on the name now, on both sides, including an outreach gate whose own comment admitted a thread without a number was let through unchecked, and a finalist card that silently degraded to availability to be confirmed for the same class of thread. And where it still cannot key anything, it now RAISES rather than returning empty, so the turn fails and no reply is sent at all, with a metric behind it. The talent sees nothing and writes again, an operator sees the failure, and the counter moves. Silence degrades honestly; a false promise does not degrade, it lies.
- Then four numbered notes from QA on what he actually says, and the tail of the flow that quietly discarded half of what a talent told us. A minimum was reading back inverted: please approach me for projects over a thousand came back as projects UNDER a thousand, noted, which names the work they just refused as the work they want, on the one message that is a talent's only window into what we stored. A second boundary was opening the same way as the first, so three turns in a row ended with the same word, which is what a bot sounds like; it is acknowledged as an ADDITION now, naming the new item. An unclear answer was asking should I add THAT as well, making somebody scroll back to work out what that was, on the one message whose entire purpose is to remove an ambiguity; it names the item in their own terms. Underneath the copy sat real data loss. Saying no logos, and nothing under five hundred is two things, a rule to add and a floor to overwrite, and the gate that pauses on the overwrite was throwing the WHOLE capture away, so the logo rule was lost to a question about money; only the part that would overwrite waits for an answer now. Answering that question with yes saved nothing at all, because the confirm path was built for an approval gate removed a week earlier and went looking for a row that no longer sits where it used to; a yes to would you like me to update that is a fresh capture with the new value, and his policy says so. The same message was rendering the ENFORCED view of their preferences, so a talent read minimum project size: nothing set two messages after being told our memory states it was a thousand, both wrong from where they sit, because nothing is active until an operator approves it. And a fix from the morning had made him go silent: told a change was waiting for approval, he concluded the system would speak for him and wrote nothing, so the talent got a bare closing line that never mentioned what they had just said. Also, a contradiction now stands alone instead of riding under his reply, because printing I have saved it beside may I overwrite it tells a talent both, and whichever half they believe is the one we did not do.
- A booked call stopped being a single bit and became a row that can be reported on. The scheduler card's answer left exactly one thing behind: a flag saying this client has booked, which answers the product question it exists for, stop inviting them, and nothing else. It cannot say when the call is, which desk took it, or whether anything ever confirmed it, and releasing an operator takeover clears it, so the history does not thin out, it vanishes. There is a real table now, one row per claim, written from the same worker turn that flips the flag and always after it, so a failure costs one row of history rather than the booking, and is metered. The load-bearing column is the verification tier, and it exists because the three desks sit on two vendors we do not own equally: one can confirm a booking and report a cancellation, the other two book through pages on a portal owned by other teams with no read path at all, so a row is honest about whether anybody ever confirmed it rather than pretending all three are equal. It shipped twice: the first attempt was reverted the same afternoon for a broken block assembled from selected patch hunks while another session held edits in the same tree, and the reland was rebuilt from a clean tree and verified before pushing. The warehouse was then granted read on it in its own change, deliberately ahead of the analytics side, because the reporting layer prepares its query as a restricted reader and an ungranted table is not a polite failure, it is a permission error that takes down that step and everything downstream of it, hourly.
- A project now remembers the device it was created on, and both admin boards can ask. The desktop, mobile and tablet split has existed since the funnel shipped, but only as an attribute on log lines going to the warehouse, which answers how much of our traffic is on phones and nothing else. To say whether ONE project came from a phone you had to go into the warehouse, find that project's earliest funnel row and hope the row carrying the id also carried the device. The database knew nothing, so no product read and no admin surface could ask at all. Three nullable columns on the project row now carry it, stamped by one shared classifier and mirrored onto the funnel line so the row and the log can never disagree. The load-bearing half is the plumbing rather than the column: most projects are created in the WORKER, off a queued turn, where no request exists, so the web edge does the classifying and carries the RESULT on the job. Without that the dominant path would store nothing forever. The queue carries the buckets and never the raw browser string, because a fingerprintable string belongs in neither a job payload nor the logs that echo one. Empty is a real and permanent value and is never backfilled: an import, an accepted suggestion and a chat-surface turn have no browser behind them, and a default would manufacture a desktop population that never existed and poison the first breakdown anybody runs, which is also why both filters offer unknown as a bucket of its own.
- The brief kept sliding open on a brief that had not earned it, and then the fix shut it on the client's own hand. Third report on the same card, with a screenshot of a checklist reading one of seven beside an open brief. The gate that decides when to open it automatically was correct; it was simply never the only thing that opens it. The remembered open re-applies on every surface it is allowed on, whatever the brief holds at that moment, so a panel opened once, by the machine before the gate existed or by the client on a fuller brief, comes back open forever after, including on a brief that has since been reset. The gate held the front door while the side door stood open. It takes the same readiness now: the preference is still remembered, closing is still sticky, and the remembered WIDTH is untouched, what waits is applying an open the brief has not earned. That went too far within the hour, because the same re-apply runs on every remount and project switch, so a panel somebody had deliberately opened a second earlier was shut again by the next one, which is a worse interruption than the one being prevented and is not what the gate is for: it exists to stop US putting a thin brief on screen, not to decide what a client may look at. A settle that is not the machine's own auto-open marks the project as CHOSEN, and chosen outranks readiness, scoped to the session on purpose, since a click three days ago should not keep a thin brief on screen today.
- And a run of phone repairs, most of them things an iPhone does that no desktop browser does. Landscape phones were landing in the desktop shell with about three hundred and ninety pixels of height, because the mobile switch was width-only and a landscape iPhone is wider than the threshold; it is two branches now, the classic width OR wider-but-short-and-touch, with the width floor making the height clause keyboard-proof so a soft keyboard can never flip the layout mid-typing. Orientation lock was researched and rejected: it does not exist on iOS Safari, and a rotate-please interstitial is an accessibility failure. The brief PDF was the third attempt at the same bug, this time with proof that the download chain is provably correct end to end and iPhones still open the file in Safari's viewer, because iOS treats a top-level PDF navigation as previewable and ignores the instruction to save it; the happy path never navigates now, it fetches the bytes and saves them through a same-origin link named by the response itself, with the old navigation kept only as the degrade for environments whose storage permissions have not applied yet. A Hebrew or Arabic message was re-wrapping into a one-word-per-line column, because the browser reports a separate rectangle per directional run and the shrink-to-fit measurement took the widest WORD as the bubble width; it bails on strongly right-to-left text and keeps the natural width. The mobile header title had a cap that fit barely a word and now takes the free run to the buttons. The progress sheet rises and lowers like a real drawer instead of appearing and vanishing. A quiet back link could sit under the floating bottom bar. And confirming a scheduled call was reading the popup's return value and throwing it away, so a blocked popup gave the buyer no tab AND a recorded booking, which is precisely the signal that stops us inviting them again.
- The warehouse may say what a project is CALLED, and that needed a second wall to be built before it could. The project name is the fourth named carve-out through the wall between the product database and the reporting layer, and the first one that is free text; every earlier one moved an id or a derived bit. The wall's text half was a DENY list, which can only forbid prose somebody already thought to name, the identical hole a buyer id fell through twice before it was moved to an allow list, so the twin now exists: any column whose name contains one of a broad vocabulary of texty words, on any table, fails until it is explicitly authorised. Two existing columns that merely sound texty are authorised with the explicit claim that they are enums. The name itself lands as OPTIONAL rather than required, which is unusual and deliberate: the promotion guard compares what the reporting side needs against the contract vendored into whatever version an environment actually deployed, and production's version predates the carve-out, so projecting it plainly would have held production's entire warehouse pin. It flips to required once a production deploy has carried the new contract. Alongside it the reporting dashboard stopped reloading everything on every interaction.
A Tuesday of 36 commits, and the through-line is a promise you can actually keep. Five talents were told their boundary was noted and nothing was stored, because every read and write keyed on a marketplace number that is nullable by design and absent on two threads in three; it keys on the username now, on both sides, and where it still cannot key anything it fails loudly with no reply rather than sending a warm confirmation over an empty row. The rest of that flow got its four QA notes: a minimum that read back inverted, a second boundary that sounded like the first, an addition that was thrown away by a question about money, and a yes that saved nothing. Mira as an app inside Claude and ChatGPT went from skeleton to recognisable over eight passes, answering on her fast lane instead of the whole turn, wearing her own tokens, showing real talent photos and a real lockup, and no longer stacking the host's own instructions into the thread once a minute; she can also open more than one project now, which she could never do, and every new hiring need had been overwriting the last one. A booked call became a durable row with an honest verification tier instead of a single bit that a takeover release erased. A project remembers the device it was created on, with empty left honestly empty. The brief stopped opening itself on a brief it had not earned, and then stopped shutting on a client who had just opened it by hand. And a batch of phone repairs, most of them things only an iPhone does.