draftbundle

package
v0.1.0-rc.2 Latest Latest
Warning

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

Go to latest
Published: Jul 5, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package draftbundle packs and unpacks non-git project content as age-encrypted, content-addressed blobs (DRAFT-02). The bundle format is:

walk project dir under the .devstrapignore allow-list (DRAFT-03) and the
draft_projects size/file-count limits (DRAFT-04) → tar → gzip →
age-encrypt to approved-device recipients → one content-addressed
age_blob:<sha256> blob.

node_modules and build artifacts are never bundled (DRAFT-05): they are excluded by the ignore compiler and rebuilt on hydrate. Plaintext secret files / private keys are never bundled: the shared secret detector refuses them before encryption.

Extraction is the inverse: age-decrypt → gunzip → untar into the skeleton. Opaque drafts are dual-copy-on-conflict, never byte-merged (decision #7).

Index

Constants

View Source
const MaxBundleBytes = 100 * 1024 * 1024 // 100 MiB

MaxBundleBytes bounds a single draft bundle so a runaway draft cannot produce a giant encrypted blob. Per-project overrides live in draft_projects.

View Source
const MaxBundleFiles = 5000

MaxBundleFiles is the default file-count ceiling for both Pack and Extract (DRAFT-04 / QUAL-01).

Variables

View Source
var ErrBundleTooLarge = errors.New("draft bundle exceeds extraction budget (decompression bomb guard)")

ErrBundleTooLarge signals that an extraction exceeded the aggregate decompression budget (QUAL-01), aborting a gzip/tar bomb authored by a compromised-but-trusted device.

Functions

func Extract

func Extract(ciphertext []byte, identity, dest string) error

Extract age-decrypts the bundle with the local device identity, then gunzips and untars it into dest (DRAFT-02 hydrate) with a default aggregate extraction budget (QUAL-01): at most MaxBundleBytes total uncompressed bytes and MaxBundleFiles files, aborting a gzip/tar decompression bomb authored by a compromised-but-trusted device. Files are written 0600; directories 0750. Existing files are not overwritten (dual-copy conflict safety, decision #7).

func ExtractWithLimits

func ExtractWithLimits(ciphertext []byte, identity, dest string, limits Limits) error

ExtractWithLimits is like Extract but with a caller-supplied aggregate extraction budget (QUAL-01). The running total uncompressed bytes and entry count are tracked across the whole tar stream — not just per file — so a bomb that spreads across many small entries or one huge entry is caught.

Types

type Limits

type Limits struct {
	MaxBytes int64
	MaxFiles int64
}

Limits are the enforced size and file-count bounds for a draft bundle (DRAFT-04).

type Snapshot

type Snapshot struct {
	BlobRef  string // age_blob:<sha256>
	ByteSize int64
	// FileCount is the number of tar entries (regular files + directory
	// headers) in the bundle (P5-QUAL-05). Counting directory entries keeps the
	// extract-side decompression-bomb budget (P5-SEC-02) and the materialize
	// floor symmetric with what Pack produced.
	FileCount  int64
	Manifest   []string // relative paths included, for diagnostics
	Ciphertext []byte   // the encrypted blob (caller stores it)
}

Snapshot records the metadata of a packed draft bundle.

func Pack

func Pack(dir string, matcher *ignore.Matcher, limits Limits, recipients []string) (Snapshot, error)

Pack walks dir under the compiled ignore policy and the given limits, tars + gzips + age-encrypts the content to recipients, and returns the content-addressed snapshot (DRAFT-02). Secret-looking files are refused before encryption.

Jump to

Keyboard shortcuts

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