Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Table of Contents

Determinism

ggen ensures deterministic, reproducible code generation through manifest hashing and version locking.

Manifest Key Calculation

For local templates:

K = SHA256(seed || graph_hash || shapes_hash || frontmatter_hash || rows_hash)

For marketplace gpacks:

K = SHA256(seed || gpack_version || gpack_deps_hash || graph_hash || shapes_hash || frontmatter_hash || rows_hash)

Hash Components

Local Templates

  • Graph hash: sorted N-Quads from RDF sources
  • Shapes hash: sorted N-Quads from SHACL validation
  • Frontmatter hash: rendered header + body bytes
  • Rows hash: ordered serialization of matrix rows

Marketplace Gpacks

  • Gpack version: exact version from ggen.toml
  • Gpack deps hash: hash of all dependency versions
  • Graph hash: sorted N-Quads from gpack RDF sources
  • Shapes hash: sorted N-Quads from gpack SHACL validation
  • Frontmatter hash: rendered header + body bytes
  • Rows hash: ordered serialization of matrix rows

Version Locking

Gpack Version Management

# Install specific version
ggen add io.ggen.rust.cli-subcommand@0.2.1

# Check installed versions
ggen packs

# View lockfile
cat ggen.lock

Lockfile Structure

[lockfile]
version = "1.0"

[gpacks]
"io.ggen.rust.cli-subcommand" = "0.2.1"
"io.ggen.macros.std" = "0.2.0"

[dependencies]
"io.ggen.rust.cli-subcommand" = {
    version = "0.2.1",
    source = "registry",
    checksum = "sha256:abc123..."
}

Deterministic Behavior

Same Inputs → Identical Outputs

# First generation
ggen gen io.ggen.rust.cli-subcommand:cli/subcommand/rust.tmpl name=hello

# Second generation (same inputs)
ggen gen io.ggen.rust.cli-subcommand:cli/subcommand/rust.tmpl name=hello

# Outputs are byte-identical
diff src/cmds/hello.rs src/cmds/hello.rs
# No differences

Cross-Language Consistency

# Generate across languages with same inputs
ggen gen io.ggen.rust.cli-subcommand:cli/subcommand/rust.tmpl name=hello
ggen gen io.ggen.python.cli-subcommand:cli/subcommand/python.tmpl name=hello
ggen gen io.ggen.bash.cli-subcommand:cli/subcommand/bash.tmpl name=hello

# All outputs share the same semantic model
# Variable binding is consistent across languages

Gpack Dependencies and Determinism

Dependency Resolution

# Install gpack with dependencies
ggen add io.ggen.rust.cli-subcommand

# Dependencies are automatically resolved
ggen packs

# Output:
# ID                                    VERSION    KIND       TAGS
# io.ggen.rust.cli-subcommand           0.2.1      template   rust, cli, clap
# io.ggen.macros.std                    0.2.0      macro      rust, macros

Dependency Hashing

Dependencies affect determinism through their versions:

# Check dependency versions
ggen show io.ggen.rust.cli-subcommand --deps

# Update dependencies
ggen update

# Verify determinism after update
ggen gen io.ggen.rust.cli-subcommand:cli/subcommand/rust.tmpl name=hello --dry

Ensuring Determinism

Gpack Development

# Pin versions in development
ggen add io.ggen.rust.cli-subcommand@0.2.1

# Test determinism
ggen gen io.ggen.rust.cli-subcommand:cli/subcommand/rust.tmpl name=test1
ggen gen io.ggen.rust.cli-subcommand:cli/subcommand/rust.tmpl name=test1
# Should produce identical output

Production Deployment

# Lock versions for production
ggen add io.ggen.rust.cli-subcommand@0.2.1
ggen add io.ggen.python.cli-subcommand@0.1.8

# Commit lockfile
git add ggen.lock
git commit -m "Lock gpack versions for production"

# Deploy with locked versions
ggen gen io.ggen.rust.cli-subcommand:cli/subcommand/rust.tmpl name=api

Troubleshooting Determinism

Non-Deterministic Output

# Check for version changes
ggen packs

# Verify lockfile
cat ggen.lock

# Check for dependency updates
ggen update --dry

Manifest Key Changes

# Enable tracing to see hash components
GGEN_TRACE=1 ggen gen io.ggen.rust.cli-subcommand:cli/subcommand/rust.tmpl name=hello

# Output shows:
# Manifest key: sha256:abc123...
# Gpack version: 0.2.1
# Graph hash: sha256:def456...
# Frontmatter hash: sha256:ghi789...

Cross-Environment Consistency

# Ensure same gpack versions across environments
ggen add io.ggen.rust.cli-subcommand@0.2.1

# Verify environment consistency
ggen gen io.ggen.rust.cli-subcommand:cli/subcommand/rust.tmpl name=hello --dry

Best Practices

Version Pinning

  • Pin specific versions for production
  • Use semantic versioning
  • Test updates before applying
  • Maintain lockfile consistency

Dependency Management

  • Minimize dependency depth
  • Use stable dependency versions
  • Test dependency updates
  • Document version requirements

Deterministic Testing

  • Test with multiple variable sets
  • Verify cross-language consistency
  • Use golden tests for validation
  • Monitor manifest key changes

Same inputs + same gpack versions + same dependencies ⇒ byte-identical outputs across all environments.