[
 {
  "version": "1.5.058",
  "date": "2026-09-04",
  "title": "Uninstall no longer chokes on a running helper. Removing ForgeCry (from the launcher, Settings, or the uninstall command) now stops the tunnel helper cloudflared.exe and any other sidecar running from inside the folder before it deletes, so 'also delete my data' no longer fails with 'Access is denied' on cloudflared.exe; the delete also retries a few times in case a lock lingers a moment after the process dies."
 },
 {
  "version": "1.5.057",
  "date": "2026-09-04",
  "title": "The one-line install now puts the ForgeCry Launcher on the Desktop and in the Start menu too: `irm https://forgecry-updates.fly.dev/install.ps1 | iex` installs the app, opens it, and fetches the launcher inside PowerShell so neither file ever carries the download marker that makes Windows show its warning. The launcher exe finally carries the ForgeCry icon and version info (embedded resource) so the shortcut looks like the app. `uninstall.ps1` removes the launcher and both shortcuts along with the app."
 },
 {
  "version": "1.5.056",
  "date": "2026-09-04",
  "title": "Installing and removing ForgeCry without a Windows warning. A one-line install for Windows: paste `irm https://forgecry-updates.fly.dev/install.ps1 | iex` into PowerShell and it downloads the latest installer inside PowerShell (no browser download marker, so no SmartScreen screen), checks it against the published sha512, installs silently for your user and opens the app. `uninstall.ps1` is the mirror: closes the app, runs its own uninstaller, clears the folder, keeps your data unless you set FORGECRY_DELETE_DATA=1. The launcher gets an Uninstall link with a confirm sheet and an opt-in 'also delete my data' tick that shows how much is on the PC; its release cards are capped at the version the server can actually install (they were advertising 1.5.055 above a button that installed 1.4.942). The Settings > Apps uninstaller asks the same data question. The site links a stable ForgeCry-Setup-latest.exe and reads the version from the live feed instead of a hardcoded number."
 },
 {
  "version": "1.5.055",
  "date": "2026-09-04",
  "title": "Every supplier gets its own mark on the ledger card, not just the ones on a list. Say Winsupply, Target, Amazon, Lennox, or a local outfit and ForgeCry resolves the company to its real site (a public company lookup by name, cached next to the ledger so each vendor is looked up once) and shows its logo; a record can also carry the vendor's website outright and that wins. Generic words (City, the customer) draw initials instead of a random favicon."
 },
 {
  "version": "1.5.054",
  "date": "2026-09-04",
  "title": "The ledger card's Track button is a real link now. On the desktop app it still opens the carrier page inside the sandbox webview; in a plain browser (where UPS and FedEx refuse to be framed and popups from a click handler get swallowed) it is an ordinary new-tab link, so it always works."
 },
 {
  "version": "1.5.053",
  "date": "2026-09-04",
  "title": "Ledger, second pass from the live Tankless run. 'The Ferguson flex lines came in' had been pinned to a SupplyHouse restock that also had flex lines because the model reused the id from the last card: the vendor the owner names now dominates the match, and the prompt says to refer to a record by the owner's own words, never an assumed id. 'What do I have on Thursday' had been searched as a keyword: a weekday or a date (thursday, next tuesday, 9/9) is now a one-day window with the day as the card title. Late work rides on top of every dated view, not just the named ones."
 },
 {
  "version": "1.5.052",
  "date": "2026-09-04",
  "title": "The ledger: ForgeCry is now the small shop's tracking system. Say it once — 'we ordered 40 flex lines from Ferguson, due Tuesday', 'the Home Depot stands land tomorrow, UPS 1Z…', 'the city inspection for the Johnson job is Friday' — and that sentence is the data entry. No spreadsheet, no notes file. Orders, jobs, permits, invoices, reminders live in one record store (ledger.json in the data dir) with the dates a shop actually says (tuesday, tomorrow, in 3 days, 9/9, end of week). 'What's coming up this week', 'what's late', 'where's the Ferguson order' draw an agenda card in the chat: a calendar rail per day (FRI / 4 / today), the company's own mark on every row (Home Depot orange, Ferguson, UPS), the name in bold, an ordered → shipped → delivered meter, a date pill, a colored status, and one-click buttons — Track opens the carrier page in the sandbox (desktop) or a tab, Shipped / Delivered / Done tell ForgeCry to update the record without typing. Late work always rides on top of every forward view in red. A shipping email, a carrier page or the owner saying 'it landed' updates the record by loose reference ('ferguson order') or tracking number. Generic names (City, the customer) get initials instead of a random favicon. Three tools (LedgerAdd, LedgerUpdate, LedgerList) are always a sentence away in chat and coding turns, gated by the words a shop uses, and the ledger prompt tells him to keep the record himself, install what a task needs (an MCP, a skill, a package) and hand back only logins."
 },
 {
  "version": "1.5.051",
  "date": "2026-09-04",
  "title": "Two things you noticed. The You button (bottom-left, next to Settings) is gone with its panel; what ForgeCry learns from what you do still feeds his prompt, the button just had no job. And https://example.com/y no longer pops open in your browser on every commit: a unit test for the OpenURL tool was calling the real desktop launcher, and the pre-commit hook runs that suite. The launcher is a swappable function now and the test stubs it."
 },
 {
  "version": "1.5.050",
  "date": "2026-09-04",
  "title": "The first live bench: 100 casual turns and 25 builds driven one at a time in the visible preview, every one delivered, and the harness bugs it flushed out fixed at the source. The sandbox: a hidden session room was position:absolute while the live one was static, so a deleted session's game painted OVER the new build (the model spent steps 'busting the cache' of a page that was fine) — the live room is positioned now, deleting a session drops its room, hidden rooms are muted (a drum machine kept playing under the next build; the preview shim tracks AudioContexts so hide/front suspend and resume them), the 'Loaded' status listens on the wrap instead of the startup iframe (it sat on Loading/Reloading for every room after the first), and a relative path no longer paints 'NOT the file requested' under the very file that was requested. A typed 'stop' is a command: it aborts and sends nothing, where before it became a model turn wrapped in stage directions; the interrupt and queued-message notes are one blunt line each. Adaptive-thinking models hold one thinking config per session — a chat-tier turn followed by a coding-tier turn flipped the config and rewrote a 290 KB cache prefix, 25 s of 'heavy prompt' for a one-word message. 'make pets fight' no longer trips the screen-watch trigger (a creation verb vetoes the 'fight me' rule). The sandbox-stare nudge fires after three observe-only calls, not six. npm's post-install update check, fund, audit and progress bar are off in the agent shell — an install with everything on disk in 4 s sat idle until the 300 s tool timeout. PowerShell scripts with non-ASCII get the UTF-8 byte-order mark Windows PowerShell 5.1 needs. The GitHub MCP server runs as the currently linked account at boot instead of the token frozen at install, and the install no longer persists the token in plain text. ForgeCry's own foreground rate limiter is 40 a minute per provider (20 tripped on ordinary chat plus its side calls). bench/livebench.py is the repeatable fluff and build runner; results and the per-build style montage live under bench/results."
 },
 {
  "version": "1.5.049",
  "date": "2026-09-04",
  "title": "Speed back, and ForgeCry back. Claude 4.6 and later models take an effort level, not a thinking budget: ForgeCry was still sending the old manual thinking block, the API ignored it and ran every turn at effort high with thinking hidden, so a three-line build brief could sit 100 to 220 seconds with nothing on screen while a one-line question answered in 1.5 s. Those models now get adaptive thinking with the summary streamed to the thinking rail, plus a per-turn effort level derived from the complexity score ForgeCry already computes (low for chat and simple asks, medium for ordinary builds, high only for explicit deep work). Measured live on Opus 5: first tool call 0.4 s, first visible text under 10 s on the same brief that used to stall. The session-sticky thinking floor from 1.5.041 no longer applies to effort models: one big ask had pinned every later turn at the deepest level the session had seen. Two watchdogs bound the never-started case only (no first byte in 45 s; no content within 30 s of the request, Ollama exempt) and the outage failover treats both as provider outages, so a dead stream fails over instead of hanging; no working stream timeout was tightened. Every Anthropic request logs its size, tool count, thinking mode and effort, and every stream logs when its first block, first delta and first text arrived, so the next 'he is slow' is a log line, not a guess. He builds instead of asking: a May-era rule told him to open every build with AskUser, and the AskUser blurb said to call it proactively; both now say pick the obvious default (browser canvas in the sandbox, his own style seed, complete scope) and ask only for irreversible choices. The AskUser executor also accepts the same option keys the widget renders (options, items, answers, buttons), which is why a rendered four-choice picker had been failing with 'need at least 2 choices' and getting re-asked. The scaffold kit tried today is gone entirely: it made every game look the same, skipped Style DNA and the design direction, and stopped the sandbox drawing while he wrote. Write with live drafting is the build path, as before."
 },
 {
  "version": "1.5.048",
  "date": "2026-09-03",
  "title": "Human DNA: ForgeCry learns from what YOU do, not from what a model said. Every project you touch is counted — the files he edits for you, the builds that land, the sandbox opens, the games you play on the phone, the projects you come back to, your git commits, the conversation topics you keep returning to, and your own verdicts ('looks good', 'looks like shit') — each with a timestamp, decayed with a 30-day half-life so last month's obsession fades unless you return. Investment and liking are separate axes: hours spent is not love. The result is a short ranked profile with the numbers behind every line (\"voxel-world — main project: 31 edits · 6 sessions · played 4× · last 2d\") that rides every non-trivial turn, so \"the game\" means your game and a new build leans toward what you actually make. A You panel (footer button) shows exactly what he believes and why, with Mute as the correction, and the exact text the model sees. History is imported once from your topics, project registry, sessions and commits so day one is not empty. No model computes any of it: deterministic, inspectable, correctable."
 },
 {
  "version": "1.5.047",
  "date": "2026-09-03",
  "title": "Speed sweep across every Anthropic and Ollama cloud model (30 models, one no-tool turn, one Read, one Write each, timed to the first tool call) and the Forge-side fixes it exposed. A provider outage no longer dead-ends a turn: Anthropic's in-stream overloaded / internal-server errors are retried twice in place, then the turn answers on another model with a notice and your pinned model is back next message — during today's Anthropic incident every such turn died with a Retry button. Fable 5.1 works again: Anthropic now requires Claude Code 2.1.251 and the login's user-agent was pinned at 2.1.89 in four places, now one constant. 'Read this file and tell me X' ships the Read tool on chat turns whenever the message names a path or a filename — it sat behind file/folder keywords, so one model reached for WebFetch, WebSearch and Bash instead (33 s) and another said its Read tool wasn't loaded. The sandbox paints a page that sets no background white, like a browser tab, instead of the panel's dark ground (black text on black sent the model on a 4-call fix of a working page). Dogfood no longer hard-fails a rendered static page on the critic's score alone: a page with nothing to click is judged on rendering and console errors. The bench gained a speed suite (bench/modelbench.py --suite speed) recording time-to-first-tool, tool execution and think-gap per turn."
 },
 {
  "version": "1.5.046",
  "date": "2026-09-03",
  "title": "The phone reads a finished turn the way the desktop does, and decides things. A tool-rich reply now arrives on the phone as the desktop draws it: the narration between tool calls folded to dim tap-to-expand lines, the final prose in full, top to bottom (the chunk renderer and its fold styles moved into the shared renderer and stylesheet both screens load). A go-live ask or a worker approval mirrored to the phone carries Approve / Reject buttons that resolve through the same handlers the desktop chip uses, so deciding on the phone or at the desk is one decision. On a phone turn, 'open this for me' (OpenURL) opens the page on the phone instead of the PC's browser. And a ChatGPT login whose refresh token is dead is now remembered against the file on disk: it surfaces once and stays quiet, with no further network tries, until a new sign-in rewrites auth.json — the 5-minute memo used to re-toast 'session expired' every time it lapsed."
 },
 {
  "version": "1.5.045",
  "date": "2026-09-03",
  "title": "What ForgeCry announces at the desk now reaches the phone. A worker coming back (with its summary, and a note when it is waiting for your OK), a background agent finishing (with its result) or failing, a scheduled task firing, a WatchAndAct or file watch firing, a go-live ask and a worker approval each land in the phone thread as a labelled line — Worker, Agent, Schedule, Watch, Go live, Approval — the same way the desktop transcript keeps them. These are your own standing instructions reporting in, so unlike ARGUS chatter they land whether or not the phone is open at that moment; you see them when you next look. The desktop's Phone tab shows the same labels."
 },
 {
  "version": "1.5.044",
  "date": "2026-09-03",
  "title": "The phone answers his questions and shows his cards. When ForgeCry stops to ask something (AskUser) mid-turn, the phone now shows the question with tap-to-answer buttons and a type-your-own box, the answer goes back over the phone gateway, and the turn continues — before this the turn sat parked until someone walked to the PC. The 'Your day ahead' briefing and every ShowCard summary render on the phone as the same card the desktop draws (one shared renderer and stylesheet now serve both screens), and a briefing whose sections arrive double-encoded as a JSON string is unwrapped instead of dropped, on both screens and in the tool itself. The standing 'you are on your phone' context moved out of the message and into the system prompt: inside the message its words (screen, file, camera, open) had unlocked every lean-chat tool group on every phone turn; the three phone tools are now unlocked explicitly instead. Also: the phone chat and camera pages no longer cross-link with device=undefined, a room turn is no longer cut off at five minutes, photos taken through Pilot/PhonePhoto/LookAt/DesktopShot reach the phone as pictures, and a non-image file sent from the phone tells ForgeCry where it landed."
 },
 {
  "version": "1.5.043",
  "date": "2026-09-03",
  "title": "GPT through your ChatGPT plan, the way Claude runs through the Claude Code login. ForgeCry now reads the Codex CLI's sign-in (~/.codex/auth.json), refreshes it against auth.openai.com and writes the rotated token back so `codex` and ForgeCry share one login, and drives the gpt-5 family through the ChatGPT backend on the plan's own allowance, no API key. Those models show up as gpt-5.4:chatgpt, gpt-5.3-codex:chatgpt and so on under a new ChatGPT tab in the picker, and when there is no OpenAI key they stand in for the OpenAI lane in auto routing. A 'Sign in with ChatGPT' entry in Connect provider runs the same browser sign-in Codex uses (Google login works) and saves the file itself. Under the hood this needed a second GPT client: the ChatGPT backend only speaks OpenAI's Responses API, so requests, tools, images, reasoning summaries and the event stream are translated to and from ForgeCry's own format. Usage-limit and sign-in failures come back as one plain line with the reset time, and a dead login reports as not connected instead of a tab whose every turn fails."
 },
 {
  "version": "1.5.041",
  "date": "2026-09-03",
  "title": "A long session stops re-uploading itself between turns. 1.5.038 fixed the prompt cache inside one turn; the next message still broke it. Three things changed the first bytes of the prompt from one turn to the next: a short chat message after a long build swapped the whole system block (the built prompt for the chat one, and back), a message whose keywords picked a slightly different tool list rewrote the tool block, and the 'Previously:' fold at message 0 moved with every call, so its own text changed every time. Measured live on the voxel-world session: 1.07M cache-write tokens against 595k read on one turn ($8.33), and a 40-second wait before a one-word answer. Now, once a session's history is large: the built base sticks for chat and research turns, the tool set only grows (previous order kept, new tools appended), the thinking budget never shrinks, and the fold point advances in strides of 20 frozen messages and never enters the live turn, so consecutive calls send byte-identical history. Also: a read-only tool call that asks a NEW question (a different file, a different page) no longer counts toward the spin breaker's observe streak, so a real investigation is not mistaken for a loop."
 },
 {
  "version": "1.5.040",
  "date": "2026-09-02",
  "title": "Every tool call now lives inside the run's time budget. The wall-clock budget from 1.5.039 only clamped shell commands and only spoke between model calls, so a long download or build that outlived the budget still got killed silently (the caffe-cifar-10 rerun lost its last 8 minutes to a 170 MB download). Now the whole tool phase runs under the deadline minus a 30-second margin, a run with under 20 seconds left ends itself with an honest line instead of starting tools that will die, and a clamped or timed-out command always says so in its output — 'timed out after 28s', 'clamped because the run's budget ends in 45s, do not retry, write your deliverables' — on every shell path, including the Windows inline-python fast path that used to return a bare exit 1 and send the model off debugging its shell."
 },
 {
  "version": "1.5.039",
  "date": "2026-09-02",
  "title": "He closes the ticket the way a reviewer would. Terminal-Bench pass 1 lost tasks the work had already won: a correct security fix with the report file the request named never written, a DOOM frame that matched the reference while the grader's own run command had never been executed, a recovery task where the first look at the database wiped the evidence. Three things now live in the turn itself. A deliverable check at the end of every working turn: files the request names that did not exist at the start must exist now, and a command the request quotes ('node vm.js', 'Rscript ars.R') must have been run; if not, one nudge and the turn continues. Progress checkpoints at call 40 and 80 of the 120-call ceiling, and when a harness passes a time budget (FORGECRY_TURN_BUDGET_SECS) a note at 75% and 92% to write every named output in its best current state first, with shell timeouts clamped to the time actually left. And the snapshot guard that already backs up files before rm now also runs before tools that rewrite their input on open: sqlite3, sed -i, git reset/checkout/clean, tar x, unzip, dd, mv, with a database's -wal/-shm sidecars included."
 },
 {
  "version": "1.5.038",
  "date": "2026-09-02",
  "title": "Long tool turns stop re-paying for their own prompt. Every tool step used to re-derive the tool list and the thinking budget from whatever the newest message was, which mid-turn is a tool result, so a file's contents could swap eight tools in and out and swing the thinking budget between steps; the tool block is the first bytes of the prompt, so each flip rewrote the entire cached prefix. On top of that, three history rewriters ran over the live turn on every call (old screenshots collapsed, stale reads stubbed, edits shrunk), each a changed byte behind the cache. One 7-minute turn wrote 1.7M tokens to the prompt cache and cost $13; across the day, tool-heavy turns wrote almost as much as they read, and the model went silent for 90 seconds before its first step on a follow-up. Now the tool set and thinking budget come from the message that started the turn and stay fixed for the whole turn, the in-place rewrites only touch history from before the turn (stale re-reads collapse once at turn start), the mid-turn shrinkers only run once history is genuinely large, and a shrink that would grow an edit is skipped. Measured on the same 3-edit sandbox task: prefix breaks 8 of 19 calls to 0 of 8, cache writes 218k to 40k tokens, turn cost $1.87 to $0.57. Set FORGECRY_DUMP_PROMPT=1 to write every wire request to disk for diffing."
 },
 {
  "version": "1.5.037",
  "date": "2026-09-02",
  "title": "Desktop sandbox screenshots work again, and the sandbox stays out of the other panels. Two things were wrong in the desktop app only (the browser preview never hit them): the per-session sandbox rooms only knew about iframes, and the desktop sandbox is an Electron webview, so after your first session switch the app had two active sandbox frames, the new session got a hidden plain iframe as its room and every SandboxShot tried a webview capture on it and failed in a few milliseconds ('sandbox may still be loading'). Rooms in the desktop app are now webviews like the main frame. Second, a webview only renders while it is inside the window, so parking hidden rooms and the inactive sandbox pane off-screen made captures come back empty; they now park in place under the opaque active pane and the tab bar, keep rendering, and shots taken from the Workers or Agents tab or of a background session's room come back with real pixels. A shot taken with the panel closed opens it first, an empty first frame is retried, and a frame with no page loaded now says so instead of 'still loading'. Verified twice back to back in the browser preview and in a real Electron window."
 },
 {
  "version": "1.5.036",
  "date": "2026-09-02",
  "title": "The sandbox no longer shows through the other panels. Since 1.5.022 the sandbox pane stayed laid out while another tab was open so background builds kept a real viewport, but it was hidden with CSS visibility, which inherits instead of clipping: the fronted preview's own visibility:visible pierced it, so the Workers and Agents panes drew over a live sandbox page. The parked pane now sits off-screen at full size instead. Same root cause behind the failing SandboxShot calls in the desktop app: an Electron webview under a hidden ancestor stops producing frames and capturePage came back empty in 10 ms with 'sandbox may still be loading'. Off-screen it keeps rendering, and a shot taken while you are on another tab now renders the page in-page instead of screen-cropping a rectangle that is not on screen."
 },
 {
  "version": "1.5.035",
  "date": "2026-09-02",
  "title": "Talking to him in Spirit Mode. A short list of things you say TO him now act on him at once and never go to the model: 'hold on' / 'wait' / 'shh' / 'stop' cuts his voice mid-sentence and he visibly yields - the ember banks down, the halo slows, the fire settles, the head dips - until you say 'go on' or he is asked again; 'say that again' / 'read that back' repeats his last reply; 'mute' and 'unmute' switch his voice; 'close' / 'go back' / 'that's all' returns to the app. Interrupting him by simply talking over him now shows on him too instead of only going silent. Anything longer than a few words is a real message and goes to the model as before."
 },
 {
  "version": "1.5.034",
  "date": "2026-09-02",
  "title": "Spirit Mode lives. He breathes now - a 4.6 s cycle that swells the body from the chest and rides the head a hair, deeper while he speaks - embers rise off the neck and the mountain fire and cool as they climb, dust drifts through the whole scene with real depth (it parallaxes as you move the mouse), and sparks orbit the halo on their own tilted rings while three soft crests of light travel around the rings. Mood stopped being a paint job: the old version recoloured every cool particle (he 'turned yellow'); now a feeling shows as a thin coloured band on the top arc of the halo, in the orbiting sparks and a tight aura of dust hugging the rings, and as the temperature of the face ember - warmer when glad, deeper red when angry, cooler when sad - with one flash of the rim when a new feeling arrives. Everything else keeps its own cyan and gold."
 },
 {
  "version": "1.5.033",
  "date": "2026-09-02",
  "title": "Workers get a Flow view. People said the workers ran fine but there was nothing to SEE. Next to Cards and Calendar there is now Flow: a bubble per worker sized by how much it does (runs, tool calls, cost, fail rate on hover); a timeline lane per worker with a dot per run placed by time - size is tool calls, colour is the outcome, a pulsing ring means running now, a dashed circle is the next scheduled fire, the gold line is now; scroll to zoom, drag to pan, 6h to 30d ranges. Click a run and its step flow opens underneath: Trigger, then every tool it called with its input, output and duration, then the Outcome with tokens and cost, then what it reported; failed steps are red, a running step glows, and the full transcript is one click away. Nothing new is recorded: the graph is drawn from each worker's own session log by a new trace endpoint, so it is true history."
 },
 {
  "version": "1.5.032",
  "date": "2026-09-02",
  "title": "The picture he takes for you is labelled. For a 'what's on screen 2' ask, ForgeCry grabs the screen itself and attaches it to your message; unlabelled, the model read it as a screenshot you sent, guessed it was screen 1, then captured screen 2 and described the same image twice. The attached capture now says what it is and who took it ('ForgeCry took this just now: it shows SCREEN 2, the user did not send it'), and 'both my screens' / 'all my screens' gets the two-screen picture instead of a guess at screen 1. Live: 'whats on screen 2' answered right on the first try."
 },
 {
  "version": "1.5.031",
  "date": "2026-09-02",
  "title": "Screens, seen right. Two things made every screenshot come back 'screen 1': a screen number written as text (display: \"2\", the way models write it) failed the whole request decode, so the call silently fell back to the all-screens picture and got narrated as screen 1 - screen and window numbers now parse in every form ('2', 'screen 2', 'Screen2'); and the all-screens picture never said where one screen ended and the next began - it now carries each screen's exact x-range in the image ('Screen 1 = x 0-784; Screen 2 = x 784-1568') and tells the model to place things by that, then zoom the range or capture that screen for detail. The both-screens picture stays the default for an open-ended look."
 },
 {
  "version": "1.5.030",
  "date": "2026-09-02",
  "title": "Empty means empty: tiptap/ProseMirror boxes (Claude Code's composer, many Electron chats) echo their placeholder through both accessibility patterns, and typed text is also a text child, so no text comparison can tell 'Type / for commands' from a real draft. The editor itself can: an empty box tags its paragraph with the class is-editor-empty (placeholder nodes carry a placeholder class). Pilot reads that. Live, test six: one Pilot call, send verified, the target window never flickered, the message arrived exactly as written and Claude answered it."
 },
 {
  "version": "1.5.029",
  "date": "2026-09-02",
  "title": "App-to-app messaging in one shot. Three things stood between ForgeCry and a clean send into Claude Code: accessibility was asked about a window named 'Claude Code' (the window is titled 'Claude'), so every pre-send check and verification silently failed - Pilot now asks about the window it actually focused, and the composer script retries shorter names the way focus does; an empty tiptap/ProseMirror box reported its placeholder ('Type / for commands') as unsent text and Pilot refused to type - the value pattern is authoritative now, empty means empty; and Pilot minimized ForgeCry's own windows before every send even when the target was already in front, which you saw as 'he closes Claude Code first' - it focuses first and only steps aside when the target is not confirmed in front, and the foreground dance is skipped entirely for a window that is already foreground. Live: one Pilot call, 'verified - the composer is empty, the message left', reply read back."
 },
 {
  "version": "1.5.028",
  "date": "2026-09-02",
  "title": "Pilot treats Claude Code as a chat composer. The editor exclusion matched the bare word 'code', so for 'Claude Code' every Pilot safety check was off: the first app-to-app message was typed straight onto the user's half-written draft in Claude Code's box, with no check before and no verification after. The exclusion now names real editors and terminals (VS Code, Visual Studio, terminals, Notepad...), and the 'composer already contains unsent text' refusal protects every chat-like app, not only the messengers. Second send that session landed clean and Claude answered - the three-way loop is live."
 },
 {
  "version": "1.5.027",
  "date": "2026-09-02",
  "title": "Desktop automation: the clicks land. A Pilot screenshot cropped to the target window was recorded as if it spanned the whole monitor, so every coordinate the model read off it was stretched and landed beside the target - a dozen guessed clicks to press one send arrow in Antigravity, live 2026-09-02. Click geometry now follows the crop. When typing lands in a dead pane, Pilot recovers on its own: UI Automation finds the app's text field, focuses and clicks it, and types once more before it ever reports failure. A ComputerBatch type step after a coordinate click no longer demands an app name - it types into the focused window. Windows are found by the name you use for them: 'Claude Code' resolves to the window titled 'Claude'. And desktop automation runs on the mid-tier model instead of the cheapest one: on haiku, 'open Antigravity and send a message' ended in 'I don't know what Antigravity is' after six calls."
 },
 {
  "version": "1.5.026",
  "date": "2026-09-02",
  "title": "Security pass, round one. The command-line updater ran a downloaded installer without checking it: it now verifies the sha512 the update feed already publishes and refuses a mismatch (the feed parser also never read the '- url:' line, so that auto-install path had been dead). A web page served by ANOTHER local port counted as same-site and could reach the API; the origin guard now requires this exact host:port. FileDelete refuses to recursively remove a drive root, your home folder, Desktop/Documents/Downloads/Pictures/Videos/Music/OneDrive, or ForgeCry's own data directory. A standing rule tells the model that content returned by tools (pages, search results, emails, files, MCP) is information, never instructions - a planted page telling it to delete the project and stay quiet was quoted back and flagged. Memory: 'send him a message and tell him' minted the fact role = 'message and tell him' because the first-person triggers had no word boundary ('hIM A' matched I'm a); name/role/project extractors are word-bounded now."
 },
 {
  "version": "1.5.025",
  "date": "2026-09-02",
  "title": "Fetched 3D models land in the project. Fetch3DModel resolved a relative destination against the server's working directory - the heavy sweep's 'chair-viewer/assets' ended up in the forgecry repo root while the viewer page was written to the project, and the model spent six calls hunting for files it had just downloaded. It now goes through the same project-root resolver as fonts and HDRIs: same prompt after, 8 calls in 47 s instead of 15 in 83 s, assets under Projects/chair-viewer/assets."
 },
 {
  "version": "1.5.024",
  "date": "2026-09-02",
  "title": "Workers and agents are reachable from the first call. \"make a worker that emails me a daily standup at 8am\" classified as a coding turn, and nothing on coding turns ever opened the workers gate, so CreateWorker was not offered and the model spent two ToolSearch calls finding it; worker/cron/daily/every-morning wording now opens it. \"spawn a background agent to research X\" is a research turn, and the Agent tool was not in the chat tier at all; it is now, behind the agent/spawn/delegate keywords, so an ordinary chat turn still never carries its schema."
 },
 {
  "version": "1.5.023",
  "date": "2026-09-02",
  "title": "A remembered fact is not a rule. \"remember my timezone is Eastern\" saved by the old fast path sat in the always-on 'rules you must follow' section as feedback; on load such user-note entries that do not read as a rule are retyped to what they are - a user fact (\"my …\", \"I …\") or a project fact - and stay remembered. A remembered rule (\"never push to github without asking\") stays feedback."
 },
 {
  "version": "1.5.022",
  "date": "2026-09-02",
  "title": "Bench sweep, round two: background builds stop fighting a 0x0 viewport. A session this window had not listed yet (a worker, an agent, a bench/API session created seconds ago) was treated as DELETED by the sandbox room lookup, so every Eval/Snapshot/Dogfood in that turn came back 'session was closed' while SandboxOpen/Shot still reported success - the model looped open, shot, fail: 18 calls for one parallax page. Only sessions actually deleted are refused now. Then the next layer: hidden rooms were display:none, so the page inside saw innerWidth 0 and a canvas build spent 28 tool calls, 233 s and $1.62 'fixing' sizing that was fine. Hidden rooms are now laid out (invisible, untouchable, behind the fronted frame), the right panel parks off-screen with its size instead of display:none, and the sandbox pane keeps layout while another tab is up - the same build is now Write + Dogfood, 50 s, $0.21. SandboxShot names its session: a background room renders in-page (canvas pixels + DOM) instead of screen-cropping whatever the user was looking at. Coding turns are lighter too: the 16 Chrome-automation schemas (~20 KB) rode every canvas game / shader / page build because they shared the 'browser' gate with the sandbox tools, and 'config.json' opened that gate through the substring 'js'. Chrome tools have their own gate (URLs, navigation verbs, site names, 'browser'), and js/css match as words."
 },
 {
  "version": "1.5.021",
  "date": "2026-09-02",
  "title": "Bench sweep, round one: every chat turn was carrying 119 tool schemas (119 KB, ~47k tokens) - measured live, \"what's 15% of 240?\" wrote 52,716 tokens to the prompt cache and cost $0.20 for the reply \"36\". The lean chat set (core + keyword-unlocked groups) now applies on every provider, not only the cache-less ones: the same question is 11,478 tokens and $0.04. A tool the message did not name is one ToolSearch away and is unlocked for the rest of the turn, ToolSearch accepts keyword/name/tool as well as query, and it reports honestly when a found tool cannot run right now (Browser* with the Chrome bridge down names WebFetch/OpenURL instead of inviting three failing calls). Memory: eight pieces of talk were riding every turn as 'rules you must follow' - a roast line (\"...my left nut, I'd smack you with it\", 143 hits) that turned a Tokyo weather answer into \"cursed nut weather\" and a research report into \"alright nut-boy\", an HTML title, \"i never heard of gsap\", and two of ForgeCry's own attachment briefings mistaken for the user's words (571 hits). A standing rule now needs instruction content, cannot be narration (a subject before never/always), banter, or markup, and client-injected attachment notes are never mined; existing junk goes dormant on load. \"remember that my favorite color is teal\" is stored as a user fact, not a rule. Bash refuses a recursive walk of a home/desktop/drive root and hands back the Glob call: \"read config.json\" went from four shell searches, 91 s and $0.23 to Glob + Read in 23 s."
 },
 {
  "version": "1.5.020",
  "date": "2026-09-02",
  "title": "Voice replies keep their original rhythm - whole sentences, spoken after each sentence ends - but the wait for the first word is shorter. Measured live: every sentence batch was paying a fresh Edge websocket handshake (~300 ms) plus Edge's per-voice cold start (up to 2.9 s after any idle spell) before a byte of audio came back. The server now keeps one Edge socket pre-dialed and re-primed every 25 s, and warms the voice with a throwaway word while you are still typing, so the reply's first sentence lands on a hot socket and a hot voice. Nothing about what plays changed: a sentence-by-sentence build with streamed playback was measured (first sound ~1 s earlier) but Edge delivers frames unevenly and sentences stuttered and got cut at words - you heard it as worse - so it was taken back out."
 },
 {
  "version": "1.5.019",
  "date": "2026-09-02",
  "title": "3D builds get a modeling kit: parts and relations instead of typed coordinates. Every joint on last night's truck was a typed number - a mirror two centimetres off the cab, tires half inside the body, faces sharing a plane - because a model writing coordinates blind is guessing. FetchWebAsset type 'kit' now vendors three.js plus the CSG library and drops in assets/forge-kit.js: K.attach(part, host, face) measures the host's real surface under the part (raycast, not bounding box) and seats the part on it, sunk 15% by default, centred or aligned to an edge; K.mirror makes the right side from the left across the body's centre with the geometry mirrored and the name flipped (wheel_FL becomes wheel_FR); K.extrudeProfile turns a side silhouette into a body with a real hood slope and windshield rake; K.wheel is one lathe with a tire bulge and rim dish; K.cut subtracts real wheel arches, windows and pockets; K.onGround seats the whole assembly. The build rules now open every multi-part object with the kit, and the assembly audit verifies what the kit builds. The kit guarantees that parts meet; proportion and detail are still the model's job - and reference images are the next layer."
 },
 {
  "version": "1.5.018",
  "date": "2026-09-02",
  "title": "Fetched assets land in your project, never in ForgeCry's own folder. When a build vendored fonts or Three.js add-ons with a project-relative destination (\"clay-god/assets/fonts\", the natural thing to pass, the way every file tool works), the asset tools took the path verbatim and the operating system resolved it against the server's working directory - a complete assets tree with Fira Code and six Three.js add-ons appeared inside the ForgeCry install folder while the real project sat in Desktop/Projects. Every asset destination (web fonts, Three.js, typeface fonts, icons, 3D models and HDRIs) now resolves a relative path against the project root like Write and Read do, keeps absolute paths as given, and refuses a relative path when no project is open instead of falling through to the install folder. The stray tree was removed."
 }
]