Skip to content

[MC-463] Preserve manual overrides on enrichment recompute#655

Merged
TarahAssistant merged 1 commit into
mainfrom
fix/preserve-manual-overrides-on-recompute
Jun 15, 2026
Merged

[MC-463] Preserve manual overrides on enrichment recompute#655
TarahAssistant merged 1 commit into
mainfrom
fix/preserve-manual-overrides-on-recompute

Conversation

@TarahAssistant

Copy link
Copy Markdown
Collaborator

MC Task: MC-463 — Fix enrichments recompute wiping manual_overrides / Lane MC-463-A

Summary

  • Made cognates/similarity recompute read-modify-write parse-enrichments.json so recompute-owned fields update only computed_at, config, auto cognate_sets, and similarity.
  • Made POST /api/enrichments merge stale client snapshots into the on-disk payload so omitted or empty manual_overrides cannot erase human cognate decisions.
  • Added regression coverage for cognates and similarity job dispatch, no-existing-file default behavior, and POST bodies that omit/send empty manual_overrides.

Fail on origin/main before fix

$ PYTHONPATH=python python3 -m pytest python/test_compare_enrichments_manual_overrides.py -q
FF.FF                                                                    [100%]
FAILED python/test_compare_enrichments_manual_overrides.py::test_compute_job_preserves_manual_overrides_and_unrelated_enrichment_keys[cognates]
E       AssertionError: assert {} == {'borrowing_flags': ..., 'cognate_sets': ...}
FAILED python/test_compare_enrichments_manual_overrides.py::test_compute_job_preserves_manual_overrides_and_unrelated_enrichment_keys[similarity]
E       AssertionError: assert {} == {'borrowing_flags': ..., 'cognate_sets': ...}
FAILED python/test_compare_enrichments_manual_overrides.py::test_post_enrichments_preserves_non_empty_disk_manual_overrides_when_client_omits_them[incoming_enrichments0]
E       KeyError: 'manual_overrides'
FAILED python/test_compare_enrichments_manual_overrides.py::test_post_enrichments_preserves_non_empty_disk_manual_overrides_when_client_omits_them[incoming_enrichments1]
E       AssertionError: assert {} == {'borrowing_flags': ..., 'cognate_sets': ...}
4 failed, 1 passed, 1 warning in 0.24s

Pass on branch after fix

$ PYTHONPATH=python python3 -m pytest python/test_compare_enrichments_manual_overrides.py -q
.....                                                                    [100%]
5 passed, 1 warning in 0.07s

Local validation

$ PYTHONPATH=python python3 -m pytest python/ -q -k 'not test_ortho_section_defaults_cascade_guard and not test_ortho_explicit_override_beats_defaults'
1920 passed, 6 skipped, 2 deselected, 1 warning, 3 subtests passed in 31.54s

$ PYTHONPATH=python python3 -m pytest python/ -q
1922 passed, 6 skipped, 1 warning, 3 subtests passed in 29.98s

$ uvx ruff check python/ --select E9,F63,F7,F82
All checks passed!

Root-level handoff command note: the literal root-scoped PYTHONPATH=python python3 -m pytest -q -k ... still hits pre-existing collection import errors under tests/migration/* (No module named 'migration.test_*'). Per backend-root-vs-python-scope guidance, I ran the backend-scoped equivalent above.

Follow-up out of scope

  • Frontend CLEF Save & populate auto-chain to similarity recompute can remain unchanged for this data-loss fix because backend recompute is now non-destructive.
  • enrichmentStore.ts optimistic-only canonical lexeme concern remains separate.

@TarahAssistant TarahAssistant added bugfix Bug fix MC-463 Mission Control MC-463 labels Jun 15, 2026
@TarahAssistant TarahAssistant merged commit 298efc4 into main Jun 15, 2026
4 checks passed
@TarahAssistant TarahAssistant deleted the fix/preserve-manual-overrides-on-recompute branch June 15, 2026 10:28
TarahAssistant pushed a commit that referenced this pull request Jun 15, 2026
#655) (#656)

* [MC-463] Make enrichment writes atomic and lock merge contract

- _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>

* [MC-463] Raise server.py thin-orchestrator LoC budget for atomic write helper

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Bug fix MC-463 Mission Control MC-463

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant