# Todo 48.3 Strict Canonical Types and Scope Token Cleanup Plan **Status:** done ## Result Canonical equality now uses strict recursive JSON types, and unique scope tokens are removed on release while still preventing old late tasks from storing into reused scopes. Final bounded gate approved. ## Goal Close the final bounded batch findings: canonical identity must use strict JSON type equality, and releasing a scope must retain no permanent generation tombstone. ## Scope - Compare JSON round-trip values recursively with exact types, matching kernel strictness; `IntEnum(1)`, `True`, `1`, and `1.0` must not be conflated unless a declared normalizer intentionally canonicalizes them. - Replace per-scope integer generations with globally unique generation tokens: - first execution for a scope allocates a unique token; - concurrent calls for the active scope share the token; - `release_scope()` removes the scope token and associated maps; - immediate reuse allocates a new token that can never equal an old late task token; - late completion checks token equality and cannot store when the scope is absent or reused. - Assert thousands of execute/release cycles leave no scope-token, replay, or in-flight growth. ## Files - Modify: `src/agent_lab/application/events/batch.py` - Modify: `tests/test_event_batch.py` ## Verification - `UV_CACHE_DIR=.uv-cache uv run pytest tests/test_event_batch.py -q` - `UV_CACHE_DIR=.uv-cache uv run pytest` - `git diff --check`