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
13 changes: 11 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
# Changelog

## Unreleased

## 0.17.2 - 2026-10-08

- The README names the agent guide at the start of Installation, and the agent
guide says that a reminder changes state only when it runs under
`solid_objects start`, so a query must not compute expiry from the clock.
- `docs/agents.md` now tells agents to install the current release instead of
a remembered version, says that step 5 is required before the first call,
shows the two arguments of `reject`, and lists four API mistakes from
agent-written code with the correct form. The gem description now states
the Ruby 3.3 and Rails 7.1 requirement, because agents in the discovery
evaluation claimed Rails 8.0.
- Claim the Context7 library: `context7.json` now carries the library `url` and
the maintainer `public_key`.
- Add the Context7 refresh workflow. A push to `main` that changes the README,
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 (0.17.1)
solid_objects (0.17.2)
actioncable (>= 7.1)
actionpack (>= 7.1)
actionview (>= 7.1)
Expand Down Expand Up @@ -384,7 +384,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 (0.17.1)
solid_objects (0.17.2)
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 @@ -44,7 +44,8 @@ And so much more.

## Installation

Solid Objects requires Ruby 3.3 or newer and Rails 7.1 or newer.
Solid Objects requires Ruby 3.3 or newer and Rails 7.1 or newer. Coding agents
should follow the [agent guide](docs/agents.md), which gives each step in order.

```bash
bundle add solid_objects
Expand Down
20 changes: 20 additions & 0 deletions docs/agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ bin/rails solid_objects:doctor
The generator adds an initializer and copies migrations into the application.
The doctor checks the configuration, the tables, and one real actor round trip.

Install the current release. `bundle add solid_objects` selects it. Do not pin
a version that you remember from earlier work; the API changed between
releases. The current version is on <https://rubygems.org/gems/solid_objects>.

The generated policies deny every call. Do step 5 before you call an actor.

The `json` gem 3.x works only with Active Support 8.1.4 or newer. On Rails
7.1, 7.2, 8.0, or 8.1 before 8.1.4, pin `gem "json", "~> 2"` in the
`Gemfile`. Without the pin, Active Support raises an `ArgumentError`, such as
Expand Down Expand Up @@ -153,11 +159,25 @@ Obey these rules in actor code:
- Use `schedule(at:, key:)` for delayed work. A reminder is one named alarm
for each actor and key. A new `schedule` with the same key moves the alarm.
- Use `reject(code, message)` for a business rule failure that must not retry.
It takes a code and a message, for example
`reject(:room_full, "The room is full")`.
- Do not write Active Record models directly in a handler. The runtime raises
`SolidObjects::ApplicationWriteForbidden`. Use `commit_action` for a short
write in the same database.
- Do not call an external API in a handler. Use `emit` and an effect handler.
- Write each handler so that it can run again. Delivery is at least once.
- A reminder changes state only when it runs, and it runs only while
`solid_objects start` runs. Do not compute expiry from the clock in a query;
read the state that the reminder committed.

Avoid these mistakes:

| Mistake | Correct form |
| --- | --- |
| `schedule(at: deadline)` with no operation after it | `schedule(at: deadline, key: buyer).expire(buyer:)`. `schedule` stages a reminder only when you call an operation on its result |
| `reject "room full"` | `reject(:room_full, "The room is full")` |
| `id` inside an actor | `actor_id`. An actor has no `id` method |
| `register_effect(:name) { \|context, arguments\| ... }` | `register_effect(:name) { \|arguments, context\| ... }`. The arguments come first |

[Reminders](reminders.md) and the [architecture guide](architecture.md) give
the full actor API.
Expand Down
3 changes: 3 additions & 0 deletions examples/quickstart/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ bin/rails db:migrate
bin/rails solid_objects:doctor
```

`bundle add solid_objects` installs the current release. Do not pin an older
version from memory; the API changed between releases.

The generator writes `config/initializers/solid_objects.rb` and copies the
migrations. The migrations add the Solid Objects tables to the application's
existing database.
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 = "0.17.1"
VERSION = "0.17.2"
end
2 changes: 1 addition & 1 deletion solid_objects.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
spec.version = SolidObjects::VERSION
spec.authors = [ "Lucas Carlson" ]
spec.summary = "SQL-backed virtual actors for Ruby on Rails"
spec.description = "Solid Objects is a SQL-backed virtual actor library for Ruby on Rails, with durable state, ordered operations, and automatic activation. It brings the Cloudflare Durable Objects programming model to Rails: addressable objects with ordered mailboxes, fenced activation, per-object reminders, transactional effects, and reactive ERB. It runs on MySQL, PostgreSQL, and SQLite without Redis."
spec.description = "Solid Objects is a SQL-backed virtual actor library for Ruby on Rails, with durable state, ordered operations, and automatic activation. It brings the Cloudflare Durable Objects programming model to Rails: addressable objects with ordered mailboxes, fenced activation, per-object reminders, transactional effects, and reactive ERB. It runs on MySQL, PostgreSQL, and SQLite without Redis, and requires Ruby 3.3 or newer and Rails 7.1 or newer."
spec.homepage = "https://solidobjects.dev/ruby"
spec.license = "MIT"
spec.metadata = {
Expand Down
1 change: 1 addition & 0 deletions test/unit/gem_specification_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class GemSpecificationTest < ActiveSupport::TestCase
assert_match(/virtual actors?/i, @specification.summary)
assert_match(/Rails/, @specification.summary)
assert_match(/SQL-backed virtual actor library for Ruby on Rails/, @specification.description)
assert_match(/requires Ruby 3\.3 or newer and Rails 7\.1 or newer/, @specification.description)
end

test "packages the agent and category guides" do
Expand Down
Loading