Skip to content

Latest commit

Β 

History

History
819 lines (621 loc) Β· 27.9 KB

File metadata and controls

819 lines (621 loc) Β· 27.9 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with the CIRIS codebase.

🎯 CURRENT FOCUS: Production Quality & Stability

Goal: Maintain production-grade quality, stability, and test coverage

Priority Areas

  1. Test Coverage - Target 80%

    • Focus on critical path services
    • Integration tests for complex flows
    • Edge case coverage
  2. Bug Fixes & Stability

    • Address any production issues from agents.ciris.ai
    • Fix flaky tests
    • Resolve memory leaks or performance issues
  3. Documentation & Code Quality

    • Update outdated documentation
    • Remove dead code and TODOs
    • Ensure all APIs are properly documented
  4. Security Hardening

    • Review authentication flows
    • Audit secret handling
    • Validate input sanitization

⚠️ CRITICAL: Medical Domain Prohibition

NEVER implement in main repo:

  • Medical/health capabilities
  • Diagnosis/treatment logic
  • Patient data handling
  • Clinical decision support

These are BLOCKED at the bus level. See PROHIBITED_CAPABILITIES in wise_bus.py.


Project Overview

CIRIS (Core Identity, Integrity, Resilience, Incompleteness, and Signalling Gratitude) is an ethical AI platform:

  • Production: Discord moderation + API at agents.ciris.ai
  • Architecture: 22 core services, 6 message buses, strict type safety
  • Philosophy: No Untyped Dicts, No Bypass Patterns, No Exceptions
  • Target: 4GB RAM, offline-capable deployment

Multi-Occurrence Deployment Support

CIRIS supports running multiple runtime occurrences of the same agent against a shared database for horizontal scaling.

Key Concepts

  • Occurrence: A single runtime instance of an agent (process/container)
  • Shared Tasks: Agent-level tasks using agent_occurrence_id="__shared__" that coordinate across occurrences
  • Atomic Claiming: Race-free task claiming using deterministic IDs + INSERT OR IGNORE

Configuration

# Set occurrence ID (defaults to "default")
export AGENT_OCCURRENCE_ID="occurrence-1"

# Set total occurrence count for discovery
export AGENT_OCCURRENCE_COUNT="9"

Architecture

Single Decision-Maker Pattern:

  • Wakeup/shutdown decisions made by ONE occurrence
  • Decision applies to ALL occurrences
  • Other occurrences skip or monitor the shared decision

Implementation:

  • try_claim_shared_task() - Atomic task claiming
  • is_shared_task_completed() - Check if another occurrence decided
  • get_latest_shared_task() - Retrieve shared decision
  • Deterministic task IDs: WAKEUP_SHARED_20251027, SHUTDOWN_SHARED_20251027

Key Files

  • Shared Task Functions: ciris_engine/logic/persistence/models/tasks.py
  • Occurrence Utils: ciris_engine/logic/utils/occurrence_utils.py
  • Wakeup Coordination: ciris_engine/logic/processors/states/wakeup_processor.py
  • Shutdown Coordination: ciris_engine/logic/processors/states/shutdown_processor.py

Testing Multi-Occurrence

# Unit tests with race simulation
pytest tests/ciris_engine/logic/persistence/test_shared_tasks.py

# Occurrence discovery tests
pytest tests/ciris_engine/logic/utils/test_occurrence_utils.py

Important: Configuration already in EssentialConfig.agent_occurrence_id (line 129)

Core Philosophy: Type Safety First

🚧 PROGRESS: Minimizing Dict[str, Any] usage in production code

The Three Rules

  1. No Untyped Dicts: All data uses Pydantic models instead of Dict[str, Any]
  2. No Bypass Patterns: Every component follows consistent rules and patterns
  3. No Exceptions: No special cases, emergency overrides, or privileged code paths

Before Creating ANY New Type

# ALWAYS search first:
grep -r "class.*YourThingHere" --include="*.py"
# The schema already exists. Use it.

Type Safety Best Practices

  1. Replace Untyped Dicts with Pydantic Models

    # ❌ Bad
    def process_data(data: Dict[str, Any]) -> Dict[str, Any]:
        return {"result": data.get("value", 0) * 2}
    
    # βœ… Good
    class ProcessRequest(BaseModel):
        value: int = 0
    
    class ProcessResponse(BaseModel):
        result: int
    
    def process_data(data: ProcessRequest) -> ProcessResponse:
        return ProcessResponse(result=data.value * 2)
  2. Use Specific Types Instead of Any

    # ❌ Bad
    metrics: Dict[str, Any] = {"cpu": 0.5, "memory": 1024}
    
    # βœ… Good
    class SystemMetrics(BaseModel):
        cpu: float = Field(..., ge=0, le=1, description="CPU usage 0-1")
        memory: int = Field(..., gt=0, description="Memory in MB")
    
    metrics = SystemMetrics(cpu=0.5, memory=1024)
  3. Leverage Union Types for Flexibility

    # For gradual migration or multiple input types
    def process(data: Union[dict, ProcessRequest]) -> ProcessResponse:
        if isinstance(data, dict):
            data = ProcessRequest(**data)
        return ProcessResponse(result=data.value * 2)
  4. Avoid Bypass Patterns - Follow Consistent Rules

    # ❌ Bad - Special bypass for "emergency"
    if emergency_mode:
        return process_without_validation(data)
    
    # βœ… Good - Same validation rules apply everywhere
    validated_data = validate_request(data)
    return process_validated_data(validated_data)
  5. Use Enums for Constants

    # ❌ Bad
    status = "active"  # Magic string
    
    # βœ… Good
    class ServiceStatus(str, Enum):
        ACTIVE = "active"
        INACTIVE = "inactive"
        ERROR = "error"
    
    status = ServiceStatus.ACTIVE
  6. Enhanced Mypy Configuration

    • strict = True enabled in mypy.ini with additional strictness flags
    • disallow_any_explicit = True temporarily disabled (too many false positives)
    • Minimal Dict[str, Any] usage remaining, none in critical code paths
    • Run mypy as part of CI/CD pipeline
  7. Build-Time Generated Files

    • Some files are generated at build time and not present in the repo/CI
    • These require # type: ignore[import-not-found] comments
    • DO NOT REMOVE these comments even if mypy reports "unused-ignore" locally
    • Examples:
      • ciris_adapters/wallet/providers/_build_secrets.py - Contains API keys/URLs injected at build time
    • Always add a comment explaining why the ignore is needed:
      # _build_secrets is generated at build time, not present in CI/repo
      from ._build_secrets import get_api_key  # type: ignore[import-not-found]

CRITICAL: OAuth Callback URL Format

PRODUCTION OAuth CALLBACK URL - DO NOT FORGET:

https://agents.ciris.ai/v1/auth/oauth/{agent_id}/{provider}/callback

Example for Datum + Google:

https://agents.ciris.ai/v1/auth/oauth/datum/google/callback

REMEMBER:

  • Agent ID comes BEFORE provider
  • /v1/ is at the ROOT level
  • This is the DEFAULT route (not /api/{agent}/v1/)

Architecture Overview

Message Bus Architecture (6 Buses)

Buses enable multiple providers for scalability:

Bussed Services:

  • CommunicationBus β†’ Multiple adapters (Discord, API, CLI)
  • MemoryBus β†’ Multiple graph backends (Neo4j, ArangoDB, in-memory)
  • LLMBus β†’ Multiple LLM providers (OpenAI, Anthropic, local models)
  • ToolBus β†’ Multiple tool providers from adapters
  • RuntimeControlBus β†’ Multiple control interfaces
  • WiseBus β†’ Multiple wisdom sources

Direct Call Services:

  • All Graph Services (except memory)
  • Core Services: secrets
  • Infrastructure Services (except wise_authority)
  • All Special Services

Service Registry Usage

Only for multi-provider services:

  1. LLM - Multiple providers
  2. Memory - Multiple graph backends
  3. WiseAuthority - Multiple wisdom sources
  4. RuntimeControl - Adapter-provided only

Cognitive States (6)

  • WAKEUP - Identity confirmation
  • WORK - Normal task processing
  • PLAY - Creative mode
  • SOLITUDE - Reflection
  • DREAM - Deep introspection
  • SHUTDOWN - Graceful termination

Localization

CIRIS supports 29 languages with full pipeline localization. The entire ethical reasoning system operates in the user's preferred language.

Supported Languages

am (Amharic), ar (Arabic), bn (Bengali), de (German), en (English), es (Spanish), fa (Persian), fr (French), ha (Hausa), hi (Hindi), id (Indonesian), it (Italian), ja (Japanese), ko (Korean), pt (Portuguese), ru (Russian), sw (Swahili), tr (Turkish), ur (Urdu), zh (Chinese)

Key Files

  • UI Strings: localization/{lang}.json - Mobile/API UI strings
  • ACCORD: ciris_engine/data/localized/accord_1.2b_{lang}.txt
  • Guides: ciris_engine/data/localized/CIRIS_COMPREHENSIVE_GUIDE_{lang}.md
  • DMA Prompts: ciris_engine/logic/dma/prompts/localized/{lang}/*.yml

Setting Language

export CIRIS_PREFERRED_LANGUAGE=am  # Set before starting server

How It Works

  1. get_preferred_language() reads CIRIS_PREFERRED_LANGUAGE env var
  2. DMAPromptLoader auto-detects language on first load
  3. Each DMA calls get_localized_accord_text(lang) for localized ACCORD
  4. Conscience strings use get_string(lang, "conscience.ponder_*")

Testing Localization

# Run streaming test with Amharic
CIRIS_PREFERRED_LANGUAGE=am python3 -m tools.qa_runner streaming --verbose
# Look for Amharic text: αŠ¨αˆ˜αŒ€αˆ˜αˆͺያው αŒ₯ያቄ α‰ αŠα‰΅...

Development Tools

Grace - Sustainable Development Companion

Grace is your intelligent pre-commit gatekeeper and development assistant that ensures sustainable coding practices:

# Quick status check
python -m tools.grace status           # Current session, health, CI status

# CI/CD Monitoring (CRITICAL for Claude)
python -m tools.grace ci               # Current branch CI + PR summary (10min throttle)
python -m tools.grace ci prs           # All PRs with conflict/block detection
python -m tools.grace ci builds        # Build & Deploy status across branches
python -m tools.grace ci hints         # Common CI failure hints & existing schemas

# Pre-commit assistance
python -m tools.grace precommit        # Detailed pre-commit status and fixes
python -m tools.grace fix              # Auto-fix pre-commit issues

# Session management
python -m tools.grace morning          # Morning check-in
python -m tools.grace pause            # Save context before break
python -m tools.grace resume           # Resume after break
python -m tools.grace night            # Evening choice point

# Deployment & incidents
python -m tools.grace deploy           # Check deployment status
python -m tools.grace incidents        # Check production incidents

# Short forms: s, m, p, r, n, d, c, pc, f, i

Grace Philosophy:

  • Be strict about safety, gentle about style - Blocks only critical issues (syntax errors, security)
  • Progress over perfection - Quality issues are reminders, not blockers
  • Sustainable pace - Tracks work sessions and encourages breaks

Pre-commit Integration: Grace is the primary pre-commit hook. It:

  1. Auto-formats with black and isort
  2. Blocks critical issues (syntax, merge conflicts, secrets)
  3. Reports quality issues as gentle reminders
  4. Runs all checks concurrently for speed

CRITICAL CI Guidance for Claude (You!)

YOUR BAD HABITS TO STOP:

  1. Creating new Dict[str, Any] - A schema already exists. Always.
  2. Creating NewSchemaV2 - The original schema is fine. Use it.
  3. Checking CI too frequently - CI takes time to complete. Check periodically.
  4. Making "temporary" helper classes - They're never temporary. Use existing schemas.
  5. Creating elaborate abstractions - Simple existing patterns work better.

BEFORE CREATING ANY NEW TYPE:

# ALWAYS search first:
grep -r "class.*YourThingHere" --include="*.py"
# The schema already exists. Use it.

Schemas That Already Exist (Stop Recreating!)

  • AuditEventData - ALL audit events
  • ServiceMetrics - ALL metrics
  • SystemSnapshot - System state
  • ProcessingQueueItem - Queue items
  • ActionResponse - Handler responses
  • ThoughtSchema - Thoughts
  • GuidanceRequest/Response - WA guidance

Service Architecture

22 Core Services

Graph Services (7): memory, consent, config, telemetry, audit, incident_management, tsdb_consolidation

Infrastructure Services (4): authentication, resource_monitor, database_maintenance, secrets

Lifecycle Services (4): initialization, shutdown, time, task_scheduler

Governance Services (4): wise_authority, adaptive_filter, visibility, self_observation

Runtime Services (2): llm, runtime_control

Tool Services (1): secrets_tool

Message Buses (6)

  • CommunicationBus β†’ Multiple adapters
  • MemoryBus β†’ Multiple graph backends
  • LLMBus β†’ Multiple LLM providers
  • ToolBus β†’ Multiple tool providers
  • RuntimeControlBus β†’ Multiple control interfaces
  • WiseBus β†’ Multiple wisdom sources (FOCUS AREA)

Adapter Development

Adapters extend CIRIS with new capabilities via the bus system. See FSD/ADAPTER_DEVELOPMENT_GUIDE.md for the full guide.

Quick Reference

Required Files:

ciris_adapters/your_adapter/
β”œβ”€β”€ __init__.py           # MUST export Adapter
β”œβ”€β”€ adapter.py            # BaseAdapterProtocol implementation
β”œβ”€β”€ manifest.json         # Metadata, services, capabilities
β”œβ”€β”€ tool_service.py       # ToolServiceProtocol implementation
└── config.py             # Pydantic config models (no Dict[str, Any])

Context Enrichment: Tools that provide situational awareness should auto-run during context gathering:

ToolInfo(
    name="get_status",
    context_enrichment=True,
    context_enrichment_params={"include_details": False},
    ...
)

DMA Guidance: Financial and destructive tools MUST have:

dma_guidance=ToolDMAGuidance(
    requires_approval=True,  # Triggers Wise Authority deferral
    min_confidence=0.95,     # High confidence required
    ethical_considerations="...",
)

Reference Implementations:

  • ciris_adapters/sample_adapter/ - Complete template
  • ciris_adapters/home_assistant/ - Context enrichment example
  • ciris_adapters/wallet/ - Financial tools example

Unified Agent UX (mobile/)

NOTE: "mobile" is a misnomer. The mobile/ directory contains the unified CIRIS agent UX - a Kotlin Multiplatform (KMP) client targeting Android, iOS, Windows, macOS, and Linux. It's the cross-platform user interface for interacting with CIRIS agents.

Unified Entry Point (ciris-agent)

The ciris-agent command is the unified entry point that starts both the Python backend and the desktop GUI:

# Unified: Start API server + launch desktop app (DEFAULT)
ciris-agent

# Server-only modes (headless)
ciris-agent --server              # API server only
ciris-agent --adapter api         # Same as --server
ciris-agent --adapter discord     # Discord bot mode

# Separate commands
ciris-server                      # Headless API server only
ciris-desktop                     # Desktop app only (connects to running server)

How it works (from ciris_engine/cli.py):

  1. Starts Python API server on port 8080 via main.py --adapter api
  2. Waits briefly to detect startup failures
  3. Launches desktop JAR via desktop_launcher.py
  4. On exit, shuts down server gracefully

Desktop JAR location:

  • Production: ciris_engine/desktop_app/CIRIS-*.jar (bundled in pip package)
  • Development: mobile/desktopApp/build/compose/jars/CIRIS-*.jar

Mobile QA Runner (ALWAYS USE THIS)

When debugging mobile app issues, always use the QA runner to pull logs:

# Pull all logs from device (debug build) - THE COMMAND TO USE
python3 -m tools.qa_runner.modules.mobile pull-logs

# Specify output directory
python3 -m tools.qa_runner.modules.mobile pull-logs -o ./my_logs

# Specific device
python3 -m tools.qa_runner.modules.mobile pull-logs -d emulator-5554

Files collected (saved to mobile_qa_reports/<timestamp>/):

  • logs/latest.log - Python runtime logs (CIRIS engine)
  • logs/incidents_latest.log - Incident/error logs (CHECK THIS FIRST!)
  • logcat_python.txt - Python stdout/stderr
  • logcat_app.txt - Kotlin/KMP logs (CIRISApp, ViewModels, etc.)
  • logcat_combined.txt - All relevant logs combined
  • logcat_crashes.txt - Android crashes
  • databases/*.db - SQLite databases (ciris_engine.db, secrets.db, audit.db)
  • prefs/*.xml - Shared preferences
  • env_file.txt - .env file (tokens redacted)
  • app_info.txt - Device and package info

Quick analysis:

# Check for errors (ALWAYS DO THIS FIRST!)
grep -i error mobile_qa_reports/*/logs/incidents_latest.log

# Recent Python logs
tail -100 mobile_qa_reports/*/logs/latest.log

# Kotlin/KMP logs (CIRISApp, ViewModels)
grep -i "CIRISApp\|ViewModel\|error" mobile_qa_reports/*/logcat_app.txt

UI Automation Tests

Automated UI testing for the CIRIS mobile app:

# Full flow test with test account
python3 -m tools.qa_runner.modules.mobile test full_flow

# Individual tests
python3 -m tools.qa_runner.modules.mobile test app_launch
python3 -m tools.qa_runner.modules.mobile test google_signin
python3 -m tools.qa_runner.modules.mobile setup_wizard
python3 -m tools.qa_runner.modules.mobile chat_interaction

# Build and test
python3 -m tools.qa_runner.modules.mobile --build full_flow

Test account: ciristest1@gmail.com (password in ~/.ciristest1_password)

Build and Deploy

# Build debug APK
cd mobile && ./gradlew :androidApp:assembleDebug

# IMPORTANT: Kill the app before reinstalling (required for Python runtime to reload)
~/Android/Sdk/platform-tools/adb shell am force-stop ai.ciris.mobile.debug

# Install to device
~/Android/Sdk/platform-tools/adb install -r mobile/androidApp/build/outputs/apk/debug/androidApp-debug.apk

# Launch the app
~/Android/Sdk/platform-tools/adb shell am start -n ai.ciris.mobile.debug/ai.ciris.mobile.MainActivity

Desktop UI Test Mode

The desktop app includes an embedded HTTP server for programmatic UI testing:

# Via unified entry point (starts server + desktop with test mode)
export CIRIS_TEST_MODE=true
ciris-agent

# Via Gradle (development - desktop only, connects to existing server)
export CIRIS_TEST_MODE=true
cd mobile && ./gradlew :desktopApp:run

# Build development JAR first (if needed)
cd mobile && ./gradlew :desktopApp:packageUberJarForCurrentOS

# Custom test server port
export CIRIS_TEST_PORT=9000

Test Server Endpoints (http://localhost:8091):

  • GET /health - Health check
  • GET /screen - Current screen name
  • GET /tree - Full UI element tree with positions
  • POST /click - Click element: {"testTag": "btn_login"}
  • POST /input - Input text: {"testTag": "input_user", "text": "admin"}
  • POST /wait - Wait for element: {"testTag": "btn_send", "timeoutMs": 5000}

Full documentation: mobile/desktopApp/src/main/kotlin/ai/ciris/desktop/testing/README.md

Development Workflow

Grace - Your Development Companion

# Daily workflow
python -m tools.grace morning          # Start day
python -m tools.grace status           # Check health
python -m tools.grace precommit        # Before commits
python -m tools.grace night            # End day

# CI monitoring (WAIT 10 MINUTES between checks!)
python -m tools.grace_shepherd status  # Check CI
python -m tools.grace_shepherd wait    # Monitor CI

Testing

# Docker-based testing (preferred)
python -m tools.test_tool test tests/
python -m tools.test_tool status
python -m tools.test_tool results

# Direct pytest (ALWAYS use -n 16 for parallel execution with 5+ minute timeout)
pytest -n 16 tests/ --timeout=300

# Coverage analysis
python -m tools.quality_analyzer       # Find gaps

# SonarCloud quality analysis
python -m tools.analysis.sonar quality-gate  # PR + main quality gate status (IMPORTANT!)
python -m tools.analysis.sonar status        # Main branch status only
python -m tools.analysis.sonar_tool status   # Alternative main branch status

QA Runner - API Test Suite

The CIRIS QA Runner provides comprehensive API testing with automatic server lifecycle management:

# Run all tests (default) - QA runner manages server lifecycle
python -m tools.qa_runner                # Run all test modules

# Quick module testing
python -m tools.qa_runner auth          # Authentication tests
python -m tools.qa_runner agent         # Agent interaction tests
python -m tools.qa_runner memory        # Memory system tests
python -m tools.qa_runner telemetry     # Telemetry & metrics tests
python -m tools.qa_runner system        # System management tests
python -m tools.qa_runner audit         # Audit trail tests
python -m tools.qa_runner tools         # Tool integration tests
python -m tools.qa_runner guidance      # Wise Authority guidance tests
python -m tools.qa_runner handlers      # Message handler tests
python -m tools.qa_runner filters       # Adaptive filtering tests (36 tests)
python -m tools.qa_runner sdk           # SDK compatibility tests
python -m tools.qa_runner streaming     # H3ERE pipeline streaming tests

# Comprehensive test suites
python -m tools.qa_runner extended_api  # Extended API coverage (24 tests)
python -m tools.qa_runner api_full      # Complete API test suite (24 tests)

# Full verbose output for debugging
python -m tools.qa_runner <module> --verbose

# Multi-backend testing (sequential by default)
python -m tools.qa_runner auth --database-backends sqlite postgres

# Parallel backend testing (run SQLite and PostgreSQL simultaneously)
python -m tools.qa_runner auth --database-backends sqlite postgres --parallel-backends

QA Runner Features:

  • πŸ€– Automatic Lifecycle Management - Starts/stops API server automatically
  • πŸ”‘ Smart Token Management - Auto re-authentication after logout/refresh tests
  • ⚑ Fast Execution - Most modules complete quickly
  • πŸ§ͺ Comprehensive Coverage - Authentication, API endpoints, streaming, filtering
  • πŸ” Detailed Reporting - Success rates, duration, failure analysis
  • πŸš€ Production Ready - Validates all critical system functionality
  • πŸ”„ Multi-Backend Support - Test against SQLite and PostgreSQL (sequential or parallel)

IMPORTANT - Server Lifecycle:

  • QA runner automatically starts and stops the API server
  • DO NOT manually start the server before running QA tests
  • If you have a server already running, kill it first: pkill -f "python main.py --adapter api"
  • Use --no-auto-start only if you need to debug with an existing server

Testing API Locally

# 1. Start API server with mock LLM
python main.py --adapter api --mock-llm --port 8000

# 2. Complete setup wizard (first run) - creates admin user with your chosen password
# Or for QA testing, use: python -m tools.qa_runner (auto-creates admin/qa_test_password_12345)

# 3. Get auth token (use the password you set during setup)
TOKEN=$(curl -X POST http://localhost:8000/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"YOUR_PASSWORD_FROM_SETUP"}' \
  2>/dev/null | python -c "import json,sys; print(json.load(sys.stdin)['access_token'])")

# 3. Check telemetry (should show 35/35 services when fully working)
curl -X GET http://localhost:8000/v1/telemetry/unified \
  -H "Authorization: Bearer $TOKEN" 2>/dev/null | \
  python -c "import json,sys; d=json.load(sys.stdin); print(f'{d[\"services_online\"]}/{d[\"services_total\"]} services healthy')"

# 4. List unhealthy services
curl -X GET http://localhost:8000/v1/telemetry/unified \
  -H "Authorization: Bearer $TOKEN" 2>/dev/null | \
  python -c "import json,sys; d=json.load(sys.stdin); print('Unhealthy:', [k for k,v in d['services'].items() if not v['healthy']])"

# 5. Interactive agent test
curl -X POST http://localhost:8000/v1/agent/interact \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"message":"Hello, how are you?"}' 2>/dev/null | python -m json.tool

Version Management

# ALWAYS bump version after significant changes
python tools/dev/bump_version.py patch     # Bug fixes
python tools/dev/bump_version.py minor     # New features
python tools/dev/bump_version.py major     # Breaking changes

Critical URLs & Paths

Production

Production Server Access

  • SSH: ssh -i ~/.ssh/ciris_deploy root@108.61.119.117
  • Agent Locations: /opt/ciris/agents/
  • Log Files: Logs are always written to files inside containers at /app/logs/
    • /app/logs/incidents_latest.log - Current incidents (ALWAYS CHECK THIS FIRST)
    • /app/logs/application.log - General application logs
    • /app/logs/ciris_YYYY-MM-DD.log - Daily log files
  • Common Commands:
    # Find agent containers
    cd /opt/ciris/agents && ls -la
    
    # Check specific agent status
    cd /opt/ciris/agents/echo-speculative-4fc6ru
    docker-compose ps
    
    # View agent logs FROM FILES (not docker logs)
    docker exec echo-speculative-4fc6ru tail -100 /app/logs/incidents_latest.log
    docker exec echo-speculative-4fc6ru tail -100 /app/logs/application.log
    
    # Check for consolidation activity
    docker exec echo-speculative-4fc6ru grep -i "consolidat" /app/logs/incidents_latest.log | tail -20
    
    # Check shutdown status
    docker exec echo-speculative-4fc6ru grep -i "shutdown" /app/logs/incidents_latest.log | tail -20
    
    # Execute commands in container
    docker-compose exec echo-speculative-4fc6ru python -c "print('hello')"
    
    # Check database files
    docker-compose exec echo-speculative-4fc6ru find /app -name '*.db'

Service Tokens (for API access):

  • Use format: Authorization: Bearer service:TOKEN_VALUE
  • Manager tokens found in agent deployment configs
  • Example: curl -H "Authorization: Bearer service:abc123..." https://agents.ciris.ai/api/agent-id/v1/system/health

Repository Structure

CIRISAgent/
β”œβ”€β”€ ciris_engine/         # Core engine
β”‚   β”œβ”€β”€ logic/           # Business logic
β”‚   β”œβ”€β”€ schemas/         # Pydantic models
β”‚   └── protocols/       # Service interfaces
β”œβ”€β”€ FSD/                 # Functional specifications
β”œβ”€β”€ tools/               # Development tools
└── tests/               # Test suite

Separate Repositories (LIABILITY ISOLATION)

CIRISMedical/            # PRIVATE - Medical implementation
└── NO medical code in main repo

Debugging Best Practices

The Golden Rule

ALWAYS check incidents_latest.log FIRST:

docker exec container tail -n 100 /app/logs/incidents_latest.log

Debug Workflow

  1. Check incidents log
  2. Use debug_tools.py for traces
  3. Verify with audit trail
  4. Test incrementally

Common Issues & Solutions

Issue Solution
Dict[str, Any] error Schema already exists - search for it
CI failing Wait for CI to complete, check SonarCloud
OAuth not working Check callback URL format
Service not found Check ServiceRegistry capabilities
WA deferral failing Check WiseBus broadcast logic

Command Timeouts

Long-running commands may need timeout parameters for CI operations and comprehensive test runs.

Important Reminders

  1. OAuth Format: /v1/auth/oauth/{agent_id}/{provider}/callback
  2. Default Auth: Set via setup wizard (QA runner uses admin/qa_test_password_12345)
  3. Service Count: 22 core services (complete, don't add more)
  4. No Service Creates Services: Only ServiceInitializer
  5. Version After Changes: Always bump version
  6. Medical Prohibition: Zero medical code in main repo
  7. Check Existing Schemas: They already exist
  8. NEVER PUSH DIRECTLY TO MAIN: Always create a branch, bump version, NO merge to main without explicit permission

Quality Standards

  • Type Safety: Minimal Dict[str, Any] usage
  • Test Coverage: Target 80%
  • Response Time: <1s API responses
  • Memory: 4GB RAM maximum
  • Security: Ed25519 signatures throughout

Getting Help


Remember: The schema you're about to create already exists. Search for it first.