Explorar o código

docs: plan batch outcome lifecycle fixes

Problem: replay drops phase metadata, released scopes can be repopulated, invalid keys collapse, timed-out sync work releases concurrency resources early, and coalesced results mis-correlate payloads and messages.

Risk: generation and deferred-release logic must remain cancellation-safe and bounded while preserving prompt timeout reporting.
zhenyu.hu hai 2 semanas
pai
achega
08146fb103

+ 54 - 0
docs/plans/todo-48.2-outcome-cache-and-sync-resource-lifecycle.md

@@ -0,0 +1,54 @@
+# Todo 48.2 Outcome Cache and Sync Resource Lifecycle Plan
+
+**Status:** in_progress
+
+## Goal
+
+Close the remaining Important batch findings by preserving complete execution semantics in cache/replay and keeping physical concurrency resources held while timed-out synchronous work is still running.
+
+## Scope
+
+- Canonical key generation must tag non-JSON/normalizer-invalid arguments distinctly instead of collapsing them to `{}`.
+- Cache/replay `_ExecutionOutcome`, including `batch_timed_out`, rather than inferring phase semantics from error text.
+- Add per-scope generations:
+  - `release_scope()` advances the generation and clears completed/in-flight mappings for the released generation;
+  - late completion from an old generation cannot repopulate cache;
+  - immediate scope reuse operates on a new generation.
+- For synchronous handlers dispatched to a worker thread:
+  - return timeout promptly;
+  - keep semaphore/conflict locks leased until the underlying shielded kernel task actually completes;
+  - consume late exceptions and release resources in a completion callback;
+  - async handlers remain cancellable normally.
+- Add explicit `deduplicated_from` result provenance and clone correlation safely:
+  - outer `event_id` and tool reply ID match each requested call;
+  - top-level payload `event_id` is rewritten only when it equals the primary result ID;
+  - Runtime policy aggregation processes a coalesced logical result once, preventing duplicate farewells/templates.
+
+## Files
+
+- Modify: `src/agent_lab/application/events/models.py`
+- Modify: `src/agent_lab/application/events/batch.py`
+- Modify: `src/agent_lab/application/tools.py`
+- Modify: `src/agent_lab/application/runtime.py` only if audit/provenance exposure needs alignment
+- Modify: `tests/test_event_batch.py`
+- Modify: `tests/test_debug_runtime.py`
+
+## Requirement Execution Loop
+
+### Plan
+
+1. Add RED tests for invalid-vs-empty canonical keys, terminal timeout replay flags, release/reuse with late completion, and concurrent in-flight cleanup.
+2. Add RED sync timeout lease tests proving conflicting/new work cannot start until the worker actually finishes.
+3. Add RED different-ID payload correlation and single farewell/template tests.
+4. Implement outcome caching, scope generations, deferred resource release, and explicit dedupe provenance.
+5. Run focused/full verification and final bounded reviews.
+
+### Observe / Update
+
+Close Todo 48 only when all named concurrency/cache findings are permanent regressions and no Critical/Important issues remain.
+
+## Verification
+
+- `UV_CACHE_DIR=.uv-cache uv run pytest tests/test_event_batch.py tests/test_debug_runtime.py -q`
+- `UV_CACHE_DIR=.uv-cache uv run pytest`
+- `git diff --check`

+ 1 - 0
docs/plans/todos.md

@@ -90,6 +90,7 @@
 | 47.3 | done | `docs/plans/todo-47.3-bare-volume-numeric-guard.md` | Apply malformed numeric rejection to the existing bare `volume to`, `volume at`, and `volume=` syntaxes. | Bare decimal/grouped tokens are rejected with no side effect; integer forms remain valid; bounded gate APPROVED. |
 | 48 | in_progress | `docs/plans/todo-48-parallel-event-batches.md` | Execute multiple flat events with bounded parallelism, failure isolation, aggregation, and a terminal barrier. | Runtime tests prove independent concurrency, stable result order, isolated failures, and termination after sibling completion or timeout. |
 | 48.1 | in_progress | `docs/plans/todo-48.1-batch-canonical-replay-and-terminal-safety.md` | Canonicalize batch keys, make replay atomic and bounded, guarantee terminal grace after sibling timeout, enforce async timeout around sync handlers, and ensure termination has a farewell. | Normalized equivalents coalesce safely; in-flight duplicates execute once; scopes release cache; terminal runs after sibling timeout; blocking sync work cannot block the loop; search two-answer and tool-only farewell regressions pass. |
+| 48.2 | in_progress | `docs/plans/todo-48.2-outcome-cache-and-sync-resource-lifecycle.md` | Preserve full replay outcomes, generation-scope cleanup, invalid-key isolation, sync worker resource leases, and deduplicated result correlation/policy cardinality. | Invalid requests never inherit success; released scopes cannot late-store; timed-out sync work retains locks/slots until completion; terminal deadline flags replay exactly; duplicate payload IDs/messages stay correct and singular. |
 | 49 | pending | `docs/plans/todo-49-tool-mode-ui-session-restore.md` | Add UI mode selection, workspace/session restoration, and clear EventAgent applicability feedback. | Static/WebSocket tests prove requests, snapshots, loaded sessions, and audit context preserve the selected mode. |
 | 50 | pending | `docs/plans/todo-50-comparable-model-tool-metrics.md` | Record mode-aware model/tool spans and include EventAgent usage so both architectures can be compared fairly. | Persistence/API tests report agent, call kind, tokens, TTFT, tool latency, fallback usage, and total turn wall time without double counting. |
 | 51 | pending | `docs/plans/todo-51-comparison-matrix-closeout.md` | Add repeatable comparison fixtures, update project documentation, and close the experimental implementation. | Both modes pass the same scenario matrix; full tests, JS syntax, app import, and documentation checks pass. |