Restore

O Operator
Restore

Restore file to captured state

Every captured change carries its SHA-256-addressed content in BLOB_STORE. Restoring writes that content back to the original path — current file gets backed up to <path>.drift_restore_backup_<epoch> before overwrite.

What will change
Preview -- nothing has been written yet.
Target file/var/www/vhosts/3dshawn.com/site1/TEMPLATES/site.html
SiteDriftSense self-monitor on local
Kindlocal
Captured at2026-07-12 00:48:44
Captured SHA89bfad940ccd5a530044896cc71842906d0331b1b1c828ce0ee5e5e511abfde5
Current state on disk
Live check just now. If SHAs match, the restore is a no-op.
File presentyes
Size25405 bytes
Current SHA1076cfffee64
Same as captured?no -- restore will change it
What restore will change — live diff
Left column shows current on-disk content; right shows what restore will write. +75 additions, -349 deletions, 69 unchanged context lines.
11<div class="page-head">
2 <a href="/sites.cgi" style="color:var(--accent-hi);text-decoration:none;font-size:12px">&larr; All sites</a>
3 <span class="page-eyebrow" style="margin-top:8px"><span class="dot"></span> Site view</span>
2 <span class="page-eyebrow"><span class="dot"></span> Site view</span>
43 <h1 class="page-title">$scan_name</h1>
54 <p class="page-subtitle">
65 <code class="mono dim">$scan_path</code>
76 &nbsp;&middot;&nbsp;on <strong>$server_name</strong> <span class="dim">($server_kind)</span>
87 &nbsp;&middot;&nbsp;retention: <strong>$retention_h</strong>
98 </p>
109</div>
1110
1211[if:$has_error]
1312<div class="module glow-rose"><div class="module-body">$error_msg</div></div>
1413[/if]
1514
1615[if:!$has_error]
17[if:$saved_id]
18<div class="banner banner-ok" style="margin:0 0 16px;padding:10px 14px;border-radius:10px;background:rgba(52,211,153,.10);border:1px solid rgba(52,211,153,.35);color:#a7f3d0;font-size:13px">
19 Snapshot saved as named release #$saved_id. Visible in <a href="/named_releases.cgi" style="color:#a7f3d0;font-weight:700">Named releases</a> and in this site's Releases panel below.
20</div>
21[/if]
22
2316<div class="ds-guide">
2417 <div class="dsg-icon">i</div>
2518 <div>
26 <span class="dsg-title">The deep dive.</span>
27 Every stat we have on this monitor. Configuration + storage math + activity breakdown + hotspots + drift + restores + cross-site dedup + compile results. Use quick actions to jump to
28 <a href="$changes_url">full file changes</a>,
29 <a href="$pin_url">pin hotspots</a>, or
30 <a href="$export_url">CSV export</a> for this site alone.
19 <span class="dsg-title">Everything for this site, one screen.</span>
20 Filtered KPIs, 90-day rhythm, recent activity, hotspots to consider pinning, and the named releases scoped here. Use the quick-action chips to jump to <a href="$changes_url">full file changes</a>, <a href="$pin_url">bulk-pin hotspots</a>, or <a href="$export_url">CSV export</a> for this site alone.
3121 </div>
3222</div>
3323
34<!-- ============ HERO KPIs ============ -->
35<div class="dash-grid" style="grid-template-columns:repeat(5,1fr);margin-bottom:16px">
24<!-- KPIs -->
25<div class="dash-grid" style="grid-template-columns:repeat(4,1fr);margin-bottom:16px">
3626 <div class="module glow-teal">
3727 <div class="module-head"><div class="left"><div class="module-title">Last 24h</div></div></div>
38 <div class="module-body kpi kpi-teal">
39 <div class="num">$kpi_24h<span class="ds-trend ds-trend-$trend_class">$trend_txt</span></div>
40 <div class="lbl">changes captured</div>
41 <div class="sub">prior 24h: $kpi_24h_prev</div>
42 </div>
28 <div class="module-body kpi kpi-teal"><div class="num">$kpi_24h</div><div class="lbl">changes captured</div></div>
4329 </div>
4430 <div class="module glow-emerald">
4531 <div class="module-head"><div class="left"><div class="module-title">Last 7 days</div></div></div>
46 <div class="module-body kpi kpi-emerald"><div class="num">$kpi_7d</div><div class="lbl">changes</div><div class="sub">30d: $kpi_30d</div></div>
32 <div class="module-body kpi kpi-emerald"><div class="num">$kpi_7d</div><div class="lbl">changes captured</div></div>
4733 </div>
4834 <div class="module glow-sky">
4935 <div class="module-head"><div class="left"><div class="module-title">Active files</div></div></div>
50 <div class="module-body kpi kpi-sky"><div class="num">$kpi_active</div><div class="lbl">not deleted</div><div class="sub">all ever seen: $kpi_all_files</div></div>
36 <div class="module-body kpi kpi-sky"><div class="num">$kpi_active</div><div class="lbl">distinct files, not deleted</div></div>
5137 </div>
5238 <div class="module glow-amber">
53 <div class="module-head"><div class="left"><div class="module-title">Storage</div></div></div>
54 <div class="module-body kpi kpi-amber"><div class="num">$bytes_gz_h</div><div class="lbl">on disk (gzipped)</div><div class="sub">$dedup_ratio dedup / $savings_pct saved</div></div>
55 </div>
56 <div class="module glow-rose">
57 <div class="module-head"><div class="left"><div class="module-title">Lifetime captures</div></div></div>
58 <div class="module-body kpi kpi-rose"><div class="num">$kpi_lifetime</div><div class="lbl">total rows</div><div class="sub">since $first_captured</div></div>
39 <div class="module-head"><div class="left"><div class="module-title">Lifetime</div></div></div>
40 <div class="module-body kpi kpi-amber"><div class="num">$kpi_all</div><div class="lbl">total captures ever</div></div>
5941 </div>
6042</div>
6143
62<!-- ============ 90-DAY TIMELINE ============ -->
44<!-- 90-day timeline -->
6345<div class="module glow-teal" style="margin-bottom:16px">
6446 <div class="module-head"><div class="left">
65 <div class="module-title">Activity, last 90 days<span class="ds-help" data-help-title="This monitor only" data-help-body="Just this site's captures &mdash; the main dashboard timeline stacks the whole portfolio."></span></div>
47 <div class="module-title">Activity, last 90 days<span class="ds-help" data-help-title="This site only" data-help-body="Just this monitor's captures &mdash; unlike the main dashboard which stacks the whole portfolio."></span></div>
6648 <span class="module-subtitle">Click any day to filter file changes to that date.</span>
67 </div></div>
68 <div class="module-body">$timeline_svg</div>
69</div>
70
71<!-- ============ CONFIGURATION + SERVER + STATUS ============ -->
72<div class="dash-grid" style="grid-template-columns:1fr 1fr;margin-bottom:16px">
73 <div class="module glow-sky">
74 <div class="module-head"><div class="left"><div class="module-title">Configuration<span class="ds-help" data-help-title="Scan behavior" data-help-body="Ignore list is UNION'd with the global settings. File-type filter here overrides the global if set. Max size + retention likewise fall back to global defaults when unset."></span></div></div></div>
75 <div class="module-body">
76 <table class="tbl">
77 <tbody>
78 <tr><td style="width:170px"><strong>Path watched</strong></td><td class="mono">$scan_path</td></tr>
79 <tr><td><strong>Ignore list</strong></td><td class="mono dim" style="font-size:11px">$ignore_list</td></tr>
80 <tr><td><strong>File-type filter</strong></td><td class="mono dim">$file_type_filter</td></tr>
81 <tr><td><strong>Max file size</strong></td><td class="mono">$max_file_size_h</td></tr>
82 <tr><td><strong>Retention</strong></td><td class="mono">$retention_h</td></tr>
83 <tr><td><strong>Last scan tick</strong></td><td class="mono dim"><span class="ts" data-ts="$last_scanned_epoch" data-fmt="relative">$last_scanned_h</span></td></tr>
84 </tbody>
85 </table>
86 </div>
87 </div>
88 <div class="module glow-emerald">
89 <div class="module-head"><div class="left"><div class="module-title">Server / reach</div></div></div>
90 <div class="module-body">
91 <table class="tbl">
92 <tbody>
93 <tr><td style="width:170px"><strong>Server name</strong></td><td>$server_name</td></tr>
94 <tr><td><strong>Kind</strong></td><td>$server_kind</td></tr>
95 <tr><td><strong>Status</strong></td><td>$server_status</td></tr>
96 [if:$is_agent]
97 <tr><td><strong>SSH reach</strong></td><td class="mono">$ssh_user@$ssh_host:$ssh_port</td></tr>
98 [/if]
99 <tr><td><strong>Last heartbeat</strong></td><td class="mono dim"><span class="ts" data-ts="$heartbeat_epoch" data-fmt="relative">$heartbeat_h</span></td></tr>
100 <tr><td><strong>First capture</strong></td><td class="mono dim">$first_captured</td></tr>
101 <tr><td><strong>Last capture</strong></td><td class="mono dim"><span class="ts" data-ts="$last_captured_epoch" data-fmt="relative">$last_captured</span></td></tr>
102 </tbody>
103 </table>
104 </div>
105 </div>
106</div>
107
108<!-- ============ ACTIVITY BREAKDOWN + STORAGE MATH ============ -->
109<div class="dash-grid" style="grid-template-columns:1fr 1fr;margin-bottom:16px">
110 <div class="module glow-amber">
111 <div class="module-head"><div class="left"><div class="module-title">Activity breakdown<span class="ds-help" data-help-title="Change kinds" data-help-body="Every FILE_CHANGES row is one of these. <strong>Added</strong> = file first seen. <strong>Modified</strong> = SHA changed. <strong>Deleted</strong> = file no longer present. <strong>ts-only</strong> = mtime touched but bytes identical -- usually noise."></span></div></div></div>
112 <div class="module-body">
113 <table class="tbl">
114 <tbody>
115 <tr><td><strong>Added</strong></td><td class="mono" style="color:var(--accent-ok)">$n_added</td></tr>
116 <tr><td><strong>Modified</strong></td><td class="mono" style="color:var(--accent-warn)">$n_modified</td></tr>
117 <tr><td><strong>Deleted</strong></td><td class="mono" style="color:var(--accent-danger)">$n_deleted</td></tr>
118 <tr><td><strong>Timestamp-only</strong></td><td class="mono dim">$n_ts_only</td></tr>
119 <tr><td><strong>Total lifetime</strong></td><td class="mono"><strong>$kpi_lifetime</strong></td></tr>
120 </tbody>
121 </table>
122 </div>
123 </div>
124 <div class="module glow-sky">
125 <div class="module-head"><div class="left"><div class="module-title">Storage math<span class="ds-help" data-help-title="How storage works" data-help-body="Content is SHA-256 addressed and gzipped. If 100 captures of the same file share identical content, they share one BLOB_STORE row plus a ref-count. This is why the raw-vs-on-disk ratio is usually 3-10x."></span></div></div></div>
126 <div class="module-body">
127 <table class="tbl">
128 <tbody>
129 <tr><td><strong>Unique blobs</strong></td><td class="mono">$unique_blobs</td></tr>
130 <tr><td><strong>Total refs</strong></td><td class="mono">$ref_total</td></tr>
131 <tr><td><strong>Raw content (all versions)</strong></td><td class="mono">$bytes_raw_h</td></tr>
132 <tr><td><strong>On disk (gzipped)</strong></td><td class="mono" style="color:var(--accent-hi)">$bytes_gz_h</td></tr>
133 <tr><td><strong>Dedup ratio</strong></td><td class="mono" style="color:var(--accent-ok)">$dedup_ratio</td></tr>
134 <tr><td><strong>Savings</strong></td><td class="mono" style="color:var(--accent-ok)">$savings_pct</td></tr>
135 </tbody>
136 </table>
137 </div>
138 </div>
139</div>
140
141<!-- ============ QUICK SAVE VERSION ============ -->
142<div class="module glow-emerald" style="margin-bottom:16px">
143 <div class="module-head"><div class="left">
144 <div class="module-icon"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg></div>
145 <div class="module-title">Save current state as a version<span class="ds-help" data-help-title="What this does" data-help-body="Creates a new Named Release scoped to this site AND explicitly pins every current-latest file. Auto-purge will keep those exact blobs forever. Great for &quot;shipped v3.0&quot; snapshots."></span></div>
146 <span class="module-subtitle">One-click bookmark of every current-latest file on this site.</span>
14749 </div></div>
14850 <div class="module-body">
149 <form method="post" action="/site.cgi?mid=$mid" style="display:flex;gap:10px;align-items:end;flex-wrap:wrap">
150 <input type="hidden" name="save_snapshot" value="1">
151 <label style="flex:1;min-width:180px;display:flex;flex-direction:column;gap:4px">
152 <span class="rb-label">Version label</span>
153 <input type="text" name="version_label" required placeholder="e.g. v1.0, stable Nov-2026"
154 style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px;font-family:var(--mono);font-size:12.5px">
155 </label>
156 <label style="width:160px;display:flex;flex-direction:column;gap:4px">
157 <span class="rb-label">Internal name</span>
158 <input type="text" name="name" placeholder="auto"
159 style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px;font-family:var(--mono);font-size:12.5px">
160 </label>
161 <label style="width:120px;display:flex;flex-direction:column;gap:4px">
162 <span class="rb-label">Tier</span>
163 <select name="tier" style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px;font-size:12.5px">
164 <option value="draft">Draft</option>
165 <option value="working">Working</option>
166 <option value="stable">Stable</option>
167 </select>
168 </label>
169 <button type="submit" class="tr-chip is-active" style="border:none;padding:8px 18px">Save snapshot</button>
170 </form>
51 $timeline_svg
17152 </div>
17253</div>
17354
174<!-- ============ RECENT + HOTSPOTS ============ -->
175<div class="dash-grid" style="grid-template-columns:3fr 2fr;margin-bottom:16px">
55<div class="dash-grid" style="grid-template-columns:2fr 1fr;margin-bottom:16px">
56 <!-- Recent activity -->
17657 <div class="module glow-teal">
17758 <div class="module-head"><div class="left">
17859 <div class="module-icon"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg></div>
179 <div class="module-title">Recent changes<span class="ds-help" data-help-title="Programmer story" data-help-body="Made an edit that got overwritten? Find it here, click <strong>Restore</strong> to write it back &mdash; or open the diff, copy the exact lines you need."></span></div>
180 <span class="module-subtitle">Last 25 captures. Click a row to open its diff.</span>
181 </div><a href="$changes_url" class="tr-chip" style="margin-left:auto">See all &rarr;</a></div>
182 <div class="module-body tight" style="max-height:520px;overflow:auto">
60 <div class="module-title">Recent changes<span class="ds-help" data-help-title="Programmer view" data-help-body="Made an edit that got overwritten? Find it here, click <strong>Restore</strong> to write it back &mdash; or open the diff, copy the exact lines you need, and paste them into the current version manually. Every restore backs up the current file first."></span></div>
61 <span class="module-subtitle">Last 40 captures on this monitor. Click a row to open the diff. "Restore" writes the captured version back to disk.</span>
62 </div>
63 <a href="$changes_url" class="tr-chip" style="margin-left:auto">See all &rarr;</a>
64 </div>
65 <div class="module-body tight" style="max-height:640px;overflow:auto">
18366 [if:$has_recent]
18467 <table class="tbl">
185 <thead><tr><th style="width:90px">Status</th><th>File</th><th style="width:90px">Blob</th><th style="width:150px">When</th><th style="width:70px">Restore</th></tr></thead>
68 <thead><tr>
69 <th style="width:90px">Status</th>
70 <th>File</th>
71 <th style="width:80px">Blob</th>
72 <th style="width:150px">When</th>
73 <th style="width:70px">Restore</th>
74 </tr></thead>
18675 <tbody>
18776 [loop:@recent]
18877 <tr>
18978 <td><span class="pill $status_pill">$status</span>[if:$is_ts_only] <span class="pill pill-mute" style="font-size:9px">ts</span>[/if]</td>
19079 <td class="mono" style="font-size:11.5px"><a href="$diff_url" style="color:var(--accent-hi);text-decoration:none">$file_short</a></td>
19180 <td class="mono dim">$blob_short</td>
192 <td class="mono dim"><span class="ts" data-ts="$ts_epoch" data-fmt="relative">$date_time</span></td>
193 <td>[if:$can_restore]<a href="$restore_url" class="tr-chip" style="padding:2px 8px;font-size:10.5px">Restore</a>[/if]</td>
194 </tr>
195 [/loop]
196 </tbody>
197 </table>
198 [/if]
199 </div>
200 </div>
201
202 <div class="module glow-amber">
203 <div class="module-head"><div class="left">
204 <div class="module-title">Hotspots (30d)</div>
205 <span class="module-subtitle">Top-10 most edited on this site.</span>
206 </div>
207 <a href="$pin_url" class="tr-chip" style="margin-left:auto">Pin these &rarr;</a></div>
208 <div class="module-body tight" style="max-height:520px;overflow:auto">
209 [if:$has_hotspots]
210 <table class="tbl">
211 <thead><tr><th>File</th><th style="width:60px">Ct</th><th style="width:120px">Latest</th></tr></thead>
212 <tbody>
213 [loop:@hotspots]
214 <tr>
215 <td class="mono" style="font-size:11.5px"><a href="$diff_url" style="color:var(--accent-hi);text-decoration:none">$file_short</a></td>
216 <td class="mono" style="color:var(--accent-warn);font-weight:700">$ct</td>
217 <td class="mono dim"><span class="ts" data-ts="$latest_epoch" data-fmt="relative">-</span></td>
218 </tr>
219 [/loop]
220 </tbody>
221 </table>
222 [/if]
223 </div>
224 </div>
225</div>
226
227<!-- ============ RELEASES + DELETIONS ============ -->
228<div class="dash-grid" style="grid-template-columns:1fr 1fr;margin-bottom:16px">
229 <div class="module glow-emerald">
230 <div class="module-head"><div class="left">
231 <div class="module-title">Releases &amp; stable versions<span class="ds-help" data-help-title="Scoped + portfolio" data-help-body="Releases scoped to this monitor, its parent server, or portfolio-wide. Stable-tier releases are highlighted."></span></div>
232 <span class="module-subtitle">One-click roll-back.</span>
233 </div>
234 <a href="/named_releases.cgi" class="tr-chip" style="margin-left:auto">Manage &rarr;</a></div>
235 <div class="module-body tight" style="max-height:400px;overflow:auto">
236 [if:$has_releases]
237 <table class="tbl">
238 <thead><tr><th>Version</th><th style="width:70px">Tier</th><th style="width:60px">Pins</th><th style="width:70px"></th></tr></thead>
239 <tbody>
240 [loop:@releases]
241 <tr>
242 <td><strong>$label</strong><div class="dim" style="font-size:11px">$description</div></td>
243 <td><span class="pill $tier_pill" style="font-size:9.5px">$tier</span></td>
244 <td class="mono">$pin_ct</td>
245 <td><a href="$restore_url" class="tr-chip" style="padding:2px 8px;font-size:10.5px">Restore</a></td>
246 </tr>
247 [/loop]
248 </tbody>
249 </table>
250 [/if]
251 [if:!$has_releases]<div style="padding:20px 14px;text-align:center;color:var(--text-dim);font-size:12px">No releases yet. Save one using the form above.</div>[/if]
252 </div>
253 </div>
254
255 <div class="module glow-rose">
256 <div class="module-head"><div class="left">
257 <div class="module-icon"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/></svg></div>
258 <div class="module-title">Deletion log<span class="ds-help" data-help-title="Something got deleted?" data-help-body="Every file this monitor saw disappear. Click <strong>Restore</strong> to write the last captured content back to disk."></span></div>
259 <span class="module-subtitle">Last 10 deletions -- restore the last-known content in one click.</span>
260 </div></div>
261 <div class="module-body tight" style="max-height:400px;overflow:auto">
262 [if:$has_deletions]
263 <table class="tbl">
264 <thead><tr><th>File</th><th style="width:150px">Deleted</th><th style="width:70px"></th></tr></thead>
265 <tbody>
266 [loop:@deletions]
267 <tr>
268 <td class="mono" style="font-size:11.5px"><a href="$diff_url" style="color:var(--accent-hi);text-decoration:none">$file_short</a></td>
26981 <td class="mono dim"><span class="ts" data-ts="$ts_epoch" data-fmt="relative">$date_time</span></td>
27082 <td>[if:$can_restore]<a href="$restore_url" class="tr-chip" style="padding:2px 8px;font-size:10.5px">Restore</a>[/if]</td>
27183 </tr>
27284 [/loop]
27385 </tbody>
27486 </table>
27587 [/if]
276 [if:!$has_deletions]<div style="padding:20px 14px;text-align:center;color:var(--text-dim);font-size:12px">Nothing deleted here. Good.</div>[/if]
88 [if:!$has_recent]<div style="padding:36px 14px;text-align:center;color:var(--text-dim)">Nothing captured yet.</div>[/if]
27789 </div>
27890 </div>
279</div>
28091
281<!-- ============ COMPILE + DRIFT ============ -->
282<div class="dash-grid" style="grid-template-columns:1fr 1fr;margin-bottom:16px">
283 <div class="module glow-warn">
284 <div class="module-head"><div class="left">
285 <div class="module-title">Compile-check summary<span class="ds-help" data-help-title="How compile-check works" data-help-body="Runs when you press <strong>Test compile</strong> on the diff viewer. Perl / node / bash / python / JSON. Results cached on BLOB_STORE so we don't re-check the same blob."></span></div>
286 <span class="module-subtitle">Blobs on this site where we've run a syntax check.</span>
287 </div></div>
288 <div class="module-body">
289 [if:$has_compile_data]
290 <div style="display:flex;gap:16px;margin-bottom:10px">
291 <div><div style="font-size:22px;color:var(--accent-ok);font-weight:800">$cc_ok</div><div class="dim" style="font-size:10.5px;text-transform:uppercase;letter-spacing:1.2px">Clean</div></div>
292 <div><div style="font-size:22px;color:var(--accent-danger);font-weight:800">$cc_err</div><div class="dim" style="font-size:10.5px;text-transform:uppercase;letter-spacing:1.2px">Errors</div></div>
293 <div><div style="font-size:22px;color:var(--text-dim);font-weight:800">$cc_checked</div><div class="dim" style="font-size:10.5px;text-transform:uppercase;letter-spacing:1.2px">Total</div></div>
294 </div>
295 [if:$has_compile_errors]
296 <div class="dim" style="text-transform:uppercase;letter-spacing:1.2px;font-size:10.5px;margin-bottom:6px;color:var(--accent-danger)">Files with syntax errors</div>
297 <div style="max-height:220px;overflow:auto">
298 <table class="tbl">
299 <tbody>
300 [loop:@compile_errors]
301 <tr>
302 <td class="mono" style="font-size:11px"><a href="$diff_url" style="color:var(--accent-danger-hi);text-decoration:none">$file_short</a>
303 <div class="dim" style="font-size:10.5px;font-family:var(--mono)">$msg</div>
304 </td>
305 </tr>
306 [/loop]
307 </tbody>
308 </table>
309 </div>
92 <!-- Hotspots + releases -->
93 <div>
94 <div class="module glow-amber" style="margin-bottom:16px">
95 <div class="module-head"><div class="left">
96 <div class="module-title">Hotspots (30d)</div>
97 <span class="module-subtitle">Files edited most often on this site. Pin them to freeze current state.</span>
98 </div>
99 <a href="$pin_url" class="tr-chip" style="margin-left:auto">Pin these &rarr;</a>
100 </div>
101 <div class="module-body tight">
102 [if:$has_hotspots]
103 <table class="tbl">
104 <thead><tr><th>File</th><th style="width:60px">Ct</th></tr></thead>
105 <tbody>
106 [loop:@hotspots]
107 <tr>
108 <td class="mono" style="font-size:11.5px"><a href="$diff_url" style="color:var(--accent-hi);text-decoration:none">$file_short</a></td>
109 <td class="mono" style="color:var(--accent-warn);font-weight:700">$ct</td>
110 </tr>
111 [/loop]
112 </tbody>
113 </table>
310114 [/if]
311 [/if]
312 [if:!$has_compile_data]<div class="dim" style="padding:14px 4px;font-size:12.5px">No compile checks run for this site yet. Open a diff and press <strong>Test compile</strong> to check any Perl / JS / Python / Bash file.</div>[/if]
313 </div>
314 </div>
315
316 <div class="module glow-rose">
317 <div class="module-head"><div class="left">
318 <div class="module-title">Pin drift on this site<span class="ds-help" data-help-title="What drift means" data-help-body="A file was pinned in a Named Release. Someone (or a scanner) modified it, so the current SHA no longer matches the pinned SHA. Click Fix to restore the release to the pinned state."></span></div>
319 <span class="module-subtitle">Pinned files here that no longer match their pinned SHA.</span>
320 </div></div>
321 <div class="module-body tight" style="max-height:320px;overflow:auto">
322 [if:$has_drift]
323 <table class="tbl">
324 <thead><tr><th>File</th><th style="width:150px">Release</th><th style="width:150px">Detected</th><th style="width:60px"></th></tr></thead>
325 <tbody>
326 [loop:@drift]
327 <tr>
328 <td class="mono" style="font-size:11px">$file_short<div class="dim mono" style="font-size:10px">$pinned_short &rarr; $current_short</div></td>
329 <td class="dim">$release_name</td>
330 <td class="mono dim"><span class="ts" data-ts="$detected_epoch" data-fmt="relative">$detected_h</span></td>
331 <td><a href="$restore_url" class="tr-chip" style="padding:2px 8px;font-size:10.5px">Fix</a></td>
332 </tr>
333 [/loop]
334 </tbody>
335 </table>
336 [/if]
337 [if:!$has_drift]<div class="dim" style="padding:14px 4px;font-size:12.5px">No pinned files are drifting. All pins are in-sync.</div>[/if]
338 </div>
339 </div>
340</div>
341
342<!-- ============ CROSS-SITE + LONGEVITY + RESTORES ============ -->
343<div class="dash-grid" style="grid-template-columns:1fr 1fr 1fr;margin-bottom:16px">
344 <div class="module glow-teal">
345 <div class="module-head"><div class="left">
346 <div class="module-title">Shared with other sites<span class="ds-help" data-help-title="Cross-site dedup" data-help-body="Blobs from this site's captures that are byte-identical to captures on other sites. Great for spotting shared templates or copy-paste code. Click a blob to sync it across sites."></span></div>
347 <span class="module-subtitle">Byte-identical content this site shares.</span>
348 </div></div>
349 <div class="module-body tight" style="max-height:400px;overflow:auto">
350 [if:$has_shared]
351 <table class="tbl">
352 <thead><tr><th style="width:60px">Sites</th><th>Blob</th><th style="width:70px">Size</th></tr></thead>
353 <tbody>
354 [loop:@shared_blobs]
355 <tr>
356 <td class="mono" style="color:var(--accent-hi);font-weight:700">$site_ct</td>
357 <td class="mono" style="font-size:11px"><a href="$diff_url" style="color:var(--accent-hi);text-decoration:none">$sha_short</a>
358 <div class="dim" style="font-size:10.5px">$scans_h</div>
359 </td>
360 <td class="mono dim">$size_h</td>
361 </tr>
362 [/loop]
363 </tbody>
364 </table>
365 [/if]
366 [if:!$has_shared]<div class="dim" style="padding:14px 4px;font-size:12.5px">No byte-identical files with other monitors.</div>[/if]
367 </div>
368 </div>
369
370 <div class="module glow-sky">
371 <div class="module-head"><div class="left">
372 <div class="module-title">Longest-lived files</div>
373 <span class="module-subtitle">Files this monitor has watched the longest.</span>
374 </div></div>
375 <div class="module-body tight" style="max-height:400px;overflow:auto">
376 [if:$has_longevity]
377 <table class="tbl">
378 <thead><tr><th>File</th><th style="width:60px">Days</th><th style="width:60px">Ct</th></tr></thead>
379 <tbody>
380 [loop:@longevity]
381 <tr>
382 <td class="mono" style="font-size:11.5px"><a href="$diff_url" style="color:var(--accent-hi);text-decoration:none">$file_short</a></td>
383 <td class="mono">$days_tracked</td>
384 <td class="mono">$ct</td>
385 </tr>
386 [/loop]
387 </tbody>
388 </table>
389 [/if]
390 [if:!$has_longevity]<div class="dim" style="padding:14px 4px;font-size:12.5px">Nothing tracked yet.</div>[/if]
115 [if:!$has_hotspots]<div style="padding:24px 14px;text-align:center;color:var(--text-dim);font-size:12.5px">No activity in the last 30 days.</div>[/if]
116 </div>
391117 </div>
392 </div>
393118
394 <div class="module glow-amber">
395 <div class="module-head"><div class="left">
396 <div class="module-title">Restore log for this site</div>
397 <span class="module-subtitle">Recent restore actions that touched this monitor's path.</span>
398 </div></div>
399 <div class="module-body tight" style="max-height:400px;overflow:auto">
400 [if:$has_restores]
401 <table class="tbl">
402 <thead><tr><th style="width:80px">Result</th><th>File</th><th style="width:120px">When</th></tr></thead>
403 <tbody>
404 [loop:@restores]
405 <tr>
406 <td><span class="pill $status_pill">$status</span></td>
407 <td class="mono" style="font-size:11px">$file_short<div class="dim" style="font-size:10px">by $restored_by &middot; $sha_short</div></td>
408 <td class="mono dim"><span class="ts" data-ts="$restored_epoch" data-fmt="relative">$restored_h</span></td>
409 </tr>
410 [/loop]
411 </tbody>
412 </table>
413 [/if]
414 [if:!$has_restores]<div class="dim" style="padding:14px 4px;font-size:12.5px">No restore actions on this site's path yet.</div>[/if]
119 <div class="module glow-emerald">
120 <div class="module-head"><div class="left">
121 <div class="module-title">Releases &amp; stable versions<span class="ds-help" data-help-title="Versions for this site" data-help-body="Portfolio-wide releases + releases scoped to this site or its server. Stable-tier releases are highlighted in green. Click <strong>Restore</strong> to roll every pinned file in that release back to the pinned state."></span></div>
122 <span class="module-subtitle">Save a working / stable version below; roll back with one click.</span>
123 </div></div>
124 <div class="module-body tight">
125 [if:$has_releases]
126 <table class="tbl">
127 <thead><tr><th>Version</th><th style="width:70px">Tier</th><th style="width:70px"></th></tr></thead>
128 <tbody>
129 [loop:@releases]
130 <tr>
131 <td><strong>$label</strong><div class="dim" style="font-size:11px">$description</div></td>
132 <td><span class="pill $tier_pill" style="font-size:9.5px">$tier</span></td>
133 <td><a href="$restore_url" class="tr-chip" style="padding:2px 8px;font-size:10.5px">Restore</a></td>
134 </tr>
135 [/loop]
136 </tbody>
137 </table>
138 [/if]
139 [if:!$has_releases]<div style="padding:20px 14px;text-align:center;color:var(--text-dim);font-size:12px">No releases yet. <a href="/named_releases.cgi" style="color:var(--accent-hi)">Save one now</a>.</div>[/if]
140 </div>
415141 </div>
416142 </div>
417143</div>
418144[/if]
Confirm restore
Backs current content to <target>.drift_restore_backup_<epoch>, writes the captured content, verifies SHA post-write.
Cancel Logged to RESTORE_LOG regardless of outcome.