Context
#189 added ExecutionContext with a thoughtful double-checked locking design, but the strategy isn't documented beyond code comments. Handler authors using get_or_run_tool() need to understand:
- What guarantees does the context provide? (same key → same result within an audit run)
- What happens under concurrent access? (different keys parallel, same key serialized)
- What can go wrong? (e.g., if
run_func raises, is the lock released properly?)
- When should handlers NOT use this? (e.g., tool output is non-deterministic or time-sensitive)
What to document
Extend docs/HANDLER_AUTHORING.md (or create a dedicated docs/execution-context.md) with:
- Locking strategy explanation — the double-checked locking pattern and why it's used (main lock fast-path + per-tool locks)
- Concurrency guarantees — what's serialized (same
tool_key), what's parallel (different keys)
- Failure semantics — if
run_func raises, is the lock released? (Yes, via with — but worth calling out.) Does the exception propagate? (Yes.) Is the key cached on failure? (No — only successful results are cached.)
- When to use vs not — cache expensive tool outputs (Scorecard, API queries); DON'T cache time-sensitive state (current time, fresh random numbers, etc.)
- Testing patterns — how to test handlers that use ExecutionContext (fixture that provides a fresh context per test)
References
Context
#189 added
ExecutionContextwith a thoughtful double-checked locking design, but the strategy isn't documented beyond code comments. Handler authors usingget_or_run_tool()need to understand:run_funcraises, is the lock released properly?)What to document
Extend
docs/HANDLER_AUTHORING.md(or create a dedicateddocs/execution-context.md) with:tool_key), what's parallel (different keys)run_funcraises, is the lock released? (Yes, viawith— but worth calling out.) Does the exception propagate? (Yes.) Is the key cached on failure? (No — only successful results are cached.)References
packages/darnit/src/darnit/core/models.py::ExecutionContextdocs/HANDLER_AUTHORING.md(brief "Shared Execution Context" section added in feat: implement shared ExecutionContext for concurrent sieve checks #189)