Skip to content

Commit fbe76dd

Browse files
author
Faxbot Agent
committed
move internal docs
1 parent 162aeec commit fbe76dd

15 files changed

+4115
-0
lines changed

internal_docs/AGENTS.md

Lines changed: 356 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,356 @@
1+
# AGENTS.md - Critical Instructions for AI Assistants
2+
3+
## Quick Check Runbook (Local Dev)
4+
5+
- Start API with flags:
6+
- `ENABLE_LOCAL_ADMIN=true`
7+
- `API_KEY=fbk_local_admin_...`
8+
- Optional: `ADMIN_UI_ALLOW_TUNNEL=true`
9+
- Optional v4 config: `CONFIG_MASTER_KEY=<44b64>`
10+
- Visit `http://localhost:8080/admin/ui`
11+
- Login with the API key
12+
- Verify:
13+
- Settings → Configuration loads (no 503 if master key set).
14+
- Settings → Settings shows Provider Setup wizard button enabled.
15+
- Tools → Plugins, Tools → Marketplace shows info banner unless enabled.
16+
17+
Notes
18+
- v4 config endpoints now have an env/default fallback for read operations so the Configuration Manager can render even without `CONFIG_MASTER_KEY` (writes still require it).
19+
- Developer unlock (local only): set `DEVELOPER_UNLOCK=true` (or allowlist via `DEVELOPER_HOST_ALLOWLIST`/`DEVELOPER_MAC_ALLOWLIST`) to bypass Admin API-key prompts on your trusted machine. This is off by default and must never be enabled in shared or production environments.
20+
21+
## ⚠️ MANDATORY: Read [AGENT_BRANCH_POLICY.md](./AGENT_BRANCH_POLICY.md) - Stop creating unnecessary branches!
22+
23+
# CRITICAL: V4 MIGRATION IN PROGRESS
24+
**FOR ANYTHING RELATED TO V4 AND THE MULTIPHASE V4 PLAN, STAY IN THE auto-tunnel branch**
25+
26+
Branching: All v4 phases (1–5) live in `auto-tunnel`. Merge to `development` via PR after green CI. Never commit directly to `main`.
27+
28+
**V4 Architecture Alert:**
29+
- **Plugin-First**: Everything is becoming a plugin (providers, storage, identity)
30+
- **7 Active Providers**: Sinch (#1 priority), Phaxio, HumbleFax, SignalWire, SIP/Asterisk, FreeSWITCH, Test
31+
- **Configuration**: Database-first with .env fallback (no more config.yaml)
32+
- **Authentication**: Dual mode - API keys + session-based auth
33+
- **UI**: Admin Console is PRIMARY - no CLI-only features allowed
34+
- **Backward Compatibility**: All v3 APIs continue to work during migration
35+
36+
## Project Identity: Faxbot
37+
38+
**Correct Name:** "Faxbot" (main project) and "faxbot-mcp" (MCP server)
39+
**Status:** Production deployment capable, handling PHI/PII in healthcare environments
40+
**Revolutionary:** First and only open source fax transmission system with AI assistant integration
41+
42+
**There has NEVER been an open source, locally hostable fax server API with AI assistant integration. EVER.** None of this exists in any AI training data. You **CANNOT** make assumptions about how this works, what patterns to follow, or what "normal" looks like.
43+
44+
**EVERY DECISION MUST BE BASED ON THE ACTUAL CODEBASE AND DOCUMENTATION PROVIDED**
45+
46+
## V4 Architecture Summary
47+
48+
### Core Changes
49+
- **Plugin Manager**: Central orchestrator with manifest-first discovery (`api/app/plugins/<type>/<id>/manifest.json`)
50+
- **Trait System**: Capabilities defined by traits, not hardcoded provider names
51+
- **Hybrid Config**: Database-first configuration with .env fallbacks
52+
- **Async Everything**: Non-blocking I/O throughout the stack
53+
- **Dual Auth**: API keys (existing) + session-based (new) authentication
54+
- **Admin Console First**: Every feature must have UI coverage
55+
56+
### Provider Implementation Status
57+
58+
| Provider | Priority | Auth | Inbound | Status | Critical Notes |
59+
|----------|----------|------|---------|---------|----------------|
60+
| **Sinch** | **#1 CRITICAL** | OAuth2/Basic | Webhook | Active | Most widely used, regional endpoints |
61+
| **Phaxio** | **#2** | HMAC | Webhook | Active | HIPAA-ready, secure callbacks |
62+
| **HumbleFax** | **#3** | API Key | Webhook+IMAP | Active | Complex dual inbound system |
63+
| **SignalWire** | Standard | API Key | Webhook | Active | Twilio-compatible API |
64+
| **SIP/Asterisk** | Self-host | AMI | Direct | Active | T.38 support, requires AMI |
65+
| **FreeSWITCH** | Preview | ESL | Hook | v4 | mod_spandsp, ESL interface |
66+
| **Test** | Dev | None | Mock | Active | Development/testing only |
67+
68+
## V4 Plugin System Guide
69+
70+
### Plugin Discovery & Loading
71+
```python
72+
# Get active provider (Python)
73+
transport = await plugin_manager.get_active_by_type('transport')
74+
result = await transport.send_fax(to_number, file_path)
75+
76+
# List all plugins by type
77+
storage_plugins = await plugin_manager.list_by_type('storage')
78+
```
79+
80+
### Trait-Based Logic
81+
```typescript
82+
// Check traits (TypeScript - canonical keys)
83+
const traits = useTraits();
84+
if (traits.has('webhook.verification', 'hmac_sha256')) {
85+
showHMACSettings();
86+
}
87+
88+
// Python trait checking (canonical keys)
89+
traits = await get_active_traits()
90+
if traits.has('oauth2_supported'):
91+
await setup_oauth2_flow()
92+
```
93+
94+
### Configuration Access
95+
```python
96+
# v4 Config Pattern (contextual)
97+
user_ctx = UserContext(user_id="admin", tenant_id="default", groups=["admins"])
98+
api_key = (await hierarchical_config.get_effective("phaxio.api_key", user_ctx)).value
99+
webhook_url = (await hierarchical_config.get_effective("system.webhook_base_url", user_ctx)).value
100+
```
101+
102+
**CRITICAL**: Never hardcode backend names. Always use plugin_manager and trait checking.
103+
104+
DB-first; .env fallback only if the database is unavailable. Defaults come from manifests.
105+
106+
## Admin Console First (GUI Mandate)
107+
108+
**North Star**: Complete GUI-first experience. Users should never need terminal for routine operations beyond starting Docker.
109+
110+
### Requirements for ALL Features
111+
- [ ] Admin Console UI coverage (not just API)
112+
- [ ] Inline help text and tooltips everywhere
113+
- [ ] "Learn more" links to `${docsBase}/section`
114+
- [ ] Mobile-first responsive design
115+
- [ ] Error states with actionable guidance
116+
- [ ] Backend isolation (show only active provider settings)
117+
- [ ] Do not rename legacy routes; add new endpoints in parallel only
118+
- [ ] Inbound handlers return 202 and are idempotent (dedupe by provider_id + external_id)
119+
120+
### Trait-Gated UI Pattern
121+
```typescript
122+
// Show provider-specific UI based on traits
123+
const { activeProvider, traits } = useProviderConfig();
124+
if (traits.hasTrait('inbound', 'requires_ami')) {
125+
return <AMIConfigSection />;
126+
}
127+
```
128+
129+
## Frontend Quick Reference
130+
131+
| Component | File | Purpose |
132+
|-----------|------|---------|
133+
| **App Shell** | `api/admin_ui/src/App.tsx:1` | Main app with tabs |
134+
| **API Client** | `api/admin_ui/src/api/client.ts:1` | AdminAPIClient |
135+
| **Theme** | `api/admin_ui/src/theme/themes.ts:1` | Dark/Light themes |
136+
| **Form Kit** | `ResponsiveFormFields.tsx:1` | Form components |
137+
| **Settings Kit** | `ResponsiveSettingItem.tsx:1` | Settings layouts |
138+
| **Types** | `api/admin_ui/src/api/types.ts:1` | TypeScript types |
139+
140+
Note: Admin Console stays on API-key login until `/auth/*` + CSRF middleware ship. Cookie sessions are gated behind a feature flag. Mark the session login component disabled by default.
141+
142+
### Key Patterns
143+
```typescript
144+
// Responsive styling
145+
sx={{ px: { xs: 1, sm: 2, md: 3 } }}
146+
147+
// Form validation
148+
<ResponsiveTextField
149+
error={!!error}
150+
helperText={error || "Helper text"}
151+
/>
152+
153+
// Theme usage
154+
const theme = useTheme();
155+
```
156+
157+
## Configuration Guide
158+
159+
### V4 Hybrid Config Priority
160+
1. **Database** (tenant/user/global hierarchy)
161+
2. **Environment variables** (.env fallback)
162+
3. **Defaults** (manifest-defined)
163+
164+
### Critical Environment Variables
165+
```env
166+
# Core API
167+
API_KEY=your_secure_api_key_here
168+
FAX_BACKEND=sinch # Primary provider
169+
DATABASE_URL=postgresql://user:pass@host/db
170+
171+
# Provider Credentials (example)
172+
SINCH_PROJECT_ID=your_project_id
173+
SINCH_API_KEY=api_key
174+
SINCH_API_SECRET=api_secret
175+
176+
# Security
177+
ENFORCE_PUBLIC_HTTPS=true # HIPAA environments
178+
AUDIT_LOG_ENABLED=true # Healthcare compliance
179+
```
180+
181+
## Security Essentials
182+
183+
### HIPAA vs Non-HIPAA
184+
| Setting | HIPAA Required | Non-HIPAA Default |
185+
|---------|----------------|-------------------|
186+
| `API_KEY` | Required strong key | Optional but recommended |
187+
| `ENFORCE_PUBLIC_HTTPS` | `true` | `false` (dev only) |
188+
| `AUDIT_LOG_ENABLED` | `true` | `false` |
189+
| `PHAXIO_VERIFY_SIGNATURE` | `true` | `true` (recommended) |
190+
191+
### Never Log PHI
192+
```python
193+
# WRONG - logs phone number
194+
logger.info(f"Sending fax to {to_number}")
195+
196+
# CORRECT - logs job ID only
197+
logger.info(f"Sending fax job {job_id}")
198+
```
199+
200+
- Fail-fast secrets: `CONFIG_MASTER_KEY` (44-char base64) and `FAXBOT_SESSION_PEPPER` are required; the app exits at startup if missing.
201+
- Webhooks: 202 Accepted + idempotency; PHI never logged.
202+
- Sessions: CSRF required for all state-changing endpoints when cookie sessions are enabled.
203+
204+
## Branch Policy (V4 Critical)
205+
206+
**📚 SEE ALSO: [AGENT_BRANCH_POLICY.md](./AGENT_BRANCH_POLICY.md) for branch creation/deletion rules**
207+
208+
| Work Type | Target Branch | Notes |
209+
|-----------|---------------|-------|
210+
| **Core API/MCP/Docs** | `auto-tunnel` | All v4 work (Phases 1–5). Merge to `development` via PR after green CI |
211+
| **Electron macOS** | `electron_macos` | App-specific |
212+
| **Electron Windows** | `electron_windows` | App-specific |
213+
| **iOS App** | `iOS` | App-specific |
214+
| **Production** | `main` | **NEVER WORK IN MAIN** |
215+
216+
### Branch Cleanup Tools
217+
```bash
218+
# Clean up unused branches left by agents
219+
./scripts/cleanup_branches_auto.sh
220+
221+
# List all branches for review
222+
git branch -r | grep -v HEAD | sed 's/origin//'
223+
```
224+
225+
## Quick Scripts (Keep Updated)
226+
227+
### Check CI Status (Understanding Red X's)
228+
```bash
229+
# See what's actually failing and why
230+
./scripts/check_ci_status.sh
231+
232+
# Quick check if CI is passing the REQUIRED checks
233+
bash scripts/ci/greps.sh
234+
```
235+
**Note:** Red X's from external services (Project preview, Scorecard, etc.) are NOT blocking merges!
236+
They're from GitHub Apps that can be removed at: Settings > Installations
237+
238+
### One-Command API Docs Refresh
239+
```bash
240+
# Local only - publishes to faxbot.net
241+
scripts/publish-api-docs.sh
242+
```
243+
244+
### Admin Console Demo Sync
245+
```bash
246+
# From faxbot.net repo
247+
./scripts/update-demo.sh --force-main
248+
```
249+
250+
### Branch Cleanup (Remove Agent-Created Mess)
251+
```bash
252+
# Auto-delete unused branches left by AI agents
253+
./scripts/cleanup_branches_auto.sh
254+
255+
# Interactive cleanup with review
256+
./scripts/cleanup_all_branches.sh
257+
```
258+
259+
## V4 Migration Checklist
260+
261+
### For Every Code Change
262+
- [ ] Using `plugin_manager` instead of direct service calls?
263+
- [ ] Checking traits instead of backend names (`providerHasTrait()`)?
264+
- [ ] Using async/await for all I/O operations?
265+
- [ ] Config via `HybridConfigProvider`, not hardcoded values?
266+
- [ ] Admin Console UI included for new features?
267+
- [ ] Backward compatibility maintained for existing API clients?
268+
- [ ] No PHI in logs (use job IDs, not phone numbers/content)?
269+
270+
### Code Pattern Checklist
271+
```python
272+
# ✅ CORRECT v4 Pattern
273+
transport = await plugin_manager.get_active_by_type('transport')
274+
if await provider_has_trait('outbound', 'oauth2_required'):
275+
token = await oauth_handler.get_token()
276+
result = await transport.send_fax(to_number, file_path, auth=token)
277+
278+
# ❌ WRONG v3 Pattern
279+
if backend == 'sinch':
280+
sinch_service.send_fax(...)
281+
elif backend == 'phaxio':
282+
phaxio_service.send_fax(...)
283+
```
284+
285+
## Common Anti-Patterns (AVOID)
286+
287+
| Anti-Pattern | Problem | v4 Solution |
288+
|-------------|---------|-------------|
289+
| `if backend == 'phaxio'` | Hardcoded provider | `if provider_has_trait('webhook', 'hmac')` |
290+
| Direct service imports | Breaks plugin system | Use `plugin_manager.get_active_by_type()` |
291+
| Mixed backend UI | Confuses users | Show only active provider settings |
292+
| Blocking I/O | Performance issues | Use async/await everywhere |
293+
| CLI-only features | Poor UX | Admin Console coverage required |
294+
295+
## Provider-Specific Critical Notes
296+
297+
### Sinch (Priority #1)
298+
- **Auth**: `auth.methods = ["basic","oauth2"]` support required
299+
- **Regional endpoints** (US, EU, etc.)
300+
- **Fallback semantics**: Only documented key/secret fallbacks (e.g., `PHAXIO_*` to Sinch key/secret) apply. Do not infer project IDs from Phaxio keys.
301+
302+
### HumbleFax (Complex)
303+
- **Dual inbound**: Webhook + IMAP polling
304+
- **Rate limiting**: Strict API limits
305+
- **Webhook verification**: Custom HMAC implementation
306+
- **IMAP**: Run threadpooled/worker-based; never block the event loop.
307+
308+
### SIP/Asterisk (Self-Hosted)
309+
- **AMI credentials** required (`ASTERISK_AMI_*`)
310+
- **T.38 protocol** for fax transmission
311+
- **Network isolation** (keep AMI internal)
312+
313+
## Final Critical Reminders
314+
315+
1. **This has never existed before** - No assumptions allowed about fax+AI systems
316+
2. **All 7 providers must work** - Sinch priority #1, but all must function
317+
3. **Plugin-first mindset** - Everything is a plugin in v4
318+
4. **Traits over names** - Check capabilities, not hardcoded provider strings
319+
5. **Admin Console mandatory** - Every feature needs UI coverage
320+
6. **HIPAA is critical** - Healthcare compliance built-in, not bolted-on
321+
7. **Backward compatibility** - v3 APIs must continue working during migration
322+
323+
## Observability
324+
325+
- Expose exactly one metrics endpoint (`/metrics` on API port).
326+
- Use the Phase-3 health monitor and circuit breaker; do not add duplicate monitors.
327+
328+
## Dev/Prod Golden Path
329+
330+
Dev: Docker Compose is canonical. Prod: Kubernetes. Bare-metal is unsupported to avoid Ghostscript/Node drift.
331+
332+
## CI Guardrails
333+
334+
### ✅ REQUIRED Checks (These block merging)
335+
- OpenAPI diff against pinned snapshot (fail on route/schema drift)
336+
- Traits JSON-Schema validation (fail on non-canonical keys/types):
337+
- `webhook.path` (string), `webhook.verification` (`hmac_sha256|basic_auth|none`), `webhook.verify_header` (string)
338+
- `auth.methods` (array of enums), `regions` (array)
339+
- Grep checks (now using standard `grep` not `rg`):
340+
- No provider name checks in UI: `grep -r "=== 'sinch'|=== 'phaxio'|=== 'sip'" api/admin_ui/src`
341+
- Require 202 in callback handlers: `grep -r "/(phaxio|sinch).*return.*202" api/app`
342+
- No duplicate health monitors: `grep -r "class .*ProviderHealthMonitor" api/app`
343+
- Secrets present in env/k8s: `CONFIG_MASTER_KEY|FAXBOT_SESSION_PEPPER`
344+
345+
### ❌ EXTERNAL Checks (Red X's that DON'T block merging)
346+
- **Project preview** - Deployment preview services (Vercel/Netlify)
347+
- **Scorecard** - OpenSSF security scoring
348+
- **Respect Monitoring** - External monitoring service
349+
350+
**To remove annoying external checks:** GitHub Settings > Installations > Remove unwanted apps
351+
352+
## North Star
353+
354+
Brownfield integration rule: We are upgrading a live system. Never rename existing routes or remove working flows. Add new capabilities behind traits, feature flags, and Admin Console UI. Return 202 for inbound callbacks and dedupe idempotently. DB-first config with .env as a true outage fallback only. Traits over names, plugins over services, Docker/K8s over bare-metal, and no PHI in logs. If a change breaks any of those, stop and fix the plan.
355+
356+
**Remember**: You are building the first open source fax server with AI integration. Your work defines how this category of software will be understood for years to come.

0 commit comments

Comments
 (0)