mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-14 08:10:26 +00:00
afc0c865d4
removeAvailabilityProjectionLocked compacted each resource's relationships in place with a Relationships[:0] filter. That is only safe if registry clones own their backing array, and they did not: cloneResource deep-copies roughly twenty-five slice and map fields but Relationships was left as the shallow copy from the struct assignment, so a clone shared the original's array. The reachable path is ordinary. GET /api/resources rebuilds a registry from Monitor.UnifiedResourceSnapshot, whose records come from GetAll clones, so the filter wrote through into the live monitor registry from an HTTP goroutine without holding that registry's lock. Every request performed unconditional same-value writes, and whenever a legacy checks edge was genuinely dropped the compaction left a duplicated trailing relationship on the live host resource. The corrupting case is the post-upgrade seed the projection exists to repair. cloneResource now clones Relationships like every other slice, and the filter builds a fresh slice so correctness no longer depends on each caller having cloned first. Regression coverage: - TestCloneResourceGivesRelationshipsTheirOwnBackingArray pins the clone isolation, and fails with the clone line removed - TestAvailabilityRepeatedProjectionKeepsHostRelationshipsStable drives the real ingest path across repeated re-projection