Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
39 changes: 32 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,29 @@ for t in skill.triggers:
"
```

## Install Targets

`ori-runtime` has two intentionally different install shapes:

```bash
# Product/demo consumers: typed rule-evaluation boundary only.
# This is what ori-energy FastAPI should use for /demo proof evaluation.
python -m pip install "ori-runtime[eval] @ git+https://github.com/ori-platform/ori-runtime.git@<commit-or-tag>"

# Runtime/device development: full transport, security, provider, and HAL deps.
python -m pip install -e ".[runtime,dev]"

# Edge deployment still uses the signed wheelhouse / hash-locked requirements path.
bash scripts/build-wheelhouse.sh
```

The base package deliberately installs only the dependency needed by
`ori.integration` (`PyYAML`) plus the packaged bundled skills. MQTT, SMS,
WhatsApp, OPC-UA, HTTP adapters, crypto transports, and hardware/provider
libraries live behind extras or the deployment wheelhouse. This keeps
`ori-energy` and other product/demo consumers from inheriting the full device
runtime dependency surface while still using the real rule engine.

### Quick Local SLM Setup (Qwen GGUF)

```bash
Expand Down Expand Up @@ -410,12 +433,14 @@ bash scripts/smoke-release-wheel.sh # Installed-wheel release readines
The test suite covers all layers — HAL adapters, event bus, rule engine (with AST safety validation), action dispatcher (all four tiers), skill loader, state store, and runtime.

Run `scripts/smoke-release-wheel.sh` before tagging a runtime release. It is
deliberately stricter than an editable install: it builds the wheel, installs
runtime dependencies from hash-locked requirements, installs the wheel with
`--no-deps`, then verifies the public `ori.integration` rule-evaluation boundary
is typed (`ori/py.typed`) and can resolve bundled skill data from the installed
artifact. This protects the `ori-energy` demo/API path from type-checker ignores
and source-checkout-only packaging mistakes.
deliberately stricter than an editable install: it builds the wheel, verifies
the wheel metadata keeps the base install slim for `ori-energy`/demo consumers,
installs runtime dependencies from hash-locked requirements, installs the wheel
with `--no-deps`, then verifies the public `ori.integration` rule-evaluation
boundary is typed (`ori/py.typed`) and can resolve bundled skill data from the
installed artifact. This protects the `ori-energy` demo/API path from
type-checker ignores, accidental dependency bloat, and source-checkout-only
packaging mistakes.

## Security

Expand Down Expand Up @@ -443,7 +468,7 @@ We welcome contributions! Start here:
3. **Understand the extension points:** [`AGENTS.md`](AGENTS.md)

```bash
pip install -e ".[dev]"
pip install -e ".[runtime,dev]"
pytest tests/ -v
```

Expand Down
3 changes: 2 additions & 1 deletion docs/CAPABILITY_MATRIX.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ This is the authoritative record of what is real versus planned.
| Secure remote DevicePolicy fetch | Implemented | policy/remote_fetch.py, runtime.py, config.py | HTTPS + bearer auth + timestamp skew check + monotonic version guard + Ed25519 verification; rejected payloads are persisted to `override_log` as `policy_rejection`. |
| Runtime supply-chain hardening | Implemented | .github/workflows/ci.yml, .pre-commit-config.yaml, requirements.txt, requirements-dev.txt, scripts/check_workflows.py, scripts/bootstrap.sh | CI uses least-privilege permissions, SHA-pinned GitHub Actions and pre-commit hooks, Harden-Runner audit mode, hash-locked dependency installs, `pip-audit`, CycloneDX SBOM artifact generation, and guards against `pull_request_target`, mutable action refs, unauthorized OIDC, and remote script execution. |
| Runtime contract-boundary typecheck | Implemented | pyproject.toml, scripts/typecheck-boundaries.sh, .github/workflows/ci.yml | Scoped mypy gate covers runtime DTO/security/policy/gateway contract boundaries consumed by gateway, demo FastAPI, ori-specs, and future ori-cloud sync. Hardware, sandbox internals, full runtime loop, and tests remain explicitly deferred from this first pass. |
| Runtime release wheel smoke test | Implemented | scripts/smoke-release-wheel.sh, .github/workflows/ci.yml, pyproject.toml | Python 3.12 CI builds the `ori-runtime` wheel, installs runtime dependencies from hash-locked requirements into a clean venv, installs the wheel with `--no-deps`, verifies the installed wheel exposes the PEP 561 `ori/py.typed` marker, verifies bundled skill data resolves from installed `share/ori-runtime/skills`, and runs a real Tier D rule evaluation through `ori.integration`. This protects `ori-energy`/demo consumers from type-checker ignores and source-checkout-only packaging mistakes before tags are cut. |
| Runtime release wheel smoke test | Implemented | scripts/smoke-release-wheel.sh, .github/workflows/ci.yml, pyproject.toml | Python 3.12 CI builds the `ori-runtime` wheel, verifies base wheel metadata remains slim for `ori-energy`/demo consumers (`PyYAML` only, with transport/provider/security dependencies behind extras), installs runtime dependencies from hash-locked requirements into a clean venv, installs the wheel with `--no-deps`, verifies the installed wheel exposes the PEP 561 `ori/py.typed` marker, verifies bundled skill data resolves from installed `share/ori-runtime/skills`, and runs a real Tier D rule evaluation through `ori.integration`. This protects `ori-energy`/demo consumers from type-checker ignores, accidental dependency bloat, and source-checkout-only packaging mistakes before tags are cut. |
| DevicePolicy enforcement layer | Implemented | action_dispatcher.py, device_policy.py | P3-R0b-iii. |
| Device policy refresh loop | Implemented | runtime.py, config.py | Optional background refresh (`device_policy.refresh_enabled`) with signed verification + cache update; transient network failures are audit-deduped to prevent log spam. |
| Device policy cache (SQLite) | Implemented | state/store.py, runtime.py | Signed cache with `raw_payload`; startup re-verifies signature from cache using `device_policy.public_key_b64` before apply. |
Expand Down Expand Up @@ -98,6 +98,7 @@ This is the authoritative record of what is real versus planned.
- 2026-06-11: Added MQTT runtime node heartbeat publisher. Runtime publishes `ori/{device_id}/runtime/heartbeat` with `retain=false`, optional device-bound HMAC signing, and no EventBus routing so the gateway can track runtime liveness separately from gateway reachability.
- 2026-06-12: Added scoped mypy gate for runtime contract-boundary modules before demo FastAPI and ori-cloud sync consume runtime-shaped DTOs.
- 2026-06-14: Added the PEP 561 `ori/py.typed` marker to the release wheel smoke test so `ori-energy`/demo FastAPI consumers can typecheck against the public `ori.integration` boundary without ignoring runtime imports.
- 2026-06-16: Split package dependency metadata so base `ori-runtime` / `ori-runtime[eval]` installs support the typed `ori.integration` rule-evaluation boundary without pulling MQTT, SMS, hardware, provider, or crypto runtime dependencies; full device deployments use the `runtime` extra or hash-locked wheelhouse path.
- 2026-06-12: Added release wheel smoke test so CI verifies the installed `ori-runtime` artifact can resolve packaged bundled skills and run a real `ori.integration` rule evaluation before v1 tags are cut.
- 2026-06-13: Hardened Tier C and SMS ingress boundaries. Live Tier C approval now requires scoped proposal replies by default, unmatched model/gateway proposals cannot create physical action authority, and public SMS webhooks can require raw-body HMAC with timestamp and nonce replay protection before payload parsing.
- 2026-06-14: Added verify-only previous-secret support for gateway MQTT HMAC, remote-command HMAC, and SMS webhook HMAC so sites can rotate secrets through config/environment updates without accepting unsigned fallback traffic.
Expand Down
33 changes: 30 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,26 @@ requires-python = ">=3.11"

dependencies = [
"pyyaml>=6.0",
]

[project.optional-dependencies]
eval = []
runtime = [
"paho-mqtt>=2.0",
"psutil>=5.9",
"pyserial>=3.5",
"pysolarmanv5>=3.0",
"asyncua>=1.1",
"aiofiles>=23.0",
"aiohttp>=3.14.1",
"httpx>=0.28",
"cryptography>=46.0.7",
"cryptography>=48.0.1",
"pyopenssl>=26.3.0",
"twilio>=9.0",
"africastalking>=1.0",
"python-dotenv>=1.0",
"urllib3>=2.7.0",
]

[project.optional-dependencies]
pi = [
"gpiozero>=2.0",
"smbus2>=0.4",
Expand All @@ -50,6 +56,27 @@ llm = [
cloud = [
"anthropic>=0.28",
]
all = [
"paho-mqtt>=2.0",
"psutil>=5.9",
"pyserial>=3.5",
"pysolarmanv5>=3.0",
"asyncua>=1.1",
"aiofiles>=23.0",
"aiohttp>=3.14.1",
"httpx>=0.28",
"cryptography>=48.0.1",
"pyopenssl>=26.3.0",
"twilio>=9.0",
"africastalking>=1.0",
"python-dotenv>=1.0",
"urllib3>=2.7.0",
"gpiozero>=2.0",
"smbus2>=0.4",
"RPi.GPIO>=0.7",
"llama-cpp-python>=0.2",
"anthropic>=0.28",
]
dev = [
"pytest>=8.0",
"pytest-asyncio>=0.23",
Expand Down
2 changes: 2 additions & 0 deletions requirements-dev.in
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ types-PyYAML>=6.0
pip-tools>=7.4
pip-audit>=2.7
cyclonedx-bom>=6.0

wait-for2==0.3.2; python_version < "3.12"
Loading