@miller-tech/uap 1.128.2 → 1.128.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/cli/deliver.js +5 -3
- package/dist/cli/deliver.js.map +1 -1
- package/dist/delivery/snapshot.d.ts +30 -16
- package/dist/delivery/snapshot.d.ts.map +1 -1
- package/dist/delivery/snapshot.js +121 -47
- package/dist/delivery/snapshot.js.map +1 -1
- package/docs/guides/DELIVER.md +13 -5
- package/package.json +1 -1
- package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
- package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
|
@@ -3,11 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Captures the project state before the convergence loop runs so deliver can
|
|
5
5
|
* roll back if it ends up worse (by the real gates' measure) than it started.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* Two classes of entry are excluded, with a SYMMETRIC contract (neither
|
|
7
|
+
* snapshotted nor touched by restore, at any depth):
|
|
8
|
+
* - heavy/derived DIRECTORIES (.git, node_modules, target, .venv, …) — not
|
|
9
|
+
* part of the task's source, and copying them is what melted a machine;
|
|
10
|
+
* - secret-bearing FILES (.env*, keys, certs) — they must not persist in
|
|
11
|
+
* snapshot storage under ~/.cache, so they are never copied and rollback
|
|
12
|
+
* leaves them exactly as they are.
|
|
13
|
+
* Files merely sharing an excluded directory name (a script called `build`)
|
|
14
|
+
* are snapshotted normally.
|
|
11
15
|
*
|
|
12
16
|
* Hardening (2026-07-08, after the project-i incident where a 424 GB Rust
|
|
13
17
|
* `target/` tree was copied into a 61 GB RAM tmpfs):
|
|
@@ -15,21 +19,25 @@
|
|
|
15
19
|
* overrides — absolute paths only), never os.tmpdir(), which is RAM-backed
|
|
16
20
|
* on many Linux setups;
|
|
17
21
|
* - the source tree is size-guarded before copying (UAP_SNAPSHOT_MAX_MB,
|
|
18
|
-
* default 4096) — over the cap
|
|
22
|
+
* default 4096) — over the cap the snapshot is skipped and the caller
|
|
19
23
|
* degrades to "no rollback this run" instead of exhausting the machine;
|
|
20
|
-
* - snapshotTree never throws:
|
|
21
|
-
*
|
|
24
|
+
* - snapshotTree never throws: it returns a discriminated SnapshotResult and
|
|
25
|
+
* any failure cleans up its partial copy (presentation belongs to callers);
|
|
22
26
|
* - restoreTree validates the snapshot before touching the project, restores
|
|
23
27
|
* copy-first (prune extras, then merge back) so an interrupted restore
|
|
24
28
|
* never leaves a gutted tree, and marks the snapshot preserve-on-failure
|
|
25
29
|
* so the reaper won't collect the only good copy;
|
|
26
|
-
* - each snapshot carries a pid marker; stale snapshots from dead
|
|
27
|
-
*
|
|
30
|
+
* - each snapshot carries a pid+host marker; stale snapshots from dead
|
|
31
|
+
* processes are reaped before a new one is taken, and markers from other
|
|
32
|
+
* hosts / pid namespaces (shared $HOME, containers) are never judged by
|
|
33
|
+
* local pid liveness — only by the 7-day age backstop.
|
|
28
34
|
*/
|
|
29
35
|
import { cpSync, rmSync, mkdtempSync, mkdirSync, readdirSync, readFileSync, writeFileSync, lstatSync, statSync, } from 'fs';
|
|
30
36
|
import { join, basename, isAbsolute, resolve } from 'path';
|
|
31
|
-
import { tmpdir, homedir } from 'os';
|
|
37
|
+
import { tmpdir, homedir, hostname } from 'os';
|
|
32
38
|
const EXCLUDE = new Set([
|
|
39
|
+
// A DIRECTORY named .env is almost always a python venv, never source.
|
|
40
|
+
'.env',
|
|
33
41
|
// VCS / UAP-internal
|
|
34
42
|
'.git',
|
|
35
43
|
'.worktrees',
|
|
@@ -60,20 +68,34 @@ const EXCLUDE = new Set([
|
|
|
60
68
|
'.ruff_cache',
|
|
61
69
|
'.tox',
|
|
62
70
|
]);
|
|
71
|
+
/**
|
|
72
|
+
* Secret-bearing file names that must never be copied into snapshot storage.
|
|
73
|
+
* Kept symmetric with restore: these files are also never pruned or
|
|
74
|
+
* overwritten by a rollback. Committed env TEMPLATES (.env.example etc.) are
|
|
75
|
+
* carved out — they contain no secrets and should roll back like source.
|
|
76
|
+
*/
|
|
77
|
+
function isSecretName(name) {
|
|
78
|
+
if (/^\.env(\..+)?$/i.test(name))
|
|
79
|
+
return !/^\.env\.(example|sample|template|dist)$/i.test(name);
|
|
80
|
+
return /^\.npmrc$|^\.netrc$|\.(pem|key|p12|pfx)$|^id_(rsa|dsa|ecdsa(_sk)?|ed25519(_sk)?)$/i.test(name);
|
|
81
|
+
}
|
|
63
82
|
/** Marker written inside each snapshot so the reaper can tell live from stale. */
|
|
64
83
|
const META_FILE = '.uap-snap.json';
|
|
65
84
|
const SNAP_PREFIX = 'uap-snap-';
|
|
66
85
|
/** Age past which a marker-less (legacy/partial) snapshot is considered stale. */
|
|
67
86
|
const LEGACY_STALE_MS = 24 * 60 * 60 * 1000;
|
|
68
|
-
/** Backstop against pid reuse
|
|
87
|
+
/** Backstop against pid reuse (and the only signal for foreign-host markers). */
|
|
69
88
|
const MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
70
89
|
const DEFAULT_MAX_MB = 4096;
|
|
71
|
-
/** True
|
|
72
|
-
function
|
|
73
|
-
|
|
90
|
+
/** True when the entry must be skipped by snapshot, prune, and size walk alike. */
|
|
91
|
+
function isExcludedEntry(path, name) {
|
|
92
|
+
const secretName = isSecretName(name);
|
|
93
|
+
const dirName = EXCLUDE.has(name);
|
|
94
|
+
if (!secretName && !dirName)
|
|
74
95
|
return false;
|
|
75
96
|
try {
|
|
76
|
-
|
|
97
|
+
const isDir = lstatSync(path).isDirectory();
|
|
98
|
+
return isDir ? dirName : secretName;
|
|
77
99
|
}
|
|
78
100
|
catch {
|
|
79
101
|
return false;
|
|
@@ -93,9 +115,9 @@ function maxSnapshotBytes() {
|
|
|
93
115
|
return (Number.isFinite(mb) && mb > 0 ? mb : DEFAULT_MAX_MB) * 1024 * 1024;
|
|
94
116
|
}
|
|
95
117
|
/**
|
|
96
|
-
* Sum file sizes under root (skipping excluded
|
|
97
|
-
* as soon as the running total exceeds `limit` so huge trees cost one
|
|
98
|
-
* partial walk, not a full traversal.
|
|
118
|
+
* Sum file sizes under root (skipping excluded entries and symlinks), bailing
|
|
119
|
+
* out as soon as the running total exceeds `limit` so huge trees cost one
|
|
120
|
+
* early partial walk, not a full traversal.
|
|
99
121
|
*/
|
|
100
122
|
function treeSizeExceeds(root, limit) {
|
|
101
123
|
let total = 0;
|
|
@@ -125,6 +147,8 @@ function treeSizeExceeds(root, limit) {
|
|
|
125
147
|
stack.push(path);
|
|
126
148
|
}
|
|
127
149
|
else {
|
|
150
|
+
if (isSecretName(name))
|
|
151
|
+
continue;
|
|
128
152
|
total += st.size;
|
|
129
153
|
if (total > limit)
|
|
130
154
|
return true;
|
|
@@ -154,10 +178,20 @@ function isStaleSnapshot(path) {
|
|
|
154
178
|
const meta = JSON.parse(readFileSync(metaPath, 'utf-8'));
|
|
155
179
|
if (meta.preserve === true)
|
|
156
180
|
return false;
|
|
181
|
+
const created = Date.parse(meta.created ?? '');
|
|
182
|
+
const expired = Number.isFinite(created) && Date.now() - created > MAX_AGE_MS;
|
|
183
|
+
// A marker from another host or pid namespace (shared $HOME, container):
|
|
184
|
+
// local pid liveness says nothing about it — age is the only safe signal.
|
|
185
|
+
// Without a parseable created field, fall back to dir mtime so a garbled
|
|
186
|
+
// foreign marker can't pin its snapshot forever.
|
|
187
|
+
if (typeof meta.host === 'string' && meta.host !== hostname()) {
|
|
188
|
+
if (Number.isFinite(created))
|
|
189
|
+
return expired;
|
|
190
|
+
return Date.now() - statSync(path).mtimeMs > MAX_AGE_MS;
|
|
191
|
+
}
|
|
157
192
|
if (!Number.isInteger(meta.pid) || meta.pid <= 1)
|
|
158
193
|
return true;
|
|
159
|
-
|
|
160
|
-
if (Number.isFinite(created) && Date.now() - created > MAX_AGE_MS)
|
|
194
|
+
if (expired)
|
|
161
195
|
return true;
|
|
162
196
|
return !pidAlive(meta.pid);
|
|
163
197
|
}
|
|
@@ -206,10 +240,10 @@ export function reapStaleSnapshots() {
|
|
|
206
240
|
}
|
|
207
241
|
}
|
|
208
242
|
/**
|
|
209
|
-
* Copy the project tree (minus excluded
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
243
|
+
* Copy the project tree (minus excluded entries) to a disk-backed snapshot
|
|
244
|
+
* dir. Never throws and never logs — callers decide presentation from the
|
|
245
|
+
* discriminated result. `ok: false` means "no rollback available for this
|
|
246
|
+
* run", not a fatal error.
|
|
213
247
|
*/
|
|
214
248
|
export function snapshotTree(root) {
|
|
215
249
|
let snap;
|
|
@@ -217,39 +251,73 @@ export function snapshotTree(root) {
|
|
|
217
251
|
reapStaleSnapshots();
|
|
218
252
|
const limit = maxSnapshotBytes();
|
|
219
253
|
if (treeSizeExceeds(root, limit)) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
254
|
+
return {
|
|
255
|
+
ok: false,
|
|
256
|
+
reason: 'size-cap',
|
|
257
|
+
detail: `project tree exceeds ${Math.round(limit / (1024 * 1024))} MB (raise UAP_SNAPSHOT_MAX_MB to override)`,
|
|
258
|
+
};
|
|
223
259
|
}
|
|
224
260
|
snap = mkdtempSync(join(snapshotBaseDir(), SNAP_PREFIX));
|
|
225
261
|
}
|
|
226
262
|
catch (err) {
|
|
227
|
-
|
|
228
|
-
return null;
|
|
263
|
+
return { ok: false, reason: 'error', detail: err.message };
|
|
229
264
|
}
|
|
230
265
|
try {
|
|
231
266
|
cpSync(root, snap, {
|
|
232
267
|
recursive: true,
|
|
233
268
|
// Never filter the root itself — a project dir named `build`/`dist`/…
|
|
234
269
|
// must still snapshot its contents, not produce an empty snapshot.
|
|
235
|
-
filter: (src) => src === root || !
|
|
270
|
+
filter: (src) => src === root || !isExcludedEntry(src, basename(src)),
|
|
236
271
|
});
|
|
237
|
-
writeFileSync(join(snap, META_FILE), JSON.stringify({ pid: process.pid, created: new Date().toISOString() }));
|
|
238
|
-
return snap;
|
|
272
|
+
writeFileSync(join(snap, META_FILE), JSON.stringify({ pid: process.pid, host: hostname(), created: new Date().toISOString() }));
|
|
273
|
+
return { ok: true, path: snap };
|
|
239
274
|
}
|
|
240
275
|
catch (err) {
|
|
241
276
|
// Never leak a partial snapshot (the original failure mode: ENOSPC
|
|
242
277
|
// mid-copy left tens of GB behind).
|
|
243
278
|
rmSync(snap, { recursive: true, force: true });
|
|
244
|
-
|
|
245
|
-
|
|
279
|
+
return { ok: false, reason: 'error', detail: err.message };
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* rm -rf that leaves secret files in place (and keeps any directory that
|
|
284
|
+
* still holds one). Excluded dirs (node_modules, target, …) encountered
|
|
285
|
+
* inside the doomed tree are derived/reinstallable — removed wholesale
|
|
286
|
+
* rather than walked. Returns true when the path was fully removed.
|
|
287
|
+
*/
|
|
288
|
+
function rmPreservingSecrets(path) {
|
|
289
|
+
let st;
|
|
290
|
+
try {
|
|
291
|
+
st = lstatSync(path);
|
|
292
|
+
}
|
|
293
|
+
catch {
|
|
294
|
+
return true;
|
|
295
|
+
}
|
|
296
|
+
if (!st.isDirectory()) {
|
|
297
|
+
if (isSecretName(basename(path)))
|
|
298
|
+
return false;
|
|
299
|
+
rmSync(path, { force: true });
|
|
300
|
+
return true;
|
|
301
|
+
}
|
|
302
|
+
if (EXCLUDE.has(basename(path))) {
|
|
303
|
+
rmSync(path, { recursive: true, force: true });
|
|
304
|
+
return true;
|
|
305
|
+
}
|
|
306
|
+
let removedAll = true;
|
|
307
|
+
for (const entry of readdirSync(path)) {
|
|
308
|
+
if (!rmPreservingSecrets(join(path, entry)))
|
|
309
|
+
removedAll = false;
|
|
246
310
|
}
|
|
311
|
+
if (removedAll)
|
|
312
|
+
rmSync(path, { recursive: true, force: true });
|
|
313
|
+
return removedAll;
|
|
247
314
|
}
|
|
248
315
|
/**
|
|
249
316
|
* Delete entries under rootDir that the snapshot doesn't contain (or whose
|
|
250
|
-
* file/dir type flipped), recursing with the same excluded-
|
|
251
|
-
* the snapshot filter so nested excluded trees (a workspace's node_modules
|
|
252
|
-
*
|
|
317
|
+
* file/dir type flipped), recursing with the same excluded-entry contract as
|
|
318
|
+
* the snapshot filter so nested excluded trees (a workspace's node_modules)
|
|
319
|
+
* and secret files survive rollback untouched — even secrets created after
|
|
320
|
+
* the snapshot inside directories the snapshot never held.
|
|
253
321
|
*/
|
|
254
322
|
function pruneToSnapshot(rootDir, snapDir) {
|
|
255
323
|
for (const entry of readdirSync(rootDir)) {
|
|
@@ -261,7 +329,7 @@ function pruneToSnapshot(rootDir, snapDir) {
|
|
|
261
329
|
catch {
|
|
262
330
|
continue;
|
|
263
331
|
}
|
|
264
|
-
if (rootStat.isDirectory()
|
|
332
|
+
if (rootStat.isDirectory() ? EXCLUDE.has(entry) : isSecretName(entry))
|
|
265
333
|
continue;
|
|
266
334
|
let snapStat = null;
|
|
267
335
|
try {
|
|
@@ -271,14 +339,16 @@ function pruneToSnapshot(rootDir, snapDir) {
|
|
|
271
339
|
/* not in snapshot */
|
|
272
340
|
}
|
|
273
341
|
if (!snapStat) {
|
|
274
|
-
|
|
342
|
+
rmPreservingSecrets(rootPath);
|
|
275
343
|
}
|
|
276
344
|
else if (rootStat.isDirectory() && snapStat.isDirectory()) {
|
|
277
345
|
pruneToSnapshot(rootPath, join(snapDir, entry));
|
|
278
346
|
}
|
|
279
347
|
else if (rootStat.isDirectory() !== snapStat.isDirectory()) {
|
|
280
|
-
// Type flip (file↔dir): remove so the merge copy can recreate it.
|
|
281
|
-
|
|
348
|
+
// Type flip (file↔dir): remove so the merge copy can recreate it. If a
|
|
349
|
+
// secret survives inside (dir→file flip), leave the dir — the copy will
|
|
350
|
+
// fail and the preserve path keeps the snapshot for manual recovery.
|
|
351
|
+
rmPreservingSecrets(rootPath);
|
|
282
352
|
}
|
|
283
353
|
}
|
|
284
354
|
}
|
|
@@ -287,7 +357,7 @@ function pruneToSnapshot(rootDir, snapDir) {
|
|
|
287
357
|
* touching the project, then prunes extras and merge-copies the snapshot
|
|
288
358
|
* back — copy-first ordering so an interruption leaves a recoverable union
|
|
289
359
|
* of both trees, never a gutted project. On failure the snapshot is marked
|
|
290
|
-
* preserve (reaper-immune) and the error is rethrown.
|
|
360
|
+
* preserve (reaper-immune) and the error is rethrown; callers own logging.
|
|
291
361
|
*/
|
|
292
362
|
export function restoreTree(root, snap) {
|
|
293
363
|
const entries = readdirSync(snap); // throws if the snapshot is gone — root untouched
|
|
@@ -297,19 +367,23 @@ export function restoreTree(root, snap) {
|
|
|
297
367
|
try {
|
|
298
368
|
pruneToSnapshot(root, snap);
|
|
299
369
|
for (const entry of entries) {
|
|
300
|
-
|
|
370
|
+
// Skip the marker and (defense-in-depth) any secrets present in a
|
|
371
|
+
// pre-hardening snapshot — never overwrite a live rotated secret.
|
|
372
|
+
if (entry === META_FILE || isSecretName(entry))
|
|
301
373
|
continue;
|
|
302
|
-
cpSync(join(snap, entry), join(root, entry), {
|
|
374
|
+
cpSync(join(snap, entry), join(root, entry), {
|
|
375
|
+
recursive: true,
|
|
376
|
+
filter: (src) => !isExcludedEntry(src, basename(src)) || src === join(snap, entry),
|
|
377
|
+
});
|
|
303
378
|
}
|
|
304
379
|
}
|
|
305
380
|
catch (err) {
|
|
306
381
|
try {
|
|
307
|
-
writeFileSync(join(snap, META_FILE), JSON.stringify({ pid: process.pid, created: new Date().toISOString(), preserve: true }));
|
|
382
|
+
writeFileSync(join(snap, META_FILE), JSON.stringify({ pid: process.pid, host: hostname(), created: new Date().toISOString(), preserve: true }));
|
|
308
383
|
}
|
|
309
384
|
catch {
|
|
310
385
|
/* marker rewrite is best-effort */
|
|
311
386
|
}
|
|
312
|
-
console.warn(` no-regress: restore FAILED — snapshot preserved at ${snap}`);
|
|
313
387
|
throw err;
|
|
314
388
|
}
|
|
315
389
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/delivery/snapshot.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/delivery/snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EACL,MAAM,EACN,MAAM,EACN,WAAW,EACX,SAAS,EACT,WAAW,EACX,YAAY,EACZ,aAAa,EACb,SAAS,EACT,QAAQ,GACT,MAAM,IAAI,CAAC;AACZ,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAE/C,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC;IACtB,uEAAuE;IACvE,MAAM;IACN,qBAAqB;IACrB,MAAM;IACN,YAAY;IACZ,cAAc;IACd,cAAc;IACd,KAAK;IACL,cAAc;IACd,MAAM;IACN,OAAO;IACP,KAAK;IACL,UAAU;IACV,OAAO;IACP,OAAO;IACP,aAAa;IACb,QAAQ;IACR,QAAQ;IACR,eAAe;IACf,kBAAkB;IAClB,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,SAAS;IACT,OAAO;IACP,MAAM;IACN,aAAa;IACb,eAAe;IACf,aAAa;IACb,aAAa;IACb,MAAM;CACP,CAAC,CAAC;AAEH;;;;;GAKG;AACH,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,0CAA0C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChG,OAAO,oFAAoF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzG,CAAC;AAED,kFAAkF;AAClF,MAAM,SAAS,GAAG,gBAAgB,CAAC;AAEnC,MAAM,WAAW,GAAG,WAAW,CAAC;AAEhC,kFAAkF;AAClF,MAAM,eAAe,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAE5C,iFAAiF;AACjF,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAE3C,MAAM,cAAc,GAAG,IAAI,CAAC;AAc5B,mFAAmF;AACnF,SAAS,eAAe,CAAC,IAAY,EAAE,IAAY;IACjD,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,CAAC,UAAU,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC1C,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,eAAe;IAC7B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,EAAE,CAAC;IACjD,4EAA4E;IAC5E,mEAAmE;IACnE,MAAM,IAAI,GAAG,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IACnG,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,gBAAgB;IACvB,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACnD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAC7E,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe,CAAC,IAAY,EAAE,KAAa;IAClD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC;IACrB,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAG,CAAC;QACzB,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACH,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,SAAS,CAAC,uDAAuD;QACnE,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAC7B,IAAI,EAAE,CAAC;YACP,IAAI,CAAC;gBACH,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YACvB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,IAAI,EAAE,CAAC,cAAc,EAAE;gBAAE,SAAS;YAClC,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;gBACrB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;oBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3C,CAAC;iBAAM,CAAC;gBACN,IAAI,YAAY,CAAC,IAAI,CAAC;oBAAE,SAAS;gBACjC,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC;gBACjB,IAAI,KAAK,GAAG,KAAK;oBAAE,OAAO,IAAI,CAAC;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW;IAC3B,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,iDAAiD;QACjD,OAAQ,GAA6B,CAAC,IAAI,KAAK,OAAO,CAAC;IACzD,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACvC,qEAAqE;QACrE,iEAAiE;QACjE,MAAM,EAAE,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC/B,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,IAAI,GAAG,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACxE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAa,CAAC;QACrE,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,UAAU,CAAC;QAC9E,yEAAyE;QACzE,0EAA0E;QAC1E,yEAAyE;QACzE,iDAAiD;QACjD,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,EAAE,CAAC;YAC9D,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,OAAO,OAAO,CAAC;YAC7C,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,GAAG,UAAU,CAAC;QAC1D,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAK,IAAI,CAAC,GAAc,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1E,IAAI,OAAO;YAAE,OAAO,IAAI,CAAC;QACzB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAa,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,oEAAoE;QACpE,iEAAiE;QACjE,oBAAoB;QACpB,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,GAAG,eAAe,CAAC;QAC/D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IAC3C,IAAI,OAAO,CAAC,GAAG,CAAC,2BAA2B,KAAK,GAAG;QAAE,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACzE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACH,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC3B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;gBAAE,SAAS;YAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC9B,IAAI,CAAC;gBACH,IAAI,eAAe,CAAC,IAAI,CAAC;oBAAE,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5E,CAAC;YAAC,MAAM,CAAC;gBACP,eAAe;YACjB,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,kBAAkB,EAAE,CAAC;QACrB,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;QACjC,IAAI,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;YACjC,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,UAAU;gBAClB,MAAM,EAAE,wBAAwB,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,6CAA6C;aAC/G,CAAC;QACJ,CAAC;QACD,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;IAC3D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC;IACxE,CAAC;IACD,IAAI,CAAC;QACH,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE;YACjB,SAAS,EAAE,IAAI;YACf,sEAAsE;YACtE,mEAAmE;YACnE,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;SACtE,CAAC,CAAC;QACH,aAAa,CACX,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EACrB,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAC1F,CAAC;QACF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,mEAAmE;QACnE,oCAAoC;QACpC,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC;IACxE,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,mBAAmB,CAAC,IAAY;IACvC,IAAI,EAAE,CAAC;IACP,IAAI,CAAC;QACH,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;QACtB,IAAI,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QAC/C,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QAChC,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,UAAU,GAAG,IAAI,CAAC;IACtB,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAAE,UAAU,GAAG,KAAK,CAAC;IAClE,CAAC;IACD,IAAI,UAAU;QAAE,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CAAC,OAAe,EAAE,OAAe;IACvD,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACtC,IAAI,QAAQ,CAAC;QACb,IAAI,CAAC;YACH,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC;YAAE,SAAS;QAChF,IAAI,QAAQ,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC;YACH,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,qBAAqB;QACvB,CAAC;QACD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC;aAAM,IAAI,QAAQ,CAAC,WAAW,EAAE,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;YAC5D,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;QAClD,CAAC;aAAM,IAAI,QAAQ,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;YAC7D,uEAAuE;YACvE,wEAAwE;YACxE,qEAAqE;YACrE,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,IAAY;IACpD,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,kDAAkD;IACrF,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,aAAa,SAAS,SAAS,CAAC,CAAC;IACnF,CAAC;IACD,IAAI,CAAC;QACH,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC5B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,kEAAkE;YAClE,kEAAkE;YAClE,IAAI,KAAK,KAAK,SAAS,IAAI,YAAY,CAAC,KAAK,CAAC;gBAAE,SAAS;YACzD,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;gBAC3C,SAAS,EAAE,IAAI;gBACf,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,eAAe,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,KAAK,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC;aACnF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC;YACH,aAAa,CACX,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EACrB,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAC1G,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,mCAAmC;QACrC,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACjD,CAAC"}
|
package/docs/guides/DELIVER.md
CHANGED
|
@@ -145,11 +145,19 @@ The pre-run snapshot lands on real disk under `~/.cache/uap/snapshots`
|
|
|
145
145
|
(`UAP_SNAPSHOT_DIR` overrides; absolute paths only) — never `/tmp`, which is
|
|
146
146
|
RAM-backed on many Linux systems. Derived directories (`.git`,
|
|
147
147
|
`node_modules`, `target`, `.venv`, `dist`, `build`, …) are neither
|
|
148
|
-
snapshotted nor touched by a rollback, at any depth.
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
148
|
+
snapshotted nor touched by a rollback, at any depth. Secret-bearing files
|
|
149
|
+
(`.env*`, `.npmrc`, `.netrc`, `*.pem`/`*.key`/`*.p12`/`*.pfx`, `id_rsa` &
|
|
150
|
+
friends) follow the same symmetric contract: they are never copied into
|
|
151
|
+
snapshot storage, and a rollback never reverts or deletes them — even inside
|
|
152
|
+
directories created after the snapshot. Committed env templates
|
|
153
|
+
(`.env.example`/`.sample`/`.template`/`.dist`) are treated as source and roll
|
|
154
|
+
back normally. Trees larger
|
|
155
|
+
than `UAP_SNAPSHOT_MAX_MB` (default 4096) skip the snapshot and the run
|
|
156
|
+
proceeds with rollback disabled. Snapshots orphaned by killed runs are reaped
|
|
157
|
+
automatically on the next `--keep-best` run (snapshots created on another
|
|
158
|
+
host or in a container are judged only by a 7-day age backstop, never by
|
|
159
|
+
local pid liveness); a snapshot whose restore failed is preserved and its
|
|
160
|
+
path printed.
|
|
153
161
|
|
|
154
162
|
---
|
|
155
163
|
|
package/package.json
CHANGED
|
Binary file
|