Add the missing --skill repeatable flag to both actor_run.py and
actor.py run commands, per specification CLI Synopsis line 277.
The flag accepts one or more namespaced skill names (e.g.
--skill local/web-tools --skill local/db-tools) that are validated
against the SkillService before execution and resolved at runtime.
DI Container: _build_skill_service() factory and skill_service
Singleton provider follow the established _build_* pattern. Falls
back to in-memory SkillService() when the database is unavailable.
CLI layer: Both actor.py and actor_run.py catch CleverAgentsError
(broad enough to cover CleverAgentsException and subclasses). On
unknown skill, emits an error and exits with code 2. Both CLI
unknown-skill tests now exercise the real error chain (mocking
only get_container(), not the entire ReactiveCleverAgentsApp).
Runtime layer: ReactiveCleverAgentsApp._resolve_skills() resolves
skill names to ResolvedToolEntry lists, converts them to tool config
dicts (identity operation baseline with skill_source metadata).
Separate except KeyError / except ValueError branches produce
distinct error messages. _sanitize_skill_name() enforces
namespace/name structure with re.ASCII flag and per-segment 127-char
limit. Zero-tool skill resolution emits a single stderr warning
(no duplicate logger.warning). Skill tools are injected only into
agents with existing tools, preventing LLM agents from conversion.
skill.py: Removed module-level _service cache — _get_skill_service()
always delegates to get_container().skill_service() so that
reset_container() correctly invalidates the cached instance.
_reset_skill_service() now overrides the container provider.
graph_executor.py: Extracted graph execution logic (334 lines).
Type annotations improved: config typed as ReactiveConfig | None,
route as RouteConfig, select_targets_fn as Callable.
Tests: 24+ Behave scenarios covering single/multiple/unknown skill
flags, skill+context combined, duplicate deduplication, skill
resolution, ValueError path, zero-tool resolution, error handling,
tool merging, default behavior, overrides, LLM agent guard,
_sanitize_skill_name edge cases (empty, too-long, ANSI, special
chars), _build_skill_service happy+fallback paths,
_get_skill_service container delegation. ContextManager assertions
moved from When steps to dedicated Then steps per BDD semantics.
@coverage tags added to all new scenarios. CLI dedup scenario
renamed to match actual pass-through behavior.
Quality gates: lint pass, typecheck pass (0 errors), 10838 unit
test scenarios pass, integration tests pass (1511), coverage 97%.
ISSUES CLOSED: #887