Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
0fbff84
chore: add baseline scaffolding and ignore generated artifacts
fraware Jul 25, 2026
1b4dfce
docs: capture MRR-ITE-00 architecture baseline
fraware Jul 25, 2026
647f3ba
feat: add ExecutionProfile JSON Schema
fraware Jul 25, 2026
5e15c8a
feat: add ExecutionProfile load and validate module
fraware Jul 25, 2026
52d4231
feat: add provider abstraction and local fake backend
fraware Jul 25, 2026
e710aab
feat: add Morph Cloud provider adapter
fraware Jul 25, 2026
fcb92ce
feat: add hermeticity mode enforcement helpers
fraware Jul 25, 2026
6f68bbe
feat: add branch replay manifest schema
fraware Jul 25, 2026
0705380
feat: add branch manifest loader and scheduler
fraware Jul 25, 2026
be84709
feat: add resource report JSON Schema
fraware Jul 25, 2026
28dcfda
feat: add resource accounting report builder
fraware Jul 25, 2026
c5e6eac
feat: add differential report JSON Schema
fraware Jul 25, 2026
89fb2b3
feat: add differential report generation
fraware Jul 25, 2026
855078c
feat: vendor PCS evidence schemas and mirror metadata
fraware Jul 25, 2026
fa411dc
feat: emit and validate PCS evidence artifacts
fraware Jul 25, 2026
a5a7db0
feat: vendor PIP lineage and morph report schemas
fraware Jul 25, 2026
43de0d7
feat: add PIP morph and lineage emitters with fixtures
fraware Jul 25, 2026
132bbe1
feat: add content hashing helpers for digests
fraware Jul 25, 2026
2e8e78c
feat: add OVK package namespace stub
fraware Jul 25, 2026
fb562a0
feat: wire CLI and core around hermetic branch-N flow
fraware Jul 25, 2026
4241e7a
test: add unit coverage for profile providers and reports
fraware Jul 25, 2026
7c31259
test: add hermetic mode and branch scheduler suites
fraware Jul 25, 2026
1cb0dfc
test: add adversarial conformance and offline integration gates
fraware Jul 25, 2026
9eefd99
ci: add offline CI workflow and slim replay job
fraware Jul 25, 2026
dcfd0f4
docs: refresh README security posture and contribution guides
fraware Jul 25, 2026
f916005
docs: add MRR-ITE ADRs 01 through 09
fraware Jul 25, 2026
10d5de6
docs: document schema layout and fixture catalog
fraware Jul 25, 2026
739795b
docs: add hermetic-branch-n end-to-end example pack
fraware Jul 25, 2026
8623ed2
chore: add schema mirror and instance validators
fraware Jul 25, 2026
4a0df9a
chore: add fixture generator and release bundle script
fraware Jul 25, 2026
2a834d7
chore: update Docker image for hermetic runner layout
fraware Jul 25, 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
71 changes: 71 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Offline CI

on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
workflow_dispatch:

jobs:
offline:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install package and dev tools
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Format check (black)
run: black --check runner tests scripts
- name: Import sort check (isort)
run: isort --check-only runner tests scripts
- name: Lint (ruff, warnings as errors)
run: ruff check runner tests scripts
- name: Typecheck (mypy strict)
run: mypy runner
- name: Schema mirror digest check
run: python scripts/check_schema_mirrors.py
- name: Vendored schema instance validation
run: python scripts/validate_vendored_instances.py
- name: Unit / hermetic / adversarial / conformance
run: pytest tests -q --tb=short
- name: Optional external CLI gates (skip-only-when-absent)
run: python scripts/optional_external_validate.py
- name: Dependency audit (strict)
run: pip-audit --strict

morph-opt-in:
if: ${{ secrets.MORPH_API_KEY != '' }}
runs-on: ubuntu-latest
needs: offline
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Morph smoke (opt-in)
env:
MORPH_API_KEY: ${{ secrets.MORPH_API_KEY }}
run: |
mkdir -p replays
echo '{"type":"file","path":"/tmp/test.txt"}' > replays/demo-file.json
zip -j replays/demo-file.zip replays/demo-file.json
replay-runner run \
--snapshot morphvm-minimal \
--bundles "replays/demo-file.zip" \
--parallel 1 \
--timeout 300 \
--provider morph \
--out ./evidence-morph
147 changes: 6 additions & 141 deletions .github/workflows/replay.yml
Original file line number Diff line number Diff line change
@@ -1,148 +1,13 @@
name: Replay Runner CI
name: Morph smoke (legacy, disabled by default)

# Retained for reference. Default CI is .github/workflows/ci.yml (offline).
# This workflow is disabled; use ci.yml morph-opt-in job with MORPH_API_KEY.

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
workflow_dispatch:
inputs:
snapshot_id:
description: 'Morph snapshot ID to test with'
required: true
default: 'morphvm-minimal'
parallel_count:
description: 'Number of parallel instances'
required: false
default: '2'

env:
MORPH_API_KEY: ${{ secrets.MORPH_API_KEY }}

jobs:
test-replay-bundles:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.9, 3.10, 3.11]
bundle: [demo-http, demo-tcp, demo-file]
parallel: [1, 2]

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"

- name: Create demo bundles
run: |
mkdir -p replays
# Create demo HTTP bundle
echo '{"type": "http", "url": "https://httpbin.org/get"}' > replays/demo-http.json
zip -j replays/demo-http.zip replays/demo-http.json

# Create demo TCP bundle
echo '{"type": "tcp", "host": "localhost", "port": 8080}' > replays/demo-tcp.json
zip -j replays/demo-tcp.zip replays/demo-tcp.json

# Create demo file bundle
echo '{"type": "file", "path": "/tmp/test.txt"}' > replays/demo-file.json
zip -j replays/demo-file.zip replays/demo-file.json

- name: Run replay runner
env:
MORPH_API_KEY: ${{ secrets.MORPH_API_KEY }}
run: |
python -m runner.main \
--snapshot ${{ github.event.inputs.snapshot_id || 'morphvm-minimal' }} \
--bundles "replays/${{ matrix.bundle }}.zip" \
--parallel ${{ matrix.parallel }} \
--timeout 300 \
--emit-cert \
--out "./evidence-${{ matrix.bundle }}-${{ matrix.parallel }}"

- name: Upload evidence artifacts
uses: actions/upload-artifact@v3
with:
name: evidence-${{ matrix.bundle }}-${{ matrix.parallel }}
path: |
evidence-${{ matrix.bundle }}-${{ matrix.parallel }}/certs/
evidence-${{ matrix.bundle }}-${{ matrix.parallel }}/logs/
evidence-${{ matrix.bundle }}-${{ matrix.parallel }}/reports/
retention-days: 30

- name: Validate certificates
run: |
# Check if certificates were generated
if [ -f "evidence-${{ matrix.bundle }}-${{ matrix.parallel }}/certs/cert_0.json" ]; then
echo "✓ Certificate generated successfully"
# Basic JSON validation
python -c "import json; json.load(open('evidence-${{ matrix.bundle }}-${{ matrix.parallel }}/certs/cert_0.json'))"
else
echo "✗ No certificate generated"
exit 1
fi

integration-test:
noop:
runs-on: ubuntu-latest
needs: test-replay-bundles

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python 3.11
uses: actions/setup-python@v4
with:
python-version: 3.11

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"

- name: Download all evidence artifacts
uses: actions/download-artifact@v3

- name: Run integration tests
run: |
# Test that all evidence directories contain expected files
for dir in evidence-*; do
echo "Checking $dir..."
[ -d "$dir/certs" ] || exit 1
[ -d "$dir/logs" ] || exit 1
[ -d "$dir/reports" ] || exit 1
[ -f "$dir/reports/index.json" ] || exit 1
echo "✓ $dir structure is valid"
done

- name: Generate summary report
run: |
python -c "
import json
import glob

summary = {
'total_runs': len(glob.glob('evidence-*')),
'timestamp': '$(date -u +%Y-%m-%dT%H:%M:%SZ)',
'status': 'success'
}

with open('ci-summary.json', 'w') as f:
json.dump(summary, f, indent=2)
"

- name: Upload CI summary
uses: actions/upload-artifact@v3
with:
name: ci-summary
path: ci-summary.json
retention-days: 90
- run: echo "Use ci.yml morph-opt-in instead"
49 changes: 49 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Byte-compiled / cache
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
*.egg-info/
.eggs/
dist/
build/
.mypy_cache/
.ruff_cache/
.pytest_cache/
.coverage
htmlcov/
.tox/
.venv/
venv/
env/

# Evidence and local outputs
/evidence/
/evidence-*/
branches/
branches-smoke/
diffs/
replays/*.zip
*.log

# Secrets and local env
.env
.env.*
!.env.example
*.pem
*.key
credentials.json

# IDE / OS
.idea/
.vscode/
*.swp
.DS_Store
Thumbs.db

# Release scratch
release-bundle/
*.whl
!examples/**/*.json

50 changes: 50 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Changelog

All notable changes to this project are documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.1.0] — 2026-07-24

First public Alpha of the hermetic branch-N backend (MRR-ITE-00 through MRR-ITE-09).

### Added

- Hermetic branch-N backend (`replay-runner branch`) with `LocalFakeProvider` offline path
- ExecutionProfile schema (`mrr.ExecutionProfile.v1`), canonical digest, secret-ref validation
- Provider Protocol: Morph adapter + `LocalFakeProvider`
- Hermeticity modes with fail-closed preflight evidence
- Resource accounting with explicit `unavailable` metrics
- Differential reports with three-valued absence (`absent ≠ equal`)
- PCS `RuntimeReceipt.v0` emission; optional PF-Core gate for elevated claim classes
- PIP `MorphReplayReport.v1` + `TransformationRecord` emission and joint fixtures
- Always-on vendored JSON Schema instance validation (no external CLI required)
- Offline CI (lint / typecheck / tests / schema mirrors); Morph smoke opt-in via `MORPH_API_KEY`
- Security policy, threat model, release checksum script (`scripts/release_bundle.py`)
- Optional `--ovk-check` (fail-closed when flag set and OVK not on PATH)
- Branch CLI fail-closed on partial branches unless `--allow-partial`
- `replay-runner validate` for schema mirrors and vendored instances
- Release documentation: `NON_CLAIMS.md`, `CONTRIBUTING.md`, `docs/release-checklist.md`,
`fixtures/README.md`, public README / SECURITY / ADR polish

### Changed

- CLI is a Click group; legacy ZIP Morph path is `replay-runner run` (compat argv still works)
- `requires-python` pinned to `>=3.9` (CI matrix 3.9–3.12)
- Removed unused `aiofiles` / `asyncio-mqtt`; deleted `core_fixed.py`
- `ReplayValidated` is claim-class metadata only; receipt status uses PCS enum
(`RuntimeObserved` / `RuntimeChecked`)
- `HASH_EXCLUDED_FIELDS` aligned with pcs-core; domain digests via `extra_excluded`
- HTTP callback flag rejected fail-closed (unimplemented / out of scope)

### Non-claims

Observational / differential evidence only. No causality, remediation ranking,
environment-semantics generation, or campaign-level verifier assurance.
See [NON_CLAIMS.md](NON_CLAIMS.md).

[Unreleased]: https://github.com/SentinelOps-CI/morph-replay-runner/compare/v0.1.0...HEAD
[0.1.0]: https://github.com/SentinelOps-CI/morph-replay-runner/releases/tag/v0.1.0
Loading