Why PGS Exists

Traditional systems:

  • embed behavior in code
  • are difficult to audit and reproduce
  • require changes across multiple layers

PGS:

  • declares behavior in protocol artifacts
  • compiles it into an execution graph
  • executes deterministically with a full trace

This onboarding shows how to work within that model.


1. What You Already Did

If you followed the pgs_workspace README, you ran this:

./scripts/bootstrap_pgs.sh
source .venv/bin/activate
./scripts/demo_sample_workflow.sh

You saw a workflow execute twice. The first run registered an actor. The second run produced ALREADY_EXISTS on one node — and still wrote to the event stream. You examined a trace.

You did not write code. You did not configure a framework. You ran a governed execution system.

This document explains just enough to let you build your own.


2. The 30-Second Mental Model

Every PGS execution follows this path:

IN → WF → CC → (CT / CS) → Trace
ConcernWhat it does
IN_ IntentAdmission gate — validates the incoming payload before anything runs
WF_ WorkflowThe execution graph — declares which CCs run and in what order
CC_ Capability ContractA named node in the graph — declares inputs, outputs, and routing outcomes
CT_ Capability TransformPure computation — deterministic, no side effects
CS_ Capability Side EffectControlled state change — registry write, event append, email, etc.
RB_ Runtime BindingConnects declared capabilities to their implementations at build time
TraceAppend-only execution record — the ground truth of what happened

The runtime traverses this graph exactly as declared. It does not interpret or alter behavior. It does not own behavior. Behavior lives in the compiled snapshot.


3. What Actually Happened in the Demo

Run #1 succeeded end-to-end:

CC_GENERATE_ACTOR_ID_V0     → SUCCESS
CC_REGISTER_ACTOR_KYC_V0    → SUCCESS      ← actor written to registry
CC_APPEND_ACTOR_EVENT_V0    → SUCCESS      ← event appended to stream

Run #2 hit the idempotency guard:

CC_GENERATE_ACTOR_ID_V0     → SUCCESS      ← same ID derived from same input
CC_REGISTER_ACTOR_KYC_V0    → ALREADY_EXISTS  ← registry rejected duplicate
CC_APPEND_ACTOR_EVENT_V0    → SUCCESS      ← event still appended

Two things to notice:

  • State is constrained — the registry enforced uniqueness. CS_REGISTRY_V0 is declared to be idempotent; this is a protocol property, not application logic.
  • History is not constrained — the event stream appended regardless. CS_APPENDONLY_JSONL_V0 never rejects. Both runs are recorded.

The routing from ALREADY_EXISTS to the next CC was declared in the workflow DAG. The runtime followed it. No code branch was evaluated. No exception was caught.


4. Build Your First Workflow

4.1 Understand the snapshot

All runnable artifacts live in protocol_snapshot/artifacts/. This directory is read-only — it is compiled output. You do not edit it by hand.

The runtime only executes snapshots marked as VALID. If the snapshot was not built successfully, execution will fail.

Browse what is available:

ls protocol_snapshot/artifacts/workflows/
ls protocol_snapshot/artifacts/capability_contracts/
ls protocol_snapshot/artifacts/capability_transforms/
ls protocol_snapshot/artifacts/capability_side_effects/
ls protocol_snapshot/artifacts/runtime_bindings/

4.2 Run an existing workflow with a different payload

The fastest way to build intuition is to run the same workflow with different input:

# Edit the payload
cp scripts/payloads/register_actor.json /tmp/my_payload.json
# change the actor fields in my_payload.json

# Run it
pgs_runtime run \
  --wf blockchain::WF_REGISTER_ACTOR_UNVERIFIED_V0 \
  --payload /tmp/my_payload.json \
  --data-root $(pwd)/data \
  --workspace $(pwd)

4.3 Examine the trace

pgs_runtime examine ./traces/<TRACE_ID>/<TRACE_ID>.jsonl

Every node execution is recorded: which artifact ran, what inputs it received, what output it produced, what outcome it returned. This is the execution record — not a log, a proof.

4.4 Try a different workflow

pgs_runtime run \
  --wf blockchain::WF_CREATE_WALLET_V0 \
  --payload <path-to-wallet-payload.json> \
  --data-root $(pwd)/data \
  --workspace $(pwd)

List all available workflows:

ls protocol_snapshot/artifacts/workflows/

At this point, you have run and observed multiple workflows. The next step is to modify or create your own to understand how behavior is declared and compiled.


5. Modify Behavior Safely

To change what a workflow does, change the protocol artifacts — not the runtime.

To change…Modify…
Execution flow (which CCs run, in what order)WF_ workflow artifact
Inputs, outputs, or routing outcomes of a nodeCC_ capability contract
The computation inside a nodeCT_ capability transform implementation
The storage/IO semantics of a nodeCS_ capability side effect implementation

All behavior changes must flow through protocol artifacts. Direct changes to runtime or snapshot will be ignored or rejected.

Critical rule: never modify the runtime to change behavior.

The runtime is generic. It has no domain knowledge. Injecting behavior into the runtime breaks the governance model — execution would no longer be constrained by compiled protocol.

After modifying protocol source (in pgs_compiler), you must recompile and rebuild the snapshot before the runtime will see the change. The protocol_snapshot/ directory in this workspace reflects the last compiled state.


6. Add a New Capability

When the existing CT and CS library does not cover what you need, you add a new capability.

To add a pure computation (CT):

  1. Implement a deterministic function with no side effects in pgs_capabilities
  2. Declare a CT_ artifact in pgs_compiler that names and describes it
  3. Add an RB_ binding entry that maps the CT declaration to your implementation
  4. Reference the CT in a CC_ capability contract inside a workflow

To add a stateful operation (CS):

  1. Implement the storage/IO operation in pgs_capabilities
  2. Declare a CS_ artifact in pgs_compiler that defines its semantics
  3. Add an RB_ binding entry that maps the CS declaration to your implementation
  4. Reference the CS in a CC_ capability contract inside a workflow

In both cases the pattern is the same: declare in protocol, implement in library, bind via RB, invoke via CC.

For a complete walkthrough of domain construction, see Chapter 13 — Constructing a Protocol-Governed Domain in the Practitioner’s Guide.


7. Common Errors

SymptomCauseFix
ExecutionError: no binding for CT_...CT declared in protocol but no RB_ entry wires it to an implementationAdd the RB_ binding for that CT
ValidationError: payload rejected at IN_...Input does not satisfy the Intent’s admission rulesCheck the IN_ artifact schema and fix the payload
BuildError: conformance check failedProtocol artifact violates a declared invariantRun the compiler with --verbose and read the assertion output
Trace shows ALREADY_EXISTS unexpectedlyCS_REGISTRY_V0 found a duplicate keyThis is correct behavior — registry is idempotent by design
Editing protocol_snapshot/ has no effectSnapshot is the compiled output — the runtime reads what is already thereModify protocol source and recompile

8. The Build Lifecycle

compile → build → run
PhaseWhat happensWhere
compileProtocol source artifacts are validated against invariants and assertionspgs_compiler
buildValidated artifacts are materialized into a closed execution snapshotpgs_compilerpgs_workspace/protocol_snapshot/
runRuntime reads the snapshot and executes against itpgs_workspace (pgs_runtime CLI)

The snapshot is sealed at build time. The runtime consumes it unchanged. No behavior enters at execution time that was not present in the snapshot.


9. Where to Go Deeper

ResourceWhat it covers
Chapter 13 — Constructing a Protocol-Governed DomainEnd-to-end domain construction: the Seven Architectural Acts from domain spec to running execution
Chapter 14 — AI Agent Governance DomainA complete worked example applying the model to AI governance
pgs_compiler repoAuthoring protocol artifacts, compiler rules, invariants
pgs_capabilities repoWriting CT and CS implementations within declared contracts
TechRxiv paperFormal model, security proofs, scalability analysis
ORCID working papersBackground theory and intellectual lineage (https://orcid.org/0009-0007-3810-6520)

10. Final Takeaway

You did not write execution code.

You declared behavior, compiled it, and ran it.

The runtime did not know what domain it was executing. It did not know what “actor registration” means. It traversed a graph defined by governance artifacts, invoked capabilities through declared bindings, and wrote a verifiable trace.

That is the PGS model. Governance is not applied after the fact — it is compiled into the execution structure before the first instruction runs.

If behavior changes, it is because the protocol changed — not because the runtime decided differently.