@miller-tech/uap 1.150.0 → 1.150.1
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.d.ts.map +1 -1
- package/dist/cli/deliver.js +212 -52
- package/dist/cli/deliver.js.map +1 -1
- package/dist/delivery/task-workspace.d.ts +70 -0
- package/dist/delivery/task-workspace.d.ts.map +1 -0
- package/dist/delivery/task-workspace.js +305 -0
- package/dist/delivery/task-workspace.js.map +1 -0
- package/docs/reference/CONFIGURATION.md +9 -0
- package/package.json +1 -1
- package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
- package/templates/hooks/__pycache__/deliver_autoroute.cpython-312.pyc +0 -0
- package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
|
@@ -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":"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"}
|
|
@@ -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
|
Binary file
|
|
Binary file
|