Elixir is the clan agent for the POAP KINGS Clash Royale clan (#J2RGCRVG).
It combines a deterministic data engine, an LLM awareness loop, scoped memory,
Discord conversation, and leadership workflows.
AGENTS.md is the source of truth for architecture and repository conventions. SETUP.md is the production operations guide.
Elixir has one external data ingress and one proactive voice:
flowchart LR
API["Clash Royale API"] --> INGRESS["cr_api.py"]
INGRESS --> RECEIPTS["append-only API receipts"]
RECEIPTS --> RAW["deduplicated payload content<br/>14-day analysis buffer"]
INGRESS --> TICK["atomic materialization generation<br/>apply → derive → manage"]
TICK --> STREAMS["battle, player, clan,<br/>and war event streams"]
TICK --> READS["current projections, rollups,<br/>management state + generation id"]
STREAMS --> AWARE["hourly awareness loop"]
READS --> AWARE
AWARE --> PLAN["validated post plan<br/>with hard coverage floors"]
PLAN --> OUTBOX["durable per-post outbox"]
OUTBOX --> DISCORD["member-facing Discord lanes"]
TICK --> ACTIONS["leader action cards"]
cr_api.pyis the only Clash Royale API ingress. Every successful response appends anapi_observation_receiptsrow; identical bodies share oneraw_api_payloadscontent row.engine.tick.run_tickrecords the admitted inputs and commits streams, projections, rollups, readiness, management, and generation status together. Interactive profile/battle-log refreshes use the same generation contract.- Event streams are durable history. Projections are disposable read models. Current state is never reconstructed from prompts.
- The awareness loop reads one SQLite snapshot identified by
data_generation, decides what is worth saying, and is the sole proactive poster. Its whole plan is validated and persisted before send; partial retries skip fulfilled posts. - Clan management is deterministic. It writes state and leader actions; it does not delegate promotion, demotion, or kick policy to the model.
The detailed v5.1 design is in docs/reference/v5.1/.
Elixir speaks as one identity across destination-specific Discord lanes:
#elixir— the awareness brain's curated public commentary and updates.#announcements— weekly recaps and major system updates.#actions— crisp leadership handoff cards and action outcomes.#ask-elixir— open member conversation and screenshot help.#clan-chat— mention-driven clan help.#leaders— private, evidence-grounded clan operations.#welcome— onboarding and identity verification.#recruiting— reusable recruiting copy.
The exact channel IDs, reply policies, memory scopes, and workflows live in prompts/DISCORD.md.
runtime/activities.py is the canonical registry for activity keys, ownership, schedules, executors, delivery targets, and enabled state. The important groups are:
- Core:
engine-tickandawareness-loop. - Clan management:
weekly-leadership-review,action-outcome-refresh, andwar-attendance-snapshot. - Member communications:
daily-clan-insight,weekly-recap,weekly-member-report,weekly-elder-standing,promotion-content, andweekly-discord-invite-relay. - Data and operations:
card-catalog-sync,api-sentinel,engine-health,db-maintenance,db-backup, andmemory-synthesis. - Optional/manual:
clan-wars-intel; tournament watching is dynamically started and resumed outside the recurring registry.
Do not duplicate schedule values in prose; inspect the registry or use the
/clanops activity ... commands.
Python 3.14 is the supported runtime.
python3 -m venv venv
./venv/bin/pip install -r requirements.lock -r requirements-dev.txt
# Create .env with the required secrets below.
./venv/bin/python elixir.pyRequired secrets:
DISCORD_TOKEN=...
CLAUDE_API_KEY=...
CR_API_KEY=...Non-secret clan and Discord configuration lives in prompts/CLAN.md and
prompts/DISCORD.md. See SETUP.md before running production.
requirements.txt contains direct runtime constraints.
requirements.lock is the exact production environment. CI and deployment
install the lock; development adds requirements-dev.txt.
- elixir.py — process entrypoint.
- elixir_agent.py — stable public LLM facade.
- cr_api.py — sole Clash Royale API ingress.
- engine/ — five-step data engine, emitters, projections, management, polling, and offline rehearsal.
- db/ — connection discipline, schema checks, and storage facade.
- storage/ — domain persistence and read helpers.
- agent/ — workflow prompts, model loop, tool contracts, and tools.
- runtime/ — Discord routing, activities, jobs, awareness, health, and the Observatory web app.
- prompts/ — identity, purpose, clan, channel, lane, and workflow instructions.
- scripts/migrate_v51/ — v5.1 baseline schema, archive transforms, and parity/rehearsal tools.
- tests/ — unit, integration, fixture, invariant, and entrypoint tests.
The operational database defaults to elixir-v51.db. Clash Royale player tags
are natural keys everywhere. The pre-cut database is the immutable cold archive
elixir-v5-archive-2026H2.db and must never be written.
The runtime data layers are:
- Raw API responses — bounded analysis buffer, not system of record.
- Baselines — current comparison substrate for state-diff emitters.
- Event streams — durable battle/player/clan/war facts.
- Rollups — durable player and clan daily metrics.
- Identity and tenure — players, Discord links, aliases, and memberships.
- Projections — rebuildable current state and management views.
- Awareness, management, operations, and scoped memory records.
See docs/data-model-erd.md and docs/reference/v5.1/schema.md.
Use the project virtualenv:
./venv/bin/python scripts/check_dependency_lock.py
./venv/bin/python scripts/check_docs.py
./venv/bin/python scripts/check_exception_hygiene.py
./venv/bin/ruff check .
./venv/bin/ruff format --check .
./venv/bin/mypy capabilities/contracts.py
./venv/bin/pytest tests/ -q --cov=capabilities --cov-report=term-missing --cov-fail-under=80Before deploying engine changes, also run:
./venv/bin/python scripts/replay_gate.py
./venv/bin/python scripts/simulate.pyFor one consolidated health answer:
./venv/bin/python scripts/confidence_report.py --jsonThe suite uses isolated SQLite databases and mocked external services. Real CR
payload shapes live in tests/fixtures/cr/; refresh them from retained raw
payloads rather than hand-editing them.
Production is managed by launchd through scripts/admin.sh:
bash scripts/admin.sh status
bash scripts/admin.sh restart
bash scripts/admin.sh activity run engine-healthMember self-service commands live under /elixir. Leadership operations live
under /clanops. System telemetry and management surfaces belong in the
Observatory web app, not general Discord commands.
Review model/channel failures with:
./venv/bin/python scripts/review_agent_feedback.py --limit 20
./venv/bin/python scripts/review_agent_feedback.py --workflow clanops --json./venv/bin/python scripts/clean.py
./venv/bin/python scripts/clean.py --dbThe database cleanup option removes only legacy local runtime files; it never
touches elixir-v51.db or the archives.
A new clan primarily rewrites prompts/CLAN.md, prompts/DISCORD.md, and any
culture-specific lane prompts. Elixir no longer publishes poapkings.com; the
site has its own standalone update process.