53 lines
3.4 KiB
Markdown
53 lines
3.4 KiB
Markdown
# Ledger Packs Snapshot Prep — PREP-LEDGER-PACKS-42-001
|
|
|
|
Status: Prep complete (2025-11-20)
|
|
Owners: Findings Ledger Guild · Mirror Creator Guild
|
|
Scope: Snapshot/time-travel contract for packs simulation and offline CLI execution (PREP-LEDGER-PACKS-42-001).
|
|
|
|
## Goals
|
|
- Provide deterministic, tenant-scoped snapshots that let pack runners/CLI replay ledger state offline.
|
|
- Allow “time-travel” queries (choose exact ledger sequence/cycle) to debug policy outcomes.
|
|
- Reuse existing export shapes where possible and avoid redundant DB projections.
|
|
|
|
## Surfaces
|
|
- `GET /v1/ledger/packs/snapshots`
|
|
- Headers: `X-Stella-Tenant` (required), bearer scope `ledger.packs.read`.
|
|
- Query: `atSequence` (long, optional), `atCycleHash` (string, optional), `sinceSequence` / `untilSequence` (long, optional), `page_size` (default 100, max 1000), `page_token`.
|
|
- Returns: list of available snapshot descriptors (JSON or NDJSON) sorted by `sequence ASC`.
|
|
- `GET /v1/ledger/packs/snapshots/{snapshotId}/download`
|
|
- Streams a gzip tarball containing the snapshot bundle (see layout).
|
|
- Supports `Accept: application/vnd.stella.pack-snapshot+tar` (default) or `application/x-ndjson` for manifest-only dry-run (no payload files) when `Prefer: return=representation` is absent.
|
|
|
|
## Snapshot descriptor fields
|
|
- `snapshot_id` (uuid, stable)
|
|
- `tenant`
|
|
- `base_sequence` (long) — earliest ledger event included
|
|
- `upper_sequence` (long) — last ledger event included (inclusive)
|
|
- `cycle_hash` (string) — Merkle cycle hash at `upper_sequence`
|
|
- `policy_version`, `projector_version`, `generator_version`
|
|
- `created_at` (ISO-8601 UTC)
|
|
- `approx_uncompressed_size_bytes`
|
|
- `content` summary: counts for `findings`, `vex`, `advisories`, `sboms`
|
|
|
|
## Bundle layout (tar.gz)
|
|
- `manifest.json`: descriptor above plus SHA-256 digests and lengths for each payload file.
|
|
- `findings.ndjson`: canonical finding shape matching `/ledger/export/findings`.
|
|
- `vex.ndjson`, `advisories.ndjson`, `sboms.ndjson`: same shapes/filters as export endpoints.
|
|
- `indexes/`: optional bloom/filter helpers for fast CLI lookup (`component_purl`, `advisory_id`, `risk_profile_version`).
|
|
- `provenance.json`: DSSE envelope with bundle hash, generator inputs (seed, source commit, policy version).
|
|
|
|
## Determinism and filters
|
|
- Snapshot is deterministic for a given `(tenant, base_sequence, upper_sequence, cycle_hash, policy_version)`.
|
|
- Page tokens: base64url JSON `{ "last": { "upper_sequence": long, "snapshot_id": uuid }, "filters_hash": sha256 }`.
|
|
- When `atCycleHash` is provided, server resolves the closest <=matching cycle and emits one descriptor; otherwise uses `untilSequence` or latest committed.
|
|
- No wall-clock dependence; `created_at` reflects generator runtime but is stored once and signed in provenance.
|
|
|
|
## Validation rules
|
|
- Reject overwrite if snapshot with identical `(tenant, upper_sequence, cycle_hash)` already published (idempotent response with existing `snapshot_id`).
|
|
- Reject if requested window crosses projector gap (missing sequences) with error `409` and `X-Stella-Gap-From/To`.
|
|
- Enforce `page_size` consistency across tokens; 400 on mismatch.
|
|
|
|
## Artefact location
|
|
- This prep: `docs/modules/findings-ledger/prep/2025-11-20-ledger-packs-42-001-prep.md`.
|
|
- Bundle schema is derived from export shapes in `docs/modules/findings-ledger/export-http-surface.md`; SDK/OAS plumbing to be added in LEDGER-PACKS-42-001 implementation.
|