solid_objects 0.14.6 → 0.14.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0616851aa1c44a26313dac95fa3f868324910a64a7023435d2c2b6aed83b7610'
4
- data.tar.gz: b54b99a40ee18b68f7d6b7f21eb9879c92a867b0715a52647f4f58b4f35997d9
3
+ metadata.gz: d36e77947a8de94216c9174cc3a34a878803bdf242efa0b10f6067d48b4e7cda
4
+ data.tar.gz: 178955e77093552df5569ee5c0badfb6035a51a479c7bcfbd1025465ac5947a4
5
5
  SHA512:
6
- metadata.gz: 5a1a03e584ad3305114993f1898294ebcc719330d2ea6466aa29b38b218bae50fca92394cc57dac95dd8f584da6c506a57f7c145d4238ed2c06e0411a93fa4a8
7
- data.tar.gz: 45b4818bc0beb1de4697155bd438c58bc3432e2d40e93c1deb6ff6db5c295d54fe9994e021ff5f7167564a3444fd2b8918b669f2dc550a88985b53e57f55d96c
6
+ metadata.gz: 491698862debab8266650dbdc21a86561d3fa7dd51764edd469a7b5173a1b2a24a2542d39a584796d3433a2bc66794d7d5251ebfe73d7c991d539f2a4c92d287
7
+ data.tar.gz: 705ce841595e49cbc892535afd15fb96b8ac4134bb01a1c92de8d12061a6fe5717b745d989decf82fb1c25a19966b9e50a88afb30a1426c23055e1333c00f2cc
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.14.7 - 2026-09-14
4
+
5
+ - Publish RBS contracts for effect callback envelopes and Ruby error summaries.
6
+ Check the runtime constructors and packaged consumer signatures strictly,
7
+ preserving ordinary hashes, keyword callbacks, serialization, and retries.
8
+ - Add optional actor-specific RBS generation for staged schedule/transmit calls
9
+ and effect callback names. Reuse application-declared operation argument types
10
+ without changing Ruby dispatch, runtime validation, or global effect registries.
11
+
3
12
  ## 0.14.6 - 2026-09-12
4
13
 
5
14
  - Preserve committed turns when an Active Record after-commit callback raises.
data/Rakefile CHANGED
@@ -14,7 +14,7 @@ task :rbs do
14
14
  FileUtils.rm_rf(File.expand_path("sig/generated", __dir__))
15
15
  sh "bundle exec rbs-inline --base lib --base app --output sig/generated lib app"
16
16
  FileUtils.rm_f(File.expand_path("sig/generated/lib/generators/solid_objects/templates/solid_objects.rbs", __dir__))
17
- sh "bundle exec rbs -I sig/generated -I sig/support validate"
17
+ sh "bundle exec rbs -I sig/generated -I sig/support -I sig/public validate"
18
18
  end
19
19
 
20
20
  desc "Run Standard Ruby"
data/docs/architecture.md CHANGED
@@ -443,6 +443,10 @@ a dead letter.
443
443
 
444
444
  `emit` creates a staged effect:
445
445
 
446
+ Typed applications can generate [actor-specific RBS signatures](development.md#actor-specific-dispatch-signatures)
447
+ to check callback names and staged `schedule`/`transmit` calls without changing
448
+ their Ruby syntax. Effect and commit-action registry names remain independent.
449
+
446
450
  ```ruby
447
451
  emit(
448
452
  :charge_payment,
@@ -483,6 +487,50 @@ and `result:`. A failure callback receives `effect_id:`, `arguments:`, and
483
487
  `error:`, so an actor can correlate concurrent effects without storing a
484
488
  separate callback ledger.
485
489
 
490
+ ### Typing your on_failure handler
491
+
492
+ The gem ships `SolidObjects::effect_error`,
493
+ `SolidObjects::effect_failure_payload[Arguments]`, and
494
+ `SolidObjects::effect_success_payload[Arguments, Result]` as public RBS aliases.
495
+ They describe the existing string-keyed hashes; they are not Ruby wrapper classes.
496
+ See [signature loading](development.md#public-effect-payload-signatures) for Steep setup.
497
+
498
+ For an actor with `generation` and `status` attributes, declare the callback keywords
499
+ in the application's RBS:
500
+
501
+ ```rbs
502
+ class ChatRun < SolidObjects::Actor
503
+ type run_arguments = { "generation" => Integer }
504
+ def fail_turn: (effect_id: String, arguments: run_arguments, error: SolidObjects::effect_error) -> void
505
+ end
506
+ ```
507
+
508
+ ```ruby
509
+ def fail_turn(effect_id:, arguments:, error:)
510
+ return unless arguments["generation"] == generation
511
+
512
+ self.status = "failed"
513
+ end
514
+ ```
515
+
516
+ Record access with `arguments["generation"]` retains its declared `Integer` type.
517
+ The callback receives top-level keywords, while nested arguments and error keys
518
+ remain strings. The failure envelope requires `"effect_id"`, `"arguments"`, and
519
+ `"error"`; the success envelope replaces `"error"` with `"result"`. Empty original
520
+ arguments remain `{}`, and a success result may be `nil` or any supported JSON value.
521
+ Ruby errors contain `"class"` (`String?`, including anonymous exception classes),
522
+ `"message"` (`String`, limited to 8,192 bytes), and `"backtrace"` (`Array[String]`,
523
+ limited to 50 entries and possibly empty).
524
+
525
+ Applications supply the generic argument/result types to describe their serialized
526
+ JSON values. These aliases do not infer or validate independently registered effect
527
+ handlers. Their type parameters are deliberately unconstrained: Ruby serialization
528
+ accepts and normalizes values such as symbols, and RBS cannot express that conversion
529
+ as a generic bound. The constructors and consumer fixtures are checked with strict
530
+ Steep diagnostics. JavaScript exposes equivalent contracts with its existing
531
+ camelCase ID and `{ name, message }` error shape in
532
+ [solid-objects-js#47](https://github.com/cardmagic/solid-objects-js/issues/47).
533
+
486
534
  A commit action is registered the same way and runs inside the short fenced
487
535
  transaction:
488
536
 
data/docs/development.md CHANGED
@@ -103,6 +103,116 @@ bundle exec rake rbs
103
103
 
104
104
  This follows the inline convention used by `cardmagic/classifier`.
105
105
 
106
+ ### Public effect payload signatures
107
+
108
+ The packaged `sig/public` directory owns the reusable effect payload aliases and
109
+ survives `rake rbs` regeneration. A host application's Steep target can load the
110
+ installed gem's complete signature tree alongside its own signatures:
111
+
112
+ ```ruby
113
+ target :app do
114
+ library "solid_objects"
115
+ signature "sig"
116
+ check "app/actors"
117
+ configure_code_diagnostics(Diagnostic::Ruby.strict)
118
+ end
119
+ ```
120
+
121
+ This requires no internal runtime imports. See the
122
+ [typed callback example](architecture.md#typing-your-on_failure-handler).
123
+ The gem's strict payload target checks the actual constructors; its packaged
124
+ consumer test also verifies that missing keys and incorrect field types fail.
125
+
126
+ ### Actor-specific dispatch signatures
127
+
128
+ Typed applications can opt into `SolidObjects::ActorSignatures` to check ordinary
129
+ `schedule`, `transmit`, and effect callback names inside actor methods. Add `rbs`
130
+ and `steep` to the application's development dependencies. This tool is loaded
131
+ explicitly and is not required by workers or ordinary Ruby applications.
132
+
133
+ Declare application operation types first, including inherited operations and
134
+ block-defined `message` operations. Inline RBS can generate this input, or keep
135
+ handwritten declarations in a separate directory such as `sig/actors`:
136
+
137
+ ```rbs
138
+ class ChatRun < SolidObjects::Actor
139
+ def recover_if_stuck: (generation: Integer) -> nil
140
+ def fail_turn: (effect_id: String, arguments: Hash[String, untyped], error: Hash[String, untyped]) -> nil
141
+ def start: () -> nil
142
+ end
143
+ ```
144
+
145
+ After loading the application's actor classes, generate a separate output file:
146
+
147
+ ```ruby
148
+ require "solid_objects/actor_signatures"
149
+
150
+ Rails.application.reloader.wrap do
151
+ signatures = SolidObjects::ActorSignatures.generate(
152
+ actors: [ChatRun],
153
+ signatures: [Rails.root.join("sig/actors").to_s]
154
+ )
155
+ FileUtils.mkdir_p(Rails.root.join("sig/generated"))
156
+ File.write(Rails.root.join("sig/generated/solid_objects.rbs"), signatures)
157
+ end
158
+ ```
159
+
160
+ Run that script with `bin/rails runner` during development or CI. Outside Rails,
161
+ require the actor definitions and call `generate` directly. The generator returns
162
+ a string and does not write files, execute actor operations, start workers, or run
163
+ migrations. Rails boot follows the application's normal loading configuration;
164
+ the explicit actor list resolves its autoloaded classes within the reloader boundary.
165
+ Keep generated output out of the input signature paths, and regenerate after a
166
+ message is renamed or removed. Output is deterministic; handwritten signatures
167
+ remain separate.
168
+
169
+ Load the gem and both application signature directories in `Steepfile`:
170
+
171
+ ```ruby
172
+ target :actors do
173
+ library "solid_objects"
174
+ signature "sig/actors"
175
+ signature "sig/generated"
176
+ check "app/actors"
177
+ configure_code_diagnostics(Diagnostic::Ruby.strict)
178
+ end
179
+ ```
180
+
181
+ The usual Ruby code now passes Steep without a dispatcher cast:
182
+
183
+ ```ruby
184
+ schedule(at: Time.now, key: "watchdog").recover_if_stuck(generation: 1)
185
+ transmit.recover_if_stuck(generation: 1)
186
+ emit :run_model, generation: 1, on_failure: :fail_turn
187
+ ```
188
+
189
+ Misspelled operations/callbacks, queries, attributes, private methods, infrastructure
190
+ methods, and incorrect keyword arguments fail the strict check. Both string and
191
+ symbol callback literals work. Staging returns `nil` even when an operation's own
192
+ return type differs. Effect and commit-action names remain global registry names;
193
+ registry contract inference is separate work.
194
+
195
+ Reflection supplies message names only. Values come from declared RBS signatures;
196
+ missing signatures and positional/block arguments are rejected. Block-defined
197
+ messages require explicit method declarations in RBS; annotate their block-local
198
+ values separately when checking the block body. Generic actor classes currently
199
+ require application-owned dispatcher signatures. The generator preserves method
200
+ overloads and method type parameters.
201
+
202
+ Deliberately dynamic names can use Ruby's explicit dynamic dispatch:
203
+
204
+ ```ruby
205
+ schedule(at: Time.now).public_send(operation_name, generation: generation)
206
+ public_send(:emit, :run_model, on_failure: callback_name, generation: generation)
207
+ ```
208
+
209
+ Those calls opt out of name/argument checking and retain the existing runtime
210
+ validation. Ordinary calls on the generated dispatcher have no string-name fallback.
211
+ `send_to`, `Reference#async`, direct calls, and queries retain their existing
212
+ signatures and runtime behavior; this generator does not provide complete reference
213
+ typing or Sorbet/Tapioca actor-specific RBI generation. The corresponding TypeScript
214
+ work is tracked in [solid-objects-js#46](https://github.com/cardmagic/solid-objects-js/issues/46).
215
+
106
216
  ## Formatting and security
107
217
 
108
218
  ```bash
data/docs/operations.md CHANGED
@@ -69,6 +69,12 @@ Rails schema migrations and actor state migrations are separate concerns.
69
69
 
70
70
  ### Host application tooling
71
71
 
72
+ RBS/Steep applications can generate
73
+ [actor-specific dispatch signatures](development.md#actor-specific-dispatch-signatures)
74
+ for reminders, transmit calls, and effect callback names. This is optional development
75
+ tooling; generated signatures do not change runtime dispatch. The generator does
76
+ not supply equivalent Sorbet/Tapioca actor-specific types.
77
+
72
78
  Installed engine migrations are copied as
73
79
  `db/migrate/*_create_solid_objects_tables.solid_objects.rb`. If the host enables
74
80
  `Rails/CreateTableWithTimestamps`, exclude engine-owned migrations rather than
data/docs/reminders.md CHANGED
@@ -39,6 +39,14 @@ raises, and nothing is logged except a `solid_objects.reminder.replaced` event.
39
39
 
40
40
  ## An alarm per item, with `key:`
41
41
 
42
+ For watchdogs paired with an effect's give-up callback, see
43
+ [typing your `on_failure` handler](architecture.md#typing-your-on_failure-handler)
44
+ to retain the original argument types without repeating the error hash contract.
45
+
46
+ For static checking of watchdog operation names and keyword arguments, opt into
47
+ [actor-specific RBS signatures](development.md#actor-specific-dispatch-signatures).
48
+ The Ruby `schedule(...).recover_if_stuck(generation: ...)` syntax stays the same.
49
+
42
50
  Pass `key:` when an actor is waiting on several things at once. The key is your
43
51
  own identifier for the item, and it names that item's alarm, so each item gets
44
52
  one:
data/docs/roadmap.md CHANGED
@@ -14,6 +14,8 @@
14
14
  dead letters, and tail retry
15
15
  - Transactional effects with success/failure actor messages carrying the
16
16
  originally staged arguments for callback correlation
17
+ - Public RBS effect success/failure envelopes and error records, checked against
18
+ the runtime constructors and a packaged consumer with strict Steep diagnostics
17
19
  - Actor-to-actor asynchronous outbox delivery. Effects and broadcasts use
18
20
  portable status rows with polling indexes and database check constraints on
19
21
  status, which works on all three adapters; a future version may add narrow
@@ -65,6 +67,10 @@
65
67
  gem's dependencies
66
68
  - Inline RBS generation/validation, Steep, Standard Ruby, Solid Queue's exact
67
69
  RuboCop policy, and a warning-free Brakeman scan
70
+ - Opt-in actor-specific RBS generation for schedule/transmit keyword arguments
71
+ and effect callback names, using application declarations and checked consumer
72
+ fixtures. Dynamic names remain an explicit escape hatch; complete reference
73
+ typing and actor-specific RBI generation are separate work
68
74
  - Compatibility CI across the supported span: Ruby 3.3, 3.4, and 4.0 against
69
75
  Rails 7.1, 7.2, 8.0, and 8.1, pinned through `RAILS_VERSION` so the advertised
70
76
  range is verified rather than assumed. The compatibility job runs SQLite only;
@@ -0,0 +1,80 @@
1
+ # rbs_inline: enabled
2
+
3
+ require "solid_objects"
4
+ require "rbs"
5
+ require "pathname"
6
+
7
+ module SolidObjects
8
+ class ActorSignatures
9
+ # @rbs (actors: Array[Class], signatures: Array[String]) -> String
10
+ def self.generate(actors:, signatures:)
11
+ new(signatures:).generate(actors:)
12
+ end
13
+
14
+ # @rbs @builder: untyped
15
+
16
+ # @rbs (signatures: Array[String]) -> void
17
+ def initialize(signatures:)
18
+ loader = RBS::EnvironmentLoader.new
19
+ loader.add(path: Pathname.new(File.expand_path("../../sig", __dir__)))
20
+ signatures.sort.each { |path| loader.add(path: Pathname.new(path)) }
21
+ environment = RBS::Environment.from_loader(loader).resolve_type_names
22
+ @builder = RBS::DefinitionBuilder.new(env: environment)
23
+ end
24
+
25
+ # @rbs (actors: Array[Class]) -> String
26
+ def generate(actors:)
27
+ actors.uniq.sort_by { |actor| actor.name.to_s }.map { |actor| actor_signature(actor) }.join("\n")
28
+ end
29
+
30
+ private
31
+
32
+ # @rbs (untyped) -> String
33
+ def actor_signature(actor)
34
+ unless actor < Actor && actor.name
35
+ raise ArgumentError, "actor signatures require named SolidObjects::Actor subclasses"
36
+ end
37
+
38
+ name = RBS::TypeName.parse("::#{actor.name}")
39
+ definition = @builder.build_instance(name)
40
+ if definition.type_params.any?
41
+ raise ArgumentError, "generic actor classes require application-owned dispatcher signatures"
42
+ end
43
+ messages = actor.definition.messages.keys.sort
44
+ methods = messages.map do |operation|
45
+ method = definition.methods[operation]
46
+ unless method && method.accessibility == :public
47
+ raise ArgumentError, "declare a public RBS signature for #{actor.name}##{operation}"
48
+ end
49
+ types = method.method_types.map { |type| staged_type(type, actor.name, operation).to_s }
50
+ " def #{operation}: #{types.join("\n | ")}"
51
+ end
52
+ callback_names = messages.flat_map { |operation| [ operation.inspect, operation.to_s.inspect ] }
53
+ callbacks = (callback_names + [ "nil" ]).join(" | ")
54
+ <<~RBS
55
+ class #{name}
56
+ interface _SolidObjectsOperations
57
+ #{methods.join("\n")}
58
+ def public_send: (Symbol | String, **untyped) -> nil
59
+ end
60
+
61
+ def schedule: (at: Time, ?every: Numeric?, ?missed: Symbol | String, ?key: (String | Symbol | Integer)?) -> #{name}::_SolidObjectsOperations
62
+ def transmit: () -> #{name}::_SolidObjectsOperations
63
+ def emit: (Symbol | String, ?on_success: (#{callbacks}), ?on_failure: (#{callbacks}), **untyped) -> nil
64
+ end
65
+ RBS
66
+ end
67
+
68
+ # @rbs (untyped, String, Symbol) -> untyped
69
+ def staged_type(method_type, actor_name, operation)
70
+ function = method_type.type
71
+ if !function.is_a?(RBS::Types::Function) || method_type.block ||
72
+ function.required_positionals.any? || function.optional_positionals.any? ||
73
+ function.rest_positionals || function.trailing_positionals.any?
74
+ raise ArgumentError, "#{actor_name}##{operation} must declare keyword-only arguments without a block"
75
+ end
76
+
77
+ method_type.update(type: function.update(return_type: RBS::Types::Bases::Nil.new(location: nil)))
78
+ end
79
+ end
80
+ end
@@ -184,11 +184,11 @@ module SolidObjects
184
184
  effect: locked_effect,
185
185
  operation: locked_effect.success_operation,
186
186
  outcome: "success",
187
- arguments: {
188
- "effect_id" => locked_effect.effect_id,
189
- "arguments" => locked_effect.arguments,
190
- "result" => serialized_result
191
- }
187
+ arguments: EffectPayload.success(
188
+ effect_id: locked_effect.effect_id,
189
+ arguments: locked_effect.arguments,
190
+ result: serialized_result
191
+ )
192
192
  )
193
193
  locked_effect.update!(
194
194
  status: "completed",
@@ -216,21 +216,17 @@ module SolidObjects
216
216
  locked_effect = Effect.lock.find(effect.id)
217
217
  verify_claim!(locked_effect)
218
218
  dead = locked_effect.attempt_count >= locked_effect.max_attempts
219
- error_details = {
220
- "class" => error.class.name,
221
- "message" => error.message.to_s.byteslice(0, 8_192),
222
- "backtrace" => Array(error.backtrace).first(50)
223
- }
219
+ error_details = EffectPayload.error(error)
224
220
  if dead
225
221
  result_message = enqueue_result_message(
226
222
  effect: locked_effect,
227
223
  operation: locked_effect.failure_operation,
228
224
  outcome: "failure",
229
- arguments: {
230
- "effect_id" => locked_effect.effect_id,
231
- "arguments" => locked_effect.arguments,
232
- "error" => error_details
233
- }
225
+ arguments: EffectPayload.failure(
226
+ effect_id: locked_effect.effect_id,
227
+ arguments: locked_effect.arguments,
228
+ error: error_details
229
+ )
234
230
  )
235
231
  end
236
232
  locked_effect.update!(
@@ -0,0 +1,27 @@
1
+ # rbs_inline: enabled
2
+
3
+ module SolidObjects
4
+ module EffectPayload
5
+ class << self
6
+ # @rbs [Arguments, Result] (effect_id: String, arguments: Arguments, result: Result) -> effect_success_payload[Arguments, Result]
7
+ def success(effect_id:, arguments:, result:)
8
+ { "effect_id" => effect_id, "arguments" => arguments, "result" => result }
9
+ end
10
+
11
+ # @rbs [Arguments] (effect_id: String, arguments: Arguments, error: effect_error) -> effect_failure_payload[Arguments]
12
+ def failure(effect_id:, arguments:, error:)
13
+ { "effect_id" => effect_id, "arguments" => arguments, "error" => error }
14
+ end
15
+
16
+ # @rbs (Exception) -> effect_error
17
+ def error(exception)
18
+ message = exception.message.to_s.byteslice(0, 8_192) # : String
19
+ {
20
+ "class" => exception.class.name,
21
+ "message" => message,
22
+ "backtrace" => Array(exception.backtrace).first(50)
23
+ }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,5 +1,5 @@
1
1
  # rbs_inline: enabled
2
2
 
3
3
  module SolidObjects
4
- VERSION = "0.14.6"
4
+ VERSION = "0.14.7"
5
5
  end
data/lib/solid_objects.rb CHANGED
@@ -55,6 +55,7 @@ require "solid_objects/wake_up_adapters/redis"
55
55
  require "solid_objects/wake_up_adapters"
56
56
  require "solid_objects/polling_backoff"
57
57
  require "solid_objects/effect_registry"
58
+ require "solid_objects/effect_payload"
58
59
  require "solid_objects/commit_action_registry"
59
60
  require "solid_objects/lease"
60
61
  require "solid_objects/lease_renewer"
@@ -0,0 +1,24 @@
1
+ # Generated from lib/solid_objects/actor_signatures.rb with RBS::Inline
2
+
3
+ module SolidObjects
4
+ class ActorSignatures
5
+ # @rbs (actors: Array[Class], signatures: Array[String]) -> String
6
+ def self.generate: (actors: Array[Class], signatures: Array[String]) -> String
7
+
8
+ @builder: untyped
9
+
10
+ # @rbs (signatures: Array[String]) -> void
11
+ def initialize: (signatures: Array[String]) -> void
12
+
13
+ # @rbs (actors: Array[Class]) -> String
14
+ def generate: (actors: Array[Class]) -> String
15
+
16
+ private
17
+
18
+ # @rbs (untyped) -> String
19
+ def actor_signature: (untyped) -> String
20
+
21
+ # @rbs (untyped, String, Symbol) -> untyped
22
+ def staged_type: (untyped, String, Symbol) -> untyped
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ # Generated from lib/solid_objects/effect_payload.rb with RBS::Inline
2
+
3
+ module SolidObjects
4
+ module EffectPayload
5
+ # @rbs [Arguments, Result] (effect_id: String, arguments: Arguments, result: Result) -> effect_success_payload[Arguments, Result]
6
+ def self.success: [Arguments, Result] (effect_id: String, arguments: Arguments, result: Result) -> effect_success_payload[Arguments, Result]
7
+
8
+ # @rbs [Arguments] (effect_id: String, arguments: Arguments, error: effect_error) -> effect_failure_payload[Arguments]
9
+ def self.failure: [Arguments] (effect_id: String, arguments: Arguments, error: effect_error) -> effect_failure_payload[Arguments]
10
+
11
+ # @rbs (Exception) -> effect_error
12
+ def self.error: (Exception) -> effect_error
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ module SolidObjects
2
+ type effect_error = {
3
+ "class" => String?,
4
+ "message" => String,
5
+ "backtrace" => Array[String]
6
+ }
7
+
8
+ type effect_failure_payload[Arguments] = {
9
+ "effect_id" => String,
10
+ "arguments" => Arguments,
11
+ "error" => effect_error
12
+ }
13
+
14
+ type effect_success_payload[Arguments, Result] = {
15
+ "effect_id" => String,
16
+ "arguments" => Arguments,
17
+ "result" => Result
18
+ }
19
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solid_objects
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.6
4
+ version: 0.14.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lucas Carlson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-09-12 00:00:00.000000000 Z
11
+ date: 2026-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actioncable
@@ -389,6 +389,7 @@ files:
389
389
  - lib/solid_objects/actor_channel.rb
390
390
  - lib/solid_objects/actor_definition.rb
391
391
  - lib/solid_objects/actor_registry.rb
392
+ - lib/solid_objects/actor_signatures.rb
392
393
  - lib/solid_objects/actor_snapshot.rb
393
394
  - lib/solid_objects/actor_view.rb
394
395
  - lib/solid_objects/administration.rb
@@ -416,6 +417,7 @@ files:
416
417
  - lib/solid_objects/doctor.rb
417
418
  - lib/solid_objects/dom_identity.rb
418
419
  - lib/solid_objects/effect_executor.rb
420
+ - lib/solid_objects/effect_payload.rb
419
421
  - lib/solid_objects/effect_registry.rb
420
422
  - lib/solid_objects/engine.rb
421
423
  - lib/solid_objects/errors.rb
@@ -478,6 +480,7 @@ files:
478
480
  - sig/generated/lib/solid_objects/actor_channel.rbs
479
481
  - sig/generated/lib/solid_objects/actor_definition.rbs
480
482
  - sig/generated/lib/solid_objects/actor_registry.rbs
483
+ - sig/generated/lib/solid_objects/actor_signatures.rbs
481
484
  - sig/generated/lib/solid_objects/actor_snapshot.rbs
482
485
  - sig/generated/lib/solid_objects/actor_view.rbs
483
486
  - sig/generated/lib/solid_objects/administration.rbs
@@ -505,6 +508,7 @@ files:
505
508
  - sig/generated/lib/solid_objects/doctor.rbs
506
509
  - sig/generated/lib/solid_objects/dom_identity.rbs
507
510
  - sig/generated/lib/solid_objects/effect_executor.rbs
511
+ - sig/generated/lib/solid_objects/effect_payload.rbs
508
512
  - sig/generated/lib/solid_objects/effect_registry.rbs
509
513
  - sig/generated/lib/solid_objects/engine.rbs
510
514
  - sig/generated/lib/solid_objects/errors.rbs
@@ -561,6 +565,7 @@ files:
561
565
  - sig/generated/models/solid_objects/ready_message.rbs
562
566
  - sig/generated/models/solid_objects/record.rbs
563
567
  - sig/generated/models/solid_objects/reminder.rbs
568
+ - sig/public/effect_payload.rbs
564
569
  - sig/support/framework.rbs
565
570
  - web/assets/javascripts/application.js
566
571
  - web/assets/javascripts/charts.js