Skip to content

test(cli): qualify the published extensions on the worker host (group 7) - #298

Merged
DamianReeves merged 11 commits into
mainfrom
DamianReeves/worker-qualify
Oct 31, 2026
Merged

DamianReeves merged 11 commits into
mainfrom
DamianReeves/worker-qualify

Conversation

@DamianReeves

@DamianReeves DamianReeves commented Oct 31, 2026 •

Copy link
Copy Markdown
Member

Summary

Group 7 of the OpenSpec change host-extensions-as-workers (bead morphir-ukvn.5.64.36.7): qualify the published extensions, and an independent fixture guest, on the CLI's worker host from the native CLI and the npm CLI.

  • scripts/extension-qualification.mbtx (argparse, --json) builds the native CLI, the npm package (npm pack, unpacked as a user installs it) and the MoonBit guests, then runs the driver apps/morphir/scripts/extension-qualification.ts once per suite. The driver downloads each pinned artifact of apps/morphir/fixtures/qualification/published.json into a new, empty directory, uses it only after its SHA-256 equals the pin, and writes one receipt per suite: one row per operation with extension, version, CLI, platform, operation, result, guest SHA-256, descriptor SHA-256 and output digests.
  • Elm (7.1): the executables of v0.4.1 and of elm-classic v0.5.1 (the fix of bead .16) as process workers, and the Elm v0.5.0-preview.2 WASM module (morphir-bytes-v1, model line) as a second Elm guest.
  • Mise tasks, all with --json: test:cli-extension-elm (7.1), test:cli-extism-python (7.2, rewritten for 0.2.0 pins), test:cli-native-prerequisites and test:portable-mep-cli (7.3, rewritten for the worker host), test:extension-conformance (7.4), test:extension-qualification (all).
  • 7.4: a conformance fixture guest built in Rust with morphir-extension-sdk at finos/morphir-rust de35f596, for wasm32-wasip1, in apps/morphir/fixtures/sdk-guest with its source, Cargo.lock, build receipt and the module (752 KB; one narrow .gitignore exception). It imports WASI preview 1, the Extism kernel and all four Morphir host functions, and claims a language no host knows (morphir-fixture-flags, .flags). It runs with no host change. Two clean builds give the same SHA-256.
  • Removed the retired-route scripts scripts/extism-python.mbtx, scripts/portable-mep-cli.mbtx, apps/morphir/scripts/test-extism-python.ts, apps/morphir/scripts/extism-python-api.py; tools/portable-command-json.test.ts drops its portable-mep-cli case. scripts/native-services.mbtx --acceptance is unchanged (group 9 removes that route).
  • New manual workflow .github/workflows/extension-qualification.yml (workflow_dispatch only) for the Windows x64 run of 7.5 and later per-platform runs. Its step logic is in scripts/extension-qualification-run.mbtx (--json, --self-test), so the workflow has one command per step. The same two files are in ci: add the manual extension qualification workflow #299, which lands first so the workflow can be dispatched.
  • Docs: apps/morphir/docs/extension.md#qualification, docs/MISE_TASKS.md, fixture READMEs. Tasks 7.1 to 7.4 ticked with notes.

Findings and follow-ups

Finding Effect Follow-up
Windows output publication: the native _WIN32 directory rename is a stub, and the Node publication creates the destination before it renames onto it Every Windows compile and generate fails to publish (extension.output_failed); task 7.5 stays open bead morphir-ukvn.5.64.36.19 (separate PR)
The portable guest's packaging (pkgs/morphir-host/embedding/build.mts) fails on Windows with ENOENT moonbit-portable not run on Windows bead morphir-ukvn.5.64.36.18
Elm extension v0.4.1 requires package.exposedModules in morphir.frontend.compile (cli2/mep/protocol.ts); the MEP Smithy model makes it optional, and the host, which conforms, does not send it v0.4.1 compile fails with -32602 and stays as a recorded failure. elm-classic v0.5.1 fixes it: its compile passes from both CLIs with no host change bead morphir-ukvn.5.64.36.16 (passing receipt on the bead)
The shared kit spec/mep/mck/guest-moonbit-bool.json asks for the frontend profile moonbit-model-bool-library-v1, which the MoonBit guest retired in #181 The kit run fails at case compile-ion for the native guest (direct) and the portable guest (native CLI worker mode) after describe, initialize and notifications pass. mise run test:portable-mep-mck is broken on main for the same reason bead morphir-ukvn.5.64.36.17 (finos/morphir)
No shared kit profile fits the SDK fixture guest (each profile names its own extension) 7.4 uses a local conformance check; the receipt says so bead morphir-ukvn.5.64.36.15; the public stdio command is issue #297

A known failure does not fail its suite, and it fails the suite if the operation starts to pass. The shared kit runs through the native CLI's internal morphir extension worker as its stdio host; no public command is added (#297).

Receipts

Full receipts, with exact digests, are on bead morphir-ukvn.5.64.36.7.

Suite macOS arm64 (local, b8277b5f) Linux x64 (ubuntu-24.04, run 41240756333, 8b0ab3c5) Windows x64 (windows-latest, run 41241517957, 52ce3720)
elm 16 passed, 2 known failures (0.4.1 compile, bead .16) 16 passed, 2 known failures describe passes for all three Elm guests; every compile fails to publish (host defect below)
python 32 passed 32 passed describe and the multi-document refusal pass; compile fails to publish
moonbit-native 12 passed, 1 known failure (shared kit, bead .17) 12 passed, 1 known failure describe passes; compile and generate fail to publish
moonbit-portable 11 passed, 1 known failure (bead .17) 11 passed, 1 known failure not run: the portable guest's packaging fails on Windows, bead morphir-ukvn.5.64.36.18
conformance 11 passed 11 passed describe and imports pass and the guest's host-function report arrives; compile fails to publish

All three CLIs-and-platforms run every guest session. Windows fails at publication, a host defect: the native CLI's morphir_host_rename_directory_new (pkgs/morphir-host/platform/platform.c) is a _WIN32 stub that returns 1 (publication.destination_unavailable), and the npm CLI's rename_directory_new_js creates the destination before it renames onto it, which Windows refuses (publication.create_failed). This is bead morphir-ukvn.5.64.36.19, fixed in its own PR ("fix(host): publish command output on Windows"), not here. Task 7.5 stays open and there is no Tested-on: trailer. A Windows checkout also turned the SDK fixture's Cargo.toml into CRLF; .gitattributes now keeps the qualification fixtures LF.

The earlier Linux run in Docker under Rosetta failed every native-CLI WASM row with SIGILL; the real-hardware run passes them all, so that was an emulation artifact.

Guest digests: Elm 0.4.1 7b4ea687… (aarch64-apple-darwin), 2f172a7f… (x86_64-unknown-linux-gnu), descriptor 152ee03d…; elm-classic 0.5.1 43716cdf… (aarch64-apple-darwin), 9cfcaf23… (x86_64-unknown-linux-gnu), b21d4b6c… (x86_64-pc-windows-msvc), descriptor ccf251ff…; Elm 0.5.0-preview.2 module 4d3ea176…, descriptor 4bc11967…; Python 0.4.1 a04722e1…, 0.4.2 10acafa0…; SDK fixture f5e1c9cd…; MCK runner v0.4.0-beta.11, kit 59485eb1….

CI impact (maintainer rule)

No new job in PR or merge-queue CI. The only workflow change is a new file whose sole trigger is workflow_dispatch:

on:
  workflow_dispatch:
    inputs:
      runner: {type: choice, options: [windows-latest, ubuntu-24.04, ubuntu-24.04-arm, macos-15], default: windows-latest}
      suite:  {type: choice, options: [all, elm, python, moonbit-native, moonbit-portable, conformance], default: all}

No existing PR or merge-queue step downloads extension bundles or Elm executables. tools/portable-command-json.test.ts gets shorter. This PR itself selects the full CI run once, because it edits .config/mise/config.toml and adds a workflow file (existing selector rule).

Build-master review

Verdict: no PR, merge-queue or push workflow gains a job or a slower step (ci-platforms.mbtx reports no violations; actionlint, mise run test:ci pass). Findings and what I did:

  • H1 npm pack cannot start on Windows (npm is npm.cmd): fixed, npm now runs as node <prefix>/…/npm/bin/npm-cli.js.
  • M1 GNU tar from Git Bash cannot read the MCK .zip: fixed, the driver uses %SystemRoot%\System32\tar.exe on Windows.
  • M2 bun/uv may be missing on Windows: fixed, the workflow runs the script through mise exec --.
  • M3 the command's JSON tests run nowhere: the workflow now runs moon test scripts/extension-qualification.mbtx and --help --json first. Adding them to test:ci is left to the maintainer.
  • M4 workflow_dispatch starts only a file on main: the Windows run (7.5) waits for the merge, or for a separate PR with only the workflow file. 7.5 stays open; I will ask before starting it.
  • L1 curl bounds: added --retry, timeouts, --max-filesize, --proto-redir. L2 Windows environment and the Node probe: added PATHEXT, ComSpec and others, where.exe node.exe, and a positive control on the npm CLI path. L3/L5: retention-days: 30, if-no-files-found: error, line-length. L4 (docs say macOS, Linux) is updated after 7.5 passes. I6 (no release gate reads the receipts) is outside group 7.

Not done here

  • 7.5 Windows x64: run and recorded; it failed at output publication (host defect), so 7.5 stays open and there is no Tested-on: trailer.
  • 7.6 is ticked: receipts for macOS arm64, Linux x64 and Windows x64 are on bead morphir-ukvn.5.64.36.7.
  • Bead .12 (nightly macOS) is untouched.

Test plan

  • mise run test:extension-qualification -- --json on macOS arm64 at b8277b5f: all suites passed
  • Linux x64 (Docker linux/amd64, emulated) at f9ef5b65: Elm and MoonBit native suites passed; npm CLI rows passed in every suite; native-CLI WASM rows fail under emulation (SIGILL)
  • Linux x64 on real hardware: run 41240756333 at 8b0ab3c5, every suite passed
  • Windows x64: run 41241517957 at 52ce3720 failed at output publication (host defect); see Receipts
  • moon test scripts/extension-qualification.mbtx; help and refusal JSON (exit 2)
  • moonx scripts/extension-qualification-run.mbtx --self-test --json
  • bun tools/portable-command-json.test.ts
  • bunx tsc -p tsconfig.node.json (no errors in new files)
  • Pre-push gates: lint, lint:moonbit, validate
  • CI

Add scripts/extension-qualification.mbtx and its driver
apps/morphir/scripts/extension-qualification.ts. They run the Elm
extension v0.4.1, the Python extension 0.4.1 and 0.4.2, the MoonBit
guest (native and portable) and a new morphir-extension-sdk fixture
guest from the native and npm CLIs, and write one receipt per suite.
Downloads go into new directories and are used only after their
SHA-256 equals the pin in apps/morphir/fixtures/qualification.

Rewrite test:cli-extism-python, test:portable-mep-cli and
test:cli-native-prerequisites for 0.2.0 pins on the worker host, and add
test:cli-extension-elm, test:extension-conformance and
test:extension-qualification. All accept --json. They stay manual.
Add .github/workflows/extension-qualification.yml, started only by
workflow_dispatch, to run scripts/extension-qualification.mbtx on one
runner and keep its receipts. It tests the command and its JSON help
first. No pull request, merge queue, push or schedule starts it.

Apply the build-master review: run npm through Node, unpack the MCK
runner with the system tar on Windows, give Windows process workers the
variables they need, check that the Node probe finds Node on the npm
CLI path, and bound each download. Tick tasks 7.1 to 7.4.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-31T18:56:27.829518Z f9ef5b6 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f9ef5b6515

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Move the step's logic (make the directories, save the JSON result,
write it to the log, keep the exit status) out of the workflow shell
block into scripts/extension-qualification-run.mbtx, which has --json
and --self-test. The workflow now runs one command per step.
… module

Add the elm-classic v0.5.1 executables, which accept a package with no
exposedModules (bead morphir-ukvn.5.64.36.16), and the Elm
v0.5.0-preview.2 module (morphir-bytes-v1, model line) to the elm suite.
Pin both releases by SHA-256. The WASM guest needs module names under
the package name, so it gets its own fixture. The Elm 0.4.1 compile
stays as a recorded failure.
In --json mode, scripts/extension-qualification-run.mbtx now catches any
error of the run, such as a --result path that is a directory, and
writes a failed command-result with error code command_failed and exit
status 1. The default mode keeps the runtime's error output. The
self-test checks that an unwritable result path raises.
The workflow's step helper makes the evidence directory before it runs
scripts/extension-qualification.mbtx, and @fs.mkdir refuses a directory
that exists. Make it only when it is missing.
On Windows the embedding build of the portable guest fails before any
suite runs. A packaging failure now fails only the moonbit-portable
suite, with its cause in the summary, and the other suites still run.
A Windows checkout converted the SDK fixture's Cargo.toml to CRLF, so
its digest no longer matched the build receipt. Check the qualification
fixtures out with LF on every platform.
The Windows x64 run of task 7.5 failed at output publication (bead
morphir-ukvn.5.64.36.19) and could not package the portable guest (bead
morphir-ukvn.5.64.36.18), so 7.5 stays open. Every receipt is recorded
on bead morphir-ukvn.5.64.36.7.
On a host with Node in /usr/bin or /bin, the native CLI's PATH exposed
node and the no-Node rows failed for the host's layout. On Unix the
native PATH is now one new, empty directory: the native CLI starts its
workers by path and needs no program from PATH. The check asserts that
each native PATH entry is empty, that the probe finds no node there and
that it finds node on the npm CLI PATH, and the receipt says so.
@DamianReeves
DamianReeves added this pull request to the merge queue Oct 31, 2026
Merged via the queue into main with commit 80c7d1c Oct 31, 2026
52 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant