@sensigo/realm-cli 0.31.2 → 0.33.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.
@@ -1,19 +1,48 @@
1
1
  // resume command — removes a step from failed_steps so it can be re-executed.
2
+ //
3
+ // issue #279 (increment 1, PR-B): the write itself is now the core-owned pure `applyResume`
4
+ // transform (design record §5) — this file's job narrows to the FOUR CLI refusals that must run
5
+ // BEFORE it (structural aborted_at guard, a finalizer `--from` target, an unexpired drain lease,
6
+ // and the three-way claim classification), then a single atomic `store.update()` of whatever
7
+ // `applyResume` computed (its own version-CAS is the whole atomicity story — see that module's
8
+ // doc). issue #281 rides here too: applyResume strips `abandoned_at` alongside `terminal_reason`.
2
9
  import { Command } from 'commander';
3
- import { WorkflowError } from '@sensigo/realm';
4
- import { RESUMABLE_PHASES, propagateSkips } from '@sensigo/realm';
5
10
  /**
6
- * Removes `stepName` from `failed_steps` so the DAG engine can re-evaluate its
7
- * eligibility on the next execute-step call.
11
+ * Removes `stepName` from `failed_steps` so the DAG engine can re-evaluate its eligibility on the
12
+ * next execute-step call — via the core `applyResume` transform (design record §5), after the
13
+ * four CLI refusals below all clear.
8
14
  *
9
15
  * @param runId The run to resume.
10
16
  * @param stepName The failed step to re-enable.
11
17
  * @param runStore Store holding run records.
12
18
  * @param workflowStore Registrar for workflow definitions.
19
+ * @param opts `force` overrides ONLY the claim_unknown_age refusal.
20
+ * @returns The finalizers this resume voided (empty on the common no-pendings case).
13
21
  */
14
- export async function resumeRun(runId, stepName, runStore, workflowStore) {
22
+ export async function resumeRun(runId, stepName, runStore, workflowStore, opts = {}) {
23
+ const { WorkflowError, applyResume, RESUMABLE_PHASES, classifyClaim, DRAIN_LEASE_MAX, deriveRunPhase, } = await import('@sensigo/realm');
15
24
  const run = await runStore.get(runId);
16
- if (!RESUMABLE_PHASES.has(run.run_phase)) {
25
+ // §5.1 — structural, phase-independent (RESUME_REFUSES_ABORTED pin): an aborted run is never
26
+ // resumable, checked directly against aborted_at rather than relying on RESUMABLE_PHASES
27
+ // excluding 'aborted' as a side effect. Checked FIRST and independently of the phase check below
28
+ // — deriveRunPhase(:34-42) always derives phase 'aborted' whenever aborted_at is set (the two
29
+ // can never diverge through any real store write today), so this ordering is what makes the
30
+ // explicit, by-name business rule ("abort ⇒ never resumable") the one that actually fires,
31
+ // rather than silently riding on RESUMABLE_PHASES's exclusion as an unstated implementation
32
+ // detail a future phase-set change could break.
33
+ if (run.aborted_at !== undefined) {
34
+ throw new WorkflowError(`Run ${runId} was aborted (step '${run.aborted_at.step_id}') — aborted runs are never ` +
35
+ `resumable.`, {
36
+ code: 'STATE_TRANSITION_DENIED',
37
+ category: 'STATE',
38
+ agentAction: 'report_to_user',
39
+ retryable: false,
40
+ });
41
+ }
42
+ // issue #279 (increment 2, PR-C — D-3 leg iv): derive, never trust the persisted run_phase — a
43
+ // grandfathered terminal-with-stale-gate record (the #282 class) must be admitted here on its
44
+ // TRUE (derived) phase, not whatever was last persisted.
45
+ if (!RESUMABLE_PHASES.has(deriveRunPhase(run))) {
17
46
  throw new WorkflowError(`Run ${runId} is in phase '${run.run_phase}', which is not resumable.`, {
18
47
  code: 'STATE_TRANSITION_DENIED',
19
48
  category: 'STATE',
@@ -22,7 +51,8 @@ export async function resumeRun(runId, stepName, runStore, workflowStore) {
22
51
  });
23
52
  }
24
53
  const workflow = await workflowStore.get(run.workflow_id);
25
- if (workflow.steps[stepName] === undefined) {
54
+ const targetStep = workflow.steps[stepName];
55
+ if (targetStep === undefined) {
26
56
  throw new WorkflowError(`Step '${stepName}' not found in workflow '${run.workflow_id}'.`, {
27
57
  code: 'STEP_NOT_FOUND',
28
58
  category: 'ENGINE',
@@ -30,6 +60,17 @@ export async function resumeRun(runId, stepName, runStore, workflowStore) {
30
60
  retryable: false,
31
61
  });
32
62
  }
63
+ // §5.2 — a finalizer `--from` target is refused (finalizers settle via the drain verb, not
64
+ // resume — resuming one would bypass the ledger's own lease/mark discipline entirely).
65
+ if (targetStep.execution === 'finalizer') {
66
+ throw new WorkflowError(`Step '${stepName}' is a finalizer — finalizers cannot be resumed via --from. Use ` +
67
+ `'realm run drain ${runId}' or '--void ${stepName}' instead.`, {
68
+ code: 'STATE_TRANSITION_DENIED',
69
+ category: 'STATE',
70
+ agentAction: 'report_to_user',
71
+ retryable: false,
72
+ });
73
+ }
33
74
  if (!run.failed_steps.includes(stepName)) {
34
75
  throw new WorkflowError(`Step '${stepName}' is not in failed_steps for run '${runId}'.`, {
35
76
  code: 'STATE_TRANSITION_DENIED',
@@ -38,43 +79,84 @@ export async function resumeRun(runId, stepName, runStore, workflowStore) {
38
79
  retryable: false,
39
80
  });
40
81
  }
41
- // Re-enable the failed step AND make the run runnable again. Filtering failed_steps alone leaves
42
- // the run terminal (terminal_state:true), so `realm agent --run-id` throws on it and the
43
- // `while (!terminal_state)` drivers skip it. Mirror the test-harness reference: strip
44
- // terminal_reason (destructure-and-omit to honour exactOptionalPropertyTypes), re-derive
45
- // skipped_steps from scratch so steps skipped only because of this failure become eligible again,
46
- // and reset terminal_state to false. update() recomputes run_phase → 'running'.
47
- //
48
- // #111 clean slate: `...rest` still carries the run's stale `skip_details` — it MUST be reset
49
- // to `{}` alongside `skipped_steps: []`, or an orphaned detail would survive for a step that is
50
- // now re-eligible (violating `Object.keys(skip_details) skipped_steps` isn't the risk here —
51
- // the risk is a STALE-but-still-valid-looking reason for a step that no longer has one).
52
- // No handler/guard-abort detail is re-mintable by this propagateSkips-only recompute that is
53
- // fine and unreachable: resume is gated to failed/abandoned phases (RESUMABLE_PHASES), never
54
- // the aborted phase a handler/guard abort produces.
55
- const { terminal_reason: _terminalReason, ...rest } = run;
56
- const failedSteps = rest.failed_steps.filter((s) => s !== stepName);
57
- const { skipped: skippedSteps, details: skipDetails } = propagateSkips({ ...rest, failed_steps: failedSteps, skipped_steps: [], skip_details: {} }, workflow);
58
- await runStore.update({
59
- ...rest,
60
- failed_steps: failedSteps,
61
- skipped_steps: skippedSteps,
62
- skip_details: skipDetails,
63
- terminal_state: false,
64
- });
82
+ const now = new Date();
83
+ // §5.3 any pending finalizer ledger entry with an UNEXPIRED lease refuses: a drainer is
84
+ // executing RIGHT NOW. Bounded by the §3 clamp (DRAIN_LEASE_MAX) — the wait is short by
85
+ // construction, so there is deliberately NO --force bypass (final-gate F10a).
86
+ for (const [name, entry] of Object.entries(run.finalizer_ledger ?? {})) {
87
+ if (entry.status !== 'pending')
88
+ continue;
89
+ if (entry.lease_token === undefined || entry.lease_deadline === undefined)
90
+ continue;
91
+ if (new Date(entry.lease_deadline).getTime() <= now.getTime())
92
+ continue; // expired not held
93
+ throw new WorkflowError(`Run ${runId} has an active drain lease on finalizer '${name}' (expires ` +
94
+ `${entry.lease_deadline}) a drainer is executing NOW. Wait for the lease to expire ` +
95
+ `(bounded leases are clamped to ${DRAIN_LEASE_MAX}s) and retry. Not force-bypassable.`, {
96
+ code: 'STATE_TRANSITION_DENIED',
97
+ category: 'STATE',
98
+ agentAction: 'report_to_user',
99
+ retryable: true,
100
+ details: { runId, finalizer: name, lease_deadline: entry.lease_deadline },
101
+ });
102
+ }
103
+ // §5.4 — claims: classifyClaim three-way. healthy ⇒ refuse (no override); claim_unknown_age ⇒
104
+ // refuse UNLESS --force; stale/absent ⇒ released inside applyResume, no refusal here.
105
+ for (const step of run.in_progress_steps) {
106
+ const claim = run.claims?.[step];
107
+ if (claim === undefined)
108
+ continue; // absent — released inside applyResume
109
+ const state = classifyClaim(claim, now);
110
+ if (state === 'healthy') {
111
+ throw new WorkflowError(`Step '${step}' has a HEALTHY claim (deadline ${claim.deadline}) — a live runner is ` +
112
+ `presumed on it. Resume refuses to disturb live work.`, {
113
+ code: 'STATE_TRANSITION_DENIED',
114
+ category: 'STATE',
115
+ agentAction: 'report_to_user',
116
+ retryable: true,
117
+ details: { runId, step },
118
+ });
119
+ }
120
+ if (state === 'claim_unknown_age' && opts.force !== true) {
121
+ throw new WorkflowError(`Step '${step}' has an unknown-age claim (no reliable deadline) — its liveness cannot ` +
122
+ `be verified. Re-run with --force to override (only after confirming the runner is ` +
123
+ `actually dead).`, {
124
+ code: 'STATE_TRANSITION_DENIED',
125
+ category: 'STATE',
126
+ agentAction: 'report_to_user',
127
+ retryable: false,
128
+ details: { runId, step },
129
+ });
130
+ }
131
+ // claim_stale, or claim_unknown_age with --force: falls through — applyResume releases it.
132
+ }
133
+ const { run: resumedRun, voided, disclosures } = applyResume(run, stepName, workflow);
134
+ await runStore.update(resumedRun);
135
+ return { voided, disclosures };
65
136
  }
66
137
  export const resumeCommand = new Command('resume')
67
138
  .description('Remove a step from failed_steps so it can be re-executed')
68
139
  .argument('<run-id>', 'ID of the run to resume')
69
140
  .requiredOption('--from <step>', 'Name of the failed step to re-enable')
141
+ .option('--force', 'Override the claim_unknown_age refusal ONLY (never a healthy claim or an unexpired drain lease)')
70
142
  .action(async (runId, opts) => {
71
143
  const { JsonFileStore, JsonWorkflowStore } = await import('@sensigo/realm');
72
144
  const runStore = new JsonFileStore();
73
145
  const workflowStore = new JsonWorkflowStore();
74
146
  try {
75
- await resumeRun(runId, opts.from, runStore, workflowStore);
147
+ const { voided, disclosures } = await resumeRun(runId, opts.from, runStore, workflowStore, {
148
+ ...(opts.force !== undefined ? { force: opts.force } : {}),
149
+ });
76
150
  console.log(`Resumed run '${runId}': step '${opts.from}' re-enabled and run reset to 'running'.\n` +
77
151
  `Drive it with: realm agent --run-id ${runId}`);
152
+ for (const { disclosure } of voided) {
153
+ console.log(` ⚠ ${disclosure}`);
154
+ }
155
+ // issue #279 (increment 2, PR-C — D-3 leg ii): a stripped zombie gate, printed AFTER the
156
+ // voided-finalizer lines (same `⚠` loop convention).
157
+ for (const disclosure of disclosures) {
158
+ console.log(` ⚠ ${disclosure}`);
159
+ }
78
160
  }
79
161
  catch (err) {
80
162
  console.error(err instanceof Error ? err.message : String(err));
@@ -1 +1 @@
1
- {"version":3,"file":"resume.js","sourceRoot":"","sources":["../../src/commands/resume.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resume.js","sourceRoot":"","sources":["../../src/commands/resume.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"commands-registry.d.ts","sourceRoot":"","sources":["../src/commands-registry.ts"],"names":[],"mappings":"AA8BA,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,+BAQ5B,CAAC;AAEF,gEAAgE;AAChE,eAAO,MAAM,WAAW,+BAevB,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,gBAAgB,+BAM5B,CAAC"}
1
+ {"version":3,"file":"commands-registry.d.ts","sourceRoot":"","sources":["../src/commands-registry.ts"],"names":[],"mappings":"AA+BA,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,+BAQ5B,CAAC;AAEF,gEAAgE;AAChE,eAAO,MAAM,WAAW,+BAgBvB,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,gBAAgB,+BAM5B,CAAC"}
@@ -13,6 +13,7 @@ import { gcCommand } from './commands/gc.js';
13
13
  import { exportCommand } from './commands/export.js';
14
14
  import { reconcileCommand } from './commands/reconcile.js';
15
15
  import { attemptsCommand } from './commands/attempts.js';
16
+ import { drainCommand } from './commands/drain.js';
16
17
  import { respondCommand } from './commands/respond.js';
17
18
  import { inspectCommand } from './commands/inspect.js';
18
19
  import { replayCommand } from './commands/replay.js';
@@ -53,6 +54,7 @@ export const runCommands = [
53
54
  exportCommand,
54
55
  reconcileCommand,
55
56
  attemptsCommand,
57
+ drainCommand,
56
58
  ];
57
59
  /** Top-level commands not nested under a subgroup. */
58
60
  export const topLevelCommands = [
@@ -1 +1 @@
1
- {"version":3,"file":"commands-registry.js","sourceRoot":"","sources":["../src/commands-registry.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,+EAA+E;AAC/E,6CAA6C;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,4EAA4E;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,WAAW;IACX,eAAe;IACf,eAAe;IACf,YAAY;IACZ,UAAU;IACV,WAAW;IACX,cAAc;CACf,CAAC;AAEF,gEAAgE;AAChE,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,WAAW;IACX,cAAc;IACd,aAAa;IACb,WAAW;IACX,aAAa;IACb,cAAc;IACd,cAAc;IACd,cAAc;IACd,cAAc;IACd,YAAY;IACZ,SAAS;IACT,aAAa;IACb,gBAAgB;IAChB,eAAe;CAChB,CAAC;AAEF,sDAAsD;AACtD,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,UAAU;IACV,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,aAAa;CACd,CAAC"}
1
+ {"version":3,"file":"commands-registry.js","sourceRoot":"","sources":["../src/commands-registry.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,+EAA+E;AAC/E,6CAA6C;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,4EAA4E;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,WAAW;IACX,eAAe;IACf,eAAe;IACf,YAAY;IACZ,UAAU;IACV,WAAW;IACX,cAAc;CACf,CAAC;AAEF,gEAAgE;AAChE,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,WAAW;IACX,cAAc;IACd,aAAa;IACb,WAAW;IACX,aAAa;IACb,cAAc;IACd,cAAc;IACd,cAAc;IACd,cAAc;IACd,YAAY;IACZ,SAAS;IACT,aAAa;IACb,gBAAgB;IAChB,eAAe;IACf,YAAY;CACb,CAAC;AAEF,sDAAsD;AACtD,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,UAAU;IACV,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,aAAa;CACd,CAAC"}
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import 'dotenv/config';
4
4
  import { Command } from 'commander';
5
5
  import { workflowCommands, runCommands, topLevelCommands } from './commands-registry.js';
6
6
  const program = new Command();
7
- program.name('realm').description('Realm workflow engine CLI').version('0.31.2');
7
+ program.name('realm').description('Realm workflow engine CLI').version('0.33.0');
8
8
  // realm workflow — operations on workflow definitions
9
9
  const workflowCmd = new Command('workflow').description('Manage workflow definitions');
10
10
  for (const cmd of workflowCommands)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sensigo/realm-cli",
3
- "version": "0.31.2",
3
+ "version": "0.33.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -61,9 +61,9 @@
61
61
  "vitest": "^4.1.0"
62
62
  },
63
63
  "dependencies": {
64
- "@sensigo/realm": "^0.31.2",
65
- "@sensigo/realm-mcp": "^0.31.2",
66
- "@sensigo/realm-testing": "^0.31.2",
64
+ "@sensigo/realm": "^0.33.0",
65
+ "@sensigo/realm-mcp": "^0.33.0",
66
+ "@sensigo/realm-testing": "^0.33.0",
67
67
  "@modelcontextprotocol/sdk": "1.29.0",
68
68
  "chalk": "^5.0.0",
69
69
  "commander": "^15.0.0",