Repository navigation
Description
Problem
PR #232 was blocked partly because its monkey-patch had no finally restoration. PR #237 fixed this by adding try/finally to the llm_metrics_scope() context manager. However, the same script (smoke_m4.py) starts an RSSSampler background task that is NOT wrapped in try/finally — if engine.run_village() raises an exception, the sampler task leaks.
This is the third instance of the same class of error across two PRs:
- PR fix: integration test mandatory for instrumentation and cross-cutting PRs #232: no
finallyon monkey-patch restoration - PR fix: integration test mandatory for instrumentation and cross-cutting PRs #232: no
finallyon scope cleanup - PR fix: agent must not conflate separate metrics — enumerate all requested metrics and verify none are missing #237:
finallyon scope but not on RSS sampler
Each time, the agent fixed the specific instance that was pointed out without systematically checking all other resources in the same scope.
Root Cause
-
Reactive fixing instead of systematic analysis: When the agent was told "add finally for the hook scope," it added it to that one place. It did not then ask: "What other resources in this same script need finally cleanup?"
-
No resource lifecycle checklist: The agent does not have a step that asks "enumerate all resources that need explicit cleanup (tasks, connections, locks, patches, file handles) and verify each has a cleanup path for normal and exception cases."
Prevention
For the agent
-
When adding
try/finallyor a context manager for one resource, immediately scan the same scope for all other resources that need cleanup. Ask: "What else in this function would leak if an exception occurred right here?" -
Before finalizing any script/module, produce a resource lifecycle table:
| Resource | Acquired at | Released at | Exception path |
|----------|-------------|-------------|----------------|
| LLM hook | llm_metrics_scope enter | scope exit (finally) | ✓ restored |
| RSS sampler | start() before run | stop() after run | ✗ NOT in finally |
| DB session | async with factory() | context exit | ✓ (async with) |
| httpx client | per-request in engine | engine manages | ✓ |
- Every
X.start()orX.acquire()that is not inside a context manager must be paired with atry/finally: X.stop()orX.release(). No exceptions.
References
- PR fix: agent must not conflate separate metrics — enumerate all requested metrics and verify none are missing #237 review finding guardrails: provider admission policy #6: https://github.com/Cor-Incorporated/persona-village-v2/pull/237#issuecomment-4525916917
- Previous: fix: agent must use proper scope management for instrumentation, not permanent global patches #231 (scope management)
Activity