Add integration contract documentation
This commit is contained in:
92
docs/integrations/source-bundle.md
Normal file
92
docs/integrations/source-bundle.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# Source Bundle Contract
|
||||
|
||||
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.
|
||||
- `created`: RFC3339 timestamp.
|
||||
- `files`: non-empty ordered list of file records.
|
||||
|
||||
Required file fields:
|
||||
|
||||
- `path`: bundle-relative slash-separated file path.
|
||||
- `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:
|
||||
|
||||
```text
|
||||
[{"path":"<path>","sha256":"<sha256>","size":<size>},...]
|
||||
```
|
||||
|
||||
File order is significant. Explicit file lists preserve caller order. Scan mode sorts paths in ascending slash-path order.
|
||||
|
||||
## Producer APIs
|
||||
|
||||
Go producers can use `gitea.maximumdirect.net/eric/distributor/pkg/bundle` to build and validate this contract:
|
||||
|
||||
- `BuildManifest`: builds a manifest from explicit file paths or scan mode.
|
||||
- `WriteManifest`: writes `manifest.json`, optionally replacing an existing manifest.
|
||||
- `WriteBundle`: copies source files into a complete bundle, validates it, and promotes it into place.
|
||||
- `LoadManifest`, `ParseManifest`, `ValidateManifest`, and `ValidateBundle`: parse and validate local bundles.
|
||||
- `FileDigest`, `BundleDigest`, and `ValidateDigest`: digest helpers.
|
||||
|
||||
CLI producers can use:
|
||||
|
||||
```sh
|
||||
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.
|
||||
|
||||
## Tests
|
||||
|
||||
Before changing this contract, inspect and run:
|
||||
|
||||
```sh
|
||||
go test ./pkg/bundle ./internal/bundle
|
||||
```
|
||||
Reference in New Issue
Block a user