monitor role, without any of the book’s detail.
What to read
Each section of the system view is read on its own: a view whose database does not answer still says who the engine is and where the ledger stands.
Health
PQS follows one party, so it moves only when that party’s ledger moves: a lag alone cannot tell a stuck projection from a quiet one. Compare the answer’s
offset across reads: one that moves is not stuck.
What to alert on
Control events
The feed also carries each finished operation (
operation.succeeded, operation.failed) and each four-eyes step (approval.requested, approval.signed, approval.approved, approval.rejected), and the ledger’s own facts as journal events. Webhooks carry the control events above.
Webhooks
Each webhook receives the types it takes, as a JSON post:type, at, the asset and the resource where there is one, and the event’s payload.
- Verify every delivery in constant time, and refuse a timestamp far from your own clock: the timestamp is signed, so a captured post cannot be sent again later under a new one.
- Delivery is at least once. A 2xx answer counts as delivered; anything else is retried with a doubling wait, and given up after the configured number of attempts.
- Deliveries wait in an outbox in the engine’s database, so a restart loses none that were queued.
The monitor role
monitor is the identity of dashboards and on-call. It reads health, the system view (with the projection’s reach and each webhook’s deliveries), the verdict and the feed’s control events, and nothing of the book:
- A ledger fact names a holder’s party and units, so the monitor’s feed holds no journal events, only control events.
- Each control event it reads is redacted. It keeps what happened, when, to which asset, and the ids, codes and counts its payload carries. It loses every free text and every person: a hold’s detail, a pause’s rationale, an approval’s reason, the maker, the approver.
- The fields the monitor reads are allow-lists, so a new field reaches it as nothing until it is allowed.

