All notable changes to Sandbar are documented in this file. Format informed by Keep a Changelog; versioning follows Semantic Versioning at and after 0.1.0.
First public release of Sandbar. Foundational substrate: metacircular RDFS-style metamodel on Datomic, the codec layer, the bidirectional projection primitive, the workflow substrate, the MCP server, and the comprehensive four-axis retrieval surface (search / aggregate / navigate / orient).
:dt/Class, :dt/Property, :dt/subclass-of, :dt/type, :dt/domain, :dt/range — the type system describes itself. Lineage: RDFS 1.1 (Brickley & Guha 2014) + KL-ONE / frames (Brachman & Schmolze 1985) + CLOS metaobject protocol (Kiczales et al 1991) + Datomic schema-on-read (Hickey 2012-present).dt/* API — class introspection (dt/all-classes, dt/all-instances-of, dt/slots-of, dt/instance-of?, dt/ancestors-of, dt/subclasses-of), property introspection (dt/domain-of, dt/range-of, dt/cardinality-of), entity construction (dt/make), validation (dt/validate). Explicit *-ident-of / *-entity-of helper split — return-shape exposed in fn names./api/* — schema / class / property / entity / workflow / event / job / status endpoints; mirrors the MCP surface for HTTP consumers.mm/Section chunking + SIOC-pairwise sibling-chain navigation.Search axis (sandbar.search):
dt/search-fulltext — single-attribute Lucene-backed search via Datomic :db/fulltextdt/bm25f-weights-of / dt/fulltext-indexed? — substrate primitivessandbar.search/search-attribute — single-field BM25 opts-shaped wrappersandbar.search/search-bm25f — canonical Robertson-Zaragoza BM25F multi-field weighted scoring, ported byte-for-byte from the corpus reference implementationsandbar.search.analysis — Unicode-aware tokenizer + Porter stemmer (Porter 1980); ported from corpus:dt/bm25f-weights declaration at schema layer; metamodel-driven analyzer:include [:snippets :scores :facets] projection options; :where Datalog composition; :facet-by aggregationAggregation axis (sandbar.aggregate):
dt/count-of / dt/group-by-of substrate primitivesdt/degree-of / dt/backlink-density-of / dt/recency-rank-of / dt/freshness-rank-of — the four structural-rank axessandbar.aggregate.count-by / .group-by / .rank-by opts-shaped wrapperssandbar.aggregate.count / .group-by / .rank-byGET /api/aggregate/count / /group-by / /rank-byNavigation axis (sandbar.navigate):
sandbar.navigate.edges — dt/inbound-edges-of / dt/outbound-edges-of substrate + opts-shaped wrapperssandbar.navigate.walk — BFS reachable-neighborhood walk with hop-cap + direction + path projection; per decisions/sandbar_graph_walk_clojure_bfs_over_datomic_recursive_rules_2026_05_14.md (corpus-side) — Clojure-side iterative BFS chosen over Datomic recursive rules for hop-cap semantics + path tracking + shortest-path guaranteessandbar.navigate.siblings — same-directory peers via caller-supplied path-slotsandbar.navigate.path — Wilbur-lineage path-grammar; Kleene-algebra-over-binary-relations; 13 of 21 operators executable today (Canonical-8 + Tier-2: :SEQ / :OR / :REP+ / :REP* / :INV / :SELF / :RESTRICT / :ANY / :NOT / :OPT / :REP bounded / :FILTER / :TEST); Tier-3 (:LANG / :VALUE / :DAEMON / :NOREWRITE / :MEMBERS / :PREDICATE-OF-*) vocabulary-registered, compilation deferredsandbar.navigate.path.{ast,ir,datomic,value}): EDN parser + algebraic-identity rewriter + Datomic compiler + path-as-first-class-value abstractionlength / prefix? / suffix? / subpath? / extend-path / concat-paths / reversesandbar.navigate.path-via / .siblings-ofGET /api/navigate/path / /siblingsOrientation axis (sandbar.orient):
dt/library-card-of substrate primitive — multi-axis typed-edge composition with caller-supplied axis-specs (class-agnostic per decisions/sandbar_phase_o_substrate_quality_scope_library_card_only_2026_05_14.md)sandbar.orient.library-card opts-shaped wrappersandbar.orient.library-card; REST endpoint GET /api/orient/library-cardarc-forest / ready-queue / session-state / index-snapshot defer to consumer layer (corpus-specific orchestration; would violate substrate-quality discipline at the Sandbar layer)sandbar.codec) — modular extensible codecs (markdown + JSON; TTL + EDN/TTL-hybrid follow post-0.1.0); per-class :dt/native-codec declaration; consumer-native representation disciplinesandbar.projection (renamed from sandbar.project-graph per Dan-directive 2026-05-14) — bidirectional project-graph / ingest-graph per James Anderson's de.setf.rdf:project-graph lineage; DB-state ↔ filesystem-hierarchy projection with :filter partition flexibility for hybrid FS/DB experimentationsandbar.entity-ref namespace — canonical boundary abstraction for entity-reference resolution across MCP / REST / in-process boundaries. Accepts keyword ident / prefixed-string / unprefixed-string / numeric-string / integer eid / entity map; returns canonical entity map (resolve) or ident keyword (resolve-ident); produces structured ex-info with :reasons #{} set-arity envelope (:entity-ref/malformed-input / :entity-ref/not-found / :entity-ref/lookup-vector-unsupported / :entity-ref/no-ident) for rejected inputs. Predicate-style validate returns {:valid? :entity :reasons :message} without raising. Resolves the F-MF-3 codex finding (integer eid AssertionError escape from the MCP error envelope) per the corpus-side ADR at decisions/sandbar_entity_ref_abstraction_2026_05_14.md.sandbar.util.jsonrpc-status namespace — semantic named constants for JSON-RPC 2.0 + MCP error codes (parallel to sandbar.util.http-status); eliminates opaque negative-integer literals (-32603 etc.) at boundary surfaces per corpus-side ADR at decisions/sandbar_jsonrpc_status_semantic_constants_namespace_2026_05_14.md.handle-call catch widening — MCP's tools/call dispatcher catches AssertionError + Exception separately (not Throwable — preserves JVM-error propagation discipline for OutOfMemoryError / StackOverflowError / etc.); residual precondition failures project to structured JSON-RPC internal-error envelope rather than escaping the boundary.class-arg / property-arg / workflow-arg) stay DB-independent (testable without fixture); handlers call eref/resolve / eref/resolve-ident directly on ref args where validation matters. Architectural distinction documented at corpus-side observations/sandbar_entity_ref_shape_helpers_vs_handler_validation_2026_05_14.md.:workflow/terminal-kind classification (:success / :failure / :cancel)task-id IS :db/id (no parallel registry):cancel-terminal statesdecisions/datomic_primary_backend_elevation_2026_05_11.md corpus-side) — Apache-2.0 license, native Lucene :db/fulltext, schema-as-data, time-as-first-classprojection rename — top-level Sandbar namespaces should read unambiguously as nouns; project-graph / ingest-graph function names preserved as verbs at call siteTwo parallel review-driven remediation arcs closed before 0.1.0 tag, joint-gating the release per plans/sandbar_fulltext_search_substrate_arc_2026_05_13.md:
Phase R (codex --effort xhigh review remediation; 9 findings across 9 stages) closed across two days:
sandbar.entity-ref boundary abstraction + 11 MCP handler migrations + REST handler db/entity → eref/validate migration + Pedestal entity-ref-error-interceptor projecting structured ex-info to HTTP 400 / 404 + handle-call catch widening (AssertionError + Exception separately) + ref-arg :pre drops at navigate/orient surfaces.:ANY path-grammar operator constrained to ref-typed attributes in the compiler (compile-any emits [?pred :db/valueType :db.type/ref] guard); restores the typed-edge algebra invariant. Adversarial tests at compiler / wrapper / REST / MCP layers.dt/degree-of inverse-row destructure fix — aligned :find ?a ?s so the shared match? predicate destructures the attribute correctly under :direction :inverse / :bidirectional with :predicates filter (pre-fix silently returned 0).log-error! stacktrace capture without stderr leak — replaced (with-out-str (.printStackTrace ex)) with PrintWriter/StringWriter capture; the stacktrace lands in :event/stacktrace data field and stderr stays clean.search-bm25f docstring narrowed to bag-of-words contract; search-attribute distinguished as the Lucene-query-syntax surface. Pinned-difference contract tests prevent future docstring drift.bench/sandbar/bench/ namespace tree (harness + synthetic-graph factory + orchestrator) + lein bench alias + doc/BENCH.md discipline + initial bench-results/baseline.edn (10/100/1k/10k ladder). Phase 3 (optimization) deferred post-0.1.0 per triage decision D-2.sandbar.navigate.path.evaluate namespace (Clojure-side BFS IR evaluator over all 8 Canonical-8 operators with frontier-as-map + Policy A first-arrival + path.value substrate); :include #{:paths} surface now populates real path data through wrapper + REST + MCP layers (:path-data-deferred placeholder permanently dropped).lein test green + namespace-load smoke + F-SF-3 audit + CHANGELOG entry + version + gpg-key verification.Phase U (parallel ultrareview remediation; 13 findings) — closed via:
lein uberjar packaging via JarURLConnection dispatchdt/codec-aliases-of + dt/range-of); no hardcoded consumer-class table2025-11-25)tasks/list dispatch entry registered; new workflow/list-processes + workflow/list-active-processes substrate primitives:db/* / :db.* / :mm.memory/rel-path from both markdown and JSON wire formatsBearer, bearer, BEARER, BeArEr all accepted)search/where-matching-eids boundary :pre guard replaces opaque deep-Datalog failure with structured AssertionErrorserver-info version aligned to project.clj (0.1.0)sandbar.navigate.path.datomic dedupes structurally-identical recursive rules across nested REP / OR / SEQ compositionssplit-frontmatter reads regex match position via re-matcher (handles --- recurring inside body)publish! detects closed-channel return + evicts dead subscribers from the registry; bounded across connect-disconnect cyclesdoc/guides/sandbar-as-substrate.md Configuration section reconciled to actual config.edn schema (:db {:url :sid} / :nrepl {:port} nested shape)Cumulative test delta from the remediation arcs: net +78 tests / +245 assertions over the start-of-2026-05-14 baseline (+38/+83 through Phase U closure end-of-2026-05-14; additional +40/+162 through Phase R Stages R-2/R-3/R-4/R-5/R-7 by end-of-2026-05-15).
:db/* regression guards (Phase U Stage U-2)sandbar.mcp.tools-db-test — DB-backed handler-dispatch acceptance suite (sibling to the shape-only tools-test): F-MF-3 verbatim falsification calls (integer eid + bogus ref + lookup-vector) + 5-shape roundtrip (keyword / prefixed-string / unprefixed-string / integer eid / entity-map) for the F-MF-3 surfaces (path-via + library-card) + per-handler error-projection sanity for every migrated handler family (Navigate/Orient + Entity + Aggregate + Type-predicates)project.clj for Clojars publicationThe substrate draws deliberately from settled algebras + decades-old design traditions:
de.setf.rdf (James Anderson; Datagraph/Dydra-era) — project-graph boundary-layer primitiveCan you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |