# AiCippy CLI v1.4.0 -- Production Deployment Guide

## Pre-Deployment Checklist

### 1. PyPI Publication

- [ ] Version bumped to 1.4.0 in `pyproject.toml`, `__init__.py`, `installer/main.py`
- [ ] `python3 -m build` produces clean wheel and sdist
- [ ] `twine check dist/*` passes
- [ ] Published to PyPI: `twine upload dist/*`

### 2. Cognito User Pool Setup (auth.aivibe.cloud)

- [ ] User Pool: `us-east-1_S2Cpx3svp` (aivibe-users-production)
- [ ] App Client: `2gj7kdplhfg4aoenqfjghpotie` (public, no secret, PKCE enabled)
- [ ] Custom domain: `https://auth.aivibe.cloud`
- [ ] USER_PASSWORD_AUTH flow enabled on the app client
- [ ] ALLOW_REFRESH_TOKEN_AUTH flow enabled on the app client
- [ ] CUSTOM_AUTH flow enabled (for OTP login via Lambda triggers)
- [ ] Custom Auth Lambda triggers deployed for OTP (DefineAuthChallenge, CreateAuthChallenge, VerifyAuthChallengeResponse)
- [ ] Scopes: `openid`, `email`, `profile`

### 3. Platform API (api.aivibe.cloud)

All endpoints require `Authorization: Bearer {cognito_access_token}` header.

| Endpoint | Method | Purpose |
|----------|--------|---------|
| `/api/v1/tenants/by-email/{email}` | GET | Tenant lookup by email |
| `/api/v1/tenants/{tenant_id}/plan` | GET | Plan validation (returns plan, status, credits, is_admin) |
| `/api/v1/tenants/{tenant_id}/credits` | GET | Get remaining credits |
| `/api/v1/tenants/{tenant_id}/credits/deduct` | POST | Deduct credits atomically |
| `/api/v1/tenants/{tenant_id}/roles` | GET | Get tenant role assignments |
| `/api/v1/tenants/{tenant_id}/roles` | POST | Assign admin role |
| `/api/v1/orgs/{org_tenant_id}` | GET | Get organization details |
| `/api/v1/orgs/{org_tenant_id}/members` | GET | List organization members |
| `/api/v1/health` | GET | Health check |

### 4. App API (api.aicippy.com)

All endpoints require `Authorization: Bearer {cognito_access_token}` and `X-Tenant-ID: {tenant_id}` headers.

| Endpoint | Method | Purpose |
|----------|--------|---------|
| `/api/v1/memory/conversations` | POST | Save conversation |
| `/api/v1/memory/conversations` | GET | List conversations |
| `/api/v1/memory/tenant/{key}` | PUT | Save tenant memory entry |
| `/api/v1/memory/tenant/{key}` | GET | Get tenant memory entry |
| `/api/v1/memory/tenant` | GET | List all tenant memories |
| `/api/v1/profile` | GET | Get user profile |
| `/api/v1/profile` | PATCH | Update user profile |
| `/api/v1/rules` | GET | Get agent rules |
| `/api/v1/rules` | POST | Save agent rule |
| `/api/v1/connectors` | GET | List MCP connectors |
| `/api/v1/connectors` | POST | Save MCP connector config |
| `/api/v1/logs/sessions` | POST | Log session data |
| `/api/v1/logs/invocations` | POST | Log invocation data |
| `/api/v1/security/audit` | POST | Start security audit |
| `/api/v1/security/audit/{audit_id}` | GET | Get audit results |

### 5. WebSocket (ws.aicippy.com)

- [ ] WebSocket endpoint: `wss://ws.aicippy.com`
- [ ] Connection establishment with Bearer token authentication
- [ ] Agent streaming via WebSocket messages
- [ ] Reconnection with exponential backoff (5 attempts, 1s base delay)

### 6. Test Users Setup

| Email | Role | Plan | Notes |
|-------|------|------|-------|
| aravind@aivibe.in | super_admin | admin (unlimited) | Primary admin |
| developer@aivibe.in | user | chakra (200 credits) | Test developer user |
| jovita@aivibe.in | admin | admin (unlimited) | Secondary admin |

Admin status is determined by:
- Platform API: `is_admin` field in `/api/v1/tenants/{id}/plan` response
- DynamoDB (legacy): `role="admin"` attribute in VibekaroTenants record
- Org-level inheritance: parent org with admin role grants admin to members
- **No hardcoded admin emails in application config**

### 7. Domain Configuration

- [ ] `aicippy.com` -- Primary domain (Route53, zone ID: Z01837521OAC5AIIB7QE6)
- [ ] `api.aicippy.com` -> API Gateway REST (app-specific endpoints)
- [ ] `ws.aicippy.com` -> API Gateway WebSocket (agent streaming)
- [ ] `docs.aicippy.com` -> Documentation site
- [ ] `auth.aivibe.cloud` -> Cognito hosted UI (shared across all AiVibe products)
- [ ] `api.aivibe.cloud` -> Platform API (universal tenant/plan/credit management)
- [ ] **NO aicippy.io references in source code** (aicippy.io is a DIFFERENT app at 34.117.53.133)

### 8. AWS Services

- [ ] Bedrock models accessible in us-east-1:
  - `us.anthropic.claude-opus-4-5-20251101-v1:0` (Claude Opus 4.5)
  - `us.anthropic.claude-sonnet-4-5-20250929-v1:0` (Claude Sonnet 4.5)
  - `us.anthropic.claude-haiku-4-5-20251001-v1:0` (Claude Haiku 4.5)
  - `us.meta.llama4-maverick-17b-instruct-v1:0` (Llama 4 Maverick, default)
- [ ] SES verified: `no-reply@aivibe.cloud` (aivibe.cloud domain verified; aicippy.com SES FAILED)
- [ ] KMS encryption configured for DynamoDB tables and S3 buckets
- [ ] S3 buckets created:
  - `aicippy-knowledge-936668162296-us-east-1`
  - `aicippy-logs-936668162296-us-east-1`
  - `aicippy-artifacts-936668162296-us-east-1`
- [ ] DynamoDB tables:
  - `aicippy-sessions`
  - `aicippy-agent-runs`
  - `aicippy-token-usage`
  - `aicippy-websocket-connections`
  - `aicippy-knowledge-metadata`

## Post-Deployment Verification

### Quick Smoke Test

```bash
# Install
pip install aicippy==1.4.0

# Version check
aicippy --version  # Should show 1.4.0

# Login (email+password)
aicippy login
# Enter: developer@aivibe.in / [password]

# Session check
aicippy session --show

# Quick chat
aicippy chat "Hello, what can you do?"

# Logout
aicippy logout
```

### Admin Verification

```bash
aicippy login
# Enter: aravind@aivibe.in / [password]
# Should show: Plan: ADMIN (unlimited credits)
```

### OTP Login Test (requires Lambda triggers)

```bash
aicippy login --otp
# Enter email -> OTP sent to email
# Enter 6-digit OTP code -> Authenticated
```

### Auto-Update Verification

```bash
# Auto-updater checks PyPI every 24 hours in background
# State stored in ~/.aicippy/aicippy/update_state.json
# Manual check:
aicippy upgrade
```

## Architecture Summary

```
CLI User
  |
  v
[AiCippy CLI v1.4.0]
  |
  +-- Auth Module (auth/)
  |     |-- CognitoAuth: email+password (USER_PASSWORD_AUTH)
  |     |-- OTP Login: CUSTOM_AUTH + Lambda triggers
  |     |-- KeychainStorage: OS keychain + encrypted file fallback
  |     '-- Token refresh: REFRESH_TOKEN_AUTH with thread-safe locking
  |
  +-- Session Module (installer/session_manager.py)
  |     |-- 60-minute timeout (SESSION_TIMEOUT_MINUTES=60)
  |     |-- Per-device session files (sessions/session_{device_id}.json)
  |     |-- Cross-terminal session sharing (adopts active sessions)
  |     '-- Automatic expired session cleanup
  |
  +-- Platform Module (platform/)
  |     |-- PlatformClient -> api.aivibe.cloud (tenant/plan/credit/org/role)
  |     |-- AppClient -> api.aicippy.com (memory/profile/rules/connectors/logs)
  |     |-- Token refresh via token_refresher callable
  |     '-- Retry with exponential backoff (3 attempts, 1-4s)
  |
  +-- Billing Module (billing/)
  |     |-- PlanValidator: Platform API or DynamoDB (legacy) fallback
  |     |-- CreditManager: Atomic credit deduction with audit trail
  |     |-- TTLCache: 5-minute cache to reduce API calls
  |     '-- Admin detection: backend-driven (no hardcoded emails)
  |
  +-- Auto-Update Module (installer/auto_updater.py)
  |     |-- 24-hour background check interval
  |     |-- Silent pip upgrade (no user prompt)
  |     |-- State persistence in update_state.json
  |     '-- Failure does not block CLI operation
  |
  +-- Agent Orchestrator (agents/)
  |     |-- Up to 10 parallel agents
  |     |-- AWS Bedrock model invocation
  |     '-- 600-second agent timeout
  |
  '-- WebSocket (websocket/)
        |-- wss://ws.aicippy.com
        |-- 5 reconnection attempts
        '-- Agent streaming
```

## Configuration Reference

Settings are loaded from environment variables with `AICIPPY_` prefix:

| Variable | Default | Description |
|----------|---------|-------------|
| `AICIPPY_AWS_REGION` | `us-east-1` | Primary AWS region |
| `AICIPPY_COGNITO_USER_POOL_ID` | `us-east-1_S2Cpx3svp` | Cognito User Pool ID |
| `AICIPPY_COGNITO_CLIENT_ID` | `2gj7kdplhfg4aoenqfjghpotie` | Cognito App Client ID |
| `AICIPPY_COGNITO_DOMAIN` | `https://auth.aivibe.cloud` | Cognito hosted UI domain |
| `AICIPPY_DEFAULT_MODEL` | `llama` | Default model (opus/sonnet/haiku/llama) |
| `AICIPPY_PLATFORM_API_URL` | `https://api.aivibe.cloud` | Platform API base URL |
| `AICIPPY_APP_API_URL` | `https://api.aicippy.com` | App API base URL |
| `AICIPPY_WEBSOCKET_URL` | `wss://ws.aicippy.com` | WebSocket endpoint |
| `AICIPPY_LOG_LEVEL` | `INFO` | Logging level |
| `AICIPPY_MAX_PARALLEL_AGENTS` | `10` | Max parallel agents |

## Known Limitations

1. **OTP login** requires Custom Auth Lambda triggers (DefineAuthChallenge, CreateAuthChallenge, VerifyAuthChallengeResponse) deployed to the Cognito user pool.
2. **Direct RDS reads** (hybrid mode) are not yet enabled (`enable_direct_db_reads=False` by default). Requires Aurora PostgreSQL reader endpoint configuration.
3. **Auto-update** requires PyPI to be accessible from the user's network. Blocked networks will silently skip updates.
4. **Session timeout** is 60 minutes (not configurable at runtime; hardcoded in `session_manager.py`). Config has `session_ttl_minutes` field but session manager uses its own `SESSION_TIMEOUT_MINUTES` constant.
5. **Credit deduction** is atomic but the CLI does not currently handle race conditions between multiple concurrent CLI sessions deducting the same user's credits. The platform API is responsible for atomicity.
6. **Billing migration**: Legacy DynamoDB (VibekaroTenants/VibekaroSubscriptions) is still supported as fallback when no PlatformClient is provided. This should be deprecated once the platform API is fully operational.

## Security Considerations

1. **Credential storage**: OS keychain (macOS Keychain, Windows Credential Manager, Linux SecretService) with encrypted file fallback at `~/.aicippy/credentials.enc`
2. **Token validation**: JWT verification against Cognito JWKS with 24-hour cache
3. **Token refresh**: Thread-safe with double-check locking to prevent concurrent refreshes
4. **Session files**: Unix permissions 0o600 on session JSON files
5. **No secrets in code**: All sensitive values from environment variables or Cognito tokens
6. **Structured logging**: Correlation IDs on all auth operations; sensitive values never logged

## Version History

| Version | Date | Changes |
|---------|------|---------|
| 1.4.0 | 2026-02-13 | OTP login, auto-updater, 60-minute session timeout, data-driven admin roles, platform API integration, security audit support |
