Carry the failure a revision landed on, wherever a revision is described #12

Merged
geusebio merged 1 commit from feature/failure-reference-on-the-wire into main 2026-08-24 01:05:14 +00:00
Owner

The platform has had a failure page since Failure rows existed — an F-code, the phase, whose fault it was, the build log, and a share link for someone who cannot sign in. None of it was on this wire, so a client could print the reason sentence and had nowhere to send the reader next. That is where every reader of sc deploy and sc apps stopped.

Failure (client/failure.go) is the handle as a person writes it plus the absolute URL of its page, and it now travels on all three places a revision is described:

Where Field Why there
Listing row Deployment.Failure A tree of deployments is exactly the rows a reader wants the failures of; a request per branch would not be drawn
Revision lookup Revision.Failure The client that was never attached to the deploy — the same reason StatusReason is there
Progress stream ProgressFrame.Failure The deploy you are watching fail, in the place in the transcript where it happened

The stream sends it as its own frame, just before the end frame, rather than as a field on the end frame. The end frame is FollowDeployment's return value — a client takes the sentence and stops reading — so anything riding along with it would be dropped by every client written before this existed. As its own frame it reaches the same callback the statuses and the build output already reach, and an older client ignores it (no case in its switch matches).

Every field is additive and a pointer, so a platform that does not send one, and a client that does not know about one, both behave exactly as before.

Verification

  • go test ./... green; hack/coverage.sh 91.4% on client against a floor of 88.8% (unchanged from main — this change is coverage-neutral).
  • hack/lint.sh — 0 issues.
  • No screenshots: this repo has no UI. The rendering lands in sc and is shown on that PR.

Platform and sc sides follow separately; this one has to merge first so the agent can bump its pin.

The platform has had a failure page since `Failure` rows existed — an F-code, the phase, whose fault it was, the build log, and a share link for someone who cannot sign in. None of it was on this wire, so a client could print the reason sentence and had nowhere to send the reader next. That is where every reader of `sc deploy` and `sc apps` stopped. `Failure` (`client/failure.go`) is the handle as a person writes it plus the absolute URL of its page, and it now travels on all three places a revision is described: | Where | Field | Why there | |---|---|---| | Listing row | `Deployment.Failure` | A tree of deployments is exactly the rows a reader wants the failures of; a request per branch would not be drawn | | Revision lookup | `Revision.Failure` | The client that was never attached to the deploy — the same reason `StatusReason` is there | | Progress stream | `ProgressFrame.Failure` | The deploy you are watching fail, in the place in the transcript where it happened | **The stream sends it as its own frame, just before the end frame**, rather than as a field on the end frame. The end frame is `FollowDeployment`'s return value — a client takes the sentence and stops reading — so anything riding along with it would be dropped by every client written before this existed. As its own frame it reaches the same callback the statuses and the build output already reach, and an older client ignores it (no case in its switch matches). Every field is additive and a pointer, so a platform that does not send one, and a client that does not know about one, both behave exactly as before. ## Verification - `go test ./...` green; `hack/coverage.sh` 91.4% on `client` against a floor of 88.8% (unchanged from `main` — this change is coverage-neutral). - `hack/lint.sh` — 0 issues. - No screenshots: this repo has no UI. The rendering lands in `sc` and is shown on that PR. Platform and `sc` sides follow separately; this one has to merge first so the agent can bump its pin.
Carry the failure a revision landed on, wherever a revision is described
All checks were successful
CI / build (pull_request) Successful in 55s
b922dd25b1
A failed deploy has had a page of its own for a while — the phase, whose
fault it was, the build log, and a share link for somebody who cannot sign
in — and nothing on this wire ever said so. A client could print the reason
sentence and stop there, which is where every reader of `sc deploy` and
`sc apps` stopped too.

So `Failure` — the handle a person quotes and the absolute URL of its page —
now travels on all three places a revision is described:

- `Deployment.Failure` on a listing row, so a tree of deployments can point
  at each bad landing without a request per branch.
- `Revision.Failure` on the single-revision lookup, for a client that was
  never attached to the deploy.
- `ProgressFrame.Failure`, sent as its own frame just before the end frame.
  Not a field *on* the end frame: that frame is FollowDeployment's return
  value, so anything travelling with it would be dropped by every client
  written before this existed. As its own frame it reaches the same callback
  the statuses and the build output reach.

Every field is additive and a pointer, so a platform that does not send one
and a client that does not know about it both behave exactly as before.
geusebio changed title from Carry the failure a revision landed on, wherever a revision is described to WIP: Carry the failure a revision landed on, wherever a revision is described 2026-08-24 00:23:17 +00:00
geusebio changed title from WIP: Carry the failure a revision landed on, wherever a revision is described to Carry the failure a revision landed on, wherever a revision is described 2026-08-24 00:38:52 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Grey.ooo/someones.computer_scclient!12
No description provided.