refactor(retain): replace orchestration with recoverable ingestion - #6
Conversation
kawhiiiileo
left a comment
There was a problem hiding this comment.
Thanks for the substantial refactor. I found two blocking correctness issues that need to be addressed before this can be merged:
-
A tracked FULL ingestion can leave a partial replacement visible after cancellation between write windows.
_execute_full_document_windows()commits each window independently. The first window callshandle_document_tracking(), which deletes the previous document and its memory units, writes only the first window, and changes the document hash toretain-inflight:*. If cancellation is accepted before the next window,OperationActivityFencerejects that next write as terminal cancellation, with no retry or cleanup. Recall does not filter out in-flight documents, so the partial replacement remains queryable and the previously valid version has already been lost.Please stage the windows and publish atomically, preserve the old version until final publication, or add transactional compensation/cleanup for accepted cancellation. Please also add a live or contract regression test using an existing multi-chunk document and
retain_chunk_batch_size=1, cancelling after the first window commits and asserting that no partial replacement is visible and the previous version is not destroyed. -
LongMemEval retrieval-only reuse does not establish the provenance it records in the artifact.
_agent_has_data()and_audit_durable_ingestion()verify only that chunks/documents with the expected IDs exist; they do not comparedocuments.content_hashwith the selected dataset content or validate the Retain pipeline/model/code identity that created the bank. A stale bank from another dataset revision or Retain configuration can therefore pass reuse checks, while the output manifest attributes the result to the current dataset SHA and model configuration.Please validate each expected document content hash before reuse and persist/validate the relevant ingestion pipeline, model, and code identity (or explicitly mark reused-bank provenance as unverifiable).
One additional non-blocking issue: recall_async() is called without enable_trace=True, so search_result.trace is always empty and the cached coarse/reranked diagnostic candidates are never populated.
Please continue updating the PR and add regression coverage for these cases. I’ll re-review once the fixes are pushed.
Route Retain through a database-neutral application service with bounded write windows, durable checkpoints, cancellation fences, and PostgreSQL/Oracle adapters. Preserve third-party attribution and add focused contract/live regression coverage. Refs #1
Add a pinned and integrity-checked Retain-to-Judge benchmark workflow with resumable checkpoints, explicit model roles, bounded concurrency, privacy-safe manifests, and public reproduction documentation. Refs #1
Run offline contracts, PostgreSQL and Oracle lifecycle checks, style validation, benchmark tests, and distribution notice verification with immutable action and service-image references. Refs #1
Run the live Oracle gate on the regular fast-start image because the slim flavor removes the CTXSYS components required by the production migration. Refs #1
Bypass SQLAlchemy text parsing for the Oracle projection JSON backfill so literal colon-number and colon-boolean tokens are not mistaken for bind parameters. Add an offline migration regression contract. Refs #1
Use DBMS_LOB.COMPARE during projection backfill because Oracle does not permit direct CLOB equality comparisons. Add an offline regression contract for the migration SQL.\n\nRefs #1
Keep existing documents and all FULL write windows inside one transaction, validate the complete publication before checkpointing, and roll Oracle cancellation back across savepoint and backend scopes. Add contract coverage for cancellation, ownership loss, invalid mappings, and successful publication. Refs #4
Audit selected LongMemEval banks against normalized document hashes and retained metadata before QA, mark reused or mixed Retain creator identity as unverifiable, and enable retrieval trace diagnostics without exposing trace to the answer generator. Cover sequential, parallel, shared-bank, only-ingested, and force-reingest paths. Refs #4
d6385c1 to
675f4d3
Compare
|
@kawhiiiileo Thanks for the review. I addressed all three items:
Validation:
Fix commits: Could you please re-review PR #6? |
Motivation
Closes #4
Retain needs explicit transaction and recovery boundaries, consistent PostgreSQL and Oracle behavior, and reproducible quality evidence. This PR replaces the monolithic orchestration path with a database-neutral ingestion service and adds the tests, benchmark tooling, and CI gates required to review that change.
Semantic conversation chunking is intentionally excluded. It follows in #5 and stacked PR #7.
Changes
retain/orchestrator.pywith layered planning, extraction, projection, persistence, and execution components.asyncio.CancelledErroras well as ordinary exceptions.HMS_API_RETAIN_EMBEDDING_FAILURE_POLICYsetting withstore_without_embeddingandraisemodes.DBMS_LOB.COMPAREfor CLOB values.Retain -> Recall -> Answer -> Judgeworkflow with integrity checks, bounded concurrency, source audits, and reproduction documentation.Validation
uv lock --check: passed, 267 packages resolved from the lockfile.bash -n .aaaSCRIPT/run_benchmark.sh: passed.A paid 500-question LongMemEval run is not required for this PR. This change makes that run reproducible but does not claim a benchmark score.
Risk / Rollback
HMS_API_RETAIN_EMBEDDING_FAILURE_POLICY=raise.HMS_RESULTS_FILENAMEfor retrieval-only output.pendingorprocessingbefore retrying asynchronous work. Review Oracle migration state separately before any manual backfill.