fix(ingest): make memory-doc filenames unique so concurrent saves do not overwrite - #3316
Conversation
…not overwrite save_query_result named files query_<second>_<slug50>.md and wrote them with write_text, so two saves in the same second whose questions share the first 50 characters resolved to one path and the later one silently replaced the earlier. Both calls returned normally. This is the common case when several agents sweep one subsystem in parallel. Add a short uuid to the name. The query_ prefix and .md suffix are unchanged so reflect.load_memory_docs and existing tests keep working. Fixes Graphify-Labs#3301
3589dd1 to
0bdf89f
Compare
There was a problem hiding this comment.
Graphify reviewed this change.
Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).
Formal verification. No changes could be formally verified in this run.
Graphify review — findings
Adds an 8-char uuid segment to the filename save_query_result generates, so two saves in the same second whose questions share a 50-char slug prefix no longer resolve to the same path and silently overwrite each other (#3301). Covers it with a concurrent test asserting 20 saves of the same question yield 20 distinct files.
No blocking issues surfaced. 4 lower-confidence candidates did not survive cross-model review.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 215 functions depend on the 40 functions this change touches.
Health — this change adds coupling hotspots:
- new:
dispatch_command()— 2 callers, 123 callees - new:
ingest()— 3 callers, 8 callees - new:
test_poisoned_manifest_is_healed()— 0 callers, 6 callees - new:
test_lessons_artifact_cannot_be_globbed_back_into_memory()— 0 callers, 6 callees
Verification — 215 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 51 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify save\_query\_result.
The verifier did not have enough to check save\_query\_result, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `memory_dir` is annotated `Path` — outside the synthesizable primitive/collection set
· 4 more finding(s) on lines outside this diff (see the check run).
Fixes #3301.
save_query_resultnames memory docsquery_<second>_<slug50>.mdand writes them with a plainwrite_text. Two saves that land in the same second and share the first 50 characters of the question resolve to one path, and the later one silently replaces the earlier. Both calls return normally.Measured on v0.9.53 (20 concurrent saves): distinct questions keep 20/20, the same question keeps 1/20, and questions differing only after character 50 keep 1/20. The third case is the ordinary one when several agents sweep one subsystem in parallel.
Change: add
uuid.uuid4().hex[:8]to the filename. Thequery_prefix and.mdsuffix are unchanged, soreflect.load_memory_docs(*.mdglob) and the existing tests are unaffected. One regression test added: 20 concurrent saves of one question → 20 files.The one-file-per-memory layout is what makes unrelated writes safe here; this only closes the filename.