From 486fe69023a012e9fcc7b8b65ce0bc4e5b2f3ac9 Mon Sep 17 00:00:00 2001 From: beamologist Date: Mon, 14 Sep 2026 16:54:58 +0200 Subject: [PATCH] feat(identity): petname -- mesh-wide deterministic node label, shared derivation Same sha256-of-lowercased-hex derivation over the shared 40x40x40 word lists plus a zero-padded four-digit suffix, matching macula-mcp, macula-rust and macula-go byte for byte. Fixtures pin cross-SDK equality. --- src/macula_py/petname.py | 55 ++++++++++++++++++++++++++++++++++++++++ tests/test_petname.py | 25 ++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 src/macula_py/petname.py create mode 100644 tests/test_petname.py diff --git a/src/macula_py/petname.py b/src/macula_py/petname.py new file mode 100644 index 0000000..5d59249 --- /dev/null +++ b/src/macula_py/petname.py @@ -0,0 +1,55 @@ +"""Petnames: a deterministic, human-readable label for a mesh node id — +Docker's adjective_color_animal convention with a four-digit suffix +(e.g. "happy_green_rabbit_4831"). A pure function of the node id +itself, not random per process: the same identity gets the same +petname across restarts, across every tool that shows it, and on every +other agent's roster too. + +The suffix exists because the mesh is expected to host THOUSANDS of +agents: the word trio alone (64,000 combinations) collides visibly +under the birthday problem at a few hundred identities; the trio plus +a 4-digit hash group (640,000,000 combinations) stays effectively +collision-free at fleet scale while remaining scannable. + +The word lists and derivation are shared verbatim with macula-mcp's +petname.ts, macula-rust's petname() and macula-go's identity.Petname: +same sha256 of the lowercased hex id, same 16-bit reads modulo the +list lengths, plus the suffix group. +""" + +import hashlib + +ADJECTIVES_A = [ + "bold", "bouncy", "brave", "breezy", "calm", "cheerful", "clever", "curious", + "daring", "eager", "elegant", "fierce", "gentle", "graceful", "humble", "jolly", + "jovial", "keen", "kind", "lively", "lucky", "mellow", "merry", "nimble", + "noble", "plucky", "proud", "quiet", "quirky", "radiant", "silly", "sleepy", + "spry", "sturdy", "tranquil", "upbeat", "vivid", "wise", "witty", "zealous", +] + +ADJECTIVES_B = [ + "amber", "azure", "bronze", "coral", "crimson", "cyan", "emerald", "golden", + "green", "indigo", "ivory", "jade", "lavender", "lilac", "magenta", "maroon", + "mauve", "navy", "olive", "orange", "peach", "pink", "plum", "purple", + "red", "rust", "ruby", "sage", "salmon", "scarlet", "sienna", "silver", + "slate", "tan", "teal", "turquoise", "violet", "yellow", "blue", "copper", +] + +NOUNS = [ + "antelope", "badger", "beetle", "bison", "cricket", "dolphin", "eagle", "elk", + "falcon", "ferret", "flamingo", "fox", "gazelle", "gecko", "hare", "heron", + "ibex", "iguana", "lynx", "marten", "mongoose", "moose", "narwhal", "orca", + "otter", "owl", "panther", "pelican", "penguin", "rabbit", "raven", "salamander", + "seal", "sparrow", "tiger", "toucan", "walrus", "weasel", "wolf", "wombat", +] + + +def petname(node_id: str) -> str: + """The stable "adjective_color_animal_0000" label for a node id: + same input, same output, on every tool and every machine.""" + digest = hashlib.sha256(node_id.lower().encode("utf-8")).digest() + a = ADJECTIVES_A[int.from_bytes(digest[0:2], "big") % len(ADJECTIVES_A)] + b = ADJECTIVES_B[int.from_bytes(digest[2:4], "big") % len(ADJECTIVES_B)] + n = NOUNS[int.from_bytes(digest[4:6], "big") % len(NOUNS)] + suffix = int.from_bytes(digest[6:8], "big") % 10_000 + return f"{a}_{b}_{n}_{suffix:04d}" diff --git a/tests/test_petname.py b/tests/test_petname.py new file mode 100644 index 0000000..882bcd5 --- /dev/null +++ b/tests/test_petname.py @@ -0,0 +1,25 @@ +from macula_py.petname import petname + + +def test_petname_deterministic_and_shaped(): + nid = "7374b0cfab4eea68e271c3815a0f78e21e913397f67345f337ddba7a3a88ab3a" + first = petname(nid) + assert petname(nid) == first + parts = first.split("_") + assert len(parts) == 4 + assert len(parts[3]) == 4 + assert parts[3].isdigit() + + +def test_petname_matches_reference(): + # Shared fixtures across the SDKs: one label everywhere. The second + # is proven against the live roster (gentle_maroon_flamingo before + # the suffix shipped). + assert ( + petname("7374b0cfab4eea68e271c3815a0f78e21e913397f67345f337ddba7a3a88ab3a") + == "calm_navy_narwhal_3381" + ) + assert ( + petname("d4b24382f4e033ad9e895070c914c8125c315f243c5a3713183352f65c322b03") + == "gentle_maroon_flamingo_3490" + )