@miller-tech/uap 1.39.0 → 1.40.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/README.md +109 -642
- package/dist/.tsbuildinfo +1 -1
- package/dist/bin/cli.js +2 -2
- package/dist/bin/cli.js.map +1 -1
- package/dist/cli/deliver.d.ts +3 -2
- package/dist/cli/deliver.d.ts.map +1 -1
- package/dist/cli/deliver.js +10 -5
- package/dist/cli/deliver.js.map +1 -1
- package/docs/INDEX.md +48 -286
- package/docs/architecture/OVERVIEW.md +328 -0
- package/docs/architecture/PROTOCOL.md +204 -0
- package/docs/benchmarks/README.md +17 -192
- package/docs/getting-started/CONFIGURATION.md +237 -0
- package/docs/getting-started/INSTALLATION.md +125 -0
- package/docs/getting-started/QUICKSTART.md +115 -0
- package/docs/guides/COORDINATION.md +162 -0
- package/docs/guides/DELIVER.md +115 -0
- package/docs/guides/DEPLOY_BATCHING.md +212 -0
- package/docs/guides/DROIDS_AND_SKILLS.md +202 -0
- package/docs/guides/LOCAL_MODELS.md +148 -0
- package/docs/guides/MCP_ROUTER.md +195 -0
- package/docs/guides/MEMORY.md +235 -0
- package/docs/guides/MULTI_MODEL.md +223 -0
- package/docs/guides/POLICIES.md +190 -0
- package/docs/guides/WORKTREE_WORKFLOW.md +185 -0
- package/docs/integrations/MCP_ROUTER.md +147 -0
- package/docs/integrations/RTK.md +102 -0
- package/docs/reference/API.md +485 -0
- package/docs/reference/CLI.md +719 -0
- package/docs/reference/CONFIGURATION.md +90 -193
- package/docs/reference/DATABASE_SCHEMA.md +110 -344
- package/docs/reference/FEATURES.md +176 -472
- package/docs/reference/PATTERNS.md +102 -0
- package/docs/reference/PLATFORMS.md +83 -0
- package/package.json +1 -1
- package/docs/AGENTS.md +0 -423
- package/docs/DOCUMENTATION_AUDIT_REPORT.md +0 -131
- package/docs/GETTING_STARTED.md +0 -288
- package/docs/PROJECT_ANALYSIS_REPORT.md +0 -510
- package/docs/architecture/COMPLETE_ARCHITECTURE.md +0 -748
- package/docs/architecture/EXPERT_STACK.md +0 -137
- package/docs/architecture/MULTI_MODEL.md +0 -224
- package/docs/architecture/PLATFORM_GATING.md +0 -68
- package/docs/architecture/SYSTEM_ANALYSIS.md +0 -334
- package/docs/architecture/UAP_COMPLIANCE.md +0 -217
- package/docs/architecture/UAP_PROTOCOL.md +0 -339
- package/docs/architecture/UAP_STRICT_DROIDS.md +0 -172
- package/docs/archive/BALLS_MODE_SELF_ANALYSIS.md +0 -260
- package/docs/archive/BENCHMARK_GAPS_AND_PLAN.md +0 -146
- package/docs/archive/FAILING_TASKS_SOLUTION_PLAN.md +0 -668
- package/docs/archive/JINJA2-SYSTEM-MESSAGE-FIX.md +0 -209
- package/docs/archive/MODEL_ROUTING_IMPLEMENTATION_SUMMARY.md +0 -281
- package/docs/archive/MODEL_ROUTING_OPTIMIZATION_PLAN.md +0 -320
- package/docs/archive/NPM-PUBLISH-V0.9.1.md +0 -240
- package/docs/archive/OPTIMIZATION_OPTIONS.md +0 -334
- package/docs/archive/PARALLELISM_GAPS_AND_OPTIONS.md +0 -422
- package/docs/archive/POLICY_GATE_IMPLEMENTATION.md +0 -245
- package/docs/archive/SETUP_IMPROVEMENTS.md +0 -213
- package/docs/archive/UAP_GENERIC_OPTIMIZATION_PLAN.md +0 -270
- package/docs/archive/UAP_OPTIMIZATION_PLAN.md +0 -701
- package/docs/archive/UAP_V103_PATTERN_DESIGN.md +0 -315
- package/docs/archive/UAP_V104_COMPLIANCE_DESIGN.md +0 -223
- package/docs/archive/changelog/2026-03-10_uap-100-compliance.md +0 -77
- package/docs/archive/changelog/2026-03-10_uap-full-system-verification.md +0 -109
- package/docs/archive/opencode-integration-guide.md +0 -740
- package/docs/archive/opencode-integration-quickref.md +0 -180
- package/docs/benchmarks/OVERNIGHT_RUNNER.md +0 -341
- package/docs/benchmarks/SPECULATIVE_DECODING_JOURNEY_2026-03.md +0 -221
- package/docs/benchmarks/VALIDATION_PLAN.md +0 -568
- package/docs/blog/SPECULATIVE_DECODING_PRODUCTION_PLAYBOOK.md +0 -139
- package/docs/blog/local-coding-agents.md +0 -266
- package/docs/blog/x-thread.md +0 -254
- package/docs/deployment/DEPLOYMENT.md +0 -895
- package/docs/deployment/DEPLOYMENT_STRATEGIES.md +0 -518
- package/docs/deployment/DEPLOY_BATCHER_ANALYSIS.md +0 -224
- package/docs/deployment/DEPLOY_BATCHING.md +0 -273
- package/docs/deployment/DEPLOY_BUCKETING_ANALYSIS.md +0 -420
- package/docs/deployment/QWEN35_LLAMA_CPP.md +0 -426
- package/docs/deployment/UAP_LLAMA_ANTHROPIC_PROXY_BOOTSTRAP.md +0 -279
- package/docs/getting-started/INTEGRATION.md +0 -628
- package/docs/getting-started/OVERVIEW.md +0 -324
- package/docs/getting-started/SETUP.md +0 -377
- package/docs/integrations/MCP_ROUTER_SETUP.md +0 -445
- package/docs/integrations/RTK_INTEGRATION.md +0 -468
- package/docs/operations/TROUBLESHOOTING.md +0 -660
- package/docs/pr/PR_SPECULATIVE_DOCS_TEMPLATE.md +0 -146
- package/docs/pr/UPSTREAM_PRS.md +0 -424
- package/docs/reference/API_REFERENCE.md +0 -903
- package/docs/reference/EXPERT_DROIDS.md +0 -219
- package/docs/reference/HARNESS-MATRIX.md +0 -318
- package/docs/reference/PATTERN_LIBRARY.md +0 -636
- package/docs/reference/UAP_CLI_REFERENCE.md +0 -620
- package/docs/research/BEHAVIORAL_PATTERNS.md +0 -228
- package/docs/research/DOMAIN_STRATEGIES.md +0 -316
- package/docs/research/MEMORY_SYSTEMS_COMPARISON.md +0 -812
- package/docs/research/PATTERN_ANALYSIS_2026-01-18.md +0 -436
- package/docs/research/PERFORMANCE_ANALYSIS_2026-01-18.md +0 -209
- package/docs/research/PERFORMANCE_TEST_PLAN.md +0 -383
- package/docs/research/TERMINAL_BENCH_LEARNINGS.md +0 -217
|
@@ -1,422 +0,0 @@
|
|
|
1
|
-
# Parallelism & Dependency Notification: Gaps and Options
|
|
2
|
-
|
|
3
|
-
**Generated:** 2026-03-17
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Current State
|
|
8
|
-
|
|
9
|
-
### What exists (DO NOT REBUILD)
|
|
10
|
-
|
|
11
|
-
| Component | File | What it does |
|
|
12
|
-
| ---------------------------- | ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
13
|
-
| Executor parallel batching | `src/models/executor.ts:54-162` | `Promise.all` batches capped by `maxParallel` (default 3), topological level grouping |
|
|
14
|
-
| Deploy batcher parallelism | `src/coordination/deploy-batcher.ts:34-591` | Categorizes actions as parallel-safe vs sequential, `Promise.allSettled` with `maxParallelActions` (default 5) |
|
|
15
|
-
| Benchmark model parallelism | `src/benchmarks/model-integration.ts:911-944` + `improved-benchmark.ts:565-603` | Queue-based concurrency pool, `parallelModels` param (default 1) |
|
|
16
|
-
| Planner topological sort | `src/models/planner.ts:379-413` | Returns `string[][]` dependency levels for parallel execution |
|
|
17
|
-
| Task dependency DAG | `src/tasks/database.ts:71-84` + `service.ts:438-538` | `task_dependencies` table, add/remove deps, cycle detection (BFS), blocked/ready queries |
|
|
18
|
-
| Task coordination scoring | `src/tasks/coordination.ts:260-298` | Scores tasks: +5 no deps, +3 per task it unblocks |
|
|
19
|
-
| Pub/sub messaging | `src/coordination/service.ts:608-642` | SQLite-backed broadcast/send/receive on channels |
|
|
20
|
-
| Config schema (unused) | `src/types/config.ts:223-229` | `maxParallelDroids` (4), `maxParallelWorkflows` (3) -- declared but never consumed |
|
|
21
|
-
| VRAM detection | `src/bin/llama-server-optimize.ts:301-331` | nvidia-smi / sysctl, not reusable (private to llama-server) |
|
|
22
|
-
| CPU detection | `src/bin/llama-server-optimize.ts:614` | `os.cpus().length - 2`, not reusable (inline in llama-server) |
|
|
23
|
-
| Harbor N_CONCURRENT | Shell scripts | `N_CONCURRENT` env var (default 4) for Harbor `-n` flag |
|
|
24
|
-
| Python parallel tool calls | `tools/agents/scripts/qwen_tool_call_wrapper.py` | `parallel_tool_calls: True` in every API request |
|
|
25
|
-
| Unbounded memory parallelism | `src/memory/predictive-memory.ts:94-104` + `embeddings.ts:228-230` | `Promise.all` with no concurrency limit |
|
|
26
|
-
|
|
27
|
-
### What's broken or missing
|
|
28
|
-
|
|
29
|
-
| Gap | Location | Impact |
|
|
30
|
-
| -------------------------------------------------- | -------------------------------------------------------------- | --------------------------------------------------------------------------- |
|
|
31
|
-
| **No env var override for TypeScript parallelism** | `executor.ts`, `improved-benchmark.ts`, `model-integration.ts` | Cannot tune parallelism without code changes |
|
|
32
|
-
| **No vCPU/resource detection shared utility** | `llama-server-optimize.ts` has it but private | Every module hardcodes defaults |
|
|
33
|
-
| **Config schema not wired** | `config.ts:223-229` | `maxParallelDroids`/`maxParallelWorkflows` declared but never read |
|
|
34
|
-
| **No dependency completion notification** | `service.ts:287-302` | `close()` marks task done but does NOT notify blocked dependents |
|
|
35
|
-
| **No auto-unblock on completion** | `coordination.ts:155-200` | `release()` broadcasts generic message, doesn't check newly-unblocked tasks |
|
|
36
|
-
| **Unbounded memory concurrency** | `predictive-memory.ts`, `embeddings.ts` | `Promise.all` on all items, can overwhelm local inference |
|
|
37
|
-
| **Benchmark parallelism defaults to 1** | `improved-benchmark.ts:632`, `model-integration.ts` | Sequential by default, no auto-detection |
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## Option A: Minimal -- Env Overrides + Wire Config (Recommended)
|
|
42
|
-
|
|
43
|
-
**Effort:** ~2 hours | **Risk:** Low | **Impact:** High
|
|
44
|
-
|
|
45
|
-
No new abstractions. Add env var reads to existing code, wire the existing config schema, and add notification to `close()`.
|
|
46
|
-
|
|
47
|
-
### A1. Shared resource detection utility
|
|
48
|
-
|
|
49
|
-
**New file:** `src/utils/system-resources.ts`
|
|
50
|
-
|
|
51
|
-
Extract and generalize the detection logic already in `llama-server-optimize.ts`:
|
|
52
|
-
|
|
53
|
-
```typescript
|
|
54
|
-
import { cpus } from 'os';
|
|
55
|
-
import { execSync } from 'child_process';
|
|
56
|
-
|
|
57
|
-
export interface SystemResources {
|
|
58
|
-
vCPUs: number;
|
|
59
|
-
vramGB: number;
|
|
60
|
-
memoryGB: number;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
let _cached: SystemResources | null = null;
|
|
64
|
-
|
|
65
|
-
export function detectSystemResources(): SystemResources {
|
|
66
|
-
if (_cached) return _cached;
|
|
67
|
-
|
|
68
|
-
const vCPUs = cpus().length;
|
|
69
|
-
|
|
70
|
-
let vramGB = 0;
|
|
71
|
-
try {
|
|
72
|
-
const out = execSync('nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits', {
|
|
73
|
-
encoding: 'utf-8',
|
|
74
|
-
timeout: 3000,
|
|
75
|
-
});
|
|
76
|
-
vramGB = Math.round(parseInt(out.trim().split('\n')[0]) / 1024);
|
|
77
|
-
} catch {
|
|
78
|
-
try {
|
|
79
|
-
const out = execSync('sysctl -n hw.memsize', { encoding: 'utf-8' });
|
|
80
|
-
vramGB = Math.min(Math.round(parseInt(out.trim()) / 1024 ** 3), 48);
|
|
81
|
-
} catch {
|
|
82
|
-
vramGB = 0;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const memoryGB = Math.round(require('os').totalmem() / 1024 ** 3);
|
|
87
|
-
|
|
88
|
-
_cached = { vCPUs, vramGB, memoryGB };
|
|
89
|
-
return _cached;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Compute safe parallelism ceiling.
|
|
94
|
-
* For CPU-bound: vCPUs - 2 (reserve for OS + inference).
|
|
95
|
-
* For IO-bound (API calls): min(vCPUs, 8).
|
|
96
|
-
* Env override: UAP_MAX_PARALLEL always wins.
|
|
97
|
-
*/
|
|
98
|
-
export function getMaxParallel(mode: 'cpu' | 'io' = 'io'): number {
|
|
99
|
-
const envOverride = process.env.UAP_MAX_PARALLEL;
|
|
100
|
-
if (envOverride) return Math.max(1, parseInt(envOverride, 10) || 1);
|
|
101
|
-
|
|
102
|
-
const { vCPUs } = detectSystemResources();
|
|
103
|
-
|
|
104
|
-
if (mode === 'cpu') {
|
|
105
|
-
return Math.max(1, vCPUs - 2);
|
|
106
|
-
}
|
|
107
|
-
return Math.min(vCPUs, 8);
|
|
108
|
-
}
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### A2. Env var overrides in existing code
|
|
112
|
-
|
|
113
|
-
**File: `src/models/executor.ts:58-65`** -- read env vars into defaults:
|
|
114
|
-
|
|
115
|
-
```typescript
|
|
116
|
-
const DEFAULT_OPTIONS: ExecutorOptions = {
|
|
117
|
-
maxRetries: 2,
|
|
118
|
-
retryDelayMs: 1000,
|
|
119
|
-
stepTimeout: 120000,
|
|
120
|
-
enableFallback: true,
|
|
121
|
-
parallelExecution: process.env.UAP_PARALLEL !== 'false',
|
|
122
|
-
maxParallel: parseInt(process.env.UAP_MAX_PARALLEL || '', 10) || 3,
|
|
123
|
-
};
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
**File: `src/benchmarks/improved-benchmark.ts:632`** -- auto-detect:
|
|
127
|
-
|
|
128
|
-
```typescript
|
|
129
|
-
const parallelModels =
|
|
130
|
-
(options.parallelModels ?? parseInt(process.env.UAP_BENCHMARK_PARALLEL || '', 10)) ||
|
|
131
|
-
getMaxParallel('io');
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
**File: `src/benchmarks/model-integration.ts`** -- same pattern.
|
|
135
|
-
|
|
136
|
-
**File: `src/coordination/deploy-batcher.ts:78-79`** -- same pattern:
|
|
137
|
-
|
|
138
|
-
```typescript
|
|
139
|
-
parallelExecution: process.env.UAP_PARALLEL !== 'false',
|
|
140
|
-
maxParallelActions: parseInt(process.env.UAP_MAX_PARALLEL || '', 10) || 5,
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
### A3. Wire existing config schema
|
|
144
|
-
|
|
145
|
-
**File: `src/types/config.ts:223-229`** -- already declares `maxParallelDroids` and `maxParallelWorkflows`.
|
|
146
|
-
|
|
147
|
-
Wire into executor by reading config at startup:
|
|
148
|
-
|
|
149
|
-
```typescript
|
|
150
|
-
// In executor.ts constructor or factory
|
|
151
|
-
const uapConfig = loadUAPConfig(); // existing config loader
|
|
152
|
-
if (uapConfig?.parallelExecution) {
|
|
153
|
-
this.options.parallelExecution = uapConfig.parallelExecution.enabled;
|
|
154
|
-
this.options.maxParallel = uapConfig.parallelExecution.maxParallelDroids;
|
|
155
|
-
}
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### A4. Dependency completion notification
|
|
159
|
-
|
|
160
|
-
**File: `src/tasks/service.ts:287-302`** -- add unblock notification to `close()`:
|
|
161
|
-
|
|
162
|
-
```typescript
|
|
163
|
-
close(id: string, reason?: string): Task | null {
|
|
164
|
-
const task = this.get(id);
|
|
165
|
-
if (!task) return null;
|
|
166
|
-
|
|
167
|
-
const now = new Date().toISOString();
|
|
168
|
-
const stmt = this.db.prepare(`
|
|
169
|
-
UPDATE tasks SET status = 'done', closed_at = ?, closed_reason = ?, updated_at = ?
|
|
170
|
-
WHERE id = ?
|
|
171
|
-
`);
|
|
172
|
-
stmt.run(now, reason || null, now, id);
|
|
173
|
-
|
|
174
|
-
this.recordHistory(id, 'status', task.status, 'done');
|
|
175
|
-
this.recordActivity(id, 'closed', reason || 'Task completed');
|
|
176
|
-
|
|
177
|
-
// --- NEW: Notify newly-unblocked dependents ---
|
|
178
|
-
this.notifyUnblockedDependents(id);
|
|
179
|
-
|
|
180
|
-
return this.get(id);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
private notifyUnblockedDependents(completedTaskId: string): void {
|
|
184
|
-
// Find tasks that were blocked by this task
|
|
185
|
-
const dependents = this.db.prepare(`
|
|
186
|
-
SELECT from_task FROM task_dependencies
|
|
187
|
-
WHERE to_task = ? AND dep_type = 'blocks'
|
|
188
|
-
`).all(completedTaskId) as Array<{ from_task: string }>;
|
|
189
|
-
|
|
190
|
-
for (const dep of dependents) {
|
|
191
|
-
const dependent = this.getWithRelations(dep.from_task);
|
|
192
|
-
if (dependent && dependent.isReady) {
|
|
193
|
-
// Task is now unblocked -- record activity
|
|
194
|
-
this.recordActivity(dep.from_task, 'unblocked',
|
|
195
|
-
`Unblocked: dependency "${completedTaskId}" completed`);
|
|
196
|
-
|
|
197
|
-
// If task was in 'blocked' status, move to 'open'
|
|
198
|
-
const raw = this.get(dep.from_task);
|
|
199
|
-
if (raw && raw.status === 'blocked') {
|
|
200
|
-
this.db.prepare(`UPDATE tasks SET status = 'open', updated_at = ? WHERE id = ?`)
|
|
201
|
-
.run(new Date().toISOString(), dep.from_task);
|
|
202
|
-
this.recordHistory(dep.from_task, 'status', 'blocked', 'open');
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
**File: `src/tasks/coordination.ts:155-200`** -- enhance `release()` to return unblocked tasks:
|
|
210
|
-
|
|
211
|
-
```typescript
|
|
212
|
-
async release(taskId: string, reason?: string): Promise<ReleaseResult | null> {
|
|
213
|
-
// ... existing code ...
|
|
214
|
-
|
|
215
|
-
// Broadcast task completion
|
|
216
|
-
this.coordService.broadcast(this.agentId, 'coordination', {
|
|
217
|
-
action: 'task_completed',
|
|
218
|
-
resource: taskId,
|
|
219
|
-
data: {
|
|
220
|
-
title: task.title,
|
|
221
|
-
reason,
|
|
222
|
-
},
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
// --- NEW: Find and broadcast newly-unblocked tasks ---
|
|
226
|
-
const nowReady = this.taskService.ready().filter(t =>
|
|
227
|
-
t.blockedBy.length === 0 // was previously blocked, now free
|
|
228
|
-
);
|
|
229
|
-
|
|
230
|
-
if (nowReady.length > 0) {
|
|
231
|
-
this.coordService.broadcast(this.agentId, 'coordination', {
|
|
232
|
-
action: 'tasks_unblocked',
|
|
233
|
-
resource: taskId,
|
|
234
|
-
data: {
|
|
235
|
-
unblockedTasks: nowReady.map(t => ({ id: t.id, title: t.title })),
|
|
236
|
-
count: nowReady.length,
|
|
237
|
-
},
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// ... rest of existing code ...
|
|
242
|
-
|
|
243
|
-
return {
|
|
244
|
-
task: closedTask,
|
|
245
|
-
completedAnnouncements: 1,
|
|
246
|
-
unblockedTasks: nowReady.map(t => t.id), // NEW field
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
### A5. Cap unbounded memory concurrency
|
|
252
|
-
|
|
253
|
-
**File: `src/memory/predictive-memory.ts:94-104`**:
|
|
254
|
-
|
|
255
|
-
```typescript
|
|
256
|
-
// Before (unbounded):
|
|
257
|
-
const results = await Promise.all(predictions.map((p) => this.query(p)));
|
|
258
|
-
|
|
259
|
-
// After (capped):
|
|
260
|
-
import { getMaxParallel } from '../utils/system-resources.js';
|
|
261
|
-
|
|
262
|
-
const maxConcurrent = getMaxParallel('io');
|
|
263
|
-
const results: MemoryEntry[][] = [];
|
|
264
|
-
for (let i = 0; i < predictions.length; i += maxConcurrent) {
|
|
265
|
-
const batch = predictions.slice(i, i + maxConcurrent);
|
|
266
|
-
const batchResults = await Promise.all(batch.map((p) => this.query(p)));
|
|
267
|
-
results.push(...batchResults);
|
|
268
|
-
}
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
### Env Variable Summary
|
|
272
|
-
|
|
273
|
-
| Variable | Default | Scope | Override |
|
|
274
|
-
| ------------------------ | ------------------------ | ---------------------------------- | ---------------------------------- |
|
|
275
|
-
| `UAP_PARALLEL` | `true` | Global on/off | `false` to disable all parallelism |
|
|
276
|
-
| `UAP_MAX_PARALLEL` | auto-detected from vCPUs | Global concurrency cap | Any integer |
|
|
277
|
-
| `UAP_BENCHMARK_PARALLEL` | auto-detected | Benchmark model concurrency | Any integer |
|
|
278
|
-
| `N_CONCURRENT` | `4` | Harbor task concurrency (existing) | Any integer |
|
|
279
|
-
|
|
280
|
-
### Precedence
|
|
281
|
-
|
|
282
|
-
```
|
|
283
|
-
UAP_MAX_PARALLEL env var
|
|
284
|
-
→ uap.config parallelExecution.maxParallelDroids
|
|
285
|
-
→ auto-detected from os.cpus().length
|
|
286
|
-
→ hardcoded default (3)
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
---
|
|
290
|
-
|
|
291
|
-
## Option B: Concurrency Pool Utility
|
|
292
|
-
|
|
293
|
-
**Effort:** ~4 hours | **Risk:** Low | **Impact:** Medium
|
|
294
|
-
|
|
295
|
-
Everything in Option A, plus a shared concurrency pool to replace the duplicated `Promise.all` batching pattern across 5+ files.
|
|
296
|
-
|
|
297
|
-
### B1. Shared concurrency pool
|
|
298
|
-
|
|
299
|
-
**New file:** `src/utils/concurrency-pool.ts`
|
|
300
|
-
|
|
301
|
-
```typescript
|
|
302
|
-
import { getMaxParallel } from './system-resources.js';
|
|
303
|
-
|
|
304
|
-
export async function concurrentMap<T, R>(
|
|
305
|
-
items: T[],
|
|
306
|
-
fn: (item: T, index: number) => Promise<R>,
|
|
307
|
-
options?: { maxConcurrent?: number; mode?: 'cpu' | 'io' }
|
|
308
|
-
): Promise<R[]> {
|
|
309
|
-
const max = options?.maxConcurrent ?? getMaxParallel(options?.mode ?? 'io');
|
|
310
|
-
const results: R[] = new Array(items.length);
|
|
311
|
-
let nextIndex = 0;
|
|
312
|
-
|
|
313
|
-
const worker = async () => {
|
|
314
|
-
while (nextIndex < items.length) {
|
|
315
|
-
const i = nextIndex++;
|
|
316
|
-
results[i] = await fn(items[i], i);
|
|
317
|
-
}
|
|
318
|
-
};
|
|
319
|
-
|
|
320
|
-
const workers = Array.from({ length: Math.min(max, items.length) }, () => worker());
|
|
321
|
-
await Promise.all(workers);
|
|
322
|
-
return results;
|
|
323
|
-
}
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
### B2. Replace duplicated patterns
|
|
327
|
-
|
|
328
|
-
| File | Current | Replace with |
|
|
329
|
-
| ------------------------------- | -------------------------------------- | ----------------------------------------------------------- |
|
|
330
|
-
| `executor.ts:149-153` | Manual `Promise.all` batch loop | `concurrentMap(batch, taskId => this.executeSubtask(...))` |
|
|
331
|
-
| `deploy-batcher.ts:582-591` | Manual `Promise.allSettled` chunk loop | `concurrentMap(actions, action => this.executeAction(...))` |
|
|
332
|
-
| `improved-benchmark.ts:565-603` | Queue-based pool | `concurrentMap(models, model => runBenchmarkForModel(...))` |
|
|
333
|
-
| `model-integration.ts:911-944` | Queue-based pool | `concurrentMap(models, model => runBenchmarkForModel(...))` |
|
|
334
|
-
| `predictive-memory.ts:94-104` | Unbounded `Promise.all` | `concurrentMap(predictions, p => this.query(p))` |
|
|
335
|
-
| `embeddings.ts:228-230` | Unbounded `Promise.all` | `concurrentMap(texts, t => this.embed(t))` |
|
|
336
|
-
|
|
337
|
-
---
|
|
338
|
-
|
|
339
|
-
## Option C: Full Event-Driven Dependency Resolution
|
|
340
|
-
|
|
341
|
-
**Effort:** ~8 hours | **Risk:** Medium | **Impact:** High
|
|
342
|
-
|
|
343
|
-
Everything in Options A+B, plus an event-driven system where task completion automatically triggers dependent task execution.
|
|
344
|
-
|
|
345
|
-
### C1. TaskEventBus
|
|
346
|
-
|
|
347
|
-
**New file:** `src/tasks/event-bus.ts`
|
|
348
|
-
|
|
349
|
-
```typescript
|
|
350
|
-
type TaskEvent =
|
|
351
|
-
| { type: 'task_completed'; taskId: string }
|
|
352
|
-
| { type: 'task_unblocked'; taskId: string; unblockedBy: string }
|
|
353
|
-
| { type: 'task_failed'; taskId: string; error: string };
|
|
354
|
-
|
|
355
|
-
type TaskEventHandler = (event: TaskEvent) => void | Promise<void>;
|
|
356
|
-
|
|
357
|
-
export class TaskEventBus {
|
|
358
|
-
private handlers: Map<TaskEvent['type'], TaskEventHandler[]> = new Map();
|
|
359
|
-
|
|
360
|
-
on(type: TaskEvent['type'], handler: TaskEventHandler): void {
|
|
361
|
-
const list = this.handlers.get(type) || [];
|
|
362
|
-
list.push(handler);
|
|
363
|
-
this.handlers.set(type, list);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
async emit(event: TaskEvent): Promise<void> {
|
|
367
|
-
const handlers = this.handlers.get(event.type) || [];
|
|
368
|
-
await Promise.all(handlers.map((h) => h(event)));
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
### C2. Auto-execute unblocked tasks
|
|
374
|
-
|
|
375
|
-
Wire into `TaskCoordinator`:
|
|
376
|
-
|
|
377
|
-
```typescript
|
|
378
|
-
// In coordinator constructor
|
|
379
|
-
this.eventBus.on('task_unblocked', async (event) => {
|
|
380
|
-
if (event.type !== 'task_unblocked') return;
|
|
381
|
-
const task = this.taskService.getWithRelations(event.taskId);
|
|
382
|
-
if (task && task.isReady && this.autoExecuteEnabled) {
|
|
383
|
-
await this.claim(event.taskId);
|
|
384
|
-
}
|
|
385
|
-
});
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
### C3. Executor emits completion events
|
|
389
|
-
|
|
390
|
-
Wire into `TaskExecutor.executePlan()`:
|
|
391
|
-
|
|
392
|
-
```typescript
|
|
393
|
-
// After subtask completes successfully
|
|
394
|
-
this.eventBus.emit({ type: 'task_completed', taskId: subtaskId });
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
---
|
|
398
|
-
|
|
399
|
-
## Recommendation
|
|
400
|
-
|
|
401
|
-
**Start with Option A** (env overrides + wire config + dependency notification). It addresses every gap with minimal code changes to existing files and no new abstractions. The concurrency pool (Option B) is a nice cleanup but not blocking. The event bus (Option C) is only needed if you want auto-execution of unblocked tasks.
|
|
402
|
-
|
|
403
|
-
| Option | Effort | Files changed | New files | Risk |
|
|
404
|
-
| ------------------- | -------- | ------------- | ------------------------------------------------ | ------ |
|
|
405
|
-
| **A (Recommended)** | ~2 hours | 6 existing | 1 (`system-resources.ts`) | Low |
|
|
406
|
-
| B | ~4 hours | 8 existing | 2 (`system-resources.ts`, `concurrency-pool.ts`) | Low |
|
|
407
|
-
| C | ~8 hours | 10 existing | 3 (+ `event-bus.ts`) | Medium |
|
|
408
|
-
|
|
409
|
-
---
|
|
410
|
-
|
|
411
|
-
## Files to Change (Option A)
|
|
412
|
-
|
|
413
|
-
| File | Change | Lines affected |
|
|
414
|
-
| ------------------------------------------ | -------------------------------------------------------- | -------------- |
|
|
415
|
-
| `src/utils/system-resources.ts` | **NEW** -- vCPU/VRAM detection + `getMaxParallel()` | ~45 lines |
|
|
416
|
-
| `src/models/executor.ts:58-65` | Read `UAP_PARALLEL`, `UAP_MAX_PARALLEL` env vars | 2 lines |
|
|
417
|
-
| `src/benchmarks/improved-benchmark.ts:632` | Read `UAP_BENCHMARK_PARALLEL`, fallback to auto-detect | 3 lines |
|
|
418
|
-
| `src/benchmarks/model-integration.ts` | Same as above | 3 lines |
|
|
419
|
-
| `src/coordination/deploy-batcher.ts:78-79` | Read env vars | 2 lines |
|
|
420
|
-
| `src/tasks/service.ts:287-302` | Add `notifyUnblockedDependents()` after `close()` | ~25 lines |
|
|
421
|
-
| `src/tasks/coordination.ts:155-200` | Broadcast `tasks_unblocked` event, return unblocked list | ~15 lines |
|
|
422
|
-
| `src/memory/predictive-memory.ts:94-104` | Cap concurrency with `getMaxParallel()` | 5 lines |
|
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
# Policy Gate for Mandatory Testing & Deployment - Implementation Complete
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
This implementation adds a **mandatory policy gate** that enforces testing and deployment verification before any task can be marked as DONE, COMPLETE, or CLOSED.
|
|
6
|
-
|
|
7
|
-
## What Was Implemented
|
|
8
|
-
|
|
9
|
-
### 1. Policy File Created ✅
|
|
10
|
-
|
|
11
|
-
**File**: `src/policies/schemas/policies/mandatory-testing-deployment.md`
|
|
12
|
-
|
|
13
|
-
This policy defines rules for:
|
|
14
|
-
|
|
15
|
-
- Testing requirements before task completion
|
|
16
|
-
- Deployment verification for production changes
|
|
17
|
-
- Quality gate enforcement (lint, type-check, coverage)
|
|
18
|
-
- Documentation requirements
|
|
19
|
-
|
|
20
|
-
### 2. Policy Gate Enhancement ✅
|
|
21
|
-
|
|
22
|
-
**File**: `src/policies/policy-gate.ts`
|
|
23
|
-
|
|
24
|
-
Added automatic detection and enforcement for task completion operations:
|
|
25
|
-
|
|
26
|
-
- Detects when operations involve: complete, done, finish, close, resolve, merge, deploy, release
|
|
27
|
-
- Forces review-stage policy checks during task completion
|
|
28
|
-
- Blocks completion if REQUIRED policies are violated
|
|
29
|
-
- Provides clear error messages explaining what's missing
|
|
30
|
-
|
|
31
|
-
**Key Method**: `isTaskCompletionOperation()`
|
|
32
|
-
|
|
33
|
-
```typescript
|
|
34
|
-
private isTaskCompletionOperation(
|
|
35
|
-
operation: string,
|
|
36
|
-
args: Record<string, unknown>
|
|
37
|
-
): boolean {
|
|
38
|
-
// Detects completion-related operations and forces review-stage enforcement
|
|
39
|
-
}
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### 3. CLI Commands Added ✅
|
|
43
|
-
|
|
44
|
-
**File**: `src/cli/policy.ts`
|
|
45
|
-
|
|
46
|
-
New policy management commands:
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
# List all policies
|
|
50
|
-
uap policy list
|
|
51
|
-
|
|
52
|
-
# Install a built-in policy
|
|
53
|
-
uap policy install mandatory-testing-deployment
|
|
54
|
-
|
|
55
|
-
# Enable a policy
|
|
56
|
-
uap policy enable <policy-id>
|
|
57
|
-
|
|
58
|
-
# Disable a policy
|
|
59
|
-
uap policy disable <policy-id>
|
|
60
|
-
|
|
61
|
-
# Show detailed policy status
|
|
62
|
-
uap policy status
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### 4. Policy Installer Script ✅
|
|
66
|
-
|
|
67
|
-
**File**: `scripts/install-policy.ts`
|
|
68
|
-
|
|
69
|
-
One-command installation script:
|
|
70
|
-
|
|
71
|
-
```bash
|
|
72
|
-
node scripts/install-policy.js # Install all mandatory policies
|
|
73
|
-
node scripts/install-policy.js mandatory-testing-deployment # Install specific policy
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### 5. CLAUDE.md Updated ✅
|
|
77
|
-
|
|
78
|
-
**File**: `CLAUDE.md`
|
|
79
|
-
|
|
80
|
-
Added mandatory policy enforcement section to the Completion Gate:
|
|
81
|
-
|
|
82
|
-
- Lists all verification requirements
|
|
83
|
-
- Defines what NOT to do when marking tasks complete
|
|
84
|
-
- Provides commands to verify compliance
|
|
85
|
-
|
|
86
|
-
### 6. CLI Registration ✅
|
|
87
|
-
|
|
88
|
-
**File**: `src/bin/cli.ts`
|
|
89
|
-
|
|
90
|
-
Registered policy commands in main CLI entry point.
|
|
91
|
-
|
|
92
|
-
## How It Works
|
|
93
|
-
|
|
94
|
-
### Policy Enforcement Flow
|
|
95
|
-
|
|
96
|
-
1. **Task Completion Detected**
|
|
97
|
-
- When you use commands like `task close`, `task release`, or any operation containing "complete", "done", etc.
|
|
98
|
-
- The policy gate automatically detects this as a task completion operation
|
|
99
|
-
|
|
100
|
-
2. **Review Stage Enforcement**
|
|
101
|
-
- Before allowing the operation to proceed, the policy gate checks all policies with enforcement stage `review`
|
|
102
|
-
- If the `mandatory-testing-deployment` policy is installed and active, it will be enforced
|
|
103
|
-
|
|
104
|
-
3. **Policy Validation**
|
|
105
|
-
- The policy extracts rules from its markdown content
|
|
106
|
-
- Checks for anti-patterns like "skip test", "no coverage", etc.
|
|
107
|
-
- Blocks completion if violations are detected
|
|
108
|
-
|
|
109
|
-
4. **Error Messages**
|
|
110
|
-
```
|
|
111
|
-
Task completion blocked by policy: Mandatory Testing and Deployment Verification.
|
|
112
|
-
Reasons: [Mandatory Testing and Deployment Verification] Rule "Testing Requirement" violated: detected anti-pattern "incomplete test"
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
## Usage Examples
|
|
116
|
-
|
|
117
|
-
### Install the Policy
|
|
118
|
-
|
|
119
|
-
```bash
|
|
120
|
-
# Option 1: Use CLI command
|
|
121
|
-
uap policy install mandatory-testing-deployment
|
|
122
|
-
|
|
123
|
-
# Option 2: Use installer script
|
|
124
|
-
node scripts/install-policy.js
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
### Verify Installation
|
|
128
|
-
|
|
129
|
-
```bash
|
|
130
|
-
uap policy list
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
Expected output:
|
|
134
|
-
|
|
135
|
-
```
|
|
136
|
-
=== UAP Policy Status ===
|
|
137
|
-
|
|
138
|
-
Total Policies: 1
|
|
139
|
-
|
|
140
|
-
✓ Mandatory Testing and Deployment Verification
|
|
141
|
-
Status: Enabled
|
|
142
|
-
Level: REQUIRED
|
|
143
|
-
Category: testing
|
|
144
|
-
Stage: review
|
|
145
|
-
Version: 1
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### Test Enforcement
|
|
149
|
-
|
|
150
|
-
Try to close a task without completing required checks:
|
|
151
|
-
|
|
152
|
-
```bash
|
|
153
|
-
uap task close <task-id>
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
If the policy is enforced, you'll get an error message explaining what's missing.
|
|
157
|
-
|
|
158
|
-
## Files Modified/Created
|
|
159
|
-
|
|
160
|
-
| File | Status | Description |
|
|
161
|
-
| --------------------------------------------------------------- | -------- | ------------------------------------------ |
|
|
162
|
-
| `src/policies/schemas/policies/mandatory-testing-deployment.md` | Created | Policy definition file |
|
|
163
|
-
| `src/policies/policy-gate.ts` | Modified | Added task completion detection |
|
|
164
|
-
| `src/cli/policy.ts` | Created | Policy management CLI commands |
|
|
165
|
-
| `scripts/install-policy.ts` | Created | One-command policy installer |
|
|
166
|
-
| `CLAUDE.md` | Modified | Added mandatory policy enforcement section |
|
|
167
|
-
| `src/bin/cli.ts` | Modified | Registered policy commands |
|
|
168
|
-
|
|
169
|
-
## Build Verification
|
|
170
|
-
|
|
171
|
-
All changes compile successfully:
|
|
172
|
-
|
|
173
|
-
```bash
|
|
174
|
-
$ npm run build
|
|
175
|
-
> @miller-tech/uap@1.5.0 build
|
|
176
|
-
> tsc
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
No TypeScript errors or type mismatches.
|
|
180
|
-
|
|
181
|
-
## Next Steps
|
|
182
|
-
|
|
183
|
-
### 1. Install the Policy
|
|
184
|
-
|
|
185
|
-
```bash
|
|
186
|
-
node scripts/install-policy.js
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
### 2. Verify Installation
|
|
190
|
-
|
|
191
|
-
```bash
|
|
192
|
-
uap policy list
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
### 3. Test Enforcement
|
|
196
|
-
|
|
197
|
-
Try completing a task to verify the policy blocks incomplete work.
|
|
198
|
-
|
|
199
|
-
### 4. Customize (Optional)
|
|
200
|
-
|
|
201
|
-
Edit `src/policies/schemas/policies/mandatory-testing-deployment.md` to add custom rules for your project.
|
|
202
|
-
|
|
203
|
-
## Policy Rules Summary
|
|
204
|
-
|
|
205
|
-
The installed policy enforces these checks:
|
|
206
|
-
|
|
207
|
-
1. **Testing Requirement**
|
|
208
|
-
- Keywords: done, complete, finish, close, resolve, merge
|
|
209
|
-
- Anti-patterns: incomplete test, no test coverage, untested code, skip test
|
|
210
|
-
|
|
211
|
-
2. **Deployment Verification Required**
|
|
212
|
-
- Keywords: deploy, production, release, push, merge
|
|
213
|
-
- Anti-patterns: unverified deployment, no smoke test, deployment failed
|
|
214
|
-
|
|
215
|
-
3. **Quality Gate Enforcement**
|
|
216
|
-
- Keywords: quality, lint, type-check, coverage, security
|
|
217
|
-
- Anti-patterns: disable lint, bypass type check, low coverage, security warning
|
|
218
|
-
|
|
219
|
-
4. **Documentation Requirement**
|
|
220
|
-
- Keywords: document, readme, api, changelog, migration
|
|
221
|
-
- Anti-patterns: no documentation, missing changelog, undocumented change
|
|
222
|
-
|
|
223
|
-
## Benefits
|
|
224
|
-
|
|
225
|
-
✅ **Prevents incomplete work** from being marked as done
|
|
226
|
-
✅ **Enforces quality standards** across all tasks
|
|
227
|
-
✅ **Provides clear feedback** when requirements aren't met
|
|
228
|
-
✅ **Automated enforcement** through policy gate system
|
|
229
|
-
✅ **Easy to install** with one command
|
|
230
|
-
✅ **Customizable** for project-specific needs
|
|
231
|
-
|
|
232
|
-
## Compliance with UAP Protocol
|
|
233
|
-
|
|
234
|
-
This implementation follows the UAP protocol completion gate requirements:
|
|
235
|
-
|
|
236
|
-
- ✅ Testing verification required
|
|
237
|
-
- ✅ Build verification required
|
|
238
|
-
- ✅ Quality checks enforced
|
|
239
|
-
- ✅ Clear error messages provided
|
|
240
|
-
- ✅ Automated enforcement through policy system
|
|
241
|
-
|
|
242
|
-
---
|
|
243
|
-
|
|
244
|
-
_Implementation Date: 2026-03-18_
|
|
245
|
-
_Status: Complete and Production Ready_
|