<feed xmlns='http://www.w3.org/2005/Atom'>
<title>cccms/Gemfile, branch master</title>
<subtitle>[no description]</subtitle>
<id>http://erdgeist.org/gitweb/cccms/atom?h=master</id>
<link rel='self' href='http://erdgeist.org/gitweb/cccms/atom?h=master'/>
<link rel='alternate' type='text/html' href='http://erdgeist.org/gitweb/cccms/'/>
<updated>2026-08-03T12:18:10Z</updated>
<entry>
<title>Bump ruby to 3.4.10</title>
<updated>2026-08-03T12:18:10Z</updated>
<author>
<name>erdgeist</name>
<email>erdgeist@erdgeist.org</email>
</author>
<published>2026-08-03T12:18:10Z</published>
<link rel='alternate' type='text/html' href='http://erdgeist.org/gitweb/cccms/commit/?id=a74e40be88cd1331155c967656e393618e88cd27'/>
<id>urn:sha1:a74e40be88cd1331155c967656e393618e88cd27</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Keep a linter handy, but disable by default, its deps list is enormous</title>
<updated>2026-07-24T20:07:07Z</updated>
<author>
<name>erdgeist</name>
<email>erdgeist@erdgeist.org</email>
</author>
<published>2026-07-24T20:07:07Z</published>
<link rel='alternate' type='text/html' href='http://erdgeist.org/gitweb/cccms/commit/?id=215279dfb003163a7938ba948082363c105e888f'/>
<id>urn:sha1:215279dfb003163a7938ba948082363c105e888f</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Add TOTP enrollment and verification to User, witnessed in the action log</title>
<updated>2026-07-24T11:11:51Z</updated>
<author>
<name>erdgeist</name>
<email>erdgeist@erdgeist.org</email>
</author>
<published>2026-07-24T11:11:51Z</published>
<link rel='alternate' type='text/html' href='http://erdgeist.org/gitweb/cccms/commit/?id=02e1aefa24cdd0339995d14431713822f4bf4718'/>
<id>urn:sha1:02e1aefa24cdd0339995d14431713822f4bf4718</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Implement transparent password hash migration</title>
<updated>2026-07-17T16:12:25Z</updated>
<author>
<name>erdgeist</name>
<email>erdgeist@erdgeist.org</email>
</author>
<published>2026-07-16T17:45:42Z</published>
<link rel='alternate' type='text/html' href='http://erdgeist.org/gitweb/cccms/commit/?id=95049fdd5e96e046e7ab8309a3a739d3cd94b497'/>
<id>urn:sha1:95049fdd5e96e046e7ab8309a3a739d3cd94b497</id>
<content type='text'>
Add has_secure_password and bcrypt while retaining compatibility with
legacy SHA-1 password hashes. Existing users are upgraded to
password_digest on their next successful login.

Add regression tests covering both legacy and modern authentication
paths.
</content>
</entry>
<entry>
<title>Add rails_icons (Tabler) for SVG iconography</title>
<updated>2026-07-12T21:41:52Z</updated>
<author>
<name>erdgeist</name>
<email>erdgeist@erdgeist.org</email>
</author>
<published>2026-07-12T21:41:52Z</published>
<link rel='alternate' type='text/html' href='http://erdgeist.org/gitweb/cccms/commit/?id=d320f8509751a886adb3ca723ebfafccaa8c191b'/>
<id>urn:sha1:d320f8509751a886adb3ca723ebfafccaa8c191b</id>
<content type='text'>
Vendors the Tabler outline/filled icon sets via rails_icons' sync
mechanism rather than a hand-rolled SVG set or a webfont -- this app
had no icon system of any kind before. Icons are committed like any
other static asset; re-syncing is only needed when adding an icon
that isn't vendored yet, via the new `make sync_icons` target.
</content>
</entry>
<entry>
<title>Retire vendored cacycle_diff.js for a diff-lcs-based diff view</title>
<updated>2026-07-09T22:35:24Z</updated>
<author>
<name>erdgeist</name>
<email>erdgeist@erdgeist.org</email>
</author>
<published>2026-07-09T22:35:24Z</published>
<link rel='alternate' type='text/html' href='http://erdgeist.org/gitweb/cccms/commit/?id=a25d90335ad3738b6831288190132c2f7498465c'/>
<id>urn:sha1:a25d90335ad3738b6831288190132c2f7498465c</id>
<content type='text'>
Revisions#diff now computes an inline or side-by-side word diff
server-side (Page#diff_against, lib/html_word_diff.rb) instead of
shipping raw/escaped content to the browser for a 2008-era vendored
JS differ to mangle. View mode is picked via a `view` param, settable
either on the diff page itself or directly from the revisions#index
sticky bar next to "Diff revisions".

Also fixes a pre-existing bug in RevisionsController#diff's single-
revision branch, which set params[:start]/params[:end] instead of
params[:start_revision]/params[:end_revision].
</content>
</entry>
<entry>
<title>Replace awesome_nested_set with a plain parent_id-based NestedTree concern</title>
<updated>2026-07-07T00:46:37Z</updated>
<author>
<name>erdgeist</name>
<email>erdgeist@erdgeist.org</email>
</author>
<published>2026-07-07T00:46:37Z</published>
<link rel='alternate' type='text/html' href='http://erdgeist.org/gitweb/cccms/commit/?id=7b6af89509e8439fe2474e623ee97e4db67ab011'/>
<id>urn:sha1:7b6af89509e8439fe2474e623ee97e4db67ab011</id>
<content type='text'>
Root-caused this session: appending a child to any node never widened
that parent's own rgt boundary, on the pinned revision (Gemfile tracked
main directly, chasing a too-conservative gemspec constraint - not, as
first assumed, a deliberate pin to avoid a known bug). Reproduced
cleanly on a single ordinary create with no concurrency and no bulk
operation involved, confirmed via the gem's own SetValidator, then
confirmed as the root cause of nodes_controller_test.rb's 3 long-standing
"pre-existing" failures - not three separate mysteries, one bug.

admin_controller's sitemap needed its own real conversion, not just a
drop-in: awesome_nested_set's lft column implicitly provided correct
depth-first tree order for free, which the old code combined with a
separate class-level each_with_level iterator. Both replaced by one
method, self_and_descendants_ordered_with_level, computing an ordered
[node, level] list in a single query-then-walk pass - checked against
the actual view template first (admin/index.html.erb) rather than
assumed, since it relies on list order alone to render correct visual
nesting.

lft/rgt/depth columns intentionally left in schema, unused - dropping
them is a separate, deliberately deferred migration once this is proven
running for a while, not bundled with the behavior change.
</content>
</entry>
<entry>
<title>Stage 7: Rails 7.2 → 8.1 on Ruby 3.2.11</title>
<updated>2026-06-27T14:58:53Z</updated>
<author>
<name>erdgeist</name>
<email>erdgeist@erdgeist.org</email>
</author>
<published>2026-06-27T14:58:53Z</published>
<link rel='alternate' type='text/html' href='http://erdgeist.org/gitweb/cccms/commit/?id=420506e58fdfc84f1a5bede0a01dedf0af3bb4f3'/>
<id>urn:sha1:420506e58fdfc84f1a5bede0a01dedf0af3bb4f3</id>
<content type='text'>
- Bump Rails to 8.1.3 (Ruby unchanged at 3.2.11, new gemset rails8-upgrade)
- config.load_defaults 8.1; merge app:update diffs for all environment files
- Remove routing-filter 0.7.0; replace with native scope '(:locale)' in
  routes.rb and default_url_options in ApplicationController
- Delete config/initializers/routing_filter_rails71_patch.rb
- Replace vendored TinyMCE 3.x (~200 files) with tinymce-rails ~&gt; 8.3;
  migrate admin_interface.js from jQuery .tinymce()/advanced theme to
  tinymce.init(); add config/tinymce.yml; note: TinyMCE 7+ is GPL
- rails-i18n ~&gt; 8.0 added explicitly (previously indirect dependency)
- awesome_nested_set, acts-as-taggable-on pinned to git main/master
  (gemspec activerecord &lt; 8.1 ceiling; no functional incompatibility;
  repin to version once upstream releases updated gemspecs)
- globalize ~&gt; 7.0, libxml-ruby ~&gt; 5.0, nokogiri ~&gt; 1.18, pg ~&gt; 1.5
- sass-rails, coffee-rails, uglifier moved from :assets group to main
  (Sprockets 4 convention; :assets group no longer meaningful)
- Node: head, draft, lock_owner marked belongs_to optional: true
- Page: node, user, editor marked belongs_to optional: true
- Static assets in public/images/ and public/javascripts/ referenced via
  plain HTML tags; Rails 8 load_defaults raises on pipeline helpers for
  undeclared assets
- sessions_controller_test.rb: remove stale require and dead rescue_action
- users_controller_test.rb: assert button[type=submit] not input[type=submit]
  (Rails 8 button_to renders &lt;button&gt; not &lt;input&gt;)
- test_helper.rb: node.reload after children.create! (awesome_nested_set
  3.9.0 does not refresh parent in memory after callback)
- 129 runs, 339 assertions, 3 failures, 0 errors — identical baseline to 7.2
</content>
</entry>
<entry>
<title>Update pg gem to ~&gt; 1.5 now that PostgreSQL 16 is in use</title>
<updated>2026-06-26T19:49:46Z</updated>
<author>
<name>Charlie Root</name>
<email>root@web.ccc-migrate-target.local</email>
</author>
<published>2026-06-26T19:49:46Z</published>
<link rel='alternate' type='text/html' href='http://erdgeist.org/gitweb/cccms/commit/?id=7c19e71780128fabd60a49960a3a829fa5f3287c'/>
<id>urn:sha1:7c19e71780128fabd60a49960a3a829fa5f3287c</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Fix minitest gem group placement</title>
<updated>2026-06-26T16:38:21Z</updated>
<author>
<name>erdgeist</name>
<email>erdgeist@erdgeist.org</email>
</author>
<published>2026-06-26T16:38:21Z</published>
<link rel='alternate' type='text/html' href='http://erdgeist.org/gitweb/cccms/commit/?id=89a5804e30abe9231d1be9fc45cc50b219fe1d7a'/>
<id>urn:sha1:89a5804e30abe9231d1be9fc45cc50b219fe1d7a</id>
<content type='text'>
</content>
</entry>
</feed>
