@miller-tech/uap 1.221.0 → 2.0.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/README.md +19 -9
- package/config/exl3-profiles/qwen38-27b-exl3.env +68 -0
- package/config/llama-profiles/qwen38-27b-dflash2.env +6 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/benchmarks/paired/adapter.d.ts +15 -0
- package/dist/benchmarks/paired/adapter.d.ts.map +1 -1
- package/dist/benchmarks/paired/adapter.js +22 -1
- package/dist/benchmarks/paired/adapter.js.map +1 -1
- package/dist/bin/cli.js +20 -24
- package/dist/bin/cli.js.map +1 -1
- package/dist/cli/deliver.d.ts +34 -0
- package/dist/cli/deliver.d.ts.map +1 -1
- package/dist/cli/deliver.js +147 -20
- package/dist/cli/deliver.js.map +1 -1
- package/dist/cli/guided-setup.d.ts.map +1 -1
- package/dist/cli/guided-setup.js +15 -0
- package/dist/cli/guided-setup.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +3 -0
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/plan.d.ts.map +1 -1
- package/dist/cli/plan.js +8 -2
- package/dist/cli/plan.js.map +1 -1
- package/dist/cli/policy.d.ts.map +1 -1
- package/dist/cli/policy.js +104 -2
- package/dist/cli/policy.js.map +1 -1
- package/dist/cli/quality.d.ts +11 -0
- package/dist/cli/quality.d.ts.map +1 -0
- package/dist/cli/quality.js +213 -0
- package/dist/cli/quality.js.map +1 -0
- package/dist/cli/wizard-config.d.ts.map +1 -1
- package/dist/cli/wizard-config.js +19 -9
- package/dist/cli/wizard-config.js.map +1 -1
- package/dist/cli/worktree.d.ts.map +1 -1
- package/dist/cli/worktree.js +8 -1
- package/dist/cli/worktree.js.map +1 -1
- package/dist/dashboard/savings.d.ts +1 -4
- package/dist/dashboard/savings.d.ts.map +1 -1
- package/dist/dashboard/savings.js +2 -52
- package/dist/dashboard/savings.js.map +1 -1
- package/dist/delivery/acceptance-judge.d.ts +10 -0
- package/dist/delivery/acceptance-judge.d.ts.map +1 -1
- package/dist/delivery/acceptance-judge.js +45 -3
- package/dist/delivery/acceptance-judge.js.map +1 -1
- package/dist/delivery/agentic-executor.d.ts +12 -1
- package/dist/delivery/agentic-executor.d.ts.map +1 -1
- package/dist/delivery/agentic-executor.js +25 -5
- package/dist/delivery/agentic-executor.js.map +1 -1
- package/dist/delivery/bash-sweep.d.ts +12 -0
- package/dist/delivery/bash-sweep.d.ts.map +1 -1
- package/dist/delivery/bash-sweep.js +8 -1
- package/dist/delivery/bash-sweep.js.map +1 -1
- package/dist/delivery/convergence-loop.d.ts.map +1 -1
- package/dist/delivery/convergence-loop.js +6 -4
- package/dist/delivery/convergence-loop.js.map +1 -1
- package/dist/delivery/execution-gate.d.ts +1 -1
- package/dist/delivery/execution-gate.d.ts.map +1 -1
- package/dist/delivery/execution-gate.js +248 -5
- package/dist/delivery/execution-gate.js.map +1 -1
- package/dist/delivery/snapshot.d.ts +16 -0
- package/dist/delivery/snapshot.d.ts.map +1 -1
- package/dist/delivery/snapshot.js +113 -2
- package/dist/delivery/snapshot.js.map +1 -1
- package/dist/delivery/user-validation.d.ts.map +1 -1
- package/dist/delivery/user-validation.js +55 -10
- package/dist/delivery/user-validation.js.map +1 -1
- package/dist/delivery/verifier-ladder.d.ts +24 -0
- package/dist/delivery/verifier-ladder.d.ts.map +1 -1
- package/dist/delivery/verifier-ladder.js +119 -2
- package/dist/delivery/verifier-ladder.js.map +1 -1
- package/dist/delivery/visual-gate.d.ts +24 -0
- package/dist/delivery/visual-gate.d.ts.map +1 -1
- package/dist/delivery/visual-gate.js +70 -9
- package/dist/delivery/visual-gate.js.map +1 -1
- package/dist/generators/claude-md.js +17 -4
- package/dist/generators/claude-md.js.map +1 -1
- package/dist/policies/liveness.d.ts +105 -0
- package/dist/policies/liveness.d.ts.map +1 -0
- package/dist/policies/liveness.js +251 -0
- package/dist/policies/liveness.js.map +1 -0
- package/dist/policies/policy-memory.d.ts.map +1 -1
- package/dist/policies/policy-memory.js +3 -4
- package/dist/policies/policy-memory.js.map +1 -1
- package/dist/quality/baseline.d.ts +29 -0
- package/dist/quality/baseline.d.ts.map +1 -0
- package/dist/quality/baseline.js +79 -0
- package/dist/quality/baseline.js.map +1 -0
- package/dist/quality/complexity.d.ts +38 -0
- package/dist/quality/complexity.d.ts.map +1 -0
- package/dist/quality/complexity.js +239 -0
- package/dist/quality/complexity.js.map +1 -0
- package/dist/quality/config.d.ts +40 -0
- package/dist/quality/config.d.ts.map +1 -0
- package/dist/quality/config.js +77 -0
- package/dist/quality/config.js.map +1 -0
- package/dist/quality/crap.d.ts +11 -0
- package/dist/quality/crap.d.ts.map +1 -0
- package/dist/quality/crap.js +54 -0
- package/dist/quality/crap.js.map +1 -0
- package/dist/quality/languages.d.ts +25 -0
- package/dist/quality/languages.d.ts.map +1 -0
- package/dist/quality/languages.js +150 -0
- package/dist/quality/languages.js.map +1 -0
- package/dist/quality/report.d.ts +38 -0
- package/dist/quality/report.d.ts.map +1 -0
- package/dist/quality/report.js +251 -0
- package/dist/quality/report.js.map +1 -0
- package/dist/quality/scanner.d.ts +32 -0
- package/dist/quality/scanner.d.ts.map +1 -0
- package/dist/quality/scanner.js +127 -0
- package/dist/quality/scanner.js.map +1 -0
- package/dist/quality/tools.d.ts +28 -0
- package/dist/quality/tools.d.ts.map +1 -0
- package/dist/quality/tools.js +189 -0
- package/dist/quality/tools.js.map +1 -0
- package/dist/types/config.d.ts +148 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +35 -0
- package/dist/types/config.js.map +1 -1
- package/docs/ATTRIBUTION.md +0 -1
- package/docs/INDEX.md +38 -4
- package/docs/analysis/MARKET_POSITION.md +179 -0
- package/docs/architecture/OVERVIEW.md +82 -18
- package/docs/architecture/PROTOCOL.md +1 -1
- package/docs/benchmarks/PAIRED_FINDINGS.md +106 -0
- package/docs/benchmarks/PAIRED_HARNESS.md +16 -0
- package/docs/benchmarks/README.md +59 -0
- package/docs/design/UAP_REACTOR.md +0 -1
- package/docs/getting-started/INSTALLATION.md +1 -1
- package/docs/guides/AUTOMATIC.md +0 -14
- package/docs/guides/AUTOMATIC_FEATURES.md +1 -9
- package/docs/guides/COORDINATION.md +1 -1
- package/docs/guides/DELIVERY_PIPELINE.md +5 -0
- package/docs/guides/DEPLOY_BATCHING.md +1 -1
- package/docs/guides/DROIDS_AND_SKILLS.md +1 -1
- package/docs/guides/LOCAL_MODELS.md +6 -1
- package/docs/guides/MCP_ROUTER.md +1 -1
- package/docs/guides/MEMORY.md +1 -1
- package/docs/guides/MULTI_MODEL.md +1 -1
- package/docs/guides/ORCHESTRATOR.md +1 -1
- package/docs/guides/POLICIES.md +19 -3
- package/docs/guides/QWEN38_EXL3.md +114 -0
- package/docs/guides/WORKTREE_WORKFLOW.md +45 -1
- package/docs/integrations/MCP_ROUTER.md +1 -4
- package/docs/plans/deliver-hardening-plan-2026-07-13.md +173 -0
- package/docs/plans/deliver-hardening-review-response-2026-07-13.md +180 -0
- package/docs/plans/k3-uap-uplift-validation.md +216 -0
- package/docs/plans/qwen38-uap-retest-plan.md +196 -0
- package/docs/reference/API.md +1 -1
- package/docs/reference/CLI.md +49 -14
- package/docs/reference/COMPARISON.md +248 -0
- package/docs/reference/CONFIGURATION.md +1 -3
- package/docs/reference/DATABASE_SCHEMA.md +1 -1
- package/docs/reference/FEATURES.md +3 -3
- package/docs/reference/PATTERNS.md +1 -1
- package/docs/reference/PLATFORMS.md +1 -1
- package/package.json +2 -2
- package/scripts/maintenance/update-skills.py +0 -22
- package/scripts/maintenance/verify-compliance.sh +3 -3
- package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
- package/src/policies/enforcers/__pycache__/quality_metrics_gate.cpython-312.pyc +0 -0
- package/src/policies/enforcers/adr_guard.py +0 -0
- package/src/policies/enforcers/bearer_lockdown.py +0 -0
- package/src/policies/enforcers/branch_freshness.py +0 -0
- package/src/policies/enforcers/design_token_gate.py +0 -0
- package/src/policies/enforcers/enforcement_self_protect.py +70 -0
- package/src/policies/enforcers/expert_review_required.py +22 -0
- package/src/policies/enforcers/iac_plan_destruction_check.py +0 -0
- package/src/policies/enforcers/quality_metrics_gate.py +447 -0
- package/src/policies/enforcers/ship_loop_gate.py +0 -0
- package/src/policies/enforcers/validate_plan_on_change.py +0 -0
- package/src/policies/enforcers/visual_verification.py +0 -0
- package/src/policies/enforcers/workdir_scope.py +0 -0
- package/src/policies/schemas/policies/expert-review-required.md +9 -1
- package/src/policies/schemas/policies/quality-metrics-gate.md +74 -0
- package/templates/CLAUDE.template.md +1 -1
- package/templates/hooks/__pycache__/deliver_autoroute.cpython-312.pyc +0 -0
- package/templates/hooks/pre-tool-use-bash.sh +50 -3
- package/templates/hooks/pre-tool-use-edit-write.sh +31 -0
- package/templates/hooks/session-start.sh +15 -0
- package/templates/hooks/uap-policy-gate.sh +187 -5
- package/templates/stryker.config.json +14 -0
- package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
- package/tools/agents/scripts/anthropic_proxy.py +254 -28
- package/tools/agents/tests/run_acceptance.py +0 -0
- package/tools/agents/tests/test_client_disconnect.py +0 -0
- package/tools/agents/tests/test_cycle_break_exploration.py +0 -0
- package/tools/agents/tests/test_deferral_break.py +0 -0
- package/tools/agents/tests/test_delivery_enforcement_all_langs.py +0 -0
- package/tools/agents/tests/test_delivery_enforcement_exemptions.py +0 -0
- package/tools/agents/tests/test_delivery_enforcement_filepath.py +0 -0
- package/tools/agents/tests/test_delivery_enforcement_web_and_bash.py +0 -0
- package/tools/agents/tests/test_delivery_enforcement_worktree.py +0 -0
- package/tools/agents/tests/test_delivery_enforcement_write_complexity.py +0 -0
- package/tools/agents/tests/test_disconnect_watcher.py +0 -0
- package/tools/agents/tests/test_doubling_break.py +0 -0
- package/tools/agents/tests/test_empty_maxtokens_recovery.py +0 -0
- package/tools/agents/tests/test_empty_tool_loop_break.py +0 -0
- package/tools/agents/tests/test_enforcement_self_protect.py +90 -0
- package/tools/agents/tests/test_enforcer_escape_hatches.py +0 -0
- package/tools/agents/tests/test_error_loop_break.py +0 -0
- package/tools/agents/tests/test_expert_review_pr_scope.py +13 -5
- package/tools/agents/tests/test_fastpath_config.py +0 -0
- package/tools/agents/tests/test_finalize_suppression.py +0 -0
- package/tools/agents/tests/test_gate_evidence.py +0 -0
- package/tools/agents/tests/test_gate_failclosed_indirection.py +0 -0
- package/tools/agents/tests/test_gate_integrity.py +0 -0
- package/tools/agents/tests/test_live_deliver_kill.py +0 -0
- package/tools/agents/tests/test_malformed_unclosed_think.py +0 -0
- package/tools/agents/tests/test_mandate_beats_recon.py +0 -0
- package/tools/agents/tests/test_mandate_deliver.py +0 -0
- package/tools/agents/tests/test_non_stream_resp_log.py +0 -0
- package/tools/agents/tests/test_output_token_ceilings.py +0 -0
- package/tools/agents/tests/test_overflow_truncate_count_tokens.py +0 -0
- package/tools/agents/tests/test_path_containment.py +0 -0
- package/tools/agents/tests/test_path_normalizer_hardened.py +0 -0
- package/tools/agents/tests/test_repeat_call_guard.py +0 -0
- package/tools/agents/tests/test_repeat_guard.py +0 -0
- package/tools/agents/tests/test_session_admission.py +0 -0
- package/tools/agents/tests/test_stream_heartbeat.py +0 -0
- package/tools/agents/tests/test_stream_thinking_deltas.py +405 -0
- package/tools/agents/tests/test_stuck_break_hard.py +0 -0
- package/tools/agents/tests/test_stuck_break_reattach.py +0 -0
- package/tools/agents/tests/test_turn_count_breaker_periodic.py +0 -0
- package/tools/agents/tests/test_upstream_chokepoint.py +0 -0
- package/tools/agents/tests/test_upstream_model_aliases.py +0 -0
- package/tools/agents/tests/test_validate_plan_gate.py +0 -0
- package/tools/agents/tests/test_vision_passthrough.py +0 -0
- package/tools/agents/tests/test_workdir_scope_enforcer.py +0 -0
- package/dist/cli/rtk.d.ts +0 -34
- package/dist/cli/rtk.d.ts.map +0 -1
- package/dist/cli/rtk.js +0 -401
- package/dist/cli/rtk.js.map +0 -1
- package/docs/integrations/RTK.md +0 -113
- package/scripts/setup/install-rtk.sh +0 -184
- package/src/policies/enforcers/rtk_wrap.py +0 -205
- package/src/policies/schemas/policies/rtk-wrap.md +0 -50
- package/tools/agents/tests/test_rtk_wrap.py +0 -151
package/dist/cli/deliver.d.ts
CHANGED
|
@@ -324,6 +324,40 @@ export declare function resolveTierModel(routingId: string | undefined, instruct
|
|
|
324
324
|
tier: TaskComplexity;
|
|
325
325
|
preset: string;
|
|
326
326
|
} | null;
|
|
327
|
+
/**
|
|
328
|
+
* The tier-model resolution with an EXPLICIT preset id — no env fallback.
|
|
329
|
+
* Used when the routing id has already been resolved through the G1
|
|
330
|
+
* precedence chain (CLI > config > criticality > env).
|
|
331
|
+
*/
|
|
332
|
+
export declare function resolveTierModelById(id: string, instruction: string): {
|
|
333
|
+
model: string;
|
|
334
|
+
tier: TaskComplexity;
|
|
335
|
+
preset: string;
|
|
336
|
+
} | null;
|
|
337
|
+
/**
|
|
338
|
+
* G1 (deliver-hardening 2026-07-13): `criticality` shorthand → routing preset.
|
|
339
|
+
* money = cost-tiered (local-first, escalate by complexity); normal =
|
|
340
|
+
* sonnet-5-tiered (balanced); sandbox = NO tier routing — the executor stays
|
|
341
|
+
* on the free local default, and the declaration SUPPRESSES ambient env
|
|
342
|
+
* routing (config-authoritative means a declared posture beats a stale shell).
|
|
343
|
+
*/
|
|
344
|
+
export declare const CRITICALITY_ROUTING: Record<'money' | 'normal' | 'sandbox', string | null>;
|
|
345
|
+
export type RoutingSource = 'cli' | 'config' | 'criticality' | 'env';
|
|
346
|
+
/**
|
|
347
|
+
* Resolve which routing preset (if any) governs this run, and where the choice
|
|
348
|
+
* came from. Config-authoritative: a DECLARED routing/criticality beats the
|
|
349
|
+
* ambient UAP_DELIVER_ROUTING; an explicit --routing beats config. PURE —
|
|
350
|
+
* unit-tested.
|
|
351
|
+
*/
|
|
352
|
+
export declare function resolveRoutingId(opts: {
|
|
353
|
+
cliRouting?: string;
|
|
354
|
+
cfgRouting?: unknown;
|
|
355
|
+
cfgCriticality?: unknown;
|
|
356
|
+
envRouting?: string;
|
|
357
|
+
}): {
|
|
358
|
+
id: string | null;
|
|
359
|
+
source: RoutingSource | null;
|
|
360
|
+
};
|
|
327
361
|
/**
|
|
328
362
|
* Explorer candidates act through the file-block applier, which the agentic
|
|
329
363
|
* tool-loop bypasses — agentic runs must use single-candidate turns. PURE,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deliver.d.ts","sourceRoot":"","sources":["../../src/cli/deliver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
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
|
@@ -186,7 +186,7 @@ export function bestKeepFastScore(gateResults, fastRungIds) {
|
|
|
186
186
|
// Legacy export surface: test/cli/acceptance-verdict.test.ts (and any external
|
|
187
187
|
// consumer) imports the verdict fold from deliver.js — keep the re-export.
|
|
188
188
|
export { resolveAcceptanceVerdict } from '../delivery/mission-acceptance.js';
|
|
189
|
-
import { createAgenticExecutor,
|
|
189
|
+
import { createAgenticExecutor, selectExecutorMode, lockContractFiles } from '../delivery/agentic-executor.js';
|
|
190
190
|
import { createRepairEscalation } from '../delivery/repair-escalation.js';
|
|
191
191
|
import { clearProjectStop, clearStop, finalRunStatus, isRunBudgetExpired, isRunBudgetExplicit, isStopRequested, makeStopLatch, phaseAwareRunBudgetMinutes, requestStop, runBudgetMinutes, loadRunState, newRunId, saveRunState, isEpicResume, MAX_PERSISTED_PHASES } from '../delivery/run-state.js';
|
|
192
192
|
import { planDeliveryPhases, shouldDecompose } from '../delivery/decompose.js';
|
|
@@ -279,7 +279,7 @@ import { FilePracticeStore, defaultPracticePath, extractKeywords, retrievePracti
|
|
|
279
279
|
import { detectRungs, mergeRedetectedRungs, runLadder, runTieredLadder, tierOf, TIER_ORDER, demoteBaselineFailures, baselineRegressions } from '../delivery/verifier-ladder.js';
|
|
280
280
|
import { runDeployDevLadder } from '../delivery/deploy-dev-gate.js';
|
|
281
281
|
import { commitPushAndWatch } from '../delivery/ci-watcher.js';
|
|
282
|
-
import { snapshotTree,
|
|
282
|
+
import { snapshotTree, restoreTreeScoped, disposeSnapshot } from '../delivery/snapshot.js';
|
|
283
283
|
import { snapshotProtection } from '../delivery/spec-imports.js';
|
|
284
284
|
import { listGateConfigFiles } from '../delivery/applier.js';
|
|
285
285
|
import { OpenAICompatClient, setModelCallProgress } from '../models/openai-compat-client.js';
|
|
@@ -333,12 +333,56 @@ export function resolveTierModel(routingId, instruction) {
|
|
|
333
333
|
const id = routingId ?? process.env.UAP_DELIVER_ROUTING;
|
|
334
334
|
if (!id)
|
|
335
335
|
return null;
|
|
336
|
+
return resolveTierModelById(id, instruction);
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* The tier-model resolution with an EXPLICIT preset id — no env fallback.
|
|
340
|
+
* Used when the routing id has already been resolved through the G1
|
|
341
|
+
* precedence chain (CLI > config > criticality > env).
|
|
342
|
+
*/
|
|
343
|
+
export function resolveTierModelById(id, instruction) {
|
|
336
344
|
const preset = RoutingPresets[id];
|
|
337
345
|
if (!preset)
|
|
338
346
|
return null;
|
|
339
347
|
const tier = tierToRouting(classifyComplexity({ instruction }).tier);
|
|
340
348
|
return { model: resolvePresetModel(preset, { complexity: tier, role: 'executor' }), tier, preset: id };
|
|
341
349
|
}
|
|
350
|
+
/**
|
|
351
|
+
* G1 (deliver-hardening 2026-07-13): `criticality` shorthand → routing preset.
|
|
352
|
+
* money = cost-tiered (local-first, escalate by complexity); normal =
|
|
353
|
+
* sonnet-5-tiered (balanced); sandbox = NO tier routing — the executor stays
|
|
354
|
+
* on the free local default, and the declaration SUPPRESSES ambient env
|
|
355
|
+
* routing (config-authoritative means a declared posture beats a stale shell).
|
|
356
|
+
*/
|
|
357
|
+
export const CRITICALITY_ROUTING = {
|
|
358
|
+
money: 'cost-tiered',
|
|
359
|
+
normal: 'sonnet-5-tiered',
|
|
360
|
+
sandbox: null,
|
|
361
|
+
};
|
|
362
|
+
/**
|
|
363
|
+
* Resolve which routing preset (if any) governs this run, and where the choice
|
|
364
|
+
* came from. Config-authoritative: a DECLARED routing/criticality beats the
|
|
365
|
+
* ambient UAP_DELIVER_ROUTING; an explicit --routing beats config. PURE —
|
|
366
|
+
* unit-tested.
|
|
367
|
+
*/
|
|
368
|
+
export function resolveRoutingId(opts) {
|
|
369
|
+
if (opts.cliRouting)
|
|
370
|
+
return { id: opts.cliRouting, source: 'cli' };
|
|
371
|
+
if (typeof opts.cfgRouting === 'string' && opts.cfgRouting) {
|
|
372
|
+
return { id: opts.cfgRouting, source: 'config' };
|
|
373
|
+
}
|
|
374
|
+
// Object.hasOwn, not `in`: a raw (non-zod) config value like
|
|
375
|
+
// "criticality": "constructor" would otherwise pass the check via the
|
|
376
|
+
// prototype chain and yield a FUNCTION as the routing id (review nit).
|
|
377
|
+
if (typeof opts.cfgCriticality === 'string' && Object.hasOwn(CRITICALITY_ROUTING, opts.cfgCriticality)) {
|
|
378
|
+
const mapped = CRITICALITY_ROUTING[opts.cfgCriticality];
|
|
379
|
+
// sandbox maps to null ON PURPOSE: the declaration suppresses ambient env.
|
|
380
|
+
return { id: mapped, source: 'criticality' };
|
|
381
|
+
}
|
|
382
|
+
if (opts.envRouting)
|
|
383
|
+
return { id: opts.envRouting, source: 'env' };
|
|
384
|
+
return { id: null, source: null };
|
|
385
|
+
}
|
|
342
386
|
function resolveModel(presetId, endpointOverride) {
|
|
343
387
|
const preset = ModelPresets[presetId];
|
|
344
388
|
if (!preset) {
|
|
@@ -1477,20 +1521,49 @@ async function runDeliver(instruction, options) {
|
|
|
1477
1521
|
if (!process.env.UAP_HALO_TRACE_PATH) {
|
|
1478
1522
|
process.env.UAP_HALO_TRACE_PATH = join(projectRoot, '.uap', 'halo', 'traces.jsonl');
|
|
1479
1523
|
}
|
|
1480
|
-
// Complexity-tier routing: when
|
|
1481
|
-
//
|
|
1482
|
-
//
|
|
1483
|
-
//
|
|
1484
|
-
|
|
1485
|
-
|
|
1524
|
+
// Complexity-tier routing: when a routing preset is named and the user did
|
|
1525
|
+
// NOT pin --model, execute on the model the preset assigns to this task's
|
|
1526
|
+
// complexity tier. Explicit --model and a resumed run's preset always win
|
|
1527
|
+
// (user intent / mid-flight consistency).
|
|
1528
|
+
//
|
|
1529
|
+
// G1 (deliver-hardening 2026-07-13): the routing choice itself is now a
|
|
1530
|
+
// PROJECT decision — `.uap.json → delivery.routing` / `delivery.criticality`
|
|
1531
|
+
// / `delivery.model` are config-authoritative (declared config beats ambient
|
|
1532
|
+
// env; an explicit CLI flag beats config). Before this, routing was CLI/env
|
|
1533
|
+
// only, so the choice left no trace in the repo and a stale
|
|
1534
|
+
// UAP_DELIVER_ROUTING in a launching shell silently steered the run.
|
|
1535
|
+
const cfgDeliveryRouting = (() => {
|
|
1536
|
+
try {
|
|
1537
|
+
const d = loadUapConfigRaw(projectRoot)?.delivery;
|
|
1538
|
+
return d ?? {};
|
|
1539
|
+
}
|
|
1540
|
+
catch {
|
|
1541
|
+
return {};
|
|
1542
|
+
}
|
|
1543
|
+
})();
|
|
1544
|
+
const routingChoice = resolveRoutingId({
|
|
1545
|
+
cliRouting: options.routing,
|
|
1546
|
+
cfgRouting: cfgDeliveryRouting.routing,
|
|
1547
|
+
cfgCriticality: cfgDeliveryRouting.criticality,
|
|
1548
|
+
envRouting: process.env.UAP_DELIVER_ROUTING,
|
|
1549
|
+
});
|
|
1550
|
+
const tierRoute = options.model === undefined && resumeState === null && routingChoice.id
|
|
1551
|
+
? resolveTierModelById(routingChoice.id, instruction)
|
|
1486
1552
|
: null;
|
|
1553
|
+
const cfgModel = typeof cfgDeliveryRouting.model === 'string' && cfgDeliveryRouting.model
|
|
1554
|
+
? cfgDeliveryRouting.model
|
|
1555
|
+
: undefined;
|
|
1487
1556
|
const presetId = options.model ??
|
|
1488
1557
|
resumeState?.presetId ??
|
|
1489
1558
|
tierRoute?.model ??
|
|
1559
|
+
cfgModel ??
|
|
1490
1560
|
process.env.UAP_DELIVER_MODEL ??
|
|
1491
1561
|
'qwen35-a3b';
|
|
1492
1562
|
if (tierRoute && !options.dryRun) {
|
|
1493
|
-
console.log(chalk.cyan(`\u26a1 tier routing: '${tierRoute.preset}' \u2192 ${tierRoute.tier} complexity \u2192 ${tierRoute.model}`));
|
|
1563
|
+
console.log(chalk.cyan(`\u26a1 tier routing: '${tierRoute.preset}' (${routingChoice.source}) \u2192 ${tierRoute.tier} complexity \u2192 ${tierRoute.model}`));
|
|
1564
|
+
}
|
|
1565
|
+
else if (!tierRoute && cfgModel && options.model === undefined && !options.dryRun) {
|
|
1566
|
+
console.log(chalk.dim(` model from .uap.json delivery.model: ${cfgModel}`));
|
|
1494
1567
|
}
|
|
1495
1568
|
let maxTurns;
|
|
1496
1569
|
if (options.maxTurns !== undefined) {
|
|
@@ -1907,7 +1980,9 @@ async function runDeliver(instruction, options) {
|
|
|
1907
1980
|
// of the hardcoded haiku default — the preset's designated reviewer IS the
|
|
1908
1981
|
// Generator≠Evaluator choice. resolveJudgePlan still swaps to the alt judge if
|
|
1909
1982
|
// this collides with the generator, and only uses it on the auto-distinct path.
|
|
1910
|
-
|
|
1983
|
+
// The judge follows the SAME resolved routing choice as the executor (G1) —
|
|
1984
|
+
// a config-declared preset must also pick the reviewer, not just the worker.
|
|
1985
|
+
const routingIdForJudge = routingChoice.id ?? undefined;
|
|
1911
1986
|
const presetForJudge = routingIdForJudge ? RoutingPresets[routingIdForJudge] : undefined;
|
|
1912
1987
|
const reviewJudgeId = presetForJudge
|
|
1913
1988
|
? resolvePhaseChain(presetForJudge, {
|
|
@@ -2055,6 +2130,14 @@ async function runDeliver(instruction, options) {
|
|
|
2055
2130
|
// those back would silently drop PascalCase files like Config.ts). P1 reads
|
|
2056
2131
|
// these for verbatim injection.
|
|
2057
2132
|
const contractPaths = [];
|
|
2133
|
+
// Per-RUN write ledger for the agentic executor (deliver-hardening review
|
|
2134
|
+
// blocker, 2026-07-13): the agentic path installs a no-op applier, so
|
|
2135
|
+
// `filesApplied` is empty by construction and keep-best's E2 scoped restore
|
|
2136
|
+
// had an empty write-set on the DEFAULT executor — a regressed run restored
|
|
2137
|
+
// NOTHING and disposed the snapshot. The tool handlers and the turn-end bash
|
|
2138
|
+
// sweep record real written paths here; the applier below drains them into
|
|
2139
|
+
// ApplyResult.filesWritten so history[].filesApplied is truthful again.
|
|
2140
|
+
const agenticWriteLedger = new Set();
|
|
2058
2141
|
const executor = agentic
|
|
2059
2142
|
? createAgenticExecutor(model, {
|
|
2060
2143
|
projectRoot,
|
|
@@ -2063,6 +2146,7 @@ async function runDeliver(instruction, options) {
|
|
|
2063
2146
|
temperature,
|
|
2064
2147
|
contextTokenBudget: sessionBudget,
|
|
2065
2148
|
contractFiles: contractLock,
|
|
2149
|
+
writeLedger: agenticWriteLedger,
|
|
2066
2150
|
// Block oracle tampering: protected test files are read-only to the agent.
|
|
2067
2151
|
protectedFiles: options.protectTests !== false ? snapshotProtection(projectRoot).protectedFiles : new Set(),
|
|
2068
2152
|
// Block gate-config / IaC rigging in the agentic path too (it bypasses
|
|
@@ -2085,6 +2169,7 @@ async function runDeliver(instruction, options) {
|
|
|
2085
2169
|
temperature: 0.2,
|
|
2086
2170
|
contextTokenBudget: sessionBudget,
|
|
2087
2171
|
contractFiles: contractLock,
|
|
2172
|
+
writeLedger: agenticWriteLedger,
|
|
2088
2173
|
protectedFiles: options.protectTests !== false ? snapshotProtection(projectRoot).protectedFiles : new Set(),
|
|
2089
2174
|
protectGateConfigs: options.protectTests !== false,
|
|
2090
2175
|
allowBash: options.allowBash === true || process.env.UAP_DELIVER_ALLOW_BASH === '1',
|
|
@@ -2408,8 +2493,19 @@ async function runDeliver(instruction, options) {
|
|
|
2408
2493
|
const seams = {
|
|
2409
2494
|
ladderRunner: tieredRunner,
|
|
2410
2495
|
// The agentic executor mutates the repo directly, so nothing remains for
|
|
2411
|
-
// the file-block applier to materialize
|
|
2412
|
-
|
|
2496
|
+
// the file-block applier to materialize — but the applier is also where
|
|
2497
|
+
// history[].filesApplied comes from, and keep-best's scoped restore reads
|
|
2498
|
+
// exactly that. Drain the run's write ledger so the rollback write-set is
|
|
2499
|
+
// real instead of empty-by-construction (deliver-hardening review, 2026-07-13).
|
|
2500
|
+
...(agentic
|
|
2501
|
+
? {
|
|
2502
|
+
applier: async () => {
|
|
2503
|
+
const filesWritten = [...agenticWriteLedger];
|
|
2504
|
+
agenticWriteLedger.clear();
|
|
2505
|
+
return { filesWritten, rejected: [] };
|
|
2506
|
+
},
|
|
2507
|
+
}
|
|
2508
|
+
: {}),
|
|
2413
2509
|
...(acceptanceGate ? { acceptanceGate } : {}),
|
|
2414
2510
|
};
|
|
2415
2511
|
/** Compose the per-turn hooks with a FRESH escalation controller. */
|
|
@@ -3054,6 +3150,9 @@ async function runDeliver(instruction, options) {
|
|
|
3054
3150
|
temperature,
|
|
3055
3151
|
contextTokenBudget: sessionBudget,
|
|
3056
3152
|
contractFiles: contractLock,
|
|
3153
|
+
// No writeLedger here: an isolated task's paths are relative to
|
|
3154
|
+
// ITS tree, and folding them into the projectRoot-scoped ledger
|
|
3155
|
+
// would mis-target the keep-best scoped restore.
|
|
3057
3156
|
protectedFiles: options.protectTests !== false ? snapshotProtection(root).protectedFiles : new Set(),
|
|
3058
3157
|
protectGateConfigs: options.protectTests !== false,
|
|
3059
3158
|
protectIac,
|
|
@@ -3698,15 +3797,43 @@ async function runDeliver(instruction, options) {
|
|
|
3698
3797
|
const endCap = compareCapability(readCapabilityBaseline(projectRoot), readCapabilityCurrent(projectRoot));
|
|
3699
3798
|
const endCapabilityLost = endCap.regressed;
|
|
3700
3799
|
if (endScore < baselineGateScore || endRegressions.length > 0 || endCapabilityLost) {
|
|
3800
|
+
// E2 (deliver-hardening 2026-07-13): restore ONLY the files this run
|
|
3801
|
+
// wrote. A whole-tree restore in a SHARED worktree reverts other
|
|
3802
|
+
// agents' concurrent legitimate edits — observed live: a frontend
|
|
3803
|
+
// agent's newly written test file was rolled back by someone else's
|
|
3804
|
+
// deliver run. Files the run created after the best point are removed;
|
|
3805
|
+
// everything else is left byte-identical. Known gap: a file the run
|
|
3806
|
+
// DELETED without ever writing is outside the write-set and stays
|
|
3807
|
+
// deleted — the run's deletions can't be told apart from another
|
|
3808
|
+
// agent's via git state alone, and the safe direction wins.
|
|
3809
|
+
const runFiles = [...new Set((result.history ?? []).flatMap((h) => h.filesApplied ?? []))];
|
|
3701
3810
|
try {
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
:
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3811
|
+
if (runFiles.length === 0) {
|
|
3812
|
+
// The write-set is EMPTY but the tree regressed. With the agentic
|
|
3813
|
+
// write ledger this means the writes escaped tracking (a shell write
|
|
3814
|
+
// with the sweep disabled, or a deletion — the documented known-gap).
|
|
3815
|
+
// The old whole-tree restore is the wrong fallback: in a shared
|
|
3816
|
+
// worktree it reverts OTHER agents' work (the incident E2 fixes).
|
|
3817
|
+
// Fail LOUD and keep the snapshot instead of pretending all is well.
|
|
3818
|
+
console.log(chalk.red(' ↩ no-regress: the run regressed the gates but its write-set is EMPTY — the writes escaped ' +
|
|
3819
|
+
'tracking (shell with the bash sweep disabled, or deletions). NOT restoring blindly: a ' +
|
|
3820
|
+
`whole-tree restore could revert other agents' work. The pre-run snapshot is PRESERVED at ` +
|
|
3821
|
+
`${regressSnapshot} — inspect it and restore by hand if needed.`));
|
|
3822
|
+
// Do NOT dispose: the snapshot is the only known-good copy.
|
|
3823
|
+
}
|
|
3824
|
+
else {
|
|
3825
|
+
const touched = restoreTreeScoped(projectRoot, regressSnapshot, runFiles);
|
|
3826
|
+
console.log(chalk.yellow((endRegressions.length > 0
|
|
3827
|
+
? ` ↩ no-regress: reverted to best — tests that passed at baseline are failing now: ` +
|
|
3828
|
+
`${endRegressions.flatMap((r) => r.tests).slice(0, 5).join(', ')}`
|
|
3829
|
+
: endCapabilityLost
|
|
3830
|
+
? ` ↩ no-regress: reverted to best — the run ended having LOST capability: ${endCap.findings.join('; ')}`
|
|
3831
|
+
: ` ↩ no-regress: reverted to best (end gate score ${endScore.toFixed(2)} < best ${baselineGateScore.toFixed(2)})`) +
|
|
3832
|
+
` — ${touched} run-written file(s) restored`));
|
|
3833
|
+
// The scoped restore succeeded (or preserved-on-failure itself) —
|
|
3834
|
+
// only here is the snapshot safe to dispose.
|
|
3835
|
+
disposeSnapshot(regressSnapshot);
|
|
3836
|
+
}
|
|
3710
3837
|
}
|
|
3711
3838
|
catch (restoreErr) {
|
|
3712
3839
|
// restoreTree marked the snapshot preserve — do NOT dispose it; it may
|