What changes, and for whom. Anyone reading the contract to learn what the edge does when the
game workload dies will get an answer that matches the running code. Today the contract describes
the unreachable case as a forward that cannot connect, which reads as the moment of dialling; in
practice the edge also answers unreachable when the workload accepted the call, started replying,
and then went away mid-answer. A reader reconciling the two today has to work out which is right.
Why now. The behaviour was settled while closing the S7 review — a workload killed mid-response
used to escape the edge entirely and surface as a generic internal failure, which told the caller
nothing about which hop had failed. The code and its test now say one thing and the contract still
says a narrower thing, and the longer that sits the more likely someone treats the narrow sentence
as the specification and reopens the question.
Done when
Agent instructions
This is a contract amendment, not a story and not a bug. The code is correct; the document
describing it is narrow. /contract owns the edit — do not hand-edit the table under a different
command's tier.
- Authority:
design/20-contract.md, The edge — EdgeError, and the invariant one paragraph
below it: "the edge produces no other error; every other status a caller sees came from the
workload". That invariant is what forces the behaviour; the table's wording is what lags it.
- Context: the forwarder uses
HttpCompletionOption.ResponseHeadersRead, so the body is still
on the wire when the handler returns. A workload killed mid-response therefore fails at the body
read, not at the send. Before S7's review fix that failure escaped and Platform's envelope
answered 500 UnhandledRequestFailure.
- Out of scope: adding a third
EdgeError variant. It was considered and rejected in
design/90-decisions.md (2026-08-10) — the retry answer is identical for both cases and a caller
cannot act on the distinction.
- Stop if: the amendment turns out to want a new code or a new status. That is a brief-level
change, not a wording fix.
What changes, and for whom. Anyone reading the contract to learn what the edge does when the
game workload dies will get an answer that matches the running code. Today the contract describes
the unreachable case as a forward that cannot connect, which reads as the moment of dialling; in
practice the edge also answers unreachable when the workload accepted the call, started replying,
and then went away mid-answer. A reader reconciling the two today has to work out which is right.
Why now. The behaviour was settled while closing the S7 review — a workload killed mid-response
used to escape the edge entirely and surface as a generic internal failure, which told the caller
nothing about which hop had failed. The code and its test now say one thing and the contract still
says a narrower thing, and the longer that sits the more likely someone treats the narrow sentence
as the specification and reopens the question.
Done when
design/20-contract.md'sEdgeErrortable describesWorkloadUnreachableas covering aforward that fails before or after the response headers arrive, alongside the readiness
probe case it already names
20-contract.mdchange is made through/contract, not by hand-editing the tableworkload_unreachablestays two variants and the existing tests still passdesign/90-decisions.mdis reconciled with theamended wording rather than left describing the contract as narrower
Agent instructions
This is a contract amendment, not a story and not a bug. The code is correct; the document
describing it is narrow.
/contractowns the edit — do not hand-edit the table under a differentcommand's tier.
design/20-contract.md, The edge —EdgeError, and the invariant one paragraphbelow it: "the edge produces no other error; every other status a caller sees came from the
workload". That invariant is what forces the behaviour; the table's wording is what lags it.
HttpCompletionOption.ResponseHeadersRead, so the body is stillon the wire when the handler returns. A workload killed mid-response therefore fails at the body
read, not at the send. Before S7's review fix that failure escaped and Platform's envelope
answered
500 UnhandledRequestFailure.EdgeErrorvariant. It was considered and rejected indesign/90-decisions.md(2026-08-10) — the retry answer is identical for both cases and a callercannot act on the distinction.
change, not a wording fix.