Skip to content

Scientific plotting library decision ​

Decision ​

Use the exact plotly.js-strict-dist-min@4.1.1 distribution as the workspace renderer. It replaces the initial Cartesian-only bundle to add pie/doughnut traces while keeping all twelve supported families under the existing nonce-only script CSP. Numerical extraction, statistics, transforms, alignment, gridding and exports remain under src/parser/plot/, shared with MCP. Plotly receives finished datasets, including category weights/shares, histogram counts and box quartiles. It does not define the numerical backend.

CandidateRequired familiesCSP/offline considerationsDecision
Plotly CartesianDirect support for Cartesian line/scatter, bars, boxes, heatmaps and contours; host supplies histogram bins/box statistics. No pie traces.Local prebuilt distribution; initial seven-family CSP/export regression passed.Initial choice; replaced for circular charts.
Plotly strictIncludes scatter/bar/box/heatmap/contour/pie; step/area/bubble are explicit scatter styles. Host computes category aggregation/shares.Exact local prebuilt bundle, MIT attribution, nonce-only scripts; twelve-family regression has no CSP violation or HTTP request. Larger than Cartesian.Selected for the expanded picker.
Apache EChartsStrong line/scatter/bar/box/heatmap coverage; contour plots need a separate adapter/custom seriesOffline bundling and accessibility features are available; SVG/Canvas renderers offer export choices. The custom contour and its masking/export/accessibility rules would be extension-owned.Not selected; greater contour-adapter scope.
Vega / Vega-LiteDeclarative scientific plotting, but contours/interpolation need additional dataflow decisionsStrict-CSP deployments require the expression interpreter rather than the default expression code-generation path; would introduce another transformation grammar beside the shared host core.Not selected for this graphical builder.

References: Plotly partial-bundle trace coverage, Plotly static image export, ECharts accessibility, Vega expression interpreter. The comparison is architectural; it is not a head-to-head benchmark of all three libraries.

Packaging and CSP ​

esbuild.js copies the strict bundle and its MIT license into media/plotly/, and builds media/plots.js plus dist/plotWorker.js. The plotting library is not imported by the host or numerical core. The mesh webview reuses the workspace adapter and loads the local Plotly script only on first opening Plots, under the preview's nonce; the standalone workspace loads it directly. There is no unsafe-eval CSP allowance, external script source or network dependency for the supported charts. Plotly inserts styles dynamically, so the workspace retains style-src 'unsafe-inline'; PNG generation uses img-src blob: as well as data:. That is an image-export allowance, not a script-CSP relaxation.

The shipped minified plotting asset is 5,158,139 bytes (the initial Cartesian asset was 1,500,041 bytes). The expanded increment's packaged extension measured 30.95 MB in this environment, versus 29.89 MB for the earlier integrated increment; that figure includes all existing renderer/WASM assets, not just plotting. Attribution is shipped as media/plotly/LICENSE. The prebuilt strict bundle includes unused map/WebGL families: the recipe whitelist and adapter expose only scatter/bar/box/heatmap/contour/pie traces. Static inspection finds dormant map-worker globalThis.eval and a global-object fallback new Function; neither runs in the supported chart paths, and the CSP does not authorize them. The twelve-family offline/export check observed no page error, CSP violation or HTTP request. This is a scoped runtime audit, not a claim that every trace in the full upstream bundle can run offline under this CSP.

The chart's default palette and chrome use VS Code tokens; explicit series colors remain user data styling. A labelled visual SVG picker, native configuration controls, visible focus, keyboard zoom/resize buttons and accessible sample tables (including bubble weights/circular shares) provide alternatives to pointer-only chart gestures. Plotly itself is not presented as fully keyboard-accessible.

Measured verification ​

  • src/test/plot.test.ts exercises parsing/correction, missing/nonfinite cells, duplicate headers, associations/independent IDs, supplied units/scales, statistics, magnitude/filter/groups, histogram/box/bar calculations, calculus/smoothing/regression, reference alignment, masked gridding, log-domain diagnostics, recipes, display sampling, worker cancellation/recovery, cache invalidation and MCP/full-resolution exports.
  • src/test/plotFem.test.ts adds analytic pressure means/integrals/resultants/moments (including linear pressure × position), constant-pressure closed-boundary cancellation, 2D thickness, supplied scales/density, associations, reaction sum-before-magnitude, region deduplication/coverage, frame resolution, batched one-load-per-frame histories, metadata gaps, progressive publication and worker retention/recovery. All numerical operations stay read-only and share MCP.
  • src/test/plotFollow.test.ts verifies captured-frame validation, owner/path/rank/timeline guards, frame-only recipe changes, fixed-profile retention, missing-cache refusal, uncovered spatial gaps and real-worker cancellation/recovery. Its worker test removes history files after collection and proves frame following retains those samples without rescanning disk; explicit refresh observes new disk values and agrees with MCP.
  • src/test/plotCharts.test.ts adds twelve-family recipe/capability validation, host category statistics/shares, missing/negative/zero/overflow handling, category budgets, unit compatibility, original provenance/uncertainty preservation, non-overlapping circular domains, explicit bubble mappings/size sampling, line/scatter/step/gap-separated area renderer contracts, horizontal signed stacks and real-worker MCP parity.
  • src/test/plotRuns.test.ts verifies the shared existing receipt contract, bounded discovery with unresolved legacy sidecars, content revisions despite restored timestamps, same-byte reused paths with changed run IDs, polling timestamps/property-order independence, missing/changed source meshes, live/uncertain refusal, rank/timeline additions, recursive PVD→PVTU pieces, filename SubModelPart companions, symlink escapes, before/after collection checks, missing entities, explicit time units/mapping, tolerance/tie rules, cancellation and export protection. Navigation checks cover exact frame/association targets, worker/MCP parity, nonzero opened-frame provenance, failed final handoffs without model adoption and exact-path registry/disposal/cancellation races. MCP tests additionally dispatch a real Node fixture process and prove later status polling cannot replace a terminal receipt's original artifact hashes. These are contract/fixture tests, not a Kratos solve; the packaged checks below separately exercise actual cross-run preview navigation.
  • src/test/plotDirectoryInventory.test.ts verifies complete conservative OpenFOAM region/processor/field/dictionary/moving/gzip inventories, Elmer header/binary/partition inputs and MFEM sibling ranks, without recursive rediscovery. It checks frozen-closure refusal for changed or removed files and added empty time/region directories, marker-only receipts, symlinks, partial baselines, depth/entry limits, cancellation, changing enumeration, relocation with explicit rebinding, protected exports and worker/MCP numerical parity. The two-region field fixture supplies values 300 and 500 but no thermal unit; the extractor keeps that unit unknown instead of inventing kelvin from its name. The inventory increment's focused plotting/run/CAE/MCP suite passed 220 tests.
  • src/test/plotController.test.ts isolates the VS Code/dialog/worker boundary to check superseded cursor replies, disposal during run verification, changed source settings during open/cursor operations, recipe changes during save dialogs and captured-image provenance/protected inputs after the active recipe changes. It also checks verified sample navigation, forged/stale origins, invalidation/disposal during target resolution and the distinction between resolving and explicitly opening a time cursor. This mocked lifecycle coverage complements, rather than replaces, the real packaged flows below.
  • scripts/screenshots/check-plot-builder.mjs drives the actual plotting bundle under the production HTML CSP, with only host delivery simulated. All twelve families rendered; 24 graphics (PNG and SVG per family) exported with no page errors, CSP violations or HTTP requests. The visual picker, keyboard navigation/Escape, narrow layout, line-only drawing, explicit bubble/pie choices and horizontal signed stacks passed. Artifacts are under /tmp/opencode/plot-check when run locally. This checks format validity and rendered families, not pixel-perfect equivalence against every chart option.
  • The same browser regression processed 100,000 rows: numerical evaluation plus display selection took about 144–199 ms across two recorded runs, and a complete UI recipe reload/preview/render round trip about 7.0–8.2 s, delivering 2,310 display points. These are Linux/Chromium 1243 smoke measurements under different concurrent test loads, not statistically controlled benchmarks or million-row/Remote-SSH budgets. The round-trip includes transferring the inline recipe and import preview; it is not an isolated Plotly render benchmark.
  • Integrated follow-up smoke runs measured 160 ms / 6.0 s in one run, 433 ms / 10.7 s in another and 448 ms / 11.3 s during the profile increment's full suite and concurrent packaged UI checks, still delivering 2,310 points. These demonstrate load sensitivity, not a performance improvement or an established scale budget.
  • Expanded strict-bundle smokes measured 145 ms / 5.5 s, 238 ms / 7.9 s, 206 ms / 7.6 s and 191 ms / 11.2 s for numerical/display evaluation and the full 100,000-row UI round trip, still delivering 2,310 points. The last run overlapped the serial suite and both packaged UI checks. These are local smoke runs, not evidence of a speedup or a larger scale budget.
  • scripts/screenshots/check-plots-vsix.mjs uses an isolated authenticated code-server profile (4.141.0 in the 2026-10-21 run), the installed VSIX and real provider/worker messages. Standalone CSV overlays, MDPA/VTK Advanced-menu entry points, dark/light/high-contrast themes and the absence of dirty mesh tabs passed. The 2026-10-21 increment adds the opt-in persistent-cache hit, cancellation of a million-row table, in-flight title supersession and disposal during collection. Guide screenshots were captured there. The dedicated saved-run harness below owns the run/navigation/save-dialog/export checks.
  • scripts/screenshots/check-fem-plots-vsix.mjs tests the installed VSIX in another isolated authenticated profile: lazy Plotly, mesh-native point histories, an actual mesh click appending a displacement history, SubModelPart pressure resultants, peak-to-frame navigation, dock orientation, keyboard resize, collapse/restore, hidden Advanced, both MDPA/VTK providers and three themes. The expanded picker adds compatible line/scatter/step/area switches, line-only style, explicit bubbles and pie/doughnut choices, curve preservation and a narrow embedded pane. It also verifies fixed-versus-following profiles in both providers, preserving following through chart-type switches, fixation/cancel/resume, pause after timeline replacement and explicit rebinding to the provider's actual resampled VTK model. The 2026-10-21 increment adds Plot distribution (20 bins over four nodal values), Show on mesh, the volumeTotal and sectionComparison presets, and the whole-mesh exterior-boundary integral with its diagnostics. No extra editor tab, dirty mesh, page error or CSP violation was observed. Seven integrated guide screenshots are captured by this check. It does not claim remote budgets; the saved-run harness covers run-owned recipes/exports/navigation separately.
  • scripts/screenshots/check-plot-runs-vsix.mjs tests real installed MCP/worker/provider/dialog flows: dispatched Node fixture processes, saved-run discovery/binding, a supplied physical-time mapping and cursor, recipe save/reload, full-resolution CSV/provenance, PNG/SVG with captured-view metadata, explicit owning-result open and rebind. It exercises exact frame/node navigation in both MDPA and VTK, an in-file PVD cursor, separate cross-run previews despite overlapping IDs, and another active case without redirecting it. The selected original node's table value is checked in the real provider. The directory increment adds an independent two-region OpenFOAM receipt-contract writer, MCP/graphical values 300/500 with unknown units, original Elements association/selected-row value verification, and refusal of a removed field or marker-only receipt. Changed/missing source files, a changed sibling timeline frame and a contradictory latest-run record are refused; unresolved legacy records adopt no files, and cancelling discovery retains the chart. The 2026-10-21 increment adds the packaged plot_run_resolve statuses (verified/unverified/unresolved), a changed companion, and a PVD→PVTU→VTU chain whose changed or missing piece and changed index are refused; the OpenFOAM case also proves Show in mesh after the view-sidecar watcher fix. Five guide screenshots show discovery, the bound history/cursor, owned navigation, directory ownership and stale-source refusal. No dirty mesh, page error or CSP violation was observed. The processes are not Kratos solves; MDPA/OpenFOAM use separate receipt-contract fixtures. The first directory UI attempt found a Data Table association bug (same-ID Nodes row after selecting an Element); after the fix the final installed-package run passed, rather than counting that earlier attempt as success.
  • The directory-inventory increment's 2,115-test suite passed serially, with 220 focused plotting/run/CAE/MCP tests. The run-navigation increment's 2,102-test suite, its earlier 2,096-, 2,095- and 2,088-test runs, the chart-expansion increment's 2,071-test run, profile increment's 2,059-test run, initial standalone increment's 2,036-test run and earlier embedded increment's 2,053-test run are historical evidence; two earlier parallel attempts were interrupted, not counted as passes.

Packaged-VSIX acceptance (2026-10-21) ​

Environment: Linux x64, code-server 4.141.0, Chromium 1243 through playwright-core, isolated authenticated profiles under /tmp/opencode/{plot-ui,fem-ui,plot-runs-ui}. The tested artifact was a 52.32 MB, 195-file VSIX built from the tree at that date and force-installed into each profile:

sh
npx vsce package --no-dependencies -o /tmp/opencode/ext.vsix
env -u VSCODE_IPC_HOOK_CLI /tmp/opencode/code-server-4.141.0-linux-amd64/bin/code-server \
  --install-extension /tmp/opencode/ext.vsix --extensions-dir /tmp/opencode/<profile>/extensions \
  --user-data-dir /tmp/opencode/<profile>/user --force

Fixtures and commands (from the repository root):

sh
PLAYWRIGHT_MODULE=/tmp/opencode/tools/node_modules/playwright-core \
CODE_SERVER=/tmp/opencode/code-server-4.141.0-linux-amd64/bin/code-server \
CHROMIUM_PATH=/home/vicente/.cache/ms-playwright/chromium-1243/chrome-linux64/chrome \
node scripts/screenshots/check-plots-vsix.mjs

The same environment runs check-fem-plots-vsix.mjs and check-plot-runs-vsix.mjs. check-plots-vsix.mjs writes large.csv (1,000,000 rows x 8 numeric columns) and a fresh cache-<timestamp>.mdpa per invocation, so a previous cache entry cannot satisfy the first extraction. check-fem-plots-vsix.mjs uses three one-tetra MDPA steps with TEMPERATURE nodal values step+1..step+4, an ENERGY elemental value 6*(step+1), and Wall/Inlet SubModelParts. check-plot-runs-vsix.mjs dispatches a real child Node process through the packaged MCP case_run, then writes synthetic version-1 .kkss-execution.json receipts for VTK, MDPA, a PVD→PVTU→VTU chain and a two-region OpenFOAM case; it is not a Kratos solve and makes no solver-output claim.

Observed results on that tree (all three checks exit 0 with no page error and no CSP violation). The same 2026-10-21 tree passed the whole Node suite: 2,965 tests across 262 files, 0 failures (run in batches, because an environment restart interrupted a single serial run). These measurements predate the merge onto 5.23.0 and were not re-run for the merged tree.

  • Cache and cancellation. The second refresh of the disk-backed MDPA source reports Persistent extraction cache hit. A 1,000,000-row collection cancelled in flight ends at Partial result · 0 full-resolution points · 0 displayed, with no chart data and no claim of the full-resolution row count. A title edit made while a large refresh runs publishes only the superseding title, and closing the plot during collection publishes no data when it is reopened.
  • Run ownership. plot_run_resolve returns verified with a binding identical to plot_run_bind for ordinary results; unverified without a receipt and through a latest-run sidecar (no binding, present-state snapshot only); and unresolved for a path outside the recorded result (not a recorded result). A changed companion and a changed or missing PVD→PVTU piece are refused by name.
  • Field and presets. Plot distribution produces 20 equal-width bins over the four TEMPERATURE values (4 non-empty bins). Show on mesh selects Nodal:DISPLACEMENT. volumeTotal over the elemental ENERGY field is [1,2,3]; sectionComparison Wall against Inlet is 12, 74/3, 112/3.
  • Exterior boundary. Whole-mesh boundaryIntegral over Nodal PRESSURE, current scope, reports 28.39230484541326 = 12*(1.5+sqrt(3)/2), with 4 faces owned once, 0 interior faces skipped and Nodal fields only; no Conditions are read. The normals control is absent because the exterior boundary owns its orientation.
  • Preserved behaviour. Both MDPA and VTK providers, dark/light/high-contrast themes, keyboard/visual chart controls, fixed and followed profiles, recipe/cursor dialogs and PNG/SVG/CSV exports still pass; no mesh tab becomes dirty.

The packaged run also exposed a real race, now fixed in src/vtkEditorProvider.ts: opening an OpenFOAM case persists case.kratosview.json beside the marker, which .foam's {*,*/*} watcher matched as a mesh change. Its 500 ms debounced rediscovery could start while Show in mesh was loading the frame, and the navigation guard then refused the handoff. scheduleRediscover now ignores *.kratosview.json, so the extension's own view sidecar no longer invalidates navigation.

Not verified in this environment: a real desktop VS Code session, Remote-SSH, KKSS, network filesystems, and the extension-host/webview memory, latency and responsiveness budgets. code-server establishes packaged behaviour, not those measurements; they remain explicitly unverified rather than passed.

Reproduce with npm run typecheck, npm run build:tests, node --test --test-concurrency=1 out/test/, and the browser scripts listed above (see their headers for PLAYWRIGHT_MODULE, CHROMIUM_PATH, UI_ROOT and CODE_SERVER). Package with node node_modules/@vscode/vsce/vsce package --no-dependencies -o /tmp/opencode/plot-navigation.vsix, then install into the isolated profiles used by the packaged checks. The run-navigation package measured 30.97 MB (earlier run-binding package: 30.96 MB); the 2026-10-21 packaged acceptance used 52.32 MB / 195 files, the larger figure reflecting the VTK-wasm assets shipped at that date. Playwright and code-server remain external test tooling, not extension dependencies.

The directory-inventory package /tmp/opencode/plot-inventory.vsix also measured 30.97 MB. Its full-suite and final saved-run UI results are /tmp/opencode/plot-inventory-full.log and /tmp/opencode/plot-inventory-ui-final.log; the tested profile is /tmp/opencode/plot-inventory-ui. Standalone and embedded regressions were repeated successfully against the same package (/tmp/opencode/plot-inventory-standalone.log, /tmp/opencode/plot-inventory-fem.log), refreshing the existing plotting screenshots as well as adding plot-directory-run.png. Typecheck, test compilation, documentation build and whitespace checks passed. The package includes the numerical inventories and final Data Table association fix; later guide/roadmap wording and screenshot additions are repository documentation, not a new numerical runtime.

Directory-result receipt contract ​

src/problemtype/runResultInventory.ts exports freezeExecutionResult(source, signal) for an owning receipt writer or explicit importer. It reads the complete source closure twice and refuses changes/missing files, returning the entrypoint as role: "result" with its byte revision and directory inventoryRevision, plus role: "result-companion" revisions for dependencies. Store those artifacts in the existing .kkss-execution.json while freezing the owning execution's terminal receipt. MCP receipt collection uses the same helper for explicitly recorded directory result entrypoints; this adds no solver output-process adapter, automatic folder adoption, run manager or retrospective legacy ownership resolution. Terminal status polling preserves the frozen artifacts.

The version-1 inventoryRevision is SHA-256 over the UTF-8 JSON serialization of [1, meshExtension, entrypointBasename, timelineKind, framePairs, fileTuples, directoryPaths]. timelineKind is single, files or inFile from shared discovery; framePairs are its ordered [label, frameIndex] pairs. fileTuples contain [relativePath, byteLength, sha256Revision] for every dependency and the selected entrypoint, relative to its parent directory with / separators, sorted by their JSON serialization using lexical code-unit ordering. directoryPaths are relative / paths sorted lexically, including empty selected directories. Absolute paths, timestamps and realpaths do not enter this portable closure. The recipe binding still pins its exact source/realpath identity, so relocating a saved run requires explicit rebinding even when the frozen closure remains valid. The packaged harness's independent fixture writer implements this contract without importing checkout runtime code.

OpenFOAM inventories conservatively include entire constant, system, numeric-time and processorN trees. Each baseline constant[/region]/polyMesh must contain points, faces and owner (plain or gzip); moving overlays may be partial. Elmer root filenames share the staging collector's patterns and partition trees are conservative; MFEM includes all matching sibling ranks, not an invented independently owned rank. Linked/non-regular dependencies, changing enumerations, over 50,000 entries or over 20 levels are refused. Hashing unread fields/dictionaries is dependency coverage, not a claim that the reader interprets their semantics. Individual file hashes alone cannot prove an unchanged directory closure, because a removed dependency would disappear from today's enumeration; directory-backed results therefore require the frozen inventoryRevision too. Do not add it to an old receipt using current bytes as evidence of a past run.

Kernel baseline hold ​

This task was held on the audited meshio++ 16.27.0 lockfile baseline until the roadmap's Tier 0 registry/options/reader/writer/transient audit covered the newer kernel; that audit is now done for 16.32.0 (2026-10-09: no reader or writer key added or removed, no options-awareness flag flipped, transient audit unedited), so the hold is lifted. None of the plotting delivery claims depended on untested new behavior.

Persistent extraction cache ​

src/parser/plot/persistentCache.ts is an opt-in, bounded on-disk cache for disk-backed extractions: mesh tables, probe profiles, current-frame regional quantities and unowned histories. Enable it with the kratos.plots.persistentCache setting (global storage), the cacheDir argument of plot_dataset, or the KRATOS_PLOT_CACHE_DIR environment variable for headless callers. Default is off.

  • Key. SHA-256 of the schema version, plotSourceIdentity(path).revision (streamed content hashes of the root file, every companion, the selected rank and the timeline steps), and the source settings without its run binding. Any changed, added or missing file, step or setting is therefore a different key; there is no mtime shortcut.
  • Verified both sides. The identity is computed before the extraction and again before the entry is stored; if the files changed in between, nothing is stored.
  • Stat shortcut. A lookup first compares a manifest of every file's size, mtime, ctime, inode and device (plus the directory listing) with the disk and, when all are identical and each file was already 2 s old when the manifest was written, reuses the stored content revision without hashing (statFastPath, default on; statSettleMs). ctime cannot be restored by a writer the way mtime can, so an in-place rewrite misses; a file written inside the settle window, an added sibling file or a directory-case source is hashed as before, and a store always rehashes. Measured on the benchmark below it is about 30x faster than a hashed hit.
  • Never cached. Live-mesh snapshots (models), tables (already content-cached in memory), inline sources and sources bound to a verified run, which keep their own verification (a cache hit would skip the before/after receipt check, so this is a decision, not a gap). The retained fixed snapshots used by profile following are a separate in-memory cache: a persistent hit never fills it, and a retained miss still fails rather than rereading disk (plotPersistentCache.test.ts).
  • Bounds. 256 MiB and 512 entries by default, evicting the least recently used by access time; other-schema files and stale temp files are swept; a corrupt entry is deleted and treated as a miss; a table holding non-finite numbers is not stored because JSON cannot reproduce it.
  • Cost, measured on the 3.6 KB example/VTK series (Node 22, one run, not a budget): identity hashing 15 ms, uncached history 28 ms, hit 9 ms. A hit still hashes every companion, so on large inputs its cost scales with the bytes of the source and companions rather than with the parse; a million-row or multi-gigabyte benchmark has not been run and no large-data budget is claimed.

Measured budgets (Node level) ​

npm run bench:plot (scripts/bench/plot-budget.mjs; verdict logic in plotBudgetStats.mjs, unit-tested in benchPlotBudget.test.ts; deliberately not part of npm test because timing on shared CI is flaky) measures the Node main thread, which is what an extension host is, and a worker. Table cases run in a fresh process per repetition so the RSS high-water mark is that case's own. The table below is the pre-fix measurement (medians of 3 runs on linux x64 Intel(R) Xeon(R) Processor @ 2.10GHz x4, node v22.22.0), kept because it records what the two failing budgets actually were:

CaseResult
1,000,000-row, 8-column CSV (67.9 MiB), plot in-process10518 ms wall, 5.9 ms max stall, 1527 MB peak RSS above an empty process
same plot through the plot worker17089 ms wall, 3137.3 ms max stall, 1698 MB peak RSS above an empty process
history extraction, 12 steps x 60000 nodes, cold2211 ms
same, persistent hit with full content hashing54.9 ms
same, persistent hit via the stat shortcut1.6 ms
worker cancellation (abort to settle)2.0 ms

Verdicts against the default budgets (worker max stall 50 ms, table peak RSS 12x the file, cancellation 500 ms, stat shortcut at least 1.5x faster) were, in that run: cancellation pass, stat shortcut pass, worker stall fail, table memory fail. The two failures were real findings, not threshold artifacts: a million-row plot held about 1.5 GB at peak (about 22x the file; the rows, per-row origins and points were all materialized as JavaScript objects), and returning that dataset from the worker blocked the host for about 3 s while it was structured-cloned, so the worker protected the host during the parse but not during delivery.

Both were fixed by streaming the import into numbers and delivering large arrays in acknowledged chunks (src/plotChunks.ts), and the 2026-10-16 run recorded in roadmap item 19 passes all four budgets: peak RSS 10.6x the file (was 23x) and worker host stall 34 ms (was about 2 s). No further benchmark run was repeated for the 2026-10-21 packaged-acceptance increment, so no newer timing numbers are claimed here.

Not measured here, and not claimed: the VS Code extension host, Remote-SSH or network filesystems, webview delivery, a packaged VSIX, and the WASM mesh formats' worker lifetime.

Remaining acceptance scope ​

Remaining work is tracked in roadmap item 19. Saved-record discovery, terminal isolated-run binding, physical-time cursor resolution, explicit provider-owned cross-run/frame/entity navigation and complete directory-case inventories are delivered, but explicit legacy/shared-output resolution, tensor-aware and pressure-conversion presets (section comparison, volume total, table relationship, section differences and threshold check are delivered), derived tensor quantities needing supplied component-order metadata, expanded geometry conventions, companion-aware caches and larger-scale/remote budgets remain pending. The packaged stale/cancellation/timeline matrix is covered by the 2026-10-21 checks above. Session-only fixed-extraction retention for frame following is not a persistent companion-aware cache. The guide states these boundaries rather than implying that chart-library adoption or an ownership increment completes the whole task.

Released under the GNU AGPL-3.0-or-later License.