Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
timeout-minutes: 15
services:
redis:
image: public.ecr.aws/docker/library/redis:7
image: mirror.gcr.io/library/redis:7
ports:
- 6379:6379
options: >-
Expand All @@ -87,7 +87,7 @@ jobs:
timeout-minutes: 15
services:
postgres:
image: public.ecr.aws/docker/library/postgres:18
image: mirror.gcr.io/library/postgres:18
env:
POSTGRES_USER: solid_objects
POSTGRES_PASSWORD: solid_objects
Expand Down Expand Up @@ -121,7 +121,7 @@ jobs:
client: [ mysql2, trilogy ]
services:
mysql:
image: public.ecr.aws/docker/library/mysql:8.4
image: mirror.gcr.io/library/mysql:8.4
env:
MYSQL_USER: solid_objects
MYSQL_PASSWORD: solid_objects
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## 1.0.3 - 2026-10-18

- Add `docs/maintenance.md`. It tells you who maintains the gem, how CI checks
each change, how a release is published, what you keep if maintenance
stops, and how to become a maintainer. The README and the comparison pages
now link to this page. They and `docs/versioning.md` no longer state a count
of maintainers. A new test fails when a page states one.

## 1.0.2 - 2026-10-15

- Add two comparison pages in `docs/compare/`: Solid Queue
Expand Down
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
solid_objects (1.0.2)
solid_objects (1.0.3)
actioncable (>= 7.1)
actionpack (>= 7.1)
actionview (>= 7.1)
Expand Down Expand Up @@ -392,7 +392,7 @@ CHECKSUMS
rubocop-rails-omakase (1.1.0) sha256=2af73ac8ee5852de2919abbd2618af9c15c19b512c4cfc1f9a5d3b6ef009109d
ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
solid_objects (1.0.2)
solid_objects (1.0.3)
sqlite3 (2.9.5-aarch64-linux-gnu) sha256=78075b6337d3d182c6d2b4691049ed45cd220826160c9ea18946bf6a1de200dc
sqlite3 (2.9.5-aarch64-linux-musl) sha256=18c801185deb4adc01ddb281e8f672a39e3d1729979ca91e39439cd3eac0402d
sqlite3 (2.9.5-arm-linux-gnu) sha256=1bdfca0c7d63998c60b0f4a8e3c8df2d33800ccc4abd2d612eddbbbc92a4c48b
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ model and when to use it.

**Status.** Version 1.0: the public API follows semantic versioning and does
not break before 2.0. [Versioning](docs/versioning.md) gives the limits of the
promise. First public release: August 6, 2026. One maintainer.
promise. First public release: August 6, 2026.

**Production use.** One first-party application with more than 100,000 users
runs it in production. That is a count of users, not a measure of load. No
Expand Down Expand Up @@ -199,6 +199,7 @@ every claim in [`test/guides/`](test/guides/):
- [Reminders](docs/reminders.md)
- [Reactive ERB](docs/realtime.md)
- [Detailed architecture](docs/architecture.md)
- [Maintenance and continuity](docs/maintenance.md)
- [Detailed documentation](docs/)

The dashboard, benchmarks, migration cookbook, schema, and exhaustive API
Expand Down
2 changes: 1 addition & 1 deletion docs/compare/good-job.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ How it works:

- First public release: August 6, 2026.
- Version 1.0.0: October 13, 2026. The public API follows [semantic versioning](../versioning.md).
- One maintainer.
- [Maintenance and continuity](../maintenance.md) tells you who maintains the project and how a release is made.
- One first-party application with more than 100,000 users runs it in production. That is a count of users, not a measure of load. No production use by other people is known.
- The [benchmarks](../benchmarks.md) are development measurements. Longer soak tests are open work.

Expand Down
2 changes: 1 addition & 1 deletion docs/compare/solid-queue.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ How it works:

- First public release: August 6, 2026.
- Version 1.0.0: October 13, 2026. The public API follows [semantic versioning](../versioning.md).
- One maintainer.
- [Maintenance and continuity](../maintenance.md) tells you who maintains the project and how a release is made.
- One first-party application with more than 100,000 users runs it in production. That is a count of users, not a measure of load. No production use by other people is known.
- The [benchmarks](../benchmarks.md) are development measurements. Longer soak tests are open work.

Expand Down
2 changes: 1 addition & 1 deletion docs/comparisons.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ The problem guides start from the same choices:

## Status

Solid Objects 1.0.0 shipped on October 13, 2026. The first public release was on August 6, 2026. It has one maintainer. One first-party application with more than 100,000 users runs it in production. That is a count of users, not a measure of load. No production use by other people is known. See [versioning](versioning.md).
Solid Objects 1.0.0 shipped on October 13, 2026. The first public release was on August 6, 2026. One first-party application with more than 100,000 users runs it in production. That is a count of users, not a measure of load. No production use by other people is known. See [versioning](versioning.md) and [maintenance and continuity](maintenance.md).
65 changes: 65 additions & 0 deletions docs/maintenance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Maintenance and continuity

This page tells you who maintains Solid Objects, how a release is made, and
what you keep if maintenance stops. It also tells you how to help maintain the
project.

## Who maintains it

Lucas Carlson ([@cardmagic](https://github.com/cardmagic)) is the lead
maintainer of the Ruby gem `solid_objects` and of the npm package
[`solid-objects`](https://github.com/cardmagic/solid-objects-js). The two
packages use the same model and the same correctness contract. A change to the
model goes into both packages, and the
[parity ledger](https://github.com/cardmagic/solid-objects-js/blob/main/docs/parity.md)
records each difference between them.

The same maintainer sells [Solid Objects Pro](https://solidobjects.pro), a
commercial package that batches operations at scale. Pro depends on this gem.
This gem does not depend on Pro, and it needs no account, license key, or
service from the maintainer.

## How a change is checked

CI runs on each push and each pull request:

- The full test suite on SQLite, on each pair of Ruby 3.3, 3.4, or 4.0 and
Rails 7.1, 7.2, 8.0, or 8.1.
- The full test suite on PostgreSQL and on MySQL, with both MySQL clients.
- Standard, RuboCop, RBS, Steep, and Brakeman.

[Compatibility and maturity](virtual-actors.md#compatibility-and-maturity)
lists the supported versions. The [correctness contract](correctness.md) lists
the guarantees that the tests check.

## How a release is made

1. The maintainer pushes a version tag, for example `v1.0.3`.
2. GitHub Actions runs all test jobs again on that tag.
3. If all test jobs pass, GitHub Actions builds the gem and pushes it to
RubyGems with trusted publishing. The repository keeps no RubyGems key.
4. The same job makes a GitHub release and attaches the gem file.

[Versioning](versioning.md) tells you what a release can change.
`CHANGELOG.md` lists each release.

## What you keep if maintenance stops

- **Your data.** Actor state, mailboxes, reminders, and effects are rows in
your application's database. [Database schema](database-schema.md) describes
each table. No service of the maintainer holds your data.
- **The code.** The [MIT License](../MIT-LICENSE) lets anyone use, change,
fork, and publish the code.
- **The checks.** The tests and the CI configuration are in this repository. A
fork can check its changes with the same suite.

## Help maintain Solid Objects

The project wants more maintainers. Experience with Rails, with locks and
transactions in PostgreSQL or MySQL, or with TypeScript and Node.js helps.

1. Read [CONTRIBUTING.md](../CONTRIBUTING.md).
2. Send a small pull request: a fix, a test, or a correction to a guide.
3. After some of your pull requests are merged, open an
[issue](https://github.com/cardmagic/solid-objects-ruby/issues) to ask to
become a maintainer.
4 changes: 2 additions & 2 deletions docs/versioning.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ lists the current minimum versions.

Version 1.0 is a promise about the API. It is not a claim of measured scale.
The [benchmarks](benchmarks.md) are development measurements and do not
guarantee capacity. Longer soak tests are open work. The project has one
maintainer, and no production use by other people is known.
guarantee capacity. Longer soak tests are open work. No production use by
other people is known.

## Releases before 1.0

Expand Down
2 changes: 1 addition & 1 deletion lib/solid_objects/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# rbs_inline: enabled

module SolidObjects
VERSION = "1.0.2"
VERSION = "1.0.3"
end
43 changes: 43 additions & 0 deletions test/unit/maintenance_documents_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# frozen_string_literal: true

require "test_helper"

class MaintenanceDocumentsTest < ActiveSupport::TestCase
ROOT = File.expand_path("../..", __dir__)
MAINTAINER_COUNT = /\b(?:\d+|one|two|three|four|five|six|seven|eight|nine|ten|only|sole|single)\s+maintainers?\b/i

def guide(path)
File.read(File.join(ROOT, path))
end

test "the README links to the maintenance page" do
assert_includes guide("README.md"), "(docs/maintenance.md)"
end

test "the maintenance page names the lead maintainer" do
assert_match(
%r{Lucas Carlson \(\[@cardmagic\]\(https://github\.com/cardmagic\)\) is the lead\s+maintainer},
guide("docs/maintenance.md")
)
end

test "the count pattern finds a count of maintainers in each form" do
[ "One maintainer.", "1 maintainer", "two maintainers", "the only\nmaintainer" ].each do |text|
assert_match MAINTAINER_COUNT, text
end
[ "the lead maintainer", "wants more maintainers", "become a maintainer" ].each do |text|
refute_match MAINTAINER_COUNT, text
end
end

test "no page states a count of maintainers" do
paths = [ "README.md", "CONTRIBUTING.md", *Dir.glob("docs/**/*.md", base: ROOT).sort ]
pages = paths.select { |path| guide(path).match?(MAINTAINER_COUNT) }

assert_empty pages
end

test "the maintenance page tells a contributor how to start" do
assert_includes guide("docs/maintenance.md"), "(../CONTRIBUTING.md)"
end
end
Loading