All notable changes to the Boundary Framework will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
boundary-devtools — DX Vision: 6-phase developer experience overhaulBND-*) with structured messages, ADRs for devtools guidance engine, REPL command center, dev dashboard, error experience, and progressive learning (ADR-024 through ADR-029).boundary.devtools.core.introspection), schema exploration (schema-tools), documentation lookup (documentation), and guidance engine (guidance). REPL namespace (boundary.devtools.shell.repl) with unified API.boundary.devtools.core.auto_fix), stacktrace parser, FC/IS checker, HTTP error middleware, and REPL error handler.localhost:9090) with pages for system overview, routes, schemas, database, errors, requests, and docs. Hiccup-rendered with custom CSS, served via Ring.boundary.devtools.core.recording), route testing (router), and rapid prototyping (prototype). Shell adapters for file-based recording persistence and route simulation.boundary-ai — REPL AI integration (Phase 6)explain-code, suggest-refactor, generate-docs in boundary.ai.shell.repl.boundary.ai.core.prompts.boundary-cache — LRU eviction bug (#137)boundary.cache.shell.adapters.in_memory to correctly identify the least-recently-used entry when multiple entries share the same timestamp.boundary-tools — BOU-15 deprecated wrapper usage scanner (BOU-15):refer'd deprecated symbols: normalize-require-spec now extracts :refer [sym ...] vectors alongside :as aliases. A new extract-referred-symbols function maps directly referred symbol names to their source namespace. find-qualified-call-sites runs a second regex pass for bare (symbol ...) call sites, so usage like (:require [boundary.search.core.index :refer [build-document]]) is no longer silently missed.find-qualified-call-sites now unconditionally searches for (namespace/symbol ...) patterns regardless of whether the file has an alias or :refer entry. Calls like (boundary.search.core.index/build-document ...) are now correctly reported.ci — E2E job disablede2e CI job with if: false to reduce pipeline run time. Tests can be run manually when needed.boundary-tools into libs/tools/ to follow monorepo convention. Removed redundant top-level boundary-tools/ directory.boundary-e2e — Admin UI end-to-end test suite (BOU-10)boundary.e2e.helpers.admin) with login-as-admin!, login-as-user!, two-phase HTMX settle waiting (install-htmx-settle-listener! / await-htmx-settle!), and table/form query utilities.with-fresh-seed fixture for isolated H2 state per test.platform — Compile-time PostgreSQL class references(:import [org.postgresql.util PGobject]) and (instance? org.postgresql.util.PSQLException ...) from boundary.user.shell.service, boundary.tenant.shell.persistence, and boundary.tenant.shell.invite-persistence. Replaced with runtime class name checks so the REPL starts without the :db alias on the classpath.admin — Table view UX improvementsadmin — Compact table view layoutadmin — Collapsible sidebaradmin-ux.js to comply with Content Security Policy.admin-ux.js now loads before alpine.min.js so the sidebar store is registered before Alpine initializes.boundary-e2e — end-to-end test suite for login sequence/web/login, /web/register, and /api/v1/auth/* — browser automation + API testing via spel (Playwright Java wrapper). No Node.js/npm/TypeScript introduced.libs/e2e/ with com.blockether/spel dependency, isolated behind opt-in :e2e alias — normal clojure -M:test runs are unaffected.bb e2e: orchestrator task that starts the app in :test profile on port 3100, runs the kaocha :e2e suite, and tears down the server.bb run-e2e-server: standalone task for manual debugging against the test-profile server.POST /test/reset endpoint (behind :test/reset-endpoint-enabled? config flag) that truncates H2 and re-seeds baseline tenant/users via production services. Guarded by startup assertion (throws in prod/acc) and bb doctor check.:e2e suite in tests.e2e.edn with ^:e2e metadata filtering.e2e job in .github/workflows/ci.yml with Playwright browser cache.boundary-user — 5 auth/session bugs discovered by e2e tests[:session :user :id] instead of [:user :id] from the request — all 4 MFA endpoints (setup, enable, disable, status) always returned 500. Fixed by reading (:user request) directly.login-submit-handler checked for "on" but the ui/checkbox component submitted "true" — remember-me never activated. Fixed by accepting any truthy form value.string->instant in boundary.core.utils.type-conversion did not handle java.time.OffsetDateTime (returned by H2 for TIMESTAMP WITH TIME ZONE columns) — caused NPE in is-session-valid?, bouncing users back to login after successful authentication. Fixed by adding OffsetDateTime handling.should-allow-login-attempt? and calculate-failed-login-consequences existed in the core layer but were never called from the service layer. Fixed by adding a service-level lockout gate that checks the threshold before delegating to authenticate-user. Only true lockout (:retry-after present) short-circuits — deactivated/deleted accounts fall through to the normal auth flow to preserve their own error semantics.+, /, = characters that caused Jetty 400 errors on GET/DELETE /api/v1/sessions/:token. Fixed by switching generate-session-token to URL-safe base64 (Base64/getUrlEncoder without padding). Breaking change: existing sessions with old-format tokens will fail validation — users must re-login after deploy.boundary-tools — 4 new developer helper toolsbb doctor — Config Doctor (rule-based)config.edn and project files — no AI required.env-refs (error): detects #env VAR references in the :active section without #or fallback that are not set in the environment.providers (error): validates :provider values against known sets (logging, metrics, error-reporting, payments, AI, cache).jwt-secret (error): verifies JWT_SECRET is set when the user module is active.admin-parity (warn): checks that admin entity EDN files exist in both dev/admin/ and test/admin/.prod-placeholders (error): flags placeholder values (company.com, example.com, TODO, CHANGEME) in prod/acc configs.wiring-requires (warn): verifies active Integrant modules have their module-wiring require in wiring.clj.bb doctor [--env dev|prod|acc|all] [--ci]. --ci exits non-zero on any error for CI pipelines.boundary.tools.doctor.bb setup — Config Setup Wizard (templates + optional AI)--database postgresql --payment stripe), or AI-powered natural language (bb setup ai "PostgreSQL with Stripe").resources/conf/dev/config.edn, resources/conf/test/config.edn, and .env.example from template fragments.boundary.ai.shell.cli-entry setup-parse; falls back to interactive if no AI provider is available.boundary.tools.setup.bb scaffold integrate — Module Integration (rule-based)bb scaffold generate: patches deps.edn (source/test paths), tests.edn (per-library suite), and wiring.clj (module-wiring require).--dry-run mode previews all changes without writing files.bb scaffold integrate <module> and bb scaffold:integrate <module>.boundary.tools.integrate.bb ai admin-entity — Admin Entity Generator (AI-powered)bb ai admin-entity "products with name, price, status").resources/conf/dev/admin/ and includes them as examples in the prompt for style consistency.--yes flag for non-interactive use.resources/conf/dev/admin/<entity>.edn and resources/conf/test/admin/<entity>.edn.#include directive).boundary.tools.admin_entity. Clojure-side additions:
boundary.ai.core.prompts: admin-entity-messages, setup-parse-messages prompt builders.boundary.ai.shell.service: generate-admin-entity, parse-setup-description orchestration functions.boundary.ai.shell.cli-entry: cmd-admin-entity, cmd-setup-parse subcommands.bb.edn: 3 new tasks registered (doctor, setup, scaffold:integrate) + 3 new requires (boundary.tools.doctor, boundary.tools.setup, boundary.tools.integrate).bb ai help text and dispatch updated with admin-entity and setup-parse subcommands.bb scaffold help text and dispatch updated with integrate subcommand.AGENTS.md (root): new tools added to Quick Reference and namespace table.CLAUDE.md: new commands added to Scripting section.boundary-tools/AGENTS.md: comprehensive documentation for all 4 tools with examples, tables, and workflow guides.libs/ai/AGENTS.md: features list updated to 7, service API examples added, 3 new pitfalls documented (#9–#11).boundary-realtime — Ring WebSocket handlerboundary.realtime.shell.handlers.ring-websocket): bridges Ring's map-based ::ring.websocket/listener response to the existing IRealtimeService connect/disconnect lifecycle. JWT authentication via token query parameter; on-open creates adapter and registers connection, on-close/on-error triggers disconnect cleanup.websocket-handler accepts keyword options: :token-param (default "token") and :on-message for optional client→server bidirectional messaging.ring/ring-core 1.15.3 added to libs/realtime/deps.edn.boundary-payments — new libraryIPaymentProvider protocol in boundary.payments.ports with create-checkout-session, get-payment-status, process-webhook, and verify-webhook-signature methods. Implementations: StripePaymentProvider, MolliePaymentProvider, MockPaymentProvider (development/tests).CheckoutRequest, CheckoutResult, PaymentStatusResult (:pending/:paid/:failed/:cancelled), WebhookResult (:payment.paid/:payment.failed/:payment.cancelled/:payment.authorized).boundary.payments.core.provider): cents->euro, normalize-event-type, mollie-status->event-type, mollie-status->payment-status, stripe-event->event-type.payment_intent_data[metadata][checkout_id] for webhook correlation, HMAC-SHA256 signature verification with constant-time comparison, 300s timestamp tolerance, graceful handling of malformed Stripe-Signature headers.get-payment-status, form-POST webhook processing with payment fetch-back verification.:boundary/payment-provider with :provider (:mock/:mollie/:stripe), :api-key, :webhook-secret, :webhook-base-url.payments-module-config in boundary.config, boundary.payments.shell.module-wiring loaded via platform wiring, boundary/payments dependency added to libs/platform/deps.edn.^:unit + ^:integration).libs/payments/deps.edn: standalone library with clj-http, cheshire, malli, integrant, tools.logging.boundary-ai — new library (Phase 19 of Boundary Roadmap)IAIProvider protocol in boundary.ai.ports with complete, complete-json, and provider-name methods. Implementations: OllamaProvider (offline-first, no API key), AnthropicProvider, OpenAIProvider, NoOpProvider (test stub).:fallback provider in :boundary/ai-service; if the primary fails, the fallback is used transparently.bb scaffold ai "<description>" [--yes]): parses a natural language module description into a validated ModuleGenerationRequest spec and delegates to the existing scaffolder pipeline. Preview + confirm by default; use --yes for non-interactive generation.bb ai explain, (ai/explain *e)): reads a Clojure/Boundary stack trace, extracts referenced source files, and returns a structured root-cause + fix-suggestion using framework-specific system prompts.bb ai gen-tests <file>): reads a source file, detects test type (:unit for core/, :contract for adapters/, :integration otherwise), and generates a complete Kaocha-compatible test namespace.bb ai sql "<description>", (ai/sql "...")): translates a natural language query description into HoneySQL map + explanation + raw SQL preview. Auto-discovers schema context from schema.clj files.bb ai docs --module <path> --type agents|openapi|readme): generates AGENTS.md developer guides, OpenAPI 3.x YAML, or README.md from source files.boundary.ai.shell.repl): (ai/explain *e), (ai/sql "..."), (ai/gen-tests "path/to/file.clj") — bind service once with (ai/set-service! system-service).:boundary/ai-service with :provider, :model, :base-url/:api-key, and optional :fallback sub-config.Message, AIRequest, AIResponse, ProviderConfig, AIConfig.boundary.ai.core.*): prompts.clj (system + user prompt builders for all 5 features), context.clj (module name extraction, stack trace parsing, function signature discovery, schema context), parsing.clj (JSON response parser, module spec → CLI args converter, SQL + test code extractors).^:unit + ^:integration).libs/ai/AGENTS.md: 7-section developer guide covering provider setup, REPL usage, CLI reference, common pitfalls (8 patterns), testing commands.libs/ai/deps.edn: standalone library with clj-http, cheshire, malli, integrant, tools.logging..github/workflows/ci.yml: test-ai job added (needs: lint); libs/ai/src added to the lint step; test-ai wired into test-summary..github/workflows/publish.yml: boundary-ai added to Layer 4 (standalone, no inter-library dependencies); updated release body and step summary.scripts/ai.clj: new Babashka script — bb ai explain, bb ai gen-tests, bb ai sql, bb ai docs.scripts/scaffold.clj: bb scaffold ai "<description>" subcommand added.bb.edn: ai task added.AGENTS.md and CLAUDE.md: ai added to library listing, test command reference, Babashka commands, and Library-Specific Guides table. Version bumped to 3.5.0.resources/conf/dev/config.edn: :boundary/ai-service added (Ollama primary, Anthropic fallback).resources/conf/test/config.edn: :boundary/ai-service {:provider :no-op} for test isolation.boundary-calendar — new library (Phase 2 / Q3 2026 roadmap)defevent macro and in-process registry (atom-backed, same pattern as defreport in boundary-reports): register named event type schemas at load time; get-event-type, list-event-types, clear-registry!.boundary.calendar.schema: Malli schemas — EventData, EventDef, OccurrenceResult, ConflictResult; helpers valid-event?, explain-event, valid-event-def?.boundary.calendar.core.event: pure helpers — duration, all-day?, within-range?.boundary.calendar.core.recurrence: DST-aware RRULE expansion via ical4j 4.x Recur with ZonedDateTime seeds; recurring?, occurrences, next-occurrence, expand-event.boundary.calendar.core.conflict: pairwise conflict detection — overlaps?, conflicts?, find-conflicts (returns ConflictResult maps with :overlap-start/:overlap-end).boundary.calendar.core.ui: pure Hiccup calendar views — event-badge, day-cell, month-view, week-view, mini-calendar.boundary.calendar.ports: CalendarAdapterProtocol (export-ical, import-ical).boundary.calendar.shell.adapters.ical: ICalAdapter backed by org.mnode.ical4j/ical4j 4.0.3; TZID extracted via regex from property text (ical4j 4.x creates synthetic zone IDs internally).boundary.calendar.shell.service: public API — export-ical, import-ical, ical-feed-response (returns Ring response with Content-Type: text/calendar; charset=utf-8).^:unit + ^:integration round-trip).libs/calendar/AGENTS.md: 11-section developer guide covering DST pitfalls, RRULE examples, ical4j 4.x API notes, registry pollution warning, REPL smoke check.docs-site/content/guides/calendar.adoc (weight 68): user-facing how-to guide.docs-site/content/api/calendar.adoc (weight 50): complete function API reference.dev-docs/adr/ADR-011-calendar-library.adoc: architecture decision record (7 decisions, alternatives considered).boundary-reports — added to CI (was missing)test-reports job added to .github/workflows/ci.yml; libs/reports/src added to the lint step..github/workflows/ci.yml: test-calendar and test-reports jobs added (both needs: lint; standalone, no inter-library dependencies). Both wired into test-summary.AGENTS.md and CLAUDE.md: reports and calendar added to library listing, test command reference, and Library-Specific Guides table. New "Adding a New Library to CI" checklist section in AGENTS.md.boundary-workflow — new library (Phase 2 / Q3 2026 roadmap)defworkflow macro and in-process registry: declare state machine definitions as data; get-workflow, list-workflows, clear-registry!.boundary.workflow.schema: Malli schemas — WorkflowDefinition, WorkflowInstance, TransitionDef, AuditEntry; state/transition validation at definition time.boundary.workflow.core.machine: pure state machine logic — can-transition?, find-transition, permission checks against :required-permissions, guard evaluation.boundary.workflow.core.transitions: available-transitions-with-status — returns all candidate transitions with :enabled?, :label, :reason for a given state and actor-roles.boundary.workflow.core.audit: pure audit entry constructors.boundary.workflow.ports: IWorkflowStore, IWorkflowEngine, IWorkflowRegistry protocols.boundary.workflow.shell.persistence: DB persistence via next.jdbc + HoneySQL (IWorkflowStore implementation).boundary.workflow.shell.service: orchestration — load → validate → persist → side-effects; create-workflow-service factory accepts optional job-queue and guard-registry.:context map; return boolean.TransitionDef (:side-effects [:notify-user]); enqueued via boundary-jobs after successful transition; silently skipped if no job queue configured.boundary.workflow.shell.http: REST API — POST /workflow/instances (start), POST /workflow/instances/:id/transition, GET /workflow/instances/:id (state + availableTransitions), GET /workflow/instances/:id/audit.boundary.workflow.shell.module-wiring: Integrant :boundary/workflow key; depends on :boundary/database-context (required) and :boundary/job-queue (optional).libs/workflow/AGENTS.md: developer guide covering defworkflow syntax, guards, side effects, auto-transitions, hooks, and Integrant wiring.docs-site/content/guides/workflow.adoc: user-facing how-to guide.boundary-workflow — lifecycle hooks, auto-transitions, available-transitions:hooks map on WorkflowDefinition: supports :on-enter-<state>, :on-exit-<state>, and :on-any-transition keys. Hooks receive the updated WorkflowInstance and fire synchronously after each successful transition (after the audit entry is saved). Exceptions are caught and logged; they do not roll back the transition.:auto? true on TransitionDef: marks a transition as system-initiated. process-auto-transitions! port method fires all eligible auto-transitions for a given workflow; uses [:system] actor-roles (no user permission check). Returns {:attempted :processed :failed} counts.available-transitions port method: returns candidate transitions with :enabled?, :label, and :reason fields for the current state and actor-roles. Exposed on the GET /api/workflow/instances/:id HTTP response as availableTransitions.:label on TransitionDef and :state-config map on WorkflowDefinition for human-readable display names.available-transitions-with-status pure function in boundary.workflow.core.transitions.boundary-search — filter support:filters key on SearchDefinition: declares filterable keyword dimensions (e.g. [:tenant-id :category-id]).:filter-values opt in index-document! and build-document: stores filter data as compact JSON in a new filters TEXT column.d.filters::jsonb->>'key' = ?; H2/SQLite uses INSTR(filters, '"key":"val"') > 0 (H2 2.4.x has no JDBC JSON function support).filter-key->json-key utility in boundary.search.core.index (kebab → snake conversion for JSON storage).resources/migrations/20260312000000-search-filters.{up,down}.sql.boundary-admin — Admin UI Frontend Redesign ("Refined Editorial")/fonts/ for CSP compliance (font-src 'self'); no external CDN dependency.fonts.css with variable-weight @font-face declarations (DM Sans 300–700, JetBrains Mono 400–600).boundary-tokens.css: --font-sans, --font-display, --font-mono.--shadow-sm through --shadow-2xl) for modern depth.--radius-sm 6px, --radius-md 8px, --radius-lg 12px, --radius-xl 16px).--transition-fast, --transition-normal, --transition-slow, --transition-bounce).--shadow-card-hover, --shadow-inner-glow, --tracking-tight, --tracking-tighter, --topbar-backdrop.backdrop-filter: blur(12px) saturate(180%).translateY(-2px)), icon color inversion on hover..entity-card-link, .entity-card-icon, .entity-card-title, .entity-card-count, .entity-card-description classes.translateY(-1px)).fadeInUp keyframe for page content entry with staggered delays.tableRowReveal keyframe for HTMX-loaded table rows (staggered first 10 rows).::after pseudo-element with scaleX transform.@media (prefers-reduced-motion: reduce) disables all animations.#0c0f17 base).rgba(255,255,255,0.08).border-radius: var(--radius-full).boundary-admin — UX Enhancements (6 features)htmx:beforeRequest / htmx:afterRequest / htmx:responseError events.HX-Trigger: {"showToast": {...}} response header or window.AdminUX.showToast() JS API..alert-success, .alert-error, etc.) auto-converted to toasts on page load.escapeHtml() prevents XSS in toast title/message content.data-href attribute).a, button, input, select, textarea, .actions-cell, .checkbox-cell, and td.editable are ignored (preserves inline editing).<thead>.w-full, w-3-4, w-1-2, w-1-3, w-1-4) for visual variety.window.confirm() for all delete operations.htmx:confirm event on elements with hx-delete or .danger class.data-confirm-title, data-confirm-cancel, data-confirm-label attributes (server-rendered via [:t ...] i18n markers); falls back to English.removeAfterAnimation() helper checks prefers-reduced-motion: reduce and removes DOM elements immediately instead of waiting for animationend (which never fires when animation: none).@media (prefers-reduced-motion: reduce).boundary-admin — Delete Flow ImprovementsHX-Redirect instead of empty response with HX-Trigger.return_to query parameter preserved through the delete flow for context-aware redirect.return_to validated to start with /web/admin/; invalid values fall back to entity list.boundary-admin — Pagination Enhancementspage-window algorithm improved: single-page gaps show the actual page number instead of an ellipsis (e.g. 1 2 3 ... 8 instead of 1 ... 3 ... 8 when page 2 is the only gap).[:t ...] markers (8 new i18n keys).boundary-i18n — New Translation Keysen.edn and nl.edn:
:admin/pagination-showing, :admin/pagination-of, :admin/pagination-label, :admin/pagination-first-page, :admin/pagination-previous-page, :admin/pagination-next-page, :admin/pagination-last-page, :admin/pagination-page.:admin/modal-button-cancel, :admin/modal-button-delete.boundary-admin — tenant entity + dashboard statsresources/conf/{dev,test}/admin/tenants.edn — list/search fields, status enum filter (active/suspended/deleted), field groups (Identity, State, Settings), readonly system fields.admin-home-handler now calls count-entities for each registered entity and passes the stats map to admin-home, so entity tiles show real counts instead of always displaying "0".#{:users :tenants}).boundary-tenant — convenience functions and protocol extensiontenant-provisioned? public function in boundary.tenant.shell.provisioning: checks if a tenant's schema exists in PostgreSQL; returns false for non-PostgreSQL databases; throws on missing :schema-name.list-tenant-schemas public function in boundary.tenant.shell.provisioning: lists all tenant_* schemas in PostgreSQL; returns empty vector for non-PostgreSQL databases.ITenantSchemaProvider protocol extended with tenant-provisioned? and list-tenant-schemas methods; TenantSchemaProvider record updated to implement both.dev-docs/adr/ADR-020-tenant-database-scope.adoc: decision to keep tenant provisioning PostgreSQL-only; MySQL/SQLite version promises removed from README.boundary-admin UI theme evolved from "Cyberpunk Professionalism" (Geist + Indigo/Lime) to "Refined Editorial" (DM Sans + JetBrains Mono, warmer surfaces, layered shadows, spring-eased transitions). Dark mode refined with blue-tinted surfaces and colored shadow glows.boundary-admin entity card markup restructured: icon standalone on its own line, then title, description, and count as metadata.boundary-admin delete handler: returns HX-Redirect header instead of empty body with HX-Trigger: entityDeleted.boundary-admin event listeners: all 7 document.body.addEventListener calls changed to document.addEventListener to survive HTMX body swaps (hx-target="body" hx-swap="outerHTML").boundary-ui-style CSS bundle: fonts.css added as first entry in admin-pilot-css; admin-ux.js added to admin-pilot-js.boundary-ui-style keyboard.js: confirm modal escape handling added; debug mode disabled.boundary-tenant promoted from "Active" to "Stable" in PROJECT_STATUS.adoc. All convenience functions documented in README are now implemented; 70 tests, 474 assertions, 0 failures.boundary-tenant README: fixed middleware naming (wrap-tenant-resolver → wrap-tenant-resolution), removed non-existent wrap-require-tenant (use :require-tenant? true option instead), clarified middleware locations (platform lib vs tenant lib), replaced MySQL/SQLite roadmap promises with ADR-020 reference.boundary-tenant integration tests: removed stale "DEFERRED" comment — tests pass with mock observability services and H2 in-memory DB.boundary-external promoted from "In Development" to "Active" (Twilio, SMTP/IMAP adapters production-capable). Stripe moved to boundary-payments.AGENTS.md updated: workflow and search added to library structure, test commands, and Library-Specific Guides table. Version bumped to 3.3.0.libs/workflow/AGENTS.md and libs/search/AGENTS.md updated to document all new features.docs-site/content/guides/workflow.adoc and docs-site/content/guides/search.adoc updated with new API examples, filter DDL, migration notes, and hook/auto-transition reference.libs/ui-style/resources/public/js/admin-ux.js — Central JS for all 5 UX features (~340 lines).libs/ui-style/resources/public/css/fonts.css — Self-hosted @font-face declarations.libs/ui-style/resources/public/fonts/dm-sans-latin.woff2 (63 KB).libs/ui-style/resources/public/fonts/dm-sans-italic-latin.woff2 (76 KB).libs/ui-style/resources/public/fonts/jetbrains-mono-latin.woff2 (31 KB).clojure -M:test:db/h2).clojure -M:test:db/h2 :admin).workflow.core.transitions-test (available-transitions-with-status), workflow.shell.service-test (hooks, auto-transitions), search.core.query-test (filter SQL), search.shell.persistence-test (filter round-trip).The first production-ready release of the Boundary Framework - a batteries-included web framework for Clojure that brings Django's productivity and Rails' conventions with functional programming rigor.
core/ namespaces (no side effects)shell/ namespacesports.clj for dependency injectionboundary-core (0.1.0)Foundation library with essential utilities:
boundary-observability (0.1.0)Multi-provider observability infrastructure:
boundary-platform (0.1.0)HTTP and database infrastructure:
boundary-user (0.1.0)Authentication and authorization:
boundary-admin (0.1.0)Auto-generated CRUD admin interface (Django Admin for Clojure):
deleted_at columnsboundary-storage (0.1.0)File storage abstraction:
boundary-scaffolder (0.1.0)Production-ready module generator:
boundary-cache (0.1.0)Distributed caching:
boundary-jobs (0.1.0)Background job processing:
run-at timestampboundary-realtime (0.1.0)WebSocket-based real-time communication:
boundary-tenant (0.1.0)Multi-tenancy infrastructure:
boundary-email (0.1.0)Email infrastructure:
boundary-external (0.1.0) - In DevelopmentExternal service adapters:
:field-order:field-groups/api/auth/mfa/setup, /api/auth/mfa/enable, /api/auth/mfa/verify:enter (request), :leave (response), :error (exception){:path "/api/admin"
:methods {:post {:handler 'handlers/create-resource
:interceptors ['auth/require-admin 'audit/log-action]
:summary "Create admin resource"}}}
(defn create-user [this user-data]
(service-interceptors/execute-service-operation
:create-user
{:user-data user-data}
(fn [{:keys [params]}]
;; Business logic here - observability automatic
(let [user (user-core/prepare-user (:user-data params))]
(.create-user repository user)))))
limit and offset parametersfirst, prev, next, last relationsdev, test, prod)#include support: Modular config files per moduleBND_ENVresources/conf/{env}/admin/{module}.edn:test alias)clojure -M:migrate uphttps://thijs-creemers.github.io/boundary/hugo server in docs-site/ directorydocs/cheatsheet.html with client-side search, copy-to-clipboard:password-hash, :created-atpassword_hash, created_atpasswordHash, createdAtsnake-case->kebab-case-map, kebab-case->snake-case-mapWhy: Recent bug caused authentication failures because service layer used :password_hash but entities had :password-hash. This convention prevents such mismatches.
:unit metadata):integration metadata):contract metadata)clojure -M:test:db/h2 # All tests
clojure -M:test:db/h2 :core # Core library
clojure -M:test:db/h2 --focus-meta :unit # Unit tests only
clojure -M:test:db/h2 --watch :core # Watch mode
clojure -M:repl-clj <<'EOF'
(require '[boundary.shared.tools.validation.repl :as v])
(spit "build/validation-user.dot" (v/rules->dot {:modules #{:user}}))
(System/exit 0)
EOF
dot -Tpng build/validation-user.dot -o docs/diagrams/validation-user.png
resources/public/css/tokens-openprops.css).github/workflows/publish.yml (304 lines)v*io.github.thijs-creemersthijs-creemers (password via GitHub Secrets)boundary-core → io.github.thijs-creemers/boundary-coreboundary-observability → io.github.thijs-creemers/boundary-observabilityboundary-platform → io.github.thijs-creemers/boundary-platformboundary-user → io.github.thijs-creemers/boundary-userboundary-admin → io.github.thijs-creemers/boundary-adminboundary-storage → io.github.thijs-creemers/boundary-storageboundary-scaffolder → io.github.thijs-creemers/boundary-scaffolderboundary-cache → io.github.thijs-creemers/boundary-cacheboundary-jobs → io.github.thijs-creemers/boundary-jobsboundary-tenant → io.github.thijs-creemers/boundary-tenantboundary-email → io.github.thijs-creemers/boundary-emailboundary-external → io.github.thijs-creemers/boundary-external (skeleton, not production-ready)Use the boundary-starter template:
git clone https://github.com/thijs-creemers/boundary-starter
cd boundary-starter
export JWT_SECRET="change-me-dev-secret-min-32-chars"
export BND_ENV="development"
clojure -M:repl-clj
In REPL:
(require '[integrant.repl :as ig-repl])
(ig-repl/go) ;; Visit http://localhost:3000
What you get:
;; deps.edn
{:deps {io.github.thijs-creemers/boundary-core {:mvn/version "1.0.0"}
io.github.thijs-creemers/boundary-platform {:mvn/version "1.0.0"}
io.github.thijs-creemers/boundary-user {:mvn/version "1.0.0"}
io.github.thijs-creemers/boundary-admin {:mvn/version "1.0.0"}}}
clojure -T:build clean && clojure -T:build uber
java -jar target/boundary-*.jar server
Use provided Dockerfile in boundary-starter template.
export JWT_SECRET="production-secret-min-32-chars"
export BND_ENV="production"
export DB_PASSWORD="secure_password"
export DATABASE_URL="jdbc:postgresql://localhost:5432/boundary"
tx (15 occurrences)tx-ctx (5 occurrences)These are false positives from clj-kondo's static analysis and do not affect runtime behavior.
let expressions: 3 warnings in test files (cosmetic issue)This is the initial 1.0.0 release. No migration from previous versions.
Copyright 2024-2025 Thijs Creemers. All rights reserved.
Can you improve this documentation? These fine people already did:
Thijs Creemers & thijscreemersEdit 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 |