Skip to content

The edge's unreachable error is described more narrowly than it behaves #106

Description

@The-Running-Dev

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's EdgeError table describes WorkloadUnreachable as covering a
    forward that fails before or after the response headers arrive, alongside the readiness
    probe case it already names
  • The 20-contract.md change is made through /contract, not by hand-editing the table
  • No code changes: workload_unreachable stays two variants and the existing tests still pass
  • The decision-log entry dated 2026-08-10 in design/90-decisions.md is reconciled with the
    amended 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. /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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:edgeGame edge and public roadmapenhancementNew feature or requestneeds-decisionRequires an architectural or contract decision

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions