feat(release): bound durable run retention
This commit is contained in:
@@ -66,9 +66,10 @@ channel, or gate input requires a new run.
|
||||
Creation requires a caller-generated `request_id`. Its SHA-256 fingerprint is
|
||||
the private, workspace-scoped durable mapping to exactly one run; the raw
|
||||
identifier is never persisted. Repeating the same identifier with the same
|
||||
immutable inputs returns that run without rebuilding the plan, even if the
|
||||
live dashboard has since drifted. Reusing it with different inputs fails
|
||||
closed. The browser keeps an uncertain create identifier in session storage,
|
||||
immutable inputs returns that run without rebuilding the plan while it remains
|
||||
inside the bounded local retention window, even if the live dashboard has
|
||||
since drifted. Reusing it with different inputs fails closed. The browser keeps
|
||||
an uncertain create identifier in session storage,
|
||||
replays it after reload, and selects the known run returned by the server. A
|
||||
successful create remains shown as saved if only the subsequent list refresh
|
||||
fails.
|
||||
@@ -86,6 +87,14 @@ modes, malformed schemas, unknown fields, invalid state combinations,
|
||||
oversized files, and digest mismatches fail closed. A bad record is neither
|
||||
rewritten nor automatically quarantined.
|
||||
|
||||
The store retains at most 512 workspace-scoped run records created through the
|
||||
console. On creation at that limit it removes only the oldest fully completed,
|
||||
integrity-verified record. Running, planned, attention, blocked, foreign, and
|
||||
unreadable records are never deleted implicitly; if no completed record is
|
||||
available, creation fails closed with a retention remediation. Unavailable
|
||||
records still consume the bound and remain visible in cursor-paginated lists
|
||||
so corruption cannot be hidden by normal turnover.
|
||||
|
||||
The full resolved-workspace SHA-256 is part of both the private storage
|
||||
namespace and immutable input snapshot. Every list, read, and state transition
|
||||
checks it. An alternate workspace therefore cannot list or resume another
|
||||
@@ -99,7 +108,7 @@ Each frozen plan step has an explicit `pending`, `running`, `succeeded`,
|
||||
`failed`, or `interrupted` state. Plan order remains a prerequisite: a later
|
||||
step is unavailable until earlier steps have succeeded. Exact attempt and
|
||||
resume/retry/reconciliation request identifiers are fingerprinted so delayed
|
||||
repetitions remain idempotent for the run's lifetime. These fingerprints are
|
||||
repetitions remain idempotent for the retained run's lifetime. These fingerprints are
|
||||
never evicted: the store fails closed before accepting more than 2,048 commands
|
||||
or 2,048 attempts and asks the operator to create a fresh run. The display
|
||||
record keeps at most 256 server-generated state events. Events contain only an
|
||||
@@ -143,9 +152,10 @@ other `/api/` route:
|
||||
- `POST /api/release-runs` requires `request_id`, then idempotently rebuilds and
|
||||
freezes a selective plan only when that creation is not already known.
|
||||
- `GET /api/release-runs` lists bounded summaries ordered by verified
|
||||
`updated_at`, then `created_at` and run identifier. Unreadable entries are
|
||||
appended deterministically when room remains instead of displacing newer
|
||||
verified runs.
|
||||
`updated_at`, then `created_at` and run identifier. `next_cursor` advances a
|
||||
stable descending traversal without offset duplicates. Unreadable entries
|
||||
remain a deterministic final section and are therefore reachable through
|
||||
pagination instead of displacing newer verified runs.
|
||||
- `GET /api/release-runs/{run_id}` reads and verifies one exact record.
|
||||
- `POST /api/release-runs/{run_id}/resume` records explicit recovery.
|
||||
- `POST /api/release-runs/{run_id}/steps/{step_id}/retry` prepares a failed or
|
||||
|
||||
Reference in New Issue
Block a user