Skip to content

fix(benchmark): close 5 should-address residuals from CE review on PR #3 - #4

Merged
HugoSkylight merged 1 commit into
masterfrom
fix/benchmark-ingest-should-address-residuals
Apr 25, 2026
Merged

fix(benchmark): close 5 should-address residuals from CE review on PR #3#4
HugoSkylight merged 1 commit into
masterfrom
fix/benchmark-ingest-should-address-residuals

Conversation

@HugoSkylight

Copy link
Copy Markdown
Contributor

Summary

Follow-up to PR #3 closing the should-address tail from the CE code review. PR #3 already shipped the must-address residuals (F1 sibling-task race, ADV-002 anchorless seed split, PERF-001 semaphore hoist). This PR closes the next 5:

  • REL-02 — Recomposition failure now propagates partial directory URIs to the caller's cleanup tracker via a new RecompositionError. Inner best-effort suppress cleanup remains for production callers that don't maintain a tracker.
  • REL-04 — Adapter cross-conversation gather no longer cascades cancel: switched to return_exceptions=True and explicit per-task CancelledError handling.
  • F4 / api-contract-005 — Idempotent-hit response now preserves summary_uri when the prior run wrote one. Closes the contract asymmetry vs cold-ingest.
  • api-contract-007 — Public MemoryOrchestrator.benchmark_conversation_ingest facade requires admin role by default (defense-in-depth). HTTP layer's _require_admin() is still the primary gate; this catches future internal callers.
  • F5 / ADV-007 — Source records gain a run_complete marker written only on successful ingest completion. Idempotent-hit path now checks both transcript_hash AND run_complete; a hash-match without the marker triggers _purge_torn_benchmark_run to drop stale leaves/directories/summary before re-ingesting. Implements the R2-17 pre-ingest purge deferred from U5.

Source: docs/residual-review-findings/feat-benchmark-offline-conv-ingest.md (run artifact at .context/compound-engineering/ce-code-review/20260425-093102-b5a311de/).

Test plan

  • 96/96 tests pass: tests.test_http_server, tests.test_locomo_bench, tests.test_e2e_phase1, tests.test_benchmark_ingest_lifecycle.
  • New tests.test_benchmark_ingest_lifecycle.test_torn_prior_run_is_not_treated_as_idempotent locks F5 behavior — strips run_complete marker, verifies the next replay calls _purge_torn_benchmark_run and re-ingests instead of returning the partial set.
  • Production conversation lifecycle (context_commit / context_end) regression suite passes — important because the RecompositionError change touches _run_full_session_recomposition which is shared, but raise_on_error=False (production default) preserves the legacy inline cleanup path exactly.
uv run python3 -m unittest tests.test_e2e_phase1 tests.test_context_manager tests.test_http_server tests.test_locomo_bench tests.test_benchmark_ingest_lifecycle -v

Risk notes

  • RecompositionError is a new public-ish exception class. Production callers (raise_on_error=False) never see it. The benchmark caller catches and re-raises exc.original, so the outer except (Exception, asyncio.CancelledError) handler's compensate flow is preserved — no change in observable failure semantics.
  • enforce_admin=True default on the orchestrator facade could break in-process callers that don't pre-seed the role contextvar. Audited: only admin_routes.py (HTTP — admin role set) and tests via httpx (admin role set in fixture) call the facade today. The CLI benchmark adapter goes via OCClient which is HTTP. If something breaks, pass enforce_admin=False explicitly.
  • run_complete marker is opt-in: only the benchmark path writes it. Existing source records without the marker (legacy / production-conversation source records) are NOT affected because the production lifecycle never enters the benchmark idempotent-hit path. Backward-compat preserved.
  • _purge_torn_benchmark_run uses _delete_immediate_families which is contextlib.suppress(Exception) per-URI. Failure to purge a stale record is logged and the re-ingest proceeds; this matches existing benchmark cleanup posture.

Deferred (still on the residual sheet)

The remaining items in docs/residual-review-findings/feat-benchmark-offline-conv-ingest.md are nice-to-haves (api-contract-001 CHANGELOG, api-contract-004 error envelope shape consistency, ADV-006 hash list-ordering, F3/ADV-003 cross-conv shared state non-determinism, KP-* Pythonic style) plus the testing gaps (TEST-001/002/005/008). None are merge-blocking — they can ride along with Phase 2 cleanup or land as standalone polish.

🤖 Generated with Claude Code

Addresses the should-address tail from the prior PR's CE review (run
20260425-093102-b5a311de) — see
docs/residual-review-findings/feat-benchmark-offline-conv-ingest.md.

REL-02 — Recomposition failure now propagates created directory URIs
to the caller's tracker. Introduces ``RecompositionError`` carrying
``created_uris`` so the benchmark layer's run-scoped cleanup can drain
them and let its compensate() path do the deletion. Production callers
(``raise_on_error=False``) keep the legacy inline best-effort cleanup
unchanged.

REL-04 — Adapter cross-conversation gather no longer cascades cancel.
Both LoCoMo and conversation adapters use ``return_exceptions=True``
and treat per-task ``CancelledError`` as a structured error so one
crashed or cancelled item cannot abort sibling work.

F4 / api-contract-005 — Idempotent-hit response now preserves
summary_uri when the prior run wrote one. Looks up the deterministic
session_summary URI and returns it; previously always returned None,
which was a contract asymmetry vs the cold-ingest path.

api-contract-007 — Public ``MemoryOrchestrator.benchmark_conversation_ingest``
facade now requires admin role by default (defense-in-depth).
``enforce_admin=True`` is the default; in-process callers
(benchmarks, maintenance scripts, tests pre-seeding role) can opt
out via ``enforce_admin=False`` — the kwarg is verbose so any
bypass shows up in code review. The HTTP layer's _require_admin()
is still the primary gate; this catches future internal callers
that might skip the route.

F5 / ADV-007 — Source records gain a ``run_complete`` marker written
only on successful ingest completion. The idempotent-hit path now
checks both ``transcript_hash`` AND ``run_complete``: a hash-match
WITHOUT the marker is treated as a torn prior run and triggers
``_purge_torn_benchmark_run`` to drop stale leaves, directories,
and summary before re-ingesting. Implements the R2-17 pre-ingest
purge that was deferred from U5. New regression test
``test_torn_prior_run_is_not_treated_as_idempotent``.

96/96 tests pass.
@HugoSkylight
HugoSkylight merged commit 90eb069 into master Apr 25, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant