Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions .config/mise/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -298,16 +298,28 @@ description = "Run and recheck the independent pinned shared MEP guest suite"
run = "moonx scripts/portable-mep-mck.mbtx"

[tasks."test:portable-mep-cli"]
description = "Run the saved MEP guest through the primary CLI extension command"
run = "moonx scripts/portable-mep-cli.mbtx"
description = "Qualify the portable MoonBit guest (morphir-bytes-v1 WASM) on the worker host from the native and npm CLIs, with the shared MEP kit; [--json]"
run = "moonx scripts/extension-qualification.mbtx moonbit-portable"

[tasks."test:wasm-workers"]
description = "Run the package tests of one target with the end-to-end WASM worker tests, or the browser Web Worker proof: --target native|js [--scope workers|browser] [--json]"
run = "moonx scripts/wasm-workers-test.mbtx"

[tasks."test:cli-extism-python"]
description = "Qualify an explicit local Python Extism bundle through native and packaged CLI entry points"
run = "moonx scripts/extism-python.mbtx"
description = "Qualify the pinned Python extension 0.4.1 and 0.4.2 releases on the worker host from the native and npm CLIs; [--python PATH] [--json]"
run = "moonx scripts/extension-qualification.mbtx python"

[tasks."test:cli-extension-elm"]
description = "Qualify the pinned Elm extension v0.4.1 executables on the worker host from the native and npm CLIs; [--json]"
run = "moonx scripts/extension-qualification.mbtx elm"

[tasks."test:extension-conformance"]
description = "Run the morphir-extension-sdk conformance fixture guest on the worker host from the native and npm CLIs; [--json]"
run = "moonx scripts/extension-qualification.mbtx conformance"

[tasks."test:extension-qualification"]
description = "Run every worker host qualification suite (Elm, Python, MoonBit native and portable, SDK fixture); [--python PATH] [--json]"
run = "moonx scripts/extension-qualification.mbtx all"

[tasks."sdk-spec:generate"]
description = "Regenerate pkgs/morphir-sdk-spec/sdk_data.mbt from pkgs/morphir-sdk-spec/sdk.scm"
Expand Down Expand Up @@ -510,8 +522,8 @@ description = "Smoke-test CLI targets and installed package"
run = "moonx scripts/typescript-tooling.mbtx test-cli"

[tasks."test:cli-native-prerequisites"]
description = "Focused native source-CLI compile, provider and local repository acceptance; requires explicit --shared or MORPHIR_SHARED_SOURCE"
run = "moon run scripts/native-services.mbtx -- --acceptance"
description = "Qualify the native MoonBit guest as a process worker on the worker host from the native and npm CLIs, with the shared MEP kit; [--json]"
run = "moonx scripts/extension-qualification.mbtx moonbit-native"

[tasks."check:typescript"]
description = "Install frozen dependencies and check all TypeScript projects"
Expand Down
7 changes: 7 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,10 @@ tools/packaged-targets-pin.json text eol=lf
# Keep the complete pinned Archify package byte-exact and collapsed in code review.
.agents/skills/archify/** -text linguist-vendored
.agents/skills/archify/UPSTREAM.md text eol=lf linguist-vendored=false
# Qualification fixtures: their digests and the IR they compile to must not
# depend on the checkout's line endings.
apps/morphir/fixtures/sdk-guest/** text eol=lf
apps/morphir/fixtures/sdk-guest/*.wasm binary
apps/morphir/fixtures/elm-extension/** text eol=lf
apps/morphir/fixtures/extism-python/** text eol=lf
apps/morphir/fixtures/qualification/** text eol=lf
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ target
**/*.mbt.js
**/*.wat
**/*.wasm
# The SDK conformance fixture guest is stored with its source and build receipt.
!apps/morphir/fixtures/sdk-guest/morphir-sdk-fixture-guest.wasm
_build/
pkgs/morphir-host/embedding/dist/

Expand Down
87 changes: 62 additions & 25 deletions apps/morphir/docs/extension.md
Original file line number Diff line number Diff line change
Expand Up @@ -433,10 +433,63 @@ session cases: MEP `0.1` compile from claimed sources, an unclaimed operation, a
unsuccessful answer, a failed shutdown, cancellation during generate and the
deadline.

`mise run test:portable-mep-cli`, `mise run test:cli-native-prerequisites` and
`mise run test:cli-extism-python` still write retired pins. They are rewritten for
contract `0.2.0` pins and the worker host when the published extensions are
qualified on it (group 7 of the OpenSpec change `host-extensions-as-workers`).
### Published extensions and fixture guests

The published extensions are examples of conformant extensions, not the
definition of support. `scripts/extension-qualification.mbtx` runs them, and an
independent fixture guest, from the native CLI and from the npm CLI, as a user
installs it (an unpacked `npm pack` of `apps/morphir`). Every task accepts
`--json`:

| Task | Suite | What it checks |
| --- | --- | --- |
| `mise run test:cli-extension-elm` | `elm` | Elm extension executables `v0.4.1` and elm-classic `v0.5.1` (process workers): describe with the release descriptor, compile of `apps/morphir/fixtures/elm-extension/v1/src`, and no `node` on the PATH of the native run. Elm `v0.5.0-preview.2` (one WASM module, `morphir-bytes-v1`): describe, compile of `v1/package` on the model line, generate, and recompile of the generated sources to the same model |
| `mise run test:cli-extism-python` | `python` | Python extension `0.4.1`: one document for IR 3 and 4, and the refusal of two documents. `0.4.2`: compile of the two-module fixture for IR 3 and 4, generate, a consumer check of the generated Python, recompile of the generated files to the same IR, and the IR version check |
| `mise run test:cli-native-prerequisites` | `moonbit-native` | The native MoonBit guest as a process worker: the shared kit's source, consumer and JSON artifacts through both CLIs, and the shared MEP kit run against the guest |
| `mise run test:portable-mep-cli` | `moonbit-portable` | The portable MoonBit guest (`morphir-bytes-v1`): the same checks, with the shared kit run through `morphir extension worker` of the native CLI |
| `mise run test:extension-conformance` | `conformance` | The `morphir-extension-sdk` fixture guest in `apps/morphir/fixtures/sdk-guest` (see its README): build receipt, WASI and Morphir host function imports, claims of a language that no host knows, compile, generate, recompile, host function answers and guest diagnostics |
| `mise run test:extension-qualification` | `all` | All five suites |

Each run builds the CLIs and the guests that it needs. It downloads each
pinned artifact of `apps/morphir/fixtures/qualification/published.json` into a
new, empty directory under `.dev/extension-qualification/downloads` and uses it
only when its SHA-256 equals the pin. It writes one receipt for each suite,
`.dev/extension-qualification/evidence/<suite>.json` (`--evidence DIR` selects
another directory). A receipt names the platform, the CLI build (commit, a dirty
flag and the program SHA-256) and one row for each operation: extension,
version, CLI (`native`, `npm` or `mck` for the shared kit runner), operation,
result, guest SHA-256, descriptor SHA-256 and the digests of the published
files. With `--json`, stdout is one `morphir/command-result` with `result.suites`
(state and row counts of each receipt) and `result.receipts`; build and driver
output goes to stderr. A failed suite exits 1 with `qualification_failed`.

A row is `passed`, `failed` or `known-failure`. A known failure is an operation
that fails for a recorded cause outside the host, with its finding and
follow-up bead. It does not fail the suite, and it fails the suite when it
passes, so the record is removed. The current known failures are:

- Elm extension `v0.4.1` compile. The extension requires
`package.exposedModules` in `morphir.frontend.compile`; the MEP model makes it
optional and the host, which conforms, does not send it. Describe passes.
Bead `morphir-ukvn.5.64.36.16`: elm-classic `v0.5.1` (the same JavaScript
extension, renamed) fixes it, and its compile passes.
- The shared MEP kit against the MoonBit guest. The kit
`spec/mep/mck/guest-moonbit-bool.json` asks for the frontend profile
`moonbit-model-bool-library-v1`, which the guest retired, so the case
`compile-ion` fails after describe, initialize and the notifications pass.
Follow-up: bead `morphir-ukvn.5.64.36.17` (finos/morphir). For the same
reason `mise run test:portable-mep-mck` does not pass.

No shared kit profile fits the SDK fixture guest, because each shared profile
names its own extension. The `conformance` suite is therefore a local check. A
generic kit profile is bead `morphir-ukvn.5.64.36.15`.

These tasks are manual. No pull request or merge-queue job runs them, because
they download published releases and build several guests. The workflow
`.github/workflows/extension-qualification.yml`, started only by
`workflow_dispatch`, runs one suite on one runner through
`scripts/extension-qualification-run.mbtx`, which saves the JSON result for the
artifact and keeps the qualification's exit status.

## Controlled local repositories

Expand Down Expand Up @@ -484,24 +537,8 @@ Every lifecycle command accepts `--json` and writes one `morphir/command-result`
after required writes. These commands do not automatically join installed
selection to invocation. That downstream acceptance remains morphir-ukvn.5.64.30.

**Pending.** `mise run test:cli-native-prerequisites` still writes retired pins and
calls the removed helper route, so it does not pass against this CLI. It is
rewritten for contract `0.2.0` pins and the worker host in group 7 of the OpenSpec
change `host-extensions-as-workers`; see [Qualification](#qualification). Until
then, the description below records what the task covered before the worker host:

```sh
mise run test:cli-native-prerequisites -- --shared /path/to/finos/morphir --json
```

It freezes separately built native guests and fault peers, tests embedded Boolean
and Elm compilation, compile/retain/generate/consumer execution, malformed/oversized
frames, tuple and context refusal, crashes, diagnostics, deadlines, cancellation,
shutdown and cleanup. It also tests local publication/install, a real version
update, corrupt and disabled selections, offline replay and removal in a fresh
home. It reruns the existing portable provider tests and CLI unit suite. The task
passes the produced CLI, adapter and guest paths explicitly to each test process,
binding its receipts to tested artifacts even when the caller has artifact
override variables set. Evidence and host pins stay under `.dev/native-services`;
no installed matrix, new CI job,
release or default switch is performed.
`mise run test:cli-native-prerequisites` used to test these commands with the
retired helper route. It now qualifies the native MoonBit guest on the worker
host; see [Qualification](#qualification). The Rust adapter acceptance stays
available as `moon run scripts/native-services.mbtx -- --acceptance --shared
/path/to/finos/morphir --json` until the helper routes are removed.
14 changes: 14 additions & 0 deletions apps/morphir/fixtures/elm-extension/v1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Elm extension qualification fixtures

`mise run test:cli-extension-elm` compiles these with the published Elm
extensions.

- `src/Rules.elm`, package `acme/rules`, for the executables of `v0.4.1` and
elm-classic `v0.5.1`. They do not claim `multiDocument`, so the fixture is one
document. Its module name has one segment, because these extensions compile
only module names that the package name does not prefix.
- `package/Acme/Rules/Main.elm`, package `Acme.Rules`, for the `v0.5.0-preview.2`
WASM module. That extension requires each module name to start with the
package name and to have one more segment, and the file path to match it.

Both hold the same two functions.
15 changes: 15 additions & 0 deletions apps/morphir/fixtures/elm-extension/v1/package/Acme/Rules/Main.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module Acme.Rules.Main exposing (eligible, priority)


eligible : Bool -> Bool -> Bool
eligible active vip =
active && not vip


priority : Bool -> Int
priority vip =
if vip then
1

else
2
15 changes: 15 additions & 0 deletions apps/morphir/fixtures/elm-extension/v1/src/Rules.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module Rules exposing (eligible, priority)


eligible : Bool -> Bool -> Bool
eligible active vip =
active && not vip


priority : Bool -> Int
priority vip =
if vip then
1

else
2
13 changes: 9 additions & 4 deletions apps/morphir/fixtures/extism-python/v1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ The local `large_value` function is an additional precision regression. Its
integer exceeds JavaScript's exact-number range and must survive generation
without rounding.

The focused CLI suite compares native Python API compilation with the real
published WASM bundle for IR 3 and 4, generates Python, checks selected consumer
behavior, and recompiles without changing the IR. This proves only this bounded
subset and the exact host/CLI cells in the resulting receipt.
`single/rules.py` is one module with no imports, for the Python extension
`0.4.1`, which does not claim `multiDocument` and compiles one document for each
request. The two-module `acme` directory is its multi-document refusal.

`mise run test:cli-extism-python` compiles `acme` with the published `0.4.2`
module for IR 3 and 4 from the native and npm CLIs, generates Python, runs
`apps/morphir/scripts/extension-qualification-consumer.py` on the generated
files, and recompiles them without a change to the IR. This proves only this
bounded subset and the exact host and CLI cells in the resulting receipt.
12 changes: 12 additions & 0 deletions apps/morphir/fixtures/extism-python/v1/single/rules.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from __future__ import annotations


def choose(flag: bool, first: int, second: int) -> int:
if flag:
return first
else:
return second


def large_value() -> int:
return 9007199254740993
159 changes: 159 additions & 0 deletions apps/morphir/fixtures/qualification/published.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
{
"contractVersion": "0.1.0",
"elm": {
"repository": "finos/morphir-elm",
"tag": "extension/elm/v0.4.1",
"version": "0.4.1",
"sourceRevision": "a3299f95c9252852f19c1ccabbb0d1525a24a25e",
"descriptor": {
"filename": "morphir-elm-extension-0.4.1.bundle.release.json",
"sha256": "152ee03ddd4e9e0b91fbe0d6a79f6228387ce35c3f42a32f844ababf0c1c924d"
},
"executables": {
"aarch64-apple-darwin": {
"filename": "morphir-elm-extension-0.4.1-aarch64-apple-darwin",
"sha256": "7b4ea687589c67e561162cc1cf7cac78d93d49cfc2dfc4e6fd17217c6b7139e9"
},
"x86_64-apple-darwin": {
"filename": "morphir-elm-extension-0.4.1-x86_64-apple-darwin",
"sha256": "5ed08c452bc70ab8c70b3cdcfb50271e3e828a840cb77b214a799a4718c98196"
},
"aarch64-unknown-linux-gnu": {
"filename": "morphir-elm-extension-0.4.1-aarch64-unknown-linux-gnu",
"sha256": "b9394d624b6962be93272b587c35379fb7ccab2468ed525e819233e8047ebd72"
},
"x86_64-unknown-linux-gnu": {
"filename": "morphir-elm-extension-0.4.1-x86_64-unknown-linux-gnu",
"sha256": "2f172a7f3979962ac1cb0203457a0b8178324712c8b58e21c578c68d626d46bb"
},
"aarch64-pc-windows-msvc": {
"filename": "morphir-elm-extension-0.4.1-aarch64-pc-windows-msvc.exe",
"sha256": "1fa57c943b209c2065499f2dcd93d2f5039d1fe82a22b2292a7d7253e660a97b"
},
"x86_64-pc-windows-msvc": {
"filename": "morphir-elm-extension-0.4.1-x86_64-pc-windows-msvc.exe",
"sha256": "5049f4ab97671ef54d183157c82b13a6687b6de5da33566756ae4c3e627d49d8"
}
}
},
"elmClassic": {
"repository": "finos/morphir-elm",
"tag": "extension/elm-classic/v0.5.1",
"version": "0.5.1",
"sourceRevision": "947a65eea45d38c4876c91a922753a24443ebf70",
"descriptor": {
"filename": "morphir-elm-classic-extension-0.5.1.bundle.release.json",
"sha256": "ccf251ff77d6a80cd5412fbc2a56b281b50fc6a4f2ebad3a9379168bee730ffe"
},
"executables": {
"aarch64-apple-darwin": {
"filename": "morphir-elm-classic-extension-0.5.1-aarch64-apple-darwin",
"sha256": "43716cdff0975ad43ad810ca37b3a7d43a0130c7d4509b72814ef656faf2cc04"
},
"x86_64-apple-darwin": {
"filename": "morphir-elm-classic-extension-0.5.1-x86_64-apple-darwin",
"sha256": "e6e6df4ffa4dec8cbbe666b106def83e3dff31c45210595175629c58aa9a701f"
},
"aarch64-unknown-linux-gnu": {
"filename": "morphir-elm-classic-extension-0.5.1-aarch64-unknown-linux-gnu",
"sha256": "151d22959d4463e2f4263ec3892c92fe9994a7895e228062192511de5b7b7b85"
},
"x86_64-unknown-linux-gnu": {
"filename": "morphir-elm-classic-extension-0.5.1-x86_64-unknown-linux-gnu",
"sha256": "9cfcaf23353e83723cd0b153ceb863a9c0470e79e344e0ab890a36fa3eba3b37"
},
"aarch64-pc-windows-msvc": {
"filename": "morphir-elm-classic-extension-0.5.1-aarch64-pc-windows-msvc.exe",
"sha256": "e962f2d4877dddef9d063efbcd872db14a63a5166120a7f095cd25c4bc735836"
},
"x86_64-pc-windows-msvc": {
"filename": "morphir-elm-classic-extension-0.5.1-x86_64-pc-windows-msvc.exe",
"sha256": "b21d4b6c6f4667b5bbb532cbe7428bef9f8524baaa55db0fdbfb47d0233e3de1"
}
}
},
"elmWasm": {
"repository": "finos/morphir-elm",
"tag": "extension/elm/v0.5.0-preview.2",
"version": "0.5.0-preview.2",
"sourceRevision": "1604c1108886ef630b877888d4f9ea877bfa32f8",
"module": {
"filename": "morphir-elm-0.5.0-preview.2.wasm",
"sha256": "4d3ea176fdc4c7b19d887c91834ba4cdfb785249e72ce23132a8d04734a8ca6c"
},
"descriptor": {
"filename": "morphir-elm-0.5.0-preview.2.release.json",
"sha256": "4bc11967398e578175a1d38c6005b3c8e949a7c2c3a5320511a60ad37b5d39eb"
}
},
"python": {
"repository": "finos/morphir-python",
"releases": {
"0.4.1": {
"tag": "extension/python/v0.4.1",
"sourceRevision": "0d7e2eb62b4b1249129ab702a5240c41266813f6",
"module": {
"filename": "morphir-python-binding-0.4.1.wasm",
"sha256": "a04722e16115667fc7c332177805dcb049aef563afcee0e5f80c5fea302f5b4e"
},
"descriptor": {
"filename": "morphir-python-binding-0.4.1.release.json",
"sha256": "6cebee18b70e75da90f1cd187f24c8185ddde2565bb7c8e5049e21bbcccf0bb3"
}
},
"0.4.2": {
"tag": "extension/python/v0.4.2",
"sourceRevision": "1f547d17f648d5b398862f9dfceb05b6d463cb3f",
"module": {
"filename": "morphir-python-binding-0.4.2.wasm",
"sha256": "10acafa0f0282c5240e9620a5f2bb21629cc7580b9add528e7b77c7e54db22b5"
},
"descriptor": {
"filename": "morphir-python-binding-0.4.2.release.json",
"sha256": "72770f73f05a72535fd8c86ad4629175019037441a758b827c1ba47cc9a52ebd"
}
}
}
},
"mck": {
"repository": "finos/morphir",
"tag": "v0.4.0-beta.11",
"sourceRevision": "9d4f4b4de0f9bd10549493bdd9c83f20709055f9",
"runners": {
"aarch64-apple-darwin": {
"filename": "morphir-0.4.0-beta.11-aarch64-apple-darwin.tgz",
"sha256": "1a1895c0b189b79c0cbb590c2b43d05c5ea9688bbc4b5cf8be6262cf57c19380"
},
"x86_64-apple-darwin": {
"filename": "morphir-0.4.0-beta.11-x86_64-apple-darwin.tgz",
"sha256": "e93f826039bbaf95226c7e3cc7698920ae3968ab5c3263633fe0188d334dfcf1"
},
"aarch64-unknown-linux-gnu": {
"filename": "morphir-0.4.0-beta.11-aarch64-unknown-linux-gnu.tgz",
"sha256": "141c7d75a5539e24f344a55c78b00a7cf22397b155f60f7c00787402660fc28f"
},
"x86_64-unknown-linux-gnu": {
"filename": "morphir-0.4.0-beta.11-x86_64-unknown-linux-gnu.tgz",
"sha256": "01d0f96bbe73dadf06188d725b823d407c0bf79ef78869d57669744eed9fd437"
},
"aarch64-pc-windows-msvc": {
"filename": "morphir-0.4.0-beta.11-aarch64-pc-windows-msvc.zip",
"sha256": "4ca0af7b9e2bc9f632ae49baca6baf615eb0171008d1a6e924a981e3a4a347c6"
},
"x86_64-pc-windows-msvc": {
"filename": "morphir-0.4.0-beta.11-x86_64-pc-windows-msvc.zip",
"sha256": "da1a24c53802fcbb2750813b2fd865334b47b3410bdae9afdc64e5a59abb1cba"
}
},
"kits": {
"guest-moonbit-bool": {
"path": "spec/mep/mck/guest-moonbit-bool.json",
"sha256": "59485eb156d50d3f4255c67561fb509e3a938aff1739d22a27099043b236a5d0"
},
"guest-python-json": {
"path": "spec/mep/mck/guest-python-json.json",
"sha256": "9b4b5079ec36275b6ab5f11e7029e40959bc6577dcae41c4659d4151fab45a9d"
}
}
}
}
Loading
Loading