Clawq follows a Coq-first architecture: core properties are machine-checked in Coq, extracted to OCaml, and wrapped by a runtime that provides I/O, networking, and channel integrations.

Build Pipeline

Coq theories → extracted OCaml → runtime libraries → clawq executable

The extracted OCaml is tracked in git so the project builds without Coq installed. Run make extract to regenerate from Coq sources, and make extract-check to verify no drift.

Coq Theories

FileRole
Interfaces.v7 record-based interface definitions: Provider, Channel, Tool, Memory, RuntimeAdapter, Tunnel, Security
Config.vConfiguration records (GatewayConfig, MemoryConfig, SecurityConfig, ClawqConfig) with defaults and validation
Cli.vCommand ADT, parse_command, dispatch, and usage string for 18 commands
Extract.vExtraction directives: type mappings and function list

Extracted OCaml

FileRole
clawq_core.mlAuto-generated OCaml from Coq. Contains command parsing, dispatch, config validation.
clawq_core.mliAuto-generated interface. Both files are tracked in git.

Runtime Module Map

ModuleRole
main.mlCLI entry point and top-level Cmdliner command registration
main_cmd_common.mlShared Cmdliner helpers for command modules
main_audit_cmds.mlCmdliner definitions for clawq audit subcommands
main_background_cmds.mlCmdliner definitions for clawq background and clawq subagents subcommands
main_models_cmds.mlCmdliner definitions for clawq models subcommands
main_plan_cmds.mlCmdliner definitions for clawq plan subcommands
main_session_cmds.mlCmdliner definitions for clawq session subcommands
command_bridge.mlBridges CLI to extracted Coq dispatch; handles runtime-only commands
command_bridge_cron.mlRuntime command bridge implementation for clawq cron
command_bridge_room_ledger.mlRuntime command bridge implementation for clawq rooms ledger
runtime_config_defaults.mlDefault runtime configuration values for all subsystems
runtime_config.mlConfiguration loading, validation, and defaults for all subsystems
config_loader.mlFile-based config loading: reads JSON, merges with env vars
session.mlPublic facade over split session lifecycle modules
session_core.mlSession manager state, queueing, locks, notifier registration, context, and persistence helpers
session_management.mlSession config/model management, reset, compaction, and debug dumps
session_postmortem.mlSession stuck-pattern postmortem circuit breaker and launcher hook
session_postmortem_launcher.mlPostmortem agent launch implementation installed by the turn loop
session_turn.mlShared buffered/streaming session turn orchestration, queue draining, skill injection, and room-policy snapshots
provider.mlLLM provider abstraction: streaming text/thinking/tool events, model selection
memory.mlKey-value memory backend: SQLite-backed store/recall/forget with namespace support and per-session archive files for forgotten memories
vector.mlLocal vector index: embedding storage, cosine similarity, hybrid FTS+vector merge
tool.mlTool type definitions and invocation framework with risk-level enforcement
tool_registry.mlDynamic tool registration: register, lookup, list by name or category
tools_builtin.mlBuilt-in tool implementations: file I/O, shell exec, web fetch, search
agent.mlThin public buffered/streaming turn entry points
agent_turn_core.mlShared agent turn loop, provider-call adapters, streaming emission, and cost tracking
agent_compact_support.mlAgent state, exceptions, token estimates, and compaction preservation helpers
agent_0_compact.mlAgent history compaction, memory flush, and compact-plan execution
agent_memory_context.mlAgent scoped and legacy memory-context injection
agent_2_tools.mlAgent tool-call validation, execution, and tool-result history integration
agent_profile.mlAgent room-profile and scoped-memory helper logic
agent_provider_ledger.mlAgent provider request/error/response room-ledger events
agent_room_budget.mlAgent room-budget guard and reservation helpers
agent_turn_setup.mlAgent construction and turn-history preparation
mcp_server.mlMCP server: exposes tools over JSON-RPC with configurable filtering
skills.mlSkill loader: discovers and loads skill definitions from the filesystem
http_server.mlHTTP server: gateway, SSE chat streaming, pairing, slash-command metadata, and web UI endpoints
ui_server.mlWeb UI asset manager: embedded bundle extraction, dev-mode disk serving, and version hashing
http_client.mlHTTP client: shared Cohttp-lwt client for provider and API calls
telegram.mlTelegram channel update handler and turn dispatch
telegram_attachments.mlTelegram inbound voice, image, and document attachment handling
telegram_rich_notifier.mlTelegram rich message delivery for buttons, polls, and file attachments
discord.mlDiscord channel: WS gateway mode, REST rate limit buckets, reconnect loop
discord_gateway.mlDiscord gateway protocol state machine (Hello, Identify, Resume, Heartbeat, Dispatch)
slack_api.mlSlack Events API parsing, HMAC verification, and Web API helpers
slack.mlSlack event handler
slack_socket.mlSlack Socket Mode: WSS-based event receiving via app_token
teams_webhook.mlMicrosoft Teams webhook orchestration and turn dispatch
teams_attachments.mlMicrosoft Teams inbound audio and file attachment handling
teams_command_cards.mlMicrosoft Teams Adaptive Card slash-command rendering
teams_command_text.mlMicrosoft Teams text-only slash-command reply rendering
teams_debug_dump.mlMicrosoft Teams session debug dump file-consent/download delivery
teams_rich_notifier.mlMicrosoft Teams rich message delivery for Adaptive Cards
ws_client.mlShared TLS WebSocket client (httpun-ws, gluten, tls-lwt, ca-certs)
daemon_config_watch.mlDaemon config-file watcher and live reload loop
daemon_channels.mlNon-Telegram daemon channel startup fanout
daemon_startup.mlDaemon database/schema initialization, room-profile reconciliation, and tool/skill registry bootstrap
daemon_heartbeat.mlPeriodic HEARTBEAT.md processing for opted-in channel sessions
daemon_background_loops.mlAuxiliary model-discovery, search-health, quota-refresh, and subagent-status daemon loops
daemon_runtime_loops.mlDatabase-backed scheduler, repo-fetch, maintenance, and background-task daemon loops
daemon.mlSupervisor: gateway + Telegram lifecycle, signal handling, SIGHUP reload, and EC process lifecycle
provider_quota_state.mlProvider quota state types, cache, persistence, history, and status formatting
provider_quota.mlProvider quota fetchers and provider-specific usage parsers
error_watcher.mlError correction shared types, helpers, and EC process lifecycle management
ec_process.mlEC process entry point: daemon log/session/background-task error scanning, correlation
ec_diagnosis.mlMulti-model diagnosis pipeline: parallel LLM queries, voting, planning, fix spawning
service.mlService orchestrator: starts/stops subsystems (server, tunnel, scheduler)
scheduler_schedule.mlSchedule parsing and cron/interval run matching helpers
scheduler_output_guard.mlCron run output hashing and consecutive-identical-output auto-disable guard
scheduler_routine_target.mlRoutine target display formatting shared by scheduler job and run history views
scheduler.mlScheduled tasks: cron-like recurring job execution
audit.mlAudit logging: append-only log of tool invocations and security events
secret_store.mlSecret encryption at rest: AES-256-GCM, PBKDF2 key derivation, $ENC: prefix format
sql_util.mlShared SQLite plumbing: exec_exn/exec_with_params, bind_params, column accessors, and a query_rows combinator used across store modules
time_util.mlShared ISO-8601/RFC-3339 timestamp formatting (iso8601_utc, iso8601_utc_micros/_millis, sql_datetime_utc, date_utc, iso8601_local), consolidating the hand-rolled Printf.sprintf "%04d-%02d-%02dT…" variants
migrate.mlDatabase migrations: versioned schema upgrades for SQLite stores
resilience.mlReliability policies: timeout, retry (exponential backoff), fallback
runtime_native.mlNative runtime adapter: wraps daemon/service for start/stop/status/health
runtime_docker.mlDocker runtime adapter: manages clawq in containers via docker CLI
tunnel_manager.mlUnified tunnel lifecycle manager: apply/stop/restart, live reconfiguration, daemon hooks
tunnel_cloudflare.mlCloudflare tunnel: manages cloudflared process, extracts assigned URL
rate_limiter.mlToken bucket rate limiter (IP, session, chat)
landlock.mlLandlock OS sandboxing (C FFI)
bg_shell.mlBackground shell job registry and lifecycle (created when shell_exec is interrupted)
tools_bg_shell.mlBackground shell tools: bg_shell_status, bg_shell_wait, bg_shell_result
slash_commands.mlSlash command parsing, dispatch, and per-connector rendering
format_adapter.mlConnector-safe formatting dispatch (markdown tables, code blocks, HTML)
table_format.mlMarkdown and plaintext table rendering
setup_common.mlShared TUI helpers for setup wizards (prompts, ANSI, box drawing)
config_wizard_model.mlConfig wizard state machine types
config_wizard_tui.mlConfig wizard terminal I/O loop
config_wizard_update.mlConfig wizard state transitions
model_discovery.mlAPI-based model catalog discovery (12h TTL cache)
request_stats.mlPer-turn token usage and cost persistence
cost_tracker.mlModel pricing table and cost calculation
runner_framework.mlCommon runner session tracking framework (session ID strategies, command generation)
background_task_spawn.mlBackground task process spawning, worktrees, scheduling, and restart/readoption
background_task_room.mlRoom background task launch and GitHub review launch orchestration
background_task_workflow.mlWorkflow-triggered background task launch orchestration
structured_pipeline_types.mlShared structured-pipeline definition, step, run, and result types
structured_pipeline_builtins.mlBuilt-in structured pipeline catalogue definitions
structured_pipeline.mlStructured pipeline parsing, discovery, persistence, and CLI formatting facade
structured_pipeline_run.mlStructured pipeline execution engine
background_task.mlBackground task public facade over split lifecycle modules
pmodel.mlCanonical provider:model format parsing (strict + flexible), deprecation warnings
stt.mlSpeech-to-text: audio transcription via Whisper-compatible API
voice_transcription.mlShared voice message handling: audio detection, music heuristic, validation, transcribe-with-progress

Dune Libraries

LibraryKey ModulesDependencies
clawq_extractedclawq_coreNone (unwrapped, -w -39 for extraction artifacts)
clawq_runtime_coreConfig, agent, session, provider, memory, tools, audit, security, rate limiter, scheduleryojson, sqlite3, lwt, cohttp-lwt-unix, mirage-crypto, digestif, clawq_extracted
clawq_runtime_integrationsHTTP server, telegram, discord, slack, daemon, MCP, WS client, tunnels, runtimesclawq_runtime_core + httpun-ws-lwt-unix, gluten-lwt-unix, ca-certs
clawq (executable)main_cmd_common, main_audit_cmds, main_background_cmds, main_models_cmds, main_plan_cmds, main_session_cmds, mainclawq_runtime_core, clawq_runtime_integrations, cmdliner

Both libraries use (wrapped false) so modules are accessible directly (e.g., Clawq_core.dispatch rather than Clawq_extracted.Clawq_core.dispatch).

Interface Inventory

From Interfaces.v, these 7 records define the contract surface:

InterfaceFieldsPurpose
Providername, complete, healthLLM provider abstraction
Channelname, start, stop, sendCommunication channel (web, telegram, etc.)
Toolname, invoke, risk_levelAgent tool with risk classification
Memorystore, recall, forgetKey-value memory backend
RuntimeAdaptername, start, stopRuntime lifecycle management
Tunnelname, start, statusNetwork tunnel (e.g., Cloudflare)
Securityworkspace_only, audit_enabled, encrypt_secretsSecurity policy flags

Dependency Direction

Coq theory dependency order
OCaml library dependency order

Runtime Split

The runtime is split into core and integrations to support a minimal build (clawq-min) that excludes network dependencies:

  1. Optional integrations stay out of clawq_runtime_core
  2. Network/server features belong in clawq_runtime_integrations
  3. Integration-only commands return “disabled in minimal build” messages in command_bridge_min.ml
  4. New dependencies are evaluated for core vs integration placement before linking

Web UI Surface

The browser chat UI is embedded into the daemon and served from the gateway root.

  • GET / serves index.html plus versioned chat.js and chat.css assets.
  • POST /chat/stream emits SSE events for reply deltas, thinking deltas, tool starts, streamed tool output, tool results, and final completion.
  • GET /commands exposes slash-command metadata for autocomplete.
  • GET /ui-version returns the current UI bundle version so the client can offer a reload banner.
  • POST /pair exchanges a 6-digit OTP for a bearer token when gateway pairing is enabled.

In normal mode the daemon extracts embedded assets into ~/.clawq/ui/ when the bundle hash changes. If ~/.clawq/ui/DEV exists, the daemon switches to disk-backed dev mode and recomputes the UI version from local files instead of overwriting them.