This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
- You can see CLJS compile status (warnings/errors, as well as completion) using
src/dev/shadow_cljs_checker.clj - Shadow-cljs will usually be running already, as will a Clojure REPL, use clojure-mcp to access REPLs for these
- ALWAYS run CLJ tests with guardrails enforcing mode locally before declaring tests pass. The CI workflow (
.github/workflows/tests.yml) runs kaocha with-J-Dguardrails.enabled=true -J-Dguardrails.config=guardrails-test.edn, which catches spec violations a plainkaocha.repl/runwill miss. To match CI from the shell:clojure -J-Dguardrails.enabled=true -J-Dguardrails.config=guardrails-test.edn -M:dev:test -e "(require '[kaocha.repl :as k]) (k/run 'your.ns-spec)"Plainkaocha.repl/runcalls without those-Jflags are NOT sufficient — they silently bypass guardrails and let bad calls through. CI will reject what your local run accepted.
The docs/ai/ directory contains comprehensive reference material for AI assistants:
Testing Guides:
writing-tests.md- Complete guide to writing tests with Fulcro Spec (assertions, mocking, spying, error handling)running-tests.md- How to run tests via REPL using Kaocha
Clojure Tooling:
clojure-library-source-and-documentation.md- Usingclojure.repl/docandclojure.repl/sourceto access library documentation
Fulcro Framework Documentation: Since this library integrates with Fulcro for visualization and UI state management, these docs cover:
02-fulcro-overview.md- Fulcro philosophy, graph-centric design, architecture comparison03-core-concepts.md- Immutability, pure rendering, data-driven architecture, graph database structure04-getting-started.md- Project setup, component anatomy, data flow basics06-data-loading.md- Loading patterns, targeting, load markers, error handling07-core-api.md- Core functions:db->tree,tree->db, normalization, denormalization08-components-and-rendering.md- Component definition withdefsc, DOM factories, lifecycle methods09-server-interactions.md- Server setup, Pathom resolvers, mutations, error handling18-eql-query-language.md- EQL syntax: properties, joins, unions, mutations, recursive queries20-normalization.md- How normalization works, idents, graph structure, merge operations21-full-stack-operation.md- Full-stack patterns, targeting rules, server integration, user-triggered loading
When to Reference These Docs:
- Writing or debugging tests →
writing-tests.md,running-tests.md - Working with Fulcro integration code in
integration/fulcro*.cljc→ Fulcro docs - Understanding visualization UI → Fulcro component and rendering docs
- Need library docs/source →
clojure-library-source-and-documentation.md
This is a Clojure/ClojureScript (CLJC) implementation of SCXML-compliant state charts. The library follows the W3C 2015-09-01 SCXML recommendation for state chart semantics and processing algorithms, but uses Clojure data structures instead of XML.
Key Characteristics:
- Production-ready, API-stable library
- Cross-platform (CLJ/CLJS) with .cljc files
- Protocol-based, highly extensible architecture
- Supports distributed systems via serializable working memory
- MIT licensed
make docs/index.html
# Generates HTML from Guide.adoc using asciidoctorThe project uses deps.edn with several aliases. Start a REPL with:
clojure -A:dev:testShadow-cljs nREPL runs on port 9000 (configured in shadow-cljs.edn).
The library uses protocol-based extensibility around 7 core components. Each major subsystem has its own CLAUDE.md with deep-dive details:
- Processor — SCXML algorithm (see
algorithms/CLAUDE.md) - DataModel — Data storage/retrieval (see
data_model/CLAUDE.md) - ExecutionModel — Expression interpretation (
execution_model/lambda.cljc) - EventQueue — Event delivery (see
event_queue/CLAUDE.md) - WorkingMemoryStore — Session persistence (
working_memory_store/) - StatechartRegistry — Chart definitions (
registry/) - InvocationProcessors — External service invocation (see
invocation/CLAUDE.md)
For Fulcro integration, see integration/CLAUDE.md. The routing/ sub-package under integration/fulcro/ provides the new routing system with URL sync, cross-chart routing, and configuration validation (replaces the deprecated ui-routes namespace).
Internally uses imperative style with volatiles (matching W3C pseudocode); externally exposes a functional interface.
Charts are nested maps processed in document order (depth-first by default, configurable to breadth-first via ::sc/document-order).
Element types:
statechart- Root containerstate- Atomic or compound stateparallel- Parallel state (all regions active)transition- Event-driven or eventless transitionsinitial,final,history- Special state typeson-entry,on-exit- Entry/exit handlersinvoke- Start external services/charts- Executable content:
script,assign,send,raise,log,cancel
Chart example pattern:
(statechart {:initial :start}
(state {:id :start}
(on-entry {} (script {:expr (fn [env data] ...)}))
(transition {:event :next :target :end}))
(final {:id :end}))- Working Memory: Serializable EDN map containing configuration (active states) and data model state
- Session: Running instance of a chart, identified by unique session-id
- Session ID: Used for event routing, persistence, and cross-chart communication
Use element functions from com.fulcrologic.statecharts.elements:
(require '[com.fulcrologic.statecharts.chart :as chart]
'[com.fulcrologic.statecharts.elements :refer [state transition script]])Convenience helpers (convenience.cljc, convenience-macros.cljc) simplify common patterns:
(on :event :target-state ...)instead of verbose transition(choice {...} pred1 :state1 pred2 :state2 :else :default)for condition nodes(send-after {...})for delayed events with auto-cancel on exit
Use com.fulcrologic.statecharts.testing namespace:
new-testing-env- Creates test environment with mock execution modelgoto-configuration!- Jump to specific state for test setupconfiguration-for-states- Calculate full configuration from leaf statesrun-events!- Process events and inspect results- Mock expressions by providing
{pred-fn true, script-fn (fn [env] ...)}map
Special features when integrating with Fulcro apps:
- Actors: Map UI components to state chart data paths (
:actor/thing) - Aliases: Named paths to data (
:fulcro/aliases) - Operations:
fop/load,fop/invoke-remotefor I/O - Hooks:
use-statechartfor component-local charts
The codebase uses Fulcrologic Guardrails for spec checking. When running tests or development, guardrails must be enabled:
-J-Dguardrails.enabled=true -J-Dguardrails.config=guardrails-test.edn
Any deviation from SCXML standard behavior (transitions, entry/exit order, etc.) is considered a bug. Bugfixes may change behavior if code relied on incorrect semantics.
Not implemented:
- Flow control executable content (if/else/foreach) - but extensible via multimethods
- Complete SCXML test suite coverage
- Most files are
.cljcfor portability invocation/future.cljis CLJ-only- CLJS builds use Shadow-cljs
- Browser tests run via Karma + Chrome
- Document order matters: State IDs must be unique, transitions are checked in order
- Working memory is immutable: Each event processing returns new working memory
- Session IDs are global: Restarting with existing ID overwrites the session
- History nodes have strict rules: Shallow history requires exactly one target, see
chart.cljc:invalid-history-elements - Executable content is data: Functions, not code - allows for serialization strategies
Specs and project tracking live in docs/ai/specs/:
TRACKER.md— Single source of truth for project statusWORKFLOW.md— Agent-centric conductor pattern guide- Individual spec files — One per feature/bug/improvement
Subdirectory CLAUDE.md files provide targeted context:
algorithms/CLAUDE.md— W3C SCXML algorithm detailsdata_model/CLAUDE.md— Data flow and operationsevent_queue/CLAUDE.md— Event delivery mechanismsintegration/CLAUDE.md— Fulcro integration patternsinvocation/CLAUDE.md— External service invocation
Update subdirectory CLAUDEs when discovering gotchas. Keep them under 50 lines. Detail goes in the closest module CLAUDE.md; root stays cross-cutting.
com.fulcrologic/guardrails- Spec validationmetosin/malli- Schema validationorg.clojure/core.async- Event loopsorg.eclipse.elk/*- Graph layout for visualizationcom.fulcrologic/fulcro(optional, dev only) - Framework integration