@miller-tech/uap 1.150.0 → 1.150.2

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-workspace.d.ts","sourceRoot":"","sources":["../../src/delivery/task-workspace.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAkBH,MAAM,WAAW,aAAa;IAC5B,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb;;;;8EAI0E;IAC1E,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAAG;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACpG,yCAAyC;IACzC,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC;+EAC2E;IAC3E,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAAC;CAC/C;AA2BD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAIzD;AA6BD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CA4L3F"}
@@ -0,0 +1,305 @@
1
+ /**
2
+ * Task Workspaces — git-worktree isolation for PARALLEL orchestrated tasks.
3
+ *
4
+ * The blackboard orchestrator can dispatch independent READY tasks
5
+ * concurrently (ATG dependency-aware parallel dispatch), but deliver's
6
+ * production runTask was not concurrency-safe: every loop mutated the same
7
+ * working tree and gates raced. This module gives each task its own detached
8
+ * git worktree — like the explorer's candidate workspaces, with one crucial
9
+ * difference: an orchestrated mission accumulates UNCOMMITTED work in the
10
+ * main tree (each merged task's files), so a bare worktree of HEAD would be a
11
+ * stale baseline from the second wave on. `acquire` therefore SYNCS the main
12
+ * tree's uncommitted state into the worktree and freezes it as a detached
13
+ * baseline commit; `mergeBack` applies only the task's own delta (diff vs
14
+ * that baseline) to the main tree.
15
+ *
16
+ * Merge-backs must be SERIALIZED by the caller (deliver holds a merge lock):
17
+ * the main tree changes one task at a time. A conflicting delta returns
18
+ * `{ok:false}` — the caller fails the task, and the orchestrator's minimal
19
+ * repair retries it in a FRESH workspace seeded with the updated baseline,
20
+ * so conflicts resolve themselves through the ATG repair path.
21
+ *
22
+ * Everything is fail-soft: manager construction returns null off-git;
23
+ * `acquire` returns null on any error (caller falls back to serialized
24
+ * in-tree execution); `cleanup` never throws.
25
+ *
26
+ * Known, accepted limitations (same class as candidate-workspace):
27
+ * - gitignored-but-required files (.env, local fixtures) are NOT seeded
28
+ * (`--exclude-standard`) — a gate depending on them can fail here while
29
+ * passing in-tree;
30
+ * - under parallel dispatch the mission's aggregate telemetry (history,
31
+ * HALO traces, finalFeedback) interleaves across concurrent loops;
32
+ * - `parallelTasks` should be sized to CPU cores, not inference slots: the
33
+ * model-slot lease bounds model calls, but concurrent GATE runs (npm
34
+ * test/build per worktree) have no governor.
35
+ */
36
+ import { execFileSync } from 'child_process';
37
+ import { copyFileSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readdirSync, readlinkSync, rmSync, statSync, symlinkSync, } from 'fs';
38
+ import { tmpdir } from 'os';
39
+ import { dirname, join } from 'path';
40
+ const HARD_PARALLEL_CEILING = 8;
41
+ /** Live workspaces for the exit sweep (a killed run must not leak /tmp trees). */
42
+ const liveWorkspaces = new Set();
43
+ let exitSweepInstalled = false;
44
+ /** Remove abandoned uap-task-* tmp trees from crashed earlier runs (>24h old). */
45
+ function sweepStaleWorkspaces() {
46
+ try {
47
+ const base = tmpdir();
48
+ const cutoff = Date.now() - 24 * 60 * 60 * 1000;
49
+ for (const name of readdirSync(base)) {
50
+ if (!name.startsWith('uap-task-'))
51
+ continue;
52
+ const p = join(base, name);
53
+ try {
54
+ if (statSync(p).mtimeMs < cutoff)
55
+ rmSync(p, { recursive: true, force: true });
56
+ }
57
+ catch {
58
+ // best-effort
59
+ }
60
+ }
61
+ }
62
+ catch {
63
+ // best-effort
64
+ }
65
+ }
66
+ /**
67
+ * Clamp the `.uap.json` `deliver.parallelTasks` value to [1, 8]. Config-only
68
+ * by design (no env override) — see the concurrency notes in
69
+ * task-orchestrator.ts: an env knob would let one exported variable flip
70
+ * every deliver run into parallel execution.
71
+ */
72
+ export function resolveParallelTasks(raw) {
73
+ const n = Number(raw);
74
+ if (!Number.isFinite(n) || n <= 1)
75
+ return 1;
76
+ return Math.min(Math.floor(n), HARD_PARALLEL_CEILING);
77
+ }
78
+ function git(cwd, args, input, timeoutMs = 120_000) {
79
+ return execFileSync('git', args, {
80
+ cwd,
81
+ encoding: 'utf-8',
82
+ timeout: timeoutMs,
83
+ // Binary deltas (assets, lockfiles) easily exceed node's 1 MiB default;
84
+ // an ENOBUFS here would misreport as a merge conflict.
85
+ maxBuffer: 64 * 1024 * 1024,
86
+ ...(input !== undefined ? { input } : {}),
87
+ stdio: [input !== undefined ? 'pipe' : 'ignore', 'pipe', 'pipe'],
88
+ // Never inherit a poisoned GIT_DIR from a hook environment.
89
+ env: { ...process.env, GIT_DIR: undefined, GIT_WORK_TREE: undefined, GIT_INDEX_FILE: undefined },
90
+ });
91
+ }
92
+ /** Tail of a git error, preferring stderr (execFileSync buries the detail there). */
93
+ function gitErrorTail(err) {
94
+ const stderr = err.stderr;
95
+ const msg = err instanceof Error ? err.message : String(err);
96
+ return `${msg} ${stderr ?? ''}`.replace(/\s+/g, ' ').trim().slice(0, 300);
97
+ }
98
+ /** NUL-separated `git ls-files` output → clean path list. */
99
+ function zList(out) {
100
+ return out.split('\0').map((s) => s.trim()).filter((s) => s.length > 0);
101
+ }
102
+ /**
103
+ * Build a task-workspace manager for `projectRoot`, or null when the project
104
+ * is not a git repo. Unlike the explorer's provider, a DIRTY tree is fine —
105
+ * that is the normal mid-mission state — because acquire syncs it.
106
+ */
107
+ export function createTaskWorkspaceManager(projectRoot) {
108
+ try {
109
+ if (git(projectRoot, ['rev-parse', '--is-inside-work-tree']).trim() !== 'true')
110
+ return null;
111
+ git(projectRoot, ['rev-parse', 'HEAD']); // unborn HEAD ⇒ no baseline to worktree
112
+ git(projectRoot, ['worktree', 'prune']);
113
+ sweepStaleWorkspaces();
114
+ }
115
+ catch {
116
+ return null;
117
+ }
118
+ // A killed run leaks /tmp trees AND their worktree registrations (prune is
119
+ // a no-op while the dir exists). Live workspaces are tracked module-wide
120
+ // and swept on process exit; ancient orphans are swept at construction.
121
+ if (!exitSweepInstalled) {
122
+ exitSweepInstalled = true;
123
+ process.once('exit', () => {
124
+ for (const ws of [...liveWorkspaces]) {
125
+ try {
126
+ ws.cleanup();
127
+ }
128
+ catch {
129
+ // best-effort
130
+ }
131
+ }
132
+ });
133
+ }
134
+ const acquire = (taskId) => {
135
+ let dir = null;
136
+ try {
137
+ dir = mkdtempSync(join(tmpdir(), 'uap-task-'));
138
+ const root = join(dir, 'tree');
139
+ git(projectRoot, ['worktree', 'add', '--detach', root, 'HEAD']);
140
+ // Gates need dependencies; share the main tree's node_modules by
141
+ // symlink (same convention + caveats as candidate-workspace).
142
+ const mainModules = join(projectRoot, 'node_modules');
143
+ const wtModules = join(root, 'node_modules');
144
+ if (existsSync(mainModules) && !existsSync(wtModules)) {
145
+ try {
146
+ symlinkSync(mainModules, wtModules, 'junction');
147
+ }
148
+ catch {
149
+ // gates may still work without it
150
+ }
151
+ }
152
+ // Seed the worktree with the main tree's CURRENT uncommitted state:
153
+ // modified + untracked + STAGED files copied in, deletions mirrored.
154
+ // (Staged paths matter because a user may start the mission with a
155
+ // pre-staged index; our own merge-backs unstage themselves below.)
156
+ // This is what makes wave-2+ baselines include earlier tasks' merged
157
+ // (uncommitted) output.
158
+ const changed = [
159
+ ...new Set([
160
+ ...zList(git(projectRoot, ['ls-files', '-mo', '--exclude-standard', '-z'])),
161
+ ...zList(git(projectRoot, ['diff', '--cached', '--name-only', '--no-renames', '-z'])),
162
+ ]),
163
+ ];
164
+ for (const rel of changed) {
165
+ const from = join(projectRoot, rel);
166
+ let st;
167
+ try {
168
+ st = lstatSync(from);
169
+ }
170
+ catch {
171
+ continue; // deleted since listing — the deletion passes handle it
172
+ }
173
+ const to = join(root, rel);
174
+ mkdirSync(dirname(to), { recursive: true });
175
+ if (st.isSymbolicLink()) {
176
+ // Recreate symlinks as symlinks: copyFileSync would FOLLOW the link
177
+ // and materialize its target's content into the model's workspace.
178
+ try {
179
+ rmSync(to, { force: true });
180
+ symlinkSync(readlinkSync(from), to);
181
+ }
182
+ catch {
183
+ // an unreproducible link is skipped, not followed
184
+ }
185
+ }
186
+ else if (st.isFile()) {
187
+ copyFileSync(from, to);
188
+ }
189
+ }
190
+ // Deletions: unstaged (ls-files -d) AND staged (`git rm` shows only in
191
+ // the cached diff as D — without this pass the worktree resurrects the
192
+ // file from HEAD and merge-back can re-add it to the main tree).
193
+ const deleted = [
194
+ ...new Set([
195
+ ...zList(git(projectRoot, ['ls-files', '-d', '-z'])),
196
+ ...zList(git(projectRoot, ['diff', '--cached', '--name-only', '--no-renames', '--diff-filter=D', '-z'])),
197
+ ]),
198
+ ];
199
+ for (const rel of deleted) {
200
+ try {
201
+ rmSync(join(root, rel), { force: true });
202
+ }
203
+ catch {
204
+ // best-effort mirror of a deletion
205
+ }
206
+ }
207
+ // Freeze the seeded state as the task's BASELINE commit (detached — no
208
+ // branch moves). mergeBack diffs against this, so only the task's own
209
+ // work travels back. Identity flags keep this working on repos/CI with
210
+ // no git user configured.
211
+ git(root, ['add', '-A']);
212
+ git(root, [
213
+ '-c', 'user.email=uap-task@local',
214
+ '-c', 'user.name=uap-task-workspace',
215
+ 'commit', '--allow-empty', '--no-verify', '-m', `uap task baseline: ${taskId}`,
216
+ ]);
217
+ const mergeBack = (isBlocked) => {
218
+ try {
219
+ git(root, ['add', '-A']);
220
+ // --no-renames: a task-side rename must travel as delete+add so the
221
+ // file list (and any unstage below) covers BOTH paths.
222
+ const files = zList(git(root, ['diff', '--cached', '--name-only', '--no-renames', '-z', 'HEAD']));
223
+ if (files.length === 0)
224
+ return { ok: true, files: [] };
225
+ const blocked = isBlocked ? files.filter((f) => isBlocked(f)) : [];
226
+ if (blocked.length > 0) {
227
+ return { ok: false, files: [], reason: `delta touches protected file(s): ${blocked.slice(0, 5).join(', ')}` };
228
+ }
229
+ const patch = git(root, ['diff', '--cached', '--binary', '--no-renames', 'HEAD']);
230
+ // Plain apply first: it is worktree-only (no index coupling), and the
231
+ // seeded baseline guarantees the preimage matches whenever no sibling
232
+ // touched the same files — INCLUDING dirty/untracked targets in the
233
+ // main tree, which is the normal wave-2 state. `--3way` alone would
234
+ // imply --index and systematically fail exactly those targets.
235
+ try {
236
+ git(projectRoot, ['apply', '--whitespace=nowarn'], patch);
237
+ return { ok: true, files };
238
+ }
239
+ catch {
240
+ // Preimage drift (a sibling merged first). --3way can resolve
241
+ // non-overlapping drift via the shared object store (git >= 2.9.3
242
+ // also gives us its path-safety checks); it stages what it
243
+ // applies, so unstage the merged paths after (chunked — argv).
244
+ git(projectRoot, ['apply', '--3way', '--whitespace=nowarn'], patch);
245
+ try {
246
+ for (let i = 0; i < files.length; i += 100) {
247
+ git(projectRoot, ['reset', '-q', 'HEAD', '--', ...files.slice(i, i + 100)]);
248
+ }
249
+ }
250
+ catch {
251
+ // staged leftovers are re-caught by the next acquire's cached-diff sync
252
+ }
253
+ return { ok: true, files };
254
+ }
255
+ }
256
+ catch (err) {
257
+ return { ok: false, files: [], reason: gitErrorTail(err) };
258
+ }
259
+ };
260
+ const cleanup = () => {
261
+ liveWorkspaces.delete(workspace);
262
+ try {
263
+ git(projectRoot, ['worktree', 'remove', '--force', root]);
264
+ }
265
+ catch {
266
+ // fall through to raw dir removal
267
+ }
268
+ try {
269
+ if (dir)
270
+ rmSync(dir, { recursive: true, force: true });
271
+ }
272
+ catch {
273
+ // best-effort
274
+ }
275
+ try {
276
+ git(projectRoot, ['worktree', 'prune']);
277
+ }
278
+ catch {
279
+ // best-effort
280
+ }
281
+ };
282
+ const workspace = { root, mergeBack, cleanup };
283
+ liveWorkspaces.add(workspace);
284
+ return workspace;
285
+ }
286
+ catch {
287
+ try {
288
+ if (dir)
289
+ rmSync(dir, { recursive: true, force: true });
290
+ }
291
+ catch {
292
+ // best-effort
293
+ }
294
+ try {
295
+ git(projectRoot, ['worktree', 'prune']);
296
+ }
297
+ catch {
298
+ // best-effort
299
+ }
300
+ return null;
301
+ }
302
+ };
303
+ return { acquire };
304
+ }
305
+ //# sourceMappingURL=task-workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-workspace.js","sourceRoot":"","sources":["../../src/delivery/task-workspace.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EACL,YAAY,EACZ,UAAU,EACV,SAAS,EACT,SAAS,EACT,WAAW,EACX,WAAW,EACX,YAAY,EACZ,MAAM,EACN,QAAQ,EACR,WAAW,GACZ,MAAM,IAAI,CAAC;AACZ,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAqBrC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAEhC,kFAAkF;AAClF,MAAM,cAAc,GAAG,IAAI,GAAG,EAAiB,CAAC;AAChD,IAAI,kBAAkB,GAAG,KAAK,CAAC;AAE/B,kFAAkF;AAClF,SAAS,oBAAoB;IAC3B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QAChD,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;gBAAE,SAAS;YAC5C,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC3B,IAAI,CAAC;gBACH,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,MAAM;oBAAE,MAAM,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAChF,CAAC;YAAC,MAAM,CAAC;gBACP,cAAc;YAChB,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,cAAc;IAChB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAY;IAC/C,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACtB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAC5C,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,GAAG,CAAC,GAAW,EAAE,IAAc,EAAE,KAAc,EAAE,SAAS,GAAG,OAAO;IAC3E,OAAO,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE;QAC/B,GAAG;QACH,QAAQ,EAAE,OAAO;QACjB,OAAO,EAAE,SAAS;QAClB,wEAAwE;QACxE,uDAAuD;QACvD,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;QAC3B,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,KAAK,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;QAChE,4DAA4D;QAC5D,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE;KACjG,CAAC,CAAC;AACL,CAAC;AAED,qFAAqF;AACrF,SAAS,YAAY,CAAC,GAAY;IAChC,MAAM,MAAM,GAAI,GAA2B,CAAC,MAAM,CAAC;IACnD,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7D,OAAO,GAAG,GAAG,IAAI,MAAM,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC5E,CAAC;AAED,6DAA6D;AAC7D,SAAS,KAAK,CAAC,GAAW;IACxB,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CAAC,WAAmB;IAC5D,IAAI,CAAC;QACH,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC;QAC5F,GAAG,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,wCAAwC;QACjF,GAAG,CAAC,WAAW,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;QACxC,oBAAoB,EAAE,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,2EAA2E;IAC3E,yEAAyE;IACzE,wEAAwE;IACxE,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,kBAAkB,GAAG,IAAI,CAAC;QAC1B,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE;YACxB,KAAK,MAAM,EAAE,IAAI,CAAC,GAAG,cAAc,CAAC,EAAE,CAAC;gBACrC,IAAI,CAAC;oBACH,EAAE,CAAC,OAAO,EAAE,CAAC;gBACf,CAAC;gBAAC,MAAM,CAAC;oBACP,cAAc;gBAChB,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,MAAc,EAAwB,EAAE;QACvD,IAAI,GAAG,GAAkB,IAAI,CAAC;QAC9B,IAAI,CAAC;YACH,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;YAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC/B,GAAG,CAAC,WAAW,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;YAEhE,iEAAiE;YACjE,8DAA8D;YAC9D,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;YACtD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;YAC7C,IAAI,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBACtD,IAAI,CAAC;oBACH,WAAW,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;gBAClD,CAAC;gBAAC,MAAM,CAAC;oBACP,kCAAkC;gBACpC,CAAC;YACH,CAAC;YAED,oEAAoE;YACpE,qEAAqE;YACrE,mEAAmE;YACnE,mEAAmE;YACnE,qEAAqE;YACrE,wBAAwB;YACxB,MAAM,OAAO,GAAG;gBACd,GAAG,IAAI,GAAG,CAAC;oBACT,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,oBAAoB,EAAE,IAAI,CAAC,CAAC,CAAC;oBAC3E,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC;iBACtF,CAAC;aACH,CAAC;YACF,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;gBAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;gBACpC,IAAI,EAAE,CAAC;gBACP,IAAI,CAAC;oBACH,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;gBACvB,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS,CAAC,wDAAwD;gBACpE,CAAC;gBACD,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;gBAC3B,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC5C,IAAI,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC;oBACxB,oEAAoE;oBACpE,mEAAmE;oBACnE,IAAI,CAAC;wBACH,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;wBAC5B,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;oBACtC,CAAC;oBAAC,MAAM,CAAC;wBACP,kDAAkD;oBACpD,CAAC;gBACH,CAAC;qBAAM,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC;oBACvB,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACzB,CAAC;YACH,CAAC;YACD,uEAAuE;YACvE,uEAAuE;YACvE,iEAAiE;YACjE,MAAM,OAAO,GAAG;gBACd,GAAG,IAAI,GAAG,CAAC;oBACT,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;oBACpD,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,iBAAiB,EAAE,IAAI,CAAC,CAAC,CAAC;iBACzG,CAAC;aACH,CAAC;YACF,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;gBAC1B,IAAI,CAAC;oBACH,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC3C,CAAC;gBAAC,MAAM,CAAC;oBACP,mCAAmC;gBACrC,CAAC;YACH,CAAC;YAED,uEAAuE;YACvE,sEAAsE;YACtE,uEAAuE;YACvE,0BAA0B;YAC1B,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;YACzB,GAAG,CAAC,IAAI,EAAE;gBACR,IAAI,EAAE,2BAA2B;gBACjC,IAAI,EAAE,8BAA8B;gBACpC,QAAQ,EAAE,eAAe,EAAE,aAAa,EAAE,IAAI,EAAE,sBAAsB,MAAM,EAAE;aAC/E,CAAC,CAAC;YAEH,MAAM,SAAS,GAAG,CAChB,SAAqC,EACc,EAAE;gBACrD,IAAI,CAAC;oBACH,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;oBACzB,oEAAoE;oBACpE,uDAAuD;oBACvD,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;oBAClG,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;wBAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;oBACvD,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBACnE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACvB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,oCAAoC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;oBAChH,CAAC;oBACD,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;oBAClF,sEAAsE;oBACtE,sEAAsE;oBACtE,oEAAoE;oBACpE,oEAAoE;oBACpE,+DAA+D;oBAC/D,IAAI,CAAC;wBACH,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,qBAAqB,CAAC,EAAE,KAAK,CAAC,CAAC;wBAC1D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;oBAC7B,CAAC;oBAAC,MAAM,CAAC;wBACP,8DAA8D;wBAC9D,kEAAkE;wBAClE,2DAA2D;wBAC3D,+DAA+D;wBAC/D,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,qBAAqB,CAAC,EAAE,KAAK,CAAC,CAAC;wBACpE,IAAI,CAAC;4BACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC;gCAC3C,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;4BAC9E,CAAC;wBACH,CAAC;wBAAC,MAAM,CAAC;4BACP,wEAAwE;wBAC1E,CAAC;wBACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;oBAC7B,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7D,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,OAAO,GAAG,GAAS,EAAE;gBACzB,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gBACjC,IAAI,CAAC;oBACH,GAAG,CAAC,WAAW,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;gBAC5D,CAAC;gBAAC,MAAM,CAAC;oBACP,kCAAkC;gBACpC,CAAC;gBACD,IAAI,CAAC;oBACH,IAAI,GAAG;wBAAE,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBACzD,CAAC;gBAAC,MAAM,CAAC;oBACP,cAAc;gBAChB,CAAC;gBACD,IAAI,CAAC;oBACH,GAAG,CAAC,WAAW,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;gBAC1C,CAAC;gBAAC,MAAM,CAAC;oBACP,cAAc;gBAChB,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,SAAS,GAAkB,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;YAC9D,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAC9B,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC;gBACH,IAAI,GAAG;oBAAE,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACzD,CAAC;YAAC,MAAM,CAAC;gBACP,cAAc;YAChB,CAAC;YACD,IAAI,CAAC;gBACH,GAAG,CAAC,WAAW,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;YAC1C,CAAC;YAAC,MAAM,CAAC;gBACP,cAAc;YAChB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC"}
@@ -87,6 +87,15 @@ Top level: `version`, `project`, `memory`, `worktree`, `costOptimization`,
87
87
  | `UAP_AGENT_ID` | Agent id for MCP execute | `mcp-<pid>` |
88
88
  | `UAP_MAX_PARALLEL` | Override max parallel workers | auto |
89
89
  | `UAP_PARALLEL` | `false` disables parallelism | enabled |
90
+
91
+ ### `.uap.json` `deliver` section
92
+
93
+ | Key | What it does | Default |
94
+ |---|---|---|
95
+ | `deliver.orchestrate` | Blackboard orchestration for decomposed missions (`"on"`/`"off"`) | `"on"` (preflight seeds it) |
96
+ | `deliver.epics` | Epic controller outer loop (`"on"`/`"off"`) | `"on"` (preflight seeds it) |
97
+ | `deliver.parallelTasks` | Worktree-isolated parallel dispatch: independent READY orchestrator tasks run concurrently, each convergence loop + its gates in a detached git worktree seeded with the mission's current state; deltas merge back serially, and a merge conflict fails the task into the minimal-repair retry. Clamped to 1–8. **Config-only by design — no env override** (an exported variable must never silently parallelize every run). | `1` (sequential) |
98
+ | `deliver.autoSizeEpics` | Context auto-size for epic sessions (`false`/`"off"` disables) | enabled |
90
99
  | `UAP_BENCHMARK_MODE` | `true` enables benchmark template mode | off |
91
100
  | `UAP_BENCHMARK_PARALLEL` | Parallel model count in benchmarks | — |
92
101
  | `UAP_SNAPSHOT_DIR` | Base dir for `--keep-best` snapshots (absolute path) | `~/.cache/uap/snapshots` |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miller-tech/uap",
3
- "version": "1.150.0",
3
+ "version": "1.150.2",
4
4
  "description": "Autonomous AI agent memory system with CLAUDE.md protocol enforcement",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",