The typing.cast import was placed after third-party imports (behave),
violating ruff/isort PEP 8 ordering enforced by CI lint. Move it into
the stdlib block before the blank-line separator from third-party.
Fixes CI / lint failure on this branch. Closes#8588
Fixes a race condition (TOCTOU) in ActorLoader.list_actors() where the namespace
filter was applied outside the threading lock, creating a window for concurrent
dictionary modifications. Moving the filter inside the with self._lock: block
ensures atomic reads and filtering.
- Move namespace filtering inside the RLock in list_actors()
- Add concurrency BDD test (threading.Barrier) for list_actors + clear race condition
- Update CHANGELOG.md with fix entry (closes#8588)
- Update CONTRIBUTORS.md with contribution details
ISSUES CLOSED: #8588
- schema.py: provider field changed to Optional[str] with model validator
validate_provider_required_for_llm_graph() that requires it only for LLM
and GRAPH actor types; TOOL actors do not require provider
- schema.py: is_v3_yaml() uses version_str == "3" or version_str.startswith("3.")
to avoid false positives from "30" or "300" version strings
- schema.py: tool namespace validation uses strict 2-part split to reject
empty namespace or empty name (e.g. "/tool", "ns/", "a/b/c")
- cli/commands/actor.py: schema_version extraction uses raw_version pattern
(no # type: ignore[assignment]) for clean static typing
- actor/__init__.py: is_v3_yaml removed from __all__ and _LAZY_IMPORTS
since it is a module-private helper, not a public API
- robot/actor_add_v3_schema_validation.robot: YAML fixtures for 'Reject v3
LLM Actor Without Model Field' and 'Reject v3 TOOL Actor Without Tools
Field' now include required provider field (and model for TOOL fixture)
- robot/helper_actor_add_v3_schema_validation.py: except clauses unified to
catch (subprocess.TimeoutExpired, FileNotFoundError) in both add_actor()
and update_actor() functions
- features/actor_add_v3_schema_validation.feature: 'Update a v3 actor with
valid YAML succeeds' scenario now includes 'And the actor should be
validated via ActorConfigSchema'; error assertions tightened to exact
messages (e.g. "Input should be 'llm', 'tool' or 'graph'", "Node ID must
be alphanumeric", "must be namespaced")
- features/steps/actor_add_v3_schema_validation_steps.py: step_run_actor_update
now spies on ActorConfigSchema.model_validate; failure paths assert
isinstance(result.exception, SystemExit)
ISSUES CLOSED: #5869
Renamed 'listing actors with namespace' step in actor_loading_steps.py
to 'listing loaded actors with namespace' to avoid collision with
actor_registry_persistence_steps.py from master. Updated
actor_loading.feature to use renamed step.