pushinbr/pam-contracts
pushinbr/pam-contracts contains small versioned contracts for packages that extend PAM. It does not include a router, server, or application framework.
Start here
Section titled “Start here”Install and verify the PAM runtime first, then add the contracts package to a PAM project through PAM’s Composer passthrough:
curl -fsSL https://github.com/push-in/pam/releases/latest/download/install.sh | shpam doctorpam composer require pushinbr/pam-contractsHTTP application contract
Section titled “HTTP application contract”ApplicationInterface defines:
interface ApplicationInterface{ public function route( string $method, string $path, callable $handler, ): self;
public function middleware(object|callable $middleware): self;
public function onError(callable $handler): self;
public function handle( Request $request, Response $response, ): Response;}Packages should depend on this contract when they need to register routes or middleware without requiring pushinbr/pam-http directly.
Middleware contract
Section titled “Middleware contract”interface MiddlewareInterface{ public function process( Request $request, Response $response, RequestHandlerInterface $next, ): Response;}Middleware must return a PAM response. The request handler contract exposes a single handle() operation.
Service providers
Section titled “Service providers”interface ServiceProviderInterface{ public function register(ApplicationInterface $application): void;
public function boot(ApplicationInterface $application): void;}Use register() to add application configuration while it remains mutable. Use boot() for work that requires all providers to be registered. Do not perform request-specific work in either lifecycle method.
Runtime compatibility
Section titled “Runtime compatibility”Packages that require native capabilities should fail during boot:
use Pam\Contracts\Runtime\RuntimeCompatibility;use Pam\Native\Capability;
RuntimeCompatibility::discover()->assert([ Capability::WebSocket,]);The compatibility object checks the native ABI version and sequential integer capability IDs. It throws when PAM is unavailable, the ABI differs, or a required capability is missing.
Stability enum
Section titled “Stability enum”Runtime contracts use an integer-backed stability enum:
| Value | Case |
|---|---|
1 |
Experimental |
2 |
Stable |
3 |
Deprecated |
Application and package code should use enum cases instead of magic numbers.
Package design rules
Section titled “Package design rules”- Depend on the smallest contract package required.
- Check native capabilities at boot, not after receiving traffic.
- Keep provider registration deterministic.
- Do not retain request objects in providers or singletons.
- Add only append-compatible integer identifiers within an ABI version.
- Document the minimum PAM ABI and capabilities.
Complete public surface
Section titled “Complete public surface”| Namespace | Type | Operations/data |
|---|---|---|
Pam\Contracts\Http |
ApplicationInterface |
route(), middleware(), onError(), handle() |
Pam\Contracts\Http |
MiddlewareInterface |
process(request, response, next) |
Pam\Contracts\Http |
RequestHandlerInterface |
handle(request, response) |
Pam\Contracts\Package |
ServiceProviderInterface |
register(application), boot(application) |
Pam\Contracts\Runtime |
RuntimeCompatibility |
Readonly abiVersion, capability integer list, discover(), assert() |
Pam\Contracts\Runtime |
Stability |
Experimental=1, Stable=2, Deprecated=3 |
RuntimeCompatibility::discover() requires the PAM runtime and reads its ABI
and capabilities. assert() checks exact ABI equality and every requested
Capability enum; it throws on absence or mismatch.