Files
CASAN/docs/plans/CASAN_PLAN_03_CLOUD_PATCH.md

74 lines
4.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CASAN PLAN 03 — Cloud Provider Patch (OpenAI/Anthropic)
> Status 2026-07-06: **MVP implemented + deterministic tests added**. The router
> can call OpenAI/Anthropic when real API keys are present, while local tests
> verify endpoint pinning, provider usage parsing, and fail-closed malformed
> payload handling without requiring paid keys.
## Delivered
| Capability | Where | Verification |
|---|---|---|
| Model spec prefixes `openai:<model>` and `anthropic:<model>` | `packages/casan-harness/scripts/bash/model-call.py` | `phase3-model-router-tests.sh` |
| Endpoint allowlist/SSRF posture | Cloud hosts are hard-pinned to `api.openai.com` and `api.anthropic.com`; Ollama remains `127.0.0.1:11434` only | router SSRF test |
| Honest unavailable state | Missing `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` exits non-zero; no fake PASS or fake token usage | router cloud-unavailable test |
| Real provider token usage path | OpenAI `usage.prompt_tokens/completion_tokens`; Anthropic `usage.input_tokens/output_tokens` | deterministic monkeypatched cloud parser test |
| Malformed provider payload fail-closed | Missing usage/schema exits non-zero via `provider_usage_invalid` | deterministic parser test |
| Provider telemetry source tags | Usage rows write `openai_api_real_tokens` or `anthropic_api_real_tokens` | `model-call.py` provider log path |
## How to run live when keys exist
```bash
cd "$(git rev-parse --show-toplevel)" # repo root (app promoted here)
export CASAN_MODEL_PRIMARY=openai:gpt-4o-mini
export OPENAI_API_KEY=...
bash packages/casan-harness/scripts/bash/model-router.sh /tmp/prompt.txt /tmp/out.json --role classify
export CASAN_MODEL_PRIMARY=anthropic:claude-sonnet-4-5
export ANTHROPIC_API_KEY=...
bash packages/casan-harness/scripts/bash/model-router.sh /tmp/prompt.txt /tmp/out.json --role judge
```
Expected evidence:
- command exits `0` for well-formed provider output;
- `/tmp/out.json` has non-zero `input_tokens` and `output_tokens`;
- `.specify/logs/level5/provider-usage.jsonl` gets a row with provider
`openai` or `anthropic` and cost source `*_api_real_tokens`;
- malformed or unreachable provider exits non-zero and does not fabricate a
successful verdict.
## Remaining production work
| Priority | Work | Done when |
|---|---|---|
| P1 | Run live smoke with real org keys on the target Mac/CI | Evidence file records real provider response, token counts, and no secret leakage |
| P2 | Add provider cost lookup table for selected models | `cost_usd` is computed from current provider pricing instead of `0.0` |
| P3 | Wire real provider billing usage API, not only per-call response usage | H6 reconcile uses OpenAI/Anthropic ground truth APIs with schema-versioned fetchers |
| P4 | Add model allowlist policy for approved cloud models | Unknown cloud model names require approval or block |
| P5 | Decide default failover order for local -> cloud or cloud -> local | `model-fallback.sh` policy is explicit per role |
## Điều kiện gỡ blocker API key (để live provider smoke không treo vô thời hạn)
Live smoke (P1 ở trên) cần API key provider thật. Plan-02 A–D đã có đường
offline/local qua `model-router`; phần còn lại ở đây chỉ là claim **live cloud
provider thật**. Ghi rõ để bất kỳ AI/người kế tiếp gỡ được:
| Hạng mục | Quyết định cần chốt |
|---|---|
| **Ai cấp key** | Org owner cấp `OPENAI_API_KEY` và/hoặc `ANTHROPIC_API_KEY` (ít nhất 1 provider đủ để mở đường). |
| **Nạp ở đâu** | Chỉ qua biến môi trường / secret store của runner CI — **không** commit vào repo, không ghi vào audit dạng plaintext (H5 mask). |
| **Model tối thiểu** | `openai:gpt-4o-mini` hoặc `anthropic:claude-*-mini` là đủ cho smoke (rẻ, đủ chứng minh đường sống). |
| **Evidence phải lưu** | 1 file smoke ghi: exit `0`, token thật > 0 trong `/tmp/out.json`, 1 dòng `provider-usage.jsonl` với source `*_api_real_tokens`, và xác nhận không rò secret. |
| **Khi CHƯA có key** | Giữ nguyên trạng thái: deterministic offline test là bằng chứng hợp lệ; **không** claim live provider. Không tạo fake PASS/fake token. |
> **Chốt:** P02 A–D có thể phát triển & test offline bằng deterministic mock/local;
> chỉ **bước xác nhận live** mới cần key. Vì vậy thiếu key **không chặn** việc
> mở rộng source-gen — chỉ chặn claim "đã chạy live provider thật".
## Notes for Plan-02
Plan-02 source generation should call `model-router.sh --role generate`, not
provider SDKs directly. This keeps H4 prompt handling, H6 telemetry, endpoint
allowlisting, and provider usage logging in one path.