diff --git a/plecos/samples/sample_metadata_local.json b/plecos/samples/sample_metadata_local.json
index cbe0036..1970d3e 100644
--- a/plecos/samples/sample_metadata_local.json
+++ b/plecos/samples/sample_metadata_local.json
@@ -33,7 +33,6 @@
         "url": "https://s3.amazonaws.com/datacommons/validation.zip"
       }
     ],
-    "checksum": "",
     "categories": [
       "image"
     ],
@@ -54,7 +53,8 @@
       {
         "name": "example code",
         "type": "example code",
-        "url": "https://github.com/slothkong/CNN_classification_10_monkey_species"
+        "url": "https://github.com/slothkong/CNN_classification_10_monkey_species",
+        "reviewed": true
       },
       {
         "url": "https://s3.amazonaws.com/datacommons/links/discovery/n5151.jpg",
diff --git a/plecos/samples/sample_metadata_remote.json b/plecos/samples/sample_metadata_remote.json
index c73d9ae..4f0a3cd 100644
--- a/plecos/samples/sample_metadata_remote.json
+++ b/plecos/samples/sample_metadata_remote.json
@@ -27,11 +27,12 @@
       },
       {
         "index": 2,
+        "contentType": "application/zip",
         "resourceId": "test ID"
       }
     ],
     "encryptedFiles": "234ab87234acbd095430853424ab87234acbd09543085340abffh21983ddhiiee9821438274234210abffh21983ddhiiee982143827423421",
-    "checksum": "",
+    "checksum": "0xd7296ccaaec630452be65a13ea1d2d750f071b6f50b779e99cc9adf05faebabc",
     "categories": [
       "image"
     ],
@@ -56,7 +57,8 @@
       {
         "url": "https://s3.amazonaws.com/datacommons/links/discovery/n5151.jpg",
         "name": "n5151.jpg",
-        "type": "discovery"
+        "type": "discovery",
+        "reviewed": true
       },
       {
         "url": "https://s3.amazonaws.com/datacommons/links/sample/sample.zip",
diff --git a/plecos/schemas/metadata_local_v0_4.json b/plecos/schemas/metadata_local_v0_4.json
index e7acf31..f99f715 100644
--- a/plecos/schemas/metadata_local_v0_4.json
+++ b/plecos/schemas/metadata_local_v0_4.json
@@ -70,7 +70,8 @@
           "default": "0",
           "examples": [
             "10"
-          ]
+          ],
+          "pattern": "^[0-9]+$"
         },
         "files": {
           "$id": "#/properties/base/properties/files",
@@ -177,16 +178,6 @@
             }
           }
         },
-        "checksum": {
-          "$id": "#/properties/base/properties/checksum",
-          "type": "string",
-          "title": "The Checksum Schema",
-          "default": "",
-          "examples": [
-            ""
-          ],
-          "pattern": "^(.*)$"
-        },
         "categories": {
           "$id": "#/properties/base/properties/categories",
           "type": "array",
@@ -271,7 +262,7 @@
             "type": "object",
             "title": "The Items Schema",
             "default": null,
-            "additionalProperties": false,
+            "additionalProperties": true,
             "required": [
               "url"
             ],
diff --git a/plecos/schemas/metadata_remote_v0_4.json b/plecos/schemas/metadata_remote_v0_4.json
index 6be4847..f9b4528 100644
--- a/plecos/schemas/metadata_remote_v0_4.json
+++ b/plecos/schemas/metadata_remote_v0_4.json
@@ -18,6 +18,7 @@
       "required": [
         "name",
         "dateCreated",
+        "datePublished",
         "author",
         "license",
         "price",
@@ -81,7 +82,8 @@
           "default": "0",
           "examples": [
             "10"
-          ]
+          ],
+          "pattern": "^[0-9]+$"
         },
         "files": {
           "$id": "#/properties/base/properties/files",
@@ -96,7 +98,8 @@
             "default": null,
             "additionalProperties": false,
             "required": [
-              "index"
+              "index",
+              "contentType"
             ],
             "properties": {
               "index": {
@@ -197,7 +200,7 @@
           "examples": [
             ""
           ],
-          "pattern": "^(.*)$"
+          "pattern": "^0x[a-fA-F0-9]{64}$"
         },
         "categories": {
           "$id": "#/properties/base/properties/categories",
@@ -285,7 +288,7 @@
             "type": "object",
             "title": "The Items Schema",
             "default": null,
-            "additionalProperties": false,
+            "additionalProperties": true,
             "required": [
               "url"
             ],

Minor fixes to sync Plecos schemas with OEP-8 version 0.3
These are minor fixes to bring the Plecos schema files more in sync with OEP-8 version 0.3. (There were some big changes in OEP-8 version 0.4, mainly adding the "services" array. Those changes aren't included in this issue.)

**In plecos/plecos/schemas/metadata_local_v0_4.json**

- Remove the overall `checksum` (not the file checksums). There should be no overall `checksum` in the local metadata because the overall `checksum` depends on the `did` and that is not known until later (after going through the register/publish flow).
- The `price` should have a "pattern" to restrict it to being digits, e.g `^[0-9]+$`. I don't know if we want to allow scientific notation such as "1.3E10" or "1.23E+9". If yes, then the regular expression would be a bit different.
- In "links" - "items", "additionalProperties" is `false` but it should be `true`: OEP-8 gives marketplaces the freedom to add additional properties to link objects.

**In plecos/plecos/schemas/metadata_remote_v0_4.json**

- In file objects, the `contentType` is required (according to OEP-8).
- The overall `checksum` should be a string starting with "0x" and ending with 64 hex characters. Change the "pattern" regular expression from `^(.*)$` to `^0x[a-fA-F0-9]{64}$`
- `datePublished` is required in the remote `base` object.
- See the local metadata task for the "pattern" on `price` (above).
- See the local metadata task for the "additionalProperties" of links (above).


More "patterns" (regular expressions) could be added. I just put some of the more important ones above.
diff --git a/tests/test_validate.py b/tests/test_validate.py
index 77e6ab8..66ed0cf 100644
--- a/tests/test_validate.py
+++ b/tests/test_validate.py
@@ -93,18 +93,6 @@ def test_fail_on_missing_file_url_attribute(schema_local_dict, schema_remote_dic
         assert e_info
 
 
-def test_fail_on_additonal_links_attribute(schema_local_dict, schema_remote_dict, sample_metadata_dict_local, sample_metadata_dict_remote):
-    sample_metadata_dict_local['base']['links'][0]['EXTRA ATTRIB!'] = 0
-    with pytest.raises(ValidationError) as e_info:
-        validate(instance=sample_metadata_dict_local, schema=schema_local_dict)
-        assert e_info
-
-    sample_metadata_dict_remote['base']['links'][0]['EXTRA ATTRIB!'] = 0
-    with pytest.raises(ValidationError) as e_info:
-        validate(instance=sample_metadata_dict_remote, schema=schema_remote_dict)
-        assert e_info
-
-
 def test_fail_on_missing_base_attribute(schema_local_dict, schema_remote_dict, sample_metadata_dict_local, sample_metadata_dict_remote):
     del sample_metadata_dict_local['base']['price']
     with pytest.raises(ValidationError) as e_info:
@@ -123,20 +111,23 @@ def test_allow_additional_information(schema_local_dict, schema_remote_dict, sam
         "item2": 2 }
     }
 
-    # delete additional info
-    del sample_metadata_dict_local['base']['additionalInformation']
+    # delete additionalInformation, if present
+    if 'additionalInformation' in sample_metadata_dict_local:
+        del sample_metadata_dict_local['additionalInformation']
     validate(instance=sample_metadata_dict_local, schema=schema_local_dict)
 
-    del sample_metadata_dict_remote['base']['additionalInformation']
+    if 'additionalInformation' in sample_metadata_dict_remote:
+        del sample_metadata_dict_remote['additionalInformation']
     validate(instance=sample_metadata_dict_remote, schema=schema_remote_dict)
 
     # add additional info
-    sample_metadata_dict_local['base']['additionalInformation'] = more
+    sample_metadata_dict_local['additionalInformation'] = more
     validate(instance=sample_metadata_dict_local, schema=schema_local_dict)
 
-    sample_metadata_dict_remote['base']['additionalInformation'] = more
+    sample_metadata_dict_remote['additionalInformation'] = more
     validate(instance=sample_metadata_dict_remote, schema=schema_remote_dict)
 
+
 def test_fail_local_missing_file_url(schema_local_dict, schema_remote_dict, sample_metadata_dict_local, sample_metadata_dict_remote):
     del sample_metadata_dict_local['base']['files'][0]['url']
     with pytest.raises(ValidationError) as e_info:
@@ -157,7 +148,7 @@ def test_fail_on_type_mismatches(schema_local_dict, schema_remote_dict, sample_m
         assert e_info
     assert e_info.value.absolute_path[0] == 'base'
     assert e_info.value.absolute_path[1] == 'price'
-    assert e_info.value.validator_value == 'integer'
+    assert e_info.value.validator_value == '^[0-9]+$'
 
     sample_metadata_dict_remote['base']['price'] = "A string is not allowed!"
     with pytest.raises(ValidationError) as e_info:
@@ -165,7 +156,7 @@ def test_fail_on_type_mismatches(schema_local_dict, schema_remote_dict, sample_m
         assert e_info
     assert e_info.value.absolute_path[0] == 'base'
     assert e_info.value.absolute_path[1] == 'price'
-    assert e_info.value.validator_value == 'integer'
+    assert e_info.value.validator_value == '^[0-9]+$'
 
 def test_validate_file(path_sample_metadata_local):
     plecos.validate_file_local(path_sample_metadata_local)

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest
3.6
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
certifi==2021.5.30
importlib-metadata==4.8.3
iniconfig==1.1.1
jsonschema==3.0.0b3
packaging==21.3
-e git+https://github.com/oceanprotocol/plecos.git@e83ee23570d855d7b14d3b8cad4bb747b2526a8a#egg=plecos
pluggy==1.0.0
py==1.11.0
pyparsing==3.1.4
pyrsistent==0.14.11
pytest==7.0.1
six==1.12.0
tomli==1.2.3
typing_extensions==4.1.1
zipp==3.6.0

name: plecos
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - jsonschema==3.0.0b3
      - packaging==21.3
      - pluggy==1.0.0
      - py==1.11.0
      - pyparsing==3.1.4
      - pyrsistent==0.14.11
      - pytest==7.0.1
      - six==1.12.0
      - tomli==1.2.3
      - typing-extensions==4.1.1
      - zipp==3.6.0
prefix: /opt/conda/envs/plecos

tests/test_validate.py::test_fail_on_type_mismatches tests/test_validate.py::test_list_errors_dict
tests/test_validate.py::test_validator_simple tests/test_validate.py::test_local_metadata_passes tests/test_validate.py::test_remote_metadata_passes tests/test_validate.py::test_fail_on_additonal_base_attribute tests/test_validate.py::test_fail_on_additonal_file_attribute tests/test_validate.py::test_fail_on_missing_file_index_attribute tests/test_validate.py::test_fail_on_missing_file_url_attribute tests/test_validate.py::test_fail_on_missing_base_attribute tests/test_validate.py::test_allow_additional_information tests/test_validate.py::test_fail_local_missing_file_url tests/test_validate.py::test_assert_remote_without_file_url tests/test_validate.py::test_validate_file tests/test_validate.py::test_validate_dict tests/test_validate.py::test_is_valid_file tests/test_validate.py::test_is_valid_dict
plecos/samples/sample_metadata_remote.json plecos/samples/sample_metadata_local.json plecos/schemas/metadata_remote_v0_4.json plecos/schemas/metadata_local_v0_4.json
plecos/samples/sample_metadata_remote.json plecos/samples/sample_metadata_local.json plecos/schemas/metadata_remote_v0_4.json plecos/schemas/metadata_local_v0_4.json