Skip to content

v2.2.5

Latest

Choose a tag to compare

@github-actions github-actions released this 10 Sep 19:16
· 830 commits to rust since this release
3b5eba8

v2.2.5

A stable patch with a broad correctness sweep. The bytecode VM and the WASM
runtime gained a long run of TclOO and command-lifecycle fixes, the refactor
engine now reads variables and command boundaries the way the segmenter does,
and # noqa is finally honoured the same way everywhere. The language server
also stops outliving the editor that started it.

New features

  • iRule translation to F5 Distributed Cloud renders pasteable XC Console
    documents
    , derives DNS-1035-safe object names, and ships the accompanying
    docs set.
  • The BIG-IP object-graph, embedded-rule, minimiser and partition-rename
    commands, and tcl-lsp.xcTranslate, are dispatched by the language server,
    so every editor gets them rather than only the ones with bespoke wiring.
  • The workspace scan's file budget is a setting, so a large monorepo can raise
    it instead of silently indexing a truncated workspace.
  • The registry answers which substitutions a call performs, and the Spec Studio
    forms expose the resolver.
  • IRULE5001 honours the debug gate its message has always promised, and stays
    off bodies that always run.

Improvements

  • # noqa is honoured by diag, lint and validate through one shared
    helper; disable=* works on an abstaining document; and a quick-fix is no
    longer offered for a check a noqa already silences. A marker must be a real
    # noqa, not the bare word appearing in prose.
  • The CLI reports the source-text findings the editor publishes, so the two
    surfaces agree.
  • SpecTcl corpus analysis batches synthetic calls, parallelises independent
    overlays and shares analyser and optimiser compilation units; SslicTcl
    consolidates its certificate metadata probes.
  • Comment and documentation prose across the tree now states what the code does
    and why, rather than how it came to be, with UK spelling throughout —
    including the W307 diagnostic text and the Spec Studio callback-taint help.

Bug fixes

  • The language server exits within a bounded grace once its session is over and
    runs its exit watchdog on an OS thread, instead of leaving a tcl-lsp-server
    process behind after the editor closes.
  • It no longer waits for the workspace index while holding the document map,
    and refreshes every locked workspace when a dependency changes.
  • A spec-pack directory outside the workspace is watched by base URI rather than
    an absolute glob. The old pattern was matched against the workspace instead,
    which made eglot watch every directory in the project until it ran out of file
    descriptors and failed to start.
  • Generating a deeply nested dict's string representation no longer recurses
    once per level, so a dict built through {*} argument expansion cannot
    overflow the native stack.
  • A long sweep of TclOO and command-lifecycle correctness in the bytecode VM and
    the runtime: identity preserved across namespace generations and command
    moves, retirement phased and qualified by generation, deferred tailcall
    activations installed, command generations re-resolved after callbacks, stable
    variable cell identity, dict info, array get element read traces, hidden
    command execution traced, byte-valued script completions preserved, and the
    error stack retained across an explicit info.
  • The refactor engine classifies extract-proc variables at the frame boundary
    and over the whole statement tree, keeps the reads a substituting command
    makes, reads a braced word as the literal it is, resolves inline-variable uses
    inside command substitutions, takes extract-variable boundaries from the
    segmenter, and guards inline-proc against a body's nested statements.
  • The optimiser stops O107 emptying complexity-guarded bodies, scopes
    runtime-selected frame opacity to its own frame, and walks lowered eval and
    uplevel bodies for binding effects.
  • subst's switches are read only through the registry, and the binary field
    grammar has a single owner gated per release.
  • f5-query names the rustls crypto provider per ClientConfig rather than
    relying on a process-wide default.
  • The Sublime plugin is held to its 3.8 host in the formatter as well as the
    plugin, and the TMM shim patchlevel is restored.
  • The GitHub Pages deploy builds again: a helper left ungated after the x509
    caveats were removed was dead code in the report-WASM build, which denies
    warnings.
  • W218's padding is repaired.

v2.2.4

This stable patch is mostly the JetBrains plugin. Three defects made it
largely unusable — Tcl files opened as plain black text, the Compiler
Explorer never opened at all, and the settings page could neither scroll nor
fit its own contents — and all three are fixed. The explorer's linear views
also gained real editor tabs, and the plugin now tells the truth about which
language-server features a JetBrains IDE actually asks for.

Breaking changes

  • The JetBrains plugin now requires IntelliJ 2025.3 or newer. Semantic
    highlighting is the reason: it is the only language-server capability the
    platform makes opt-in, and taking that opt-in requires building against
    2024.3 at minimum, while moving off the getters deprecated since 2025.2
    requires 2025.3. Users on 2024.1 through 2025.2 keep the version they have
    and stop receiving updates.

New features

  • Compiler Explorer views open in ordinary editor tabs. Open in editor
    puts the current view in a read-only tab where find, folding and the colour
    scheme all work, and moving the caret through it reveals the matching source
    span. The CFG, WASM and optimiser-diff panes stay in the tool window, where
    their edges and connectors are drawn rather than written.
  • The JetBrains settings page gained the optimiser profile selector it
    never had, alongside a link that hands every per-code choice back to the
    chosen profile.
  • JetBrains diagnostics now carry their code, whether they are an optimiser
    rewrite or a defect, and what accepting a quick fix would write — the
    problems view previously showed only the message.

Bug fixes

  • Tcl files are syntax-highlighted in JetBrains again. The grammar shipped in
    the plugin but nothing registered it with the IDE.
  • The JetBrains Compiler Explorer opens. Its webview was missing from every
    published plugin: the build extracted it on a best-effort basis and
    swallowed the failure, so the plugin shipped without it. The extraction is
    now a hard build failure.
  • The JetBrains settings page scrolls, and its checkboxes reflow to the
    window instead of running off the right edge.
  • Semantic highlighting refreshes when a spec pack changes. Editing a pack
    updated diagnostics and hover but left the colours stale until the buffer
    was touched.
  • Editor navigation from the Compiler Explorer lands on the right character
    in files containing non-ASCII text. Explorer ranges were byte offsets fed
    to editors that count UTF-16, which agreed only for ASCII.
  • A JetBrains IDE no longer force-enables optimisations the chosen profile
    disables. The plugin sent every per-code toggle as an explicit "on", which
    overrode the profile — so suggestions the default profile suppresses, such
    as constant propagation, appeared anyway.

Improvements

  • The VS Code extension and the JetBrains plugin are each about 24 MB
    smaller. Both bundled a second code editor and a WebAssembly language
    server that neither has loaded since they began using the host IDE's own
    editor.
  • The optimiser profile list is generated for every editor from one
    definition, so a profile cannot exist in one editor and not another.
  • The JetBrains settings page, README and marketplace description now mark
    the features no JetBrains IDE requests, and note the IDE version that
    brings each of the remaining ones.
  • Visible spec selection in the registry is faster.

Security and maintenance

  • Code-scanning findings resolved.
  • Continuous integration splits the language-server end-to-end suite across
    workers, skips work unaffected by a change, and reuses a green pull-request
    result when a release tag points at the same tree.

v2.2.3

This stable patch completes the editor rollout that was blocked during 2.2.2,
removes a whole-server didOpen publication wedge, and includes the compiler,
runtime, Spec Studio, and CI fixes made since that tag.

Reliability and editor delivery

  • Live document publication no longer holds the edit-order or document locks
    while waiting for Salsa or the workspace index. Generation-checked,
    revision-tagged publication now cancels stale work and rolls back only its
    own obsolete index replacement, keeping unrelated requests responsive and
    preventing stale spans from crossing document revisions.
  • The native VS Code extension suite now has deterministic coverage for the
    didOpen contention that wedged 2.2.2, including superseding edits, closes,
    dialect changes, index readers, rehoming, deletion, and workspace-symbol
    races.
  • JetBrains settings generation gives every diagnostic section a unique Kotlin
    panel variable, restoring the plugin build and marketplace publication.
  • Browser-host and native extension tests, front-end package gates, runner
    watchdogs, and targeted Rust smoke selection are more deterministic and
    cheaper to run.

Compiler and runtime correctness

  • Word values now retain the distinction between source spelling and evaluated
    value. Escaped substitution markers remain data, braced bracket text remains
    literal, and live unbraced substitutions in switch subjects and patterns
    contribute their variable and command-binding effects before dispatch.
  • Nested substitutions in assignments and other word-valued operands now
    invalidate the right compiler facts without evaluating a word twice.
  • Compiled Tcl units are revalidated after command mutation, and procedure
    bodies can be installed and dispatched as native WASM functions through the
    shared runtime table while preserving Tcl frame, result, depth, and error
    semantics.
  • Rename, trace, coroutine, child-interpreter, namespace teardown, welded
    quote, and numeric-tower behaviour move closer to the corresponding C Tcl
    releases.

Spec Studio and SpecTcl

  • Spec Studio now treats packs as the top-level unit of work, supports several
    open commands, provides a focus-following documentation dock and setting
    examples, and exports the complete pack and generated Rust/stub files in one
    operation.
  • Open .tclspec documents receive declaration outlines, durable loader
    notices, formatting coverage, include links, and spelling quick fixes from
    the same registry-backed language services used by the Studio.
  • Exhaustive Rust and SpecTcl rendering still checks all 46,722
    dialect/command comparisons, but deduplicates shared immutable specs and
    batched evaluator work, reducing the two focused sweeps by roughly 87% and
    83% in the recorded warm runs.

Security and maintenance

  • Editor webviews validate message origins and keep paths out of shell command
    construction; uploaded report paths are contained and closed correctly.
  • Dependency advisories were resolved, release-token scope was narrowed, and
    generated or vendored JavaScript is excluded from duplicate CodeQL scans.

v2.2.2

This stable update adds first-class SslicTcl authoring, restores the native
container workflow, advances Tcl-to-WASM execution, and fixes parser,
analysis, runtime, and editor integration defects found after 2.2.1.

New features

  • .sslictcl TLS declarations are now a first-class authoring format. The
    server detects the extension or header and provides vocabulary-aware
    completion, hover, signature help, semantic tokens, folding, document
    symbols, and ranged SSLIC* diagnostics in editors and tcl diag. The
    loader supports the complete version 1 vocabulary, deterministic round
    trips, and separate policy evaluation without executing declaration files
    or retained predicate scripts.
  • tcl pkg discover finds statically resolvable package require calls,
    reports dynamic and conditional cases for review, and can add proven
    dependencies to tclpkg.tcl with --add.
  • tcl docker now generates Debian-based Dockerfiles that install Tcl, the
    native tcl CLI, and locked packages without Python. Release binaries are
    selected by architecture and verified against SHA256SUMS; Alpine is
    rejected when the generated image would require an unavailable musl build.
  • The compiler and Rust WASM runtime gain runtime ABI v2 and proof-driven
    native lowering for the straight-line and expression/control-flow tiers.
    The compwasm and explore commands expose semantic code-generation
    passes through --codegen-passes, and Compiler Explorer can toggle and
    display the same registry-backed pass set.
  • A C Tcl extension shim lets trusted host code run commands written against
    the supported object, result, conversion, and command-registration subset
    of the C Tcl API on the project engines without rewriting those commands.

Improvements

  • JimTcl is represented as a resolved dialect profile with its own command,
    expression, number, escape, and release surfaces instead of being treated
    as an alias for a Tcl release.
  • SpecTcl 2.0 environment bodies are evaluated as scripts, so variables and
    loops can generate rows. Bundled EDA packs now own their environment
    declarations, and restyle directives resolve those environments through
    the same central profile catalogue.
  • Binary extensions can declare packages they load implicitly, such as Tk,
    through # tcl-lsp: package … provides …, [packages.provides], or the
    matching VS Code setting. Package availability, completion, hover, version
    checks, and diagnostics all consume the declared dependency graph.
  • Resource-scoped package, BIG-IP version, and target settings now resolve
    field by field for each workspace folder and reach every analysis path,
    including recovery, disk indexing, re-indexing, fix-all, and unindexed
    buffers.
  • VS Code and JetBrains can associate file extensions declared by loaded
    SpecTcl packs at runtime. JetBrains also supports the 2026.2 JCEF layout.
  • Sublime is now a lightweight Package Control LSP helper using Sublime's
    built-in Tcl syntax, while Zed is an LSP-only extension that finds or
    downloads the matching native server.
  • Disk re-indexing no longer holds the document lock. Spec Studio reuses one
    source index, generated files retain their timestamps when unchanged, and
    build and CI caches track the source inputs that actually affect outputs.

Bug fixes

  • Command and word boundaries, word substitutions, parse-error cuts, and
    incremental reparse decisions now come from shared lexer/segmenter owners.
    This fixes welded close-braces, stray closers, incomplete input, quoted and
    braced word distinctions, and substitutions nested at arbitrary depth.
  • The Rust runtime parses all words in a command before substituting any of
    them, matching Tcl evaluation order, and improves numeric-tower, variable,
    trace, rename, interpreter, namespace, array, and completion-code behaviour.
  • SSA, taint, and shimmer analysis now see reads inside nested command
    substitutions, preserve compatible numeric representations, and distinguish
    integer-only operators from general arithmetic. This closes diagnostics
    gaps where bracing or another substitution level previously hid a real
    read.
  • Spec Studio no longer treats a word left outside a declaration block as an
    executable program.

v2.2.1

This stable update broadens Linux compatibility and hardens the Rust runtime,
language intelligence, and editor delivery introduced in 2.2.0.

Linux portability

  • The prebuilt x86_64 and aarch64 GNU/Linux binaries now target a
    GLIBC_2.28 ABI floor. Release CI builds them natively in UBI 8 and rejects
    any newer symbol imports before publishing.
  • RISC-V uses Ubuntu 22.04's maintained packaged cross-toolchain and a
    GLIBC_2.35 floor. EL8 did not ship RISC-V, so this keeps the toolchain
    minimal without inventing an unsupported 2.28 sysroot.
  • Release CI starts the exact x86_64 release server across maintained Ubuntu,
    Debian, EL8/Oracle Linux, Amazon Linux, openSUSE, Fedora, and Arch containers.
    All four Linux programs (tcl-lsp-server, tcl-mcp, tcl, and f5-query)
    are checked at the producer and again after artifact fan-in.
  • The build uses current Rust plus ordinary GCC/binutils: no Zig toolchain,
    downloaded libc, or statically bundled musl. Programs continue to use the
    host's maintained glibc and receive its security updates normally.
  • Alpine and other non-glibc systems remain source-build targets. The
    separately published WASI server is unchanged and provides a libc-independent
    option for hosts that choose a WebAssembly runtime.

The portability change adds 29,328 bytes to the raw x86_64 server compared
with the former newest-glibc build. The paired Linux x64 VSIX grows by 12,654
bytes (0.024%). It adds no bytes to WASI or browser-WASM artifacts. In focused
measurements the glibc 2.28 build remained within noise of the newer-glibc
build, while the rejected static-musl experiment made the cold workspace scan
more than ten times slower.

Tcl runtime and conformance

  • TclVM namespace and ensemble behavior now preserves live token state and
    matches Tcl's command lifecycles more closely, including variable homes and
    pair-valued array access.
  • Real Tcl 9.0.4 startup, package paths, and Tcltest loading were repaired and
    moved behind a focused conformance runner shared by the supported engines.
  • Platform bootstrap, TclOO information/property dispatch, core grammar, and
    Tcl 9 array-index validation now use their central semantic owners rather
    than parallel implementations.

Language intelligence and dialects

  • Signature help no longer leaks from procedure parameter lists into procedure
    bodies.
  • Inherited TclOO callback captures honor effective visibility, and the
    registry's callback inventory now fails when authored coverage is silently
    downgraded.
  • iRulesLX navigation follows literal ILX::call and ILX::notify method
    names through ILXServer.addMethod, declared plugin workspaces, and their
    JavaScript definitions.
  • Registry result typing can derive a type from the call itself. Dialect and
    SpecTcl availability now use explicit surface rows and profile points rather
    than an availability bitmask, improving package- and release-specific
    answers.

Editors and transports

  • The language server now ships as native stdio, WASI stdio, and browser-WASM
    transports. The universal VSIX carries the WASI fallback, and the VS Code web
    extension is tested in a browser extension host.
  • The same VSIX set is published to Open VSX as well as the VS Code
    Marketplace.
  • The Sublime Text package is platform-independent and downloads a
    checksum-pinned native server on demand.

v2.2.0

The 2.x line is out of preview. After twenty-five 2.1.x pre-releases, the
Rust rewrite becomes the default release and the default Marketplace install.
VS Code and JetBrains users on the stable channel move to 2.x without opting
in to anything; the pre-release and eap channels remain for the next
development line, and the 1.x line stays available on its existing tags.

Python is retired. The whole toolchain is native: the language server
(tcl-lsp-server), the tcl and f5-query CLIs, and the tcl-mcp MCP
server all ship as single-file binaries for every supported platform, and
installing or running them needs no Python runtime and no interpreter
bundle.

Tk widgets, callbacks, and static preview

  • The language server now builds a conservative static model of a Tk widget
    tree, driven entirely by the command registry. It models only what is
    recoverable from source without running Tcl: a variable or command
    substitution in a widget path is recorded as an uncertainty rather than
    guessed at, so the preview never invents a widget that the script would not
    create.
  • Geometry-manager semantics are registry facts rather than hard-coded rules.
    pack and grid both claim a geometry container and cannot both propagate
    through one, while place manages content without claiming or resizing the
    container — modelled precisely instead of collapsed into a single
    mixed-manager heuristic.
  • Widget coverage is substantially wider: ttk::labelframe, ttk::scrollbar
    and ttk::toggleswitch are newly modelled, and ttk::treeview,
    ttk::notebook, ttk::combobox, text, spinbox, listbox, menu,
    send and the core tk command all gained substantially deeper specs.
  • The VS Code Tk preview panel renders the richer model — notebook tabs,
    treeview headings, listbox contents, menu items and toplevel titles — and
    shows an explicit badge where layout could not be determined statically,
    so an abstention is visible rather than silently drawn as an empty frame.

TclOO callback navigation

  • References, rename and code lenses now agree with each other on callback
    sites. A method used as a callback is found by all three providers, and the
    count on a lens matches what "find all references" returns.
  • Callback prefixes are resolved through the shapes real code uses: prefixes
    built as lists around self, prefixes stored in a variable and used one hop
    later, my-based callbacks wrapped in a namespace, and inherited wrapped
    callbacks resolved across files.
  • Where the receiver genuinely cannot be determined — an inherited callback
    cursor with no unique target — every provider abstains consistently instead
    of one of them guessing a method and the others disagreeing.

Registry and Spec Studio

  • A new cargo xtask callback-inventory gate generates and verifies a
    registry-backed inventory of every executable and callback-valued surface.
    Surfaces behind a resolver are retained as explicitly dynamic rows rather
    than having a position guessed from a function pointer.
  • Command-prefix construction is a typed registry vocabulary
    (BUILDS_COMMAND_PREFIX / WRAPS_COMMAND_PREFIX), so consumers prove what
    a prefix expression evaluates to by following registry traits instead of
    matching on command names.
  • CommandSpec carries structured side-effect metadata, feeding effect
    analysis from registry data rather than per-command branches in the
    analyser.
  • Closed compiler vocabularies — traits, taint colours, side-effect targets —
    now own their worked examples as registry data. Adding a vocabulary item
    fails to compile until it has one, and Spec Studio, the Compiler Explorer
    and the editor's help panels all render the same example.
  • Spec Studio gained inline help on catalogue items, registry-owned flow
    examples, and a clearer split between traits that mark a carrier and traits
    that describe flow.

Improvements and fixes

  • Taint analysis was substantially extended across the interprocedural and
    SSA paths, with the propagation rules and their tests grown to match.
  • SpecTcl pack loading was hardened, and spec projections no longer disagree
    with the registry they were generated from.
  • The workspace builds clean under Rust 1.98's tightened lint and
    documentation gates, and the dev tooling now audits the toolchain against
    the workspace requirement.
  • Tk method lifecycle checks respect the documented version floors rather
    than reporting against the newest release.
  • The Spec Studio browser tests drive Monaco's hover directly and tolerate its
    portalled widget, removing a class of flaky page tests.

v2.1.24

2.x alpha — pre-release channel.

This prerelease makes the Spec Studio and Compiler Explorer reference surfaces
easier to navigate, keeps their embedded language tooling aligned with the
compiler registry, and strengthens the release path. It remains opt-in through
the VS Code Marketplace pre-release channel, the JetBrains Marketplace
eap channel, or the assets on this GitHub release. The stable 1.x line
remains the default.

Spec Studio and Compiler Explorer

  • Compiler traits now have one typed, closed registry definition for their
    names, groups, author-facing documentation, and annotated examples. New or
    unknown trait groups fail at compile time, while Spec Studio and Compiler
    Explorer receive the same generated reference automatically.
  • Spec Studio replaces the flat trait-label bucket with grouped, searchable
    toggles. Every help and reference entry includes a small Tcl example with
    callouts showing where the trait, taint rule, or other behaviour applies.
  • Standalone web interfaces use Monaco exclusively, with the SpecTcl/Tcl 9
    language configuration, semantic highlighting, and hover available from the
    initial render. Editor extensions keep their native file tabs and place the
    Studio or Explorer beside them.

Release delivery

  • Every v* release tag now deploys the unified Pages site from the exact
    tagged commit, while branch deployments retain their path filtering. A drift
    gate protects the trigger and concurrency contract.
  • Post-release installer verification now affirmatively installs and validates
    MCP and Claude skills in an isolated temporary home, including an offline
    checksum, protocol, version, skills, and cleanup regression test.

v2.1.23

2.x alpha — pre-release channel.

This prerelease hardens the Rust-native compiler, runtimes, language server,
SpecTcl packs, and editor integrations. It remains opt-in through the VS Code
Marketplace pre-release channel, the JetBrains Marketplace eap channel,
or the assets on this GitHub release. The stable 1.x line remains the
default.

Tcl, compiler, and runtime correctness

  • Tcl 8.x and Tcl 9.x ${...} parsing now follows one release-aware rule
    across lexing, expressions, substitution, analysis, refactors, optimisation,
    code generation, and both execution engines. Nested Tcl 9 names no longer
    truncate or inherit an 8.x closing-brace rule.
  • Namespace, ensemble, TclOO, variable, trace, list, and dictionary behaviour
    is aligned more closely with C Tcl. This includes prefix resolution,
    namespace teardown, export/import options, element references, trace order,
    last-value-wins dictionaries, and command-binding-aware constant folding.
  • Compiler and analyser fixes cover quoted whole-command evaluation, braced
    loop lists, lambda and untyped-body fall-through, computed metaclasses,
    versioned command arguments, and deeply nested source walks without stack
    overflow.

Language server, SpecTcl, and editors

  • Diagnostic publishing now uses a persistent, latest-wins per-URI mailbox and
    performs client I/O outside document-ordering locks. A stalled publish can no
    longer freeze edits and unrelated requests across the language-server
    session; retained telemetry makes any residual scheduler stall
    self-diagnosing.
  • Cross-file analysis no longer strands callers on W123 while a definition is
    opening, or repeatedly re-wakes a deleted-on-disk buffer after facts move.
    Extension-host liveness verdicts now distinguish load, document-pipeline
    stalls, and whole-server wedges with process and thread evidence.
  • SpecTcl packs gain versioned arity, per-argument lifecycle rows, ambient
    package versions, robust malformed-pack notices, deterministic collision
    handling, and live pack-declared file-extension registration. VS Code keeps
    user associations intact while adding and retiring pack associations.
  • Editor language IDs, filename patterns, and dialect associations now come
    from the shared catalogue, closing drift across VS Code, JetBrains, Sublime,
    and the command-line tools.

WebAssembly and delivery

  • The browser language server uses a JavaScript-backed clock instead of native
    time primitives that trap in WebAssembly, and the import-free VM build stays
    import-free.
  • Pull requests now build and execute the browser language-server WebAssembly
    target, including its complete local Cargo dependency closure, so Pages-only
    failures are caught before merge.
  • The workspace is clean on Rust 1.98, runtime formatting is part of the Rust
    gate, and generated and satellite WebAssembly surfaces have stronger drift
    and real-link coverage.

v2.1.22

2.x alpha — pre-release channel.

This maintenance prerelease carries forward v2.1.21 with refreshed release
performance measurements and the portable source-data build tooling.

Engineering and delivery

  • Release verification remains portable across GNU and BSD host utilities,
    including the PEM source-data generation path.

For the complete feature list, see the v2.1.21 release notes.

v2.1.21

2.x alpha — pre-release channel.

This maintenance prerelease carries forward the v2.1.20 Rust-native compiler,
analyser, language server, runtime, and editor tooling while fixing the release
packaging path for the embedded Spec Studio.

Engineering and delivery

  • VS Code and JetBrains release jobs now install the pinned
    wasm-bindgen-cli and stable Rust toolchain required to build the embedded
    language-server worker, so both editor artefacts are produced reliably.

For the complete feature list, see the v2.1.20 release notes.

v2.1.20

2.x alpha — pre-release channel.

This release advances the Rust-native compiler, analyser, language server,
runtime, and extension tooling. It remains opt-in through the VS Code
Marketplace pre-release channel, the JetBrains Marketplace eap channel,
or the assets on this GitHub release. The stable 1.x line remains the
default.

Compiler and runtime correctness

  • Optimisation now respects dynamic variable observation, trace state,
    executable control-flow edges, computed names, frame reach, and NaN-sensitive
    comparisons. This closes a batch of silent-miscompile cases while retaining
    guarded fast paths when their proofs hold.
  • Tcl release selection now drives lexing, escape decoding, expression
    operators and numerals, formatting, command availability, compilation, and
    host execution end to end. Tcl 8.4 through 9.1 programs no longer inherit
    syntax or built-ins from the host's default release.
  • Shared syntax owners now handle substitution literals, parameter lists,
    word closers, case-list layouts, expression numeral boundaries, comments,
    and iRules event regions. Compiler, analyser, formatter, diagram, and LSP
    consumers use those facts instead of maintaining divergent parsers.
  • The virtual machine preserves command-surface and profile identity through
    aliases, hide/expose, rename, imports, coroutines, child interpreters, traces,
    and cached bytecode. Switch, try/return, expression, and host-fallback paths
    now retain their exact Tcl completion and dialect behaviour.

Language server, iRules, and extensibility

  • iRules event discovery, symbols, semantic tokens, comments, selection,
    diagnostics, and compilation now share top-level, registry-resolved event
    boundaries. Nested or unreachable declarations are excluded, exact command
    identity survives aliases, and conflicting event priorities are diagnosed.
  • Dialect strings are resolved once at CLI and LSP ingress and carried as typed
    profiles. Editor dialect choices and lexical grammars are generated from the
    same registry and syntax owners for VS Code, JetBrains, and Sublime.
  • Registry lifecycle facts model Tcl startup globals for W210 without hiding
    genuine undefined locals or values invalidated by unset. Other LSP
    features now consume shared case, frame, reference, and embedded-language
    contracts, including canonical Windows diagnostic URIs.
  • Project SpecTcl packs apply consistently across the CLI and VS Code, with
    version ranges and release history enforced throughout their lifecycle. Spec
    Studio gains native editor hosts, import/export provenance, formatting,
    highlighting, and a Monaco-backed Pack DSL client whose LSP readiness is
    explicitly verified.

BIG-IP and TLS assurance

  • A new safe, non-executing SslicTcl engine models certificates, keys, chains,
    trust programmes, protocols, ciphers, HSTS, endpoint evidence, nginx,
    OpenSSL, and testssl.sh input. Its pinned Chromium and Trust Stores
    Observatory data is embedded with deterministic provenance and offline
    verification.
  • BIG-IP reports now project effective client- and server-SSL configuration,
    correlate certificate and key material, validate object references, and
    surface TLS assurance and chain findings across native, compatibility, and
    WebAssembly outputs. Unknown evidence remains explicitly unknown rather than
    receiving an optimistic grade.

Engineering and delivery

  • The native installer is stricter and more portable, including archive
    verification, platform selection, upgrade behaviour, and a broader harness.
    CI cache-warming and VS Code test downloads are corrected and faster.
  • New owner-resolution, editor-generator, documentation-link, diagnostic-tag,
    iRule-test-data, and tooling drift gates keep generated assets and semantic
    contracts aligned with their Rust sources of truth.
  • Differential-fuzz campaigns now pin one Tcl release across both engines and
    replay it from durable, race-safe finding records, preventing deliberate
    cross-release differences or incomplete record pairs from being reported as
    findings.

Performance across the 2.x releases

These graphs cover every measured 2.x release from v2.1.0 through
v2.2.0, run by scripts/perf/ against a pinned 113-file corpus (scope
small, revision 1). The corpus, scope, and revision are fixed across the
whole series, so the lines are comparable with each other.

2.2.0 is this release: it is the bright-blue line in the memory and CPU
graphs and the rightmost bar in each wall-time group. Earlier releases are
drawn in grey and fade with age.

The series spans more than one measurement host — Apple M1 Max (darwin-arm64);
AMD EPYC 9V74 80-Core Processor (linux-x86_64); AMD EPYC 7763 64-Core
Processor (linux-x86_64); Apple M5 Max (darwin-arm64); Intel(R) Xeon(R)
Processor @ 2.10GHz (linux-x86_64). Wall time and CPU are properties of the
machine as much as of the build, so compare within a host era rather than
reading the boundary as a product change. Resident memory is far less
host-sensitive.

Resident memory

Resident memory across the 2.x releases

CPU utilisation

CPU utilisation across the 2.x releases

Per-check wall time

Per-check wall time across the 2.x releases

Benchmark table and method
notes

— the raw result JSON is attached to this release as perf-2.2.0.json.