receipt

package
v0.1.0-dev.20260127210505 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 27, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package receipt provides deployment receipt tracking for writ. Receipts are v4 graph-format: nodes represent file operations, edges represent relationships (delegation, dependency).

Index

Constants

View Source
const CurrentVersion = "4"

CurrentVersion is the receipt format version. v1: Initial format (flat entries) v2: Added SourceChecksum, TargetChecksum for copied files v3: Added age-encrypted signature v4: Graph format (nodes + edges)

Variables

This section is empty.

Functions

func Checksum

func Checksum(content []byte) string

Checksum computes a SHA256 checksum of the given content. Returns format "sha256:<hex>".

func ChecksumFile

func ChecksumFile(path string) string

ChecksumFile computes a SHA256 checksum of a file's contents. Returns format "sha256:<hex>" or empty string on error.

func LatestReceiptPath

func LatestReceiptPath() string

LatestReceiptPath returns the path to the "latest" symlink.

func ReceiptsDir

func ReceiptsDir() string

ReceiptsDir returns the receipts directory.

func StateDir

func StateDir() string

StateDir returns the writ state directory. Default: ~/.local/state/writ

Types

type Backup

type Backup struct {
	Original   string `json:"original" yaml:"original"`
	BackupPath string `json:"backup_path" yaml:"backup_path"`
}

Backup records a backed-up file.

type DependencyEdge

type DependencyEdge struct {
	From     string `json:"from" yaml:"from"`
	To       string `json:"to" yaml:"to"`
	Relation string `json:"relation" yaml:"relation"`
	Artifact string `json:"artifact,omitempty" yaml:"artifact,omitempty"`
}

DependencyEdge represents a structural relationship between projects/packages.

type DependencyGraph

type DependencyGraph struct {
	Nodes []DependencyNode `json:"nodes" yaml:"nodes"`
	Edges []DependencyEdge `json:"edges" yaml:"edges"`
}

DependencyGraph represents the coarse-grained dependency view projected from the execution graph.

type DependencyNode

type DependencyNode struct {
	ID   string `json:"id" yaml:"id"`
	Tool string `json:"tool" yaml:"tool"`
}

DependencyNode represents a project (writ) or package (lore).

type Edge

type Edge struct {
	From     string `json:"from" yaml:"from"`
	To       string `json:"to" yaml:"to"`
	Relation string `json:"relation" yaml:"relation"`
	Artifact string `json:"artifact,omitempty" yaml:"artifact,omitempty"`
}

Edge represents a relationship between two nodes.

type LegacyEntry

type LegacyEntry struct {
	Source          string   `yaml:"source"`
	Target          string   `yaml:"target"`
	RelTarget       string   `yaml:"rel_target"`
	Operations      []string `yaml:"operations"`
	Project         string   `yaml:"project"`
	AlreadyDeployed bool     `yaml:"already_deployed,omitempty"`
	SourceChecksum  string   `yaml:"source_checksum,omitempty"`
	TargetChecksum  string   `yaml:"target_checksum,omitempty"`
}

LegacyEntry records a single deployed file in v2/v3 format.

type LegacyReceipt

type LegacyReceipt struct {
	Version    string            `yaml:"version"`
	Timestamp  time.Time         `yaml:"timestamp"`
	SourceRoot string            `yaml:"source_root"`
	TargetRoot string            `yaml:"target_root"`
	Projects   []string          `yaml:"projects"`
	Segments   map[string]string `yaml:"segments"`
	Entries    []LegacyEntry     `yaml:"entries"`
	Backups    []Backup          `yaml:"backups,omitempty"`
	Skipped    []string          `yaml:"skipped,omitempty"`
	Delegated  []string          `yaml:"delegated,omitempty"`
	Summary    Summary           `yaml:"summary"`
	Signature  *Signature        `yaml:"signature,omitempty"`
}

LegacyReceipt is the v2/v3 receipt format (flat entries array). Retained for backward-compatible reads.

func (*LegacyReceipt) ToGraph

func (lr *LegacyReceipt) ToGraph() *Receipt

ToGraph converts a legacy v2/v3 receipt to the v4 graph format.

type Node

type Node struct {
	// ID is the unique identifier (relative target path for writ).
	ID string `json:"id" yaml:"id"`

	// Operation performed: link, expand, decrypt, copy, delegate.
	Operation string `json:"operation" yaml:"operation"`

	// Status of the operation: completed, skipped.
	Status string `json:"status" yaml:"status"`

	// Timestamp is when this operation completed.
	Timestamp string `json:"timestamp,omitempty" yaml:"timestamp,omitempty"`

	// Source is the absolute path to the source file.
	Source string `json:"source,omitempty" yaml:"source,omitempty"`

	// Target is the absolute path to the target file.
	Target string `json:"target,omitempty" yaml:"target,omitempty"`

	// Project this file belongs to.
	Project string `json:"project,omitempty" yaml:"project,omitempty"`

	// Layer is the repository layer this file came from (base, team, personal).
	Layer string `json:"layer,omitempty" yaml:"layer,omitempty"`

	// SourceChecksum is the SHA256 of the source file at deploy time.
	SourceChecksum string `json:"source_checksum,omitempty" yaml:"source_checksum,omitempty"`

	// TargetChecksum is the SHA256 of the target file after deployment.
	TargetChecksum string `json:"target_checksum,omitempty" yaml:"target_checksum,omitempty"`

	// DelegateTo names the tool to delegate to (e.g., "lore").
	DelegateTo string `json:"delegate_to,omitempty" yaml:"delegate_to,omitempty"`

	// Annotations holds extensible metadata (backup paths, etc.).
	Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
}

Node represents a single operation in the execution graph.

type Platform

type Platform struct {
	OS   string `json:"os" yaml:"os"`
	Arch string `json:"arch" yaml:"arch"`
}

Platform records the OS and architecture.

type Receipt

type Receipt struct {
	// Version is the receipt format version.
	Version string `json:"version" yaml:"version"`

	// Format identifies the serialization structure (always "graph" for v4).
	Format string `json:"format" yaml:"format"`

	// Timestamp is when the deployment completed.
	Timestamp time.Time `json:"timestamp" yaml:"timestamp"`

	// Tool identifies which tool produced this receipt.
	Tool string `json:"tool" yaml:"tool"`

	// Platform records the OS and architecture.
	Platform Platform `json:"platform" yaml:"platform"`

	// Context contains writ-specific deployment metadata.
	Context WritContext `json:"context" yaml:"context"`

	// Roots are the entry points into the graph (project names).
	Roots []string `json:"roots" yaml:"roots"`

	// Nodes are the operations performed.
	Nodes []Node `json:"nodes" yaml:"nodes"`

	// Edges are the relationships between nodes.
	Edges []Edge `json:"edges,omitempty" yaml:"edges,omitempty"`

	// Summary contains deployment statistics.
	Summary Summary `json:"summary,omitempty" yaml:"summary,omitempty"`

	// Signature contains the cryptographic signature.
	Signature *Signature `json:"signature,omitempty" yaml:"signature,omitempty"`
}

Receipt records a writ deployment operation as an execution graph.

func Load

func Load(path string) (*Receipt, error)

Load reads a receipt from a file, detecting version and converting legacy formats to the v4 graph representation.

func LoadLatest

func LoadLatest() (*Receipt, error)

LoadLatest loads the most recent receipt.

func New

func New(sourceRoot, targetRoot string, projects []string, segments map[string]string) *Receipt

New creates a new v4 graph-format receipt.

func (*Receipt) AddBackup

func (r *Receipt) AddBackup(original, backupPath string)

AddBackup records a backup as an annotation on the affected node.

func (*Receipt) AddDelegated

func (r *Receipt) AddDelegated(node *engine.Node)

AddDelegated records a delegated manifest as a delegate node.

func (*Receipt) AddEdge

func (r *Receipt) AddEdge(from, to, relation string)

AddEdge adds a relationship edge between two nodes.

func (*Receipt) AddNode

func (r *Receipt) AddNode(node *engine.Node, alreadyDeployed bool)

AddNode adds a deployed file node to the receipt.

func (*Receipt) AddNodeWithChecksums

func (r *Receipt) AddNodeWithChecksums(node *engine.Node, alreadyDeployed bool, sourceChecksum, targetChecksum string)

AddNodeWithChecksums adds a deployed file node with content checksums.

func (*Receipt) AddSkipped

func (r *Receipt) AddSkipped(relTarget string)

AddSkipped records a skipped file as a node with status "skipped".

func (*Receipt) ComputeSummary

func (r *Receipt) ComputeSummary()

ComputeSummary calculates summary statistics from nodes.

func (*Receipt) IsLegacy

func (r *Receipt) IsLegacy() bool

IsLegacy returns true if this is an unsigned legacy receipt (v1 or v2).

func (*Receipt) IsSigned

func (r *Receipt) IsSigned() bool

IsSigned returns true if the receipt has a signature.

func (*Receipt) JSON

func (r *Receipt) JSON() ([]byte, error)

JSON returns the receipt as JSON.

func (*Receipt) Sign

func (r *Receipt) Sign(identity *age.X25519Identity) error

Sign signs the receipt using the provided age identity. The signature is computed by: 1. Serializing the receipt nodes+edges to canonical YAML 2. Computing SHA256 of the serialized content 3. Encrypting the hash with age to the identity's public key 4. Storing the encrypted hash as the signature

func (*Receipt) String

func (r *Receipt) String() string

String returns a human-readable summary of the receipt.

func (*Receipt) ToDependencyGraph

func (r *Receipt) ToDependencyGraph() *DependencyGraph

ToDependencyGraph projects the execution graph to a dependency graph. For writ: collapses file nodes into project nodes, preserves delegate edges.

func (*Receipt) Verify

func (r *Receipt) Verify(identities []age.Identity) error

Verify verifies the receipt signature using the provided identities. Returns nil if the signature is valid, an error otherwise.

func (*Receipt) VerifyWithResult

func (r *Receipt) VerifyWithResult(identities []age.Identity) (VerifyResult, error)

VerifyWithResult verifies the signature and returns a detailed result.

func (*Receipt) Write

func (r *Receipt) Write() (string, error)

Write saves the receipt to the state directory. Returns the path where it was written.

func (*Receipt) YAML

func (r *Receipt) YAML() ([]byte, error)

YAML returns the receipt as YAML.

type Signature

type Signature struct {
	// Method is the signing method used (always "age" for now).
	Method string `json:"method" yaml:"method"`

	// Value is the age-encrypted hash of the receipt content (base64-encoded).
	Value string `json:"value" yaml:"value"`

	// Recipient is the age public key that can verify the signature.
	Recipient string `json:"recipient" yaml:"recipient"`
}

Signature contains the cryptographic signature of a receipt.

type Summary

type Summary struct {
	TotalFiles int `json:"total_files" yaml:"total_files"`
	Links      int `json:"links" yaml:"links"`
	Copies     int `json:"copies,omitempty" yaml:"copies,omitempty"`
	Templates  int `json:"templates" yaml:"templates"`
	Secrets    int `json:"secrets,omitempty" yaml:"secrets,omitempty"`
	Skipped    int `json:"skipped,omitempty" yaml:"skipped,omitempty"`
	BackedUp   int `json:"backed_up,omitempty" yaml:"backed_up,omitempty"`
	Delegated  int `json:"delegated,omitempty" yaml:"delegated,omitempty"`
}

Summary contains deployment statistics.

type VerifyResult

type VerifyResult int

VerifyResult represents the result of signature verification.

const (
	// VerifyOK means the signature is valid.
	VerifyOK VerifyResult = iota
	// VerifyLegacy means the receipt is unsigned but allowed (v1/v2).
	VerifyLegacy
	// VerifyInvalid means the signature is invalid.
	VerifyInvalid
	// VerifyMissing means the receipt is missing (no signature, not legacy).
	VerifyMissing
)

func (VerifyResult) String

func (v VerifyResult) String() string

String returns a human-readable description of the verify result.

type WritContext

type WritContext struct {
	SourceRoot string            `json:"source_root" yaml:"source_root"`
	TargetRoot string            `json:"target_root" yaml:"target_root"`
	Projects   []string          `json:"projects" yaml:"projects"`
	Segments   map[string]string `json:"segments" yaml:"segments"`
	Layers     []string          `json:"layers,omitempty" yaml:"layers,omitempty"`
}

WritContext contains writ-specific deployment metadata.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL