Skip to content

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.

Install and verify the PAM runtime first, then add the contracts package to a PAM project through PAM’s Composer passthrough:

Terminal window
curl -fsSL https://github.com/push-in/pam/releases/latest/download/install.sh | sh
pam doctor
pam composer require pushinbr/pam-contracts

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.

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.

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.

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.

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.

  • 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.
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.