type: axiom

category: infrastructure

axiom: Never put internal infrastructure services on product or brand domains. Infrastructure (tunnels, relays, file servers) gets a dedicated domain. Product domains are customer-facing only.

trigger: files.sunaiva.com and relay.sunaiva.com were created on the product domain sunaiva.com. Kinan caught it immediately — sunaiva.com is the memory MCP product domain.

resolution: Migrated to adaptigenai.com (dedicated infra domain). Created Rule 19: Optimal Foundation Protocol.

rule_updated: GLOBAL_GENESIS_RULES.md Rule 19


axiom: Always choose the optimal route AND the long-term solid foundation. When these conflict, long-term wins. Quick fixes that create future debt are forbidden.

trigger: Kinan asked 'is dedicated optimal?' — forcing evaluation of whether the first working approach was actually the best approach.

resolution: Evaluated 3 options (dedicated path-based, individual subdomains, brand domain subdomains). Individual subdomains on non-product domain won as simplest + most scalable.


axiom: Cloudflare has two scoped API tokens in Genesis: DNS-only (hrpgSO...) for record CRUD, and Workers (oi76kT...) for wrangler deploys/secrets. Neither can create new zones — that requires zone.create permission or the dashboard.

trigger: Attempted to add adaptigenai.com zone via API, both tokens returned 'Requires permission com.cloudflare.api.account.zone.create'.

resolution: Domain was already on Cloudflare (added previously). For new zones, use dashboard or create a third token with zone.create.


axiom: WSL2 has no systemd user services (no D-Bus). Use cron @reboot + periodic health checks for persistent services instead.

trigger: Attempted systemd user service for tunnel management, got 'Failed to connect to bus'.

resolution: Created tunnel_manager.sh with cron: @reboot for startup, */2 for auto-heal health checks.


axiom: When killing SSH reverse tunnels, ALWAYS free the VPS-side port too. The remote sshd listener survives local process death, leaving the port bound.

trigger: After pkill of local SSH process, VPS port 9876 remained bound to dead sshd. New tunnel failed with 'remote port forwarding failed'.

resolution: stop_tunnel() now does both: pkill -9 locally AND ssh VPS 'fuser -k PORT/tcp' to free remote port.


axiom: ALWAYS verify CDN/script URLs return HTTP 200 before deploying to production. A 404 script tag silently kills all dependent functionality.


axiom: ALWAYS verify DNS resolution of a domain before choosing deployment target. talkingwidget.ai resolved to VPS (152.53.201.221) not Netlify — deploying to Netlify was wasted work.


axiom: NEVER assume npm package renames without checking npm registry. @telnyx/ai-agent-widget was NOT renamed to @telnyx/ai-agent — the latter does not exist.


axiom: Telnyx-hosted models (Qwen3-235B, Llama-3.3-70B) cause 'greeting works but can't hear user' on WebRTC widget calls. The symptom: assistant speaks greeting, user talks, assistant does not respond. Root cause is model-level — these models don't properly handle the Telnyx real-time voice pipeline's two-way audio processing. PROVEN FIX: google/gemini-2.5-flash with llm_api_key_ref: google_gemini_key. This pattern has repeated across Maya widget AND VTB phone assistant.


axiom: When debugging 'assistant can't hear user' on Telnyx: check the MODEL FIRST, not the frontend. If greeting plays but user speech gets no response, the model is not processing transcribed audio. Switch to google/gemini-2.5-flash (proven working). Frontend mic permission issues would prevent the call from connecting at all.

source: failure_015 + failure_016


axiom: Two failed fix attempts = mandatory revert to last known working state. Ship working state to production. THEN iterate with ONE small change at a time, testing each before deploying. Never stack untested fixes — each builds on an unverified assumption.


axiom: Shadow DOM web components may use their own position:fixed styling that ignores the host element's layout. Never assume a web component's rendered UI will be constrained by the host element's CSS. Always inspect the actual shadow DOM rendering before building overlay strategies.


axiom: getUserMedia() (microphone/camera) REQUIRES a REAL user gesture with isTrusted:true. Programmatic dispatchEvent() ALWAYS sets isTrusted:false — it CANNOT satisfy browser permission requirements. For any web component needing browser permissions: position the real element on top as an invisible overlay (opacity:0, pointer-events:auto, higher z-index) and let real clicks pass through. Never proxy clicks via synthetic events.


axiom: When wrapping a third-party web component with a custom UI: use the INVISIBLE OVERLAY pattern. Place the real component ON TOP of your custom UI with opacity:0 and higher z-index. Your custom UI is purely visual (underneath). Real user clicks hit the real component. Listen for the component's events to update your visual UI state. Never intercept clicks and re-dispatch — always let them pass through.


axiom: SubAIVA KnowledgeStore is USELESS unless Genesis agents can QUERY it. Ingestion without retrieval = dead knowledge. Every ingestion pipeline MUST have a corresponding query endpoint wired into the Genesis orchestration layer (MCP server, skill, or direct API call in agent prompts).


axiom: RLM swarm memory must be BIDIRECTIONAL: Genesis writes knowledge IN (ingestion) AND reads knowledge OUT (retrieval). A one-way pipe is not a memory system — it is a graveyard. Wire swarm/search into every agent's capability manifest.


axiom: Qwen3-235B-A22B on Telnyx generates <think> reasoning tags in EVERY response via the OpenAI-compatible chat API. These thinking tokens are NOT handled by Telnyx TTS — they either get spoken aloud (nonsensical) or cause a timeout before the actual response content arrives. This is the ROOT CAUSE of 'greeting works, can't hear response' with Qwen3 on Telnyx. The greeting is static text (no LLM needed) so it always works regardless of model issues.

evidence: curl Telnyx chat/completions with Qwen/Qwen3-235B-A22B returned: <think>Okay, the user wants me to say hello... Same endpoint with google/gemini-2.5-flash returned: Hello (clean, no tags)


axiom: Telnyx AI secrets (llm_api_key_ref) are write-only — you CANNOT read the stored value. If an external model (google/gemini-2.5-flash) fails silently, the FIRST thing to check is whether the stored secret has the correct API key. Delete and recreate the secret with a verified key. Use Telnyx POST /v2/ai/secrets with 'token' field (NOT 'value').

evidence: google_gemini_key secret existed since 2026-02-20 but may have had wrong value. DELETE + POST with verified key fixed the issue. POST requires 'token' field, not 'value'.


title: KB ingestion without retrieval bridge = dead knowledge

axiom: Ingesting knowledge into passive files (.gemini/knowledge/, KNOWLEDGE_GRAPH/) is NECESSARY but INSUFFICIENT. Knowledge must have a forced-read mechanism that routes it to agents at the moment of task execution. Three compounding failures proved this: (1) KB stored in passive files with no forced-read, (2) SDK discovered 3 days after KB was built but never back-propagated into KB/skill/CLAUDE.md, (3) MCP server identified as missing but never added to settings.json. Fix: every platform KB must have a forced-read directive in CLAUDE.md + be referenced in the relevant skill + have its MCP server configured.

severity: critical

source: Telnyx KB failure pre-mortem

guardrails_added: TELNYX_DEEP_KB.md v4.0 with SDK patterns


title: Back-propagation is mandatory after discovery

axiom: When a new capability is discovered (SDK, MCP, widget), it MUST be immediately back-propagated into all authoritative references: (1) the relevant .gemini/knowledge/ KB file, (2) the relevant .claude/skills/ SKILL.md, (3) CLAUDE.md if it references the platform, (4) settings.json if MCP exists. Discovery without back-propagation = knowledge rot. The SDK was found 3 days after KB was built; those 3 days of agents using curl instead of SDK were avoidable.

severity: high


title: Session start memory injection is lossy — forced-read beats semantic retrieval for critical knowledge

axiom: Session start injects memories via semantic search on 'Genesis session start' signal. Telnyx platform knowledge competes with all other memories for top-15 slots capped at 6000 chars. Critical platform knowledge CANNOT rely on winning this competition. Fix: CLAUDE.md mandatory pre-read section directs agents to explicitly read skill files before platform work.