Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
af5ab0a
docs(openspec): finalize the published site
DamianReeves Oct 28, 2026
ef91231
feat(extension): add bounded process framing
DamianReeves Oct 28, 2026
77385ae
feat(binding): adapt bounded JSON model envelopes
DamianReeves Oct 28, 2026
22c7a83
feat(extension): serve standalone MEP sessions
DamianReeves Oct 28, 2026
0df6584
fix(binding): enforce portable model admission
DamianReeves Oct 28, 2026
30a216a
build(extension): stage canonical process bundles
DamianReeves Oct 28, 2026
6d8f291
test(extension): verify isolated process sessions
DamianReeves Oct 28, 2026
6945b7f
ci(extension): qualify portable process artifacts
DamianReeves Oct 28, 2026
5962a58
build(extension): verify complete process candidates
DamianReeves Oct 28, 2026
b2c6dfa
fix(release): isolate mismatched install metadata
DamianReeves Oct 28, 2026
b38e00e
chore: merge finalized documentation specs
DamianReeves Oct 28, 2026
820c9d0
fix(extension): enforce installed runtime integrity
DamianReeves Oct 28, 2026
981d182
test(extension): qualify Rust host runtimes
DamianReeves Oct 28, 2026
dfdca79
test(extension): require platform diagnostic parity
DamianReeves Oct 28, 2026
8a9f051
build(extension): seal process download archives
DamianReeves Oct 28, 2026
fb77200
feat(extension)!: support model MEP sessions
DamianReeves Oct 28, 2026
b3f55b1
build(extension): pin merged Python MCK profile
DamianReeves Oct 28, 2026
f5cf244
ci(extension): gate dual-runtime releases with MCK
DamianReeves Oct 28, 2026
15c4453
fix(release): preserve declaration bytes on Windows
DamianReeves Oct 28, 2026
faf66f9
build(mck): bound checker build disk usage
DamianReeves Oct 28, 2026
63ba6ce
fix(mck): decode reports independently of locale
DamianReeves Oct 28, 2026
27bbf5e
fix(mck): expose failed checker build diagnostics
DamianReeves Oct 28, 2026
0af5339
fix(mck): shorten Windows dependency checkout paths
DamianReeves Oct 28, 2026
4520858
ci(mck): inspect Windows build checkout changes
DamianReeves Oct 28, 2026
e338a68
fix(ci): inspect checker source directories directly
DamianReeves Oct 28, 2026
bce5d85
fix(mck): configure submodule path handling
DamianReeves Oct 28, 2026
d16b917
docs(mep): record qualified dual-runtime delivery
DamianReeves Oct 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .config/mise/tasks/rust/consumer
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ trap 'rm -rf "$(dirname "$consumer")"' EXIT
cargo new --quiet "$consumer"
cat >>"$consumer/Cargo.toml" <<TOML
morphir-python-binding = { git = "file://$repository", rev = "$revision" }
morphir-extension-sdk = "=0.3.0"
morphir-extension-sdk = "=0.4.0"
serde_json = "1"
TOML
# The README example is the consumer's main program.
Expand Down
11 changes: 11 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@

# Use bd merge for beads JSONL files
.beads/issues.jsonl merge=beads

# Release receipts bind these inputs as bytes on every runner OS.
rust/Cargo.lock text eol=lf
rust/extension.toml text eol=lf
scripts/*.py text eol=lf
.github/scripts/*.ps1 text eol=lf
tools/extension-qualification/Cargo.lock text eol=lf
tools/extension-qualification/Cargo.toml text eol=lf
tools/extension-qualification/*.rs text eol=lf
tools/extension-qualification/src/*.rs text eol=lf
tools/extension-qualification/src/bin/*.rs text eol=lf
45 changes: 45 additions & 0 deletions .github/scripts/check_process_windows.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
param(
[Parameter(Mandatory = $true)][string]$Executable,
[Parameter(Mandatory = $true)][string]$Report
)
$ErrorActionPreference = "Stop"
$processBinary = (Resolve-Path -LiteralPath $Executable).Path
$vsWhere = Join-Path ${env:ProgramFiles(x86)} "Microsoft Visual Studio\Installer\vswhere.exe"
$toolCandidates = @(& $vsWhere -latest -products "*" -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -find "VC\Tools\MSVC\**\bin\Hostx64\x64\dumpbin.exe")
$toolLocation = $toolCandidates | Select-Object -First 1
if ($LASTEXITCODE -ne 0 -or !$toolLocation) {
throw "Cannot locate the MSVC dependency inspector"
}
$dependencyOutput = & $toolLocation /DEPENDENTS $processBinary
if ($LASTEXITCODE -ne 0) {
throw "MSVC dependency inspection failed"
}
$dependencies = @(
[regex]::Matches(($dependencyOutput -join "`n"), '(?i)\b[A-Za-z0-9_.-]+\.dll\b') |
ForEach-Object { $_.Value.ToLowerInvariant() } |
Sort-Object -Unique
)
if ($dependencies.Count -eq 0) {
throw "Dependency inspection returned no Windows system DLLs"
}
if ($dependencies -match '^(vcruntime|msvcp|concrt|python)\d') {
throw "Standalone process imports an external VC or Python runtime: $($dependencies -join ', ')"
}
$receipt = @{
sourceCommit = $env:GITHUB_SHA
crt = "static"
artifact = @{
sha256 = (Get-FileHash -LiteralPath $processBinary -Algorithm SHA256).Hash.ToLowerInvariant()
}
checkerSha256 = (Get-FileHash -LiteralPath $PSCommandPath -Algorithm SHA256).Hash.ToLowerInvariant()
tool = @{
name = "dumpbin.exe"
sha256 = (Get-FileHash -LiteralPath $toolLocation -Algorithm SHA256).Hash.ToLowerInvariant()
version = (Get-Item -LiteralPath $toolLocation).VersionInfo.FileVersion
}
dependencies = $dependencies
}
$reportFile = [System.IO.Path]::GetFullPath($Report)
[System.IO.Directory]::CreateDirectory([System.IO.Path]::GetDirectoryName($reportFile)) | Out-Null
[System.IO.File]::WriteAllText($reportFile, ($receipt | ConvertTo-Json -Depth 5) + "`n", [System.Text.UTF8Encoding]::new($false))
$receipt | ConvertTo-Json -Depth 5
94 changes: 94 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ on:
description: Package-specific tag that must match its project version
type: string
default: ''
qualify-mep:
description: Run the source-pinned canonical MCK before release promotion
type: boolean
default: false

permissions:
contents: read
Expand Down Expand Up @@ -104,12 +108,21 @@ jobs:

- name: Build the manylinux_2_28 wheel and source archive
uses: PyO3/maturin-action@v1
env:
# Maturin builds the wheel from an isolated sdist. Share registry
# dependency objects with the process hook across that source path.
CARGO_TARGET_DIR: ${{ github.workspace }}/rust/target
with:
working-directory: packages/morphir-python-native
maturin-version: '1.15.0'
rust-toolchain: '1.98.1'
manylinux: '2_28'
target: x86_64-unknown-linux-gnu
# Build the standalone guest in the same glibc 2.28 container. Its
# shared compiler objects are then reused by the Python wheel build.
before-script-linux: >-
cargo build --manifest-path ../../rust/Cargo.toml --locked --release
-p morphir-python-extension --target x86_64-unknown-linux-gnu
args: --release --locked --sdist --out ../../dist/native

- name: Audit the Linux baseline and bundled libraries
Expand All @@ -130,6 +143,13 @@ jobs:
path: dist/native/
if-no-files-found: error

- name: Upload the process executable from the portable build
uses: actions/upload-artifact@v6
with:
name: process-linux-x86_64
path: rust/target/x86_64-unknown-linux-gnu/release/morphir-python-extension
if-no-files-found: error

test:
name: Test
needs: [changes, native-wheel]
Expand Down Expand Up @@ -218,9 +238,83 @@ jobs:
run: |
MORPHIR_NATIVE_WHEEL="$(ls dist/native/*.whl)" mise run install

- name: Download the portable process executable
uses: actions/download-artifact@v7
with:
name: process-linux-x86_64
path: dist/process/

- name: Package and qualify the bundle offline
run: mise run extension:bundle

- name: Package and qualify the process guest offline
run: |
mkdir -p .morphir/build/extensions .dev/qualification
uv run --no-sync python -m scripts.process_extension \
--executable dist/process/morphir-python-extension \
--output .morphir/build/extensions/python-process \
--commit "$GITHUB_SHA" \
--report .dev/qualification/process-x86_64-unknown-linux-gnu.json \
--host-check

# Full executable conformance belongs to candidate qualification. The
# normal PR path already covers model negotiation and framing in Rust.
- name: Cache the source-pinned canonical MCK build
if: inputs.qualify-mep || github.event_name == 'workflow_dispatch'
uses: actions/cache@v5
with:
path: .dev/mep-tool/
key: mep-${{ runner.os }}-${{ runner.arch }}-rust-1.98.1-${{ hashFiles('rust/extension.toml', 'scripts/mep_tool.py') }}
restore-keys: mep-${{ runner.os }}-${{ runner.arch }}-rust-1.98.1-

- name: Cache the independent WASM adapter build
if: inputs.qualify-mep || github.event_name == 'workflow_dispatch'
uses: Swatinem/rust-cache@v2
with:
workspaces: tools/extension-qualification -> ../../.dev/host-qualification-target

- name: Prepare the shared checker and transparent WASM adapter
if: inputs.qualify-mep || github.event_name == 'workflow_dispatch'
env:
CARGO_TARGET_DIR: ${{ github.workspace }}/.dev/host-qualification-target
run: |
python -m scripts.mep_tool --output .dev/qualification/mep-tool.json
cargo build --locked --release --manifest-path tools/extension-qualification/Cargo.toml --bin mep_wasm_host

- name: Run and independently recheck canonical MEP reports
if: inputs.qualify-mep || github.event_name == 'workflow_dispatch'
run: |
python -m scripts.qualify_mep \
--bundle .morphir/build/extensions/python-process --runtime process \
--tool .dev/qualification/mep-tool.json --commit "$GITHUB_SHA" \
--report .dev/qualification/mep-x86_64-unknown-linux-gnu-report.json \
--receipt .dev/qualification/mep-x86_64-unknown-linux-gnu-recheck.json
python -m scripts.qualify_mep \
--bundle .morphir/build/extensions/python --runtime wasm \
--tool .dev/qualification/mep-tool.json --commit "$GITHUB_SHA" \
--adapter .dev/host-qualification-target/release/mep_wasm_host \
--report .dev/qualification/bundle-mep-report.json \
--receipt .dev/qualification/bundle-mep-recheck.json

- name: Retain failed checker build diagnostics
if: failure() && hashFiles('.dev/mep-tool/*/build.log') != ''
uses: actions/upload-artifact@v6
with:
name: mep-build-log-linux-x86_64
path: .dev/mep-tool/*/build.log
include-hidden-files: true

- name: Upload the qualified process bundle and receipt
uses: actions/upload-artifact@v6
with:
name: morphir-python-process-x86_64-unknown-linux-gnu
path: |
.morphir/build/extensions/python-process/
.dev/qualification/process-x86_64-unknown-linux-gnu.json
.dev/qualification/mep-x86_64-unknown-linux-gnu-*.json
include-hidden-files: true
if-no-files-found: error

- name: Upload the extension bundle
uses: actions/upload-artifact@v6
with:
Expand Down
Loading
Loading