feat: initial commit — antigravity proxy with MITM, standalone LS, and snapshot tooling

This commit is contained in:
Nikketryhard
2026-02-14 02:24:35 -06:00
commit d5e7f09225
30 changed files with 9980 additions and 0 deletions

109
KNOWN_ISSUES.md Normal file
View File

@@ -0,0 +1,109 @@
# Known Issues & Future Work
---
## Medium
### 1. Cascade Correlation Is Heuristic
**File:** `src/mitm/intercept.rs``extract_cascade_hint()`
The MITM proxy matches intercepted API traffic to cascade IDs by scanning for `metadata.user_id` or `workspace_id` in the request body. If neither is found, it stores under `_latest`. Since `take_usage()` no longer falls back to `_latest`, unidentified requests will have **no MITM usage data at all**.
**Fix:** Investigate the actual request body format the LS sends for better correlation keys. Alternatively, use timing-based correlation (match MITM capture timestamp to cascade polling window).
---
### 2. Domain Certificate Cache Is Unbounded
**File:** `src/mitm/ca.rs``domain_cache`
The `domain_cache` (`HashMap<String, Arc<ServerConfig>>`) grows without bound. Each unique domain gets a cached entry containing a full `ServerConfig` with an RSA key pair. In practice, only ~510 domains are intercepted so this is unlikely to matter, but there's no eviction.
**Fix:** Set a max cache size (e.g., 100 entries) with LRU eviction, or use a TTL since leaf certs are generated with a 1-year validity.
---
### 3. Request Modification Not Implemented
**File:** `src/mitm/proxy.rs``modify_requests: false`
The `MitmConfig.modify_requests` flag exists and is plumbed through, but no actual modification logic is implemented. The flag is hardcoded to `false`.
**Fix:** When needed, implement request body mutation in `handle_http_over_tls()` — parse JSON, modify, reserialize, update `Content-Length`.
---
### 4. `total_cost_usd` Is Dead
**File:** `src/mitm/store.rs` (line 28)
`ApiUsage.total_cost_usd` is `Option<f64>` but is **always `None`** — set to `None` in all 4 construction sites (`h2_handler.rs` ×2, `intercept.rs` ×2). Neither Anthropic nor Google include cost in API responses.
**Fix:** Either remove the field (simpler), or populate it via a pricing table lookup (model → $/1K tokens) at `record_usage()` time.
---
## 🟢 Low
### 5. Wrapper Script Fallback Paths May Be Stale
**File:** `scripts/mitm-wrapper.sh``LS_FALLBACK_DIRS`
The fallback glob patterns (e.g., `~/.cursor/extensions/antigravity.antigravity-*/...`) assume a specific extension naming convention. These are only used when no running LS process is found via `/proc` scanning (Method 1), which is the primary and robust discovery mechanism.
**Impact:** Only affects `install` when the LS isn't running. Low priority.
---
### 6. No Integration Tests for MITM Module
The MITM module has unit tests for protobuf decoding and intercept parsing, but no integration tests that verify:
- TLS interception end-to-end with the generated CA
- Full HTTP/1.1 request/response cycle through the proxy
- gRPC (HTTP/2) request/response cycle through `h2_handler`
- Store recording and retrieval under concurrency
- Wrapper script install/uninstall lifecycle
---
## 🔍 Investigation
### 7. LS Exposes Credit/Quota Data via `GetUserStatus`
**Confirmed via live probing.** The LS's `GetUserStatus` RPC already returns structured cost/quota data:
```json
"planStatus": {
"planInfo": {
"planName": "Pro",
"monthlyPromptCredits": 50000,
"monthlyFlowCredits": 150000,
"monthlyFlexCreditPurchaseAmount": 25000,
"canBuyMoreCredits": true
},
"availablePromptCredits": 500,
"availableFlowCredits": 100
}
```
Each model also includes **per-model quota info**:
```json
"quotaInfo": {
"remainingFraction": 0.2,
"resetTime": "2026-02-14T07:41:37Z"
}
```
**Key findings:**
- `GetUserStatus` is the single source for credit/quota data (exposed via `LanguageServerService`)
- `SeatManagementService` methods (`GetPlanStatus`, `GetTeamCreditEntries`, `GetCascadeAnalytics`, `GetUserSubscription`) are **not routed through the LS** — they're backend-only
- `PredictionService/RetrieveUserQuota` is also backend-only (not proxied by LS)
- `GetUserAnalyticsSummary` returns empty `{}` (may not be implemented or requires different context)
- `GetModelStatuses` returns empty `{}` (separate from the model configs in `GetUserStatus`)
- `userTier` field shows subscription level: `{"id": "g1-ultra-tier", "name": "Google AI Ultra"}`
**Potential use:** We could poll `GetUserStatus` periodically and expose `availablePromptCredits`, `availableFlowCredits`, and per-model `remainingFraction` via the `/v1/usage` endpoint — giving users real-time credit burn visibility without needing MITM token counting.