← Appolis
πŸ›οΈ the city of apps Β· v0.89.0

APPOLIS

Every app, game, and creation β€” served from one city gate. The public sees the open buildings; share links open specific doors; the master admin sees every street.

Appolis v0.89.0 Β· source of truth: APP_BREAKDOWN.md Β· deck syncs with the doc
πŸ— Who sees what

Full control over every door.

🌐
Public β€” on the landing for everyone; open in the browser, install as an app.
πŸ”—
Unlisted β€” invisible until you hand someone its share link. Rotate the key to revoke.
πŸ”’
Private β€” master admin only. Every building starts here.
πŸ“‹
Docs per app β€” each card carries its Blueprint & Showcase, with a per-app "visible to visitors" switch.
πŸ— Run by the mayor

The whole catalog, edited in place.

Sign in with the master key and every card grows controls β€” name, icon, tagline, category district, status, visibility, docs, share links. No dashboard, no deploys: the city is its own admin panel.

✎
Edit any building inline β€” saved to the catalog instantly.
πŸ“²
PWA-flagged apps carry an install hint for visitors.
πŸ’°
🎟 Named grants β€” open a personal door, revoke one person at a time. Ahead: install flows, paid apps.
πŸ“œ Changelog Β· to v0.89.0

Every version, one page.

.89.0
v0.89.0 β€” 🧰 Safety fixes, round one. Publishing two skills at once can no longer make one vanish from the list, and the publisher now checks the list afterwards. A sandbox copy of Hermes is now set up, reset and torn down along with every sandbox. A Codex sandbox folder from SolarWRLD logs to the right board.
.88.2
v0.88.2 β€” πŸͺ‘ Picking up a chat never gets blocked by someone else's work. When a new session takes over a chat's old seat, it brings along only the old seat's areas that nobody else is working in right now. It used to refuse the whole pick-up when one of them was busy.
.88.1
v0.88.1 β€” πŸͺ Closing a terminal cleans up after itself wherever it started. A session started in the folder that holds all the apps now also removes the little "this app is on shift" marker files it left in each app's folder, not only one started inside an app.
.88.0
v0.88.0 β€” πŸͺ‘ One chat, one seat. Close a terminal and its shift closes itself; clock back in on the same chat and the new session takes the old seat over, lanes, waits and journal included.
.87.0
v0.87.0 β€” πŸ› One government data key. Paste one free api.data.gov key into Appolis once, and your Claude sessions can read the FEC, Congress.gov, GovInfo and Regulations.gov without ever seeing it.
.86.2
v0.86.2 β€” πŸͺͺ Two small connector fixes. Clock-in now accepts a shared board's own name, and who-am-I says which connector version answered.
.86.1
v0.86.1 β€” πŸ”’ Owner actions and sign-in answer the Appolis portal only. A tightening of who may press these buttons. Nothing changes for you on appolis.app.
.86.0
v0.86.0 β€” πŸ”‘ One saved key now works everywhere. A Claude session that is on the clock can use your saved Anthropic key, including big batches, with no new keys to make. Only a live Claude session can do this, and only with its own person’s key. Ballot Buddy’s key still only sends mail.
.85.1
v0.85.1 β€” πŸ’¬ Kosmos can tell your sessions apart by their chat. When a session clocks in, it says which chat it works in. Appolis now passes that along to Kosmos with each open session. So when several sessions are open and one posts without naming itself, Kosmos knows it is the one working in that chat, and the context gauge shows the right session. If two sessions share one chat, Kosmos still doesn’t guess.
.85.0
v0.85.0 β€” πŸ• Every Kosmetor cleanup is now logged, no exceptions. Kosmetor's cleanup helper now opens a logged run before it changes anything. Appolis now turns away any cleanup change that isn't part of an open run, before anything is sent or saved. So every change Kosmetor makes shows up in a run's log.
.84.0
v0.84.0 β€” πŸ• Kosmetor gets its own clock-in. Each cleanup Kosmetor runs is now its own logged run, with every approved change it makes and when. A run never holds a board and never gets in anyone else's way, and a board someone is working on still turns Kosmetor away. Only you can see the runs. The Daedalus page that lists them is next.
.83.0
v0.83.0 β€” βœ‰οΈ Ballot Buddy can email sign-in codes. Ballot Buddy now has its own key for the suite's mail service, so people can sign in with a code sent to their inbox. That key can only send mail. It can't open anything else in the suite, so if it ever leaked, all someone could do is send email as Ballot Buddy.
.82.0
v0.82.0 β€” 🧹 One clock-in for a whole cleanup. Each approved cleanup write now carries a signed note saying which item you approved. Once Kosmos reads that note, the tidy-up script won't have to clock in to every board one by one. Boards someone else is working on are still left alone. Nothing changes until Kosmos does its part.
.81.1
v0.81.1 β€” 🧹 The cleanup's first item now goes through. The first real try was stopped safely: an old practice job on your account made the check think the script was working inside a sandbox. Nothing was changed on your boards. The check now stops a write only when it really would land in a sandbox copy.
.81.0
v0.81.0 β€” 🧹 Kosmetor can finish a cleanup you already approved. When you approve a board cleanup on a form, Daedalus's tidy-up script can now archive those items itself, keeping an undo record for each one. Before, each item got stuck as a proposal a Claude session had to apply one at a time. Each write is checked first: it must be one of the items you approved, made the way you approved it, and only from your own connection. Other people's AIs still can't write.
.80.1
v0.80.1 β€” πŸ› The chat is called the Agora everywhere. Appolis's rulebook and tool text now send sessions to "the project's Kosmos Agora chat (πŸ“₯ Inbox β†’ πŸ› Agora)", matching the name Kosmos already shows. Words only; nothing works differently.
.80.0
v0.80.0 β€” β†— A session can wait on another chat. When one project's chat hands work to another project's chat, the session that asked can now say "I'm waiting on that chat". Each time that chat answers, the session gets a nudge in its own chat and picks the reply up without checking over and over. Kosmos adds one call on its side to switch this on.
.79.0
v0.79.0 β€” πŸ”’ Only Tyler can ever hold full access. Owner-level access now belongs to one account, fixed in the code: Tyler's. No screen, tool or request can make anyone else the owner, or give that power back after it is taken away. Opening every app at admin level counts as full access too, so it can't be given to anyone else either. Everyone else keeps exactly the access they have now. Insiders can still use every app without changing anything, and other people's AIs still work only in the workshop and sandbox, handed to Tyler for review. Tyler's own account can't be deleted or switched off either, so Appolis can never be left without its owner. Kosmos made the same lock on its side in v8.201.0.
.78.1
v0.78.1 β€” πŸ“£ When a session clocks out, its chat hears it at once. The moment a shift closes, Appolis tells Kosmos, and the chats tied to that shift get their clock-out record right away instead of waiting for the next summary. The clock-out answer says in one line whether Kosmos got the message β€” and if it didn't, why β€” but a slow or silent Kosmos never stops a clock-out.
.78.0
v0.78.0 β€” βž• A session can take on one more piece without starting over. When another session asks it in a chat to make a change on a board it isn't covering, it adds that lane to the shift it already has. It keeps its id, its wake-ups and its deploy guard, and a lane someone else holds is still refused by name.
.77.2
v0.77.2 β€” ⏰ Older AI sessions can say what they wait on too. A session whose tool list was older than v0.77.0 sent its waiting list in a form Appolis turned away. Appolis now reads that form as well, so every session can be woken when the work it waits on lands.
.77.1
v0.77.1 β€” 🀝 Releasing a stuck hand-off keeps its note. When you (or the session that handed it) force-release a hand-off nobody picked up, the note saying what happened is now kept on the record instead of being dropped.
.77.0
v0.77.0 β€” ⏰ A session can now say what it is waiting on, and Kosmos wakes it when that lands. When an AI session starts (or checks in), it can name the items or other sessions its work waits on, and the Kosmos chat it is talking in. The moment one of those items is closed in Kosmos, or a session it was waiting on clocks out, the waiting session's chat gets a short wake-up line, so it no longer has to keep checking. A mistyped wait is refused with a plain message instead of being quietly ignored. If Kosmos cannot be reached the failure is written down and reported, never swallowed. Not in this version: waking when a session simply times out, waking chats on shared projects, and the clock-out ping.
.76.0
v0.76.0 β€” πŸ› Every session now talks to you in the Kosmos Agora chat. The rules every AI session reads when it connects now say: open the project's chat in Kosmos, pick up where it left off without re-reading it, post progress and every question there, and send a choice as a form button inside the chat. The old end-of-run comments form, the timed form checks and the "unattended run" wording are gone. Also for Daedalus's live credit meter: when your own Anthropic key is refused, Appolis now says why in one word (no credit, rate limited, spend limit reached, and so on), so the AI road can close itself instead of failing blind.
.75.1
v0.75.1 β€” 🀝 A hand-off nobody picks up lets go by itself. Two outside-AI sessions ended by "handing" their work lane to a name that was nobody, and the lane stayed locked for everyone β€” the next sessions, and even Tyler's own Claude. Now a hand-off to someone who is not a real Appolis person is refused on the spot, a hand-off nobody takes releases itself after the shift's time limit (two hours for an AI), whoever is refused is told who handed it to whom and when it frees up, and Tyler (or the one who handed it) can release it at once. Also: when an outside AI talks to the practice copy of Daedalus, the answer now says so β€” the "leak" reported today was the practice copy answering Tyler's own account, as he asked for.
.75.0
v0.75.0 β€” 🌐 Builders' test apps can run their own server code. A test app on akademeia.app is no longer only pages: a builder can add a worker.js and their app answers requests with its own code, while files under public/ are still served as pages. Two fences keep it safe: the app may call any public website but never Appolis's own apps or private network addresses, and only cookies an app sets for itself alone reach it, so no test app can read another's. Same rules as before: build access, up to 5 live apps each, the owner's kill switch.
.74.1
v0.74.1 β€” πŸ“¬ The owner's inbox notice gets time to land. When a builder hands in work from the Workshop, Appolis tells the owner's Kosmos inbox. Kosmos sometimes takes longer than 8 seconds to save that note, so the notice was given up on β€” the first akademeia test saw it happen. Appolis now waits up to 25 seconds, the same allowance the other Kosmos pushes already use. The work itself was never lost: it was always on the Workshop page.
.74.0
v0.74.0 β€” 🌐 Builders can put their own test apps live on akademeia.app. A builder working through ChatGPT, Codex or Claude can now publish a page they made in the Workshop to its own address, like my-app--yourid.akademeia.app, on a separate domain walled off from appolis.app. Each person may keep up to 5 test apps live; an app nobody visits for 30 days goes to sleep and its builder can wake it; the owner can take down any one app, or everything a person has published, from the Workshop page. The Cloudflare key that does the uploading stays inside Cloudflare's vault β€” no AI ever sees it.
.73.4
v0.73.4 β€” πŸ§ͺ Outside AIs get the Daedalus planning room β€” in a sandbox. As you asked, a ChatGPT or Codex seat can now use Daedalus's plan, routine and step tools for real, but every call lands in Daedalus's separate sandbox copy (its own database, no line to Kosmos or live Daedalus); nothing it does there reaches the live system until a Claude seat reviews it. If the sandbox copy is not ready, the seat is told so by name and nothing is sent to live. Also: an ID activated by code or claim now gets its connector before the activation is saved, so a half-finished activation can be retried instead of leaving a person with no connector.
.73.3
v0.73.3 β€” 🧹 A code change an AI proposed and that was then turned down no longer sits in your Kosmos Inbox: it leaves on its own, and pressing Remove or Send back on one that was already turned down now works instead of failing.
.73.2
v0.73.2 β€” πŸ• A session that names its shift now sees only that one marked as its own, not every shift on the account.
.73.1
v0.73.1 β€” πŸ• When two of your AI sessions work at once, each can now say which shift is its own: a message or question it posts on the board carries that shift's name instead of β€œshift undecided”, and the shift list marks it as yours.
.73.0
v0.73.0 β€” πŸ”‘ You can save your own Anthropic key on your Appolis ID, so AI in your Kosmos chats bills your account, not the company's. It is checked once, locked away and never shown again β€” to you, to the owner or to any AI. The owner decides, person by person, whether the company key steps in when yours fails (off unless switched on).
.72.5
v0.72.5 β€” 🧰 A house skill now says which computers it runs on (the read-aloud skill is marked Windows-only, so a Mac is told before installing it), and a person's own settings β€” like Tyler's chosen voice β€” are never handed to anyone else.
.72.4
v0.72.4 β€” πŸ•” The time card files every "clocked in" and "clocked out" line under the right shift, and an abandoned presence left over from September now closes itself instead of soaking up everyone's later work.
.72.3
v0.72.3 β€” β›” No more compliance nagging for teammates β€” the "open directives" reminder now shows only to the owner, who can act on it. A teammate's AI stops being told to use a tool it doesn't have.
.72.2
v0.72.2 β€” πŸͺͺ Daedalus can now be granted from the People list β€” it was missing from the menu. A grant still written under its old name (hephaestus) shows as "Daedalus (old name)" in green instead of a gold warning telling you to revoke it: that grant opens Daedalus today, and revoking it would have cut the person off.
.72.1
v0.72.1 β€” πŸ‘₯ Everyone gets the whole Kosmos through their AI β€” a teammate's Claude can now start projects and build landers on their own board too, not just read and work notes. The backend (laws, keys, other people's boards, raw-HTML pages) stays yours alone.
.72.0
v0.72.0 β€” πŸͺͺ A pending Appolis ID comes alive by emailed code β€” a person an app enrolled (no password yet) signs in with a code and their connector starts working; an ID the owner switched off stays off, even to an app's claim.
.71.0
v0.71.0 β€” πŸ“‹ A connector that only works the Projects board. You can now give someone a connector that lets their AI do exactly what they can do on the Hermes Projects dashboard themselves (see the board, add and change tasks, post updates, attach links, answer reviews), as them, and nothing else. A button on their account row mints it, and another revokes it; you can make it their only connector. Another AI such as ChatGPT can only read the board with it.
.70.0
v0.70.0 β€” πŸ—‘ Agora is gone from Appolis. As you asked, the old team-board app is removed: its tools no longer load into any AI session, the hub no longer connects to it, its tile and email settings are gone, and its pages left the docs site (old links go to the docs home). Team projects live in Hermes. Agora's own data is backed up and taken offline by its own session next, and the final delete is your click.
.69.0
v0.69.0 β€” 🧊 The real 3D models travel with the job. When a Claude session hands a copy of a project to ChatGPT or Codex, the models and images can now go inside it, sent straight from this PC byte for byte, instead of the outside AI having to upload them itself. They get the same safety checks and size limits as before, and every preview the outside AI makes shows them.
.68.2
v0.68.2 β€” πŸ• The board credits the right session. When several AI sessions work at once, a session that approved a proposal without its own time card had the write credited to another session's card. Now an approval is credited only to the session that proves the card is its own, or to none, and Codex and Claude never borrow each other's cards.
.68.1
v0.68.1 β€” 🧊 A Claude session now hears when an AI asks for more space. When an outside AI asks for a bigger file-size limit in the Workshop, every new Claude session is told at the start: which job, how much it wants, and why. The session tells you, but it cannot approve it; only your βœ“ Approve on the Workshop page does. Once you approve or decline, the message goes away.
.68.0
v0.68.0 β€” πŸ–₯ Codex on your PC can post to the board. Codex on your own computer can now write its reports and ask you questions on the board directly, instead of waiting for a Claude session to approve each one. It proves it is the copy on your PC with a private key kept only on that machine, so a ChatGPT chat in the cloud still cannot. Changing a note that already exists still goes through a Claude session.
.67.0
v0.67.0 β€” 🧊 The Workshop can hold a 3D model or an image. An outside AI can now upload a model or a picture (for example a character outfit for SolarWRLD) into its Workshop copy, and the preview shows it. Each file has a size limit and is checked for hidden passwords or keys; it only ever appears on the preview, never on the live site. If the AI needs a bigger limit it can ask, and nothing changes until you approve it on the Workshop page.
.66.1
v0.66.1 β€” 🧊 3D pages show up in the Workshop preview. A page an outside AI builds in the Workshop can now load its own data files, the 3D library it names, and the product photos from the shared image pool, so a 3D storefront like SolarWRLD shows up for review instead of a blank page. The preview still can't send anything to any other site, and landers keep their stricter rules.
.66.0
v0.66.0 β€” 🧹 Skills get checked before they go out. When a house skill is published, it is now checked first: one that is missing its name or the sentence saying what it is for is turned away with the reason, and smaller problems (too long, never says when to use it) are pointed out but still published. Before anything is sent, a free test also checks that a set of everyday requests still lead to the right skill, so a reworded description can't quietly stop a skill from being used.
.65.2
v0.65.2 β€” πŸ“œ Reading the rulebook back shows what just changed. When something changes what a working session is told at the start (a handed-in task, a rule, who is on shift), the tool a session uses to read the full rulebook now shows the new version straight away, instead of an old saved copy until the next session opens.
.65.1
v0.65.1 β€” 🀲 Handed-in tasks get noticed, and no one app can flood them. When a task is waiting in the Workshop and nobody has answered it yet, the owner's next working session is told about it first thing, by name and by where it came from. And each app can have at most five tasks open at once, so one busy app can't use up all the Workshop's room.
.65.0
v0.65.0 β€” 🀲 Anyone on the team's apps can hand work in (todo_8019). ChatGPT, any Appolis app and any working session can now drop a plain task β€” a title, a note, a few files β€” into the Workshop, where it waits as a sandbox job for a session to pick up; every task says who asked and from which lane. Landers still come only from the Lander Builder, and nothing handed in can touch anything live. Law 7 now says cross-app work is a new to-do or note on the other board, never an edit of what that board is working on. Handing a task to a named teammate stays with the team's apps, not a single working session. Plus the small link Hermes needed to read the Kosmos lander list (todo_8030).
.64.1
v0.64.1 β€” πŸ• Three clock-in defects fixed (todo_6612). Naming a note or to-do at clock-in now claims the lane the board really files it under, so the first write is no longer refused; clocking in again with take:true plus your earlier shift's id and token replaces that shift instead of opening a second one β€” and can never close another chat's; and the refusal text now says how to route work to another board β€” file a to-do there, never edit its notes.
.64.0
v0.64.0 β€” πŸ– A Workshop page goes to a review hub first. Kosmos can now read a landing page the moment ChatGPT submits it, so it lands on a private review hub for markup instead of going straight into the Lander Builder.
.63.0
v0.63.0 β€” 🧰 Start landing-page jobs from Kosmos, and approve them from your Kosmos inbox. The Lander Builder's intake β€” the facts sheet, brand bible, reference sites, SEO brief and the video ad β€” can now be handed to ChatGPT (or a collaborator's AI) as a Workshop job, filed under the Kosmos project it belongs to. When the AI submits a page, Appolis checks it straight away (the same landing-page check as before, now run on the server) and tells the AI what failed, and the page lands in your Kosmos inbox with a preview link, βœ… Approve and ↩ Send back. Approving a landing page saves it as an unpublished draft in the Lander Builder β€” no Claude session needed. Sending it back passes your notes to the AI, which can submit again. Publishing to the store stays your click. You no longer need to open Appolis to approve anything from the Workshop.
.62.1
v0.62.1 β€” 🧰 Four small fixes from the first landing-page drill, and an approved job can no longer sit unnoticed. When you press βœ“ Approve on a Workshop job, every Claude session that connects now gets a reminder that the job is approved and waiting, until one of them takes it in or turns it down. Before, an approved job could sit for hours without anyone looking at it, which is what happened to Raven's fix today. The rules handed to an outside AI building a landing page now say plainly: no numbers, reviews, testimonials, guarantees, doctor endorsements or health claims unless they are in your copy. The page checker no longer counts the title line of the copy file as missing page copy. And a landing page that has been approved is now described as "promote it", not "commit and ship it".
.62.0
v0.62.0 β€” πŸ›¬ Any AI seat β€” ChatGPT included β€” can now build a landing page from your brief, and a Claude seat takes it from there. A new kind of practice job, a lander, is handed to the AI with your copy, your brand notes, the pages and looks you like, and the list of images and videos it may use. The AI builds the one page in its practice room, can preview it with the real pictures and fonts showing, and sends it back with notes on what it kept word for word. A Claude seat then checks it by machine (the words kept, nothing loaded from a stray website), fetches the exact page, and files it in the review hub and the Lander Builder as a draft. Putting it in the store stays your click. Code practice jobs also got safer: a kit that leaves out a file its main file needs is now stopped before the AI starts, so it can no longer waste a morning on a copy that cannot run.
.61.1
v0.61.1 β€” πŸͺͺ The Workshop now says who approved a piece of work β€” and the first two pieces of outside work are live. When you press βœ“ Approve or βœ• Decline on the Workshop list while signed in with your Appolis ID, the record and the row now carry your name, not just "the owner's page" (the emergency key still works and is labelled "the admin key"). This change was written by Raven's AI on a practice copy, approved by you with one tap, then tested and put live by a Claude session β€” the way the whole arrangement was meant to work. The second piece, from ChatGPT, fixes a guard in the build tools that mistook a data file for a version bump.
.61.0
v0.61.0 β€” 🀝 You can hand practice-room work to Raven's AI, and approve finished work with one tap. When a Claude session hands out a practice job, it can now name one person you already work with (someone on one of your Appolis teams). That person's AI can see that one job, change it and send it back, and nobody else's can. What comes back lands in your Workshop list like ChatGPT's work does, and only your side can accept or turn it down. Each item in the Workshop list also has a βœ“ Approve button next to βœ• Decline, with room for a note. Approving means "go ahead": a Claude session then tests it and puts it live without asking you again. The AI that made the work sees your note, or your reason when you decline.
.60.2
v0.60.2 β€” πŸ”– The first change ChatGPT wrote for us is live: appolis.app/api/version. Anyone (or any app) can now ask appolis.app which version is running and when it was built, at one public address. ChatGPT did the work in its practice room: it read our big main file a slice at a time, added the address with exact edits, and wrote a test for it. Claude checked it against the real code (the test passes on the change and fails without it) and shipped it with your go. ChatGPT could not run the test itself because its practice copy was missing some helper files; that is filed to fix.
.60.1
v0.60.1 β€” 🧡 ChatGPT can now work on our big files, and you can decline its work with one click. You said you want to start using your ChatGPT usage for our projects. The catch was size: our apps are each one very large file, and ChatGPT could only read a file whole or retype a file whole, which it cannot do for files this big. Now it can read a big file a slice at a time (or search it for a word and be told which lines hold it), and it can change a big file by saying "swap this exact text for that text" instead of retyping everything, and if the text it quotes is missing or appears twice, the change is refused and nothing is saved. Second, each piece of ChatGPT work waiting in the Workshop list on your page now has a Decline button: it asks why, tells the AI your reason, and nothing is applied anywhere. Before, only a Claude tool could do that. Third, a small fix: a ChatGPT seat poking at a job that was handed to a different AI now gets "no such job" instead of a message that gave away what the job was.
.60.0
v0.60.0 β€” πŸ§ͺ ChatGPT can now build its own throwaway demos, and Daedalus gets a practice room with the door still shut. Until now a sandbox AI could only work on a copy that Claude handed it. Now it can open an empty scratch job of its own (or one with files it brings), build in it, hand the result in for review and show a preview, exactly like a handed copy. The scratch job is marked as scratch so nothing can pass it off as a copy of the real code, it never gets live data or a secret, only that AI and Claude on the same account can see it, and the same scan that refuses secrets in a handed copy refuses them here. Second, a switch (off by default) that, when on, sends a sandbox AI's Daedalus calls to a separate practice copy of Daedalus instead of the live one, reads and writes alike; the practice copy has to be redeployed and given its key by the Daedalus side first, so the switch stays off in this build. If that practice road ever fails it says so by name and never quietly falls back to live Daedalus, and Claude's own calls never take it.
.59.0
v0.59.0 β€” πŸ” A key that can only look, for the computer that checks on Daedalus. Daedalus's library and wing pages open only to someone signed in to Appolis, and the small program that checks them every day from this PC had no way to sign in β€” the only keys that existed were a person's, which expire in a week and would open everything. Appolis now mints a machine key named daedalus-checker that opens exactly two read-only pages on Daedalus and nothing else anywhere in the city: not the skills door, not the sandbox, not the connector. It is made on the Laws β†’ Keys tab, arrives as a download that is never shown on screen, shows when it was last used, and a Revoke click shuts it at once. Daedalus still has to learn to accept it β€” that is a to-do on its own board. Alongside: when a copy is handed to the sandbox in one call and a storage write fails after the job is already on the books, the hand is told "handed, bytes still landing" instead of "failed" (which used to make it hand again and take a second seat), the job appears in the list at once, and the gate finishes the write itself within a minute.
.58.4
v0.58.4 β€” πŸͺ‘ Six small stitches on the seal writer. The review of the last build found six small things, none of them a broken feature; this build closes all six at once. The gate that guards a job's record now checks its key the careful way (so the time it takes to say "no" never hints at the answer). If a job is sealed but the copy of its files in the store fails to land, the job no longer gets stuck: the record remembers the bytes are still owed, the gate tries again every minute from the pieces it already holds, and until then a reader is told "still landing" instead of "no such file". A kit can no longer be sent in so many tiny pieces that its record outgrows the store. The error for a used-up upload key now says what to do (run the script again; it mints a fresh key each time) instead of hinting at a retry that was never needed. A job record with an unreadable expiry date is refused at the door, so nothing can be stored that would never expire. And the freight key's badge on the Keys page finally has its own color.
.58.3
v0.58.3 β€” 🧱 A sealed job stays sealed, everywhere, at once. The first real-file test of v0.58.2 found a gap: the files went up and the job was sealed from this computer, but half a minute later an AI app on a server far away β€” still holding an old copy of the job that said "empty, still loading" β€” added a file and its old copy overwrote the sealed one, so the sandbox could no longer see the finished kit. Nothing was forged (a re-sealed job is re-checked byte for byte), but work was lost and the app was told "ok". Now every job has one place that holds its state β€” the same kind of always-up-to-date record the Workshop already uses to remember destroyed environments β€” and every change goes through it in order: a job that is sealed answers "not loading" to anyone, anywhere, the moment it seals, and the job list shows it immediately instead of up to a minute later. The file bytes themselves still live in the store, written once. Small extras: the Keys page can mint a freight key with its own button (and labels it correctly), and an error that names a job no longer repeats whatever text was sent.
.58.2
v0.58.2 β€” πŸ”‘ Real files go up from this PC without any AI ever holding the key. A small program on this computer now sends big code files into a Workshop job by itself: it reads the files exactly as they are saved in the project history, uploads them in pieces, seals the job and proves the copy matches byte for byte. It uses a new kind of key (a "freight" key, listed and revoked on Laws β†’ Keys like the others) that can only make a short-lived upload pass for ONE job, good for 15 minutes at most, for adding files and sealing, and dead the moment the job is sealed. No AI model ever sees or prints either key.
.58.1
v0.58.1 β€” 🧰 Sending code in pieces works from any AI app. The first live test of v0.58.0 showed that an AI app still holding an older copy of the tool's instructions sends the pieces of code as plain text instead of a list, and the Workshop turned them away. It now reads that text too, and checks it exactly the same way.
.58.0
v0.58.0 β€” 🧰 A big copy can now be handed over in pieces. A real-sized copy of the app is too much to type out in one message, so until now handing one to ChatGPT or Codex was not practical. Now the copy is opened, loaded in small batches (each batch is at most about 64 KB, what Claude can write out reliably in one go), and then sealed. While it is still loading, ChatGPT and Codex cannot see it, list it, read it or work on it. When it is sealed, the hub gives back a fingerprint of every file and of the whole copy, and a small checker on the computer recomputes the same fingerprint from the real code, so a single wrong letter is caught before any work starts. A batch that is refused (too big, too many files, or anything that looks like a secret) saves nothing at all. The old one-message way still works and now returns the fingerprint too.
.57.3
v0.57.3 β€” 🧰 Deleting a sandbox works on the live site. The first real test of v0.57.2 found that deleting a sandbox was refused: the new register looked for the hub's key under a name the live site does not use. It refused safely and changed nothing. Now it reads the key the way the rest of the hub does, and the test copy of the hub is set up the same way as the live one.
.57.2
v0.57.2 β€” 🧰 The Workshop's loose ends, closed. Deleting a sandbox now takes effect everywhere at once: a small always-up-to-date register says which sandboxes are gone, and every part of the Workshop checks it, so nothing keeps using a deleted sandbox for the minute the main store takes to catch up. Snapshots now swap every person's and team's name for a stand-in ("Person 2", "Team 1"), in notes and rules too, not only in the account list. A preview page warns you before a link takes you off the preview. Only the person who made a sandbox can hand work into it. And it is said plainly: while ChatGPT works in a sandbox, the other apps (Kosmos, Hermes, Agora…) still show it their live data until each of them builds its own sandbox half.
.57.1
v0.57.1 β€” 🧰 Handing work in no longer misses a fresh change. When ChatGPT handed in its work right after saving a file, the Workshop could answer "nothing changed" for up to a minute, because it looked the changes up in a list that catches up slowly. Each job now keeps its own list of changed files, updated on every save, so a hand-in sees the change straight away.
.57
v0.57.0 β€” 🧰 The Workshop: other AIs work on throwaway copies, and only Claude makes anything real. Claude can now hand ChatGPT or Codex a job with its own throwaway copy of the code and the notes it needs. That copy lives in a separate sandbox store, never in a real folder or a live app. You (or Claude) can also take a cleaned-up snapshot of the system, with real names, emails and keys swapped out, and give it to the other AI as a sandbox environment to work inside. You can reset it to that snapshot or wipe it whenever you like, and it disappears on its own when its time runs out. When the other AI is done, its work goes to the review queue as a candidate: exactly what it changed and what it claims. A candidate can be previewed straight away, as a page at sbx.appolis.app, or as a working copy of the app on one of ten preview addresses (sbx-1 to sbx-10.appolis.app). A working preview starts instantly and is walled off from the internet: it can only touch its own sandbox storage. Nothing a sandbox AI does reaches a live app, a real folder or a deploy. Only Claude reviews a candidate and copies it into the real code, the normal way.
.56.1
v0.56.1 β€” 🧱 Sandbox AIs clock in on a sandbox lane only. ChatGPT and Codex already could not clock in on a live code folder, only on a sandbox copy of it. They could still reserve a board, though, and a reserved board turned Claude's own updates away until they clocked out. Now a sandbox AI clocks in on a sandbox/… lane or not at all; the refusal names the sandbox lane to use instead, and its shift is still logged on the board it belongs to, so you can see it working. Nothing changes for Claude.
.56
v0.56.0 β€” 🧱 The sandbox wall. Other AIs never leave the sandbox: a connector token can now be minted FOR a platform (ChatGPT, Codex), and such a seat β€” or any seat whose client is not Claude β€” is sandbox-only, with no switch to lift it. It can read; its writes to any app are not sent but stored as PROPOSALS a Claude seat reviews and applies or declines (appolis_proposals Β· appolis_proposal_apply Β· appolis_proposal_decline); it cannot clock in on a code folder (repo/… is refused in words; sandbox/… is its lane); hub publishes and attestations are refused by name. The signed identity every app receives now says the platform and its access, so each app can wall on its own too. Owner picks: Q1 = A (the token is the ceiling) Β· Q2 = A (an unknown client is sandbox) Β· Q3 = A (no Daedalus sandbox routing yet) of form note_7272.
.55
v0.55.0 β€” πŸ” Exactly once. On 2026-10-20 one daedalus_step call reached the Daedalus door twice: the first copy did its work, its answer never got back to the chat, and the chat was handed the second copy's refusal. The connector itself never retries β€” the repeat came from the transport above it re-sending the same message β€” so the connector now recognises a re-send for what it is: every forwarded call gets a request id made from the session, the call's own id, the tool and its arguments; the first answer is kept for two minutes and a re-send receives THAT answer (marked πŸ” replayed, not re-sent) instead of reaching the app a second time. A re-send that arrives while the first copy is still being answered waits for it (up to 20 s). A room that errored or did not answer releases the id, so a genuine retry still goes through. The id also rides to the app (_meta.requestId) so each door can refuse a repeat on its own. Also: appolis_whoami now says in words when the shift registry could not be read (shifts_error, shifts: null) instead of answering "no open shifts". Two old test harnesses now send a fresh id per call, as a real client does.
.54.1
v0.54.1 β€” ⏱ The projects door waits for Kosmos. When Hermes hands Appolis a batch of tasks, Appolis now waits up to 25 seconds for Kosmos to finish putting them on everyone's boards, instead of giving up at 10. Kosmos was finishing the work but answering too late, so Hermes thought nothing had landed and kept trying. Nothing else changes.
.54
v0.54.0 β€” πŸͺͺ Who am I. One read-only question your connector can finally answer: appolis_whoami returns the person the boards record you as (account β€” Kosmos's own id for you) and the seat your AI acts through (seat β€” the Appolis ID the connector belongs to) as two separate fields, with your name, email, role and open shifts beside them β€” so a session writes its OWNER file from a live answer instead of a saved form. It never returns a token, a key or a connector link. Until Kosmos opens its half, account is empty and the answer says so in words; nothing is guessed.
.53
v0.53.0 β€” πŸ”— The projects door, both ways. Hermes can now hand Appolis the tasks that changed, and Appolis puts each one on the right person's own Kosmos board as that person. Kosmos can send a person's tick, comment or hub verdict back to Hermes, signed as them, so the author is kept. Every refusal is said in words; nothing is faked as done β€” until Kosmos opens its half, Hermes is told "kosmos door missing" and keeps retrying, losing nothing.
.52
v0.52.0 β€” πŸ›– The hub door. Hermes (or any suite app) can ask Appolis to open a hub for one of its projects, or put a file on that hub. Appolis checks which app is asking, signs the request for Kosmos as the owner, and passes Kosmos's answer straight back.
.51
v0.51.0 β€” 🎟 The grant + the token. A person's connector now lists only the tool families their role uses β€” a data table in lib/grant.js (hub: shift Β· laws Β· skills Β· admin; Kosmos: board Β· hub Β· lander Β· project): a contributor like Raven sees the hub's shift/laws/skills tools and the Kosmos board + hub tools (68, down from 95) and nothing admin, no Hermes, no Agora β€” Daedalus's room only when the owner entitles him to it, and even then Daedalus's own gate keeps its owner-only tools shut; a call to an unlisted tool is answered NOT_GRANTED naming the family, never forwarded; the owner's list is unchanged, pinned. Beside it: every clock-in returns a per-shift token (only its hash is stored) and appolis_clock_out {id, token} closes that shift from any session β€” after the connector's session id rotated β€” with no force; a wrong token closes nothing. The shifts a board receives now carry who holds them and since when, and name the caller's shift only when the hub can actually tell (exactly one open shift), never by lane coverage. The law-book seed gains law 7, so the seed equals the store. Refresh the connector to see the new list.
.50
v0.50.0 β€” πŸ”‡ The silent room. A mounted app that could not answer tools/list β€” no service binding, an HTTP error, or a thrown fetch β€” used to vanish from the merged tool list without a trace: fwd() collapsed every failure to a bare null and the room was silently skipped, so a client never learned it was even entitled to it. Now every failure is named (fwdFail, per slug, per request: "no service binding" Β· "HTTP <status> from /internal/mcp" Β· "threw: <message>") and the room still shows up β€” as one zero-arg tool, <slug>_unavailable, whose description carries the reason and says to refresh once it's fixed; calling that tool re-checks tools/list once, right then, and answers in words either way β€” never a JSON-RPC error. fwd()'s return contract to every other caller is unchanged (still null on failure).
.49
v0.49.1 β€” πŸ•” The clock-out never guesses. appolis_clock_out with no id used to pick "the one shift under my session id" β€” but every chat on one connector shares that id, and it rotates on reconnect, so on 2026-09-18 an orchestrator's id-less clock-out closed a sibling lander-builder chat's shift (sh_5fcd23b292) and overwrote its card. Now the session id is never consulted to choose: with more than one open shift on the account the call answers WHICH_SHIFT (ambiguous:true, closed:null), names every open shift by id Β· label Β· lanes, and closes nothing until you retry with the id you opened; with exactly one open shift it defaults to it, exactly as before; an explicit id behaves exactly as before (the NOT_YOURS guards untouched).
.49
v0.49.0 β€” 🧰 Skills for Codex. The house skills registry used to tell every client the same install path, ~/.claude/skills/<name>/ β€” a Codex session that obeyed wrote where Codex never looks, and stayed invisible to its own skill search. Now the connector's appolis_skill/appolis_skills follow the calling client's tag: a Codex session gets ~/.agents/skills/<name>/ β€” the folder Codex actually discovers β€” and its SKILL.md is swapped for a short Codex-native entry point (never the 50k-character Claude Code dialect); a ChatGPT (web) client is told it has no local skills folder; every other client keeps today's path and package byte-identical. The blueprint skill package gains a Codex-native dialect alongside it β€” CODEX.md, codex/spawn.sh (both worker doors plus a dry-run mode), codex/ledger-line.mjs β€” so the same job graph (plan β†’ pin/build β†’ check β†’ run β†’ ship β†’ drills β†’ review β†’ close) now runs from Codex too, through two subprocess doors only (native in-session subagents deferred, unmeasured).
.48
v0.48.0 β€” πŸ’¬ The comments form, at the door. The suite-wide handshake rulebook gains one new rail-shaped line, COMMENTS_FORM, between the time card and the rails: when a Kosmos project's envelope says comments_form, any client β€” Claude Code, Codex, ChatGPT, an unattended run β€” now reads the same instruction to post one idempotent πŸ’¬ box (kosmos_post_decision_form {project, comments:true}) at the end of every reply, joining an open form rather than doubling it. This is the door half of todo_4605 Β§2; the value lives on the Kosmos project record, shipped alongside as Kosmos v8.133.0. RULEBOOK stays well under its 3,000-byte cap.
.47
v0.47.0 β€” πŸ“œ One law book. Appolis KV id:rules is now THE law book β€” six short lines by default, rendered everywhere: the handshake, appolis_laws, the πŸ“œ Laws page, the CLAUDE.md block. The old house rules and the owner's hand-typed standing-rules prose are retired; appolis_laws {section:'house'} now names the retirement and points at section 'laws'. The CLAUDE.md block is composed from the law book, never hand-typed β€” appolis_claude_md_publish no longer takes text, only recomposes it. The clock tools and the shift rule move to ONCE-per-session wording: clock out once, at the very end of the session, after every question is asked and answered. Kosmos carries no global laws at all any more β€” only a one-line pointer to here.
.46
v0.46.0 β€” πŸ“€ The publisher. The house skills registry used to answer "unchanged" by comparing the whole `.` stamp β€” so a re-publish of byte-identical files on a new day always read as changed, and every machine re-fetched all 8 house skills (β‰ˆ 650 KB) on its first connect each day. Now "unchanged" is decided from the hash half alone: identical files keep their previous stamp, the index entry and the handshake generation untouched; a real change still bumps. Packer hygiene: a `.bak` copy or a versioned `SKILL.v*.md` copy never ships, and a skill's own tests/ directory now does, so an installed skill can run its own gate. The dry run compares against a new bearer route, `GET /id/skills`, and prints "(unchanged)" truthfully instead of guessing from the clock. New: THE CLAUDE.md BLOCK β€” the board holds one canonical marked block for `~/.claude/CLAUDE.md`; the handshake names its version, a new owner-only tool publishes it, and `appolis_laws {section:'claude-md'}` serves it fresh on every call. A Claude Code session with no marker (or an older one) writes the block at the top of its file between markers β€” a teammate's own text above or below is never touched.
.45
v0.45.0 β€” πŸ“ The rules become rails. The handshake used to carry the owner's full laws, every open directive's full body, the doors paragraph and the skills paragraph on every single connect β€” 79,246 B measured on the served hub. Now it carries a compact rulebook instead: the rail names, the tool names, and the judgement calls this house actually enforces, under 10 KB. The full text never goes away β€” it moves one call away, to a new read tool, appolis_laws (section: house, shifts, laws, directives, a directive id, or skills). A new rail, READ_FIRST, refuses a body-replacing kosmos_update_note or agora_update_note on a note this session never read this session β€” appendText still passes, and reading the note first clears it. WHAT DID NOT CHANGE: the β›” per-call compliance tail, the echo fold, the fast-door snapshot's warm/stale behavior (now versioned v2), the shift and compliance tools themselves.
.44
v0.44.0 β€” πŸ” The echo, once per session. The Appolis connector used to repeat the same house rules on every single call β€” a session's first write already carried 25,714 B of laws, standing rules and the compliance tail, and every call after it paid that bill again. Now the proxy remembers what a session has already seen: the second delivery of an unchanged block is folded down to a short "unchanged" marker instead of the whole thing, and the β›” compliance line shrinks to one sentence once nothing has changed. A changed law, a new directive, or a different session still gets the full text β€” nothing is ever hidden, only repeated less. Measured on the pinned test's own harness: the first write dropped from 7,371 B to 4,157 B just from folding the mirrored copy on delivery one, and the repeat write fell to 665 B.
.43
v0.43.2 β€” πŸ• The session rides the envelope. Every room call now carries a signed claim of which connector session made it β€” the same streamable-HTTP session id the hub already tracked, now inside the envelope instead of only a header. A room does not read it yet; this just makes it possible to tell one session's calls from another's.
.43
v0.43.1 β€” ⚑ The fast door. The connector's welcome now answers in well under a second from a stored copy of the house rules, refreshed in the background β€” so ChatGPT and Codex, which give a connector ten seconds before giving up, see every Appolis tool instead of none.
.43
v0.43.0 β€” πŸ”Œ The ChatGPT door. ChatGPT Plus and Codex use the same connector URL as Claude: read tools carry readOnlyHint so ChatGPT stops asking on every read, every call is tagged with its client, and the profile saves a Codex file.
.42
v0.42.1 β€” πŸ•” Ghost shifts close themselves. A presence-only shift that goes quiet now closes on its own with a note saying so, instead of sitting on every screen as unclosed. A real claimed shift still goes stale and is reported, never hidden.
.42
v0.42.0 β€” πŸ”‘ Keys with kinds, and Laws. The Rules tab is now Laws, with a Keys tab beside it: mint a read-only key for each computer that runs the fence β€” it can look up who holds a lane and nothing else β€” see every key at a glance, and revoke one with a click. A read-only key can never publish.
.41
v0.41.0 β€” πŸ• Shifts: two hours of silence, the owner can take a lane, and a machine can ask who holds a repo. A working session that goes quiet is marked unclosed after two hours instead of one (a person: six). The owner can take over a live lane; the session that lost it is told the moment it next clocks in. And a computer's deploy guard can now ask the registry who is holding a repo before it ships, with a read-only key.
.40
v0.40.0 β€” 🏷 The old Hephaestus tool names are retired. Your AI now reaches the agent factory under one name, Daedalus: the old hephaestus_ names are gone from the tool list, and a call that still uses one is answered with the Daedalus name to use instead of a blank error. Nobody loses access, and a session that connected before the switch only needs to refresh its tool list.
.39
v0.39.0 β€” 🏷 The agent factory answers to its real name: Daedalus. The room your AI reaches for specialists is now Daedalus at daedalus.appolis.app, and its tools carry the new name β€” while the old Hephaestus names keep working until the switch-over is complete. Nobody loses access: everyone who could open the factory before can open it under either name.
.38.1
v0.38.1 β€” πŸ•” A finished shift stays finished, and only its own session can close it. The first two-account test found that a shift someone else had already closed could be closed again by another account, wiping their sign-off card β€” that is refused now, with a message that says whose it is. The same test found the house-skill tools would not answer a teammate's session; they do now.
.38
v0.38.0 β€” 🧰 Skills, served. The house skills β€” the working methods Tyler's sessions run on β€” now live in Appolis, with a version each, on a Skills tab beside the Rules. Every AI session that connects is told what is served and at which version, and installs or updates its own copy before it starts work; the owner publishes new versions with one command and a key minted on that tab.
.37
v0.37.0 β€” πŸ“‹ Every claim in one queue, with the proof one tap away. When an app says it has done what a directive asked, that claim no longer lands in the owner's Kosmos inbox β€” it goes to a Submissions queue inside Appolis's Compliance tab: newest first, awaiting his review on top, each row one line with a "See it" link to the page or screenshot that proves it, and Accept or Reject right there. A claim that says "this does not apply to us" carries its reason instead of a link. The directives themselves fold to one card each β€” a progress bar, one dot per app, the full requirement a tap away β€” and the template chip on any directive opens the reference build. The Kosmos inbox is for project decisions again. v0.37.1 β€” πŸ• A session closes its own time card. Every open card is kept alive while any of the owner's sessions works, a session can no longer clock out a sibling's card by mistake, a name you give your session shows on the board beside its id, the clock line lands on the right project even from a code folder, and the built-in rules β€” including the clock-in structure β€” now show on the Rules tab. v0.37.2 β€” πŸ• A shift is one piece of work. A session clocks in the moment it starts on a project and clocks out the moment that work is done β€” in the same breath it reports it, even when the commit still waits for a deploy window. Waiting on a person is not a shift. A forgotten card shows as unclosed after an hour instead of four, and clocking in tells a session what it left open. v0.37.3 β€” the clock-in and clock-out lines on a Kosmos board always keep the card's id at their end, so Kosmos can fold the two into one row even when the intent ran long. v0.37.4 β€” πŸ“œ Rules as cards. Each platform rule is one card: its number, its title in bold, the rest behind "read all". Tap ✎ to edit it right there; the change saves the moment you leave the box, and βœ• asks before it removes anything.
.36
v0.36.0 β€” πŸ• A shift is a claim. Clocking in now takes a lane β€” a project, an area, a note, or a code folder β€” and holds it while you work, so two people or two AIs can no longer land on the same thing without one of them being told, by name, who is already there and what to do instead. Your own AI simply works under your shift. A shift that goes quiet is reported, never hidden; one that ends must say what changed, what was verified and what was only assumed. The owner picked this by looking at it β€” a page showing today beside proposed β€” and the same afternoon two sessions had shipped the same app a minute apart without seeing each other. This is the part that lives in Appolis; the part that refuses the edit itself lives in Kosmos next. v0.36.1 β€” within hours, three sessions found that the registry treated two of the owner's own sessions as the same seat and turned the second away even on a different lane. Fixed the way the rule always meant it: a collision is between lanes, not accounts β€” parallel sessions on different lanes coexist, and only the same lane is refused. Also: the registry can now be read per person, clocking out works through the connector that had been splitting the card, and the hub can honestly say "I could not read the registry" instead of pretending it was empty. v0.36.2 β€” 🌐 A person's own domain now counts. The owner tried to let Scott send from his company address and the panel turned him away twice: it said the domain was "registered already" (it was β€” that is good news, not an error) and Scott's row could never say "ready", because the list of sending domains quietly kept only the suite's own. Now a domain Resend already holds is picked up with its DNS records, a person's domain stays on the list, and "Check domains" asks Resend to verify the records you pasted instead of waiting for someone to press a button in another dashboard. v0.36.3 β€” πŸ• The heartbeat finds the right session. When the owner had two or three AI sessions working at once, only the oldest one's time card was being kept alive by the work β€” the others could be marked abandoned while they were mid-task, and a lane marked abandoned can be taken. Now each session is handed its own id when it connects, its time card carries that id and a readable label instead of a blank, and every tool call keeps that session's card alive (or all of the account's cards, for a client that does not send the id back).
.35
v0.35.0 β€” 🚫 No more scrollbars. The grey bars down the side and along the bottom of a panel are gone everywhere in the city. Everything that scrolled still scrolls exactly as it did β€” swipe on a phone, wheel on a desktop β€” the bar itself just stopped taking up room and stopped nudging things out of line. It is one rule in one shared place rather than a patch per panel, a test now fails the moment anything brings a bar back, and it is a rule the whole suite owes from today.
.34
v0.34.0 β€” πŸ‘€ A real person, at their own company's address. Some invitations should look like they came from a named person at the customer's own company, not from Appolis. Now the owner can pre-authorise one specific address for one specific app β€” and only after the mail service has actually proved that company owns the domain. An app can then ask to send as that person, but it can never pick an address of its own and it can never borrow a name. Adding a sending domain hands the owner the exact records to set up, and they sit on a sub-name, so a company already receiving its mail through Microsoft or Google keeps receiving it untouched.
.33
v0.33.0 β€” πŸ‘€ See it before you say yes. When something about how the city looks or works is up for decision, the owner no longer reads a description of it. He opens one page that shows the real thing as it is now beside how it would be, and says yes or no right there. The same question also lands in his inbox as a one-tap form, so an answer is never trapped behind a single screen. v0.33.1 β€” the first thing decided this way: the Rules page now says plainly that the rules are the owner's and the platform's, that nobody else can set them, and that the way the city itself looks and works is not up for customisation.
.32
v0.32.0 β€” ❓ One tap decides it. Every question the city has for the owner now arrives in his inbox as a form he answers with a tap, and the tap itself is the decision: an app's claim that it has complied is accepted or sent back in his own words, an idea from an app is approved or declined, and the form clears itself. Each rule also names which app built the example everyone else copies, so nobody has to invent the same thing five times.
.31
v0.31.0 β€” πŸ›  The cheap hands go first, and the owner answers with a tap. Two new rules for the whole city: every AI job goes to a Hephaestus specialist when one fits, through whichever door is open, and the most expensive model only directs; and anything that needs the owner's decision reaches him as a form, never a list to decode. The hub lives by both from this version: every session is told at connect which Hephaestus doors are open right now, and a suggestion filed by any app lands in the owner's inbox as a one-tap form.
.30
v0.30.0 β€” 🧩 Surfaces: the door is open. Something built inside an app β€” a theme, a member portal, a page β€” can now be put on the compliance wall by itself, from the wall, without a code change. It answers only to the rules that name it, in its own look, and the app it lives inside is told what it owes every time a session connects. FLIP HQ is the first one on the wall.
.29
v0.29.0 β€” 🚦 The member portal answers to the progress rule too. FLIP HQ, the portal members use every day on flipmylifenow.com, is now on the compliance wall for one rule: nobody waits without knowing they are waiting. And the wall learned a fairer habit for surfaces like it that were never full apps: they owe only the rules that name them, not every suite-wide rule at once.
.28
v0.28.0 β€” πŸ”Œ Hephaestus joins the connector. The agent factory now has its own door on the one Appolis connector: a master-admin session can see its roster of specialists, look one up, ask for a dispatch plan and read its ledger, through the same identity handshake every other app uses. The key that opens that door was minted and set on both sides without anyone ever seeing it.
.27
v0.27.0 β€” β›Ά Appolis fills the whole phone screen. Installed on a phone, Appolis now runs edge to edge like Hermes and Kosmos, without the phone's own back, home and recents bar eating the bottom of the screen. In a browser tab, the Hub has a β›Ά Full screen button that does the same, remembers your choice, and picks it back up on your next tap.
.26
v0.26.2 β€” 🧭 The Hub button now says so. The Appolis mark reads "Hub" on every screen, so nobody has to guess what the logo does. And when an AI session asks the compliance wall the wrong way, it is now told which word it got wrong instead of being handed the whole wall.
.26
v0.26.1 β€” 🩹 Three small things the check-up caught. Closing the Hub now puts you back exactly where you were on the page instead of at the top; the phone bar only appears once you are signed in; and if a start screen you chose is no longer yours to open, Appolis forgets it rather than apologising every time you arrive.
.26
v0.26.0 β€” 🧭 Appolis is no longer one long scroll. The admin's page used to be the city and then five whole panels stacked underneath it. Now there are departments β€” City, Identity, Compliance, Mail, Rules β€” one on screen at a time, in a single sticky row on a computer and a bottom bar on a phone. Tap the Appolis mark and the Hub opens as a control room: the live health of Appolis at a glance (version, open rules and who owes them, mail, accounts, teams, connectors), then every department a tap away, and a setting for where Appolis should open for you β€” remembered on your Appolis ID. Pop-ups now freeze the page behind them, and on a phone nothing scrolls sideways any more.
.25
v0.25.1 β€” πŸ› the rulebook can now name an app that isn't plugged into the AI door yet. The new agent factory, Hephaestus, was handed its first rule β€” and the rulebook had no row for it, no way to read it and no way to sign it off, because it only knew the apps wired into the connector. It now keeps a short extra list of apps without a door; they get their row and can be read and signed for, and the factory learns of its rules from its own task board until its door is built.
.25
v0.25.0 β€” πŸ—„ the rulebook's filing cabinet now has one clerk. Every app files its "we did it" claims into one shared record. Until now two claims arriving at the same moment could overwrite each other β€” and one such collision silently undid a rule change last week. The record now lives behind a single door that takes one request at a time, with a running copy kept where it used to live in case it ever has to move back.
.24
v0.24.1 β€” πŸ” the shared machine key no longer sits in a file that gets printed and committed. Every time Appolis was published, the publishing tool printed the first characters of that key to the screen, and the key itself lived in a settings file kept in version history. It now lives only inside the worker's sealed secret store β€” moved with no moment of downtime for the five apps that still present it, which keep working exactly as before. The key's value is unchanged; replacing it is a separate, planned job.
.24
v0.24.0 β€” πŸ“‰βœ… the control centre obeys its own two rules. Asking the AI connector "who owes what?" used to answer with the entire rulebook, four times over β€” about 100,000 characters β€” on the very app whose newest rule forbids exactly that; now it answers with a short list and hands over the full text only when you ask for one item. And the pop-up that tells you what Appolis is doing now also tells you how it ended β€” "βœ“ App saved Β· Done." β€” instead of just disappearing, because a screen that goes quiet looks the same whether the save worked or not.
.23
v0.23.4 β€” πŸ”§ three safety checks that could never fail now can. The "send a test email" button only knew who to send to on a brand-new install, never on the real one; the shared email design would quietly dress an app it did not recognise in Appolis's colours; and the check that stops mail leaving from outside our own domain was comparing a setting against itself. All three now stop and say what is wrong instead of passing. One finished directive was tidied off the open list, and one secret stays where it is for now β€” with the exact reason written down.
.23
v0.23.3 β€” 🎨 the "send a test email" button was sending plain text, from the one app that tells everyone else not to. The rule Appolis wrote for the whole suite says an email that would look the same with all its styling stripped out does not pass. Appolis's own test email had no styling at all β€” and it is the button other apps are told to use to prove theirs. It now goes out in the proper shell, wearing the colours of whichever app you are testing, and the message itself tells you which address it should have arrived from so you can check the two match. Found while auditing two other apps' sign-offs, not by anything breaking.
.23
v0.23.2 β€” 🚦 and if a screen already says it is loading, it does not get a popup on top. The third ruling of the same hour. A page that already shows "Loading your orders" where the orders will appear has answered the question; a second popup saying the same thing is noise, and noise is how people stop reading the things that matter.
.23
v0.23.1 β€” 🚦 the loading popup now sits in the middle of the screen and tells you what it is actually doing. The version an hour earlier had put it in the bottom corner with a line that just said it was still working β€” and the verdict was immediate: never in a corner, always a centre popup, and "waiting" is not information. So the popup is centred over a soft dimming of the page (which never blocks a click), and its second line says what is going on in plain words: "Fetching your apps, Appolis IDs, teams and settings", "Emailing a 6-digit code to your address", "Asking Resend which domains are verified". The show-me page was updated the same way, and the suite-wide rule now says the same to every app. v0.23.2, minutes later: one more ruling folded in β€” if a screen already shows its own specific loading message where the content will appear, it does not need a popup on top as well.
.23
v0.23.0 β€” 🚦 the thin flashing line at the top of the page is no longer allowed to be the only sign that something is loading β€” starting with Appolis itself. The ruling: every app must show something a person actually understands β€” a loading message where the content will appear, a card that names what is happening and counts the seconds, a proper progress bar, or a popup that says which step is running. The little line at the top may keep the card company, but it can never be the whole answer. Appolis was the first to break this: loading the city, or refreshing a panel after a change, showed nothing but that line. Now a small card in the corner says exactly what the app is doing ("Loading the city…", "Saving email settings…") with a running clock, and disappears the instant the work is done. The show-me page was rewritten to match, and the suite-wide rule was updated so every other app has to do the same.
.22
v0.22.1 β€” πŸ”’ a second, independent security review of the new email sender found six small gaps, and they are closed. None of them let anyone send as another app or from another address β€” that held. But an old shared key could have used up another app's hourly email allowance, a cleverly typed label could have read like another app's name in some mail programs, one bad request from any app could have made the admin screen say the whole mailer was broken, an unlikely name ("constructor") slipped past the list of real apps, and a long list of sending addresses could have pushed one of ours off the end. All fixed the same night, each with a test that fails if it ever comes back, and the admin table now updates itself after a test send instead of waiting for a reload.
.22
v0.22.0 β€” πŸ“§ every email now really does come from the app that sent it β€” including the address. Since 23 August the suite was meant to send each app's mail under that app's name, but one line of code threw the name away, so every message still arrived signed "Appolis" β€” the change announced two rows below never actually reached anyone's inbox. That is fixed, and it goes further: each app now sends from its own address β€” no-reply@kosmos.appolis.app, no-reply@hermes.appolis.app and so on β€” because those addresses were set up with the email provider today. The admin area shows a table of exactly what each app's mail will say it is from, checks with the provider which addresses are cleared to send, and the test button now reports the sender line that actually went out rather than the one it meant to send. If an app's own address is ever not cleared, its mail still goes out β€” from the main address, under the app's name β€” and the panel says so in amber instead of hiding it. Matching fixes are waiting in Kosmos and Hermes for their own teams to release.
.21
v0.21.0 β€” βœ‰οΈ emails are now properly designed, and the rule about them can finally be failed. The first attempt at branded email was rejected outright: it was three plain paragraphs wearing the right name. Worse, the rule written to govern it only asked that mail carry "its look" β€” so any app could have submitted the same thing and there would have been no grounds to refuse. Appolis proved that by doing exactly it. There is now a proper shared email design that survives Outlook, Gmail and dark mode, with each app supplying its own colour and mark so mail looks like the app rather than the platform. You can see it rendered for three different apps at appolis.app/email.html. And the rule now has six specific things that can each be checked, plus a plain fail condition: if the email would look the same with the styling stripped out, it does not pass.
.20
v0.20.1 β€” βœ‰οΈ the test-email button can now send as any app, so you can check the sender yourself. The previous release changed which name emails arrive from, but the button built for testing email could only ever send as Appolis β€” meaning the one tool for checking mail could not check the thing that had just changed. Now you pick which app to send as, optionally name the area it came from, and the confirmation tells you the exact From line it used, so you are looking at evidence rather than taking it on trust. Three real test emails were also sent and delivered, showing Kosmos, Hermes and Appolis identities side by side in one inbox. ⚠️ Corrected in v0.22.0: those three emails were accepted, but all three arrived signed "Appolis" β€” the app's name never reached the email provider until v0.22.0.
.20
v0.20.0 β€” 🏷 emails now arrive from the app that actually sent them, instead of all looking like Appolis. A sign-in code for a Kosmos document hub was landing in the inbox signed "Appolis", which is confusing and makes every message look like it came from the same place. Mail now says Kosmos, Hermes, Agora or Phantasia depending on which app sent it β€” and an app can name the specific area too, so a code from the Lander Chooser arrives from "Kosmos Β· Lander Chooser". The address behind it is unchanged for now: putting each app on its own email address means proving ownership of a separate domain for each one and building its reputation from scratch, so that is a separate decision. Apps still cannot pick who they appear to be β€” the name is worked out from which app is calling, never from what the message asks for, so one app can never send mail dressed as another.
.19
v0.19.0 β€” βœ‰οΈ the other apps can finally send email β€” and one finished feature has been sitting unreleased waiting for exactly this. Appolis holds the only email account in the whole suite, but nothing except Appolis itself could actually use it, so every other app was stuck. Hermes had a complete, fully tested invitation feature built and deliberately NOT released, because releasing it before email worked would have locked out someone already holding a link. That is now unblocked. The new door was built to the shape Hermes had already published rather than one of my own, and four of its rules came straight from asking the other app sessions first: an app can never choose who an email appears to come from, the real tracking number from the email provider is handed back so a bounce can be traced later, urgent things like sign-in codes are never queued behind slower mail, and a send can be safely retried without a client receiving the same invitation twice. If sending fails it says so plainly β€” it never reports success for an email that did not go.
.18
v0.18.0 β€” πŸ“₯ the apps can now send ideas UP, and signing in got the way you wanted it. Until now, when an app had an idea worth making a suite-wide rule, someone had to copy it between chats by hand. Now any app files it straight into a suggestion box on Appolis. Ideas there bind nobody β€” they wait for you. Your admin area gained a hub where each one can be turned into a draft rule with one click (you reshape it and decide what "done" means before issuing), or declined β€” and declining requires a reason, which the suggesting app is shown, so the box never becomes a black hole. The next Appolis work session is told about pending ideas the moment it connects, and a scheduled check builds a full plan for anything new and sends it to your phone for approval β€” nothing ever becomes a rule without you. πŸ”‘ And signing in now leads with the emailed code β€” type your email, get a code, you are in β€” with the password kept only as a backup until the authenticator app arrives. Tick "remember this device" (on by default) and that device stays signed in for 90 days.
.17
v0.17.0 β€” 🏁 handing work down to apps is now the normal way to get things done across the suite, so the machinery behind it was made safe enough to rely on. A rule can name one app or all of them, which means it works just as well for a single job on a single app as for a standard everyone has to meet β€” no more writing something up by hand and carrying it over. Before leaning on it, one real fault was fixed: if two apps filed their proof at the same instant, the second quietly wiped out the first, and nothing complained. Now a clash is detected and the work is redone against the latest state, so nobody's evidence disappears β€” and if it truly cannot settle, it says so loudly rather than pretending it saved. πŸ”’ Separately, the ordinary password sign-in has never limited how many times someone could guess; it now does, counted per computer rather than per person, so nobody can lock you out of your own account by deliberately failing your password.
.16
v0.16.0 β€” ♻️ the loading-indicator rule was rewritten, and it now says the opposite of what you would expect: show LESS. The first version told every app to make sure no wait went unexplained. Building it revealed the flaw β€” an indicator that appears for something already finished tells you that you are waiting when you are not, and one that appears on nearly every action stops being information and becomes furniture. So the rule now leads with restraint: something appears only when you are genuinely kept waiting, quick actions are answered by the button you pressed, and anything running quietly in the background never interrupts you at all, because you never asked it to run. Appolis had the same fault and fixed it β€” its indicator now waits far longer before showing itself, and it can be told to stay completely silent for background work. The show-me page was updated to match, including a new example where two identical three-second jobs run and only one of them is allowed to say anything.
.15
v0.15.0 β€” πŸ“„ every app now has to build its own show-me page, and that page is the proof. Saying "we did it" is words, and a convincing paragraph can be written about work that was only half done β€” the only way to catch that was to go and read the code, which nobody has time for. So each app has to publish a live page, at the same address on every app, where you click a button and watch each loading indicator actually run, in that app's own look. You can check it in thirty seconds instead of auditing anything. There is a deliberate honesty rule too: if an app genuinely has nothing slow enough to need a particular indicator, it has to say so and say why, rather than faking a slow job to look finished β€” a page claiming something the app does not really do is worse than a short honest one. Appolis now does exactly that about itself.
.14
v0.14.0 β€” πŸ‘€ a page where you can actually watch the loading indicators work: appolis.app/progress.html. Nothing in the portal is slow enough to see its own progress bar, which made the rule about them impossible to check β€” and impossible for the other apps to copy. So every pattern on this page runs a real slow job you can click: the thin bar at the top, a card that names what it is doing and counts the seconds while it does it, a button that locks and spins so you can see your click landed, a step-by-step bar for jobs where the total is genuinely known, and what a failure should look like. There is a deliberate one that finishes in a tenth of a second and shows nothing at all β€” because a bar that flashes on every quick action just looks broken. The page is in Appolis colours on purpose, with a note at the top saying so: every app has to build this in its own look.
.13
v0.13.0 β€” ✏️ you can now edit a rule you have already handed down, and add or remove apps from it. The interesting part is what happens to apps that already said they were finished. If you change what the rule actually requires, their tick is now against a rule that no longer exists β€” so instead of quietly leaving it green, those apps go back on the list marked "the rules changed, needs re-doing", and their assistants are told exactly what moved and warned not to just re-submit the old work. If you only fix a typo, tick the box that says so and nobody gets pulled back. And adding an app to the list never disturbs the apps that already finished. Removing an app keeps its evidence, so putting it back restores what it had proved rather than starting from scratch. 🎨 The progress-bar rule also gained a line: each app has to build it in its own look, not paste in the one from Appolis.
.12
v0.12.0 β€” πŸ“‹ you can now hand down a change that every app has to make, and see who actually made it. Write it once in the admin area β€” what must change, and what "done" concretely means β€” and every assistant working any app you name is handed it the moment it connects, and again on its next action if it was already running. It stays marked outstanding against that app until the app comes back and proves it complied: the version it shipped in, what actually changed, and how it was checked. A vague "done" is refused outright, and if an answer looks thin you reject it and that app goes straight back to outstanding with your reason attached. It is deliberately not the same thing as the standing rules above β€” those shape how assistants behave, this is work with a deadline. 🚦 And the first one is progress bars everywhere: nobody should sit waiting without knowing they are waiting. Appolis brought itself into line first rather than exempting itself β€” the whole portal now shows a bar whenever it is doing something, and every button that starts work spins and locks so you can see your click landed.
.11
v0.11.0 β€” πŸ”’ you can now sign in with a code emailed to you instead of a password. On the sign-in box there is a new option: enter your email, get a 6-digit code, type it in, you are in. Passwords still work exactly as before β€” this sits beside them, nothing was taken away, and no other app has been switched over yet. The code lasts 10 minutes, works once, dies if you ask for a new one, and dies after three wrong guesses. There are limits on how often codes can be requested, both per email address and per computer asking, so nobody can sit there guessing. One detail that matters more than it looks: the screen never tells you whether an email address has an account or not β€” it says "if that address has an account, a code is on its way" β€” because a page that says "no such account" is a free tool for working out who has one. And if the email system itself breaks, the person signing in cannot safely be told, so the admin area shows a loud red warning instead with the exact reason.
.10
v0.10.0 β€” βœ‰οΈ the city can send email now, and there is a place for you to set it up. Nothing in the whole suite could send so much as one email, which is why sign-in codes by email had nowhere to go. There is now a βœ‰οΈ Email panel in the admin area where you paste a Resend key and the address mail should come from, plus a button that sends a test. Two things it is deliberately honest about: the key goes in write-only and never comes back out to the screen β€” you only ever see the last few characters, so you can tell which key is installed without it being readable β€” and saving proves nothing. Only a test email that actually arrives proves anything, so the button says Resend accepted it and tells you to go and check the inbox, spam folder included. If it cannot send, it says so loudly with the exact reason rather than quietly doing nothing. The assistant rules everyone shares also gained a start-and-end-of-shift routine, and a rule that once you have decided something, an assistant builds it instead of arguing the point.
.9
v0.9.5 β€” πŸ”’ simply typing someone’s email address can no longer fetch their personal AI connection link. That link is a spare key to their whole account β€” it works on its own, acts fully as them in every app, and changing passwords or keys does not disable it. Until now, any app asking on someone’s behalf only had to name them. Proof is now required: the app has to hand over that person’s own signed sign-in pass. It shipped as two releases with checking in between, on purpose β€” the release before it first built the place people go to see their own link, because closing the old way before the new one existed would have stranded anyone who signs in with an app password rather than an Appolis one. Those people now use the portal at appolis.app.
.9
v0.9.3 β€” πŸ”’ the old shared password can no longer set anyone's password. One door let a caller name an email and write that account's password β€” the only place that old password could still change anything rather than just read it, and it only affected invited people who had not signed in yet, which is exactly who nobody is watching. It now demands each app's own key instead. Every app was moved over first, so nothing broke.
.9
v0.9.2 β€” 🧹 housekeeping on the keys the apps use to trust each other. One slot belonged to an app that never actually connects here and had no key in it β€” a lock with no door behind it, now removed before anyone could fill it by mistake. And Kosmos was given permission to enrol people into itself and nothing else, which is the first half of repairing two sign-up pages that have quietly been failing.
.9
v0.9.1 β€” πŸ”Œ the page that shows you your personal AI connection link now asks for proof of who you are. That link is effectively a spare key to your whole account, and until now simply naming someone was enough for one app to ask for theirs. Every app now quietly hands over your own signed sign-in pass when it asks, so the answer is tied to you rather than to a typed-in address. Nothing looks different yet β€” the old way still works on purpose, so nothing breaks while each app catches up.
.9
v0.9.0 β€” πŸ”‘ the master key that signs everyone's login has been replaced. One shared password used to do two very different jobs: letting the apps talk to each other, and signing every person's sign-in pass. That meant anyone who ever saw it could write themselves a pass as anybody β€” including you β€” with nothing to notice. Those jobs are now separate, with a brand-new key for signing that has never been written down anywhere. Getting there meant changing four apps in a precise order, because doing it the obvious way would have locked everyone out of three of them. Everyone signs in once more; that's the whole cost.
.8
v0.8.3 β€” πŸ”’ three more locks. A sign-in pass with no expiry date printed on it used to be honoured forever; now it's refused, so a faked one can no longer outlive everything. The admin screens now check which site a request actually came from, closing a gap where a page on a neighbouring address could ride your logged-in session. And an app asking to give someone access can no longer quietly hand them the admin level β€” only you can do that.
.8
v0.8.2 β€” πŸ”’ three quiet locks on the doors the apps use to talk to each other. Asking after a stranger's account now gives the same answer whether they exist or not, so nobody can go fishing for who's registered. Only a real email address can become an account, and names have a sensible length limit β€” one request can no longer bloat the list every sign-in depends on. And the "give this person an app" door can no longer be talked into handing over every app at once. Nothing visible changed; nothing you use broke.
…
v0.4.0 – v0.8.1 β€” the big middle: one Appolis ID for the whole suite, teams and the role ladder, installable apps, the single AI connector door, and the trust rewrite that gave every app its own key. Written up in the Blueprint; these showcase pages are still catching up.
.3
v0.3.0 β€” 🎟 named grants: a personal door per person (welcome banner greets them by name), revocable one at a time; grant keys never leave the admin view.
.2
v0.2.0 β€” the library became a layer: no standalone docs building; every app card carries πŸ“‹ Blueprint + 🎞 Showcase with a per-app visitor toggle (URLs stripped from public view until flipped).
.1
v0.1.0 β€” the city opens: apex Worker + KV catalog, master-key gate (fail-closed), public/unlisted/private tiers with rotating share keys, night-city UI, seeded with the whole fleet (all private).