1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//! **The attention strip, escalated to the desktop** (DESIGN §6 as amended,
//! bl-e160). §6 is yog's core promise — *does anything need me?* — and it is
//! invisible whenever the window is buried or minimized. When a new thing needs
//! you and you are not looking at yog, the desktop says so.
//!
//! **No second attention model.** An alert is a projection of
//! [`QueueRow`](crate::boundary::answer::queue::QueueRow) — the §6 decision
//! queue, which is already "what needs you" made addressable (VISION §5 V5.2).
//! The predicate, the roster order and the wording are all read from there, so
//! a rule the strip counts and a rule the desktop announces cannot diverge.
//!
//! **Dedupe rides the acknowledgement that already exists.** A row leaves the
//! queue exactly when the operator acknowledges it — focusing the conversation
//! (§6) or `/seen` (§8.5) — so the alert set is the queue set, and "announce
//! what is new" is a set difference against what this window last saw. Nothing
//! is stored, no watermark is written (an alert is *render output*, never a
//! mutation — I7 untouched), and a signal that re-arms because a ref moved
//! re-arms here too, for free, because a moved ref puts the row back.
//!
//! **The identity is the row's own sentence.** A conversation is announced once
//! per *set of firing rules*, not once per frame and not once per rule: a
//! second rule firing on the same conversation is a changed sentence and says
//! itself, while the same sentence again is the same unanswered ask. That is
//! the flag's behaviour too — it stays raised, it does not re-raise.
//!
//! **Nothing at boot.** A window that has just opened has witnessed no
//! *arrival*: everything already waiting was waiting before it existed. So the
//! first fold is the baseline and announces nothing —
//! [`Announced::arrivals`]'s general path with no prior observation, not a
//! first-run branch.
/// Handing an alert to the desktop — the one spawn, and the argv it becomes.
use crateAttentionKind;
use crateQueueRow;
use BTreeSet;
/// One thing to tell the desktop about (§6): which conversation, in which
/// workspace, and why it is asking.
/// The alerts one decision queue implies — one per row, in queue order.
///
/// A row whose signals somehow list none is dropped rather than announced with
/// an empty reason: the queue holds only attention-bearing rows, so this cannot
/// arise from the derivation, and a silent alert would say nothing anyway.
/// The firing rules as one sentence, in the badge order the queue lists them.
/// **The whole decision**, in one pure place: what this pass should hand the
/// desktop, given the §6 queue, what this window has already said, whether the
/// window has focus, and the §4.1 knob.
///
/// The fold runs unconditionally and the *announcing* is what the two gates
/// suppress — so a signal that landed while the operator was looking at yog, or
/// while the knob was off, is absorbed into the baseline rather than saved up.
/// Losing focus must not replay the news you already had.
/// What this window has already told the desktop (§5.3 RAM — viewport
/// ephemera, per instance and never durable: two windows each own their own
/// desktop, and a restart is a new window, not a missed one).