From d951aab997ffe61310d8eca97f0ead404f0ac2f8 Mon Sep 17 00:00:00 2001 From: filemon Date: Tue, 21 Apr 2026 23:07:51 -0300 Subject: [PATCH] Derive adultType from effectiveSeed, rename sync terminology BlobbiCompanion.adultType now derives from the effective seed for adult Blobbies instead of reading the (potentially stale) stored tag. Falls back to the tag only for legacy events without a seed. Renames to reflect the broadened scope of the sync system: - needsColorSync -> needsSeedIdentitySync - eventNeedsColorSync -> eventNeedsSeedIdentitySync No behavior change beyond making adultType consistent with the seed- truth model and aligning names with what the code already does. --- src/blobbi/core/hooks/useSeedIdentitySync.ts | 4 ++-- src/blobbi/core/lib/blobbi.ts | 14 ++++++++------ src/blobbi/onboarding/lib/blobbi-preview.ts | 2 +- src/pages/BlobbiPage.tsx | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/blobbi/core/hooks/useSeedIdentitySync.ts b/src/blobbi/core/hooks/useSeedIdentitySync.ts index d49062fd..f88bca02 100644 --- a/src/blobbi/core/hooks/useSeedIdentitySync.ts +++ b/src/blobbi/core/hooks/useSeedIdentitySync.ts @@ -20,7 +20,7 @@ import { } from '../lib/blobbi'; /** - * For each visible companion that has needsColorSync === true, + * For each visible companion that has needsSeedIdentitySync === true, * republish it with an `updateBlobbiTags` call that includes the * companion's (possibly adjusted) seed. The merge pipeline's * syncMirrorTagsToSeed will overwrite all stale mirror tags. @@ -41,7 +41,7 @@ export function useSeedIdentitySync( if (companions.length === 0) return; const toSync = companions.filter( - (c) => c.needsColorSync && !c.isLegacy && c.seed && !syncedRef.current.has(c.d), + (c) => c.needsSeedIdentitySync && !c.isLegacy && c.seed && !syncedRef.current.has(c.d), ); if (toSync.length === 0) return; diff --git a/src/blobbi/core/lib/blobbi.ts b/src/blobbi/core/lib/blobbi.ts index 2e4d0230..39388b97 100644 --- a/src/blobbi/core/lib/blobbi.ts +++ b/src/blobbi/core/lib/blobbi.ts @@ -262,7 +262,7 @@ export interface BlobbiCompanion { /** Whether this is a legacy event that needs migration */ isLegacy: boolean; /** Whether stored mirror tags differ from seed-derived identity and need republishing */ - needsColorSync: boolean; + needsSeedIdentitySync: boolean; /** Timestamp of last user interaction (unix seconds) */ lastInteraction: number; /** Timestamp used for stat decay checkpoint (unix seconds) */ @@ -974,7 +974,7 @@ export function companionNeedsMigration(companion: BlobbiCompanion): boolean { * - no seed exists (legacy event; tags are authoritative) * - all mirror tags already match the seed-derived values */ -export function eventNeedsColorSync(tags: string[][]): boolean { +export function eventNeedsSeedIdentitySync(tags: string[][]): boolean { const seed = getTagValue(tags, 'seed'); if (!seed || seed.length !== 64) return false; @@ -1204,7 +1204,7 @@ export function parseBlobbiEvent(event: NostrEvent): BlobbiCompanion | undefined // Check if stored mirror tags need syncing with seed-derived values // Uses the effective seed (which may be adjusted during compat window) - const needsColorSync = eventNeedsColorSync( + const needsSeedIdentitySync = eventNeedsSeedIdentitySync( effectiveSeed !== seed ? tags.map((t) => t[0] === 'seed' ? ['seed', effectiveSeed!] : t) : tags, @@ -1215,7 +1215,7 @@ export function parseBlobbiEvent(event: NostrEvent): BlobbiCompanion | undefined d: d.length > 30 ? `${d.slice(0, 20)}...` : d, name, isLegacy, - needsColorSync, + needsSeedIdentitySync, hasSeed: !!seed, traits: `${visualTraits.baseColor} ${visualTraits.pattern} ${visualTraits.size}`, }); @@ -1252,7 +1252,7 @@ export function parseBlobbiEvent(event: NostrEvent): BlobbiCompanion | undefined seed: effectiveSeed, visualTraits, isLegacy, - needsColorSync, + needsSeedIdentitySync, lastInteraction: parseNumericTag(tags, 'last_interaction')!, lastDecayAt: parseNumericTag(tags, 'last_decay_at'), stats: { @@ -1270,7 +1270,9 @@ export function parseBlobbiEvent(event: NostrEvent): BlobbiCompanion | undefined careStreakLastDay: getTagValue(tags, 'care_streak_last_day'), incubationTime: parseNumericTag(tags, 'incubation_time'), startIncubation: parseNumericTag(tags, 'start_incubation'), - adultType: getTagValue(tags, 'adult_type'), + adultType: stage === 'adult' && effectiveSeed && effectiveSeed.length === 64 + ? deriveAdultTypeFromSeed(effectiveSeed) + : getTagValue(tags, 'adult_type'), stateStartedAt: parseNumericTag(tags, 'state_started_at'), progressionStartedAt: parseNumericTag(tags, 'progression_started_at') ?? parseNumericTag(tags, 'state_started_at'), tasks, diff --git a/src/blobbi/onboarding/lib/blobbi-preview.ts b/src/blobbi/onboarding/lib/blobbi-preview.ts index 9810b8b9..c94beeaa 100644 --- a/src/blobbi/onboarding/lib/blobbi-preview.ts +++ b/src/blobbi/onboarding/lib/blobbi-preview.ts @@ -183,7 +183,7 @@ export function previewToBlobbiCompanion(preview: BlobbiEggPreview) { // Required but not used for preview rendering isLegacy: false, - needsColorSync: false, + needsSeedIdentitySync: false, lastInteraction: preview.createdAt, lastDecayAt: preview.createdAt, generation: 1, diff --git a/src/pages/BlobbiPage.tsx b/src/pages/BlobbiPage.tsx index f5f3b53b..61d0c2d1 100644 --- a/src/pages/BlobbiPage.tsx +++ b/src/pages/BlobbiPage.tsx @@ -228,7 +228,7 @@ function BlobbiContent() { }, [filteredCompanions]); // STEP 3: Sync visible companions whose mirror tags are stale. - // Republishes only companions with actual mismatches (needsColorSync flag). + // Republishes only companions with actual mismatches (needsSeedIdentitySync flag). useSeedIdentitySync(filteredCompanions, updateCompanionEvent); // STEP 5: localStorage for UI selection (user-scoped key)