Turicum 2.0.0 — Release Notes
Changes since release 1.4.2 (commit 0e49a49, 45 commits). The major
version bump reflects deliberate breaking changes in the string/binary API and
in the sandbox capability model, described first.
Breaking changes
str.bytes()andstr.from_base64()returnbin, the new first-class
byte-array type, instead of alstof numbers. Indexing and iterating the
result keeps working shape-wise, with one value-level fix: byte values are
now presented unsigned (0…255), so bytes ≥0x80change from negative
numbers to their unsigned form. Code that used list-specific operations
(append, list+) must adjust or call.to_list().
(str.from_base64_str()is unaffected.)jsonify()of abinis an error with guidance to convert explicitly
(.base64(),.hex(),.to_list()) — JSON has no byte type, and silently
choosing a representation would bake in a lossy convention.- Sandbox capability split:
IMPORTis no longer part ofFILE_READ.
import,sys_import, andsource_directoryare gated by the new
Capability.IMPORT;FILE_READnow gates data-file reading. Untrusted
policy validation changed accordingly:IMPORTrequiresimportRoot(...),
FILE_READrequires at least one file root (fileReadRoot/
fileReadWriteRoot). Untrusted embedders that grantedFILE_READto enable
imports must now grantIMPORT. turi.iois deprecated. Thefilesclass still works — it now
delegates to thefile_lines/file_writebuilt-ins (and therefore also
works in sandboxes that denyJAVA_REFLECTION) — but new code should call
the file I/O built-ins directly.
Embedding and sandboxing (new API, ch.turic.embed)
A complete Java embedding API for running Turicum scripts with controlled
trust, documented in EMBEDDING.md:
TuriEngine/TuriSession/TuriProgram— compile once, evaluate in
cheap isolated sessions; inject frozen globals, read results back as plain
Java values; programs serializable to the binary.turcformat.SandboxPolicywith three stances:trusted()(all granted,deny…to
trim),untrusted()(nothing granted,allow…to add), andUNRESTRICTED.- Resource limits: step limit, wall-clock timeout with watchdog abort,
thread cap (maxThreads/singleThread), output redirection, and
grace steps — a bounded step allowance forfinally/exit blocks to
release resources after a halt, without letting cleanup code outlive it. - Capability gating: built-ins are registered only when their required
capabilities are granted — an unavailable built-in is an ordinary
"undefined symbol", not a runtime denial. Capabilities:JAVA_REFLECTION,
IMPORT,FILE_READ,FILE_WRITE,FILE_CREATE,FILE_DELETE,
FILE_TEMP,ENV,NETWORK. - Class-access filter for reflection with a mandatory deny floor
(pierceable in trusted mode only), and import-root confinement as a
ceiling over the normal APPIA search.
The bin type
A first-class byte-array type (design in BIN_TYPE.md); the runtime value is
a raw Java byte[], exactly as str is a raw String, so reflection interop
is zero-copy:
- Constructor
bin()(empty / n zero bytes / from list / from encoded string
/ copy); conversionstext(charset),to_list(),hex()/str.from_hex(),
base64()/base64_url(); digests (md5…sha_512, returningbin). - Indexing, slicing, and iteration with an unsigned surface (0…255);
single-index assignment writes in place (aliasing observable), growing
operations produce new values. - Operators: concatenation, repetition, content equality, unsigned ordering,
infor byte values and subsequences. - Search (
index_of,contains,starts_with,count, …), in-place
fill/set,xor,reverse,left/right. - Binary structure codecs:
u8_at…u64_at,i8_at…i64_atand
their setters, with big/little endian and arbitrary byte-permutation order
strings (e.g."3412"). - Textual form
bin"48656c6c6f"— lossless and round-trippable via
from_hex.
File I/O built-ins
A complete file-access family (design in FILE_IO.md), sandbox-aware from the
ground up — the host grants scoped read and/or write access to directory trees
without opening reflection:
- Whole-file and metadata:
file_read,file_lines,file_write
(append/overwrite/mkdirs options, atomicCREATE_NEWfor
overwrite=false),file_exists,is_file,is_dir,file_stat,
mkdir,file_delete(recursive withforce=true),file_copy,
file_move. Binary modes read and writebinvalues; binary writes accept
binonly — encoding stays explicit. - Streaming handles:
file_reader/file_writerwithread_line/read/
read_all/write/write_line/flush/closeand fullwith-command
support (closed on every exit path, including after a halt, within the
grace window). - Random access:
file_random_reader/file_random_editor—
byte-orientedposition/seek/size/read/read_at/write/write_at/
truncateover aFileChannel; the reader handle physically lacks the
mutating methods. - Memory-mapped files:
file_map_reader/file_map_editorwith
get/put/flush, capped by the newSandboxPolicy.maxMappedBytes(long)
budget (untrusted default 0). Documented Java 21 caveat:close()
invalidates the handle, the pages are released at GC. - Temp files:
tmp_file()/tmp_dir()under the newFILE_TEMP
capability — a per-session scratch directory that acts as an implicit
read-write root and is deleted when the session ends. - Sandbox file roots: repeatable
fileReadRoot(...)/
fileReadWriteRoot(...)on the policy builder; relative reads search the
roots in declaration order, relative writes resolve against the first
read-write root; symlinks are followed but confined by their real path.
globmoved under the same confinement (no longer under the import root). - Leak safety: every open handle is force-closed when the session or
interpreter ends; write-family capabilities implyFILE_READ. - The
withcommand now accepts Java-implemented, fields-only resources in
theas aliasform, enabling lean built-in handles with unforgeable
entry/exit.
Debugger and tooling
- DAP (Debug Adapter Protocol) support — the Turicum debugger works
inside Visual Studio Code; atools/vscode-turicum-debugextension was
added, and the language server was cleaned up alongside. - Homebrew packaging:
brew install verhas/tap/turicuminstalls the
turiCLI from the Maven Central distribution zip; versioned formulae keep
older releases installable (BREW.md,homebrew/). - Release process documented in
RELEASE.md; CI workflows updated
(actions bumped to Node 24 majors).
Concurrency
mtxmutexes and thesynccommand — reentrant, abort-interruptible
locking with guaranteed release on halt.- Grace period machinery:
finally/exit blocks get a bounded step
allowance after a step-limit, timeout, or abort halt. - Halts (step limit, abort) use a dedicated exception type invisible to
Turicumtry/catch. - Global variables are volatile — safe cross-thread visibility without a
synchronization point. flowfixes: I/O-bound cells no longer hang indefinitely on timeout, cell
shadowing corrected,until-condition errors other than undefined-variable
now fail loudly.- Channel (
BlockingQueueChannel) bug fixes; several thread-hang and
multi-thread race fixes (includingtoLngObjectand thread-permit races).
Language and library
veilcommand — makes class/object fields inaccessible from the
outside.let mutdeclarations allowed.- BASIC preprocessor promoted to the production distribution
(turi/basic.turi), and therxregular-expression builder corrected and
extended. - Parameter declaration machinery (
Declare.params(...)) for built-in
functions: typed, named/positional parameters with defaults, shared by the
new built-in families. - Cycle guards in
toString/equals/hashCodefor self-referential lists
and objects. Castnumeric asymmetries fixed;isLong/isInteger/toIntegerhelpers.
Documentation
EMBEDDING.md— the embedding and sandboxing guide; every example is a
working unit test included verbatim.BIN_TYPE.md,FILE_IO.md— design documents with the decision records.REFERENCE.adoc— new chapters forbin, the file I/O family,mtx/
sync,veil, and the updatedglob.BREW.md,RELEASE.md— packaging and release process records.