it-pack / run-it
The execution model and runtime backbone for the ItPack ecosystem.
Requires
- php: ^8.4
- just-bases/php-obs-base: ^1.0
Requires (Dev)
- codeception/module-asserts: ^3.3
- codeception/module-phpbrowser: ^4.1
- infection/codeception-adapter: ^0.4
- just-bases/php-obs-dev-base: ^0.1.0
- just-bases/php-qa-base: ^1.0
- just-bases/php-unit-test-base: ^1.0
- nyholm/psr7: ^1.8
- open-telemetry/api: ^1.9
- open-telemetry/sdk: ^1.0
- phparkitect/phparkitect: ^1.2
- psr/clock: ^1.0
- psr/event-dispatcher: ^1.0
- psr/http-client: ^1.0
- psr/http-server-handler: ^1.0
- psr/http-server-middleware: ^1.0
- psr/log: ^3.0
- symfony/http-client: ^8.1
Suggests
- ext-openswoole: OpenSwoole coroutine execution adapter
- ext-swoole: Swoole coroutine execution adapter
- cloudevents/sdk-php: CloudEvents occurrence mapping
- open-telemetry/api: OpenTelemetry mapping
- open-telemetry/sdk: OpenTelemetry SDK/export support
- psr/clock: PSR-20 clock integration
- psr/event-dispatcher: PSR-14 occurrence integration
- psr/http-message: HTTP context propagation
- psr/http-server-handler: PSR-15 execution middleware
- psr/log: PSR-3 observation and logger integration
Provides
None
Conflicts
None
Replaces
None
README
The execution model and runtime backbone for the ItPack ecosystem.
RunIt provides composable, reusable, and non-intrusive execution components for PHP applications and libraries.
It models execution itself rather than coupling application code directly to tracing, logging, metrics, event, or runtime technologies.
Execution
├── Context
├── Activity
├── Measurement
├── Observation
├── Occurrence
└── Snapshot
OpenTelemetry, CloudEvents, PSR interfaces, Fibers, and Swoole are integrations around this model—not the model itself.
Everything happens within an execution.
The canonical semantic resources are the RunIt OWL vocabulary and its companion SKOS taxonomy. Public contracts and documentation refer to the relevant terms as they are implemented.
Table of Contents
- Purpose
- Project Status
- Requirements
- Installation
- Core Concepts
- Quick Start
- Architecture
- Integrations
- Documentation
- Security and Privacy
- Performance
- Testing
- Development
- Roadmap
- Versioning
- Contributing
- License
Purpose
Runtime behavior is commonly represented through unrelated systems:
- Traces and spans.
- Logs.
- Metrics.
- Events.
- Configuration snapshots.
- Queue metadata.
- Request context.
- Diagnostic reports.
These systems frequently describe the same operation using incompatible vocabularies.
RunIt establishes a shared semantic foundation:
Execution
owns Context
contains Activities
records Measurements
captures Observations
publishes Occurrences
produces Snapshots
This allows ItPack packages, applications, and third-party libraries to cooperate without depending on a specific telemetry vendor, framework, event bus, logger, or execution runtime.
Example execution kinds
RunIt can represent:
- HTTP requests.
- CLI commands.
- Queue jobs.
- Configuration resolution.
- Workflows.
- Event processing.
- Scheduled tasks.
- Background workers.
- Build processes.
- Database migrations.
- LLM pipelines.
- Custom operations.
Project Status
RunIt is currently at release candidate 1.0.0-rc.1.
The public API is frozen. It comprises 372 public symbols (147 interfaces, 206 classes, 13 enums) plus a stable normalization schema, recorded in tools/api-compat/api-baseline.json and tools/api-compat/normalization-schema-baseline.json. Backward compatibility is enforced by composer api:check.
Through the release candidate, a change to a frozen public symbol is a deliberate, documented act: update the baseline with composer api:baseline and record the change in docs/CHANGELOG.md (see docs/releases/1.0.0-rc.1.md).
The initial development priorities are complete:
- Stable execution semantics.
- Immutable domain artifacts.
- Lifecycle-safe execution and activity runners.
- Context propagation.
- Composable artifact publication.
- OpenTelemetry integration.
- CloudEvents integration.
- PSR integration.
- Fiber and Swoole runtime adapters.
- Adoption by other ItPack packages and a third-party usability sample (
it-pack/run-it-third-party-sample).
Remaining work toward 1.0.0 and beyond is tracked in docs/ROADMAP.md.
Requirements
- PHP 8.4 or later.
- Composer 2.
- No framework requirement.
- No mandatory PHP extension beyond those required by PHP itself.
Optional integrations may require additional packages or extensions:
- OpenTelemetry PHP API and SDK.
- CloudEvents PHP SDK.
- PSR-3 logger interfaces.
- PSR-14 event dispatcher interfaces.
- PSR-15 HTTP server interfaces.
- PSR-20 clock interfaces.
- Swoole or OpenSwoole.
- FFI for selected Fiber-aware OpenTelemetry configurations.
Installation
Install RunIt through Composer:
composer require it-pack/run-it
For the release candidate, pin to the RC constraint:
composer require it-pack/run-it:^1.0.0@RC
The stable ^1.0.0 constraint becomes available once 1.0.0 is tagged.
RunIt is designed to remain usable without installing telemetry exporters, framework bridges, or runtime extensions.
Core Concepts
RunIt describes one operation as an execution that carries immutable context
and emits six kinds of artifact. Each is documented in depth under
docs/concepts/; a hands-on tour is the
tutorial.
| Concept | One-line definition | Reference |
|---|---|---|
| Execution | One logical operation; the root aggregate everything belongs to. | concepts/execution.md · tutorial 1 |
| Activity | A bounded unit of work (a step) inside an execution; may nest. | concepts/activity.md · tutorial 2 |
| Measurement | A quantitative, named, typed, unit-bearing value. | concepts/measurement.md · tutorial 3 |
| Observation | A qualitative note at a PSR-3 severity; throwables are safely normalized. | concepts/observation.md · tutorial 3 |
| Occurrence | An immutable, versioned fact (order.placed.v1); maps to CloudEvents. |
concepts/occurrence.md · tutorial 4 |
| Snapshot | An immutable state projection bound to a content hash. | concepts/snapshot.md · tutorial 4 |
| Context | Immutable, classified per-execution metadata; secrets are deny-by-default. | concepts/context.md · tutorial 5 |
New here? Start with Getting Started.
Quick Start
The canonical API executes a callable within an explicit execution scope:
<?php declare(strict_types=1); use ItPack\RunIt\Application\Runner\ExecutionRunnerInterface; use ItPack\RunIt\Application\Scope\ExecutionScopeInterface; use ItPack\RunIt\Domain\Execution\ExecutionDefinition; /** @var ExecutionRunnerInterface $runner */ $result = $runner->run( ExecutionDefinition::named('configuration.resolve') ->ofKind('configuration.resolution'), static function (ExecutionScopeInterface $execution): array { return [ 'environment' => 'production', 'debug' => false, ]; }, );
The runner is responsible for:
- Creating the execution.
- Attaching its context.
- Publishing lifecycle artifacts.
- Invoking the operation.
- Recording success or failure.
- Producing the terminal execution snapshot.
- Restoring the previous execution context.
- Returning the result or rethrowing the original exception.
See the full, runnable version in docs/getting-started.md
and examples/sdk.php.
Architecture
RunIt uses hexagonal (ports-and-adapters) architecture. The immutable domain model is the center; application services orchestrate it; the SDK and external adapters sit at the edge; and every technology-specific effect crosses the boundary through an explicit port.
SDK / Consumer Adapters → Application → Domain
Infrastructure Adapters ──► Ports ◄── Application
The domain never depends on application services, the SDK, or any adapter; external adapters are optional and never referenced by the domain (ADR-006, ADR-010).
- Dependency rules and the generated layer graph:
docs/architecture/dependency-graph.md.- Lifecycle, publication, context propagation, security, performance, self-instrumentation:
docs/architecture/. - Runtime architecture diagram (components, primary request path, ports/adapters, trust boundary):
docs/diagram/runit-runtime.html.
- Lifecycle, publication, context propagation, security, performance, self-instrumentation:
Integrations
RunIt's adapters are optional and sit at the edge. Pick what you need:
- OpenTelemetry — executions→traces, activities→spans, measurements→metrics. See
docs/integrations/opentelemetry.md. - CloudEvents — occurrences as versioned events, both directions. See
docs/integrations/cloudevents.md. - PSR-3 / PSR-14 — observations and occurrences to logs and events. See
docs/integrations/psr.md. - HTTP — per-request execution context and middleware. See
docs/integrations/README.md. - Swoole / OpenSwoole — coroutine-local context and server middleware. See
docs/integrations/swoole.md. - Fibers — per-Fiber context isolation. See
docs/integrations/fibers.md.
Documentation
The documentation has a front door: docs/index.md.
- Evaluating RunIt? Read Purpose, the Execution Model, Use cases, and the Ecosystem.
- Integrating it? Start at Getting Started, follow the tutorial, then pick a recipe and an integration.
- Extending it? Read the Architecture, Base contracts, the ADR index, and the Third-party adapter recipe.
Other entry points: glossary, vocabulary (the canonical OWL ontology + SKOS taxonomy), compatibility, conformance, and the roadmap.
Security and Privacy
Context, observations, occurrences, and snapshots are treated as potential data exfiltration paths. Secret values are never exported or serialized; restricted values are masked on redaction; cardinality and payload sizes are bounded by default. These are deny-by-default behaviors, with negative tests required for security-sensitive changes.
- Threat model and supply chain:
docs/SECURITY.md,docs/security/. - Classification and redaction behavior:
docs/architecture/security.md.
Performance
RunIt is built for request, command, job, worker, and library hot paths. The core avoids network/filesystem access, reflection in ordinary execution, eager stack-trace collection, and global mutable state. Durations use monotonic time.
Tuning levers include NullArtifactPublisher, sampling, deferred normalization, bounded
buffering, batch exporters, and activity filtering. Details:
docs/architecture/performance.md.
Testing
RunIt uses a test-framework-agnostic strategy: domain invariants, lifecycle
state-machine, application service, adapter contract, integration, property-based,
failure-injection, Fiber/coroutine isolation, leak, serialization round-trip, mutation,
and benchmark tests. Reusable contract suites let third-party adapters verify
compatibility without adopting RunIt's internal framework. See docs/QA.md.
Development
Clone the repository and install dependencies:
git clone <repository> cd run-it composer install
Quality checks
The Composer scripts are stable for the release candidate. The intended commands are:
composer validate
composer test
composer analyse
composer architecture
composer coding-style
composer api:baseline
composer api:check
composer mutation
composer benchmark
composer audit
composer examples
composer quality
Expected aggregate behavior:
composer quality
should run:
- Composer validation.
- Coding-standard checks.
- PHPStan.
- DepTrac.
- Unit and integration tests.
- Security audit.
- Public API compatibility checks where applicable.
Static analysis
RunIt targets the highest practical PHPStan level with:
- Strict rules.
- No first-party baseline.
- No implicit
mixed. - Generic type validation.
- Exception declaration checks.
- Custom architectural rules.
Dependency architecture
DepTrac protects the intended dependency direction:
Domain → Contracts
Application → Contracts, Domain, Ports
SDK → Contracts, Domain, Application, Ports
Adapters → Contracts, Domain, Ports, external APIs
The domain must never depend on application services or adapters.
Mutation testing
Mutation testing focuses on:
- Lifecycle transitions.
- Context restoration.
- Failure policies.
- Redaction.
- Sampling.
- Identifier validation.
- Adapter mappings.
- Exception preservation.
Coding standards
All PHP files must:
- Declare strict types.
- Follow the project coding standard.
- Use explicit parameter and return types.
- Avoid unnecessary inheritance.
- Avoid mutable static state.
- Keep concrete classes
final. - Use
readonlywhere practical.
Roadmap
RunIt 1.0.0-rc.1 implements the complete initial feature set described in this document:
- The domain kernel (execution, context, activity, measurement, observation, occurrence, snapshot) with deterministic normalization.
- Lifecycle-safe execution and activity runners, explicit and ambient context propagation, and nested-execution policies.
- A composable artifact-publication pipeline with redaction, sampling, buffering, backpressure, failure policies, and recursion protection.
- An SDK with immutable builders, callable and interface decorators, and metadata attributes.
- Integrations for OpenTelemetry, CloudEvents, PSR-3, PSR-14, PSR-20, PSR-7/15/18, Fibers, and Swoole/OpenSwoole.
- Third-party usability, validated by the
it-pack/run-it-third-party-samplepackage.
The public API is frozen at this release candidate. Remaining milestones, including the promotion to 1.0.0 and post-1.0 planning, are tracked in docs/ROADMAP.md. The authoritative compatibility baseline is tools/api-compat/api-baseline.json.
Versioning
RunIt follows Semantic Versioning after 1.0.0.
Public API includes:
- Public interfaces.
- Public classes.
- Public enums.
- Public attributes.
- Public method signatures.
- Normalized artifact field names.
- Occurrence naming rules.
- Serialized schema formats explicitly marked stable.
The ItPack\RunIt\Behavior and ItPack\RunIt\Conformance namespaces are internal and are not covered by the backward-compatibility guarantee. As of 1.0.0-rc.1, the remaining public namespaces (Domain, Application, Contract, Adapter, SDK, Common) are frozen.
Before 1.0.0:
- Minor versions may contain breaking changes.
- Breaking changes must be documented.
- Migration notes should accompany each pre-release.
- Deprecated APIs should be retained where practical until the next minor release.
From 1.0.0-rc.1 onward, any change to a frozen public symbol is a breaking change and requires a deliberate, documented baseline update (composer api:baseline + docs/CHANGELOG.md).
Contributing
Contributions are welcome. The public API is frozen at 1.0.0-rc.1, so propose any API change through an issue and an ADR before implementation.
Before submitting a change:
- Open or reference an issue.
- Explain the execution-model use case.
- Preserve dependency direction.
- Add or update tests.
- Add contract tests for new extension points.
- Update documentation.
- Run the complete quality pipeline.
- Document backward-compatibility impact.
- Include an ADR for significant architectural decisions.
New features should be built from small, focused components rather than by expanding existing interfaces with unrelated responsibilities.
Design Philosophy
RunIt is intentionally not defined in terms of an external standard.
OpenTelemetry is an adapter.
CloudEvents is an adapter.
PSR-3 is an adapter.
PSR-14 is an adapter.
Swoole is an adapter.
The semantic model remains:
Execution carries context. Activities perform work. Measurements quantify work. Observations describe work. Occurrences record work. Snapshots preserve work.
License
RunIt is released under the MIT License.