Audience: producer developers, integrators, and maintainers who create or validate source bundles consumed by `distributor`.
A source bundle is a directory containing `manifest.json` and every regular file listed by that manifest. This is the producer-to-`distributor` file-format contract.
## Manifest Schema
Current schema version: `1`.
```json
{
"schema_version": 1,
"id": "reports.example.2026-06-04",
"digest": "sha256:...",
"created": "2026-06-04T12:00:00Z",
"files": [
{
"path": "report.md",
"sha256": "sha256:...",
"size": 1234
}
]
}
```
Required manifest fields:
-`schema_version`: must be `1`.
-`id`: non-empty bundle identifier.
-`digest`: lowercase `sha256:<64 hex>` digest of the ordered `files` list.
-`sha256`: lowercase `sha256:<64 hex>` digest of the file bytes.
-`size`: file size in bytes, zero or greater.
## Path Rules
Manifest file paths must be clean relative slash-separated paths. They must not be empty, absolute, contain backslashes, contain `.` or `..` segments, include empty path segments, or normalize to a different path.
Any basename of `manifest.json` or `.distributor.json` is reserved, including nested occurrences such as `nested/manifest.json`.
Listed files must be regular files. Symlinks and other special file types are rejected during local bundle validation and manifest building.
## Digest Rules
File digests use SHA-256 over each file's raw bytes.
The bundle digest is SHA-256 over the canonical JSON-like payload for the ordered file records. The payload is constructed as:
Go producers can use `gitea.maximumdirect.net/eric/distributor/pkg/bundle` to build and validate this contract. See [`pkg/bundle`](../consumers/pkg-bundle.md) for producer workflow guidance.
Go producers that submit bundles to `distributor serve` can use `gitea.maximumdirect.net/eric/distributor/pkg/upload`. See [Upstream Producer Integration](../consumers/api.md) and [HTTP Upload API Contract](http-upload.md).
go run ./cmd/distributor manifest create <bundle-path> --id <bundle-id>
go run ./cmd/distributor validate <bundle-path>
```
## Scan Mode
Manifest scan mode walks the local bundle root recursively, includes regular files, includes dotfiles, skips files whose basename is `manifest.json` or `.distributor.json`, rejects symlinks, and sorts paths before building the manifest.
## Boundaries
The source bundle manifest does not configure routing, destination selection, public URLs, credentials, transforms, notification behavior, or storage backends. Those concerns belong in `distributor` configuration and destination state.