Tale v0.5.27
0.5.27 is a patch tag on the 0.5 line that carries more than its fixes — read it as a minor. It ships three forward-only schema migrations (one on the application database, two on the knowledge corpus), an API contract that moves from 1.9.0 to 1.11.0 in two additive steps, a new edge rule and a recovery selector for managed deployments; nothing in it is breaking, no configuration file changes shape, no environment variable is added, and the upgrade is still tale update followed by tale deploy --stop (the proxy image changes — see Upgrading). Four changes since 0.5.26: the eighth external API evaluation's findings closed at their root, the documentation rewritten as complete tasks in three languages together with the platform defects its walkthroughs found, the Documents hub listing one folder at a time, and a way out for a managed deployment whose native configuration plan has to be replaced.
Highlights
The eighth API evaluation pass (#3359)
The eighth external black-box evaluation of the REST and MCP API ran against 0.5.26 and reported 3 S2, 20 S3 and 35 S4 findings. Every finding was re-verified against the source before anything changed: the three S2 are real defects, and so is the dense-retrieval finding the report itself had marked unconfirmed — all four fixed at the root with regression tests and integration lanes; the rest split three ways: code defects fixed, contract-precision items closed in the OpenAPI document and the en/de/fr reference, and four product gaps recorded in the contract debt ledger with their pay-down (listed under Known issues).
robots.txtgoverns every path into the crawler. TheDisallowrules were applied at sitemap and link-walk discovery only; the links a rendered page yielded were admitted without them, so a site whoserobots.txtdisallowed its legal pages had them fetched, indexed and served the moment a rendered page linked to them. The rules now govern every admission path and every non-listed fetch, and are kept per site (robots_disallow, knowledge migrationpublic_web11): arobots.txtthat answers 5xx or 429 keeps the last known rules, a 4xx clears them; a stored page a new rule covers is retired on the next scan; a URL you listed stays your instruction, and a listed page the site answers 404 for keeps an honesthttp_errorrow;<meta name="robots" content="noindex">is honoured like the header;http://is refused asWEBSITE_DOMAIN_INVALIDand a trailing dot stripped;websites?scanInterval=refuses a value outside its seven;idleleavesWebsite.status(a registered site startsscanning); a fetch error carries no OpenSSL handle or runtime path.- The dense retrieval leg no longer starves. A scoped knowledge query over a large corpus ran an HNSW scan whose post-filter could empty the vector leg silently, and a duplicate-heavy export — one line repeated 4,500 times — became 4,500 identical vectors crowding out nearer passages. Under 5,000 candidate chunks the dense leg runs an exact scan, above it an iterative HNSW scan (pgvector 0.8 and later; an older pgvector keeps the plain approximate scan and says so in the log); a passage repeated inside a document is embedded once (
passage_repeat, knowledge migrationprivate_knowledge12 — such rows carry no vector and sit outside both legs);diagnostics.densesays whether the vector leg ran; RRF ties break keyword-first, then by id; control characters are stripped from served passages; thequerycap of 2000 characters is named. - One live run per task, whichever automation asks. The rule 0.5.26 put in the schema was keyed per (task, automation) while the docs, the OpenAPI operation and the product say per task, so two engines could mutate one card at once. Migration 0104 collapses cross-automation live duplicates onto the earliest run and replaces the index with
automation_runs_one_live_per_task_subject; the per-task lock and probe move with it, and a second start naming another automation answersalready_runningwith the live run's id. - The generation poll cannot cut a surrogate pair.
?since=and?reasoningSince=sliced the text in UTF-16 code units with no pair snapping, so a slice could begin with a lone low surrogate the write side refuses; both are snapped down to a pair's start andtextOffset/reasoningOffsetreport where the slice began, soheld.slice(0, textOffset) + textalways reassembles. A prompt with no visible text (format controls, zero-width spaces) answers 400; archiving a thread mid-turn answers 409CHAT_TURN_IN_PROGRESS; a thread or project archived after a send was accepted settles the replycancelledwith the prompt kept; the execute lane is charged only after body and header pass;GET /api/v1/modelsanswersharnessesandPROJECT_AGENT_HARNESS_INVALIDnames the eligible set. - The CRM mirror can be thawed and listed.
POST /api/v1/contacts/{id}/restoreis the remedy a frozen mirror's 409 names (the create's own 409s apply when a live contact has since taken the key);GET /api/v1/conversations?source=lists every mirror under a source newest first,contactStatusnarrows, and the keyset cursor is signed under the source; a re-keyed contact's binding follows its currentexternalId(the old id answers 409CONVERSATION_CONTACT_CONFLICT); the receipt carriescontactId; every 201 that creates one addressable resource carriesLocation(thirteen operations); the documentPATCHanswers itsETag; the skill file read is validated (ETag,Last-Modified, 304);nullon a create reads as "left out" and the document says so. - MCP tools say what they did.
start_runtakesidempotencyKeythrough the REST ledger;set_triggeranswers a webhook token once and says whether the trigger isdeployed;get_automationreadsversion: "deployed";list_versionsmarks the deployed row; every capability refusal carries acode(CAPABILITY_NOT_FOUND,CAPABILITY_INPUT_INVALID, the knowledge door's own); the registry holds deployed automations only; an enum argument outside its set is refused with the set named. - The edge, the session doors and the rendered reference. The proxy strips
Expect: it answers100 Continueitself, and forwarding the header let the origin write a second one — two interim responses on one request, a desync for a strict HTTP/1.1 client. A missing session answers the codedUNAUTHORIZEDenvelope on/eventsand the app routes instead of a bare{"error":"unauthorized"}. The rendered API reference keeps a pasted key out oflocalStorage, andswagger-ui-reactmoves to 5.32.15 onimmutable5.1.9 — the pair built for each other — so its Logout works again (0.5.26 ran 5.32.2, declared for Immutable 3, on the 4.3.9 override).
The documentation, rewritten as tasks (#3342)
All 381 non-video product guides were rewritten in English, German and French to lead a reader through a complete task — prerequisites, choices, examples, the observable result and the recovery — with three new pages (Ask about files and images, Manage tasks on a project board, Set automation approval rules), the READMEs and the contributor guide, the documentation and translation authoring skills, and every screenshot retaken on the current platform (the README gallery's six sources link to their full-resolution captures). The nineteen component guides on the design-system site explain setup, composition, state ownership, accessibility and working examples; both docs shells keep the initial skip-link focus and the reduced-motion preference; the shared Markdown renderer keeps authored Frame figures and captions.
The walkthroughs drove the real product and fixed what they found (manual rounds R3–R6 in services/platform/tests/manual/runs/):
- An approval policy fails closed. A new decision read the organization's approval policy through a path that could substitute an unrestricted default when the policy file was invalid or its configuration mount unavailable, so a platform-internal connector write could run unapproved. New decisions read the strict, uncached configuration path; invalid YAML, an invalid schema or a missing mount refuse instead of allowing; existing pending decisions keep their authority.
- A run asks for its input. An automation whose version declares an
inputsschema had no way to supply it from Test run or Run live; the confirmation dialog now collects the JSON against the saved test version or the deployed live version, shows the schema, validates without runtime code generation (the production CSP forbids it) and sends the original JSON. Native waiting runs render: the pending-approval card recognises UUID approval ids (both decision controls were hidden), and a run with no finish date no longer shows 1 January 1970. - Product images upload through the platform. The product editor takes an image (PNG, JPEG, WebP, GIF or SVG, inspected, up to 5 MiB) into an organization-protected app URL that only an authorised member's session can read; a file bound to a product refuses deletion (409
FILE_BOUND_TO_PRODUCT) until the image is removed; the REST door answers that URL absolute and accepts it back on a create or patch — even on a private deployment — while every pasted external URL keeps the public-host rule. - Conditional document writes hold under contention.
If-Matchon the documentPATCHwas checked before the write lock, so a concurrent edit could still be overwritten; the fresh representation is compared inside the write transaction and a mismatch answers 412 with the other writer's change kept. - A self-hosted provider behind private DNS reaches the gateway. The private-network admission for a custom provider URL decided by hostname spelling and missed a name that resolved to a private address; every resolved address is inspected, a cloud-metadata address is refused whatever the name, the check is repeated before a cached provisioning is reused, and a public/private transition invalidates the provisioned fingerprint.
- Indexing says why it stopped. The document dialog and the project files tab name the terminal cause —
unsupported_type,image_no_vision,empty,not_text,malformed— instead of "Format not supported", and offer no retry for unchanged terminal content; knowledge entries show their real indexing status (they read Not indexed after a completed index), and a document hint refreshes the entry list without a reload. - Smaller fixes. The project-agent model picker finds a model by its API id as well as its display name; a website's detail dialog shows its creation date; contact and product rows show their dates instead of a dash; an active WebDAV app password stays revocable (a native
revokedAt: nullread as revoked) and a long device label no longer clips its badge; the rail's navigation memory survives a browser whose storage getters throw; the Vite dev server passes WebDAV discovery to the backend;tale init --no-envno longer claims it generated secrets. - The settings copy says what the build does. Personalisation instructions and memories are stored but not yet used by chat replies; a skill's "hidden from the model" switch is advisory metadata; the SSO description names the organization picker; Microsoft 365 file import has its own consent flow (do not add
Files.ReadorSites.Read.Allto the SSO scopes); the audit verifier's truncation and scrub notes read as the bounded PostgreSQL verifier behaves, and the environment reference saysTALE_AUDIT_SIGNING_KEYis retained for compatibility and not read by it.
The Documents hub lists one folder at a time (#3356)
Since the 0.5.0 Postgres port, the hub's root page listed every document in the organization: a file synced from a OneDrive or Google Drive folder appeared at the root and inside its folder, and deleting the folder took both rows with it. The root page now lists only the documents that sit in no folder, a folder page lists that folder, and no request shape lists the whole hub; a cloud import refreshes the folder list too, so the sync-root folder shows without a reload. Two defects went with it: a parent crumb in the breadcrumb navigated to the root (the folder rows were keyed id, the crumb read _id), and the manual-suite guide checker could not see the design-system catalog's keys. On REST, folderId=root on GET /api/v1/documents and GET /api/v1/projects/{id}/files lists the unfiled documents — the root no folder id could name; omitting the parameter still lists everything (contract 1.10.0).
A managed deployment recovers a replaced configuration plan (4f7b426)
A deployment that fails while verifying a provider catalog retains a native configuration plan; when a reviewed replacement bundle repaired the provider's endpoint, the native phase still selected the old plan, refused the changed declaration, and bundle recovery could not finish. supersedesPendingConfigurationPlan in a managed deployment declaration — config apply --supersedes-pending-plan <sha256> on a standalone workspace — selects the exact retained plan by the SHA-256 of its canonical JSON (keys sorted recursively, arrays kept, no whitespace). The engine keeps the prior journal and verified writes, requires the same organization, origin and resource identities, refuses native state outside the old operation's recorded preimages and results, keeps the native compare-and-set checks, and replays an interrupted replacement without duplicating completed writes; supersedesPendingBundle alone never replaces native configuration intent. The receipt keeps the superseded plan and its verified subset under superseded; drop the selector once the replacement reaches ready. The CLI README and the CLI install page carry the recipe.
Behaviour changes
- The Documents page lists one folder at a time: the root shows folders and unfiled documents only, and a synced cloud folder's files stand inside their folder. A cloud import shows its sync-root folder without a reload; a parent crumb opens that folder.
- Test run and Run live on a version that declares inputs open the confirmation dialog with a Run input (JSON) field and the schema beside it; malformed or non-conforming input is refused before anything is scheduled.
- An invalid or unavailable approval policy refuses a new platform-internal write instead of allowing it.
- The pending-approval card renders for UUID approval ids; a waiting run shows no finish date.
- The product editor uploads an image; a file bound to a product cannot be deleted until the image is removed from the product;
Product.imageUrlover REST is absolute, and the deployment's own image URL is accepted back. - A document that cannot be indexed names its cause (Document cannot be indexed, with the reason) and offers no retry; a project file in that state shows the same label; knowledge entries show their indexing status.
- Websites: a registered site starts Scanning (the Idle status is gone); the page counts move while a scan runs; pages
robots.txthas come to disallow leave the index on the next scan, and a page carrying<meta name="robots" content="noindex">is not indexed; anhttp://address is refused when adding a site; the detail dialog shows the creation date. - Knowledge search: a passage repeated inside a document is returned once; a scoped search over a large corpus keeps the dense hits it used to drop; control characters are stripped from passages.
- Task automation: a task holds one live run whichever automation started it; a second start naming another automation returns the existing run as
already_running. The guide's "per-task safeguard" pause never existed; the guide now says the one-engine rule is the stop. - REST chat: a prompt with no visible text answers 400; archiving a thread mid-turn answers 409; a thread or project archived after acceptance settles the reply
cancelledwith the prompt kept;sinceandreasoningSincenever split a surrogate pair. - REST: every 201 that creates one resource carries
Location;nullon a create or bulk import reads as the field left out; the documentPATCHanswers itsETag; the skill file read answers 304 onIf-None-Match/If-Modified-Since;GET /api/v1/modelsanswersharnesses;websites?scanInterval=and an unknownharnessare refused by name. - The session doors answer coded envelopes: a missing session
UNAUTHORIZEDwithCache-Control: no-storeon/eventsand the app routes, a missingorgIdINVALID_QUERY, a non-memberORG_FORBIDDEN. - The rendered API reference at
/docskeeps a pasted key in page memory only (a reload asks again); its Logout works. - The edge strips
Expectonce the proxy is recreated (see Upgrading); the proxy's self-signed mode log names the root certificate to copy instead ofcaddy trust. - The project-agent model picker matches the API model id; contact, product and website rows show their dates; an active WebDAV credential stays revocable and its badge readable.
- The settings copy for personalisation, memories, skill invocation, SSO and Microsoft 365 import describes the current build (see Highlights).
tale deployon a managed deployment honourssupersedesPendingConfigurationPlan;tale config applytakes--supersedes-pending-plan;tale initends with a backup reminder instead of the "production-ready by default" line, and--no-envsays the environment setup was skipped.- docs.tale.dev: three new pages; the attachments page is a page again (its redirect to the chat basics page is gone); the initial skip-link focus and the reduced-motion preference are kept.
API contract changes
The OpenAPI document moves from 1.9.0 to 1.11.0 in two additive steps (1.10.0 dated 2026-09-14, 1.11.0 dated 2026-09-15); the Error.code enum keeps its 149 values. One enum value leaves — Website.status loses idle, which no running instance ever answered (a registered site starts scanning) — and every nullable enum now lists null.
Added
- 1.10.0 —
folderId=rootonGET /documentsandGET /projects/{id}/files: the documents (files) in no folder; a folder id answers that folder, an unknown id on the project door the opaque 404FOLDER_NOT_FOUND, a blank value 400; omitting the parameter still lists everything. - 1.11.0 —
POST /contacts/{id}/restore(200 with the contact; a live contact is a no-op; 409CONTACT_DUPLICATE_EMAIL/CONTACT_DUPLICATE_EXTERNAL_IDwhen a live contact has since taken the key; a body other than{}400);GET /conversations(sourcerequired;contactStatus,cursor,limit) —ConversationMirrorrows newest first under a source-signed cursor;contactIdon the conversation-sync receipt;Locationon the thirteen 201 creates (documents, websites, products, contacts, projects, project agents, folders, files, tasks, threads, project threads, knowledge entries,PUT /skills/{slug});harnessesonGET /models;ETagon the documentPATCHresponse;ETag,Last-Modifiedand 304 onGET /skills/{slug}/files/{path};KnowledgeDiagnostics.dense; on the MCP endpointstart_run.idempotencyKey,deployedonset_trigger,version: "deployed"onget_automation, thedeployedmarker anddeployedVersiononlist_versions, and acodeon every capability refusal.
Changed
PATCH /threads/{threadId}witharchived: truewhile the turn is queued or streaming answers 409CHAT_TURN_IN_PROGRESS; a thread or project archived after a send was accepted settles that replycancelled.POST /conversations/sync— a re-keyed contact's binding follows its currentexternalId; a snapshot naming the old id answers 409CONVERSATION_CONTACT_CONFLICT.POST /websites— adomaincarrying a scheme answers 400WEBSITE_DOMAIN_INVALID; a trailing dot is stripped.GET /websites?scanInterval=— a value outside60m,6h,12h,1d,5d,7d,30danswers 400INVALID_QUERY;Website.statusisscanning,active,error,deleting.POST /projects/{id}/agentsand itsPUT— aharnessoutside the eligible set answers 400PROJECT_AGENT_HARNESS_INVALIDwith the set indata.harnesses.- The generation poll —
sinceandreasoningSinceare snapped down to a surrogate pair's start;textOffsetandreasoningOffsetsay where the slice begins. - Thread sends — a
contentwith no visible text answers 400; the execute-lane budget is charged only after the body and theIdempotency-Keyheader pass. POST …/tasks/{taskId}/start—already_runningmay name a run another automation started (itsnamesays which).ContactInputandProductInputdeclare their nullable fields; anullor blank on a create or bulk import reads as the field left out; the enum query filters are declared.Product.imageUrl— the deployment's own product-image URL is accepted back on a create or patch, even on a private deployment; a missing or inaccessible image answers 404FILE_NOT_FOUND.- The session doors (
/events,/api/app/…, the control routes) —UNAUTHORIZED,INVALID_QUERYandORG_FORBIDDENbeside the sentence. - The MCP endpoint —
set_triggertakes one shape per kind (a key of another kind is refused by name); an enum argument outside its set is refused with the set named;start_runrefuses a reusedidempotencyKeywith different arguments asIDEMPOTENCY_KEY_REUSED.
Documented, unchanged on the wire (en, de, fr): the edge's bare 431 and 400 carry no X-Request-Id; Idempotency-Key is read only by the operations that declare it, and curl -H 'Idempotency-Key:' sends no header at all; the redirect ceiling (redirect_limit_exceeded past five redirects); the knowledge query cap of 2000 characters and the similarity-threshold recipe; a skill keeps no version history on the machine door; the per-task circuit breaker is not built; Product.imageUrl and WebsitePage.lastErrorKind say what they carry.
Security
- An approval policy fails closed (#3342): an invalid or unavailable approval-policy file no longer lets a platform-internal connector write run without the approval the organization configured. If a deployment carried a malformed policy file, review the automation runs of that period.
robots.txtis honoured on every crawl path (#3359): pages a site asked crawlers to leave alone are no longer fetched, indexed or served through rendered-page links, and pages a rule covers leave the index on the next scan.- The rendered API reference no longer persists a pasted key in the browser's
localStorage;swagger-ui-react5.32.15 runs onimmutable5.1.9, clear of the two advisories the dependency gate tracks (GHSA-v56q-mh7h-f735, GHSA-xvcm-6775-5m9r). - The edge strips
Expect, closing an interim-response desync a strict HTTP/1.1 client could be confused by. - The product-image intake inspects the bytes (the declared type is not trusted; an SVG with active content is refused), serves them only to an authorised app session — an API key does not authorise the route — and refuses a caller claiming the intake's reserved source on the generic file registration.
- A custom provider host is resolved and every address checked before the gateway is provisioned; a cloud-metadata address is refused whatever the name.
- Fetch errors from the crawler carry no OpenSSL handles or runtime paths; a missing session answers
Cache-Control: no-store.
Known issues
- Unchanged from v0.5.20, where each is described in full: the
es/co-ccColombian cédula detector still ships switched off and a locale-agnostic PII toggle still widens national-ID matching to every locale (the PII library is untouched in this range); thinking-block replay on the native Anthropic connector is not done and the live Max-plus-tool-call check is still owed;rag_searchembedding calls inside a harness turn are unmetered; the product edit dialog cannot clear a field; the app's skill editor still carries the retiredprivatevisibility. - The
x-tale-paginationextension is a declaration on the OpenAPI document; generated clients that do not read vendor extensions still branch on the two cursor names untilcursoris retired. - The
Expectrule was not exercised on a running deployment. It went into atale-proxyimage no deployment has run yet, andservices/proxyhas no test of its own. The 0.5.26 gap is closed: the hosted platform's edge has answered 400BODY_CHUNK_MALFORMEDto a malformed chunked body since 2026-09-14, and the analytics header rides the same recreated proxy. - Documents indexed before this release keep one vector per repeated passage until they are re-indexed; the content hash is unchanged, so only an explicit
retry-indexing(or a content change) re-embeds them. A site's robots rules are empty until its first scan on this release; that scan readsrobots.txtafresh and retires the pages it covers. - The rail's navigation memory has had part of its manual round: R5 drove six EN/DE/FR desktop and phone cases (restore, reset, a fresh chat, two-tab isolation) covering parts of
NAV-F16–NAV-F19; the remaining section, the second-account cases andNAV-B6–NAV-B9are still unrun. - ui.tale.dev is not live at this tag.
tale-ui-docs:0.5.27exists from this release, but the site goes live with the operator's deployment of it; until then the link on the contributor-setup page does not resolve. The site still has its nineteen seed pages, and the docs chrome is duplicated between the docs site and the design-system site rather than shared. - A reply-language directive is a directive: a model may still answer in the prompt's language and nothing on the wire marks a slip.
- No image input on the REST chat send. A
visionmodel reads an image over REST only on a thread the app continued with an image attachment; the design of anattachmentsfield on the send is recorded as contract debt. - No REST door authors or deploys an automation —
POST /automationsanswers 405 by design. Build and deploy in the app, or over the MCP endpoint'ssave_automationanddeploy_automation; the REST key lists, reads, runs and wires triggers. - The app's zip upload of a skill bundle rewrites the bundle and moves
updatedAteven when the zip is byte-identical, wherePUT /skills/{slug}writes nothing. - A tool call the reply cap cut keeps
input: {}on the storedtool-callpart; the part says its arguments were cut, but the raw text the model emitted is still not on the transcript. - Folder names written before 0.5.24 keep their bytes; a sync engine's hub-path lookup can create an NFC twin beside a legacy NFD folder. No backfill ships.
- Behind a Docker-published port, every IPv6 client arrives as the bridge gateway's address and shares one per-address rate-limit bucket and one audit address until the daemon runs with
ip6tablesand the proxy's network is IPv6-enabled — an operator item, documented on the Own Compose page. - Recorded as contract debt by the eighth evaluation, each with its design in the ledger:
GET /notificationsrows carrytypeas a free string and nothing pushes them to a machine caller (poll only); a skill keeps no version history on the machine door (PUT /skills/{slug}replaces, and the app's history is not readable over/api/v1); the per-task circuit breaker is not built — no counter pauses automation on a task after N runs in an hour, the one-engine rule and cancel are the only stops;GET /conversationslists the mirrors, but the messages a snapshot applied are readable only in the app. - Still open from the seventh evaluation: a run carries no
usageor cost; approvals and asks have no REST twins (a run parked onwaitingFor: approvaloraskis decided in the app); a task cannot be archived or deleted over REST; a webhook bind does not say whether the deployedinputsschema admits a delivery; an exhaustedrepeatUntilis only a trace note;Websitecarries noscanStartedAtand the crawler has no page cap, path filter or stop verb of the caller's; website search has no dense leg and its substring fallback (a knowledge database without ParadeDB) stampsscore: 0silently; noIdempotency-Keyon the task start, so a retry after the run finished starts another; no queue position on a queued send; a corrupt Office document (docx,pptx,xlsx,odt) still fails asindexer_errorand is retried five times where a PDF landsmalformed; no/.well-known/security.txt; no changelog feed on tale.dev; no SDK, collection or per-code table beyond theError.codeenum.
Migration notes
- Three migrations, all forward-only and rolling-safe.
- 0104
automation_runs_one_live_per_task_subjecton the application database, applied by the backend at boot inside the advisory lock while the previous image keeps serving: it first collapses any live runs (queued,running,waiting) that share an organization, a project and a task subject across automations onto the earliest-started run, marking the restcancelled, then adds the partial unique index over that key and drops 0102's per-(task, automation) index, which the new one implies. Inside the roll window a cross-automation start on the previous image answers a unique violation as a 500 for that one request — never a second run. public_web11website_robots_rulesandprivate_knowledge12chunks_passage_repeaton the knowledge corpus —ADD COLUMN IF NOT EXISTS(robots_disallow,robots_fetched_at;passage_repeatdefaulting tofalse), metadata-only and idempotent; the previous image neither reads nor writes the columns. The backend applies them to the deployment-default corpus at boot from the files the platform image ships (the same files, version-aware); the database image applies them in its knowledge role when its container starts on the new image; a bring-your-own corpus gets them from the same converge path on first use. Neither has a down migration by design.- No backfill runs: rows indexed earlier read
passage_repeat = falseand heal on re-index; a site's rules areNULLuntil its next scan. Thetask_labels_project_id_name_keyconstraint 0.5.22 kept for its rolling deploy is still in place; dropping it is a follow-up migration.
- 0104
- No new environment variable. The root
.env.exampleonly rewrites the comment onTALE_AUDIT_SIGNING_KEY: the key is generated and retained by the CLI for compatibility, and the current PostgreSQL audit verifier does not read it. Keep the value with the deployment's secrets; nothing to change. - The proxy image changes — the
Expectrequest header is stripped before the origin sees it, and the self-signed mode's startup hint names the root certificate to copy. The proxy is in the stop-gated tier: a plaintale deployleaves a running proxy untouched and names it in a hint, so pass--stopto take the new rule (a brief downtime whiledb,object-storeandproxyrecreate); until then a client sendingExpect: 100-continuestill gets 0.5.26's two interim responses. An own-Compose deployment pulls the newtale-proxytag. - The platform (the backend, the app, the message catalogs), proxy, db (the two knowledge migration files), docs (the rewritten pages in en, de and fr and their screenshots) and ui-docs (the component guides and the docs chrome) images carry source changes; the web image rebuilds with the updated
@tale/uipackage and has no change of its own; the sandbox, sandbox-runtime, sandbox-buildkitd, sandbox-egress and sandbox-llm-gateway images have none. The CLI has source changes — the pending-plan recovery selector and thetale initcompletion text — and the release executables report 0.5.27. @tale/uiand@tale/marketing-uiare pinned by this release as theui-v0.5.27andmarketing-ui-v0.5.27tags on their snapshot branches; a consumer outside the monorepo installs"@tale/ui": "github:tale-project/tale#ui-v0.5.27".- Documentation redirects:
platform/chat/attachmentsis a page again (its redirect to the chat basics page is removed); every other redirect stays.
Upgrading
-
On the 0.5 line (0.5.0 – 0.5.26):
tale update tale deploy --stop
The three migrations run at boot.
--stoprecreatesdb,object-storeandproxyso the edge carries the new rule (a brief downtime); a plaintale deployapplies everything else — the knowledge columns included — and leaves the running proxy on 0.5.26's rules. -
Managed deployments move by pinning the CLI and the runtime to this release's commit, preparing a new bundle and applying it with the pinned CLI — see Managed deployments on the CLI install page. The bundle's backend-local phases run under the interpreted CLI (
cli/tale.mjs) that thesetup-cliaction andbun run --filter @tale/cli buildproduce beside the executable; the executable from the release page has no interpreted bundle beside it and cannot prepare a managed bundle. A deployment stranded on a retained native configuration plan declaressupersedesPendingConfigurationPlanwith the plan's hash beside the correctedconfiguration, as above. On a Linux x64 host whose CPU lacks AVX2, passlinux-baseline: 'true'to thesetup-cliaction so the bundle embeds the baseline executable. -
New install:
curl -fsSL https://raw.githubusercontent.com/tale-project/tale/main/scripts/install-cli.sh | bash mkdir tale-05 && cd tale-05 tale init tale deploy
On a CPU without AVX2 the downloaded executable aborts with
Illegal instruction; build it from source withbun run build:linux-baselineintools/cliinstead.
What's Changed
- fix(platform): list only unfiled documents at the hub root by @larryro in #3356
- fix(cli): recover explicitly replaced native configuration plans by @yannickmonney in 4f7b426
- docs(docs): overhaul guides, translations and authoring skills by @yannickmonney in #3342
- fix(platform): close the 2026-09-14 API evaluation's round-h findings by @larryro in #3359
Full Changelog: v0.5.26...v0.5.27