Publish rolled-up status.summary verdict on StackResource - #63
Merged
Conversation
The agent now publishes its conclusion, not just its evidence: a summary block (state Waiting|Building|Deploying|Ready|Failed + reason + message + observedGeneration) written by the status derivation every pass, so the hub maps it 1:1 to release timeline events instead of re-deriving state from condition order, values, absence, PortCheck and failure details. - summarize() in status derivation, single writer, stamped before StatusHash so the hash covers it; precedence: Failed verdict > Building > Waiting > runtime crash > Ready/Deploying - Deploying detail picks port dial > readiness detail > verdict message, with a "previous revision still serving traffic" note while the old revision holds traffic - Exported ReasonBuildFailed / ReasonPortNotListening; literals replaced - BuildLastFailureDetail now stamps Type=runtime_crash (was unset; readers no longer normalize empty Type) - CRDs regenerated in config/deploy/crds and chart crds (identical) Claude-Session: https://claude.ai/code/session_01TpRLszVTJudSd86RreufSC
ashishmax31
commented
Aug 4, 2026
| if pc := resource.Status.PortCheck; pc != nil && pc.Status == v1alpha1.PortCheckStatusTypeFailure { | ||
| return v1alpha1.ReasonPortNotListening, portDialMessage(pc.FailingPortNumbers) | ||
| } | ||
| if resource.Status.PortCheck == nil { |
Contributor
Author
There was a problem hiding this comment.
resource.Status.PortCheck cant be nil when failureDetail is populated due to port check
…deployingDetail A readiness_failure entry has one writer, recordPortFailure, which only runs past the port-check grace window and files the PortNotListening Failed verdict in the same pass — so the Deploying path can never see one. Inside the grace window the details are cleared and only PortCheck carries the diagnosis, which the port-dial branch above already handles. Claude-Session: https://claude.ai/code/session_01TpRLszVTJudSd86RreufSC
ashishmax31
commented
Aug 4, 2026
| // portDialMessage names the declared ports the last dial proved closed. | ||
| func portDialMessage(ports []int32) string { | ||
| if len(ports) == 0 { | ||
| return "declared ports not accepting connections" |
Contributor
Author
There was a problem hiding this comment.
If no failing part numbers then we are good right?
Failure is only written when at least one dialed port is closed, so a Failure PortCheck always carries FailingPortNumbers. The guard was a hub-transplant defensive leftover. Claude-Session: https://claude.ai/code/session_01TpRLszVTJudSd86RreufSC
Precedence now reads as a single switch — one case per state, first case wins — with the inputs named up front. The serving-traffic note moves to appendServingNote, applied only to Deploying. Claude-Session: https://claude.ai/code/session_01TpRLszVTJudSd86RreufSC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The agent publishes its conclusion, not just its evidence:
status.summary(state: Waiting|Building|Deploying|Ready|Failed+reason+message+observedGeneration), written by the status derivation every pass. The hub will map it 1:1 to release timeline events instead of re-deriving state from condition order/values/absence +portCheck+ failure details (its current second-interpreter ladder).How
summarize()instatus_derive.go— single writer, runs after the full sub-reconciler chain, stamped immediately beforeStatusHash()so the hash covers it (hub change-detection is free).Failed verdict > Building > Waiting > runtime crash > Ready/Deploying. Build/deps outrank the crash detail because when those gates fail the workload reconciler never ran this pass — a crash entry is a previous revision's leftover.Deployingpicks the most specific diagnosis: port dial > kubelet readiness detail > verdict message, with a "(previous revision still serving traffic)" note while the old revision holds traffic.ReasonBuildFailed/ReasonPortNotListeningso the hub never mirrors literals; converted all literal sites.BuildLastFailureDetailnever setTypeon crash entries — readers were compensating with empty-Type normalization. Writer now stampsruntime_crash; normalization removed.Rollout note
CRD schema is structural (pruning): clusters must get the release
crds.yamlapplied before the chart upgrade, orstatus.summaryis silently dropped. Helm skipscrds/on upgrade.Tests
make test-unitgreen,go vetclean, CRD copies verified identical.https://claude.ai/code/session_01TpRLszVTJudSd86RreufSC