If the API surface looks large, it is because six ideas are being enforced everywhere rather than suggested in a guide. Learn these and the rest reads as consequence.

1. The model is a proposer, never an authority

Figure 1. This is not a recommendation about prompt design. It is a structural property: the objects that grant permission are constructed by host code and are never present in model context. The practical test: can a perfectly persuasive prompt injection change the outcome? In Pactmark it can change what the model asks for, and nothing else. There is no instruction, no metadata and no argument value that turns a denied tool into an allowed one.

2. Events are truth; everything else is a cache

Figure 2. A projection is a fold over events. Deleting it costs you nothing but CPU. Deleting the events costs you the run. This is why a run survives a process restart, why pactmark replay can verify a terminal run without executing anything, and why “the request timed out” tells you nothing about whether the work finished.

3. Identity is a digest, not a name

Names collide, get reused and drift. Pactmark binds behaviour to digests: When something drifts, the run suspends rather than resumes. That is a feature: a same-version behaviour change is exactly the failure mode a name-based system hides.

4. Uncertainty is a state, not an exception

Figure 3. The most consequential design decision in the framework. A lost response is not evidence that the effect did not happen, so Pactmark refuses to treat it that way. Most systems collapse “it failed” and “I don’t know” into one retry path. Pactmark keeps them apart, because a duplicated refund and a missing refund are very different conversations.

5. Every boundary declares what it will not do

Look for these three phrases across the API — they are all real, enforced behaviours:

fails closed

Unknown metadata, unsupported capability, missing grant — the answer is no, not “probably fine”.

doesNotProve

A required, non-empty array on every EvidenceRecord. Evidence must state its own limits.

not ready

Readiness reports the profile it cannot satisfy instead of degrading quietly.

6. Configuration is injection, not ambience

There is no global config object, no environment-variable magic and no hidden default client. Clocks, ID generators, stores, transaction boundaries, the authority issuer, admission, policy, credentials, models, tools, the executor, the egress broker, verifiers, the evidence builder, telemetry and the wake-up driver are all constructor input.
createLocalRuntime exists for development and assembles deterministic memory-backed defaults — and it reports its own limits rather than pretending to be production.

Putting it together

1

You describe work, not conversation

A WorkOrder binds tenant, principal, purpose, budget, data class and deadline before anything runs.
2

The host reserves authority before export

Admission and policy commit budgets and grants before context reaches the model.
3

The model proposes; policy re-checks

Every tool request is re-evaluated against current grants and kill switches.
4

Effects record their own uncertainty

Prepared, dispatched, acknowledged — or parked with an explicit reconciliation path.
5

Output becomes bytes, then a verified artifact

Content addressing first, verification bound to that address second.
6

Evidence states both sides

What the run supports, and what it does not prove.

Now read the architecture

How these six ideas are split across nineteen packages, and which ones you actually import.