Add integration contract documentation
This commit is contained in:
99
docs/integrations/destination-state.md
Normal file
99
docs/integrations/destination-state.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# Destination State Contract
|
||||
|
||||
Audience: operators, integrators, and maintainers who inspect or reason about destination `.distributor.json` files.
|
||||
|
||||
Each managed destination bundle path contains `.distributor.json`. This file is the destination sentinel and state record used for comparison, skip, replacement, and recovery decisions.
|
||||
|
||||
## State Schema
|
||||
|
||||
Current schema version: `1`.
|
||||
|
||||
```json
|
||||
{
|
||||
"schema_version": 1,
|
||||
"distributor_version": "dev",
|
||||
"pipeline_id": "reports",
|
||||
"destination_id": "archive",
|
||||
"published_at": "2026-06-04T12:00:00Z",
|
||||
"source": {
|
||||
"manifest": {
|
||||
"schema_version": 1,
|
||||
"id": "reports.example.2026-06-04",
|
||||
"digest": "sha256:...",
|
||||
"created": "2026-06-04T11:55:00Z",
|
||||
"files": [
|
||||
{"path": "report.md", "sha256": "sha256:...", "size": 1234}
|
||||
]
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"primary_url": "https://reports.example.com/archive/report.html"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"path": "report.html",
|
||||
"kind": "generated",
|
||||
"source_path": "report.md",
|
||||
"transform": "markdown_to_html",
|
||||
"url": "https://reports.example.com/archive/report.html",
|
||||
"sha256": "sha256:...",
|
||||
"size": 2345
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Required fields:
|
||||
|
||||
- `schema_version`: must be `1`.
|
||||
- `pipeline_id`: configured pipeline id that wrote the state.
|
||||
- `destination_id`: configured destination id that wrote the state.
|
||||
- `published_at`: RFC3339 publication timestamp.
|
||||
- `source.manifest`: embedded source bundle manifest.
|
||||
- `outputs`: output records array; empty is allowed, but the field is required.
|
||||
|
||||
Optional fields:
|
||||
|
||||
- `distributor_version`: application version string when available.
|
||||
- `links.primary_url`: absolute HTTP or HTTPS URL selected by destination link policy.
|
||||
|
||||
## Output Records
|
||||
|
||||
Each output record has:
|
||||
|
||||
- `path`: destination-relative output path.
|
||||
- `kind`: `source` or `generated`.
|
||||
- `source_path`: source manifest path used for the output.
|
||||
- `transform`: required for `generated` outputs; omitted for copied source outputs.
|
||||
- `url`: optional absolute HTTP or HTTPS URL for the output.
|
||||
- `sha256`: lowercase `sha256:<64 hex>` digest of the output bytes.
|
||||
- `size`: output byte size, zero or greater.
|
||||
|
||||
Output paths must be unique and use clean relative slash-separated path rules.
|
||||
|
||||
## Comparison Semantics
|
||||
|
||||
`distributor` compares the current source manifest to destination state before writing:
|
||||
|
||||
- No state and no content: publish new outputs.
|
||||
- No state and existing content: treat the destination as unmanaged.
|
||||
- Matching embedded source manifest: skip.
|
||||
- Same source id with older `created`: replace if policy allows.
|
||||
- Same source id with newer `created`: skip by default.
|
||||
- Same source id and same `created` with different digest: conflict.
|
||||
- Different source id, pipeline id, or destination id: conflict.
|
||||
- Invalid state JSON or invalid state fields: conflict.
|
||||
|
||||
Normal replacement deletes only managed output paths recorded in `outputs` plus `.distributor.json`. Forced replacement deletes the bounded destination bundle path.
|
||||
|
||||
## Boundaries
|
||||
|
||||
Destination state is internal managed state written by `distributor`. Operators may inspect it during recovery, but normal workflows should not edit it by hand. Source `manifest.json` is not copied as destination state.
|
||||
|
||||
## Tests
|
||||
|
||||
Before changing this contract, inspect and run:
|
||||
|
||||
```sh
|
||||
go test ./internal/state ./internal/publish
|
||||
```
|
||||
Reference in New Issue
Block a user