Add shared-root destination state model

This commit is contained in:
2026-06-08 18:45:16 +00:00
parent ef0b6c1056
commit eb86cf9ab6
13 changed files with 1165 additions and 10 deletions

View File

@@ -4,9 +4,9 @@ Audience: operators, integrators, and maintainers who inspect or reason about de
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
## Single-Owner State Schema
Current schema version: `2`.
Current state written by `run` uses schema version `2`.
```json
{
@@ -119,7 +119,80 @@ Normal replacement deletes only managed output paths recorded in `outputs` plus
`distributor` can read schema version `1` destination state for compatibility. When v1 state is read, it is treated as single-owner state with `reconciliation.mode: replace`. Missing top-level `created_at` and `updated_at` are inferred from `published_at`, and missing per-output timestamps are also inferred from `published_at`.
Newly written destination state uses schema version `2`.
Newly written destination state from publish execution uses schema version `2`.
## Shared-Root State Schema
`distributor` can parse and validate shared-root destination state with schema version `3`. Publish execution currently writes single-owner state.
```json
{
"schema_version": 3,
"distributor_version": "dev",
"created_at": "2026-06-04T12:00:00Z",
"updated_at": "2026-06-04T12:10:00Z",
"state": {
"mode": "shared_root"
},
"owners": [
{
"pipeline_id": "reports",
"destination_id": "archive",
"reconciliation": {
"mode": "merge"
},
"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,
"pipeline_id": "reports",
"destination_id": "archive",
"source_id": "reports.example.2026-06-04",
"source_digest": "sha256:...",
"source_created": "2026-06-04T11:55:00Z",
"created_at": "2026-06-04T12:00:00Z",
"updated_at": "2026-06-04T12:10:00Z"
}
]
}
```
Shared-root required fields:
- `schema_version`: must be `3`.
- `created_at`: RFC3339 timestamp for when this shared-root state record was first created.
- `updated_at`: RFC3339 timestamp for the latest shared-root state update.
- `state.mode`: must be `shared_root`.
- `owners`: owner records keyed by `pipeline_id` and `destination_id`; each owner records its latest source manifest and reconciliation mode.
- `outputs`: output records for every managed path under the shared destination root.
Shared-root optional fields:
- `distributor_version`: application version string when available.
- `owners[].links.primary_url`: absolute HTTP or HTTPS URL selected by that owner's destination link policy.
Shared-root output records carry the same `path`, `kind`, `source_path`, `transform`, `url`, `sha256`, `size`, `created_at`, and `updated_at` fields as single-owner outputs. They also include the owner `pipeline_id` and `destination_id`, plus compact source identity fields `source_id`, `source_digest`, and `source_created`.
## Boundaries