# Backseat Driver Internals

> Backseat Driver extension internals — Ex framework contracts, app-db state architecture, MCP socket server lifecycle, enrichment system, Datascript output log, activation sequences, and namespace reference. Use when: modifying core extension code, debugging state issues, working with app-db or Ex framework, understanding activation or MCP server flow, investigating enrichment or Datascript connections, or working with tool registration.

- Skill: `betterthantomorrow/backseat-driver-internals` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add betterthantomorrow/backseat-driver-internals`
- Raw SKILL.md: https://api.skillmd.com/api/skills/betterthantomorrow/backseat-driver-internals/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: betterthantomorrow (https://skillmd.com/u/betterthantomorrow)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/betterthantomorrow/backseat-driver-internals

---


# Backseat Driver Extension Internals

Subsystem contracts, state architecture, and temporal sequences for the Backseat Driver extension.

## Key Namespaces

| Namespace | Purpose |
|---|---|
| `ex.ex` | Dispatcher — the only entry point for state changes |
| `ex.ax` | Action routing, enrichment, accumulation |
| `ex.fx` | Effect routing (context-enriched before domain dispatch) |
| `app.db` | `!app-db` atom, `!output-conn` & `!history-conn` Datascript, serialization |
| `app.axs` | App lifecycle actions (activate, init, commands, cleanup) |
| `app.fxs` | App effects (logging, command registration, Language Model tools) |
| `db.axs` | Generic state mutation actions (`assoc-in`, `update-in`) |
| `mcp.axs` | MCP server lifecycle actions (start/stop/error/handle-request) |
| `mcp.fxs` | MCP effects (start/stop server, notifications, request handling, wrapper copy) |
| `mcp.server` | TCP socket server implementation (low-level net, port file, buffering) |
| `mcp.requests` | MCP protocol handler — tool listings, initialize, tools/call dispatch |
| `mcp.skills` | Skill frontmatter parsing, filtering, instruction composition |
| `mcp.logging` | MCP server log output |
| `extension` | VS Code activate/deactivate entry points |
| `integrations.calva.api` | Calva API access (REPL eval, ranges, editor, document, info) |
| `integrations.calva.editor` | Structural editing implementation |
| `integrations.calva.editor-util` | File context formatting (line-numbered windows) |
| `integrations.vscode.tools` | VS Code Language Model tool registration |
| `integrations.parinfer` | Bracket balancing via Parinfer |
| `stdio.wrapper` | MCP stdio-to-socket relay (`dist/calva-mcp-server.js`) |

## Subsystem Contracts

```
λ app_db_contract.
  db/!app-db ≡ atom {
    :vscode/extension-context    ExtensionContext     ;; set before dispatch, circular refs
    :app/getConfiguration        fn                   ;; VS Code config reader

    ;; From init-db
    :extension/disposables       [Disposable]         ;; VS Code subscriptions
    :extension/when-contexts     {:calva-mcp-extension/activated? bool
                                  :calva-backseat-driver/started? bool
                                  :calva-backseat-driver/starting? bool
                                  :calva-backseat-driver/stopping? bool}
    :calva/output-line-counter   int                  ;; monotonic for output entities

    ;; From initial-state (extension.cljs)
    :app/log-file-uri            Uri                  ;; log location
    :app/min-log-level           keyword              ;; :debug/:info/:warn/:error
    :mcp/wrapper-config-path     string               ;; ~/.config/calva/backseat-driver
    :calva/history-storage-uri   Uri|nil              ;; eval-history.transit.json

    ;; Runtime
    :app/log-dir-initialized+    promise              ;; resolved when log dir exists
    :app/server-info             {:server/instance Server
                                  :server/port int
                                  :server/port-file-uri Uri
                                  :server/port-note string?}
  }
  | inspection: always(dissoc :vscode/extension-context) | circular_ref_guard
  | mutation: only_through_dispatch! | ¬direct_swap!

λ ex_dispatcher_contract.
  dispatch!(context, actions) ≡ the_only_state_entry_point
  | ~16 lines of code | the entire framework
  |
  | flow:
  |   ax/handle-actions(@!app-db, context, actions)
  |     reduce_over_actions:
  |       1. enrich-from-context(action, context)    → :context/x.y → js-get-in
  |       2. enrich-from-state(action, state)        → [:db/get k], :vscode/config.x
  |       3. route_by(namespace action-kw) → domain_handler
  |       4. handler_returns {:ex/db, :ex/fxs, :ex/dxs}
  |     accumulate: merge_db, into_fxs(enriched_from_state), into_dxs
  |   when db → reset!(!app-db)
  |   when dxs → recursive dispatch!(context, dxs)
  |   when fxs → for_each: enrich_from_context → route → execute

λ enrichment_contract.
  context_enrichment:
    :context/x.y.z → js-get-in(context, ["x" "y" "z"])
    | applied_to: actions ∧ effects
  state_enrichment:
    [:db/get key] → (get state key)
    :vscode/config.settingName → VS Code configuration API
    | applied_to: actions_only (effects get context enrichment only)
  args_enrichment:
    :ex/action-args → entire_result_from_effect
    :ex/action-args%N → (nth result (dec N))
    | applied_to: continuation_actions_via :ex/then

λ action_routing.
  (namespace action-kw) → handler_namespace:
    "app"      → app.axs
    "mcp"      → mcp.axs
    "db"       → db.axs
    "vscode"   → integrations.vscode (via axs)
    "node"     → integrations.node (via axs)
    "calva"    → integrations.calva (via axs)
  | new_domain → add_case_in ex/ax.cljs handle-action

λ effect_routing.
  (namespace fx-kw) → handler_namespace:
    "app"      → app.fxs
    "mcp"      → mcp.fxs
    "vscode"   → integrations.vscode (via fxs)
    "node"     → integrations.node (via fxs)
    "calva"    → integrations.calva (via fxs)
  | effects_receive(dispatch!, context, enriched-fx)
  | new_domain → add_case_in ex/fx.cljs perform-effect!

λ datascript_contract.
  !output-conn ≡ session_scoped | schemaless | cap: 1000 entities
    | all_output_categories: evaluationResults, evaluatedCode, evaluationOutput,
    |   evaluationErrorOutput, otherOutput, otherErrorOutput
  !history-conn ≡ persistent | schema: {:output/line {:db/unique :db.unique/identity}}
    | cap: 10000 | evaluatedCode_only
    | serialized_to: eval-history.transit.json | cognitect.transit JSON
    | format: {:format-version 1 :entities [...]}
  entity_attributes:
    :output/line        int (monotonic, from :calva/output-line-counter)
    :output/category    string
    :output/text        string
    :output/who         string?
    :output/timestamp   inst
    :output/ns          string?
    :output/repl-session-key string?

λ mcp_server_contract.
  socket_server: TCP | net.createServer | localhost_only
  | port: configured(default 1664) | 0 ≡ random | EADDRINUSE → fallback_to_0
  | port_file: ${workspaceFolder}/.calva/mcp-server/port
  | protocol: newline_delimited_JSON | buffered_partial_reads
  | active_sockets: atom | tracks_connected_clients
  | notifications: broadcast_to_all_active_sockets

  stdio_wrapper: dist/calva-mcp-server.js
  | reads_port_from_port_file → TCP_connect → relay(stdio ↔ socket)
  | one_server_per_workspace_folder

λ calva_api_contract.
  calva-api ≡ {
    :repl     {:evaluateCode, :currentSessionKey, :onOutputLogged}
    :ranges   {:currentTopLevelForm, :currentEnclosingForm, ...}
    :editor   {:replace}
    :document {:getNamespace, :getNamespaceAndNsForm}
    :info     {:getSymbolInfo, :getClojureDocsDotOrg}
  }
  | accessed_at: integrations.calva.api/calva-api
  | capability_gated: tools_appear_disappear_based_on_calva_support

λ structural_editing_contract.
  editing_unit ≡ top_level_form | ¬lines_of_text
  | parinfer: bracket_balancing | integrations/parinfer.cljs
  | targeting: targetLineText + line ±2 scan_window
  | rich_comments: forms_inside(comment ...) ≡ top_level
  | diagnostic_context: 21_line_window | line_numbers | → arrow_marker
  | bottom_to_top: multiple_edits_highest_line_first
```

## Temporal Sequences

```
λ activation_sequence.
  1_vscode_calls: extension.activate(context) | entry_point
  2_store_context: assoc(:vscode/extension-context) into !app-db | before_dispatch
  3_store_config_reader: assoc(:app/getConfiguration) | vscode/workspace.getConfiguration
  4_dispatch_activate: [:app/ax.activate (initial-state context)]
  5_ax.activate: merge(init-db, initial-state) | set when-contexts | dispatch ax.init
  6_ax.init: register_commands ∧ language_model_tools | init_output_listener
  7_fx.init-logging: ensure_log_directory | resolve(:app/log-dir-initialized+)
  8_fx.copy-wrapper-script: copy(calva-mcp-server.js) to(~/.config/calva/backseat-driver/)
  9_auto_start_check: if(:vscode/config.autoStartMCPServer) → dispatch(ax.start-server)
  | skip(2) → enrichment_fails | context_not_available
  | skip(8) → stdio_wrapper_missing | MCP_clients_cant_connect

λ mcp_server_lifecycle.
  start:
    1_dispatch: [:mcp/ax.start-server]
    2_set_starting: when-context(starting? → true, stopping? → false)
    3_fx.start-server → server/start-server!+
      3a_create_server: net.createServer(TCP)
      3b_listen: configured_port | EADDRINUSE → port_0
      3c_write_port_file: .calva/mcp-server/port
    4_ax.server-started: store(:app/server-info) | when-context(started? → true, starting? → false)
    5_fx.show-server-started-message: info_notification_with_port

  client_connection:
    1_socket_connects: stdio_wrapper → TCP_connect(port)
    2_data_handler: UTF-8 | buffer → split(\n) → parse_JSON
    3_dispatch: [:mcp/ax.handle-request parsed-message]
    4_fx.handle-request → requests/handle-request-fn
    5_response: write_JSON\n_to_socket

  stop:
    1_dispatch: [:mcp/ax.stop-server]
    2_set_stopping: when-context(stopping? → true)
    3_fx.stop-server → server/stop-server!+
      3a_end_sockets: end+destroy_all_active_sockets
      3b_close_server: server.close()
      3c_delete_port_file: vscode_workspace.fs | node_fs_fallback
    4_ax.server-stopped: clear(:app/server-info) | when-context(started? → false, stopping? → false)

λ mcp_request_flow.
  initialize → {:protocolVersion "2024-11-05", :capabilities, :instructions (compose-instructions)}
  tools/list → read(package.json languageModelTools) → transform_to_mcp_format | capability_filtered
  tools/call → multimethod(handle-tool-call) by(:name) → {:content [{:type :text :text result}]}
  resources/list → skill_manifests | filtered_by_settings
  resources/read → read(assets/skills/{name}/SKILL.md) | full_content

λ tool_registration_sequence.
  1_package_json: languageModelTools manifest (name, description, inputSchema, when-clause)
  2_activation: ax.register-language-model-tools → fx.register-language-model-tools
  3_vscode_api: tools.cljs registers with Language Model API
  4_mcp_server: requests.cljs reads same manifests at runtime
  5_capability_gating: tools conditionally available based on Calva version + settings
  | single_source_of_truth: package.json | change_once → applied_everywhere

λ hot_reload_sequence.
  1_edit_source: modify .cljs file | save
  2_shadow_detects: file_watcher → incremental_compile
  3_compile: cljs → js | check_for_warnings
  4_extension_host: picks_up_changes | ¬restart_needed
  5_verify: re_evaluate_in_repl | require_with_reload
  | zero_warnings_policy: new_warnings_stand_out_only_when_baseline_clean
  | package_json_changes → extension_host_restart_required
```

## Interactive Development Patterns

```clojure
;; Explore runtime state
(in-ns 'calva-backseat-driver.app.db)
(dissoc @!app-db :vscode/extension-context)

;; Test Calva API
(in-ns 'calva-backseat-driver.integrations.calva.api)
(keys (:repl calva-api))

;; Inspect MCP server state
(in-ns 'calva-backseat-driver.mcp.server)
@active-sockets

;; Query output log
(in-ns 'calva-backseat-driver.app.db)
(d/q '[:find ?text :where [?e :output/category "evaluatedCode"] [?e :output/text ?text]] @!output-conn)

;; Test enrichment
(in-ns 'calva-backseat-driver.ex.ax)
(enrich-from-context [:some/ax.test :context/subscriptions] context)
```

## Configuration Settings

| Setting | Type | Default | Purpose |
|---|---|---|---|
| `enableMcpReplEvaluation` | boolean | true | Expose REPL eval via MCP (set `false` to disable) |
| `mcpSocketServerPort` | number | 1664 | Socket server port (0 = random) |
| `autoStartMCPServer` | boolean | false | Start MCP server on activation |
| `provideBdSkill` | boolean | true | Provide Backseat Driver skill via MCP |
| `provideEditSkill` | boolean | true | Provide structural editing skill via MCP |

Settings accessed via enrichment: `:vscode/config.settingName` in action handlers.

