# Predge Trust Pack (v1)

**Updated 20.10.2026:** the Postgres restore test is done (logical restore, PASS). Wording that said "result pending" has been replaced.

Status as of 20.10.2026. Every statement below is marked as verified in code or on-chain, per founder notes, or unverified. Where something is not in place, it is listed under Gaps with a target date.

**Owner of security and compliance:** Amir Latypov, founder. Sole operator. No other staff with production access. Single point of failure, acknowledged.
**Legal entity:** none yet. Predge is not incorporated. A Delaware C-Corp via Clerky is planned. No DPA, SLA or contract can be signed in an entity's name until incorporation.
**Contact:** hello@predge.io. Incidents: hello@predge.io and X @PredgeAI.

## 1. What Predge does, and does not do

- **Does:** issues signed verdicts (`delivered`, `not_delivered`, `inconclusive`) on a paid job, with a refund recommendation. Anyone can check a signature offline against the published ed25519 key. First vertical: signed settlement-risk records for Polymarket. Also a paid whale/smart-money data API over x402.
- **Does not:** the API and dispute service never hold, move or refund customer funds. Verified in code: every verdict carries `refund.status = "recommendation_only"`. The merchant moves the money.
- **Qualification:** the on-chain contracts (AgentJob escrow, validator bond, refund arbiter) can hold funds if used. As of 20.10.2026 the canonical contracts held a zero balance on Arc, Ethereum, Arbitrum and Base, with no jobs, bonds or rulings. The other 12 chains were not checked. Whether any on-chain path is a custody activity under applicable law is an open legal question (see Gaps G12).

## 2. Architecture and data flow

1. A caller (agent or merchant) sends `POST /v1/verdicts` with the job spec, the delivery evidence (HTTP status, content type, body SHA-256, body size, latency) and a payment reference.
2. Predge runs deterministic checks, stores the signed record in Postgres, and returns the verdict with a refund recommendation.
3. The caller or any third party verifies the signature offline with the public key from `https://api.predge.io/.well-known/predge-keys.json`, or calls `GET /verify`.
4. Paid calls settle in USDC over x402 through facilitators. The API serves the response only on a 2xx, so a refused call is not charged (verified in code comments).
5. The web app (predge.io, Vercel) serves the docs, sign-in (Privy), checkout (Paddle, NOWPayments) and the Desk alerts settings. Desk alerts go to customer webhooks (HMAC-signed) or Telegram.

## 3. Sub-processors

| Provider | Role | Status |
|---|---|---|
| Railway | Hosts API, Postgres, Redis, bot services | Verified: services and Postgres are on Railway (founder notes). Region not pinned in repo: unverified |
| Vercel | predge.io web app, Vercel Analytics, Speed Insights | Verified in code |
| Zoho Mail (EU) | hello@predge.io mailbox | Per founder notes; not in code |
| Name.com | DNS (per founder notes) | Per founder notes; not in code |
| Privy | Sign-in (email, wallet) | Verified in code |
| Paddle | Card checkout | Verified in code |
| NOWPayments | Crypto checkout | Verified in code |
| Telegram | Bot and Desk alert delivery | Verified in code |
| PostHog | Web analytics, only when key is set | Verified in code; enabled state unverified |
| Sentry | Error reporting (web and API), only when DSN is set | Verified in code; enabled state unverified |
| Cloudflare Turnstile | Signup bot check, only when secret is set | Verified in code; enabled state unverified |
| x402 facilitators | Verify and settle paid calls: x402.org (code default), PayAI (Base, Solana), Circle Facilitator Service (Arc), GoPlausible (Algorand), Monad facilitator. Coinbase CDP optional, off by default | Verified in code; which are live depends on production env, unverified |
| Public RPC | Polygon reads for settlement risk (tenderly, publicnode, drpc by default); Arc and Monad RPC | Verified in code defaults; production env unverified |
| Polymarket APIs | Data sources (not processing customer data) | Verified in code |
| Anthropic | Optional AI one-sentence comment on Pro-tier whale alerts (trade, wallet and market context), only when the API key is set | Verified in code (bot repo); enabled state unverified |
| GitHub, npm | Source code and packages (no customer data by design) | Development tooling |

Correction 20.10.2026: an earlier draft said no Anthropic API use exists. That was wrong. The bot repo (predgeAI/predge) calls the Anthropic API from `packages/ai/commentary.py` to add a one-sentence comment to Pro-tier whale alerts. It runs only when `ANTHROPIC_API_KEY` is set (whether it is set in production is unverified) and sends trade, wallet and market context. Anthropic is therefore a conditional sub-processor and the terms page entry stays. Separately, the package `@circle-fin/developer-controlled-wallets` is declared but never imported in the x402 API repo. Both are listed in Gaps G15.

## 4. Data we store and retention

Verified in the table definitions and handlers:

- **pilot_keys, desk_accounts, signups:** key hashes only for API keys (SHA-256). Signups keep email, company, use case, key id, and a hash of the client IP. Desk accounts keep wallet addresses, Telegram chat ids, the webhook URL, and the **webhook HMAC secret in plaintext** (needed to sign).
- **x402_payments:** payer address, route, price, network, settlement tx, user agent, referer.
- **verdicts:** the job spec including the endpoint URL as submitted, delivery status, content type, body hash and size, latency, payment reference (payer, payee, tx), optional `buyer_id` and `merchant_id` (up to 128 characters each, caller-supplied), agent identity fields, and the signed record. **The raw delivered body is not stored**, only its hash.
- **signed_calls, signal_stakes, attestations:** public-chain-derived records and caller notes (free text).
- **Web:** PostHog page events, Sentry error reports, account data via Privy.

**Retention:** there is no automatic deletion. No purge job exists in either repo. The only deletes are user-triggered removals of push subscriptions and decisions. The public privacy page states durations (bot logs 90 days, server logs 30 days, analytics 12 months, backups 30 days, payment records 7 years, accounts until deletion plus 90 days). These are **not enforced by code**. Gap G6.

**Deletion requests:** by email to hello@predge.io, handled manually by the owner, within 30 days (per privacy page). No self-serve deletion.

**Known issue:** the signup IP hash is `SHA-256("predge-signup-v1:" + ip)`. That prefix is a fixed public string, not a secret salt. An IPv4 address space can be enumerated, so the hash can be reversed. Gap G7.

## 5. Keys and custody

- **Attestation signing key:** one ed25519 key, `kid 13fa3d18a369e6c7`. Public key published at `api.predge.io/.well-known/predge-keys.json`. Private key held in a Railway environment variable (`ATTEST_SIGNING_KEY`) and loaded into the API process. No HSM, KMS, MPC or dual control. Access is limited to Railway project members. MFA status unverified (Gap G9).
- **Second published key:** `kid a122cc095c0f7fe5`, role `cachet-oracle`. It signs market resolutions from an operator machine, not from the API. It is listed in the same registry.
- **Revocation:** the registry has no status or revocation field. The rotation text says a compromised key is "removed immediately", and the handler emits only the current key. `GET /verify` returns `valid: true` for any signature that checks against the supplied key, and reports `key_published: false` once the key is removed. A verifier that reads only `valid` will accept a compromised key's signatures. Gap G5.
- **Contract owner:** one externally owned account, the deployer `0x5d016C1B4d7A42eB7c982da1Ae7fFdB958CFCAe9`, is owner, validator and operator of the canonical contracts on the 16 chains. The key file is on a founder workstation (`~/.predge-deployer/deployer.json`, permissions 0600). No ownership transfer function exists in v1 (review finding M-01). Gap G2.
- **Webhook secrets:** one per Desk account, shown once, stored in plaintext in Postgres. Gap G8.
- **Pending credential hygiene:** the 03.10 infra audit listed a Telegram bot token and an OpenAI key for rotation. Current status is unverified (Gap G9).

## 6. Contracts and audits

- **Six canonical contracts** (PredgeAgentValidator, AgentJob, PredgeValidatorBond, PredgeSettlement, MockRefundProtocol, PredgeRefundArbiter). Same addresses on 16 EVM mainnets: Ethereum, Base, BNB, Celo, Polygon, Optimism, Arbitrum, Avalanche, Gnosis, Linea, Unichain, Sonic, Mantle, Monad, Robinhood Chain, Arc.
- **Verified on Sourcify (exact_match) on all 16 chains** for PredgeAgentValidator, checked 20.10.2026. I checked one of the six contracts per chain. The other five are not individually re-checked here.
- **Source:** github.com/predgeAI/predge-deploy (public).
- **Status: v1 reference with known issues.** Our own manual review on 20.10.2026 found:
  - **H-01:** a verdict recorded before submission can be reclaimed unchallenged.
  - **H-02:** the expected output is public, so an honest score-0 verdict can be slashed. Committing after submission makes the bond meaningless.
  - **H-03:** after a ruling, a challenge can never succeed. Evidence is not bound to the payment parties, and refunds execute before the window closes.
  - **M-01:** a single externally owned account is owner with no ownership transfer.
  - Plus M-02 to M-05, L-01 to L-07 and info items. The full list is in the review and will ship with v2.
- **Fixes:** the 03.10 internal review was reported as closed. The 20.10 review found that several fixes are incomplete (F3, F5, F6 open; H-01 and H-03 introduced or exposed by the F1 and F2 changes). The 03.10 "all fixed" wording is superseded.
- **Plan:** v2 contracts with fixes, a Safe multisig owner and a separate operations key, targeted for 09.11.2026. External scan through Circle's accelerator (Olympix) next. External audit after v2.
- **Not done:** external penetration test (Vaultline application, decision expected 02.11 per notes). No bug bounty.

On-chain bonds and verdicts are therefore not a security guarantee in v1. Do not rely on them for value.

## 7. Backups and recovery

- **Postgres (Railway):** daily backups kept 6 days and weekly kept 27 days, configured 03.10.2026 (founder notes). Not verified by me. Encryption of backups unverified.
- **Redis:** weekly backups (founder notes).
- **Restore test: PASS on 20.10.2026.** A logical restore of all 29 business tables (28 in `public`, plus `support.support_tickets`) from a consistent snapshot of production into an isolated PostgreSQL 18.6 matched exactly: same row counts, same primary-key checksums, same full-row checksums, same schema objects. About 17 seconds end to end (dump 1.7 s, restore 2.2 s; the dump is 15.6 MB). The two history tables, `trades` (about 9.2 GB) and `wallet_score_history` (about 795 MB), were restored schema-only, so their data was not tested. Production was only read.
- **What this test does not show (remaining gaps, G1):** it was not a restore of a Railway volume snapshot, so the time to restore the whole 10 GB database is not measured. There is no point-in-time recovery (no WAL archiving, no replicas), so worst-case data loss is up to 24 hours on the daily backup schedule. All backups sit with the same provider, account and region as production; the off-site GitHub Actions backup to Cloudflare R2 has been failing since 27.04.2026 because its secrets are missing. There is one instance in one region and no standby.
- **RPO and RTO:** not defined yet. Gap G16.
- **Signing key recovery:** no offline sealed copy of `ATTEST_SIGNING_KEY` is documented. Losing it means the kid can no longer sign. Gap G18.

## 8. Incident response and contact

Owner: Amir Latypov. Channels: hello@predge.io, X @PredgeAI, and a status section on this page (not yet live, Gap G17). Full runbook: INCIDENT-RESPONSE.md. No status page or uptime history exists yet.

## 9. What we can prove today

- Public key registry: `https://api.predge.io/.well-known/predge-keys.json`
- Offline or hosted check: `https://api.predge.io/verify`, and free re-read `GET /v1/verdicts/:id`
- Contract source on Sourcify, for example Base: `https://sourcify.dev/#/contracts/8453/0x925767fdce6C819F027f55CC50464e3bCdfD2671`
- Contract repo: `https://github.com/predgeAI/predge-deploy`
- Our 20.10.2026 self-review, summary published with this page.

We can show one logical restore test of the critical tables (PASS, 20.10.2026). We cannot prove today: SOC 2, ISO 27001, an external pentest, a restore from a Railway volume snapshot, point-in-time recovery, off-site backups, a signed DPA, insurance, or an uptime history.

## 10. Gaps and target dates

Dates marked "proposed" are my suggestions and need owner confirmation before they are published as commitments.

| # | Gap | Target |
|---|---|---|
| G1 | Postgres recovery. Logical restore test of the 29 business tables: PASS 20.10.2026. Still open: restore drill from a Railway snapshot into a new service; point-in-time recovery (WAL archiving); working off-site backup (R2 workflow failing since 27.04, missing secrets); single region | Logical test done 20.10.2026. Remaining items: no date committed |
| G2 | Contract owner from one EOA to Safe 2-of-3, and a separate operations key | 09.11.2026 (with v2). Interim key split via setValidator/setOperator: 27.10.2026 (proposed) |
| G3 | v2 contracts fixing H-01 to H-03 and M-01 to M-05 | 09.11.2026 |
| G4 | Olympix scan via Circle accelerator | Before 09.11.2026 |
| G5 | Revocation status in the key registry, and `/verify` returns invalid for revoked keys | 06.11.2026 (proposed) |
| G6 | Retention: align privacy page with reality (27.10.2026, proposed); purge jobs (30.11.2026, proposed) | See date |
| G7 | Replace the signup IP hash with a keyed HMAC using a secret | 13.11.2026 (proposed) |
| G8 | Encrypt Desk webhook secrets at rest | 13.11.2026 (proposed) |
| G9 | MFA on GitHub, Railway, Vercel, Zoho, Name.com, npm, Circle; FileVault and firewall on; leaked tokens rotated | 24.10.2026 (proposed) |
| G10 | External penetration test | Vaultline outcome 02.11.2026; test complete by 15.01.2027 (notes) |
| G11 | DPA signed with customers | After incorporation. Template ready 20.10.2026 |
| G12 | Counsel view on whether bond and escrow contracts count as holding funds | Before any on-chain bond is used with a customer; quote by 09.11.2026 (proposed) |
| G13 | SOC 2 | Decision after pre-seed close. No date committed |
| G14 | ISO 27001 | Not planned for 2026 |
| G15 | Confirm whether Anthropic commentary is enabled in production and disclose it in the privacy page; remove unused Circle package | 27.10.2026 (proposed) |
| G16 | RPO and RTO defined and tested | 27.10.2026 (proposed) |
| G17 | Status section and uptime history on this page | Section 27.10.2026 (proposed); history starts on publication |
| G18 | Offline sealed backup and recovery plan for the signing key | 27.10.2026 (proposed) |
| G19 | Cyber and professional liability insurance | After incorporation. No date |
| G20 | Legal entity incorporated | Delaware planned via Clerky. No date committed |
| G21 | Public terms and privacy residency statement (US and EU) verified against Railway and Vercel regions | 27.10.2026 (proposed) |

## 11. Downloads

- SECURITY-QUESTIONNAIRE.md
- DPA-TEMPLATE.md
- SLA.md
- INCIDENT-RESPONSE.md
- TABLETOP-2026-10-20-signing-key-leak.md
