controller v0.268.0: the undo finds volumes by definition; a held app names only a whole copy; one press = one tested step (R-658, R-659, R-660, R-651; 09 §6.4 part 5)
gates / gates (push) Successful in 27s
gates / gates (push) Successful in 27s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -1304,6 +1304,31 @@ func (n *Notifier) NotifyAppUpdateHeld(d AppUpdateDetails, sentence func(lang st
|
||||
n.pushEventBoth("app_update_held", "error", hu, household, d)
|
||||
}
|
||||
|
||||
// AppHoldNoWholeCopyDetails is the payload of app_hold_no_whole_copy (v0.268.0, R-659).
|
||||
type AppHoldNoWholeCopyDetails struct {
|
||||
App string `json:"app"`
|
||||
StackName string `json:"stack_name"`
|
||||
From map[string]string `json:"from,omitempty"`
|
||||
To map[string]string `json:"to,omitempty"`
|
||||
At string `json:"at"`
|
||||
CopiesSeen []string `json:"copies_seen"`
|
||||
UndoState string `json:"undo_state,omitempty"`
|
||||
}
|
||||
|
||||
// NotifyAppHoldNoWholeCopy (v0.268.0, R-659; operator ruling 2026-09-24, option A): an app is held
|
||||
// after a failed update AND a failed undo, and no copy on its box brings it back whole. OPERATOR-ONLY
|
||||
// on the hub (operatorOnlyEvents) — the household's side is its app_update_held mail, which now says
|
||||
// support is informed; this event is that information. Severity critical: a household's app is
|
||||
// stopped and only support can bring it back.
|
||||
func (n *Notifier) NotifyAppHoldNoWholeCopy(d AppHoldNoWholeCopyDetails) {
|
||||
if d.CopiesSeen == nil {
|
||||
d.CopiesSeen = []string{} // the JSON reads [] — "none seen" is a finding, not a missing field
|
||||
}
|
||||
msg := fmt.Sprintf("%s is HELD after a failed update and a failed undo (%s), and NO copy on this box brings it back whole. Copies seen: %v. Support must act.",
|
||||
d.App, d.UndoState, d.CopiesSeen)
|
||||
n.pushEventBoth("app_hold_no_whole_copy", "critical", msg, "", d)
|
||||
}
|
||||
|
||||
// healthSeverity is the event severity a health status would be sent at (R-647): the disabled path
|
||||
// names what it drops, and "warn" is a health STATUS, not a severity the hub knows.
|
||||
func healthSeverity(status string) string {
|
||||
|
||||
Reference in New Issue
Block a user