Changelog

Everything that's shipped

From the first proof of concept to today β€” newest first. Built in a nine-day sprint; versions were assigned to capability milestones afterwards.

v1.253.02026-09-07

🌍 One sentence in 28 languages described a product that no longer exists

  • The team-invitation screen told most of the world to “create a link and send it over a channel you trust” — the way invitations worked before they moved to e-mail. Czech and English were updated at the time; the other twenty-eight languages were not.
  • 283 sentences opened a quotation mark and closed it with a typewriter apostrophe — 88 of them in Polish alone.
  • The word for the box beside your television came back into 103 sentences: Norwegian had respelled it, Ukrainian transliterated it, and Greek and Turkish had translated it into the ordinary word for a cardboard carton.
  • An internal web address stopped appearing inside an error message anyone with access to a device could see.
  • Greek used two different words for a watch — one on the screen’s title, the other on that same screen’s buttons.
  • Smaller things throughout: a sentence saying an account “holds a role” where it meant a higher role, a Finnish “about ten” where every other language says twelve, and links that named a settings page by a title that page does not use.
v1.252.02026-09-07

🎯 A failed suite on the home screen opens its own summary

  • When a whole suite of checks fails overnight, its name on the home screen is now a link — it opens that night’s summary: which televisions it ran on, how many passed, and every member check with the reason the failing one gave.
  • From there, one click opens any individual check’s own detail, in the same panel.
  • A single check and a whole suite now lead to the same kind of place, so the two look-alike frames on the home screen promise the same thing.
  • A check with nothing behind it — no run, no summary — still stays plain text rather than looking like a control that does nothing.
v1.251.02026-09-07

👤 People fill in their own name, and dialogs fit on a phone

  • Adding someone no longer asks you to type their name for them. They fill it in themselves the first time they sign in, and the app will not let them past without it — so nobody has to guess how a colleague spells their own name.
  • Dialogs that are taller than a phone screen now scroll. A long one could previously run off the top, taking its heading and its first controls with it and leaving no way to reach them.
  • The main button in a dialog no longer sits flush against the bottom edge of the screen.
  • Two labels that were quietly wrong: the role you pick is now called the role in the team, because you are not always inviting anyone; and the password box says the minimum length instead of repeating what it is for.
v1.250.02026-09-07

🎯 A failed check on the home screen opens the run that failed

  • The name of a failing check is now a link, and it takes you straight to that run — no walking to Watches and scrolling for it.
  • When several checks fail, each one leads to its own run rather than to a shared list.
  • Only the checks are links. An offline television has no run behind it, so it stays plain text instead of looking like a control that does nothing.
v1.249.02026-09-06

🎨 The home screen says when production is behind

  • Overview now tells you when scenarios have been written but never promoted, instead of leaving that on the Scenarios screen where you had to go looking for it.
  • Across all projects it names them, one row each, and each row opens that project’s Releases — a single total would not tell you where to go.
  • It stays out of the way when there is nothing to say. No band means production is up to date.
  • The band is not part of the status verdict above it: work waiting to be released is not a fault, and it does not colour that card.
v1.248.02026-09-06

✨ Invitations become the way in

  • Adding somebody is one dialog now, wherever you start from, and it leads with an invitation: they get a link by e-mail and choose their own password.
  • Every invitation is addressed to one person. Transferable links and reusable invitations are gone — an e-mail address is what an account IS.
  • You can now invite somebody who belongs to no team at all.
  • If you still create an account with a password yourself, a welcome e-mail goes out. It never contains the password — it names the person to ask for it.
  • Before an invitation leaves, the app asks you to check the address. It cannot be changed later.
v1.247.02026-09-06

🎨 Tidying up old runs moved out of the way

  • “Delete runs of inactive scenarios” was a long button wedged into the filter row on Runs, and it never fitted — it dropped onto a line of its own at every window size, even on a wide monitor.
  • It is now an item under a small “⋯” button at the end of the row, so the filters stay on one line in all 30 languages.
  • When there is nothing to tidy the button dims and says why, as before.
v1.246.02026-09-06

📱 Setting a time on a phone now works with a thumb

  • The little arrows next to the time were far too small to hit on a touch screen. They are now full-size buttons on either side of the value.
  • On a phone the time control takes the whole width of its row instead of being squeezed beside its label, and the scheduling dialog no longer runs off the side of the screen.
  • Nothing changes on a computer.
v1.245.02026-09-06

🔒 The privacy dialog no longer names an internal role

  • “Hide my history” explained that a “superadmin” would go on seeing your records — an internal role name, in 29 of the 30 languages. It now says the operator of the Screenwhere service, which is what it always meant.
  • The sentence is grammatical in each language rather than one word swapped in, and in four of them it deliberately avoids the word already used, a few words earlier, for your own team’s admin.
  • The Turkish and Italian versions of that same sentence carried older wording faults; both are fixed.
v1.244.02026-09-06

🎨 The last control the operating system drew for us is gone

  • The time field on Installation was drawn by your operating system, not by Screenwhere: its own shape, its own font, and a dark chip even in the light theme — and different in every browser. It is now the app’s own control.
  • Setting a time looks and behaves the same everywhere in Screenwhere, because the scheduling dialog and this row are now literally the same control.
  • The time is saved once you have finished typing it, rather than while you are still in the middle of a number.
v1.243.02026-09-05

🎨 Sliders now say what you are setting, and between which limits

  • The number you were setting sat at the far left of the row while the control sat at the far right — you had to look across the whole row to read your own change. It now sits with the control.
  • Neither end of the range was written anywhere, so three settings on completely different scales all looked as though they were set near the bottom. Both limits are now shown under each slider.
  • The handle is easier to see and to grab, on a desktop and on a phone, and every slider in the app now looks and behaves the same way.
v1.242.02026-09-05

🎨 The health panel now shows how big the problem actually is

  • One failing check used to turn the whole panel red, even while six other lines inside it said everything was fine. The panel is calm again, and only the thing that is actually wrong is marked.
  • Each problem gets its own line with its own name — a television that is off is named, instead of being counted as “1 device offline”.
  • When we cannot reach our own status page, the panel says so plainly instead of reporting that everything is fine. It had been giving the all-clear about something it had not managed to check.
  • v1.241.02026-09-05

    🎨 The folder picker’s last column reads as content again

    • The column listing what already lives in a folder was greyed down three ways at once — a tinted panel, quieter text and a smaller size — so the level you are actually aiming at looked switched off beside the ones you had already passed.
    • It now sits on the same surface as its neighbours at the same size and weight, and what marks it out is its heading and a firmer dividing line instead.
    • Where that column is the thing you pick from, nothing changes: the highlight there still means the one you chose.
    v1.240.02026-09-05

    🔒 Access tokens now need a name — and a new one looks like one token, not two

    • A token could be issued with no name at all. The list of tokens is the only place you can tell which one to revoke, revoking cannot be undone, and it cuts off whatever agent or script is using it — so two rows both reading “Unnamed” were two rows nobody could act on.
    • A name is now required, and it is the server that requires it, so a script cannot skip what the screen asks for. Pressing Enter in the name field also creates the token, which it never did before.
    • A token you have just created is now shown as its own entry in the list, under its own name. Previously the secret appeared in a separate panel above the list while the name appeared in the list below it, and the same credential read as two different ones.
    v1.239.02026-09-04

    🔒 The app no longer calls a third-party server to draw its text

    • Every page load used to hand a visitor’s address and browser details to an outside font service before a single word appeared. The typeface now comes from Screenwhere’s own server, and the app makes no request outside it at all.
    • It is also faster: one file of 293 kB instead of seven requests totalling 672 kB, so text settles sooner on a slow connection — and if that outside service ever goes down, nothing here changes.
    • Headings and labels are drawn at the exact weight they were designed for, rather than being rounded to the nearest available one.
    v1.238.02026-09-04

    🐛 The timezone setting shows the whole zone again

    • The timezone control in Settings was held to a fixed width and cut its own value in the middle of the zone name — on a desktop row that was two thirds empty, and on the phone too.
    • It now takes the width it needs and fills the row on a phone, so the value you go to that row to read is actually readable.
    • And on a screen too narrow for any width, a select that has to cut now ends in an ellipsis instead of stopping inside a word — everywhere in the app, in both reading directions.
    v1.237.02026-09-04

    📝 The app does load a webfont, and five places said it did not

    • The claim that the app bundles no webfont was false wherever it stood — the page has been loading Inter from an external stylesheet all along.
    • Nothing about the shipped languages changes: reading the font file itself confirms it carries Cyrillic and Turkish but no Arabic and no CJK, which is exactly what those releases concluded for other reasons.
    • A new check keeps the documentation honest by comparing what it says about fonts against what the page actually loads, in both directions.
    v1.236.02026-09-04

    🐛 The camera check can tell your camera moved again

    • The calibration card is now shown on the television as an app rather than in its browser, so it fills the screen instead of being drawn inside a toolbar at nine tenths of its size.
    • And the check no longer mistakes something in the room for a corner of the card — which is what made it report a card that was in fact perfectly placed as too small to judge.
    v1.235.02026-09-04

    🎨 Arabic that reads at its own size

    • Arabic is drawn smaller than Latin at the same size, so it now has a face of its own that is scaled up — and the Latin words beside it, a device name or a branch, keep exactly the size they had.
    • A select’s arrow no longer sits under its own text, the scenario editor reads left to right the way code does, and a run’s verdict says PASS, FAIL, SKIP or STOP in every language.
    v1.234.12026-09-04

    🎨 Right to left, round two

    • Icons that slide on hover now slide the way the page reads; the accent stripe on a row’s edge sits on the starting edge; and the words inside the video player, the review bar and the error plate align to their own side in Arabic.
    v1.234.02026-09-04

    🐛 Sentences that count, in thirty languages

    • “Cameras · 1 of 3 moved” now agrees with its count in every language that inflects the verb — Czech, German, French, the Slavic languages and a dozen more said it in the plural for one camera.
    • Forty-eight Czech strings opened a quotation mark and closed it with a typewriter one. They close properly now.
    • The empty-branches note says in every language what the app does: a branch left untouched merges itself into develop.
    v1.233.02026-09-04

    🐛 Two green ticks that had asked nobody

    • Before Screenwhere puts a debug build on a television it shows you two readiness lines. Both were fixed text: they said everything was in order for every television, whether or not it was.
    • The certificate line now asks the site box, and says what it hears — stored, missing, or that the box did not answer at all. The three are shown differently, because they mean different things.
    • The developer-mode line cannot be measured from here, so it no longer pretends: it states what the television needs instead of claiming the television has it.
    v1.232.22026-09-04

    🐛 The calibration card, spelling the set’s name

    • The card a television shows during camera calibration wrote the set’s name with plus signs where the spaces belong — SAMSUNG+UE43NU7192+(2018,+TIZEN). It reads the name properly now.
    v1.232.12026-09-04

    🐛 The Bin’s message, in thirteen languages

    • When a deleted scenario cannot be restored because one with the same identifier is already back, the message in thirteen languages spoke of the scenario’s name and sent people off to rename something. It now says what actually happened, in every language.
    • The neighbouring message about a name already taken in that folder contradicted itself in Polish and Ukrainian. It reads straight now.
    v1.232.02026-09-04

    ✨ Arabic — and the app reads right to left

    • Thirty languages. Arabic is the first written right to left, and the whole app turns with it: navigation, forms, lists, the sign-in and consent screens, the calibration card on the television.
    • What must not turn, does not: the logo, the video player and its timeline, the remote’s d-pad, charts — and every number with a unit, so "0.25 GB / 6 GB" reads the same everywhere.
    • Names people typed keep their own direction and are trimmed at their own end; Latin e-mails and addresses stay left to right inside Arabic sentences.
    v1.231.02026-09-04

    🐛 The audit legend, in Norwegian and Bulgarian

    • On the audit screen, the label for ordinary work — scenarios, installs, recordings, operating a television — read as "inspection" in Norwegian and Bulgarian. It is the opposite of what those rows are.
    • Both now say what they mean, and the Norwegian tooltip under the label goes with them.
    v1.230.02026-09-03

    🔒 Opening a television's debug console is written down

    • Screenwhere can put Chrome DevTools on a television's running app — the most far-reaching thing anyone can do here. Until now it was also the only one the audit trail said nothing about.
    • Opening a console is now recorded: who, which television, and when. The audit screen has a new filter category for it, in every language the app speaks.
    • One line per session, not one per click — and the trail records only what the server itself saw, so it never claims a session ended when nobody could know that.
    v1.229.02026-09-03

    🐛 A second camera reference no screen knew about

    • A television can keep a second reference photograph of its room, taken after dark, so the camera check has something to compare against at night. Recalibrating the camera is supposed to retire that photograph along with the rest of the old calibration.
    • It retired it only halfway: the device screen stopped listing it, while the check itself kept reading the picture off the disk. On one of our televisions that left a DAYTIME photograph sitting in the night slot, ready to be used as the judge after dark — and nothing on screen could have told you.
    • The check now asks the same record the screen does. What a device says about itself and what it measures itself against are the same thing again.
    v1.228.02026-09-03

    ✨ Chinese, Japanese and Korean

    • Screenwhere now speaks 29 languages. Chinese (Simplified), Japanese and Korean join the picker — the whole app, the sign-in consent screen an AI agent asks you to approve, and the calibration card that goes up on the television.
    • These three count differently from every language before them: they have a single plural form, and a number needs a counter word attached to it — so „3 devices“ is written three different ways in the three tables, each correct in its own grammar.
    • The calibration card is set in capitals with the letters spaced out, which is Latin typography. These scripts have no capitals, and the spacing pushes their characters apart — so the card drops both for them and keeps them everywhere else.
    • We expected to have to ship a font. We measured a television instead, and it already had one.
    v1.227.02026-09-03

    🐛 The camera check can use the calibration card again

    • When a run suspects the camera has been knocked, it puts the calibration card on the television and measures against that. On one of our cameras it could never find the card, and on the other it found four „markers“ that were furniture and a wall — and reported a camera shift of 237 pixels on a camera that had not moved.
    • The card is now looked for as a card: four discs of comparable size, arranged as a rectangle, on a bright white field. A yellow wall is not a yellow marker.
    • If the television draws the card at the wrong size — its browser sometimes leaves fullscreen — the check says it cannot judge instead of blaming the camera.
    v1.226.02026-09-03

    🐛 The scenario editor now speaks your language too

    • When a scenario does not validate, the editor explains why in the language you are using. Those messages had stayed Czech in every language — so a German saw a Czech sentence in the middle of a German screen.
    • Around twenty smaller labels that had been written into the app by hand now come from the translations as well: the remote’s OK and Mute keys, the device list’s State and Response rows, and the „Nothing found“ notices.
    • The audit screen’s filter for remote-control actions was called „Kontrola“ in nine languages, which reads as „inspection“ rather than „operating a device“. Corrected in all of them.
    v1.225.02026-09-03

    ✨ The app now speaks Ukrainian, Russian and Turkish

    • Three more languages, twenty-six in all. Pick yours under Settings — the list shows each language’s own name for itself, so you can find it without being able to read the current one.
    • The calibration card shown on a television now shouts your set’s name correctly in Turkish, where a lower-case „i“ becomes „İ“ and not „I“.
    • „N days ago“ now reads correctly in languages that count in more than two groups — it had been picking between just two forms.
    v1.224.02026-09-03

    🐛 Dates and numbers now look the way your language writes them

    • If you read the app in German, dates were shown the Czech way — „3. 9. 2026“ where German writes „3.9.2026“, and Hungarian writes something different again. The same for the decimal point in timings.
    • A few places asked your browser instead of the app, so the two could disagree on the same screen.
    • „5 min ago“ and the month names on the energy chart were written in Czech in every language. They are now in yours.
    v1.223.02026-09-03

    🌙 A television takes a second reference after dark

    • The overnight camera check was reporting that a camera had moved when nobody had touched it. It was comparing a dark room against a reference photographed in daylight, so nothing matched.
    • A device can now store a second reference, taken after dark with the calibration pattern on screen, so night is compared against night. The button sits under the camera calibration in the device detail.
    • In daylight it declines β€” the existing reference still works then, and a second one would add nothing.
    • Only do it when you know nobody has moved the camera: the stored position becomes what “the camera is where it belongs” means for every night after.
    v1.222.12026-09-03

    🔒 The address in our e-mails is the one you actually go to

    • The address printed under the button in invitation and password-reset e-mails is now plain text rather than a link. Our sending provider rewrites every clickable link through its own click tracker, so the address you could read and the address you would have gone to were not the same one.
    • That address is there so you can check the domain before you trust the mail, and it only does its job if it is the truth. Copy it if the button does not work.
    • The button itself still works exactly as before.
    v1.222.02026-09-03

    🐛 When there is one of something, the sentence now says so

    • In twenty-one languages the app used to write „1 Überwachungen werden gestoppt“ — the plural word beside the number one. German, French, Polish, Swedish and sixteen more.
    • It was not a typo in any of them. The sentences never offered the translator a place to put the counted word, so every language had to write it in and every language wrote it in the plural. Czech is the one language where that happens to be correct, and Czech is the language the app is written in.
    • Fixed at the root: a sentence can now be written once for one and once for many, in whichever languages need the difference. The ones that do not — Czech, Hungarian — write nothing extra.
    v1.221.12026-09-03

    🔒 Pages you see before signing in no longer show the app’s menu

    • The password-reset pages and an opened team invitation were drawing the full sidebar and top bar behind them. They are pages you reach without an account, so there was nothing there for you to use — only the shape of an application you had not signed in to.
    • Nothing private was ever reachable from them; the menu was scenery, and it is gone.
    v1.221.02026-09-03

    ✨ The app speaks twenty-three languages

    • Ten more: Swedish, Danish, Norwegian, Finnish, Bulgarian, Croatian, Slovenian, Lithuanian, Latvian and Estonian. That completes European coverage.
    • Slovenian has a dual and Latvian a zero form, so counted words there need shapes the engine could not produce before — „2 napravi“ is not „2 naprave“, and nothing but a reader of the language would ever have noticed.
    • Translating found faults in languages already shipped: a Polish audit line said a colleague had deleted your recording when the storage sweep had, and the French consent screen sent you to a menu item that is not called that.
    v1.220.02026-09-03

    ✨ A forgotten password is now yours to fix

    • The sign-in screen sends you a reset link instead of an address to write to — the whole thing takes a minute and needs nobody at our end.
    • The link is good for an hour and works once; asking for a new one retires the old, so an old mail in your inbox is never a spare key.
    • The form answers the same way whatever you type into it. It will not tell a stranger whether an address has an account here, which is the point.
    • A reset signs you out everywhere, including devices you had marked as trusted — and it does not switch off two-factor: the link proves your mailbox, not your identity.
    v1.219.02026-08-31

    ✨ The app speaks thirteen languages

    • Dutch, European Portuguese, Romanian, Hungarian and Greek join the eight already there — the whole interface, the sign-in consent screen and the calibration card a television puts on screen.
    • Each language is picked from a switcher that names it in its own words, and the choice follows the person rather than the browser.
    • Translating the product found five faults in the original that reviews in English could not see — among them a dashboard line that read “1 devices offline” in six languages, and a tab named one way in the interface and another way in the sentence pointing at it.
    • Counting words now follow each language’s own grammar rather than Czech’s, which is what lets Romanian say “20 de dispozitive” and Hungarian keep a counted noun singular.
    v1.218.02026-08-31

    ⚙️ The app can send e-mail, and the invitation lands in the inbox

    • The mail plane is live in production: team invitations now arrive as an e-mail instead of a link somebody has to copy and forward by hand.
    • Proven by delivery rather than by configuration — the first message from a brand-new domain landed in the inbox, not in spam, which is DKIM and DMARC both passing.
    • An API key that cannot be carried in an HTTP header now reads as off rather than as configured, and the relay says so once at startup. A pasted placeholder used to fail silently on every send.
    • Invitations still mint and stay copyable whenever mail is unavailable: no feature here requires e-mail to exist.
    v1.217.02026-08-31

    ✨ A first-time visitor gets English

    • If you have never picked a language and your browser asks for one Screenwhere does not speak, you now get English rather than Czech — Czech is exactly as unreadable to a Swede as Swedish is to us.
    • Anyone who has ever chosen a language sees no change at all: your choice still wins, on every screen, including the ones rendered before you sign in.
    • The app now asks your browser which language it prefers. Until now it never did, so a German browser was handed the fallback even though German was there all along.
    • A missing translation still falls back to Czech behind the scenes, which is deliberate: it is the one table guaranteed to be complete.
    v1.216.02026-08-31

    📝 The documentation is drawn, in light and dark

    • Forty-four screens across the docs are now drawings rather than screenshots or empty frames, each one pointing at the single thing that matters on it — and each following your theme.
    • The walkthrough promised a tour of every screen and covered sixteen of twenty-one. Scenarios, the editor, monitoring, runs, the client’s day view, releases, promotion, projects, installation and the invitation page were all missing.
    • A new Guide page walks through using Screenwhere in the order you actually meet it, from the first sign-in to handing the installation to an agent.
    • Both pages had been describing pictures that were never going to arrive. They describe what is actually there now, and a test keeps it that way.
    v1.215.02026-08-31

    ✨ Screenwhere now speaks eight languages

    • German, Slovak, Polish, French, Spanish and Italian join Czech and English — the whole app, not just the main screens, including the sign-in screen an AI agent sends you to and the calibration card that goes up on the television.
    • Pick yours in Settings: the list shows each language in its own name, alphabetically, and switches instantly without reloading. A language downloads only for the people who read it, so eight of them cost nothing to everybody else.
    • Translating every sentence turned up an old mistake in the English: two messages named a “Manager role” that does not exist — the role is called Read-only. If you ever hit that message and went looking for the role, that is why you could not find it.
    • More languages are coming in batches; this is the first six.
    v1.214.02026-08-31

    🐛 “The camera moved” — when it hadn’t

    • One office TV refused to run its nightly check four nights in a row, reporting that its camera had been knocked out of position. The camera had not been touched. In daylight the same camera measured fine.
    • The check compares what the camera sees now against what it saw when it was set up, and reports how far it has drifted. Before dawn the room is nearly dark, so there is almost nothing to compare — and the check was answering anyway, with the closest of many equally poor matches. Because the same thing happened every night, the same wrong answer came back every night, which made it look convincing.
    • It now asks a second question before it answers: did we actually find a match? When the answer is no, it says the measurement was inconclusive instead of blaming the camera.
    • The nightly check on that TV still does not pass in the dark — a check that could not measure anything should not report success. But it no longer sends anybody up a ladder to a camera that is exactly where it should be.
    v1.213.02026-08-31

    📝 The documentation stops leaving out half the app

    • A new Guide page walks through using Screenwhere in the order you actually meet it — first sign-in, adding a television and the camera watching it, recording, writing a scenario, letting it watch on a schedule, and handing the whole thing to an agent.
    • The screen-by-screen tour claimed to cover every screen and covered sixteen of twenty-one. Scenarios, the editor, monitoring, runs, the client’s day view, releases, promotion, projects, installation and the invitation page were all missing.
    • Two things the pages said were simply no longer true: that Settings still holds the installation controls, and that the empty frames would fill themselves in from a build. Neither was the case.
    • Team invitations and the client’s day view are described in the feature list for the first time.
    v1.212.02026-08-30

    ⚙️ Getting ready to speak your language

    • Screenwhere speaks Czech and English today; this release builds the machinery for roughly nineteen more European languages, starting with German, Slovak, Polish, French, Spanish and Italian. Each language will download only for the people who actually read it.
    • Plural forms now follow each language’s own grammar rather than inheriting Czech rules — Polish counts 22 differently than Czech does, and the app will get that right before the first Polish word ships.
    • If a translation is ever missing a phrase, you’ll see it in English rather than Czech — a gap in a German screen should read in the language every market half-knows.
    • The audit log’s coloured markers from the last release now carry a legend, so you don’t have to guess what a red row means — and a record opens from a click anywhere on its row, not just the little arrow.
    v1.211.02026-08-30

    🧪 The checks that guard our own code, checked

    • Nothing in the product changes here. We went through every automated check that exists to stop a mistake reaching you, and asked whether it tests what it promises or merely something that usually comes with it. Eight of thirteen tested the easier thing.
    • The most serious: the check that stops one of us deploying over a colleague’s work-in-progress could be switched off by a single character, and the test written to protect it would still have reported everything fine. It now looks at what the script does rather than at the words in it.
    • Two checks were already right, and they are the pattern the rest were rebuilt on: one compares two lists against each other, the other simply runs the thing and watches what happens. Neither can be fooled by rewriting how the code is spelled.
    • Four of them now try to break themselves on every run. A check nobody has watched fail is a check whose strength nobody knows.
    v1.210.02026-08-30

    🎨 The audit log shows you which events matter

    • Changing a password, turning off two-factor sign-in or promoting somebody used to look exactly like running a scenario — the same grey line in the same list. Security events now carry a red marker, team and project changes an amber one, so the things worth a second look find you instead of waiting to be noticed.
    • The log shows the most recent records, not all of them — and it never said so, which meant a search that came back empty could mean “this never happened” or “it happened before the window”. A line above the list now tells you how many records you are looking at and how far back they go.
    • Searching works while you type, tells you how much it narrowed things down, and stays on screen as you scroll. It is also available to everybody now, not only administrators — looking up your own sign-ins is exactly why you open this screen.
    • Every row opens to the exact time down to the second, the technical name of the action, and where it came from — the detail you need when you are reconstructing what happened in a busy minute.
    v1.209.02026-08-30

    🧪 Two test runs stop climbing into each other

    • Our own test suite used to reserve fixed network ports, so two runs on one machine fought over them and the loser failed for reasons that had nothing to do with what was being tested. Every suite now picks a port of its own.
    • The check meant to prevent that had been passing over the last two offenders for a year, because it recognised only the way the problem had looked the first time. It now asks what a test does rather than how it is written.
    • Nothing in the product changed. This is the kind of release that makes the next few more trustworthy: a failing test now means a real fault, not a collision with somebody else’s run.
    v1.208.02026-08-30

    🎨 Settings keeps the person, and the installation gets its own screen

    • Everything about the installation itself — recording limits, disk reserve, operations alerts and the nightly branch sweep — moved to its own Installation screen under Administration. Settings is about you again, and is roughly a third shorter.
    • The groups were redrawn: sign-in and security apart from what agents and connected apps may reach, and preferences split by when they apply — while you drive a device, and while you play a recording back.
    • Your name is edited straight from the account card at the top, which was already printing it. The row that repeated it is gone, and deleting the account is a quiet link under the screen rather than a row you scroll past.
    • Changing a preference now says it saved. Four of them used to change silently, which looked like a setting that had moved on screen but nowhere else.
    • The Installation screen states who it belongs to instead of opening for whoever asks: hiding its menu row was never a lock, and the address could simply be typed.
    v1.207.02026-08-30

    🎨 The Day screen uses the app’s own controls, and an empty tile stops talking

    • Picking the television and the date now uses the same controls as the rest of the app. The Day screen held the only native date box anywhere in it, so a system widget sat among styled ones.
    • The date opens a small calendar; the arrows and “Today” stay, because stepping one day is the common move.
    • When an hour has no picture, the tile simply shows there is none instead of writing “no picture” over it — the reason stays in the one place every other hour keeps it.
    • Found on the way: the Day screen could not be exercised in the local fixture at all, so it now seeds a full day with real pictures and one hour deliberately without one.
    v1.206.02026-08-30

    ✨ Joining a team is an invitation, not a list

    • A team admin mints an invite link on the team card — role, expiry, single- or multi-use, revocable. Whoever opens it sees the inviting team’s name and nothing else: no customer roster ever renders anywhere.
    • A new person picks their own password on accepting — the temporary-password handoff is gone for this door. Adding someone by hand still works alongside.
    • An expired, spent, revoked or made-up invite all answer the same one sentence, so the invite address cannot be used to probe which teams exist.
    • The relay can now deliver an invite by e-mail, bound to that address — and only that address can accept it. The team-admin role can be granted exclusively this way: possession of the mailbox is the verification.
    v1.205.02026-08-30

    🎨 The account badge shows only where it means something

    • Every row used to carry a badge, and eight of nine said “ordinary user” — which is not a state, it is the absence of one. The one badge worth finding was buried in a column you had to read.
    • In a list of nine accounts the superadmin is now the only thing lit, so you find it at a glance.
    • Nothing shifted: the slot keeps its width, so the ⋯ menu stays on one vertical line down the list.
    • On a phone the badge sits on its own line, so there it is dropped rather than reserved — no blank line under every ordinary account.
    v1.204.02026-08-30

    🎨 The screen is named after the one thing only it can say

    • “Device status” is “Cameras and availability” now, and the camera overview comes first. Three of the screen’s four blocks were already answered by the home status band and the device list; the cameras were not answered anywhere.
    • The “N online / M offline” pills are gone — that was the band’s own device row counted a second time, by a different route and on a different clock.
    • A blind camera on a perfectly healthy box now ranks with the offline sets instead of sinking into the alphabet, and the row says why it ranked there. An unplugged camera reports itself online, and always did.
    • Found on the way: a clock test failed for one hour in every twenty-four — the hour in which Prague is already tomorrow and Lisbon is not. It took the wall clock; it now takes a fixed instant, and that seam has a test of its own.
    v1.203.02026-08-29

    🎨 Users speaks the same language as Teams

    • An account row carried five look-alike buttons; it now carries one badge and a ⋯ menu — the shape the member row on Teams has had all along. A three-account screen went from fifteen controls to six.
    • Superadmin was a button sitting in a row of buttons. It is a badge now, because it says what an account IS; the switch moved into the menu with the other account actions.
    • An action you cannot use stays in the menu with its reason written into it — “Reset 2FA — not enabled for this account” — instead of a greyed button whose reason you had to hover for.
    • Someone in more than three teams gets a summary by role — “9 teams · 3× team admin” — and one press unfolds every team, each still a link into it.
    • Found on the way: memberships, not buttons, decided how tall a row was. An account in nine teams drew a 349px row against 147px for two. It is 92px now.
    v1.202.02026-08-29

    🐛 A click closes the hint instead of pinning it

    • Clicking into a dropdown used to leave its hint hanging over the very menu it opened. A click means you are using the control, so the hint now gets out of the way — and hovering again brings it back.
    • On a phone, tapping a live control opens it without drawing the hint over it — a tap is a command, not a question.
    • Controls that are switched off still explain themselves when tapped: on a phone that hint is the only place the reason is written.
    • Choosing with the keyboard closes the hint too.
    v1.201.02026-08-29

    📱 Picking a scenario on a phone stops being a squeezed desktop

    • The folder browser was built for a wide screen. On a phone it now steps forward instead: the panel you are in slides aside, the list fills the screen, and one arrow takes you back — out of a folder first, then out of the picker.
    • The same on all six screens that ask where something belongs or which scenario you mean, so there is one thing to learn rather than six.
    • Typing into it no longer zooms the whole page in and leaves it there — a small detail that made the search box unusable on an iPhone.
    • Rows are large enough to hit with a thumb, and the sideways scrolling inside a page that already scrolls down is gone.
    v1.200.02026-08-29

    ✨ A camera check that measured nothing no longer passes

    • A camera was unplugged for two days and every nightly run stayed green. The check had honestly reported that it could not see — and “could not see” was being read as “all fine”. It is not: a check that measures nothing now stops the run.
    • Device status has one Cameras line. Green while every camera is being measured; the moment one is not, it changes colour, says how many, and names the one that is out.
    • A camera now keeps its own state between runs — when it was last measured successfully, and since when it has not been. That is what makes “for two days” something you can read anywhere.
    • A run’s detail says WHY a check passed, not only that it did. There are four ways a camera check can pass, and until now all four wore the same green tick.
    v1.199.02026-08-29

    ✨ The team’s clock for watches, your clock for reading

    • A team can declare its time zone. Daily watches of its projects are typed and run on that clock — “at 03:00” means 03:00 on the team’s wall all year round, daylight saving included, which stored times never managed before.
    • Everyone on the team sees the same number on a watch, wherever they sit; your own reading appears beside it only when your clock disagrees today.
    • Your account has a clock of its own too, set in Settings and following you across devices — every time in the app reads in it, and the row compares your “now” with each team’s at a glance.
    • Changing a zone never moves when anything runs. It changes how a time is written; every scheduled moment stays exactly where it was.
    • Two repairs found by clicking: the dialog for a new scenario watch had been broken for three days without anyone noticing, and the two-factor prompt greeted every start even where two-factor is not required.
    v1.198.02026-08-29

    🎨 Choosing a scenario works the same way everywhere now

    • The run history had the last plain drop-down list of scenarios left in the app. It is now the same browser you already use to file a scenario and to set up a watch — folders on one side, what is in them on the other.
    • It can be searched. Three letters find a scenario by name and show which folder it lives in, which a plain drop-down cannot do at all.
    • It also closes a quiet fault: two scenarios may share a name, and asking for the runs of one by name alone came back empty — indistinguishable from “this one has never run.” The filter now says exactly which of the two it means.
    • Narrowing the list still works the way it did: pick a scenario and a band appears saying which one, with a cross to clear it.
    v1.197.02026-08-28

    πŸ“ These release notes are readable too

    • The previous pass shortened the internal record; this one does the same for the page you are reading. All 331 entries, back to the first proof of concept, are now a handful of short points instead of a paragraph.
    • A single icon on each heading says what kind of release it was — a new capability, a repair, a matter of appearance, a question of who may do what.
    • Nothing was invented for the occasion: the page carried bullets like these until about v1.51, and the styling for them had been sitting unused ever since. This is a return rather than a redesign.
    • A little over a quarter shorter overall, and the longest entry is now shorter than the old average.
    v1.196.02026-08-28

    🎨 Every drop-down menu now looks like the app it lives in

    • Pickers had quietly grown apart: some screens dressed them to match the app, others left the browser’s bare grey control.
    • Even the dressed ones gave themselves away the moment you clicked — the list that unfolds was the operating system’s own menu, in its own font and its own blue, ignoring dark mode entirely.
    • Both halves are one thing now: every picker wears the same clothes closed, and opening one unfolds the same styled list you already know from the filters on the Devices screen — in your theme, over dialogs when it needs to be, on the phone too.
    • Nothing about how they work changed. The same choices, chosen the same way, and the keyboard still does everything it did: arrows, Enter, Escape, even typing a name to jump to it.
    v1.195.02026-08-27

    πŸ“ The release notes are readable again

    • Every entry in the release history has been rewritten as a handful of short points instead of an essay.
    • The record is now under half its previous length, with nothing dropped that a reader would come looking for — the findings and the measurements are all still there, just said once instead of three times.
    • The shape is written down, so it stays that way.
    v1.194.02026-08-27

    ✨ The home screen now opens by telling you whether anything is wrong

    • The home screen opens with a single sentence across the top: green and quiet when there is nothing to do, and when there is, it opens by itself and shows what.
    • Underneath, two groups — the checks on your own application, and the machinery we run to carry them out. The second is new, because something down the corridor cannot honestly report its own outage.
    • The quiet reassurance behind a red check: when our televisions and our video are confirmed healthy, a failed check really is about your application. And while something of ours is broken, the app stops presenting failed checks as verdicts at all.
    • Each part of the service is named by what stops working — live picture, sign-in — instead of by the machine behind it.
    v1.193.02026-08-26

    🎨 A suite of checks now reads as one line, phone included

    • A set of checks is drawn as a group of its own: the count leads, and a coloured bar shows the shape of the result at a glance.
    • The runs are gathered under the television that ran them, each with its own count — the sum people were doing in their heads.
    • On a phone every one of these lays itself out properly instead of being squeezed, and a failure reason is written out in full rather than cut off mid-sentence.
    • The button that runs a set has left the row of filters it was hiding in: it is the only control there that actually presses buttons on a television.
    v1.192.02026-08-26

    πŸ”’ Your team’s builds and your team’s history follow the team

    • The shared library of uploaded builds opened to anyone who merely happened to be in the same team as whoever uploaded a package — while the person genuinely running that team, if their account said “ordinary user”, was shown nothing but their own.
    • The activity history did the same thing with people: a title was enough to read colleagues’ activity in every team the account sat in, administered or not.
    • Both now ask the only question that means anything here — which teams do you administer. Nothing about your own uploads or your own history changed.
    • With this, the title on an account no longer decides anything anywhere in the product.
    v1.191.02026-08-26

    πŸ”’ When something is greyed out, it now tells you which team said no

    • Every control the app will not let you use carries one short sentence explaining why, and it said your account was read-only — which stopped being true the moment roles began belonging to teams.
    • A greyed-out control with a false explanation is worse than one with none: it sends you off to ask for permission you already have somewhere else.
    • The sentence now names the team the refusal came through. Where two teams share the thing it names neither, because the wider of your two roles is what decided.
    • Underneath the wording, a quieter fault: the app was still deciding what to grey out from the old word on the account — so somebody genuinely read-only everywhere saw every button lit and failing on click, while an older account carrying the word saw the whole application greyed out for no reason at all.
    v1.190.02026-08-26

    πŸ”’ The same person can be a manager in one team and a reader in another

    • A role now belongs to the MEMBERSHIP, not to the person. The colleague who runs your team’s testing may be a guest in the team next door, there only to watch.
    • Where two teams share a television the rights add up: being read-only in one team was never meant to take away what another team gave you.
    • The Users screen stops handing out roles and starts explaining them — each person’s row lists the teams they are in and what they may do in each. The only switch left there is superadmin.
    • An account that is in no team says so plainly, with the one door out of that state beside it; otherwise somebody reports it as a broken application two days later.
    v1.189.02026-08-26

    ✨ See what was actually on the screen at the hour you asked for

    • A new screen called Day: one television, one day, read left to right, with a camera frame and a result at every hour you ordered. The hours come from the daily checks you already have.
    • The picture is the answer rather than an attachment to it — the camera was already taking that frame at every check and quietly throwing it away.
    • UNKNOWN is a real answer and deliberately grey rather than red: a camera somebody nudged says nothing about your application, and if those glowed red you would soon learn to skip red altogether — and skip the real failures with them.
    • One note of honesty: the timeline will look sparse at first, because older runs simply have no photograph to show.
    v1.188.02026-08-26

    πŸ”’ Who may take a television is decided by the team it belongs to

    • A single word on someone’s account let them take over any television in the whole installation, calibrate it and read every device’s network addresses — whether or not they belonged to the team that television was given to.
    • The question is now asked the way the rest of the product already asks it: the people who administer the TEAM a television belongs to are the people who may take it from whoever is using it.
    • One rule did not change — nobody takes a television away from Screenwhere support while they are holding it.
    • The “Take over” button is drawn from what the server actually permits for that television, so it is never offered to someone who would be refused, nor hidden from someone who may press it.
    v1.187.02026-08-26

    ✨ Your test results and our outages stop sharing one inbox

    • One webhook carried two completely different kinds of news. “The agent in your office has gone offline” is our obligation; “last night’s smoke test did not pass” is a verdict about your application.
    • Sharing one channel meant whoever watched for one kind learned to scroll past the other, which is how an alert quietly stops being an alert.
    • Scheduled-run results can now have a channel of their own. Leaving the field empty is a real answer and the common one — everything arrives exactly where it always has — and emptying it again sends the verdicts back rather than dropping them.
    • Each field has its own “send a test” button, because “alerting works” is now two claims and one button could only ever prove one of them.
    v1.186.02026-08-26

    ✨ A label is now something you can run

    • A label IS a suite. Labelling a scenario adds it to the nightly set; removing the label takes it out.
    • A schedule can watch a label, your build server can ask for one in a single line, and an agent has a tool for it — so “the suite passed 11 of 12” is a sentence this product can finally say.
    • One row instead of a dozen: one line in your notifications and one message to your team’s channel instead of thirty-six over a night.
    • A member that could not be run does not quietly count as a pass. A set two thirds of which never ran is not reported as green, because a number like that is worse than no number.
    v1.185.02026-08-26

    πŸ”’ A television nobody has been given to belongs to nobody

    • A television that had just been added — before anyone decided which team should have it — was visible to every single person with an account.
    • It was a leftover safeguard from an old data migration, quietly answering a question it was never meant to answer. A device now belongs to nobody until it is given to a team.
    • The device list tells the operator in one amber line how many are still waiting to be handed over, with a button that shows exactly which. A device deliberately kept private is not counted — that one is withheld on purpose rather than forgotten.
    • A colleague who has not been given anything yet no longer reads “add your first device” next to a button they are not allowed to press.
    v1.184.02026-08-26

    ✨ Your build server can run a test on a real television

    • A single line in your build script can now run a scenario on a real television and get the answer back, with no Screenwhere window open and nobody watching.
    • The answer arrives the way a build script expects one, so a failing test fails the build without anyone writing code to interpret it.
    • “The application was wrong” and “the test could not be run” are different answers: if a colleague is using that television, your build is not marked broken, and the television is left alone rather than taken over mid-demo.
    • A run started this way is labelled as coming from your pipeline everywhere it appears afterwards, so the history never suggests a person was standing there at three in the morning.
    v1.183.02026-08-25

    🎨 Setting up a watch reads like one page again

    • The window for scheduling a scenario had grown to seven stacked sections in a narrow strip, so it scrolled. It now reads in two columns — what gets watched on the left, when and how on the right — and fits.
    • Choosing which scenario to watch is the same column browser used when filing one, so you walk projects and folders to it, with a filter box when you would rather type.
    • A selected switch used to wear the same solid green as “Save”, so the control for choosing a schedule looked exactly like the control for committing it. Selected things are now marked rather than shouted, everywhere in the app.
    • The paragraph of assorted footnotes was split up, each sentence moved next to the thing it explains, and the ones that only reassured were dropped.
    v1.182.02026-08-25

    🎨 Watching and runs are two screens now

    • The screen called Watching held two things with opposite rhythms: the plans that run scenarios by themselves, and the stream of everything that ever ran — most of which was not watching at all. The stream now has a screen of its own.
    • The menu reads in the order things actually happen: scenarios are what you wrote, watches are when they run by themselves, runs are how it went.
    • Each screen’s attention badge counts only what is yours to act on — your own things, or your team’s if you run that team — instead of everything you happen to be allowed to see.
    • A camera nudged out of position used to record as a plain failure, indistinguishable from the application breaking, and those failures counted as evidence when deciding whether a test was fit for production. It now records as an equipment error and stays out of the evidence.
    • A watch can no longer be asked to run more often than every thirty minutes: checking a screen every five minutes is uptime monitoring by another name, and the previous round would not even have finished.
    v1.181.32026-08-25

    πŸ› Choosing a team’s colour now shows you the colour

    • Pressing a colour did change the team, and the preview sitting directly in front of you did not move — what got redrawn was the list behind the dialog rather than the dialog itself. A control that appears to do nothing is worse than no control.
    • The custom colour, chosen with a slider rather than from the ready-made set, could not be picked at all: the code that follows the slider was looking for the card the picker used to sit on, and a dialog is a different kind of card.
    v1.181.22026-08-25

    πŸ› The team screen stopped saying the opposite of what the system does

    • The switch beside every person reading “administers the team” was showing the wrong thing. It showed a per-team mark, while the rule the system actually applies combines that mark with the account’s own type.
    • That produced two plain contradictions on screen: a colleague whose account type was already “team administrator” appeared with the switch off, as if he could not run the team — while the system let him; and a read-only colleague was offered a switch that could not possibly do anything.
    • The switch now shows the answer rather than one of its two inputs, and where the account type is what decides, it is dimmed and says so when you point at it.
    • The mark has not become pointless — it still decides who is told when the team’s tests run — so where the two come apart it moves into the row’s small menu, named after the job it still does.
    • Adding somebody to a team now asks in two steps: give an address, and if that person already exists they are simply added. The form only grows a name and a password when the address turns out to belong to nobody yet.
    v1.181.12026-08-25

    πŸ› The screens now look the way they were drawn

    • The two screens redrawn in the previous release did not match their sketches, and most of the difference had one dull cause: the app has a single button style, written years ago for a phone, where a button fills the width and is sized for a thumb. Every sketch quietly assumed a smaller version the app never had.
    • The word used to ask for that smaller version is a real word elsewhere in the styling, so last release’s automatic check looked it up, found it, and reported no problem. What was missing was the pairing of the word with the button, not the word — and once the check looked for pairs it immediately found a second of the same kind.
    • The panel at the top of the releases screen was repeating, word for word, the first row of the list a few centimetres below it.
    • Rows were nearly a metre wide while holding a short sentence, with their one control pinned to the far edge. That empty middle became a column that says something.
    v1.181.02026-08-24

    🎨 Two screens redrawn as wholes, instead of patched one finding at a time

    • The rows listing a team’s people were sized backwards. The largest thing on a row was an unlabelled × that removes somebody from a team — undone in a second — while the button that deletes their whole account, which cannot be undone at all, sat beside it at two thirds the size.
    • A row now carries one control, the only thing that screen actually changes. Everything to do with the account moved behind a small menu, so nothing irreversible is one stray click away, and a picture of each person sets the height so the rows stop drifting.
    • The Releases screen had never shown you a single release. That history had been sitting in the underlying record all along, written down at the moment of each release; the screen simply never asked for more than the newest entry.
    • One thing was deliberately left ugly. The coloured panels announcing that something needs a decision are louder than everything around them, and they stayed that way at the owner’s request. That settled another question: a tidier version of the screen was drawn with tabs and rejected, because a warning you have to switch to a tab to see is not a warning.
    v1.180.02026-08-24

    πŸ§ͺ The automated checks stopped blaming the wrong thing

    • For three releases running, a handful of the few thousand automated checks reported failures that turned out not to exist — run the same check on its own and it passed. Each time that cost an hour of looking for a fault in whatever had just been written, and each time there was none to find.
    • Most checks need a private copy of the server and each had been given a fixed telephone number to reach it on. This project is normally worked on in several parallel copies at once, so two copies running the same check both dial the same number; one gets through and the other fails deep in its own work, which reads exactly like a real defect.
    • Ten others started their private server and then waited a fixed moment before speaking to it — each figure a guess made on whatever machine the check was first written on. They now wait for the server to announce that it is ready, which it has always done.
    • The most useful change is the smallest: when a check fails, the report now names which one. It used to print only the closing lines, which is precisely why one of these was dismissed as unreliable twice rather than investigated once.
    v1.179.02026-08-23

    ✨ The app calls you by your name

    • Five more places name the person rather than printing an e-mail address: a team’s members, the activity log, the badge saying a television is busy, the message sent to a chat channel when a run finishes, and the label on a recording.
    • An account with no name yet falls back to its address, not to a note saying the name is missing. A one-line badge has no room for such a note, and “busy — name not filled in” would throw away the useful half of the sentence in order to apologise for the other.
    • The address is still what the product runs on underneath — it identifies the account and nothing is decided by the name — so two colleagues who happen to share one cause no trouble.
    • The half that was nearly missed: a name is a second way of identifying the same person, so every protection hiding the operator’s own account had to start covering names as well, or the product would have concealed the address and published the name beside it. The guard could not have caught it, because the hidden account had never been given a name and its broadest checks were comparing against nothing.
    v1.178.02026-08-22

    πŸ”’ The account types are named after what they may do

    • “Manager” sounded like the most powerful thing on the list and was in fact the only one of the four that may change nothing at all; “Member” described everybody, since an administrator is a member of a team too.
    • The four were also written down twice in what was supposed to be order of increasing power, both times with the read-only one above the ordinary one — so the menu that hands somebody an account type offered its first two choices back to front.
    • They are now Read-only, Standard user, Team admin and Superadmin, listed in the order they actually rank. The bottom two are named after what the account may do and the top two after who the person is, which is deliberate.
    • Worth spelling out, because getting it wrong would have been silent and serious: an account left carrying the old name would not merely have shown the wrong label — the system treats an unfamiliar account type as an ordinary one, so a read-only account would have quietly gained the ability to change things.
    v1.177.02026-08-22

    πŸ”’ The people who run Screenwhere are now invisible to the people who use it

    • Screenwhere has one account that can see and do everything, so a television can be looked at when a customer asks for help — and using it announced itself: the moment it took control, everyone else watching was told the e-mail address behind it.
    • Customers now see “Screenwhere support”, and what they are told stays true: if the picture disappears because support took the television, it says so rather than pretending the connection dropped.
    • Two moments were more revealing than any label. Asking to take over a television support was holding produced no reply whatsoever — a holder who can never be asked identifies themselves more surely than a name would. That also uncovered a fault: told nothing when its takeover was refused, an assistant assumed it had succeeded and carried on pressing buttons.
    • One honest limit: this hides the role from someone using the application, not from someone willing to read the page’s source.
    v1.176.02026-08-21

    πŸ› A notification is read by being looked at

    • Four failed overnight checks all lead to the same page of run history, and opening one of them used to leave the other three sitting there unread — the opposite of what the list is for, since you had just been shown all four.
    • The tempting repair is to say that arriving at a page reads everything about it, and that is worse: walking through a section is not the same as looking at what is in it, and it would quietly throw away the record of what you had not seen.
    • So the rule is the honest one. A run’s notification is read when its row actually crosses your screen and stays there a moment; a fast flick past it counts for nothing. Clicking one takes you to that run and makes it flash, rather than dropping you at the top of a list to find it yourself.
    • The flash had to be rebuilt: in the dark theme it was painted in a colour within a hair of the row it was highlighting, invisible in exactly the setting it was needed in.
    • A notification whose run has since been discarded is closed out on behalf of everybody who could have seen it — closed, never deleted, because a line here says something happened and only ever fades.
    v1.175.02026-08-21

    ✨ People have names now, not just e-mail addresses

    • Until now a person in Screenwhere was an e-mail address: the circle in the top corner showed its first two letters, so two colleagues at the same company could easily wear identical initials.
    • An account now has a first name, a surname and an optional second surname — three boxes rather than two, because some names really are three parts long, while a surname that happens to be two words fits in one box on its own.
    • The e-mail address has not been demoted: it still identifies the account, it is still what you sign in with, and nothing is worked out from the name except those initials.
    • Filling it in is not optional. Anyone whose account predates this release is asked once, on their next sign-in, by a panel whose only other way out is to sign out.
    • Two faults were found only by opening the app and using it, and neither would ever have failed a test: the panel stood back while the two-factor panel was up, which is wrong where two-factor is merely an offer — there the name would never have been asked for again, in any session, ever — and the Save button greyed itself out using a style this app does not define, so the instruction read perfectly and drew nothing.
    v1.174.02026-08-21

    πŸ“± The app can be added to a phone’s home screen

    • Screenwhere can now be added to a phone’s home screen like any other app: its own icon, its own name, and a launch that fills the screen without the browser’s address bar around it.
    • Two things had to change on the server, and both are the kind of fault that leaves no trace: describe the app’s own description file with the wrong label and the browser quietly ignores it, so the offer to install never appears; and without an explicit permission the background program takes charge of only the corner of the site its own file sits in, while every screen lives elsewhere.
    • Deliberately, that background program stores no part of the app. Storing it is the usual reason to have one, and it is also the reliable way to leave somebody running last week’s code with no way to notice.
    • It keeps exactly one page: the one shown when the connection is gone, written in both languages rather than guessing, because at that moment there is no way left to ask.
    v1.173.12026-08-21

    πŸ› Two log lines stopped hedging the gender of a machine

    • Czech carries the gender of whoever did something in the verb, so every line of the activity log has to take a position — and where the doer is a person, the log declines to guess and writes the ending both ways.
    • Two lines turned out to have the opposite problem: they hedged the gender of the server, which is the only thing that can ever write them and which the app names with a masculine word. The result read as if the machine might have been a woman.
    • The check that reads every Czech log line now runs in both directions, and no longer keeps a hand-written list of which lines describe the server — it reads that from the server’s own code, so a line that starts being written by the machine moves sides on its own.
    v1.173.02026-08-21

    🎨 The empty home screen says what to do next

    • On an account with no televisions yet, the home screen said one grey sentence and stopped there: no button, no link, not even the heading every other section keeps. The code drawing that part gave up before it reached its own heading.
    • It now shows what the device list itself shows when empty — the picture, the same wording, and for somebody actually allowed to add a television, a button straight to the form.
    • Who gets that button matters, and the page cannot work it out by counting: the server hides televisions a member has no right to see before it answers at all, which makes a member on a full installation look exactly like a superadministrator on an empty one. What the reader is allowed to do decides what they are told.
    • The two screens had also been describing one and the same emptiness in two different grammatical forms; they now share a single sentence, with the odd one out removed rather than left lying around.
    v1.172.12026-08-21

    πŸ› A recording plays back for the person allowed to watch it

    • Viewing a camera was recently put behind the sign-in, but playing back a saved recording does not travel over the camera’s own channel — it comes back on a separate playback channel that no television claims as its own.
    • The check therefore found no owner, and being deliberately built to refuse whatever it cannot place, it would have turned away every viewer, including the person whose recording it was. Nobody had hit it only because no recordings exist on the live server yet.
    • It now looks the television up by the camera the playback channel belongs to, and only when the channel itself matches nothing — so a camera genuinely named that way still speaks for itself rather than for its neighbour.
    • Who may watch has not changed in either direction: someone not signed in, an unknown channel and a camera the viewer has no right to see are all still refused.
    v1.172.02026-08-21

    πŸ› The audit log stopped deciding the actor is a man

    • Eleven lines of the audit log, all about projects, simply said the actor was a man, while the other eighty-one hedge the ending both ways. The two shapes sat two rows apart on screen, in the same log.
    • Four more of the same fault turned up that the original report had not counted — including one that looked like something the server did on its own, but is in fact recorded against the person who had been holding the device.
    • A new check reads every Czech audit line and refuses any that decides the matter, unless somebody has written down beside it why that line is an exception: the server naming itself, or a sentence with no particular person in it.
    • The same release fixes a test that had been calling the work queue broken in every working copy whose folder name contains a hyphen.
    v1.171.02026-08-21

    πŸ”’ Nobody reaches a camera by guessing its name

    • Publishing a video stream to the server required no password at all. The media server accepted any publisher on its streaming port, which the firewall opens to the whole internet — so anyone who knew or guessed a stream’s name could push their own video onto it, and the same unrestricted permission let them read a live office camera.
    • Each site now has its own publishing account, allowed to publish only its own stream and that stream’s playback twin. Reading is reserved for the server itself, so a viewer arrives only through the application and its sign-in.
    • Three further openings turned up while closing that one: the camera sign-in gate added the previous day could be walked around by typing the site’s older hostname, and browser-based publishing reached the media server directly over HTTPS, which meant restricting its own port had never closed that route.
    • Two of the tools that build this server would have quietly undone the work — the firewall script still opened both the streaming port and the administrative interface to the internet, and the configuration script replaced the web server’s configuration in a way the running container could never see, so every change reported success and changed nothing. That is the kind of fault that hides for months: editing the file by hand had always worked.
    v1.170.02026-08-20

    πŸ› Three small things the walkthrough saw

    • The checkbox offering to trust this device for thirty days was the single control on the sign-in card still drawn by the operating system, in the operating system’s blue. The stylesheet already contained the rule explaining why that must not happen, written out twice for other checkboxes; rather than a third copy it is now one shared style.
    • The badge counting devices that are online was coloured a successful green regardless of the number it showed, because the colour followed the label rather than the value — so with every device offline, in the worst state the screen can describe, it wore a green badge. A count of zero now renders neutral.
    • The Teams screen fetched its list once when the app started, so a change made by another administrator stayed invisible until a full page reload, while the neighbouring screens all refresh on every visit. Entering Teams now asks again, with the remembered list painted immediately and the fresh answer replacing it.
    v1.169.02026-08-20

    ✨ Two screens outside the app learned a second language

    • Two screens were never translated, and by coincidence they were the two most likely to be read by somebody who never opens the app at all.
    • The first is where you connect an AI assistant to your televisions. It carries what is probably the single most important sentence in the product — where that access is about to be sent — which is the one thing distinguishing a genuine connection from an impersonation, and a warning nobody can read is not a warning.
    • All five of its refusals are translated too. They reach the screen by a different route than the page, so translating one without the other would have produced an English page carrying a Czech error.
    • Which language you get is decided by the choice you made in the app, not by what your browser advertises: a great many Czech speakers run their browser in English, and going by the browser alone would have handed them an English consent screen.
    v1.168.02026-08-19

    ✨ Being signed out now tells you why

    • “Your sign-in has expired” was sometimes simply true and sometimes meant somebody had just signed your account out of everywhere. The same sentence covered both, which is a problem in one direction only: the moment it ought to have read as a warning was the moment it read as routine.
    • There are now six things it can tell apart, and the two that a person who did not do it needs to act on also say what to do about it.
    • A cancelled sign-in used to leave no trace at all, which is why every ending looked identical from the outside. The server now keeps a short note of the reason beside a one-way fingerprint of the sign-in — the fingerprint rather than the sign-in itself, so the note cannot become a second place where usable credentials pile up.
    • It survives a restart, because a restart is what happens on every update and an explanation that does not outlive one is an explanation nobody receives. After a month it is discarded, since by then the sign-in would have run out on its own.
    • Asking about a sign-in that never existed gets exactly the same empty answer as asking about one that expired, so this cannot be turned into a way of testing whether somebody else’s credentials are real.
    v1.167.02026-08-19

    🎨 The sign-in animation moves while somebody is still watching

    • The sign-in screen’s animated mark advanced once every thirty seconds, counting from the moment the page loaded — so the earliest it could ever move was half a minute in. Signing in takes about fifteen seconds.
    • The one audience this screen has, people arriving to type a password and leave, therefore never saw it; it played only for whoever had walked away from the keyboard.
    • The fix needed two numbers rather than one, because the interesting number was the first: the opening move now comes eight seconds after the page appears, and every move after that sixteen seconds apart.
    • Everything that used to stop the animation still stops it, and a missed moment is skipped rather than queued, so nothing ever plays catch-up.
    v1.166.02026-08-19

    πŸ”’ The team owns the work

    • The previous release stopped a departed colleague from changing a team’s tests but let them carry on reading them. The owner overruled that, and the correction is about ownership rather than permissions: the work belongs to the team, not to whoever happened to type it.
    • Somebody no longer on a team no longer sees that team’s tests at all, and gets it back by being invited back in — not by having written something once.
    • The reasoning that had been left standing was borrowed from the wrong place: everything that existed when projects arrived was marked open to everybody purely so the upgrade would not make anything disappear overnight, and that quietly became the standing answer to who is allowed to see this.
    • The mark grants nothing now, so it has been removed rather than ignored — the “visible to everyone” label included, because a label for a permission nobody holds is the interface lying about itself.
    v1.165.02026-08-18

    πŸ”’ An open project grants sight, never the right to change things

    • Take somebody off a team and they kept the ability to rewrite every test they had ever written, indefinitely — and an administrator could change the work of teams they had never belonged to. Both were described in the design notes as removed, and neither was.
    • Nothing about it looked wrong: the check deciding whether you may change a test never asks about the team, and the check standing in front of it begins with a shortcut for projects marked visible to everyone — which on the real system is the default project, holding every test there is.
    • Seeing a project and changing it are separate questions now, and the mark that was meant to preserve the first no longer answers the second. Nobody loses sight of anything.
    • It mattered most for work done from your own editor: those access tokens are not cancelled when somebody leaves a team, so a departed colleague’s connection kept working — over a route that also, by design, does not ask for the second login factor.
    v1.164.02026-08-18

    🎨 The masterplan joins the main menu

    • The product’s own build queue lives on a page inside the app, and the only way to reach it was to know its address and type it — which is another way of saying it was not really in the app.
    • It now has a row at the tail of the administration group, visible to the superadmin alone: the queue belongs to the product rather than to any customer’s data, and the server would refuse anyone else anyway — the menu entry is visibility, not the lock.
    • The navigation, the server’s list of countable sections and the audit screen’s labels are three copies of one list checked against each other by the tests, so the new row joined all three at once, and visits to the queue now show up in the audit’s counts like any other screen.
    v1.163.42026-08-18

    πŸ› The sidebar's active item has a shape, and the menu can be scrolled

    • On a medium-width window the sidebar collapses to a column of icons, and the marker behind the item you are on had shrunk to the width of the icon. The section dividers had shrunk the same way, which nobody had connected to the same cause: one instruction meant to centre the logo also tells every item to be no wider than its own contents.
    • Measuring that turned up something worse underneath. The menu needs about five hundred pixels of height and a phone held sideways offers four hundred and eleven, with no way to scroll — so Teams, Users and Audit were not merely out of sight but genuinely unreachable.
    • The scrolling had to be given to the list itself rather than the column around it, because the little cards that pop out beside a menu row would have been sliced off at the column’s edge.
    • The scrollbar stays hidden so the column does not change width depending on how tall the window is; the row left half-cut at the bottom is what tells you there is more below.
    v1.163.32026-08-18

    πŸ“± The touch floor asks about the finger, not the window

    • Controls meant to be poked with a thumb have a minimum size, and that minimum had been attached to how narrow the window is — which works right up until the phone is turned on its side, at which point the same device reports itself as nine hundred pixels wide and every one of those minimums switches off.
    • The finger does not change when a phone rotates, so the size was being decided by the wrong thing. The clearest example was the recording badge over the live picture: twenty-three pixels tall in landscape, and a tap on it starts or stops a recording.
    • Those sizes now hang on a question about the pointer — whether it can hover, and whether there is a mouse behind it — written once rather than in two places that could drift apart. A narrow window on a desktop keeps its larger controls, because reading a browser docked beside another one is a real way to work.
    • There was a tidier-sounding alternative — refuse landscape on a phone altogether — and it was rejected: a web page has no reliable way to forbid a rotation, so all it could do is cover itself with a request to turn the phone back, which declines to draw the screen rather than repairing it.
    v1.163.22026-08-18

    πŸ“± Fullscreen on a phone survives a rotation

    • Two of three faults came from the same wrong assumption: that a phone can be recognised by how wide the screen is. Turn the device on its side and the very same phone is nine hundred pixels across, so every rule written for “a phone” quietly switched itself off.
    • That is why the keyboard button and its hint reappeared in landscape on a device with no keyboard — and in fullscreen the hint arrived unprompted, because entering fullscreen gives the picture keyboard focus. The question it actually needs answered is whether there is a mouse behind the pointer at all.
    • Two buttons in the top corner drifted into each other: the minimum touch size was applied to one and not the other, while the gap holding them apart was arithmetic derived from the smaller size.
    • The third could lose a control for good: the floating remote is pinned by absolute position once dragged, so rotating the phone put it outside the picture, taking with it the only handle that could have moved it back.
    v1.163.12026-08-18

    πŸ› The keyboard control really leaves the player on a phone

    • On a phone the keyboard button over the live picture had already been removed once, and it had not held: touching the picture still raised a hint reading “the keyboard controls the TV”, which is advice about hardware the reader is not holding.
    • Two separate pieces had each been written assuming the other was doing the work. The script declined to move focus at phone width — but the video frame is focusable, so the browser was focusing it on its own as the ordinary consequence of a touch, and declining to ask for something that happens anyway changes nothing.
    • The check that had pronounced the first attempt sound was itself the third mistake: it simulated a touch from script, and a simulated touch carries none of the browser’s own consequences, so the very behaviour at fault could not appear in it.
    • One outright outage surfaced along the way: on the older of the two addresses the application did not start at all, because three shared code files were handed to the video server instead of the application server — and since the app cannot run without them, what remained was an empty page with no way even to sign in.
    v1.163.02026-08-17

    πŸ“± The scenario editor is a document on a phone, not a form

    • The whole app was walked on a phone, screen by screen, and the scenario editor was the stop that had to be rebuilt rather than tuned.
    • Measured on the device: the scenario’s own body began 821 pixels down, one entire screenful, with chrome and metadata occupying almost half the document — and stacked inside that were three separate scrolling surfaces, the innermost sliding sideways so that nearly two hundred pixels of every long line could only be reached by dragging.
    • The editor now opens on the scenario itself: one header row, the branch and tags collapsed into a summary line, and the schematic outline — previously hidden entirely on narrow screens — drawn as the default view, so nine tappable steps stand in place of thirty-eight lines of source.
    • Running moved to the floor where the thumb is, and the television a run will touch is named on the line directly above the button instead of seven hundred pixels below it.
    • One outright fault surfaced behind the appearance: a scenario’s folder could not be changed at all from the details sheet, because the picker’s popover was clipped away by the very sheet that contained it.
    v1.162.02026-08-17

    🎨 The menu grows a second level β€” and administration is finally visible

    • Projects, Teams, Users, the audit trail and device health lived two clicks deep behind the avatar, and while you stood on any of them the menu lit nothing at all — the whole administrative tree was invisible from the navigation.
    • The new structure follows a dividing line that fits in one sentence: the menu gets places, the avatar keeps the person.
    • Sections now carry indented child rows that appear while you stand inside the section, as real links that hide by display and never by a transform, so closed rows cannot linger in the keyboard’s tab order.
    • On the narrow icon rail the second level slides out as a panel beside the parent row, whose rows are clones of the real ones so the two renderings cannot drift apart — and since a lit child has no row of its own there, its parent wears the marker, without which the rail answered “you are nowhere” on the install screen.
    • The section-visit counter grew to cover all twelve destinations, so even the new rows’ right to exist will be decided by measurement rather than by guess.
    v1.161.02026-08-16

    ✨ Accounts can finally be created β€” and deleted

    • Until now an account could only come into existence sideways, by being added to a team. The screen actually called Users — whose icon has always been a little person with a plus sign — could change a role and set a password, but not add anyone.
    • No account could ever be deleted either: removing somebody from a team left their sign-in standing forever. Both doors now exist.
    • Creating over an existing address is refused outright rather than quietly resetting somebody’s password, which is why this is a new route and not a reuse of the password one.
    • Deletion follows one permission matrix on the server: your own always; a team admin only for an ordinary member who belongs exclusively to teams they run, because a foreign team must not lose a member behind its admin’s back; a superadmin for anyone except the last superadmin, who can never be deleted for the same reason they can never be demoted.
    • A deleted account takes its whole footprint with it — team memberships, live sessions, trusted devices, access tokens and connected apps.
    v1.160.02026-08-16

    ✨ The app remembers what happened while nobody was looking

    • A check that failed at 03:12 and healed itself by 04:05 used to leave nothing behind: the badge was clean because the situation was clean, and the alert had gone off to a chat channel and did not come back.
    • A bell in the top strip is that missing memory, carrying seven kinds of event — a device dropping off and returning, a check finishing either way, a branch that will not merge, a request to promote, a push, recordings deleted to stay inside a quota, and an install finishing or failing.
    • The dividing line against the badges already in the menu is deliberate: a badge means something is waiting for you and disappears when it is dealt with, while a row here records that something happened and only greys out.
    • Reading is per event. Opening one notification reads that one; opening the panel reads nothing at all, because a glance must not erase the record of what you had not seen.
    v1.159.02026-08-15

    ✨ Section visits are counted, so the menu's order can stand on measurement

    • The order of the sections in the new menu was the owner’s best guess, because nothing recorded anybody opening one — the audit trail keeps deliberate changes, not visits, so the two sections he ranked highest were precisely the ones nobody could see.
    • Every entry into a section is now counted: moving around inside a section is one entry, not several, and simply rendering a screen counts for nothing.
    • Counting requests on the server would have been easier and wrong — one background check quietly asks about releases on every navigation anywhere, so the release section would have won by a landslide while the number actually measured was total navigation.
    • It appears on the audit screen as a single sorted line, the ranking itself, where a section nobody visits shows an explicit zero: “nobody goes there” is an answer, not missing data.
    v1.158.02026-08-14

    🎨 The navigation no longer has to fit β€” it stands beside the content

    • The main menu had been overflowing quietly for a while: the content column is capped at a thousand pixels, the horizontal bar of sections needed more, and in a band of common laptop widths the avatar and the theme switch simply hung outside the window.
    • No amount of trimming closed that gap, so the sections moved into a vertical sidebar standing in the margin the app was already throwing away — the content gives up nothing.
    • Three widths rather than one threshold: the full menu, a slim rail of icons with the content column still whole, and on a phone a drawer that slides over the page, closes on Escape and hands focus back where it came from.
    • The home screen finally answers “where am I” — Overview is a row of the list and lights up like every other section, which the old bar never did.
    • The rows are real links rather than buttons, so a middle click, a ctrl-click or “open in new tab” now do exactly what they do everywhere else on the web. The navigation, which until this release had not a single automated test, is held by a net of fifty-four written against its structure and never its order.
    v1.157.02026-08-14

    🎨 Four more places where a picture was missing and prose was standing in for one

    • Four more places where a picture replaces prose, chosen by how much writing a drawing would save rather than by where one would look handsome.
    • The largest was where test suites live: three paragraphs describing a shape, which is the one thing prose is bad at. They are now two sentences beside a picture, with the forbidden route into production drawn rather than described.
    • The second explains something a customer feels on the invoice: the camera only sends its picture while somebody is watching, without which each camera would push around one and a half terabytes a month for nobody. Until now that lived in a single parenthesis.
    • One fault from the previous walk became an automated check: an amber route was ending in a green arrowhead, because an arrowhead knows nothing about the line pointing at it.
    v1.156.12026-08-14

    πŸ› A label's backing plate had bitten a gap out of the line it was meant to protect

    • Where a label sits on top of a line it gets a small plate of background colour behind it, so the line breaks cleanly around the words instead of striking through them.
    • On the architecture page that plate sat behind a label that does not sit on its line at all — it floats just above it — and its lower edge landed exactly on the line’s own height, nibbling a visible gap out of the green arrow the whole page is about.
    • An automated check now refuses to let a plate be placed over a line again. Unlike an overlapping word, whose width depends on the font and can only be judged by eye, a plate is a rectangle with known numbers and the straight runs of a line are too, so the overlap can be worked out exactly.
    • Two paragraphs beneath other diagrams had quietly become redundant: when the words moved out of the pictures and into the legend, the prose that followed was left saying the same thing a second time. Both now carry what a legend cannot.
    v1.156.02026-08-14

    🎨 The documentation's diagrams now draw what gets refused, too

    • The request was to smarten up the documentation diagrams. Measuring them first turned up two faults that were not matters of taste.
    • The picture explaining the one hard problem — that a television behind an office firewall can only be reached if the box inside dials outward — drew its lines by animating them into view. Readers who ask their computer to reduce motion never saw that animation, and so were left with only the dashed line showing the direction that is blocked: a picture asserting the exact opposite of the page it illustrates.
    • The second was a colour pointing at a name the stylesheet never defined, so the drawings always fell back on a dark red that reads fine on white and turns to unreadable brown on the dark theme.
    • Both are now held by the first automated check these pages have ever had — the absence of which is precisely how they survived unnoticed.
    • The look changed too: each step is a numbered marker on the line it belongs to, with the words moved into a legend below. Hover a number and its line, its marker and its sentence light up together — and it works from either end, by keyboard and by touch as much as by mouse.
    v1.155.02026-08-14

    πŸ› Coming back to the TV preview takes the TV back

    • Leave the editor’s live TV preview long enough and the system rightly concludes nobody is looking: after a quarter of an hour it stops the camera, releases the television and freezes the pane with a note promising that coming back will bring it to life. Half of that promise worked.
    • Verifying the other half needed something no test rig here can produce — a genuine human switch away to another browser tab and back, because automation always keeps its own tab in the foreground — so the owner supplied the two minutes himself while the server’s logs were read alongside.
    • The picture sprang back, but the television was not taken back: the screen said the set was free while its camera was being watched, and anyone else could have grabbed it mid-viewing. The resume logic knew only one of the two ways a returning tab can find itself holding nothing.
    • Returning now reclaims the television whenever it holds nothing — and if somebody genuinely took it while you were away, it stays theirs and the pane says so honestly, because a comeback must never steal a set out of someone else’s hands.
    v1.154.02026-08-14

    πŸ› Reclaiming storage removed a real file for the first time

    • When somebody goes over their storage allowance the system deletes their oldest unprotected clips until they are back under. That rule has been in the product for months and had never once removed a single real byte.
    • The reason is arithmetic rather than a bug: the smallest allowance anyone could set was one gigabyte, and the heaviest user on our own installation holds a hundred and seventy-seven megabytes. There was no way to bring the line down to where the usage actually is, so the rule sat waiting for usage to grow into it.
    • Underneath sat a second reason nothing had written down: every recording on our installation is marked to keep, and marked recordings are never touched, so even a crossed allowance would have deleted nothing.
    • The rehearsal was the real thing — three actual video files on disk, the allowance dragged below them through the real slider, and the next sweep deleted the two oldest unprotected ones, left the protected one standing, and wrote both removals into the audit log naming the file and the person.
    • We deliberately did not rehearse this on the live installation, because doing so would have meant unprotecting someone’s real recordings in order to have them permanently deleted.
    v1.153.02026-08-14

    πŸ§ͺ Two thresholds that had never once been crossed

    • Working branches age visibly: after a month without a save the picker dims a branch and prints its age, and after three months it folds it away. Nothing is ever deleted by age.
    • Those two numbers lived hard-coded in the browser page. A browser has no dial to turn for tests, and our own production has never held a branch older than a few hours — so in the entire life of the feature the dimming had never actually happened outside a rehearsal with artificially back-dated history. Rules that can never fire are rules nobody would notice breaking.
    • The server now owns the two numbers and sends them with the branch list itself, which means a test server can set them to zero days and watch a minute-old branch dim for real, boundaries and all.
    • For anyone running an older server the page keeps its previous behaviour untouched.
    v1.152.02026-08-14

    ✨ A branch the night could not merge used to stand forever

    • Every night the working branches nobody has touched merge themselves into the shared line. When such a merge hits a genuine conflict it stops and leaves it for a person — but the night then retried the exact same merge every single night, with the same result and a fresh audit entry each time, forever.
    • The sweep now remembers precisely what state the conflict was measured against and leaves the branch alone until either side actually moves; the moment it does, it tries again.
    • The owner of the branch hears about it once, the night it first appears. And the settings switch for sending conflicts to the operator’s channel, which had never been connected to anything since the day it was built, finally does what it says.
    • Two guards against quiet accumulation came with it: branches no test case leads to — invisible on every normal screen — now show on one list where they can be deleted recoverably, and pushing from a checkout refuses to create new branches past a sensible ceiling. Everyone in a project pays a small price on every open for every branch that exists, so a pile with no floor was everyone’s problem.
    v1.151.12026-08-13

    πŸ› Sign out everywhere” now admits everything it signs out

    • The panic button in Settings promised to sign out your sessions and forget your trusted devices — and it also, quite deliberately, revokes your access tokens and disconnects any AI apps you had connected, because a panic button that leaves working keys behind is not a panic button.
    • The dialog just never said that part, so anyone pressing it also silently cut off their own running AI agents mid-task. The sentence now tells the whole story before you confirm.
    • Behind this sits a full rehearsal of every destructive action in Settings against a disposable local copy — each proven from both sides: the thing that should die died, and the thing that should survive survived.
    • The rehearsal also caught a page that would wait forever instead of admitting failure: it had already promised the browser a success before it tried to build the page, so when building failed the browser waited indefinitely for a body that would never come.
    v1.151.02026-08-13

    πŸ› The screen pattern the camera check shows was never actually being looked at

    • When a scheduled watch suspects the camera has been bumped it can put a known test pattern on the TV and check again. Measuring that step revealed something embarrassing: the re-check compared exactly the same thing as the first one — the wall around the TV — and by design never looks at the screen itself, so the pattern it had just displayed was the one thing it ignored.
    • “Confirmed with the pattern” was really a third ordinary look, six seconds later. The re-check now genuinely finds the pattern’s four coloured discs and measures where they are against where the calibration says they should be.
    • That also unlocks a case that used to go unanswered: a TV against a bare or dark wall, where the first check has nothing to grip and previously shrugged — roughly one time in five on our own history. Now the pattern goes up and decides.
    • The result stopped lumping three different outcomes into one: “false alarm, cleared” and “the wall could not be read, the pattern decided” are different facts, and calling the second a false alarm would invent an alarm that never happened.
    v1.150.82026-08-13

    πŸ› A release that never happened, and a server that would not admit it had failed to start

    • The releases screen named a date and a person for projects where nothing had ever been pushed to production — it was reading the very first thing ever saved and calling it a release. We checked our own server: nothing has ever been pushed there, and both projects were nonetheless reporting one. It now says “never”.
    • The line translating the nightly tidy-up into your own clock was translating from a timezone it had assumed rather than one it had asked about. On our machines the guess happened to be right; anywhere else it was silently wrong. It now asks, and when it cannot find out it says nothing — a missing translation tells you nothing, a wrong one tells you the wrong hour.
    • And invisible unless you run this yourself: when the server could not claim its address because something else already had it, it complained into the log and carried on running without serving anything at all. Two of those overlapping on the same data left part of the app answering nothing, forever, with no error anywhere — which looks exactly like a broken feature and is not one.
    v1.150.72026-08-13

    πŸ› We kept your work.” β€œSaving failed.” Both, at once

    • If your sign-in expires part-way through editing a test case, the product tucks the unfinished work away and the sign-in screen says so, in your language.
    • It was also, at the same moment, putting up a second message from the server saying that saving had failed — in English, in an app running in Czech, and saying the opposite of what had just happened.
    • A message that reports a loss one second after a promise of rescue is worse than no message at all, because it teaches you not to believe the promise. This refusal should say nothing rather than say it better: by the time it happens the screen in front of you is already the explanation.
    • Everything else the original release promised holds — one better than promised: the rescued work survived a complete restart of the server, coming back with its folder and in the same format it was written in.
    v1.150.62026-08-13

    πŸ› A counter that told you something needed doing, right after you had done it

    • The small number beside the test-case section refreshes whenever you move between sections, which covers almost everywhere — but not the one place it matters most.
    • When two people change the same test case, the question is raised and answered on the same screen. Nothing moves between sections, so nothing told the counter anything: after settling the question it kept saying one thing was still waiting, for eighteen seconds of standing still in our measurement, while the record behind it had been clear the whole time.
    • It now updates the moment a decision is made — and equally the moment one is needed, which is the other half of the same problem and was fixed with it.
    • Everything else here was exercised and works, including all five things that only came to light last time by clicking rather than reading.
    v1.150.52026-08-13

    πŸ› Deleting a test case can be undone. The warning said it could not

    • Deleting a saved test case used to be final, and the question before it said so. Some time ago that changed: a deleted test case drops into a bin, waits a month and comes back at the press of a button, with its working copies going down and coming back with it. The confirmation was never updated.
    • For half a dozen releases it went on telling people the thing they were about to do could not be undone — which is the worst direction for a warning to be wrong in: it does not cause an accident, it prevents a harmless action. Someone unsure whether to tidy up would have decided not to.
    • The same release that built the bin had already corrected the equivalent warning for working copies; this one was simply missed.
    • Worth noting for anyone who has read our earlier notes: this is the same mistake as one we recorded before, running the other way — that time a note in the code promised the deletion could be undone while nothing in the product could undo it.
    v1.150.42026-08-13

    πŸ› A blue ring around dialogs that belonged to the browser, not to us

    • When a dialog opens with nothing in it to type into, the app deliberately moves the keyboard’s attention onto the dialog itself, so Tab carries you through the dialog rather than the page behind it.
    • The browser decided this counted as the keyboard being in use and drew its own highlight — a blue outline all the way around the box — every time, including when the dialog had been opened with the mouse and nothing had been typed at all.
    • Blue is not a colour this product uses to show where the keyboard is, and the box is not something you can press, so the ring was pointing at nothing. Anything inside a dialog that you can actually use still shows its highlight exactly as before.
    • Found by opening the dialogs one at a time and looking, which was the only way it could have been found: the ring was the browser’s own and appears nowhere in our styling.
    v1.150.32026-08-13

    πŸ› A clip you trimmed came back whole

    • When you download a piece of a recording, the keys that were pressed are drawn into the picture. That drawing had been on the box in the office for a month, but nobody had ever downloaded a finished clip from that box and looked at it. So we did, and the drawing is right.
    • The same clip showed something we were not looking for: we had asked for the first twenty seconds and got back all ten minutes. The instruction saying where to stop had been written in the one position where it stopped applying to the video and started applying to one of the little key pictures instead — where it means nothing, because a picture has no length.
    • Nothing complained. The file was valid, it played, it started in the right place, and the only sign anything was wrong was that it was thirty times larger than it should have been and took minutes to prepare instead of seconds.
    • Why the automated checks had not caught it is worth saying out loud: they had never exercised this part at all, and the check covering the older variant words the rule in a way the broken version would also have satisfied. Both are now worded so that only the correct one passes.
    v1.150.22026-08-13

    πŸ”’ Settings kept what the read-only account is entitled to, and lost what it never could use

    • With an account type that cannot change anything, how much of the Settings screen should still be there? Not none of it — Settings is also where a person manages their own account, and that half belongs to them whatever else they may do.
    • The release before had left the read-only account’s own notification channel off the list of things it may still save. That is precisely the setting this account type needs most, because it never runs anything itself: the only messages it will ever receive are about a team’s work, which it is still allowed to subscribe to. The subscription was permitted and the place for it to arrive was not.
    • Two other preferences turned out to be neither permitted nor forbidden, but simply moot — both describe what happens while you are driving a television, and this account never does. They are greyed with a sentence saying exactly that, not a refusal, because nothing is refusing them.
    • The account header itself was quietly wrong: it introduced the person by the wrong account type, having been written when there were only three of them and never revisited when a fourth arrived.
    v1.150.12026-08-13

    πŸ› A refusal that spoke the wrong language, behind a door that should have been shut

    • The new read-only account type went live, and the first person to try it pressed the save shortcut and got a sentence in English lifted straight from the server — true, and useless twice over: not the language they were working in, and no word about what to do next.
    • The more interesting part is that the attempt should never have been possible. Every writing button had been greyed out, and pressing a greyed-out button does nothing — but the keyboard shortcut for saving does not go through a button at all, so it walked straight past.
    • And the button that starts a brand-new scenario had been missed entirely: it looked available, opened an empty editor, and the refusal arrived at the very end, after the person had been invited to do work that could never be kept. The button beside it already did this correctly — turn the offer down at the door, with a reason, rather than at the end.
    • Found by using the feature on the day it shipped, which is the only way this class of gap gets found.
    v1.150.02026-08-13

    πŸ› The greyed-out buttons are now on β€” and the folder they act on is the one you pointed at

    • The previous release fixed what the greyed-out rename and delete buttons said and deliberately left them greyed. Switching them on as they stood would have produced two buttons that looked alive and did nothing whatsoever, because the view showing every project at once keeps each project’s folders separately and the code behind those buttons reached for a single set that is empty there.
    • What made this more than a wiring job: a folder’s internal name is only unique within its own project. Two projects can each have a folder called “Tests”, and in this view both are on screen at the same time — so the name alone no longer identifies which row anybody means. Every row now carries its project, and the pair is used everywhere.
    • The delete question was walked through again in this setting, and three of the things it says would have been untrue here — including listing what is inside the folder by looking names up in one shared list, which could name a scenario from a different project entirely. A sentence that reads perfectly and is false.
    • Driving it by hand also turned up something nobody would have found by reading: the rename box in that view appeared correctly and never took the cursor.
    v1.149.02026-08-13

    πŸ”’ An account that sees everything and changes nothing

    • Some people need to watch the work without being able to touch it. There is now an account type for exactly that: it reads whatever its teams can see and writes nowhere.
    • The request had been for something finer — read-only in one team while still running another — and that turned out not to be buildable honestly, for a reason about the product rather than the code: a television does not belong to one team. Somebody read-only in one and an administrator in another has two contradictory standings over the same screen, and there is no answer that is not wrong. Both televisions in production are shared exactly that way today.
    • Two things were non-negotiable while building it. Nothing is hidden: every control this account cannot use stays where it was, greyed, saying in one sentence why — because the whole point is to see what exists.
    • And the rule is enforced by the server at every route a change can arrive through, not by the buttons. A restriction that lives only in the browser is not a restriction.
    v1.148.52026-08-13

    πŸ› A greyed-out button explained itself with a doubt nobody had

    • In the view showing every project at once, the rename and delete buttons on a folder are greyed, and the product’s rule is to always say why rather than simply hide a control.
    • The explanation read: a folder belongs to one project — pick one at the top first. Next to the button that creates a folder that is exactly right; on the rename and delete buttons of folders that already exist it is not ambiguous at all, because the folder has a project and is listed under that project’s own heading.
    • So the explanation was answering a question the person had not asked, and quietly implying they had been careless. Each button now gives the reason that actually applies to it.
    • The buttons stay greyed: turning them on is a separate, larger job, and doing it carelessly would produce a button that looks alive and does nothing at all.
    v1.148.42026-08-13

    🎨 The list could already be reordered by dragging β€” it just never said so

    • The list of what is to be built next had learned to be reordered by dragging a row, and the one line of guidance at the foot of the page had never been told — it went on naming only the older way, typing a command.
    • The person who had asked for dragging went looking for it a second time and concluded it had been lost. It had not; the page had simply been silent about it.
    • That line now depends on where it is being read. On the version that is only for looking at, it names both ways and explains why that particular page has nothing to grab: it is a view of the list and has no way to save a change, so rather than quietly offering nothing — which amounts to hiding it — it says as much.
    • On the version that can be dragged it stops advising a command to somebody whose hand is already on the row, and describes the gesture instead, including the fact that the whole thing works from the keyboard.
    v1.148.32026-08-12

    🎨 Delete this folder?” β€” but which one of them?

    • Deleting a folder asks first, and the question named the folder and stopped there. That is enough right up until two folders are called the same thing — and then the two questions are word for word identical, with nothing to say which is about to go.
    • This was not imagined: going back through an earlier release by hand produced exactly that, two folders both called “Nová složka” side by side, one empty and one with tests inside. The only way to tell them apart was to inspect the page’s underlying structure — which is to say, no way at all.
    • The question now says three things in the order a person can check them: what the folder is called, where it sits, and what is directly inside it.
    • But no wording settles every case — two empty folders with the same name in the same place produce an identical sentence no matter how much detail is added. So the folder being asked about is highlighted in the list behind the question, and the highlight cannot be left behind afterwards.
    v1.148.22026-08-12

    πŸ› One screen kept ignoring the light-and-dark switch β€” in the one place people actually open it

    • The page showing the product’s own plan of work kept ignoring the light-and-dark switch. That had been fixed once already — but the fix lived inside the page, and the page is shown in two ways.
    • Opened directly by its address it worked. Opened the way it is actually opened, as a screen inside the app, the page sits inside a sealed frame that by design cannot see the app’s stored settings at all: its attempt to read them fails, the failure is silently swallowed, and it falls back to following the computer’s preference.
    • So a person with a dark computer and a light app got one black page in an otherwise light app, with no error anywhere, for exactly as long as the fix existed.
    • The screen now reads the setting where it can — out in the app — and hands it over together with the page, so the frame comes up in the right colours from its very first moment.
    v1.148.12026-08-12

    πŸ› One field that answered to two different names

    • There are two places to type in who made a television, and both write the same thing to the same place. Only they did not call it the same thing: one asked for the manufacturer, the other for the brand.
    • Nothing broke and no value was ever lost, which is exactly why it stood for as long as it did — a difference like this is invisible unless somebody opens both in the same sitting and happens to notice. Somebody did.
    • The wording that disagreed has not been rewritten to match; it has been removed, so the two cannot quietly drift apart again the next time either screen is touched.
    v1.148.02026-08-12

    🎨 Sending something back for changes, without having to say what they are

    • Sending a set of tests back for changes opens a window asking what needs to change — and the whole reason it exists is so the answer travels with the decision.
    • The window could be dismissed with the field blank. Nothing objected: the work was sent back, the author was told so, and the line that should have explained it was simply empty, with nothing anywhere to say the sentence had gone missing rather than never been written. At the moment this release went into service, a request in exactly that state was sitting on the live system.
    • An empty note can no longer be sent. The send button goes quiet and the reason is written next to it in plain words, rather than hidden behind having to hover over something.
    • Instead of promising that the author will see what is written, it shows it: the card the author will actually read is drawn underneath, from the words being typed, updating as they are typed.
    • It also says which release it is talking about, because the screen carrying all of that is covered up while the window is open.
    v1.147.22026-08-12

    πŸ”’ A name is not a key, and several things here had been treating it as one

    • This release is the result of going looking for trouble rather than waiting for it. Nothing below was reported by anyone, and the seven findings share a shape: each one worked, looked right, and was wrong.
    • A scenario can be named in three ways, and the third handed it over — along with any reference photograph from the television — without checking whether the person asking was allowed to see it. Its safety rested on being private: it is short enough to guess, and the service wrote it into its own log in plain view.
    • The protection against guessing a password or a six-digit code could be sidestepped entirely: failed attempts were counted against the part of the record the caller writes, so a fresh invented address on each try meant the count never rose.
    • A key issued so software could change channels turned out to be able to change the account’s password — not a key to a room, but a key to every future visit.
    • Any application may register itself and choose the name it displays, so the screen asking whether to let one connect could be composed by somebody else entirely. It now states where the access will be sent, and that the name is the application’s own claim.
    • Also: a recording could be asked for by a name pointing outside its folder, and the service no longer runs with unrestricted rights on its own machine.
    v1.147.12026-08-10

    🎨 Two pages that had decided, on your behalf, to be dark

    • The status page — the one that will say publicly whether the service is up — had the dark theme nailed into place, with no light one to fall back on. It is the page somebody opens from a search result during an outage, on whatever machine is in front of them.
    • Two of the old colours are worth describing because of how they would have failed: both were white at a fraction of full strength, which works on black and vanishes on white. They were the badge meaning “no data” and the icon shown when the page has stopped trusting its own figures — the one state that page exists to be honest about.
    • The internal roadmap view had both themes but chose by asking the computer rather than reading the setting in the product, so anyone with a light theme and a dark machine got exactly one black page.
    • Both pages apply a remembered choice before drawing anything: read it a moment too late and the page appears in one theme and then jumps to the other, every time it is opened.
    v1.147.02026-08-10

    🎨 A failed run keeps pointing at the line that failed

    • When a run fails the console says so plainly, but the code itself went back to looking untouched the moment the run ended — the highlight that follows a run line by line is cleared on the way out, and that clearing took the failure’s address with it.
    • The line the run fell over on now stays marked, in the same red tint the console uses for the failure itself, so the two halves of the screen visibly point at each other.
    • The mark knows when to let go: it moves with the text while you fix it, yields to a new run, and is removed by any change that rewrites the whole document at once — because after a rewrite of that scale the old position would be a guess, and a confident mark in a guessed place is worse than none.
    • One kind of failure deliberately gets no mark: a run refused up front, or broken before the first key press, has no line to blame.
    v1.146.12026-08-10

    πŸ› A brand-new installation could come up unable to open anything

    • A team’s name is the first part of every address inside the product, so nothing can be opened until at least one team exists. On a fresh installation the file listing them does not exist yet — the server writes it the first time anything changes.
    • Being told where the file will live and then not finding it there was treated as a failure rather than as the ordinary first-run situation it is, and the consequence was total and almost silent: the copy started normally, wrote a single line into its log, and from then on answered every request by complaining that no project had been named.
    • What makes this worth describing is that the situation immediately next to it — no such file configured at all — had always been handled correctly, a few lines away in the same place.
    • Existing installations were never affected, the live one included: their file is there, which is also why nobody met this except somebody setting up a new copy.
    v1.146.02026-08-09

    ✨ Two windows side by side no longer disagree about where things are

    • Folders are shared, so a colleague can rename one while you are looking at the same list — and the product only noticed when you came back to it. That misses the situation people with two monitors are in all the time: both windows visible, neither ever brought to the front, so neither ever asks.
    • The library now keeps a line open and is told when the folders have moved. What travels down it is only the fact that they changed — which keeps one answer to what the tree looks like, and one place where who may see what is decided.
    • Permission is checked when something is sent rather than when the line opens: a window left open for hours can outlive being removed from a project.
    • Building it uncovered something older. In the view showing every project at once, the list had never refreshed itself at all — it asked for the current folders and concluded every time that nothing had changed. It was invisible because it failed by doing nothing, and it was found by driving two real windows against a running server rather than by trusting the tests.
    v1.145.42026-08-09

    πŸ› Rearranging a scenario you are still fixing

    • The outline beside the code lets you drag a step to a new place, which is most useful precisely while a scenario is half-written — and it had stopped working entirely the moment the document contained any mistake at all. A key typed in lower case is enough.
    • The message that came back named that unrelated mistake, so it looked as though the drag had caused it. Nothing moved, and there was no way to tell why.
    • A drop is now refused only for what the drop itself did. Getting that distinction right is less obvious than it sounds, because the check reports where a problem is by naming its position, and rearranging steps changes every position — compare the reports naively and every successful drag looks like a new problem.
    • Two things rode along: the refusal for nesting something too deeply had never actually been run by anything but a reader, because no document used for checking was deep enough to reach it — and it turns out to count nested blocks rather than steps.
    v1.145.32026-08-09

    πŸ› Counting things out loud, correctly

    • Czech changes the shape of a word depending on the number in front of it, and in eleven places the product had a number sitting next to a word frozen in one shape — each correct at some counts and visibly wrong at others.
    • Two of them needed a different sentence entirely rather than a different word, because the language agrees in more than one place at a time: the verb has to move with the number as well as the noun.
    • What is worth saying is how they kept being found. Four were spotted by a person reading a screen, over two days, and every single time the pieces needed to say it properly were already sitting a few lines away in the same file. That is not four accidents, so the check that found the rest is now part of the test suite: a new sentence of that shape cannot be added without someone writing down why it is fine.
    • Three were deliberately left alone and the reasons recorded — including a family that looks identical and is the opposite: those parentheses hedge the gender of the person who did something, which the product does not know and should not guess.
    v1.145.22026-08-08

    πŸ› Work the product saved for you now comes back complete

    • When your sign-in expires over a half-written scenario the product keeps what you were writing. For one that had never been saved, the folder you had chosen came back missing — and until a folder is chosen a new scenario cannot be saved at all, so the work was handed back with a hole in exactly the place the feature exists to fill.
    • It happened whenever you were looking at all projects at once, which is where the product opens as soon as you can see more than one.
    • The cause was three reasonable pieces meeting: the saved copy remembered the project from the screen rather than from the field a new scenario actually uses; without a project there is no folder list to check against; and a rule that exists to stop a folder from a project you have just left being treated as an answer then threw the restored one away.
    • Separately: the setting for the nightly tidy-up told you what time it would run in your own clock and was an hour out for the whole summer, because it worked the conversion out against a fixed winter date.
    v1.145.12026-08-08

    πŸ› A box you type into that looked like it belonged to a different program

    • The box you write a note in when sending a change back was never given the product’s own appearance, so the browser supplied its own: a dark panel with pale text inside a white dialog, in a typewriter face nothing else uses, at about a third of the width it had room for.
    • It looked wrong in the light appearance and merely a little odd in the dark one, which is why it went unnoticed through six releases. The giveaway, when it was finally measured, was that both appearances produced exactly the same colours — which no part of the product that follows your chosen appearance ever does.
    • Alongside it, a small piece of language: the confirmation before running everything left on a television counted correctly and then said “run 1 scenarios”, while the wording for one, a few and many already existed a few lines away, unused. That confirmation is the one that takes a television away from everybody else for several minutes.
    v1.145.02026-08-08

    ✨ The make and system of a television are suggestions now, not a fixed list

    • Adding a television asked for its make and system from a short menu, with no blank entry and no way to write your own. Three things followed, and none announced itself.
    • With no blank entry, every television added through the form was recorded as the first make and system on those menus — and the list can be filtered by make, so a fleet quietly files itself under one manufacturer.
    • A television from anyone else could not be entered at all, and one entered elsewhere in the app came back to this form blank and was erased on saving, while the form said the change had been saved.
    • Both places now suggest the makes and systems your own fleet already uses, alongside the usual ones, and both let you simply type. The camera type deliberately stays a fixed list: the box cannot connect to a camera whose type it does not recognise, and a stray value there once took a camera off the air.
    v1.144.02026-08-07

    ✨ A deleted scenario can be brought back, and a line of work can be thrown away

    • Deleting a scenario used to be permanent. Nothing in the product said so — the code even described it internally as reversible — but that was true only of the data, not of anybody using it.
    • Scenarios deleted in the last thirty days now appear in a bin at the foot of the library, and one press returns them along with any lines of work that went down with them. It is read from the record the product already keeps, so it also offers scenarios deleted long before this existed.
    • Alongside it, the opposite: a line of work you have decided against can simply be thrown away. That was always a real outcome and the product had no door for it.
    • Lines of work show their age, and nothing is ever removed for being old — that is the rule that eventually deletes the one thing somebody was coming back to.
    v1.143.02026-08-07

    ✨ Try a change on a real television before it goes live

    • Putting work live is the one step a second person signs off, and until now that person could only read it. They can now run it — on a real television, in the room, before they approve anything.
    • Every scenario waiting to go live carries what a television has actually said about this version of it, and opening a row gives the answer complete: which television, when, who ran it, and which version — because a verdict without those is a rumour rather than evidence.
    • Televisions that are busy or switched off are still listed, dimmed, each saying why. A television that simply vanished from the list would read as one that had been deleted.
    • Nothing here blocks anything: a failure adds a sentence to the confirmation and to the record, and the decision stays with the person making it — televisions go offline, and a rule that cannot be satisfied at six on a Friday only teaches people to work around it.
    • The confirmation was rebuilt in the same release. A count is where a question starts rather than where it ends — “two scheduled checks are affected” is not an answer until you know which two — so each fact opens into the detail behind it, and the ones carrying risk are open already.
    v1.142.12026-08-07

    πŸ› When two versions disagree, the line that disagrees is now marked

    • When two versions disagree the app stops and asks which one stands — and it showed you the two side by side, in two undifferentiated blocks of text with no line numbers and nothing marked.
    • Every other comparison in the product already did this properly. This one screen, whose entire purpose is that single question, had quietly been given a second, simpler implementation of its own.
    • Three colours and a typeface the stylesheet referred to had never been defined. A stylesheet says nothing when that happens, so the result looks exactly like a rule nobody wrote: the comparison was drawn in the ordinary text font, and the badge marking a scenario that needs a decision had no background at all.
    • The reason is a trap rather than an oversight: designs are drawn as standalone pages carrying their own palette under shorter names, and rules copied from a drawing bring those names with them. The drawing looked right and the product never did.
    v1.142.02026-08-07

    ✨ A scenario can be written in your own editor and sent back

    • The scenario library could already be copied onto your own machine and opened in a normal editor, but only to look at. Now it can be sent back, and the moment it arrives the library shows it, runs use it and scheduled checks monitor it — there is no longer a version of your test suite that only your laptop knows about.
    • Sending work back is treated as saving it, not as asking permission: it lands on whichever line of work you are on, and merging that into the shared one stays a separate, deliberate step.
    • Some things are refused, and each refusal explains itself rather than reporting a number. Deleting a scenario something is scheduled to run is refused outright, naming what would have stopped running — which matters most for people who were not deleting anything at all, because renaming a file in an editor is, to the system, deleting one thing and creating another.
    • A wrinkle worth knowing: each scenario is kept in three interchangeable formats, so editing one leaves the other two behind and the server rewrites them in a follow-up of its own, which quietly puts your copy one step behind. The copy you download now carries a small tool that does that tidying on your machine first.
    v1.141.02026-08-07

    πŸ› The hover explanations are drawn on top of everything, including the panel they explain

    • When the hover explanations moved onto a single shared layer drawn over the page, the layer kept a setting from its previous life, when it served one screen only: it sat lower in the stacking order than dialogs and full-screen overlays.
    • Nothing depended on that yet, so nothing looked wrong anywhere — but the moment an explanation belonged to a control inside a dialog it would have been drawn behind that dialog and been invisible, which is precisely the failure the whole change existed to end.
    • The part worth keeping: moving a piece of machinery from one screen to the whole product brings its old assumptions along, and the ones that break are the ones nobody thought to write down.
    v1.140.02026-08-07

    ✨ Work you had not saved yet survives a sign-in running out

    • When a sign-in lapses mid-scenario the app takes you back to the sign-in screen — and the text you were part-way through was quietly thrown away, because signing back in reopened the scenario and loaded the saved copy straight over the top of it.
    • Every other way of leaving that screen asks first; an expiry is the one that cannot, because by the time anyone knows the sign-in is gone, saving is no longer possible. So it is kept instead.
    • It is stored on your own machine rather than held in the page, because the instinct when an app stops responding is to reload it, and a rescue a reload destroys is no rescue. It is labelled with whose work it is, so a shared computer never offers one person another’s unfinished writing.
    • What is deliberately not restored is the assumption that nothing else changed: if a colleague saved that scenario in the meantime the offer says so, and putting your version back is treated as an ordinary edit on top of theirs rather than a silent overwrite.
    • A dialog left open when the sign-in expired used to keep standing over the sign-in form, still accepting clicks and answering every one with a failure message.
    v1.139.02026-08-07

    🎨 The little explanations that appear when you hover now work everywhere, and can be read

    • A control that cannot be used right now stays where it is and dims, and hovering it tells you why — that is the whole reason it does not simply vanish. Those small explanations had become the least reliable thing on the screen.
    • On one screen in a single afternoon, four of them failed in four different ways: one came out see-through and tangled with the paragraph behind it, one was sliced off mid-word at the edge of its card, one was sliced off at the opposite edge after the first was fixed, and some never appeared at all — that last had quietly happened on seven separate screens, because every new page had to be added to a list by hand and nobody ever remembered.
    • They were all one problem: the explanation was drawn inside the very thing it was explaining, so it faded when that faded, was cut off by whatever cut that off, and existed only where somebody had said so.
    • It is drawn on top of the page now, once, by a single piece of shared machinery. There is no longer a list to be left off, nothing that can trim it, and nothing that can fade it — and it reaches the keyboard for the first time.
    v1.138.02026-08-07

    ✨ Getting work into production finally has a place of its own

    • The one screen that decides what your televisions actually run could only be reached through a strip of text that appeared on the scenario list when, and only when, there happened to be something to send. If nothing was pending there was no way in at all — the screen even told you to send somebody the web address, because there was nothing else to point them at.
    • It has a home now, called Releases, and it is built as a to-do list rather than a dashboard: the things actually waiting on a decision are the loud part, and when there is nothing waiting the page says so and stops rather than filling itself with numbers.
    • Underneath sits a quiet line of what production is running, and under that, folded away, every branch anybody in the project is working on — visible in the app for the first time.
    • The alert deliberately does not live on the new page: it sits on Scenarios, where people already are, and clicking it takes you to the actual thing rather than merely to the section.
    • It is also where the app finally mentions that you can clone the whole scenario library onto your own machine — a capability that shipped a version ago without a single word about it anywhere in the product.
    v1.137.12026-08-07

    πŸ› An expired sign-in takes you to the sign-in screen, not to a spinner

    • Open a page by its address after your sign-in has lapsed and the app told you so — then left you looking at a loading placeholder that would never finish, with no way out but reloading by hand.
    • The handling of the expiry was correct all along: the stored sign-in had been cleared and the sign-in screen raised, and then the next step of the start-up sequence put the page you had asked for back on top of it.
    • The rule now lives in the single place every screen change passes through. The “this address is not here” page stays reachable on purpose — a mistyped address is not private, and asking somebody to sign in only to be told the page does not exist is the wrong answer.
    • Worth naming the general shape, because this is the second time in a day it has cost something: a check placed next to one particular request only protects that one request, and the next feature to add an earlier request quietly walks around it.
    v1.137.02026-08-07

    πŸ› A scheduled check now tells you about the version it actually runs

    • A scheduled check can watch either production or the shared working copy, and the card describing it never learned about that choice — it looked in the library, which is the working copy, so it was wrong in both directions at once.
    • Delete a scenario and a check watching production keeps running perfectly well, yet the card announced its scenario no longer existed. And the advice could not be followed: saving that check was refused, including simply switching it off.
    • The quiet half is worse. A new scenario exists only in the working copy and a new check watches production by default, so writing a test and asking for it to be watched produced something that failed every night behind a card that looked healthy.
    • The server could always tell these situations apart and only ever did so at three in the morning, inside a failed run. The screen and the scheduler read the same answer now.
    v1.136.12026-08-07

    πŸ› Four fixes from the first real walk through promoting to production

    • The owner stepped through the promotion screen one action at a time and found four things, all circling the same point: when a button is unavailable, the bubble explaining why is the only thing that makes it honest — and it was unreadable.
    • It was dimmed together with the button it belonged to, so its text faded into the paragraph behind it; then, once legible, it was cut off at the card’s right edge; then, once that was fixed, at the left edge too, because a clipping fix has two sides and only one had been done.
    • The button offering to close your own pending request called it rejecting, which is what a reviewer does to somebody else’s proposal. On your own request it is cancelling, and it says so now.
    • This was also the first time anybody walked the whole promotion flow on the live system — ask, approve, promote — so the rule that somebody other than the author must approve has now been seen working by a person rather than only by the test suite.
    v1.136.02026-08-07

    ✨ The scenario library can be cloned onto your own machine

    • The whole scenario library can be copied onto your own computer with a single command and opened in whatever editor you already use. It is read-only for now; writing back comes next.
    • Signing in uses the same access token the command-line tool does, because git has nowhere to type a six-digit code — so the second factor is spent at the moment you create the token rather than each time you use it.
    • A clone carries the working branches too. A branch here is a shared workspace over one test case rather than anybody’s private desk, and a copy that quietly omitted them would be a second, softer set of permissions living beside the one in the app. That has a price worth stating plainly: a copy on a laptop is offline and permanent, so withdrawing somebody’s access does not withdraw what they already have.
    • The copied repository brings its own type definitions, generated from the format itself, so a fresh clone reports mistakes in an editor with nothing installed and nothing configured.
    • Three different refusals — no such repository, not your team, bad token — answer identically, or the address would become a way to guess what projects exist.
    v1.135.02026-08-07

    βš™οΈ A scenario is three files now, and one writer produces all three

    • Nothing on screen changed, and this is the release after which somebody can open a scenario in the editor on their own computer. A scenario is three files now, one per format the editor offers — three views of a single document.
    • They are written by one shared writer that the server, the browser and the command-line tool all call. Two of them had disagreed about line length and quote marks, so saving in the app and then pushing from the command line rewrote the punctuation of a file nobody had edited.
    • Key order comes from the format’s own definition rather than from whatever order a document arrived in, so two versions that mean the same thing can no longer show a difference nobody made.
    • Testing the conversion found a fault that would otherwise have surfaced in production: every open branch would have collided with everything it touched, asking somebody to settle a difference that was purely a change of file layout.
    v1.134.02026-08-06

    ✨ A scenario reaches production by being promoted, and somebody has to look at it first

    • Until this release, what ran at night was simply whatever had been saved last. Production has its own shape now, and a scenario gets there one way: a promotion that somebody other than its author approves. That is not paperwork — promoting is deploying, because production is exactly what the nightly watches run.
    • The review has its own address, precisely because the approver is by definition somebody else and has to be sent a link.
    • How far it reaches is on the screen before you press anything — and the line worth the most is a watch whose scenario this promotion deletes, named while you can still do something about it. Today that would be discovered at three in the morning, as a failed run nobody was awake for.
    • A new commit cancels an approval, because what was approved was a specific shape and not an intention, and the moment before it goes live the system checks once more that nothing moved underneath.
    • Alone on a team you approve and promote your own work — the alternative is a gate nobody can satisfy — and it is recorded as exactly that. Every watch that existed before today keeps running precisely what it ran yesterday.
    v1.133.02026-08-06

    🎨 Choosing where something belongs is one control now, not four

    • “Where does this belong” was asked in four places and answered differently in each: twice by a dropdown whose indentation was drawn with box characters, once by a flat list, and once by a real tree. It is one control now, and it browses in columns the way a system folder dialog does.
    • The last column shows what already lives in the folder you are pointing at, which is the whole argument for columns over a tree: you are not deciding where to navigate, you are deciding where to file something, and what it will sit next to is the fact that settles it.
    • Making a folder happens inside the picker, under whichever one is open, and it says where before you commit. Until now that meant leaving what you were doing and coming back.
    • Three faults surfaced only from using it, none of them visible in the code: the first choice made straight after a save was discarded — exactly once, silently — and in the narrower dialog the first column was sliced through the middle of a word, because the number of columns followed the width of the window instead of the width of the control.
    v1.132.02026-08-06

    🎨 On a computer, dialogs stopped pretending to be a phone

    • Every window that asked a question slid up from the bottom edge and stuck there. On a phone that is right; on a monitor it made the whole app read as a mobile site in disguise. Above 740 pixels a dialog is now a dialog — and below that width nothing whatsoever changed.
    • It sits a little above centre rather than dead in the middle, which sounds like a detail and is the only reason a dialog no longer jumps when its content arrives late: the QR code for two-factor, the calculated difference in a save conflict, the list of signed-in devices coming off the network.
    • The app had no closing animation at all before this — dialogs simply vanished mid-frame.
    • Escape and clicking the backdrop now work on all of them; they worked on six of seventeen, and not on the ones where it mattered most. Two deliberate exceptions remain, including a takeover request somebody else is waiting on with a countdown running, which cannot be waved away at all.
    • Tall dialogs finally fit: none of them had a height limit, so on a short window they ran off it.
    v1.131.22026-08-06

    πŸ› A disagreement is remembered even if you do not settle it now

    • When two versions of a scenario disagreed, the app asked the server what would happen — a question that by definition changes nothing — and drew the choice. Leaving it for later therefore threw it away: no mark on the row, nothing in the library, nothing to come back to, in a feature whose whole promise is that the task waits for you where you work.
    • Meeting the disagreement now really does attempt the merge, and the refusal is what records the task. That also fixes the opposite case: if somebody else settles it meanwhile, pressing the reminder simply completes the merge and the task disappears.
    • The merge button stopped borrowing the green that belongs to Run: in this editor that green means “this touches a real television”, and two of them on one card cost each other their meaning.
    • The button that applies your decision is unavailable until every disagreement has one — but inside that panel it looked entirely pressable, full colour, with the reason hidden in a hover that panels do not show at all. A button that looks ready and does nothing is worse than either honest state.
    v1.131.12026-08-06

    πŸ› After a merge you can branch off again

    • A branch could only ever be made at the moment a scenario was created, and merging one now ends it — so once you had merged, the branch list offered the shared version and nothing else, permanently. Each half looked finished on its own; only using it showed that together they were a one-way street.
    • The branch list carries the way back now: one row that makes a branch and takes you to it, named by the server from the scenario and its folder, so there is nothing to type and nothing to get wrong.
    • Branches fork from a shared version only — branching off somebody’s branch would turn a flat list into a tree nobody can read at a glance.
    v1.131.02026-08-06

    ✨ Work on a branch can be sent home β€” and overnight it sends itself

    • A branch could be made, written to and thrown away, but there was no way to get the work back out of it. The line above a scenario’s name gains one button: send this branch into the shared everyday version.
    • Nothing has to be approved — approval belongs to the step after, into the version the overnight checks actually run — so when it goes through, it goes through, and the branch ends there, kept in the bin for thirty days.
    • Before it happens you are told what will happen, and every one of those numbers is the server’s answer rather than a sentence the page composed for itself.
    • The only thing that can stop a merge is a genuine disagreement, and that is handed back as a question rather than settled by the machine. Leaving it for later is a real answer, and the task waits somewhere you can find it: the scenario is marked in the library and the mark takes you straight to the decision, on the right branch.
    • Branches nobody has touched for a while merge themselves overnight. The hour says which clock it is in, because the server keeps time differently from the person reading the screen, and a promise of “midnight” would quietly drift by an hour every autumn.
    v1.130.22026-08-06

    πŸ› Deleting a scenario no longer takes somebody else's unfinished work

    • The fix in the previous release was too broad. A branch counts as belonging to a scenario if it is named after it or if it has ever been used to change it — and that second case is ordinary, because a branch is a workspace for a piece of work and a piece of work can span more than one scenario.
    • So a branch named after somebody else’s task could be carrying your scenario too, and deleting yours deleted their branch: unfinished work, gone, with nothing they would ever see to explain it.
    • Only the branch named after the scenario is deleted now. A branch belonging to other work stays where it is and the deleted scenario is simply removed from it — so nobody loses anything, and the branch stops carrying a document that no longer exists, which is what would have let the overnight tidy-up put it back.
    • Branches put in the bin were meant to be cleared after thirty days, which was written in the documentation and done by nothing at all, so they piled up indefinitely.
    v1.130.12026-08-06

    πŸ› A deleted scenario does not come back two days later

    • Deleting a scenario removed it from the everyday version but left its branches alive, with the file still inside them. Nothing showed it — the list of branches belongs to a scenario, and that scenario was gone.
    • But the overnight tidy-up being built merges branches nobody has touched for a while, on its own. Merging one of those would have put the deleted scenario back in the list, days later, with nothing to explain where it came from.
    • Deleting a scenario now deletes the branches over it as well, each kept in a bin so undoing it stays a single step. The shared versions are never touched: they do not belong to any one scenario.
    • The clean-up cannot fail the deletion itself — it runs afterwards and complains in the log if it could not finish, because a scenario that disappears from the library but answers with an error would be much the worse outcome.
    v1.130.02026-08-06

    ✨ You can change a scenario without everyone seeing it half-finished

    • Branches have existed since the last release, but nothing in the app could reach one. Above a scenario’s name there is now a line saying which version you are working on, and one click switches.
    • The address carries the branch too, so a link to work in progress opens exactly what you were looking at — and a branch that no longer exists opens the everyday version and says so, instead of quietly showing you something else under its name.
    • The line above the run button is a fact rather than a label: the server takes the document from that branch and refuses a branch it does not know, rather than silently falling back.
    • A brand-new scenario is asked for its name and its folder together, because the folder is half the branch’s name — and the top of the library is a legitimate answer that has to be chosen, not the thing that happens when you look away.
    • Three older mistakes went with it: the history tab always answered for the everyday version, even marking somebody else’s entry as the current one while a different document sat in the editor; the branch list offered branches created before the scenario existed; and a comment typed below the last step vanished on save while the header went on saying it was saved.
    v1.129.02026-08-06

    ✨ A wrong address stops disappearing before you can read it

    • Screenwhere never had a page for an address that does not exist, and the way it coped was worse than nothing: typing a wrong address quietly dropped you on the overview and rewrote the address out of the bar, so the one thing worth reporting was gone before you could copy it.
    • A stale device link rendered a device page for a device that was not there, and a link to a deleted scenario opened a blank new one under an address naming something that no longer existed.
    • There is now one error page for the whole site, the documentation included, and it comes before signing in — looking for a renamed documentation page should not mean being asked for a password first, only to be told the page does not exist.
    • The address you tried stays in the bar and on the page, selectable in one click, and it survives pressing Back.
    • Since the product controls televisions, a wrong address is drawn as a television showing nothing: switch its inputs and there is nothing on any of them, switch it off and the picture collapses the way an old set did. The keys that cannot do anything stay where they are, dimmed, and say why. None of it changes the error — that is the joke.
    v1.128.02026-08-06

    βš™οΈ A scenario can have more than one version at a time

    • Groundwork, and deliberately invisible: nothing in the app offers it yet. A scenario could have a history — a straight line of what it used to be — and can now have branches instead: a place to change something without everybody else seeing it half-finished.
    • There are three levels. One is what the scheduled overnight checks run, reached only by promoting something into it; one is what everybody works from; and a branch is where a change lives until it is merged back, named after the work rather than after whoever happened to write it.
    • Everything that has not been told about branches carries on unchanged: the library still shows one row per scenario, and reading the everyday version costs exactly what it cost before.
    • Being out of date became a more precise answer: saving onto a branch compares against that branch’s version, so “somebody changed this while you were editing” means the person working beside you rather than anybody anywhere.
    • On a server running without the version record, branches are refused with a reason instead of quietly answering with the everyday version under a branch’s name.
    v1.127.02026-08-05

    πŸ”’ Required two-factor authentication is finally required

    • On a server that insists on two-factor authentication, the sign-up screen with the QR code turned out to be a picture of a wall rather than a wall. Close it and you stayed signed in — able to do less than usual, but able to carry on, which is not what “required” means.
    • Behind it, thirteen addresses were still quietly answering an account that had not finished setting it up: the project list, a scenario’s whole history and any past version of its contents, the package library, notification settings, and enough to release a colleague’s editing lock or sign a device out.
    • The server now refuses everything except signing in, signing out and the setup itself — and it refuses by default, so an address added in future is closed until someone deliberately opens it. That is the third time this gap has been found, and the first time the cause has been fixed rather than the symptom.
    • If an administrator resets your two-factor authentication while you have the app open, the page used to answer “couldn’t load” to everything and the remote read “offline”. It now simply asks you to set it up again.
    v1.126.02026-08-05

    ✨ A scenario finally remembers more than its last save

    • Until now a test scenario had exactly one past: whatever version happened to be stored. Change it and the previous one was simply gone.
    • Every save that actually changes something now becomes a version you can look back at — who changed it, when, and whether it came from the editor, the command line or an AI assistant — with the difference shown beside it.
    • Going back never erases anything: it creates a new version holding the old content, so every version in between stays and the restore itself can be undone. If you only want one step out of an old version, a second button loads it into the editor without saving.
    • Scenarios that existed before all this get a first entry saying exactly that, because an empty list meaning “the record starts here” reads as “nothing ever happened to this”.
    • Nothing about saving changed: the record sits alongside, a failure to write it never costs you a save, and it can be switched off entirely without weakening the protection that stops two people overwriting each other.
    v1.125.02026-08-05

    πŸ”’ Controlling a television and rewriting your tests are two different permissions

    • When you connect an AI assistant, the approval screen described what it could do to your televisions. It did not mention that the same approval also let it rewrite, delete and re-file every test scenario you could see.
    • It could never do more than you could do yourself — but a permission nobody was asked about is not a permission that was given.
    • There is now a third choice on that screen for assistants that genuinely need to write scenarios, and one approved only for televisions is turned away and told the one thing that helps, since trying again cannot fix it: ask the person to reconnect and approve it.
    • Anything connected before today keeps working exactly as it did, because that approval really did carry those rights at the time — and the connected-apps list now says so in plain words, so a permission the approval screen never mentioned does not look like a bug.
    • Separately: saving somebody else’s scenario as your own copy used to leave you sitting at their address while editing yours, so reloading the page quietly opened their document instead of your copy.
    v1.124.02026-08-05

    ✨ Someone else is in here too

    • The last two releases dealt with what happens after two people have already collided. This one is about the collisions that never need to happen.
    • Open a scenario and a small note appears beside its name telling you who else has it open — and whether they are actually part-way through a change or merely looking, which are different things and read as two. Your own second window says so quietly rather than pretending to be a colleague.
    • If something changes while you are sitting there, a single line offers to show you the difference or load their version, and it asks before throwing away anything you have typed.
    • If the scenario is deleted out from under you, the same line says so instead of letting you discover it at your next save; the two buttons that would have nothing to act on stay put and explain why.
    • One thing already shipped was quietly wrong and is fixed here: after being shown a save conflict, simply closing the panel and pressing save again wrote over your colleague without another word. Looking at something is not agreeing to it.
    v1.123.02026-08-05

    ✨ Show me what changed

    • The previous release stopped a save from quietly wiping out somebody else’s work — but being told “no” without being shown why still leaves you stuck.
    • When a save is refused you now get the two versions side by side, yours and what is actually on the server, lined up so you can read straight across, with unchanged stretches folded away and counted.
    • From there you can compare, overwrite theirs — you are asked first, and told plainly that their change will be gone — or save your work as a proposal. That last is greyed out for now and says so, because proposals need branches and branches are not built yet: it stays on screen rather than disappearing, so the shape of the choice is honest about what is missing.
    • Whatever you pick, the text you typed is never touched, and closing the panel does nothing at all.
    v1.122.02026-08-05

    πŸ› Two windows, one scenario β€” and nobody loses work

    • If two people had the same scenario open, whoever saved second quietly wrote over the first — and the one whose work had just been erased was shown a cheerful “Saved ✓”.
    • Every time you open a scenario you are now handed a marker for the exact version you are looking at, and saving sends it back. If anything changed in between the save is refused and the newer version comes back with the refusal, so you can see what happened. Nothing you typed is touched.
    • The same protection reaches the command-line tool, which refuses to push a file that has gone stale, and AI assistants, which are told not simply to try again — trying again with an out-of-date marker is exactly the overwrite being prevented.
    • Saving a scenario you have not actually changed no longer counts as a save at all.
    v1.121.12026-08-05

    πŸ› The question nobody could see

    • Five things in Settings that were all wrong in the same quiet way. The worst: when the app asked you to confirm something irreversible, the question was drawn underneath the panel that asked it, so it never appeared at all. The panel just sat there looking unchanged — which reads as nothing having happened — and the only way forward was to click blindly where the buttons happened to land.
    • A token you had just deleted stayed on screen as though it still worked, and closing the panel kept warning you that you were about to lose it.
    • Connecting an AI assistant left two registrations behind every single time and nothing ever cleared them up. Nine had piled up for one working connection, none of them visible anywhere — so nobody could have removed them either.
    • Reconnecting now reuses the registration it already has, disconnecting tidies up after itself, and a restart clears out anything left over from before. The limit on how many can accumulate no longer fails in silence.
    v1.121.02026-08-05

    ✨ Which project? β€” for an agent, a terminal and an alert

    • A screen in the app always tells you which project you are looking at. The three places with no header to carry it — an AI agent, a terminal and an alert — have now been taught to say it out loud.
    • When the command-line tool pulls everything at once it writes each project into its own folder: two clients can perfectly well both have a scenario called “smoke”, and one flat folder would have written the second over the first while cheerfully reporting that it had saved two.
    • Alerts name the project only if you can see more than one. On a single project that line would appear on every message you ever get and tell you nothing, which is how people stop reading a channel.
    • Underneath it all is one rule: nothing guesses. A short scenario name still works whenever it points at exactly one thing; when it points at two you are told which two and asked to pick, because the alternative is a real television somewhere being driven from the wrong client’s script.
    v1.120.02026-08-05

    🎨 Frame the logo, and match its colour exactly

    • The logo square became something you can actually compose: drag the picture around inside it, zoom in and out, and let the space around it take the project’s colour instead of sitting on a grey gap.
    • All of that stays adjustable afterwards. The previous version quietly locked the framing into the picture at the moment of upload, so changing your mind about a colour meant uploading the file again — which was simply the wrong way round.
    • The background behind a logo can now be an exact colour, so it can match the logo’s own and the two read as one shape. That was refused before for a good reason applied too broadly: where a name is written on a colour it has to stay readable in both themes, so the app still decides how strong and how light those are. Behind a logo nothing is written.
    v1.119.12026-08-05

    🎨 Zoom the logo into its square

    • Cropping a wide logo from the centre worked for a symbol and badly for a wordmark, which simply lost its ends. The upload now has a slider: zoom out until the whole thing fits, and the space around it stays empty rather than filled in.
    • What gets saved is exactly the square you were looking at while you dragged, so nothing later has to remember how far you zoomed.
    • The little project label also lost a strange shape it had picked up — with a logo in it the name was being pushed onto a second line, and the rounded pill turned into a circle with the logo sitting above the text.
    v1.119.02026-08-05

    🎨 A project can wear its own logo

    • Upload a client’s logo and it becomes the thing you recognise the project by — in the switcher, on the projects screen, and on the little label each scenario wears when you are looking at everything at once.
    • Logos are shown as squares, cropped from the centre, which is a deliberate trade: a wide wordmark reads better at its natural shape, but then every list would need a rule for how narrow and how wide a logo may be, and the header would stretch by however long a logo somebody happened to upload.
    • A project without a logo simply keeps its coloured dot — that is the normal state, not a missing one, so there is no empty frame and nothing that looks broken while an image is still arriving.
    • The colour picker moved into a panel now called Appearance, since the logo and the colour are really one choice, and it can suggest a colour measured from the logo you just uploaded — a suggestion you are free to ignore, because plenty of people want a background that contrasts rather than matches.
    v1.118.12026-08-05

    πŸ› The custom colour works for teams too

    • Clicking the rainbow swatch on a team did nothing whatsoever. The spectrum only appeared if the colour was already outside the ready-made set — and clicking “custom” started you on a colour that happened to be in it, so the strip never showed up and the click looked broken.
    • Whether the spectrum is open is now simply remembered, rather than guessed from the colour.
    • The team labels on the projects screen were also showing a slightly out-of-date colour after a change, because that screen was reading a remembered copy of the team list instead of asking for the current one.
    v1.118.02026-08-05

    🎨 Your own colour, not one of eight

    • Eight ready-made colours stop being enough somewhere around your tenth project, so both pickers now offer a “custom” option that opens the whole spectrum.
    • Drag along it and the dialog shows you the actual dot and the actual label as they will look, in the theme you are using, changing as you drag. What you see when you press save is what you get.
    • One thing is deliberately not yours to choose: how strong and how light the colour is. Those come from the theme, which is what lets a single choice work in both and keeps the name on the label readable either way — a free-for-all picker would happily let you choose a pale yellow that disappears the moment someone switches to dark.
    • A colour is now remembered as a position on the spectrum rather than as “number four in our list”, which is what made room for the other three hundred and fifty-two.
    v1.117.12026-08-05

    πŸ› and you get the colour you picked

    • Choosing a colour repainted the project in a different one. The list was asking a second, older copy of the answer — one that only catches up after the screen has already drawn itself — instead of using the colour it had just been handed.
    • It now uses the one it is holding, and the list, the switcher and the header badge all show the same shade.
    • The menu entry lost its trailing dots too: “Barva…” suggested a step that was not there, and every other entry beside it is a plain instruction.
    v1.117.02026-08-05

    🎨 Pick your own colours

    • Every project has worn a colour since projects arrived, picked automatically so that it would never change on its own — rename the project or the team above it and the colour you had learned to look for stays exactly where it was. Now you can choose it instead.
    • The automatic one does not go away: choosing “automatic” again brings back the very same colour rather than some new one, so a colour picked by mistake is never a door that shuts behind you.
    • Teams gained a colour of their own in the same breath, and that one was a genuine bug: the little team label on each project row was borrowing the project’s colour, so the same team appeared in a different shade on every line and the colour taught you nothing at all.
    • A team now keeps one colour everywhere, derived from its original address so renaming does not repaint it either — and the little house mark still shows which team owns the project, because colour should answer which team and the mark should answer which role.
    • Teams can be recoloured by hand too, for the simple reason that eight colours and more than eight teams means two of them will eventually match.
    v1.116.02026-08-04

    🎨 Projects as a table β€” and the day you have none

    • The list of projects was a row each, and it did not survive being looked at: the buttons wrapped so “Delete” fell onto a line of its own, and the four counts ran together into one string of numbers.
    • It is a table now — the numbers line up in columns and on their digits, so a 4 and a 48 stay comparable at a glance, and a zero is grey so an empty project is recognisable without reading a word.
    • The per-row actions moved into a “…” menu, where the ones you may not use still dim and still say why, but now have room to say it in a full sentence instead of a tooltip squeezed against the edge.
    • The bigger addition is a state that had simply been missing: what you see when you have no projects at all. It says what a project is for and offers to make one — and if you are not the person allowed to make one, it tells you who to ask instead, which is the only thing that actually moves you forward.
    • It also closed a trap: with no project, “New scenario” used to open the editor, let you do the work, and then refuse to save it, pointing at a field that was not on the screen.
    v1.115.02026-08-04

    ✨ Projects you can actually manage

    • Projects have had a switcher since the last release, but making a second one still meant editing a file on the server. Now there is a screen for it.
    • Creating a project takes standing in the team that will own it, because that team’s name goes into the address and stays there. Renaming moves the address and keeps the old one working for good.
    • Archiving stops the project’s watches and names them before you confirm, so nothing keeps pressing keys on a real television at one in the morning — and bringing it back does not switch them on again behind your back.
    • Moving a scenario between projects says all of it up front: a new address, its history stays behind, and the watches that will stop, by name. Every one of those warnings is counted by the server rather than guessed by the screen.
    v1.114.12026-08-04

    πŸ› The one door you could not open

    • The project switcher refused to open when you only had one project — there was, after all, nothing to switch to.
    • Except that the way to make a second one lives inside it, so the state you most wanted to leave was the one state you could not leave from.
    • It opens in every case now, and each entry says how many scenarios are in there.
    v1.114.02026-08-04

    ✨ The project you are in, and the address that says so

    • The last release put a project underneath everything without changing a single screen. This one is the half you can see: a switcher in the header, immediately right of the name, because it governs everything to its right.
    • When there is only one project it does not disappear — it stays where it is, greyed, telling you why and where to make another.
    • The project you are looking at is written into the address, with a plain “everything” view that has an address of its own, so a link you paste into a message means the same thing to whoever opens it. Every link written before today still opens and quietly corrects itself to the new form.
    • In the “everything” view each row wears the project it came from, because two clients may both have a “smoke test” and the name alone would not tell them apart.
    • A recording made before any of this belongs to the starting project rather than to nothing, because a filter that finds an empty field would hide it with nothing on screen saying so.
    v1.113.02026-08-04

    βš™οΈ Projects, and a floor to stand them on

    • A studio testing for two clients at once wants their work genuinely apart, not merely in different folders — so a project is now a real thing the system understands, and everything you author or capture belongs to exactly one.
    • This release is only the floor: nothing on any screen changes, because everything that already existed moved into a single starting project and the app behaves precisely as it did.
    • What it buys is the part that had to come first: a scenario is addressed by its team, its project and its name, so two clients can each have a “smoke test” without one of them being told the name was taken by somebody they cannot see.
    • When a name genuinely could mean two things the system says so and lists them instead of picking one, because guessing wrong here means pressing buttons on the wrong client’s television.
    • The move happens when the server starts, keeps a backup of everything it rewrites, and is safe to run again.
    v1.112.02026-08-04

    ✨ Who gets told, and about which run

    • The last two releases built the machinery for telling you when your own test finishes, and then it sat there doing nothing, because there was nowhere in the app to say where to reach you. This one gives it a face.
    • The button that proves the address works matters more than it sounds: a mistyped address is silent in exactly the way a working one is, so without it you would find out at the first real failure, by not hearing about it.
    • The address is stored and never shown again, not even to you, so the field sits empty afterwards — and now says why, rather than letting that read as lost work.
    • Someone who runs a team can ask to hear about their team-mates’ runs, one switch per team, and only for runs on that team’s own televisions, so a message never names a screen they could not otherwise see. The people in that team are told this is happening, because it is about them.
    • Each run carries its own “let me know” beside the button that starts it — yours alone to switch off: silencing your own message never silences the one going to the person watching the team.
    v1.111.02026-08-03

    ✨ Being told when your own test finishes

    • Until now only one place could ever be notified, it belonged to whoever runs the server, and it only spoke up when a scheduled check went wrong. Start a test yourself and you had to sit and watch it.
    • The system can now tell the person who started it — including the tests you kick off by hand, which were silent by design.
    • Run one script across ten televisions and you get a single message summing them up rather than ten, because ten televisions is one decision to the person who pressed the button.
    • Failures always reach you; the all-clear only if you ask for it, since a steady drip of good news is how people learn to dismiss messages unread.
    • None of it sends anything yet: there is nowhere to put your address until the settings screen lands, so this is the machinery arriving ahead of the switch.
    v1.110.12026-08-03

    βš™οΈ Groundwork: telling you when your own test finishes

    • The plan is for anyone to be told about their own tests, and this release lays the plumbing without switching anything on: the app can remember a personal notification address, and the sender can be pointed at one. Nothing is sent to it yet and nothing you see has changed.
    • The care went into the rules around it, because an address that can post into your chat is a password: the system will never show it back to anyone, not even to you.
    • An administrator can delete a colleague’s but can neither read it nor set it — deleting is the one thing they genuinely need when somebody leaves, and it destroys rather than reveals.
    v1.110.02026-08-03

    πŸ› Three small ones, done from a phone

    • A puzzle in the logs: recordings sometimes appeared to start twice without ever stopping. Nothing was wrong with the recordings — two places in the code changed the state without writing a line about it, so the diary had gaps where the day had none.
    • The whole app is a single page, and the sign-in form was quietly present on every screen of it — invisible, but real enough that password managers kept offering to fill it in places that ask for no password. Away from the sign-in screen it is no longer a password field at all, and it becomes one again the moment you need it.
    • Naming a test used to tell you the name was taken only once you pressed save, which is the worst moment to learn it. It now says so while you type, and names the test already sitting there.
    v1.109.12026-08-03

    πŸ› The pause now actually pauses

    • Leave a camera view open and walk away, and after a quarter of an hour the system lets the camera go and tells you so. Checking that promise turned out to be worth the wait: the message was true about intent and false about everything else.
    • Four minutes after announcing the camera had been released, the picture was still arriving in real time at full resolution, and the camera was still being paid for.
    • The release had happened on the server, which stops asking for the picture; the browser had simply never hung up its end of the call, and one end still listening is enough to keep the whole thing running.
    • One more thing fell out of it: the button offering to turn the picture back on was, in that paused state, quietly wired to turn it off — so getting it back took two presses instead of one.
    v1.109.02026-08-03

    πŸ› A television that is not there now says so

    • A screen can vanish in a very quiet way: someone unplugs the little computer beside it, and nothing announces it. We pulled ours out of the wall to find out what the system would say, and the answer was nothing at all — for over four minutes it went on reporting both televisions as present and healthy, and no alert was ever sent.
    • The reason is dull and worth knowing: a machine that loses power never gets the chance to hang up, so the connection sits there looking perfectly fine.
    • We stopped trusting the connection and started listening for the screen’s own voice instead: it checks in every few seconds, so silence is now the signal.
    • The same sitting turned up three smaller versions of the same habit inside the editor — a status dot left glowing green on a television that had gone, a refresh button that failed without a word, and a message blaming the camera when it was the computer beside it that was missing.
    • And the camera alignment check that arrived a version ago could be written and saved but not run or scheduled: the editor had never been told it existed, and quietly marked every example of it as broken.
    v1.108.12026-08-03

    πŸ› A message you can finish reading

    • The little note at the bottom of the screen always disappeared after the same two and a half seconds, whether it said one word or a whole sentence. That was fine for “Saved” and useless for anything worth reading — a warning nobody gets to the end of is a warning that did not happen.
    • It now stays up for as long as its text takes to read, with a ceiling so nothing lingers. Short confirmations behave exactly as before.
    • Along the way one of those warnings turned out to be invisible in the editor entirely: it was shown and then immediately overwritten by the plain “Saved” that followed it.
    v1.108.02026-08-03

    πŸ› Two tests can no longer share a name

    • Saving your own copy of somebody else’s test used to keep that test’s name, which left the library showing two rows that read exactly the same — you could tell them apart only by a colour stripe and a line of small print.
    • Names now have to be distinct within a folder, which is where two rows actually sit next to each other. The same name in a different folder stays allowed, because that is how people separate one context from another, though you are told when it happens.
    • The refusal names the test already sitting there, and the rename box stays open on the field so nothing you typed is lost.
    • Where nobody chose the name — a copy, or a test made from a recording — it steps aside by itself rather than blocking you.
    • And the comparison works the way a person reads: capitals and stray spaces do not make two names different, while accented letters genuinely do.
    v1.107.02026-08-03

    ✨ Checking that the camera still sees the television β€” wherever you need it

    • A camera watching a television is only useful while it still points at it, so before every scheduled test the system compares what it sees against the picture it was set up with. That check could only ever happen at the very beginning, and it had one shot at the answer: a person walking past at the wrong moment counted the same as a camera someone had knocked.
    • It is now also a step you can drop anywhere into a test, and it argues with itself before complaining: if the view looks wrong it waits and looks again, and if it still looks wrong it puts the calibration card back on the television and compares once more.
    • That last comparison is the same picture on both sides, which is the only honest way to tell a moved camera from a screen that simply shows something different.
    • Anything it genuinely cannot judge — a dark room, a covered lens, a card that will not appear — is reported as undecided and the test carries on, because a warning system that invents alarms is worse than none.
    • The card is always taken back off the screen, even when the check fails.
    v1.106.12026-08-03

    🎨 Choosing who gets pinged, and on what

    • A warning is only useful if the right person notices it, so alerts can now tag someone — everyone in the channel, or one named person — and you choose which situations are worth interrupting for.
    • By default that means a failed check or a device dropping offline, never a test message and never a recovery, because something that interrupts you constantly stops being read.
    • Successful runs can be reported as well, though this stays off unless you ask: an all-clear every quiet night teaches you to dismiss the message without looking, which is precisely when the real one arrives.
    • It also repaired a setting from the previous release that could be switched on and quietly did nothing at all.
    v1.106.02026-08-03

    πŸ› Alerts that actually arrive

    • The system has long been able to send a message when something goes wrong. In practice it sent nothing: no destination had ever been filled in, so a failed five-in-the-morning check reached nobody and could only be found by opening the app and looking.
    • Worse, had a destination been set, one of the most common ones would have refused every message, because it expects a different shape than the one being sent.
    • One place in the code now knows how to talk to each service, so a chat channel receives a properly formatted card while any other destination keeps receiving exactly what it did before.
    • A refused delivery is finally written to the log, and Settings has a button that sends a test message and tells you whether it was accepted — because the moment something genuinely fails is the worst possible time to discover the warnings were never arriving.
    v1.105.12026-08-03

    πŸ› Someone taking your television mid-recording no longer passes unnoticed

    • While recording a scenario the television belongs to you and the keys you press become the steps. If a senior administrator took it away in the middle of that, the editor carried on as though nothing had happened: it still said it was recording, the text stayed locked, and the keys went nowhere.
    • The dialog the other person had just confirmed promised they would be told.
    • The strip now stays where it is, turns to warning colours and explains what happened, in the same words the device screen uses: who took it, and by what right. The text unlocks and the recording ends properly.
    • The same applies when the system releases a device left idle — nobody pressed anything there either, which is exactly when a dropped connection is the natural suspicion.
    v1.105.02026-08-03

    πŸ”’ Who took your television, and by what right

    • When a television changes hands, who is allowed to do it and what is the other person told? A senior administrator’s session used to be safe only by accident: on an unrestricted television a team administrator could simply take it from them, and an ordinary member’s unanswered request handed itself over once the timer ran out.
    • Nobody below that rank takes it now, and the request is not even delivered. Losing a television tells you who took it and by what right, and the notice stays on screen instead of vanishing.
    • Ending a session no longer frees somebody else’s television by accident. The applications send that signal whenever they finish, including a run that never started because the set was busy — which meant a senior administrator merely pressing “Start” on a colleague’s television quietly threw them off it.
    • Alongside: the editor warns that a television is busy before you press Start, and the picker’s counter agrees with the list beneath it.
    v1.104.12026-08-02

    πŸ› A dark room is not a moved camera

    • Before a scheduled test presses a single button, the system checks that the camera still sees the television where the calibration left it — and that check asks whether the picture carries enough detail to work with.
    • It had only ever asked the stored reference photograph, never the picture arriving right now. A dark frame therefore did not come back undecided: it came back confident, reporting that the camera had moved by more than twice the allowed amount.
    • The trigger was nothing more than the lights going off in the evening — and the watches that run at five in the morning are the ones running in the dark.
    • Both pictures are now held to the same standard, and a dark one says so in its own words: the calibration is fine, look at the light or at the camera.
    v1.104.02026-08-02

    🎨 The screens stop speaking in half-sentences

    • A day spent walking the review queue one item at a time, mostly on what the app tells you rather than what it does.
    • A failed step now hides its whole verdict behind the row that caused it, opening with the camera frame already shown and the reason laid out as facts instead of a sentence repeating the row above it.
    • Schedules ask in hours and days rather than a raw minute count, and an interval longer than a day can finally be saved.
    • The audit’s filter reached a fifth of the log and now reaches all of it, with a search beside it.
    • And Settings stopped being the app’s exception: Escape closes its panels, the irreversible actions ask first, a new password is masked, and the lists load like every other list in the product.
    v1.103.02026-08-01

    πŸ› A run you start is a run that happens

    • Starting a scenario on a television that was already running one used to leave you with neither: the first stopped, as it should, and the second died a fraction of a second later with an empty console.
    • The editor now declines the second run instead, and says which scenario is running and who started it.
    • In the same pass, the document is held still while a scenario runs — you can read and copy it, but not change it, the same as while recording — because an edit mid-run quietly moved the marker showing which line the television was on.
    v1.102.12026-08-01

    πŸ› A step's icon is an icon, not a column

    • Beside the code, the editor draws a schematic of the same scenario, one row per step. A step that starts an application had its little coloured badge stretched to the full height of the browser window, opening a screen-high gap with the step’s own text stranded at the bottom of it.
    • The badge’s colour class happened to share a name with the application frame’s own, and quietly inherited its full-height rule.
    • In the same pass: when the schematic is narrow, the small dot marking a step that carries a comment was being cut off the edge and could not be seen or hovered, and long values were cut mid-letter instead of ending in an ellipsis.
    v1.102.02026-08-01

    🎨 The editor's preview shows the screen, not the angle

    • A camera pointed at a television sees it from the side, so the picture it sends is a lopsided quadrilateral. The device page could already straighten that back into a proper rectangle; the scenario editor’s preview could not.
    • So you wrote a test against one picture while the checks that run it measured another. The preview now straightens by default, with a toggle under the picture and the same setting the device page uses.
    • A television that has never been calibrated says so instead of hiding the option, and the still image left behind when you release the camera keeps the same shape as the live one.
    v1.101.02026-08-01

    πŸ› A watch is scheduled for the scenario you were looking at

    • From the scenario editor you can put a scenario on a schedule. If you had visited the monitoring screen earlier in the session and then written something new, the dialog was built from a list that predated it — so it opened on whichever scenario happened to be first, and creating the watch would have put that one on a nightly schedule instead.
    • The dialog now refreshes itself whenever it is asked for a scenario it does not recognise.
    • Two smaller things from the same pass: Escape closes the dialog like every other one in the app, and setting a watch for a daily time no longer runs it once immediately just because that time had already gone by today.
    v1.100.02026-08-01

    πŸ› The preview stops cutting its own picture

    • The editor can show you what the camera sees while you write a scenario. Watched properly for the first time, it turned out to be dropping the picture roughly every seven seconds — each time throwing away the connection it had just made and starting another.
    • After a minute of that it gave up and announced that the camera was disconnected and free, while the picture carried on playing and the TV stayed booked out under your name.
    • It now leaves a working picture alone, hands the TV back when a connection really does fail, and says the camera is free only when it is.
    v1.99.02026-08-01

    πŸ› The editor stops insisting a broken document is fine

    • Press Enter at the end of a step and the editor writes the next one’s dash for you. Start a comment on that line instead, and you had a step with nothing in it — an invalid scenario the editor then failed to notice, because the very check that should have caught it fell over on the way.
    • It kept showing the last thing it knew: a green “valid”, a save button that looked ready, and a condition inspector that did nothing at all when clicked.
    • The dash now gets out of the way as soon as you type a comment, the insert palette offers a comment of its own, and when a scenario really is broken the editor says so on the spot.
    v1.98.112026-07-31

    πŸ› A check is called what it actually is

    • Watch a scenario run and every condition announced itself as an OCR check — including the ones that never look at the picture. An assertion about an element inside the app read back as `ocr "el:.play-pause-button"`, followed by a match percentage, for something that either exists or does not.
    • Each condition is now named by what it really is, and only the two kinds that measure anything — reading text off the screen, and comparing images — report a percentage. The rest say nothing instead of something false.
    • A failing element check also echoes what the app actually reported, which is the sentence you needed.
    v1.98.92026-07-31

    πŸ› The element picker answers in your language

    • Press Element and the likeliest thing to happen is that the app on the TV has no debug module — and the picker answered that in raw English, in small grey type, with no hint of what to do next. It said so one screen away from where the app explains the same situation properly and hands you the button that fixes it.
    • The picker now says it in your language and points at that button.
    • And when the app does have a debug module but the list comes back empty, it tells you what the picker looks for — visible things with short text, form fields, whatever holds focus — so an empty list stops being indistinguishable from a broken connection.
    v1.98.82026-07-31

    πŸ› Recording stops eating what you type

    • While a recording runs, every key you press on the TV lands in the document as a step. What nobody had tried was typing into that document between two presses — and the next key threw the edit away without a word.
    • The recording owns the document while it runs, so it now says so and locks it: the code, the name, the labels, and the drag handle on a pause.
    • It dims by cooling the colour rather than fading it, because you are reading that code while you record against it. Everything unlocks the moment you stop.
    v1.98.72026-07-31

    πŸ› Insert drops you where you have to type

    • Six of the eleven steps in the Insert list arrive with a blank you have to fill — the text to type, the words to look for, the element to wait on.
    • The list promised the editor would jump there so you could fill it in, and it jumped to the start of the line instead: a red bar, a dimmed Run, and you still had to aim for the empty quotes.
    • The cursor now lands between them and the next thing you type is the answer. The steps that arrive complete are untouched, because there is nothing to fill.
    v1.98.62026-07-31

    πŸ› It stops telling you it saved something it never did

    • Start a new scenario and the editor said “Saved ✓” before the thing existed anywhere. That line is the one you glance at before closing a tab, so being reassuring was exactly the wrong thing for it to do.
    • The indicator has three states now instead of two — saved, unsaved changes, and never saved at all — the last in the same amber as the middle, because both mean the same thing to you: what is on your screen is not on the server.
    • Found the only way this sort of thing is found, by clicking the button and watching what it claimed.
    v1.98.52026-07-31

    🎨 The toolbar learns to fold

    • Ten controls stopped fitting the editor card, and the row broke in two — a lone run button stranded under a half-empty line. So the row learned to fold instead.
    • Save moved up beside the “Saved ✓” it acts on, and Run became a split control whose chevron carries the two rarer ways to start it.
    • When the window still gets too narrow the tools drop their labels one zone at a time: the icon stays exactly where it was and the button’s right edge slides in over it, ending as a circle. Save and Run keep their words at every step — they are the two that commit something.
    • The labels above reflow just as smoothly, so nothing on the row jumps while the rest glides.
    v1.97.02026-07-30

    ✨ Run it from where you are standing

    • A scenario whose first forty seconds are setup you have already watched is a scenario you stop testing. You can now start it at the step your cursor is on, and everything before it is skipped.
    • It only ever starts from a top-level step, and that is the honest rule rather than a shortcut: a line inside an “if” has no condition that was ever evaluated, and one inside a loop has no idea which time round it is — so a line inside a block counts as that block.
    • Which means it never has to refuse a line; it just tells you, before you click, which step it will start from and on which line.
    v1.96.02026-07-30

    ✨ Everything a scenario can do, in one list

    • Autocomplete only helps someone who already knows what to type. The new Insert button lays the whole vocabulary out instead: eleven kinds of step, each with a line saying what it does, and every remote key with its name beside its code — searchable, and honest about being complete.
    • A click drops the step in right after the one your cursor is on, and the editor jumps to it so you can fill it in.
    • Underneath, a number you can drag now looks like one: hover the pause after “wait” and it says so.
    v1.95.02026-07-30

    🎨 The schematic follows the code

    • The diagram and the code were bound together in one direction only — click a row and the code jumped, but scroll the code and the diagram stayed put, so on a long scenario the two halves showed different parts of the same document. The code leads now and the diagram follows.
    • The editor also stopped opening on two blank panels while its half-megabyte of machinery loaded.
    • And a step’s note is finally readable: the hover text used to be trimmed away by the very panel it needed to escape.
    v1.94.02026-07-30

    🎨 A dim button says why it is dim

    • The toolbar had been quietly breaking the rule the rest of the app follows. “Watch” vanished entirely if you were not an admin — which also shortened the row, so every button after it sat somewhere else depending on who you were.
    • Run, Dry-run, Record, Inspector and Element all looked ready with no usable TV and only said no after you clicked.
    • Every control now keeps its place, greys out when it cannot act, and names the reason on hover: “Can’t run: the TV is offline”.
    • Two traps found on the way, both worth knowing: a disabled button is not a reliable thing to hover, and dimming a button with transparency dims the explanation along with it.
    v1.93.02026-07-30

    🎨 A broken scenario says what is wrong, and where

    • The editor always knew what was wrong with a document; it just kept it where nobody would look — under a code panel two thirds of a screen tall, off the bottom exactly when you reached for Save.
    • The strip moved above the code, the offending lines are marked in red, and clicking the strip puts your cursor on the first one. Save greys out while the document cannot be saved and says why.
    • And with a line number to give you, the message drops the machine-speak: “line 18: invalid key” instead of “steps[14]”.
    v1.92.02026-07-30

    πŸ› The editor stops losing your work

    • Leaving the editor with unsaved edits threw them away without a word. It asks now — save and go, discard, or stay — and closing the tab raises the browser’s own warning.
    • The “unsaved changes” note stopped lying too: it used to latch on forever, so undoing your way back to the original left it complaining about changes that no longer existed. It compares against what was actually saved, which also means switching between the three ways of writing the same scenario is correctly not a change.
    • And Ctrl/⌘+S saves, as it should have from the start.
    v1.91.02026-07-29

    πŸ› A recorded scenario is one row, and it opens at once

    • Keeping a recording as a scenario minted a fresh copy every single time you opened it, so the library filled with near-identical rows and each open waited on a round trip to the box before the editor could even begin loading.
    • One recording is now one scenario: starred, it becomes a document that remembers where it came from; deleting it unstars the clip; the folder it sat in comes along.
    • Opening it a second time asks the box nothing at all — six seconds became a twentieth of one.
    v1.90.12026-07-29

    🎨 The little dialog nobody looked at

    • Click the pencil on a scenario and you used to get a huge, mostly empty box: three unlabelled fields floating in a card built for something else entirely, a folder picker that looked like it had escaped from the operating system, and no way to close with Esc or save with Enter.
    • It is a proper little form now, and labels are built by typing: each becomes a chip you can pluck off again, and the ones already used elsewhere sit underneath waiting to be clicked.
    • The rules the server has always enforced — five at most, short, lowercase — are finally visible while you type rather than applied behind your back.
    • Underneath: three colour recipes in the stylesheet referred to names that were never defined, so they had quietly done nothing — which is why the “smoke” label had been an invisible pill all along.
    v1.90.02026-07-29

    🎨 Scenarios move into folders

    • The scenario library stopped being a flat pile. Every row says whose it is and where it came from, and turns into a play button when you point at it: one click picks the TVs and runs it, whichever kind it is.
    • Four buttons sit on every row in the same order, dimmed with a reason when they do not apply — and deleting a scenario is finally possible at all.
    • Above them: folders, shared with the whole team, that you build and rearrange by dragging. Hold over a closed folder and it opens for you.
    • Delete a folder and it asks the honest question — move the contents up, or throw everything away — and it never throws away what is not yours to delete.
    • Three ways to read the tree, one button apart: dashed rainbow guides, shades that darken as a branch nests, or a colour per folder.
    v1.89.02026-07-28

    πŸ”’ Watching the watchers

    • Watches now belong to people — you see your own and your team’s, anyone can watch a TV they can see, and editing one no longer means deleting it first.
    • Each card reads like a report: a verdict chip, then one line per TV with its own PASS/SKIP/FAIL pill and the time of its last round. Click it and the run’s story opens.
    • A skipped round finally stopped crying wolf: it is amber, not red, everywhere — including the nav badge, which turned two-tone and explains itself when you hover the number.
    • History became yours to prune: a trash can on every run, plus one button that clears everything no active watch cares about.
    • And the phantom five-in-the-morning “TV in use”? A phone tab dozing in the background kept re-claiming the TV all night on every reconnect. Hidden tabs now politely keep their hands off.
    v1.88.02026-07-28

    🎨 Fullscreen, first-class

    • Fullscreen playback stopped being the poor cousin: the thin progress line grew into the same timeline as the page — coloured ticks, cluster bands, count bubbles whose press list opens upward — joined by a real play/pause button, the time, and the what-comes-next countdown in a slot that never shifts the lane.
    • Leave the mouse still for a moment and the whole bar melts away with the cursor; move and it is back.
    • Every control explains itself on hover without a single tooltip bleeding off-screen, and the speed pill keeps its dark glass in both themes.
    v1.87.02026-07-28

    🎨 The timeline became the instrument

    • The global recordings screen learned the rules the set tab already lived by — ownership as a quiet colour stripe, actions that never move, a share switch right on the row — plus a one-word filter that hides every machine-made clip with no key presses.
    • The review player was rebuilt around its seekbar: every press sits in the lane as a coloured tick, and dense runs melt into one band with a count bubble.
    • Cutting a clip became a mode: handles and a download bar appear only when you ask.
    • A countdown names the next key before it fires, every press renders as a little remote button (no more “OK OK”), and playback narrates itself in a slim corner column — the current press big and pulsing, the last four fading below it, each gone three seconds after its moment.
    v1.86.02026-07-27

    🎨 Watching a scenario breathe

    • The scenario tab is always there now: it opens on a picker of everything replayable on this TV and arms into a player that shows time passing.
    • Every recorded press sits as a coloured tick on a timeline, the fill creeps toward the next one, and a countdown says exactly how long the silence will last. The current step holds its colour until the next press fires, then dims into history.
    • On the camera, a press pulses a coloured ring at the centre of the picture — sized to the video, fullscreen included — while recorded playback stacks its presses in a corner queue you can actually read.
    • And the whole key-icon set was reviewed one icon at a time: Back stopped pretending to be Left.
    v1.85.02026-07-27

    🎨 Buttons that never move

    • The recordings tab was redesigned around one rule: every action keeps its place on every row — a missing one dims instead of disappearing, so muscle memory always lands.
    • Ownership became a quiet colour stripe, hovering anything explains it (even why a button is dimmed), and the time reveals its full date.
    • Launching a scenario grew up too: a two-pane dialog previews every recorded press on the left and lists all your TVs on the right — searchable, grouped, unavailable ones dimmed with the reason.
    • Replaying on the same TV no longer reloads the live camera.
    v1.84.12026-07-24

    🎨 The last bit of clutter

    • A device link used to carry `?from=picker` — a note about where you had clicked from, riding along in an address you might send to someone else.
    • It travels out of band now, so the whole URL is the device.
    v1.84.02026-07-24

    🎨 Devices have real addresses

    • The detail page dropped its query-string deep link. Instead of `?set=…&cam=cam&chii=…` the address reads `/devices/samsung-ue43nu7192-02`, and every tab is a path of its own — send someone a link straight to a TV’s DevTools.
    • Back and forward walk the tabs.
    • The camera path and debug target left the URL entirely: they belong to the device, so the app looks them up.
    v1.83.02026-07-24

    βš™οΈ Its own address

    • Screenwhere moved off the IP-derived hostname onto its own domain: the app now lives at `app.screenwhere.com`, with the dashboard on the bare root and every screen one clean path below it.
    • Sessions and MCP connections are tied to the origin, so the move asked everyone to sign in once more.
    v1.82.02026-07-18

    πŸ”’ Recordings belong to their owner

    • A recording is now visible only to its owner, their team admin and the superadmin — and a superadmin’s clips to nobody else.
    • A per-clip share switch opens one recording to the owner’s teammates, and every path that carries footage — list, poster, stream, export, key-track — enforces the same rule.
    • The tab grew ownership chips, the ★ keep star, and per-row and bulk delete: deletes vanish instantly and finish in the background.
    v1.81.02026-07-17

    🎨 One bar to act on anything

    • The library’s action bar now serves both worlds: it installs or debugs a freshly dropped file just like a stored package, with rename and delete politely greying out for files not yet in the library.
    • The DevTools debugging flow wears the same bar — one button runs the pipeline, the other hops to the install tab with your source preselected.
    v1.80.72026-07-17

    πŸ› One install intent at a time

    • A staged upload and a selected library package could both look chosen at once.
    • The tab now holds a single intent: dropping a file clears the library selection, and picking from the library quietly discards the staged file.
    v1.80.62026-07-17

    🎨 The dropzone reaches DevTools

    • Uploading a package while adding the debug module now uses the same drag-and-drop zone as the install tab — drop a file and it becomes a selectable source with a save-to-library switch in the familiar style.
    v1.80.52026-07-17

    πŸ› The off switch shows itself

    • A switched-off install option no longer melts into its background: the track got a proper grey in both themes.
    v1.80.42026-07-17

    🎨 Daintier switches

    • The install options’ switches shrank to the mockup’s petite size — no more oversized toggles crowding out their own labels.
    v1.80.32026-07-17

    🎨 Pixel-matched to the mockup

    • The install options got their explanations back — short, one line, never wrapping — with the exact proportions of the approved mockup. Third try’s the charm.
    v1.80.22026-07-17

    🎨 The options bar slims down

    • The two install switches now sit in one tidy line each: shorter labels, smaller icons, explanations tucked into tooltips. Same choices, half the visual weight.
    v1.80.12026-07-17

    🎨 Options appear when they matter

    • The install tab rests as a single clean drop area. The moment you pick a package it turns into a tidy card with the file, two clearly explained switches — launch right away, keep in the library — and one Install button.
    • No more settings hanging around with nothing to apply to.
    v1.80.02026-07-17

    🎨 One library to rule both tabs

    • The install tab and the debugging flow now share a single package library: the same clean selectable rows everywhere, with one action bar — install, debug, rename, delete.
    • Each package wears its owner’s colour: green for yours, blue for your team’s, amber for the superadmin’s.
    v1.79.82026-07-17

    🎨 Debug uploads join the library

    • Uploading a package while adding the debug module now offers the same “save to library” switch the install tab has — the clean original is stored, so next time it is one click away on any TV.
    v1.79.72026-07-17

    🎨 One click less, one acronym less

    • Re-opening the debugging offer no longer routes through a card asking for the same click twice; it goes straight to picking the package.
    • And the footnote under DevTools dropped a cryptic acronym nobody needed to know.
    v1.79.62026-07-17

    πŸ› The popout hands over cleanly

    • Opening DevTools in a separate window now closes the embedded panel and says where to continue, so two inspectors never wrestle over one TV.
    • The header learned to read the app’s real name straight from the package, and the add-debug flow openly says when a package already carries the debug module.
    v1.79.52026-07-17

    🎨 DevTools tell you what you're debugging

    • The DevTools header now names the app actually running on the TV instead of an internal code name, and a new close button lets you disconnect the inspector and reconnect with one click.
    • The widescreen layout lost its mystery gap: the camera stretches, the remote compacts, and the tools sit right where they should.
    v1.79.42026-07-17

    πŸ› Debugging waits for the app to come back

    • Adding a debug module restarts the app on the TV — and the page now patiently waits for it to call home instead of giving up after the first look. Only after a good minute does it offer a retry.
    • Plus clearer wording on the upload row, and the package library sorted newest-first.
    v1.79.32026-07-17

    🎨 Certificates are nobody's business

    • The install tab stopped lecturing about signing certificates — that all happens quietly in the background.
    • What stayed, front and centre, is the one note that matters: an installed app is temporary and uninstalls itself once you release the device.
    v1.79.22026-07-17

    🎨 Install moves up front

    • A small reshuffle on the device detail: the install tab now sits right after Information. Installing apps became an everyday action for everyone, so it earned the spot before the debugging tools.
    v1.79.12026-07-17

    🎨 Library polish

    • Deleting a stored package now asks for confirmation, and the rename field grew to fit longer names.
    • The DevTools debugging flow can take its package straight from the library — the same one the install tab uses, with the same sharing rules.
    v1.79.02026-07-17

    πŸ”’ The library follows the org chart

    • Package sharing now mirrors how the team works: everyone gets the superadmin’s packages, a team admin sees the whole team’s, and a member sees their own plus what their admins share. A colleague’s private uploads stay private.
    • Packages can also be renamed in place, with the same common-sense rules about whose you may touch.
    v1.78.12026-07-17

    πŸ› Members see the certs are ready

    • Right after opening installs to everyone, members still saw “certificates not set up” on devices where the superadmin had set them — the readiness check itself was locked to superadmins. Everyone now sees whether a device is ready to install, while certificate details stay with the superadmin.
    v1.78.02026-07-17

    ✨ Everyone installs; the TV forgets when you leave

    • Installing an app onto a TV is no longer a superadmin privilege: anyone drops in a package and it is signed and installed automatically.
    • The twist is that apps installed by regular users and team admins are temporary — release the device and the TV uninstalls them by itself, debug builds included.
    • A new package library keeps your uploads around: your own stay private, a team admin’s are shared with the team, a superadmin’s with everyone.
    v1.77.12026-07-17

    🎨 No stray divider for members

    • A tiny cosmetic fix on the device info card: for regular members the last visible row no longer draws a divider line into the empty space where the admin-only rows would be.
    v1.77.02026-07-17

    πŸ”’ Roles mean what they say

    • The three roles got honest names: Superadmin runs the infrastructure, a Team admin manages their own team, a Member uses its TVs.
    • The names now match the powers — a team admin’s audit view covers their team instead of everyone, and only a superadmin creates teams.
    • DevTools, which was never really restricted, is now openly available to every role, listing only the TVs you are allowed to see.
    v1.76.12026-07-17

    πŸ”’ Amber everywhere it belongs

    • The amber marking now covers every superadmin-only block on the device detail, with the explaining legend under the last of them.
    • And the emergency power restart is truly superadmin-only: the server refuses anyone else, and nobody else sees the button.
    v1.76.02026-07-17

    🎨 Admin-only details wear amber

    • On a device’s information tab, everything only privileged roles can see — the IP addresses and the live power meter — is now tinted amber with a small edge stripe, and a one-line legend explains the colour.
    • The live power card itself became superadmin-only, so regular users simply do not see it at all.
    v1.75.12026-07-16

    🎨 Details in their right places

    • The keyboard button now glows green while it is driving the TV.
    • The remote-layout switcher went back under the remote, with the layout jump fixed properly, so the volume row lines up with the top of the picture again.
    • And the picture controls moved out of the tab row to sit right under the video, where they belong.
    v1.75.02026-07-16

    ✨ Type like a remote

    • Click the live picture and your keyboard becomes the TV remote: arrows steer, Enter confirms, Backspace goes back, and R, G, B, Y press the colour keys.
    • A small badge shows when the keyboard is live, Escape turns it off, and every keystroke visibly presses the matching button in the on-screen remote.
    v1.74.02026-07-16

    🎨 A tidier TV remote

    • Launching apps is now a proper dropdown fed by what is actually installed on the TV, and the text-and-apps drawer reads as one card with a clear name.
    • The layout no longer jumps when switching remote layouts — the switcher moved on top — and the picture controls sit together neatly even on narrow screens.
    v1.73.02026-07-16

    πŸ› The certificate remembers its TVs

    • A signing certificate covers a list of TVs, but the app never showed which — and regenerating it for a new TV started from a blank list, quietly dropping the old ones.
    • The stored certificate card now names every TV it covers, and “Replace” starts from that full list, so adding a TV really just adds it.
    v1.72.12026-07-16

    πŸ› Signing helper, delivered

    • The app-signing wizard’s first step asked you to run a helper script you had no way to obtain — running the command ended in “file not found”.
    • The helper now lives on the server and the command fetches it for you before running it.
    v1.72.02026-07-16

    🎨 A tidier device form

    • Network addresses now sit in one clean grid — a labelled row per component, matching fields and buttons, technical MAC addresses in a technical font — and the camera-calibration status shows the exact date and time.
    • App signing got two clear tabs, generate automatically or upload by hand, with a step-by-step guide.
    • And the camera-type menu only offers cameras we actually own.
    v1.71.02026-07-16

    🎨 Device health tucked into Settings

    • The device-health monitor moved out of everyone’s way and now lives in Settings as an admin tool.
    • The one piece regular users care about stays in sight: an offline device says right in the device list when it was last online.
    v1.70.02026-07-16

    🎨 Favourites first

    • Devices you have starred now sit at the top of the device list, whatever sorting you choose.
    • Prefer the plain order? One tick in the sort menu turns the pinning off.
    v1.69.22026-07-16

    πŸ› Filter menus close when you click away

    • An open filter or sort menu on the device list now closes on a click anywhere else on the page — before, clicking the header or footer left it hanging open.
    v1.69.12026-07-16

    🎨 Device-list polish: one sort button, tidy checkboxes, settled power chip

    • Sorting now lives in a single neat button, field and direction together in one menu.
    • The filter checkboxes were redrawn to sit right in the light theme, and the little power readout on grid cards found its home: a chip in the card’s corner that stays put instead of floating over the neighbours.
    v1.69.02026-07-16

    🎨 Smarter device filters & instant returns

    • Device-list filters now select more than one value at a time — several teams, brands or states at once, each filter a neat checkbox menu.
    • Grid cards say what they mean: brand and model each get their own line.
    • And coming back to the list from a device is instant — the app remembers what it just showed you instead of reloading everything from scratch.
    v1.68.12026-07-16

    πŸ› List tooling always visible

    • A well-meant rule had been hiding the search box, the list/grid switch, sorting, filters and the column chips until a list reached about eight items — with two real devices that meant no tools at all.
    • The rule is gone: the toolbar always shows, on devices, recordings and monitoring history alike.
    v1.68.02026-07-16

    🎨 Login polish: the living mark + pre-auth theme & language

    • The sign-in screen’s logo comes alive: every half minute the stack of screens advances like a conveyor — a new edge appears from afar, the bars ride down, and the front one unfolds into the next TV.
    • And the two things you could not change before signing in — light or dark theme, and language — now sit as subtle controls in the footer.
    v1.67.42026-07-16

    🎨 Install progress: real-time streaming

    • The install checklist now tracks the actual work in real time: the TV box streams each step the moment it finishes and it appears on screen right away, instead of the whole list arriving at the end and the app faking the progression.
    v1.67.32026-07-16

    🎨 Install progress: step by step

    • The install checklist reveals each step one at a time as it finishes rather than all at once, each step’s full technical detail is available by clicking it open, and the working spinner is clearer.
    v1.67.22026-07-16

    🎨 Install progress: cleaner steps

    • More install-tab refinements from a live test: the signing step visibly shows it is working, and the step list is clean — no raw device logs, with details shown only when a step fails.
    • The drop area appears immediately while certificates are verified quietly in the background.
    v1.67.12026-07-15

    🎨 Install tab polish

    • Small refinements to the new install tab after a live test: the drop area sits tidily under the tabs, picking a package clearly shows the progress starting, and the step checklist looks nicer.
    • A device that already has certificates goes straight to the drop area instead of briefly flashing a “no certificates” message.
    v1.67.02026-07-15

    ✨ Install onto the TV: drop-and-go

    • Putting an app on a TV is now one step: the device’s install tab is a single drop area, and a dropped package is automatically signed, sent to the TV, installed and launched, with a live checklist of each step.
    • The old manual certificate and signing screens are gone from here — certificate setup moved into the device’s edit form, where it is done once.
    v1.66.02026-07-15

    🎨 UX audit batch C: localization

    • Text that used to leak the app’s internal wording into the Czech interface is tidied up.
    • The activity log describes every action in plain language — saved a watch, signed an app, connected an app — instead of showing a raw internal event name.
    • And the monitoring screen shows its scheduler messages, like “the TV is in use, a live session wins”, in your chosen language.
    v1.65.02026-07-15

    🎨 UX audit follow-up (batches A & B)

    • Polish from a fresh whole-app UX audit, a screen-by-screen designer’s pass in light and dark.
    • Consistency and brand: a redundant version stamp is gone from Settings, the auto-play preference matches its neighbours, the device-health rows no longer say “Online” three times, and recording key-counts show one consistent glyph and number.
    • A loading layer: the top navigation bar is present the moment a screen opens, instead of appearing only after the data loads, and every section shows a loading state during that wait rather than a brief empty flash.
    v1.64.02026-07-15

    🎨 A growing nav and a hero login lockup

    • The top navigation bar is now larger while you are scrolled to the top, showing the full wordmark, and smoothly shrinks to the compact bar as you scroll down.
    • The sign-in screen becomes a hero: a big stacked logo with a soft green brand glow behind it, in both light and dark.
    v1.63.22026-07-15

    πŸ› Relay-only must also mean TCP-only

    • Follow-up to the relay fallback: on half-open networks the relay itself must be reached over TCP/TLS, because a relay reached over UDP dies exactly like the direct path. The fallback now uses exclusively the TLS relay on port 443.
    v1.63.12026-07-15

    πŸ› Half-open networks: relay-only fallback

    • Some restrictive networks are half-open: connection checks pass but the video packets themselves are silently dropped, so the player looked connected while showing nothing.
    • The player now detects that signature — connected twice in a row with zero media arriving — and re-dials exclusively through the TLS relay, which such networks do pass.
    v1.63.02026-07-15

    ✨ Camera works on 443-only networks (TURNS)

    • Live camera now reaches phones and laptops on restrictive networks — train, hotel and corporate wifi that block everything except HTTPS.
    • The media path can relay over TLS on port 443, indistinguishable from HTTPS to a firewall, and the web player fetches its full relay configuration from the server before connecting.
    • Built and verified live from a moving train, on the network that exposed the gap.
    v1.62.42026-07-15

    πŸ› Camera-failed overlay: no more eternal spinner

    • When the camera stream cannot come up at all, the terminal “video failed” message no longer keeps the spinner spinning as if still trying.
    • Waiting states — connecting, TV offline — keep their spinner.
    v1.62.32026-07-14

    🎨 Status pills back to the legible generic glyphs

    • The brand mark family from the previous release is reverted, on the owner’s call the same day: at pill size the generic check, play, person and lock glyphs say what a state means at a glance, and five near-identical screen marks did not.
    • Legibility wins over brand consistency for functional icons. The offline alert mark stays.
    v1.62.22026-07-14

    🎨 Brand state marks on the set status pills

    • The set status pills all carry the brand state-mark family now: one “stack of screens” mark, where the front screen’s glyph tells the state and the pill’s colour tells whose.
    v1.62.12026-07-14

    πŸ§ͺ Coverage push + agent socket hygiene

    • A test-coverage batch: the Samsung pairing state machine now runs against a mock TV in CI, including the stale-token self-heal.
    • It surfaced one real fix: a pairing attempt the TV refuses no longer leaves a half-open socket behind.
    v1.62.02026-07-14

    βš™οΈ Infra identifier migration to screenwhere

    • The live identifiers deferred by the rename are migrated, and nothing visible changes in the app.
    • Filesystem paths on the site box and the cloud server now say screenwhere, the site agent runs as one templated service per set, and new installs pair with the TV as “Screenwhere Agent” — existing sets keep their stored pairing untouched.
    v1.61.12026-07-14

    🎨 Brand rollout: two-tone wordmark + state marks

    • The new logo family shows up across the product: a two-tone wordmark on the login, the app footer and these docs, the brand alert mark on offline badges, and the real mark and favicon on the documentation site.
    v1.61.02026-07-14

    ✨ The product is now Screenwhere

    • The internal working code name is retired — the product is now called Screenwhere, screen plus anywhere.
    • Every user-visible surface is renamed: the app wordmark and titles, the burned-in recording watermark, the sign-in pages, the AI-agent metadata and these docs.
    • The same release ships the final logo, the “stack of screens” mark, as the app icon, nav mark and first favicon.
    v1.60.32026-07-14

    πŸ› Agent self-heals a dead TV socket

    • When the TV dropped the remote-control connection — standby, or two agents sharing one TV — the box kept using the dead handle forever: keys silently went nowhere and the calibration card refused to open until the agent was restarted.
    • A failed send now reconnects once and retries by itself.
    v1.60.22026-07-14

    πŸ› Straightened view honours 4:3 cameras

    • The straighten-view renderer assumed every camera streams 16:9, so a 4:3 camera had its straightened picture squeezed to 75 % width — calibration discs could never reach their target rings.
    • The output now letterboxes to the TV panel’s own shape and the lens model uses the camera’s real aspect. 16:9 cameras are unaffected.
    v1.60.12026-07-14

    πŸ› Wait for the card's fullscreen before locking on

    • The faster live detection could lock onto a frame before the TV browser had gone fullscreen, so its toolbar shifted the card down and the calibration came out offset. It now waits for fullscreen to settle before detecting.
    v1.60.02026-07-14

    🎨 Detection runs off the live stream now

    • The “finding the markers” step used to sit for several seconds fetching slow snapshots from the camera.
    • It now uses the live video stream instead — you watch the camera feed the whole time, and the colour discs are found within a frame or two of the card appearing. Much faster, and it always looks like something is happening.
    v1.59.12026-07-14

    🎨 Faster, calmer capture polling

    • The calibration “capturing…” status used to flicker a few times before detecting, because every retry re-asserted fullscreen and waited over a second. Now only the first try does that; the rest just re-snap quickly until the colour discs appear.
    v1.59.02026-07-14

    🎨 Calibration targets match the colour discs

    • The alignment targets in the rectified pane are now coloured circles with a centre dot, one per corner, matching the disc colours — and the draggable handles wear their corner’s colour too.
    • Each disc on the TV card also gained a precise white centre dot to aim the handle at.
    v1.58.12026-07-14

    πŸ› Wait for the card before detecting

    • The frame could be captured before the TV finished drawing the colour card, so detection ran on a blank screen. It now retries the capture until the card is up before placing the handles.
    v1.58.02026-07-14

    ✨ New calibration card: colour discs that auto-detect

    • The calibration card now shows four big solid colour discs — one per corner — instead of the old black squares that were hard to spot in a dim room.
    • The app finds each by its colour, so the handles land on the markers automatically and it cannot get the corners mixed up.
    • Missing a colour, from bad framing, simply falls back to pre-placed handles you nudge.
    v1.57.02026-07-14

    🎨 Calibration live preview is a real stream now

    • The “live preview” toggle in the calibration editor used roughly one frame a second and looked choppy. It now dials a real video stream into the editor — one decoder, full frame rate — with the rectified result rendered from it every frame.
    v1.56.02026-07-14

    🎨 Handles always pre-placed; the background stream truly pauses

    • Marker detection is fragile in a dim room, so the four handles are now always pre-placed — from the previous calibration when there is one, otherwise on the aim guides — and you just nudge each onto its marker.
    • And the live stream behind the calibration dialog now genuinely stops decoding, so dragging is smooth. It had been revived each time by the camera self-heal loop.
    v1.55.02026-07-14

    🎨 Calibration polish: tight sliders, smarter detection, live preview

    • Slider ranges now match real edits, and the marker detection pre-places the handles reliably: it looks near the previous calibration first and automatically re-captures when the TV was still loading the card.
    • The left pane can switch to a live preview, and buttons that did nothing useful are gone — the TV returns automatically on save or close.
    v1.54.02026-07-14

    ✨ Calibration: one flow, correct mapping, both-way zoom

    • Opening the calibration now does everything itself: the card loads on the TV with a narrated progress line, a frame is captured, the markers are found automatically, and you land straight in the editor.
    • The handle mapping was fixed — handles belong exactly on the marker centres and the result is the whole panel edge to edge, with a saved zoom in both directions for that sliver of margin around the screen.
    • The background live stream pauses while calibrating, so dragging stays smooth.
    v1.53.02026-07-14

    🎨 "Straighten picture" in the recordings player too

    • The same display-only straightening the live view got is now available when reviewing recordings, as a toggle next to the speed buttons, shown when the device has a saved calibration.
    • Recordings stay raw on disk and the current calibration is applied at playback — so clips recorded before a camera re-aim may not line up perfectly, which is exactly why it is a toggle.
    v1.52.32026-07-14

    πŸ› The straightening is truly permanent now

    • The straightened view held only within one session — coming back showed the raw picture again.
    • The server had it stored all along: the app’s device-list loaders copied an explicit list of fields and the straightening was not on it, so every fresh page load dropped it.
    • It carries through now, on every visit, until you recalibrate or remove it.
    v1.52.22026-07-13

    πŸ› The straightening survives the device-edit form

    • Saving the device-edit form right after calibrating brought the raw view back: the app’s cached device list predated the calibration, so it “forgot” the fresh straightening until a reload.
    • The calibration save now updates that cache too, so the straightened view sticks through any navigation.
    v1.52.12026-07-13

    🎨 Saving the calibration lands you at the result

    • “I saved — and now what?” The save now finishes the job: the TV returns to what it was showing, the live player’s straighten toggle switches on for that device, and the dialog closes.
    • Open the live detail and the stream is already straightened. Recordings stay raw by design.
    v1.52.02026-07-13

    ✨ Calibration: aim live, then one-click fine-calibrate

    • The calibration dialog now leads with the live picture: aim the camera so the on-TV markers overlay the dashed outlines, press the button, and the four marker centres are detected automatically — dropping you straight into the straighten editor with the handles pre-placed.
    • One save stores both the checks calibration and the view straightening.
    • Clicking the centres by hand remains only as a fallback when detection is not confident.
    v1.51.22026-07-13

    πŸ› The straighten editor now matches the approved mockup

    • The first shipped editor looked nothing like the concept that had been approved. It is now that concept, faithfully: the original view with four draggable handles on the left, the straightened result with ghost marker outlines, guides, zoom, grid and an A/B toggle on the right.
    • Dragging is smooth too — frames upload to the GPU once, and repaints batch into single animation frames.
    v1.51.12026-07-13

    πŸ› Your own live session no longer blocks calibration

    • Opening the live screen made you the device’s holder — and the calibration dialog then refused with “someone is using this device”, even though that someone was you.
    • Calibration now proceeds when the session holding the device is your own. A device held by another user still says no.
    v1.51.02026-07-13

    ✨ Straighten the camera view

    • A camera never hangs perfectly — the picture is tilted and the wide lens bows straight lines. The view can now be straightened in software: drag the four marked card centres, dial the lens curvature until the markers settle into their ghost outlines, and save.
    • The live player then offers a “straighten picture” toggle that re-projects the stream on the graphics card — no extra decoding, no added latency.
    • Purely cosmetic: recordings stay raw and the automated checks keep their own calibration, so this can never break a watch.
    v1.50.02026-07-10

    πŸ› Idle sessions release themselves

    • A pocketed phone kept holding a TV — and kept the recording signal on — for seven and a half hours overnight, because a background tab’s connection never dies on its own.
    • The server is now the authority: a session that shows no sign of life for fifteen minutes has its control released and its watching stopped, which also ends the recording.
    • While you are actually there — tapping, typing, or just watching the live picture with the screen on — the app quietly pings the server, so a real session is never cut, and a running scenario is never touched.
    • Coming back after an idle stop resumes with a single tap.
    v1.49.32026-07-10

    πŸ› No more browser-default input boxes

    • Reported from the phone: the alert-webhook URL field and the access-token name field looked alien — grey browser-default boxes with a light border.
    • The app styled inputs per screen and had no global base, so a field outside any styled scope fell back to the browser’s own dark-mode rendering.
    • There is now a base style for every text input, so a bare input can never render browser-default again — and every screen-specific style still wins.
    v1.49.22026-07-10

    🎨 One gold star everywhere + the add/edit-device screen got its review pass

    • Every active star in the app — favourite devices on the dashboard and in the picker, permanently kept recordings and their poster badges — now turns the same gold. Previously half of them turned the brand green.
    • The standalone add and edit device form finally got its own walkthrough: the delete button is styled as the destructive action it is, the camera type offers an explicit “not set” instead of rendering blank, and filled network addresses no longer look like placeholder text.
    v1.49.12026-07-10

    πŸ› A frozen camera picture now heals itself β€” "the remote does nothing" was a stale frame

    • Reported from a real phone: after camera fullscreen, the remote seemed dead. Checking the whole chain proved every key press did reach the TV — its menu cursor moved exactly as pressed.
    • What actually broke was the picture. The fullscreen-to-remote transition made the phone throttle the video decoder mid-session, and since the previous release the app correctly no longer tears down a connection whose data still flows — so the preview showed the last decoded frame, frozen, and the TV’s reactions were invisible.
    • When data flows but nothing decodes for about three seconds while somebody is actually watching, the app re-dials the stream so a fresh decoder starts at a keyframe. Hidden previews stay untouched, because that throttling is fine and saves battery.
    v1.49.02026-07-10

    πŸ“± The phone camera picture now floats β€” drag it to any corner

    • The little camera preview on the remote tab no longer sits in the page flow — it floats over the remote, tucked into a corner under the sticky nav, and stays put while you scroll a long remote so the TV stays visible next to the bottom rows.
    • Do not like the corner? Drag the box anywhere; it snaps to the nearest corner on release, and each set remembers its own.
    • Desktop is untouched.
    v1.48.42026-07-09

    πŸ› The phone camera picture-in-picture shows the real picture

    • Follow-up to the previous release: the little camera picture stopped blinking but stayed black.
    • A second video element mirroring the same stream cannot render on phones — the decoder is throttled while the only rendered sink is missing, and a sink attached mid-stream does not wake it up.
    • So the preview now borrows the real camera video element: it moves into the corner box on the remote tab and moves back when you leave. One element, always visible somewhere, and the picture never stops.
    v1.48.32026-07-09

    πŸ› The phone camera picture-in-picture no longer blinks in and out

    • On a real phone the little camera picture on the remote tab kept flashing up and vanishing in an endless loop.
    • The culprit was our own seven-second liveness watchdog: it only trusted decoded frames as proof of life, and mobile Chrome pauses decoding while the video element is hidden — so a perfectly healthy stream was torn down and rebuilt every seven or eight seconds.
    • Receiving data now counts as alive too.
    v1.48.22026-07-09

    πŸ“± The mobile menu now drops down from the burger β€” not up from the bottom

    • Tapping the burger now opens a classic dropdown anchored right under the header — where the eye goes after tapping — instead of a sheet sliding up from the bottom edge.
    • Everything else is unchanged: it still closes when you pick a section or tap outside.
    v1.48.12026-07-09

    πŸ› The app survives a slashless URL β€” and an expired session lands on login

    • Two fixes straight from a real phone. Visiting the app’s address without the trailing slash used to render it as raw unstyled HTML, because the browser resolved every asset against the site root. Both addresses now redirect to the slashed form, query string preserved.
    • And opening the app with a stale stored session now lands on the login screen instead of an empty dashboard with zero devices and no user.
    v1.48.02026-07-09

    ✨ Run history that goes all the way back β€” "Load older" in Monitoring

    • The run history no longer stops at the newest hundred runs: a “load older” button fetches earlier ones fifty at a time, all the way back to the start of what is retained.
    • Pages are keyed by run rather than by position, so rows do not shift when new runs land between clicks, and the verdict filters keep working across everything loaded.
    v1.47.02026-07-09

    ✨ Scenarios can assert memory and load time β€” from inside the app

    • A new kind of condition reads the running app’s real performance numbers over the same debug channel element checks use — no camera involved.
    • It can assert the live memory footprint (“the app stays under 150 MB”) and how fast the page actually got ready, so a watched scenario can fail the moment an app starts leaking or loading slowly.
    • Metrics that do not exist yet — the page still loading, no memory reporting — report as a soft “not yet” instead of an error, so launch-then-wait sequences just work.
    v1.46.02026-07-09

    πŸ“± See the TV while you press keys β€” camera PiP on the phone remote

    • On a phone the remote tab now docks a small live camera preview above the volume row, so you can see the TV while you press keys. Dismiss it per device and a dashed chip brings it back, or jump to the full camera.
    • It mirrors the already-running stream, so it costs no extra bandwidth.
    • Plus phone polish: a one-line sticky header on the device detail, two-line title clamps, settings controls that drop under their label, and a stacked install form.
    v1.45.02026-07-09

    πŸ“± Comfortable on a phone: swipeable stats, fixed device rows, one tablet breakpoint

    • First build wave of the phone and tablet pass. On phones the dashboard stats become a swipeable row with position dots — the fourth card used to be clipped and unreachable, and the storage card collapsed into a jumble.
    • Device-list titles no longer paint under the status chip, the navigation sheet closes after picking a section, and the review player stops scrolling sideways.
    • Tablets get one deliberate threshold: at 740 pixels the camera-beside-remote layout and the horizontal navigation flip together, so an iPad mini in portrait gets the full arrangement.
    v1.44.12026-07-09

    πŸ› Monitoring run history: trigger icons back to text size

    • Found during the phone and tablet audit but broken at every screen size for sixteen releases: the run-history trigger glyphs shipped without a size rule, so the icons rendered about 135 pixels wide and every history row took half a screen.
    • One rule returns them to inline text size.
    v1.44.02026-07-09

    ✨ Scenarios can assert the video really plays + installs are clean reinstalls

    • An element condition can now read the player itself: that the video truly renders — not paused, not ended, buffered enough — and that it has played at least so many seconds. That proves playback from inside the instrumented app, with no camera needed.
    • Separately, every install now uninstalls an already-present package of the same name first, so installs always start clean.
    • That retires the “already installed under a different certificate” dialog entirely, and wiping the old app’s data gives scenarios a defined starting state.
    v1.43.12026-07-09

    πŸ› The DevTools tab now loads its target list

    • Found while verifying the add-debug chain live: the DevTools pane fetched the target list without the authentication header every other call sends, so it always got an empty list and showed “no debug module” even with a target registered.
    v1.43.02026-07-09

    πŸ› Add-debug fixes: the debug target attaches, and already-installed apps are handled

    • Two bugs surfaced on the first live end-to-end run of “add debug to this app” on a real TV.
    • The injected debug client now registers under a title the DevTools tab can actually select, so the target is selectable and element checks can reach it.
    • And installing over an app already on the TV under a different certificate no longer dead-ends: a confirmation offers to uninstall the original and install the debug build in its place, done on the box with no operator step.
    v1.42.02026-07-09

    ✨ Pick elements visually in the scenario editor

    • No more hand-writing selectors for element conditions: the editor’s new Element button lists the running app’s elements live — selector, label, focus state — and one click drops a “press DOWN until it has focus” block into the scenario.
    • Selectors are derived to survive focus moves: ids win, and state-ish class names are excluded.
    • An app without the debug module reads out why instead of listing.
    v1.41.02026-07-09

    ✨ el: conditions β€” the app itself as the oracle

    • Scenarios can now assert what the running TV app’s own page shows — “press DOWN until the row named Movies has focus” — through the debug plane, with no camera involved. The run log reads out what the app actually showed.
    • It works in every condition slot next to the text and image checks, and an app without the debug module simply never passes, with a clear read-out. Camera conditions remain the universal fallback.
    • Free-form code conditions stay refused by design: this gives authors assertions, never code execution.
    v1.40.02026-07-08

    ✨ The tva CLI β€” scenarios live in git

    • Authored scenarios sync between the server and local files: pull them into a repository, edit them in your own editor — each file carries a schema header, so autocomplete and validation just work — and push them back, authenticated by a personal access token with the same author and admin rules as the app.
    • A brand-new local file creates a scenario on push and is renamed to the id the server minted, so it stays pushable.
    • Validator problems print per file, so nothing invalid ever lands on the server.
    v1.39.02026-07-08

    ✨ Schedule a watch straight from the editor

    • A scenario you just wrote can go under monitoring without hunting for it in another screen: the editor toolbar gains a watch button that saves your edits and opens the new-watch dialog with the scenario already picked.
    • Same save-first rule as Run — the watch always schedules the stored document.
    v1.38.12026-07-08

    πŸ› Stable-fullscreen calibration capture

    • The TV browser drops out of fullscreen after fifteen or twenty seconds, so the calibration card’s geometry could differ between captures.
    • Capture and save now re-assert fullscreen and use a fresh frame, so the marked geometry and the stored camera reference are always the fullscreen card. The card itself also retries fullscreen the moment it drops out.
    v1.38.02026-07-08

    ✨ Rectified checks + the standing camera watch

    • The calibration’s two consumers land, and the fallen-camera incident’s fix is complete. Every check frame on a calibrated set is warped into a canonical panel space, so regions and references live in TV coordinates and survive a camera re-aim.
    • Every scheduled run first verifies the camera still sees the TV where calibration left it. A bumped camera now fails the watch with the live frame as evidence and fires the alert — never a silent pass again.
    • The camera check anchors on the panel’s surroundings, so it works whatever the TV happens to show; too little detail is reported as inconclusive rather than as a false alarm.
    • The condition inspector previews through the same rectified eye the checks use.
    v1.37.12026-07-08

    πŸ› Calibration status refreshes after the overlay closes

    • Polish from the first real remote calibration, on a set aimed from a thousand kilometres away: the device-edit forms now re-fetch the “calibrated” status the moment the calibration overlay closes, instead of showing the stale value until a reload.
    v1.37.02026-07-08

    ✨ Camera install calibration β€” aim every camera the same way

    • The fallen-camera incident’s systematic fix begins with a guided calibration flow: the TV shows a full-screen test card in its own browser, with no app install needed, and the installer aims the camera against ghost marker outlines over a live view, clicks the four marker centres and saves.
    • Every camera then frames its TV the same way, which is what makes check regions and reference frames transferable between sets.
    • Each set stores its camera-to-screen mapping and a “camera sees the TV” reference frame; the standing watch check hooks on next.
    • Admin-only, recorded in the log, and a set somebody is actively using refuses the card — a live session always wins.
    v1.36.12026-07-08

    🎨 Scenario tags are now clickable filters

    • Tags in the scenario library used to be decoration: the search box quietly matched them, but nothing told you.
    • Clicking a tag chip now filters the list and clicking it again clears, chips respond to hover and keyboard, and the search bar stays visible whenever the library has anything in it.
    v1.36.02026-07-08

    ✨ The condition inspector β€” tune checks against live camera evidence

    • Scenario checks stop being guesswork: open the inspector on any condition, see the live camera frame with the checked region outlined, drag the strictness knobs and press “test now” — pass or fail with the measured numbers, before the scenario ever runs.
    • Text checks expose the expected words, the region and the match strictness; image checks add content and position tolerance plus one-click capture of a new reference frame.
    • Everything writes back into the scenario code — the editor stays the source of truth.
    • The editor’s syntax colours are finally readable in the dark theme, and still right in light.
    v1.35.02026-07-08

    🎨 A lighter TV detail and Settings that read like a page, not a pile

    • The remote’s occasional tools — type text, launch an app — fold into one block, so the everyday controls stay put and the remote just loses a storey of rarely-used rows.
    • Expert tabs show only to the roles that use them, and the install and signing workflow finally gets the full screen width, with the certificate and signing cards side by side.
    • Settings regroup into four titled sections, and device health moved next to the device list where it belongs.
    v1.34.02026-07-08

    🎨 One scenario library β€” origin is a badge, not a section

    • Scenarios from recordings and scenarios written in the editor now live in one list, each row wearing a small badge saying where it came from.
    • A recorded one converts to a fully editable scenario in one click, which turns its key-track into a document and drops you straight into the editor.
    • One search, sort and team filter for everything.
    v1.33.02026-07-08

    🎨 Global navigation β€” every section one click away

    • The app’s sections now live in one persistent top bar with icon tabs, an active indicator and the familiar avatar, on every screen. No more bouncing off the dashboard to get anywhere.
    • Hover a section for a one-breath explanation of what lives there, and a red badge counts failing watches.
    • The dashboard puts your tasks first: failing watches and devices on top, charts folded into a collapsed section.
    • Deep screens keep a contextual back-crumb under the bar, and on phones the sections tuck into a bottom sheet.
    v1.32.02026-07-08

    🎨 A consistency pass β€” the UX audit's quick wins

    • A whole-app UX audit ran this week, and this release ships its first batch.
    • The alert webhook is now set in Settings instead of on the server, so device outages and failed watches reach your URL with no server access needed.
    • Watch schedules display and accept times in your own wall clock, so “daily 05:00” and “next 05:00” finally agree.
    • Search, sort and filter controls on short lists step aside until the list grows, and device and recording rows stop repeating the model name twice.
    • Old links work again, back-links name where they go, and the settings page no longer claims to be version 0.1.0.
    v1.31.02026-07-08

    ✨ Screenshot checks β€” "the screen looks like this", position included

    • Scenarios can now assert against a stored reference frame, not just text: capture what the screen should look like, and every run compares the live camera against it — content and position. A layout that slid twenty pixels down fails the check even when every word still matches.
    • Reference frames are captured straight off the live camera and stored with the scenario, so they version and die with it.
    • Two knobs per check — how different the pixels may be, and how far the region may move — and the failure report includes where the content actually was.
    • A camera quality change does not break checks, because frames are scale-normalised before comparing.
    • Also fixed: a tab reopened after your session expired now lands on the sign-in screen with an explanation, instead of a broken page.
    v1.30.02026-07-08

    ✨ Pick the app to launch β€” the TV tells you what's installed

    • The launch row and AI agents now ask the TV for its installed apps instead of you hand-typing internal ids: open the row, get a type-ahead list of names, pick, launch.
    • The list is read straight off the TV and parsed with a format written against a real 52-app capture — ids with dashes and non-ASCII titles included. It is cached per TV and refreshed on reconnect, and typing an id by hand keeps working even when the list cannot load.
    • Closing or restarting an app was probed on the real hardware and is not offered by this TV’s locked shell, so launching stays the one verb — now with none of the typing.
    v1.29.02026-07-07

    ✨ Launch an app on the TV β€” from the app and from AI agents

    • Start any installed app in one step: a launch row on the live remote, and a matching tool for AI agents. No more navigating the home menu to get an app on screen.
    • A progress message covers the multi-second round trip, and a failure shows the box’s actual error — including how to fix developer mode.
    • A malformed app id never leaves the browser, because the client mirrors the box’s own guard.
    v1.28.02026-07-07

    ✨ Type text on the TV β€” from the app and from AI agents

    • No more arrow-key hunt-and-peck on on-screen keyboards. The live remote gains a text-entry row that types straight into whatever field is focused on the TV, and AI agents get the matching tool — search boxes and login forms filled in one step.
    • Sending replaces the field’s content, and an empty send clears it. The hint under the field says so, and agents get the same semantics spelled out.
    • Typed text may be a credential: it is never logged anywhere, and the field is cleared when you switch TVs.
    v1.27.02026-07-07

    ✨ A monitoring screen β€” scenarios watch your TVs on a schedule

    • Scheduled scenarios now watch your apps, and a monitoring screen shows what happened: a card per watch with the last verdict, a colour-coded chip per TV, a filterable run history, and — for a failure — the camera frame from the exact moment a check failed.
    • A watch can target several TVs or a whole team, running them in parallel or one at a time, with an optional cleanup scenario between TVs.
    • Watch a whole team and new TVs join automatically. A busy TV is skipped, so a live session always wins, and a failing scheduled run alerts your webhook.
    v1.26.02026-07-07

    ✨ Runs remember themselves β€” and can run on a schedule

    • Every scenario run is now recorded: each step with its timing, every check with its measured match, and the final verdict.
    • Scenarios can also run unattended on a schedule — nightly at three, or every half hour — and a run that does not pass sends an alert.
    • A scheduled run never interrupts a person: if somebody is using the TV it steps aside, and records that it did.
    • AI agents got the full loop too: they can list, read, write and run scenarios, and get back pass or fail with what was expected versus what the screen actually said.
    v1.25.02026-07-07

    ✨ Scenarios can check the screen β€” and say PASS or FAIL

    • Until now a scenario replay was blind: it pressed the keys and a human watched the camera to judge the result. Scenarios can now assert what is actually on the TV — “the screen says Welcome” — through the real camera, with no changes to the app being tested.
    • A run finally ends with a verdict: pass, or fail with what the screen actually said.
    • Checks read the screen through the camera and match fuzzily, because camera frames are noisy: a tunable threshold decides, and the editor shows the measured similarity for every attempt.
    • The building blocks compose — a check with a timeout that polls until the screen settles, “press DOWN until the row appears”, branches on what is visible, and soft checks that record a miss without stopping the run.
    v1.24.02026-07-07

    ✨ A code editor for scenarios

    • Authored scenarios got their editor: syntax highlighting and autocomplete, opened straight from the Scenarios screen. One scenario, three interchangeable notations — switch tabs and nothing is lost.
    • Below the code sits a run console: pick a TV, run the scenario, and watch each step light up in the code with the exact wall-clock time it fired. Dry-run walks the steps without sending anything.
    • You can record straight into the editor: drive the TV from its live view in another window and the presses stream in as steps with their real pauses. Drag a wait value right in the code to retime it.
    • The typed notation is a literal — parsed, never executed — so an editor, a repository and an AI agent can all safely read and write the same scenario.
    v1.23.02026-07-07

    ✨ Scenarios become editable documents

    • Until now a scenario was whatever you happened to record. It can now be an authored document: a readable list of steps, stored on the server, validated against a published format, and run step by step onto any TV.
    • The format is deliberately simple data, not code — steps and bounded loops with a published schema — so editors and AI agents can safely read and write it.
    • Two new abilities arrive as steps and surface in the app next: typing whole text into the TV’s focused input, and launching an installed app by its id.
    • Anyone signed in can author scenarios; editing somebody else’s needs the author, an admin or a superadmin, and every save, run and delete is recorded.
    v1.22.02026-07-06

    πŸ› Release everywhere + multi-window awareness

    • Have the same TV’s live view open in three tabs and on your phone? The app now treats all of them as you: any window can drive the TV, the banner says you are using it in four windows, and Release means release — it frees the set from every window and session at once.
    • Releasing works by identity, not by the lucky tab that happened to grab control first.
    • After you release, open windows become viewers and never silently re-take the set on a reconnect; an explicit button brings it back when you want it.
    • Strangers are rejected exactly as before — this only unifies your own windows.
    v1.21.02026-07-06

    🎨 Burned exports draw the actual buttons

    • A downloaded QA clip no longer labels presses with plain text — it draws the remote’s buttons. The last few presses ride along the bottom of the picture as icon chips: the newest big and glowing in its category colour, older ones shrinking and fading to the left, so a reviewer sees the sequence rather than just the last press.
    • Nothing renders on the box: the chips are pre-made images composited in with per-press time windows, so a burn costs about what it did before.
    • Presses without a matching icon, and very long tracks, still burn as the plain-text labels — and both styles can share one clip.
    v1.20.02026-07-06

    ✨ Scenario library + running on several TVs at once

    • Kept recordings with key presses are now a first-class scenario library, and a scenario can replay on several TVs in parallel.
    • The new screen turns timestamps into readable test scripts — name them, tag them, search them — and runs one on any set of free TVs with a live progress row per TV.
    • The runner multi-selects eligible TVs, fires the replay on each in parallel, and shows per-TV step progress with stop-one or stop-all. Busy and offline sets are locked.
    • Running on several TVs takes several sessions, released automatically when the run ends.
    v1.19.02026-07-06

    ✨ OAuth click-to-connect for MCP

    • AI clients can now connect with a click instead of pasting a token. Screenwhere is its own authorization server: you sign in with your existing account and the connected app acts as you.
    • It is a front door onto your account, not a separate identity or a third-party login — a short-lived token that auto-refreshes and resolves to your account with your live role, so all the usual access rules and audit apply unchanged.
    • On the consent screen you choose read-only or read and control, and a read-only connection can look but never drive the TV, enforced on the server.
    • Settings lists what you have connected and lets you disconnect any of them; “sign out everywhere” drops them too.
    v1.18.02026-07-06

    ✨ MCP control tools β€” an agent can drive the TV

    • An AI agent can now control a TV: press remote keys, switch power, and replay recorded scenarios — each action as the user who drives it.
    • Each action runs as the holder of the set, taken automatically on a free TV or taken over by an admin. A regular user cannot wrest control from somebody else who is using it.
    • Nothing new is trusted: the server stays the single authority, the agent-facing layer holds no standing credential, and every key press, power switch and replay is recorded as the real user.
    v1.17.02026-07-06

    ✨ Personal access tokens + MCP server (read-only)

    • Groundwork for letting an AI agent drive your TVs: mint a personal access token and point a client at your sets to read state, health, recordings and statistics — each agent acting as the user who drives it, never more.
    • A token resolves to a user through the same live-role model as a session, so it cannot out-rank or outlive the user, and it is always filtered to what that user may see.
    • Minting requires a real web session, so a token cannot mint more tokens, and “sign out everywhere” revokes them.
    • The agent-facing server is a stateless façade that forwards your token onward — it holds no standing credential of its own.
    v1.16.02026-07-06

    ✨ Add debugging to any TV app (chii-inject)

    • The DevTools tab can now turn a customer’s app into a debuggable one: if the running app has no debug client, the box injects one into the app’s start page, re-signs the package with the site’s certificate and reinstalls it, then the DevTools attach as normal. The injected client self-activates on every boot, so it is a one-time step.
    • It is available to every user who can use the set, not just the superadmin: the pipeline runs on the box with the set’s stored certificates, so the user never handles certificate material.
    • The live pipeline is shown step by step — inject, repackage, sign, push, install, launch, connect — each with its status, and a plain-language reason and retry on failure.
    v1.15.32026-07-05

    πŸ› Plug polling rides out sleepy WiFi radios

    • A smart plug on weak WiFi can stall its first connection for seconds, and the agent’s flat four-second timeout killed exactly those requests — so energy polling failed and the log filled with an identical line every twenty seconds.
    • Plug calls now use a generous timeout plus one retry, and failure logging is rate-limited to one line on first failure, a summary at most every ten minutes, and a “recovered” line when the plug comes back.
    • The emergency power-cycle path gets the same hardening: the last-resort recovery must not fail just because the plug’s radio was asleep.
    v1.15.22026-07-05

    πŸ› Power gauge reads correctly in light mode

    • The live-power callout and gauge on the dashboard cards were tuned for dark mode — in light mode the callout was a dark blob and the gauge’s level dot vanished on the white card.
    • Both now adapt to the theme; dark mode is unchanged.
    v1.15.12026-07-05

    🎨 Dashboard recordings show the key-press count

    • Each recording in the dashboard’s per-device strip now shows how many buttons were pressed during it, matching the recordings grid. The number was already captured; this surfaces it on the dashboard too.
    v1.15.02026-07-05

    ✨ Generate the signing certificate on the box β€” no Certificate Manager

    • Screenwhere now mints the Samsung developer certificates itself, straight from Samsung’s certificate authority — the last manual step in getting an app onto a TV. The only thing left for a person is a one-time Samsung account sign-in. Proven end to end on the real office TV.
    • Sign in through a small helper, pick the privilege level and the TV identifiers, and press generate: the certificates are created and stored encrypted on the box, ready for the existing sign and install flows.
    • The box builds the keys and the request, has Samsung’s authority sign it, and assembles the bundle with the vendored chain. Private keys never leave the box.
    • Samsung locks the sign-in redirect to the local machine, so a thin operator-side helper captures the token and hands it over through a code-gated, single-use endpoint. The token is never stored or logged.
    v1.14.22026-07-04

    πŸ› Install staging file no longer piles up on the TV

    • The package we push to the TV to install it now reuses one stable filename that each install overwrites, so it never accumulates — instead of leaving a new file behind every time.
    • This TV’s shell is locked to app-management commands, with no remote file delete, so a timed cleanup is not possible; overwrite-reuse keeps the footprint to a single small file.
    v1.14.12026-07-04

    πŸ› App signing: the TV actually accepts our .wgt now

    • Our signature was cryptographically valid but every Samsung TV rejected it. Fixed, and verified on the real office TV — including re-signing another company’s app with our own certificate so that it installs.
    • The cause: the vendor’s own tooling stores the signature in a specific layout — newlines between elements, base64 wrapped at 76 columns, a compact properties object, no XML declaration — and signs over exactly that. We emitted compact XML, and the TV’s validator only accepts the vendor’s layout.
    • Our output is now byte-for-byte identical for the same content and certificate, so it is guaranteed installable. Unsigned and tampered packages are still correctly rejected.
    v1.14.02026-07-04

    ✨ Install onto the TV, straight from the app

    • The install tab now installs a signed app onto the Samsung TV over the box — no operator laptop in the loop — instead of only signing it for a manual install.
    • The box pushes the signed package to the TV, installs it and optionally launches it, reporting each step: connect, push, install, launch.
    • A device-identifier read-out hands you the value to enrol when generating the distributor certificate.
    • Superadmin-only and recorded, and it runs entirely on the box, which is a requirement of running this as a service for several tenants.
    v1.13.12026-07-04

    πŸ› App signing: match Tizen Studio's algorithms

    • Aligned the signer to what the vendor’s current tooling emits — SHA-512 digests, RSA-SHA512, exclusive canonicalisation — validated against two real reference packages.
    v1.13.02026-07-04

    ✨ App signing (Tizen .wgt) β€” get our app onto the TV

    • A new app-signing plane: sign a Tizen install package with the site’s own author and distributor certificates so a TV accepts it.
    • The signer runs on the box, and the certificates are stored encrypted at rest and never leave the site’s network. Private keys transit only in flight and are never stored in the cloud.
    • The endpoints are superadmin-only and recorded.
    v1.12.22026-07-03

    🎨 Dashboard power reading moved left of the bar

    • The live-power watt reading on the dashboard device cards now sits as a callout to the left of the gauge, matching the device grid.
    v1.12.12026-07-03

    🎨 Bigger, status-tinted TV thumbnail

    • The device list and dashboard device rows get a larger TV thumbnail, tinted by status.
    v1.12.02026-07-01

    🎨 Left-edge live-power gauge on device cards

    • The device cards’ power indicator is redesigned from a mini sparkline into a glowing left-edge gauge driven by live wattage.
    v1.11.02026-07-01

    🎨 Live-power sparkline on device cards

    • Device cards on the dashboard and the all-devices picker show a mini power trend from the smart plug’s live draw.
    v1.10.02026-07-01

    ✨ Energy: consumption history, cost & live power

    • Screenwhere now tracks the smart plugs’ energy itself — all local, nothing goes to the cloud.
    • A superadmin-only consumption and cost panel, and an on-demand live-power sparkline on the set detail.
    v1.9.02026-07-01

    ✨ Shelly plug goes live: emergency power-cycle

    • The emergency power-cycle — a hard restart of the TV’s wall socket through a Shelly plug — is verified on real hardware, with digest authentication.
    v1.8.22026-07-01

    🎨 ZÑznamy tab polish: author, durations, action icons

    • The set-detail recordings tab reads cleaner: your own recordings no longer repeat your name on every row, and a teammate’s clip gets a colour-coded dot and name so it stands out.
    • Tidier durations — a whole minute drops its trailing zero seconds — and the play and scenario actions got proper icons with a unified hover.
    • The per-session recording pill on the camera stage is now top-aligned with the fullscreen button.
    v1.8.12026-06-30

    🎨 Loading skeletons on ZaΕ™Γ­zenΓ­ + ZΓ‘znamy

    • The device list and the recordings overview now show themed shimmer placeholders while they load, matching the dashboard — so opening them reads as “loading” instead of looking frozen.
    • The skeleton pieces are shared across all three screens, and reduced-motion is respected.
    v1.8.02026-06-30

    ✨ Per-session recording control + a faster Dashboard

    • Recording can be turned on and off per session on the live screen, on top of the set’s own recording setting — and turning it off mid-session offers to keep the clip, delete it, or carry on recording.
    • The dashboard loads with a skeleton, never flashes the device list, and re-opens instantly from a cache that refreshes behind it, chart selection preserved.
    • Camera on networks that block UDP: the stream can now relay over TCP where UDP is blocked.
    v1.7.02026-06-30

    πŸ› Set-detail ZΓ‘znamy tab UX (+ live-camera WebRTC fix)

    • The recordings tab on the live detail loads reliably now — a race on deep links is fixed — plays through the review player with the camera staying live, and both in-app and browser Back return to the detail.
    • A real live-camera fix: the media server was advertising the loopback address as its connection candidate, so media never reached the browser. It is now bound to the public address, and a failure says plainly that the network may be blocking the stream.
    v1.6.02026-06-29

    🎨 Set-detail UX review pass

    • The screen-by-screen review reaches the live set detail: the remote collapses to icon-only below 340 pixels so labels never spill the camera-resized column, with a tooltip on every key.
    • A performance win: the per-frame blur behind the live video is gone.
    • Plus plane-editor fixes — edit-handle clipping, click-outside to close, and the name shown only in edit mode.
    v1.5.02026-06-29

    🎨 Picker UX review pass

    • The review reaches the device picker: you can now edit a device without connecting to it, and release a held device straight from the picker.
    • A field selector, an ascending/descending sort toggle, and cross-screen card unification with a shared TV thumbnail and system ribbon.
    v1.4.02026-06-29

    πŸ› Dashboard UX review pass

    • The review reaches the dashboard, and it turned up two real bugs: a helper that recursed and crashed every set detail since the previous release, and a recording duration reading “3274 min”.
    • Polish alongside: Czech plurals, a single source for the version number, crisp chart labels, a redesigned most-used panel, and a coloured live-bandwidth gauge.
    v1.3.02026-06-29

    πŸ§ͺ DOM-heavy web typing

    • The type-checking pass finishes on the browser code, and the type checker earned its keep.
    • Every web module is now checked in CI — and the checker surfaced four real latent bugs, all from one shadowed translation helper.
    v1.2.02026-06-29

    βš™οΈ Deep relay split

    • The 1.9-thousand-line server file is broken into thirteen focused modules: a thin bootstrap of ninety-two lines wires them together, with shared state mutated in place.
    • Behaviour-identical, verified step by step against the test suite and the type checker.
    v1.1.02026-06-29

    πŸ§ͺ Quality pass: tests, security, types & CI

    • Prove it works, harden the public server, and stop the bug class at the source — without a rewrite.
    • A one-command test suite grew to twenty-four groups and 462 assertions, six security findings were fixed, and dev-only type checking arrived.
    • Continuous integration runs on every push and pull request. The architecture review’s verdict: keep the lean stack, no rewrite.
    v1.0.02026-06-28

    πŸ“ First documented release

    • Everything that was built is now written down — and versioned.
    • Restructured documentation, this visual site, the full changelog, and an in-app “what’s new” link, plus a retroactive version history and tags.
    • No behavioural change: this release is about being understandable.
    v0.12.02026-06-28

    ✨ Hardening & polish batch

    • Manual network-address entry, a burned-in QA video export, and a superadmin-only live bandwidth panel.
    • Safer installs: provisioning is safe to re-run, and caching headers mean no stale assets after a deploy.
    v0.11.02026-06-27

    ✨ Dashboard (PΕ™ehled)

    • A glanceable home with favourites, recent recordings and usage charts, and it is now the default landing screen.
    • Real charts behind it, clean English addresses, and controller authentication that needs no token.
    v0.10.02026-06-26

    ✨ Bilingual (cs/en)

    • The whole app speaks Czech and English, switchable live with no reload.
    v0.9.02026-06-26

    ✨ Recording, replay & storage

    • Record a session and replay the exact key presses onto a live TV, with a synchronised key-track and a review player.
    • Storage stays in check: a per-user quota and disk-reserve eviction, which never touches a clip you have marked to keep.
    v0.8.02026-06-25

    ✨ Audit, health, power & on-demand camera

    • A trustworthy log, offline alerts and a remote power-cycle: a structured audit trail with usage statistics, device health, and a hard restart of a TV’s wall socket.
    • And a camera that only streams while somebody is watching, with a two-minute linger — the fix for bandwidth once there are twenty sets.
    v0.7.02026-06-25

    πŸ”’ Authentication hardening

    • Real, tamper-proof logins: server-minted session tokens carrying an unforgeable role, properly hashed passwords, two-factor authentication for everyone, and thirty-day device trust.
    v0.6.02026-06-25

    ✨ LAN discovery, MAC identity & smart power

    • Find devices on the network, follow them by their hardware address, and switch a TV’s power with one button.
    • The registry is keyed by hardware address rather than by network address, and the box on site heals itself when a camera’s address drifts.
    v0.5.02026-06-24

    ✨ Device registry write API

    • Devices can be added and edited from the app, with the box on site configured from the cloud.
    v0.4.02026-06-23

    ✨ Teams, accounts & takeover

    • Shared access through teams, real accounts, and a graceful hand-over when somebody else wants the television.
    • Team access is enforced on the server, including the gate in front of the video, and the Raspberry Pi build is documented as built.
    v0.3.02026-06-22

    🎨 The product UI

    • The app gets its real look and is wired to the live system.
    • A design-system prototype first, then the real web application wired to the live camera, the control plane and the debugging plane.
    v0.2.02026-06-20

    ✨ Multiple sets & provisioning

    • Run many televisions from one app and one box per site.
    • The camera push folded into the site agent, a token per set, a registry with a picker in the web app, and one service instance per set.
    v0.1.02026-06-19

    ✨ Proof of concept + one-set MVP

    • Control a television on a foreign network, with live video and debugging, from anywhere.
    • The cloud control relay, and one set with a live camera, a remote pad and a DevTools deep link. Verified from a phone on cellular.