Skip to content

Build and qualify the VS Code extension

The extension is developed in the dedicated outerspace-apizr-vscode repository, under GPL-3.0-or-later, with its own fast client CI. The engine repository retains only the repository/commit/hash lock in policy/vscode-source.json. Explicit preparation fetches that revision into ignored .output/vscode-source/; no client implementation is tracked in the engine repository. Its runtime npm dependency count is zero. The four locked build/type-declaration packages are checked against exact versions, SRI and licence/notice hashes in policy/vscode-dependencies.json; the complete npm audit is blocking without dependency exclusions. policy/vscode-distribution.json pins Node, TypeScript and the CI VS Code binary and SHA-256.

Develop the client in its own repository. To update the engine's integration pin, check out a clean, exact client commit and run:

python -m scripts.qualification.packaging.vscode_source --source /path/to/outerspace-apizr-vscode --commit FULL_COMMIT_SHA

policy/vscode-source.json records the dedicated repository, commit and every source-file hash. Candidate builds refuse a changed or forked snapshot. This retains the complete engine/client qualification without coupling ordinary client development to the engine's full test suite.

client=$(python -m scripts.qualification.packaging.vscode_source --prepare --print-directory)
npm ci --prefix "$client" --ignore-scripts --no-audit --no-fund
npm test --prefix "$client"
npm audit --prefix "$client" --include=prod --include=dev --include=optional --include=peer --audit-level=low
python -m scripts.qualification.packaging.vscode_distribution --output /absolute/vscode-dist

A retained build requires clean source. --allow-dirty is available only for local development and is recorded explicitly in evidence. The VSIX contains the extension manifest, own TypeScript source, compiled JavaScript, lock/configuration, README, pinned CLI descriptor and repository licence. It embeds no engine, node_modules, credentials, project files or experiment store. Sorted stored ZIP entries, fixed timestamps and modes make repeated builds byte-identical; the build record retains each file's SHA-256, archive SHA-256, engine source commit, dedicated client commit and tool versions. Verifying a retained VSIX compares its source bytes to the approved hashes without fetching or checking out the client.

The distributions CI job builds the VSIX alongside the eight Python archives. Its v2 candidate manifest retains the VSIX hash, complete ZIP inventory, source commit, reproducibility proof and dependency licence report. The vscode job consumes that same candidate VSIX and engine wheel on development and protected master. It installs the engine outside the checkout, installs the VSIX into clean profiles and exercises real inspection, notebook navigation, saved/dirty and stale results, mixed CLI/SDK/Jupyter history, canonical show/diff, publication notifications, telemetry opt-out and incompatible-engine refusal. A synthetic 0.4.5 VSIX containing the same reviewed extension code qualifies the update path; there is no previously published extension implied by that fixture. Uninstall is checked for extension-owned storage. VS Code retains user-owned settings according to its normal behaviour. This manual-engine qualification creates no persistent application storage. Managed installation keeps the CLI and its completion marker in extension storage; VS Code may retain that storage on uninstall. Project environments, notebook kernels and local experiment history remain user-owned.

The separate remote proof creates an SSH server in a disposable Docker container, binds its random port to loopback only and opens the real Remote SSH workspace extension host. It uses the candidate wheel, hash-locked notebook dependencies, the same VSIX and the same canonical journey assertions. The repository mount is read-only; only the temporary proof directory is writable. The extension is extracted from the qualified VSIX into the disposable server, alongside a distinct qualification driver. Native installation/update/uninstall remains the proof above.

python -m scripts.qualification.interfaces.vscode_ssh_proof \
  --wheel /absolute/candidate/outerspace_apizr-0.4.6-py3-none-any.whl \
  --requirements /absolute/engine.lock --vsix /absolute/apizr-0.4.6.vsix \
  --code /absolute/code --output /absolute/fresh-ssh-proof

The core wheel and VSIX both declare 0.4.6; retain their exact hashes and source commit. Use the hash-bearing uv export --locked --no-default-groups --group jupyter-qualification --extra notebook --no-emit-project output as engine.lock. policy/vscode-distribution.json pins the Remote SSH tool version and container base digest. The proof records actual extension versions and artifact hashes, requires remoteName == ssh-remote and an engine outside the checkout, and removes its desktop process group, container, image tag and client private key afterwards. Retained qualification requires a clean checkout; --allow-dirty is reserved for explicit local development and is recorded with the qualifier's source hash. Retain remote-proof.json, synthetic fixture/results and top-level proof logs. Do not publish the raw VS Code profile: its transport logs contain session tokens. Dev Containers and other remote transports remain unqualified.

The existing required build and dependencies checks also require this job for product changes. Product prose routing skips it while retaining contribution and package-description checks. Website changes are qualified separately on gh-pages. The existing codeql context retains Python and JavaScript/TypeScript SARIF; GitHub's default Python/Actions alerts remain enabled without duplicate SARIF uploads.

Publication

The dedicated repository owns extension development and packaging. The Marketplace extension is published by Alien6 Studio (alien6-studio).

Publish the exact qualified VSIX after maintainer approval and after its matching CLI is available on PyPI. Keep the VSIX, source commit, checksums and build evidence in the GitHub release. Registry credentials stay outside the repository and artifacts. Open VSX publication is separate.