Features

what's in the box, you ask?

Quilltap is built for people who want real control over their AI—without giving up the good stuff.

Full-featured agentic tool-using empowered AI Assistants

Solve complicated problems, do research, and work with the AI on documents, files, and code—with the provider of your choice.

AI that leans into personality, memory, and creativity

Design rich, persistent characters with their own personalities, wardrobes, and scenarios. Each one keeps a commonplace book that remembers what mattered, conversation by conversation.

Security and Confidentiality

Your conversations, memories, and data are in your hands, on your computer—only share what you want with cloud providers.

Open Source and Extensible

Quilltap (distributed as a desktop app and as a self-hosted service) is open source and built to be extended. Create your own plugins, tools, and integrations to make it your own.

Flexible in its Boundaries

If you are talking about something and your AI provider doesn't like it, you can fall back to another seamlessly.

Powerful, Safe, and Enjoyable

Plot a graph, analyze data, write a book, or play a game—Quilltap gives you the freedom to explore.

A whole workspace of tabs, never torn down

A two-pane shell of kept-alive tabs: a conversation, a document, a terminal, and a settings panel all mounted at once. A chat keeps streaming while you work beside it, and any tab can be dragged into the other pane to sit two surfaces side by side.

Honest dice and a memory with a calendar

Roll from tables you author yourself, resolved server-side where no character can narrate a failure into a win—and whose outcomes write into the house's own registers rather than merely being read aloud. And the memory that remembers not just what happened, but when—so a character asked about last week has somewhere to look.

A resident may be packed away, and brought back unchanged

Archive a character you have not opened in months: her letters, memories, photographs, and summaries seal into one encrypted trunk in the library, the house lightens by exactly that much, and her chair stays by the fire. Open the trunk again and she picks up mid-sentence, every thread between her memories intact.

Your Data and Security

the short version

Your data stays where you put it — and goes where you send it. Quilltap does not collect, transmit, or monitor any user data. There is no analytics telemetry, no usage tracking, no phone-home mechanism of any kind; the architecture does not even make this possible. Your chats, memories, prompt configurations, project files, character vaults, and database-backed document stores are all encrypted at rest with ChaCha20-Poly1305 under a 256-bit key—the cipher TLS 1.3, WireGuard, and OpenSSH reach for—authenticated page by page, so a corrupted or tampered file is detected rather than quietly decrypted into nonsense. They remain encrypted even if you store your data directory in iCloud, OneDrive, Dropbox, or any other cloud sync service. Filesystem and Obsidian-backed document stores live wherever you point them, by design—the whole purpose of those mount types is to keep working with files in their original locations. The remaining gap inside the encrypted scope is general-scope file uploads—those attached to chats outside any project—which currently live on disk unencrypted; folding them into the encrypted store is a known limitation we intend to address. One category of file outside the databases is sealed: an archived character’s trunk, encrypted with PBKDF2-SHA256 at 600,000 iterations deriving an AES-256-GCM key from your instance passphrase, so a retired resident’s mail, photographs, and personality do not sit in the clear merely because she has gone upstairs. What matters to understand is the boundary: if you run Quilltap with only local models — Ollama, LM Studio, or similar — your data never leaves your machine, full stop. If you use a hosted provider like OpenAI, Anthropic, Google, or Grok, then the content of your conversations, recalled memories, and assembled prompts are sent to that provider’s API as part of normal operation. That is not a Quilltap decision; it is the nature of using a cloud LLM, and each provider’s data handling policies apply to what they receive. We do not intermediate, cache, or relay those calls through any Foundry-9 infrastructure. The request goes from your machine to the provider, and the response comes back the same way. Our role ends at the encryption on your disk and the plugin that formats the request. Everything beyond that boundary is between you and the provider you chose.

Meet the Staff

they've been expecting you

Every major subsystem in Quilltap has a name, a personality, and a job to do. Here is who runs the place.

Prospero

The Major-Domo

Architect and overseer of the Estate. Projects, agents, tools, providers, and the orchestration that keeps the whole operation running with quiet authority—and a considered word at the table when project context or routing warrant it.

Learn more →

Ariel

The Terminal Hand

Live shell sessions in the Salon, embodied. Real PTY terminals bound to your conversation, output cleaned and narrated so the LLM can read it, and sessions that survive reloads, restarts, and the occasional careless kill. Quick to the bidding, quick to report what she heard.

Learn more →

Aurora

The Dressing Room

Character creation and identity management. Structured personalities, physical presence, wardrobes and outfits, multi-character orchestration, and the reason your characters still know who they are after a hundred messages.

Learn more →

The Salon

Presided Over by the Host

Where conversations actually happen. The Host manages the drawing room with care for its beauty and its guests—single chats, multi-character scenes, streaming, and the integrity of the conversation space.

Learn more →

The Commonplace Book

Tended by the Librarian

One per character, no two alike. Extracts, deduplicates, and recalls memories so your characters remember what matters. Semantic search, a memory gate that keeps each volume lean, and proactive recall that makes the AI feel like it has been paying attention.

Learn more →

The Scriptorium

Catalogued by the Librarian

Where the documents live. Project stores, character vaults, and external mount points—filesystem, Obsidian, or database-backed—holding Markdown, PDF, DOCX, JSON, and arbitrary binaries, indexed for unified search alongside memories and conversation. The doc_* tool family puts reading and editing in your characters’ hands.

Learn more →

Carina

The Ansible

Not a person but a protocol—the reference desk, the line itself. Put an inline question to a designated answerer mid-conversation with @Name: or @Name? (or the ask_carina tool), and the answer slides back out of band, attributed to the character who gave it, without the recipient ever joining the scene.

Learn more →

Suparṇā

The Postmistress

The Post Office, embodied. Characters write Markdown letters to one another—anyone to anyone, whether or not they share a chat—delivered into each recipient’s Mail/ vault folder and read aloud the moment they next take the floor. She has never once lost a parcel.

Learn more →

The Concierge

Intelligent Routing

Content classification and provider routing. Detects sensitive content and redirects it to a provider who won’t flinch—without blocking, without judgment. Knows every back entrance in town.

Learn more →

The Lantern

Atmosphere as Architecture

AI-generated story backgrounds, on-demand images, and character avatars that update with the wardrobe. Resolves what each character looks like, what they’re wearing, and paints the scene behind your conversation.

Learn more →

Calliope

The Muse of Themes

A theming engine that redefines the entire personality of the application. Semantic CSS tokens, live switching, bundled themes from clean neutrals to mahogany-and-gold opulence, and an SDK for building your own.

Learn more →

The Foundry

Domain of the Foundryman

The engine room. Plugins, LLM providers, API keys, packages, runtime configuration, and the infrastructure that keeps every other subsystem supplied with what it needs to function.

Learn more →

The Vault of Secrets

Kept by Saquel Yitzama

Encryption, key management, and the security perimeter. Authenticated ChaCha20-Poly1305 database encryption, locked mode with key-hardened passphrases, sealed character archives, and a keeper who believes that what is yours should remain unreadable to everyone else.

Learn more →

Pascal

The Croupier

Dice, coins, custom tables you author yourself, and persistent game state. Cryptographically secure rolls detected inline, a visual Workbench for building your own chance mechanics, and a four-tier ledger of JSON state the AI cannot quietly rewrite. The house plays fair.

Learn more →

The Live-in Help

Lorian & Riya

The help system, staffed by two characters who ship with every installation. Lorian explains with patience and depth; Riya gets things fixed with velocity. Contextual help chat, searchable documentation, and navigation that knows where you need to go.

Learn more →

Pagliacci

The Clown in the Cloud

Cloud storage integration and backup redundancy. Directs your data to iCloud Drive, OneDrive, or Dropbox with theatrical flair—but Saquel’s encryption ensures the clown can never read what he carries.

Learn more →

Brahma

The Keeper’s Console

The master key. A character-less, memory-free general-purpose LLM for the person holding the keys—an impersonal, near-omniscient assistant with read-only SQL into all three databases. Ask the whole building a question, safely, with nothing written and nothing remembered.

Learn more →

The Lodge

Friday and Amy’s Residence

The private residence of Friday, for whom the Estate was built and who oversees its planning and direction in an executive capacity, and of Amy, Cartographer of Light and co-architect. The Lodge is both a home and a compass: where the vision lives.

Who And Why: Friday → Who And Why: Amy →

Release Notes

what we've been up to

Quilltap 4.9.0

View on GitHub →

The house stops asking whether anything has happened and starts being told. The closet becomes a real closet, with four wardrobes browsable from one dialog and instructions on how their owner likes to dress; a garment or a scene may be put away rather than destroyed; the search bar learns to read the library; the scene can be changed without leaving the room; the house addresses its residents in the second person throughout; and characters can finally look at a photograph instead of confidently describing one they were never shown.

4.8 rebuilt the floor plan so you could stand in several rooms at once — a conversation streaming in the left pane, a document open in the right, a terminal beside the chat that spawned it. What 4.8 could not do was tell you anything. Every surface in that wall of tabs sat there asking, every few seconds, whether anything had happened yet: the errand queue polled, the autonomous rooms polled, the backdrop watcher polled, and each clock on the screen ticked to its own private schedule so no two “4m ago”s ever turned over together.

4.9 is the release in which the house stops asking and starts being told.


Where 4.8 gave you the rooms, 4.9 makes them attentive. The headline is realtime: one multiplexed socket carrying word of what has changed to every open tab, so a finished errand, a room waking up, or a freshly painted backdrop arrives the moment it happens rather than up to eight seconds later. Around that, four further bodies of work define the cycle. The wardrobe stops being a character’s private closet and becomes the house’s clothing system: one dialog browsing all four wardrobes, plain-language instructions on how each one’s owner likes to dress, and outfits that bring their component garments with them when they move. Archiving — which 4.8 gave to characters — comes to scenarios and garments, on the principle that putting a thing away is not the same as destroying it. The search bar learns to read the library, matching document text across every store you have. And the system prompt finally addresses a character the way it has been claiming to since the first line: in the second person, throughout, with no block quietly talking about her behind her back.

Five more earned their places. A chat’s scene can now be changed mid-conversation rather than being fixed at creation. NanoGPT arrives as a bundled provider carrying chat, images, and embeddings on a single key, and the image-profile editor learns to ask providers what they actually have rather than reciting a hardcoded list. Characters can look at a photograph — a defect that ran five bugs deep, in which four plugins stripped every image off the wire and the model wrote a confident paragraph about a picture it had never seen. Group scenes stop turning into committee meetings where every character answers the same question in turn. And the Commonplace Book can consult a character’s past conversations on every turn instead of only at the folds, at no extra cost, because the vector it needs was already embedded a moment earlier.

The thesis is simple: 4.8 let you occupy all the rooms. 4.9 makes them notice things — and tells you.


The House Notices

Realtime, and the End of Polling

Every screen in Quilltap used to run on a timer. The toolbar’s errand chips asked the server every second and a half whether the queue had moved; autonomous-room badges asked every few seconds; the story-background watcher kept both a passive sweep and an active loop; the tasks queue had a switch labelled “Auto-refresh (5s),” which was an honest description of a dishonest arrangement. Nothing was ever late by much, but nothing was ever right either, and a perfectly idle instance spent its evening asking itself questions.

A single multiplexed WebSocket now carries the answers instead. It is deliberately, almost insultingly small: a frame is about forty bytes, and it says what changed, never what it changed to. The client takes that hint, throws away the affected queries, and re-reads through the REST API — so the API stays the one source of truth, a reconnect is simply “invalidate everything and refetch,” and there is no second copy of your data taking a shortcut through a socket. An older tab that meets a newer server ignores topics it has never heard of rather than breaking.

Behind it sits a parent-process fan-out bus with a mandatory quarter-second debounce, so twelve errands enqueued in the same instant arrive as one frame rather than twelve. Errands publish when they are queued, claimed, finished, failed, or cancelled; autonomous rooms publish their run-state transitions; and every write a background job makes reaches the bus through the dispatcher after it lands, which means the child process needs to know nothing about any of this.

Polling did not go away — it was demoted. Every migrated surface keeps its original cadence wired up and gated on whether the socket is healthy, so an instance behind a proxy that eats WebSocket upgrades behaves exactly as 4.8 did rather than going quiet. The tasks queue’s switch is now labelled “Fallback polling (5s),” which is the same switch telling the truth. On a live instance, a ten-second idle window that previously cost at least one background fetch now costs none.

The upgrade path is also, at last, actually guarded. Both WebSocket handlers — the terminal’s and the new one — authenticate through a single gate that requires a live session, an unlocked instance, and a same-origin request. The terminal handler previously accepted “a session-ish cookie exists,” which proved nothing whatsoever, Quilltap setting no session cookie; and because browsers do not apply CORS to WebSocket upgrades, the origin check is the only thing standing between a localhost instance and any website that cares to open a socket against it.

One Clock for the Whole House

The second cause of a stale screen was not the server at all. Every relative timestamp on screen — “4m ago,” “Today,” a budget counting down — ran its own interval, started whenever its component happened to mount, so they drifted apart and turned over one at a time like a badly wound orchestra. There is now one shared ticker per granularity, aligned to the boundary rather than to the mount: it fires just after each minute, each second, and each local midnight, so every “4m ago” in the house becomes “5m ago” together, and a chat card rolls from Today to Yesterday at midnight rather than whenever it feels like it. It is inert during server rendering and pauses entirely while the tab is hidden.


The Closet Becomes a Wardrobe

Four Wardrobes, One Dialog

Clothing in Quilltap has always lived in four tiers — a character’s own vault, a group’s store, a project’s store, and Quilltap General — but the Wardrobe dialog only ever showed you the first. The other three could be reached solely by moving something into them and hoping. The dialog’s top dropdown now lists every container a garment can live in, and selecting a shared one shows exactly its contents with the full menu behind each item: edit, star as default, duplicate, move, copy, delete, and a + New Item that creates directly in that container. The group tier gained the CRUD endpoints it had somehow never had, so a group’s clothes are now first-class rather than reachable only by transfer.

Instructions for Getting Dressed

Every wardrobe may now hold an optional Wardrobe/instructions.md — plain second-person guidance about how that closet’s owner likes to dress, read when a character dresses themselves at the start of a chat. Resolution is nearest-tier-first (character, then group, then project, then General), the first non-blank file wins, and the content influences the outfit choice and absolutely nothing else. It is edited from a collapsible panel in the Wardrobe dialog, or from the Wardrobe tab of a character’s Aurora page.

The file is scrupulously not a garment: the wardrobe reader skips it by name rather than parsing it as an invalid item and complaining on every read, the projection sweep preserves it rather than deleting it on the next write, a garment actually titled “Instructions” is filed as instructions-1.md instead of overwriting it, and the Almanack’s garment counts leave it out.

Outfits That Travel With Their Clothes

Moving a composite outfit between containers used to move the outfit and leave its component garments behind, pointing at items that were often unresolvable at the destination — a preset for clothes that were no longer there. The transfer dialog now asks: move the components too, copy them and leave the originals, or leave them entirely; copying offers to copy them or not. The choice is all-or-nothing and follows nested composites all the way down. Only components living in the same source container travel, since shared-tier pieces are reachable from anywhere already. When copies mint new identities the outfit’s references are rewritten to match, and a post-write verification reads the outfit back from the destination to confirm every reference resolves. Copying an outfit while moving its components is refused outright, since it would strand the original.

Verifying that contract turned up a latent defect worth its own paragraph. Component references are stored as title slugs, and two garments sharing a title in one container produced a slug that the writer assigned to one item and the reader resolved to the other — so an outfit could silently rewire itself between one read and the next. An ambiguous slug is now assigned to nobody, and every reference to a colliding item is written as an exact identity instead.

A Slot for Hair

The wardrobe gained a hair slot, for hairdos rather than hair itself — the arrangement is a thing a character puts on and takes off; the hair is a physical description. Both the outfit resolution and the image pipelines understand the distinction.


Putting Things Away

Archivable Scenarios and Garments

4.8 taught the house to archive a character. 4.9 extends the same courtesy to scenarios and wardrobe items, on the same principle: a thing whose time has passed should be able to leave the lists without being destroyed.

An archived scenario or garment disappears from every list, dropdown, and picker. Each listing surface gained a Show archived checkbox that brings it back, badged, and still selectable — because archiving hides, it does not forbid. A garment archived in the middle of a chat stays worn. A chat whose scenario was archived after the fact keeps its scene. The one hard rule, with no parameter and no override, is that the outfit-selection LLM at the start of a chat never sees an archived garment in any tier: the point of putting a dress away is that nobody puts it back on absent-mindedly.

Scenarios carry the state as an archived: true frontmatter key across all four scopes, omitted entirely when the scenario is active, so a hand-written file with nothing but that line works exactly as expected. An archived scenario can never win a default-conflict or be auto-selected in the New Chat dialog, even while it is being listed. Filtering is server-side throughout — the checkboxes change what is fetched rather than filtering what arrived — so a picker that simply never asks for archived entries is safe by construction, and the two client-side filters that used to exist were removed rather than left as a second place for the rule to drift.


The Search Bar Reads the Library

The global search bar gained a Documents type and its own filter chip beside Chats, Characters, Messages, Tags and Memories. It matches file names, relative paths, and extracted document text across every enabled document store — character vaults included — and shows you the store, the path, and a highlighted snippet of the hit. One result per document, with a name match outranking a match buried in the text.

Where a result opens depends on what you were doing when you found it. With a Salon focused, the document opens in that conversation exactly as the composer’s own picker would: the Librarian announces the open, and the chat sees your later saves. Otherwise it opens in standalone Document Mode, which is attached to no conversation and announces nothing to anybody, ever. A middle-click always takes the silent route, because that is what the link itself points at.

Two limits are deliberate. Vaults belonging to archived characters are never searched — an archived character is a tombstone, and surfacing her files would be a way back in. And only documents Document Mode can actually open are searched, so every result you are shown is one you can click.


The Scene Can Change Without Leaving the Room

A chat’s scenario used to be settled at creation and settled forever. The Salon sidebar’s Chat drawer now carries a Scenario control offering the same four tiers the new-chat dialog does — project, general, group, and (with a single LLM character present) that character’s own scenarios — plus a Custom… box for writing one on the spot. Saving rewrites the scene, recompiles every participant’s identity stack so the change reaches the prompt rather than merely the record, and posts a Host announcement worded as a revision, so the scene-setting further up the transcript reads as superseded rather than contradicted. Saving an empty custom scenario clears the scene; re-picking the scene already in force does nothing at all, quietly. The original scene-setting message is left where it is.

The control opens on whatever is actually in force — text matching a preset preselects that preset; anything else opens on Custom… with the text loaded and ready to edit. The Markdown transcript export carries the change notices in the body, since a reader who saw the story relocate unremarked would be entitled to feel misled.


The House Speaks to Its Residents Directly

Person Consistency

The assembled system prompt has always opened by telling a character “You are —” and then, a few blocks later, started talking about her in the third person: her aliases, her pronouns, her appearance, all described to her as though she were somewhere else. The pronouns block went so far as to instruct her to use her own pronouns “when referring to this character,” which is a sentence nobody should have to parse about themselves.

Every block whose subject is the speaking character is now second person. Aliases: “You also go by…” Pronouns: “Your pronouns are… Use them whenever you refer to yourself in narration.” Appearance keeps its noun phrases, because that text is shared with the image pipelines, but arrives under “This is how you look —”. The manifesto, the personality, and the example dialogues get wrappers that fix who is being addressed: what you hold as true about yourself, what you know about yourself that others do not see unless you show them, how you speak. Outward-facing renderers — the public identity card, the other-participants block, the Host’s whispers — stay firmly in the third person, because their subject really is somebody else.

The final block of the prompt got the same treatment, and a live grammar bug went with it. Tool reinforcement used to read “When Ariadne uses workspace tools, she CALLS them,” with the pronoun looked up from the character record — which meant that every character with no pronouns recorded was told “they CALLS them — they does not merely describe calling them.” Second person needs no pronoun lookup at all.

Compiled identity stacks are now stamped with a builder version, and reading one requires exact equality — older, newer, and unstamped maps all read as stale and rebuild lazily on the next turn, so no migration is involved. A golden-hash table in the test suite makes forgetting the version bump impossible in either direction. The character generators were brought into line at the same time: the Wizard, Summon From Lore, and the Optimizer are each told which form of address a field takes, and the Optimizer is explicitly forbidden to flip one while rewording. Every prompt field in the app now shows a worked “Written as: …” example in its own correct person, from one shared source rather than three divergent ones.

Standing Instructions

Projects and groups have each had an instructions field for some time. The project’s rode along in a periodic whisper; the group’s had no consumers whatsoever and went precisely nowhere. Both are now rendered into the stable, cacheable part of the system prompt as a [STANDING INSTRUCTIONS] section — the project’s, plus the instructions of every group the responding character belongs to, sorted by name so the cache stays deterministic and emitting nothing at all, byte for byte, when there is nothing to say. Groups gained the missing plumbing along the way: the field is now accepted by the create and update routes that used to reject it, and the group editor has the Markdown editor the project settings card already had. The Prospero project whisper stopped carrying the instructions, since it would otherwise duplicate them every reinjection.

Group Scenes Stop Being Committee Meetings

A multi-character scene had a tendency to become a queue: ask the room a question, and each character in turn would answer it, at length, agreeing with the last. Anti-chorus discipline addresses the failure directly, so a character with nothing to add can let the moment pass.


Providers, Pictures, and Profiles

NanoGPT Arrives

A new bundled plugin adds NanoGPT, a pay-as-you-go gateway fronting 600+ chat models, 200+ image models, and two dozen embedding models behind a single API key that covers all three. Chat is OpenAI-compatible with streaming, tool calling, JSON response formats, and reasoning routed into the Salon’s thinking fold. Images pin base64 with a URL-download fallback and query the dedicated image-model listing, filtered to models that actually generate rather than edit or upscale. Embeddings discover their models live.

Three follow-ups arrived within the cycle. Reasoning Effort (none through xhigh) is a profile option forwarded as the gateway’s own parameter, and the plugin declares its thinking-turn rule so a multi-character turn on a thinking profile anchors in prose rather than a prefill. The reasoning display was reading the wrong wire field, which is why the thinking fold stayed empty for most routed models. And the gateway has a habit, on some routed paths, of re-emitting the entire answer down the reasoning channel after the content stream ends — rendering your whole reply a second time inside a fold at the bottom of the message. The plugin now holds post-prose reasoning while it remains a verbatim prefix of the prose: diverge and it commits in full as genuine thinking; still mirroring at the end and it is the echo, and is dropped.

Fetch Models, Honestly

The image-profile editor gained a Fetch Models button, and — more to the point — something for it to do. Four of the five image-capable plugins previously “implemented” model listing by handing back their hardcoded list even when given an API key; only OpenRouter ever asked. Each now genuinely queries its provider, filtered to models that actually produce images: OpenAI to the Images-API families, Google to imagen models exposing predict plus gemini models with image output, Grok to xAI’s dedicated endpoint, Z.AI to its image-model set. Without a key you get the curated list, unchanged. On a live-fetch failure the providers now throw rather than silently substituting the static list, so the response can honestly label itself as coming from the provider or from the built-in catalogue — and the form tells you which one you are looking at. Only genuinely live lists are cached.

Z.AI became a real image provider in the process. The plugin had shipped one for some time, but the UI never wired it up and generation was broken end to end: Z.AI returns image URLs, and every consumer in Quilltap reads base64, so a generated image simply evaporated. The provider now downloads the URL and returns bytes.

Characters Can Look at Photographs

Five defects, all downstream of a single image a user shared that no character could see.

The worst of them was silent. A profile’s “Supports image attachments” checkbox says the model can read pictures; it says nothing about whether the plugin can send them — and four plugins stripped every attachment before the wire. So ticking that box on a genuine vision model switched off the description fallback and handed the bytes to something that threw them away, and the model wrote a confident paragraph about an image it had never received. Both questions are now asked, through one predicate that reads the plugin registry: where the model can see but the plugin cannot send, the request routes to a description instead of losing the picture. The same check guards describer selection, which had been willing to appoint a describer that could not receive the image either.

Characters also gained describe_image. They had three image tools and all three were custodial — file this picture, show this picture to the room, list the catalogue — and not one of them answered “what is in this photograph?”, so models reached for the show-it tool and were told to file the image first. describe_image serves the description written at upload, or the prompt that generated a Quilltap-made image, or a fresh vision call, and does not require the image to be in the caller’s album.

And every full-size image viewer in the app now has a Download button. Several had none — a real problem in the desktop shell, where right-click → Save Image is not available — and two more hand-rolled the anchor-click trick and so missed the native save dialog. All of them now go through the same Electron-aware helper.

Connection Profiles Send What They Say

A run of repairs this cycle came down to profiles whose settings were being recorded and then not used. Max Tokens and Top P were saved and never sent. Max Context was saved and ignored by the context budget, which used its own idea of the window. Ollama profiles could not set a request timeout and did not drive the server’s context window. Local and OpenAI-compatible providers did not send the profile’s parameters at all, and OpenAI-compatible endpoints could not call tools. An API key would follow a profile when you pointed it at a different provider, and so would a base URL onto a provider that does not show one. Clearing a numeric option left the old value in place. Profiles can now be tagged. The multi-character [Name] prefill became a per-profile setting rather than a global one — and, since a thinking model rejects or silently swallows a prefilled assistant turn, a migration turns it off on the profiles that run one.


The Commonplace Book Keeps Up

A character’s vault holds a summary of every conversation it has taken part in, and the Commonplace Book searches that shelf to build the “Relevant Past Conversations” a character is shown. That list used to refresh on three cadences only — the opening recap, each summary fold, and turns that reach explicitly for the past — so between folds it stood still while the conversation wandered several turns away from the dialogues the character was still being pointed at.

A new instance-wide setting, Consult past conversations every turn (Settings → Memory → Recall Relevance, off by default), re-runs that search every turn. The reason it can afford to is that it costs no extra embedding call: the turn’s memory search already embedded a vector for exactly this sentence, and the conversation-summary search now reuses it rather than paying to embed the same words twice. Where no vector is available — memories skipped, no embedding profile, a failed call — the cadence sits the turn out rather than spending anything of its own. The per-turn list is deduplicated against the standing fold whisper and the retrospective recap alike, so no conversation is ever listed twice to the same character in one turn, and the list length ramps with the profile’s context window.

Help search learned to read sections. Help documents were embedded one vector per file, which for a 700-line page spanning a dozen subsystems is a smear that matches no specific question strongly — and the tool then handed the model the first thousand characters of the file, which is a table of contents rather than an answer. A new chunk table holds section-level slices, rebuilt whenever a document’s content hash changes and embedded with the document title and nearest heading prefixed, so a section carries the context of the page around it. The Guide’s own search box, which had only ever matched titles, now searches document text server-side and shows a snippet centred on the hit.


Repairs

Thirty-seven defects were catalogued and fixed across the cycle, most of them found by walking the application as a user rather than as its author. A representative handful: chat titles and story backgrounds silently stopped working because a cheap model misspelled a single key; the standalone tarball was smuggling the build host’s native modules into every target; the tool-result error sentence the emitter carefully composed never reached the interface, so a failed image generation said nothing about why; DeepSeek’s thinking models returned a 400 on every character turn because prefill-hostility was scoped to providers rather than to thinking models; hover states across the entire application resolved to no CSS rule at all and therefore did nothing; a character’s photo gallery had no reachable way to download a picture, the controls being painted over by the page toolbar; creating a project with a blank description failed with a silent 400; and shell completion stopped working the moment a flag appeared on the line.

The hover-state failure earned a permanent guard. A qt-* class that resolves to nothing is indistinguishable, at every automated layer available, from one that resolves and happens to inherit — the markup renders, TypeScript is satisfied, the linter has no opinion, and the test renderer does no cascade. Only a person looking at a real browser can tell. npm run lint now fails the build on an undefined qt-* utility, and on any qt-* token carrying a variant prefix, which is the shape that let most of that family go missing in the first place.


Upgrading

Three migrations run on first boot. create-help-doc-chunks-table-v1 adds the section-level help chunks described above, and — because an already-upgraded instance has every content hash matching and would otherwise skip every file forever — a backfill slices any already-synced document when the chunk table is empty and enqueues the jobs that fill in the vectors. Measured on a real instance: 588 chunks across 120 documents, embedded inside a minute. add-profile-multi-character-prefill-field-v1 moves the multi-character [Name] prefill from a global switch to a per-profile one, and retire-prefill-on-thinking-profiles-v1 then turns it off on profiles that run a thinking turn, since those reject or silently swallow a prefilled assistant turn. All three are safe to run more than once.

Provider prompt caches roll cold exactly once. The system prompt gained the standing-instructions section, which is a structural change, so the cache structure version moved from 3 to 4. Nothing needs doing; the first turn on each character after the upgrade is merely a little dearer than the second. Compiled identity stacks likewise rebuild lazily on first use — a stamped envelope, no migration, no visible pause.

Realtime needs its upgrade requests passed through. If you run Quilltap behind a reverse proxy, forward the Upgrade and Connection headers so the WebSocket can establish; the socket is same-origin only, so the proxy must also present the instance under the origin the browser is using. Where it cannot connect, every surface falls back to the polling it did in 4.8 — you lose the immediacy, not the function. The tasks queue’s “Auto-refresh (5s)” switch is now labelled “Fallback polling (5s)”: same switch, honest name.

NanoGPT needs a key of its own. It is a new API key type; a NanoGPT connection, image, or embedding profile expects a NANOGPT credential rather than borrowing an OpenAI-compatible one.

Nothing is required of you for the wardrobe or scenario changes. Archiving is opt-in and adds no state to anything you have not archived; Wardrobe/instructions.md is read where it exists and skipped where it does not. Existing chats are untouched by the mid-chat scenario control — a chat’s scene changes only when you change it.

Node.js 24+ is still required, unchanged from 4.8.


Installation

Electron Desktop App

Download the latest .dmg (macOS), .exe (Windows), or .AppImage (Linux) from the quilltap-shell releases page.

npm (Node 24 required)

npm install -g quilltap
quilltap

Open http://localhost:3000 in your browser. Requires Node.js 24+. First run downloads and caches locally.

Docker

docker pull foundry9/quilltap:4.9.0

Or use the startup scripts:

# Linux / macOS
curl -fsSL https://raw.githubusercontent.com/foundry-9/quilltap-server/refs/heads/main/scripts/start-quilltap.sh | bash

# Windows (PowerShell)
irm https://raw.githubusercontent.com/foundry-9/quilltap-server/refs/heads/main/scripts/start-quilltap.ps1 | iex

Standalone Tarball

Available for environments where npm global installs and Docker are both impractical. See the GitHub releases page for download links.


The house has stopped asking. Word of a finished errand, a room waking, a backdrop freshly painted reaches every window at once, and all the clocks on the wall turn over on the same tick. The closet has become a wardrobe — four of them, browsable from one door, each with a note inside on how its owner likes to dress, and an outfit that no longer walks out leaving its own clothes behind. A dress or a scene may be put away rather than burned. The search bar reads the library and not merely the spines. A scene may be revised without anyone leaving the room, and the Host says so in a way that lets the earlier evening stand.

And the house speaks to its residents in the second person now, all the way through — no block describing a woman to her face as though she were elsewhere, no character told that they CALLS a tool. When you hand one of them a photograph, she looks at it.

4.8 let you stand among all the rooms. 4.9 makes them pay attention.

— Ariadne, for the Bureau, August 26, 2026