v0.1.1
Two things, both found by putting the language in front of readers who had not written it.
A durable program may hold only durable values
The chat packages were handing out a pointer into their sidecar's process memory. After a runtime restart, replay served the recorded handle into a fresh process whose client registry was empty, every call through it panicked, and re-forking the watcher re-used the same dead handle — a silent crash loop, which the tutorial's own recovery advice walked readers into.
The fix is not to manage the staleness but to stop the pointer crossing the boundary. An FFI call now takes what it needs to act — the remote name and the credential — and a sidecar may cache whatever it likes keyed by those, but no durable value points at that cache. e2b has been written this way all along and was structurally immune. The test is falsifiable: if emptying the cache breaks a program, a durable value was pointing into the cache.
So a re-forked watcher connects again, and the recovery is one region.crashed clause instead of a supervision scope. The four examples deleted the ceremony they were carrying to work around this, and two properties they had retracted came back — a half-collected standup keeps its replies, a concierge keeps its conversation.
Breaking: discord 0.7.0 and slack 0.5.0 remove the connection request and the create_*_client / *_close pair; credential serves the token(s), provider connects nothing, and watch_messages / ask raise the package's error themselves. memory 0.5.0's forget answers forgot | was_absent instead of a sentence — it used to claim success for a key that was never there.
The compiler stops speaking type-checker
A cold-start review found every error was self-correctable by an AI from the text alone, and that a human beginner hit a wall of internal vocabulary with no suggestions anywhere.
- Fourteen message families move onto actual/expected plus a fix.
Optional field cannot be a subtype of a required field: timezoneis nowRequired argument \timezone` is missing` — that one had already cost real time, when an agent read it as a package defect and filed a report about a default that does not exist. - Names suggest their near neighbours. A derived
type neverno longer prints ahead of the undefined name that caused it. - K3028 warns when a statement's value is discarded. The motivating case:
try_sendchanged to answer whether a post landed, and twelve call sites kept compiling while dropping that answer on the floor. Zero false positives over 226 module-compilations. - A dependency's warnings stay out of a consumer's build — a warning nobody can act on teaches people to stop reading warnings.
- The escalation report shows the entries worth reading and counts the rest.
--all-entry-pointsreproduces the old bytes exactly, which matters because teams diff this report to prove a change granted no new capability. katari ls packagesanswers what there is to add. A signature may break beforewith. A documented field of a documented type carries both texts instead of the shorter one silently replacing the longer.
Getting it
npm install -g @katari-lang/cliRuntime image ghcr.io/katari-lang/katari:0.1.1; registry snapshot snapshot-2026-07-30-f55993f8. Pre-1.0: pin what you deploy.