Conversation
…ference
A cluster value's uuid is its permanent identity: MISP keys on it and every
`related` edge across the repo points at it. Four generators produced uuids
that do not survive regeneration:
gen_malpedia.py:38,62 uuid4() for the cluster and all 3683 families
gen_amitt.py:46,73,94,... uuid4() throughout
plot4ai:200 uuid5 seeded with the enumerate() index, so
reordering one card reminted every later uuid
gen_microsoft_activity_group.py:173
uuid5 over the display name, so a Microsoft
rename orphaned the old entry
Add tools/galaxy_uuid.py with a UuidAssigner that (1) derives with uuid5
from a stable key -- name or upstream id, never a position -- and (2)
prefers the uuid already committed in the cluster being overwritten.
Synonyms are indexed as well, so a rename that demotes the old name to a
synonym keeps the original uuid.
gen_malpedia.py additionally sorts os.walk filenames and replaces
list(set(...)) with sorted(set(...)) for refs/synonyms, so the output stops
churning on set iteration order.
Verified by feeding the committed values through the exact for_value() call
each generator now makes (they need upstream inputs unavailable offline):
gen_malpedia.py 3683 values, 3683 preserved, 0 changed
gen_amitt.py 61 values, 61 preserved, 0 changed
plot4ai 138 values, 138 preserved, 0 changed
gen_microsoft_activity_group.py 179 values, 179 preserved, 0 changed
No committed uuid changes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HZGwPoa8MMfkhCw47rDLA4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
BLUF — Four generators remint every uuid on regeneration, orphaning every inbound
relatededgeuuidis its permanent identity — MISP instances key on it and everyrelatededge points at it — yetgen_malpedia.pyandgen_amitt.pymintuuid4on every run, plot4ai's generator seedsuuid5with theenumerate()index, andgen_microsoft_activity_group.pyseeds it with the current display name. Regenerating replaces rather than updates entries (3,683 malpedia families, 61 AM!TT entries).tools/galaxy_uuid.pyUuidAssignerthat derivesuuid5from stable seeds, indexes synonyms so renames keep the old id, and reuses whatever uuid is already committed.Problem
A cluster value's
uuidis its permanent identity — MISP instances key on it, and everyrelatededge in every other galaxy points at it by uuid. Four generators mint uuids that do not survive a regeneration:gen_malpedia.py:38,62uuid.uuid4()for the cluster and for every malware familygen_amitt.py:46,73,94,120,141uuid.uuid4()throughoutplot4ai/generate_plot4ai_galaxy.py:200uuid5seeded with theenumerate()indexgen_microsoft_activity_group.py:173uuid5over the current display nameIn each case "regenerating the cluster" does not update entries, it replaces them — and silently breaks every inbound reference.
Demonstrating the plot4ai index dependency:
Fix
A shared
tools/galaxy_uuid.pywith aUuidAssignerthat applies two rules:uuid4, never seed on a position. Derive withuuid5from something stable — the entry's name, or its upstream framework id (external_idfor AM!TT).Synonyms are indexed too, so an upstream rename that demotes the old name to a synonym keeps the original uuid:
gen_malpedia.pyalso got two reproducibility fixes on the same code path:os.walk's filenames are now sorted, andlist(set(...))forrefs/synonymsbecamesorted(set(...))— set iteration order varies between runs, so the file churned even when the data had not changed.Verification
These generators need upstream inputs that are not available offline (a cloned Malpedia repository, an AM!TT spreadsheet, network fetches). So rather than running them, the committed values are fed through the exact
for_value(...)call each generator now makes, and checked against the uuid already in the file:Each cluster's own top-level uuid is asserted preserved too. All five files compile.
No committed uuid changes. The behavioural change is only for entries that do not exist yet, and for regenerations that previously churned.
🤖 Generated with Claude Code