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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
//! What the derivation FOUND about its own fidelity — the §7.2 instrumentation
//! (bl-49f4, extended bl-ee0a).
//!
//! Drift is **divergence between what the frame renders and what is on disk**.
//! There are two ways to get it, and this module names both:
//!
//! 1. *A change nobody announced* — the watcher was armed and silent while disk
//! moved. The 15 s full sweep exists because a filesystem event can be lost;
//! that made it self-healing over a defect nobody could see, so **a sweep
//! that catches something is evidence of a bug** and is written down.
//! 2. *A derivation that arrived late* (bl-ee0a). Since the derivation moved off
//! the frame thread there is no longer a structural claim that the rendered
//! snapshot is this instant's disk — it is the last *completed* pass. When a
//! pass takes longer than the poll cadence it is meant to keep, everything
//! rendered meanwhile was that far behind, and that is drift too: the same
//! divergence, a different cause. It is named rather than hidden, because the
//! thing it used to do instead was freeze the window (bl-ee0a).
//!
//! The signal is almost free, because [`Mark`](crate::watch::Mark) already rides
//! every dirty root: a re-derivation that *changes* a snapshot is only
//! interesting in the light of what claimed the root had changed. Under
//! `Mark::Watch` it is the watcher working. Under `Mark::Poll` it is the
//! liveness re-probe, for which no filesystem event exists at all. Under
//! `Mark::Sweep` **nothing announced it** — that is a dropped event, measured at
//! the one moment it costs something.
//!
//! Nothing here is stored. A [`Drift`] lives for one tick and is folded into
//! `ops.jsonl` (§4.2) — yog's existing durable, two-instance-shared trail — as
//! one line per kind. The operator's count is then a *query* over that tail
//! ([`crate::opslog::activity`]), reachable at the §11 activity accessory with
//! no debugger, no fourth surface, and no counter that could drift from what
//! actually happened.
use crateOpEntry;
use ;
use Duration;
/// The §11 ops-surface staleness line, or `None` while the snapshot is fresh
/// (the normal case, and the one that must render nothing at all). Pure over
/// the age so the threshold is provable without a slow machine.
///
/// `stale_after` is the live cadence's bound
/// ([`Cadence::stale_after`](super::Cadence::stale_after), bl-3381): twice the
/// full-sweep period — the worker re-stamps the snapshot on every full sweep
/// even when nothing changed, so exceeding two of them means passes are not
/// completing, not that the world is quiet.
/// A pass's own lateness, or `None` when it kept its cadence (§7.2). `started`
/// and `finished` come from the injected clock, so the late branch is reachable
/// in a test without a slow machine. `late_pass` is the live cadence's bound
/// for **the sweep this pass ran**
/// ([`Cadence::late_pass`](super::Cadence::late_pass), bl-3381, bl-4b28): the
/// period that pass promised to keep, so a pass that eats its whole interval
/// has already failed to keep it — not a threshold picked for feel, the
/// schedule's own period.
///
/// Whether a *finding* is written is the caller's edge test, not this one's
/// (bl-4b28): this answers "was this pass late", which is a fact about one
/// pass; the trail records the transition into lateness.
pub
/// The finding a pass's own lateness earns, given whether the pass before it
/// was late (§7.2, bl-4b28) — the edge test [`Drift::Late`] is written on.
///
/// Four cases, one line: a pass that misses after one that kept cadence is the
/// event ("passes stopped keeping cadence"); a pass that misses after one that
/// already missed adds nothing a reader did not have; and a pass that keeps
/// cadence is not a finding at either end. Recovery writes nothing on purpose —
/// the trail is a record of what went wrong, and *is it late now* is the §11
/// staleness line's derived answer, not a row anyone has to find.
pub
/// One thing a sweep or the watch backend found that the watcher should have
/// announced and did not.
pub
/// Fold a tick's findings into `ops.jsonl` lines (§4.2): **one line per kind**,
/// with every root it names newline-joined in `stderr`.
///
/// Per-kind rather than per-root on purpose. A systematic drift source affects
/// every workspace at once, and a line each would flood the 256-line tail the
/// §11 accessory reads — burying the evidence under itself. One line per kind
/// bounds a sweep's output to three lines however wide the damage, while the
/// attribution stays complete in the field the accessory already expands.
///
/// `ts` is the caller's wall-clock stamp (the injected clock mints it, §4.2 —
/// this module reads no time) and `cwd` the yog state root the observation was
/// made from.
pub