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
//! FJ-3010, second half: record what the host already satisfies.
//!
//! Split out of `refresh.rs` for the same reason `refresh.rs` was split out of
//! `mod.rs` — to keep each file small enough to read in one sitting.
//!
//! `refresh_locks` could only ever REMOVE lock entries whose live check failed,
//! so `--refresh` worked exactly when a lock existed and reality had drifted
//! from it, and was a no-op when the lock was EMPTY and reality was fine: there
//! was nothing to remove.
//!
//! An empty lock is not an edge case. It is every CI checkout, every reimaged
//! box, every `--state-dir` a run has not written yet. In all of those,
//! `--refresh` contacted the host, learned every check passed, and planned
//! `create` anyway — re-running every command against a machine already in its
//! declared state.
//!
//! Measured on 1.20.1: a `type: task` with `completion_check: "[ -d / ]"` and
//! `command: touch /tmp/marker`, applied with `--refresh` against a fresh state
//! dir, created the marker.
//!
//! It is also the only state in which forjar can express an ASSERTION — a guard
//! whose `completion_check` is the claim and whose `command` reports the
//! violation. Without this, every such guard ran its failure path on a healthy
//! host.
use codegen;
use resolver;
use *;
use ApplyConfig;
use cratetransport;
/// Did this resource's check DEFINITELY pass on `machine_name`?
///
/// Deliberately not `!refresh_check_fails`. That function treats "could not
/// observe" — exit 2, a transport error, an unresolvable machine — as
/// not-failing, which is the right call when deciding whether to RE-APPLY:
/// rebuilding the world because a host blinked is worse than waiting.
///
/// Seeding a lock entry is the opposite kind of claim. It records that the host
/// IS in its declared state, and "I could not look" is not evidence for that.
/// So this returns true only on a check that ran and exited 0.
pub
/// FJ-3010, second half: record resources the HOST already satisfies.
///
/// `refresh_locks` could only ever REMOVE lock entries, so `--refresh` worked
/// exactly when a lock existed and reality had drifted from it, and was a no-op
/// when the lock was EMPTY and reality was fine — there was nothing to remove.
///
/// An empty lock is not an edge case. It is every CI checkout, every reimaged
/// box, every `--state-dir` a run has not written yet. In all of those,
/// `--refresh` contacted the host, learned that every check passed, and then
/// planned `create` for all of them anyway — re-running every command against a
/// machine already in its declared state.
///
/// Measured on forjar 1.20.1: a `type: task` with `completion_check: "[ -d / ]"`
/// and `command: touch /tmp/marker`, applied with `--refresh` against a fresh
/// state dir, created the marker. The check was satisfied before the run and
/// nothing consulted it.
///
/// "Re-run check scripts, only re-apply what fails" has two halves. This is the
/// one that says what PASSES is not re-applied.
pub
/// Does the HOST — not the lock — report this resource as being in its declared
/// state right now?
///
/// Shared by seeding (an entry that does not exist) and unlatching (an entry
/// that exists and says the resource is broken), because the evidence required
/// is identical: the resource is in this apply's scope, it is declared for this
/// machine, and its check ran here and exited 0.
/// A lock entry for a resource the host already satisfies.
///
/// No apply happened, so there is no `applied_at` or `duration_seconds` to
/// record — writing one would date an event that never occurred. `observed` is
/// a digest of the state query's stdout, and the check script is not that
/// query; conflating the two is forjar#305.
/// Record, as converged, each candidate the host says is already converged.
///
/// The one writer both halves of `--refresh` go through: seeding (candidates
/// with no lock entry) and unlatching (candidates the lock calls broken) differ
/// only in which entries they nominate, never in the evidence required.
/// PMAT-214 (forjar#487): re-check the entries the lock records as BROKEN.
///
/// `refresh_locks` evicts an entry whose live check FAILS, and `seed_converged`
/// adds one for a resource that has NO entry. Between them sits the case
/// neither covers: an entry that EXISTS, says `failed`, and whose check now
/// passes. Nothing re-ran that check, so `--refresh` planned an `Update`, and
/// the generated script is command-then-check —
///
/// ```sh
/// set -euo pipefail
/// <command> # a guard's command exits 1 by design
/// if ! { <completion_check> } # never reached
/// ```
///
/// — so the command re-failed and the failure was re-recorded. A latch.
///
/// It closes on the resources forjar's own idioms require: a guard whose command
/// cannot succeed because the action needs a secret no config may hold, and whose
/// job is to refuse loudly and name the make target. Measured on yoga 2026-09-07
/// against a correctly registered runner — check PASS by hand inside forjar's own
/// wrapper, `drift` skipping the entry, `apply --refresh -r runner-registered`
/// still "0 converged, 0 unchanged, 2 failed". On gx10 it also took three
/// dependents with it under `policy.failure: stop_on_first`.
///
/// NOT a forgiveness rule: the promotion demands a fresh check that exits 0, so
/// nothing reaches `converged` without the host saying so.
pub