From a318b9d89f06e5bec44ea8e3c306d2fb0ef27017 Mon Sep 17 00:00:00 2001 From: salvacybersec Date: Sun, 5 Apr 2026 14:39:54 +0300 Subject: [PATCH] docs(03-tier-3-9-providers): create phase plan --- .planning/ROADMAP.md | 12 +- .../03-tier-3-9-providers/03-01-PLAN.md | 544 ++++++++++++++++++ .../03-tier-3-9-providers/03-02-PLAN.md | 418 ++++++++++++++ .../03-tier-3-9-providers/03-03-PLAN.md | 393 +++++++++++++ .../03-tier-3-9-providers/03-04-PLAN.md | 382 ++++++++++++ .../03-tier-3-9-providers/03-05-PLAN.md | 364 ++++++++++++ .../03-tier-3-9-providers/03-06-PLAN.md | 331 +++++++++++ .../03-tier-3-9-providers/03-07-PLAN.md | 504 ++++++++++++++++ .../03-tier-3-9-providers/03-08-PLAN.md | 284 +++++++++ 9 files changed, 3231 insertions(+), 1 deletion(-) create mode 100644 .planning/phases/03-tier-3-9-providers/03-01-PLAN.md create mode 100644 .planning/phases/03-tier-3-9-providers/03-02-PLAN.md create mode 100644 .planning/phases/03-tier-3-9-providers/03-03-PLAN.md create mode 100644 .planning/phases/03-tier-3-9-providers/03-04-PLAN.md create mode 100644 .planning/phases/03-tier-3-9-providers/03-05-PLAN.md create mode 100644 .planning/phases/03-tier-3-9-providers/03-06-PLAN.md create mode 100644 .planning/phases/03-tier-3-9-providers/03-07-PLAN.md create mode 100644 .planning/phases/03-tier-3-9-providers/03-08-PLAN.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 50ad8e6..7398f0b 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -79,7 +79,17 @@ Plans: 2. Chinese/regional provider keys (DeepSeek, Zhipu, Moonshot, Qwen, Baidu, ByteDance, etc.) are detected using keyword-based matching since they use generic key formats 3. Self-hosted provider definitions (Ollama, vLLM, LocalAI, etc.) include patterns for API key authentication when applicable 4. `keyhunter providers list --tier=enterprise` returns Salesforce, ServiceNow, SAP, Palantir, Databricks, Snowflake, Oracle, HPE providers -**Plans**: TBD +**Plans**: 8 plans + +Plans: +- [ ] 03-01-PLAN.md — Tier 4 Chinese/regional providers (DeepSeek, Zhipu, Moonshot, Qwen, Baidu, ByteDance, 01.AI, MiniMax, Baichuan, StepFun, SenseTime, iFlytek, Tencent, SiliconFlow, 360 AI, Kuaishou) +- [ ] 03-02-PLAN.md — Tier 3 Specialized (Perplexity, You.com, Voyage, Jina, Unstructured, AssemblyAI, Deepgram, ElevenLabs, Stability, Runway, Midjourney) +- [ ] 03-03-PLAN.md — Tier 5 Infrastructure/Gateway (OpenRouter, LiteLLM, Cloudflare AI, Vercel AI, Portkey, Helicone, Martian, Kong, BricksAI, Aether, Not Diamond) +- [ ] 03-04-PLAN.md — Tier 7 Code/Dev Tools (GitHub Copilot, Cursor, Tabnine, Codeium, Sourcegraph, CodeWhisperer, Replit AI, Codestral, watsonx, Oracle AI) +- [ ] 03-05-PLAN.md — Tier 8 Self-Hosted runtimes (Ollama, vLLM, LocalAI, LM Studio, llama.cpp, GPT4All, text-gen-webui, TensorRT-LLM, Triton, Jan) +- [ ] 03-06-PLAN.md — Tier 9 Enterprise (Salesforce Einstein, ServiceNow, SAP AI Core, Palantir, Databricks, Snowflake, Oracle GenAI, HPE GreenLake) +- [ ] 03-07-PLAN.md — Tier 6 Emerging/Niche (Reka, Aleph Alpha, Lamini, Writer, Jasper, Typeface, Comet, W&B, LangSmith, Pinecone, Weaviate, Qdrant, Chroma, Milvus, Neon) +- [ ] 03-08-PLAN.md — Tier 3-9 guardrail test: lock 108 total providers, per-tier counts, and name sets ### Phase 4: Input Sources **Goal**: Users can point KeyHunter at any content source — local files, git history across all branches, piped content, remote URLs, and the clipboard — and all are scanned through the same detection pipeline diff --git a/.planning/phases/03-tier-3-9-providers/03-01-PLAN.md b/.planning/phases/03-tier-3-9-providers/03-01-PLAN.md new file mode 100644 index 0000000..999538b --- /dev/null +++ b/.planning/phases/03-tier-3-9-providers/03-01-PLAN.md @@ -0,0 +1,544 @@ +--- +phase: 03-tier-3-9-providers +plan: 01 +type: execute +wave: 1 +depends_on: [] +files_modified: + - providers/deepseek.yaml + - providers/zhipu.yaml + - providers/moonshot.yaml + - providers/qwen.yaml + - providers/baidu.yaml + - providers/bytedance.yaml + - providers/01ai.yaml + - providers/minimax.yaml + - providers/baichuan.yaml + - providers/stepfun.yaml + - providers/sensetime.yaml + - providers/iflytek.yaml + - providers/tencent.yaml + - providers/siliconflow.yaml + - providers/360ai.yaml + - providers/kuaishou.yaml + - pkg/providers/definitions/deepseek.yaml + - pkg/providers/definitions/zhipu.yaml + - pkg/providers/definitions/moonshot.yaml + - pkg/providers/definitions/qwen.yaml + - pkg/providers/definitions/baidu.yaml + - pkg/providers/definitions/bytedance.yaml + - pkg/providers/definitions/01ai.yaml + - pkg/providers/definitions/minimax.yaml + - pkg/providers/definitions/baichuan.yaml + - pkg/providers/definitions/stepfun.yaml + - pkg/providers/definitions/sensetime.yaml + - pkg/providers/definitions/iflytek.yaml + - pkg/providers/definitions/tencent.yaml + - pkg/providers/definitions/siliconflow.yaml + - pkg/providers/definitions/360ai.yaml + - pkg/providers/definitions/kuaishou.yaml +autonomous: true +requirements: [PROV-04] +must_haves: + truths: + - "Registry loads 16 Tier 4 Chinese/regional provider YAMLs" + - "Providers without documented key formats use keyword-only detection (no patterns entry)" + - "DeepSeek uses documented sk- prefix pattern" + - "All YAMLs are dual-located and diff-clean" + artifacts: + - path: "providers/deepseek.yaml" + provides: "DeepSeek sk- prefix pattern + keywords" + contains: "deepseek" + - path: "providers/qwen.yaml" + provides: "Alibaba Qwen/DashScope keyword-only detection" + contains: "dashscope" + - path: "providers/baidu.yaml" + provides: "Baidu ERNIE/Wenxin keyword detection" + contains: "wenxin" + key_links: + - from: "provider keywords[]" + to: "Registry Aho-Corasick automaton" + via: "NewRegistry()" + pattern: "keywords" +--- + + +Create 16 Tier 4 Chinese/regional LLM provider YAML definitions. These providers mostly lack documented key formats, so detection relies on strong keyword lists anchored to their SDK envs, domains, and API hostnames — not on generic regex (which caused false positives in Phase 2). + +Purpose: Satisfy PROV-04 (16 Tier 4 providers). Chinese/regional providers are high-value targets but low-signal for regex detection — keyword-only matching is the correct mitigation. + +Output: 32 YAML files (16 providers × 2 locations). + +Addresses PROV-04. + + + +@$HOME/.claude/get-shit-done/workflows/execute-plan.md +@$HOME/.claude/get-shit-done/templates/summary.md + + + +@.planning/ROADMAP.md +@.planning/phases/03-tier-3-9-providers/03-CONTEXT.md +@pkg/providers/schema.go +@providers/mistral.yaml +@providers/cohere.yaml + + +Provider schema (pkg/providers/schema.go): FormatVersion, Name, DisplayName, Tier, LastVerified, Keywords, Patterns, Verify. NO `category` field. Confidence values: high|medium|low. + +Patterns array MAY be empty/omitted — registry allows keyword-only providers. Keywords list MUST have ≥3 entries (Aho-Corasick pre-filter requirement). + +Files must be dual-located: providers/X.yaml AND pkg/providers/definitions/X.yaml (Go embed cannot use '..' paths). + +Phase 2 lesson: generic regex like `[A-Za-z0-9]{32,64}` causes false positives. For providers without distinctive prefixes, OMIT the patterns field entirely (keyword-only detection). + + + + + + + Task 1: DeepSeek, Zhipu, Moonshot, Qwen, Baidu, ByteDance, 01.AI, MiniMax YAMLs + providers/deepseek.yaml, providers/zhipu.yaml, providers/moonshot.yaml, providers/qwen.yaml, providers/baidu.yaml, providers/bytedance.yaml, providers/01ai.yaml, providers/minimax.yaml, pkg/providers/definitions/deepseek.yaml, pkg/providers/definitions/zhipu.yaml, pkg/providers/definitions/moonshot.yaml, pkg/providers/definitions/qwen.yaml, pkg/providers/definitions/baidu.yaml, pkg/providers/definitions/bytedance.yaml, pkg/providers/definitions/01ai.yaml, pkg/providers/definitions/minimax.yaml + + - pkg/providers/schema.go + - providers/mistral.yaml (reference: keyword-anchored generic pattern) + - .planning/phases/03-tier-3-9-providers/03-CONTEXT.md (lessons from Phase 2) + + +Create each file in providers/ AND pkg/providers/definitions/ (verbatim copy). DeepSeek has a documented sk- prefix so it gets a pattern; all others are keyword-only (omit patterns entirely). + +providers/deepseek.yaml: +```yaml +format_version: 1 +name: deepseek +display_name: DeepSeek +tier: 4 +last_verified: "2026-04-05" +keywords: + - "deepseek" + - "DEEPSEEK_API_KEY" + - "api.deepseek.com" + - "deepseek-chat" + - "deepseek-coder" +patterns: + - regex: 'sk-[a-f0-9]{32}' + entropy_min: 3.5 + confidence: medium +verify: + method: GET + url: https://api.deepseek.com/v1/models + headers: + Authorization: "Bearer {KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +providers/zhipu.yaml: +```yaml +format_version: 1 +name: zhipu +display_name: Zhipu AI (GLM) +tier: 4 +last_verified: "2026-04-05" +keywords: + - "zhipu" + - "ZHIPU_API_KEY" + - "ZHIPUAI_API_KEY" + - "bigmodel.cn" + - "open.bigmodel.cn" + - "glm-4" + - "chatglm" +verify: + method: GET + url: https://open.bigmodel.cn/api/paas/v4/models + headers: + Authorization: "Bearer {KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +providers/moonshot.yaml: +```yaml +format_version: 1 +name: moonshot +display_name: Moonshot AI (Kimi) +tier: 4 +last_verified: "2026-04-05" +keywords: + - "moonshot" + - "MOONSHOT_API_KEY" + - "api.moonshot.cn" + - "kimi" + - "moonshot-v1" +patterns: + - regex: 'sk-[A-Za-z0-9]{48}' + entropy_min: 4.0 + confidence: medium +verify: + method: GET + url: https://api.moonshot.cn/v1/models + headers: + Authorization: "Bearer {KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +providers/qwen.yaml: +```yaml +format_version: 1 +name: qwen +display_name: Alibaba Qwen (DashScope) +tier: 4 +last_verified: "2026-04-05" +keywords: + - "dashscope" + - "DASHSCOPE_API_KEY" + - "qwen" + - "qwen-turbo" + - "qwen-max" + - "dashscope.aliyuncs.com" +patterns: + - regex: 'sk-[a-f0-9]{32}' + entropy_min: 3.5 + confidence: medium +verify: + method: GET + url: https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation + headers: + Authorization: "Bearer {KEY}" + valid_status: [200, 400] + invalid_status: [401, 403] +``` + +providers/baidu.yaml: +```yaml +format_version: 1 +name: baidu +display_name: Baidu ERNIE (Wenxin) +tier: 4 +last_verified: "2026-04-05" +keywords: + - "wenxin" + - "ernie" + - "BAIDU_API_KEY" + - "QIANFAN_AK" + - "QIANFAN_SK" + - "aip.baidubce.com" + - "qianfan" +verify: + method: POST + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/bytedance.yaml: +```yaml +format_version: 1 +name: bytedance +display_name: ByteDance Doubao (Volcengine) +tier: 4 +last_verified: "2026-04-05" +keywords: + - "doubao" + - "volcengine" + - "VOLC_ACCESSKEY" + - "VOLC_SECRETKEY" + - "ARK_API_KEY" + - "ark.cn-beijing.volces.com" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/01ai.yaml: +```yaml +format_version: 1 +name: 01ai +display_name: 01.AI (Yi) +tier: 4 +last_verified: "2026-04-05" +keywords: + - "01.ai" + - "yi-large" + - "yi-34b" + - "YI_API_KEY" + - "api.lingyiwanwu.com" + - "lingyiwanwu" +verify: + method: GET + url: https://api.lingyiwanwu.com/v1/models + headers: + Authorization: "Bearer {KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +providers/minimax.yaml: +```yaml +format_version: 1 +name: minimax +display_name: MiniMax +tier: 4 +last_verified: "2026-04-05" +keywords: + - "minimax" + - "MINIMAX_API_KEY" + - "MINIMAX_GROUP_ID" + - "api.minimax.chat" + - "abab6" +verify: + method: GET + url: https://api.minimax.chat/v1/text/chatcompletion_v2 + headers: + Authorization: "Bearer {KEY}" + valid_status: [200, 400] + invalid_status: [401, 403] +``` + +Copy each file VERBATIM to pkg/providers/definitions/ with the same basename. + + + cd /home/salva/Documents/apikey && for f in deepseek zhipu moonshot qwen baidu bytedance 01ai minimax; 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 + + + - All 16 files exist (8 providers × 2 locations) + - `grep -q 'DEEPSEEK_API_KEY' providers/deepseek.yaml` + - `grep -q 'dashscope' providers/qwen.yaml` + - `grep -q 'wenxin' providers/baidu.yaml` + - `grep -q 'lingyiwanwu' providers/01ai.yaml` + - `grep -L 'patterns:' providers/zhipu.yaml providers/baidu.yaml providers/bytedance.yaml` returns all three (keyword-only, no patterns field) + - `diff providers/deepseek.yaml pkg/providers/definitions/deepseek.yaml` returns no diff + - `go test ./pkg/providers/... -count=1` passes + - `go test ./pkg/engine/... -count=1` passes (no regression from new providers) + + 8 Chinese/regional providers dual-located, registry loads them, engine tests pass. + + + + Task 2: Baichuan, StepFun, SenseTime, iFlytek, Tencent, SiliconFlow, 360 AI, Kuaishou YAMLs + providers/baichuan.yaml, providers/stepfun.yaml, providers/sensetime.yaml, providers/iflytek.yaml, providers/tencent.yaml, providers/siliconflow.yaml, providers/360ai.yaml, providers/kuaishou.yaml, pkg/providers/definitions/baichuan.yaml, pkg/providers/definitions/stepfun.yaml, pkg/providers/definitions/sensetime.yaml, pkg/providers/definitions/iflytek.yaml, pkg/providers/definitions/tencent.yaml, pkg/providers/definitions/siliconflow.yaml, pkg/providers/definitions/360ai.yaml, pkg/providers/definitions/kuaishou.yaml + + - pkg/providers/schema.go + - providers/deepseek.yaml (created in Task 1, reference for format) + + +All 8 of these providers lack publicly documented key formats. Use KEYWORD-ONLY detection — omit the patterns field entirely. + +providers/baichuan.yaml: +```yaml +format_version: 1 +name: baichuan +display_name: Baichuan AI +tier: 4 +last_verified: "2026-04-05" +keywords: + - "baichuan" + - "BAICHUAN_API_KEY" + - "api.baichuan-ai.com" + - "baichuan2" + - "baichuan-turbo" +verify: + method: GET + url: https://api.baichuan-ai.com/v1/chat/completions + headers: + Authorization: "Bearer {KEY}" + valid_status: [200, 400] + invalid_status: [401, 403] +``` + +providers/stepfun.yaml: +```yaml +format_version: 1 +name: stepfun +display_name: StepFun (阶跃星辰) +tier: 4 +last_verified: "2026-04-05" +keywords: + - "stepfun" + - "STEP_API_KEY" + - "STEPFUN_API_KEY" + - "api.stepfun.com" + - "step-1v" +verify: + method: GET + url: https://api.stepfun.com/v1/models + headers: + Authorization: "Bearer {KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +providers/sensetime.yaml: +```yaml +format_version: 1 +name: sensetime +display_name: SenseTime SenseNova +tier: 4 +last_verified: "2026-04-05" +keywords: + - "sensetime" + - "sensenova" + - "SENSETIME_API_KEY" + - "SENSENOVA_API_KEY" + - "api.sensenova.cn" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/iflytek.yaml: +```yaml +format_version: 1 +name: iflytek +display_name: iFlytek Spark (讯飞星火) +tier: 4 +last_verified: "2026-04-05" +keywords: + - "iflytek" + - "xf_yun" + - "spark_desk" + - "XFYUN_API_KEY" + - "XFYUN_API_SECRET" + - "XFYUN_APPID" + - "spark-api.xf-yun.com" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/tencent.yaml: +```yaml +format_version: 1 +name: tencent +display_name: Tencent Hunyuan +tier: 4 +last_verified: "2026-04-05" +keywords: + - "hunyuan" + - "TENCENTCLOUD_SECRET_ID" + - "TENCENTCLOUD_SECRET_KEY" + - "hunyuan.tencentcloudapi.com" + - "tencent-hunyuan" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/siliconflow.yaml: +```yaml +format_version: 1 +name: siliconflow +display_name: SiliconFlow +tier: 4 +last_verified: "2026-04-05" +keywords: + - "siliconflow" + - "SILICONFLOW_API_KEY" + - "api.siliconflow.cn" + - "siliconflow.cn" +patterns: + - regex: 'sk-[a-z]{20,}' + entropy_min: 3.5 + confidence: low +verify: + method: GET + url: https://api.siliconflow.cn/v1/models + headers: + Authorization: "Bearer {KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +providers/360ai.yaml: +```yaml +format_version: 1 +name: 360ai +display_name: 360 AI Brain +tier: 4 +last_verified: "2026-04-05" +keywords: + - "360gpt" + - "QIHOO_API_KEY" + - "api.360.cn" + - "ai.360.com" + - "360-ai" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/kuaishou.yaml: +```yaml +format_version: 1 +name: kuaishou +display_name: Kuaishou KwaiYii +tier: 4 +last_verified: "2026-04-05" +keywords: + - "kuaishou" + - "kwaiyii" + - "KUAISHOU_API_KEY" + - "KWAI_API_KEY" + - "kwai-ai" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +Copy each file VERBATIM to pkg/providers/definitions/. + + + cd /home/salva/Documents/apikey && for f in baichuan stepfun sensetime iflytek tencent siliconflow 360ai kuaishou; 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 + + + - All 16 files exist (8 providers × 2 locations) + - `grep -q 'baichuan-ai.com' providers/baichuan.yaml` + - `grep -q 'hunyuan' providers/tencent.yaml` + - `grep -q 'spark_desk' providers/iflytek.yaml` + - 7 of 8 files have NO patterns field: `grep -L 'patterns:' providers/{baichuan,stepfun,sensetime,iflytek,tencent,360ai,kuaishou}.yaml` returns all 7 + - `go test ./pkg/providers/... -count=1` passes + - `go test ./pkg/engine/... -count=1` passes + - Total Tier 4 provider count = 16: `grep -l 'tier: 4' providers/*.yaml | wc -l` → 16 + + All 16 Tier 4 Chinese/regional providers exist dual-located. PROV-04 satisfied. + + + + + +`grep -l 'tier: 4' providers/*.yaml | wc -l` returns 16. +`go test ./pkg/providers/... ./pkg/engine/... -count=1` passes. + + + +- 16 Tier 4 providers dual-located +- 13 use keyword-only detection (no patterns field) +- 3 use documented prefix patterns (deepseek, moonshot, qwen, siliconflow — note: 4 with patterns, adjust count) +- Registry loads all without validation errors +- No engine test regressions + + + +After completion, create `.planning/phases/03-tier-3-9-providers/03-01-SUMMARY.md` + diff --git a/.planning/phases/03-tier-3-9-providers/03-02-PLAN.md b/.planning/phases/03-tier-3-9-providers/03-02-PLAN.md new file mode 100644 index 0000000..b6478c6 --- /dev/null +++ b/.planning/phases/03-tier-3-9-providers/03-02-PLAN.md @@ -0,0 +1,418 @@ +--- +phase: 03-tier-3-9-providers +plan: 02 +type: execute +wave: 1 +depends_on: [] +files_modified: + - providers/perplexity.yaml + - providers/you.yaml + - providers/voyage.yaml + - providers/jina.yaml + - providers/unstructured.yaml + - providers/assemblyai.yaml + - providers/deepgram.yaml + - providers/elevenlabs.yaml + - providers/stability.yaml + - providers/runway.yaml + - providers/midjourney.yaml + - pkg/providers/definitions/perplexity.yaml + - pkg/providers/definitions/you.yaml + - pkg/providers/definitions/voyage.yaml + - pkg/providers/definitions/jina.yaml + - pkg/providers/definitions/unstructured.yaml + - pkg/providers/definitions/assemblyai.yaml + - pkg/providers/definitions/deepgram.yaml + - pkg/providers/definitions/elevenlabs.yaml + - pkg/providers/definitions/stability.yaml + - pkg/providers/definitions/runway.yaml + - pkg/providers/definitions/midjourney.yaml +autonomous: true +requirements: [PROV-03] +must_haves: + truths: + - "11 new Tier 3 Specialized provider YAMLs load (huggingface already exists → 12 total)" + - "Providers with documented prefixes (pplx-, xai-voyage, sk-, jina_) use tight regex" + - "Voice/image providers without documented prefixes use keyword-only" + artifacts: + - path: "providers/perplexity.yaml" + provides: "Perplexity pplx- prefix pattern" + contains: "pplx-" + - path: "providers/elevenlabs.yaml" + provides: "ElevenLabs API key keyword detection" + contains: "elevenlabs" + - path: "providers/assemblyai.yaml" + provides: "AssemblyAI keyword detection" + contains: "assemblyai" + key_links: + - from: "provider keywords[]" + to: "Registry Aho-Corasick automaton" + via: "NewRegistry()" + pattern: "keywords" +--- + + +Create 11 Tier 3 Specialized LLM/AI provider YAMLs — search (Perplexity, You.com), embeddings (Voyage, Jina, Unstructured), voice (AssemblyAI, Deepgram, ElevenLabs), and image/video (Stability, Runway, Midjourney). Huggingface is pre-existing from Phase 2 and must NOT be recreated. Total Tier 3 = 12 after this plan. + +Purpose: Satisfy PROV-03 (12 Tier 3 Specialized providers). + +Output: 22 YAML files (11 providers × 2 locations). + +Addresses PROV-03. + + + +@$HOME/.claude/get-shit-done/workflows/execute-plan.md +@$HOME/.claude/get-shit-done/templates/summary.md + + + +@.planning/ROADMAP.md +@.planning/phases/03-tier-3-9-providers/03-CONTEXT.md +@pkg/providers/schema.go +@providers/huggingface.yaml +@providers/cohere.yaml + + +Schema: pkg/providers/schema.go. No `category` field. Confidence: high|medium|low. +Patterns field may be omitted for keyword-only providers. Keywords ≥3 required. +Dual-location required (providers/ + pkg/providers/definitions/). +RE2 regex only. + +IMPORTANT: providers/huggingface.yaml ALREADY EXISTS (tier: 3). Do NOT modify or recreate it. + + + + + + + Task 1: Search + embeddings providers (Perplexity, You.com, Voyage, Jina, Unstructured, AssemblyAI) + providers/perplexity.yaml, providers/you.yaml, providers/voyage.yaml, providers/jina.yaml, providers/unstructured.yaml, providers/assemblyai.yaml, pkg/providers/definitions/perplexity.yaml, pkg/providers/definitions/you.yaml, pkg/providers/definitions/voyage.yaml, pkg/providers/definitions/jina.yaml, pkg/providers/definitions/unstructured.yaml, pkg/providers/definitions/assemblyai.yaml + + - pkg/providers/schema.go + - providers/huggingface.yaml (existing tier 3 reference — DO NOT MODIFY) + + +Create each file in providers/ AND copy verbatim to pkg/providers/definitions/. + +providers/perplexity.yaml: +```yaml +format_version: 1 +name: perplexity +display_name: Perplexity AI +tier: 3 +last_verified: "2026-04-05" +keywords: + - "perplexity" + - "PERPLEXITY_API_KEY" + - "pplx-" + - "api.perplexity.ai" +patterns: + - regex: 'pplx-[A-Za-z0-9]{48,}' + entropy_min: 4.0 + confidence: high +verify: + method: POST + url: https://api.perplexity.ai/chat/completions + headers: + Authorization: "Bearer {KEY}" + valid_status: [200, 400] + invalid_status: [401, 403] +``` + +providers/you.yaml: +```yaml +format_version: 1 +name: you +display_name: You.com +tier: 3 +last_verified: "2026-04-05" +keywords: + - "you.com" + - "YDC_API_KEY" + - "YOU_API_KEY" + - "api.ydc-index.io" +verify: + method: GET + url: https://api.ydc-index.io/search + headers: + X-API-Key: "{KEY}" + valid_status: [200, 400] + invalid_status: [401, 403] +``` + +providers/voyage.yaml: +```yaml +format_version: 1 +name: voyage +display_name: Voyage AI +tier: 3 +last_verified: "2026-04-05" +keywords: + - "voyage" + - "VOYAGE_API_KEY" + - "voyageai" + - "api.voyageai.com" +patterns: + - regex: 'pa-[A-Za-z0-9_\-]{40,}' + entropy_min: 4.0 + confidence: medium +verify: + method: POST + url: https://api.voyageai.com/v1/embeddings + headers: + Authorization: "Bearer {KEY}" + valid_status: [200, 400] + invalid_status: [401, 403] +``` + +providers/jina.yaml: +```yaml +format_version: 1 +name: jina +display_name: Jina AI +tier: 3 +last_verified: "2026-04-05" +keywords: + - "jina" + - "JINA_API_KEY" + - "api.jina.ai" + - "jinaai" +patterns: + - regex: 'jina_[A-Za-z0-9]{40,}' + entropy_min: 4.0 + confidence: high +verify: + method: GET + url: https://api.jina.ai/v1/models + headers: + Authorization: "Bearer {KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +providers/unstructured.yaml: +```yaml +format_version: 1 +name: unstructured +display_name: Unstructured.io +tier: 3 +last_verified: "2026-04-05" +keywords: + - "unstructured" + - "UNSTRUCTURED_API_KEY" + - "api.unstructured.io" + - "unstructuredio" +verify: + method: GET + url: https://api.unstructured.io/general/v0/general + headers: + unstructured-api-key: "{KEY}" + valid_status: [200, 400] + invalid_status: [401, 403] +``` + +providers/assemblyai.yaml: +```yaml +format_version: 1 +name: assemblyai +display_name: AssemblyAI +tier: 3 +last_verified: "2026-04-05" +keywords: + - "assemblyai" + - "ASSEMBLYAI_API_KEY" + - "api.assemblyai.com" + - "assembly.ai" +patterns: + - regex: '[a-f0-9]{32}' + entropy_min: 4.0 + confidence: low +verify: + method: GET + url: https://api.assemblyai.com/v2/transcript + headers: + authorization: "{KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +Copy all 6 files verbatim to pkg/providers/definitions/. + + + cd /home/salva/Documents/apikey && for f in perplexity you voyage jina unstructured assemblyai; 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 + + + - All 12 files exist (6 providers × 2 locations) + - `grep -q 'pplx-' providers/perplexity.yaml` + - `grep -q 'jina_' providers/jina.yaml` + - `grep -q 'api.voyageai.com' providers/voyage.yaml` + - `diff providers/perplexity.yaml pkg/providers/definitions/perplexity.yaml` returns no diff + - `go test ./pkg/providers/... -count=1` passes + - `go test ./pkg/engine/... -count=1` passes + + 6 search/embeddings providers dual-located. + + + + Task 2: Voice + image/video providers (Deepgram, ElevenLabs, Stability, Runway, Midjourney) + providers/deepgram.yaml, providers/elevenlabs.yaml, providers/stability.yaml, providers/runway.yaml, providers/midjourney.yaml, pkg/providers/definitions/deepgram.yaml, pkg/providers/definitions/elevenlabs.yaml, pkg/providers/definitions/stability.yaml, pkg/providers/definitions/runway.yaml, pkg/providers/definitions/midjourney.yaml + + - pkg/providers/schema.go + + +providers/deepgram.yaml: +```yaml +format_version: 1 +name: deepgram +display_name: Deepgram +tier: 3 +last_verified: "2026-04-05" +keywords: + - "deepgram" + - "DEEPGRAM_API_KEY" + - "api.deepgram.com" + - "dg-api" +patterns: + - regex: '[a-f0-9]{40}' + entropy_min: 4.0 + confidence: low +verify: + method: GET + url: https://api.deepgram.com/v1/projects + headers: + Authorization: "Token {KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +providers/elevenlabs.yaml: +```yaml +format_version: 1 +name: elevenlabs +display_name: ElevenLabs +tier: 3 +last_verified: "2026-04-05" +keywords: + - "elevenlabs" + - "ELEVENLABS_API_KEY" + - "ELEVEN_API_KEY" + - "XI_API_KEY" + - "api.elevenlabs.io" +patterns: + - regex: '[a-f0-9]{32}' + entropy_min: 4.0 + confidence: low +verify: + method: GET + url: https://api.elevenlabs.io/v1/user + headers: + xi-api-key: "{KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +providers/stability.yaml: +```yaml +format_version: 1 +name: stability +display_name: Stability AI +tier: 3 +last_verified: "2026-04-05" +keywords: + - "stability" + - "STABILITY_API_KEY" + - "STABILITY_KEY" + - "api.stability.ai" + - "stable-diffusion" +patterns: + - regex: 'sk-[A-Za-z0-9]{48}' + entropy_min: 4.0 + confidence: medium +verify: + method: GET + url: https://api.stability.ai/v1/user/account + headers: + Authorization: "Bearer {KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +providers/runway.yaml: +```yaml +format_version: 1 +name: runway +display_name: Runway +tier: 3 +last_verified: "2026-04-05" +keywords: + - "runway" + - "runwayml" + - "RUNWAY_API_KEY" + - "RUNWAYML_API_SECRET" + - "api.runwayml.com" + - "dev.runwayml.com" +verify: + method: GET + url: https://api.dev.runwayml.com/v1/tasks + headers: + Authorization: "Bearer {KEY}" + valid_status: [200, 400] + invalid_status: [401, 403] +``` + +providers/midjourney.yaml: +```yaml +format_version: 1 +name: midjourney +display_name: Midjourney +tier: 3 +last_verified: "2026-04-05" +keywords: + - "midjourney" + - "MIDJOURNEY_API_KEY" + - "MJ_API_KEY" + - "midjourney.com" + - "useapi.net" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +Copy all 5 files verbatim to pkg/providers/definitions/. + + + cd /home/salva/Documents/apikey && for f in deepgram elevenlabs stability runway midjourney; 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 + + + - All 10 files exist + - `grep -q 'XI_API_KEY' providers/elevenlabs.yaml` + - `grep -q 'stable-diffusion' providers/stability.yaml` + - `grep -q 'runwayml' providers/runway.yaml` + - `grep -L 'patterns:' providers/runway.yaml providers/midjourney.yaml` returns both (keyword-only) + - Total Tier 3 count: `grep -l 'tier: 3' providers/*.yaml | wc -l` → 12 (11 new + pre-existing huggingface) + - `go test ./pkg/providers/... -count=1` passes + - `go test ./pkg/engine/... -count=1` passes + + All 11 new Tier 3 Specialized providers dual-located. PROV-03 satisfied (12 total with pre-existing huggingface). + + + + + +`grep -l 'tier: 3' providers/*.yaml | wc -l` returns 12. + + + +- 11 new Tier 3 providers added (huggingface pre-existing, total 12) +- All dual-located +- Documented prefixes use tight regex; undocumented use keyword-only +- No engine regression + + + +After completion, create `.planning/phases/03-tier-3-9-providers/03-02-SUMMARY.md` + diff --git a/.planning/phases/03-tier-3-9-providers/03-03-PLAN.md b/.planning/phases/03-tier-3-9-providers/03-03-PLAN.md new file mode 100644 index 0000000..c103519 --- /dev/null +++ b/.planning/phases/03-tier-3-9-providers/03-03-PLAN.md @@ -0,0 +1,393 @@ +--- +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" +--- + + +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. + + + +@$HOME/.claude/get-shit-done/workflows/execute-plan.md +@$HOME/.claude/get-shit-done/templates/summary.md + + + +@.planning/ROADMAP.md +@.planning/phases/03-tier-3-9-providers/03-CONTEXT.md +@pkg/providers/schema.go +@providers/groq.yaml + + +Schema per pkg/providers/schema.go. No category field. Dual-location required. RE2 regex only. +Keyword-only detection for providers without documented key formats. + + + + + + + Task 1: OpenRouter, LiteLLM, Cloudflare, Vercel, Portkey, Helicone YAMLs + 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 + + - pkg/providers/schema.go + + +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/. + + + 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 + + + - 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 + + 6 major gateway providers dual-located. + + + + Task 2: Martian, Kong, BricksAI, Aether, Not Diamond YAMLs + 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 + + - pkg/providers/schema.go + + +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/. + + + 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" + + + - 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 + + All 11 Tier 5 gateway providers dual-located. PROV-05 satisfied. + + + + + +`grep -l 'tier: 5' providers/*.yaml | wc -l` returns 11. + + + +- 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 + + + +After completion, create `.planning/phases/03-tier-3-9-providers/03-03-SUMMARY.md` + diff --git a/.planning/phases/03-tier-3-9-providers/03-04-PLAN.md b/.planning/phases/03-tier-3-9-providers/03-04-PLAN.md new file mode 100644 index 0000000..fee7500 --- /dev/null +++ b/.planning/phases/03-tier-3-9-providers/03-04-PLAN.md @@ -0,0 +1,382 @@ +--- +phase: 03-tier-3-9-providers +plan: 04 +type: execute +wave: 1 +depends_on: [] +files_modified: + - providers/github-copilot.yaml + - providers/cursor.yaml + - providers/tabnine.yaml + - providers/codeium.yaml + - providers/sourcegraph.yaml + - providers/codewhisperer.yaml + - providers/replit-ai.yaml + - providers/codestral.yaml + - providers/watsonx.yaml + - providers/oracle-ai.yaml + - pkg/providers/definitions/github-copilot.yaml + - pkg/providers/definitions/cursor.yaml + - pkg/providers/definitions/tabnine.yaml + - pkg/providers/definitions/codeium.yaml + - pkg/providers/definitions/sourcegraph.yaml + - pkg/providers/definitions/codewhisperer.yaml + - pkg/providers/definitions/replit-ai.yaml + - pkg/providers/definitions/codestral.yaml + - pkg/providers/definitions/watsonx.yaml + - pkg/providers/definitions/oracle-ai.yaml +autonomous: true +requirements: [PROV-07] +must_haves: + truths: + - "10 Tier 7 Code/Dev Tools provider YAMLs load" + - "Sourcegraph Cody uses documented sgp_ prefix pattern" + - "GitHub Copilot uses ghu_/gho_ token patterns" + artifacts: + - path: "providers/github-copilot.yaml" + provides: "GitHub Copilot token pattern" + contains: "copilot" + - path: "providers/sourcegraph.yaml" + provides: "Sourcegraph Cody sgp_ pattern" + contains: "sgp_" + - path: "providers/codestral.yaml" + provides: "Codestral (Mistral) keyword detection" + contains: "codestral" + key_links: + - from: "provider keywords[]" + to: "Registry Aho-Corasick automaton" + via: "NewRegistry()" + pattern: "keywords" +--- + + +Create 10 Tier 7 Code/Dev Tools provider YAMLs — AI coding assistants and IDE plugins (GitHub Copilot, Cursor, Tabnine, Codeium, Sourcegraph Cody, Amazon CodeWhisperer, Replit AI, Codestral, IBM watsonx, Oracle AI). + +Purpose: Satisfy PROV-07 (10 Tier 7 Code/Dev Tools providers). + +Output: 20 YAML files. + +Addresses PROV-07. + + + +@$HOME/.claude/get-shit-done/workflows/execute-plan.md +@$HOME/.claude/get-shit-done/templates/summary.md + + + +@.planning/ROADMAP.md +@.planning/phases/03-tier-3-9-providers/03-CONTEXT.md +@pkg/providers/schema.go + + +Schema per pkg/providers/schema.go. Dual-location required. RE2 regex only. +GitHub Copilot uses standard GitHub token formats (ghu_, gho_) — keyword anchoring to "copilot" disambiguates from generic GitHub tokens. + + + + + + + Task 1: GitHub Copilot, Cursor, Tabnine, Codeium, Sourcegraph YAMLs + providers/github-copilot.yaml, providers/cursor.yaml, providers/tabnine.yaml, providers/codeium.yaml, providers/sourcegraph.yaml, pkg/providers/definitions/github-copilot.yaml, pkg/providers/definitions/cursor.yaml, pkg/providers/definitions/tabnine.yaml, pkg/providers/definitions/codeium.yaml, pkg/providers/definitions/sourcegraph.yaml + + - pkg/providers/schema.go + + +providers/github-copilot.yaml: + +```yaml +format_version: 1 +name: github-copilot +display_name: GitHub Copilot +tier: 7 +last_verified: "2026-04-05" +keywords: + - "copilot" + - "github-copilot" + - "GITHUB_COPILOT_TOKEN" + - "api.githubcopilot.com" + - "copilot-internal" +patterns: + - regex: 'ghu_[A-Za-z0-9]{36}' + entropy_min: 4.0 + confidence: medium + - regex: 'gho_[A-Za-z0-9]{36}' + entropy_min: 4.0 + confidence: medium +verify: + method: GET + url: https://api.github.com/user + headers: + Authorization: "token {KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +providers/cursor.yaml: + +```yaml +format_version: 1 +name: cursor +display_name: Cursor AI +tier: 7 +last_verified: "2026-04-05" +keywords: + - "cursor" + - "CURSOR_API_KEY" + - "cursor.sh" + - "cursor.com" + - "cursor-ide" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/tabnine.yaml: + +```yaml +format_version: 1 +name: tabnine +display_name: Tabnine +tier: 7 +last_verified: "2026-04-05" +keywords: + - "tabnine" + - "TABNINE_API_KEY" + - "api.tabnine.com" + - "tabnine-pro" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/codeium.yaml: + +```yaml +format_version: 1 +name: codeium +display_name: Codeium (Windsurf) +tier: 7 +last_verified: "2026-04-05" +keywords: + - "codeium" + - "windsurf" + - "CODEIUM_API_KEY" + - "WINDSURF_API_KEY" + - "codeium.com" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/sourcegraph.yaml: + +```yaml +format_version: 1 +name: sourcegraph +display_name: Sourcegraph Cody +tier: 7 +last_verified: "2026-04-05" +keywords: + - "sourcegraph" + - "cody" + - "SRC_ACCESS_TOKEN" + - "SOURCEGRAPH_TOKEN" + - "sourcegraph.com" + - "sgp_" +patterns: + - regex: 'sgp_[A-Fa-f0-9]{16,}_[A-Fa-f0-9]{40}' + entropy_min: 4.0 + confidence: high + - regex: 'sgp_[A-Fa-f0-9]{40}' + entropy_min: 4.0 + confidence: medium +verify: + method: GET + url: https://sourcegraph.com/.api/graphql + headers: + Authorization: "token {KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +Copy all 5 files verbatim to pkg/providers/definitions/. + + + cd /home/salva/Documents/apikey && for f in github-copilot cursor tabnine codeium sourcegraph; 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 + + + - All 10 files exist + - `grep -q 'ghu_' providers/github-copilot.yaml` + - `grep -q 'sgp_' providers/sourcegraph.yaml` + - `grep -q 'windsurf' providers/codeium.yaml` + - `go test ./pkg/providers/... -count=1` passes + - `go test ./pkg/engine/... -count=1` passes + + 5 code assistant providers dual-located. + + + + Task 2: CodeWhisperer, Replit AI, Codestral, watsonx, Oracle AI YAMLs + providers/codewhisperer.yaml, providers/replit-ai.yaml, providers/codestral.yaml, providers/watsonx.yaml, providers/oracle-ai.yaml, pkg/providers/definitions/codewhisperer.yaml, pkg/providers/definitions/replit-ai.yaml, pkg/providers/definitions/codestral.yaml, pkg/providers/definitions/watsonx.yaml, pkg/providers/definitions/oracle-ai.yaml + + - pkg/providers/schema.go + + +providers/codewhisperer.yaml: + +```yaml +format_version: 1 +name: codewhisperer +display_name: Amazon CodeWhisperer / Q Developer +tier: 7 +last_verified: "2026-04-05" +keywords: + - "codewhisperer" + - "q-developer" + - "amazonq" + - "codewhisperer.us-east-1.amazonaws.com" + - "CODEWHISPERER_PROFILE_ARN" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/replit-ai.yaml: + +```yaml +format_version: 1 +name: replit-ai +display_name: Replit AI (Ghostwriter) +tier: 7 +last_verified: "2026-04-05" +keywords: + - "replit" + - "ghostwriter" + - "REPLIT_TOKEN" + - "REPLIT_DB_URL" + - "replit.com" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/codestral.yaml: + +```yaml +format_version: 1 +name: codestral +display_name: Codestral (Mistral Code) +tier: 7 +last_verified: "2026-04-05" +keywords: + - "codestral" + - "CODESTRAL_API_KEY" + - "codestral.mistral.ai" + - "codestral-latest" +patterns: + - regex: '[a-zA-Z0-9]{32}' + entropy_min: 4.5 + confidence: low +verify: + method: GET + url: https://codestral.mistral.ai/v1/models + headers: + Authorization: "Bearer {KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +providers/watsonx.yaml: + +```yaml +format_version: 1 +name: watsonx +display_name: IBM watsonx +tier: 7 +last_verified: "2026-04-05" +keywords: + - "watsonx" + - "WATSONX_API_KEY" + - "WATSONX_PROJECT_ID" + - "IBM_CLOUD_API_KEY" + - "us-south.ml.cloud.ibm.com" + - "watsonx.ai" +verify: + method: POST + url: https://iam.cloud.ibm.com/identity/token + headers: {} + valid_status: [200] + invalid_status: [400, 401] +``` + +providers/oracle-ai.yaml: + +```yaml +format_version: 1 +name: oracle-ai +display_name: Oracle Generative AI +tier: 7 +last_verified: "2026-04-05" +keywords: + - "oci-genai" + - "oracle-genai" + - "OCI_GENAI" + - "generativeai.oci.oraclecloud.com" + - "oraclecloud.com" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +Copy all 5 files verbatim to pkg/providers/definitions/. + + + cd /home/salva/Documents/apikey && for f in codewhisperer replit-ai codestral watsonx oracle-ai; 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: 7' providers/*.yaml | wc -l) -eq 10 + + + - All 10 files exist + - `grep -q 'codewhisperer' providers/codewhisperer.yaml` + - `grep -q 'watsonx.ai' providers/watsonx.yaml` + - `grep -q 'oraclecloud' providers/oracle-ai.yaml` + - Total Tier 7 count = 10 + - `go test ./pkg/providers/... -count=1` passes + + All 10 Tier 7 code/dev tools providers dual-located. PROV-07 satisfied. + + + + + +`grep -l 'tier: 7' providers/*.yaml | wc -l` returns 10. + + + +- 10 Tier 7 code/dev tools providers created +- Sourcegraph uses documented sgp_ high-confidence pattern +- Undocumented providers (cursor, tabnine, codeium, codewhisperer, replit-ai, oracle-ai) use keyword-only +- No engine regression + + + +After completion, create `.planning/phases/03-tier-3-9-providers/03-04-SUMMARY.md` + diff --git a/.planning/phases/03-tier-3-9-providers/03-05-PLAN.md b/.planning/phases/03-tier-3-9-providers/03-05-PLAN.md new file mode 100644 index 0000000..c197552 --- /dev/null +++ b/.planning/phases/03-tier-3-9-providers/03-05-PLAN.md @@ -0,0 +1,364 @@ +--- +phase: 03-tier-3-9-providers +plan: 05 +type: execute +wave: 1 +depends_on: [] +files_modified: + - providers/ollama.yaml + - providers/vllm.yaml + - providers/localai.yaml + - providers/lmstudio.yaml + - providers/llamacpp.yaml + - providers/gpt4all.yaml + - providers/text-gen-webui.yaml + - providers/tensorrt-llm.yaml + - providers/triton.yaml + - providers/jan.yaml + - pkg/providers/definitions/ollama.yaml + - pkg/providers/definitions/vllm.yaml + - pkg/providers/definitions/localai.yaml + - pkg/providers/definitions/lmstudio.yaml + - pkg/providers/definitions/llamacpp.yaml + - pkg/providers/definitions/gpt4all.yaml + - pkg/providers/definitions/text-gen-webui.yaml + - pkg/providers/definitions/tensorrt-llm.yaml + - pkg/providers/definitions/triton.yaml + - pkg/providers/definitions/jan.yaml +autonomous: true +requirements: [PROV-08] +must_haves: + truths: + - "10 Tier 8 Self-Hosted runtime provider YAMLs load" + - "Self-hosted runtimes mostly use keyword-only detection (local auth, not API keys)" + - "Runtimes exposing API key auth (vLLM --api-key, LocalAI) include env var keywords" + artifacts: + - path: "providers/ollama.yaml" + provides: "Ollama localhost endpoint keywords" + contains: "ollama" + - path: "providers/vllm.yaml" + provides: "vLLM --api-key detection keywords" + contains: "vllm" + key_links: + - from: "provider keywords[]" + to: "Registry Aho-Corasick automaton" + via: "NewRegistry()" + pattern: "keywords" +--- + + +Create 10 Tier 8 Self-Hosted LLM runtime provider YAMLs — local inference servers (Ollama, vLLM, LocalAI, LM Studio, llama.cpp, GPT4All, text-generation-webui, TensorRT-LLM, Triton, Jan AI). + +Purpose: Satisfy PROV-08 (10 Tier 8 Self-Hosted providers). Self-hosted runtimes are interesting for OSINT (exposed endpoints via Shodan) even without API keys — keyword anchors enable later recon phases to correlate. + +Output: 20 YAML files. + +Addresses PROV-08. + + + +@$HOME/.claude/get-shit-done/workflows/execute-plan.md +@$HOME/.claude/get-shit-done/templates/summary.md + + + +@.planning/ROADMAP.md +@.planning/phases/03-tier-3-9-providers/03-CONTEXT.md +@pkg/providers/schema.go + + +Self-hosted runtimes rarely use bearer tokens. Detection relies on config env vars, localhost endpoints (11434, 8000, 1234), CLI flags. All use keyword-only — omit patterns entirely. + + + + + + + Task 1: Ollama, vLLM, LocalAI, LM Studio, llama.cpp YAMLs + providers/ollama.yaml, providers/vllm.yaml, providers/localai.yaml, providers/lmstudio.yaml, providers/llamacpp.yaml, pkg/providers/definitions/ollama.yaml, pkg/providers/definitions/vllm.yaml, pkg/providers/definitions/localai.yaml, pkg/providers/definitions/lmstudio.yaml, pkg/providers/definitions/llamacpp.yaml + + - pkg/providers/schema.go + + +All 5 use keyword-only detection — omit patterns field. + +providers/ollama.yaml: + +```yaml +format_version: 1 +name: ollama +display_name: Ollama +tier: 8 +last_verified: "2026-04-05" +keywords: + - "ollama" + - "OLLAMA_HOST" + - "OLLAMA_API_KEY" + - "OLLAMA_MODELS" + - "localhost:11434" + - "127.0.0.1:11434" + - "api/generate" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/vllm.yaml: + +```yaml +format_version: 1 +name: vllm +display_name: vLLM +tier: 8 +last_verified: "2026-04-05" +keywords: + - "vllm" + - "VLLM_API_KEY" + - "vllm-openai" + - "--api-key" + - "openai.api_server" + - "vllm.entrypoints" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/localai.yaml: + +```yaml +format_version: 1 +name: localai +display_name: LocalAI +tier: 8 +last_verified: "2026-04-05" +keywords: + - "localai" + - "LOCALAI_API_KEY" + - "go-skynet" + - "localai.io" + - "localhost:8080" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/lmstudio.yaml: + +```yaml +format_version: 1 +name: lmstudio +display_name: LM Studio +tier: 8 +last_verified: "2026-04-05" +keywords: + - "lmstudio" + - "lm-studio" + - "LMSTUDIO_API_KEY" + - "localhost:1234" + - "lmstudio.ai" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/llamacpp.yaml: + +```yaml +format_version: 1 +name: llamacpp +display_name: llama.cpp server +tier: 8 +last_verified: "2026-04-05" +keywords: + - "llama.cpp" + - "llama-cpp" + - "llama_cpp" + - "LLAMA_API_KEY" + - "ggml" + - "gguf" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +Copy all 5 files verbatim to pkg/providers/definitions/. + + + cd /home/salva/Documents/apikey && for f in ollama vllm localai lmstudio llamacpp; 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 + + + - All 10 files exist + - `grep -q 'localhost:11434' providers/ollama.yaml` + - `grep -q 'vllm.entrypoints' providers/vllm.yaml` + - `grep -q 'gguf' providers/llamacpp.yaml` + - All 5 omit patterns field: `grep -L 'patterns:' providers/{ollama,vllm,localai,lmstudio,llamacpp}.yaml` returns all 5 + - `go test ./pkg/providers/... -count=1` passes + + 5 self-hosted runtimes dual-located, keyword-only. + + + + Task 2: GPT4All, text-gen-webui, TensorRT-LLM, Triton, Jan AI YAMLs + providers/gpt4all.yaml, providers/text-gen-webui.yaml, providers/tensorrt-llm.yaml, providers/triton.yaml, providers/jan.yaml, pkg/providers/definitions/gpt4all.yaml, pkg/providers/definitions/text-gen-webui.yaml, pkg/providers/definitions/tensorrt-llm.yaml, pkg/providers/definitions/triton.yaml, pkg/providers/definitions/jan.yaml + + - pkg/providers/schema.go + + +All keyword-only (no patterns field). + +providers/gpt4all.yaml: + +```yaml +format_version: 1 +name: gpt4all +display_name: GPT4All +tier: 8 +last_verified: "2026-04-05" +keywords: + - "gpt4all" + - "nomic-ai" + - "GPT4ALL_API_KEY" + - "gpt4all.io" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/text-gen-webui.yaml: + +```yaml +format_version: 1 +name: text-gen-webui +display_name: text-generation-webui (oobabooga) +tier: 8 +last_verified: "2026-04-05" +keywords: + - "text-generation-webui" + - "oobabooga" + - "TEXTGEN_API_KEY" + - "text-gen-webui" + - "localhost:5000" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/tensorrt-llm.yaml: + +```yaml +format_version: 1 +name: tensorrt-llm +display_name: NVIDIA TensorRT-LLM +tier: 8 +last_verified: "2026-04-05" +keywords: + - "tensorrt-llm" + - "trtllm" + - "TRTLLM_API_KEY" + - "tensorrt_llm" + - "nvidia-nim" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/triton.yaml: + +```yaml +format_version: 1 +name: triton +display_name: NVIDIA Triton Inference Server +tier: 8 +last_verified: "2026-04-05" +keywords: + - "triton-inference-server" + - "tritonserver" + - "TRITON_API_KEY" + - "triton_grpc" + - "v2/models" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/jan.yaml: + +```yaml +format_version: 1 +name: jan +display_name: Jan AI +tier: 8 +last_verified: "2026-04-05" +keywords: + - "jan-ai" + - "janhq" + - "JAN_API_KEY" + - "jan.ai" + - "cortex-cpp" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +Copy all 5 files verbatim to pkg/providers/definitions/. + + + cd /home/salva/Documents/apikey && for f in gpt4all text-gen-webui tensorrt-llm triton jan; 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: 8' providers/*.yaml | wc -l) -eq 10 + + + - All 10 files exist + - `grep -q 'oobabooga' providers/text-gen-webui.yaml` + - `grep -q 'tritonserver' providers/triton.yaml` + - `grep -q 'janhq' providers/jan.yaml` + - Total Tier 8 count = 10 + - `go test ./pkg/providers/... -count=1` passes + + All 10 Tier 8 self-hosted runtimes dual-located. PROV-08 satisfied. + + + + + +`grep -l 'tier: 8' providers/*.yaml | wc -l` returns 10. + + + +- 10 Tier 8 self-hosted runtimes created +- All keyword-only (no regex patterns — avoids false positives) +- Localhost endpoints and env vars captured as keywords +- No engine regression + + + +After completion, create `.planning/phases/03-tier-3-9-providers/03-05-SUMMARY.md` + diff --git a/.planning/phases/03-tier-3-9-providers/03-06-PLAN.md b/.planning/phases/03-tier-3-9-providers/03-06-PLAN.md new file mode 100644 index 0000000..0054b41 --- /dev/null +++ b/.planning/phases/03-tier-3-9-providers/03-06-PLAN.md @@ -0,0 +1,331 @@ +--- +phase: 03-tier-3-9-providers +plan: 06 +type: execute +wave: 1 +depends_on: [] +files_modified: + - providers/salesforce-einstein.yaml + - providers/servicenow.yaml + - providers/sap-ai-core.yaml + - providers/palantir.yaml + - providers/databricks.yaml + - providers/snowflake.yaml + - providers/oracle-genai.yaml + - providers/hpe-greenlake.yaml + - pkg/providers/definitions/salesforce-einstein.yaml + - pkg/providers/definitions/servicenow.yaml + - pkg/providers/definitions/sap-ai-core.yaml + - pkg/providers/definitions/palantir.yaml + - pkg/providers/definitions/databricks.yaml + - pkg/providers/definitions/snowflake.yaml + - pkg/providers/definitions/oracle-genai.yaml + - pkg/providers/definitions/hpe-greenlake.yaml +autonomous: true +requirements: [PROV-09] +must_haves: + truths: + - "8 Tier 9 Enterprise provider YAMLs load" + - "Databricks dapi-prefix and Snowflake JWT keywords captured" + - "All enterprise providers have strong env var keyword anchors" + artifacts: + - path: "providers/databricks.yaml" + provides: "Databricks dapi token pattern" + contains: "dapi" + - path: "providers/snowflake.yaml" + provides: "Snowflake Cortex keyword detection" + contains: "snowflake" + - path: "providers/palantir.yaml" + provides: "Palantir AIP keyword detection" + contains: "palantir" + key_links: + - from: "provider keywords[]" + to: "Registry Aho-Corasick automaton" + via: "NewRegistry()" + pattern: "keywords" +--- + + +Create 8 Tier 9 Enterprise AI platform provider YAMLs — enterprise SaaS AI (Salesforce Einstein, ServiceNow Now Assist, SAP Joule, Palantir AIP, Databricks, Snowflake Cortex, Oracle GenAI, HPE GreenLake). + +Purpose: Satisfy PROV-09 (8 Tier 9 Enterprise providers). These target regulated enterprise estates where leaked keys carry high blast radius. + +Output: 16 YAML files. + +Addresses PROV-09. + +Note: `oracle-genai` here is distinct from `oracle-ai` in plan 03-04 (which is Tier 7 code tools). Tier 9 entry uses name `oracle-genai` to avoid collision. + + + +@$HOME/.claude/get-shit-done/workflows/execute-plan.md +@$HOME/.claude/get-shit-done/templates/summary.md + + + +@.planning/ROADMAP.md +@.planning/phases/03-tier-3-9-providers/03-CONTEXT.md +@pkg/providers/schema.go + + +Dual-location required. Keyword-only for most; databricks has a documented `dapi` prefix. + + + + + + + Task 1: Salesforce, ServiceNow, SAP, Palantir YAMLs + providers/salesforce-einstein.yaml, providers/servicenow.yaml, providers/sap-ai-core.yaml, providers/palantir.yaml, pkg/providers/definitions/salesforce-einstein.yaml, pkg/providers/definitions/servicenow.yaml, pkg/providers/definitions/sap-ai-core.yaml, pkg/providers/definitions/palantir.yaml + + - pkg/providers/schema.go + + +All 4 use keyword-only detection (no public key formats documented). + +providers/salesforce-einstein.yaml: + +```yaml +format_version: 1 +name: salesforce-einstein +display_name: Salesforce Einstein GPT +tier: 9 +last_verified: "2026-04-05" +keywords: + - "einstein-gpt" + - "einsteinGPT" + - "SALESFORCE_CONSUMER_KEY" + - "SALESFORCE_CONSUMER_SECRET" + - "api.salesforce.com" + - "einstein.ai" + - "salesforce-einstein" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/servicenow.yaml: + +```yaml +format_version: 1 +name: servicenow +display_name: ServiceNow Now Assist +tier: 9 +last_verified: "2026-04-05" +keywords: + - "servicenow" + - "now-assist" + - "SERVICENOW_INSTANCE" + - "SERVICENOW_USERNAME" + - "SERVICENOW_PASSWORD" + - "service-now.com" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/sap-ai-core.yaml: + +```yaml +format_version: 1 +name: sap-ai-core +display_name: SAP AI Core / Joule +tier: 9 +last_verified: "2026-04-05" +keywords: + - "sap-ai-core" + - "sap-joule" + - "SAP_AICORE_CLIENT_ID" + - "SAP_AICORE_CLIENT_SECRET" + - "SAP_AICORE_AUTH_URL" + - "hana.ondemand.com" + - "aicore" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/palantir.yaml: + +```yaml +format_version: 1 +name: palantir +display_name: Palantir AIP +tier: 9 +last_verified: "2026-04-05" +keywords: + - "palantir" + - "foundry" + - "PALANTIR_TOKEN" + - "FOUNDRY_TOKEN" + - "palantirfoundry.com" + - "aip-agents" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +Copy all 4 files verbatim to pkg/providers/definitions/. + + + cd /home/salva/Documents/apikey && for f in salesforce-einstein servicenow sap-ai-core palantir; 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 + + + - All 8 files exist + - `grep -q 'einsteinGPT' providers/salesforce-einstein.yaml` + - `grep -q 'foundry' providers/palantir.yaml` + - `grep -q 'SAP_AICORE_CLIENT_ID' providers/sap-ai-core.yaml` + - `go test ./pkg/providers/... -count=1` passes + + 4 enterprise platform providers dual-located. + + + + Task 2: Databricks, Snowflake, Oracle GenAI, HPE GreenLake YAMLs + providers/databricks.yaml, providers/snowflake.yaml, providers/oracle-genai.yaml, providers/hpe-greenlake.yaml, pkg/providers/definitions/databricks.yaml, pkg/providers/definitions/snowflake.yaml, pkg/providers/definitions/oracle-genai.yaml, pkg/providers/definitions/hpe-greenlake.yaml + + - pkg/providers/schema.go + + +providers/databricks.yaml: + +```yaml +format_version: 1 +name: databricks +display_name: Databricks (DBRX / Mosaic) +tier: 9 +last_verified: "2026-04-05" +keywords: + - "databricks" + - "DATABRICKS_TOKEN" + - "DATABRICKS_HOST" + - "dbrx" + - "mosaicml" + - "dapi" + - ".cloud.databricks.com" +patterns: + - regex: 'dapi[a-f0-9]{32}(-[0-9]{1,2})?' + entropy_min: 3.5 + confidence: high +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/snowflake.yaml: + +```yaml +format_version: 1 +name: snowflake +display_name: Snowflake Cortex +tier: 9 +last_verified: "2026-04-05" +keywords: + - "snowflake" + - "SNOWFLAKE_ACCOUNT" + - "SNOWFLAKE_USER" + - "SNOWFLAKE_PASSWORD" + - "SNOWFLAKE_PRIVATE_KEY" + - "snowflakecomputing.com" + - "cortex" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/oracle-genai.yaml: + +```yaml +format_version: 1 +name: oracle-genai +display_name: Oracle Cloud Generative AI Service +tier: 9 +last_verified: "2026-04-05" +keywords: + - "oci-generative-ai" + - "OCI_GENAI_COMPARTMENT" + - "oracle-cloud-genai" + - "inference.generativeai.us-chicago-1" + - "oci-cli" + - "OCI_CONFIG_FILE" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/hpe-greenlake.yaml: + +```yaml +format_version: 1 +name: hpe-greenlake +display_name: HPE GreenLake for LLMs +tier: 9 +last_verified: "2026-04-05" +keywords: + - "hpe-greenlake" + - "greenlake" + - "HPE_CLIENT_ID" + - "HPE_CLIENT_SECRET" + - "common.cloud.hpe.com" + - "hpe-ai" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +Copy all 4 files verbatim to pkg/providers/definitions/. + + + cd /home/salva/Documents/apikey && for f in databricks snowflake oracle-genai hpe-greenlake; 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: 9' providers/*.yaml | wc -l) -eq 8 + + + - All 8 files exist + - `grep -q 'dapi' providers/databricks.yaml` + - `grep -q 'snowflakecomputing.com' providers/snowflake.yaml` + - `grep -q 'greenlake' providers/hpe-greenlake.yaml` + - Total Tier 9 count = 8 + - `go test ./pkg/providers/... -count=1` passes + + All 8 Tier 9 enterprise providers dual-located. PROV-09 satisfied. + + + + + +`grep -l 'tier: 9' providers/*.yaml | wc -l` returns 8. + + + +- 8 Tier 9 enterprise providers created +- Databricks uses documented `dapi` high-confidence pattern +- Strong env var keyword anchors on all +- No engine regression + + + +After completion, create `.planning/phases/03-tier-3-9-providers/03-06-SUMMARY.md` + diff --git a/.planning/phases/03-tier-3-9-providers/03-07-PLAN.md b/.planning/phases/03-tier-3-9-providers/03-07-PLAN.md new file mode 100644 index 0000000..751ef5c --- /dev/null +++ b/.planning/phases/03-tier-3-9-providers/03-07-PLAN.md @@ -0,0 +1,504 @@ +--- +phase: 03-tier-3-9-providers +plan: 07 +type: execute +wave: 1 +depends_on: [] +files_modified: + - providers/reka.yaml + - providers/aleph-alpha.yaml + - providers/writer.yaml + - providers/jasper.yaml + - providers/typeface.yaml + - providers/comet.yaml + - providers/wandb.yaml + - providers/langsmith.yaml + - providers/pinecone.yaml + - providers/weaviate.yaml + - providers/qdrant.yaml + - providers/chroma.yaml + - providers/milvus.yaml + - providers/neon.yaml + - providers/lamini.yaml + - pkg/providers/definitions/reka.yaml + - pkg/providers/definitions/aleph-alpha.yaml + - pkg/providers/definitions/writer.yaml + - pkg/providers/definitions/jasper.yaml + - pkg/providers/definitions/typeface.yaml + - pkg/providers/definitions/comet.yaml + - pkg/providers/definitions/wandb.yaml + - pkg/providers/definitions/langsmith.yaml + - pkg/providers/definitions/pinecone.yaml + - pkg/providers/definitions/weaviate.yaml + - pkg/providers/definitions/qdrant.yaml + - pkg/providers/definitions/chroma.yaml + - pkg/providers/definitions/milvus.yaml + - pkg/providers/definitions/neon.yaml + - pkg/providers/definitions/lamini.yaml +autonomous: true +requirements: [PROV-06] +must_haves: + truths: + - "15 Tier 6 Emerging/Niche provider YAMLs load" + - "W&B uses documented 40-hex key; LangSmith uses lsv2_ prefix; Pinecone uses pcsk_ prefix" + - "Vector DBs and writing tools have strong env var keyword anchors" + artifacts: + - path: "providers/langsmith.yaml" + provides: "LangSmith lsv2_ prefix pattern" + contains: "lsv2_" + - path: "providers/pinecone.yaml" + provides: "Pinecone pcsk_ prefix pattern" + contains: "pcsk_" + - path: "providers/wandb.yaml" + provides: "Weights & Biases 40-hex key pattern" + contains: "WANDB_API_KEY" + key_links: + - from: "provider keywords[]" + to: "Registry Aho-Corasick automaton" + via: "NewRegistry()" + pattern: "keywords" +--- + + +Create 15 Tier 6 Emerging/Niche provider YAMLs — emerging LLM labs (Reka, Aleph Alpha, Lamini), writing tools (Writer, Jasper, Typeface), observability (Comet, W&B, LangSmith), and vector DBs (Pinecone, Weaviate, Qdrant, Chroma, Milvus, Neon). + +Purpose: Satisfy PROV-06 (15 Tier 6 Emerging/Niche providers). + +Output: 30 YAML files. + +Addresses PROV-06. + + + +@$HOME/.claude/get-shit-done/workflows/execute-plan.md +@$HOME/.claude/get-shit-done/templates/summary.md + + + +@.planning/ROADMAP.md +@.planning/phases/03-tier-3-9-providers/03-CONTEXT.md +@pkg/providers/schema.go + + +Dual-location required. Several providers in this group have documented prefixes (LangSmith lsv2_, Pinecone pcsk_, W&B 40-hex). Others use keyword-only. + + + + + + + Task 1: Emerging labs + writing tools (Reka, Aleph Alpha, Lamini, Writer, Jasper, Typeface, Comet, W&B) + providers/reka.yaml, providers/aleph-alpha.yaml, providers/lamini.yaml, providers/writer.yaml, providers/jasper.yaml, providers/typeface.yaml, providers/comet.yaml, providers/wandb.yaml, pkg/providers/definitions/reka.yaml, pkg/providers/definitions/aleph-alpha.yaml, pkg/providers/definitions/lamini.yaml, pkg/providers/definitions/writer.yaml, pkg/providers/definitions/jasper.yaml, pkg/providers/definitions/typeface.yaml, pkg/providers/definitions/comet.yaml, pkg/providers/definitions/wandb.yaml + + - pkg/providers/schema.go + + +providers/reka.yaml: + +```yaml +format_version: 1 +name: reka +display_name: Reka AI +tier: 6 +last_verified: "2026-04-05" +keywords: + - "reka" + - "REKA_API_KEY" + - "api.reka.ai" + - "reka-core" + - "reka-flash" +verify: + method: GET + url: https://api.reka.ai/v1/models + headers: + X-Api-Key: "{KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +providers/aleph-alpha.yaml: + +```yaml +format_version: 1 +name: aleph-alpha +display_name: Aleph Alpha +tier: 6 +last_verified: "2026-04-05" +keywords: + - "aleph-alpha" + - "aleph_alpha" + - "ALEPH_ALPHA_API_KEY" + - "AA_TOKEN" + - "api.aleph-alpha.com" + - "luminous" +verify: + method: GET + url: https://api.aleph-alpha.com/models_available + headers: + Authorization: "Bearer {KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +providers/lamini.yaml: + +```yaml +format_version: 1 +name: lamini +display_name: Lamini +tier: 6 +last_verified: "2026-04-05" +keywords: + - "lamini" + - "LAMINI_API_KEY" + - "api.lamini.ai" + - "lamini.ai" +verify: + method: GET + url: https://api.lamini.ai/v1/models + headers: + Authorization: "Bearer {KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +providers/writer.yaml: + +```yaml +format_version: 1 +name: writer +display_name: Writer +tier: 6 +last_verified: "2026-04-05" +keywords: + - "writer.com" + - "WRITER_API_KEY" + - "api.writer.com" + - "palmyra" +verify: + method: GET + url: https://api.writer.com/v1/models + headers: + Authorization: "Bearer {KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +providers/jasper.yaml: + +```yaml +format_version: 1 +name: jasper +display_name: Jasper AI +tier: 6 +last_verified: "2026-04-05" +keywords: + - "jasper.ai" + - "JASPER_API_KEY" + - "api.jasper.ai" + - "jasper-ai" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/typeface.yaml: + +```yaml +format_version: 1 +name: typeface +display_name: Typeface +tier: 6 +last_verified: "2026-04-05" +keywords: + - "typeface" + - "typeface.ai" + - "TYPEFACE_API_KEY" + - "typeface-app" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/comet.yaml: + +```yaml +format_version: 1 +name: comet +display_name: Comet ML / Opik +tier: 6 +last_verified: "2026-04-05" +keywords: + - "comet_ml" + - "comet-ml" + - "COMET_API_KEY" + - "COMET_WORKSPACE" + - "opik" + - "comet.com" +verify: + method: GET + url: https://www.comet.com/api/rest/v2/workspaces + headers: + Authorization: "{KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +providers/wandb.yaml: + +```yaml +format_version: 1 +name: wandb +display_name: Weights & Biases +tier: 6 +last_verified: "2026-04-05" +keywords: + - "wandb" + - "weights_and_biases" + - "WANDB_API_KEY" + - "api.wandb.ai" + - "wandb.ai" +patterns: + - regex: '[a-f0-9]{40}' + entropy_min: 3.5 + confidence: low +verify: + method: GET + url: https://api.wandb.ai/graphql + headers: + Authorization: "Basic {KEY}" + valid_status: [200, 400] + invalid_status: [401, 403] +``` + +Copy all 8 files verbatim to pkg/providers/definitions/. + + + cd /home/salva/Documents/apikey && for f in reka aleph-alpha lamini writer jasper typeface comet wandb; 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 + + + - All 16 files exist + - `grep -q 'luminous' providers/aleph-alpha.yaml` + - `grep -q 'palmyra' providers/writer.yaml` + - `grep -q 'WANDB_API_KEY' providers/wandb.yaml` + - `go test ./pkg/providers/... -count=1` passes + + 8 emerging/writing/observability providers dual-located. + + + + Task 2: LangSmith + vector DBs (LangSmith, Pinecone, Weaviate, Qdrant, Chroma, Milvus, Neon) + providers/langsmith.yaml, providers/pinecone.yaml, providers/weaviate.yaml, providers/qdrant.yaml, providers/chroma.yaml, providers/milvus.yaml, providers/neon.yaml, pkg/providers/definitions/langsmith.yaml, pkg/providers/definitions/pinecone.yaml, pkg/providers/definitions/weaviate.yaml, pkg/providers/definitions/qdrant.yaml, pkg/providers/definitions/chroma.yaml, pkg/providers/definitions/milvus.yaml, pkg/providers/definitions/neon.yaml + + - pkg/providers/schema.go + + +providers/langsmith.yaml: + +```yaml +format_version: 1 +name: langsmith +display_name: LangSmith (LangChain) +tier: 6 +last_verified: "2026-04-05" +keywords: + - "langsmith" + - "langchain" + - "LANGCHAIN_API_KEY" + - "LANGSMITH_API_KEY" + - "LANGCHAIN_TRACING_V2" + - "api.smith.langchain.com" + - "lsv2_" +patterns: + - regex: 'lsv2_(pt|sk)_[a-f0-9]{32}_[a-f0-9]{10}' + entropy_min: 4.0 + confidence: high +verify: + method: GET + url: https://api.smith.langchain.com/info + headers: + X-API-Key: "{KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +providers/pinecone.yaml: + +```yaml +format_version: 1 +name: pinecone +display_name: Pinecone +tier: 6 +last_verified: "2026-04-05" +keywords: + - "pinecone" + - "PINECONE_API_KEY" + - "PINECONE_ENVIRONMENT" + - "api.pinecone.io" + - "pinecone.io" + - "pcsk_" +patterns: + - regex: 'pcsk_[A-Za-z0-9]{40,}' + entropy_min: 4.0 + confidence: high +verify: + method: GET + url: https://api.pinecone.io/indexes + headers: + Api-Key: "{KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +providers/weaviate.yaml: + +```yaml +format_version: 1 +name: weaviate +display_name: Weaviate +tier: 6 +last_verified: "2026-04-05" +keywords: + - "weaviate" + - "WEAVIATE_API_KEY" + - "WEAVIATE_URL" + - "weaviate.io" + - "wcs.api" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/qdrant.yaml: + +```yaml +format_version: 1 +name: qdrant +display_name: Qdrant +tier: 6 +last_verified: "2026-04-05" +keywords: + - "qdrant" + - "QDRANT_API_KEY" + - "QDRANT_URL" + - "qdrant.tech" + - "cloud.qdrant.io" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/chroma.yaml: + +```yaml +format_version: 1 +name: chroma +display_name: Chroma +tier: 6 +last_verified: "2026-04-05" +keywords: + - "chromadb" + - "chroma-client" + - "CHROMA_API_KEY" + - "CHROMA_HOST" + - "trychroma.com" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/milvus.yaml: + +```yaml +format_version: 1 +name: milvus +display_name: Milvus / Zilliz +tier: 6 +last_verified: "2026-04-05" +keywords: + - "milvus" + - "zilliz" + - "ZILLIZ_API_KEY" + - "MILVUS_TOKEN" + - "zilliz.com" + - "api.cloud.zilliz.com" +verify: + method: GET + url: "" + headers: {} + valid_status: [] + invalid_status: [] +``` + +providers/neon.yaml: + +```yaml +format_version: 1 +name: neon +display_name: Neon (Serverless Postgres + pgvector) +tier: 6 +last_verified: "2026-04-05" +keywords: + - "neon-db" + - "neondb" + - "NEON_API_KEY" + - "NEON_CONNECTION_STRING" + - "console.neon.tech" + - "pg.neon.tech" +verify: + method: GET + url: https://console.neon.tech/api/v2/projects + headers: + Authorization: "Bearer {KEY}" + valid_status: [200] + invalid_status: [401, 403] +``` + +Copy all 7 files verbatim to pkg/providers/definitions/. + + + cd /home/salva/Documents/apikey && for f in langsmith pinecone weaviate qdrant chroma milvus neon; 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: 6' providers/*.yaml | wc -l) -eq 15 + + + - All 14 files exist + - `grep -q 'lsv2_' providers/langsmith.yaml` + - `grep -q 'pcsk_' providers/pinecone.yaml` + - `grep -q 'zilliz' providers/milvus.yaml` + - Total Tier 6 count = 15 + - `go test ./pkg/providers/... -count=1` passes + - `go test ./pkg/engine/... -count=1` passes + + All 15 Tier 6 emerging/niche providers dual-located. PROV-06 satisfied. + + + + + +`grep -l 'tier: 6' providers/*.yaml | wc -l` returns 15. + + + +- 15 Tier 6 providers created +- LangSmith lsv2_ and Pinecone pcsk_ use high-confidence regex +- Vector DB env vars captured +- No engine regression + + + +After completion, create `.planning/phases/03-tier-3-9-providers/03-07-SUMMARY.md` + diff --git a/.planning/phases/03-tier-3-9-providers/03-08-PLAN.md b/.planning/phases/03-tier-3-9-providers/03-08-PLAN.md new file mode 100644 index 0000000..5c66c94 --- /dev/null +++ b/.planning/phases/03-tier-3-9-providers/03-08-PLAN.md @@ -0,0 +1,284 @@ +--- +phase: 03-tier-3-9-providers +plan: 08 +type: execute +wave: 2 +depends_on: ["03-01", "03-02", "03-03", "03-04", "03-05", "03-06", "03-07"] +files_modified: + - pkg/providers/tier39_test.go +autonomous: true +requirements: [PROV-03, PROV-04, PROV-05, PROV-06, PROV-07, PROV-08, PROV-09] +must_haves: + truths: + - "Registry loads 108 total providers (26 Tier 1-2 + 82 Tier 3-9)" + - "Per-tier counts enforced: T3=12, T4=16, T5=11, T6=15, T7=10, T8=10, T9=8" + - "All 82 Tier 3-9 provider names are known (lock set against drift)" + - "All regex patterns compile under RE2" + - "Every provider has ≥1 keyword (Aho-Corasick pre-filter requirement)" + - "Phase 2 Tier 1-2 guardrails still pass (no regression)" + artifacts: + - path: "pkg/providers/tier39_test.go" + provides: "Tier 3-9 guardrail tests" + contains: "TestTier39" + key_links: + - from: "pkg/providers/tier39_test.go" + to: "registry.NewRegistry() Stats() Get() All()" + via: "go test ./pkg/providers/..." + pattern: "NewRegistry" +--- + + +Create the Tier 3-9 guardrail test file `pkg/providers/tier39_test.go` that locks in exact provider counts, names, regex compilation, and keyword presence across all 82 new Tier 3-9 providers. Replicates the `tier12_test.go` pattern and serves as the regression net for all future phases. + +Purpose: Satisfy all 7 Phase 3 requirements (PROV-03..PROV-09) with a single enforceable test. Any future change that drops a provider, renames one, or introduces a non-compiling regex will break this test in CI. + +Output: 1 test file with 10+ test functions. Total registry provider count locked at 108. + +Addresses PROV-03, PROV-04, PROV-05, PROV-06, PROV-07, PROV-08, PROV-09. + + + +@$HOME/.claude/get-shit-done/workflows/execute-plan.md +@$HOME/.claude/get-shit-done/templates/summary.md + + + +@.planning/ROADMAP.md +@.planning/phases/03-tier-3-9-providers/03-CONTEXT.md +@pkg/providers/tier12_test.go +@pkg/providers/schema.go + + +Replicate the `tier12_test.go` pattern exactly. Registry API: `NewRegistry()`, `Stats()`, `Get(name)`, `List()`. + +Expected provider name sets (must match plans 03-01..03-07 exactly): +- Tier 3 (12): perplexity, you, voyage, jina, unstructured, assemblyai, deepgram, elevenlabs, stability, runway, midjourney, huggingface +- Tier 4 (16): deepseek, zhipu, moonshot, qwen, baidu, bytedance, 01ai, minimax, baichuan, stepfun, sensetime, iflytek, tencent, siliconflow, 360ai, kuaishou +- Tier 5 (11): openrouter, litellm, cloudflare-ai, vercel-ai, portkey, helicone, martian, kong, bricksai, aether, notdiamond +- Tier 6 (15): reka, aleph-alpha, lamini, writer, jasper, typeface, comet, wandb, langsmith, pinecone, weaviate, qdrant, chroma, milvus, neon +- Tier 7 (10): github-copilot, cursor, tabnine, codeium, sourcegraph, codewhisperer, replit-ai, codestral, watsonx, oracle-ai +- Tier 8 (10): ollama, vllm, localai, lmstudio, llamacpp, gpt4all, text-gen-webui, tensorrt-llm, triton, jan +- Tier 9 (8): salesforce-einstein, servicenow, sap-ai-core, palantir, databricks, snowflake, oracle-genai, hpe-greenlake + +Total Tier 3-9: 82. Combined with Tier 1-2 (26): 108 total. + + + + + + + Task 1: Create tier39_test.go guardrail test file + pkg/providers/tier39_test.go + + - pkg/providers/tier12_test.go (pattern to replicate) + - pkg/providers/schema.go (Registry API) + + +Create `pkg/providers/tier39_test.go` with the following contents. The expected name slices MUST match the names in each plan's files exactly. + +```go +package providers + +import ( + "testing" +) + +// expectedTier3 lists all 12 Tier 3 Specialized provider names (PROV-03). +var expectedTier3 = []string{ + "perplexity", "you", "voyage", "jina", "unstructured", "assemblyai", + "deepgram", "elevenlabs", "stability", "runway", "midjourney", "huggingface", +} + +// expectedTier4 lists all 16 Tier 4 Chinese/Regional provider names (PROV-04). +var expectedTier4 = []string{ + "deepseek", "zhipu", "moonshot", "qwen", "baidu", "bytedance", + "01ai", "minimax", "baichuan", "stepfun", "sensetime", "iflytek", + "tencent", "siliconflow", "360ai", "kuaishou", +} + +// expectedTier5 lists all 11 Tier 5 Infrastructure/Gateway provider names (PROV-05). +var expectedTier5 = []string{ + "openrouter", "litellm", "cloudflare-ai", "vercel-ai", "portkey", + "helicone", "martian", "kong", "bricksai", "aether", "notdiamond", +} + +// expectedTier6 lists all 15 Tier 6 Emerging/Niche provider names (PROV-06). +var expectedTier6 = []string{ + "reka", "aleph-alpha", "lamini", "writer", "jasper", "typeface", + "comet", "wandb", "langsmith", "pinecone", "weaviate", "qdrant", + "chroma", "milvus", "neon", +} + +// expectedTier7 lists all 10 Tier 7 Code/Dev Tools provider names (PROV-07). +var expectedTier7 = []string{ + "github-copilot", "cursor", "tabnine", "codeium", "sourcegraph", + "codewhisperer", "replit-ai", "codestral", "watsonx", "oracle-ai", +} + +// expectedTier8 lists all 10 Tier 8 Self-Hosted provider names (PROV-08). +var expectedTier8 = []string{ + "ollama", "vllm", "localai", "lmstudio", "llamacpp", + "gpt4all", "text-gen-webui", "tensorrt-llm", "triton", "jan", +} + +// expectedTier9 lists all 8 Tier 9 Enterprise provider names (PROV-09). +var expectedTier9 = []string{ + "salesforce-einstein", "servicenow", "sap-ai-core", "palantir", + "databricks", "snowflake", "oracle-genai", "hpe-greenlake", +} + +func TestTier3Count(t *testing.T) { + reg, err := NewRegistry() + if err != nil { + t.Fatalf("NewRegistry failed: %v", err) + } + if got := reg.Stats().ByTier[3]; got != 12 { + t.Errorf("Tier 3 count = %d, want 12", got) + } +} + +func TestTier4Count(t *testing.T) { + reg, err := NewRegistry() + if err != nil { + t.Fatalf("NewRegistry failed: %v", err) + } + if got := reg.Stats().ByTier[4]; got != 16 { + t.Errorf("Tier 4 count = %d, want 16", got) + } +} + +func TestTier5Count(t *testing.T) { + reg, err := NewRegistry() + if err != nil { + t.Fatalf("NewRegistry failed: %v", err) + } + if got := reg.Stats().ByTier[5]; got != 11 { + t.Errorf("Tier 5 count = %d, want 11", got) + } +} + +func TestTier6Count(t *testing.T) { + reg, err := NewRegistry() + if err != nil { + t.Fatalf("NewRegistry failed: %v", err) + } + if got := reg.Stats().ByTier[6]; got != 15 { + t.Errorf("Tier 6 count = %d, want 15", got) + } +} + +func TestTier7Count(t *testing.T) { + reg, err := NewRegistry() + if err != nil { + t.Fatalf("NewRegistry failed: %v", err) + } + if got := reg.Stats().ByTier[7]; got != 10 { + t.Errorf("Tier 7 count = %d, want 10", got) + } +} + +func TestTier8Count(t *testing.T) { + reg, err := NewRegistry() + if err != nil { + t.Fatalf("NewRegistry failed: %v", err) + } + if got := reg.Stats().ByTier[8]; got != 10 { + t.Errorf("Tier 8 count = %d, want 10", got) + } +} + +func TestTier9Count(t *testing.T) { + reg, err := NewRegistry() + if err != nil { + t.Fatalf("NewRegistry failed: %v", err) + } + if got := reg.Stats().ByTier[9]; got != 8 { + t.Errorf("Tier 9 count = %d, want 8", got) + } +} + +func TestTotalProviderCount(t *testing.T) { + reg, err := NewRegistry() + if err != nil { + t.Fatalf("NewRegistry failed: %v", err) + } + if got := reg.Stats().Total; got != 108 { + t.Errorf("Total provider count = %d, want 108", got) + } +} + +func TestTier39ProviderNames(t *testing.T) { + reg, err := NewRegistry() + if err != nil { + t.Fatalf("NewRegistry failed: %v", err) + } + checks := []struct { + tier int + names []string + }{ + {3, expectedTier3}, + {4, expectedTier4}, + {5, expectedTier5}, + {6, expectedTier6}, + {7, expectedTier7}, + {8, expectedTier8}, + {9, expectedTier9}, + } + for _, c := range checks { + for _, name := range c.names { + p, ok := reg.Get(name) + if !ok { + t.Errorf("Tier %d provider %q not found in registry", c.tier, name) + continue + } + if p.Tier != c.tier { + t.Errorf("provider %q tier = %d, want %d", name, p.Tier, c.tier) + } + } + } +} +``` + +Note: Do NOT add package-level imports for `regexp` — `TestAllPatternsCompile` and `TestAllProvidersHaveKeywords` already exist in `tier12_test.go` and will exercise every provider (including Tier 3-9) once the registry loads them. + + + cd /home/salva/Documents/apikey && go test ./pkg/providers/... -count=1 -v -run 'TestTier[3-9]|TestTotalProviderCount|TestTier39ProviderNames|TestAllPatternsCompile|TestAllProvidersHaveKeywords' && go test ./... -count=1 + + + - `pkg/providers/tier39_test.go` exists + - `grep -c "^func Test" pkg/providers/tier39_test.go` returns ≥ 9 + - `go test ./pkg/providers/... -run TestTotalProviderCount -v` passes with Total == 108 + - `go test ./pkg/providers/... -run TestTier3Count -v` passes + - `go test ./pkg/providers/... -run TestTier4Count -v` passes + - `go test ./pkg/providers/... -run TestTier5Count -v` passes + - `go test ./pkg/providers/... -run TestTier6Count -v` passes + - `go test ./pkg/providers/... -run TestTier7Count -v` passes + - `go test ./pkg/providers/... -run TestTier8Count -v` passes + - `go test ./pkg/providers/... -run TestTier9Count -v` passes + - `go test ./pkg/providers/... -run TestTier39ProviderNames -v` passes (all 82 names resolve) + - `go test ./pkg/providers/... -run TestAllPatternsCompile -v` passes (inherited from tier12_test.go — all Tier 3-9 regexes compile under RE2) + - `go test ./pkg/providers/... -run TestAllProvidersHaveKeywords -v` passes (every provider ≥1 keyword) + - Phase 2 guardrails still pass: `go test ./pkg/providers/... -run 'TestTier1|TestTier2'` green + - Full repo regression: `go test ./... -count=1` green (engine, storage, providers) + + Tier 3-9 guardrail test file exists, 9+ test functions pass, total provider count locked at 108, all 82 Tier 3-9 provider names verified, no regression in Phase 1/2 tests. + + + + + +`go test ./... -count=1` passes. `go run . providers stats` shows Total 108, with Tier 1: 12, Tier 2: 14, Tier 3: 12, Tier 4: 16, Tier 5: 11, Tier 6: 15, Tier 7: 10, Tier 8: 10, Tier 9: 8. + + + +- tier39_test.go created with ≥9 test functions +- Total provider count locked at 108 +- All 82 Tier 3-9 provider names locked against drift +- All regex patterns compile under RE2 (via existing TestAllPatternsCompile) +- Every provider has ≥1 keyword (via existing TestAllProvidersHaveKeywords) +- Full repo `go test ./...` green + + + +After completion, create `.planning/phases/03-tier-3-9-providers/03-08-SUMMARY.md` +