Skip to content

chore(deps)!: upgrade acton-service 0.34.1 -> 0.35.0 - #126

Merged
rrrodzilla merged 2 commits into
devfrom
chore/acton-service-0.35.0
Aug 4, 2026
Merged

chore(deps)!: upgrade acton-service 0.34.1 -> 0.35.0#126
rrrodzilla merged 2 commits into
devfrom
chore/acton-service-0.35.0

Conversation

@rrrodzilla

Copy link
Copy Markdown
Contributor

Branched from dev, so this is independent of #125 (hook transport security). Whichever lands second will need a trivial rebase — they touch different files apart from Cargo.lock.

What reaches us

0.35.0 bumps acton-reactive 8.1.1 → 9.0.0. Two things affect this workspace.

AppState::actor returns an owned Option<ActorHandle>, not a borrow — because a restart replaces the actor and a stored handle would silently go stale. Every route handler already resolved the handle per request, which is exactly the pattern that change is designed for, so this is mechanical: 18 call sites in routes/entities.rs and routes/schemas.rs now pass &forge to the helpers that borrow it.

ActorExtension::restart_policy is now actually read. This is the part worth reviewing. Before 0.35.0 the spawner used the legacy supervise(), which never consulted the policy and registered children with no blueprint, so no extension could be restarted at all — the declared policy was inert. The default Permanent is now live for the first time, and the two extensions here want opposite answers.

HookDispatchActor → stays Permanent

struct HookDispatchActor; carries no state; every input travels with the DispatchHook message. A replacement rebuilt from Default is indistinguishable from the original. This is a genuine gain — post-commit hook dispatch now survives a handler panic.

ForgeActor → opts out with Temporary

configure registers handlers but sets no state. The registry, backend, tenant config, policy store, storage registry and hook dispatcher all arrive in the single InitForge that serve sends at boot, and nothing would ever send a second one.

So a restarted ForgeActor would come back with an empty registry and no backend: a process that stays up and answers 404 schema not found on every entity route. That is fail-closed — the empty policy_store denies everything — but it points an operator at a data problem when the actual fault is a dead actor. Declining the restart keeps the failure legible (the handle resolves to None, routes answer 500 naming the missing actor) and preserves 0.34.1 behaviour, where no restart was possible.

Making ForgeActor genuinely restartable means giving it a way to re-initialise from the backend. That is its own change, not a side effect of a version bump — happy to file it if you want it.

Test choice

a_restarted_forge_actor_would_be_unusable asserts the condition behind the policy (no backend, empty registry, no policy store after Default), not just the policy value. The acton-service commit itself notes the old policy was "declared, documented, unit-tested for its return value, and consumed by nothing" — a return-value test is the weak version. This one fails if someone later teaches the actor to self-initialise, which is the moment the policy should be revisited.

Verification

2166 tests pass (+2), clippy clean workspace-wide with --features surrealdb.

0.35.0 bumps acton-reactive 8.1.1 -> 9.0.0. Two things reach this
workspace.

`AppState::actor` now returns an owned `Option<ActorHandle>` rather
than a borrow, because a restart replaces the actor and a stored handle
would silently go stale. Every route handler already resolved the
handle per request, which is the pattern that change is designed for,
so the migration is mechanical: 18 call sites in `routes/entities.rs`
and `routes/schemas.rs` now pass `&forge` to the helpers that borrow it.

`ActorExtension::restart_policy` is now actually read. Before 0.35.0 the
spawner used the legacy `supervise()`, which never consulted the policy
and registered children with no blueprint, so no extension could be
restarted at all. The declared policy was inert.

That makes the default `Permanent` live for the first time, and the two
extensions here want opposite answers:

`HookDispatchActor` stays `Permanent`. It is `struct HookDispatchActor;`
— every input travels with the `DispatchHook` message, so a replacement
rebuilt from `Default` is indistinguishable from the original. This is a
real gain: post-commit hook dispatch now survives a handler panic.

`ForgeActor` opts out with `Temporary`. Its `configure` registers
handlers but sets no state — registry, backend, tenant config, policy
store, storage registry and hook dispatcher all arrive in the single
`InitForge` that `serve` sends at boot, and nothing would ever send a
second one. A restarted `ForgeActor` would come back with an empty
registry and no backend, leaving a process that stays up and answers
404 on every entity route. That is fail-closed, but it points an
operator at a data problem when the fault is a dead actor. Declining
the restart keeps the failure legible and preserves 0.34.1 behaviour,
where no restart was possible. Making `ForgeActor` restartable means
giving it a way to re-initialise from the backend; that is its own
change, not a side effect of a version bump.

`a_restarted_forge_actor_would_be_unusable` pins the condition rather
than the policy value, so teaching the actor to self-initialise fails
the test and prompts revisiting the policy instead of quietly diverging
from its rationale.

2166 tests pass, clippy clean with --features surrealdb.
…35.0

# Conflicts:
#	crates/schema-forge-acton/Cargo.toml
@rrrodzilla
rrrodzilla merged commit 9ca0990 into dev Aug 4, 2026
1 check passed
@rrrodzilla
rrrodzilla deleted the chore/acton-service-0.35.0 branch August 4, 2026 16:15
rrrodzilla added a commit that referenced this pull request Aug 4, 2026
Release v0.36.0 — authenticated hook transport (PR #125) and the
acton-service 0.34.1 -> 0.35.0 upgrade (PR #126).

Minor bumps, both crates. `schema-forge-acton` gains public surface
(`hooks::credential`, `HooksConfig::{allow_plaintext, client_identity}`,
`HookError::InsecureEndpoint`) and changes hook dispatch behaviour:
plaintext endpoints are now refused at startup and every hook RPC
carries a per-call PASETO bearer. `schema-forge-cli` changes what
`hooks generate` emits: the scaffold boots through `ServiceBuilder`
with a live `[token]` section instead of a bare tonic server, so a
generated hook service authenticates its callers out of the box.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant