Status: done
Added generic deterministic normalizers shared by text and provider sources, standard/custom format checking, strict blank/invalid input rejection, safe volume parsing, and canonical adapter cache keys while preserving provider raw arguments and no-fallback behavior.
Close review-confirmed plugin safety gaps while preserving the generic kernel and identical built-in behavior across dual_agent and chat_agent_tools.
1000 are rejected rather than truncated to 100.The lab adapters will cache by event ID plus canonical normalized arguments, not event ID alone. This preserves same-call replay behavior while preventing event_1 with a different operation from returning an earlier result. Runtime-scoped deduplication and production session/turn idempotency remain Todo 48/service integration responsibilities.
src/agent_lab/application/events/models.pysrc/agent_lab/application/events/kernel.pysrc/agent_lab/application/events/registry.pysrc/agent_lab/application/events/__init__.pysrc/agent_lab/application/events/builtin_plugins.pysrc/agent_lab/application/tools.py only to preserve ToolDefinition compatibility with the new optional normalizertests/test_event_kernel.pytests/test_builtin_event_plugins.py1000, invalid dates, invalid IANA zones, blank query/title, and no port calls.Close Todo 47 only when all four plugins reject unsafe inputs before ports, both invocation modes share deterministic normalization, and no event-name logic enters generic orchestration.
UV_CACHE_DIR=.uv-cache uv run pytest tests/test_event_kernel.py tests/test_builtin_event_plugins.py -qUV_CACHE_DIR=.uv-cache uv run pytestgit diff --check