Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
1671 commits
Select commit Hold shift + click to select a range
f30269c
run: when scripts/ is missing, say what happened and how to get the w…
codeGlaze Oct 21, 2026
e2dacb1
rules: a rule's preview card fits a phone screen
codeGlaze Oct 21, 2026
929b60c
Remove A5: design for Letter and A4
codeGlaze Oct 21, 2026
188d0e9
Keep what WinAnsi can draw: curly quotes, dashes, oe, euro
codeGlaze Oct 21, 2026
aef07d0
Use Nimbus Sans, not Vollkorn, for sheet fields Helvetica cannot draw
codeGlaze Oct 21, 2026
e08522e
Guard degenerate SVG arcs; fold CLI emails without the machine locale
codeGlaze Oct 21, 2026
c843de2
Set every sheet field in Nimbus Sans; keep the templates' own sizes
codeGlaze Oct 21, 2026
414f21d
Show what signup will do in the boot report, and fix the stale no-SMT…
codeGlaze Oct 21, 2026
8c4c849
Spec docstrings for the registration row; branch changelog
codeGlaze Oct 21, 2026
c44bf76
Fold the branch changelog into Summer Patch's startup-report line
codeGlaze Oct 21, 2026
9eaa478
Boot report: the ALLOW_UNVERIFIED_REGISTRATION note says the open-on-…
codeGlaze Oct 21, 2026
20b6561
weapons: a saved character keeps once-per-dawn and short-rest weapon …
codeGlaze Oct 22, 2026
bec855b
weapons: browser check for the desktop result card; a natural 20 no l…
codeGlaze Oct 22, 2026
0c5446d
Player emails go through an outbox: saved with their action, retried,…
codeGlaze Oct 22, 2026
fe7737c
Player emails go through an outbox: saved with their action, retried,…
codeGlaze Oct 22, 2026
93eb3cc
dev: measure what lookups by value cost as users grow, with and witho…
codeGlaze Oct 22, 2026
459f6bb
dev: measure-lookups names its password hash without shadowing hash
codeGlaze Oct 22, 2026
1e230f3
Docker: capped logs, crash evidence kept and reported, JAVA_OPTS reac…
codeGlaze Oct 22, 2026
e6958cc
Pin the fonts the export's drawing uses
codeGlaze Oct 22, 2026
26aae0b
Set all drawn PDF text in embedded Nimbus Sans
codeGlaze Oct 22, 2026
935306e
Security events in the log, request lines out, crash files in a visib…
codeGlaze Oct 22, 2026
eefceec
Docker: keep logs/ out of the image build; the app's private folder t…
codeGlaze Oct 22, 2026
2c29dc3
Limits and the security log see each player's address, not the proxy's
codeGlaze Oct 23, 2026
1985976
Crash files and unsent alerts live in /var/log/<APP_LOGS_NAME>, on Co…
codeGlaze Oct 23, 2026
84eea2a
Heavy Docker checks: real out-of-memory crashes and a real Swarm deploy
codeGlaze Oct 23, 2026
311388f
TEMPORARY: run the heavy Docker checks on pushes to this branch (remo…
codeGlaze Oct 23, 2026
1c5c93e
Swarm stacks deploy; the crash check always says what it found
codeGlaze Oct 23, 2026
02c0527
server: start every component before the web server, which blocks in …
codeGlaze Oct 23, 2026
4f69c2c
ci heavy: Swarm failures show Datomic's log, secrets, volumes and the…
codeGlaze Oct 23, 2026
6214259
Fix review findings: overflow site line, dropped-picture notice, tests
codeGlaze Oct 23, 2026
baf53bd
swarm: note the Datomic image is rebuilt after ./run --swarm; heavy c…
codeGlaze Oct 23, 2026
807b7d6
items: charges as data, one pool per item, with regains and priced casts
codeGlaze Oct 23, 2026
0325231
swarm: the transactor host is a start-time setting the Swarm stack se…
codeGlaze Oct 23, 2026
e4dc229
srd-2014 items: charges, regains and spells cast for 46 charged items
codeGlaze Oct 23, 2026
45ce62a
run --check and --upgrade warn when the Swarm stack lacks TRANSACTOR_…
codeGlaze Oct 23, 2026
e038c7a
run: the end-of-run warning banner names a Swarm stack without TRANSA…
codeGlaze Oct 23, 2026
38d1b63
swarm: the transactor.properties reference serves on 0.0.0.0, as Swar…
codeGlaze Oct 23, 2026
19cdb7e
items: a saved character keeps each carried item's charges; Necklace …
codeGlaze Oct 23, 2026
a7e2746
items: charges on the sheet, tap a pip to spend or get one back
codeGlaze Oct 23, 2026
2855a11
CodeRabbit: review a PR when it opens or is marked ready, not on ever…
codeGlaze Oct 23, 2026
35dcae4
CI: run the locale and Windows checks only when what they test changes
codeGlaze Oct 23, 2026
982fa12
Merge feature/coderabbit-incremental: CodeRabbit reviews once per PR;…
codeGlaze Oct 23, 2026
578d495
swarm: per-setup Datomic host defaults; regenerating keeps the admin'…
codeGlaze Oct 24, 2026
1af20e7
run: --upgrade and --check report what this release changes for the i…
codeGlaze Oct 24, 2026
6278395
srd-2014 weapons: staff powers that cost charges, spent from the + menu
codeGlaze Oct 24, 2026
5cf9860
ci heavy: drop the temporary push trigger; runs by hand and on deploy…
codeGlaze Oct 24, 2026
d40aa2d
rests: a long rest no longer means dawn; dusk as a reset time; Robe o…
codeGlaze Oct 24, 2026
71b4f43
rests: one engine for short and long rests, dawn and dusk
codeGlaze Oct 24, 2026
d5552ae
deploy: Datomic detects Swarm when its addresses are unset; the app s…
codeGlaze Oct 24, 2026
8b528b9
rests: the Rest box on the Features tab
codeGlaze Oct 24, 2026
094038c
ci heavy: Swarm wait prints progress each minute; failure diagnostics…
codeGlaze Oct 24, 2026
2dbf423
rests: Rest box spacing and dividers as designed
codeGlaze Oct 24, 2026
a807b40
deploy: Datomic treats an unresolvable service name as Swarm; heavy p…
codeGlaze Oct 24, 2026
e1facb3
ci heavy: accept either of Datomic's Swarm messages; all three jobs r…
codeGlaze Oct 24, 2026
2515b1f
server: the DEPLOYMENT block drops JAVA_OPTS, which the container nev…
codeGlaze Oct 24, 2026
6d8df9b
ci heavy: drop the temporary push trigger
codeGlaze Oct 24, 2026
a298561
artist email tests: switch email on through the namespace's own check…
codeGlaze Oct 24, 2026
7adc6a1
server: the startup report gives Java's memory limit
codeGlaze Oct 24, 2026
836e8aa
server: startup report lists each group once, new settings as one wra…
codeGlaze Oct 24, 2026
d5bdc56
email: admin alerts and artist notices fall back to APP_SUPPORT_EMAIL…
codeGlaze Oct 24, 2026
1b3ee30
server: refuses to start without email unless told; the startup repor…
codeGlaze Oct 24, 2026
dd16070
items: cast spells from charged items, on the item and the Spells tab
codeGlaze Oct 24, 2026
5a93ffa
Ignore agent instruction files: AGENTS.md, BRANCH.md and other AI too…
codeGlaze Oct 24, 2026
59e8401
Merge fix/ignore-files: ignore agent instruction files from every AI …
codeGlaze Oct 24, 2026
20de2fe
server: the startup email: problems, this release's settings, those w…
codeGlaze Oct 25, 2026
02d966d
server: the startup email names new tuning settings on one line
codeGlaze Oct 25, 2026
827c51d
server: the startup email keeps the comma where a name list wraps; do…
codeGlaze Oct 25, 2026
f54e5eb
test: the startup email's content, timing and memory
codeGlaze Oct 25, 2026
43164c3
CodeRabbit: reviews on request only, never automatic
codeGlaze Oct 25, 2026
d24893a
server: the startup email lists new settings one per line, with their…
codeGlaze Oct 25, 2026
e62a089
test: new settings in the startup email are listed one per line by area
codeGlaze Oct 25, 2026
5210d0b
srd-2014 spells: rolling data for every spell, generated from the SRD…
codeGlaze Oct 25, 2026
2c6bdd2
srd-2014 spells: a test that the rolling data names real spells and t…
codeGlaze Oct 25, 2026
fe6db87
builders: the labelled builder fields move to views.builder-fields
codeGlaze Oct 25, 2026
cbd64b8
items: the item builder's Charges group, and custom items save their …
codeGlaze Oct 25, 2026
fd2947d
items: tests that the Charges group edits the item and custom items s…
codeGlaze Oct 25, 2026
4490ff4
items: a cast with no spell chosen yet no longer breaks the Charges g…
codeGlaze Oct 25, 2026
d9580f4
items: a test that a cast with no spell chosen yet has no roll line
codeGlaze Oct 25, 2026
ce250ec
rests: the Rest box moves to views.rest-controls
codeGlaze Oct 25, 2026
8bbac32
rests: a floating Rest button on every sheet tab but Features
codeGlaze Oct 25, 2026
94a0056
rests: a browser test for the floating Rest button and the casting sw…
codeGlaze Oct 25, 2026
5b6d569
ci heavy: one run on this branch
codeGlaze Oct 25, 2026
292051a
Merge integration into feature/weapons-table
codeGlaze Oct 26, 2026
3ac37d6
weapons: the roll result sheet sits above the floating Rest button
codeGlaze Oct 26, 2026
cde5e5a
changelog: what feature/weapons-table adds, changes and fixes
codeGlaze Oct 26, 2026
141dbf0
ci heavy: drop the one-off push trigger
codeGlaze Oct 26, 2026
6bcd1b9
server: admin addresses are found under a Turkish locale
codeGlaze Oct 26, 2026
19ee9e7
server: the startup email lists an unset From address once
codeGlaze Oct 26, 2026
5a1b137
server: the email worker reports a database outage, and a delivered e…
codeGlaze Oct 26, 2026
b6519cc
deploy: nginx appends the address it saw to X-Forwarded-For
codeGlaze Oct 26, 2026
d2a9470
deploy: Compose passes TRANSACTOR_HOST; release checks read the stack…
codeGlaze Oct 26, 2026
73bf63e
hooks: pre-push matches the heavy-Docker paths as globs
codeGlaze Oct 26, 2026
46debfe
items: Roll damage after casting a spell from an item
codeGlaze Oct 26, 2026
cfb69be
items: tests that a spell's damage scales with the cast level
codeGlaze Oct 26, 2026
5350f47
items: a browser check that Roll damage rolls a cast's damage
codeGlaze Oct 26, 2026
db611f0
changelog: rolling a cast's damage
codeGlaze Oct 26, 2026
1abbd88
server: setting names are upper-cased the same way under a Turkish lo…
codeGlaze Oct 26, 2026
c74ee1e
Merge pull request #75 from codeGlaze/feature/email-and-alerts
codeGlaze Oct 26, 2026
8e4ee3f
weapons: the mastery band reads the attack's own ability modifier
codeGlaze Oct 26, 2026
1b6f179
weapons: a test that an attack's ability modifier leaves out damage b…
codeGlaze Oct 26, 2026
755cf46
db: index the attributes the server looks up by value
codeGlaze Oct 26, 2026
5a64b67
test: value lookups are indexed, and an old database gains the indexe…
codeGlaze Oct 26, 2026
ca64645
test: lookup-indexes helper no longer shadows clojure.core/indexed?
codeGlaze Oct 26, 2026
f42306e
server: email lookups match an indexed lowercase key instead of readi…
codeGlaze Oct 26, 2026
efb0916
test: email lookups use the key; every writer sets it; older accounts…
codeGlaze Oct 26, 2026
f1218c7
docs: the email lookup key, how to write an email, and the backfill
codeGlaze Oct 26, 2026
8908141
client: the account is fetched once per page load, and who you follow…
codeGlaze Oct 26, 2026
6c0eb73
weapons: an attack's ability is named, and its own save DC reuses sav…
codeGlaze Oct 26, 2026
f2f4675
test: the account is fetched once per page load and keeps who you follow
codeGlaze Oct 26, 2026
2c1a8b5
dev: measure-lookups runs against the indexed schema and the email key
codeGlaze Oct 26, 2026
97c89f4
changelog: upgrade note for the indexes and email key; follow state a…
codeGlaze Oct 26, 2026
cbfb8b4
weapons: tests that an unused ability entry adds nothing and the weap…
codeGlaze Oct 26, 2026
ffb32af
changelog: the low-Strength monk attack fix
codeGlaze Oct 26, 2026
6fecae2
ci: the branch changelog check waits for the "ready to merge" label
codeGlaze Oct 26, 2026
09749a7
server: the email-key backfill skips accounts whose email is blank
codeGlaze Oct 26, 2026
6ad9b23
test: an account with a blank email does not stop the backfill
codeGlaze Oct 26, 2026
f251782
weapons: leave the discarded UA Hexblade reference as it was
codeGlaze Oct 26, 2026
b4501f1
changelog: cite #713 for the low-Strength monk fix
codeGlaze Oct 26, 2026
831a412
weapons: extra damage and effects can name the attack's modifier and …
codeGlaze Oct 26, 2026
68fa5d1
weapons: tests that a weapon's value references become its numbers
codeGlaze Oct 26, 2026
1a58bb2
homebrew: grant editors update the stored list, so a quick second cli…
codeGlaze Oct 26, 2026
960252c
test: two adds before a redraw keep both rows
codeGlaze Oct 26, 2026
0b90e94
Merge integration into feature/asi-spreads
codeGlaze Oct 26, 2026
b48b0e8
Merge pull request #69 from codeGlaze/feature/asi-spreads
codeGlaze Oct 26, 2026
e1f761d
server: the email-key backfill reads the accounts once, then writes i…
codeGlaze Oct 26, 2026
47a5754
server: email lookups also match the stored address while the backfil…
codeGlaze Oct 26, 2026
dabdfa8
test: accounts are found before the backfill, and the backfill reads …
codeGlaze Oct 26, 2026
89de0b8
client: a start-up account answer for an old login is dropped
codeGlaze Oct 26, 2026
68f9fd1
test: a start-up account answer for an old login is dropped
codeGlaze Oct 26, 2026
03589af
e2e: user-fetched-once waits for the kept account and keeps an existi…
codeGlaze Oct 26, 2026
cdb3648
weapons: effect lines as sentences with condition links; Missed? for …
codeGlaze Oct 26, 2026
92fae65
changelog: only older mixed-case addresses wait for the backfill
codeGlaze Oct 26, 2026
6ffc267
weapons: tests for effect sentences and the Missed? option
codeGlaze Oct 26, 2026
31dd227
Merge integration into fix/lookup-indexes
codeGlaze Oct 26, 2026
967619f
weapons: an attack mode switch in the Weapons header, and a long pres…
codeGlaze Oct 26, 2026
f2eaed0
weapons: tests for the attack mode switch and the long press
codeGlaze Oct 26, 2026
149d33c
changelog: attack mode on any device
codeGlaze Oct 26, 2026
5f8689d
weapons: an effect can set the next attack's mode (Vex)
codeGlaze Oct 26, 2026
3db1c22
weapons: a test that an effect sets the next attack's mode
codeGlaze Oct 26, 2026
7f47073
weapons: an effect can be an extra attack, once per turn (Cleave)
codeGlaze Oct 26, 2026
4577c6e
weapons: a test that an extra attack is a once-per-turn menu use
codeGlaze Oct 26, 2026
1f4ad6e
weapons: all eight masteries as made-up item data, through the engine
codeGlaze Oct 26, 2026
2dab805
Merge integration into refactor/pdf-canvas
codeGlaze Oct 26, 2026
5c3e00e
server: the email-key backfill writes a key only while the account ha…
codeGlaze Oct 26, 2026
c202a5f
client: a start-up 401 for an old login does not sign out a newer one
codeGlaze Oct 26, 2026
7b4de8f
dev: create-user! sees an account by its stored address before it has…
codeGlaze Oct 26, 2026
bff3f46
test: the backfill keeps a newer key; a 401 for an old login is ignored
codeGlaze Oct 26, 2026
617e749
changelog: fold the branch changelog into Summer Patch
codeGlaze Oct 27, 2026
8dfa6fa
items: a Weapon powers group in the item builder
codeGlaze Oct 27, 2026
9a58352
items: tests that weapon powers are edited and saved
codeGlaze Oct 27, 2026
65aa5ad
changelog: weapon powers for custom weapons
codeGlaze Oct 27, 2026
df38a66
Merge pull request #76 from codeGlaze/fix/lookup-indexes
codeGlaze Oct 27, 2026
c271cbc
weapons: the attack mode switch shows "—" for Normal; long-press mode…
codeGlaze Oct 27, 2026
91cad1d
weapons: attack mode checks for the dash and the bottom sheet
codeGlaze Oct 27, 2026
006e730
weapons: the + menu opens in the bottom sheet on phones too
codeGlaze Oct 27, 2026
04cf25d
weapons: a check that the + menu opens in the bottom sheet on a phone
codeGlaze Oct 27, 2026
bbc267f
weapons: the browser test saves a shot of the + menu sheet
codeGlaze Oct 27, 2026
7ca156b
Merge integration into refactor/pdf-canvas
codeGlaze Oct 27, 2026
2005cd8
Merge pull request #63 from codeGlaze/refactor/pdf-canvas
codeGlaze Oct 27, 2026
bc6130d
items: switches, targets, melee or ranged, next attack and extra atta…
codeGlaze Oct 27, 2026
a6d8a3a
items: tests for weapon switches, conditions, vector targets and the d20
codeGlaze Oct 27, 2026
730736c
changelog: weapon switches and conditions for custom weapons
codeGlaze Oct 27, 2026
7da426d
weapons: the two-hands message names what to unequip (owner's wording)
codeGlaze Oct 27, 2026
155fd25
Merge integration into feature/artist-pages
codeGlaze Oct 27, 2026
04becd2
Credit notices: queue each email in the transaction that records it; …
codeGlaze Oct 27, 2026
5bb6d63
Tests: an overdue batch survives the next save; credit emails are que…
codeGlaze Oct 27, 2026
cc24d2a
My Account: page switches start from the setting in force; ones the s…
codeGlaze Oct 27, 2026
c93b3f3
Merge integration into feature/weapons-table
codeGlaze Oct 27, 2026
52b52c9
Tests: My Account's page switches show the setting in force, locked w…
codeGlaze Oct 27, 2026
406d4e1
Docs: the off page redirects, the show switches are overridable, one …
codeGlaze Oct 27, 2026
e4da21b
changelog: fold feature/weapons-table into Summer Patch
codeGlaze Oct 27, 2026
93b3d19
Merge pull request #73 from codeGlaze/fix/coderabbit-config
codeGlaze Oct 27, 2026
84733d7
weapons, rests: CodeRabbit's review of #74
codeGlaze Oct 27, 2026
a841b4d
Merge integration into test/page-load-budget
codeGlaze Oct 27, 2026
8dc9c5c
weapons, rests: tests for a crit on 19 and for Rest events with no re…
codeGlaze Oct 27, 2026
28ffc76
weapons, rests, items: CodeRabbit's full review of #74
codeGlaze Oct 27, 2026
57b30c5
weapons, rests, items: tests for the full-review fixes
codeGlaze Oct 27, 2026
4784ea7
Review fixes (server): switches reach My Account and the settings; re…
codeGlaze Oct 27, 2026
43399c8
Tests for the server review fixes: switches, settings, referrer chain…
codeGlaze Oct 27, 2026
bd0e94a
Review fixes (client): a full preparation list refuses another spell;…
codeGlaze Oct 27, 2026
48a14d8
Keep this branch's heal re-dispatch: :character-updated keeps the por…
codeGlaze Oct 27, 2026
e6ccb1e
Test that a spell cannot be prepared once every preparation is used
codeGlaze Oct 27, 2026
de27f6d
Header probe: a phone must show the desktop's menus, and say how they…
codeGlaze Oct 27, 2026
9f5dfe0
Artist page docs: a page switched off redirects; examples are cached,…
codeGlaze Oct 27, 2026
6acf7c4
Prepared-spell test requires re-frame.core for the dispatch it redefines
codeGlaze Oct 27, 2026
3084497
Start the branch changelog: homebrew guarded by default
codeGlaze Oct 20, 2026
05b9539
Measure what malformed homebrew crashes, and the design to stop it
codeGlaze Oct 20, 2026
27c7af8
The junk audit reaches pages, share links and imports, and counts sil…
codeGlaze Oct 20, 2026
c9ef984
The junk audit's baseline on integration: 498 failures over 46 fields
codeGlaze Oct 21, 2026
907b8e2
The guard design read against our own documents
codeGlaze Oct 21, 2026
cd1e943
The homebrew shape table, a junk audit in 8 minutes, and a faster dee…
codeGlaze Oct 21, 2026
7557ebf
The guard design as agreed: checks where homebrew comes in and where …
codeGlaze Oct 21, 2026
caf5df4
Guard design: the check runs in a global interceptor on every library…
codeGlaze Oct 21, 2026
ca8b7d6
The junk audit's checks each catch a planted failure, and count what …
codeGlaze Oct 21, 2026
538fae1
Check every homebrew library change against the shape table
codeGlaze Oct 22, 2026
2ce7925
Check homebrew where the app reads it, not only where it is written
codeGlaze Oct 25, 2026
d63d8ff
Offer homebrew boons and invocations under their stored key
codeGlaze Oct 25, 2026
a17f2f7
Harden the helpers every option passes through, ranked by the unguard…
codeGlaze Oct 25, 2026
0775732
A homebrew addition that breaks a class or race costs only itself
codeGlaze Oct 26, 2026
625f92d
An event that throws says so and changes nothing
codeGlaze Oct 26, 2026
724d305
A homebrew entry that cannot be drawn costs its own part of the page
codeGlaze Oct 26, 2026
3ee4ad5
The share banner names the shared homebrew it cannot use
codeGlaze Oct 26, 2026
0303dc4
Plain words in what people read about set-aside homebrew
codeGlaze Oct 26, 2026
16ade19
Move the view guards out of views.cljs into views/guards.cljs
codeGlaze Oct 26, 2026
a2d63b6
Move the set-aside and write-check logic out of events.cljs into home…
codeGlaze Oct 26, 2026
8a50173
One repair path: fold e5/mend-* into homebrew-shapes
codeGlaze Oct 26, 2026
59f255e
Put the view guards back in views.cljs
codeGlaze Oct 26, 2026
15c87e1
page-load budget: 900 KB bundle ceiling, allowances, known portrait-a…
codeGlaze Oct 27, 2026
83104bd
Builder: the header logo and the portrait mask share one logo request
codeGlaze Oct 27, 2026
837a262
Merge pull request #66 from codeGlaze/test/page-load-budget
codeGlaze Oct 27, 2026
06c054f
Merge integration into feature/guarded-homebrew
codeGlaze Oct 27, 2026
b4f01f6
Merge integration into feature/registration-in-boot-report
codeGlaze Oct 28, 2026
24461df
Test that the boot report's registration row follows the environment …
codeGlaze Oct 28, 2026
1c86f6d
Isolate the registration-row report test from the process environment
codeGlaze Oct 28, 2026
8852421
Merge pull request #70 from codeGlaze/feature/registration-in-boot-re…
codeGlaze Oct 28, 2026
134d04c
Merge integration into feature/artist-pages
codeGlaze Oct 28, 2026
4a15c78
Artist pages review fixes: credit notices write the pending batch wit…
codeGlaze Oct 28, 2026
5cafb47
Artist pages review fixes: What's New names the link that reaches an …
codeGlaze Oct 28, 2026
4ed89a7
Test the artist pages review fixes
codeGlaze Oct 28, 2026
5041c6c
Changelog: cite the new umbrella issues #714-#721 on the Summer Patch…
codeGlaze Oct 28, 2026
e466cae
CodeRabbit: skip docs/design so a large PR is not skipped for file count
codeGlaze Oct 28, 2026
d2cef86
Artist pages: review fixes (marks default, notice failure, locked swi…
codeGlaze Oct 28, 2026
a812f90
Artist pages: tests for the review fixes
codeGlaze Oct 29, 2026
af89cf0
Fold the branch changelog into Summer Patch
codeGlaze Oct 29, 2026
59e2180
Merge integration into feature/weapons-table
codeGlaze Oct 29, 2026
971cfd3
Merge pull request #65 from codeGlaze/feature/artist-pages
codeGlaze Oct 29, 2026
c878e98
Merge integration into feature/guarded-homebrew
codeGlaze Oct 29, 2026
c804ea5
Docstrings for the guard's helper functions and tests
codeGlaze Oct 29, 2026
9e80be3
Merge integration into feature/weapons-table
codeGlaze Oct 29, 2026
dde6c94
Merge pull request #74 from codeGlaze/feature/weapons-table
codeGlaze Oct 29, 2026
097f983
Merge integration into feature/guarded-homebrew
codeGlaze Oct 29, 2026
091cee5
Offer a homebrew subclass under its stored key, so one named "x" or w…
codeGlaze Oct 29, 2026
84e381c
Test that a homebrew subclass is offered under its stored key
codeGlaze Oct 29, 2026
603853b
Branch changelog: homebrew subclasses are offered under their stored key
codeGlaze Oct 29, 2026
04e153b
Point guard comments at the KB page; the design doc moves to agents/d…
codeGlaze Oct 29, 2026
14b0603
Guarded homebrew: fix the review's findings (leading-zero numbers, mo…
codeGlaze Oct 29, 2026
71d9301
Test the review's fixes: leading-zero numbers, monster scores, lone a…
codeGlaze Oct 29, 2026
c1b4d2b
Add the agent-trailers PR check; rename a shadowing test local
codeGlaze Oct 29, 2026
90838e7
Fold the branch changelog into the Summer Patch
codeGlaze Oct 29, 2026
b734cac
Merge pull request #77 from codeGlaze/feature/guarded-homebrew
codeGlaze Oct 29, 2026
d8629e4
Browser scripts: one static server with a guard CodeQL recognizes, an…
codeGlaze Oct 29, 2026
75cf6fd
Merge pull request #78 from codeGlaze/feature/registration-in-boot-re…
codeGlaze Oct 29, 2026
d764388
Dev mode: a banner when the compiled client or stylesheet is older th…
codeGlaze Oct 30, 2026
c06a3eb
Test the dev-mode stale-bundle check
codeGlaze Oct 30, 2026
6a077da
Merge develop into fix/release-cleanup: the wider design-handoff and …
codeGlaze Nov 2, 2026
62d41a0
Move mockups, plans, reports and research scripts off the code line
codeGlaze Nov 2, 2026
bac1a91
A server start builds what is out of date, replacing the stale-build …
codeGlaze Nov 2, 2026
d7337dd
PR check behind the branch-shape hook: stray files and the file limit
codeGlaze Nov 2, 2026
393c3ef
Review fixes for the start build and the archive pointers
codeGlaze Nov 2, 2026
5ec530c
Merge pull request #79 from codeGlaze/fix/release-cleanup
codeGlaze Nov 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
47 changes: 45 additions & 2 deletions .clj-kondo/config.edn
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,25 @@
:exclude-files "resources/public/js/compiled"
:output {:exclude-files [".*resources/public/js/compiled.*"
".*docker/scripts/.*"]}
:linters {;; Enabled at :warning so NEW accidental shadows are caught.
:linters {;; A BLANK ENVIRONMENT VALUE IS AN ABSENT ONE, and (or (env :k) default)
;; does not implement that: environ returns "" for an exported-but-empty
;; variable and "" is truthy, so the default never applies. That shape
;; was written independently at five sites and cost, among others, JWTs
;; signed and verified against the empty string.
;;
;; orcpub.config already had a correct accessor and routes.clj read
;; (environ/env :signature) raw anyway, four times -- which is why this
;; is a lint rule and not just a helper. Read through orcpub.env/value.
;; :error, not :warning -- `lein lint` runs with --fail-level error, so
;; this is the difference between a rule and a suggestion. The helper
;; it points at already existed once and was bypassed.
:discouraged-var
{:level :error
environ.core/env
{:message "Use orcpub.env/value -- (or (env :k) d) treats an empty value as set. See orcpub.env."}
java.lang.System/getenv
{:message "Use orcpub.env/value -- environ already reads env vars, and this skips the blank check."}}
;; Enabled at :warning so NEW accidental shadows are caught.
;; :exclude covers established patterns: core vars used as param names
;; (name, key, type, etc.) and domain terms used as both defs and params
;; (level, ability, armor, etc.) across modifier/option/character code.
Expand Down Expand Up @@ -79,6 +97,13 @@
:unresolved-symbol
{:exclude
[read-string
;; test macros that bind their first argument -- clj-kondo cannot
;; see through them, so each use reads as an unresolved symbol
(orcpub.portrait-credit-test/with-conn)
(orcpub.portrait-og-test/with-conn)
(orcpub.portrait-artists-endpoint-test/with-conn)
(orcpub.portrait-store-test/with-conn)
(orcpub.page-escape-test/with-conn)
(clojure.test.check.clojure-test/defspec)
(clojure.core.match/match)
(cljs.core.match/match)
Expand All @@ -98,6 +123,7 @@
(orcpub.dnd.e5.modifiers/skill-expertise)
(orcpub.dnd.e5.modifiers/tool-expertise)
(orcpub.dnd.e5.modifiers/ac-bonus-fn)
(orcpub.dnd.e5.modifiers/ac-formula)
(orcpub.dnd.e5.modifiers/attack)
(orcpub.dnd.e5.modifiers/action)
(orcpub.dnd.e5.modifiers/bonus-action)
Expand All @@ -107,10 +133,27 @@
(orcpub.routes-test/with-conn)
(orcpub.routes.folder-test/with-conn)
(orcpub.email-change-test/with-conn)
(orcpub.routes.public-reads-test/with-conn)
(orcpub.routes.item-save-test/with-conn)
(orcpub.routes.share-test/with-conn)
(orcpub.routes.party-test/with-conn)
(orcpub.heartbeat-test/with-conn)
(orcpub.artist-accounts-test/with-conn)
(orcpub.artist-credit-test/with-conn)
(user/with-db)]}}
;; native/cljs and web/cljs are separate source roots; kondo doesn't know
;; about them so ns names appear to mismatch their file paths.
:config-in-ns {orcpub.core {:linters {:namespace-name-mismatch {:level :off}}}
;; orcpub.env is the one place allowed to read the environment; the whole
;; point of the namespace is to be the single exception.
:config-in-ns {orcpub.env {:linters {:discouraged-var {:level :off}}}
;; These two STUB environ.core/env with with-redefs, which is how
;; you test the accessor and the locale behaviour at all -- kondo
;; counts the var reference as a use. Exempted by namespace rather
;; than for all of test/, so an ordinary bare read in a test is
;; still an error (routes_test.clj had one).
orcpub.env-test {:linters {:discouraged-var {:level :off}}}
orcpub.config-test {:linters {:discouraged-var {:level :off}}}
orcpub.core {:linters {:namespace-name-mismatch {:level :off}}}
orcpub.views {:linters {:namespace-name-mismatch {:level :off}}}
orcpub.dnd.e5.native-views {:linters {:namespace-name-mismatch {:level :off}}}}
;; with-conn macros use bare symbol bindings — handled via
Expand Down
7 changes: 7 additions & 0 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# CodeRabbit settings for the codeGlaze/orcpub fork only. Leave this file out of pull requests to
# Orcpub/orcpub. Reviews are requested, never automatic: the allowance is small and shared by every
# agent (all push as codeGlaze). Ask with `@coderabbitai full review` when a PR is ready.
# CodeRabbit reads this file from the PR's own branch, so a branch made before a change keeps the old one.
reviews:
auto_review:
enabled: false
10 changes: 4 additions & 6 deletions .devcontainer/post-create.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ set -euo pipefail

# Source .env from repo root if present (authoritative config)
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
if [ -f "$REPO_ROOT/.env" ]; then
set -a
# shellcheck disable=SC1090
. "$REPO_ROOT/.env"
set +a
fi
# Read, never run: scripts/load-env.sh.
# shellcheck source=scripts/load-env.sh
. "$REPO_ROOT/scripts/load-env.sh"
load_env "$REPO_ROOT/.env"

# Redirect all output to persistent logs for visibility during Codespace creation
LOG="/tmp/orcpub-post-create.log"
Expand Down
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# Secrets — never copy into build context
.env
.lein-env
logs/console.log
logs/
docker-compose*
test/*
*.md
Expand Down
153 changes: 145 additions & 8 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
#
# Or run the setup script to generate .env with secure random values:
# ./run
#
# Each line is NAME=value, read exactly as written: spaces and apostrophes are fine without
# quotes (APP_NAME=Dungeon Master's Vault). Quotes are optional. Use $$ for a literal $.
# ============================================================================

# --- Application ---
Expand Down Expand Up @@ -35,13 +38,32 @@ TZ=America/Chicago
# Old URLs with ?password= still work — the embedded password takes priority.
ADMIN_PASSWORD=change-me-admin
DATOMIC_PASSWORD=change-me-datomic
DATOMIC_URL=datomic:dev://datomic:4334/orcpub
# Left COMMENTED OUT on purpose, so that each way of running picks its own
# correct value instead of inheriting the other's:
#
# bare metal -> config.clj/default-datomic-uri = datomic:dev://localhost:4334/orcpub
# docker -> docker-compose.yaml already defaults it to the "datomic"
# service hostname, which only resolves inside that network
#
# Setting it here would defeat both. Compose reads this .env for substitution,
# so an uncommented localhost would override compose's own default and break
# the container; an uncommented "datomic" hostname breaks every non-Docker
# install, which is how it used to ship.
#
# Uncomment ONLY for a database somewhere else -- a remote transactor, a
# non-default port, or Datomic SQL storage:
# DATOMIC_URL=datomic:dev://localhost:4334/orcpub
# DATOMIC_URL=datomic:sql://orcpub?jdbc:postgresql://db:5432/datomic

# --- Transactor Tuning ---
# These rarely need changing. See docker/transactor.properties.template.
# ALT_HOST: peer fallback hostname (default: 127.0.0.1, set to service name for Swarm)
# TRANSACTOR_HOST: address the transactor serves on and gives the app
# (Compose: datomic; the Swarm stack from ./run --swarm: 0.0.0.0)
# ALT_HOST: the second address the app tries (Compose: 127.0.0.1; Swarm stack: datomic)
# Both default to the right value for each; set them only to override.
# ENCRYPT_CHANNEL: encrypt peer-transactor communication (default: true)
ALT_HOST=127.0.0.1
# TRANSACTOR_HOST=
# ALT_HOST=
ENCRYPT_CHANNEL=true
# Password rotation — set OLD vars during rotation, remove after all peers reconnect
# ADMIN_PASSWORD_OLD=
Expand All @@ -55,11 +77,22 @@ SIGNATURE=change-me-to-something-unique-and-long
# Content Security Policy (strict|permissive|none)
CSP_POLICY=strict

# Dev mode: CSP violations are logged (Report-Only) instead of blocked,
# allowing Figwheel hot-reload scripts to execute.
# Dev mode: no CSP header is sent at all, so Figwheel's scripts and its
# websocket (ws://localhost:3449) work. Leave this true for development.
# With DEV_MODE unset or false, CSP_POLICY=strict sends an ENFORCING policy
# whose connect-src does not include the Figwheel socket, and hot reload is
# blocked with no obvious cause.
# Must be the string "true" (case-insensitive). Any other value is treated as false.
DEV_MODE=true

# --- Proxies in front of the app ---
# true only when the site is served through Cloudflare: limits and the security log then see each
# player's real address. Leave unset otherwise, since anyone can send requests from Cloudflare.
# TRUST_CLOUDFLARE=true
# Extra proxies to trust (comma-separated addresses or ranges). Private networks, where Docker and
# Swarm proxies sit, are always trusted.
# TRUSTED_PROXIES=203.0.113.10,198.51.100.0/24

# --- Plugins ---
# URL to fetch server-hosted .orcbrew plugins on first page load.
# Leave empty to disable (plugins come only from local file imports).
Expand All @@ -68,6 +101,16 @@ DEV_MODE=true
# --- Logs ---
# Defaults to project logs/ if unset
LOG_DIR=
# Docker: the app keeps crash files and unsent admin alerts in /var/log/<this name> on the host,
# on Compose and Swarm alike. A plain name only; default orcpub.
# APP_LOGS_NAME=orcpub
# Docker: each container keeps at most this many log files of this size. Defaults 5 of 10m.
# LOG_MAX_SIZE=10m
# LOG_MAX_FILES=5

# --- App memory (Docker) ---
# Java's memory options for the app. Empty: it uses 25% of its container's memory.
# JAVA_OPTS=-XX:MaxRAMPercentage=75.0

# --- Remote Dev (optional) ---
# Figwheel WebSocket port for hot-reload (default: 3449)
Expand All @@ -79,29 +122,123 @@ LOG_DIR=
# FIGWHEEL_CONNECT_URL=

# --- Email (SMTP) ---
# Leave EMAIL_SERVER_URL empty to disable email functionality
# EMAIL_SERVER_URL empty means this deployment cannot send mail, and registration
# then REFUSES to create accounts -- deliberately, because a dropped or typo'd
# value would otherwise silently turn a public site into open registration.
#
# With EMAIL_SERVER_URL empty a deployed server (DEV_MODE not true) will not start
# unless you say email is not needed: EMAIL_REQUIRED=false (sign-up stays off).
# EMAIL_REQUIRED=
#
# To let people sign up without email, say so: ALLOW_UNVERIFIED_REGISTRATION=true.
# Accounts are then verified on creation and no mail is ever sent. Only sensible
# for a private instance where you hand out the accounts, since nobody proves
# they own the address they typed.
EMAIL_SERVER_URL=
EMAIL_ACCESS_KEY=
EMAIL_SECRET_KEY=
EMAIL_SERVER_PORT=587
EMAIL_FROM_ADDRESS=
# MUST be an address your SMTP provider is authorised to send as (SPF/DKIM),
# not just any address you own. Left blank it falls back to no-reply@example.com,
# a placeholder no provider will deliver -- set it.
EMAIL_FROM_ADDRESS=no-reply@example.com
# Where admin alerts (server errors, crashes) are emailed. Empty: EMAIL_ADMIN_TO, then
# APP_SUPPORT_EMAIL; with none set, alerts go to the server log only.
EMAIL_ERRORS_TO=
EMAIL_SSL=FALSE
EMAIL_TLS=FALSE

# Accept registrations without verifying the address. Requires EMAIL_SERVER_URL
# to be empty; ignored otherwise. Private instances only.
ALLOW_UNVERIFIED_REGISTRATION=false

# --- Admin alerts (optional) ---
# Where alerts wait when the mail server is down; they are sent once it is back. Default: a folder
# in the system temp directory. In Docker, point it at a volume, or a replaced container loses them.
# ALERT_SPOOL_DIR=/var/lib/orcpub/state/alerts
# Most alert emails sent in an hour; past it they are only logged. Default 20.
# ALERT_MAX_PER_HOUR=20

# --- Preferred names and portrait artists ---
# Encrypts the preferred names people give on My Account. Comma-separated id:key pairs, each
# key 32 random bytes in base64; the first encrypts, all decrypt (put a new key first to
# rotate). Keep it safe: lose it and stored names cannot be read. Without it, preferred
# names cannot be saved. Generate: echo "k1:$(openssl rand -base64 32)"
PROFILE_ENCRYPTION_KEYS=
#
# Portrait artist credits and accounts, as JSON (see ARTISTS.md). An "account" email gets an
# artist account and a welcome email when the server starts, so leave real addresses out of
# a test server unless that is wanted. Artist emails link to APP_URL (Branding, below).
# PORTRAIT_ARTISTS={"house-pack": {"name": "Fusspot", "account": "artist@example.test"}}
# Who hears about artist account changes (falls back to EMAIL_ERRORS_TO, then APP_SUPPORT_EMAIL).
# EMAIL_ADMIN_TO=
#
# Where the server keeps its drawings of shared-link portraits (default: orcpub-portraits in the
# system temp directory, which the Docker image's user can write). Point several containers at one shared volume and each portrait is
# drawn once for all of them. They are derived files: deleting them only means they are drawn again.
# Mount a shared volume at this path; the image creates it for the app's user.
# PORTRAIT_STORE_DIR=/var/lib/orcpub/portraits

# --- Capacity (optional) ---
# Defaults suit most servers; see docs/ENVIRONMENT.md "Capacity" before raising them.
# Requests of any kind handled at once. Default: Pedestal's own (50 on most machines).
# ORCPUB_HTTP_MAX_THREADS=50
# Character sheets generated at once. Default: 8, or twice the CPU cores if more.
# ORCPUB_PDF_CONCURRENCY=8
# How long an export waits for a free slot before the player is told to retry, in ms. Default 30000.
# ORCPUB_PDF_QUEUE_TIMEOUT_MS=30000
# How many times the busy page retries an export by itself before waiting for a click. Default 3.
# ORCPUB_PDF_MAX_RETRIES=3
# Most spellcasting sections one sheet can grow to. Default 13 (every class).
# ORCPUB_PDF_MAX_CASTER_SECTIONS=13
# Most cards of each kind one export prints, 9 to a page. Default 198 (22 pages).
# ORCPUB_PDF_MAX_CARDS=198
# Shared-link portrait images drawn at once. Default: half the CPU cores, at least 2.
# ORCPUB_PORTRAIT_CONCURRENCY=2
# How long a portrait image waits to be drawn before the request is refused, in ms. Default 5000.
# ORCPUB_PORTRAIT_QUEUE_TIMEOUT_MS=5000

# --- Share links and passwords (optional) ---
# Largest compressed homebrew one character's share link keeps, in KB. Default 64.
# ORCPUB_SHARE_MAX_UPLOAD_KB=64
# Largest that homebrew may be once unpacked, in KB. Default 256.
# ORCPUB_SHARE_MAX_TEXT_KB=256
# Shared homebrew one account keeps across all its characters, in KB. Default 1024.
# ORCPUB_SHARE_MAX_ACCOUNT_KB=1024
# Days a share link may go unused before it is deleted (the character never is). 0 keeps them. Default 180.
# ORCPUB_SHARE_PRUNE_DAYS=180
# Check new passwords against known breaches (Have I Been Pwned). on or off. Default on.
# ORCPUB_PWNED_CHECK=on

# --- Branding (optional) ---
# Override app identity for forks. All have sensible defaults in fork/branding.clj.
# The site's name, logos, links and email identity. Each has a default in fork/branding.clj;
# a value set here overrides it. See docs/BRANDING-AND-INTEGRATIONS.md.
# Site name, used in titles, emails and the legal pages.
# APP_NAME=Dungeon Master's Vault
# Public address of the site; links in emails and share previews point here.
# APP_URL=https://www.dungeonmastersvault.com
# Logo in the header and splash page: a path on this site or a web address.
# APP_LOGO_PATH=/image/dmv-logo.svg
# Picture shown when a link to the site is shared on social media.
# APP_OG_IMAGE=/image/dmv-box-logo.png
# Name in the footer's copyright line, the year shown, and where the name links to.
# APP_COPYRIGHT_HOLDER=Dungeon Master's Vault
# APP_COPYRIGHT_YEAR=2026
# APP_COPYRIGHT_URL=https://www.dungeonmastersvault.com
# Name emails come from, and who the friendlier emails are signed by.
# APP_EMAIL_SENDER_NAME=Dungeon Master's Vault Team
# APP_EMAIL_SIGNOFF=The Dungeon Master's Vault Team
# Browser tab title, and the one-line description used in search and link previews.
# APP_PAGE_TITLE=Dungeon Master's Vault
# APP_TAGLINE=A D&D 5e character builder and resource compendium
# Contact address shown to players and on the privacy page. Empty hides it.
# APP_SUPPORT_EMAIL=thDM@dungeonmastersvault.com
# Help link in the footer. Empty hides it.
# APP_HELP_URL=https://www.dungeonmastersvault.com/help/
# Longest a player may type: character notes, text fields, number fields. Defaults 50000, 255, 7.
# APP_FIELD_LIMIT_NOTES=50000
# APP_FIELD_LIMIT_TEXT=255
# APP_FIELD_LIMIT_NUMBER=7

# --- Social Links (optional) ---
# Shown in app header. Leave empty to hide a link.
Expand Down
Loading
Loading