setdigest

package
v0.22.0 Latest Latest
Warning

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

Go to latest
Published: Oct 6, 2026 License: MPL-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package setdigest is GitHub issue #1754's set digest: one digest over a set of per-root plans, order-independent, moving whenever any one root's change set moves. internal/live/setplan prints it and internal/live/waves checks an approval against it.

It imports the standard library only, and must keep doing so: internal/live/setplan reaches internal/command/views and from there almost every package, so anything this package imported would join that graph (the import cycles that broke #1816's first gate). TestImportsStdlibOnly holds it.

What a root digest covers

SHA-256 over a canonical encoding of what that root's plan would change, and nothing that varies between two plans that change the same things:

  • the root's directory as the set names it, and its estate;
  • its status and, for a failed root, its error text, so a failed root never shares a digest with a planned one;
  • whether stock marked the plan errored;
  • every element of the plan's resource_changes whose actions are not exactly ["no-op"], whole and unedited: address, deposed key, actions, before, after, after_unknown, the sensitivity maps, replace_paths, action_reason, importing, every field stock writes there;
  • every entry of output_changes whose actions are not ["no-op"].

Each JSON value is decoded and re-encoded so that key order and whitespace cannot move the digest, numbers keep their literal text, and resource_changes are sorted by address then deposed key, which are unique within a plan. Nothing is normalized away: two plans that differ in any value they would write have different digests. The no-op entries are left out because they write nothing, so the digest does not move when a resource the plan does not touch drifts. The top-level timestamp, prior_state, configuration and resource_drift are left out for the same reason: they describe the plan, not what it changes.

The set digest is SHA-256 over the root digests, each framed with its root's directory, in directory order. It is therefore independent of the order roots were given in and changes whenever any one root's digest does. A set that names one directory twice has no digest.

Index

Constants

View Source
const DigestPrefix = "sha256:"

DigestPrefix starts every digest this package prints, so a reader can tell which hash it is and a later version can change the hash without a digest from one being mistaken for the other.

View Source
const StatusPlanned = "planned"

StatusPlanned is the status of a root whose plan was written.

Variables

This section is empty.

Functions

func DocumentDigests

func DocumentDigests(doc *SetDocument) (map[string]string, string, error)

DocumentDigests computes every root's digest in doc and the digest of the whole set, keyed by root.

func RootDigest

func RootDigest(r RootPlan) (string, error)

RootDigest is r's digest. See the package documentation for what it covers.

func SetDigest

func SetDigest(entries []RootDigestEntry) (string, error)

SetDigest is the digest over a set of root digests: independent of their order, and different whenever any one of them is. It refuses a set that names one root twice, which has no single change set for that root.

Types

type RootDigestEntry

type RootDigestEntry struct {
	Root   string `json:"root"`
	Digest string `json:"digest"`
}

RootDigestEntry is one root and its digest, the input to SetDigest.

type RootPlan

type RootPlan struct {
	Root   string          `json:"root"`
	Estate string          `json:"estate"`
	Status string          `json:"status"`
	Error  string          `json:"error"`
	Plan   json.RawMessage `json:"plan"`
}

RootPlan is one root of a set plan document (GitHub issue #1752's -json output): only the fields the digest reads.

type SetDocument

type SetDocument struct {
	Roots []RootPlan `json:"roots"`
}

SetDocument is the part of a set plan document this package reads.

func ParseSetDocument

func ParseSetDocument(data []byte) (*SetDocument, error)

ParseSetDocument reads a set plan document. It requires a top-level "roots" array and a "root" on every element.

Jump to

Keyboard shortcuts

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