* docs(arch): consolidate ARCHITECTURE + PLATFORM-TECH-STACK + NAMING + EPICS-1-6 + BOOTSTRAP-KIT-EXPANSION → docs/ARCHITECTURE.md (lean doc strategy) Single canonical "how OpenOva works" doc per founder's lean-doc strategy. 2926 source lines → 1110 consolidated lines, no semantic loss. Sections: §1 High-level model (Catalyst/Sovereign/Org/Env/Application/Blueprint) §2 Repo layout §3 Tech stack by layer (CNI/GitOps/IaC/event-spine/data/secrets/identity/...) §4 Naming conventions (dimensions, patterns, labels, DOMAINS-CANON) §5 Catalyst control plane (rules, CRDs, controllers, cutover, identity, surfaces) §6 Per-host-cluster infrastructure §7 Application Blueprints §8 Multi-region topology (1 cpx52/region, WireGuard-over-public-IPs, ClusterMesh) §9 Bootstrap-kit slot ordering (full 48-slot canonical list) §10 EPIC-level design overview (EPIC-0 through EPIC-6) §11 Per-chart DESIGN.md inventory §12 OAM influence §13 Read further Stale literal fixes: - omantel.openova.io → omantel.biz / <sovereign>.<tld> / t38.omani.works (7 instances) - SPIRE marked DEFERRED / opt-in only (PR #665, TBD-V29 #2055) - failover-controller marked REPLACED by bp-continuum New PR refs wired into §3: - PR #665 SPIRE deferral - PR #2071 bp-cnpg-pair synchronous remote_apply (zero-tx-loss multi-region) - PR #2087 bp-cnpg-pair pre-merge guard - PR #2093 bp-cnpg-pair pre-merge guard New stack components added to §3: - bp-cnpg-pair (synchronous remote_apply ReplicaCluster across ClusterMesh) - bp-continuum (lease-based failover orchestrator) - bp-self-sovereign-cutover (8-tether pivot, ADR-0002, Principle #11) Source docs (to be deleted by orchestrator in final PR): - docs/PLATFORM-TECH-STACK.md - docs/NAMING-CONVENTION.md - docs/EPICS-1-6-unified-design.md - docs/BOOTSTRAP-KIT-EXPANSION-PLAN.md * docs(principles): consolidate INVIOLABLE-PRINCIPLES + ANTI-PATTERN-CATALOG → docs/PRINCIPLES.md (lean doc strategy) * docs(dod): consolidate 5-PILLAR-DOD + DOMAINS-CANON + SOVEREIGN-MULTI-REGION-DOD + PERSONAS-AND-JOURNEYS → docs/DOD.md (lean doc strategy) * docs(runbooks+status+glossary): consolidate 5 runbooks → RUNBOOKS.md + refresh STATUS.md + fold banned-terms into GLOSSARY.md (lean doc strategy) Part 1 — Runbook consolidation: - NEW docs/RUNBOOKS.md with 7 numbered sections (provisioning, day-2 ops, Blueprint authoring, chart conventions, demo walk, failover, troubleshooting) - Folds BLUEPRINT-AUTHORING / CHART-AUTHORING / DEMO-RUNBOOK / RUNBOOK-OPERATIONS / RUNBOOK-PROVISIONING into one canonical surface - Documents dual-annotation requirement for charts with enabled.default: false (GUARD 1 #2087 no-upstream + GUARD 2 #2093 smoke-render) with bp-network-policies:1.0.1 dead-reserve incident as the live evidence - All admin.<fqdn> legacy URL refs → console.<fqdn>/bss (BSS lives in operator console) - All openova.io / omantel.omani.works test commands → canonical t<NN>.omani.works - Cites PRs #2076 (docs migration), #2082 (no-auto-close-keyword), #2087, #2093 Part 2 — STATUS.md refresh (renamed from IMPLEMENTATION-STATUS.md): - Header dated 2026-05-20 (was 2026-04-29; 22 days stale per audit) - Adds 🟦 CODE-COMPLETE state for "controllers + CRDs + tests landed, awaiting fresh-prov walk" (per 5-pillar DoD) - Pillar 3 marked CODE-COMPLETE (PRs #2071/#2072/#2073/#2074/#2075/#2053) - Adds 3 new CRDs verified in products/catalyst/chart/crds/: CNPGPair, PDM, Sandbox - Sandbox controller chain CODE-COMPLETE (PRs #1615/#1618/#1621/#1622/#1626/#1631/#1632) - SPIRE marked DEFERRED — opt-in only (PRs #665, #2056, #2061) - New §6 CI / supply-chain guards table: hollow-chart (#2087), smoke-render (#2093), no-auto-close-keyword (#2082), observability-toggle, subchart 4-step, Flux version-pin replay - New §9 Pillar-status table — Pillars 1/2/3/4 CODE-COMPLETE, Pillar 5 🚧 - Pillar 1 (PRs #2038 V18, #2043 V18-D), Pillar 2 (PR #2029 V20), Pillar 3 (per above), Pillar 4 (Sandbox chain) Part 3 — GLOSSARY.md folded as single source of truth for banned terms: - Header dated 2026-05-20, notes "single source of truth for banned terms" and "no separate BANNED-TERMS.md" - Existing 11 banned-terms rows rewritten with italicized qualifiers - NEW Forbidden test domains subsection: openova.io (mothership-only), omantel.openova.io (hallucinated), Nova Cloud (predecessor brand), eventforge.io (hallucinated), admin.<fqdn> (dead BSS URL) - SPIFFE/SPIRE identity row + acronym row marked deferred per PR #665 with TBD-V29 (#2055) re-introduction roadmap - Cross-links updated: IMPLEMENTATION-STATUS → STATUS, SOVEREIGN-PROVISIONING + BLUEPRINT-AUTHORING → RUNBOOKS.md CLAUDE.md NOT touched. Source files NOT deleted (orchestrator owns deletion). No push, no PR. Manifest at /tmp/merge-D-runbooks-status-glossary-manifest.txt. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs: assemble lean doc strategy — delete legacy sources, move ledger/sessions/archive, ADR-0004, rewrite cross-refs Per founder direction 2026-05-20 + user-global ~/.claude/CLAUDE.md §11. This is the orchestrator commit on top of the four cherry-picked consolidation commits (ARCHITECTURE, PRINCIPLES, DOD, RUNBOOKS+STATUS+GLOSSARY). It: 1. Deletes 15 legacy source docs (now folded into the 7 canonical): PLATFORM-TECH-STACK, NAMING-CONVENTION, EPICS-1-6-unified-design, BOOTSTRAP-KIT-EXPANSION-PLAN, INVIOLABLE-PRINCIPLES, ANTI-PATTERN-CATALOG, 5-PILLAR-DOD, DOMAINS-CANON, SOVEREIGN-MULTI-REGION-DOD, PERSONAS-AND-JOURNEYS, BLUEPRINT-AUTHORING, CHART-AUTHORING, DEMO-RUNBOOK, RUNBOOK-OPERATIONS, RUNBOOK-PROVISIONING. 2. Moves transient + historical docs into proper subdirs: - docs/ledger/{TRUST,TRACKER}.md (cron-refreshed live state) - docs/sessions/{2026-05-17-convergence,2026-05-19-20-trust-recovery, 2026-05-20-trust-audit,2026-05-20-walk-runbook}.md - docs/archive/{validation-log,orchestrator-state,omantel-handover-wbs}.md 3. Adds docs/adr/0004-cnpg-sync-replication.md (Pillar 3 zero-tx-loss decision) + docs/adr/README.md index. 4. Updates CLAUDE.md reading-order + repo-structure block to match the lean strategy and current core/ tree (controllers/, marketplace/, etc.). 5. Sweeps all .md files + .github/workflows + scripts to repoint old doc paths to the new canonical homes. ADR cross-references kept intact (ADRs are immutable historical artifacts). Operator-side cron scripts that still write to the old paths (/home/openova/bin/refresh-dod-dashboard.sh, refresh-wbs.sh and openova-private/bin/trust-audit.sh) need a one-line path update — flagged in the PR body. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * test(bootstrap-kit): update repo-root sentinel to docs/PRINCIPLES.md The bootstrap-kit Go test used `docs/INVIOLABLE-PRINCIPLES.md` as its repo-root sentinel; the file no longer exists after the lean-doc consolidation (it's now `docs/PRINCIPLES.md`). Update the walker to match the new canonical filename. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: hatiyildiz <269457768+hatiyildiz@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| chart | ||
| blueprint.yaml | ||
| README.md | ||
Anthropic Adapter
OpenAI-compatible proxy for Anthropic Claude API. Application Blueprint (see docs/ARCHITECTURE.md §4.6). Lets Apps written against the OpenAI SDK call Anthropic Claude with no code change. Pairs with the LLM Gateway in bp-cortex.
Status: Accepted | Updated: 2026-04-27
Overview
Anthropic Adapter provides an OpenAI-compatible API layer that translates requests to the Anthropic Claude API format, enabling tools like Claude Code to work with internal models.
flowchart LR
subgraph Adapter["Anthropic Adapter"]
Translate[Request Translator]
Stream[Stream Handler]
end
ClaudeCode[Claude Code] -->|OpenAI Format| Adapter
Adapter -->|Anthropic Format| Claude[Claude API]
Adapter -->|OpenAI Format| Internal[Internal LLM]
Claude --> Adapter
Internal --> Adapter
Adapter --> ClaudeCode
Why Anthropic Adapter?
| Feature | Benefit |
|---|---|
| API translation | OpenAI ↔ Anthropic format |
| Claude Code support | Use internal models with Claude Code |
| Streaming | Real-time response translation |
| Model routing | Route to Claude or internal LLM |
Use Cases
| Use Case | Description |
|---|---|
| Claude Code + internal LLM | Use Claude Code with self-hosted models |
| API compatibility | Anthropic clients on OpenAI backends |
| Model switching | Seamless backend switching |
Configuration
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: anthropic-adapter
namespace: ai-hub
spec:
replicas: 2
template:
spec:
containers:
- name: adapter
image: harbor.<location-code>.<sovereign-domain>/ai-hub/anthropic-adapter:latest
ports:
- containerPort: 8000
env:
- name: BACKEND_TYPE
value: "openai" # or "anthropic"
- name: BACKEND_URL
value: "http://vllm.ai-hub.svc:8000/v1"
- name: BACKEND_API_KEY
valueFrom:
secretKeyRef:
name: adapter-secrets
key: backend-api-key
- name: DEFAULT_MODEL
value: "qwen3-32b"
resources:
requests:
cpu: 100m
memory: 256Mi
API Translation
Anthropic → OpenAI
| Anthropic | OpenAI |
|---|---|
messages[].content (list) |
messages[].content (string) |
max_tokens |
max_tokens |
system (top-level) |
messages[0].role: system |
stream: true |
stream: true |
Request Translation
# Anthropic format (input)
{
"model": "claude-3-opus",
"max_tokens": 4096,
"system": "You are helpful.",
"messages": [
{"role": "user", "content": "Hello"}
]
}
# OpenAI format (translated)
{
"model": "qwen3-32b",
"max_tokens": 4096,
"messages": [
{"role": "system", "content": "You are helpful."},
{"role": "user", "content": "Hello"}
]
}
Claude Code Configuration
# Set Claude Code to use adapter
export ANTHROPIC_API_KEY="your-adapter-key"
export ANTHROPIC_BASE_URL="http://anthropic-adapter.ai-hub.svc:8000"
# Claude Code will now use internal LLM
claude-code "Explain this code..."
Implementation
# proxy.py
from fastapi import FastAPI, Request
from fastapi.responses import StreamingResponse
import httpx
app = FastAPI()
@app.post("/v1/messages")
async def messages(request: Request):
body = await request.json()
# Translate Anthropic → OpenAI format
openai_body = translate_to_openai(body)
# Forward to backend
async with httpx.AsyncClient() as client:
if body.get("stream"):
return StreamingResponse(
stream_response(client, openai_body),
media_type="text/event-stream"
)
else:
response = await client.post(
f"{BACKEND_URL}/chat/completions",
json=openai_body
)
return translate_to_anthropic(response.json())
def translate_to_openai(anthropic_body: dict) -> dict:
messages = []
# Move system to first message
if "system" in anthropic_body:
messages.append({
"role": "system",
"content": anthropic_body["system"]
})
# Convert message content
for msg in anthropic_body.get("messages", []):
content = msg["content"]
if isinstance(content, list):
# Flatten content blocks
content = " ".join(
block.get("text", "")
for block in content
if block.get("type") == "text"
)
messages.append({"role": msg["role"], "content": content})
return {
"model": DEFAULT_MODEL,
"messages": messages,
"max_tokens": anthropic_body.get("max_tokens", 4096),
"stream": anthropic_body.get("stream", False)
}
Streaming Translation
async def stream_response(client, openai_body):
async with client.stream(
"POST",
f"{BACKEND_URL}/chat/completions",
json=openai_body
) as response:
async for line in response.aiter_lines():
if line.startswith("data: "):
data = json.loads(line[6:])
# Translate to Anthropic SSE format
anthropic_event = translate_sse(data)
yield f"event: content_block_delta\ndata: {json.dumps(anthropic_event)}\n\n"
yield "event: message_stop\ndata: {}\n\n"
Monitoring
| Metric | Query |
|---|---|
| Request count | adapter_requests_total |
| Latency | adapter_request_duration_seconds |
| Backend errors | adapter_backend_errors_total |
| Stream duration | adapter_stream_duration_seconds |
Consequences
Positive:
- Claude Code with internal models
- API format translation
- Streaming support
- Easy model switching
Negative:
- Feature parity limitations
- Translation overhead
- Some Anthropic features unsupported
Part of OpenOva