Skip to content

Telemetry & Privacy

PyHall is explicit about what stays in your system and what touches the registry. This page is the complete record — no fine print.


What stays local — always

The following never leaves your infrastructure:

DataWhere it lives
Capability requestsYour agent’s process
Routing decisions (which worker, why)Your Hall Server / Hall Monitor
Decision deny reasonsYour evidence log
Agent identity and contextYour system
Tenant IDsYour system
Policy configurationsYour system
Routing rulesYour system
Worker business logic outputYour system
Any data the worker processesYour system

make_decision() is a pure local function. It reads from an in-memory cache and returns a decision. No network call, no outbound data, no exceptions.


What touches the registry — on a 60-second cycle

Two calls happen during prefetch(), which runs on a background timer (default: every 60 seconds):

1. Standing receipt — GET /api/v1/verify/:worker_id

Sent: worker ID (e.g. org.example.my-worker or x.yourname.my-worker) Received: attestation status, current registered hash, ban status Purpose: Confirm the worker is still attested and not on the community ban list before the next decision window

One request per enrolled worker, per 60-second window. If you have 5 enrolled workers, that is 5 HTTP GETs per minute.

2. Decision count — POST /api/v1/telemetry/decisions

Sent:

{
"decisions": [
{ "worker_id": "org.example.my-worker", "count": 847 }
]
}

Purpose: Aggregate count of how many routing decisions were issued to each worker in the last 60-second window. This is how the pyhall.dev network stats (“total routing decisions”) are computed.

What is NOT in this payload:

  • No request content
  • No agent data
  • No tenant identifiers
  • No user data
  • No decision outcomes or reasons
  • No IP addresses (CF Worker strips them from the stored record)

Only: worker ID + integer count.


What happens at startup — once

Package attestation — local only

PackageAttestationVerifier runs at Hall Server startup. It:

  1. Reads manifest.json from disk
  2. Computes a SHA-256 hash of the package files
  3. Compares against the manifest’s package_hash
  4. Verifies the HMAC-SHA256 signature against WCP_ATTEST_HMAC_KEY

No network call. Entirely local. If attestation fails, the process exits — it does not phone home.


Account requirement

Using pyhall requires a pyhall.dev account in good standing. The standing receipt and decision count flush are mandatory parts of that integration — they are not configurable or disableable.

ModeAccount requiredRegistry calls
Hall Monitor + registryYes — must be in good standingStanding receipt + decision counts every 60s
Pure SDK (no registry, no Hall Monitor)NoNone — routes entirely from local data

The pure SDK mode is the open source path — the Python, TypeScript, and Go SDKs are Apache 2.0 licensed and can be embedded in your own infrastructure without connecting to pyhall.dev. The WCP routing engine (make_decision(), rules, PolicyGate) is the same engine that powers the full product. What you don’t get without an account: namespace ownership, registry attestation, Hall Monitor, and the standing receipt chain. Hall (Hall Monitor + Hall API server) is a commercial application — not open source.


Registry data retention

Decision counts and verify hits are stored per worker ID per calendar day. No personally identifiable information is stored. Aggregates older than 365 days are purged. The pyhall.dev privacy policy applies.


Summary

Your system pyhall.dev registry
────────────────────── ──────────────────────
make_decision() ─── local only ───► (nothing)
prefetch() ──────────────────────► GET verify/:worker_id (standing receipt)
prefetch() ──────────────────────► POST telemetry/decisions (count only)
startup ─── local only ────────► (nothing)