Salamatrix framework gap analysis

Status date: 2026-08-08

Source vision: <https://krtkovo.eu/salamander/framework.html>

This audit compares the framework vision with the implementation in this repository. It distinguishes working code from API placeholders, samples, and catalog metadata. The target is not to reproduce the complete native Plugin SDK in scripting languages. It is the middle extensibility layer described by the vision: persistent lightweight extensions with commands, UI, events, storage, and a shared Salamander object model.

Status labels in the matrix are deliberately requirement-level, rather than commit-level: Implemented means the scoped vision item is covered by working code and a focused test; MVP means the public slice works end-to-end but the vision still calls for a broader surface; Partial means substantial pieces exist but the current slice is not yet a coherent user-facing feature; Missing means there is no implementation of the requested surface yet.

Executive summary

The repository already contains a real Salamatrix foundation, not only a design:

The repository now covers the scoped first-version middle layer, including the lightweight Viewer and flat FS roles. It is no longer only an MVP/PoC for this scope. The remaining work below is hardening, richer variants, or intentionally out of the v1 boundary rather than a missing basic extension role. In particular:

Requirement matrix

Vision area Status Current implementation Missing work
Three extensibility levels MVP Native plugins, one-shot Automation scripts, and persistent manifest-backed workers now share an owner-aware lifecycle catalog; registration activates persistent workers and the host-call dispatcher binds commands, sides, storage, event subscriptions, and UI calls. Extension host callbacks now hold owner-aware unload leases. Persistent teardown in both Salamatrix and the Automation compatibility bridge closes new callback admission, stops the worker, and joins its pump while the UI thread services only synchronous sent host calls; neither path releases a live session after a timeout. The append-only IRuntimeSession::GetDiagnostic contract reports bounded running/stopped/exited/failed lifecycle state, cached process id/exit code, and diagnostic text without exposing process handles. After the splash screen closes, the visible main window is covered by one localized startup progress window while load-on-start plugins and extensions initialize; Salamatrix reports the current package and distinct discovery, extension, FS, menu, activation, toolbar, and Viewer registration phases through a temporary host-owned service. The matching shutdown service keeps one localized dialog visible across the complete close sequence, identifies each native plug-in, and reports each Salamatrix package while toolbar contributions and extension registrations are removed, runtime sessions and extension windows are stopped, services are released, panels are closed, configuration is saved, and shutdown is finalized. Structured per-extension startup failure details, timed unload diagnostics, and richer lifecycle diagnostics; no separate Extension Manager is planned.
Shared cross-runtime API MVP The Salamatrix service layer, versioned ABI, SMX1 transport, and Python/PowerShell/PHP/JavaScript worker facades use the same host method vocabulary, including commands, sides, file operations, storage, events, clipboard, UI, and AI. Storage now preserves string, boolean, and signed 64-bit integer values across the host boundary and exposes typed storage.keys() enumeration with deterministic JSON ordering. Broader runtime-neutral value model, complete object model, and formal error/threading rules.
Left/Right/Source/Target sides MVP Salamatrix.Sides and all modern workers resolve all four references and expose active tabs, bounded path/type, selected-item snapshots, focused-item metadata, item name/path/extension/size/attributes/UTC write time and hidden/link/offline/size-valid flags, and active/source/target/locked/detached flags without raw core pointers. Modern workers now also enumerate tabs, activate a tab, change the active-side path, request a side refresh, select individual/all items, and move focus by stable panel index. View mode/tree state and item change events.
Tabs and detached windows MVP SDK snapshots and opaque process-local ids expose tab count, index, path/type, active/source/target/locked/detached flags, activation, path changes, refresh, selection/focus, and snapshot-derived lifecycle events. Sides schema 1.3 now publishes append-only create/close/reorder/move/detach methods, the host bridge validates decimal tab ids and side/index inputs, and all five worker facades expose the same contract. Isolated process-runtime coverage uses an explicit SALAMATRIX_WORKER_ROOT built from provider workers. Direct core load/version negotiation, colors, richer detached-window operations, and persistence semantics.
Existing Salamander commands MVP The stable catalog now covers view/edit/open, rename, copy/move, email/delete/properties, case/attribute/space operations, refresh, directory creation, drive info, directory sizes, and disconnect; execution still uses Salamander's normal enablement and dialogs. Parameterized command calls, richer synchronous/modal results, state/change notifications, and non-modal operation handles.
Programmatic file operations MVP IFileOperationsService and all modern worker bindings expose interactive rename/copy/move/delete/create-directory/refresh/properties workflows. Typed source/target values, progress/cancellation handles, and final structured results without requiring the native dialog.
Lightweight Viewer role Implemented Manifest schema 2 accepts bounded viewers[] contributions with optional display names. Salamatrix registers each enabled contribution separately through the native Viewer association path during Connect, independently of runtime-provider startup order; Configuration lists every extension/Viewer identity as its own Associated viewer choice and persists that identity with the association. The host passes the chosen identity through versioned Viewer invocation data, so a concrete extension Viewer manually associated with *.* or selected as an alternate Viewer by Alt+F3 dispatches that exact handler instead of re-matching the file against its original manifest mask. The shared dispatcher supplies path, window geometry/show state, always-on-top state, and enumeration context through the cross-runtime Salamander.invocation object. Newly discovered masks are forced exactly once and later user removals remain respected. Optional signature/content sniffing and framework-owned modeless rendering controls; new associations still require a Salamander restart because viewer masks are a connect-time host contract.
Flat file-system role Implemented Manifest schema 2 accepts bounded fileSystems[] providers, actions, and up to 16 localized detailed-view columns. The framework-owned salamatrix: native FS lists providers and atomically collects up to 4096 flat runtime items through the capability-gated salamander.fileSystem.addItem or batch addItems call. Batch publication uses one worker/host round-trip for the complete snapshot. The native FS renders and sorts text/numeric custom column values, resolves validated light/dark SVG item icons inside the package, refreshes on a bounded timer, and builds a native Unicode action context menu with localized titles, separators, and per-action refresh control; only an explicitly default action runs on Enter. Runtime listing runs asynchronously behind a per-open-FS snapshot cache; the UI listing path returns immediately, displays the panel throbber while the initial empty cache is loading, and posts the completed snapshot without creating a refresh loop. Provider executions are serialized where they share package dispatch state, and close joins the worker while dispatching sent UI-thread calls. Provider contents begin with ..; Directory Line exposes clickable root/provider segments; full, shortened, and directory-only title modes are honored. All five workers expose equivalent single-item and batch publication semantics and all five bundled demos implement equivalent Viewer/FS handlers. Complex hierarchy, copy/move/delete/upload, free-space/search/security integration, and multi-selection batch actions are intentionally outside the Hyper-V-Machines-level v1 role.
Extension command registration MVP Discovery-time metadata gives a script stable identity/caption/placement hints, and a persistent worker can register/unregister multiple owner-scoped commands with synthetic native menu ids, context masks, native menu hotkeys, toolbar contributions, optional handler names, and append-only enabled/visible state. Manifest command records are now published automatically with their initial state, while worker setState updates the existing Plugin Manager/menu/toolbar path and removal triggers a menu/toolbar rebuild. A manifest command may alternatively declare a fixed path; the host then changes the active panel directly without starting a runtime worker and enforces panels.write. Each selected runtime command propagates its ID and handler into the worker as Salamander.command_id/Salamander.command_handler, so one entry point can dispatch distinct handlers. Enable/visible callbacks, command palette integration, richer handler lifecycle metadata, and richer ownership/unload leases.
Plugin and context menu placement MVP Metadata booleans and context masks are applied to Automation menu items and persistent registrations. Independent placement contributions, icons, and dynamic menu APIs beyond the current MVP surface.
Toolbar and shortcuts Partial Dynamically registered extension commands now pass Salamander hotkeys through the normal menu-extension path, contribute toolbar buttons, and honor per-command enabled/visible state. Native/runtime registrations use core-owned DPI-aware image lists; manifests may provide package-wide SVG icon and optional dark-mode iconDark, or override them on each commands[] item. If the selected iconDark is missing or invalid, the core generates a dark-friendly raster variant from the normal icon and also creates the disabled/gray image. Dynamic placement is now serialized with stable extension/plugin keys instead of transient runtime ids. Explicit placement/conflict UX, command palette integration, richer state callbacks/change notifications, and richer toolbar metadata.
Events MVP Salamatrix.Events maps host lifecycle/settings/configuration/color/panel events, successful shared-Sides path/selection/tab/refresh operations, core path/selection/tab notifications, and core filesystem-change notifications (fileChanged, including the affected path and recursive-scope flag) to unsubscribe-safe native callbacks; successive tab snapshots add tabCreated, tabClosed, tabReordered, windowDetached, and windowAttached with changedTabId, tabIndex, and previousTabIndex, delivered before legacy tabChanged. Automation exposes subscribe/unsubscribe with copied payloads and preserves the V1 payload prefix. Manifest-backed extensions may declare an event allow-list, which the host enforces before creating a subscription. Persistent worker sessions now enqueue bounded event frames instead of writing from the core callback directly into a potentially back-pressured pipe. Typed create/rename/delete classification, UI-thread marshalling for richer event payloads, coalescing, event replay, richer direct window lifecycle hooks, and unload-safe leases across modern runtimes.
Per-extension storage Implemented Salamatrix.Storage persists isolated manifest-id namespaces with UTF-8 strings, signed 64-bit integers, booleans, delete/clear, validation, and synchronized access. Manifest packages may declare typed settings with optional defaults; the host materializes missing defaults without overwriting user values and exposes storage.schema() to every modern worker. The SMX1 host dispatcher and Python/PowerShell/PHP/JavaScript/Lua workers preserve all three value types instead of coercing settings to strings. The Plugin Manager can now edit the declared scalar settings through the shared UI service. Versioned manifest migrations apply typed rename/remove operations before defaults and persist their bounded migration version. Legacy global persistence remains for compatibility. Settings files/enumeration, quotas, transactional batches, and uninstall retention/deletion policy.
Shared UI framework MVP Salamatrix.UI provides a reusable native IDialog/IControl model and NativeDialog implementation for labels, text boxes, check/radio buttons, combo boxes, ordinary buttons, native ListView/TreeView/TabControl controls, editable folder/file pickers, group boxes, CGUIStaticTextAbstract, CGUIHyperLinkAbstract, CGUIProgressBarAbstract, arrow/text-arrow/color-arrow buttons, and CGUIToolbarHeaderAbstract. Explicit layouts, item/column/selection binding, validation, change events, hyperlink actions, tooltips, static-text style/path flags, known and indeterminate progress, color values, and toolbar-header masks cross the same SMX1 package-host dispatcher. JavaScript, Python, PowerShell, PHP, and Lua facades forward an equivalent option set; Automation exposes a thin COM dialog adapter and native plugins use IUIService directly. Each bundled demo and DemoPlug independently constructs the same capabilities dialog and its runtime/extension identity group; none depends on a prebuilt Automation-owned gallery. The native implementation applies the selected Salamander dark scheme, keyboard traversal, initial focus, per-monitor WM_DPICHANGED scaling, and bounded accessibility metadata/tooltip fallback. Progress-dialog, immediate UI, clipboard, and picker services remain on the same framework-owned surface. See doc/salamatrix-ui.md. Richer notification actions/stacking, virtualized data, full accessible roles/UI Automation and screen-reader audit, interactive per-monitor GUI testing, reentrancy policy, and migration of legacy Forms wrappers.
Manifest/package Implemented Strict UTF-8 JSON parsing accepts compatible schema 1 and final schema 2 through the canonical schema key and the supported schemaVersion compatibility alias; it rejects conflicting values when both are present. It validates package/runtime identity and minimum version, safe entry points, package-owned SVG assets, capabilities, typed settings/defaults and migration chains, dependencies, locale resources, up to 64 command records, up to 16 Viewer contributions, and up to 16 flat FS providers with bounded actions, custom columns, and refresh intervals. Discovery materializes settings migrations/defaults, resolves package dependencies, restores persisted enabled state, activates eligible workers, and publishes the result through the owner-aware Extensions registry. Salamatrix Studio scaffolds schema: 2, accepts both compatible keys, and preserves Viewer/FS records. Signed packages, transactional install/update/rollback, dependency acquisition prompts, and uninstall retention policy remain distribution hardening rather than missing runtime capability.
Runtime adapters MVP Salamatrix.Runtime registers/enumerates versioned adapters and executes manifest entry points through structured requests/results. Automation registers only legacy ActiveScript adapters; modern CPython, PowerShell, PHP CLI, Node, and Lua runtimes are supplied through independent .spl providers using the same broker. All five standalone providers have Debug and Release x64 projects, with deferred registration when Salamatrix loads later; Lua additionally passes an isolated SMX1 demo call sequence without starting Salamander. The isolated process-runtime contract test runs with an explicit SALAMATRIX_WORKER_ROOT, exercises Python/PowerShell/PHP host-worker lifecycle and UI calls, and verifies GetDiagnostic running/stopped/exited/failed state, cached process id/exit code, and diagnostic message. A native regression reproduces the shutdown deadlock topology with a pump thread blocked in synchronous SendMessage and verifies that the UI-thread join dispatches that callback before releasing the session. Manifest publication checks the requested adapter and minimum version, marks unavailable extensions as waiting, and retries them after a broker refresh. Direct standalone .spl load test through Salamander, startup failure capture before a session exists, cancellation beyond process termination, debugging, dependency environments, and richer dependency policy.
JavaScript runtime Process MVP Windows JScript remains the compatibility fallback for legacy .js; JavaScriptRuntime.SPL now discovers Node via SALAMATRIX_NODE, node.exe, or node, owns the dependency-free SMX1 .mjs worker, and registers JavaScript.Node independently of Automation. The worker now exposes the same host API surface as Python/PowerShell/PHP, including convenience dialog controls, native dialogs, and event subscriptions. Debug and Release x64 builds are verified. Explicit .js/.mjs precedence with the legacy fallback, package deployment policy, and richer value bindings.
Python runtime Process MVP ActivePython COM compatibility remains; Python.CPython discovers python.exe/python3.exe or SALAMATRIX_PYTHON, runs .py entries out of process, and the optional worker bootstrap exposes the shared SMX1 Salamander API including multiple command registration. A standalone PythonRuntime.SPL project owns the same adapter/worker, unregisters it through the broker, and now passes a Debug x64 build. Richer UI/value bindings, environment/dependency policy, and bundled runtime.
PowerShell runtime Process MVP PowerShell discovers pwsh.exe/powershell.exe or SALAMATRIX_POWERSHELL, runs .ps1 entries out of process, and ships the same SMX1 worker bootstrap/API shape including multiple command registration. A standalone PowerShellRuntime.SPL project owns the adapter/worker and broker registration path and now passes a Debug x64 build. Richer UI/value bindings, environment policy, cancellation/error mapping, and bundled runtime.
PHP runtime Process MVP Legacy PHPScript remains; PHP.CLI discovers php.exe or SALAMATRIX_PHP, runs .php entries out of process, and ships the same SMX1 worker bootstrap/API shape including multiple command registration. A standalone PHPRuntime.SPL project owns the adapter/worker and broker registration path and now passes a Debug x64 build. Richer UI/value bindings, dependency policy, and support decision/bundled runtime.
Lua runtime Process MVP Lua prefers an explicit SALAMATRIX_LUA override, otherwise uses the bundled vcpkg-built Lua 5.5.0 interpreter, with PATH discovery as a compatibility fallback. It runs .lua entries out of process and ships a dependency-free Lua SMX1 worker with the common Salamander facade. The runtime package contains lua.exe, lua.dll, the full MIT notice, and the worker; Release x64 build, PE/package verification, syntax loading, and an isolated storage/notification SMX1 call sequence pass. Direct provider load through Salamander, debugger integration, and dependency environment policy.
Extension management Partial The existing Plugin Manager remains the single management surface: it shows ordinary .SPL plugins and now appends discovered manifest-extension rows from Salamatrix.Extensions with name, state, version, runtime, entry point, and manifest ID details. Extension rows use the package SVG icon, prefer iconDark in dark mode, and derive a dark-friendly bitmap from the normal icon when the dark asset is absent or invalid. Their Functions detail is driven by Extensions 1.4 contribution flags and identifies manifest commands[] as Menu Extension, viewers[] as File Viewer, and fileSystems[] as File System (FS). Missing runtime adapters are shown as runtime unavailable; unresolved manifest dependencies are shown as dependency unavailable; a user-deactivated extension is explicitly shown as disabled. Its existing Activate/Deactivate action persists the enabled state in the extension's isolated Storage namespace, stops the worker before disabling, and reactivates it after re-enabling. Configure opens a Salamatrix.UI native dialog for up to 24 declared string/integer/boolean settings, uses localized labels and visible groups, applies bounded width/multiline layout metadata, and writes typed values into the extension's isolated Storage namespace. Rows are still not treated as loadable .SPL files. No separate Extension Manager is planned. Remove, package install/uninstall, settings help/tooltips and richer layout semantics, more than 24 settings, and richer runtime/status details in the existing Plugin Manager.
Permissions/capabilities MVP Manifest capabilities are enforced by the framework-owned package dispatcher for commands, interactive file operations, flat FS item publication, sides read/write, storage, events, UI, clipboard, and runtime discovery. The file-system capability gates addItem and addItems; panel mutations require panels.write; legacy manifests without a capabilities list remain compatible. Explicit user grant/revocation UI, filesystem/network/process sandbox policy, effect audit trail, and richer package UX.
AI automation assistant MVP Salamatrix.AI provides provider registration, structured generation validation, parsed effect flags, runtime/existing-script/feedback hints, explicit unsupported-capability responses, a safe generate/preview seam, and focused Salamander.ai.api(topic) retrieval. The separately installable SalamatrixAI.SPL owns the bounded local command provider, the optional native WinHTTP local model provider, and an interactive multiline chat with Ask/Preview/Run/Save actions; follow-up prompts carry the previous script as repair context. The optional Salamatrix AI Local LLaMA.SPL companion owns the server-free local.bundled llama.cpp CLI provider and its separately installed CPU/model assets. The chat enumerates providers, shows ready/unavailable status, and supports explicit selection or automatic fallback. Its dynamic Menu Extension publishes the sole localized command for opening the chat, and its shutdown path validates the borrowed AI service identity before unregistering providers so framework-first unload cannot dereference a stale pointer. A shared static validator checks response shape, capabilities, effects, runtime identity, undeclared external/network operations, and the optional canImplement/missingCapabilities fields; bounded GenerateWithRepair is used by the standalone chat and shared Automation AI host/API consumers. When Automation is loaded, Salamatrix.ScriptRunner routes Run through the same capability-aware SMX1 host dispatcher as regular extensions; Automation does not publish an Ask-AI menu or own the chat flow. The full API description now also carries live native service contract versions, the currently registered runtime adapter inventory, and schema fragments supplied by the native command, file-operation, UI, sides, events, storage, extensions, and runtime contracts. Complete method/field schema coverage without hand-maintained fragments, model variants, and remote providers.
Testing Initial Standalone /W4 /WX tests cover the strict manifest parser (including localized setting metadata, layout validation, and initial command state), Storage persistence, Events subscribe/publish/self-unsubscribe/capacity/payload validation, Extensions registration/lifecycle/ownership and legacy setting-schema prefixes, the local owned-service registry, runtime raw-JSON context and AI service contracts (including focused API slices), the synchronous-host-callback runtime-pump join regression, and integration tests for Python/PowerShell/PHP process execution, output capture, timeout, editable file-picker protocol calls with flat filter/save options, command enabled/visible state changes, persistent-session lifecycle diagnostics for running/stopped/exited/failed workers, native dialog host calls, and deterministic UI layout/DPI metrics. The explicit SALAMATRIX_WORKER_ROOT run uses isolated copies of provider worker assets and passes without starting Salamander. Worker syntax checks cover Python, PowerShell, PHP, Node, and Lua; all five demos expose the same explicit gallery geometry. Release x64 builds of Salamatrix, Automation (including its COM type library), and DemoPlug cover the native API additions. A fast source-contract regression test locks key Plugin Manager, AI, service-lifetime, runtime-shutdown, and dynamic-menu paths. Direct core-registry runtime tests, automated pixel/accessibility testing of the capabilities gallery, interactive per-monitor GUI tests, extension fixtures, lifecycle/unload integration tests, startup-failure fixtures, and end-to-end Salamander API adapter tests.

Persistent runtime shutdown crash regression (2026-08-09)

Two x64 crash reports identified one teardown race, not a manifest schema compatibility failure. One fault returned from a PowerShell worker pump into a freed IRuntimeSession; the other executed a queued main-thread host callback after salamatrix.spl had already been unloaded. Both were enabled by a five-second pump-thread wait followed by session release (and, in Automation, forced thread termination) while the pump could be synchronously blocked in InvokeOnMainThread/SendMessage.

Salamatrix Framework 0.6 and Automation 2.4 now mark the session as stopping before removing its bindings, reject newly arriving host/event/dialog calls, stop the worker, and retain the session and module until the pump has actually returned. When teardown runs on Salamander's UI thread, the shared join helper dispatches only nonqueued synchronous sent messages, avoiding the circular UI-thread/pump-thread wait without consuming posted application work.

A follow-up close-time report from the same build exposed a separate native UI lifetime bug: a long-lived notification popup survived framework release, and USER32 later dispatched WM_WINDOWPOSCHANGING to Salamatrix::UI::NotificationWindowProc at RVA 0x5D5B0 after salamatrix.spl had been unloaded. Salamatrix Framework 0.7 tracks every notification HWND alongside modeless native dialogs, destroys those windows synchronously during CPluginInterface::Release, and unregisters their window class before the module can unload. The PR-running native UI test creates a long-timeout notification and verifies that the shutdown hook leaves no window of that class alive.

Current verification snapshot

The newest implementation commits include d5f7e56d9 (runtime-built Salamatrix.UI capabilities dialogs), 4a380ef3c (editable native FilePicker and standalone worker parity), 89a1d4fbf (isolated process runtime verification), a6a8cedc8 (Plugin Manager settings configuration), 9aa3cbf84 (per-command SVG toolbar artwork), and 6e1711cd8 (dialog FolderPicker). They were compiled into isolated Debug x64 output directories; the user's locally running Salamander process was never started, stopped, or otherwise controlled by this work.

The current implementation separates the optional Salamatrix AI Local LLaMA.SPL companion from the model-free SalamatrixAI.SPL. Its configuration downloader is syntax-checked and pins the official llama.cpp CPU x64 archive and both selectable Qwen GGUF models by SHA-256; the plugin build contains only the downloader script, not the binary or model. A live model download was intentionally stopped at the 120-second command limit in this environment; no Salamander process was started or controlled.

At the previous pause point all Salamatrix source and documentation changes were committed. The pre-existing worktree-only .gitignore change keeps the two syntax-check artifacts out of source control: src/plugins/automation/runtime/__pycache__/ and src/plugins/pythonruntime/runtime/__pycache__/. They are not source changes and are not staged.

On 2026-07-26, the append-only lifecycle diagnostic contract was verified by an isolated Debug x64 rebuild of the process test, protocol test, and all four standalone provider projects. With SALAMATRIX_WORKER_ROOT set to build\verification\runtime-diagnostics\worker-root, the process-runtime executable passed with exit code 0; its one-shot worker reported running, then exited with exit code 0. The run also exposed stale typed-storage/schema methods in the standalone Python worker, which were brought back to parity before the passing rerun.

The UI slice was verified on 2026-07-26 with an isolated Debug x64 Salamatrix.SPL rebuild and the standalone ui_layout_tests.exe. The test passed picker geometry checks plus 96-to-144 DPI and 144-to-96 DPI scaling checks. No GUI Salamander process was started or controlled.

The current runtime baseline was rebuilt from the current source into build\verification\current-runtime-baseline. Its process-runtime executable passed with SALAMATRIX_WORKER_ROOT explicitly set to an isolated root containing only the Python, PowerShell, and PHP workers copied from their standalone runtime-provider projects. The run returned exit code 0 and no Salamander process was started or controlled.

The current worktree was audited again after the SalamatrixAI workflow changes: build\verification\worker-root-current was created as an isolated root from the Python, PowerShell, and PHP worker files in this checkout. The existing Debug x64 process-runtime executable from the parent-revision baseline was run with that root in SALAMATRIX_WORKER_ROOT and returned exit code 0. It covered the same host-call, persistent-session, UI, storage, event, picker, AI preview, shutdown, output-capture, and timeout paths; Node was additionally syntax checked with node --check. This validates the current worker assets and SMX1 contract, while a fresh current-source Debug x64 rebuild remains dependent on the unavailable Visual C++/MSBuild toolchain in this environment.

Existing implementation evidence

Core service and plugin integration

Runtime provider packaging boundary

The runtime broker is already a host service rather than an Automation-private API: IRuntimeService::RegisterAdapter and UnregisterAdapter accept adapter objects from any loaded plugin, and runtime descriptors are enumerated through the same service by native callers and workers. The standalone PythonRuntime.SPL, PowerShellRuntime.SPL, PHPRuntime.SPL, and JavaScriptRuntime.SPL projects now own their provider adapters, interpreter discovery, and worker bootstrap. Their standalone Windows projects pass isolated Debug x64 builds, and the worker package gate verifies their bootstrap/export boundary without launching Salamander. Final loading and GUI behavior still require the target machine; Automation retains only its legacy ActiveScript engines and consumes the broker like every other plugin.

Shared services already working

Script discovery and manifest parsing

Existing legacy Automation value

The new platform should preserve these working capabilities:

Important implementation risks found by the audit

1. The core service registry still exposes borrowed interface pointers to callers, but provider ownership and short consumer leases now prevent new acquisitions during unload and wait for active calls before removal. The extension lifecycle registry has the same owner-aware callback behavior; unload diagnostics are still minimal. 2. Runtime provider registration is still an explicit plugin-lifetime contract; unload diagnostics and a user-facing dependency view remain. 3. Posted Commands/FileOperations report ok when a command was accepted, not when the modal operation completed successfully. cancel is not observable. 4. The command catalog currently maps both Move and MoveRename to the same native command and contains only three unique operations. 5. The manifest parser retains every validated command and the Automation menu surface iterates all registered runtime command contributions; remaining work is richer independent placement/toolbar metadata rather than dropping additional commands. 6. Discovery and execution now go through runtime adapters. The v1 compatibility callback still keeps old ActiveScript hosting inside Automation; modern process cancellation is currently stop/termination based. 7. Long-lived script callbacks still require richer UI-thread, reentrancy, cancellation, and exception rules; host callbacks now reject new calls during extension deactivation and hold an unload lease while active. 8. A language process must never receive raw C++/COM implementation pointers. Out-of-process adapters need a versioned RPC/value protocol, while in-process adapters need ABI-stable interfaces.

Phase 0: make the foundation safe

1. Route extension discovery and execution through the existing Salamatrix.Runtime broker. Implemented. 2. Add provider ownership/leases, diagnostics, and lifecycle rules to runtime and core services. Provider ownership and short leases are implemented; richer diagnostics remain. 3. Replace the manifest text scanner with a real parser and validate a versioned schema.

Phase 1: complete the useful common object model

1. Publish Salamatrix.Sides with Left, Right, Source, and Target. Implemented. 2. Add side and tab snapshots/handles: path, active tab, tabs, focused/selected items, view mode, tree visibility, detached state. Implemented for tab identity, enumeration, path, activation, active/source/target/locked/ detached state, side path changes, refresh, selection mutation, and focus; item/view details remain. 3. Add clipboard and panel refresh. 4. Expand stable Commands and implement synchronous, programmatic file operations. 5. Add isolated per-extension storage. Implemented for typed key/value persistence; settings schemas, quotas, migrations, and uninstall policy remain.

Phase 2: make extensions persistent

1. Extension instances and lifecycle: discover, load, activate, deactivate, unload. The owner-aware Salamatrix.Extensions registry and persistent IRuntimeSession activation seam are implemented; host dispatch and worker bindings remain. 2. Command contribution service independent of menu/toolbar/hotkey placement. 3. Event service with a small first set: startup/shutdown, active side/tab, path, selection, tab create/close. Implemented for host lifecycle, settings/configuration/colors, panel swap, active-panel events, successful shared-Sides path/selection/tab/refresh operations, and core path/selection/tab notifications; persistent instance queues now use bounded worker-session frames. File-operation and window lifecycle hooks remain. 4. Package state in the existing Plugin Manager.

Phase 3: runtimes

1. Keep current Automation as the legacy-wsh compatibility adapter. 2. Add a modern bundled JavaScript adapter as the default lightweight runtime. 3. Add PowerShell and CPython adapters as separate runtime components. 4. Add PHP only after the common out-of-process protocol is proven; it should reuse the same protocol rather than introduce a fourth binding architecture. 5. Run the same runtime contract suite against every adapter.

An out-of-process JSON-RPC-style transport is the safest common denominator for CPython, PowerShell, and PHP. The host owns all Salamander objects and returns serializable handles/snapshots; runtimes send typed API requests. A bundled JavaScript engine may be in-process for size and speed but should implement the same logical contract.

Phase 4: shared UI

The native dialog/control surface, explicit layout, collection binding, pickers, validation/events, and the complete DemoPlug control gallery are now implemented through one framework-owned service. The five worker runtimes, Automation JScript, and native DemoPlug independently exercise that surface; the old Automation Forms classes remain compatibility wrappers rather than the owner of modern dialogs. Continue with automated dark-mode/DPI interaction, full UI Automation roles and screen-reader testing, virtualized collections, richer notifications, reentrancy rules, and localization guidance for extension-authored text. See doc/salamatrix-ui.md for the current contract and examples.

Phase 5: AI assistant

Start only after the common API is useful without AI:

1. Generate a machine-readable API schema from the real contracts. 2. Define a provider-neutral model interface and structured result containing title, description, required capabilities, estimated effects, and script. 3. Implement Ask -> Preview -> Validate -> Run -> Save. 4. Add static validation and a repair loop against the exact installed API version. 5. Add an external local provider first, then an optional bundled local backend. 6. Treat the AI as a script author with no privileged control path.

First implementation slice

The first code slice following this audit is implemented:

The second code slice is also implemented:

The third code slice is also implemented:

The fourth code slice is also implemented:

The fifth code slice is also implemented:

The sixth code slice is also implemented:

This slice intentionally stops before host API dispatch. The registry and session are the stable seam for the next runtime-host work.

The seventh code slice is now implemented:

The transport foundation is covered by a standalone /W4 /WX test for partial frames, round trips, malformed ids, newline rejection, and the 1 MiB limit.

The eighth code slice is now implemented:

This does not pretend that modern Python or PowerShell support is complete. It creates the contract those adapters need and removes the current architectural assumption that every script file must map directly to an IActiveScript COM CLSID.

The ninth code slice is now implemented:

The tenth code slice is now implemented:

The eleventh code slice is now implemented:

The twelfth code slice is now implemented:

The thirteenth code slice is now implemented:

The fourteenth code slice is now implemented:

The fifteenth code slice is now implemented:

The sixteenth code slice is now implemented:

The seventeenth code slice is now implemented:

The eighteenth code slice is now implemented:

The nineteenth code slice is now implemented:

The twentieth code slice is now implemented:

The twenty-first code slice is now implemented:

The twenty-second code slice is now implemented:

The twenty-third code slice is now implemented:

The twenty-fourth code slice is now implemented:

The twenty-fifth code slice is now implemented:

The twenty-sixth code slice is now implemented:

The twenty-seventh code slice is now implemented:

The twenty-eighth code slice is now implemented:

The twenty-ninth code slice is now implemented:

The thirtieth code slice is now implemented:

The thirty-first code slice is now implemented:

The thirty-second code slice is now implemented:

The thirty-third code slice is implemented and verified:

The thirty-fourth code slice is implemented and verified:

The thirty-fifth code slice is implemented and verified:

The thirty-sixth code slice is implemented and verified:

The thirty-seventh code slice is implemented and verified:

The previous storage-table note that listed key enumeration as missing is superseded by this thirty-seventh slice. Remaining storage gaps are settings files, quotas, transactional batches, and uninstall retention/deletion policy.

The thirty-eighth code slice is implemented and verified:

The thirty-ninth code slice is implemented and verified:

The fortieth code slice is implemented and verified:

The forty-first code slice is implemented and verified:

The forty-second code slice is implemented and verified:

The forty-third code slice is implemented and verified:

The forty-fourth code slice is implemented and verified:

The forty-fifth code slice is implemented and verified: