# `pkg/bundle` Audience: upstream Go producer developers and LLM coding agents using `distributor` source bundle helpers. Import path: ```go import "gitea.maximumdirect.net/eric/distributor/pkg/bundle" ``` `pkg/bundle` builds, writes, parses, and validates local source bundles. Use it directly when a producer writes bundles for `distributor` to discover, or when a producer wants to assemble and validate a bundle before using another transport. The canonical source bundle file-format contract is [Source Bundle Contract](../integrations/source-bundle.md). ## Preferred Complete-Bundle Workflow Use `WriteBundle` when producer-generated files live outside the final bundle root. ```go manifest, err := bundle.WriteBundle(bundle.WriteBundleOptions{ Root: "/var/spool/distributor/weather/hourly-2026-06-07T15", ID: "weather.hourly.brentwood.2026-06-07T15", Files: []bundle.BundleFile{ {SourcePath: "/tmp/weather/report.md", Path: "report.md"}, {SourcePath: "/tmp/weather/summary.txt", Path: "summary.txt"}, }, }) if err != nil { return err } _ = manifest ``` `WriteBundle` copies each source file into a staged bundle root, writes `manifest.json`, validates the staged bundle, and promotes it into place. Set `Overwrite: true` only when the producer intentionally replaces an existing bundle root. ## Existing Bundle Root Workflow Use `BuildManifest` and `WriteManifest` when files are already staged under the final bundle root. ```go root := "/var/spool/distributor/weather/hourly-2026-06-07T15" manifest, err := bundle.BuildManifest(bundle.BuildOptions{ Root: root, ID: "weather.hourly.brentwood.2026-06-07T15", Files: []string{"report.md", "summary.txt"}, }) if err != nil { return err } if err := bundle.WriteManifest(root, manifest, bundle.WriteManifestOptions{}); err != nil { return err } if err := bundle.ValidateBundle(root, manifest); err != nil { return err } ``` Use `Scan: true` instead of `Files` only when every valid regular file under the root should be included. Scan mode includes dotfiles, skips reserved metadata files, rejects symlinks, and sorts paths lexically. ## Paths And Ordering Bundle paths are slash-separated paths relative to the bundle root. Invalid paths include: - empty paths; - absolute paths; - paths containing backslashes; - `.` or `..` path segments; - empty path segments; - any basename of `manifest.json` or `.distributor.json`. Explicit file lists preserve caller order. File order is part of the bundle digest, so producers should choose it deliberately and keep it stable. ## Validation And Digest Helpers Use `ValidateBundle` before handing an existing local bundle to another process. It verifies manifest semantics, file existence, regular-file type, file size, per-file SHA-256 digests, and bundle digest. Useful helpers: - `LoadManifest`: read `manifest.json` from a bundle root. - `ParseManifest` and `MarshalManifest`: parse or write manifest bytes. - `ValidateManifest`: validate manifest-only semantics. - `FileDigest`, `BundleDigest`, and `ValidateDigest`: digest helpers for diagnostics and tests. ## Boundaries `pkg/bundle` does not upload bundles, publish destinations, transform Markdown, select pipelines, configure credentials, or write destination state. Those concerns belong to `pkg/upload` or the `distributor` application.