Skip to content

runtime: extract the supervised host-actor primitive from the venue adapter#441

Merged
mfw78 merged 1 commit into
dev/m1from
feat/m2-supervised-primitive
Jul 20, 2026
Merged

runtime: extract the supervised host-actor primitive from the venue adapter#441
mfw78 merged 1 commit into
dev/m1from
feat/m2-supervised-primitive

Conversation

@mfw78

@mfw78 mfw78 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Closes #377

What

Extracts the generic supervised host-actor primitive (host::actor::{ActorSlot, SupervisedStore, ActorFault}) out of the venue adapter and generalises provider boot: ProviderKind::install now takes a ProviderInstance and returns Installed { Live | Dead }, ComponentKind replaces ModuleKind with an open Provider(String) spelling resolved against a registered-kinds map (seeded with VenueAdapterKind at boot), and VenueRegistry gained a self-locking install so adapters register through the shared handle instead of the builder. VenueActor is rebuilt on top of SupervisedStore.

Why

AdapterActor/VenueActor special-cased the one provider kind the core knew about; the fuel-refuel, trap-projection and call-serialisation machinery only worked for venue adapters. Lifting it into host::actor and routing manifest kind resolution through a registered-kinds table lets any extension-registered provider reuse the same supervised-store primitive instead of the core baking in a venue-named kind.

Testing

  • nix develop -c cargo fmt --all --check
  • nix develop -c cargo check --workspace --all-features
  • nix develop -c cargo clippy --workspace --all-targets --all-features -- -D warnings
  • nix shell nixpkgs#cargo-nextest -c cargo nextest run --workspace --all-features --no-fail-fast
  • cargo test --doc

Closes #377

AI Assistance

Implemented with AI assistance (Claude Code).

@lgahdl lgahdl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Traced the three riskiest areas (self-locking install, the fuel-refuel/trap-projection generalization, Installed::{Live,Dead} exhaustiveness) and found no correctness bugs — the lock is provably atomic by inspection, trap/refuel messages are byte-identical to the old venue-specific versions, and the one Installed call site is an equality check, not a wildcard. Two things worth a look, both non-blocking:

}
adapters.insert(venue, Arc::new(AsyncMutex::new(invoker)));
Ok(())
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two small things on this one:

  1. Doc gap: nothing here says install takes a synchronous std::sync::Mutex for the duration of a plain HashMap insert, never held across an .await. That's precisely the fact a future reader needs to trust before adding an .await inside this critical section, or wondering whether it can deadlock against the async ActorSlot mutex used elsewhere in this file. Worth a line: // Takes the adapter-map mutex only for the synchronous insert; never held across an await.
  2. Surface: this went from a private builder method (which encoded "install happens before build() consumes self, then you're frozen") to a pub method on the shared, cloneable VenueRegistry handle. Nothing calls it post-boot today, but the type system no longer distinguishes boot-time install from runtime install — a future caller holding a clone can register at any point with no compiler signal. Worth pub(crate) until there's a real post-boot use case, or a boot-only capability/token gating it.

Either is easy to defer; neither blocks this PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both confirmed still valid at HEAD. install (now videre-host/src/registry.rs:348) is still pub on the cloneable handle, and the mutex-discipline doc line is still absent (the std-mutex-not-across-await comment lives on a different method at line 555, not on install). Tracked in #507.

Worker,
/// A provider the host holds behind a serialised actor, named by its
/// manifest spelling.
Provider(String),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ComponentKind::Provider(String) trades the old enum's compile-time-checked kind set for a runtime-checked open string — a reasonable trade for extensibility, but it means toml::from_str on the manifest now always succeeds regardless of spelling; a typo'd kind = "venu-adapter" only surfaces one layer later, at Supervisor::new/boot (the boot_rejects_an_unregistered_provider_kind test confirms this path is covered and gives a good error naming the registered kinds). Just flagging that manifest-parse success no longer implies a routable kind — worth keeping in mind if any future tooling (a standalone manifest lint command, say) assumes parse success is validation success.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still the case at HEAD (manifest/types.rs:226 is still Provider(String)), and by-design: the open provider kind is the extensibility mechanism the extension seam is built on, so a closed enum would defeat it. Validation happens at boot rather than at parse, and boot_rejects_an_unregistered_provider_kind still covers it with an error naming the registered kinds. Leaving as-is; recording the caveat that parse success is not validation success for any future manifest lint-style tooling. (Distinct from #506, which is the closed capability/fault vocabulary that should be enum-typed.)

@mfw78
mfw78 force-pushed the feat/m2-nexum-world branch from ca81a60 to 230d417 Compare July 20, 2026 07:05
Base automatically changed from feat/m2-nexum-world to dev/m1 July 20, 2026 08:08
@mfw78
mfw78 force-pushed the feat/m2-supervised-primitive branch from 0ddfa13 to ac5e01b Compare July 20, 2026 08:10
@mfw78
mfw78 merged commit 7963c3a into dev/m1 Jul 20, 2026
5 of 6 checks passed
@mfw78
mfw78 deleted the feat/m2-supervised-primitive branch July 20, 2026 12:48
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.

2 participants