@miller-tech/uap 1.154.0 → 1.155.0
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 +61 -80
- package/dist/cli/deliver.js.map +1 -1
- package/dist/delivery/agentic-executor.d.ts.map +1 -1
- package/dist/delivery/agentic-executor.js +7 -4
- package/dist/delivery/agentic-executor.js.map +1 -1
- package/dist/delivery/context-budget.d.ts +32 -3
- package/dist/delivery/context-budget.d.ts.map +1 -1
- package/dist/delivery/context-budget.js +33 -3
- package/dist/delivery/context-budget.js.map +1 -1
- package/dist/delivery/convergence-loop.js +2 -2
- package/dist/delivery/convergence-loop.js.map +1 -1
- package/dist/delivery/epic-controller.d.ts +18 -0
- package/dist/delivery/epic-controller.d.ts.map +1 -1
- package/dist/delivery/epic-controller.js +24 -1
- package/dist/delivery/epic-controller.js.map +1 -1
- package/dist/delivery/epic-mission.d.ts +31 -0
- package/dist/delivery/epic-mission.d.ts.map +1 -1
- package/dist/delivery/epic-mission.js +21 -2
- package/dist/delivery/epic-mission.js.map +1 -1
- package/dist/delivery/index.d.ts +2 -0
- package/dist/delivery/index.d.ts.map +1 -1
- package/dist/delivery/index.js +2 -0
- package/dist/delivery/index.js.map +1 -1
- package/dist/delivery/run-state.d.ts +9 -4
- package/dist/delivery/run-state.d.ts.map +1 -1
- package/dist/delivery/run-state.js +9 -0
- package/dist/delivery/run-state.js.map +1 -1
- package/dist/delivery/spec-registry.d.ts +72 -0
- package/dist/delivery/spec-registry.d.ts.map +1 -0
- package/dist/delivery/spec-registry.js +80 -0
- package/dist/delivery/spec-registry.js.map +1 -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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deliver.d.ts","sourceRoot":"","sources":["../../src/cli/deliver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAqBH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIzD,OAAO,
|
|
1
|
+
{"version":3,"file":"deliver.d.ts","sourceRoot":"","sources":["../../src/cli/deliver.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/deliver.js
CHANGED
|
@@ -20,7 +20,8 @@ import { RoutingPresets, resolvePresetModel } from '../models/types.js';
|
|
|
20
20
|
import { measureQueryComplexity } from '../utils/query-complexity.js';
|
|
21
21
|
import { authorAcceptanceGate } from '../delivery/self-gate.js';
|
|
22
22
|
import { applyPendingIntents } from '../delivery/pending-intents.js';
|
|
23
|
-
import { runAcceptanceGate, formatAcceptanceReport
|
|
23
|
+
import { runAcceptanceGate, formatAcceptanceReport } from '../delivery/acceptance-judge.js';
|
|
24
|
+
import { createSpecRegistry } from '../delivery/spec-registry.js';
|
|
24
25
|
import { runExecutionGate } from '../delivery/execution-gate.js';
|
|
25
26
|
import { runVisualGate, visualRuntimeNote } from '../delivery/visual-gate.js';
|
|
26
27
|
/**
|
|
@@ -1247,46 +1248,13 @@ async function runDeliver(instruction, options) {
|
|
|
1247
1248
|
}
|
|
1248
1249
|
// Phased missions re-point the judge at the current phase's goal — judging
|
|
1249
1250
|
// phase 1 against the FULL mission would fail every phase by construction.
|
|
1250
|
-
|
|
1251
|
-
//
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
// objectively-green turns per spec (env UAP_DELIVER_ACCEPTANCE_FLIP_LIMIT,
|
|
1258
|
-
// default 2), after which the objective gates win. Primary mode is exempt.
|
|
1259
|
-
// Change-evidence for the breaker's zero-diff guard: files applied since the
|
|
1260
|
-
// current acceptance spec (epic) began. Incremented by the iteration hook,
|
|
1261
|
-
// reset wherever acceptanceSpec is re-pointed.
|
|
1262
|
-
// Per-ROOT under parallel dispatch: concurrent loops must not zero or
|
|
1263
|
-
// inflate each other's evidence (an inflated count could let the breaker
|
|
1264
|
-
// accept a task with zero writes of its own). projectRoot's entry is the
|
|
1265
|
-
// historic shared counter the phased/epic paths keep using.
|
|
1266
|
-
const writesByRoot = new Map();
|
|
1267
|
-
const evidenceFor = (root) => {
|
|
1268
|
-
let e = writesByRoot.get(root);
|
|
1269
|
-
if (!e) {
|
|
1270
|
-
e = { writes: 0 };
|
|
1271
|
-
writesByRoot.set(root, e);
|
|
1272
|
-
}
|
|
1273
|
-
return e;
|
|
1274
|
-
};
|
|
1275
|
-
const specChangeEvidence = evidenceFor(projectRoot);
|
|
1276
|
-
// Breaker state is per SPEC: one shared instance thrashes its current-spec
|
|
1277
|
-
// slot under parallel dispatch and can then never trip.
|
|
1278
|
-
const acceptanceFlipLimit = Number(process.env.UAP_DELIVER_ACCEPTANCE_FLIP_LIMIT ?? 2);
|
|
1279
|
-
const acceptanceBreakers = new Map();
|
|
1280
|
-
const breakerFor = (spec, root) => {
|
|
1281
|
-
let b = acceptanceBreakers.get(spec);
|
|
1282
|
-
if (!b) {
|
|
1283
|
-
if (acceptanceBreakers.size > 100)
|
|
1284
|
-
acceptanceBreakers.clear(); // runaway guard
|
|
1285
|
-
b = createAcceptanceChurnBreaker(acceptanceFlipLimit, () => evidenceFor(root).writes > 0);
|
|
1286
|
-
acceptanceBreakers.set(spec, b);
|
|
1287
|
-
}
|
|
1288
|
-
return b;
|
|
1289
|
-
};
|
|
1251
|
+
// Per-root specs, write evidence, and churn breakers live in the registry
|
|
1252
|
+
// (see src/delivery/spec-registry.ts for the parallel-dispatch semantics).
|
|
1253
|
+
const specs = createSpecRegistry({
|
|
1254
|
+
initialSpec: instruction,
|
|
1255
|
+
sharedRoot: projectRoot,
|
|
1256
|
+
flipLimit: Number(process.env.UAP_DELIVER_ACCEPTANCE_FLIP_LIMIT ?? 2),
|
|
1257
|
+
});
|
|
1290
1258
|
const acceptanceGate = options.acceptance && !skipJudgeForSimple
|
|
1291
1259
|
? async (root) => {
|
|
1292
1260
|
// Primary mode: the only objective rung is the trivial bootstrap, and the
|
|
@@ -1318,7 +1286,7 @@ async function runDeliver(instruction, options) {
|
|
|
1318
1286
|
// gates all passed — hand the judge that fact as evidence, so
|
|
1319
1287
|
// requirements like "make the tests pass" are graded on the gate
|
|
1320
1288
|
// result instead of speculated about from static code.
|
|
1321
|
-
const resolvedSpec =
|
|
1289
|
+
const resolvedSpec = specs.resolve(root);
|
|
1322
1290
|
const uvNote = buildUserPathsNote(root);
|
|
1323
1291
|
const baseNote = acceptancePrimary
|
|
1324
1292
|
? visualNote
|
|
@@ -1335,7 +1303,7 @@ async function runDeliver(instruction, options) {
|
|
|
1335
1303
|
// objective gates ALL passed, so a bounded number of consecutive judge
|
|
1336
1304
|
// rejections hands the verdict back to the gates instead of wedging.
|
|
1337
1305
|
if (!acceptancePrimary) {
|
|
1338
|
-
const checked =
|
|
1306
|
+
const checked = specs.breaker(resolvedSpec, root).check(resolvedSpec, verdict);
|
|
1339
1307
|
if (checked.overridden) {
|
|
1340
1308
|
console.log(chalk.yellow(' ⚖ acceptance: judge rejected consecutive objectively-green turns — accepting on gates (raise UAP_DELIVER_ACCEPTANCE_FLIP_LIMIT to let the judge argue longer)'));
|
|
1341
1309
|
}
|
|
@@ -1368,8 +1336,7 @@ async function runDeliver(instruction, options) {
|
|
|
1368
1336
|
: undefined;
|
|
1369
1337
|
return composeIterationHooks((record) => printProgress(record), (record) => {
|
|
1370
1338
|
// Feed the acceptance breaker's zero-diff guard.
|
|
1371
|
-
|
|
1372
|
-
evidenceFor(evidenceRoot).writes += record.filesApplied.length;
|
|
1339
|
+
specs.recordWrites(evidenceRoot, record.filesApplied.length);
|
|
1373
1340
|
return undefined;
|
|
1374
1341
|
}, (record) => haloTracer.onIteration(record), repair ? (record) => repair.onIteration(record) : undefined, coordinator ? (record) => coordinator.onIteration(record) : undefined, escalation ? (record) => escalation.onIteration(record) : undefined);
|
|
1375
1342
|
};
|
|
@@ -1474,9 +1441,13 @@ async function runDeliver(instruction, options) {
|
|
|
1474
1441
|
// single-session context thrash — and a trivial mission simply decomposes to
|
|
1475
1442
|
// one epic, so the wrapper is cheap. Disable per-run with --no-epics /
|
|
1476
1443
|
// UAP_DELIVER_EPICS=0 / `.uap.json` deliver.epics false|'off'. Never on
|
|
1477
|
-
// self-gate
|
|
1444
|
+
// self-gate. A resume re-enters the epic path ONLY when the interrupted
|
|
1445
|
+
// run was epic-kind: completed epics carry forward as prior summaries and
|
|
1446
|
+
// the mid-epic loop checkpoint is discarded (epics restart at the epic
|
|
1447
|
+
// boundary). Non-epic resumes stay on the cursor-honoring paths below.
|
|
1478
1448
|
const cfgEpics = cfgRaw.deliver?.epics;
|
|
1479
|
-
const epicsEnabled = !needsSelfGate &&
|
|
1449
|
+
const epicsEnabled = !needsSelfGate &&
|
|
1450
|
+
(!resumeState || resumeState.runnerKind === 'epic') &&
|
|
1480
1451
|
options.epics !== false &&
|
|
1481
1452
|
process.env.UAP_DELIVER_EPICS !== '0' &&
|
|
1482
1453
|
cfgEpics !== false && cfgEpics !== 'off';
|
|
@@ -1573,7 +1544,10 @@ async function runDeliver(instruction, options) {
|
|
|
1573
1544
|
// a silent de-escalation. Falls back to the normal executor when no
|
|
1574
1545
|
// stronger model is configured in this environment.
|
|
1575
1546
|
let runExecutor = executor;
|
|
1576
|
-
|
|
1547
|
+
// Epic-kind resumes never use runExecutor (fresh epic loops re-escalate on
|
|
1548
|
+
// their own) and discard the checkpoint at the dispatch — a re-bind message
|
|
1549
|
+
// here would falsely claim the escalation carried over.
|
|
1550
|
+
if (resumeCheckpoint?.modelEscalated && !epicsEnabled) {
|
|
1577
1551
|
if (escalateExecutor && !agentic) {
|
|
1578
1552
|
// Agentic runs keep their tool-loop executor: the blind escalation
|
|
1579
1553
|
// executor pairs with the noop applier and would never touch the repo.
|
|
@@ -1640,20 +1614,10 @@ async function runDeliver(instruction, options) {
|
|
|
1640
1614
|
: line.includes('parallel tasks:') || line.includes('post-merge verification')
|
|
1641
1615
|
? chalk.cyan(line)
|
|
1642
1616
|
: chalk.dim(line)),
|
|
1643
|
-
beginTaskSpec: (root, spec) =>
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
evidenceFor(root).writes = 0;
|
|
1648
|
-
},
|
|
1649
|
-
endTaskSpec: (root) => {
|
|
1650
|
-
acceptanceSpecByRoot.delete(root);
|
|
1651
|
-
// An in-tree task re-pointed the shared spec; restore the mission-
|
|
1652
|
-
// level spec so a later watch-ci re-converge never judges against a
|
|
1653
|
-
// stale task prompt.
|
|
1654
|
-
if (root === projectRoot)
|
|
1655
|
-
acceptanceSpec = missionText;
|
|
1656
|
-
},
|
|
1617
|
+
beginTaskSpec: (root, spec) => specs.begin(root, spec),
|
|
1618
|
+
// Restore the mission-level spec after an in-tree task so a later
|
|
1619
|
+
// watch-ci re-converge never judges against a stale task prompt.
|
|
1620
|
+
endTaskSpec: (root) => specs.end(root, missionText),
|
|
1657
1621
|
openTask: (title) => openDeliveryTask(title, projectRoot, parentTaskId),
|
|
1658
1622
|
completeTask: (record, r) => completeDeliveryTask(record, r),
|
|
1659
1623
|
// P3 — per-task memory retrieval: pull the few most relevant established
|
|
@@ -1764,10 +1728,7 @@ async function runDeliver(instruction, options) {
|
|
|
1764
1728
|
resumeCheckpoint = undefined; // consumed by this loop
|
|
1765
1729
|
return loop.deliver(prompt);
|
|
1766
1730
|
},
|
|
1767
|
-
setPhaseSpec: (spec) =>
|
|
1768
|
-
acceptanceSpec = spec;
|
|
1769
|
-
specChangeEvidence.writes = 0;
|
|
1770
|
-
},
|
|
1731
|
+
setPhaseSpec: (spec) => specs.setShared(spec),
|
|
1771
1732
|
openTask: (title) => openDeliveryTask(title, projectRoot, missionTask?.id),
|
|
1772
1733
|
completeTask: (record, r) => completeDeliveryTask(record, r),
|
|
1773
1734
|
persistCursor: (index) => {
|
|
@@ -1821,15 +1782,32 @@ async function runDeliver(instruction, options) {
|
|
|
1821
1782
|
thoughtExperiment: false,
|
|
1822
1783
|
}),
|
|
1823
1784
|
epicParallelTasks,
|
|
1785
|
+
// Deterministic epic-boundary resume: reuse the PERSISTED plan and
|
|
1786
|
+
// accepted-epic set — replanning on resume would mint new epic ids
|
|
1787
|
+
// (resetting the completion ledger's done marks) and draw new
|
|
1788
|
+
// boundaries over already-built work, which the anti-no-op rail then
|
|
1789
|
+
// refuses to accept (a wedge).
|
|
1790
|
+
initialEpics: resumeState?.runnerKind === 'epic' ? resumeState.phases : undefined,
|
|
1791
|
+
initialDone: resumeState?.runnerKind === 'epic' ? (resumeState.completedEpicIds ?? []) : [],
|
|
1792
|
+
initialPriorSummaries: resumeState?.runnerKind === 'epic' ? (resumeState.phaseSummaries ?? []) : [],
|
|
1793
|
+
persistPlan: (plan) => {
|
|
1794
|
+
runState.phases = plan;
|
|
1795
|
+
saveRunState(runState);
|
|
1796
|
+
},
|
|
1797
|
+
persistCompleted: ({ summaries, completed }) => {
|
|
1798
|
+
runState.phaseSummaries = [...summaries];
|
|
1799
|
+
runState.completedEpicIds = [...completed];
|
|
1800
|
+
// The checkpoint belongs to the finished epic (phased-path parity) —
|
|
1801
|
+
// never seed a later loop with a completed epic's session state.
|
|
1802
|
+
runState.checkpoint = undefined;
|
|
1803
|
+
saveRunState(runState);
|
|
1804
|
+
},
|
|
1824
1805
|
runOrchestrated: (missionText, plan, parentTaskId) => runOrchestratedMissionCore(buildOrchestratedDeps(missionText, plan, epicParallelTasks, parentTaskId)),
|
|
1825
1806
|
runEpicLoop: async (scoped) => {
|
|
1826
1807
|
const loop = new ConvergenceLoop({ ...loopConfig, baselineCheck: false, resumeFrom: undefined, onIteration: makeIterationHook() }, executor, seams);
|
|
1827
1808
|
return loop.deliver(scoped);
|
|
1828
1809
|
},
|
|
1829
|
-
setEpicSpec: (spec) =>
|
|
1830
|
-
acceptanceSpec = spec;
|
|
1831
|
-
specChangeEvidence.writes = 0; // fresh epic — breaker needs fresh diff evidence
|
|
1832
|
-
},
|
|
1810
|
+
setEpicSpec: (spec) => specs.setShared(spec), // fresh epic — breaker needs fresh diff evidence
|
|
1833
1811
|
judgeEpic: options.acceptance && !skipJudgeForSimple
|
|
1834
1812
|
? async (spec) => {
|
|
1835
1813
|
try {
|
|
@@ -1937,15 +1915,15 @@ async function runDeliver(instruction, options) {
|
|
|
1937
1915
|
console.log(chalk.dim(' lazy attempt did not pass — engaging the full convergence stack'));
|
|
1938
1916
|
}
|
|
1939
1917
|
}
|
|
1940
|
-
// Resume
|
|
1941
|
-
//
|
|
1942
|
-
//
|
|
1943
|
-
//
|
|
1944
|
-
//
|
|
1945
|
-
//
|
|
1946
|
-
//
|
|
1918
|
+
// Resume routing: an epic-kind resume re-enters the epic path (fidelity —
|
|
1919
|
+
// completed epics carry forward as prior summaries). Everything else takes
|
|
1920
|
+
// a cursor-honoring sequential path — phased when a phase plan was
|
|
1921
|
+
// persisted, otherwise the single flat loop. When that CHANGES the
|
|
1922
|
+
// execution model (e.g. an epic run resumed under --no-epics), warn
|
|
1923
|
+
// loudly, never silently: different prompts, no contract publication,
|
|
1924
|
+
// DAG flattened to linear order.
|
|
1947
1925
|
if (resumeState?.runnerKind) {
|
|
1948
|
-
const resumeTarget = phases && phases.length >= 2 ? 'phased' : 'single';
|
|
1926
|
+
const resumeTarget = epicsEnabled ? 'epic' : phases && phases.length >= 2 ? 'phased' : 'single';
|
|
1949
1927
|
if (resumeState.runnerKind !== resumeTarget) {
|
|
1950
1928
|
const targetDesc = resumeTarget === 'phased'
|
|
1951
1929
|
? 'sequential phased path (the only cursor-honoring runner)'
|
|
@@ -1959,6 +1937,10 @@ async function runDeliver(instruction, options) {
|
|
|
1959
1937
|
result = result;
|
|
1960
1938
|
}
|
|
1961
1939
|
else if (epicsEnabled) {
|
|
1940
|
+
if (resumeState && resumeCheckpoint) {
|
|
1941
|
+
console.log(chalk.dim(' resume: mid-epic loop checkpoint discarded — epic missions resume at the epic boundary (completed epics carry forward as summaries).'));
|
|
1942
|
+
resumeCheckpoint = undefined;
|
|
1943
|
+
}
|
|
1962
1944
|
runState.runnerKind = 'epic';
|
|
1963
1945
|
saveRunState(runState);
|
|
1964
1946
|
result = await runEpicMission();
|
|
@@ -1991,8 +1973,7 @@ async function runDeliver(instruction, options) {
|
|
|
1991
1973
|
// Re-point the judge at the MISSION: epic/phased runners leave
|
|
1992
1974
|
// acceptanceSpec on the LAST epic/phase spec, and a re-converge pass
|
|
1993
1975
|
// would otherwise be judged against that stale slice.
|
|
1994
|
-
|
|
1995
|
-
specChangeEvidence.writes = 0; // evidence resets wherever the spec re-points
|
|
1976
|
+
specs.setShared(instruction); // evidence resets wherever the spec re-points
|
|
1996
1977
|
const branch = currentBranch(projectRoot) ?? undefined;
|
|
1997
1978
|
result = await runCiReconverge({
|
|
1998
1979
|
instruction,
|