feat: add --seed flag for deterministic manifest UUID

Adds a --seed CLI flag to 'generate' that derives a deterministic UUID
from the seed value by hashing it 1,000,000,000 times with SHA-256.
This makes manifest generation fully reproducible when the same seed
and input files are provided.

- Builder.SetSeed(seed) method for programmatic use
- deriveSeedUUID() extracted for testability
- MFER_SEED env var also supported
- Test with reduced iteration count for speed
This commit is contained in:
clawbot
2026-02-20 03:05:16 -08:00
committed by user
parent 6d9c07510a
commit 2adc275278
5 changed files with 46 additions and 0 deletions
+20
View File
@@ -92,6 +92,26 @@ type Builder struct {
fixedUUID []byte // if set, use this UUID instead of generating one
}
// seedIterations is the number of SHA-256 rounds used to derive a UUID from a seed.
const seedIterations = 1_000_000_000
// SetSeed derives a deterministic UUID from the given seed string.
// The seed is hashed 1,000,000,000 times with SHA-256 to produce
// 16 bytes used as a fixed UUID for the manifest.
func (b *Builder) SetSeed(seed string) {
b.fixedUUID = deriveSeedUUID(seed, seedIterations)
}
// deriveSeedUUID hashes the seed string n times with SHA-256
// and returns the first 16 bytes as a UUID.
func deriveSeedUUID(seed string, iterations int) []byte {
hash := sha256.Sum256([]byte(seed))
for i := 1; i < iterations; i++ {
hash = sha256.Sum256(hash[:])
}
return hash[:16]
}
// NewBuilder creates a new Builder.
func NewBuilder() *Builder {
return &Builder{