2026-06-04 12:18:30 +00:00
# Source Bundle Internals
2026-05-31 02:07:30 +00:00
2026-06-04 12:18:30 +00:00
Audience: developers and LLM coding agents changing `internal/bundle` .
2026-05-31 02:07:30 +00:00
2026-06-04 12:18:30 +00:00
## Purpose
2026-05-31 02:07:30 +00:00
2026-06-04 12:18:30 +00:00
`internal/bundle` discovers and validates source bundles through the storage abstraction. It adapts the public producer-facing source manifest contract from `pkg/bundle` to local, SSH/SFTP, S3-compatible, and test storage backends.
2026-05-31 02:07:30 +00:00
2026-06-04 12:18:30 +00:00
## Inputs And Outputs
2026-05-31 02:07:30 +00:00
2026-06-04 12:18:30 +00:00
Inputs are a context, a `storage.Backend` , and a source-root prefix or bundle root path. Outputs are sorted `Bundle` records containing the source-root-relative bundle path and validated manifest.
2026-05-31 02:07:30 +00:00
2026-06-04 12:18:30 +00:00
## Boundaries
2026-05-31 02:07:30 +00:00
2026-06-04 12:18:30 +00:00
`internal/bundle` delegates manifest parsing, digest calculation, source path validation, and manifest validation to `pkg/bundle` . It does not publish files, inspect destination state, choose pipelines, or know concrete backend implementations.
2026-05-31 02:07:30 +00:00
2026-06-04 12:18:30 +00:00
The external source bundle file-format contract is documented in `docs/integrations/source-bundle.md` .
2026-05-31 02:07:30 +00:00
2026-06-04 12:18:30 +00:00
## Config Fields Used
2026-06-02 19:00:09 +00:00
2026-06-04 12:18:30 +00:00
The package does not read config directly. App workflows pass it storage backends that were opened from configured source fields.
2026-05-31 02:07:30 +00:00
2026-06-04 12:18:30 +00:00
## Adapters Used
2026-05-31 03:22:20 +00:00
2026-06-04 12:18:30 +00:00
The package depends only on `internal/storage.Backend` . Concrete local, SSH/SFTP, S3-compatible, and fake backends are hidden behind that interface.
2026-05-31 02:07:30 +00:00
2026-06-04 12:18:30 +00:00
## State And Manifest Behavior
2026-05-31 02:07:30 +00:00
2026-06-04 12:18:30 +00:00
Discovery walks recursively under the source root, finds entries whose basename is `manifest.json` , converts each manifest path to a bundle root, sorts roots, rejects nested bundle roots, and validates each bundle.
2026-05-31 02:07:30 +00:00
2026-06-04 12:18:30 +00:00
Validation reads `manifest.json` , parses it, stats each manifest-listed file, requires regular files, verifies file sizes, reads file bytes, checks per-file SHA-256 digests, and recomputes the bundle digest.
2026-05-31 02:07:30 +00:00
2026-06-04 12:18:30 +00:00
## Skip And Resume Behavior
2026-05-31 04:06:48 +00:00
2026-06-04 12:18:30 +00:00
The package has no skip or resume state. Each call performs discovery or validation from the supplied backend state.
2026-05-31 04:06:48 +00:00
2026-06-04 12:18:30 +00:00
## Failure Behavior
2026-05-31 02:07:30 +00:00
2026-06-04 12:18:30 +00:00
Failures include invalid storage prefixes, missing manifests, parse errors, nested manifests, unsafe manifest paths, non-regular files, size mismatches, digest mismatches, backend stat/read errors, and no discovered bundles.
2026-05-31 02:07:30 +00:00
2026-06-04 12:18:30 +00:00
## Tests To Inspect
2026-05-31 02:07:30 +00:00
2026-06-04 12:18:30 +00:00
- `internal/bundle/*_test.go`
- `pkg/bundle/*_test.go`
- `internal/storage/fake/*_test.go`
2026-05-31 04:06:48 +00:00
2026-06-04 12:18:30 +00:00
## Architectural Invariants
2026-05-31 04:06:48 +00:00
2026-06-04 12:18:30 +00:00
- Source manifest semantics remain owned by `pkg/bundle` .
- Discovery order is deterministic.
- Nested manifests are rejected before returning bundles.
- Source paths stay clean, relative, slash-separated, and confined to the backend root.
- Concrete adapters never leak into bundle validation logic.