Skip to content

fix(cloud): shed corrupt store entries instead of resetting whole stores - #698

Merged
Neonforge98 merged 1 commit into
developfrom
fix/cloud-store-per-entry-resilience
Aug 6, 2026
Merged

fix(cloud): shed corrupt store entries instead of resetting whole stores#698
Neonforge98 merged 1 commit into
developfrom
fix/cloud-store-per-entry-resilience

Conversation

@Neonforge98

Copy link
Copy Markdown
Collaborator

Problem

createZodJsonStorage answers a failed whole-store parse with the initial value. Every record-shaped cloud store therefore converted ONE corrupted entry (disk damage, or a future entry shape rolled back onto an older build) into a whole-store reset at load, and several of those resets are destructive at fleet scale:

  • accessSettings: reset drops every explicit per-session sharing override → the next sync pass resolves previously shared sessions effective-off and retracts their cloud rows — one corrupted byte silently unshares the user's work.
  • sessionOrgTags: had no validation at all (default JSON storage — any parse failure resets every tag), and the ownership gate retracts a pushed session whose tag disappeared.
  • pushCursors: hardened per-entry in fix(cloud): incrementally replay imported histories #692; its inline transform migrates to the shared helper.
  • repoScopes / syncEnabled / pushedMetadata / collabStateCursors: resets re-enable orgs the user disabled, orphan metadata rows, or widen deltas — non-destructive but the same shape.

Solution

A shared tolerantRecordSchema(label, valueSchema) in zodStorage parses record entries independently and drops only invalid ones, warning per dropped key. Applied to all seven stores; accessSettings gets it at every nesting level, so a corrupt session-mode entry costs that one session's override, not the org. A non-record root still falls back to the initial value — that is unrecoverable garbage rather than partial loss, and the two behaviors are asserted separately.

Verification

  • New unit tests: helper semantics (drop-only-invalid, empty record, non-record root, composition through createZodJsonStorage), accessSettings nested shedding (corrupt org entry + corrupt session entry inside a healthy org), and the existing fix(cloud): incrementally replay imported histories #692 cursor tests keep passing against the migrated helper.
  • pnpm vitest run over storage utils + Org2Cloud + TeamCollaboration: 20 files / 314 tests green.
  • pnpm typecheck — clean.

createZodJsonStorage answers a failed whole-store parse with the initial
value. For the cloud push planes' record-shaped stores that turned one
corrupted entry into a fleet-scale event at load:

- accessSettings reset drops every explicit per-session override; the
  next pass resolves previously shared sessions effective-off and
  RETRACTS their cloud rows — one corrupted byte silently unshares the
  user's work.
- sessionOrgTags had no validation at all (default JSON storage), and a
  reset makes the ownership gate retract every explicitly moved
  session's row.
- repoScopes/syncEnabled/pushedMetadata/collabStateCursors resets
  re-enable disabled orgs, orphan metadata rows, or widen deltas.

A shared tolerantRecordSchema now parses record entries independently
and drops only invalid ones (nested for accessSettings, so a corrupt
session entry costs that session, not its org). The push-cursor store's
inline transform from the incremental-replay work migrates to the same
helper. A non-record root still falls back to the initial value — that
is unrecoverable garbage, not a partial loss.

Pre-commit hook ran. Total eslint: 58, total circular: 0
@Neonforge98
Neonforge98 merged commit b12cf95 into develop Aug 6, 2026
3 checks passed
@Neonforge98
Neonforge98 deleted the fix/cloud-store-per-entry-resilience branch August 6, 2026 05:55
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.

1 participant