Summary
#682 establishes the invariant that "the map and the card can never hold different pairs" by normalising an experience role's date pair on commit (setExperienceField → applyNormalizedDateOverrides). That holds for every override map this build writes. It does not hold for an override map persisted by an earlier build and replayed from a saved draft — replay deliberately passes no resolvedEntry, so it writes the stored keys verbatim, un-normalised.
What actually happens
A draft saved before #682 can hold exactly the #672 shape, {start_date: "", end_date: "2022"} — that shape is the bug #682 fixes, so users who hit it are precisely the ones with such drafts.
Verified against applyOverrides on the #682 branch:
stored override map : { start_date: "", end_date: "2022" }
EXPORTED (applied) : { start_date: "2022" } ← correct, normalised
CARD READS (raw map): start = "" end = "2022" ← stale
The data is safe. applyExperienceHeaderOverrides normalises regardless of how the map got there, so the exported PDF and the re-parse are correct. The defect is display-only: the edit card shows an empty Start cell and 2022 in End, contradicting the file, until the user commits any date cell on that role — at which point normalisation runs and the two re-converge.
Why it is worth closing anyway
It is a narrow, self-healing, display-only inconsistency — but it is the exact class of card-vs-file disagreement #682 exists to eliminate, and the module docblock states the invariant without this caveat.
Options
- Normalise experience date pairs once when a draft's overrides are replayed (a migration pass over
experienceOverrides, not a change to replay's per-key contract — replay must stay un-normalised, since re-resolving a snapshot's keys one at a time can produce 2022 – 2022).
- Or normalise at the point the draft is loaded from storage, before it reaches
replay.
Acceptance criteria
Found during review of #682. Related: #672.
Summary
#682 establishes the invariant that "the map and the card can never hold different pairs" by normalising an experience role's date pair on commit (
setExperienceField→applyNormalizedDateOverrides). That holds for every override map this build writes. It does not hold for an override map persisted by an earlier build and replayed from a saved draft —replaydeliberately passes noresolvedEntry, so it writes the stored keys verbatim, un-normalised.What actually happens
A draft saved before #682 can hold exactly the #672 shape,
{start_date: "", end_date: "2022"}— that shape is the bug #682 fixes, so users who hit it are precisely the ones with such drafts.Verified against
applyOverrideson the #682 branch:The data is safe.
applyExperienceHeaderOverridesnormalises regardless of how the map got there, so the exported PDF and the re-parse are correct. The defect is display-only: the edit card shows an empty Start cell and2022in End, contradicting the file, until the user commits any date cell on that role — at which point normalisation runs and the two re-converge.Why it is worth closing anyway
It is a narrow, self-healing, display-only inconsistency — but it is the exact class of card-vs-file disagreement #682 exists to eliminate, and the module docblock states the invariant without this caveat.
Options
experienceOverrides, not a change toreplay's per-key contract —replaymust stay un-normalised, since re-resolving a snapshot's keys one at a time can produce2022 – 2022).replay.Acceptance criteria
{start_date: "", end_date: "2022"}renders in the edit card asStart 2022 / End empty, matching what the export draws.Found during review of #682. Related: #672.