Skip to content

Turicum 2.0.0

Latest

Choose a tag to compare

@verhas verhas released this 18 Jul 12:42

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() and str.from_base64() return bin, the new first-class
    byte-array type, instead of a lst of 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 ≥ 0x80 change 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 a bin is 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: IMPORT is no longer part of FILE_READ.
    import, sys_import, and source_directory are gated by the new
    Capability.IMPORT; FILE_READ now gates data-file reading. Untrusted
    policy validation changed accordingly: IMPORT requires importRoot(...),
    FILE_READ requires at least one file root (fileReadRoot/
    fileReadWriteRoot). Untrusted embedders that granted FILE_READ to enable
    imports must now grant IMPORT.
  • turi.io is deprecated. The files class still works — it now
    delegates to the file_lines/file_write built-ins (and therefore also
    works in sandboxes that deny JAVA_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 .turc format.
  • SandboxPolicy with three stances: trusted() (all granted, deny… to
    trim), untrusted() (nothing granted, allow… to add), and UNRESTRICTED.
  • Resource limits: step limit, wall-clock timeout with watchdog abort,
    thread cap (maxThreads/singleThread), output redirection, and
    grace steps — a bounded step allowance for finally/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); conversions text(charset), to_list(), hex()/str.from_hex(),
    base64()/base64_url(); digests (md5sha_512, returning bin).
  • 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,
    in for byte values and subsequences.
  • Search (index_of, contains, starts_with, count, …), in-place
    fill/set, xor, reverse, left/right.
  • Binary structure codecs: u8_atu64_at, i8_ati64_at and
    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, atomic CREATE_NEW for
    overwrite=false), file_exists, is_file, is_dir, file_stat,
    mkdir, file_delete (recursive with force=true), file_copy,
    file_move. Binary modes read and write bin values; binary writes accept
    bin only — encoding stays explicit.
  • Streaming handles: file_reader/file_writer with read_line/read/
    read_all/write/write_line/flush/close and full with-command
    support (closed on every exit path, including after a halt, within the
    grace window).
  • Random access: file_random_reader/file_random_editor
    byte-oriented position/seek/size/read/read_at/write/write_at/
    truncate over a FileChannel; the reader handle physically lacks the
    mutating methods.
  • Memory-mapped files: file_map_reader/file_map_editor with
    get/put/flush, capped by the new SandboxPolicy.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 new FILE_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.
    glob moved 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 imply FILE_READ.
  • The with command now accepts Java-implemented, fields-only resources in
    the as alias form, 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; a tools/vscode-turicum-debug extension was
    added, and the language server was cleaned up alongside.
  • Homebrew packaging: brew install verhas/tap/turicum installs the
    turi CLI 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

  • mtx mutexes and the sync command — 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
    Turicum try/catch.
  • Global variables are volatile — safe cross-thread visibility without a
    synchronization point.
  • flow fixes: 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 (including toLngObject and thread-permit races).

Language and library

  • veil command — makes class/object fields inaccessible from the
    outside.
  • let mut declarations allowed.
  • BASIC preprocessor promoted to the production distribution
    (turi/basic.turi), and the rx regular-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/hashCode for self-referential lists
    and objects.
  • Cast numeric asymmetries fixed; isLong/isInteger/toInteger helpers.

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 for bin, the file I/O family, mtx/
    sync, veil, and the updated glob.
  • BREW.md, RELEASE.md — packaging and release process records.