Skip to content

Sheet Build & Verify

This example walks through building a .sheet workbook from a Lua script, filling it with CSV data, and verifying the fingerprint — a full provenance cycle for auditable spreadsheets.

build.lua — defines the sheet structure:

-- Sheet 1: Summary
set("A1", "Metric")
set("B1", "Value")
set("A2", "Total Revenue")
set("B2", "=SUM(tx!B:B)")
set("A3", "Transaction Count")
set("B3", "=COUNTA(tx!A:A)")
set("A4", "Average Amount")
set("B4", "=AVERAGE(tx!B:B)")
-- Metadata (included in fingerprint)
meta("A1:B1", { header = true })
meta("B2:B4", { format = "currency" })
-- Style (excluded from fingerprint)
style("A1:B1", { bold = true })
style("B2:B4", { number_format = "#,##0.00" })

The script uses three functions:

  • set(cell, value) — set a cell value or formula
  • meta(target, table) — semantic metadata (affects fingerprint)
  • style(target, table) — presentation styling (excluded from fingerprint)
Terminal window
vgrid sheet apply model.sheet --lua build.lua --stamp "Q1 Close v1"

This creates model.sheet with:

  • A “Summary” sheet with formulas referencing a “tx” sheet
  • An embedded fingerprint stamped with the label “Q1 Close v1”

Use --dry-run to compute the fingerprint without writing:

Terminal window
vgrid sheet apply model.sheet --lua build.lua --dry-run

transactions.csv:

Date,Amount,Description
2025-01-02,1200.00,Acme Corp Invoice
2025-01-03,85.50,Office Supplies
2025-01-06,3500.00,Client Payment
Terminal window
vgrid fill model.sheet \
--csv transactions.csv \
--target tx!A1 \
--headers \
--out filled.sheet

This loads the CSV into the “tx” sheet starting at A1. The Summary formulas (=SUM(tx!B:B), etc.) now compute against real data.

Terminal window
# Check computed values
vgrid sheet inspect filled.sheet --sheet Summary B2:B4 --json
{
"cells": [
{"cell": "B2", "value": "4785.5", "formula": "=SUM(tx!B:B)"},
{"cell": "B3", "value": "3", "formula": "=COUNTA(tx!A:A)"},
{"cell": "B4", "value": "1595.1666...", "formula": "=AVERAGE(tx!B:B)"}
]
}
Terminal window
# List all sheets
vgrid sheet inspect filled.sheet --sheets --json

The fingerprint covers the build script’s operations (structure + metadata), not the filled data. This means you can verify that the model hasn’t been tampered with, independent of what data was loaded.

Terminal window
# Verify the model's structure matches the build script
vgrid sheet verify model.sheet
Verification: PASS (matches expected)

If someone manually edits the sheet structure, verification fails:

Verification: FAIL (fingerprint mismatch)
expected: v1:8:a3b2c1d4...
actual: v1:9:f5e6d7c8...

To reproduce the sheet from source:

Terminal window
# Rebuild from the Lua script
vgrid sheet apply rebuilt.sheet --lua build.lua --verify
# Fill with the same data
vgrid fill rebuilt.sheet \
--csv transactions.csv \
--target tx!A1 \
--headers \
--out rebuilt-filled.sheet
# Compare the two
vgrid diff filled.sheet rebuilt-filled.sheet \
--key A --no-fail --out json
#!/bin/bash
set -e
# Build
vgrid sheet apply model.sheet --lua build.lua --verify
# Fill
vgrid fill model.sheet \
--csv "$DATA_FILE" \
--target tx!A1 --headers \
--out output.sheet
# Assert expected values
vgrid publish output.sheet \
--repo acme/analytics \
--assert-cell "Summary!B2:4785.50:0.01" \
--strict
OperationIn fingerprintApplied on replay
set()YesYes
clear()YesYes
meta()YesYes
style()NoYes
Sort, mergeYes (tamper detection)No

The fingerprint format is v1:<count>:<blake3-hash>. Scripts with nondeterministic functions (NOW(), RAND()) cannot be verified.