Skip to content

feat: runnable onboarding quickstart, recipes, and fixtures (issue #32)#47

Open
levleontiev wants to merge 65 commits intomainfrom
feature/issue-32-quickstart
Open

feat: runnable onboarding quickstart, recipes, and fixtures (issue #32)#47
levleontiev wants to merge 65 commits intomainfrom
feature/issue-32-quickstart

Conversation

@levleontiev
Copy link
Contributor

Summary

Implements #32 — packages the edge repo as a runnable onboarding funnel.

What's added:

  • examples/quickstart/docker compose up -d quickstart (wrapper mode, standalone). Reusable as the base for e2e-smoke CI. Demonstrates /openai/v1/chat/completions with Bearer CLIENT_JWT:UPSTREAM_KEY composite auth.
  • examples/recipes/team-budgets/ — per-team JWT TPM + 30-day cost budget with staged warn/throttle/reject
  • examples/recipes/runaway-agent-guard/ — loop detector + TPM guard keyed on jwt:agent_id
  • examples/recipes/provider-failover/ — dual-provider policies (OpenAI + circuit breaker, Anthropic fallback)
  • fixtures/ — 10 canonical artifacts:
    • normal_request.json, over_limit_request.json, anthropic_normal_request.json
    • allow_response.json (proves auth-header stripping: no Authorization/x-api-key/x-goog-api-key in response)
    • reject_tpm_exceeded.json, reject_tpd_exceeded.json, reject_prompt_too_large.json
    • reject_openai.json, reject_anthropic.json, reject_gemini.json (provider-native bodies)
  • README: quickstart pointer, updated project layout, benchmark link → fairvisor/benchmark

Spec 019 / wrapper mode coverage:

  • Quickstart uses FAIRVISOR_MODE=wrapper and provider-prefixed paths (/openai/v1/...)
  • allow_response.json explicitly documents auth-header stripping
  • reject_anthropic.json and reject_gemini.json prove provider-native error bodies
  • Business event vs. request log distinction preserved (no audit-event drift)

Acceptance criteria met:

  • docker compose up -d + curl to /openai/v1/chat/completions with over-limit fixture → 429 matching fixtures/reject_tpm_exceeded.json
  • Same path with normal fixture → 200 ✓
  • One canonical repo-owned path from clone to result ✓
  • examples/ read as deployable recipes, not disconnected policy fragments ✓
  • Benchmark links to fairvisor/benchmark instead of duplicating methodology ✓

Downstream: Fixture paths and compose structure are stable — ready to coordinate with fairvisor/documentation#8.

Test plan

  • docker compose -f examples/quickstart/docker-compose.yml up -d starts healthy
  • curl to /openai/v1/chat/completions with over_limit_request.json returns 429 with body matching fixtures/reject_tpm_exceeded.json
  • Same path with normal_request.json returns 200
  • Response headers in 200 case: no Authorization, x-api-key, x-goog-api-key
  • CI e2e-smoke passes (compose reuse contract preserved)
  • Recipe policies validate (fairvisor validate)

🤖 Generated with Claude Code

levleontiev and others added 30 commits March 17, 2026 11:47
Failover between providers is a client-side pattern, not a Fairvisor
feature. Replace with a focused circuit-breaker recipe that demonstrates
the actual cost-spike auto-shutdown capability:
- spend_rate_threshold_per_minute triggers full traffic block
- auto_reset_after_minutes provides hands-free cooldown
- per-org TPM limit continues to run in parallel
levleontiev and others added 30 commits March 19, 2026 20:42
…x, ip:address, curl formatting, Architecture ToC
… support

- Fix _simple_word_estimate to properly skip false-positive "content" key
  matches (e.g. when key appears inside a string value) by verifying
  the value separator (: "...") before counting characters
- Add _extract_max_tokens() to parse max_tokens / max_completion_tokens
  from raw request body when request_context.max_tokens is not set,
  enabling accurate budget reservation for OpenAI-compatible payloads

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…vars

- Remove trailing whitespace on blank lines (lines 201, 205)
- Replace unused s, e variables with _ in _extract_max_tokens()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add two scenarios to exercise the uncovered branches in _extract_max_tokens:
- body contains "max_tokens" field → uses it (covers return tonumber(val) branch)
- body has no max_tokens/max_completion_tokens → falls back to default_max_completion
  (covers return nil branch)

Fixes coverage regression (91.61% < 91.63% threshold).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants