The framework-agnostic contracts core of Milpa — a modular PHP runtime for applications operable by both humans and agents. Not another web framework: the primitives that let modules declare capabilities, expose tools, and gate actions behind verification.
milpa/core is the dependency-light heart of the framework: the attributes, events,
value objects, enums, interfaces, and the verification seam that every Milpa module
builds on. No Doctrine, no HTTP client, no framework kernel — just the contracts and
primitives, so you can depend on them from anywhere.
composer require milpa/coreMost PHP frameworks are built for one kind of caller: a human writing code, or a browser sending requests. Milpa is built for two — humans and agents operating the same application through the same declared surface.
Modules don't just register routes and services. They declare the capabilities they provide and require, expose tools an agent can invoke, and gate mutating actions behind verification — deterministic checks, human/agent approvals, or async results. The contract loop that runs through the whole system:
plugin → capability → tool → verification → event → result
Three seams in this package make that loop possible:
- Capability system — a plugin manifest declares what it provides, requires, and
suggests, so the runtime can wire modules together and reason about what's installed.
Each entry comes in either real shape
#[PluginMetadata]sanctions: a bare interface FQCN (legacy) or a structured capability record ({id, interface, contractVersion, …}), parsed by the capability value objects'parse()— mixing both in one list is the incremental migration path. - Agent tool-readiness —
ToolProviderInterface/ToolRegistryInterfacelet a module publish declarative tools that both humans and agents can discover and call. - Verification seam —
VerifierInterfacegates a mutating action behind a deterministic evaluation, a human/agent approval, or a pending async result that resolves through an event.
Be honest about scope: this package ships the contracts and primitives only. It
does not run an HTTP server or boot an application by itself. The web tier lives in the
sibling milpa/http package, and the runtime/CLI is coa. Depend on milpa/core
when you want to build against those seams without pulling in a framework.
Value objects are immutable and self-validating. For instance, SemanticVersion:
use Milpa\ValueObjects\SemanticVersion;
$v = SemanticVersion::parse('2.4.1');
$v->satisfies('^2.0'); // true
$v->greaterThan(SemanticVersion::parse('2.4.0')); // true
$v->incrementMinor(); // 2.5.0 (a new instance)
$v->isStable(); // true — no pre-release tag| Namespace | What it provides |
|---|---|
Milpa\Attributes |
Declarative attributes (RegisterService, BusinessRule, Subscribe, …) |
Milpa\Interfaces |
Core contracts, grouped by seam: Di, Plugin, Event, Config, Observability, Tooling, Verification |
Milpa\ValueObjects |
Immutable, validated values (SemanticVersion, capability & verification VOs, …) |
Milpa\Enums |
Shared enums (ApprovalPolicy, VerificationStatus, DispatcherType, …) |
Milpa\Events |
Framework event contracts + dispatch primitives |
Milpa\DTO |
Data-transfer objects passed across seam boundaries |
Milpa\Exceptions |
Typed exception hierarchy for the contracts |
Milpa\Services |
Framework-agnostic service contracts and helpers |
Milpa\Support |
Small framework-agnostic utilities |
Every public symbol carries a DocBlock — the API reference is generated straight from them.
Milpa\Services\CapabilityMatcher is the single criterion for "is this provision the thing that
requirement is asking for?". It lives here, in the package with no dependencies, because everyone
who asks that question has to get the same answer:
$matcher->identityMatches($provision, $requirement); // is it the same capability?
$matcher->satisfies($provision, $requirement); // …and does the contract version fit?
The two are separate because they are asked at different moments. Before boot, nothing knows contract versions yet, and asking whether the capability exists at all is a different question from whether the version fits — collapsing them makes a missing provider and an incompatible one look identical to whoever has to fix it.
It exists because there were four implementations of this comparison in the family and they did not agree. Four comparisons of the same thing are four chances to disagree; the only question is when.
- PHP ≥ 8.3
Full API reference: getmilpa.github.io/core — generated straight from the source DocBlocks and dressed with the Milpa design system.
Contributions are welcome — see CONTRIBUTING.md. Please report security issues via SECURITY.md, and note that this project follows a Code of Conduct.
Apache-2.0 © Rodrigo Vicente - TeamX Agency.
Milpa is designed, built, and maintained by Rodrigo Vicente - TeamX Agency.