Discord bot inbound adapter (adapters/inbound/discord_bot.py):
- ChatService injected directly — no HTTP roundtrip to FastAPI API
- No module-level singleton: create_bot() factory for construction
- Pure functions extracted for testing: build_answer_embed,
build_error_embed, parse_conversation_id
- Uses message.reference.resolved cache before fetch_message
- Error embeds never leak exception details
- 19 new tests covering embed building, footer parsing, error safety
Removed old app/ directory (9 files):
- All functionality preserved in hexagonal domain/, adapters/, config/
- Old test_basic.py removed (superseded by 120 adapter/domain tests)
Other changes:
- docker-compose: api uses main:app, discord-bot uses run_discord.py
with direct ChatService injection (no API dependency)
- Removed unused openai dependency from pyproject.toml
- Removed app/ from hatch build targets
Test suite: 120 passed, 1 skipped
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prompt injection mitigation:
- Wrap user question in <user_question> XML tags in LLM prompt
- Add system prompt instruction to treat tagged content as untrusted
Docker security:
- Bind ChromaDB and API ports to localhost only (127.0.0.1)
- Remove redundant DB init command from api service (lifespan handles it)
- Remove deprecated version field and unused volume definitions
- Add API_SECRET env var to api and discord-bot services
Gitea labels fix:
- Remove string labels from API payload (Gitea expects integer IDs)
- Include label names as text in issue body instead
Conversation cleanup:
- Add periodic background task in lifespan (every 5 minutes)
- Cleans up conversations older than CONVERSATION_TTL (default 30 min)
- Graceful cancellation on shutdown
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add vector store with sentence-transformers for semantic search
- FastAPI backend with /chat and /health endpoints
- Conversation state persistence via SQLite
- OpenRouter integration with structured JSON responses
- Discord bot with /ask slash command and reply-based follow-ups
- Automated Gitea issue creation for unanswered questions
- Docker support with docker-compose for easy deployment
- Example rule file and ingestion script
- Comprehensive documentation in README