@wrongstack/core 0.6.5 → 0.6.7

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 (53) hide show
  1. package/dist/{agent-bridge-BBXK_ppx.d.ts → agent-bridge-BCVxmrOn.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-DsSm9lKN.d.ts → agent-subagent-runner-BTloSwjE.d.ts} +3 -3
  3. package/dist/{compactor-C8NhpSt5.d.ts → compactor-BUJ8550X.d.ts} +1 -1
  4. package/dist/{config-DfC6g6KV.d.ts → config-BHkYGzUT.d.ts} +1 -1
  5. package/dist/{context-DN5v-uQX.d.ts → context-C8mBUzBv.d.ts} +3 -5
  6. package/dist/coordination/index.d.ts +10 -10
  7. package/dist/coordination/index.js +62 -30
  8. package/dist/coordination/index.js.map +1 -1
  9. package/dist/defaults/index.d.ts +21 -21
  10. package/dist/defaults/index.js +130 -32
  11. package/dist/defaults/index.js.map +1 -1
  12. package/dist/{events-CJqwQl8G.d.ts → events-DounT6pP.d.ts} +10 -1
  13. package/dist/execution/index.d.ts +56 -14
  14. package/dist/execution/index.js +74 -18
  15. package/dist/execution/index.js.map +1 -1
  16. package/dist/extension/index.d.ts +6 -6
  17. package/dist/{goal-store-_Er467ya.d.ts → goal-store-HHgaq5ue.d.ts} +1 -1
  18. package/dist/{index-CXnWsGBp.d.ts → index-BlVITqm-.d.ts} +6 -9
  19. package/dist/{index-DcnXDPdY.d.ts → index-DiIGZh5I.d.ts} +20 -5
  20. package/dist/index.d.ts +28 -28
  21. package/dist/index.js +251 -131
  22. package/dist/index.js.map +1 -1
  23. package/dist/infrastructure/index.d.ts +6 -6
  24. package/dist/kernel/index.d.ts +9 -9
  25. package/dist/kernel/index.js.map +1 -1
  26. package/dist/{mcp-servers-CevFHHM1.d.ts → mcp-servers-CXFfDN_d.d.ts} +3 -3
  27. package/dist/models/index.d.ts +2 -2
  28. package/dist/{multi-agent-D5IbASk_.d.ts → multi-agent-Iy8YUe3v.d.ts} +4 -4
  29. package/dist/observability/index.d.ts +2 -2
  30. package/dist/{path-resolver-CBx_q1HA.d.ts → path-resolver-DwJO5XBn.d.ts} +2 -2
  31. package/dist/{plan-templates-BEOllUJV.d.ts → plan-templates-CG_pInJV.d.ts} +4 -4
  32. package/dist/{provider-runner-Byh5TcJs.d.ts → provider-runner-DoohzfyD.d.ts} +3 -3
  33. package/dist/{retry-policy-BZSIMxrJ.d.ts → retry-policy-DOnwHAyz.d.ts} +1 -1
  34. package/dist/sdd/index.d.ts +9 -4
  35. package/dist/sdd/index.js +21 -0
  36. package/dist/sdd/index.js.map +1 -1
  37. package/dist/{secret-scrubber-CT7wefiO.d.ts → secret-scrubber-C9UJxFCJ.d.ts} +1 -1
  38. package/dist/{secret-scrubber-I0QHY_ob.d.ts → secret-scrubber-DcTK9JHC.d.ts} +1 -1
  39. package/dist/security/index.d.ts +3 -3
  40. package/dist/{selector-DDb_mq9X.d.ts → selector-DVo3eT-P.d.ts} +1 -1
  41. package/dist/{session-reader-B9nVkziM.d.ts → session-reader-BXWxFAhS.d.ts} +1 -1
  42. package/dist/storage/index.d.ts +6 -6
  43. package/dist/storage/index.js +3 -2
  44. package/dist/storage/index.js.map +1 -1
  45. package/dist/{system-prompt-gL06H9P4.d.ts → system-prompt-BBGles-N.d.ts} +1 -1
  46. package/dist/{task-graph-BITvWt4t.d.ts → task-graph-D1YQbpxF.d.ts} +1 -0
  47. package/dist/{tool-executor-BF7QfYVE.d.ts → tool-executor-CwpjhwHC.d.ts} +4 -4
  48. package/dist/types/index.d.ts +16 -16
  49. package/dist/types/index.js +1 -3
  50. package/dist/types/index.js.map +1 -1
  51. package/dist/utils/index.d.ts +1 -1
  52. package/package.json +1 -1
  53. package/skills/sdd/SKILL.md +122 -106
@@ -1,4 +1,4 @@
1
- import { U as Usage, a2 as Context, z as ToolProgressEvent, v as Tool } from './context-DN5v-uQX.js';
1
+ import { U as Usage, a2 as Context, z as ToolProgressEvent, v as Tool } from './context-C8mBUzBv.js';
2
2
 
3
3
  /**
4
4
  * EventBus — observe-only typed event bus.
@@ -341,6 +341,15 @@ interface EventMap {
341
341
  };
342
342
  };
343
343
  };
344
+ /**
345
+ * Fired by the delegate tool when a subagent finishes. The agent's run
346
+ * loop listens for this to collect `delegateSummaries` for the RunResult,
347
+ * so the CLI/TUI can render flashy completion banners.
348
+ */
349
+ 'subagent.done': {
350
+ summary: string;
351
+ ok: boolean;
352
+ };
344
353
  'mcp.server.connected': {
345
354
  name: string;
346
355
  toolCount: number;
@@ -1,21 +1,21 @@
1
- export { C as CompactorOptions, a as DefaultErrorHandler, b as DefaultRetryPolicy, H as HybridCompactor, T as ToolExecutor } from '../tool-executor-BF7QfYVE.js';
2
- import { g as Provider, a2 as Context } from '../context-DN5v-uQX.js';
3
- import { a as Compactor, C as CompactReport } from '../compactor-C8NhpSt5.js';
4
- import { M as MessageSelector } from '../selector-DDb_mq9X.js';
5
- import { E as EventBus } from '../events-CJqwQl8G.js';
6
- import { c as MiddlewareHandler } from '../system-prompt-gL06H9P4.js';
7
- import { e as ContextWindowAggressiveOn, i as ContextWindowPolicy } from '../config-DfC6g6KV.js';
8
- import { A as Agent, R as RunResult, j as SystemPromptContributor } from '../index-DcnXDPdY.js';
9
- import { D as DoneCondition } from '../multi-agent-D5IbASk_.js';
10
- import { J as JournalEntry } from '../goal-store-_Er467ya.js';
11
- import { A as AgentFactory } from '../agent-subagent-runner-DsSm9lKN.js';
1
+ export { C as CompactorOptions, a as DefaultErrorHandler, b as DefaultRetryPolicy, H as HybridCompactor, T as ToolExecutor } from '../tool-executor-CwpjhwHC.js';
2
+ import { g as Provider, a2 as Context } from '../context-C8mBUzBv.js';
3
+ import { a as Compactor, C as CompactReport } from '../compactor-BUJ8550X.js';
4
+ import { M as MessageSelector } from '../selector-DVo3eT-P.js';
5
+ import { E as EventBus } from '../events-DounT6pP.js';
6
+ import { c as MiddlewareHandler } from '../system-prompt-BBGles-N.js';
7
+ import { e as ContextWindowAggressiveOn, i as ContextWindowPolicy } from '../config-BHkYGzUT.js';
8
+ import { A as Agent, R as RunResult, j as SystemPromptContributor } from '../index-DiIGZh5I.js';
9
+ import { D as DoneCondition } from '../multi-agent-Iy8YUe3v.js';
10
+ import { J as JournalEntry } from '../goal-store-HHgaq5ue.js';
11
+ import { A as AgentFactory } from '../agent-subagent-runner-BTloSwjE.js';
12
12
  import { a as SkillLoader, b as SkillManifest, S as SkillEntry } from '../skill-CxuWrsKK.js';
13
13
  import { W as WstackPaths } from '../wstack-paths-86YPFktR.js';
14
- import '../retry-policy-BZSIMxrJ.js';
14
+ import '../retry-policy-DOnwHAyz.js';
15
15
  import '../models-registry-Y2xbog0E.js';
16
16
  import '../logger-BMQgxvdy.js';
17
17
  import '../observability-BhnVLBLS.js';
18
- import '../secret-scrubber-CT7wefiO.js';
18
+ import '../secret-scrubber-C9UJxFCJ.js';
19
19
 
20
20
  interface SkillLoaderOptions {
21
21
  paths: WstackPaths;
@@ -334,6 +334,13 @@ interface EternalAutonomyOptions {
334
334
  /** Side-channel notifications (logging, UI updates). */
335
335
  onIteration?: (entry: JournalEntry) => void;
336
336
  onError?: (err: Error, iteration: number) => void;
337
+ /**
338
+ * Per-iteration phase notifications for live UI updates (TUI status bar,
339
+ * etc.). Fires at each major stage transition: idle → decide → execute →
340
+ * reflect → (sleep | paused | stopped). Fire-and-forget — the engine
341
+ * does not await the callback.
342
+ */
343
+ onStage?: (stage: IterationStage) => void;
337
344
  /**
338
345
  * Optional injected git status reader — production code uses git, tests
339
346
  * stub this out so they don't shell out.
@@ -380,8 +387,37 @@ interface EternalAutonomyOptions {
380
387
  transientBackoffBaseMs?: number;
381
388
  /** Ceiling for the exponential backoff. Default 60_000 (60 s). */
382
389
  transientBackoffMaxMs?: number;
390
+ /** Called when the eternal loop stops for any reason (manual stop, goal complete, etc.). */
391
+ onEternalStop?: () => void;
383
392
  }
384
393
  type EternalEngineState = 'idle' | 'running' | 'stopped';
394
+ /**
395
+ * Per-iteration phase emitted via `onStage` so UIs can render the
396
+ * engine's live location in the sense-decide-execute-reflect loop.
397
+ */
398
+ type IterationStage = {
399
+ phase: 'idle';
400
+ } | {
401
+ phase: 'decide';
402
+ reason: string;
403
+ } | {
404
+ phase: 'execute';
405
+ task: string;
406
+ } | {
407
+ phase: 'reflect';
408
+ status: 'success' | 'failure' | 'aborted' | 'skipped';
409
+ note?: string;
410
+ } | {
411
+ phase: 'sleep';
412
+ ms: number;
413
+ } | {
414
+ phase: 'paused';
415
+ } | {
416
+ phase: 'stopped';
417
+ } | {
418
+ phase: 'error';
419
+ message: string;
420
+ };
385
421
  declare class EternalAutonomyEngine {
386
422
  private readonly opts;
387
423
  private state;
@@ -477,6 +513,12 @@ declare class EternalAutonomyEngine {
477
513
  * goal is already `completed`.
478
514
  */
479
515
  private markGoalCompleted;
516
+ /**
517
+ * Manually clear the goal — equivalent to `/goal clear` typed by the user.
518
+ * Sets goalState to `abandoned`, removes the goal file, and fires
519
+ * `onEternalStop` so the REPL returns to normal mode.
520
+ */
521
+ private clearGoalManually;
480
522
  private appendFailure;
481
523
  private persistEngineState;
482
524
  }
@@ -618,4 +660,4 @@ declare function makeAutonomyPromptContributor(opts: AutonomyPromptContributorOp
618
660
  */
619
661
  declare function buildGoalPreamble(goal: string): string;
620
662
 
621
- export { AutoCompactionMiddleware, AutonomousRunner, type AutonomousRunnerOptions, type AutonomyPromptContributorOptions, DefaultSkillLoader, type DoneCheckResult, DoneConditionChecker, EternalAutonomyEngine, type EternalAutonomyOptions, type EternalEngineState, IntelligentCompactor, type IntelligentCompactorOptions, type ParallelEngineState, ParallelEternalEngine, type ParallelEternalOptions, SelectiveCompactor, type SelectiveCompactorOptions, type SkillLoaderOptions, buildGoalPreamble, makeAutonomyPromptContributor };
663
+ export { AutoCompactionMiddleware, AutonomousRunner, type AutonomousRunnerOptions, type AutonomyPromptContributorOptions, DefaultSkillLoader, type DoneCheckResult, DoneConditionChecker, EternalAutonomyEngine, type EternalAutonomyOptions, type EternalEngineState, IntelligentCompactor, type IntelligentCompactorOptions, type IterationStage, type ParallelEngineState, ParallelEternalEngine, type ParallelEternalOptions, SelectiveCompactor, type SelectiveCompactorOptions, type SkillLoaderOptions, buildGoalPreamble, makeAutonomyPromptContributor };
@@ -1707,7 +1707,8 @@ function appendJournal(goal, entry) {
1707
1707
  // src/execution/eternal-autonomy.ts
1708
1708
  var execFileP = promisify(execFile);
1709
1709
  var BRAINSTORM_DONE = /* @__PURE__ */ Symbol("brainstorm-done");
1710
- var GOAL_COMPLETE_MARKER = /^\s*\[goal[_\s-]?complete\]\s*$/im;
1710
+ var GOAL_COMPLETE_MARKER = /^\s*\[goal[_\s-]*complete\]\s*$/im;
1711
+ var GOAL_CLEAR_MARKER = /^\s*\[\/?goal\s*clear\]\s*$/im;
1711
1712
  var EternalAutonomyEngine = class {
1712
1713
  constructor(opts) {
1713
1714
  this.opts = opts;
@@ -1789,23 +1790,33 @@ var EternalAutonomyEngine = class {
1789
1790
  * `agent.run()` avoids race conditions on the shared Context.
1790
1791
  */
1791
1792
  async runOneIteration() {
1793
+ const emit = (stage) => {
1794
+ this.opts.onStage?.(stage);
1795
+ };
1792
1796
  const goal = await loadGoal(this.goalPath);
1793
1797
  if (!goal) {
1798
+ emit({ phase: "stopped" });
1794
1799
  this.stopRequested = true;
1795
1800
  return false;
1796
1801
  }
1797
1802
  const missionState = goal.goalState ?? "active";
1798
1803
  if (missionState !== "active") {
1804
+ emit({ phase: missionState === "paused" ? "paused" : "stopped" });
1799
1805
  this.stopRequested = true;
1800
1806
  return false;
1801
1807
  }
1808
+ emit({ phase: "decide", reason: "picking next task" });
1802
1809
  const action = await this.decide(goal);
1803
1810
  if (!action) {
1804
1811
  if (!this.stopRequested) {
1812
+ emit({ phase: "sleep", ms: 5e3 });
1805
1813
  await sleep(5e3);
1814
+ } else {
1815
+ emit({ phase: "stopped" });
1806
1816
  }
1807
1817
  return false;
1808
1818
  }
1819
+ emit({ phase: "execute", task: action.task });
1809
1820
  const ctrl = new AbortController();
1810
1821
  this.currentCtrl = ctrl;
1811
1822
  const timer = setTimeout(
@@ -1883,6 +1894,7 @@ var EternalAutonomyEngine = class {
1883
1894
  tokens,
1884
1895
  costUsd
1885
1896
  });
1897
+ emit({ phase: "reflect", status, note });
1886
1898
  let iterationIndex = 0;
1887
1899
  try {
1888
1900
  const reloaded = await loadGoal(this.goalPath);
@@ -1904,6 +1916,7 @@ var EternalAutonomyEngine = class {
1904
1916
  this.consecutiveTransientRetries++;
1905
1917
  const delay = this.computeTransientBackoffMs();
1906
1918
  if (delay > 0) {
1919
+ emit({ phase: "sleep", ms: delay });
1907
1920
  await this.sleepInterruptible(delay);
1908
1921
  }
1909
1922
  return false;
@@ -1917,8 +1930,16 @@ var EternalAutonomyEngine = class {
1917
1930
  return false;
1918
1931
  }
1919
1932
  this.consecutiveTransientRetries = 0;
1933
+ const cycleGapMs = this.opts.cycleGapMs ?? 1e3;
1934
+ emit({ phase: "sleep", ms: cycleGapMs });
1935
+ await sleep(cycleGapMs);
1920
1936
  if (GOAL_COMPLETE_MARKER.test(finalText)) {
1921
- await this.markGoalCompleted(action, finalText);
1937
+ await this.clearGoalManually(finalText);
1938
+ this.stopRequested = true;
1939
+ return true;
1940
+ }
1941
+ if (GOAL_CLEAR_MARKER.test(finalText)) {
1942
+ await this.clearGoalManually(finalText);
1922
1943
  this.stopRequested = true;
1923
1944
  return true;
1924
1945
  }
@@ -2218,6 +2239,30 @@ ${recentJournal}` : "No prior iterations.",
2218
2239
  });
2219
2240
  await saveGoal(this.goalPath, withEntry);
2220
2241
  }
2242
+ /**
2243
+ * Manually clear the goal — equivalent to `/goal clear` typed by the user.
2244
+ * Sets goalState to `abandoned`, removes the goal file, and fires
2245
+ * `onEternalStop` so the REPL returns to normal mode.
2246
+ */
2247
+ async clearGoalManually(note) {
2248
+ const current = await loadGoal(this.goalPath);
2249
+ if (current) {
2250
+ const abandoned = { ...current, goalState: "abandoned" };
2251
+ await saveGoal(this.goalPath, abandoned);
2252
+ }
2253
+ try {
2254
+ const { unlink: unlink2 } = await import('fs/promises');
2255
+ await unlink2(this.goalPath);
2256
+ } catch {
2257
+ }
2258
+ this.opts.onEternalStop?.();
2259
+ void this.appendIterationEntry({
2260
+ source: "manual",
2261
+ task: "goal cleared",
2262
+ status: "success",
2263
+ note: note.slice(0, 240)
2264
+ });
2265
+ }
2221
2266
  async appendFailure(task, note) {
2222
2267
  await this.appendIterationEntry({ source: "manual", task, status: "failure", note });
2223
2268
  }
@@ -2285,10 +2330,10 @@ var SubagentBudget = class _SubagentBudget {
2285
2330
  * or hung listener (Director not built / event filter detached mid-run)
2286
2331
  * leaves the budget over-limit and never enforces anything, since
2287
2332
  * `checkLimit` returns synchronously via `void this.checkLimitAsync`.
2288
- * Hardcoded for now most fleets set their own per-task timeout that
2289
- * dwarfs this anyway. 30 s matches the existing event-emit timeoutMs.
2333
+ * Raised from 30s to 60s to give subagents more headroom before
2334
+ * the threshold negotiation times out and triggers a hard stop.
2290
2335
  */
2291
- static DECISION_TIMEOUT_MS = 3e4;
2336
+ static DECISION_TIMEOUT_MS = 6e4;
2292
2337
  /**
2293
2338
  * Injected by the runner when wiring the budget to its EventBus.
2294
2339
  * Used by `checkLimitAsync` to emit `budget.threshold_reached` events.
@@ -2718,13 +2763,19 @@ function providerStatusToCode(status, type) {
2718
2763
  return "PROVIDER_INVALID_REQUEST";
2719
2764
  }
2720
2765
  var FLEET_ROSTER_BUDGETS = {
2721
- "audit-log": { timeoutMs: 8 * 60 * 1e3, maxIterations: 150, maxToolCalls: 500 },
2722
- "bug-hunter": { timeoutMs: 15 * 60 * 1e3, maxIterations: 200, maxToolCalls: 600 },
2723
- "refactor-planner": { timeoutMs: 12 * 60 * 1e3, maxIterations: 180, maxToolCalls: 550 },
2724
- "security-scanner": { timeoutMs: 15 * 60 * 1e3, maxIterations: 200, maxToolCalls: 600 }
2766
+ "audit-log": { timeoutMs: 7.5 * 60 * 60 * 1e3, maxIterations: 5e3, maxToolCalls: 15e3 },
2767
+ "bug-hunter": { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 },
2768
+ "refactor-planner": { timeoutMs: 7.5 * 60 * 60 * 1e3, maxIterations: 6e3, maxToolCalls: 18e3 },
2769
+ "security-scanner": { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 }
2770
+ };
2771
+ var GENERIC_SUBAGENT_BUDGET = {
2772
+ timeoutMs: 3 * 60 * 60 * 1e3,
2773
+ maxIterations: 5e3,
2774
+ maxToolCalls: 15e3
2725
2775
  };
2726
2776
  function applyRosterBudget(cfg) {
2727
- const defaultBudget = FLEET_ROSTER_BUDGETS[cfg.role ?? ""];
2777
+ const roleBudget = cfg.role ? FLEET_ROSTER_BUDGETS[cfg.role] : void 0;
2778
+ const defaultBudget = roleBudget ?? (cfg.name ? GENERIC_SUBAGENT_BUDGET : void 0);
2728
2779
  if (!defaultBudget) return cfg;
2729
2780
  return {
2730
2781
  ...cfg,
@@ -2795,7 +2846,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
2795
2846
  // hasParentBridge() — the type now reflects this.
2796
2847
  parentBridge: null,
2797
2848
  doneCondition: this.config.doneCondition,
2798
- maxConcurrent: this.config.maxConcurrent ?? 4
2849
+ maxConcurrent: this.config.maxConcurrent ?? 16
2799
2850
  };
2800
2851
  this.subagents.set(id, {
2801
2852
  config: { ...subagent, id },
@@ -2922,7 +2973,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
2922
2973
  }
2923
2974
  }
2924
2975
  canDispatch() {
2925
- const max = this.config.maxConcurrent ?? 4;
2976
+ const max = this.config.maxConcurrent ?? 16;
2926
2977
  return this.inFlight < max && this.pendingTasks.length > 0;
2927
2978
  }
2928
2979
  takeNextDispatchableTask() {
@@ -3016,13 +3067,18 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
3016
3067
  task.subagentId = subagentId;
3017
3068
  subagent.context.tasks.push(task);
3018
3069
  this.emit("task.assigned", { task, subagentId });
3070
+ const rawMaxIterations = subagent.config.maxIterations;
3071
+ const rawMaxToolCalls = subagent.config.maxToolCalls;
3072
+ const rawMaxTokens = subagent.config.maxTokens;
3073
+ const rawMaxCostUsd = subagent.config.maxCostUsd;
3074
+ const rawTimeoutMs = subagent.config.timeoutMs;
3019
3075
  const configWithRosterDefaults = applyRosterBudget(subagent.config);
3020
3076
  const budget = new SubagentBudget({
3021
- maxIterations: configWithRosterDefaults.maxIterations ?? this.config.defaultBudget?.maxIterations,
3022
- maxToolCalls: task.maxToolCalls ?? configWithRosterDefaults.maxToolCalls ?? this.config.defaultBudget?.maxToolCalls,
3023
- maxTokens: configWithRosterDefaults.maxTokens ?? this.config.defaultBudget?.maxTokens,
3024
- maxCostUsd: configWithRosterDefaults.maxCostUsd ?? this.config.defaultBudget?.maxCostUsd,
3025
- timeoutMs: task.timeoutMs ?? configWithRosterDefaults.timeoutMs ?? this.config.defaultBudget?.timeoutMs
3077
+ maxIterations: rawMaxIterations ?? this.config.defaultBudget?.maxIterations ?? configWithRosterDefaults.maxIterations,
3078
+ maxToolCalls: rawMaxToolCalls ?? this.config.defaultBudget?.maxToolCalls ?? configWithRosterDefaults.maxToolCalls,
3079
+ maxTokens: rawMaxTokens ?? this.config.defaultBudget?.maxTokens ?? configWithRosterDefaults.maxTokens,
3080
+ maxCostUsd: rawMaxCostUsd ?? this.config.defaultBudget?.maxCostUsd ?? configWithRosterDefaults.maxCostUsd,
3081
+ timeoutMs: rawTimeoutMs ?? this.config.defaultBudget?.timeoutMs ?? configWithRosterDefaults.timeoutMs
3026
3082
  });
3027
3083
  subagent.activeBudget = budget;
3028
3084
  if (!this.runner) {
@@ -3093,7 +3149,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
3093
3149
  kind: "timeout",
3094
3150
  used: elapsed,
3095
3151
  limit,
3096
- timeoutMs: 3e4,
3152
+ timeoutMs: 6e4,
3097
3153
  extend: (extra) => resolveDecision({ extend: extra }),
3098
3154
  deny: () => resolveDecision("stop")
3099
3155
  });