Change summary
AGENTS.md | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 103 insertions(+)
Detailed changes
@@ -0,0 +1,103 @@
+# AGENTS.md
+
+This file provides guidance to AI coding agents when working with code in this repository.
+
+## Project Architecture & Core Components
+
+This is an XMPP to SMS gateway for Bandwidth's V2 Messaging API (sgx-bwmsgsv2). The system consists of:
+
+**Core Services:**
+- `sgx-bwmsgsv2.rb` - Main XMPP gateway using Blather DSL, handles XMPP→Bandwidth API communication
+- `r2s-bwmsgsv2.rb` - Redis queue to HTTP request translator, processes pending messages
+- `h2r-bwmsgsv2.php` - Helper script for HTTP to Redis operations
+
+**Key Libraries:**
+- `lib/bandwidth_error.rb` - Custom error handling for Bandwidth API responses
+- `lib/registration_repo.rb` - Redis-backed registration management with conflict detection
+- `bin/notify_inbound_failures_job` - Background job for handling inbound message failures
+
+**Architecture Notes:**
+- Uses EventMachine for async operations throughout
+- Redis for message queuing and registration storage
+- Bandwidth API V2 integration with proper error handling
+- XMPP protocol via Blather gem (custom fork from develop branch)
+
+## Development Commands & Workflow
+
+**Environment Setup:**
+```bash
+bundle install # Install Ruby dependencies
+```
+
+**Testing & Quality:**
+```bash
+bundle exec rake # Run full test suite
+bundle exec rake test # Alternative test command
+bundle exec ruby test/test_component.rb -n test_name # Single test
+bundle exec rubocop -a # Auto-fix linting issues
+bundle exec rake lint # Check linting
+bundle exec rake entr # Watch mode (requires entr tool)
+```
+
+**Running Services:**
+```bash
+# Main XMPP gateway
+./sgx-bwmsgsv2.rb <jid> <password> <host> <port> <app_id> <http_port> <mms_proxy_url>
+
+# Redis translator
+./r2s-bwmsgsv2.rb <redis_queue_suffix> <sgx_hostname> <sgx_https_port>
+
+# Background job
+./bin/notify_inbound_failures_job --webhook-endpoint URL --bw-acct-id ID --bw-password PASS --bw-username USER
+```
+
+## Technical Implementation Details
+
+**Async Programming Patterns:**
+- All async tests use `em :test_name` decorator and must call `EM.stop`
+- EventMachine promises via `em_promise.rb` for async operations
+- FakeRedis in tests returns EMPromise objects for consistency
+
+**Registration Management:**
+- `RegistrationRepo` handles JID↔telephone mapping with Redis transactions
+- Uses `LazyObject` for Redis connection to defer initialization
+- Implements conflict detection for duplicate telephone registrations
+- Key patterns: `catapult_cred-{jid}` and `catapult_jid-{tel}`
+
+**Error Handling:**
+- `BandwidthError.for(http_code, body)` parses API error responses
+- Handles JSON error bodies with field-specific error messages
+- Falls back to generic error messages for non-JSON responses
+
+**Testing Infrastructure:**
+- FakeRedis class mocks all Redis operations with Promise-based returns
+- WebMock for HTTP stubbing - always stub external Bandwidth API calls
+- SimpleCov with branch coverage enabled
+- Test helper includes pry integration for debugging
+
+## Critical Dependencies & Requirements
+
+**Required System Components:**
+- `tai` binary must be present in working directory for high-precision timestamps
+- Redis server for message queuing and registration storage
+- EventMachine reactor for async operations
+
+**Key Gem Dependencies:**
+- `blather` (custom fork from develop branch) for XMPP
+- `em-hiredis` for async Redis operations
+- `em-http-request` for async HTTP calls
+- `goliath` for HTTP server capabilities
+- `sentry-ruby` for error tracking
+
+## Configuration & Environment
+
+**Environment Variables:**
+- `ENV` - General environment configuration
+- `MMS_PATH` - MMS file storage path
+- `MMS_URL` - MMS proxy URL for media handling
+
+**Security Practices:**
+- Never commit credentials, API keys, or phone numbers
+- All sensitive data passed via CLI arguments or environment variables
+- Redis transactions used for atomic registration updates
+- External HTTP calls must be stubbed in tests