From 17775c0245feb63732da6b73312d9722805a5674 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Fri, 1 May 2026 01:02:09 -0400 Subject: [PATCH 01/25] Add schema validation CI job Co-authored-by: OpenAI Codex GPT-5 --- .github/workflows/CI.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 6ab8a1f..8ec4392 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -94,8 +94,16 @@ jobs: path: versions.json if-no-files-found: error + schema-check: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 6.0.2 + + - run: npx -p ajv-cli@3.3.0 ajv compile -s schema.json + upload-to-s3: - needs: [package-tests, full-test] + needs: [package-tests, full-test, schema-check] if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' runs-on: ubuntu-latest timeout-minutes: 60 From 1e0e5935c084d339a0d66f5aee6ea99b6d9adc70 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Fri, 1 May 2026 01:06:35 -0400 Subject: [PATCH 02/25] Add portable URL constraints to schema Co-authored-by: OpenAI Codex GPT-5 --- schema.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/schema.json b/schema.json index c79c1c6..08c5338 100644 --- a/schema.json +++ b/schema.json @@ -67,6 +67,14 @@ ".exe", ".gz", ".zip" + ], + "allOf": [ + { + "pattern": "^https://" + }, + { + "pattern": "\\.(?:dmg|exe|gz|zip)$" + } ] }, "asc": { From 8fa0c689f948468b0ba6ef73712609d30a0e75ba Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:50:18 -0400 Subject: [PATCH 03/25] Add sha256 schema pattern Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schema.json b/schema.json index 08c5338..c69df30 100644 --- a/schema.json +++ b/schema.json @@ -39,7 +39,8 @@ "$ref": "#/definitions/Arch" }, "sha256": { - "type": "string" + "type": "string", + "pattern": "^[0-9A-Fa-f]{64}$" }, "git-tree-sha1": { "type": "string" From 9e862e5c18073933509b1805c6676f9cc11b9959 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:50:25 -0400 Subject: [PATCH 04/25] Add git-tree-sha1 schema pattern Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schema.json b/schema.json index c69df30..c9eef3a 100644 --- a/schema.json +++ b/schema.json @@ -43,7 +43,8 @@ "pattern": "^[0-9A-Fa-f]{64}$" }, "git-tree-sha1": { - "type": "string" + "type": "string", + "pattern": "^[0-9A-Fa-f]{40}$" }, "git-tree-sha256": { "type": "string" From 2e0db2a41c8c8b81c053b45e1cfa93788eaec402 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:50:32 -0400 Subject: [PATCH 05/25] Add git-tree-sha256 schema pattern Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schema.json b/schema.json index c9eef3a..91db3c1 100644 --- a/schema.json +++ b/schema.json @@ -47,7 +47,8 @@ "pattern": "^[0-9A-Fa-f]{40}$" }, "git-tree-sha256": { - "type": "string" + "type": "string", + "pattern": "^[0-9A-Fa-f]{64}$" }, "size": { "type": "integer" From 6a0b2302fa9a06b3605043c504f73f2386f96ccf Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:50:41 -0400 Subject: [PATCH 06/25] Add version schema pattern Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schema.json b/schema.json index 91db3c1..5abc1dc 100644 --- a/schema.json +++ b/schema.json @@ -54,7 +54,8 @@ "type": "integer" }, "version": { - "type": "string" + "type": "string", + "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(?:-(?:alpha[0-9]*|beta[0-9]*|rc[0-9]+|pre\\.(?:alpha|beta)))?$" }, "os": { "$ref": "#/definitions/OS" From 88df3cf034ecd20fd2561dc28d2a9f1a1c65db76 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:50:49 -0400 Subject: [PATCH 07/25] Add top-level version key pattern Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/schema.json b/schema.json index 5abc1dc..986ca86 100644 --- a/schema.json +++ b/schema.json @@ -1,6 +1,9 @@ { "$schema": "http://json-schema.org/draft-06/schema#", "type": "object", + "propertyNames": { + "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(?:-(?:alpha[0-9]*|beta[0-9]*|rc[0-9]+|pre\\.(?:alpha|beta)))?$" + }, "additionalProperties": { "$ref": "#/definitions/WelcomeValue" }, From 285affb1e84bcd9e6f713ca9d2bfe353b967bfd5 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:51:01 -0400 Subject: [PATCH 08/25] Add asc PGP armor schema pattern Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schema.json b/schema.json index 986ca86..c5a3f57 100644 --- a/schema.json +++ b/schema.json @@ -85,7 +85,8 @@ ] }, "asc": { - "type": "string" + "type": "string", + "pattern": "^-----BEGIN PGP SIGNATURE-----\\n(?:[A-Za-z0-9-]+: [^\\n]*\\n)*\\n(?:[A-Za-z0-9+/]{1,76}=*\\n)+=[A-Za-z0-9+/]{4}\\n-----END PGP SIGNATURE-----\\n?$" }, "extension": { "$ref": "#/definitions/FileExtension" From 2d60af045586b8eeb19c0345f66632a67c1710ff Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:51:09 -0400 Subject: [PATCH 09/25] Require nonempty asc values Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 1 + 1 file changed, 1 insertion(+) diff --git a/schema.json b/schema.json index c5a3f57..58f8745 100644 --- a/schema.json +++ b/schema.json @@ -86,6 +86,7 @@ }, "asc": { "type": "string", + "minLength": 1, "pattern": "^-----BEGIN PGP SIGNATURE-----\\n(?:[A-Za-z0-9-]+: [^\\n]*\\n)*\\n(?:[A-Za-z0-9+/]{1,76}=*\\n)+=[A-Za-z0-9+/]{4}\\n-----END PGP SIGNATURE-----\\n?$" }, "extension": { From 2738e9577e281472b5b888bece9a4530493722e3 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:51:19 -0400 Subject: [PATCH 10/25] Require tar.gz URL suffixes Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema.json b/schema.json index 58f8745..1b00311 100644 --- a/schema.json +++ b/schema.json @@ -80,7 +80,7 @@ "pattern": "^https://" }, { - "pattern": "\\.(?:dmg|exe|gz|zip)$" + "pattern": "\\.(?:dmg|exe|tar\\.gz|zip)$" } ] }, From 626c8a978b1c78b1b003829b6fe2dd90ead4c009 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:51:25 -0400 Subject: [PATCH 11/25] Require nonempty HTTPS URL hosts Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema.json b/schema.json index 1b00311..229a281 100644 --- a/schema.json +++ b/schema.json @@ -77,7 +77,7 @@ ], "allOf": [ { - "pattern": "^https://" + "pattern": "^https://[^/?#]+/" }, { "pattern": "\\.(?:dmg|exe|tar\\.gz|zip)$" From 63117c6385438566857ef1d60d6dece3d28819f8 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:51:34 -0400 Subject: [PATCH 12/25] Reject whitespace in URLs Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/schema.json b/schema.json index 229a281..8df2407 100644 --- a/schema.json +++ b/schema.json @@ -79,6 +79,9 @@ { "pattern": "^https://[^/?#]+/" }, + { + "pattern": "^https://\\S+$" + }, { "pattern": "\\.(?:dmg|exe|tar\\.gz|zip)$" } From 020f8af90ec4957daf5309f4c781a56c91be5c08 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:51:41 -0400 Subject: [PATCH 13/25] Require URL filename basenames Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema.json b/schema.json index 8df2407..1135448 100644 --- a/schema.json +++ b/schema.json @@ -83,7 +83,7 @@ "pattern": "^https://\\S+$" }, { - "pattern": "\\.(?:dmg|exe|tar\\.gz|zip)$" + "pattern": "/[^/?#]+\\.(?:dmg|exe|tar\\.gz|zip)$" } ] }, From 4c995fcee9ccb5fe627b1822578e07b7816256f8 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:51:48 -0400 Subject: [PATCH 14/25] Update URL extension metadata for tar.gz Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema.json b/schema.json index 1135448..081d714 100644 --- a/schema.json +++ b/schema.json @@ -72,7 +72,7 @@ "qt-uri-extensions": [ ".dmg", ".exe", - ".gz", + ".tar.gz", ".zip" ], "allOf": [ From 41ba1f8178cf8cba5ecd76432fa2e051db8ceabc Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:51:58 -0400 Subject: [PATCH 15/25] Require positive file sizes Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schema.json b/schema.json index 081d714..25129e2 100644 --- a/schema.json +++ b/schema.json @@ -54,7 +54,8 @@ "pattern": "^[0-9A-Fa-f]{64}$" }, "size": { - "type": "integer" + "type": "integer", + "minimum": 1 }, "version": { "type": "string", From 56b4b599ac2b1bd33835ddedeb19379f9847d2f8 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:52:04 -0400 Subject: [PATCH 16/25] Require version entries to list files Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 1 + 1 file changed, 1 insertion(+) diff --git a/schema.json b/schema.json index 25129e2..d1dbe5f 100644 --- a/schema.json +++ b/schema.json @@ -14,6 +14,7 @@ "properties": { "files": { "type": "array", + "minItems": 1, "items": { "$ref": "#/definitions/File" } From 1beb5221b03cc3bccab722f84fb655578f923f39 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:52:13 -0400 Subject: [PATCH 17/25] Require at least one version entry Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 1 + 1 file changed, 1 insertion(+) diff --git a/schema.json b/schema.json index d1dbe5f..aa3ccb1 100644 --- a/schema.json +++ b/schema.json @@ -1,6 +1,7 @@ { "$schema": "http://json-schema.org/draft-06/schema#", "type": "object", + "minProperties": 1, "propertyNames": { "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(?:-(?:alpha[0-9]*|beta[0-9]*|rc[0-9]+|pre\\.(?:alpha|beta)))?$" }, From d908299052f3450edd2ed89ddcab8fa8019afeed Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:52:23 -0400 Subject: [PATCH 18/25] Require unique file entries Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 1 + 1 file changed, 1 insertion(+) diff --git a/schema.json b/schema.json index aa3ccb1..c313637 100644 --- a/schema.json +++ b/schema.json @@ -16,6 +16,7 @@ "files": { "type": "array", "minItems": 1, + "uniqueItems": true, "items": { "$ref": "#/definitions/File" } From a936a10aa73a59636f72e2874009737397e31441 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:52:38 -0400 Subject: [PATCH 19/25] Require extension to match URL suffix Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/schema.json b/schema.json index c313637..007f5b1 100644 --- a/schema.json +++ b/schema.json @@ -111,6 +111,52 @@ "url", "version" ], + "allOf": [ + { + "anyOf": [ + { + "properties": { + "extension": { + "const": "dmg" + }, + "url": { + "pattern": "\\.dmg$" + } + } + }, + { + "properties": { + "extension": { + "const": "exe" + }, + "url": { + "pattern": "\\.exe$" + } + } + }, + { + "properties": { + "extension": { + "const": "tar.gz" + }, + "url": { + "pattern": "\\.tar\\.gz$" + } + } + }, + { + "properties": { + "extension": { + "const": "zip" + }, + "url": { + "pattern": "\\.zip$" + } + } + } + ] + } + ], "title": "File" }, "Arch": { From 03192c20a0cdee29a9738a110fafa0f56d8c74b4 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:52:47 -0400 Subject: [PATCH 20/25] Require kind to match extension Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/schema.json b/schema.json index 007f5b1..3ad11f6 100644 --- a/schema.json +++ b/schema.json @@ -155,6 +155,34 @@ } } ] + }, + { + "anyOf": [ + { + "properties": { + "kind": { + "const": "installer" + }, + "extension": { + "const": "exe" + } + } + }, + { + "properties": { + "kind": { + "const": "archive" + }, + "extension": { + "enum": [ + "dmg", + "tar.gz", + "zip" + ] + } + } + } + ] } ], "title": "File" From 42c5e8ffef81ae0a0528654852f1921ba080b2a2 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:53:05 -0400 Subject: [PATCH 21/25] Require triplet to match OS Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/schema.json b/schema.json index 3ad11f6..141dcb9 100644 --- a/schema.json +++ b/schema.json @@ -183,6 +183,63 @@ } } ] + }, + { + "anyOf": [ + { + "properties": { + "os": { + "const": "mac" + }, + "triplet": { + "enum": [ + "x86_64-apple-darwin14", + "aarch64-apple-darwin14" + ] + } + } + }, + { + "properties": { + "os": { + "const": "winnt" + }, + "triplet": { + "enum": [ + "x86_64-w64-mingw32", + "i686-w64-mingw32" + ] + } + } + }, + { + "properties": { + "os": { + "const": "linux" + }, + "triplet": { + "enum": [ + "x86_64-linux-gnu", + "i686-linux-gnu", + "powerpc64le-linux-gnu", + "aarch64-linux-gnu", + "armv7l-linux-gnueabihf", + "x86_64-linux-musl" + ] + } + } + }, + { + "properties": { + "os": { + "const": "freebsd" + }, + "triplet": { + "const": "x86_64-unknown-freebsd11.1" + } + } + } + ] } ], "title": "File" From 6c88b05efc3984e9e2d3ca88a16503d56f742fd0 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:53:20 -0400 Subject: [PATCH 22/25] Require triplet to match architecture Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/schema.json b/schema.json index 141dcb9..83dd4da 100644 --- a/schema.json +++ b/schema.json @@ -240,6 +240,72 @@ } } ] + }, + { + "anyOf": [ + { + "properties": { + "arch": { + "const": "x86_64" + }, + "triplet": { + "enum": [ + "x86_64-apple-darwin14", + "x86_64-w64-mingw32", + "x86_64-linux-gnu", + "x86_64-unknown-freebsd11.1", + "x86_64-linux-musl" + ] + } + } + }, + { + "properties": { + "arch": { + "const": "i686" + }, + "triplet": { + "enum": [ + "i686-w64-mingw32", + "i686-linux-gnu" + ] + } + } + }, + { + "properties": { + "arch": { + "const": "powerpc64le" + }, + "triplet": { + "const": "powerpc64le-linux-gnu" + } + } + }, + { + "properties": { + "arch": { + "const": "aarch64" + }, + "triplet": { + "enum": [ + "aarch64-linux-gnu", + "aarch64-apple-darwin14" + ] + } + } + }, + { + "properties": { + "arch": { + "const": "armv7l" + }, + "triplet": { + "const": "armv7l-linux-gnueabihf" + } + } + } + ] } ], "title": "File" From 03e509ae60517a45ba394c7e4d735c4488e81a78 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:55:23 -0400 Subject: [PATCH 23/25] Require prereleases to be unstable Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/schema.json b/schema.json index 83dd4da..635afb0 100644 --- a/schema.json +++ b/schema.json @@ -5,6 +5,19 @@ "propertyNames": { "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(?:-(?:alpha[0-9]*|beta[0-9]*|rc[0-9]+|pre\\.(?:alpha|beta)))?$" }, + "allOf": [ + { + "patternProperties": { + "^[0-9]+\\.[0-9]+\\.[0-9]+-(?:alpha[0-9]*|beta[0-9]*|rc[0-9]+|pre\\.(?:alpha|beta))$": { + "properties": { + "stable": { + "const": false + } + } + } + } + } + ], "additionalProperties": { "$ref": "#/definitions/WelcomeValue" }, From 8efeb3f29ac511eefbcb0eb68d661c0f2115e6f8 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:55:32 -0400 Subject: [PATCH 24/25] Require plain releases to be stable Co-authored-by: OpenAI Codex [GPT-5] --- schema.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/schema.json b/schema.json index 635afb0..1f6c806 100644 --- a/schema.json +++ b/schema.json @@ -16,6 +16,17 @@ } } } + }, + { + "patternProperties": { + "^[0-9]+\\.[0-9]+\\.[0-9]+$": { + "properties": { + "stable": { + "const": true + } + } + } + } } ], "additionalProperties": { From c89aeb60b2e85384547e175fdc28a9b5f3332f32 Mon Sep 17 00:00:00 2001 From: DilumAluthge-LLM <267464666+DilumAluthge-LLM@users.noreply.github.com> Date: Sat, 2 May 2026 16:55:11 -0400 Subject: [PATCH 25/25] Validate current S3 versions.json against schema Co-authored-by: OpenAI Codex [GPT-5] (cherry picked from commit 3fd851977177490ab21e69284d65328cb092321f) --- .github/workflows/CI.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 8ec4392..faf66aa 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -149,5 +149,7 @@ jobs: run: rm -fv versions.json - name: Download the current versions.json from S3 run: curl -LO https://julialang-s3.julialang.org/bin/versions.json + - name: Validate versions.json against schema + run: npx -p ajv-cli@3.3.0 ajv -s schema.json -d versions.json - name: Run the post-build tests on the versions.json that we downloaded from S3 run: julia --project test/more_tests.jl versions.json