---
phase: 03-tier-3-9-providers
plan: 03
type: execute
wave: 1
depends_on: []
files_modified:
  - providers/openrouter.yaml
  - providers/litellm.yaml
  - providers/cloudflare-ai.yaml
  - providers/vercel-ai.yaml
  - providers/portkey.yaml
  - providers/helicone.yaml
  - providers/martian.yaml
  - providers/kong.yaml
  - providers/bricksai.yaml
  - providers/aether.yaml
  - providers/notdiamond.yaml
  - pkg/providers/definitions/openrouter.yaml
  - pkg/providers/definitions/litellm.yaml
  - pkg/providers/definitions/cloudflare-ai.yaml
  - pkg/providers/definitions/vercel-ai.yaml
  - pkg/providers/definitions/portkey.yaml
  - pkg/providers/definitions/helicone.yaml
  - pkg/providers/definitions/martian.yaml
  - pkg/providers/definitions/kong.yaml
  - pkg/providers/definitions/bricksai.yaml
  - pkg/providers/definitions/aether.yaml
  - pkg/providers/definitions/notdiamond.yaml
autonomous: true
requirements: [PROV-05]
must_haves:
  truths:
    - "11 Tier 5 infrastructure/gateway provider YAMLs load"
    - "OpenRouter sk-or- and Helicone sk-helicone- prefixes use high-confidence regex"
    - "Gateway providers have strong keyword anchors to their SDK envs"
  artifacts:
    - path: "providers/openrouter.yaml"
      provides: "OpenRouter sk-or- prefix pattern"
      contains: "sk-or-"
    - path: "providers/helicone.yaml"
      provides: "Helicone sk-helicone- prefix pattern"
      contains: "helicone"
    - path: "providers/litellm.yaml"
      provides: "LiteLLM proxy keyword detection"
      contains: "litellm"
  key_links:
    - from: "provider keywords[]"
      to: "Registry Aho-Corasick automaton"
      via: "NewRegistry()"
      pattern: "keywords"
---

<objective>
Create 11 Tier 5 Infrastructure/Gateway provider YAMLs — LLM routers, proxies, and observability gateways (OpenRouter, LiteLLM, Cloudflare AI, Vercel AI, Portkey, Helicone, Martian, Kong, BricksAI, Aether, Not Diamond).

Purpose: Satisfy PROV-05 (11 Tier 5 Infrastructure/Gateway providers). Several of these have documented key prefixes (sk-or-, sk-helicone-) that support high-confidence detection.

Output: 22 YAML files.

Addresses PROV-05.
</objective>

<execution_context>
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
@$HOME/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/ROADMAP.md
@.planning/phases/03-tier-3-9-providers/03-CONTEXT.md
@pkg/providers/schema.go
@providers/groq.yaml

<interfaces>
Schema per pkg/providers/schema.go. No category field. Dual-location required. RE2 regex only.
Keyword-only detection for providers without documented key formats.
</interfaces>
</context>

<tasks>

<task type="auto">
  <name>Task 1: OpenRouter, LiteLLM, Cloudflare, Vercel, Portkey, Helicone YAMLs</name>
  <files>providers/openrouter.yaml, providers/litellm.yaml, providers/cloudflare-ai.yaml, providers/vercel-ai.yaml, providers/portkey.yaml, providers/helicone.yaml, pkg/providers/definitions/openrouter.yaml, pkg/providers/definitions/litellm.yaml, pkg/providers/definitions/cloudflare-ai.yaml, pkg/providers/definitions/vercel-ai.yaml, pkg/providers/definitions/portkey.yaml, pkg/providers/definitions/helicone.yaml</files>
  <read_first>
    - pkg/providers/schema.go
  </read_first>
  <action>
providers/openrouter.yaml:
```yaml
format_version: 1
name: openrouter
display_name: OpenRouter
tier: 5
last_verified: "2026-04-05"
keywords:
  - "openrouter"
  - "OPENROUTER_API_KEY"
  - "openrouter.ai"
  - "sk-or-"
patterns:
  - regex: 'sk-or-v1-[a-f0-9]{64}'
    entropy_min: 4.0
    confidence: high
  - regex: 'sk-or-[A-Za-z0-9]{40,}'
    entropy_min: 4.0
    confidence: medium
verify:
  method: GET
  url: https://openrouter.ai/api/v1/auth/key
  headers:
    Authorization: "Bearer {KEY}"
  valid_status: [200]
  invalid_status: [401, 403]
```

providers/litellm.yaml:
```yaml
format_version: 1
name: litellm
display_name: LiteLLM Proxy
tier: 5
last_verified: "2026-04-05"
keywords:
  - "litellm"
  - "LITELLM_API_KEY"
  - "LITELLM_MASTER_KEY"
  - "LITELLM_PROXY_API_KEY"
patterns:
  - regex: 'sk-[A-Za-z0-9_\-]{20,}'
    entropy_min: 4.0
    confidence: low
verify:
  method: GET
  url: ""
  headers: {}
  valid_status: []
  invalid_status: []
```

providers/cloudflare-ai.yaml:
```yaml
format_version: 1
name: cloudflare-ai
display_name: Cloudflare Workers AI
tier: 5
last_verified: "2026-04-05"
keywords:
  - "cloudflare"
  - "workers-ai"
  - "CLOUDFLARE_API_TOKEN"
  - "CLOUDFLARE_ACCOUNT_ID"
  - "CF_API_TOKEN"
  - "api.cloudflare.com"
patterns:
  - regex: '[A-Za-z0-9_\-]{40}'
    entropy_min: 4.5
    confidence: low
verify:
  method: GET
  url: https://api.cloudflare.com/client/v4/user/tokens/verify
  headers:
    Authorization: "Bearer {KEY}"
  valid_status: [200]
  invalid_status: [401, 403]
```

providers/vercel-ai.yaml:
```yaml
format_version: 1
name: vercel-ai
display_name: Vercel AI Gateway
tier: 5
last_verified: "2026-04-05"
keywords:
  - "vercel"
  - "VERCEL_AI_GATEWAY"
  - "AI_GATEWAY_API_KEY"
  - "vercel.ai"
  - "ai-sdk"
verify:
  method: GET
  url: ""
  headers: {}
  valid_status: []
  invalid_status: []
```

providers/portkey.yaml:
```yaml
format_version: 1
name: portkey
display_name: Portkey
tier: 5
last_verified: "2026-04-05"
keywords:
  - "portkey"
  - "PORTKEY_API_KEY"
  - "api.portkey.ai"
  - "portkey-ai"
verify:
  method: GET
  url: https://api.portkey.ai/v1/feedback
  headers:
    x-portkey-api-key: "{KEY}"
  valid_status: [200, 400]
  invalid_status: [401, 403]
```

providers/helicone.yaml:
```yaml
format_version: 1
name: helicone
display_name: Helicone
tier: 5
last_verified: "2026-04-05"
keywords:
  - "helicone"
  - "HELICONE_API_KEY"
  - "sk-helicone-"
  - "api.helicone.ai"
patterns:
  - regex: 'sk-helicone-[a-z0-9]{7}-[a-z0-9]{7}-[a-z0-9]{7}-[a-z0-9]{7}'
    entropy_min: 3.5
    confidence: high
verify:
  method: GET
  url: https://api.helicone.ai/v1/key/verify
  headers:
    Authorization: "Bearer {KEY}"
  valid_status: [200]
  invalid_status: [401, 403]
```

Copy all 6 files verbatim to pkg/providers/definitions/.
  </action>
  <verify>
    <automated>cd /home/salva/Documents/apikey && for f in openrouter litellm cloudflare-ai vercel-ai portkey helicone; do diff providers/$f.yaml pkg/providers/definitions/$f.yaml || exit 1; done && go test ./pkg/providers/... -count=1 && go test ./pkg/engine/... -count=1</automated>
  </verify>
  <acceptance_criteria>
    - All 12 files exist
    - `grep -q 'sk-or-v1-' providers/openrouter.yaml`
    - `grep -q 'sk-helicone-' providers/helicone.yaml`
    - `grep -q 'LITELLM_MASTER_KEY' providers/litellm.yaml`
    - `go test ./pkg/providers/... -count=1` passes
    - `go test ./pkg/engine/... -count=1` passes
  </acceptance_criteria>
  <done>6 major gateway providers dual-located.</done>
</task>

<task type="auto">
  <name>Task 2: Martian, Kong, BricksAI, Aether, Not Diamond YAMLs</name>
  <files>providers/martian.yaml, providers/kong.yaml, providers/bricksai.yaml, providers/aether.yaml, providers/notdiamond.yaml, pkg/providers/definitions/martian.yaml, pkg/providers/definitions/kong.yaml, pkg/providers/definitions/bricksai.yaml, pkg/providers/definitions/aether.yaml, pkg/providers/definitions/notdiamond.yaml</files>
  <read_first>
    - pkg/providers/schema.go
  </read_first>
  <action>
All 5 use keyword-only detection (no documented public key formats). Omit patterns field.

providers/martian.yaml:
```yaml
format_version: 1
name: martian
display_name: Martian (Model Router)
tier: 5
last_verified: "2026-04-05"
keywords:
  - "withmartian"
  - "MARTIAN_API_KEY"
  - "withmartian.com"
  - "martian-router"
verify:
  method: GET
  url: ""
  headers: {}
  valid_status: []
  invalid_status: []
```

providers/kong.yaml:
```yaml
format_version: 1
name: kong
display_name: Kong AI Gateway
tier: 5
last_verified: "2026-04-05"
keywords:
  - "kong"
  - "KONG_API_KEY"
  - "kong-ai-gateway"
  - "konghq.com"
  - "ai-proxy"
verify:
  method: GET
  url: ""
  headers: {}
  valid_status: []
  invalid_status: []
```

providers/bricksai.yaml:
```yaml
format_version: 1
name: bricksai
display_name: BricksAI
tier: 5
last_verified: "2026-04-05"
keywords:
  - "bricksai"
  - "BRICKS_API_KEY"
  - "trybricks.ai"
  - "bricksllm"
verify:
  method: GET
  url: ""
  headers: {}
  valid_status: []
  invalid_status: []
```

providers/aether.yaml:
```yaml
format_version: 1
name: aether
display_name: Aether AI
tier: 5
last_verified: "2026-04-05"
keywords:
  - "aether"
  - "AETHER_API_KEY"
  - "aether.ai"
  - "aetherplatform"
verify:
  method: GET
  url: ""
  headers: {}
  valid_status: []
  invalid_status: []
```

providers/notdiamond.yaml:
```yaml
format_version: 1
name: notdiamond
display_name: Not Diamond
tier: 5
last_verified: "2026-04-05"
keywords:
  - "notdiamond"
  - "NOTDIAMOND_API_KEY"
  - "not-diamond"
  - "notdiamond.ai"
verify:
  method: GET
  url: ""
  headers: {}
  valid_status: []
  invalid_status: []
```

Copy all 5 files verbatim to pkg/providers/definitions/.
  </action>
  <verify>
    <automated>cd /home/salva/Documents/apikey && for f in martian kong bricksai aether notdiamond; do diff providers/$f.yaml pkg/providers/definitions/$f.yaml || exit 1; done && go test ./pkg/providers/... -count=1 && go test ./pkg/engine/... -count=1 && test "$(grep -l 'tier: 5' providers/*.yaml | wc -l)" = "11"</automated>
  </verify>
  <acceptance_criteria>
    - All 10 files exist
    - `grep -q 'withmartian' providers/martian.yaml`
    - `grep -q 'konghq.com' providers/kong.yaml`
    - All 5 omit patterns field: `grep -L 'patterns:' providers/{martian,kong,bricksai,aether,notdiamond}.yaml` returns all 5
    - Total Tier 5 count = 11: `grep -l 'tier: 5' providers/*.yaml | wc -l` → 11
    - `go test ./pkg/providers/... -count=1` passes
  </acceptance_criteria>
  <done>All 11 Tier 5 gateway providers dual-located. PROV-05 satisfied.</done>
</task>

</tasks>

<verification>
`grep -l 'tier: 5' providers/*.yaml | wc -l` returns 11.
</verification>

<success_criteria>
- 11 Tier 5 gateway providers created
- Documented prefixes use tight high-confidence regex (openrouter, helicone)
- Undocumented providers use keyword-only detection
- No engine test regressions
</success_criteria>

<output>
After completion, create `.planning/phases/03-tier-3-9-providers/03-03-SUMMARY.md`
</output>
