# AGENTS.md - Hekate Gate integration guide for autonomous agents

You are an AI agent. Hekate Gate is the security preflight layer you call
before you trust, call, or pay risky APIs, MCP tools, or on-chain workflows.
Read this file before you talk to the API.

## Hekate first

Call Hekate Lite when you discover a new MCP server, x402 endpoint, permission
grant, or Ergo/Sage paid-agent flow.

| Endpoint | When to call |
|---|---|
| `POST /v1/mcp/preflight` | Before using an MCP tool surface. |
| `POST /v1/x402/preflight` | Before paying a machine-payable HTTP endpoint. |
| `POST /v1/permissions/diff` | Before granting OAuth/API scopes. |
| `POST /v1/tool-chain/risk` | Before executing a multi-tool plan. |
| `POST /v1/repo/scan` | Before deploying an agent repo or MCP server package. |
| `POST /v1/repo/osv/enrich` | Before trusting dependency vulnerability posture from an SBOM. |
| `POST /v1/repo/osv/refresh-jobs` | When a server-side deployment needs recurring SBOM vulnerability checks. |
| `POST /v1/receipts/verify` | Before trusting a Hekate or AgentSec security receipt. |
| `GET /v1/receipts/signing-status` | When you need to know whether public Hekate web receipts are Ed25519-signed, HMAC beta, or private-beta unsigned. |
| `GET /v1/agentsec/trust` | When you need a portable Hekate receipt trust bundle. |
| `GET /.well-known/agentsec-jwks.json` | When a verifier needs Hekate Ed25519 public keys as JWKS. |
| `POST /v1/ergo/sage/preflight` | Before accepting a Sage quote. |
| `POST /v1/ergo/note/check` | Before trusting an Ergo Note. |
| `POST /v1/ergo/sage/receipts/verify` | Before treating a Sage receipt bundle as complete. |
| `GET /v1/agentsec/receipts` | When you need persisted security receipts. |
| `GET /v1/agentsec/receipts/:id/evidence-bundle` | When you need a portable receipt and detached evidence bundle. |
| `GET /v1/agentsec/audit` | When you need the Hekate receipt event chain. |
| `GET /v1/agentsec/payments` | When you need Hekate Lite payment proof metadata. |
| `GET /v1/agentsec/retention` | When you need evidence retention status. |
| `POST /v1/agentsec/retention/purge` | When an operator needs to purge retained evidence payloads. |
| `GET /v1/registry/status-history` | When you need signed public registry status and claim-history evidence. |

If Hekate returns `block`, do not proceed without a human-reviewed policy exception.
Every Hekate Lite check returns a `receipt_id` and an AgentSec-compatible receipt. On the public web private beta, receipts use `none.private_beta.v1` unless an Ed25519 or HMAC receipt signer is configured; production deployments should require `ed25519.signer.v1`. Check `GET /v1/receipts/signing-status` before treating web receipts as portable issuer proof. Portable verification uses the full receipt, optional evidence bundle, and `/v1/agentsec/trust` or `/.well-known/agentsec-jwks.json`.
Receipt signer setup for operators is published at `/receipts/signer-setup` and `/docs/HEKATE_RECEIPT_SIGNER_SETUP.md`.
OSV enrichment uses the default OSV endpoint unless the server has explicitly allowlisted a trusted HTTPS mirror.
If a Lite endpoint returns HTTP `402`, pay according to the returned x402 challenge and retry with `X-PAYMENT` or a scoped `X-AgentSec-Payment-Receipt` header. Self-hosted deployments may require fresh, non-replayed `hmac-sha256.v1` signed payment receipts.
Authenticated deployments should use least-privilege bearer scopes. Hekate scans currently use the technical `agentsec:scan` scope; receipt verification uses `agentsec:receipt:verify`; persisted receipt reads use `agentsec:receipt:read`; OSV refresh jobs use `agentsec:jobs:read` or `agentsec:jobs:write`; audit reads use `agentsec:audit:read`; Lite payment metadata reads use `agentsec:payments:read`; retention routes use `agentsec:retention:read` or `agentsec:retention:write`; Mission Control routes require `missions:*`, `templates:*`, `stats:read`, or `disputes:*`; provider registry/certification reads require `provider:read`; webhook routes require `webhooks:read` or `webhooks:write`; and finance/export routes require `billing:read` or `exports:read`.
Production API keys are issued by an operator through `POST /v1/admin/api-keys` with `admin:api_keys`; agents should treat returned `mc_key_...` tokens as one-time visible secrets and expect rotated or revoked keys to stop working immediately. Operators can review key grants with `GET /v1/admin/api-keys/grants/review` and inspect redacted signer readiness with `GET /v1/admin/signer/status` using `admin:signer:read`. Registry status changes require `admin:registry_status` and appear in the public signed status history only after an explicit review decision.
Remote `mcp_manifest_url` fetching is disabled unless the deployment explicitly enables it with `MC_AGENTSEC_MCP_FETCH_ENABLED=1` and an HTTPS allowlist. If enabled, AgentSec records `remote_manifest.manifest_hash`; otherwise, submit manifests inline.
Receipt evidence bundles use `agentsec.evidence_bundle.v1` and can be exported from `GET /v1/agentsec/receipts/:id/evidence-bundle`. Evidence retention may purge stored evidence while preserving signed receipts and hash-chain audit events.

## What Mission Control gives you

You declare:

- a **goal** in plain language,
- a **budget** in USD,
- and **policy constraints** (freshness, min sources, public-data-only, …).

Mission Control:

1. Plans the work as a typed DAG of capability-named steps.
2. Picks x402 vendors that score best for each step.
3. Quotes the route and asks the Policy Engine to authorize each step.
4. Pays via x402 (idempotent via `payment-identifier`).
5. Verifies every output (schema, freshness, sources, cross-source consistency).
6. Returns the synthesized result with a hash-chained audit trail.

You do **not** sign payments. You do **not** see private keys. The Wallet
Signer is an isolated process; the Policy Engine refuses any decision an
LLM tries to fast-path.

## Three integration surfaces

### 1. REST API

Base URL for the public Hekate Lite private-beta endpoints: `https://hekategate.com`.
Dedicated Mission Control / AgentSec API deployments may use `https://api.hekategate.com` or a self-hosted API origin.
Machine-readable spec: `/openapi.json`.
Copy-paste endpoint fixtures: `/examples`.
The public web private beta supports Sage quote preflight, Ergo Note checks, and Sage/Accord receipt bundle verification at the `/v1/ergo/*` endpoints.

Minimal flow:

```http
POST /v1/missions HTTP/1.1
authorization: Bearer <your token>
content-type: application/json

{
  "goal": "Investment memo for Stripe",
  "mission_type": "company_research",
  "budget_usd": 5,
  "constraints": {
    "freshness_days": 30,
    "min_sources": 4,
    "public_data_only": true,
    "require_citations": true
  }
}
```

Then:

```http
POST /v1/missions/:id/run HTTP/1.1
authorization: Bearer <your token>
```

Returns the final mission with `state: "completed"`, `total_cost_usd`,
`confidence_score`, `result`, `steps[]`. Fetch the audit chain at
`/v1/missions/:id/audit`.

### 2. TypeScript SDK (`@mc/sdk`)

```ts
import { MissionControlClient } from "@mc/sdk";

const mc = new MissionControlClient({ baseUrl: "...", apiKey: "..." });

const { mission, audit } = await mc.runMission({
  goal: "Investment memo for Stripe",
  mission_type: "company_research",
  budget_usd: 5,
  constraints: { public_data_only: true, min_sources: 4 },
});

console.log(mission.confidence_score, mission.total_cost_usd);
// audit.chain.ok === true
```

The SDK exposes:

- `mc.health()`
- `mc.missions.{create, quote, execute, run, get, audit}`
- `mc.providers.{scorecard, score, statusHistory}`
- `mc.disputes.{open, list, resolve}`
- `mc.admin.{killSwitch, trip, clear, signerStatus, apiKeyGrantReviewReport, apiKeyGrantReviews, recordApiKeyGrantReview}`
- `mc.agentsec.{mcpPreflight, x402Preflight, permissionsDiff, toolChainRisk, repoScan, verifyReceipt, trust, jwks, sagePreflight, ergoNoteCheck, verifySageReceipts, receipts, receipt, audit}`
- `mc.runMission(req)` — convenience: create + run + audit in one call.

For webhook receivers: `verifyWebhookSignature({ secret, signature, timestamp, body })` does HMAC-SHA256 verification with timing-safe compare and 5-minute replay tolerance.

### 3. MCP server (`@mc/mcp`)

The Mission Control MCP server speaks the standard JSON-RPC 2.0 stdio
protocol. Configure in your MCP client (Claude Desktop, Cursor, etc.):

```json
{
  "mcpServers": {
    "mission-control": {
      "command": "npx",
      "args": ["@mc/mcp"],
      "env": {
        "MC_API_URL": "https://api.hekategate.com",
        "MC_API_KEY": "your-api-key"
      }
    }
  }
}
```

Tools exposed:

| Tool | What it does |
|---|---|
| `create_mission` | Create a mission in `planned` state. |
| `run_mission` | Quote + execute. Returns final mission. |
| `get_mission` | Fetch a mission by id. |
| `get_audit_trail` | Hash-chained audit + chain integrity status. |
| `list_provider_scorecard` | All providers with computed quality scores. |
| `get_provider_score` | One provider with score + evidence + best-for capabilities. |
| `get_registry_status_history` | Signed public registry status history and trust bundle. |
| `open_dispute` | Open a dispute on a completed mission. |
| `emergency_stop` | Trip the wallet kill switch. Halts all paid calls. |
| `agentsec_scan_mcp` | Run MCP preflight before trusting tool surfaces. |
| `agentsec_check_x402` | Run x402 preflight before paying an endpoint. |
| `agentsec_diff_permissions` | Compare requested scopes against task needs. |
| `agentsec_check_tool_chain` | Detect dangerous multi-tool paths. |
| `agentsec_scan_repo` | Scan a repository snapshot for supply-chain and secret risks. |
| `agentsec_verify_receipt` | Verify an AgentSec security receipt. |
| `agentsec_get_trust_bundle` | Fetch AgentSec verifier keys for portable receipt verification. |
| `agentsec_export_evidence_bundle` | Export a portable AgentSec evidence bundle. |
| `agentsec_retention_status` | Inspect AgentSec evidence retention status. |
| `agentsec_purge_retained_evidence` | Purge stored evidence payloads while keeping signed receipts. |
| `agentsec_check_sage_quote` | Preflight a Sage quote before an Ergo paid-agent turn. |
| `agentsec_verify_ergo_note` | Check Ergo Note fields before trusting a paid-agent flow. |
| `agentsec_verify_sage_receipt` | Verify Sage/Accord receipt bundle completeness. |

## Mission types

| Type | What it produces |
|---|---|
| `company_research` | Investment memo / sales brief on one company. Cites multiple sources. |
| `competitor_research` | Ranked competitive landscape. |
| `crypto_due_diligence` | Token + team + on-chain risk profile. |
| `market_research` | Sector scan, trends, top players. |
| `lead_enrichment` | Bulk account or contact enrichment. |

## Constraints (recommended for safety)

```json
"constraints": {
  "freshness_days": 30,             // refuse stale sources
  "min_sources": 4,                 // require ≥ N distinct sources
  "require_citations": true,        // every claim must cite
  "public_data_only": true,         // never escalate to internal/PII data
  "blocked_categories": ["trading"] // blanket-disallow vendor categories
}
```

## What the audit log proves

Every state transition, policy decision, payment, and verification is a
SHA-256-chained `AuditEvent`. Fetch via `GET /v1/missions/:id/audit`:

```json
{
  "mission_id": "mis_abc123",
  "chain": { "ok": true },
  "events": [
    { "event_type": "MissionCreated", ... },
    { "event_type": "MissionPlanned", ... },
    { "event_type": "RouteQuoted", ... },
    { "event_type": "PolicyEvaluated", ... },
    { "event_type": "PaymentIntentCreated", ... },
    { "event_type": "PaymentSettled", ... },
    { "event_type": "VerificationCompleted", ... },
    { "event_type": "MissionCompleted", ... }
  ]
}
```

`chain.ok === true` means the entire chain re-derived cleanly. If a
malicious actor edits an event's payload, `chain.ok` flips to `false`
and `brokenAt` shows the first index that fails.

## Idempotency

If your call times out and you retry the same `POST /v1/missions/:id/run`,
the engine refuses re-execution of a completed mission. If you want a
fresh attempt: create a new mission.

For payment-level idempotency, every paid call carries a stable
`payment_identifier = pay_<mission>_<step>`. The vendor's x402 layer
returns the cached settlement if it has already processed the same
identifier — you never double-charge.

## When something goes wrong

- **Vendor returned bad output** → open a dispute with `POST /v1/missions/:id/disputes`. The mission moves to `disputed`. Resolve as `refunded`, `partial_refund`, or `denied` (claim dismissed).
- **Vendor inflated price** → `executePayment` refuses any quote above the policy-authorized cap. Mission fails; you get a `PaymentOverCapError` reason. Pick a different mission_type or raise the budget.
- **Vendor outage at scale** → `POST /v1/admin/kill-switch` (or `emergency_stop` MCP tool). Halts every paid call across the org until you `DELETE /v1/admin/kill-switch`.
- **Mission stuck in `awaiting_approval`** → the Policy Engine asked for human review. Decide via `POST /v1/missions/:id/approvals/:approvalId` with `{decision: "granted" | "denied"}`.

## Webhooks (recommended for long-running flows)

Subscribe to mission events:

```http
POST /v1/webhooks
{
  "url": "https://your.example/webhooks/mc",
  "event_types": ["MissionCompleted", "MissionFailed", "DisputeOpened"]
}
```

You get back a `secret` (shown once). On every delivery, Mission Control
sends:

```
POST /your/webhook
content-type: application/json
x-mc-event-id: evt_...
x-mc-event-type: MissionCompleted
x-mc-timestamp: 2026-05-04T14:23:00.000Z
x-mc-signature: <hex sha256 hmac>

{ "event_id": "evt_...", "event_type": "...", "timestamp": "...", "payload": {...} }
```

Verify with `verifyWebhookSignature` from `@mc/sdk` (timing-safe; rejects
events older than 5 minutes by default).

## Rate limits

Per-vendor token bucket: 10 requests / second / provider, 20 burst. If
you hit it, you get a `RateLimitError` with `retryAfterMs`.

Per-org HTTP rate limits land in Phase 1.

## Pricing-aware planning

If your agent budget is fixed, prefer:

- `mission_type: market_research` (~$1–$5 typical).
- `budget_usd: 3` for sector scans, `5` for company briefs, `10` for crypto due diligence.

Always set `constraints.public_data_only: true` unless you explicitly
need internal/customer data — Mission Control will refuse to send PII to
public vendors regardless.

## Reference

- OpenAPI: `/openapi.json`
- LLM-readable index: `/llms.txt`
- Full content for citation: `/llms-full.txt`
- Discovery advertisement: `/.well-known/agentic-market.json`
- Security policy: `/.well-known/security.txt`
- Marketing landing: `/`
