[MC-463] Atomic enrichment writes + harden merge contract (follow-up to #655)#656
Merged
Conversation
- _write_json_file: tmp + fsync + os.replace so a crash, a concurrent reader, or two interleaved read-modify-write callers never see (or are left with) a half-written or truncated file. - _api_post_enrichments: docstring documenting deep-merge (not replace) semantics so non-frontend callers know omitted keys are preserved and deletions must send an emptied shape. - Tests: atomic-write round-trip + no .tmp residue; POST empty-group deep-merge contract lock (emptied cognate group stays []). Follow-up hardening to #655 (MC-463). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e helper Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
MC Task: MC-463 — Fix enrichments recompute wiping manual_overrides / Lane MC-463-B
Follow-up hardening to #655 (the manual_overrides persistence fix), addressing the review's hardening suggestions.
Changes
_write_json_file(python/server.py): writes to a sibling.tmpthenos.fsync+os.replace, with cleanup on failure. A crash, a concurrent reader, or two interleaved read-modify-write callers (the recompute job thread and aPOST /api/enrichmentsnow both do RMW) can no longer observe — or be left with — a half-written or truncatedparse-enrichments.json. This is the durability gap flagged in the [MC-463] Preserve manual overrides on enrichment recompute #655 review._api_post_enrichments(python/server_routes/compare.py): documents that the endpoint deep-merges (does NOT replace), so non-frontend callers (scripts, external API) know omitted keys are preserved and a deletion must send an emptied shape.test_write_json_file_atomic.py— content round-trip (incl. unicode + trailing newline), no.tmpresidue after success, clean overwrite.test_compare_enrichments_manual_overrides.py— locks the deep-merge contract: a full snapshot that empties cognate group B leavesB == []on disk (not re-populated). Guards against a future 'prune empty groups' change silently reintroducing deletion-suppression.test_server_route_modularization.py):server.pythin-orchestrator budget 2050 → 2070 to absorb the atomic-write helper (same documented mechanism used for PR [MC-368-B] feat: compare-bundle API + canonical-lexemes storage #368).Validation (PC, kurdish_asr env)
Out of scope
🤖 Generated with Claude Code