#!/usr/bin/env python3 """Build the pinned model bundle for `wai.generate.spectral` — a deterministic, INTEGER, byte-exact generative synthesizer (the `intent=create` analog of the integer-exact codecs: generation whose output hash is portable, not similarity). The "model" is small and committable: a fixed-point integer sine LUT plus the generator's configuration. The float `sin()` is used ONCE here to bake the LUT; the generator (Rust) reads only integers, so generation is byte-identical on every machine. Pinning this bundle's sha256 + (prompt, seed, steps) pins the output exactly — same inputs → same bytes → same hash, anywhere. python tools/wai_generate_model.py """ import sys, os, json, hashlib, math LUT_BITS = 14 # sine amplitude scale: values in [-2^14, 2^14] T = 1024 # LUT size (one full turn) # Semantic lexicon (the "model" half that makes the prompt's MEANING shape the # image, deterministically): concept word -> spectral intent # [r, g, b] per-channel hue weight 0..255 (the dominant channel tints the image) # freq frequency multiplier, Q8 (256 = neutral; <256 calmer/smoother, >256 busier) # orient -256..256 (negative = horizontal bands, positive = vertical, 0 = isotropic) # Pure-colour words stay frequency/orientation-neutral so they only tint; element # and mood words also carry texture and direction. Unknown words don't match and # fall back to the prompt-seeded (untinted, isotropic) draw — honest about scope. LEX = { # colours (tint only) "red": [255, 40, 30, 256, 0], "crimson": [220, 20, 40, 256, 0], "scarlet": [240, 30, 30, 256, 0], "orange": [255, 140, 20, 256, 0], "amber": [255, 170, 40, 256, 0], "gold": [255, 200, 40, 256, 0], "golden": [255, 200, 40, 256, 0], "yellow": [255, 240, 60, 256, 0], "green": [40, 220, 60, 256, 0], "emerald": [20, 200, 120, 256, 0], "lime": [120, 240, 40, 256, 0], "teal": [20, 200, 200, 256, 0], "cyan": [40, 230, 240, 256, 0], "turquoise": [40, 220, 200, 256, 0], "blue": [40, 90, 255, 256, 0], "azure": [80, 160, 255, 256, 0], "cobalt": [40, 70, 230, 256, 0], "indigo": [60, 40, 200, 256, 0], "violet": [160, 40, 230, 256, 0], "purple": [160, 40, 230, 256, 0], "magenta": [240, 40, 200, 256, 0], "pink": [255, 120, 200, 256, 0], "rose": [255, 100, 150, 256, 0], "white": [240, 240, 240, 256, 0], "silver": [180, 190, 200, 256, 0], "grey": [170, 175, 185, 256, 0], "gray": [170, 175, 185, 256, 0], "black": [40, 40, 55, 256, 0], # elements (colour + texture + direction) "fire": [255, 90, 20, 360, 60], "flame": [255, 110, 30, 380, 80], "ember": [240, 100, 30, 300, 40], "water": [50, 140, 230, 150, -120], "ocean": [30, 90, 220, 120, -200], "sea": [30, 100, 215, 130, -200], "wave": [40, 120, 230, 200, -160], "river": [60, 150, 220, 170, -60], "sky": [120, 180, 255, 90, -120], "cloud": [200, 210, 230, 110, -80], "mist": [200, 215, 225, 80, -60], "forest": [40, 160, 60, 280, 160], "tree": [60, 150, 70, 240, 200], "leaf": [60, 200, 80, 240, 120], "earth": [150, 100, 60, 200, 0], "soil": [140, 95, 55, 200, 0], "stone": [150, 150, 160, 190, 0], "sand": [230, 200, 140, 90, -120], "desert": [235, 195, 130, 90, -140], "dune": [225, 195, 135, 80, -160], "mountain": [150, 150, 170, 180, 40], "valley": [120, 160, 110, 140, -80], "sun": [255, 200, 70, 110, 0], "sunset": [255, 140, 60, 110, -80], "dawn": [255, 180, 140, 100, -100], "moon": [220, 220, 240, 80, 0], "star": [230, 230, 255, 300, 0], "night": [40, 40, 90, 100, 0], "snow": [225, 235, 255, 90, 0], "ice": [200, 230, 255, 120, 0], "frost": [210, 230, 245, 110, 0], "storm": [90, 90, 130, 420, 100], "rain": [120, 150, 200, 300, 220], "lightning": [240, 240, 180, 470, 200], "wind": [180, 200, 210, 260, -60], "smoke": [120, 120, 130, 280, 120], # moods / textures (texture + tendency) "calm": [120, 175, 205, 70, -150], "peaceful": [130, 185, 200, 70, -120], "serene": [140, 190, 210, 70, -120], "soft": [200, 190, 210, 80, 0], "smooth": [185, 200, 220, 70, 0], "gentle": [175, 200, 205, 80, -60], "quiet": [160, 180, 195, 80, -40], "dream": [200, 160, 230, 120, 0], "dreamy": [200, 165, 230, 110, 0], "chaos": [200, 100, 80, 470, 0], "chaotic": [205, 95, 75, 470, 0], "wild": [210, 130, 70, 420, 40], "sharp": [220, 220, 230, 430, 0], "busy": [200, 160, 120, 410, 0], "intense": [240, 80, 60, 440, 0], "bright": [255, 250, 220, 220, 0], "dark": [50, 50, 70, 150, 0], "deep": [40, 60, 120, 130, 0], "warm": [255, 150, 80, 180, 0], "cool": [80, 160, 220, 160, 0], "vivid": [255, 80, 120, 360, 0], # explicit orientation "horizon": [120, 160, 220, 80, -240], "horizontal": [180, 180, 185, 160, -240], "vertical": [180, 180, 185, 160, 240], "tall": [160, 180, 160, 220, 200], "flat": [170, 185, 195, 90, -200], # SHAPE-grammar words (their colour/freq base; the shape weights come from SHAPE) "ring": [200, 200, 210, 300, 0], "target": [235, 70, 70, 320, 0], "eye": [180, 140, 220, 260, 0], "ripple": [60, 150, 220, 260, 0], "circle": [200, 205, 215, 240, 0], "orb": [225, 200, 150, 180, 0], "halo": [255, 240, 205, 160, 0], "spiral": [205, 120, 220, 360, 0], "vortex": [170, 80, 200, 420, 0], "portal": [120, 80, 230, 320, 0], "eclipse": [205, 150, 80, 180, 0], "bubble": [180, 220, 240, 220, 0], "lens": [200, 210, 230, 200, 0], "mandala": [235, 160, 60, 380, 0], "radiant": [255, 220, 120, 240, 0], "kaleidoscope": [205, 120, 230, 380, 0], "crystal": [180, 220, 240, 320, 0], "snowflake": [220, 235, 255, 300, 0], "gem": [120, 200, 235, 320, 0], "prism": [235, 235, 255, 320, 0], "butterfly": [235, 140, 200, 300, 0], "symmetry": [185, 190, 200, 220, 0], "mirror": [185, 195, 210, 220, 0], "sunrise": [255, 180, 120, 110, 0], "dusk": [120, 90, 160, 110, 0], "twilight": [90, 80, 150, 110, 0], "depth": [40, 70, 130, 130, 0], "ombre": [205, 165, 205, 100, 0], "gradient": [180, 190, 210, 120, 0], "fade": [190, 200, 215, 90, 0], "glow": [255, 230, 170, 200, 0], "aurora": [80, 230, 180, 200, -120], # extended colours (tint only) "maroon": [128, 30, 40, 256, 0], "navy": [20, 40, 110, 256, 0], "olive": [110, 120, 40, 256, 0], "beige": [225, 210, 170, 256, 0], "charcoal": [55, 58, 66, 256, 0], "ivory": [255, 250, 230, 256, 0], "coral": [255, 120, 90, 256, 0], "salmon": [250, 140, 120, 256, 0], "peach": [255, 200, 160, 256, 0], "lavender": [200, 170, 240, 256, 0], "lilac": [200, 160, 220, 256, 0], "mint": [180, 245, 210, 256, 0], "sage": [160, 190, 150, 256, 0], "jade": [60, 200, 150, 256, 0], "ruby": [220, 30, 70, 256, 0], "sapphire": [40, 70, 200, 256, 0], "amethyst": [150, 90, 210, 256, 0], "copper": [200, 120, 70, 256, 0], "bronze": [180, 130, 80, 256, 0], "rust": [180, 80, 40, 256, 0], "ochre": [200, 150, 60, 256, 0], "sepia": [150, 110, 80, 256, 0], "cream": [255, 250, 220, 256, 0], "tan": [210, 180, 140, 256, 0], "khaki": [190, 180, 130, 256, 0], "mauve": [200, 150, 170, 256, 0], "periwinkle": [150, 160, 235, 256, 0], "chartreuse": [180, 240, 60, 256, 0], "vermillion": [230, 70, 40, 256, 0], "ultramarine": [40, 50, 200, 256, 0], "cerulean": [40, 150, 230, 256, 0], "chrome": [200, 210, 225, 320, 0], "neon": [80, 255, 180, 380, 0], # nature (colour + texture + direction) "meadow": [120, 210, 90, 130, -100], "field": [150, 200, 100, 110, -120], "jungle": [40, 170, 70, 360, 160], "swamp": [80, 120, 70, 220, -40], "glacier": [200, 225, 245, 110, 0], "tundra": [190, 200, 210, 90, -100], "canyon": [200, 130, 80, 200, 60], "cliff": [160, 150, 140, 200, 200], "cave": [70, 65, 78, 150, 0], "volcano": [210, 80, 40, 400, 80], "lava": [240, 90, 20, 380, 60], "lagoon": [40, 200, 200, 140, -150], "tide": [50, 130, 200, 180, -180], "foam": [220, 235, 245, 200, -60], "waterfall": [120, 180, 230, 360, 230], "lake": [70, 150, 210, 90, -200], "stream": [90, 170, 220, 200, -40], "pebble": [170, 165, 160, 180, 0], "boulder": [140, 140, 150, 160, 0], "dust": [200, 185, 160, 220, 0], "ash": [130, 130, 136, 200, 0], "moss": [90, 160, 80, 240, 0], "fern": [70, 180, 90, 280, 140], "grass": [90, 200, 80, 300, 200], "petal": [255, 160, 200, 200, 0], "blossom": [255, 180, 210, 180, 0], "pine": [40, 120, 70, 320, 200], "oak": [120, 140, 70, 280, 180], "palm": [80, 180, 100, 260, 200], "cactus": [110, 170, 90, 300, 160], "bamboo": [150, 200, 110, 320, 240], "wheat": [225, 200, 120, 200, -150], "reef": [80, 200, 180, 300, 0], # weather "fog": [200, 205, 212, 70, 0], "haze": [205, 200, 196, 80, 0], "drizzle": [150, 170, 200, 280, 210], "downpour": [110, 140, 190, 380, 235], "blizzard": [225, 235, 255, 430, 200], "thunder": [90, 90, 122, 440, 60], "breeze": [180, 210, 210, 200, -80], "gale": [150, 180, 200, 360, -40], "monsoon": [90, 120, 170, 400, 210], "tornado": [140, 140, 162, 460, 240], "hail": [200, 215, 236, 440, 0], # celestial / space "galaxy": [120, 80, 200, 360, 0], "nebula": [180, 80, 210, 320, 0], "cosmos": [60, 50, 140, 280, 0], "comet": [220, 220, 255, 380, 0], "meteor": [230, 180, 120, 400, 60], "planet": [120, 150, 200, 160, 0], "orbit": [150, 180, 230, 220, 0], "constellation": [220, 225, 255, 340, 0], "solar": [255, 210, 90, 200, 0], "lunar": [210, 215, 236, 100, 0], "stellar": [220, 225, 255, 320, 0], "void": [30, 30, 52, 100, 0], "abyss": [25, 30, 56, 110, 0], "cyclone": [130, 140, 170, 460, 0], "hurricane": [120, 130, 160, 460, 0], # materials "metal": [150, 155, 166, 300, 0], "steel": [160, 170, 186, 280, -40], "iron": [110, 110, 122, 260, 0], "silk": [225, 215, 226, 90, -40], "velvet": [120, 40, 90, 110, 0], "marble": [225, 225, 232, 130, 0], "granite": [150, 150, 156, 220, 0], "slate": [110, 120, 132, 180, -60], "glass": [210, 225, 236, 160, 0], "ceramic": [230, 220, 212, 140, 0], # moods / abstract "joy": [255, 210, 90, 280, 0], "melancholy": [90, 110, 170, 100, -60], "tranquil": [140, 200, 200, 70, -120], "frenzy": [240, 90, 70, 470, 0], "fury": [230, 40, 30, 470, 0], "rage": [220, 30, 22, 470, 0], "bliss": [255, 200, 220, 200, 0], "gloom": [70, 75, 98, 110, 0], "hope": [180, 220, 255, 200, -60], "mystic": [120, 80, 200, 260, 0], "ethereal": [200, 210, 255, 150, 0], "surreal": [220, 120, 230, 300, 0], "ominous": [80, 70, 92, 200, 0], "eerie": [110, 140, 130, 260, 0], "cozy": [230, 170, 120, 150, 0], "vibrant": [255, 90, 150, 380, 0], "muted": [170, 165, 176, 120, 0], "festive": [255, 120, 140, 360, 0], # light "shadow": [60, 60, 76, 150, 0], "shimmer": [225, 230, 200, 360, 0], "sparkle": [240, 245, 226, 420, 0], "gleam": [240, 240, 212, 280, 0], "beam": [255, 250, 210, 200, 200], "dazzle": [255, 250, 232, 440, 0], "moonlight": [200, 210, 236, 100, 0], "sunlight": [255, 235, 160, 180, 0], "starlight": [220, 225, 255, 320, 0], # geometric "lattice": [180, 190, 200, 360, 0], "grid": [185, 190, 200, 340, 0], "mesh": [180, 185, 196, 380, 0], "web": [170, 180, 196, 360, 0], "fractal": [180, 120, 210, 420, 0], "mosaic": [210, 150, 120, 360, 0], "weave": [190, 170, 150, 340, 0], # creatures (colour + texture + direction) "tiger": [240, 130, 30, 300, -190], "zebra": [180, 180, 186, 340, 240], "peacock": [30, 180, 180, 300, 0], "dragon": [200, 50, 40, 400, 0], "phoenix": [255, 110, 30, 400, 0], "serpent": [120, 180, 90, 320, 200], "jellyfish": [180, 150, 230, 200, 0], "octopus": [180, 80, 160, 320, 0], "feather": [220, 210, 232, 240, 200], "dragonfly": [80, 200, 200, 340, 0], "firefly": [230, 230, 120, 300, 0], "koi": [240, 120, 60, 240, -60], "swan": [240, 240, 246, 110, -60], "raven": [50, 50, 66, 220, 0], "owl": [180, 150, 110, 220, 0], "fox": [220, 120, 50, 260, 0], "wolf": [140, 145, 156, 240, 0], "deer": [180, 140, 100, 200, 0], "whale": [70, 110, 160, 100, -200], "dolphin": [120, 180, 220, 160, -120], "shark": [120, 140, 162, 220, -80], # food / drink (tint) "wine": [110, 30, 50, 256, 0], "honey": [240, 190, 70, 256, 0], "coffee": [110, 70, 46, 256, 0], "chocolate": [90, 55, 36, 256, 0], "berry": [120, 40, 90, 256, 0], "cherry": [200, 30, 50, 256, 0], "plum": [120, 60, 110, 256, 0], "grape": [110, 70, 140, 256, 0], "mango": [255, 170, 50, 256, 0], "lemon": [245, 230, 70, 256, 0], "caramel": [200, 140, 70, 256, 0], "cinnamon": [180, 90, 50, 256, 0], "saffron": [240, 160, 40, 256, 0], "matcha": [140, 190, 80, 256, 0], "cocoa": [120, 75, 50, 256, 0], "blueberry": [60, 80, 160, 256, 0], "strawberry": [230, 50, 70, 256, 0], "pumpkin": [240, 140, 40, 256, 0], "pistachio": [160, 210, 130, 256, 0], "vanilla": [245, 235, 200, 256, 0], # gems / minerals "opal": [200, 220, 236, 280, 0], "pearl": [240, 238, 236, 150, 0], "onyx": [40, 40, 52, 200, 0], "quartz": [225, 220, 236, 280, 0], "topaz": [230, 180, 80, 256, 0], "garnet": [150, 30, 50, 256, 0], "obsidian": [35, 35, 46, 240, 0], "malachite": [40, 160, 90, 300, 0], "jet": [40, 40, 52, 200, 0], "moonstone": [210, 220, 236, 180, 0], # architecture / places "city": [150, 160, 180, 360, 240], "cathedral": [180, 170, 200, 280, 200], "temple": [200, 180, 150, 240, 200], "ruins": [160, 150, 136, 240, 0], "castle": [150, 150, 162, 260, 200], "tower": [160, 165, 176, 300, 240], "dome": [200, 200, 212, 200, 0], "spire": [180, 180, 196, 320, 240], "labyrinth": [150, 140, 132, 380, 0], "garden": [140, 200, 110, 240, 0], "maze": [160, 160, 172, 400, 0], "bridge": [170, 160, 152, 220, -100], # abstract concepts "love": [255, 120, 150, 200, 0], "passion": [220, 40, 60, 380, 0], "harmony": [160, 210, 200, 90, 0], "balance": [180, 190, 200, 110, 0], "energy": [255, 200, 40, 420, 0], "power": [230, 70, 40, 420, 0], "freedom": [150, 200, 255, 180, -120], "wonder": [200, 180, 255, 200, 0], "mystery": [90, 70, 130, 220, 0], "infinity": [120, 150, 220, 240, 0], "eternity": [110, 130, 200, 180, 0], "silence": [200, 205, 216, 60, 0], "echo": [180, 190, 210, 220, 0], "zen": [180, 200, 190, 60, -100], # cosmic / sci-fi "plasma": [200, 80, 200, 420, 0], "quasar": [180, 200, 255, 400, 0], "pulsar": [220, 230, 255, 380, 0], "supernova": [255, 180, 120, 440, 0], "blackhole": [30, 30, 52, 300, 0], "matrix": [60, 230, 90, 380, 240], "circuit": [80, 200, 160, 360, 0], "hologram": [120, 220, 230, 360, 0], "laser": [255, 60, 90, 400, 0], "wormhole": [120, 90, 200, 380, 0], "cyber": [90, 210, 200, 400, 0], "digital": [100, 200, 180, 380, 0], # botanical "lotus": [255, 170, 210, 200, 0], "orchid": [210, 120, 200, 220, 0], "daisy": [245, 240, 212, 240, 0], "sunflower": [250, 200, 50, 260, 0], "poppy": [220, 40, 40, 300, 0], "tulip": [230, 80, 120, 240, 200], "ivy": [70, 140, 70, 300, 200], "willow": [130, 180, 120, 240, 200], "lily": [240, 235, 246, 200, 0], # seasons / time "autumn": [210, 120, 50, 240, 0], "spring": [150, 220, 120, 200, 0], "summer": [255, 200, 90, 220, 0], "winter": [200, 220, 240, 150, 0], "harvest": [220, 160, 60, 240, 0], "equinox": [200, 180, 160, 180, -100], "solstice": [255, 200, 120, 200, 0], # synesthetic (music / sound) "rhythm": [220, 120, 80, 400, 0], "melody": [180, 200, 230, 120, -60], "pulse": [230, 90, 120, 300, 0], "bass": [80, 90, 142, 80, 0], "jazz": [200, 140, 90, 360, 0], "blues": [60, 90, 180, 180, -100], "resonance": [160, 180, 220, 260, 0], # angular rays (the angular component is in SHAPE) "star": [240, 235, 255, 320, 0], "ray": [255, 245, 200, 280, 0], "rays": [255, 245, 200, 280, 0], "sunburst": [255, 210, 90, 300, 0], "starburst": [240, 240, 255, 360, 0], "pinwheel": [220, 130, 200, 320, 0], "spoke": [200, 200, 210, 300, 0], "fan": [200, 210, 220, 260, 0], "radiate": [255, 220, 150, 300, 0], "burst": [255, 180, 120, 380, 0], "flare": [255, 170, 90, 360, 0], "shine": [255, 245, 200, 280, 0], # spirals (the spiral component is in SHAPE) "swirl": [200, 140, 210, 320, 0], "whirl": [180, 150, 210, 340, 0], "whirlpool": [70, 140, 200, 320, 0], "twist": [200, 160, 180, 320, 0], "twirl": [220, 160, 200, 320, 0], "helix": [150, 190, 220, 340, 0], "coil": [180, 170, 200, 320, 0], "hypnotic": [180, 120, 220, 360, 0], "curl": [200, 180, 200, 300, 0], "eddy": [90, 160, 200, 300, 0], } # shape overlay: word -> [radial, mirror, gradient]; radial/mirror in 0..256 # (weight toward that component type), gradient in -256..256 (vertical brightness # ramp, +bright top). Merged onto the 5-element base above; unlisted words → [0,0,0]. SHAPE = { "sun": [235, 0, 60], "moon": [185, 0, 0], "eye": [245, 0, 0], "target": [255, 0, 0], "ring": [255, 0, 0], "ripple": [235, 0, 0], "circle": [245, 0, 0], "orb": [235, 0, 0], "halo": [235, 0, 40], "bloom": [205, 50, 0], "flower": [205, 90, 0], "spiral": [215, 0, 0], "vortex": [235, 0, 0], "portal": [235, 0, 0], "eclipse": [245, 0, 0], "bubble": [215, 0, 0], "lens": [205, 0, 0], "mandala": [205, 190, 0], "radiant": [235, 0, 40], "glow": [200, 0, 30], "kaleidoscope": [70, 255, 0], "mirror": [0, 255, 0], "symmetry": [0, 245, 0], "symmetric": [0, 235, 0], "crystal": [50, 225, 0], "snowflake": [130, 245, 0], "gem": [50, 205, 0], "prism": [50, 205, 0], "butterfly": [0, 215, 0], "sky": [0, 0, 205], "dawn": [40, 0, 175], "dusk": [40, 0, -175], "sunrise": [60, 0, 175], "sunset": [60, 0, -170], "horizon": [0, 0, 120], "gradient": [0, 0, 205], "fade": [0, 0, 165], "depth": [0, 0, -150], "ombre": [0, 0, 185], "twilight": [0, 0, -160], "aurora": [0, 0, 150], "night": [0, 0, -90], # extended: celestial / swirls → radial "galaxy": [200, 90, 0], "nebula": [205, 0, 0], "cosmos": [185, 0, -60], "planet": [235, 0, 0], "orbit": [240, 0, 0], "solar": [235, 0, 40], "lunar": [205, 0, 0], "cyclone": [230, 0, 0], "hurricane": [225, 0, 0], "mystic": [170, 60, 0], "sparkle": [120, 0, 0], # extended: lattices / weaves → mirror (some also radial) "lattice": [0, 235, 0], "grid": [0, 245, 0], "mesh": [0, 235, 0], "fractal": [60, 215, 0], "mosaic": [0, 225, 0], "weave": [0, 215, 0], "marble": [0, 150, 0], "web": [130, 150, 0], # extended: atmosphere → gradient "fog": [0, 0, 170], "haze": [0, 0, 150], "drizzle": [0, 0, 150], "downpour": [0, 0, 130], "blizzard": [0, 0, 120], "moonlight": [0, 0, 170], "sunlight": [0, 0, 185], "ethereal": [0, 0, 160], "abyss": [0, 0, -180], "void": [0, 0, -120], "beam": [0, 0, 150], # batch 3: radial (some with a gradient) "peacock": [200, 0, 0], "jellyfish": [205, 0, 0], "firefly": [180, 0, 0], "dome": [235, 0, 0], "energy": [215, 0, 0], "wonder": [185, 0, 0], "echo": [220, 0, 0], "plasma": [215, 0, 0], "quasar": [235, 0, 30], "pulsar": [235, 0, 0], "supernova": [240, 0, 60], "blackhole": [225, 0, -160], "hologram": [195, 0, 0], "wormhole": [235, 0, 0], "pulse": [215, 0, 0], "resonance": [205, 0, 0], "lotus": [200, 0, 0], "daisy": [215, 0, 0], "sunflower": [235, 0, 0], "lily": [195, 0, 0], "opal": [150, 0, 0], "pearl": [185, 0, 0], "moonstone": [165, 0, 0], "phoenix": [185, 0, 40], "dragonfly": [60, 0, 0], # batch 3: mirror (lattices, symmetry, weaves) "cathedral": [0, 215, 0], "labyrinth": [0, 235, 0], "maze": [0, 245, 0], "harmony": [0, 185, 0], "balance": [0, 215, 0], "matrix": [0, 215, 0], "circuit": [0, 205, 0], "digital": [0, 215, 0], "quartz": [0, 175, 0], "malachite": [0, 165, 0], "infinity": [180, 175, 0], "eternity": [195, 0, 0], # batch 3: gradient "silence": [0, 0, 130], "zen": [0, 0, 120], "freedom": [0, 0, 150], "melody": [0, 0, 130], "blues": [0, 0, -120], "onyx": [0, 0, -150], "obsidian": [0, 0, -160], } # batch 4 — angular (rays) and spiral. These entries are 5-element # [radial, mirror, gradient, angular, spiral]; the merge keeps the first 5 of any # overlay, so existing 3-element entries above still zero-pad angular/spiral. SHAPE.update({ # angular rays "star": [0, 0, 0, 235, 0], "ray": [0, 0, 0, 235, 0], "rays": [0, 0, 0, 235, 0], "sunburst": [0, 0, 40, 235, 0], "starburst": [0, 0, 0, 240, 0], "pinwheel": [0, 0, 0, 235, 40], "spoke": [0, 0, 0, 225, 0], "fan": [0, 0, 0, 200, 0], "radiate": [0, 0, 30, 225, 0], "burst": [0, 0, 0, 235, 0], "flare": [0, 0, 20, 225, 0], "shine": [0, 0, 40, 200, 0], # spirals (a touch of angular keeps the arms tight) "swirl": [0, 0, 0, 40, 235], "whirl": [0, 0, 0, 40, 235], "whirlpool": [0, 0, 0, 30, 240], "twist": [0, 0, 0, 30, 225], "twirl": [0, 0, 0, 40, 225], "helix": [0, 0, 0, 30, 235], "coil": [0, 0, 0, 30, 230], "hypnotic": [0, 0, 0, 50, 240], "curl": [0, 0, 0, 30, 200], "eddy": [0, 0, 0, 40, 210], # reclassify the swirl-words that were radial → spiral (galaxy = radial + spiral arms) "spiral": [0, 0, 0, 40, 215], "vortex": [0, 0, 0, 40, 210], "cyclone": [0, 0, 0, 30, 210], "galaxy": [200, 0, 0, 0, 130], }) def main(outdir): os.makedirs(outdir, exist_ok=True) sine_lut = [int(round(math.sin(2.0 * math.pi * i / T) * (1 << LUT_BITS))) for i in range(T)] model = { 'version': 'wai.generate.spectral/4', # /4 adds angular (rays) + spiral components 'lut_size': T, 'lut_bits': LUT_BITS, 'sine_lut': sine_lut, 'freq_max': 24, # spatial frequency range drawn per component (at neutral) 'amp_bits': 6, # component amplitude range [0, 2^amp_bits) 'color_offsets': [0, T // 3, 2 * T // 3], # per-channel phase (RGB) — a colour wheel 'base_components': 8, # components at steps=0; total K = base + steps·step_components 'step_components': 8, # concept word -> [r, g, b, freq_q8, orient, radial, mirror, gradient, angular, spiral] 'lexicon': {w: list(v) + (SHAPE.get(w, []) + [0, 0, 0, 0, 0])[:5] for w, v in LEX.items()}, } path = f'{outdir}/generate_spectral_model.json' blob = json.dumps(model, separators=(',', ':')).encode() open(path, 'wb').write(blob) # The model PIN is the sha256 of the committed file bytes — anyone can verify # it, and (pin, prompt, seed, steps) pins the output exactly. pin = hashlib.sha256(blob).hexdigest() print(f"wrote generate_spectral_model.json ({len(sine_lut)} LUT entries), file sha256 {pin[:16]}…") if __name__ == '__main__': main(sys.argv[1])