Skip to content

Comments

Breaking/2026 stack modernization#649

Open
codeGlaze wants to merge 43 commits intoOrcpub:developfrom
codeGlaze:breaking/2026-stack-modernization
Open

Breaking/2026 stack modernization#649
codeGlaze wants to merge 43 commits intoOrcpub:developfrom
codeGlaze:breaking/2026-stack-modernization

Conversation

@codeGlaze
Copy link

This is a doozy, i need other eyes on this for testing!

2026 Full-Stack Modernization

Upgrades every major dependency from 2018-era pinned versions to current releases, modernizes the dev/CI/deployment toolchain, and fixes a backlog of bugs surfaced by the upgrades.

Stack Changes

Component Before After
Java 8 21
Clojure 1.10.0 1.12.4
ClojureScript 1.10.439 1.12.134
Datomic Free 0.9.5697 Pro 1.0.7482 (Apache 2.0)
Pedestal 0.5.1 0.7.0
React 16.6 18.3
Reagent 0.7.0 2.0.1
re-frame 0.10.9 1.4.4
PDFBox 2.1.0-SNAPSHOT 3.0.6
Buddy (auth) 1.4.1 3.0.323
Hiccup 1.0.5 2.0.0
Figwheel sidecar 0.5.19 figwheel-main 0.2.20
Garden 1.3.2 lambdaisland 1.9.606
clj-time 0.15.0 java-time 1.4.2
Jackson 2.11.1 (transitive) 2.15.2 (pinned)
Guava 21.0 32.1.2-jre

Bug Fixes

  • 56 subscribe-outside-reactive-context warnings eliminated — two-phase refactor across events, options, classes, subs, pdf_spec, equipment_subs, views. Patterns: pure character fns replacing @(subscribe) in prereqs, reg-sub-raw for plugin-data threading, r/track! template cache, plain atom mirror for scroll handler.
  • :class-name:class for Reagent 2.x — Reagent 2.0 overwrites hiccup tag classes with :class-name. All UI uses converted; 18 remaining :class-name are D&D data keys (correct).
  • Party creation page crash.reload js/window.location in :http map literal executed eagerly on button click instead of after POST response. Replaced with dispatch vector.
  • Template cache timing raceautosave_fx.cljs equipment-subs require changed namespace load graph, causing content blowout on soft refresh. Reverted to setTimeout 0 + r/track! self-healing pattern.
  • Content reconciliation accuracy — Fixed index paths ([:class 0] → strip indices), corrected builtin sets (SRD-only, not all PHB), added feat detection (Grappler is the only SRD feat).
  • Flyout menu flickering + duplicate React keys in dropdown menus.
  • Combat tracker nil-state — Guard against localStorage corruption.
  • Duplicate selection options in homebrew prevented and deduped.

New Features

  • Character auto-naming — Auto-save generates descriptive labels ("High Elf Ranger 3") for unnamed characters. Manual save generates race-appropriate random names. Display fallback in party/encounter views.
  • Import validation — Unicode normalization (smart quotes, em-dashes → ASCII), required field auto-fill, trait/option validation, multi-plugin format detection.
  • Content reconciliation — Missing homebrew detection with fuzzy key matching, source inference, and warning banner in character builder.
  • Conflict resolution modal — Duplicate key detection on import with rename/keep/skip options and color-coded UI.
  • Export validation — Pre-export warning modal listing missing required fields.
  • Input debounce — Moved from component-level to debounced-build-sub (leading+trailing edge, 500ms). Eliminates per-keystroke entity/build recomputation.
  • Folder hardening — Server-side blank-name validation, on-folder-failure re-fetch, named tempids, 404 for missing folders.
  • Error handling — Structured errors across database, email, PDF generation, routes. handle-api-response HOF replaces bare case on HTTP status in 7 API-calling subscriptions.

Code Quality

  • ~92 dead vars #_ reader-discarded across 10 source files with explanatory comments.
  • 591 if→when lint fixes across 33 files (scripted, column-precise). 2 pre-existing bugs found and fixed.
  • 11 orphaned subscriptions removed (4 deleted, 7 reader-discarded).
  • Lint config consolidated to .clj-kondo/config.edn — single source of truth for IDE + CLI. Scope expanded to native/, test/, web/.

Dev Tooling

  • Devcontainer — Dockerfile + devcontainer.json + post-create.sh. One-click setup in VS Code / Codespaces with Java 21, Leiningen, Datomic Pro.
  • Service scriptsmenu (interactive TUI), start.sh, stop.sh, common.sh. Auto-source .env, health checks, port management, graceful shutdown.
  • user.clj overhaul — Lazy figwheel, nREPL helpers, system lifecycle. Lein aliases: fig:dev, fig:watch, fig:build, fig:test.
  • Dev SIGNATURE defaultproject.clj :dev profile includes JWT secret so lein repl works with auth out of the box.

CI

  • Java 8 → 21, Leiningen 2.9 → 2.11, actions v3 → v4.
  • Maven dependency caching.
  • Step summaries with lint/test results in PR checks.
  • Lint scope expanded to cover all source trees.

Tests

  • 206 JVM tests, 945 assertions, 0 failures (up from 102/261 on develop).
  • CLJS test infrastructure — figwheel-main test build, test_runner.cljs, pure function tests for compute, entity, character accessors.
  • New test coverage: CSP nonces, dependency integration (Jackson/Guava), compute-all-weapons-map, feat prereqs, pdf_spec pure functions, folder routes, content reconciliation, import validation, event handlers.

Documentation

Breaking Changes

  • Java 21 required — Datomic Pro is incompatible with Java 8. See JAVA-COMPATIBILITY.md.
  • Datomic Pro replaces Datomic Free — Free is incompatible with Java 21. Pro is now Apache 2.0 licensed.
  • .env file needed for productionSIGNATURE, DATOMIC_URL, PORT. See ENVIRONMENT.md and .env.example.
  • Pedestal 0.7 CSP — Content Security Policy with nonces enabled by default. Dev mode uses relaxed policy.
  • React 18 concurrent mode — Reagent 2.0 uses createRoot. No more ReactDOM.render.

Test Plan

  • lein test — 206 tests pass, 0 failures
  • lein fig:build — 0 warnings, 0 errors
  • lein lint — 0 errors
  • Fresh devcontainer build → ./menu → start all services
  • Create character, auto-save shows descriptive name in list
  • Manual save generates random name for unnamed character
  • Import homebrew .orcbrew with unicode issues → auto-fixed
  • Import homebrew with duplicate keys → conflict resolution modal
  • Export homebrew with missing fields → warning modal
  • Character with missing plugin content → warning banner
  • PDF export works (PDFBox 3 migration)
  • Party creation/management works
  • Login/logout cycle (Buddy 3.x JWT)

Dependency upgrades: Clojure 1.12.4, ClojureScript 1.12.134,
Pedestal 0.7.0, Datomic Pro 1.0.7482, React 18.3.1, Reagent 2.0.1,
re-frame 1.4.4, PDFBox 3.0.6, Buddy 3.x, figwheel-main 0.2.20,
java-time 1.4.2, and supporting library updates.

Key changes:
- Datomic Free -> Pro (Java 21 compatibility)
- Pedestal interceptor wrapping + CSP nonce handling (required by 0.7)
- React 18 createRoot migration
- clj-time -> java-time
- lein-figwheel -> figwheel-main
- CI updated to Java 21
- Devcontainer + scripts for Datomic Pro setup

74 tests, 237 assertions, 0 failures.
Migration index + per-topic docs covering Pedestal 0.7 (CSP, interceptor
wrapping, Jetty 11 pin), Datomic Pro, React 18/Reagent 2, library upgrades,
dev tooling, Java 21 compatibility, and environment variables.

Also fixes CI workflow Java version 8 → 21.
Move dev_init.clj and dev_tools.clj into dev/user.clj so dev tooling
stays off the production classpath (src/clj/ is AOT-compiled into the
uberjar). The user namespace now serves as both REPL helper and CLI
entrypoint via -main dispatch.

- user.clj: add :gen-class, conn helper, user CRUD, -main CLI
- project.clj: :init-db profile includes dev/ in source-paths
- scripts: rewire start.sh, create_dummy_user.sh, dev-setup.sh
- docs/migration/dev-tooling.md: rewrite for Clojure newcomers
- README.md: full overhaul for modern stack (Java 21, Datomic Pro,
  Pedestal 0.7, React 18, figwheel-main)
- Delete src/clj/orcpub/dev_init.clj and dev_tools.clj
Frontend:
- Fix message component white-on-white text (Garden CSS class)
- Fix login form input alignment (Garden CSS class)
- Fix favicon.clj 196→192 size typo
- Use :class instead of :class-name (Reagent 2.x merge behavior)

Build:
- Add externs.js for React 18 APIs (ReactDOM.Root.render, flushSync)
- Upgrade cljs-http 0.1.45→0.1.49 (fixes no.en.core shadowing warnings)
- Switch to lambdaisland/garden 1.9.606 (fixes clojure.core/abs shadowing)
- Add simplelogger.properties to suppress PDFBox font fallback WARN
- Add fonts-liberation to Dockerfile (root cause fix for font fallback)
- All builds now 0 errors, 0 warnings

Dev tooling:
- CSP nonce interceptor is no-op in dev mode (eliminates console spam)
- Figwheel uses fig:watch (headless) via start.sh; fig:dev for interactive
- menu CLI for user management (create/verify/delete with .test-users log)
- dev-setup.sh auto-creates test user (--no-test-user to skip)
- Updated migration docs (CSP behavior, core shadowing, externs, figwheel modes)
Extract pure compute helpers to compute.cljc and shared utils to
event_utils.cljc (moved from .cljs). Replace all 12 instances of
@(subscribe [...]) inside event handlers with direct db reads,
component-passed parameters, or replicated computation chains.

Adds autosave_fx.cljs with track!-based template caching for the
autosave handler that previously depended on @(subscribe [:built-character]).
Add fig:test alias and test.cljs.edn for figwheel-based CLJS testing.
New tests: compute_test.cljc (plugin vals, spell/item filtering, sort
order), event_utils_test.cljc (auth headers, mod config), events_test.cljs
(re-frame handler integration via dispatch-sync). Fix character_test.cljc
for CLJS compatibility with reader conditionals around JVM-only APIs.
Reagent 2.x changed :class-name behavior — it now OVERWRITES hiccup
tag classes instead of merging them. This caused widespread visual
regressions where base CSS classes on elements were silently dropped.

114 hiccup prop instances fixed across 6 files. Data map :class-name
keys (D&D class names in character/template/spell data) left unchanged.
22 subscribe calls in options.cljc prereq-fn closures replaced with
direct character/* pure function calls. These were never reactive —
the subscribe signal wrapped the passed entity in a plain atom. Now
prereq-fns receive built-char directly from callers (views_aux,
character_builder, entity) matching the old data flow exactly.

Also: fix meets-prereqs? when/if bug, overflow-x:hidden for
horizontal scroll, user.clj clean exit, search-input-keypress fix.
…cljc

7 subscribe calls in prereq-fn closures replaced with direct
char5e/ability-values and char5e/spells-known calls. Also removed
unused re-frame.core/subscribe import.
Phase 2: 13 subscribes across options.cljc, pdf_spec.cljc,
equipment_subs.cljs, and views.cljs replaced with pure functions,
parameter threading, plugin-data maps, and reg-sub-raw.

pdf_spec.cljc is now fully pure — no re-frame dependency.
options.cljc threads race-map from caller instead of subscribing.
equipment_subs ::mi5e/item converted to reg-sub-raw for conditional sub.

Also fixes input-field flickering in components.cljc — tracks
:prev-value to clear temp-val only when parent value catches up,
instead of clearing in setTimeout (which raced with Reagent 2.x
synchronous rendering).
Tests cover the SSOT pure functions and parameter threading changes
from the subscribe refactor:

- compute-all-weapons-map: PHB weapons, magic weapon merge, custom
  weapon expansion, nil/empty equivalence, custom doesn't clobber base
- feat-prereqs: exact label assertions for ability/spellcasting/armor
  prereqs, race-map parameter threading, mixed prereq combinations
- pdf_spec: class-string formatting (single/multi/subclass/empty),
  entity-vals key mapping and rename behavior

123 tests, 332 assertions, 0 failures.
…tion

input-field now dispatches on every keystroke. The expensive
entity/build call is debounced in the :built-character subscription
with leading+trailing edge: first change computes immediately
(dropdowns stay snappy), rapid keystrokes batch until 500ms quiet.

input-field keeps a minimal local atom to buffer typed text and
prevent controlled-input flicker while re-frame propagates.
option-language-proficiency-choice used def+partial which evaluated
@(subscribe [::langs/languages]) at namespace load time, outside any
reactive context. Converted to defn so subscribe runs during render.
Merges 24 commits from origin/develop:
- Character folders feature (13 commits)
- Equipment/weapon fixes: special, loading properties (5 commits)
- Docker verified users and setup scripts (3 commits)
- Additional test coverage

Conflict resolutions:
- views.cljs: merged folder UI with subscribe refactor + :class-name fixes
- docker-compose*.yaml: kept ${VAR:-default} pattern with datomic:dev:// URLs
- magic_items_test.clj: kept both compute-all-weapons-map and weapon property tests
- pdf_spec.cljc: threaded all-magic-items-map through plugin-data (new subscribe from develop)

Post-merge fixes:
- 4 new :class-name → :class conversions in folder/filter code (Reagent 2.x)
- Added :all-magic-items-map to plugin-data assembly in views.cljs
- Fix events/show-generic-error undefined alias in subs.cljs
- Add on-failure handlers to all folder HTTP ops (re-fetch on error)
- Client + server validation: reject blank folder names
- Wrap check-folder-owner with interceptor/interceptor, add 404
- Use named tempid in create-folder (d/resolve-tempid)
- Add default clause to folders subscription case statement
- Fix builder-dropdown CSS class (undefined → builder-option-dropdown)
- Add 3 server-side tests: blank rejection, trim, nil-name default
- Update MIGRATION-INDEX test counts, frontend-stack subscribe totals
- Add docs/STACK.md: library/dependency onboarding guide
Delete 4 static map wrapper subs (weapons-map, armor-map, equipment-map,
treasure-map) superseded by homebrew-aware versions. Reader-discard 7
unused subs with explanatory comments. All pre-existing tech debt.
Use event-utils/show-generic-error instead of the def alias that
appears later in the file. Brings lint errors from 1 to 0.
591 if-without-else converted to when/when-let/when-not across 33 files.
Resolved 11 merge conflicts (re-ran fix script on breaking's versions).
Fixed 2 pre-existing bugs: when with implicit do discarding first expr
in classes.cljc (ranger terrain) and options.cljc (spell level title).

Lint: 0 errors, 0 warnings. Tests: 174/444/0.
- Move all linter config from project.clj :lint profile to .clj-kondo/config.edn
  (single source of truth for both IDE and CLI)
- Expand lint scope: src, native, test, web (was src only)
- Bump clj-kondo 2024.05.22 → 2026.01.19
- Fix deprecated :if → :missing-else-branch linter name
- Add :clojure-lsp/unused-public-var :exclude for live false-positives
- Add :exclude-when-defined-by for re-frame registration macros
- Add shadowed-var :exclude list for intentional shadows
#_ discard 43 dead vars:
- common.cljc (4): ptime, hours-per-day, rounds-to-hours, rounds-to-minutes
- character.cljc (6): add-namespaces + 2 cascade helpers, base-climbing-speed,
  saving-throw-advantages, max-armor-class
- classes.cljc (4): blessings-of-knowledge-skill, spell-level-to-cleric-level,
  spell-in-spells-known?, pact-weapon-option
- options.cljc (15): deprecated ua/scag refs, #_ template refs, zero-caller defs
- template.cljc (14): ability roller UI (superseded by character_builder.cljs),
  amazon frames, content-list, custom-race-builder;
  #_ subscribe/dispatch refers (no live callers remain)

Redundant expression fixes:
- classes.cljc: remove nested (str (str ...))
- options.cljc: flatten (and (and ...)) in dual-wield checks,
  remove duplicate source destructuring param
#_ discard 49 dead vars:
- views.cljs (25): dead style defs, duplicate constants, superseded components
- events.cljs (22): dead defs (max-iterations, dnd-5e-characters-path,
  validate-registration, set-active-tabs, remove-subtypes, compute aliases),
  17 never-dispatched reg-event-db/fx handlers
- db.cljs (1): musical-instrument-choice-cfg (duplicate of classes.cljc)
- subs.cljs (1): ::char5e/summary reg-sub (never subscribed to)

Redundant expression fixes:
- views.cljs, character_builder.cljs, events.cljs: remove (str "literal")
Native:
- Remove unused refers (atom, subscribe, dispatch, dispatch-sync)
- Add missing font-size param to remaining-bubble
- if→when for side-effect-only branches

Web:
- if→when for protocol redirect and route matching

Tests:
- Narrow :refer lists (deftest/is only, remove unused diff/testing)
- Fix misindented (* 2 v) in entity_spec_test
- if→when in event_handlers_test

Registration:
- Remove unreachable {} before cond-> in validate-registration

Docs:
- CHANGELOG: document lint commits (if→when, forward-ref fix), update status
- MIGRATION-INDEX: update lint status to 0 errors, 0 warnings
Merge feature/error-handling-import-validation into breaking/2026-stack-modernization.
29 conflicting files resolved, 21 new files auto-merged, 206 tests passing.

New features: import/export validation pipeline, email change flow,
missing content detection, conflict resolution UI, backend error handling,
nil guards in PDF/routes, orcbrew CLI tool.

Post-merge fixes: handle-api-response moved to event_utils.cljc,
srd-link un-discarded, key-to-name → common/kw-to-name,
:class-name → :class for Reagent 2.x, hiccup2 str wrapping.
Auto-merged content_reconciliation.cljs references these functions
but they didn't survive the merge into common.cljc. Restored from
feature branch. 0 CLJS warnings, 206 JVM tests passing.
…ions

::char5e/template is used by autosave_fx.cljs and as input signal
for ::char5e/built-template. ::char5e/summary-map is used by the
combat tracker in views.cljs. Both were false-positive dead code.
header-tab: on-mouse-over/out → on-mouse-enter/leave to prevent
menu from disappearing when cursor moves from button to dropdown.
mouse-enter/leave doesn't fire between parent and child elements.

dropdown: map → map-indexed with index-prefixed keys to handle
duplicate option values from homebrew plugin data (e.g.,
:alchemical-homunculus appearing twice in the same selection).
Builder: block save when option names are empty or duplicated, with
inline red borders and error messages on offending fields. Import
pipeline: dedup identical options silently, rename different-content
same-name options with number suffixes. Dropdown: distinct-by safety
net for pre-existing data in localStorage.
set-combat-path-prop now falls back to default-combat when the path
interceptor extracts nil, preventing assoc-in from building maps with
integer keys instead of vectors. Also improves the invalid-item log
message to include the localStorage key name for easier debugging.

Adds docs/TODO.md to track the broader localStorage cleanup strategy.
4 static equipment map subscriptions (weapons-map, armor-map,
equipment-map, treasure-map) were deleted during orphan cleanup but
are still used by character_builder's inventory-selector via dynamic
sub vectors. Restores them — fixes IDeref crash on equipment page.

Template cache init (autosave_fx) now retries if the subscription
isn't registered yet. In dev mode each namespace loads as a separate
script, and setTimeout 0 can fire before equipment_subs.cljs has
loaded — preventing the IDeref crash on cold page load.
…sitives

autosave_fx: require equipment-subs directly instead of retry logic.
This guarantees ::char5e/template sub is registered before the defonce
runs, so subscribe stays inside r/track! (reactive context, no warning).

content_reconciliation: remove catch-all that labeled everything under
a class path as "Class" content. Keys like :roll (HP method), :feat
(ASI choice), :great-weapon-fighting (fighting style), :intimidation
(skill pick) were being flagged as missing homebrew. Now only flags
keys at content-relevant depths: class at [:class], subclass at
[:class :archetype-type], race, subrace, background.
- Strip vector indices from entity paths so multi-select options (class,
  subclass, feats) are detected as missing, not just single-select (race)
- Correct builtin exclusion sets to SRD-only: backgrounds #{:acolyte},
  subclasses reduced to 12 SRD entries (was all PHB)
- Add feat detection via :feats parent keyword in option paths
- Add plugin-feats to available-content subscription
- Plain atom mirror in scroll handler eliminates subscribe-outside-reactive
  warnings (DOM event listeners aren't reactive contexts)
- Revert equipment-subs require from autosave_fx (caused content blowout
  on soft refresh by pulling subscription tree into events load chain)
- Keep DEBUG subscribe tracing in core.cljs for continued diagnosis
- Rewrite CONTENT_RECONCILIATION.md with accurate SRD/plugin distinction
The is-feat? check used (last (butlast kw-path)) which matches keys
nested UNDER feats (ability scores, language choices) rather than
the feat keys themselves. For example, a Metabolic Control feat with
a nested :asi ability score choice produced kw-path [:feats :asi] —
(last (butlast ...)) = :feats, so :orcpub.dnd.e5.character/con was
misidentified as a missing feat.

Fix: use (last kw-path) to match only direct children of :feats.
Actual feats have kw-path [:feats] (top-level) or
[:class :levels :asi-or-feat :feats] (class-level). Both end in
:feats. Sub-selections end in :asi, :language-choice, etc.

Add CLJS tests covering top-level feat detection, ability score
exclusion, and missing/loaded feat scenarios.
The content reconciliation module was walking the entire entity options
tree with traverse-nested, then reverse-engineering content types from
path shapes. This duplicated the app's own get-in patterns for
accessing race, class, background, feats, and subclasses.

Replace with direct extraction functions that use the same entity
access patterns as the rest of the codebase:
- extract-race-keys: get-in [:race ::entity/key]
- extract-background-key: get-in [:background ::entity/key]
- extract-class-keys: iterate class vector, check known archetype keys
- extract-feat-keys: iterate top-level :feats vector

This eliminates the annotate-content-type heuristics, the index
stripping, the internal-key-patterns exclusions, and the path-shape
matching that caused the :con false positive. Sub-selections under
feats (ability scores, language choices) are never extracted because
the code only reads direct children of each selection.
Template cache: replace fragile defonce+setTimeout with explicit
init-template-cache! called from core.cljs after all subs registered.
Guards subscribe call itself (when-let [sub ...]) so @nil never throws.

check-auth: return diagnostic 500 when SIGNATURE env var missing instead
of raw buddy IKeyProvider stack trace. Startup warning on missing secret.
Add docs/GETTING-STARTED.md with full clone-to-running walkthrough for
devcontainer, local machine, and REPL workflows.

Add dev SIGNATURE to :dev profile :env in project.clj so lein repl works
with auth out of the box. README quick start rewritten as compact stubs
pointing to the full guide. ENVIRONMENT.md updated with .lein-env
sourcing notes and SIGNATURE marked as required.
make-empty-party had :on-success (.reload js/window.location true)
which evaluated eagerly during map construction, reloading the page
before the POST even completed. Replaced with a proper dispatch
vector to a new make-empty-party-success handler that appends the
new party to app-db reactively, matching the existing make-party
pattern.
Auto-save summary uses descriptive label from race/class/level when
character name is blank (e.g., "High Elf Ranger 3"). Manual save
generates a random race-appropriate name via random.cljc generators
and persists it to the entity. Display fallback in character lists,
party dropdowns, and encounter selectors.

Also adds Grappler to builtin-feats in content reconciliation -
the only SRD feat was missing from the exclusion set, causing a
false "missing content" warning.
Auto-detects the tech stack by checking for dev.cljs.edn (figwheel-main
sentinel file). PRs from breaking/2026-stack-modernization get Java 21 +
fig:build + Datomic Pro download. PRs from develop-based branches get
Java 8 + cljsbuild.

Also makes Docker Integration gracefully skip container tests when
orcpub/orcpub:latest is unavailable on Docker Hub — script validation
(shellcheck, .env) still runs and the check passes green.
ci: dual-stack detection for Java 8 and Java 21 branches
Resolve conflict in continuous-integration.yml by taking the dual-stack
detection workflow from ci/dual-stack-workflow. This version auto-detects
Java 8 vs 21 based on dev.cljs.edn presence, downloads Datomic Pro in CI,
and uses dynamic CLJS build commands.
- Add trampoline to lint alias so clj-kondo exit code propagates
  (lein run -m suppresses System/exit)
- Remove native/ from lint paths (directory doesn't exist)
- Add (declare generate-random-name) for forward reference
- Add email-change-test/with-conn to kondo unresolved-symbol exclude
- Fix misplaced paren in import_validation_test.cljs (line 758 missing
  close, line 839 had compensating extra) — caused 7 inline-def warnings
- Add *error-prefix* dynamic var to errors.cljc so tests can rebind
  error output prefix to TEST_ERROR: (distinguishable from real errors)
- Bind TEST_ERROR: prefix in errors-test and email-change-test fixtures
- Route email-send-failed prn through log-error for prefix support
- Remove stale debug prn "NAMES" from magic-items-test
- Capture orcbrew CLI stdout in tests with with-out-str
- Remove broken :macroexpand hooks from kondo config (produced WARNING
  noise; :unresolved-symbol :exclude already handles the with-conn macros)
- docker-compose.yaml: pin orcpub image to release-v2.5.0.27 (no
  :latest tag exists on Docker Hub), configurable via ORCPUB_TAG env var
- continuous-integration.yml: continue-on-error on PR comment step
  (fork PRs get read-only GITHUB_TOKEN, can't post to upstream)
- docker-integration.yml: clarify that container tests validate
  deployment infrastructure, not application code
- events.cljs: remove redundant (str "...") that produced kondo info
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant