@miller-tech/uap 1.163.13 → 1.164.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.
Files changed (108) hide show
  1. package/README.md +1 -1
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/bin/cli.js +5 -4
  4. package/dist/bin/cli.js.map +1 -1
  5. package/dist/cli/deliver.d.ts +5 -3
  6. package/dist/cli/deliver.d.ts.map +1 -1
  7. package/dist/cli/deliver.js +95 -19
  8. package/dist/cli/deliver.js.map +1 -1
  9. package/dist/cli/guided-setup.d.ts.map +1 -1
  10. package/dist/cli/guided-setup.js +13 -1
  11. package/dist/cli/guided-setup.js.map +1 -1
  12. package/dist/cli/model.d.ts.map +1 -1
  13. package/dist/cli/model.js +9 -1
  14. package/dist/cli/model.js.map +1 -1
  15. package/dist/cli/proxy-lifecycle.d.ts +66 -13
  16. package/dist/cli/proxy-lifecycle.d.ts.map +1 -1
  17. package/dist/cli/proxy-lifecycle.js +116 -49
  18. package/dist/cli/proxy-lifecycle.js.map +1 -1
  19. package/dist/cli/proxy.d.ts +46 -0
  20. package/dist/cli/proxy.d.ts.map +1 -1
  21. package/dist/cli/proxy.js +353 -23
  22. package/dist/cli/proxy.js.map +1 -1
  23. package/dist/cli/wizard-config.d.ts +4 -0
  24. package/dist/cli/wizard-config.d.ts.map +1 -1
  25. package/dist/cli/wizard-config.js +14 -3
  26. package/dist/cli/wizard-config.js.map +1 -1
  27. package/dist/config/settings-registry.d.ts.map +1 -1
  28. package/dist/config/settings-registry.js +25 -0
  29. package/dist/config/settings-registry.js.map +1 -1
  30. package/dist/coordination/effort-profile.d.ts +39 -0
  31. package/dist/coordination/effort-profile.d.ts.map +1 -0
  32. package/dist/coordination/effort-profile.js +74 -0
  33. package/dist/coordination/effort-profile.js.map +1 -0
  34. package/dist/dashboard/server.d.ts.map +1 -1
  35. package/dist/dashboard/server.js +68 -10
  36. package/dist/dashboard/server.js.map +1 -1
  37. package/dist/delivery/convergence-loop.d.ts +37 -0
  38. package/dist/delivery/convergence-loop.d.ts.map +1 -1
  39. package/dist/delivery/convergence-loop.js +51 -4
  40. package/dist/delivery/convergence-loop.js.map +1 -1
  41. package/dist/delivery/critic.d.ts +7 -0
  42. package/dist/delivery/critic.d.ts.map +1 -1
  43. package/dist/delivery/critic.js.map +1 -1
  44. package/dist/delivery/decompose.d.ts +9 -0
  45. package/dist/delivery/decompose.d.ts.map +1 -1
  46. package/dist/delivery/decompose.js +11 -0
  47. package/dist/delivery/decompose.js.map +1 -1
  48. package/dist/delivery/graph-safety.d.ts +75 -0
  49. package/dist/delivery/graph-safety.d.ts.map +1 -0
  50. package/dist/delivery/graph-safety.js +98 -0
  51. package/dist/delivery/graph-safety.js.map +1 -0
  52. package/dist/delivery/per-phase-escalation-controller.d.ts +37 -0
  53. package/dist/delivery/per-phase-escalation-controller.d.ts.map +1 -0
  54. package/dist/delivery/per-phase-escalation-controller.js +68 -0
  55. package/dist/delivery/per-phase-escalation-controller.js.map +1 -0
  56. package/dist/delivery/per-phase-escalation.d.ts +53 -0
  57. package/dist/delivery/per-phase-escalation.d.ts.map +1 -0
  58. package/dist/delivery/per-phase-escalation.js +57 -0
  59. package/dist/delivery/per-phase-escalation.js.map +1 -0
  60. package/dist/delivery/reflect.d.ts +56 -0
  61. package/dist/delivery/reflect.d.ts.map +1 -0
  62. package/dist/delivery/reflect.js +79 -0
  63. package/dist/delivery/reflect.js.map +1 -0
  64. package/dist/delivery/verification-provenance.d.ts +47 -0
  65. package/dist/delivery/verification-provenance.d.ts.map +1 -0
  66. package/dist/delivery/verification-provenance.js +48 -0
  67. package/dist/delivery/verification-provenance.js.map +1 -0
  68. package/dist/models/complexity.d.ts +36 -0
  69. package/dist/models/complexity.d.ts.map +1 -0
  70. package/dist/models/complexity.js +75 -0
  71. package/dist/models/complexity.js.map +1 -0
  72. package/dist/models/router.d.ts.map +1 -1
  73. package/dist/models/router.js +39 -10
  74. package/dist/models/router.js.map +1 -1
  75. package/dist/models/types.d.ts +60 -10
  76. package/dist/models/types.d.ts.map +1 -1
  77. package/dist/models/types.js +128 -11
  78. package/dist/models/types.js.map +1 -1
  79. package/dist/self-tuning/prompt-variants.d.ts +93 -0
  80. package/dist/self-tuning/prompt-variants.d.ts.map +1 -0
  81. package/dist/self-tuning/prompt-variants.js +143 -0
  82. package/dist/self-tuning/prompt-variants.js.map +1 -0
  83. package/dist/tasks/types.d.ts +2 -2
  84. package/dist/types/config.d.ts +8 -0
  85. package/dist/types/config.d.ts.map +1 -1
  86. package/docs/INDEX.md +1 -1
  87. package/docs/benchmarks/COMPREHENSIVE_BENCHMARKS.md +47 -53
  88. package/docs/benchmarks/VALIDATION_RESULTS.md +0 -2
  89. package/docs/guides/COORDINATION.md +1 -1
  90. package/docs/guides/DEPLOY_BATCHING.md +1 -1
  91. package/docs/guides/DROIDS_AND_SKILLS.md +1 -1
  92. package/docs/guides/LOCAL_MODELS.md +1 -1
  93. package/docs/guides/MCP_ROUTER.md +1 -1
  94. package/docs/guides/MEMORY.md +2 -2
  95. package/docs/guides/MULTI_MODEL.md +1 -1
  96. package/docs/guides/POLICIES.md +1 -1
  97. package/docs/guides/PROXY.md +47 -4
  98. package/docs/guides/SANDBOX.md +1 -1
  99. package/docs/guides/WORKTREE_WORKFLOW.md +1 -1
  100. package/docs/reference/CLI.md +16 -3
  101. package/docs/reference/CONFIGURATION.md +1 -1
  102. package/docs/reference/FEATURES.md +1 -1
  103. package/package.json +1 -1
  104. package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
  105. package/templates/hooks/__pycache__/deliver_autoroute.cpython-312.pyc +0 -0
  106. package/templates/hooks/session-end.sh +9 -0
  107. package/templates/hooks/session-start.sh +10 -0
  108. package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Graph-engineering safety (S7).
3
+ *
4
+ * Pure implementations of the three failure modes from the graph-engineering
5
+ * playbook, so a fan-out/fan-in decomposition is safe at scale:
6
+ *
7
+ * 1. FALSE INDEPENDENCE — two nodes with no data dependency but a shared write
8
+ * target (same file) have a hidden edge; they must serialize. `syntheticEdges`
9
+ * derives those edges from predicted writes (fed by the coordination DB).
10
+ * 2. SILENT NODE FAILURE — one failed node among many vanishes into a report
11
+ * that looks complete. `reconcileFanIn` checks completed-vs-expected and
12
+ * surfaces the gap instead of synthesizing partial output.
13
+ * 3. CONTEXT COLLAPSE — feeding N raw outputs into one consolidation blows the
14
+ * context window. `layerFanIn` batches into groups for layered summary.
15
+ */
16
+ /**
17
+ * Derive serialization edges between nodes that write the SAME file, even with
18
+ * zero data dependency (false independence). Deterministic: for each shared
19
+ * write target, chains the nodes in input order (earlier → later). Pure.
20
+ */
21
+ export function syntheticEdges(nodes) {
22
+ const byResource = new Map();
23
+ for (const n of nodes) {
24
+ for (const w of n.writes ?? []) {
25
+ const list = byResource.get(w) ?? [];
26
+ if (!list.includes(n.id))
27
+ list.push(n.id);
28
+ byResource.set(w, list);
29
+ }
30
+ }
31
+ const edges = [];
32
+ for (const [resource, ids] of byResource) {
33
+ for (let i = 1; i < ids.length; i++) {
34
+ edges.push({ from: ids[i - 1], to: ids[i], resource });
35
+ }
36
+ }
37
+ return edges;
38
+ }
39
+ /**
40
+ * Silent-node-failure guard: compare completed node ids against the expected
41
+ * set BEFORE synthesizing. `complete` is false when any expected node is
42
+ * missing, so the caller flags the gap rather than shipping partial output.
43
+ * Pure.
44
+ */
45
+ export function reconcileFanIn(expected, completed) {
46
+ const done = new Set(completed);
47
+ const missing = expected.filter((id) => !done.has(id));
48
+ return {
49
+ complete: missing.length === 0,
50
+ expectedCount: expected.length,
51
+ completedCount: expected.length - missing.length,
52
+ missing,
53
+ };
54
+ }
55
+ /**
56
+ * Layer a list into fan-in batches (context-collapse fix). Batches of at most
57
+ * `batchSize` (default 30) so a consolidation step summarizes group summaries
58
+ * rather than N raw outputs. Pure.
59
+ */
60
+ export function layerFanIn(items, batchSize = 30) {
61
+ const size = Math.max(1, Math.floor(batchSize));
62
+ const batches = [];
63
+ for (let i = 0; i < items.length; i += size) {
64
+ batches.push(items.slice(i, i + size));
65
+ }
66
+ return batches;
67
+ }
68
+ /**
69
+ * Augment DAG phases with false-independence serialization edges: phases
70
+ * predicted to write the SAME file get their `deps` extended so the scheduler
71
+ * serializes them, even with zero data dependency. `predictWrites` is injected
72
+ * (fed by the coordination DB's predicted writes). Pure — returns new phase
73
+ * objects with a merged `deps`; input order defines the serialization chain.
74
+ * This is the S7 fix wired at the DeliveryPhase layer.
75
+ *
76
+ * PRECONDITION: `phases` must be in an order consistent with their existing
77
+ * `deps` (topologically ordered, as planDeliveryPhases emits). Synthetic edges
78
+ * run earlier→later by input order; passing a phase before one it already
79
+ * depends on could combine with the pre-existing dep to form a cycle. Callers
80
+ * that don't guarantee topological input order should cycle-check the result.
81
+ */
82
+ export function augmentPhasesWithWriteEdges(phases, predictWrites) {
83
+ const nodes = phases.map((p) => ({ id: p.id, writes: predictWrites(p) }));
84
+ const edges = syntheticEdges(nodes);
85
+ const extra = new Map();
86
+ for (const e of edges) {
87
+ const set = extra.get(e.to) ?? new Set();
88
+ set.add(e.from);
89
+ extra.set(e.to, set);
90
+ }
91
+ return phases.map((p) => {
92
+ const merged = new Set(p.deps ?? []);
93
+ for (const from of extra.get(p.id) ?? [])
94
+ merged.add(from);
95
+ return { ...p, deps: [...merged] };
96
+ });
97
+ }
98
+ //# sourceMappingURL=graph-safety.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-safety.js","sourceRoot":"","sources":["../../src/delivery/graph-safety.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAiBH;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,KAAkB;IAC/C,MAAM,UAAU,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC/C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC1C,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IACD,MAAM,KAAK,GAAoB,EAAE,CAAC;IAClC,KAAK,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,UAAU,EAAE,CAAC;QACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAUD;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,QAAkB,EAAE,SAAmB;IACpE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACvD,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC;QAC9B,aAAa,EAAE,QAAQ,CAAC,MAAM;QAC9B,cAAc,EAAE,QAAQ,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM;QAChD,OAAO;KACR,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAI,KAAmB,EAAE,SAAS,GAAG,EAAE;IAC/D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IAChD,MAAM,OAAO,GAAU,EAAE,CAAC;IAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,2BAA2B,CACzC,MAAoB,EACpB,aAAqC;IAErC,MAAM,KAAK,GAAgB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACvF,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC7C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,GAAG,EAAU,CAAC;QACjD,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAChB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACtB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QACrC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE;YAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3D,OAAO,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC;IACrC,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Per-phase escalation controller (integration of S5 into the loop).
3
+ *
4
+ * A stagnation-driven `onIteration` hook that walks the EXECUTE phase's
5
+ * escalation chain (S5 `resolveEscalation`) rung by rung, then the capability
6
+ * ceiling — superseding the single global `escalateModel` with the full
7
+ * per-(tier, phase) ladder. The single-executor convergence loop can only host
8
+ * the execute-phase ladder; plan/review/reflect ladders belong at the
9
+ * orchestrator layer (they run distinct executors). This controller composes via
10
+ * `composeIterationHooks`, so no loop-core change is needed — it just emits
11
+ * `switchExecutor` directives, exactly like the existing escalation controller.
12
+ */
13
+ import type { IterationRecord, IterationDirective, LoopExecutor } from './convergence-loop.js';
14
+ import type { RoutingPreset, TaskComplexity } from '../models/types.js';
15
+ import type { EscalationScope } from '../coordination/effort-profile.js';
16
+ export interface PerPhaseEscalationConfig {
17
+ preset: RoutingPreset;
18
+ complexity?: TaskComplexity;
19
+ /** Effort scope gating whether the execute phase may escalate at all. */
20
+ scope: EscalationScope;
21
+ /** Bind a resolved model id to a LoopExecutor (provided by the CLI). */
22
+ bindExecutor: (modelId: string) => LoopExecutor;
23
+ stagnationTurns?: number;
24
+ improvementEpsilon?: number;
25
+ onEscalate?: (info: {
26
+ rung: number;
27
+ model: string;
28
+ policy: 'fixed' | 'capability';
29
+ }) => void;
30
+ }
31
+ export interface PerPhaseEscalationController {
32
+ onIteration: (record: IterationRecord) => IterationDirective;
33
+ /** Current execute-phase rung (0 = primary, ≥1 = escalated). For tests. */
34
+ rung: () => number;
35
+ }
36
+ export declare function createPerPhaseEscalationController(cfg: PerPhaseEscalationConfig): PerPhaseEscalationController;
37
+ //# sourceMappingURL=per-phase-escalation-controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"per-phase-escalation-controller.d.ts","sourceRoot":"","sources":["../../src/delivery/per-phase-escalation-controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE/F,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAKzE,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,yEAAyE;IACzE,KAAK,EAAE,eAAe,CAAC;IACvB,wEAAwE;IACxE,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,YAAY,CAAC;IAChD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,GAAG,YAAY,CAAA;KAAE,KAAK,IAAI,CAAC;CAC9F;AAED,MAAM,WAAW,4BAA4B;IAC3C,WAAW,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,kBAAkB,CAAC;IAC7D,2EAA2E;IAC3E,IAAI,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,wBAAgB,kCAAkC,CAChD,GAAG,EAAE,wBAAwB,GAC5B,4BAA4B,CAiD9B"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Per-phase escalation controller (integration of S5 into the loop).
3
+ *
4
+ * A stagnation-driven `onIteration` hook that walks the EXECUTE phase's
5
+ * escalation chain (S5 `resolveEscalation`) rung by rung, then the capability
6
+ * ceiling — superseding the single global `escalateModel` with the full
7
+ * per-(tier, phase) ladder. The single-executor convergence loop can only host
8
+ * the execute-phase ladder; plan/review/reflect ladders belong at the
9
+ * orchestrator layer (they run distinct executors). This controller composes via
10
+ * `composeIterationHooks`, so no loop-core change is needed — it just emits
11
+ * `switchExecutor` directives, exactly like the existing escalation controller.
12
+ */
13
+ import { resolveEscalation, phaseMayEscalate } from './per-phase-escalation.js';
14
+ const DEFAULT_STAGNATION_TURNS = 2;
15
+ const DEFAULT_EPSILON = 0.01;
16
+ export function createPerPhaseEscalationController(cfg) {
17
+ const stagnationTurns = cfg.stagnationTurns ?? DEFAULT_STAGNATION_TURNS;
18
+ const epsilon = cfg.improvementEpsilon ?? DEFAULT_EPSILON;
19
+ let bestScore = -1;
20
+ let stagnant = 0;
21
+ let rung = 0; // 0 = the primary model already running; escalate from rung 1
22
+ let ceilingReached = false;
23
+ return {
24
+ rung: () => rung,
25
+ onIteration: (record) => {
26
+ if (record.passed)
27
+ return {};
28
+ if (!phaseMayEscalate('execute', cfg.scope))
29
+ return {};
30
+ // Don't let infra flakiness (an executor error / never-verified turn,
31
+ // both score 0) count toward stagnation and walk the ladder to the
32
+ // ceiling — mirror the loop's own `inconclusive` guard.
33
+ if (record.executorError || record.gateResults.length === 0)
34
+ return {};
35
+ // Once at the capability ceiling there is nothing stronger to switch to;
36
+ // stop re-binding the same model every stagnation window.
37
+ if (ceilingReached)
38
+ return {};
39
+ if (record.score > bestScore + epsilon) {
40
+ bestScore = record.score;
41
+ stagnant = 0;
42
+ return {};
43
+ }
44
+ stagnant += 1;
45
+ if (record.score > bestScore)
46
+ bestScore = record.score;
47
+ if (stagnant < stagnationTurns)
48
+ return {};
49
+ // Stagnated — advance one execute rung along the chain / to the ceiling.
50
+ rung += 1;
51
+ stagnant = 0;
52
+ const step = resolveEscalation({
53
+ preset: cfg.preset,
54
+ complexity: cfg.complexity,
55
+ phase: 'execute',
56
+ rung,
57
+ });
58
+ if (step.exhausted)
59
+ ceilingReached = true;
60
+ cfg.onEscalate?.({ rung, model: step.model, policy: step.policy });
61
+ return {
62
+ switchExecutor: cfg.bindExecutor(step.model),
63
+ note: `per-phase escalate execute → ${step.model} (rung ${rung}, ${step.policy})`,
64
+ };
65
+ },
66
+ };
67
+ }
68
+ //# sourceMappingURL=per-phase-escalation-controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"per-phase-escalation-controller.js","sourceRoot":"","sources":["../../src/delivery/per-phase-escalation-controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAIhF,MAAM,wBAAwB,GAAG,CAAC,CAAC;AACnC,MAAM,eAAe,GAAG,IAAI,CAAC;AAoB7B,MAAM,UAAU,kCAAkC,CAChD,GAA6B;IAE7B,MAAM,eAAe,GAAG,GAAG,CAAC,eAAe,IAAI,wBAAwB,CAAC;IACxE,MAAM,OAAO,GAAG,GAAG,CAAC,kBAAkB,IAAI,eAAe,CAAC;IAE1D,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC;IACnB,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,8DAA8D;IAC5E,IAAI,cAAc,GAAG,KAAK,CAAC;IAE3B,OAAO;QACL,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI;QAChB,WAAW,EAAE,CAAC,MAAuB,EAAsB,EAAE;YAC3D,IAAI,MAAM,CAAC,MAAM;gBAAE,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YACvD,sEAAsE;YACtE,mEAAmE;YACnE,wDAAwD;YACxD,IAAI,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YACvE,yEAAyE;YACzE,0DAA0D;YAC1D,IAAI,cAAc;gBAAE,OAAO,EAAE,CAAC;YAE9B,IAAI,MAAM,CAAC,KAAK,GAAG,SAAS,GAAG,OAAO,EAAE,CAAC;gBACvC,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC;gBACzB,QAAQ,GAAG,CAAC,CAAC;gBACb,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,QAAQ,IAAI,CAAC,CAAC;YACd,IAAI,MAAM,CAAC,KAAK,GAAG,SAAS;gBAAE,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC;YACvD,IAAI,QAAQ,GAAG,eAAe;gBAAE,OAAO,EAAE,CAAC;YAE1C,yEAAyE;YACzE,IAAI,IAAI,CAAC,CAAC;YACV,QAAQ,GAAG,CAAC,CAAC;YACb,MAAM,IAAI,GAAG,iBAAiB,CAAC;gBAC7B,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,UAAU,EAAE,GAAG,CAAC,UAAU;gBAC1B,KAAK,EAAE,SAAS;gBAChB,IAAI;aACL,CAAC,CAAC;YACH,IAAI,IAAI,CAAC,SAAS;gBAAE,cAAc,GAAG,IAAI,CAAC;YAC1C,GAAG,CAAC,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACnE,OAAO;gBACL,cAAc,EAAE,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC;gBAC5C,IAAI,EAAE,gCAAgC,IAAI,CAAC,KAAK,UAAU,IAAI,KAAK,IAAI,CAAC,MAAM,GAAG;aAClF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Per-phase escalation — hybrid policy (S5).
3
+ *
4
+ * Generalizes the single global escalate-model (repair-escalation.ts's
5
+ * resolveEscalateModelId) into a per-(tier, phase) escalation ladder that
6
+ * composes S3's per-phase model chains:
7
+ * - rungs 0..n-1 walk the FIXED chain for the (tier, phase) — deterministic,
8
+ * testable (e.g. execute: qwen → sonnet → opus);
9
+ * - once the chain is exhausted, the FINAL rung defers to a CAPABILITY-driven
10
+ * pick (the adaptive ceiling) — the "hybrid" the design selected.
11
+ *
12
+ * Pure and injectable: the capability pick is a parameter so the real
13
+ * unified-router selector can be wired in without changing this contract. Each
14
+ * phase escalates on its OWN ladder, so a stalled execute phase advances the
15
+ * execute chain without disturbing the review/plan phases (Generator≠Evaluator
16
+ * is preserved because review/execute chains are independent).
17
+ */
18
+ import { type RoutingPreset, type Phase, type TaskComplexity } from '../models/types.js';
19
+ import type { EscalationScope } from '../coordination/effort-profile.js';
20
+ export type EscalationPolicy = 'fixed' | 'capability';
21
+ export interface EscalationStep {
22
+ /** The model id to run this rung on. */
23
+ model: string;
24
+ /** Whether this rung came from the fixed chain or the capability ceiling. */
25
+ policy: EscalationPolicy;
26
+ /** The (clamped) rung index that produced this step. */
27
+ rung: number;
28
+ /** True once the fixed chain is exhausted (capability fallback engaged). */
29
+ exhausted: boolean;
30
+ }
31
+ /** Default capability ceiling: the preset's fallback role, else the last model
32
+ * in the preset's model list, else the executor role. */
33
+ export declare function defaultCapabilityPick(preset: RoutingPreset): string;
34
+ /**
35
+ * Resolve the model for an escalation rung of a (tier, phase). Hybrid policy:
36
+ * fixed chain first, capability-driven ceiling once exhausted. PURE.
37
+ */
38
+ export declare function resolveEscalation(opts: {
39
+ preset: RoutingPreset;
40
+ complexity?: TaskComplexity;
41
+ phase: Phase;
42
+ /** 0-based escalation rung (0 = primary, 1 = first escalation, …). */
43
+ rung: number;
44
+ /** Injectable capability picker for the final rung; defaults to the ceiling. */
45
+ capabilityPick?: (preset: RoutingPreset) => string;
46
+ }): EscalationStep;
47
+ /**
48
+ * Whether a phase is allowed to escalate under an effort scope. `execute` is
49
+ * always allowed; `plan` only under plan+/all scopes; `review`/`reflect` only
50
+ * under `all`/`all+fallback`; `fallback` only under `all+fallback`.
51
+ */
52
+ export declare function phaseMayEscalate(phase: Phase, scope: EscalationScope): boolean;
53
+ //# sourceMappingURL=per-phase-escalation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"per-phase-escalation.d.ts","sourceRoot":"","sources":["../../src/delivery/per-phase-escalation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAqB,KAAK,aAAa,EAAE,KAAK,KAAK,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC5G,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAEzE,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,YAAY,CAAC;AAEtD,MAAM,WAAW,cAAc;IAC7B,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,MAAM,EAAE,gBAAgB,CAAC;IACzB,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;yDACyD;AACzD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAEnE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,KAAK,EAAE,KAAK,CAAC;IACb,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,MAAM,CAAC;CACpD,GAAG,cAAc,CAQjB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAc9E"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Per-phase escalation — hybrid policy (S5).
3
+ *
4
+ * Generalizes the single global escalate-model (repair-escalation.ts's
5
+ * resolveEscalateModelId) into a per-(tier, phase) escalation ladder that
6
+ * composes S3's per-phase model chains:
7
+ * - rungs 0..n-1 walk the FIXED chain for the (tier, phase) — deterministic,
8
+ * testable (e.g. execute: qwen → sonnet → opus);
9
+ * - once the chain is exhausted, the FINAL rung defers to a CAPABILITY-driven
10
+ * pick (the adaptive ceiling) — the "hybrid" the design selected.
11
+ *
12
+ * Pure and injectable: the capability pick is a parameter so the real
13
+ * unified-router selector can be wired in without changing this contract. Each
14
+ * phase escalates on its OWN ladder, so a stalled execute phase advances the
15
+ * execute chain without disturbing the review/plan phases (Generator≠Evaluator
16
+ * is preserved because review/execute chains are independent).
17
+ */
18
+ import { resolvePhaseChain } from '../models/types.js';
19
+ /** Default capability ceiling: the preset's fallback role, else the last model
20
+ * in the preset's model list, else the executor role. */
21
+ export function defaultCapabilityPick(preset) {
22
+ return preset.roles.fallback ?? preset.models[preset.models.length - 1] ?? preset.roles.executor;
23
+ }
24
+ /**
25
+ * Resolve the model for an escalation rung of a (tier, phase). Hybrid policy:
26
+ * fixed chain first, capability-driven ceiling once exhausted. PURE.
27
+ */
28
+ export function resolveEscalation(opts) {
29
+ const chain = resolvePhaseChain(opts.preset, { complexity: opts.complexity, phase: opts.phase });
30
+ const rung = Math.max(0, Math.floor(opts.rung));
31
+ if (chain.length > 0 && rung < chain.length) {
32
+ return { model: chain[rung], policy: 'fixed', rung, exhausted: false };
33
+ }
34
+ const pick = opts.capabilityPick ?? defaultCapabilityPick;
35
+ return { model: pick(opts.preset), policy: 'capability', rung, exhausted: true };
36
+ }
37
+ /**
38
+ * Whether a phase is allowed to escalate under an effort scope. `execute` is
39
+ * always allowed; `plan` only under plan+/all scopes; `review`/`reflect` only
40
+ * under `all`/`all+fallback`; `fallback` only under `all+fallback`.
41
+ */
42
+ export function phaseMayEscalate(phase, scope) {
43
+ switch (phase) {
44
+ case 'execute':
45
+ return scope !== 'fallback';
46
+ case 'plan':
47
+ return scope === 'plan+execute' || scope === 'all' || scope === 'all+fallback';
48
+ case 'review':
49
+ case 'reflect':
50
+ return scope === 'all' || scope === 'all+fallback';
51
+ case 'fallback':
52
+ return scope === 'all+fallback' || scope === 'fallback';
53
+ default:
54
+ return false;
55
+ }
56
+ }
57
+ //# sourceMappingURL=per-phase-escalation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"per-phase-escalation.js","sourceRoot":"","sources":["../../src/delivery/per-phase-escalation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,iBAAiB,EAAuD,MAAM,oBAAoB,CAAC;AAgB5G;yDACyD;AACzD,MAAM,UAAU,qBAAqB,CAAC,MAAqB;IACzD,OAAO,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;AACnG,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAQjC;IACC,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IACjG,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAC5C,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACzE,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,IAAI,qBAAqB,CAAC;IAC1D,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AACnF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAY,EAAE,KAAsB;IACnE,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,SAAS;YACZ,OAAO,KAAK,KAAK,UAAU,CAAC;QAC9B,KAAK,MAAM;YACT,OAAO,KAAK,KAAK,cAAc,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,cAAc,CAAC;QACjF,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS;YACZ,OAAO,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,cAAc,CAAC;QACrD,KAAK,UAAU;YACb,OAAO,KAAK,KAAK,cAAc,IAAI,KAAK,KAAK,UAAU,CAAC;QAC1D;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * GEPA-style reflect phase (S6).
3
+ *
4
+ * Upgrades the loop's reflection from "fix-list for the next turn" (critic.ts)
5
+ * to "reflect on WHY the approach failed → rewrite the approach/instruction →
6
+ * retry", with a Pareto archive of the best reflected candidates so the loop
7
+ * reseeds from proven approaches instead of always mutating the latest one
8
+ * (which collapses to a local optimum — the same anti-Goodhart insight as the
9
+ * per-phase Generator≠Evaluator rule).
10
+ *
11
+ * This module is pure: the archive + the rewrite parser. The live wiring
12
+ * (a reflect turn before model escalation, feeding IterationDirective
13
+ * .mutateInstruction into the PromptBuilder) is the consumption step.
14
+ */
15
+ export interface ApproachRewrite {
16
+ /** Reflection: why the prior approach/reasoning failed. */
17
+ why: string;
18
+ /** The rewritten instruction/approach to try next. */
19
+ newInstruction: string;
20
+ }
21
+ export interface ReflectCandidate {
22
+ /** The (possibly rewritten) approach/instruction. */
23
+ instruction: string;
24
+ /** The acceptance/quality score this approach achieved. */
25
+ score: number;
26
+ /** The turn it was produced on (tie-break: prefer earlier). */
27
+ turn: number;
28
+ }
29
+ /**
30
+ * A bounded best-K archive of reflected candidates by score. Deterministic:
31
+ * dedupes by instruction (keeping the higher score), sorts by score desc then
32
+ * earlier turn, and truncates to K. Pure — no I/O, no clock.
33
+ */
34
+ export declare class ReflectArchive {
35
+ private readonly k;
36
+ private items;
37
+ constructor(k?: number);
38
+ add(c: ReflectCandidate): void;
39
+ best(): ReflectCandidate | undefined;
40
+ all(): ReflectCandidate[];
41
+ size(): number;
42
+ /**
43
+ * The best archived candidate whose instruction differs from `current` — so a
44
+ * reflect turn tries a proven-but-DIFFERENT approach rather than re-deriving
45
+ * the one that just stalled. Returns undefined when the archive holds nothing
46
+ * new to try.
47
+ */
48
+ reseedFrom(current: string): ReflectCandidate | undefined;
49
+ }
50
+ /**
51
+ * Parse a reflect model's output into an ApproachRewrite. Fail-soft: returns
52
+ * null when no usable rewrite is present, so a flaky reflect turn never wedges
53
+ * the loop (the caller falls back to model escalation).
54
+ */
55
+ export declare function parseApproachRewrite(raw: string): ApproachRewrite | null;
56
+ //# sourceMappingURL=reflect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reflect.d.ts","sourceRoot":"","sources":["../../src/delivery/reflect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,eAAe;IAC9B,2DAA2D;IAC3D,GAAG,EAAE,MAAM,CAAC;IACZ,sDAAsD;IACtD,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,qBAAa,cAAc;IAGb,OAAO,CAAC,QAAQ,CAAC,CAAC;IAF9B,OAAO,CAAC,KAAK,CAA0B;gBAEV,CAAC,GAAE,MAAU;IAI1C,GAAG,CAAC,CAAC,EAAE,gBAAgB,GAAG,IAAI;IAW9B,IAAI,IAAI,gBAAgB,GAAG,SAAS;IAIpC,GAAG,IAAI,gBAAgB,EAAE;IAIzB,IAAI,IAAI,MAAM;IAId;;;;;OAKG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;CAG1D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAYxE"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * GEPA-style reflect phase (S6).
3
+ *
4
+ * Upgrades the loop's reflection from "fix-list for the next turn" (critic.ts)
5
+ * to "reflect on WHY the approach failed → rewrite the approach/instruction →
6
+ * retry", with a Pareto archive of the best reflected candidates so the loop
7
+ * reseeds from proven approaches instead of always mutating the latest one
8
+ * (which collapses to a local optimum — the same anti-Goodhart insight as the
9
+ * per-phase Generator≠Evaluator rule).
10
+ *
11
+ * This module is pure: the archive + the rewrite parser. The live wiring
12
+ * (a reflect turn before model escalation, feeding IterationDirective
13
+ * .mutateInstruction into the PromptBuilder) is the consumption step.
14
+ */
15
+ /**
16
+ * A bounded best-K archive of reflected candidates by score. Deterministic:
17
+ * dedupes by instruction (keeping the higher score), sorts by score desc then
18
+ * earlier turn, and truncates to K. Pure — no I/O, no clock.
19
+ */
20
+ export class ReflectArchive {
21
+ k;
22
+ items = [];
23
+ constructor(k = 4) {
24
+ this.k = k;
25
+ this.k = Math.max(1, Math.floor(k));
26
+ }
27
+ add(c) {
28
+ const i = this.items.findIndex((x) => x.instruction === c.instruction);
29
+ if (i >= 0) {
30
+ if (c.score > this.items[i].score)
31
+ this.items[i] = c;
32
+ }
33
+ else {
34
+ this.items.push(c);
35
+ }
36
+ this.items.sort((a, b) => b.score - a.score || a.turn - b.turn);
37
+ if (this.items.length > this.k)
38
+ this.items = this.items.slice(0, this.k);
39
+ }
40
+ best() {
41
+ return this.items[0];
42
+ }
43
+ all() {
44
+ return [...this.items];
45
+ }
46
+ size() {
47
+ return this.items.length;
48
+ }
49
+ /**
50
+ * The best archived candidate whose instruction differs from `current` — so a
51
+ * reflect turn tries a proven-but-DIFFERENT approach rather than re-deriving
52
+ * the one that just stalled. Returns undefined when the archive holds nothing
53
+ * new to try.
54
+ */
55
+ reseedFrom(current) {
56
+ return this.items.find((x) => x.instruction !== current);
57
+ }
58
+ }
59
+ /**
60
+ * Parse a reflect model's output into an ApproachRewrite. Fail-soft: returns
61
+ * null when no usable rewrite is present, so a flaky reflect turn never wedges
62
+ * the loop (the caller falls back to model escalation).
63
+ */
64
+ export function parseApproachRewrite(raw) {
65
+ try {
66
+ const m = raw.match(/\{[\s\S]*\}/);
67
+ if (!m)
68
+ return null;
69
+ const o = JSON.parse(m[0]);
70
+ if (typeof o.newInstruction === 'string' && o.newInstruction.trim() !== '') {
71
+ return { why: typeof o.why === 'string' ? o.why : '', newInstruction: o.newInstruction };
72
+ }
73
+ return null;
74
+ }
75
+ catch {
76
+ return null;
77
+ }
78
+ }
79
+ //# sourceMappingURL=reflect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reflect.js","sourceRoot":"","sources":["../../src/delivery/reflect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAkBH;;;;GAIG;AACH,MAAM,OAAO,cAAc;IAGI;IAFrB,KAAK,GAAuB,EAAE,CAAC;IAEvC,YAA6B,IAAY,CAAC;QAAb,MAAC,GAAD,CAAC,CAAY;QACxC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,GAAG,CAAC,CAAmB;QACrB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC;QACvE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK;gBAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACvD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;QAChE,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;YAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IAED,GAAG;QACD,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,OAAe;QACxB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,OAAO,CAAC,CAAC;IAC3D,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAW;IAC9C,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACnC,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACpB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAgD,CAAC;QAC1E,IAAI,OAAO,CAAC,CAAC,cAAc,KAAK,QAAQ,IAAI,CAAC,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3E,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc,EAAE,CAAC;QAC3F,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Verification provenance (S1) — enforces Principle 3: "the model cannot verify
3
+ * itself." Deliver must never let the generator be the SOLE grader of its own
4
+ * output. When no evaluator is configured and the operator has not explicitly
5
+ * opted into self-judging, a cheap DISTINCT judge is chosen. Local/offline
6
+ * generators cannot reach a distinct model, so they keep self-judging but are
7
+ * flagged distinct=false (the honest, documented fallback).
8
+ *
9
+ * The selection logic is pure (`resolveJudgePlan`) so it is unit-testable in
10
+ * isolation from the model call; deliver.ts wires the executor from the plan.
11
+ */
12
+ export interface JudgePlan {
13
+ /** Model id that will AUTHOR/JUDGE the acceptance gate. */
14
+ judgeModelId: string;
15
+ /** True when the judge differs from the generator (Generator≠Evaluator). */
16
+ distinct: boolean;
17
+ /** Why this judge was chosen — for logs/telemetry. */
18
+ reason: 'configured-evaluator' | 'self-judge-allowed' | 'auto-distinct-judge' | 'offline-local-no-distinct-judge';
19
+ }
20
+ /**
21
+ * Decide who judges. PURE. Precedence:
22
+ * 1. an explicitly-configured evaluator preset → distinct
23
+ * 2. operator opted into self-judge → generator (distinct=false)
24
+ * 3. cloud generator, distinct cheap judge avail → the distinct judge
25
+ * 4. local/offline (no distinct reachable) → generator (distinct=false)
26
+ */
27
+ export declare function resolveJudgePlan(opts: {
28
+ evaluatorPresetId: string | null;
29
+ generatorId: string;
30
+ generatorProvider?: string;
31
+ allowSelfJudge: boolean;
32
+ /** Cheap distinct judge preferred when the generator is cloud. */
33
+ distinctJudgeId?: string;
34
+ /** Cheap distinct judge to use when the generator itself IS distinctJudgeId. */
35
+ altJudgeId?: string;
36
+ hasPreset: (id: string) => boolean;
37
+ }): JudgePlan;
38
+ export interface VerificationProvenance {
39
+ executorModel: string;
40
+ judgeModel: string;
41
+ distinct: boolean;
42
+ /** Names of gates that ran fail-open this delivery (observability). */
43
+ failOpenGates?: string[];
44
+ }
45
+ /** One-line provenance banner emitted at delivery end. */
46
+ export declare function formatVerificationProvenance(p: VerificationProvenance): string;
47
+ //# sourceMappingURL=verification-provenance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verification-provenance.d.ts","sourceRoot":"","sources":["../../src/delivery/verification-provenance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,SAAS;IACxB,2DAA2D;IAC3D,YAAY,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,QAAQ,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,MAAM,EACF,sBAAsB,GACtB,oBAAoB,GACpB,qBAAqB,GACrB,iCAAiC,CAAC;CACvC;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,OAAO,CAAC;IACxB,kEAAkE;IAClE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gFAAgF;IAChF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;CACpC,GAAG,SAAS,CAsBZ;AAED,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,0DAA0D;AAC1D,wBAAgB,4BAA4B,CAAC,CAAC,EAAE,sBAAsB,GAAG,MAAM,CAI9E"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Verification provenance (S1) — enforces Principle 3: "the model cannot verify
3
+ * itself." Deliver must never let the generator be the SOLE grader of its own
4
+ * output. When no evaluator is configured and the operator has not explicitly
5
+ * opted into self-judging, a cheap DISTINCT judge is chosen. Local/offline
6
+ * generators cannot reach a distinct model, so they keep self-judging but are
7
+ * flagged distinct=false (the honest, documented fallback).
8
+ *
9
+ * The selection logic is pure (`resolveJudgePlan`) so it is unit-testable in
10
+ * isolation from the model call; deliver.ts wires the executor from the plan.
11
+ */
12
+ /**
13
+ * Decide who judges. PURE. Precedence:
14
+ * 1. an explicitly-configured evaluator preset → distinct
15
+ * 2. operator opted into self-judge → generator (distinct=false)
16
+ * 3. cloud generator, distinct cheap judge avail → the distinct judge
17
+ * 4. local/offline (no distinct reachable) → generator (distinct=false)
18
+ */
19
+ export function resolveJudgePlan(opts) {
20
+ // A configured evaluator only counts as distinct if it is actually a
21
+ // DIFFERENT model than the generator (CWE-345: don't assert distinctness we
22
+ // haven't verified). If it collides, fall through to the auto/offline logic.
23
+ if (opts.evaluatorPresetId && opts.evaluatorPresetId !== opts.generatorId) {
24
+ return { judgeModelId: opts.evaluatorPresetId, distinct: true, reason: 'configured-evaluator' };
25
+ }
26
+ if (opts.allowSelfJudge) {
27
+ return { judgeModelId: opts.generatorId, distinct: false, reason: 'self-judge-allowed' };
28
+ }
29
+ const cloud = opts.generatorProvider === 'anthropic' || opts.generatorProvider === 'openai';
30
+ const preferred = opts.distinctJudgeId ?? 'haiku-4.5';
31
+ const alt = opts.altJudgeId ?? 'sonnet-5';
32
+ const distinctId = opts.generatorId === preferred ? alt : preferred;
33
+ if (cloud && opts.hasPreset(distinctId)) {
34
+ return { judgeModelId: distinctId, distinct: true, reason: 'auto-distinct-judge' };
35
+ }
36
+ return {
37
+ judgeModelId: opts.generatorId,
38
+ distinct: false,
39
+ reason: 'offline-local-no-distinct-judge',
40
+ };
41
+ }
42
+ /** One-line provenance banner emitted at delivery end. */
43
+ export function formatVerificationProvenance(p) {
44
+ const distinct = p.distinct ? 'yes' : 'NO(self-verify)';
45
+ const fo = p.failOpenGates && p.failOpenGates.length ? ` failOpen=[${p.failOpenGates.join(',')}]` : '';
46
+ return `verify: exec=${p.executorModel} judge=${p.judgeModel} distinct=${distinct}${fo}`;
47
+ }
48
+ //# sourceMappingURL=verification-provenance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verification-provenance.js","sourceRoot":"","sources":["../../src/delivery/verification-provenance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAeH;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAUhC;IACC,qEAAqE;IACrE,4EAA4E;IAC5E,6EAA6E;IAC7E,IAAI,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,iBAAiB,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;QAC1E,OAAO,EAAE,YAAY,EAAE,IAAI,CAAC,iBAAiB,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC;IAClG,CAAC;IACD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,OAAO,EAAE,YAAY,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC3F,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,KAAK,WAAW,IAAI,IAAI,CAAC,iBAAiB,KAAK,QAAQ,CAAC;IAC5F,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,IAAI,WAAW,CAAC;IACtD,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC;IAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IACpE,IAAI,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;QACxC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC;IACrF,CAAC;IACD,OAAO;QACL,YAAY,EAAE,IAAI,CAAC,WAAW;QAC9B,QAAQ,EAAE,KAAK;QACf,MAAM,EAAE,iCAAiC;KAC1C,CAAC;AACJ,CAAC;AAUD,0DAA0D;AAC1D,MAAM,UAAU,4BAA4B,CAAC,CAAyB;IACpE,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC;IACxD,MAAM,EAAE,GAAG,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACvG,OAAO,gBAAgB,CAAC,CAAC,aAAa,UAAU,CAAC,CAAC,UAAU,aAAa,QAAQ,GAAG,EAAE,EAAE,CAAC;AAC3F,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Unified complexity classifier (S2).
3
+ *
4
+ * Before this module UAP had two disconnected notions of complexity:
5
+ * - router.ts → low | medium | high | critical (keyword-driven)
6
+ * - query-complexity → simple | moderate | complex (heuristic scorer)
7
+ * bridged one-way by deliver.ts's COMPLEXITY_TO_TIER, which silently DROPPED
8
+ * `critical`. This module is the single source of truth: one 5-level `Tier`
9
+ * (adds `trivial` as a floor) that composes the existing scorer and preserves
10
+ * `critical` end-to-end. It is CHEAP-FIRST — a pure heuristic, no model call —
11
+ * so classifying a task adds no overhead. `source` leaves room for a future
12
+ * model-assisted tie-break in the ambiguous band without changing callers.
13
+ */
14
+ export type Tier = 'trivial' | 'low' | 'medium' | 'high' | 'critical';
15
+ export interface ComplexitySignal {
16
+ tier: Tier;
17
+ /** 0..1 continuous — for thresholds/telemetry. */
18
+ score: number;
19
+ /** Why this tier — keyword hits, size, file count, risk flags. */
20
+ reasons: string[];
21
+ /** How it was decided; 'model' reserved for a future ambiguous-band tie-break. */
22
+ source: 'heuristic' | 'model';
23
+ }
24
+ /**
25
+ * Classify task complexity into one 5-level tier. PURE, no model call.
26
+ * Precedence: risk/critical > trivial-floor > 3-level scorer (low/medium/high),
27
+ * with a file-count bump.
28
+ */
29
+ export declare function classifyComplexity(input: {
30
+ instruction: string;
31
+ affectedFiles?: string[];
32
+ riskFlags?: string[];
33
+ }): ComplexitySignal;
34
+ /** Map the 5-level tier onto the 4-level routing scale (trivial folds to low). */
35
+ export declare function tierToRouting(tier: Tier): 'low' | 'medium' | 'high' | 'critical';
36
+ //# sourceMappingURL=complexity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"complexity.d.ts","sourceRoot":"","sources":["../../src/models/complexity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,MAAM,MAAM,IAAI,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAEtE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,IAAI,CAAC;IACX,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,kFAAkF;IAClF,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;CAC/B;AA6BD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,GAAG,gBAAgB,CAgCnB;AAED,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAEhF"}