Replay
Replay answers a narrow question with a deterministic pass or fail, before a proposal reaches review: does this bounded repair produce the expected result on fixtures shaped like the traffic that failed? It exists because a fluent explanation and a clean code review cannot establish that a change preserves the expected output on the shapes that produced the incident. Replay is shown inside the incident's Repair tab so the proposal and the evidence validating it stay together.
Deterministic evidence
Replay validates supported transformations against privacy-safe fixtures. It does not execute arbitrary code, call the provider, or touch production systems.
Fixtures without customer data
A replay dataset is built automatically from approved incident evidence when a repair proposal is requested. It inherits the privacy posture of the evidence: observations contain structure, not values, so fixture values are generated, never copied. Each dataset records one fixture source, and every fixture in it comes from that source.
| Fixture source | Used when | What a field holds |
|---|---|---|
shape | Any observation in the evidence has no value profile | A fixed placeholder for its type: the string seamward_fixture_string, the number 1, the boolean true |
profile | Every observation in the evidence carries a value profile | A generated value matching the recorded profile: a field recorded as an ISO date holds a valid date, a 4-digit number holds a 4-digit number, a list keeps its recorded length band |
Profile fixtures are synthesised from labels and bands, such as "ISO date, 10 to 19 characters". A profile holds no values, so a profile fixture cannot contain one. A field the profile does not cover, including every redacted or excluded field, keeps the shape placeholder. Booleans are always true, and a field recorded with value hashes gets a generated string, never one of the hashed values.
The dataset is immutable and self-describing: it records its incident, integration, redaction policy, evidence count, and a hashed manifest. Immutability matters because the fixture is created before a candidate is evaluated, so the expected result cannot drift to match whatever the model produced.
Isolated execution
- Supported operations run in a separate JavaScript interpreter with resource limits and no network access. The adapter receives only synthetic JSON and has no host filesystem, process, or module capabilities. Each fixture starts with a fresh interpreter.
- Only the bounded transformation vocabulary runs (the same one repair proposals are limited to); arbitrary application code is outside the replay contract by design.
- The supported transformation vocabulary produces comparable results for the same dataset and adapter version. Every requested fixture must return a validated outcome or an explicit error.
Where a replay runs
Every run records its executor, so a result is never read as more than it was.
| Executor | What runs | Where | How the result is labelled |
|---|---|---|---|
seamward-sandbox | Seamward's bounded transformation for the proposed repair | The isolated interpreter described above | Validation, decided by Seamward's deterministic comparison |
customer-runner | Your own handler, at a commit you choose | Your machine or pipeline, through the CLI | Reported by your runner; Seamward cannot confirm the outcomes |
The sandbox run is what gates a proposal: a candidate that fails it cannot be approved. A run from your own environment is extra evidence for the reviewer. It never approves a proposal and never changes its status. The replay runner guide covers declaring a handler, running the fixtures, and reporting the result.
Results you can review
Every fixture produces a pass or fail with stable mismatch paths, so a failure reads like $.candidate.salary: expected string, produced number, not "validation failed". Checks cover status ranges, acceptance, business object type, transformed output, and named assertions. The Repair tab compares the current implementation with the proposed repair, then keeps detailed run history and fixture provenance in a disclosure. The full run result is preserved next to the approval decision it informed.
What replay does not establish
Read a pass as evidence for a reviewer, not as proof that your integration is fixed.
- Your application code does not run in the sandbox. The sandbox executes Seamward's bounded transformation, the same vocabulary a repair proposal is limited to. Your handler, your validation, and your parsers are not involved unless you run the fixtures yourself with the replay runner, and that result is reported by you, not verified by Seamward.
- Fixture values are representative, not real. A
shapefixture holds a placeholder string or number, so logic that depends on a value, such as parsing a date or converting an amount, is not exercised. Aprofilefixture holds a value in the recorded format and size, so that logic sees a well-formed value, but never the one the provider sent. Branching on a specific status or enumeration value is not exercised by either source. - It is not recorded traffic. Seamward stores structure and never payload values, so there is no past request to play back.
A pass shows that the proposed mapping turns the changed shape back into the shape your contract expects. Whether your code then does the right thing with it is for your own tests and the reviewer.
Interrupted validation
A worker interruption does not authorize a repair. Execution uses expiring claims so a later attempt can resume safely and an older attempt cannot overwrite its result. A repair resumes its saved candidate and replay, with at most three execution attempts. An unrecoverable legacy run ends with an explicit error. Review the incident evidence and request a new proposal if recovery is exhausted.
Boundaries
The legacy custom-source replay endpoint has been retired. Requests to it return
410 with custom_replay_retired after authorization. Request a repair proposal
from the incident's Repair tab to validate a supported transformation. Existing
run evidence remains readable. Custom application-code execution is not a public API.
- A passing replay does not merge, deploy, or promise your full test suite passes; it establishes one specific claim about fixtures built from the shapes in the incident's evidence.
- A failing or unsafe candidate stays unavailable for approval; there is no override.
- Your repository's CI, review, and release process remain the authority on shipping.
During a release rollback, interrupted attempts receive the terminal error
execution_interrupted_by_rollback before older workers start. Completed
validation reports remain available. After service recovery, request a new
proposal if you need another validation.
Evidence capacity
Dataset creation and repair generation use all currently missing evidence links.
At more than 1,000 fixtures, the request returns 409 with
replay_evidence_capacity_exceeded, limit: 1000 and the current total.
It does not silently replay a sample or create a partial repair. Inspect the full
incident evidence and its recovery status. A successful subsequent reconciliation
can reduce the current set; do not discard observations to bypass the limit.
Legacy incidents without a maintained evidence snapshot use their recorded timeline
and the same fixture limit.
An explicitly selected dataset whose observation IDs no longer match the complete
current evidence returns 409 replay_evidence_snapshot_changed. Create a fresh
dataset or start proposal generation without selecting the stale dataset. Automatic
preparation rebuilds an immutable dataset when the current evidence changes.
Next steps
- Validate repairs before delivery: the workflow around replay.
- Repair proposals: what gets validated.
