Skip to content

fix: stop older FableLoom peers erasing delivery plans and beat outlines (#6005) - #6120

Merged
atomantic merged 1 commit into
mainfrom
claim/issue-6005
Sep 3, 2026
Merged

fix: stop older FableLoom peers erasing delivery plans and beat outlines (#6005)#6120
atomantic merged 1 commit into
mainfrom
claim/issue-6005

Conversation

@atomantic

Copy link
Copy Markdown
Owner

Summary

A FableLoom story synced from a federated peer running an older wire schema silently lost data. preserveLegacyVisualProduction retained render settings, protagonist bindings, and challenge mappings across a legacy whole-record LWW overwrite, but not the series delivery plan or the per-episode beat outline. A peer on fableLoom schema v3 or older cannot represent either field, so its sanitizer drops them and the merge wrote that gap back over the upgraded install's copy — erasing overnight/inter-episode voicemails, the next-season teaser, and every episode's outline plus its validation state.

The receiver now restores both from the local record when a <=v3 sender omits them:

  • preserveLegacyDeliveryPlan puts deliveryOptions, interEpisodeVoicemails, and nextSeasonTeaser back, keying on the key being absent (hasOwnProperty) rather than empty, so a peer that understands the fields and clears them still propagates the clear.
  • preserveLegacyStoryOutline restores localEpisode.storyOutline whole when the remote episode carries none, and otherwise keeps today's per-scene plotPointId/challengePhase merge. This also lifts the outline branch out of the episode map, which was the densest nesting in the function.

Scope notes (deviations from the filed plan, detailed in a comment on #6005)

Tracing when each field entered the wire schema changed two details of the proposed fix:

  1. Guarded at senderVersion < 4, not < 5. Both the delivery plan and episode.storyOutline shipped in the commit that bumped fableLoom from 1 to 4, so a v4 peer round-trips them intact. Preserving at < 5 would resurrect a plan or outline a v4 author deliberately deleted. The real loss window is v1–v3, and that is what closes here. The existing < 5 handling of plotPoints[].kind, outline-scene plotPointId/challengePhase, and productionStatus is unchanged.
  2. participationMode / audienceCommunicationMedium need no preservation. They predate wire v1, so no sender version fails to represent them — every v1–v3 peer returns them intact. Adding preservation would instead discard a legitimate participation-mode change made on an older peer. That acceptance criterion is closed as not-a-bug.

The v4 note in server/lib/schemaVersions.js now records the outline and delivery-plan fields, which had shipped undocumented and cost this fix an archaeology pass.

Test plan

  • cd server && npm test -- services/fableLoom/records.test.js — 54 passed.
  • cd server && npm test -- services/fableLoom/ services/sharing/ lib/schemaVersions — 32 files / 854 tests passed.
  • New: preserves the delivery plan and beat outline when a v3 peer wins an unrelated LWW edit — verified red on main's merge logic before the fix, green after.
  • New: lets a v4 peer clear the delivery plan and beat outline it fully understands — pins the version boundary at 4 so a future widening to < 5 cannot pass unnoticed.

Closes #6005

https://claude.ai/code/session_01VjkWVTfzKyRuAv3HEsspwN

…nes (#6005)

A FableLoom story synced from a peer running wire schema v3 or older lost its
series delivery plan (overnight voicemails, inter-episode voicemails, the
next-season teaser) and every episode's beat outline. Those peers cannot
represent the fields, so their sanitizer drops them, and whole-record LWW then
wrote the gap back over the upgraded install's copy.

The receiver now restores both from the local record when a <=v3 sender omits
them, keying the delivery-plan check on the key being absent rather than empty
so a v4+ peer clearing a plan still propagates the clear. Both fields entered
the wire schema at v4, so v4 and v5 senders keep their existing behavior.

Also records the outline and delivery-plan fields in the v4 note in
schemaVersions.js, which had shipped undocumented.

Claude-Session: https://claude.ai/code/session_01VjkWVTfzKyRuAv3HEsspwN
@atomantic
atomantic merged commit 7cef7cb into main Sep 3, 2026
12 checks passed
@atomantic
atomantic deleted the claim/issue-6005 branch September 3, 2026 22:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FableLoom sync: preserveLegacyVisualProduction strips delivery plans, outlines, and audience mode when merging from older peers

1 participant