A pre-execution firewall for autonomous agents. ProofGate buys a URL safety
verdict through Telegraph, applies a local fail-closed policy, and performs the
requested network action only after an ALLOW decision. Every decision,
payment receipt, and action result is written to a tamper-evident audit chain.
- Live console: https://proofgate-six.vercel.app
- Miner declaration: https://proofgate-six.vercel.app/miner.yaml
- Track 2 scorer:
proofgate-url-scorer.wasm - Source: https://github.com/karan68/proofgate
- Verified settlement: 0.01 USDC on Base Sepolia
- Track 1 submission: verified Miner registration
386
Current production safety state: the public deployment intentionally has no payer key (
payment_ready: false). Discovery, health, the ProofGate Miner, Miner YAML, and the console are live. Paid guard execution remains disabled until an operator explicitly enables it. Replacement registration386is active on-chain and in Telegraph's node, and the Track 1 portal submission is saved and verified against item386. The Track 2 scorer registrations1810,1814, and1816were each rejected at 12/15 hidden ordering wins. The saved Track 2 portal entry still points to rejected1814; ProofGate does not claim an accepted Track 2 registration.
A URL scanner answers a question. ProofGate enforces a boundary.
Autonomous agents routinely receive links from email, retrieval systems, tickets, browser tasks, and other agents. A confidence score in a dashboard does not prevent the next tool call. ProofGate sits on that tool boundary:
- Normalize and validate the requested public URL.
- Discover the current Telegraph
URL_SCANMiner pool. - Select a Miner whose live contract declares synchronous
verdictandconfidenceoutput. - Pay only a compatible Base Sepolia x402 requirement within a hard cap.
- Normalize the Miner result and apply local
ALLOW / WARN / BLOCKpolicy. - Execute a DNS-pinned
GETorHEADonly afterALLOW. - Append the scan, settlement, action, and previous record hash to the ledger.
flowchart LR
A[Agent requests a URL action] --> V[URL and DNS validation]
V --> D[Discover live URL_SCAN Miners]
D --> S[Select compatible contract]
S -->|capped x402| M[Telegraph Miner]
M --> P{Local policy}
P -->|ALLOW| E[DNS-pinned GET or HEAD]
P -->|WARN| W[Withhold action]
P -->|BLOCK| B[Withhold action]
E --> L[Hash-chained audit record]
W --> L
B --> L
| Surface | Implemented behavior |
|---|---|
| Agent firewall | Scan-only and guard-and-execute modes with GET / HEAD controls |
| Telegraph client | Live intent discovery, contract-based Miner selection, capped x402 payment, settlement decoding |
| Local policy | Deterministic ALLOW, WARN, BLOCK; unknown or under-confident answers fail closed |
| Guarded executor | Public HTTP(S) only, DNS pinning, TLS SNI preservation, standard ports, manual redirects, bounded bodies |
| ProofGate Miner | Eight live evidence sources plus a bounded, sourced 10-incident history catalog; the only target contact is one pinned, redirect-free HEAD |
| Audit ledger | Canonical SHA-256 chain, JSONL locally, atomic Redis compare-and-append in serverless production |
| MCP server | Four MCP v2 stdio tools for status, scan, guarded fetch, and audit tail |
| Web console | Live Miner pool, payment readiness, operator auth, evidence, receipts, execution result, audit history |
| Production controls | Constant-time bearer auth, per-identity distributed limits, security headers, secret-free public deployment |
| Registration | Dynamic Miner YAML plus dry-run-first Base Sepolia registration tooling |
| Track 2 scorer | Import-free URL_SCAN WASM with deterministic fact binding and bounded semantic credit |
| Continuous verification | GitHub Actions: install, typegen/typecheck, lint, tests, app build, MCP build, dependency audit |
Historical URL_SCAN questions are handled independently from live URL safety.
An exact historical hostname can return its documented account while retaining
the separately computed live verdict. A legitimate publisher URL whose path or
question mentions malware remains classified from its live evidence; the
incident is attached as context, not treated as evidence against the publisher.
Unknown no-URL incidents return a zero-confidence abstention instead of invented
facts. Run npm run history:replay to score all 10 unique public historical
question/ground-truth pairs against the pinned URL_SCAN champion binary.
ProofGate includes a standalone, import-free Rust scoring module for
Telegraph validators. It is intentionally specialized for URL_SCAN: a
security verdict should not receive credit merely because it repeats the right
keywords while changing the target, count, source, or conclusion.
The module exports linear memory plus the required ABI:
alloc(size: i32) -> i32
dealloc(ptr: i32, size: i32)
rank_answer(
question_ptr: i32, question_len: i32,
ground_truth_ptr: i32, ground_truth_len: i32,
answer_ptr: i32, answer_len: i32
) -> f32
The scorer uses a 2 MiB per-call input arena and scans at most 128 KiB and 384 tokens per input. The arena resets after each score and traps rather than returning overlapping memory if a caller exceeds it. The scorer performs:
- exact significant-token matching
- URL, host, IP, and long-hash identity binding
- safe, malicious, suspicious, boolean, and negation-aware verdict extraction
- field-aware numeric checks for engine counts and reputation values
- confirmation, source-agreement, entity-swap, and mixed-verdict checks
- bounded GloVe similarity for unmatched ordinary content words
- weighted recall/precision scoring when no deterministic verdict rail applies
Verdict-looking words inside identifiers, such as secure in a hostname, are
treated as target data rather than as an answer. Blank answers score 0, exact
answers score 1, and all paths return a finite f32 in [0, 1].
Semantic credit is capped at 35% and cannot override target, verdict, numeric,
entity, direction, scale, or relation conflicts. The packed vector asset and
licenses are recorded in THIRD_PARTY_NOTICES.md.
| Field | Value |
|---|---|
| Intent | URL_SCAN |
| Artifact | public/wasm/proofgate-url-scorer.wasm |
| Compiled size | 817,538 bytes |
| Keccak-256 | 0xc04a107cdeab50dca4b0d06cd4f2a48c0fc64e3eef0767f7d82d6dc43e0147b7 |
| Imports | 0 |
| Required exports | memory, alloc, dealloc, rank_answer |
| Toolchain | Rust 1.96.1, target wasm32-unknown-unknown |
| Registration | 1816 rejected: candidate 12/15, champion 15/15 |
Build and verify it from source:
npm run wasm:test
npm run wasm:verify
npm run wasm:build
npm run wasm:benchmarkThe verify command checks the committed artifact's registered Keccak plus its size, imports, ABI, 10,000-call repeatability, and oversized-allocation trap. The benchmark command runs against those exact committed bytes and exits nonzero unless every pinned independent URL case is ordered correctly and every pinned URL attack passes. CI then compiles the source independently; Rust does not guarantee byte-identical WASM output across host operating systems.
The comparison uses the current live champion binary from
zkasuran/telegraph-salience-scorer@0174a85
and URL-specific corpora pinned to
sneg55/verdictlock@9f06db3.
| Public corpus | ProofGate | Live champion |
|---|---|---|
| Telegraph fixture, URL ordering | 1/1, margin 1.0000 |
1/1, margin 1.0000 |
| Independent URL ordering | 26/26, margin 0.9599 |
20/26, margin 0.4103 |
| URL gaming/robustness attacks | 18/18 |
9/18 |
| Independent gate-stress ordering | 26/26, margin 0.8428 |
22/26, margin 0.6072 |
These public corpora are development proxies, not Telegraph's private promotion
evaluator. The 26/26 and 18/18 results are reproducible evidence, not a claim
that this module passes Telegraph's private evaluation. Registrations 1810,
1814, and 1816 each achieved 12/15 private ordering wins versus the
champion's 15/15 and were rejected. For 1816, the current vector-assisted
artifact scored margin 0.7189615 against the champion's 0.94808555. Its
semantic layer improved both pinned public margins but recovered no hidden win.
This screenshot is a replay of the recorded audit receipt, not a new request.
The underlying run selected Telegraph Miner 5001 (URL Sentinel), returned
safe at 0.90 confidence, settled exactly 0.01 USDC, executed the pinned
request, received HTTP 200 with 559 bytes, and appended an ACTION record.
| Evidence | Verified value |
|---|---|
| Intent | URL_SCAN |
| Miner | URL Sentinel (5001) |
| Policy | ALLOW at 0.90 confidence; threshold 0.80 |
| x402 | 0.01 Base Sepolia USDC |
| Transaction | 0xfb8e49d1...ee316585 |
| Independent receipt check | Successful receipt in block 45,680,053; exact 0.01 USDC transfer to Telegraph Diamond |
| Guarded action | GET https://example.com/ -> HTTP 200, 559 bytes |
| Audit | ACTION, decision ALLOW, record hash 2c7d71af...32b7a27 |
This is a deterministic no-payment fixture captured with /api/guard
intercepted before the request left Chrome. It demonstrates that a nominally
safe result with only 0.65 confidence remains WARN; unavailable reputation
providers never count as clean evidence.
This is a deterministic no-payment fixture using an invalid fixture domain.
No malicious site was contacted. It demonstrates malicious-source precedence
and confirms that execution is explicitly shown as withheld.
The mobile capture is a direct public-production screenshot. No key or payment was used.
Screenshot provenance and exact reproduction instructions are in
docs/VERIFICATION.md.
ProofGate does not let a Miner decide whether an action executes. Miners produce evidence; the local policy owns enforcement.
| Normalized finding | Confidence | Decision | Action |
|---|---|---|---|
malicious |
any | BLOCK |
Withheld |
suspicious |
any | WARN |
Withheld |
pending or unknown |
any | WARN |
Withheld |
safe |
missing | WARN |
Withheld |
safe |
below 0.80 |
WARN |
Withheld |
safe |
0.80 or greater |
ALLOW |
May execute if requested |
Policy option domains are validated. Confidence is finite and bounded to
[0, 1]; the VirusTotal harmless-engine threshold must be a non-negative safe
integer.
ProofGate deliberately avoids LLM intent classification for enforcement. It selects from Telegraph's machine-readable integration catalog.
A candidate must declare all of the following before ProofGate can pay it:
URL_SCANinsupported_intents- a synchronous
POST /scanendpoint - a
urlinput field verdictandconfidenceoutput fields- signal mapping to those fields
- a price no greater than
PROOFGATE_MAX_TELEGRAPH_PAYMENT_ATOMIC - a slug other than ProofGate's own Miner, preventing routing loops
The selected endpoint is called through Telegraph's Miner dispatcher using
@x402/fetch and @x402/evm. Requirements are filtered before signing:
- network must equal
eip155:84532 - amount must be an integer
- amount must not exceed the configured cap
The payment signer uses a dedicated Base Sepolia burner account. x402 uses an EIP-3009 authorization, so payer gas is not required for inference payments. The production deployment currently has no signer by design.
ProofGate also exposes its own deterministic URL_SCAN Miner at
POST /api/miner/scan. It gathers metadata, reputation and bounded historical
evidence, and adds one bounded HEAD reachability probe. It never renders,
executes, or downloads the target.
| Source | Always available | Signal |
|---|---|---|
| URL structure | Yes | HTTP, punycode, literal IP, shortener, executable path |
| DNS | Yes | Resolution and public-address validation |
| Reachability | Yes, network permitting | HTTP status, scheme and declared redirect from one HEAD request |
| RDAP | Yes, network permitting | Domain registration age; under 30 days is suspicious |
| PhishTank | With key | Verified phishing database match |
| Google Safe Browsing | With key | Malware/social-engineering threat match |
| URLhaus | With key | Exact malware distribution URL match |
| VirusTotal | With key | Multi-engine malicious/suspicious/harmless counts |
The reachability probe is deliberately narrow. It runs only after
assertPublicTarget has resolved the hostname and rejected every private,
loopback and reserved address; it is pinned to that validated address through the
same undici connector the guarded execution path uses, so a second DNS answer
cannot redirect it inward; it sends HEAD only, does not follow redirects, reads
no response body, and times out after 5 seconds. A probe that fails is recorded
as a name in not_observed and never becomes a verdict.
The benign verdict is no_threat_signal, not safe. ProofGate reports that it
found no threat evidence; it does not certify that a URL is safe.
Aggregation is deterministic:
- one authoritative malicious match ->
malicious, confidence0.97 - two or more malicious sources -> confidence
0.995 - suspicious evidence -> confidence
0.62or0.72 - no clean reputation provider -> safe finding at
0.65(policy still warns) - one clean reputation provider -> confidence
0.86 - two or more clean reputation providers -> confidence
0.96
Missing, failed, or rate-limited providers are reported as unavailable or
error. They are never silently converted into clean votes.
Example:
Invoke-RestMethod `
-Method Post `
-Uri https://proofgate-six.vercel.app/api/miner/scan `
-ContentType application/json `
-Body '{"url":"https://example.com"}'A scan result alone never opens a socket. Execution begins only after policy
returns ALLOW and the caller requested execution.
Security controls:
- only
http:andhttps:URLs - embedded credentials rejected
- localhost, metadata hosts, and private hostname suffixes rejected
- private, loopback, link-local, multicast, carrier-grade NAT, and reserved IPs rejected
- every DNS answer validated; one private answer rejects the target
- connection pinned to a validated address while preserving TLS SNI and Host
- standard ports only: HTTP 80 and HTTPS 443
- methods limited to
GETandHEAD - redirects handled manually and never followed automatically
- default response limit
256 KiB; hard maximum1 MiB - text preview sanitized and capped at 2,000 bytes
- connection, header, body, and overall request timeouts
- optional target-origin x402 payment subject to its own lower cap
Each record contains:
- UUID and timestamp
SCANorACTION- normalized target and policy decision
- finding, confidence, reason, and evidence
- Miner ID/name, intent, signal hash, cost, duration, settlement receipt
- execution attempt, HTTP status, bytes, final URL, redirect, preview, error
previous_hashrecord_hash
Records are hashed from canonical JSON with sorted object keys.
Local development stores newline-delimited JSON at
data/proofgate-audit.jsonl unless overridden. Writes are serialized in one
process, and the entire chain is verified before append.
Vercel uses an Upstash-compatible Redis REST backend. A Lua compare-and-append
operation atomically verifies the current tail hash before RPUSH. Independent
instances retry if another writer advanced the chain. Production guard requests
verify storage before beginning a paid scan.
The chain detects modification, insertion, deletion from the middle, and
reordering. It is tamper-evident, not encrypted, and cannot independently prove
that the newest tail was not truncated; see SECURITY.md.
/api/guard and /api/audit require
Authorization: Bearer <PROOFGATE_API_KEY> in production. Comparison is
constant-time after SHA-256 normalization.
| Scope | Limit | Identity |
|---|---|---|
| Guard | 10 requests/minute | bearer credential + source IP hash |
| Audit | 60 requests/minute | bearer credential + source IP hash |
| Public Miner | 120 requests/minute | anonymous marker + source IP hash |
Redis provides distributed counters in production. Local development uses an in-memory fallback. Live production verification observed ten schema refusals followed by two HTTP 429 responses, without reaching Telegraph or payment code.
| Route | Method | Auth | Rate limit | Payment | Purpose |
|---|---|---|---|---|---|
/api/health |
GET |
Public | - | No | Version, time, Telegraph readiness, provider flags |
/api/network |
GET |
Public | - | No | Live URL_SCAN discovery and runtime policy |
/api/miner/scan |
GET |
Public | - | No | Miner/provider readiness |
/api/miner/scan |
POST |
Public | 120/min | No | ProofGate's metadata/reputation URL scan |
/api/guard |
POST |
Bearer in production | 10/min | Telegraph x402 | Scan, policy, optional execution, audit |
/api/audit?limit=50 |
GET |
Bearer in production | 60/min | No | Recent records and chain integrity; max 500 |
/miner.yaml |
GET |
Public | - | No | Dynamic Telegraph Miner declaration |
Guard request:
{
"url": "https://example.com",
"execute": true,
"method": "GET"
}Representative error contracts:
| Status | Error | Meaning |
|---|---|---|
| 400 | invalid_request, invalid_json, unsafe_target |
Input or target rejected before payment |
| 401 | unauthorized |
Missing or wrong operator bearer key |
| 429 | rate_limited |
Scope quota exceeded; includes Retry-After |
| 502 | telegraph_request_failed, target_execution_failed |
Upstream scan or guarded action failed |
| 503 | payment_not_configured, storage_not_configured, operator_access_not_configured |
Required production control is absent |
ProofGate ships a stable MCP v2 stdio server built with
@modelcontextprotocol/server.
| Tool | Payment | Target fetch | Purpose |
|---|---|---|---|
proofgate_network_status |
No | No | Runtime readiness and live Miner pool |
proofgate_scan |
Telegraph x402 | No action execution | Intent-bound scan and policy decision |
proofgate_guarded_fetch |
Telegraph x402; target x402 if required | Only after ALLOW |
Guarded GET / HEAD |
proofgate_audit_tail |
No | No | Recent records and chain verification |
Build and run the real client handshake:
npm run mcp:build
npm run mcp:smokeThe smoke client spawns the bundled server, completes MCP initialization, lists all four tools, calls live free discovery and audit, checks chain integrity, and verifies three invalid inputs are rejected. stdout is reserved for JSON-RPC; diagnostics use stderr.
VS Code configuration is included in .vscode/mcp.json.
GET /miner.yaml emits a structured declaration containing identity, endpoint,
input/output schemas, signal mapping, limits, docs, and direct on-chain field
mapping. Non-local public origins must use HTTPS and cannot contain URL
credentials.
Registration tooling follows Telegraph's official permissionless flow against the current Base Sepolia Diamond:
$env:PROOFGATE_MINER_YAML_URL="https://proofgate-six.vercel.app/miner.yaml"
npm run registration:check # read-only: fetch, hash, validate, check balances
npm run registration:submit # sends the on-chain registerMiner transactionTrack 2 registration separately requires a commit-pinned raw GitHub URL. The
check command fetches that URL, compares its bytes to the local artifact,
recomputes Keccak-256, reads canonical intents, and simulates registerWasm
before submit mode can send a gas-only transaction:
$env:PROOFGATE_WASM_URL="https://raw.githubusercontent.com/karan68/proofgate/<40-character-commit>/public/wasm/proofgate-url-scorer.wasm"
npm run wasm:registration:check
npm run wasm:registration:submitRegistration was completed with the fresh burner wallet:
- registration
309was created on-chain, then rejected by Telegraph's updated YAML validator because four mapped output descriptions were required - commit
4450182added those four schema-required descriptions updateMiner(309, ...)created replacement registration310updateMiner(310, ...)declared the endpoint'sURL_SCANintent and requiredurlbody parameter, creating active replacement registration384updateMiner(384, ...)preserved the canonical URL contract, added bounded historical-question input and answer-first output, and created replacement registration386- registration
386is confirmed active on-chain with YAML SHA-256a7783891544380f745c860cf704d25b8ee9c8b935b9cb90cea62964a368be5a1 - Telegraph's node exposes
386as active with no rejection or retry and the exact registered YAML hash - the node also still exposes retired on-chain registration
384as active; this stale duplicate is a Telegraph indexing inconsistency, while the portal is pinned to replacement386 - the existing Track 1 portal submission
6a930a4aae9ddfbc70a760d9was edited in place and is saved and verified with item386 - X username:
@karanyadav38450 - the wallet retained all
1testnet USDC; registration used only test ETH gas
Public transaction evidence:
- initial registration
- schema-correcting update
- request-contract update
- historical-answer contract update
Latest on-chain metadata:
- Base Sepolia registration ID:
386 - Miner slug:
proofgate-url-intelligence - YAML SHA-256:
0xa7783891544380f745c860cf704d25b8ee9c8b935b9cb90cea62964a368be5a1 1testnet USDC- hosted YAML SHA-256 verified
- all descriptor checks passed
- node activation: active, no rejection, no retry
- stale node state: retired on-chain registration
384is still also listed - portal item:
386, saved and verified
The known chat-exposed test address remains hard-blocked by the registration script and was not used for registration or submission.
- Node.js 20 or newer; CI uses Node.js 22
- npm
- optional provider keys for stronger local Miner coverage
- optional dedicated Base Sepolia burner for paid integration testing
git clone https://github.com/karan68/proofgate.git
Set-Location proofgate
npm ci
Copy-Item .env.example .env.local
npm run devOpen http://localhost:3000.
Free surfaces work without a wallet. Do not paste secrets into chat, shell
history, screenshots, browser-local storage, or NEXT_PUBLIC_* variables.
| Variable | Required | Purpose | Default |
|---|---|---|---|
TELEGRAPH_EVM_PRIVATE_KEY |
Paid scans only | Dedicated Base Sepolia x402 signer | unset |
TELEGRAPH_NODE_URL |
No | Telegraph node origin | https://devnode.telegraphprotocol.com |
PROOFGATE_MAX_TELEGRAPH_PAYMENT_ATOMIC |
No | Per Telegraph payment ceiling | 100000 ($0.10) |
PROOFGATE_MAX_TARGET_PAYMENT_ATOMIC |
No | Per target-origin x402 ceiling | 50000 ($0.05) |
PROOFGATE_API_KEY |
Production guard/audit | Operator bearer credential | unset |
PROOFGATE_PUBLIC_URL |
Publishing | Canonical HTTPS app origin | local request origin |
PROOFGATE_MINER_YAML_URL |
Registration script | Exact hosted YAML URL | <public URL>/miner.yaml |
PROOFGATE_WASM_URL |
Track 2 registration | Commit-pinned raw GitHub artifact URL | unset |
PROOFGATE_MINER_ID |
Miner YAML | Registration ID placeholder/metadata | 7402 |
PROOFGATE_REPOSITORY_URL |
Publishing | Public source URL in YAML | unset |
PROOFGATE_AUDIT_FILE |
Local optional | JSONL path override | data/proofgate-audit.jsonl |
PROOFGATE_AUDIT_REDIS_KEY |
Redis optional | Audit list key | proofgate:audit:v1 |
UPSTASH_REDIS_REST_URL |
Serverless audit | Redis REST URL | unset |
UPSTASH_REDIS_REST_TOKEN |
Serverless audit | Redis REST token | unset |
KV_REST_API_URL, KV_REST_API_TOKEN |
Vercel alternative | Marketplace aliases | unset |
PHISHTANK_APP_KEY |
Optional | PhishTank evidence | unset |
GOOGLE_SAFE_BROWSING_API_KEY |
Optional | Safe Browsing evidence | unset |
URLHAUS_AUTH_KEY |
Optional | URLhaus evidence | unset |
VIRUSTOTAL_API_KEY |
Optional | VirusTotal evidence | unset |
BASE_SEPOLIA_RPC_URL |
Registration optional | Registration RPC override | public RPC fallback |
Current verified baseline:
| Gate | Result |
|---|---|
| TypeScript | clean after next typegen |
| ESLint | clean |
| Vitest | 120 passed, 0 failed across 13 files |
| Historical scorer replay | candidate mean 0.981413, minimum 0.815805, 10/10 wins versus best recorded fields |
| Coverage | previous 74-test baseline retained in the verification ledger; not rerun for this release |
| Next.js production build | passed; all routes generated |
| MCP build and real stdio handshake | passed |
| npm audit | 0 vulnerabilities |
| Live API parameter matrix | 28/28 expected statuses |
| Production responsive checks | 1440x900 and 390x844, no horizontal overflow |
| Public GitHub CI | schema-fix run passed |
| Miner registration | replacement ID 386 active on-chain and in the node with matching deployed YAML |
| Track 1 submission | item 386 saved and verified in portal submission 6a930a4aae9ddfbc70a760d9 |
| Track 2 scorer tests | 18 passed, 0 failed; vector lookup, arbitrary bytes, and 200 KiB input included |
| Track 2 artifact | 817,538 bytes; 0 imports; required ABI exports present |
| Track 2 public URL benchmark | 26/26 core, 26/26 stress, and 18/18 attacks on pinned corpora |
Run locally:
npm run typecheck
npm run lint
npm test
npm exec -- vitest run --coverage
npm run build
npm run mcp:build
npm run mcp:smoke
npm auditFull evidence, screenshot provenance, live-versus-fixture classification, and
verification commands are in docs/VERIFICATION.md.
.github/workflows/ci.yml public verification pipeline
.vscode/mcp.json local MCP host configuration
mcp/server.ts MCP v2 stdio server
scripts/mcp-smoke.ts real MCP client handshake
scripts/register-miner.ts dry-run-first on-chain registration
scripts/register-wasm.ts immutable-byte check, simulation, WASM registration
scripts/benchmark-wasm-scorer.mjs pinned public scorer comparisons and attack gates
scripts/capture-readme-screenshots.mjs reproducible no-payment docs captures
wasm-scorer/src/lib.rs bounded import-free URL_SCAN scoring module
public/wasm/proofgate-url-scorer.wasm compiled Track 2 artifact
src/app/api/* HTTP route handlers
src/app/miner.yaml/route.ts dynamic Miner declaration
src/components/proofgate-console.tsx operations UI
src/lib/proofgate/access.ts bearer auth and rate limits
src/lib/proofgate/audit.ts JSONL and atomic Redis audit stores
src/lib/proofgate/execute.ts DNS-pinned guarded execution
src/lib/proofgate/guard.ts scan -> policy -> action orchestration
src/lib/proofgate/miner.ts ProofGate URL intelligence Miner
src/lib/proofgate/policy.ts normalization and decisions
src/lib/proofgate/redis.ts Redis REST transport
src/lib/proofgate/target.ts URL, DNS, IP, and port validation
src/lib/proofgate/telegraph.ts discovery, selection, x402 dispatch
The live deployment uses Vercel with an Upstash Redis integration.
- Import or deploy the GitHub repository.
- Configure non-secret public URL, repository URL, node URL, ID, and caps.
- Attach Redis for persistent audit and distributed rate limits.
- Generate a strong
PROOFGATE_API_KEYas a sensitive variable. - Redeploy and verify unauthenticated audit returns 401 while authenticated audit returns a valid chain.
- Keep the payer key absent until an operator intentionally enables payments.
The committed vercel.json contains no secrets.
.vercelignore, .gitignore, staged-secret scans, and server-only variables
keep local credentials out of source and deployment bundles.
- Production payment is currently disabled by choice; the successful paid run is historical verified evidence, not a claim that the public instance is funded.
- The Miner is registered and Track 1 is verified, but inclusion and ranking in Telegraph's routed Miner pool remain controlled by the protocol.
- Reputation strength depends on configured provider keys. Missing providers reduce confidence instead of being counted clean.
- A clean result is evidence, not proof against zero-day threats.
- Redirects are reported and intentionally not followed; the destination must be submitted as a new guarded action.
- The audit ledger is tamper-evident, not encrypted or externally witnessed.
- Local JSONL serialization is intended for one process; production uses Redis.
- Telegraph and third-party provider availability remain external dependencies.
- Public scorer benchmarks do not reveal or guarantee the private Track 2 result.
- The scorer is intent-specific and remains weaker on lexical paraphrases in the disclosed gate-stress corpus.
- The operator is responsible for key rotation, Redis retention, and protecting target URLs that contain sensitive query parameters.
Security and disclosure guidance: SECURITY.md.
No open-source license has been added. All rights remain with the repository owner unless a license is added later.




