Unreleased
Changed
- Diagnostic, explanation and generated-page text no longer names milestones, design-log
entries or another release:
V8005reads "Sakura Lang does not support packages yet",V9002's root-handler message says which effects get root handlers, andD096no longer namesSAKURA_MAX_HEAP, which the WASM host does not read. Codes,kinds and JSON fields are unchanged; occurrence ids, which hash the message, change with it.
0.1.0 - Unreleased
The first non-alpha preview and the close of milestone M4, the WebAssembly backend (exit
commit dee11301). Sakura Lang is still pre-1.0: read STABILITY.md before
depending on anything below. The Rust MSRV is unchanged (1.99).
What is stable and what is not
- No stability promise yet. There is no stable language, std, CLI,
--jsonor ABI contract in0.1.0. RFC 0001 (Draft) proposes the guarantees, and the draft inventory in STABILITY.md names what each covers; if the owner accepts it, its promises begin atv0.2.0. Every--jsonrecord is versioned (kind,schema_version), andcompiler/contracts/json.txtlists its fields. - WASM backend: done.
--target wasmbuilds, runs, tests (with--contracts) and verifies programs as--target jsdoes; CI's parity suite compares the two backends' output, traces and defect records on Linux x64 and ARM64, macOS ARM64 and Intel, and Windows x64.sakura test --recordstill needs--target js. Modules carry runtime ABI 1.4.0. --target native: experimental. It exists only in a compiler built from source with the Cargonativefeature; the release binaries and packages do not include it. It is outside every compatibility promise and stays experimental atv0.2.0. Natively,Http,serveandLlmstill stop with aD090orD091defect.- Packages: not supported.
[dependencies]insakura.tomlis reserved and refused withV8005 dependencies_not_supported; nothing is fetched. Packages are planned for a 1.x minor release. - Platforms. A packaging target is called supported for this release only after its published-install smoke passes on every applicable channel; the install page states each platform's level.
- Performance. These notes quote no benchmark ratios: benchmark numbers stay advisory until a quiet-window run on the exit commit is blessed.
Semantics changes for owner review (rows 8–10 of the M4 exit checklist):
Serve.host()on--target wasmanswers a request the heap cannot take503with aD096record, a request still waiting when the program ends500, and a trap500before the server stops and the program exits 70; on both backends a request arriving after the server stops is503(Fixed below; design §17.223).- A response body cut short in
Http.host()'ssendisErr(HttpError)on both backends instead of a defect or a crash (Changed below, Breaking; design §17.209 (2)). - Symbolic links in an
fs.writegrant: a write through a dangling link is refused, and the JS and WASM hosts open the resolved path withO_NOFOLLOW, so a link planted during the call is refused within the limits ABI §8.3 states (Security below; design §17.233). The dangling-link hole shipped inv0.1.0-alpha.1.
Entries marked Breaking can change what a program that worked on v0.1.0-alpha.1 does.
Added
-
The npm packages carry a README, keywords and an issues link, so the npm page shows how to install and start. Each platform package's README points to
sakuralang. -
Experimental
sakura build --target nativeandsakura run --target nativein a compiler built with thenativefeature (plan M5 N2): Cranelift compiles the program to an executablemainlinked with the native runtime, whose defect records carry the same spans as JS and WASM. Native stays experimental atv0.2.0; release builds do not include it. Native executables carry unwind tables and a DWARF line table, solldb,gdband profilers show Sakura frames at their.saklines, and asakura.nativerecord that the runtime checks before running (V8003for another target, layout profile or ABI).sakura build --target native --native-checksbuilds a checked executable that stops at any generated heap access outside its object. -
sakura run --target native(a compiler built with thenativefeature) runsJson.encode,Json.decode,Json.parse,Json.schema,Cli.argsandCli.parse(plan row N1b). The JSON codec is written once in the Rust runtime and matches the JS runtime's text and decode messages,whereclauses included. Programs that useHttp,serveorLlmstill stop with aD090orD091defect natively. -
Sql.memory()andSql.sqlite(path)run natively on bundled SQLite, each database on its own worker thread, with rows, decode errors and SQLite's messages matching the JS runtime. Cancelling a running statement (a lostTask.race, atimeout) interrupts it, and a write that committed before stays committed. -
The WASM runtime's
stats()reports four more counters, recorded bySAKURA_WASM_STATS,SAKURA_NATIVE_STATSandbench/harness(runtime ABI 1.3.0, design §17.176 (1), plan row N0b):reuse_attemptsandreuses(an ownedList,MaporSetupdate testing whether it may write its wrapper and each node on its path in place, and the tests that could),borrow_candidates(executed reference-count increments before a call that only reads the value, which stays live after it) andborrows(always 0 until borrowing lands). Benchmark records addreuse_rate(nullwhen nothing was attempted) and the module'sabi_version. -
sakura build --target wasm --dump ownedprints the ownership facts as the LIR computes them from the committed Core snapshot (design §17.176 (2)); they match the JS backend's dump. -
The WASM module's
stats()export reports an eleventh counter,restarts: the calls of a direct function run again through frames after its native twin ran out of stack gauge (runtime ABI 1.2.0, design §17.160 (2)). ABI 1.2.0 also lists the host imports and handle kinds as built; a 1.1 host refuses a 1.2 module (V8003), so the bundled host and the module move together. -
A tree-sitter grammar in
editors/tree-sitter-sakura/(not published) with highlight, locals, indent and injection queries and Rust and Node bindings. CI parses every.sakfile in the repository with it and checks that, wherever the compiler's parser reports no syntax error, its tokens, items, statements and match arms have the compiler's spans, with LF and CRLF line endings. It is for editors and tooling; the compiler's parser stays the parser of record. -
bench/bench run --suite wasmtimes the benchmark suite built with--target wasmon Node and Wasmtime against hand JS on Node, after the same oracle, recording each row'sbackendand the module'sstats()counters; its numbers stay advisory until a quiet-window bless (design §17.191 (2), §17.153). The nightly benchmark workflow runs it as its own job. -
V4004 match_too_large(pattern phase): amatch,catchorletpattern whose decision tree passes 1,048,576 nodes, counting the rows its or-patterns expand into and the matches in its guards, is an error fromsakura build,runandtestinstead of a build that runs away in memory and time (design §17.193). The arm count itself is not limited. -
sakura newandsakura initwrite.gitattributeswith*.sak text eol=lf, so Windows checkouts of sources stay LF, and*.snap -text, so git never converts a snapshot's line endings and a value with\r\ncompares byte for byte (design §17.180 (4b), §17.196 (1)). A snapshot that differs only in line endings names*.snap -textandsakura test --update-snapshots. -
sakura verify --jsonwritesschema_version: "1.1"on every record, and itssummarycountsreused: the obligations whose record was rebuilt from an authenticated cache entry instead of being solved; the human summary prints(n reused). Consumers check the major version and ignore unknown fields. Anunknownwhose reason isresource_limitis now cached and reused bysakura verify(therlimitis in the key), so a second run does not spend the full budget on it again; it never removes a check. Proof cache entries move to format 2, so each obligation is solved once more after upgrading (design §17.164 (1), (2)). -
sakura verify --target wasmreplays adisprovedobligation on the LIR evaluator, whoseIntis WASM's i64, and marks a counterexample that defects as predictedconfirmed, as the JS profile already did on the Core evaluator (plan V4b, design §17.164 (4)). -
sakura build --target wasm --manifestwritestarget/sakura/manifest.jsoninstead of refusing. The manifest is schema 1.1 and gainstarget(jsorwasm); a WASM manifest listssakura_rt.wasm,sakura_wasm_host.jsandsakura_runtime.jsas its runtime, and every clause staysruntime_checkedbecause WASM builds drop no checks yet (design §17.163 (3)). -
Release candidate checks enforce deprecation notice periods, major-only removals and unchanged Rust MSRV in patch releases; the deprecation registry starts empty.
-
Draft grammar and diagnostic specification in
docs/spec/, indexed by fixtures, with a generated diagnostic identity table and a Python drift check; lexical boundary, grammar-alternative and tree-sitter divergence fixtures back its rules, andV8003has an emission test. -
Draft RFC 0001 proposes stability guarantees and identifies enforcement gaps for owner acceptance at
v0.2.0; current compatibility policy is unchanged. -
Intel macOS archives, npm and Homebrew packaging with public Intel-hosted suites, parity and release smoke; both Darwin architectures enter the existing signing job. Release-specific support still requires published-channel acceptance.
-
Linux ARM64 glibc release archives and the
sakuralang-linux-arm64-gnunpm package, built and smoke-tested on public GitHub-hosted ARM runners. CI runs the Rust suites with pinned Z3/cvc5 and both JS/WASM parity lanes on Linux ARM64. The Homebrew formula directs Linux ARM64 users to the release installer or npm. -
Windows x64 MSVC ZIP and npm packaging, a checksum-verifying PowerShell installer, hosted Windows suites/parity, and native
sakura.exeselection in VS Code. Release-specific supported status still requires the published smoke. -
Published-channel acceptance workflow with exact version/commit checks, a deliberate installer target override, and a platform-report issue form for community confirmations.
-
Per-OS website install instructions with release-specific platform claims, Node 26 setup for Raspberry Pi users; Windows x64 and Intel macOS are published for 0.1.0, supported once their published-install check is green.
Changed
-
Every
--jsonrecord carrieskindandschema_version(design §17.232 (b)):sakura doc --jsongains"kind": "symbol_query"and"schema_version": "1.0", andtarget/sakura/manifest.jsongains"kind": "manifest"(still schema 1.1).sakura verify --jsonon a program that does not compile now writes its diagnostics and summary at schema 1.1, like every otherverifyrecord, instead of 1.0. The fields of every kind are listed incompiler/contracts/json.txt, which a test checks every command's output against. -
Breaking:
sakura.tomlrefuses[dependencies]withV8005 dependencies_not_supported(RFC 0001, design §17.232). Packages arrive in a later minor release and the key is reserved: an empty table, entries, an inlinedependencies = {}or a dotted key is an error at the key fromcheck,build,run,testand the LSP before anything runs, and nothing is fetched. Remove the table. -
Breaking: a
sakura.tomlthat is not a valid manifest isV8006 manifest_invalid(design §17.239): an unknown table or key, a value of the wrong type, a missing[package] nameor malformed TOML is reported bycheck,build,run,test,verifyand the LSP at the place insakura.toml, with the parser's message,--jsonrecords and exit 1. It replaces the human-onlysakura.toml: …usage error (exit 2) that onlyrun,test --recordandverifyprinted. Beside[dependencies]bothV8005andV8006are reported. -
Breaking: a connection that drops while
Http.host()'ssendreads the response body fails withHttpError(status: None, the reason from the host), as a failed connection already did, on both backends: the JS backend reported the defectD091, and--target wasmended the process with an unhandled promise rejection, also when a task was cancelled while itssendread a body (design §17.209 (2)). A program that retries onHttpErrornow retries a cut body too; nothing else changes. This is a semantics change: owner review requested (§17.209 (2)). -
Breaking: a program means the same whatever its checkout's line endings (design §2, §17.180 (4b)): a
\r\ninside a string literal is\n, and a line comment ends before the\r, so a CRLF file no longer prints a longer string.sakura fmtwrites LF (a bare\rin a string of a CRLF file becomes the\rescape), andsakura fmt --checknames CRLF line endings as the reason a file is listed.sakura testreports a snapshot that differs only in\r\nagainst\nas a line-ending mismatch. -
WASM modules record runtime ABI
0x010400(1.4.0: 1.3.0's counters and 1.4.0's native profile text, design §17.229 (1)). A 1.2 host refuses them withV8003, as the ABI's MINOR rule says, since a module now writes counters an older host does not read; the 1.4 host still runs 1.1 and 1.2 modules. -
Release flags follow the version string (design §17.249): a plain
X.Y.Zsuch as0.1.0is a GitHub release marked latest and publishes to npmlatest; only-alpha.Nor-rc.Nis a GitHub prerelease under thealphaorrcdist-tag. The release notes call every 0.x version a pre-1.0 preview with no stability promise yet (RFC 0001, STABILITY.md). -
The documented npm install is the plain
npm install --global sakuralang: the packages ship no lifecycle scripts, andrelease.pynow refuses to pack one that declarespreinstall,install,postinstallorprepare. -
The JS and WASM hosts answer an OS error by its class, as the native host does (design §17.229 (5)): a permission error is
Err("permission denied"), not Node'sEACCES: permission denied, open '…'; likewisealready exists,is a directoryandnot a directory. On Node a sleep longer than 2^31 − 1 ms (about 24.8 days) now waits its full duration instead of firing after 1 ms. -
An
Intinterpolated intosql"…"is bound as an SQLite INTEGER on the JS and WASM hosts, as natively. It was bound as REAL, sosql"select {7} / 2"gave3.5(and anIntrow failed to decode) where SQLite's integer division gives3, andtypeof(?)saidreal. -
Json.decode,Cli.parseandSql.queryinto a tuple type the program never builds (say(Int, Float, Bool)) work on--target wasm; they stopped withD090 a malformed value crossed the host boundary. -
sakura check,build,run,test, the LSP and the MCP server read std's analysis from a cache on disk instead of analysing std in every process (design §17.195 (3), §17.214 (5)). The cache holds one file per compiler build in<cache>/sakuralang/std,<cache>being$SAKURA_CACHE_DIR, else$XDG_CACHE_HOMEor~/.cacheon Unix and%LOCALAPPDATA%on Windows;SAKURA_NO_CACHE=1turns it off. Output is unchanged with and without it; a damaged or missing file is recomputed and rewritten. The files carry no compatibility promise (STABILITY.md). -
A process that analyses several programs (the LSP and MCP servers, test suites) analyses the std library once and reuses it for every program after the first; a single
sakura checkis unchanged. Snapshot files now list std first, soFileIds in--dump coreand the Core snapshot'sfileschange order, and the snapshot hash changes (design §17.195). -
An analysis that reuses std carries std's symbols, interface hashes and evaluated names and its lowered items instead of walking its 45 trees again (design §17.204 (2)).
-
V1002onType.membersuggests the one exported function that is a prefix of the typed name or extends it (List.lenght→len,List.fil→filter) when no near spelling exists, as asuggestedfix, nevermachine_applicable;sakura explain V1002names std'slenconvention (design §17.182 (2)). -
V1002onType.memberno longer falls back to the one function within two edits when the usual did-you-mean finds none:List.sizegets noList.slicefix, andList.lenth→List.lencomes from the prefix rule assuggested, notmachine_applicable(design §17.187, withdrawing §17.165 (2)'s fallback, which shipped inv0.1.0-alpha.1). -
V2002names aType.membercallee as written:List.map` (std/list) takes 2 arguments, this call passes 1rather than the baremap(design §17.182 (3)). -
--target wasmruns aperformbound to a handler literal in the same function (design §17.113 (a)) as a direct call of its clause, and gives such functions and their clauses direct twins, so a loop performing a local handler's operation allocates no continuation frames:handled_d1,_d4and_d16run 4 frames perrun(1000)where they ran 1,005 (design §17.211 (1)). Output, traces and defects are unchanged. -
--target wasmcalls a closure inside a direct function through the closure's own direct twin when it has one, soList.map,fold,filterand the other std functions taking a callback run their loop without continuation frames:contracts_plain,pipeline,shapes,map_setandnbodyrun 4 frames at their smallest size where they ran 1,121, 2,508, 5,010, 2,005 and 7,005 (design §17.211 (2)). A callback that performs still runs through frames. Output, traces and defects are unchanged. -
On
--target wasm, a fusedxs[i].expect(…)ormap[k].expect(…)(design §17.151) reads the element in place instead of building and dropping anOption; output and defects are unchanged. -
sakura test --contracts --target wasmruns the synthesized contract properties on WASM instead of refusing, with the counterexamples, shrinks, stored regressions and exit code JS reports for the same seed (design §17.163 (4)).sakura test --record --target wasmis refused with`--record` needs `--target js`before the permission check. -
sakura build --target wasmdrops the checks of obligationssakura verify --target wasmproved on thei64profile, as the JS build does for thejsprofile, and its manifest saysprovedfor those clauses (design §17.163 (4), M4-OPT). The JS modules a WASM build writes for decoding keep every check. -
sakura builddeletes a proved check's predicate along with the check: anensuresorwherebuilt from comparisons, arithmetic, projections and constructors is no longer evaluated oncesakura verifyproved it. A predicate that calls a function is still evaluated, so a defect inside that function is still reported (design §17.98, §17.118). -
==and!=on an enumeration whose constructors have no fields (type Dir = North | South), or against a field-less constructor (shape == Empty,o == None), compare constructor tags instead of walking the values, on JS and WASM; results, traces and defects are unchanged and--dump coreshows the comparison astag_eq(design §17.183, WS-P11a). -
Exhaustiveness checking costs each
matcharm the earlier arms with the same head constructor, not every earlier arm (design §17.200 (8)), so a longmatchof guarded rows alternating with literal rows no longer checks in quadratic time. Diagnostics are unchanged. -
The exhaustiveness index recurses into every column a
matchspecialises (design §17.200 (8)), so thousands of arms under one constructor (Some(1),Some(2), …), over a tuple of literals or over nested constructors no longer cost each arm every earlier arm. Diagnostics are unchanged. -
A loop body with more than eight CPS steps keeps the shared-continuation form instead of the resumable
for (;;)loop, which copies the rest of an iteration once per step;sakura build --dump directlists each such loop asresumableorshared(too-many-steps(<n>))(design §17.181 (1)). -
The Sakura skill keeps its examples, syntax list, and edit loop in a smaller entry point, with repair and completion detail in its references. Its 7,500-byte ASCII limit now measures release metadata after template fill, with a 7,000-byte source working target (design §17.188).
-
The agent-DX offline fixture validator runs independent tasks in a thread pool, with
--jobs 1for serial execution and byte-identical task-ordered reports (design §17.197). -
The agent-eval runner caps the episodes of one approved run with
--max-episodes(default 48) instead of 48 across all runs, leaving the dollar ledger as the only cap across runs;agent-eval.ymlgainsseedandmax_episodesinputs (design §17.182 (4)).
Removed
-
The unused
[targets]manifest table. It was parsed and never read; it is now an unknown key and soV8006. -
The native host's
SAKURA_BLOCKING_THREADS: nothing used its blocking pool (design §17.229 (4)), andSqlruns on per-database workers instead.
Fixed
-
Serve.host()on--target wasmanswers a request the guest heap cannot take with503andretry-after: 1, writing the defectD096to stderr, where it was a500with nothing on stderr; the server keeps serving. A request still waiting when the program ends is now answered500(it got no answer), with oneD090"server stopped" record unless a defect ended the program. On both backends, once the server stops, a request still arriving on an open connection is503with the connection closed and its handler never runs (design §17.223, ABI 1.2.3). -
A runtime trap while
Serve.host()serves on--target wasmno longer ends the process with an unhandled exception: the request is answered500, the server stops (later requests are503), and the program exits 70 with oneD090record that names the function and the PC (design §17.223 (2), ABI 1.2.3).sakura testreports the test as a defect and runs the rest on a fresh instance, as for any trap. -
Serve.host()on--target wasmno longer ends the process when a request is larger thanSAKURA_MAX_COPY_BYTES: the request is answered413with the connection closed and the handler not run, as a body over 1 MiB already is, and a handler's response over the budget is500; each writes the defectD091to stderr, and the server keeps serving (design §17.216 (4)). The JS backend copies nothing into a guest and is unchanged. -
On
--target wasm, runningmainagain on one instance (the benchmark harness's Node cells do, once per sample) no longer keeps 4 objects per run: the Node host releases each finished root task through the new module exporttask_free, and the clauses of a host handler (Console.host(),Clock.host()and the other*.host()handlers) are freed with it instead of being static (design §17.212, ABI 1.2.2). -
A WASM function with more than about 16,000
&&-guardedmatchrows no longer aborts Node after printing its output (design §17.236, plan row 31). Past 256 jumps back to a function's dispatch loop, each 256 jumps branch through a stub, so the loop header has at most ⌈jumps/256⌉ + 1 predecessors; V8's optimizing tier failed past 65,535. 16,384 and 32,768 rows run on Node and Wasmtime; functions of at most 256 jumps are byte-identical. -
Type arguments on the first alternative of a variant list (
type T = Some<Int> | Nada) areV0001, as on a later alternative. They were accepted, andsakura fmtprinted the declaration asSome | Nada. A loneName<Args>is still an alias. -
The WASM test runner (
sakura test --target wasm) reports a module of another ABI aserror[V8003]and exits 2, asrunMaindoes, instead of throwing. -
A syntax error now hides only the diagnostics that point into the body holding it (design §17.207 (1)). Before, every diagnostic raised while that body was checked was dropped, so
sakura checkcould miss an error in another module, such as a bad signature (V2002) first used from the broken body, that an analysis after an edit then reported. Diagnostics inside the broken body, and aV3001about its calls, stay suppressed as before. -
After an edit, a literal into a refined type is checked again when the edited function is reached from the refinement only through a
requiresorensuresclause, in the LSP and MCP servers and any other process that analyses more than once (design §17.87). Before, the literal kept its old verdict, so aV5004could be missing. Only the names a refinement's evaluation can call now make a function's body interface, so editing a function that merely shares its name with a parameter or local of such a call chain rechecks its own module only. -
After an edit, an unchanged module's
testblock no longer reports aV5004(a literal that breaks a refinement) twice, or a typed hole twice, in the LSP and MCP servers and any other process that analyses more than once: a reused module's tests, types and effects are no longer checked again (plan WS-C1a). Type diagnostics within a file are listed by position inAnalysisresults, so a reusing analysis lists them as a fresh one does; the human and JSON output already sorted them. -
A long flat
matchno longer overflows the compiler's stack (design §17.193): a 3,000-arm literalmatchcrashed a debugsakura run, because its decision tree is anifchain as deep as its arms. Every recursive walk over an IR (the match compiler, Core passes, the LIR lowering, the snapshot converter, the evaluator) grows its stack on the heap when it runs low, so no number of arms,lets or constructors bounds a pass. The JS output and--dump corestop indenting past 32 levels, so deep code is linear in size (the 3,000-arm program's JS falls from 406 MB to 5.4 MB), andsakura checkindexes atypeof thousands of variants in linear time. Such a program still exceeds node's limits when it runs: its JS nests a labeled block per arm, and its WASM ablockper LIR block. -
A 3,000-arm literal
matchnow runs on node with both backends (design §17.200): amatchonIntorStringliterals is oneswitchover its literals instead of a chain of tests (--dump coreshows it) whose cases hold the arms that one row reaches, wildcard rows are compiled once below the literals before them, anelseno longer nests, a join past 64 nested labeled blocks is an arrow function, and the rows after a failed guard continue in a join, so the emitted JS nests as deep as the source plus a constant. On WASM a function past 256 blocks dispatches through two levels ofbr_tableand its blocks share locals, and anIntswitch of more than eight arms is a jump by index arithmetic when its keys are dense or a binary search: the module no longer traps at compile, and V8 no longer runs out of memory optimizing a function of thousands of blocks. The snapshot writer grows its stack like its reader. -
A long run of guarded
matchrows now runs on node with both backends (design §17.220): the rows after a failed guard follow in itselserather than in a join, so the JS is a flat sequence ofifs and WASM has one block fewer per guard. 3,000 guarded rows in a loop overflowed node's parser and about 10,000 outside one exhausted its stack;deep_ir.rsnow runs 3,000 in a direct-style and a performing loop and 20,000 outside one. Past 256 nested blocks the rest of the run starts a new chunk, and the chunks are joined as a balanced tree, so Core stays within the snapshot's depth bound and JS nests only log₂ of the chunks. -
Core is a function of the source: type and row parameters are numbered per definition, so
sakura build --dump core, the Core snapshot and the emitted JS of a program no longer depend on what an earlier analysis in the same process (an LSP or MCP server, a test run) had checked.sakura verifysolves the obligations of generic definitions once more, since their cache keys hash the renumbered Core (design §17.194). -
Tail calls around a cycle of up to four monomorphic functions without contract checks (
is_even/is_odd, a state machine) run as one loop on both backends instead of through continuation frames, so they need constant stack: each function of the cycle carries a copy of the others (design §17.160 (5), WS-P9). Output, effect order, defect messages and blame sites are unchanged. A generic member, or one that checks a contract, is not copied (a contracted function still runs the others in its own loop); non-tail calls stay calls. -
A call in tail position under an
else if, or under anifnested in anifbranch, is a tail call: self-recursive and mutually recursive functions written that way run as loops too, where they ran through frames before. A terminating program's output, effects and defects are unchanged. -
A tail-call cycle whose functions cannot be nested inside each other, such as three functions that each call both others, also runs as one loop per function: the loop dispatches on a state number, with one
switch(§17.208 (1)), to its copies of the other functions (design §17.192 (2), WS-P9b). WS-P9's limits still apply (four functions, 1,024 copied expressions), and output, effects, defect messages and blame sites are unchanged. -
Terminal output names a source outside the working directory by its OS path (
C:\other\main.sak,/other/a b.sak) instead of the URI's path (/C:/other/main.sak,/other/a%20b.sak) (design §17.196 (3)). -
file://URIs are RFC 8089 on every OS (design §17.180 (4a)): on Windows a source isfile:///C:/dir/src/main.sakinstead offile://C:%5Cdir%5Csrc%5Cmain.sak, so its module name, thesakura.tomllookup, terminal paths relative to the working directory and the MCPpathsfilter work there. Unix URIs are unchanged. The MCPpathsfilter accepts a client's spelling of afile:URI (file:///c%3A/…). -
sakura runexits 70 with the raw code on stderr when the program's exit code is outside0..=255(a Windows NTSTATUS such as Ctrl-C's), instead of truncating it to a byte. On Windows,nodeis found throughPATHEXT(anode.cmdshim works), solvers are found asz3.exeandcvc5.exe, and test permission grants carry no\\?\prefix (design §17.180 (4c)). Windows is not yet a supported platform. -
agent_docsnormalizes Windows path separators so the skill mirror, manifest, hashes, and ZIP are byte-identical to Unix output (design §17.180 (5)). -
The agent skill entry point is at most 7,500 bytes of ASCII, pinned by a
sakura_clitest, so it fits below the eval harness tool-output limit with its metadata filled in. Its four examples stay; the provenance details moved toreferences/repairs.mdand theauditandverifynotes to the cookbook (design §17.182 (1)).
Security
-
On the JS backend and
--target wasm, a symbolic link that another process plants at a write's path between the grant check and the open is refused with"escapes the directory"and its target is never created. Before, the host checked the path and then opened it in a separate call, which followed the new link.Fs.write,Fs.read, aFileopened to read, write or append, andsakura test --record's cassette now open the resolved path withO_NOFOLLOWand do their I/O through the descriptor (design §17.233). A link inside the directory that exists before the call still works. Known limit, stated in ABI §8.3: a parent directory swapped for a link in that window,Sql.sqlite's database file, the directoryFs.listreads (entry names only) and Windows are not covered on the JS hosts. The native host has no window. -
A write through a dangling symbolic link inside a directory the manifest's
fs.writegrants is refused with"escapes the directory"on the JS backend and--target wasm, as the native host already refuses it. Before,Fs.write, aFileopened to write or append,sakura test --record's cassette andSql.sqlitefollowed the link and created its target wherever it pointed, outside the grant (shipped inv0.1.0-alpha.1; N1a review). A dangling link pointing back inside the directory is refused too. To migrate, write to the link's target path instead of the link. -
Breaking:
SAKURA_MAX_COPY_BYTESmust be decimal digits with a value from 1 to 2^53 - 1: any other value (empty,0, a sign, a fraction, an exponent such as1e3, hex, spaces such as" 42", words) is the defectD091naming the variable and the value, at first use:Http.host()'ssendon the JS backend, and on--target wasm, where the budget covers every host answer, the first answer orServe.host()starting. A non-numeric value turned the limit off, an empty one refused every response body, and forms like1e3were accepted (design §17.209 (1)). To migrate, set the variable to a plain byte count or unset it for the 256 MiB default. -
Http.host()'ssendon the JS backend reads at mostSAKURA_MAX_COPY_BYTES(default 256 MiB) of a response body, as--target wasmalready did: a larger body, or a declaredcontent-lengthover the limit, aborts the fetch and fails withHttpError"response too large", where the whole body was read with no limit (design §17.205 (3)). To migrate, raiseSAKURA_MAX_COPY_BYTESor read a large response withHttp.stream. -
sakura test --recordstores at most 16 MiB (16,777,216 bytes) of a response body, sent or streamed: past that,Http.sendorHttp.streamunderHttp.recordingfails withHttpError"response body over 16 MiB: sakura test --record stores at most 16,777,216 bytes of a response body"and the cassette is not appended to. A larger streamed body was held whole, one list element per byte, until the test runner's heap ran out (security review C2, design §17.205 (2)); a sent body was appended whole (design §17.209 (4), which also changed the message's last words from "of a streamed body"). To migrate, record a smaller response, or read a large one outsideHttp.recording. -
New macOS tag releases require Developer ID signing with team
P62B65A837and Apple notarization before checksums, Homebrew archives and npm packages are assembled. Ordinary dry runs skip signing. A separate protectedsign_testdispatch exercises fresh signed binaries without publishing; bare Mach-O executables cannot carry a stapled notarization ticket.
Performance
-
Ownership facts follow a collection through records, tuple results, borrowing parameters and closures, and through recursive calls (design §17.201 (3), WS-P13b): a def that threads a record of lists, such as DeltaBlue's
Planner, updates them in place when its caller's record is owned, on the direct and the CPS ABI.--dump ownedgains the reasonsparam,fieldandtuple, and prints each consuming def's owned-entry verdict beside the plain one. Outputs are unchanged. -
The DeltaBlue benchmark stores dense variable and constraint ids in
Listinstead ofMap, following design §17.217 and WS-P13c. The std index and Sakura skill reference document this collection choice. Oracle checksums are unchanged. -
SAKURA_TRACEeffect traces are written in batches on JS and WASM rather than one write per record. The lines are unchanged; a run killed by a signal can lose the tail of its trace. -
--target wasmgives each variable of a function its own local only up to 256 variables; past that, a block's variables share locals by liveness (design §17.219 (3), plan row 29), so V8 no longer needs memory in proportion to the variable count to compile a function of thousands oflets. Functions of at most 256 variables compile to the same bytes.
Documentation
-
CI requires authored guide examples and rendered documentation links to pass, reusing the existing compiler and website builds.
-
Draft public-interface inventory in
STABILITY.md, with a generated clap/environment/exit-code baseline and workspace drift test; classifications await RFC 0001 acceptance at v0.2.0. -
Rechecked M4 guides against the compiler, repaired runnable tour examples, and documented current-main migration notes, runtime limits, caching and release status. Added a broad sample gate and rendered-route/link checks; refreshed generated agent references and kept the skill entry point below 7,000 bytes.
0.1.0-alpha.1 - 2026-10-18
The first published preview (GitHub prerelease, Homebrew tap and npm). This section is the development log as it stood at the tag, including the implementation history before it.
Security
-
The proof key is refused when its directory is writable by other users or owned by another user, as a readable key file already was; a key inside the project root or the proofs directory is refused from any working directory;
sakura buildonly reads the key and never creates it; and a proof cache entry carries aformatunder its MAC, so an entry of another format is solved again (security review K1–K3, design §17.164 (3)). -
--target wasmchecks what its JS host answers instead of trusting it (security review W1–W4, W7–W11; ABI 1.1.2): an operation index or a builtin result of the wrong shape is aD090defect, never a heap read, and a completion payload must be a freshBytes. A response overSAKURA_MAX_COPY_BYTES(256 MiB) isErr("response too large")fromHttpand aD091defect elsewhere, instead ofD096; a full request table isD091forClock.sleep(which returned at once) andserve_listen. A database fromSql.sqliteorSql.memory()and anLlm.anthropichandler, with its key, are released when their handler ends rather than at exit.sakura test --target wasmruns the tests after a host fault on a fresh instance. On both backendsSql.sqlite'sFs.root()runs in the clause's task, so it no longer spends a task number inSAKURA_TRACEon JS (design §17.159 (5)). -
Breaking:
Secret.map(s, f, reason: Trust)takes a@trust("…")reason, andsakura auditlists each call besideSecret.expose: a purefcannot perform, but a defect in it can print the clear value (security review S1, design §17.159 (2)).Http.beareris unchanged for callers; std's own site is not listed. -
Serve.host()reads at most 1 MiB of a request body: a larger body is answered413and its connection closed without running the handler. A reply whose status or headers the server cannot send is reported as aD091defect and answered500, and the server keeps running instead of stopping (security review H1, H2). -
--target wasmnow sendsSecretHTTP headers (Http.bearer, andLlm.anthropicoverHttp.host()) instead of refusing the request, as gate 10 approved (security review W0):http_sendandhttp_stream_openare kind-secrethost imports besidejs_handler, and cassettes still see the header redacted. The guest and the host overwrite their transport copies of the value once it has crossed (ABI 1.1.1 erratum, §8.1 and §8.4). -
The installer verifies GitHub artifact attestations when
ghis available and fails on verification errors; otherwise it reports "integrity verified, not attested". Installation now requires an absolute prefix and uses a securely created staging file. -
M3 exit gate 10 passed on 2026-10-18: the security review of the escape rules, the cassette format and the
Untrustedtemplate rule is signed by Claude Fable 5.1 under the owner's written delegation (design §17.159; not the owner's personal review). M3 is complete and the reviewed code is no longer frozen. The review records follow-up findings as plan WS12:Secret.mapwill take aTrustreason, plainsakura testwill pass empty permissions to the runtime,Serve.host()gains a request body cap, the proof key's directory mode is checked, non-release workflows pin action SHAs, and WASM may sendSecretheaders once the approved transport change lands. -
sakura testalways passesSAKURA_PERMISSIONS: without--recordits grants are empty, so a test that installsEnv.host()reads no runner variable andSql.sqliteunderFs.host()cannot create a database file (WS12 item 2, review R1/R2).Test.fixtures()keeps its own grants.
Changed
-
Breaking: Sakura Lang source files end in
.sakinstead of.sakura, a clean switch with no fallback (owner decision, design §17.179). Rename sources withgit mv main.sakura main.sak;sakuranames the rename when given a.sakurafile or a tree with only.sakurasources. The VS Code extension, the skill bundle, the agent-DX tasks (revision 2) and every document follow.sakura.toml, thesakura:///std/…URIs and thesakuralanguage id are unchanged. -
Design round 13 (§17.169–§17.178) defines M5's offset32 native ABI, native host coverage, single-thread execution and cancellation, proven-copy warnings, four memory-checking lanes, dependency pins and staged platform matrix; regions and representation changes remain deferred pending measurements.
-
N0a adds opt-in native codegen/host skeletons, exact toolchain dependency pins and a platform-A CI job that links and executes a constant object and a test-only runtime staticlib wrapper. Real runtime staticlib linkage and the ABI export move to N1a; native compilation and execution of Sakura programs remain unimplemented.
-
V2002on a call to a declared function names the callee and its home module and fillsexpected/actualwith the two counts (`Env.get` (std/env) takes 1 argument, this call passes 2); a call through a function value keeps the type form (design §17.165). -
V1002onType.membersuggests the one function within two edits when the usual did-you-mean finds none (List.lenth→List.len, machine-applicable) (§17.165). -
V3001'swithfix names the effect's one deterministicstdhandler when there is one (with Env.of(?vars), stillincomplete), andsakura explain V3001says how to recover from a residualFail<E>(§17.165). -
The agent-eval harness (version 2) records each lookup with its size and success, splits reported diagnostics from codes quoted in documents, reports the remaining input and the refused request, and pairs input-cap arms (
--input-caps 40000,60000) (§17.165). -
Design round 12 (§17.160–§17.168): design §12.1 now lists only the
sakura buildflags that exist (--releaseis removed; every build keeps its checks) and markssakura mcp serve --toolsas planned;sakura verify --jsonwill reportsummary.reusedunder schema 1.1 and reuseunknown(resource_limit)results; WASM defect records will match JS in code, message and site before M4 is called complete; the rest of M4 is ordered in planm3-completion-and-m4.md§3.8, M5 planning opens indocs/plans/m5-native.md, anddocs/plans/road-to-1.0.mdis a provisional outline.
Fixed
-
--target wasmdefect records now match--target jsin code, message and site (design §17.162): a contract defect saysprecondition `nonzero` of positive violated(notcontract `nonzero` violated) and carries the samespans, the blamed call first and the clause asdefinition;Option.expectreports the program's own message, andD004,D011andD031name the value, the inner defect and the offset as JS does. The spans come from the module'ssakura.debugsection (ABI 1.1.3, wording only), so--stripdrops them. -
A cassette line that lacks an exchange field (or has one of the wrong type) now fails
Http.recording's open with<path>:<line>: not a cassette exchange (missing <field>)instead of aD090at replay (security review C1). -
The Sakura skill starts with a bounded guide read and recommends targeted lookup to avoid repeated full-guide input costs. The first paid DX5 pilot now has a public report; no additional episodes are authorized.
-
A
requiresviolated inside a self-tail-recursive function now blames the self call (down2(n - 2)) instead of the outer call that entered the loop. Contracted functions take their blame site as a trailing parameter on the JS backend, and predicates that cannot defect skip theD011bracket (design §17.115); defect codes are unchanged. -
M4 documentation now describes source-built WASM execution and verification, CI parity, the pending Secret-header transport review, and implemented versus planned backend and agent tooling. Added the static-verification tour.
-
The committed skill manifest omits its history-dependent
commitfield; file and ZIP SHA-256 hashes remain. Identical contents stay fresh across commits and rebases, and generation no longer requires Git history. CLI commit metadata stays build-time. -
Restored std index complexity and behaviour notes and added a task-oriented lookup table; the checked skill reference and downloadable bundle include both.
-
Website production builds preserve Fumadocs search highlights without Lightning CSS's false positive
::highlightwarnings; Turbopack still minifies the emitted CSS. -
Native benchmark builds include the OCaml shared modules and Unix library and resolve Koka shared imports from the entry directory, matching the independent verifier's C build configuration without changing port algorithms or toolchain pins.
-
Benchmark nbody uses persistent
List.set, and the countdown hand-JS control checks arithmetic overflow in source operation order (§17.150). Checksums are unchanged; pre-change ratios are excluded across these definition boundaries. The WS-S10 evidence records the remaining controls' arithmetic-check gaps.
Added
-
--target wasmruns direct code without continuation frames: each direct top-level function whose body is first-order gets a native twin withInt/Floatarguments in registers, and deep recursion falls back to frames past a stack gauge (design §17.118).fib30 runs about 4× faster on Node; output, defects and traces are unchanged.--no-directbuilds the all-frame module. -
The WASM module's
stats()export also reports frames,Int/Floatboxes,Dups andDrops (runtime ABI 1.1.0), andSAKURA_WASM_STATS=<path>makes the WASM host append them at exit. The LIR computes the same direct facts assakura build --dump direct. -
--target wasmrunsHttp.host()sends and streams,Sql.sqlite,Serve.host(),Llm.streamthroughLlm.anthropicandLog.json()as the JS backend does; every semantics fixture and example agrees with JS on output and effect trace, with@js/@wasmfixture expectations whereIntdiffers, and the parity harness reports which host imports the corpus exercised (plan M4 W2). Until the owner's review ofSecrettransport (design §17.155), a WASM request carryingsecret_headersis refused rather than sent. JS traces no longer spend a task number on a refinement check inside a JSON decode, so task numbers compare exactly across backends. -
A VS Code extension in
editors/vscode/(not published; build a.vsixlocally):.sakhighlighting generated from the website grammar, language configuration, and a client forsakura lspper project (nearestsakura.toml) with error-page links, quick fixes showing their impact class, stale-fix refusal, Show Hole Context and format on save.sakura lspdiagnostics gaincodeDescriptionlinks to/docs/errors/<code>, quick fixes carrydata.impact/data.applicability, and a client supportingdocumentChangesgets fixes pinned to the document version. New docs page: Editor setup. -
Release preparation for
v0.1.0-alpha.1(not published): the workspace version is0.1.0-alpha.1;sakura --versionand MCPcompiler_info(commit) report the source commit of a stamped build.release.ymlbuilds macOS arm64 and Linux x86-64 archives with SHA-256 sums, a provenance record, the skill ZIP,tools/install/install.sh(pinned version, strict checksum verification), a Homebrew formula and npm packages; a manual run is a dry run, and every publishing step waits for the owner. -
Twelve agent-DX pilot tasks with isolated oracle fixtures, gold/hollow solutions, schema and frozen-baseline checks in ordinary Cargo CI. The protocol defines the Anthropic-only $10 pilot budget; paid execution and its runner remain deferred.
-
The agent-DX episode runner (
evals/agent-dx/harness/runner.py): isolated episodes, hidden oracles on frozen snapshots, JSONL transcripts, metrics, transcript replay and a scripted backend tested offline in CI. Live Anthropic runs require an owner approval, a budget and pinned prices, and stop at a committed $10-total spend ledger;agent-eval.ymlis manual-dispatch only. No paid run has happened. -
Eight offline cookbook projects cover refined JSON, file CLI, HTTP retry/cassettes, SQLite parameters, direct router tests, scripted LLM tools, budgeted agents and persistent indexed updates. Cookbook pages and the embedded skill reference are generated from those projects; CI checks their source, fixtures and freshness.
-
Downloadable Sakura skill with a byte-identical website mirror, deterministic ZIP, SHA-256 checksum and content manifest.
agent_docs --checkand the CLI harness reject distribution drift; the agents docs and/llms.txtlink the bundle. -
Error-code reference pages at
/docs/errors/<code>, generated byagent_docsfor all 90 registered codes: the explanation, thetests/uiprogram that triggers the code, its JSON diagnostic and, for 64 codes, a fixed program the ui suite checks clean.sakura explainprints the page URL after its text, and 32 explanations that lacked a repair gained one. -
sakura newandsakura initwriteAGENTS.mdand aCLAUDE.mdimporting it when absent.sakura setup [--client claude|codex|cursor|all] [--apply]prints, and with--applywrites, the project-localsakuraskill, the client's MCP entry (merged into an existing config; a config it cannot parse gets a printed entry and nothing is written) and Cursor's rule;sakura new --setup <client>runs it after scaffolding.sakura mcp servewithout--rootuses the nearestsakura.tomlupward and refuses to start outside a project (§17.143). -
Canonical Sakura agent skill source with a compiler-driven edit loop, four offline examples and a fixture-seeded repair table. Generated references, embedded metadata and distribution are tracked separately in the agent DX plan.
-
Benchmark results retain every process peak RSS, and comparisons report process medians alongside the unchanged maximum-based +25% RSS gate. The WS-P1 variance study and raw evidence are documented in
bench/README.md. -
Benchmark runs record host load and a quiet-window verdict (
meta.host.quiet);bench blessrefuses runs that are not quiet,bench comparereports loaded-host runs asadvisory (host load L),map_settimes itsInt,Stringand tuple keys as separate cells, and the CI noise job runs weekly (design §17.153). -
Research on language design, agent ergonomics, memory management, effects, standard-library direction, and open-source engineering practices in
research/. -
Bun / Next.js / Fumadocs website and documentation delivery in
website/. -
Initial language design in
docs/design.md, with proposed syntax and open decisions. -
Community governance, contribution and AI-assistance policies, security guidance, and dual MIT OR Apache-2.0 licensing.
-
RFC and architecture decision records, compatibility policy, GitHub contribution forms, and bootstrap CI/dependency automation.
-
sakura mcp serve: the compiler as an MCP server with check, symbol and hole queries, docs, formatting, checked patches and test runs. Setup: docs/mcp.md. -
sakura lsp: a language server with diagnostics, hover, go to definition, completion, formatting and quick fixes. -
sakura fix [--preview] [--apply ids]applies compiler fixes by impact class, andsakura check --frozen-specs <symbols|all> [--since rev]reports spec changes since a git revision asV8020. -
sakura new <cli|lib|agent|api> <name>andsakura initscaffold a project, andsakura runexits 75 whenmaindeclares an effect that[permissions]does not grant. -
sakura audit [--json] [paths]lists every@trust(with its reason and sink),@total,@external,@resourceand refined-typeT.fromsite in your packages, as a table by file or as JSON Linesauditrecords plus asummary. It exits 0 after reporting sites; loading/usage failures remain errors. A literal whose refinement is undecidable at compile time is listed as afromsite withreason: "literal". -
sakura doc [--search "fn(List<A>) -> Int"] [symbol] [--json]prints signatures, effect rows, contracts and doc comments offline;--jsonreturns the records of MCPsymbol_query. -
sakura test --contractsalso runs one property perpub fnwith a refined parameter or arequiresclause: inputs come from the parameter types,requiresfilters them, andensuresis checked. A property that discards more than 90% of its inputs fails and is reported asW7001at the function. A shrunk failure is saved totests/regressions/<fn>.jsonand runs first next time. Functions with effects other thanFail,ClockandRandomare skipped unless@contract_test(handlers: [Effect.constructor()])names their handlers. -
The
sakura explainpages forV5003,V5004,V6002,V6003,W5005andW7001describe the M3 rules with minimal pairs; the retiredV5002page remains for older reports. -
Test fixtures accept backend-suffixed expectations (
// expect-defect@js: D003,// expect-exit@wasm: …) beside the unsuffixed default; the M4 harness will use them. -
compiler/fuzz: cargo-fuzz targets for parsing, checking, formatter idempotence and row unification laws, run nightly for ten minutes each, with minimized failing inputs uploaded as workflow artifacts. -
Tool.oflowers a named@toolfunction throughTool.fromwith synthesized argument schema. -
Effect-row parameters on types, including
Tool<e>,Agent<T, e>andRouter<e>. -
Opaque constructor/field access outside the defining module is rejected with
V1006; compiler-known preludeTrustrestricts@trust("reason")to trusted sink arguments (V6001). -
sql"…"interpolations convert throughSqlValue.fromand remain bound parameters. -
Typed failures escaping test bodies are reported as test failures.
-
sakura build --manifestemits the trusted base and runtime contract obligations totarget/sakura/manifest.json. -
sakura build --emit lirwrites the WASM backend's validated low-level IR as text totarget/sakura/lir/main.lir(M4 preview; no WASM is emitted yet).--layout=nicheis accepted and refused until theOptionniche layout lands. -
sakura build --dump coreprints the user modules' Core, with eachIntoperation the JS backend's interval pass proves markedproved(design §17.114). -
sakura build --dump ownedlists each collection update asowned(in place) orshared(<reason>)with reasonsorigin,borrowed-after,captured,stored,escapes-call <name>andjoin;--dump coremarks owned updates (design §17.149). -
sakura verify [--json] [--target js|wasm] [--rlimit N] [--solver PATH]discharges contract, overflow and division obligations with Z3 5.3.1 (proved,disprovedwith a counterexample replayed through the evaluator,unknown,unsupported, andW7002for a proof over an impossible path) and records statuses in the manifest;sakura buildthen drops a provedensures/wherecheck only while its MAC-authenticated proof still matches the code.[verify] rlimitinsakura.tomlsets the solver budget. The website now documents verification, with a captured CLI example, JSON Lines records, cache authentication and check-removal limits. -
sakura test --record,Http.recording,Llm.replayandTest.fixturessupport scoped cassette recording and offline replay. Example fixtures are explicitly synthetic. -
Scoped escape diagnostics
V6002/V6003, foreign-capability FFI rejectionV6001, and refined-targetUntrusted.validatewithV5003for invalid targets. -
Bounded compile-time scalar refinement evaluation: invalid literals report
V5004; undecidable literals retain startup checks without a warning. -
Html.fromand HTML-valued template interpolation compose markup while escaping text. -
All twelve examples execute (seven run plus test, five test), including committed cassette replay in
llm_extract,agent_loopandsecrets. This does not close all M3 gates.
Changed
-
sakura verifyno longer re-solves an obligation whose MAC-authenticated proof record still matches its key and was obtained with the same solvers: it rebuilds the record from the cached solver answers, so a second run on an unchanged tree prints the same records without solving.unknownresults are still solved every time, and forged or foreign records are solved again. Proof records written before this change are not read; rerunsakura verifyonce so thatsakura builddrops proved checks again. -
Updated live repository links and clone instructions to
icantcodefyi/sakuralang. -
Benchmark peak-RSS crossings above 25% now require one confirmation group on Node; Bun crossings warn only (design §17.136). Compare output retains both groups' maxima, medians and counts, and CI reuses the timing confirmation run.
-
Security (design §17.130): an opaque type is
Schemaonly inside its declaring module. Elsewhere, anySchemabound that reaches one (Json.decode,Sql.queryrows,Llm.generate,Cli.parse,Tool.ofarguments,propertyparameters) is the new errorV2033 opaque_not_schema, so data can no longer forge aQuery<R>,HtmlorUrlPart.sakura test --contractsskips apub fnwith such a parameter and names it.Uuidis nowString where is_canonical(it)andDecimalisDecimalRepr where is_canonical(it), so both decode with their check; programs that builtUuid("…")or matched on it useUuid.parse. -
The JS backend emits
Intarithmetic it can prove in range (loop counters under their guard,n - 1undern >= 1, a non-zero literal divisor) as the raw operator, and inlines the safe-integer test of every other+,-and*. Semantics are unchanged: everyD001/D002/D003still happens where it did (design §17.114). -
A
sakura.tomlnaming its packagestdormainisV8002 reserved_package_name(§17.131). -
A field assignment through a refined type (
x.n = -1onvar x: Pos, orr.total.frac = …through aDecimal) is the new errorV2034 refined_field_assignment(design §17.135), in every module: the sugar rebuilt the base type and skipped the predicate. The suggested fix rewrites it tox = Pos.from(PosRepr { ..x, n: -1 }); usePos.validate(…)?for data. Whole reassignment of a refinedvaris unchanged. -
sakura fmtkeeps anif … elseon one line only when every branch fits; otherwise every branch is a block (§17.133). -
Retired
V5002; narrowedW5005to user clauses scanning collection parameters withList.all,List.anyorList.contains.String.containsno longer triggers it. -
WS7 Phase B documents the landed CLI and language behavior, regenerates the website std signatures from
compiler/std/INDEX.md, and describes early M4 R1–R3/L1–L2/V1–V2 work separately from gated integration. -
Refreshed the tours, cassette guide and README for landed contract properties, streaming HTTP,
Llm.recording, memory filesystem attenuation, untrusted templates and generic refinements, with source-built CLI verification. -
Renamed the language from Vow to Sakura Lang: binary
sakura, sources.sakura, manifestsakura.toml, cratessakura_*, envSAKURA_*, URIssakura://, repoicantcodefyi/sakura-lang. Diagnostic codes are unchanged. -
Host handlers enforce manifest grants delivered by
sakura runinSAKURA_PERMISSIONS. -
Analysis reuses unchanged modules' signatures and bodies; private-body edits lower and check only the edited module. Item/import/export collection remains global. Bodies reachable from refinement predicates participate in interface invalidation.
-
Roadmap and source-build documentation now distinguish implemented M3 behavior from M3 exit gates, planned M4 WASM/verification and M5 native execution.
-
M3 is complete pending the owner's security review (gate 10): the re-audit after the M3 close-out passes gates 1–9 and 11 at
a843e60(gate report). The reviewed escape, cassette and template code stays frozen until the review packet is signed. -
Faster effect handlers on the JS backend (design §17.113): an operation performed directly in the body of
withover a handler literal, or over a call of a function that only builds one (counter(),Clock.fixed(…)), calls its clause directly instead of searching the handler stack. It stays a cancellation point and is traced as before, and a function whose only effects are handled that way runs without continuations. Other operations run a clause that performs nothing inline. Semantics, traces and output are unchanged. -
Direct-style JS no longer keeps a value used once by the next call alive for the rest of the function (design §17.138), which lowered
binary_trees' peak memory on Node. -
Faster checked reads on the JS backend (design §17.151):
xs[i].expect(…)andMap.get(m, k).expect(…), when theOptionis used only there, compile to one checked read that builds noOption. A miss is stillD030with the same message and exit 70. -
Loops on the JS backend that perform effects whose handlers are found at run time now run as plain JS loops (design §17.156): an iteration whose handler answers directly continues in place, and only an iteration that suspends or reaches a handler that itself performs allocates a continuation.
handled_suspendruns about 3× faster on Node and its peak memory there fell from ~120 MB to ~50–64 MB. Semantics, traces and output are unchanged. -
Faster collections on the JS backend (design §17.116):
List.map,filter,filter_map,flat_map,range,zipandenumeratebuild their result in place before returning it,forover a list reads each leaf of the vector once,forover aMaporSetcopies nothing, and string splitting and map inserts allocate less.String.lenis documented as O(n) on JS: compute it once outside a loop. -
List.set,List.push,Map.insert,Map.removeandSet.insertupdate a collection in place when the compiler proves no other reference to it exists (design §17.149): built from a literal, a fresh constructor, an empty collection or an earlier such update, and only read (len,get,contains) before it is replaced.sieveno longer copies a trie path per write. Every other update stays persistent, so results are unchanged. The WASM runtime writes any path node with a reference count of one in place.
Fixed
-
Agent-facing status and MCP documentation now distinguish implemented CLI, stdio, WASM and verification capabilities from planned exports, and explain opt-in frozen specs. Contributor guidance points to the existing Rust workspace and its checks.
-
sakura fmtkeeps file header comments above sorted imports when an inline block comment precedes the first import, while moving that inline comment with its import. -
sakura fmtpreserves U+FDD0 in strings and comments instead of decoding it as a newline, and keeps Unicode separators and control characters inside line comments until LF. -
Llm.streamunderLlm.anthropicrequests server-sent events and callson_partialonce per text delta instead of once with the whole reply. -
sakura fmtno longer drops comments in import lists, afterwhere, or before a binary-, keeps one-line block comments inline in lists and statements, and lays out comments after=and=>instead of copying the statement verbatim. If formatting would still lose a comment or produce code that does not parse, the file is left unchanged andV9001reported. -
A generic refined type such as
type NonEmpty<T> = List<T> where List.len(it) > 0is its base at its own arguments:NonEmpty<Int>now coerces toList<Int>for calls, methods, fields, patterns and constraints instead of reportingV2032/V2001aboutT. -
A non-exhaustive
matchon a refined list type reportsV4001with the missing case instead of an internal compiler error.