Skip to content

docs(m3h): finalize verified mainline, public installer and exact-tag Linux evidence #7

docs(m3h): finalize verified mainline, public installer and exact-tag Linux evidence

docs(m3h): finalize verified mainline, public installer and exact-tag Linux evidence #7

name: M3.H Stable Release and Main Provenance Guard (Read Only)
on:
push:
branches: [main]
paths:
- '.github/workflows/m3h-source-main-reconciliation.yml'
pull_request:
branches: [main]
paths:
- '.github/workflows/m3h-source-main-reconciliation.yml'
- 'docs/integration/M3H_MAINLINE_RELEASE_SOURCE_CLOSURE_2026-10-24.md'
workflow_dispatch:
permissions:
contents: read
jobs:
verify-immutable-m3h:
if: github.repository == 'masarray/arstack61850'
runs-on: ubuntu-latest
timeout-minutes: 8
env:
GH_TOKEN: ${{ github.token }}
VERIFIED_SOURCE_SHA: a922e9bdba4e57a4e88406eb83344455dd8ff142
RELEASE_TAG: processbus-sim-m3h-20261024
TAG_COMMIT: a4b6e53d0dbbcababc55ba8a4ff97ade6f2a6200
steps:
- name: Checkout full history with release tag (no mutable writes)
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Confirm tested source and official release tag both are in mainline ancestry
shell: bash
run: |
set -euo pipefail
git fetch --force --tags origin
test "$(git rev-parse "$RELEASE_TAG^{commit}")" = "$TAG_COMMIT"
git merge-base --is-ancestor "$VERIFIED_SOURCE_SHA" HEAD
git merge-base --is-ancestor "$TAG_COMMIT" HEAD
echo "PASS: immutable source and official tag are ancestors of this mainline candidate."
- name: Confirm immutable release tag contains exact accepted firmware/Studio implementation
shell: bash
run: |
set -euo pipefail
python3 - <<'PY'
import subprocess
source = 'a922e9bdba4e57a4e88406eb83344455dd8ff142'
protected = ('CMakeLists.txt','apps/arstack_studio/','embedded/esp32p4_smv_injector/',
'include/','src/','tests/','scripts/','tools/')
readme_exceptions = {'apps/arstack_studio/README.md','embedded/esp32p4_smv_injector/README.md'}
tag = 'a4b6e53d0dbbcababc55ba8a4ff97ade6f2a6200'
changed = subprocess.check_output(['git','diff','--name-only',source,tag],text=True).splitlines()
drift = [p for p in changed if (p == 'CMakeLists.txt' or
any(p.startswith(prefix) for prefix in protected if prefix.endswith('/')))
and p not in readme_exceptions]
if drift:
raise SystemExit('M3.H tagged release rejected: changes to tested runtime source: '+repr(drift))
print('PASS: tagged release firmware, Studio, runtime, tests and build code match shipped tested source. Future mainline development remains allowed.')
PY
- name: Query GitHub release metadata and immutable asset identities (read only)
shell: bash
run: |
set -euo pipefail
gh api "repos/$GITHUB_REPOSITORY/releases/tags/$RELEASE_TAG" > release.json
python3 - <<'PY'
import json
from pathlib import Path
release=json.loads(Path('release.json').read_text())
assert release['id']==422544367
assert release['tag_name']=='processbus-sim-m3h-20261024'
assert release['target_commitish']=='a4b6e53d0dbbcababc55ba8a4ff97ade6f2a6200'
assert release['draft'] is False and release['prerelease'] is False
expected={
'ARStack-ProcessBus-M3H-win-x64-setup.exe': (671406892,31059935,'4902e8bf44e78fc55a139ce84a1273f0768ef6fe10000f5d0f85d75d2f6c736e'),
'ARStack-ProcessBus-M3H-win-x64-portable.zip': (671406890,48335087,'ca01424e4102aa65e353737024ebf3258b4d2f614fa60d932c95c353ee228d8f'),
'ARStack-ESP32P4-ProcessBus-M3H-firmware.bin': (671406887,542096,'61c508e9bf1357eb964d2b817b260b6a0e985446ddd68de1d45d9467e25c4607'),
'firmware-manifest.json': (671406893,942,'b2878148a1cda30f11a4c93a200bcba07bb63548aa571de8d05260c2ef630f9a'),
'SHA256SUMS.txt': (671406889,416,'c7674d1a97b77b66adda12216f7d5e460f86da5cb07fd1d1f02bf3011b99c876'),
}
actual={a['name']:(a['id'],a['size'],a['digest'].removeprefix('sha256:')) for a in release['assets']}
assert actual==expected, 'M3.H immutable GitHub assets changed'
print('PASS: Existing Public Stable release, original five asset IDs, sizes and SHA-256 verified.')
PY