From b33f48de18c9cb6b36e402c7df1bc169b1325e5d Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Wed, 11 Nov 2026 17:34:30 +0000 Subject: [PATCH 1/9] Pin repaired local Power and Base Metals migration inputs --- docs/NATIVE12111.md | 10 ++++++++-- gradle.properties | 12 ++++++------ tools/verify-native-port.js | 11 ++++++----- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/docs/NATIVE12111.md b/docs/NATIVE12111.md index 15447d4..a74191b 100644 --- a/docs/NATIVE12111.md +++ b/docs/NATIVE12111.md @@ -46,9 +46,15 @@ for compile diagnostics only. All 88 production sources, 36 test sources and the GameTest source compile with javac and actual Eclipse ECJ; both fresh unit outputs pass all 111 tests without failures, skips or assumptions. The new Power integration input is frozen at SHA-256 -0240E032075AF6B158887FBF98CE038504942329527036B82FD7CF9EEE602503; +D8BA2501148845FFE1659569D1CB00C242C462123CB5A6B89D68FC346CABA7E9; the approved local source commit is -398439074a60bf9b8f8872f92485cffc4aa96be9. The default no-override release suite, +1f5085f1cc7adbcb1bd8cd1062601d490e5749f3. Base Metals is pinned to local hook +616d527e50e4bf0137eeb9c44fa586e34a0452a0 at SHA-256 +598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA. +These inputs repair the shared migration RETURN hooks to mutate the same NBT +in place without cancelling the other mod's callback. Earlier 0240/6D24 inputs +and their receipts are retained, not relabelled as qualification of these bytes. +The default no-override release suite, dependency/artifact/checksum audits, Javadoc, generated Eclipse metadata and actual ECJ main/test/GameTest/client scopes pass on these inputs. This is a LOCAL_SOURCE integration pin, not a merged/public 1.21.11 release. diff --git a/gradle.properties b/gradle.properties index 175a932..e6334bb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -43,17 +43,17 @@ poweradvantage_version=2.4.15.121111 poweradvantage_pin_state=LOCAL_SOURCE poweradvantage_source_repository=MinecraftModDevelopmentMods/basePower # Owner-approved stable local integration input; not a public release pin. -poweradvantage_source_ref=398439074a60bf9b8f8872f92485cffc4aa96be9 +poweradvantage_source_ref=1f5085f1cc7adbcb1bd8cd1062601d490e5749f3 poweradvantage_public_file_id= -poweradvantage_deobf_sha256=0240E032075AF6B158887FBF98CE038504942329527036B82FD7CF9EEE602503 -poweradvantage_runtime_sha256=0240E032075AF6B158887FBF98CE038504942329527036B82FD7CF9EEE602503 +poweradvantage_deobf_sha256=D8BA2501148845FFE1659569D1CB00C242C462123CB5A6B89D68FC346CABA7E9 +poweradvantage_runtime_sha256=D8BA2501148845FFE1659569D1CB00C242C462123CB5A6B89D68FC346CABA7E9 basemetals_version=3.1.2.121111 -basemetals_source_commit=e6b869ffe7d6fd6a011a99f1844d2a7995394daf +basemetals_source_commit=616d527e50e4bf0137eeb9c44fa586e34a0452a0 # Approved local migration-hook artifact, not a public release pin. basemetals_public_file_id= -basemetals_deobf_sha256=6D24D760E8E025960095DE04C51E6B79CFF93071618FC0B6BF64E05C346CC097 -basemetals_runtime_sha256=6D24D760E8E025960095DE04C51E6B79CFF93071618FC0B6BF64E05C346CC097 +basemetals_deobf_sha256=598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA +basemetals_runtime_sha256=598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA orespawn_version=4.1.0.121111 orespawn_source_commit=ecad75b24309a344f712d898d717c6a8823fc9f2 diff --git a/tools/verify-native-port.js b/tools/verify-native-port.js index 18c3e3a..b05f908 100644 --- a/tools/verify-native-port.js +++ b/tools/verify-native-port.js @@ -44,11 +44,12 @@ check('Exact Forge 61 and local port identity', () => { mod_id: 'baseelectric', mod_name: 'baseElectric', mod_version: '2.2.16.121111', poweradvantage_version: '2.4.15.121111', basemetals_version: '3.1.2.121111', poweradvantage_pin_state: 'LOCAL_SOURCE', - poweradvantage_source_ref: '398439074a60bf9b8f8872f92485cffc4aa96be9', - poweradvantage_deobf_sha256: '0240E032075AF6B158887FBF98CE038504942329527036B82FD7CF9EEE602503', - poweradvantage_runtime_sha256: '0240E032075AF6B158887FBF98CE038504942329527036B82FD7CF9EEE602503', - basemetals_source_commit: 'e6b869ffe7d6fd6a011a99f1844d2a7995394daf', - basemetals_deobf_sha256: '6D24D760E8E025960095DE04C51E6B79CFF93071618FC0B6BF64E05C346CC097', + poweradvantage_source_ref: '1f5085f1cc7adbcb1bd8cd1062601d490e5749f3', + poweradvantage_deobf_sha256: 'D8BA2501148845FFE1659569D1CB00C242C462123CB5A6B89D68FC346CABA7E9', + poweradvantage_runtime_sha256: 'D8BA2501148845FFE1659569D1CB00C242C462123CB5A6B89D68FC346CABA7E9', + basemetals_source_commit: '616d527e50e4bf0137eeb9c44fa586e34a0452a0', + basemetals_deobf_sha256: '598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA', + basemetals_runtime_sha256: '598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA', orespawn_source_commit: 'ecad75b24309a344f712d898d717c6a8823fc9f2', orespawn_deobf_sha256: 'DE39929057288CEA110196C9E9D708E129B80BC360A2E53976337FFA6A84A67B', orespawn_version: '4.1.0.121111', curseforge_project_id: '1783006', From 01735d0ad46f9aa65977fa59a6216afb099106c5 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Wed, 11 Nov 2026 17:55:21 +0000 Subject: [PATCH 2/9] Repin local Power B native registry compatibility input --- docs/NATIVE12111.md | 7 +++++-- gradle.properties | 6 +++--- tools/verify-native-port.js | 6 +++--- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/NATIVE12111.md b/docs/NATIVE12111.md index a74191b..12e5831 100644 --- a/docs/NATIVE12111.md +++ b/docs/NATIVE12111.md @@ -46,14 +46,17 @@ for compile diagnostics only. All 88 production sources, 36 test sources and the GameTest source compile with javac and actual Eclipse ECJ; both fresh unit outputs pass all 111 tests without failures, skips or assumptions. The new Power integration input is frozen at SHA-256 -D8BA2501148845FFE1659569D1CB00C242C462123CB5A6B89D68FC346CABA7E9; +71E0E84F217AA33F4F190D26A44D236461C95BE4D5A3832B5DED214B883A3AD6; the approved local source commit is -1f5085f1cc7adbcb1bd8cd1062601d490e5749f3. Base Metals is pinned to local hook +3c94944d300462badfbd88cef9f5f1dd6a51c32a. Base Metals is pinned to local hook 616d527e50e4bf0137eeb9c44fa586e34a0452a0 at SHA-256 598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA. These inputs repair the shared migration RETURN hooks to mutate the same NBT in place without cancelling the other mod's callback. Earlier 0240/6D24 inputs and their receipts are retained, not relabelled as qualification of these bytes. +The earlier D8BA/598D candidate and its receipts are also preserved. Power B +adds native vanilla registry/DFU compatibility; Electric production source is +unchanged and its manifest records this separate local Power source pin. The default no-override release suite, dependency/artifact/checksum audits, Javadoc, generated Eclipse metadata and actual ECJ main/test/GameTest/client scopes pass on these inputs. This is a diff --git a/gradle.properties b/gradle.properties index e6334bb..28180fc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -43,10 +43,10 @@ poweradvantage_version=2.4.15.121111 poweradvantage_pin_state=LOCAL_SOURCE poweradvantage_source_repository=MinecraftModDevelopmentMods/basePower # Owner-approved stable local integration input; not a public release pin. -poweradvantage_source_ref=1f5085f1cc7adbcb1bd8cd1062601d490e5749f3 +poweradvantage_source_ref=3c94944d300462badfbd88cef9f5f1dd6a51c32a poweradvantage_public_file_id= -poweradvantage_deobf_sha256=D8BA2501148845FFE1659569D1CB00C242C462123CB5A6B89D68FC346CABA7E9 -poweradvantage_runtime_sha256=D8BA2501148845FFE1659569D1CB00C242C462123CB5A6B89D68FC346CABA7E9 +poweradvantage_deobf_sha256=71E0E84F217AA33F4F190D26A44D236461C95BE4D5A3832B5DED214B883A3AD6 +poweradvantage_runtime_sha256=71E0E84F217AA33F4F190D26A44D236461C95BE4D5A3832B5DED214B883A3AD6 basemetals_version=3.1.2.121111 basemetals_source_commit=616d527e50e4bf0137eeb9c44fa586e34a0452a0 diff --git a/tools/verify-native-port.js b/tools/verify-native-port.js index b05f908..60fb97e 100644 --- a/tools/verify-native-port.js +++ b/tools/verify-native-port.js @@ -44,9 +44,9 @@ check('Exact Forge 61 and local port identity', () => { mod_id: 'baseelectric', mod_name: 'baseElectric', mod_version: '2.2.16.121111', poweradvantage_version: '2.4.15.121111', basemetals_version: '3.1.2.121111', poweradvantage_pin_state: 'LOCAL_SOURCE', - poweradvantage_source_ref: '1f5085f1cc7adbcb1bd8cd1062601d490e5749f3', - poweradvantage_deobf_sha256: 'D8BA2501148845FFE1659569D1CB00C242C462123CB5A6B89D68FC346CABA7E9', - poweradvantage_runtime_sha256: 'D8BA2501148845FFE1659569D1CB00C242C462123CB5A6B89D68FC346CABA7E9', + poweradvantage_source_ref: '3c94944d300462badfbd88cef9f5f1dd6a51c32a', + poweradvantage_deobf_sha256: '71E0E84F217AA33F4F190D26A44D236461C95BE4D5A3832B5DED214B883A3AD6', + poweradvantage_runtime_sha256: '71E0E84F217AA33F4F190D26A44D236461C95BE4D5A3832B5DED214B883A3AD6', basemetals_source_commit: '616d527e50e4bf0137eeb9c44fa586e34a0452a0', basemetals_deobf_sha256: '598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA', basemetals_runtime_sha256: '598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA', From 1149d2b006f3f0353a375af9e0b9a3100acf07d2 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Wed, 11 Nov 2026 18:45:27 +0000 Subject: [PATCH 3/9] Pin local Power C2 native item and atlas fixes --- docs/NATIVE12111.md | 12 +++++++----- gradle.properties | 6 +++--- tools/verify-native-port.js | 6 +++--- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/docs/NATIVE12111.md b/docs/NATIVE12111.md index 12e5831..4f51cd0 100644 --- a/docs/NATIVE12111.md +++ b/docs/NATIVE12111.md @@ -46,17 +46,19 @@ for compile diagnostics only. All 88 production sources, 36 test sources and the GameTest source compile with javac and actual Eclipse ECJ; both fresh unit outputs pass all 111 tests without failures, skips or assumptions. The new Power integration input is frozen at SHA-256 -71E0E84F217AA33F4F190D26A44D236461C95BE4D5A3832B5DED214B883A3AD6; +134FF55595E86D450DBFB5531F389BF0BE81FE6347F1EB03765B571A1D488B59; the approved local source commit is -3c94944d300462badfbd88cef9f5f1dd6a51c32a. Base Metals is pinned to local hook +a1cd197b4b6c3fc9c5d56da254d0f0ae9929fe8c. Base Metals is pinned to local hook 616d527e50e4bf0137eeb9c44fa586e34a0452a0 at SHA-256 598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA. These inputs repair the shared migration RETURN hooks to mutate the same NBT in place without cancelling the other mod's callback. Earlier 0240/6D24 inputs and their receipts are retained, not relabelled as qualification of these bytes. -The earlier D8BA/598D candidate and its receipts are also preserved. Power B -adds native vanilla registry/DFU compatibility; Electric production source is -unchanged and its manifest records this separate local Power source pin. +The earlier D8BA/598D and 71E0/598D candidates and their receipts are also +preserved. Power C2 adds native vanilla registry/DFU compatibility, block-item +description prefixes and partitioned atlases. Electric production source and +its BLOCKS-only atlas are unchanged; its manifest records this separate local +Power source pin. Graphical probe receipts remain separate from release gates. The default no-override release suite, dependency/artifact/checksum audits, Javadoc, generated Eclipse metadata and actual ECJ main/test/GameTest/client scopes pass on these inputs. This is a diff --git a/gradle.properties b/gradle.properties index 28180fc..217e9b2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -43,10 +43,10 @@ poweradvantage_version=2.4.15.121111 poweradvantage_pin_state=LOCAL_SOURCE poweradvantage_source_repository=MinecraftModDevelopmentMods/basePower # Owner-approved stable local integration input; not a public release pin. -poweradvantage_source_ref=3c94944d300462badfbd88cef9f5f1dd6a51c32a +poweradvantage_source_ref=a1cd197b4b6c3fc9c5d56da254d0f0ae9929fe8c poweradvantage_public_file_id= -poweradvantage_deobf_sha256=71E0E84F217AA33F4F190D26A44D236461C95BE4D5A3832B5DED214B883A3AD6 -poweradvantage_runtime_sha256=71E0E84F217AA33F4F190D26A44D236461C95BE4D5A3832B5DED214B883A3AD6 +poweradvantage_deobf_sha256=134FF55595E86D450DBFB5531F389BF0BE81FE6347F1EB03765B571A1D488B59 +poweradvantage_runtime_sha256=134FF55595E86D450DBFB5531F389BF0BE81FE6347F1EB03765B571A1D488B59 basemetals_version=3.1.2.121111 basemetals_source_commit=616d527e50e4bf0137eeb9c44fa586e34a0452a0 diff --git a/tools/verify-native-port.js b/tools/verify-native-port.js index 60fb97e..e2f5262 100644 --- a/tools/verify-native-port.js +++ b/tools/verify-native-port.js @@ -44,9 +44,9 @@ check('Exact Forge 61 and local port identity', () => { mod_id: 'baseelectric', mod_name: 'baseElectric', mod_version: '2.2.16.121111', poweradvantage_version: '2.4.15.121111', basemetals_version: '3.1.2.121111', poweradvantage_pin_state: 'LOCAL_SOURCE', - poweradvantage_source_ref: '3c94944d300462badfbd88cef9f5f1dd6a51c32a', - poweradvantage_deobf_sha256: '71E0E84F217AA33F4F190D26A44D236461C95BE4D5A3832B5DED214B883A3AD6', - poweradvantage_runtime_sha256: '71E0E84F217AA33F4F190D26A44D236461C95BE4D5A3832B5DED214B883A3AD6', + poweradvantage_source_ref: 'a1cd197b4b6c3fc9c5d56da254d0f0ae9929fe8c', + poweradvantage_deobf_sha256: '134FF55595E86D450DBFB5531F389BF0BE81FE6347F1EB03765B571A1D488B59', + poweradvantage_runtime_sha256: '134FF55595E86D450DBFB5531F389BF0BE81FE6347F1EB03765B571A1D488B59', basemetals_source_commit: '616d527e50e4bf0137eeb9c44fa586e34a0452a0', basemetals_deobf_sha256: '598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA', basemetals_runtime_sha256: '598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA', From d79fb25727593ec104da2296a6275090001f3fc0 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Wed, 11 Nov 2026 19:24:22 +0000 Subject: [PATCH 4/9] Repin local Power D biome-index compatibility input --- docs/NATIVE12111.md | 12 +++++++----- gradle.properties | 6 +++--- tools/verify-native-port.js | 6 +++--- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/docs/NATIVE12111.md b/docs/NATIVE12111.md index 4f51cd0..545d669 100644 --- a/docs/NATIVE12111.md +++ b/docs/NATIVE12111.md @@ -46,19 +46,21 @@ for compile diagnostics only. All 88 production sources, 36 test sources and the GameTest source compile with javac and actual Eclipse ECJ; both fresh unit outputs pass all 111 tests without failures, skips or assumptions. The new Power integration input is frozen at SHA-256 -134FF55595E86D450DBFB5531F389BF0BE81FE6347F1EB03765B571A1D488B59; +3EAE894F8F305676AEACF85E96A7497ACD7104CC953DD87AEB951F8567EA25DB; the approved local source commit is -a1cd197b4b6c3fc9c5d56da254d0f0ae9929fe8c. Base Metals is pinned to local hook +3eedaeb19039c0bd16437e8a7025cd20c31f2eac. Base Metals is pinned to local hook 616d527e50e4bf0137eeb9c44fa586e34a0452a0 at SHA-256 598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA. These inputs repair the shared migration RETURN hooks to mutate the same NBT in place without cancelling the other mod's callback. Earlier 0240/6D24 inputs and their receipts are retained, not relabelled as qualification of these bytes. The earlier D8BA/598D and 71E0/598D candidates and their receipts are also -preserved. Power C2 adds native vanilla registry/DFU compatibility, block-item -description prefixes and partitioned atlases. Electric production source and +preserved, as are the C2 input and its scoped receipts. Power D retains native +vanilla registry/DFU compatibility, block-item description prefixes and +partitioned atlases, and corrects biome indexes. Electric production source and its BLOCKS-only atlas are unchanged; its manifest records this separate local -Power source pin. Graphical probe receipts remain separate from release gates. +Power source pin. Graphical C2 receipts remain bound to C2, not relabelled as D +qualification. Combined/raw/endurance and manual gates remain parent-owned. The default no-override release suite, dependency/artifact/checksum audits, Javadoc, generated Eclipse metadata and actual ECJ main/test/GameTest/client scopes pass on these inputs. This is a diff --git a/gradle.properties b/gradle.properties index 217e9b2..f0e0084 100644 --- a/gradle.properties +++ b/gradle.properties @@ -43,10 +43,10 @@ poweradvantage_version=2.4.15.121111 poweradvantage_pin_state=LOCAL_SOURCE poweradvantage_source_repository=MinecraftModDevelopmentMods/basePower # Owner-approved stable local integration input; not a public release pin. -poweradvantage_source_ref=a1cd197b4b6c3fc9c5d56da254d0f0ae9929fe8c +poweradvantage_source_ref=3eedaeb19039c0bd16437e8a7025cd20c31f2eac poweradvantage_public_file_id= -poweradvantage_deobf_sha256=134FF55595E86D450DBFB5531F389BF0BE81FE6347F1EB03765B571A1D488B59 -poweradvantage_runtime_sha256=134FF55595E86D450DBFB5531F389BF0BE81FE6347F1EB03765B571A1D488B59 +poweradvantage_deobf_sha256=3EAE894F8F305676AEACF85E96A7497ACD7104CC953DD87AEB951F8567EA25DB +poweradvantage_runtime_sha256=3EAE894F8F305676AEACF85E96A7497ACD7104CC953DD87AEB951F8567EA25DB basemetals_version=3.1.2.121111 basemetals_source_commit=616d527e50e4bf0137eeb9c44fa586e34a0452a0 diff --git a/tools/verify-native-port.js b/tools/verify-native-port.js index e2f5262..707f853 100644 --- a/tools/verify-native-port.js +++ b/tools/verify-native-port.js @@ -44,9 +44,9 @@ check('Exact Forge 61 and local port identity', () => { mod_id: 'baseelectric', mod_name: 'baseElectric', mod_version: '2.2.16.121111', poweradvantage_version: '2.4.15.121111', basemetals_version: '3.1.2.121111', poweradvantage_pin_state: 'LOCAL_SOURCE', - poweradvantage_source_ref: 'a1cd197b4b6c3fc9c5d56da254d0f0ae9929fe8c', - poweradvantage_deobf_sha256: '134FF55595E86D450DBFB5531F389BF0BE81FE6347F1EB03765B571A1D488B59', - poweradvantage_runtime_sha256: '134FF55595E86D450DBFB5531F389BF0BE81FE6347F1EB03765B571A1D488B59', + poweradvantage_source_ref: '3eedaeb19039c0bd16437e8a7025cd20c31f2eac', + poweradvantage_deobf_sha256: '3EAE894F8F305676AEACF85E96A7497ACD7104CC953DD87AEB951F8567EA25DB', + poweradvantage_runtime_sha256: '3EAE894F8F305676AEACF85E96A7497ACD7104CC953DD87AEB951F8567EA25DB', basemetals_source_commit: '616d527e50e4bf0137eeb9c44fa586e34a0452a0', basemetals_deobf_sha256: '598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA', basemetals_runtime_sha256: '598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA', From bb458c2b5ff1ec90913adc00313e400dfcb5fcae Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Wed, 11 Nov 2026 20:50:03 +0000 Subject: [PATCH 5/9] Require Base Metals and pin approved local Power metadata input --- CHANGELOG.txt | 1 + README.md | 3 +- build.gradle | 14 ++-- docs/NATIVE12111.md | 65 ++++++++++++------- gradle.properties | 6 +- src/main/resources/META-INF/mods.toml | 2 +- .../NativePackRangeContractTest.java | 18 +++++ .../verification/NativePackResourceProof.java | 30 +++++++++ tools/verification/Verify-ElectricEcj.ps1 | 2 +- tools/verify-native-port.js | 10 +-- 10 files changed, 110 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 4fc7dcc..25b16d9 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -4,6 +4,7 @@ baseElectric 2.2.16.121111 (Minecraft 1.21.11 / Forge, local integration) - Preserve machine state, legacy aliases, battery charge and recipe progression. - Use native render extraction, item definitions and per-PackType Forge resources. - Reconcile with released 1.21.1 source while retaining local-only dependency pins. +- Require Base Metals 3.1.2.121111 on both client and server in Forge metadata. baseElectric 2.2.15.121011 (Minecraft 1.21.1 / Forge) diff --git a/README.md b/README.md index 18ca2a0..0d1077e 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ in the shared basePower creative tab. This local port targets Minecraft **1.21.11**, Forge **61.1.0**, official mappings with MCP **20251223.124241**, ForgeGradle **7.0.34**, Gradle **9.6.1**, and Java **21**. The version is **2.2.16.121111**. It requires basePower **2.4.15.121111**. -The coordinated dependencies are Base Metals **3.1.2.121111** and OreSpawn +Base Metals **3.1.2.121111** is also **REQUIRED** on both client and server; +Forge enforces this dependency. The coordinated OreSpawn version is **4.1.0.121111**. The migration-hook Base Metals jar is approved for local use only. This port is not published or ready for release promotion. See the [1.21.11 notes](docs/NATIVE12111.md) for compatibility and verification status. diff --git a/build.gradle b/build.gradle index 1e4b645..016231a 100644 --- a/build.gradle +++ b/build.gradle @@ -89,8 +89,8 @@ tasks.named('test', Test) { } afterSuite { descriptor, result -> if (!descriptor.parent && filter.includePatterns.empty && filter.commandLineIncludePatterns.empty - && (result.testCount != 111 || result.skippedTestCount != 0)) { - throw new GradleException("Expected 111 tests with no skips, got ${result.testCount} tests and ${result.skippedTestCount} skips") + && (result.testCount != 112 || result.skippedTestCount != 0)) { + throw new GradleException("Expected 112 tests with no skips, got ${result.testCount} tests and ${result.skippedTestCount} skips") } } doFirst { @@ -395,8 +395,8 @@ tasks.register('nativeResourceChecks', Test) { testClassesDirs = files(nativeResourceCheckClasses) classpath = testClassesDirs + nativeResourceCheckClasspath.get() + files(layout.buildDirectory.dir('classes/native-api-diagnostics')) afterSuite { descriptor, result -> - if (!descriptor.parent && (result.testCount != 22 || result.skippedTestCount != 0)) { - throw new GradleException("Expected 22 native resource tests without skips, got ${result.testCount}/${result.skippedTestCount}") + if (!descriptor.parent && (result.testCount != 23 || result.skippedTestCount != 0)) { + throw new GradleException("Expected 23 native resource tests without skips, got ${result.testCount}/${result.skippedTestCount}") } } doFirst { @@ -601,8 +601,8 @@ tasks.register('verifyReleaseConfiguration') { throw new GradleException("Source mods.toml is missing ${marker}") } } - if (!metadata.contains('modId="basemetals"\nmandatory=false')) { - throw new GradleException('Base Metals must remain Forge-optional; CurseForge installs it for players') + if (!metadata.contains('modId="basemetals"\nmandatory=true')) { + throw new GradleException('Base Metals must be required by Forge on both client and server') } } } @@ -794,7 +794,7 @@ tasks.register('verifyReleaseArtifacts') { .getText(StandardCharsets.UTF_8.name()) if (!metadata.contains('modId="baseelectric"') || !metadata.contains("version=\"${project.mod_version}\"") - || !metadata.contains('modId="basemetals"\nmandatory=false')) { + || !metadata.contains('modId="basemetals"\nmandatory=true')) { throw new GradleException('Packaged mods.toml identity or version is incorrect') } def manifest = new Manifest(zip.getInputStream(zip.getEntry('META-INF/MANIFEST.MF'))).mainAttributes diff --git a/docs/NATIVE12111.md b/docs/NATIVE12111.md index 545d669..87f667e 100644 --- a/docs/NATIVE12111.md +++ b/docs/NATIVE12111.md @@ -9,6 +9,11 @@ The port is reconciled with merged 1.21.1 head ## Compatibility +Base Metals 3.1.2.121111 is REQUIRED on both client and server. Forge metadata +declares mandatory=true, version range [3.1.2.121111,4.0.0), AFTER ordering and +BOTH sides. A runtime without Base Metals is not a supported optional profile. +The approved local migration-hook pin remains separate from public releases. + Persistent registrations, legacy Electric Advantage aliases, configuration keys, root machine NBT, battery components and recipe progression are retained. The 58 recipe files use native item and tag ingredients. All 50 discovery @@ -35,42 +40,56 @@ only Minecraft 1.21.11. The independent native resource/API checks do not require sibling mod jars. They retain the previous 17 resource checks, add two native fabricator-plan tests including root-NBT round-trips, and add three native pack range/path -checks. The independent suite expects 22 tests. The static audit retains all -106 accepted unit tests and four GameTests; the full suite now expects 111 +checks, plus a native ModInfo dependency regression with an optional-metadata +negative control. The independent suite expects 23 tests. The static audit retains all +106 accepted unit tests and four GameTests; the full suite now expects 112 unit tests without skips. A static inventory check does not establish that the full suite compiles or executes. -The local Base Metals migration hook is pinned separately from public releases. -An owner-supplied, unqualified basePower 1.21.11 jar was frozen by its SHA-256 -for compile diagnostics only. All 88 production sources, 36 test sources and -the GameTest source compile with javac and actual Eclipse ECJ; both fresh unit -outputs pass all 111 tests without failures, skips or assumptions. The new -Power integration input is frozen at SHA-256 -3EAE894F8F305676AEACF85E96A7497ACD7104CC953DD87AEB951F8567EA25DB; -the approved local source commit is -3eedaeb19039c0bd16437e8a7025cd20c31f2eac. Base Metals is pinned to local hook +The approved local Power integration source is +41959572b11dce236df98f23e97c6a3868cdda03, with player/development SHA-256 +C98D2CF163BE2480D9AFB0023BBD2D92D401AE0D50BEF73191235BF3F83774A7. +This includes the required-Base-Metals metadata correction and the native +registry/DFU, description-prefix, atlas and biome-index repairs. This is a +LOCAL_SOURCE integration pin, not a merged/public 1.21.11 release. +Base Metals is pinned to the separately approved local migration hook 616d527e50e4bf0137eeb9c44fa586e34a0452a0 at SHA-256 598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA. These inputs repair the shared migration RETURN hooks to mutate the same NBT in place without cancelling the other mod's callback. Earlier 0240/6D24 inputs and their receipts are retained, not relabelled as qualification of these bytes. The earlier D8BA/598D and 71E0/598D candidates and their receipts are also -preserved, as are the C2 input and its scoped receipts. Power D retains native -vanilla registry/DFU compatibility, block-item description prefixes and -partitioned atlases, and corrects biome indexes. Electric production source and -its BLOCKS-only atlas are unchanged; its manifest records this separate local -Power source pin. Graphical C2 receipts remain bound to C2, not relabelled as D -qualification. Combined/raw/endurance and manual gates remain parent-owned. -The default no-override release suite, -dependency/artifact/checksum audits, Javadoc, generated Eclipse metadata and -actual ECJ main/test/GameTest/client scopes pass on these inputs. This is a -LOCAL_SOURCE integration pin, not a merged/public 1.21.11 release. +preserved, as are the C2 and D inputs and their scoped receipts. The D player +jar at 6FB613EECAE677A66BF4A9BEDACD632A621CFD61BC4981CAF2F5372BB89A0240 +remains held separately. Entry-by-entry comparison confirms Electric production +classes and resources are unchanged: only mods.toml and the provenance manifest +differ from D in the new player jar. The sources jar differs only in mods.toml; +the Javadoc jar is byte-identical. Graphical C2 receipts remain bound to C2, not relabelled +as current qualification. Combined/raw/endurance and manual gates remain +parent-owned. + +The required-dependency correction's native parser and static dependency +checks are separate from the prior D release/GameTest receipts: +the optional metadata first failed the native mandatory assertion, then the +correction passed all 23 independent tests without failures or skips and all +seven static audits. Release-configuration, recipe, layout and hygiene checks +also pass. On the approved 4195957/C98D input, the default no-path-override +release suite passes with 46 forced tasks, 112 unit tests in 33 suites and the +23 independent resource tests, all without failures or skips. Dependency, +artifact, checksum, Javadoc and generated production Eclipse audits pass. +Actual Eclipse ECJ compiles all 88 main, 36 test, one GameTest and three client +sources; its fresh Java 21 JUnit output passes all 112 tests without failures, +ignored tests or assumptions. Its restricted-JDK negative control is rejected. +Player/source/Javadoc SHA-256 values are generated from actual bytes in +build/release/SHA256SUMS. OreSpawn, mod versions and publication state are +unchanged. Family qualification remains separate. Native ingredient-codec tests cover item strings, tag strings and alternative arrays, including rejection of old item/tag objects. The live recipe GameTest also decodes all 58 packaged recipe JSONs against actual runtime registries and -round-trips them through Recipe.CODEC. All four live GameTests pass. Native -test functions and test-instance resources are registered explicitly; the run +round-trips them through Recipe.CODEC. All four live GameTests passed on their +original candidates; no world/GameTest run is repeated for this metadata batch. +Native test functions and test-instance resources are registered explicitly; the run selects baseelectric:* and requires the exact four successful IDs in its report. The network oracle compares exact bytes of the current native recipe-book display packet, rather than the obsolete full-recipe synchronization path. diff --git a/gradle.properties b/gradle.properties index f0e0084..2badd19 100644 --- a/gradle.properties +++ b/gradle.properties @@ -43,10 +43,10 @@ poweradvantage_version=2.4.15.121111 poweradvantage_pin_state=LOCAL_SOURCE poweradvantage_source_repository=MinecraftModDevelopmentMods/basePower # Owner-approved stable local integration input; not a public release pin. -poweradvantage_source_ref=3eedaeb19039c0bd16437e8a7025cd20c31f2eac +poweradvantage_source_ref=41959572b11dce236df98f23e97c6a3868cdda03 poweradvantage_public_file_id= -poweradvantage_deobf_sha256=3EAE894F8F305676AEACF85E96A7497ACD7104CC953DD87AEB951F8567EA25DB -poweradvantage_runtime_sha256=3EAE894F8F305676AEACF85E96A7497ACD7104CC953DD87AEB951F8567EA25DB +poweradvantage_deobf_sha256=C98D2CF163BE2480D9AFB0023BBD2D92D401AE0D50BEF73191235BF3F83774A7 +poweradvantage_runtime_sha256=C98D2CF163BE2480D9AFB0023BBD2D92D401AE0D50BEF73191235BF3F83774A7 basemetals_version=3.1.2.121111 basemetals_source_commit=616d527e50e4bf0137eeb9c44fa586e34a0452a0 diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index e4997ac..427e222 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -37,7 +37,7 @@ side="BOTH" [[dependencies.baseelectric]] modId="basemetals" -mandatory=false +mandatory=true versionRange="[3.1.2.121111,4.0.0)" ordering="AFTER" side="BOTH" diff --git a/src/test/java/zone/moddev/mc/baseelectric/resources/NativePackRangeContractTest.java b/src/test/java/zone/moddev/mc/baseelectric/resources/NativePackRangeContractTest.java index 93b7e2b..3e40320 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/resources/NativePackRangeContractTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/resources/NativePackRangeContractTest.java @@ -12,6 +12,24 @@ import static org.junit.Assert.*; public class NativePackRangeContractTest { + @Test public void baseMetalsIsRequiredByNativeModInfoWithOptionalNegativeControl() throws Exception { + var proof = NativePackResourceProof.read(); + assertEquals("net.minecraftforge.fml.loading.moddiscovery.ModInfo", proof.get("modInfoClass").getAsString()); + var dependencies = proof.getAsJsonObject("dependencies"); + assertEquals(java.util.Set.of("forge", "minecraft", "basepower", "basemetals"), dependencies.keySet()); + var metals = dependencies.getAsJsonObject("basemetals"); + assertTrue("Forge must require Base Metals on both sides", metals.get("mandatory").getAsBoolean()); + assertEquals("[3.1.2.121111,4.0.0)", metals.get("versionRange").getAsString()); + assertEquals("AFTER", metals.get("ordering").getAsString()); + assertEquals("BOTH", metals.get("side").getAsString()); + var control = proof.getAsJsonObject("optionalBaseMetalsControl"); + assertFalse("Native ModInfo must detect optional metadata", control.getAsJsonObject("basemetals") + .get("mandatory").getAsBoolean()); + var expectedControl = dependencies.deepCopy(); + expectedControl.getAsJsonObject("basemetals").addProperty("mandatory", false); + assertEquals("Only the control dependency requirement may differ", expectedControl, control); + } + @Test public void combinedPackRangeAcceptsBothNativePackTypes() throws Exception { var proof = NativePackResourceProof.read(); assertEquals(0, proof.getAsJsonArray("warningsAndErrors").size()); diff --git a/src/test/java/zone/moddev/mc/baseelectric/verification/NativePackResourceProof.java b/src/test/java/zone/moddev/mc/baseelectric/verification/NativePackResourceProof.java index 7bada09..bef8653 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/verification/NativePackResourceProof.java +++ b/src/test/java/zone/moddev/mc/baseelectric/verification/NativePackResourceProof.java @@ -93,6 +93,17 @@ public static void main(String[] args) throws Exception { } ModFile mod = new ModFile(SecureJar.from(jar), new ForgeDevLocator(), ModFileParser::modsTomlParser); if (mod.getModFileInfo().showAsResourcePack()) throw new AssertionError("Electric must use Forge's hidden client pack"); + Path optionalJar = evidence.resolve("baseelectric-optional-basemetals-control.jar"); + String modMetadata = Files.readString(resources.resolve("META-INF/mods.toml")); + var dependency = java.util.regex.Pattern.compile("(modId=\"basemetals\"\\s+mandatory=)(true|false)") + .matcher(modMetadata); + if (!dependency.find()) throw new AssertionError("Missing Base Metals metadata for the negative control"); + try (JarOutputStream output = new JarOutputStream(Files.newOutputStream(optionalJar), manifest)) { + output.putNextEntry(new JarEntry("META-INF/mods.toml")); + output.write(dependency.replaceFirst("$1false").getBytes(StandardCharsets.UTF_8)); + output.closeEntry(); + } + ModFile optionalMod = new ModFile(SecureJar.from(optionalJar), new ForgeDevLocator(), ModFileParser::modsTomlParser); ModList.of(List.of(mod), mod.getModInfos().stream().map(ModInfo.class::cast).toList()); List diagnostics = new ArrayList<>(); AbstractAppender appender = new AbstractAppender("ElectricPackContract", null, @@ -105,6 +116,9 @@ public static void main(String[] args) throws Exception { var logger = (org.apache.logging.log4j.core.Logger)LogManager.getRootLogger(); logger.addAppender(appender); JsonObject result = new JsonObject(); + result.addProperty("modInfoClass", mod.getModInfos().getFirst().getClass().getName()); + result.add("dependencies", dependencies(mod)); + result.add("optionalBaseMetalsControl", dependencies(optionalMod)); try { for (PackType type : PackType.values()) { PackRepository repository = new PackRepository(); @@ -182,4 +196,20 @@ public static void main(String[] args) throws Exception { if (!diagnostics.isEmpty()) throw new AssertionError("Native Forge resource diagnostics: " + diagnostics); System.out.println("BASEELECTRIC_NATIVE_PACK_RESOURCES_PASS " + result); } + + private static JsonObject dependencies(ModFile mod) { + ModInfo info = ModInfo.class.cast(mod.getModInfos().stream() + .filter(entry -> entry.getModId().equals("baseelectric")).findFirst().orElseThrow()); + JsonObject result = new JsonObject(); + for (var dependency : info.getDependencies()) { + JsonObject entry = new JsonObject(); + entry.addProperty("mandatory", dependency.isMandatory()); + entry.addProperty("versionRange", dependency.getVersionRange().toString()); + entry.addProperty("ordering", dependency.getOrdering().name()); + entry.addProperty("side", dependency.getSide().name()); + if (result.has(dependency.getModId())) throw new AssertionError("Duplicate native dependency"); + result.add(dependency.getModId(), entry); + } + return result; + } } diff --git a/tools/verification/Verify-ElectricEcj.ps1 b/tools/verification/Verify-ElectricEcj.ps1 index 3cb4d03..373e928 100644 --- a/tools/verification/Verify-ElectricEcj.ps1 +++ b/tools/verification/Verify-ElectricEcj.ps1 @@ -137,7 +137,7 @@ try { $expected += [int]$inventory.testsuite.tests $report.gradleInventory += Get-Pin $xml.FullName } - if ($classes.Count -ne 33 -or $expected -ne 111 -or $sources.test.Count -ne 36 -or $sources.main.Count -ne 88) { throw 'Unexpected Electric 1.21.11 source/test inventory' } + if ($classes.Count -ne 33 -or $expected -ne 112 -or $sources.test.Count -ne 36 -or $sources.main.Count -ne 88) { throw 'Unexpected Electric 1.21.11 source/test inventory' } $main = Invoke-Ecj 'main' $sources.main $mainLibraries $test = Invoke-Ecj 'test' $sources.test (@($main) + $testLibraries) $gameTests = @(Get-ChildItem -LiteralPath (Join-Path $ProjectRoot 'src/gametest/java') -Recurse -File -Filter '*.java' | ForEach-Object { $_.FullName }) diff --git a/tools/verify-native-port.js b/tools/verify-native-port.js index 707f853..a799d70 100644 --- a/tools/verify-native-port.js +++ b/tools/verify-native-port.js @@ -44,9 +44,9 @@ check('Exact Forge 61 and local port identity', () => { mod_id: 'baseelectric', mod_name: 'baseElectric', mod_version: '2.2.16.121111', poweradvantage_version: '2.4.15.121111', basemetals_version: '3.1.2.121111', poweradvantage_pin_state: 'LOCAL_SOURCE', - poweradvantage_source_ref: '3eedaeb19039c0bd16437e8a7025cd20c31f2eac', - poweradvantage_deobf_sha256: '3EAE894F8F305676AEACF85E96A7497ACD7104CC953DD87AEB951F8567EA25DB', - poweradvantage_runtime_sha256: '3EAE894F8F305676AEACF85E96A7497ACD7104CC953DD87AEB951F8567EA25DB', + poweradvantage_source_ref: '41959572b11dce236df98f23e97c6a3868cdda03', + poweradvantage_deobf_sha256: 'C98D2CF163BE2480D9AFB0023BBD2D92D401AE0D50BEF73191235BF3F83774A7', + poweradvantage_runtime_sha256: 'C98D2CF163BE2480D9AFB0023BBD2D92D401AE0D50BEF73191235BF3F83774A7', basemetals_source_commit: '616d527e50e4bf0137eeb9c44fa586e34a0452a0', basemetals_deobf_sha256: '598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA', basemetals_runtime_sha256: '598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA', @@ -60,7 +60,7 @@ check('Exact Forge 61 and local port identity', () => { const mods = read('src/main/resources/META-INF/mods.toml').toString(); assert.match(mods, /^showAsResourcePack=false$/m); assert.match(mods, /modId="basepower"\s+mandatory=true\s+versionRange="\[2\.4\.15\.121111,3\.0\.0\)"/); - assert.match(mods, /modId="basemetals"\s+mandatory=false\s+versionRange="\[3\.1\.2\.121111,4\.0\.0\)"/); + assert.match(mods, /modId="basemetals"\s+mandatory=true\s+versionRange="\[3\.1\.2\.121111,4\.0\.0\)"/); }); function checkTrackModel(file, model) { @@ -158,7 +158,7 @@ check('All 106 accepted tests and their assertions are retained without skips', assert.equal(methods(added).length, 2); assert.doesNotMatch(added.toString(), /@Ignore|Assume\.|assumeTrue\(|assumeFalse\(/); const pack = read(javaRoot.replace('main', 'test') + 'resources/NativePackRangeContractTest.java'); - assert.equal(methods(pack).length, 3); + assert.equal(methods(pack).length, 4); assert.doesNotMatch(pack.toString(), /@Ignore|Assume\.|assumeTrue\(|assumeFalse\(/); const gameTests = javaRoot.replace('main', 'gametest') + 'gametest/ElectricGameTests.java'; const names = value => [...value.toString().matchAll(/public static void (\w+)\(GameTestHelper/g)].map(m => m[1]); From e53d4e376c3e8d03e403e648497f6cc851322cc9 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Wed, 11 Nov 2026 23:49:00 +0000 Subject: [PATCH 6/9] Prepare accepted 1.21.11 release and noninteractive resource checks --- CHANGELOG.txt | 3 + README.md | 12 +++- build.gradle | 8 +-- docs/NATIVE12111.md | 64 +++++++++++++++---- .../NativePackRangeContractTest.java | 53 +++++++++++++++ .../verification/NativePackResourceProof.java | 38 +++++++---- tools/verification/Verify-ElectricEcj.ps1 | 2 +- tools/verify-native-port.js | 2 +- 8 files changed, 151 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 25b16d9..7986186 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -5,6 +5,9 @@ baseElectric 2.2.16.121111 (Minecraft 1.21.11 / Forge, local integration) - Use native render extraction, item definitions and per-PackType Forge resources. - Reconcile with released 1.21.1 source while retaining local-only dependency pins. - Require Base Metals 3.1.2.121111 on both client and server in Forge metadata. +- Complete the combined machine, upgrade, graphical and two-world endurance checks against the current jars; keep manual acceptance and publication separate. +- Accepted for the 1.21.11 release. Publication awaits the verified released dependency pins. +- Run native resource checks without an interactive terminal while retaining strict warning and error checks. baseElectric 2.2.15.121011 (Minecraft 1.21.1 / Forge) diff --git a/README.md b/README.md index 0d1077e..673da01 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,15 @@ with MCP **20251223.124241**, ForgeGradle **7.0.34**, Gradle **9.6.1**, and Java **21**. The version is **2.2.16.121111**. It requires basePower **2.4.15.121111**. Base Metals **3.1.2.121111** is also **REQUIRED** on both client and server; Forge enforces this dependency. The coordinated OreSpawn version is -**4.1.0.121111**. The migration-hook Base Metals jar is approved for local use -only. This port is not published or ready for release promotion. +**4.1.0.121111**. The migration-hook Base Metals jar is still recorded as a +local input. This version has been accepted for release but is not yet published. See the [1.21.11 notes](docs/NATIVE12111.md) for compatibility and verification status. +The current jars pass the combined machine, upgrade, graphical and two-world +30-minute endurance checks. The full record and its manual-test limits are in +basePower's `docs/1.21.11/QUALIFICATION.md`. Those limits still apply. +Publication is waiting for the verified released dependency pins. + Back up your world and try the upgrade on a copy. Replace Electric Advantage and Power Advantage with baseElectric and basePower; do not install both sets. @@ -59,6 +64,9 @@ Local jars do not satisfy that gate. ## Verification +The current local checks pass 114 unit tests, 25 native resource tests and +114 tests from fresh Eclipse compiler output, with no failures or skips. + Run `runGameTestServer` with the same pinned mod inputs, an existing accepted EULA passed as `-PelectricGameTestEula=`, and a new directory passed as `-PelectricGameTestRunDirectory=build/port-evidence/`. The test code and diff --git a/build.gradle b/build.gradle index 016231a..19be2d0 100644 --- a/build.gradle +++ b/build.gradle @@ -89,8 +89,8 @@ tasks.named('test', Test) { } afterSuite { descriptor, result -> if (!descriptor.parent && filter.includePatterns.empty && filter.commandLineIncludePatterns.empty - && (result.testCount != 112 || result.skippedTestCount != 0)) { - throw new GradleException("Expected 112 tests with no skips, got ${result.testCount} tests and ${result.skippedTestCount} skips") + && (result.testCount != 114 || result.skippedTestCount != 0)) { + throw new GradleException("Expected 114 tests with no skips, got ${result.testCount} tests and ${result.skippedTestCount} skips") } } doFirst { @@ -395,8 +395,8 @@ tasks.register('nativeResourceChecks', Test) { testClassesDirs = files(nativeResourceCheckClasses) classpath = testClassesDirs + nativeResourceCheckClasspath.get() + files(layout.buildDirectory.dir('classes/native-api-diagnostics')) afterSuite { descriptor, result -> - if (!descriptor.parent && (result.testCount != 23 || result.skippedTestCount != 0)) { - throw new GradleException("Expected 23 native resource tests without skips, got ${result.testCount}/${result.skippedTestCount}") + if (!descriptor.parent && (result.testCount != 25 || result.skippedTestCount != 0)) { + throw new GradleException("Expected 25 native resource tests without skips, got ${result.testCount}/${result.skippedTestCount}") } } doFirst { diff --git a/docs/NATIVE12111.md b/docs/NATIVE12111.md index 87f667e..bc03b8d 100644 --- a/docs/NATIVE12111.md +++ b/docs/NATIVE12111.md @@ -9,6 +9,19 @@ The port is reconciled with merged 1.21.1 head ## Compatibility +The current 54662C9A player jar, with Power C98D, Steam F23D, Base Metals 598D +and OreSpawn DE39, has completed the supported automated family qualification. +This version is accepted for release but is not yet published. basePower's +`docs/1.21.11/QUALIFICATION.md` records the complete hashes and scope. +The current frozen jars pass 132 finite machine jobs, restart and migration +tests, chunk/network and drill lifecycle tests, recipes, generation, oils and +graphical checks. Two 30-minute worlds pass cold restart, resumed work and +independent exact stopped-save replay. All nine family artifacts reproduce +from independent builds. Electric's current 114 unit tests, 25 native resource +tests, 114 tests from fresh Eclipse compiler output and four fresh source +GameTests pass. Live turbine animation, connected-player interaction and the +other explicit manual requirements are not converted into automated passes. + Base Metals 3.1.2.121111 is REQUIRED on both client and server. Forge metadata declares mandatory=true, version range [3.1.2.121111,4.0.0), AFTER ordering and BOTH sides. A runtime without Base Metals is not a supported optional profile. @@ -41,10 +54,11 @@ The independent native resource/API checks do not require sibling mod jars. They retain the previous 17 resource checks, add two native fabricator-plan tests including root-NBT round-trips, and add three native pack range/path checks, plus a native ModInfo dependency regression with an optional-metadata -negative control. The independent suite expects 23 tests. The static audit retains all -106 accepted unit tests and four GameTests; the full suite now expects 112 -unit tests without skips. A static inventory check does not establish that -the full suite compiles or executes. +negative control. Two further checks cover a real piped TERM=dumb child and +strict diagnostic rejection. The independent suite expects 25 tests. The +static audit retains all 106 accepted unit tests and four GameTests; the full +suite now expects 114 unit tests without skips. A static inventory check does +not establish that the full suite compiles or executes. The approved local Power integration source is 41959572b11dce236df98f23e97c6a3868cdda03, with player/development SHA-256 @@ -73,17 +87,27 @@ checks are separate from the prior D release/GameTest receipts: the optional metadata first failed the native mandatory assertion, then the correction passed all 23 independent tests without failures or skips and all seven static audits. Release-configuration, recipe, layout and hygiene checks -also pass. On the approved 4195957/C98D input, the default no-path-override -release suite passes with 46 forced tasks, 112 unit tests in 33 suites and the -23 independent resource tests, all without failures or skips. Dependency, +also pass. At that metadata checkpoint, on the approved 4195957/C98D input, the +default no-path-override release suite passed with 46 forced tasks, 112 unit +tests in 33 suites and the 23 independent resource tests, all without failures +or skips. Dependency, artifact, checksum, Javadoc and generated production Eclipse audits pass. Actual Eclipse ECJ compiles all 88 main, 36 test, one GameTest and three client -sources; its fresh Java 21 JUnit output passes all 112 tests without failures, -ignored tests or assumptions. Its restricted-JDK negative control is rejected. +sources; its current fresh Java 21 JUnit output passes all 114 tests without +failures, ignored tests or assumptions. Its restricted-JDK negative control +is rejected. Player/source/Javadoc SHA-256 values are generated from actual bytes in build/release/SHA256SUMS. OreSpawn, mod versions and publication state are unchanged. Family qualification remains separate. +The current test-only terminal correction passes 114 unit tests and all 25 +independent native resource checks. The real piped child uses the official +terminalconsoleappender 1.2.0 option -Dterminal.jline=false and TERM=dumb; +its native receipt confirms interactiveTerminalDisabled=true. Strict +WARN/ERROR/FATAL validation is unchanged, with six rejecting negative controls. +No logger filtering or warning allowlist is used. The player, sources and +Javadoc jars remain byte-identical to the qualified metadata candidate. + Native ingredient-codec tests cover item strings, tag strings and alternative arrays, including rejection of old item/tag objects. The live recipe GameTest also decodes all 58 packaged recipe JSONs against actual runtime registries and @@ -98,9 +122,10 @@ network-unpacked shaped recipes cannot encode their original source JSON. Both failed observations are retained without patching frozen Forge jars. Approved source/artifact pins are recorded and cannot be overridden. The -accepted 1.21.1 jars are not valid substitutes. Full combined packaged clean-log -and client visual gates remain pending. The development GameTest log retains -initial-config and upstream Power method-annotation warnings; a successful +accepted 1.21.1 jars are not valid substitutes. Current supported combined and +graphical results are summarized above; their narrower receipt scopes remain. +The development GameTest log retains initial-config and upstream Power +method-annotation warnings; a successful GameTest run is not a clean-log or graphical qualification. Final qualification must use one stable set of hashes, including actual @@ -110,3 +135,18 @@ Generated logs and failed receipts remain local under build/port-evidence. No whole-world upgrade, family gameplay, restart, client visual acceptance, publication or release readiness is established by the independent checks. + +## Release Preparation + +Release acceptance does not change the retained automated/manual evidence +boundaries above. Released dependency source refs, hashes and public file IDs +must be verified before replacing the current local Power and Base Metals pins. +Hosted builds still reject local-only pins, and remote Maven publication remains +disabled in this checkout. These guards are not bypassed by release acceptance. +Publication uses the default-branch dispatcher and its sealed CI artifacts, +not this checkout's disabled remote Maven tasks. + +Changing the Power source ref or API pin state changes the player manifest and +therefore the whole jar hash, even if all production classes and resources stay +identical. Keep the qualified 54662C9A artifact and receipts unchanged; qualify +and checksum the newly pinned artifact separately before publication. diff --git a/src/test/java/zone/moddev/mc/baseelectric/resources/NativePackRangeContractTest.java b/src/test/java/zone/moddev/mc/baseelectric/resources/NativePackRangeContractTest.java index 3e40320..339ae89 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/resources/NativePackRangeContractTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/resources/NativePackRangeContractTest.java @@ -12,6 +12,59 @@ import static org.junit.Assert.*; public class NativePackRangeContractTest { + @Test public void pipedDumbTerminalChildUsesOfficialNonInteractiveFlag() throws Exception { + Path root = Path.of("build/native-pack-resources").toAbsolutePath(); + Files.createDirectories(root); + Path evidence = Files.createTempDirectory(root, "piped-dumb-"); + var builder = NativePackResourceProof.childProcess(evidence); + assertEquals("dumb", builder.environment().get("TERM")); + assertEquals("terminal.jline", net.minecrell.terminalconsole.TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY); + assertEquals(ProcessBuilder.Redirect.PIPE, builder.redirectInput()); + assertEquals(ProcessBuilder.Redirect.PIPE, builder.redirectOutput()); + assertTrue(builder.redirectErrorStream()); + Process child = builder.start(); + child.getOutputStream().close(); + var output = java.util.concurrent.CompletableFuture.supplyAsync(() -> { + try { + return new String(child.getInputStream().readAllBytes(), java.nio.charset.StandardCharsets.UTF_8); + } catch (java.io.IOException failure) { + throw new java.io.UncheckedIOException(failure); + } + }); + try { + assertTrue("Piped native proof timed out", child.waitFor(90, java.util.concurrent.TimeUnit.SECONDS)); + String log = output.get(10, java.util.concurrent.TimeUnit.SECONDS); + Path logPath = evidence.resolve("piped-resources.log"); + Files.writeString(logPath, log); + assertEquals(log, 0, child.exitValue()); + NativePackResourceProof.requireNoDiagnostics(logPath, log); + JsonObject proof = JsonParser.parseString(Files.readString(evidence.resolve("receipt.json"))).getAsJsonObject(); + var property = proof.get("terminalJline"); + assertEquals("Native child must disable JLine using the official property", "false", + property.isJsonNull() ? null : property.getAsString()); + assertFalse(proof.get("terminalPresent").getAsBoolean()); + assertTrue(proof.get("interactiveTerminalDisabled").getAsBoolean()); + assertEquals(0, proof.getAsJsonArray("warningsAndErrors").size()); + assertTrue(proof.getAsJsonObject("CLIENT_RESOURCES").get("resourcesVerified").getAsInt() > 0); + assertTrue(proof.getAsJsonObject("SERVER_DATA").get("resourcesVerified").getAsInt() > 0); + } finally { + if (child.isAlive()) child.destroyForcibly().waitFor(); + } + } + + @Test public void nonInteractiveModeDoesNotWhitelistAnyDiagnostic() { + Path log = Path.of("negative-control.log"); + for (String diagnostic : new String[] { + "[main/WARN] real resource warning", "[main/ERROR] real resource error", "[main/FATAL] real fatal", + "2026-11-11T00:00:00Z main WARN Advanced terminal features are not available in this environment", + "2026-11-11T00:00:00Z main ERROR real bootstrap error", "2026-11-11T00:00:00Z main FATAL fatal bootstrap" + }) { + assertThrows(diagnostic, AssertionError.class, + () -> NativePackResourceProof.requireNoDiagnostics(log, diagnostic)); + } + NativePackResourceProof.requireNoDiagnostics(log, "[main/INFO] valid resource receipt"); + } + @Test public void baseMetalsIsRequiredByNativeModInfoWithOptionalNegativeControl() throws Exception { var proof = NativePackResourceProof.read(); assertEquals("net.minecraftforge.fml.loading.moddiscovery.ModInfo", proof.get("modInfoClass").getAsString()); diff --git a/src/test/java/zone/moddev/mc/baseelectric/verification/NativePackResourceProof.java b/src/test/java/zone/moddev/mc/baseelectric/verification/NativePackResourceProof.java index bef8653..2b20da4 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/verification/NativePackResourceProof.java +++ b/src/test/java/zone/moddev/mc/baseelectric/verification/NativePackResourceProof.java @@ -48,30 +48,41 @@ public static synchronized JsonObject read() throws Exception { Path evidenceRoot = Path.of("build/native-pack-resources").toAbsolutePath(); Files.createDirectories(evidenceRoot); Path evidence = Files.createTempDirectory(evidenceRoot, "forge61-"); + Path log = evidence.resolve("forge-resources.log"); + Process process = childProcess(evidence).redirectOutput(log.toFile()).start(); + if (!process.waitFor(90, TimeUnit.SECONDS)) { + process.destroyForcibly().waitFor(); + throw new AssertionError("Native Forge resource proof timed out: " + log); + } + String output = Files.readString(log); + if (process.exitValue() != 0) throw new AssertionError("Native Forge resource proof failed: " + log + "\n" + output); + requireNoDiagnostics(log, output); + receipt = JsonParser.parseString(Files.readString(evidence.resolve("receipt.json"))).getAsJsonObject(); + return receipt.deepCopy(); + } + + public static ProcessBuilder childProcess(Path evidence) { String classpath = Arrays.stream(System.getProperty("baseelectric.nativePackClasspath", System.getProperty("java.class.path")).split(java.util.regex.Pattern.quote(java.io.File.pathSeparator))) .map(entry -> new java.io.File(entry).getAbsolutePath()) .collect(java.util.stream.Collectors.joining(java.io.File.pathSeparator)); Path javaExecutable = Path.of(System.getProperty("java.home"), "bin", "java"); if (!Files.isExecutable(javaExecutable)) javaExecutable = javaExecutable.resolveSibling("java.exe"); - Path log = evidence.resolve("forge-resources.log"); - Process process = new ProcessBuilder(javaExecutable.toString(), "-XX:ActiveProcessorCount=4", "-Xmx512m", + ProcessBuilder process = new ProcessBuilder(javaExecutable.toString(), "-XX:ActiveProcessorCount=4", "-Xmx512m", + "-Dterminal.jline=false", "--add-opens", "java.base/java.lang.invoke=ALL-UNNAMED", "-cp", classpath, NativePackResourceProof.class.getName(), Path.of("build/resources/main").toAbsolutePath().toString(), evidence.toString()).directory(evidence.toFile()) - .redirectErrorStream(true).redirectOutput(log.toFile()).start(); - if (!process.waitFor(90, TimeUnit.SECONDS)) { - process.destroyForcibly().waitFor(); - throw new AssertionError("Native Forge resource proof timed out: " + log); - } - String output = Files.readString(log); - if (process.exitValue() != 0) throw new AssertionError("Native Forge resource proof failed: " + log + "\n" + output); + .redirectErrorStream(true); + process.environment().put("TERM", "dumb"); + return process; + } + + public static void requireNoDiagnostics(Path log, String output) { if (java.util.regex.Pattern.compile("(?m)(?:\\[[^\\r\\n]*\\b(?:WARN|ERROR|FATAL)\\b[^\\r\\n]*\\]|\\bmain (?:WARN|ERROR|FATAL)\\b)") .matcher(output).find()) { throw new AssertionError("Native Forge resource diagnostic in " + log + "\n" + output); } - receipt = JsonParser.parseString(Files.readString(evidence.resolve("receipt.json"))).getAsJsonObject(); - return receipt.deepCopy(); } public static void main(String[] args) throws Exception { @@ -116,6 +127,11 @@ public static void main(String[] args) throws Exception { var logger = (org.apache.logging.log4j.core.Logger)LogManager.getRootLogger(); logger.addAppender(appender); JsonObject result = new JsonObject(); + result.addProperty("terminalJline", System.getProperty(net.minecrell.terminalconsole.TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY)); + result.addProperty("terminalPresent", net.minecrell.terminalconsole.TerminalConsoleAppender.getTerminal() != null); + result.addProperty("interactiveTerminalDisabled", "false".equals(System.getProperty( + net.minecrell.terminalconsole.TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY)) + && net.minecrell.terminalconsole.TerminalConsoleAppender.getTerminal() == null); result.addProperty("modInfoClass", mod.getModInfos().getFirst().getClass().getName()); result.add("dependencies", dependencies(mod)); result.add("optionalBaseMetalsControl", dependencies(optionalMod)); diff --git a/tools/verification/Verify-ElectricEcj.ps1 b/tools/verification/Verify-ElectricEcj.ps1 index 373e928..ac7be30 100644 --- a/tools/verification/Verify-ElectricEcj.ps1 +++ b/tools/verification/Verify-ElectricEcj.ps1 @@ -137,7 +137,7 @@ try { $expected += [int]$inventory.testsuite.tests $report.gradleInventory += Get-Pin $xml.FullName } - if ($classes.Count -ne 33 -or $expected -ne 112 -or $sources.test.Count -ne 36 -or $sources.main.Count -ne 88) { throw 'Unexpected Electric 1.21.11 source/test inventory' } + if ($classes.Count -ne 33 -or $expected -ne 114 -or $sources.test.Count -ne 36 -or $sources.main.Count -ne 88) { throw 'Unexpected Electric 1.21.11 source/test inventory' } $main = Invoke-Ecj 'main' $sources.main $mainLibraries $test = Invoke-Ecj 'test' $sources.test (@($main) + $testLibraries) $gameTests = @(Get-ChildItem -LiteralPath (Join-Path $ProjectRoot 'src/gametest/java') -Recurse -File -Filter '*.java' | ForEach-Object { $_.FullName }) diff --git a/tools/verify-native-port.js b/tools/verify-native-port.js index a799d70..4cae68c 100644 --- a/tools/verify-native-port.js +++ b/tools/verify-native-port.js @@ -158,7 +158,7 @@ check('All 106 accepted tests and their assertions are retained without skips', assert.equal(methods(added).length, 2); assert.doesNotMatch(added.toString(), /@Ignore|Assume\.|assumeTrue\(|assumeFalse\(/); const pack = read(javaRoot.replace('main', 'test') + 'resources/NativePackRangeContractTest.java'); - assert.equal(methods(pack).length, 4); + assert.equal(methods(pack).length, 6); assert.doesNotMatch(pack.toString(), /@Ignore|Assume\.|assumeTrue\(|assumeFalse\(/); const gameTests = javaRoot.replace('main', 'gametest') + 'gametest/ElectricGameTests.java'; const names = value => [...value.toString().matchAll(/public static void (\w+)\(GameTestHelper/g)].map(m => m[1]); From 019dbac083bef9e2e649756ddc5116729d76ca47 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Wed, 11 Nov 2026 23:53:53 +0000 Subject: [PATCH 7/9] Use final release wording in current Electric documentation --- CHANGELOG.txt | 5 ++--- README.md | 16 +++++++--------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 7986186..6d6f662 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,12 +1,11 @@ -baseElectric 2.2.16.121111 (Minecraft 1.21.11 / Forge, local integration) +baseElectric 2.2.16.121111 (Minecraft 1.21.11 / Forge) - Port to Forge 61.1.0 with basePower 2.4.15.121111 and Java 21. - Preserve machine state, legacy aliases, battery charge and recipe progression. - Use native render extraction, item definitions and per-PackType Forge resources. -- Reconcile with released 1.21.1 source while retaining local-only dependency pins. +- Keep the released 1.21.1 recipes, progression and world upgrade behavior. - Require Base Metals 3.1.2.121111 on both client and server in Forge metadata. - Complete the combined machine, upgrade, graphical and two-world endurance checks against the current jars; keep manual acceptance and publication separate. -- Accepted for the 1.21.11 release. Publication awaits the verified released dependency pins. - Run native resource checks without an interactive terminal while retaining strict warning and error checks. baseElectric 2.2.15.121011 (Minecraft 1.21.1 / Forge) diff --git a/README.md b/README.md index 673da01..ffb8cd1 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,12 @@ baseElectric continues DrCyano's Electric Advantage. It adds electric machines, generation, storage, automation and defence to basePower. Its equipment appears in the shared basePower creative tab. -This local port targets Minecraft **1.21.11**, Forge **61.1.0**, official mappings -with MCP **20251223.124241**, ForgeGradle **7.0.34**, Gradle **9.6.1**, and Java -**21**. The version is **2.2.16.121111**. It requires basePower **2.4.15.121111**. +baseElectric **2.2.16.121111** runs on Minecraft **1.21.11**, Forge **61.1.0**, +official mappings with MCP **20251223.124241**, ForgeGradle **7.0.34**, Gradle +**9.6.1**, and Java **21**. It requires basePower **2.4.15.121111**. Base Metals **3.1.2.121111** is also **REQUIRED** on both client and server; Forge enforces this dependency. The coordinated OreSpawn version is -**4.1.0.121111**. The migration-hook Base Metals jar is still recorded as a -local input. This version has been accepted for release but is not yet published. +**4.1.0.121111**. This version has been accepted for release but is not yet published. See the [1.21.11 notes](docs/NATIVE12111.md) for compatibility and verification status. The current jars pass the combined machine, upgrade, graphical and two-world @@ -36,10 +35,9 @@ node tools/verify-native-port.js node tools/generate-recipe-unlocks.js --check ``` -For a full local build, supply files matching the exact coordinated source -and jar pins recorded in `gradle.properties`. The target-native basePower pin -is a stable local integration input, not a public release. The sibling paths -are the defaults and these flags are optional path overrides: +For a full local build, use the exact dependency jars recorded in +`gradle.properties`. The sibling paths are the defaults and these flags are +optional path overrides: ```text -PpowerAdvantageRuntimeJar=/path/to/basePower-2.4.15.121111.jar From 7758634a94f179851bd3dd7508b607f3c28ebd35 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Thu, 12 Nov 2026 00:44:29 +0000 Subject: [PATCH 8/9] Use released dependencies for baseElectric 1.21.11 --- CHANGELOG.txt | 3 ++- README.md | 14 +++++++++----- docs/NATIVE12111.md | 36 ++++++++++++++++++++++++++++++------ gradle.properties | 14 +++++++------- tools/verify-native-port.js | 8 +++++--- 5 files changed, 53 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 6d6f662..7a0fea9 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -5,7 +5,8 @@ baseElectric 2.2.16.121111 (Minecraft 1.21.11 / Forge) - Use native render extraction, item definitions and per-PackType Forge resources. - Keep the released 1.21.1 recipes, progression and world upgrade behavior. - Require Base Metals 3.1.2.121111 on both client and server in Forge metadata. -- Complete the combined machine, upgrade, graphical and two-world endurance checks against the current jars; keep manual acceptance and publication separate. +- Use the verified public basePower and Base Metals releases. +- Retain the combined machine, upgrade, graphical and two-world endurance results under their original tested jar hashes. - Run native resource checks without an interactive terminal while retaining strict warning and error checks. baseElectric 2.2.15.121011 (Minecraft 1.21.1 / Forge) diff --git a/README.md b/README.md index ffb8cd1..b6689c0 100644 --- a/README.md +++ b/README.md @@ -6,16 +6,20 @@ in the shared basePower creative tab. baseElectric **2.2.16.121111** runs on Minecraft **1.21.11**, Forge **61.1.0**, official mappings with MCP **20251223.124241**, ForgeGradle **7.0.34**, Gradle -**9.6.1**, and Java **21**. It requires basePower **2.4.15.121111**. -Base Metals **3.1.2.121111** is also **REQUIRED** on both client and server; +**9.6.1**, and Java **21**. It requires +[basePower **2.4.15.121111**](https://www.curseforge.com/minecraft/mc-mods/basepower/files/9566998). +[Base Metals **3.1.2.121111**](https://www.curseforge.com/minecraft/mc-mods/base-metals/files/9566738) +is also **REQUIRED** on both client and server; Forge enforces this dependency. The coordinated OreSpawn version is **4.1.0.121111**. This version has been accepted for release but is not yet published. See the [1.21.11 notes](docs/NATIVE12111.md) for compatibility and verification status. -The current jars pass the combined machine, upgrade, graphical and two-world -30-minute endurance checks. The full record and its manual-test limits are in +Combined machine, upgrade, graphical and two-world 30-minute endurance checks +passed before the released dependency retarget. The full record and its manual-test limits are in basePower's `docs/1.21.11/QUALIFICATION.md`. Those limits still apply. -Publication is waiting for the verified released dependency pins. +Publication is waiting for the final combined restart/endurance checks and +baseSteam's public release. The released dependency pins are recorded in +`gradle.properties`. Back up your world and try the upgrade on a copy. Replace Electric Advantage and Power Advantage with baseElectric and basePower; do not install both sets. diff --git a/docs/NATIVE12111.md b/docs/NATIVE12111.md index bc03b8d..d00677f 100644 --- a/docs/NATIVE12111.md +++ b/docs/NATIVE12111.md @@ -9,7 +9,8 @@ The port is reconciled with merged 1.21.1 head ## Compatibility -The current 54662C9A player jar, with Power C98D, Steam F23D, Base Metals 598D +Before the released-pin retarget, the frozen 54662C9A player jar, with Power +C98D, Steam F23D, Base Metals 598D and OreSpawn DE39, has completed the supported automated family qualification. This version is accepted for release but is not yet published. basePower's `docs/1.21.11/QUALIFICATION.md` records the complete hashes and scope. @@ -60,13 +61,13 @@ static audit retains all 106 accepted unit tests and four GameTests; the full suite now expects 114 unit tests without skips. A static inventory check does not establish that the full suite compiles or executes. -The approved local Power integration source is +The qualified local Power integration source was 41959572b11dce236df98f23e97c6a3868cdda03, with player/development SHA-256 C98D2CF163BE2480D9AFB0023BBD2D92D401AE0D50BEF73191235BF3F83774A7. This includes the required-Base-Metals metadata correction and the native registry/DFU, description-prefix, atlas and biome-index repairs. This is a -LOCAL_SOURCE integration pin, not a merged/public 1.21.11 release. -Base Metals is pinned to the separately approved local migration hook +LOCAL_SOURCE integration pin at that checkpoint, not a public release pin. +Base Metals then used the separately approved local migration hook 616d527e50e4bf0137eeb9c44fa586e34a0452a0 at SHA-256 598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA. These inputs repair the shared migration RETURN hooks to mutate the same NBT @@ -139,8 +140,13 @@ publication or release readiness is established by the independent checks. ## Release Preparation Release acceptance does not change the retained automated/manual evidence -boundaries above. Released dependency source refs, hashes and public file IDs -must be verified before replacing the current local Power and Base Metals pins. +boundaries above. The current MERGED_SOURCE Power pin is the public +2.4.15.121111 release at 9b0043483d79d3e575895f12aeb0dde7ef6c4890, +[CurseForge file 9566998](https://www.curseforge.com/minecraft/mc-mods/basepower/files/9566998), +with the same C98D player/development bytes. Base Metals uses public merge +6f4c44e4d0a68bca3838fb025c09cddfaaa08fe8, +[file 9566738](https://www.curseforge.com/minecraft/mc-mods/base-metals/files/9566738), +with unchanged 598D bytes. Full SHA-256 values are in gradle.properties. Hosted builds still reject local-only pins, and remote Maven publication remains disabled in this checkout. These guards are not bypassed by release acceptance. Publication uses the default-branch dispatcher and its sealed CI artifacts, @@ -150,3 +156,21 @@ Changing the Power source ref or API pin state changes the player manifest and therefore the whole jar hash, even if all production classes and resources stay identical. Keep the qualified 54662C9A artifact and receipts unchanged; qualify and checksum the newly pinned artifact separately before publication. +Its exact hash must be handed over for a fresh presealed combined final-hash +restart/endurance campaign. Live publication requires that parent-owned gate +and baseSteam's verified public release. The 54662C9A receipts above stay bound +to their original jar and are not relabelled as new-hash runtime evidence. + +The released-pin player jar is +7128973D7A7529463E8F4328D0949F45641BD1560008A9925B09C74F9BE94F6D. +All 570 file entries match 54662C9A except META-INF/MANIFEST.MF; its only +changed attributes are API-Pin-State and basePower-Source-Ref. Sources and +Javadoc are byte-identical. The new default-path release suite passes all +46 forced tasks, 114 unit tests and 25 native resource tests. Fresh actual +Eclipse compiler output passes 114 tests, with no ignored tests or assumptions. +An independent path-with-spaces build reproduces all three jars using the +already cold-qualified native engine. A fresh packaged witness passes all +29 Electric operations, complete JVM restart and independent stopped-save +audits before and after restart, using Electric 7128973D, Power C98D, Steam +F23D, Base Metals 598D and OreSpawn DE39. This does not replace the parent's +separate final-family restart/endurance and replay publication gate. diff --git a/gradle.properties b/gradle.properties index 2badd19..79bd931 100644 --- a/gradle.properties +++ b/gradle.properties @@ -40,18 +40,18 @@ cf_optionals= cf_versions=1.21.11 poweradvantage_version=2.4.15.121111 -poweradvantage_pin_state=LOCAL_SOURCE +poweradvantage_pin_state=MERGED_SOURCE poweradvantage_source_repository=MinecraftModDevelopmentMods/basePower -# Owner-approved stable local integration input; not a public release pin. -poweradvantage_source_ref=41959572b11dce236df98f23e97c6a3868cdda03 -poweradvantage_public_file_id= +# Verified public basePower release; the ordinary native jar is also the dev jar. +poweradvantage_source_ref=9b0043483d79d3e575895f12aeb0dde7ef6c4890 +poweradvantage_public_file_id=9566998 poweradvantage_deobf_sha256=C98D2CF163BE2480D9AFB0023BBD2D92D401AE0D50BEF73191235BF3F83774A7 poweradvantage_runtime_sha256=C98D2CF163BE2480D9AFB0023BBD2D92D401AE0D50BEF73191235BF3F83774A7 basemetals_version=3.1.2.121111 -basemetals_source_commit=616d527e50e4bf0137eeb9c44fa586e34a0452a0 -# Approved local migration-hook artifact, not a public release pin. -basemetals_public_file_id= +basemetals_source_commit=6f4c44e4d0a68bca3838fb025c09cddfaaa08fe8 +# Verified public release includes the shared non-cancelling migration hook. +basemetals_public_file_id=9566738 basemetals_deobf_sha256=598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA basemetals_runtime_sha256=598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA diff --git a/tools/verify-native-port.js b/tools/verify-native-port.js index 4cae68c..afc44b2 100644 --- a/tools/verify-native-port.js +++ b/tools/verify-native-port.js @@ -43,11 +43,13 @@ check('Exact Forge 61 and local port identity', () => { mapping_version: '1.21.11', mcp_version: '20251223.124241', java_version: '21', mod_id: 'baseelectric', mod_name: 'baseElectric', mod_version: '2.2.16.121111', poweradvantage_version: '2.4.15.121111', basemetals_version: '3.1.2.121111', - poweradvantage_pin_state: 'LOCAL_SOURCE', - poweradvantage_source_ref: '41959572b11dce236df98f23e97c6a3868cdda03', + poweradvantage_pin_state: 'MERGED_SOURCE', + poweradvantage_source_ref: '9b0043483d79d3e575895f12aeb0dde7ef6c4890', + poweradvantage_public_file_id: '9566998', poweradvantage_deobf_sha256: 'C98D2CF163BE2480D9AFB0023BBD2D92D401AE0D50BEF73191235BF3F83774A7', poweradvantage_runtime_sha256: 'C98D2CF163BE2480D9AFB0023BBD2D92D401AE0D50BEF73191235BF3F83774A7', - basemetals_source_commit: '616d527e50e4bf0137eeb9c44fa586e34a0452a0', + basemetals_source_commit: '6f4c44e4d0a68bca3838fb025c09cddfaaa08fe8', + basemetals_public_file_id: '9566738', basemetals_deobf_sha256: '598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA', basemetals_runtime_sha256: '598D3FB0FF956EBCC67FE477A01CE393C75D0013AF0CE00A79E2072B63E9F2BA', orespawn_source_commit: 'ecad75b24309a344f712d898d717c6a8823fc9f2', From 41227bf370781c1eb3b09e8099878c820529f1f4 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Thu, 12 Nov 2026 00:59:59 +0000 Subject: [PATCH 9/9] Make generated API documentation portable across platforms --- build.gradle | 38 +++++++++++++++++++++++++++++++++++++ docs/NATIVE12111.md | 13 ++++++++++++- tools/verify-native-port.js | 5 +++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 19be2d0..9483094 100644 --- a/build.gradle +++ b/build.gradle @@ -500,10 +500,33 @@ tasks.named('sourcesJar', Jar) { } } +def javadocLegalNames = ['LICENSE', 'ADDITIONAL_LICENSE_INFO', 'ASSEMBLY_EXCEPTION'] +tasks.named('javadoc', Javadoc) { + inputs.files(javadocTool.map { tool -> + javadocLegalNames.collect { tool.metadata.installationPath.file("legal/java.base/${it}").asFile } + }) + doLast { + File legalRoot = javadocTool.get().metadata.installationPath.dir('legal/java.base').asFile + javadocLegalNames.each { name -> + if (!new File(legalRoot, name).isFile()) { + throw new GradleException("Selected JDK is missing legal/java.base/${name}") + } + } + // Windows JDK module notices point outside the generated documentation. + project.copy { + from legalRoot + include javadocLegalNames + into new File(destinationDir, 'legal') + filesMatching(javadocLegalNames, normalizeArchiveLineEndings) + } + } +} + tasks.named('javadocJar', Jar) { filteringCharset = 'UTF-8' archiveClassifier = 'javadoc' filesMatching(archiveTextPatterns, normalizeArchiveLineEndings) + filesMatching('**/*.svg', normalizeArchiveLineEndings) manifest { attributes([ 'Maven-Artifact' : "${project.group}:${base.archivesName.get()}:${project.version}:javadoc", @@ -832,6 +855,21 @@ tasks.register('verifyReleaseArtifacts') { if (javadocZip.getEntry('index.html') == null) { throw new GradleException('Javadoc jar is missing index.html') } + ['copy.svg', 'link.svg'].each { name -> + def entry = javadocZip.getEntry(name) + if (entry == null || javadocZip.getInputStream(entry).getText('UTF-8').contains('\r')) { + throw new GradleException("Javadoc resource ${name} must use canonical LF line endings") + } + } + File legalRoot = tasks.named('javadoc', Javadoc).get().javadocTool.get() + .metadata.installationPath.dir('legal/java.base').asFile + javadocLegalNames.each { name -> + def entry = javadocZip.getEntry("legal/${name}") + String expectedLegal = new File(legalRoot, name).getText('UTF-8').replace('\r\n', '\n') + if (entry == null || javadocZip.getInputStream(entry).getText('UTF-8') != expectedLegal) { + throw new GradleException("Javadoc legal/${name} must contain the selected JDK's full canonical legal text") + } + } } } } diff --git a/docs/NATIVE12111.md b/docs/NATIVE12111.md index d00677f..58c8d8d 100644 --- a/docs/NATIVE12111.md +++ b/docs/NATIVE12111.md @@ -165,7 +165,7 @@ The released-pin player jar is 7128973D7A7529463E8F4328D0949F45641BD1560008A9925B09C74F9BE94F6D. All 570 file entries match 54662C9A except META-INF/MANIFEST.MF; its only changed attributes are API-Pin-State and basePower-Source-Ref. Sources and -Javadoc are byte-identical. The new default-path release suite passes all +Javadoc were byte-identical at the initial retarget. The new default-path release suite passes all 46 forced tasks, 114 unit tests and 25 native resource tests. Fresh actual Eclipse compiler output passes 114 tests, with no ignored tests or assumptions. An independent path-with-spaces build reproduces all three jars using the @@ -174,3 +174,14 @@ already cold-qualified native engine. A fresh packaged witness passes all audits before and after restart, using Electric 7128973D, Power C98D, Steam F23D, Base Metals 598D and OreSpawn DE39. This does not replace the parent's separate final-family restart/endurance and replay publication gate. + +The first hosted comparison exposed five JDK-generated Javadoc differences: +Windows SVG line endings and legal forwarding notices versus Linux's full +license texts. Javadoc now copies the complete legal texts from the selected +JDK's java.base module and normalizes those files and the generated SVGs to LF. +The release audit rejects noncanonical SVGs and incomplete or different legal +texts. This packaging correction affects only the Javadoc artifact, not the +player or sources. The earlier local 207BD6FE Javadoc remains preserved under +its original receipt; it is not relabelled as the cross-platform artifact. +The corrected Windows Javadoc matches the hosted Linux jar byte-for-byte: +7633A1BFCC86BE22F2814E5E6387289F722F67C484034CDDF366258A15D70845. diff --git a/tools/verify-native-port.js b/tools/verify-native-port.js index afc44b2..fb49ac0 100644 --- a/tools/verify-native-port.js +++ b/tools/verify-native-port.js @@ -63,6 +63,11 @@ check('Exact Forge 61 and local port identity', () => { assert.match(mods, /^showAsResourcePack=false$/m); assert.match(mods, /modId="basepower"\s+mandatory=true\s+versionRange="\[2\.4\.15\.121111,3\.0\.0\)"/); assert.match(mods, /modId="basemetals"\s+mandatory=true\s+versionRange="\[3\.1\.2\.121111,4\.0\.0\)"/); + const build = read('build.gradle').toString(); + assert.match(build, /inputs\.files\(javadocTool\.map/); + assert.match(build, /legal\/java\.base/); + assert.match(build, /filesMatching\('\*\*\/\*\.svg', normalizeArchiveLineEndings\)/); + assert.match(build, /must contain the selected JDK's full canonical legal text/); }); function checkTrackModel(file, model) {