@sensigo/realm 0.15.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/adapter-utils.d.ts +6 -0
- package/dist/adapters/adapter-utils.d.ts.map +1 -1
- package/dist/adapters/adapter-utils.js +21 -0
- package/dist/adapters/adapter-utils.js.map +1 -1
- package/dist/adapters/file-adapter.d.ts +1 -1
- package/dist/adapters/file-adapter.d.ts.map +1 -1
- package/dist/adapters/file-adapter.js +10 -2
- package/dist/adapters/file-adapter.js.map +1 -1
- package/dist/adapters/gorgias-adapter.d.ts +6 -4
- package/dist/adapters/gorgias-adapter.d.ts.map +1 -1
- package/dist/adapters/gorgias-adapter.js +102 -18
- package/dist/adapters/gorgias-adapter.js.map +1 -1
- package/dist/adapters/notion-adapter.d.ts +1 -0
- package/dist/adapters/notion-adapter.d.ts.map +1 -1
- package/dist/adapters/notion-adapter.js +7 -6
- package/dist/adapters/notion-adapter.js.map +1 -1
- package/dist/adapters/slack-adapter.d.ts.map +1 -1
- package/dist/adapters/slack-adapter.js +11 -0
- package/dist/adapters/slack-adapter.js.map +1 -1
- package/dist/engine/backoff.d.ts +4 -0
- package/dist/engine/backoff.d.ts.map +1 -0
- package/dist/engine/backoff.js +18 -0
- package/dist/engine/backoff.js.map +1 -0
- package/dist/engine/capability.d.ts +52 -0
- package/dist/engine/capability.d.ts.map +1 -0
- package/dist/engine/capability.js +76 -0
- package/dist/engine/capability.js.map +1 -0
- package/dist/engine/claim-liveness.d.ts +86 -0
- package/dist/engine/claim-liveness.d.ts.map +1 -0
- package/dist/engine/claim-liveness.js +108 -0
- package/dist/engine/claim-liveness.js.map +1 -0
- package/dist/engine/execution-loop.d.ts.map +1 -1
- package/dist/engine/execution-loop.js +137 -33
- package/dist/engine/execution-loop.js.map +1 -1
- package/dist/engine/reclaim-step.d.ts +37 -0
- package/dist/engine/reclaim-step.d.ts.map +1 -0
- package/dist/engine/reclaim-step.js +122 -0
- package/dist/engine/reclaim-step.js.map +1 -0
- package/dist/evidence/snapshot.d.ts +5 -0
- package/dist/evidence/snapshot.d.ts.map +1 -1
- package/dist/evidence/snapshot.js +3 -0
- package/dist/evidence/snapshot.js.map +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/store/atomic-write.d.ts +29 -0
- package/dist/store/atomic-write.d.ts.map +1 -0
- package/dist/store/atomic-write.js +51 -0
- package/dist/store/atomic-write.js.map +1 -0
- package/dist/store/json-file-store.d.ts +2 -0
- package/dist/store/json-file-store.d.ts.map +1 -1
- package/dist/store/json-file-store.js +51 -23
- package/dist/store/json-file-store.js.map +1 -1
- package/dist/store/store-interface.d.ts +9 -0
- package/dist/store/store-interface.d.ts.map +1 -1
- package/dist/types/run-record.d.ts +60 -0
- package/dist/types/run-record.d.ts.map +1 -1
- package/dist/types/workflow-definition.d.ts +10 -0
- package/dist/types/workflow-definition.d.ts.map +1 -1
- package/dist/types/workflow-error.d.ts +1 -1
- package/dist/types/workflow-error.d.ts.map +1 -1
- package/dist/types/workflow-error.js.map +1 -1
- package/dist/workflow/registrar.d.ts.map +1 -1
- package/dist/workflow/registrar.js +3 -2
- package/dist/workflow/registrar.js.map +1 -1
- package/dist/workflow/yaml-loader.js +38 -0
- package/dist/workflow/yaml-loader.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slack-adapter.js","sourceRoot":"","sources":["../../src/adapters/slack-adapter.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"slack-adapter.js","sourceRoot":"","sources":["../../src/adapters/slack-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { RetryConfig } from '../types/workflow-definition.js';
|
|
2
|
+
/** Computes the delay (ms) before a retry attempt based on the configured backoff strategy. */
|
|
3
|
+
export declare function computeBackoff(config: RetryConfig, attemptNum: number): number;
|
|
4
|
+
//# sourceMappingURL=backoff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backoff.d.ts","sourceRoot":"","sources":["../../src/engine/backoff.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAEnE,+FAA+F;AAC/F,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAe9E"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Computes the delay (ms) before a retry attempt based on the configured backoff strategy. */
|
|
2
|
+
export function computeBackoff(config, attemptNum) {
|
|
3
|
+
const backoff = config.backoff ?? 'fixed';
|
|
4
|
+
const base = config.base_delay_ms ?? 0;
|
|
5
|
+
let delay;
|
|
6
|
+
switch (backoff) {
|
|
7
|
+
case 'linear':
|
|
8
|
+
delay = base * attemptNum;
|
|
9
|
+
break;
|
|
10
|
+
case 'exponential':
|
|
11
|
+
delay = base * Math.pow(2, attemptNum - 1);
|
|
12
|
+
break;
|
|
13
|
+
default: // 'fixed'
|
|
14
|
+
delay = base;
|
|
15
|
+
}
|
|
16
|
+
return config.max_delay_ms !== undefined ? Math.min(delay, config.max_delay_ms) : delay;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=backoff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backoff.js","sourceRoot":"","sources":["../../src/engine/backoff.ts"],"names":[],"mappings":"AAOA,+FAA+F;AAC/F,MAAM,UAAU,cAAc,CAAC,MAAmB,EAAE,UAAkB;IACpE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC;IAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,aAAa,IAAI,CAAC,CAAC;IACvC,IAAI,KAAa,CAAC;IAClB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,QAAQ;YACX,KAAK,GAAG,IAAI,GAAG,UAAU,CAAC;YAC1B,MAAM;QACR,KAAK,aAAa;YAChB,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC;YAC3C,MAAM;QACR,SAAS,UAAU;YACjB,KAAK,GAAG,IAAI,CAAC;IACjB,CAAC;IACD,OAAO,MAAM,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC1F,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { WorkflowDefinition, StepDefinition } from '../types/workflow-definition.js';
|
|
2
|
+
import type { RunRecord } from '../types/run-record.js';
|
|
3
|
+
import type { ExtensionRegistry } from '../extensions/registry.js';
|
|
4
|
+
/** The single handler/adapter an auto step requires. `step` is the step name (StepDefinition carries none). */
|
|
5
|
+
export interface Requirement {
|
|
6
|
+
step: string;
|
|
7
|
+
kind: 'handler' | 'adapter';
|
|
8
|
+
name: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The capability requirement a step imposes on the executing registry, or `undefined` if it imposes none.
|
|
12
|
+
*
|
|
13
|
+
* Mirrors the dispatch precedence in the execution loop EXACTLY (uses_service → adapter; else handler),
|
|
14
|
+
* and ONLY for `execution: 'auto'` steps — agent/guard/finalizer steps and the built-in agent dispatcher
|
|
15
|
+
* impose no registry requirement. For an adapter step whose service is absent from `definition.services`,
|
|
16
|
+
* returns `undefined`: that is a workflow-authoring bug surfaced elsewhere (service-not-found), not a
|
|
17
|
+
* capability gap the runner can fix by registering an adapter.
|
|
18
|
+
*/
|
|
19
|
+
export declare function requirementForStep(step: string, stepDef: StepDefinition, definition: WorkflowDefinition): Requirement | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Part B pre-flight: the auto-step requirements the given registry CANNOT satisfy. Pure — `registry.has`
|
|
22
|
+
* is a Map lookup, no dispatch. Callers WARN on a non-empty result at run creation; they never REFUSE
|
|
23
|
+
* (a run can be created against one runner and executed by a differently-provisioned one — see #134).
|
|
24
|
+
*/
|
|
25
|
+
export declare function unmetCapabilities(definition: WorkflowDefinition, registry: ExtensionRegistry): Requirement[];
|
|
26
|
+
/**
|
|
27
|
+
* Advisory warning line for one unmet capability — shared by every run-creating path (#134) so the
|
|
28
|
+
* pre-flight warning phrasing can never drift between start_run, start_run_batch, CLI run, and the
|
|
29
|
+
* run-agent create path. Advisory ONLY: names the gap and its recoverable consequence; never a refusal.
|
|
30
|
+
*/
|
|
31
|
+
export declare function capabilityWarning(requirement: Requirement): string;
|
|
32
|
+
/** A capability-blocked step surfaced by {@link findCapabilityBlockedSteps}. */
|
|
33
|
+
export interface CapabilityBlockInfo {
|
|
34
|
+
step: string;
|
|
35
|
+
requirement: {
|
|
36
|
+
kind: 'handler' | 'adapter';
|
|
37
|
+
name: string;
|
|
38
|
+
};
|
|
39
|
+
code: string;
|
|
40
|
+
at: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Part A recovery detection: steps parked by a mid-run not-registered failure that are STILL eligible.
|
|
44
|
+
*
|
|
45
|
+
* Definition-free by design — reads only `capability_blocks` and the four step sets. A marker is reported
|
|
46
|
+
* only when its step is eligible-but-unclaimed (∉ completed ∪ in_progress ∪ failed ∪ skipped). This
|
|
47
|
+
* cross-check makes a stale marker self-suppress: if the step has since completed (or been claimed) on a
|
|
48
|
+
* correctly-provisioned runner, its marker is silently ignored, so CLEARING the marker on recovery is
|
|
49
|
+
* hygiene, not correctness. Returns [] for legacy/capability-clean records (no `capability_blocks`).
|
|
50
|
+
*/
|
|
51
|
+
export declare function findCapabilityBlockedSteps(run: RunRecord): CapabilityBlockInfo[];
|
|
52
|
+
//# sourceMappingURL=capability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../../src/engine/capability.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAC1F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,+GAA+G;AAC/G,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,GAAG,SAAS,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,EACvB,UAAU,EAAE,kBAAkB,GAC7B,WAAW,GAAG,SAAS,CAWzB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,kBAAkB,EAC9B,QAAQ,EAAE,iBAAiB,GAC1B,WAAW,EAAE,CASf;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAMlE;AAED,gFAAgF;AAChF,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE;QAAE,IAAI,EAAE,SAAS,GAAG,SAAS,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,SAAS,GAAG,mBAAmB,EAAE,CAehF"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The capability requirement a step imposes on the executing registry, or `undefined` if it imposes none.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the dispatch precedence in the execution loop EXACTLY (uses_service → adapter; else handler),
|
|
5
|
+
* and ONLY for `execution: 'auto'` steps — agent/guard/finalizer steps and the built-in agent dispatcher
|
|
6
|
+
* impose no registry requirement. For an adapter step whose service is absent from `definition.services`,
|
|
7
|
+
* returns `undefined`: that is a workflow-authoring bug surfaced elsewhere (service-not-found), not a
|
|
8
|
+
* capability gap the runner can fix by registering an adapter.
|
|
9
|
+
*/
|
|
10
|
+
export function requirementForStep(step, stepDef, definition) {
|
|
11
|
+
if (stepDef.execution !== 'auto')
|
|
12
|
+
return undefined;
|
|
13
|
+
if (stepDef.uses_service !== undefined) {
|
|
14
|
+
const service = definition.services?.[stepDef.uses_service];
|
|
15
|
+
if (service === undefined)
|
|
16
|
+
return undefined;
|
|
17
|
+
return { step, kind: 'adapter', name: service.adapter };
|
|
18
|
+
}
|
|
19
|
+
if (stepDef.handler !== undefined) {
|
|
20
|
+
return { step, kind: 'handler', name: stepDef.handler };
|
|
21
|
+
}
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Part B pre-flight: the auto-step requirements the given registry CANNOT satisfy. Pure — `registry.has`
|
|
26
|
+
* is a Map lookup, no dispatch. Callers WARN on a non-empty result at run creation; they never REFUSE
|
|
27
|
+
* (a run can be created against one runner and executed by a differently-provisioned one — see #134).
|
|
28
|
+
*/
|
|
29
|
+
export function unmetCapabilities(definition, registry) {
|
|
30
|
+
const unmet = [];
|
|
31
|
+
for (const [step, stepDef] of Object.entries(definition.steps)) {
|
|
32
|
+
const requirement = requirementForStep(step, stepDef, definition);
|
|
33
|
+
if (requirement !== undefined && !registry.has(requirement.kind, requirement.name)) {
|
|
34
|
+
unmet.push(requirement);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return unmet;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Advisory warning line for one unmet capability — shared by every run-creating path (#134) so the
|
|
41
|
+
* pre-flight warning phrasing can never drift between start_run, start_run_batch, CLI run, and the
|
|
42
|
+
* run-agent create path. Advisory ONLY: names the gap and its recoverable consequence; never a refusal.
|
|
43
|
+
*/
|
|
44
|
+
export function capabilityWarning(requirement) {
|
|
45
|
+
return (`Step '${requirement.step}' needs ${requirement.kind} '${requirement.name}', which is not ` +
|
|
46
|
+
`registered in this runner. If reached it will block recoverably (not fail) until a runner that ` +
|
|
47
|
+
`provides this ${requirement.kind} executes it — load the missing extension or run on a capable runner.`);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Part A recovery detection: steps parked by a mid-run not-registered failure that are STILL eligible.
|
|
51
|
+
*
|
|
52
|
+
* Definition-free by design — reads only `capability_blocks` and the four step sets. A marker is reported
|
|
53
|
+
* only when its step is eligible-but-unclaimed (∉ completed ∪ in_progress ∪ failed ∪ skipped). This
|
|
54
|
+
* cross-check makes a stale marker self-suppress: if the step has since completed (or been claimed) on a
|
|
55
|
+
* correctly-provisioned runner, its marker is silently ignored, so CLEARING the marker on recovery is
|
|
56
|
+
* hygiene, not correctness. Returns [] for legacy/capability-clean records (no `capability_blocks`).
|
|
57
|
+
*/
|
|
58
|
+
export function findCapabilityBlockedSteps(run) {
|
|
59
|
+
const blocks = run.capability_blocks;
|
|
60
|
+
if (blocks === undefined)
|
|
61
|
+
return [];
|
|
62
|
+
const settled = new Set([
|
|
63
|
+
...run.completed_steps,
|
|
64
|
+
...run.in_progress_steps,
|
|
65
|
+
...run.failed_steps,
|
|
66
|
+
...run.skipped_steps,
|
|
67
|
+
]);
|
|
68
|
+
const blocked = [];
|
|
69
|
+
for (const [step, block] of Object.entries(blocks)) {
|
|
70
|
+
if (settled.has(step))
|
|
71
|
+
continue;
|
|
72
|
+
blocked.push({ step, requirement: block.requirement, code: block.code, at: block.at });
|
|
73
|
+
}
|
|
74
|
+
return blocked;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=capability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability.js","sourceRoot":"","sources":["../../src/engine/capability.ts"],"names":[],"mappings":"AAqBA;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,OAAuB,EACvB,UAA8B;IAE9B,IAAI,OAAO,CAAC,SAAS,KAAK,MAAM;QAAE,OAAO,SAAS,CAAC;IACnD,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAC5D,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC5C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;IAC1D,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAClC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;IAC1D,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,UAA8B,EAC9B,QAA2B;IAE3B,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/D,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QAClE,IAAI,WAAW,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACnF,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAwB;IACxD,OAAO,CACL,SAAS,WAAW,CAAC,IAAI,WAAW,WAAW,CAAC,IAAI,KAAK,WAAW,CAAC,IAAI,kBAAkB;QAC3F,iGAAiG;QACjG,iBAAiB,WAAW,CAAC,IAAI,uEAAuE,CACzG,CAAC;AACJ,CAAC;AAUD;;;;;;;;GAQG;AACH,MAAM,UAAU,0BAA0B,CAAC,GAAc;IACvD,MAAM,MAAM,GAAG,GAAG,CAAC,iBAAiB,CAAC;IACrC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS;QAC9B,GAAG,GAAG,CAAC,eAAe;QACtB,GAAG,GAAG,CAAC,iBAAiB;QACxB,GAAG,GAAG,CAAC,YAAY;QACnB,GAAG,GAAG,CAAC,aAAa;KACrB,CAAC,CAAC;IACH,MAAM,OAAO,GAA0B,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QAChC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { RunRecord, ClaimRecord } from '../types/run-record.js';
|
|
2
|
+
import type { WorkflowDefinition, StepDefinition } from '../types/workflow-definition.js';
|
|
3
|
+
/**
|
|
4
|
+
* Default execution timeout (issue A3) enforced on every `execution: 'auto'` step that declares no
|
|
5
|
+
* `timeout_seconds` — bounds a hung adapter/handler call so it fails loudly (`STEP_TIMEOUT`)
|
|
6
|
+
* instead of pinning the runner forever. Generous (1 hour, GitHub-Actions-style): it guards against
|
|
7
|
+
* a genuine hang, not normal-operation latency. Also now the basis of the claim-deadline DETECTION
|
|
8
|
+
* horizon in `computeClaimDeadline` below, so detection tracks the real enforcement bound. See
|
|
9
|
+
* plans/execution-timeout-a3-design.md for the full rationale.
|
|
10
|
+
*/
|
|
11
|
+
export declare const DEFAULT_EXECUTION_TIMEOUT_SECONDS = 3600;
|
|
12
|
+
/**
|
|
13
|
+
* Whether `step`'s dispatch must be bounded by a timeout (issue A3). Pure: `execution === 'auto'`,
|
|
14
|
+
* period. Deliberately NOT conjoined with `hasFinalizers` — that conjunct is correct for
|
|
15
|
+
* *detection*'s claim horizon below (a claim may legitimately be held through a finalizer drain),
|
|
16
|
+
* but would be WRONG for *enforcement*: it would leave every auto step in a finalizer-bearing
|
|
17
|
+
* workflow completely unbounded — the exact hang this feature exists to prevent. Do NOT re-add a
|
|
18
|
+
* `hasFinalizers`/finalizer conjunct here (this split was the Design Reviewer's blocking-fix).
|
|
19
|
+
*/
|
|
20
|
+
export declare function shouldEnforceTimeout(step: StepDefinition): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* @deprecated Superseded by `DEFAULT_EXECUTION_TIMEOUT_SECONDS`; retained for API compatibility.
|
|
23
|
+
* Assumed handler wall-clock bound when a step declares no `timeout_seconds`. Biased large.
|
|
24
|
+
*/
|
|
25
|
+
export declare const DEFAULT_STEP_TIMEOUT_SECONDS = 300;
|
|
26
|
+
/** Added to a step's `timeout_seconds` to absorb scheduling / clock skew before a claim is stale. */
|
|
27
|
+
export declare const RECLAIM_MARGIN_SECONDS = 60;
|
|
28
|
+
/**
|
|
29
|
+
* Minimum staleness horizon. A concrete claim is never `claim_stale` sooner than this, even for a
|
|
30
|
+
* fast handler — so a live-but-slow runner is not mislabeled. Biased large: too-large only delays
|
|
31
|
+
* the label (Phase 1 gates no action); too-small risks flagging live work. (Concrete deadlines are
|
|
32
|
+
* set ONLY for finalizer-free auto steps, so the worst-case finalizer-drain span never applies to a
|
|
33
|
+
* deadline-carrying claim — finalizer-bearing steps get `deadline: null` → `claim_unknown_age`.)
|
|
34
|
+
*/
|
|
35
|
+
export declare const RECLAIM_FLOOR_SECONDS = 900;
|
|
36
|
+
/**
|
|
37
|
+
* Computes the claim deadline for `stepName` at claim time. A CONCRETE deadline is returned ONLY
|
|
38
|
+
* for a reliably time-boundable claim: an `execution: 'auto'` (handler-driven) step in a workflow
|
|
39
|
+
* with NO `execution: 'finalizer'` steps (so no finalizer drain can legitimately extend the claim
|
|
40
|
+
* past the seal). Every other claim returns `null` (→ `claim_unknown_age`): agent steps have no
|
|
41
|
+
* reliable wall-clock bound (the dispatcher returns instantly; `timeout_seconds` is advisory), and
|
|
42
|
+
* any step in a finalizer-bearing workflow may hold its claim through the terminal drain.
|
|
43
|
+
*
|
|
44
|
+
* The horizon is the WORST-CASE wall-clock across every retry attempt (issue #101 follow-up —
|
|
45
|
+
* Design Reviewer finding #4 from the A3 debate): a single-attempt bound understates a retrying
|
|
46
|
+
* step's real claim span (`max_attempts × per-attempt-timeout + the declared backoffs between
|
|
47
|
+
* attempts`), so a legitimately-retrying step could be labeled `claim_stale` — and, if
|
|
48
|
+
* `idempotent`, become eligible for a premature `realm run reclaim --all --force` re-drive —
|
|
49
|
+
* while still on an early attempt. For `n = 1` (no `retry:`, or `max_attempts: 1`) this reduces
|
|
50
|
+
* EXACTLY to the prior single-attempt formula `max(RECLAIM_FLOOR, perAttemptSec + MARGIN)`, so
|
|
51
|
+
* non-retry steps' horizons are byte-unchanged. This uses the DECLARED backoff schedule only — a
|
|
52
|
+
* runtime `retry_after` (rate-limit 429 override, applied in execution-loop.ts) is not knowable at
|
|
53
|
+
* claim time; the horizon stays a best-effort, floored, advisory bound (Phase 1 gates no action on
|
|
54
|
+
* this label) and does not attempt to model `retry_after`.
|
|
55
|
+
*/
|
|
56
|
+
export declare function computeClaimDeadline(definition: WorkflowDefinition, stepName: string, now: Date): string | null;
|
|
57
|
+
/**
|
|
58
|
+
* Returns a NEW claims record with `stepName` removed (a fresh object — never mutates the input,
|
|
59
|
+
* so it is safe to use on a value spread from the prior record). Used at the settle/seal sites to
|
|
60
|
+
* delete the claim clock in the SAME record mutation that removes the step from
|
|
61
|
+
* `in_progress_steps`. Returns `{}` when the last claim is removed (harmless; detection ignores a
|
|
62
|
+
* run with no in-progress steps). A missed delete self-heals: `claimStep` overwrites `claims[S]`.
|
|
63
|
+
*/
|
|
64
|
+
export declare function omitClaim(claims: Record<string, ClaimRecord> | undefined, stepName: string): Record<string, ClaimRecord>;
|
|
65
|
+
/**
|
|
66
|
+
* The 3-state liveness classification of a single in-progress claim (issue #101):
|
|
67
|
+
* - `healthy` — a concrete deadline that has not yet passed (a live runner is presumed on it).
|
|
68
|
+
* - `claim_stale` — a concrete deadline that has passed (the runner is presumed dead).
|
|
69
|
+
* - `claim_unknown_age` — no claim record, or a `null` deadline (agent / finalizer-bearing /
|
|
70
|
+
* legacy run). Detect-only, human-judged, NEVER auto-reclaimed.
|
|
71
|
+
*/
|
|
72
|
+
export type ClaimState = 'healthy' | 'claim_stale' | 'claim_unknown_age';
|
|
73
|
+
/** Classifies a single claim record against `now`. Definition-free (reads only the stored deadline). */
|
|
74
|
+
export declare function classifyClaim(claim: ClaimRecord | undefined, now: Date): ClaimState;
|
|
75
|
+
/** A classified in-progress claim: the step, its liveness state, and its stored deadline. */
|
|
76
|
+
export interface InProgressClaimInfo {
|
|
77
|
+
step: string;
|
|
78
|
+
state: ClaimState;
|
|
79
|
+
deadline: string | null;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Classifies every in-progress claim on a run. Definition-free — works even when the workflow
|
|
83
|
+
* definition is unresolved (detection reads the stored per-claim deadline, not the definition).
|
|
84
|
+
*/
|
|
85
|
+
export declare function classifyInProgressClaims(run: RunRecord, now?: Date): InProgressClaimInfo[];
|
|
86
|
+
//# sourceMappingURL=claim-liveness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claim-liveness.d.ts","sourceRoot":"","sources":["../../src/engine/claim-liveness.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAG1F;;;;;;;GAOG;AACH,eAAO,MAAM,iCAAiC,OAAO,CAAC;AAEtD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAElE;AAKD;;;GAGG;AACH,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAChD,qGAAqG;AACrG,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,kBAAkB,EAC9B,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,IAAI,GACR,MAAM,GAAG,IAAI,CAgBf;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,SAAS,EAC/C,QAAQ,EAAE,MAAM,GACf,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAI7B;AAED;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,mBAAmB,CAAC;AAEzE,wGAAwG;AACxG,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,EAAE,GAAG,EAAE,IAAI,GAAG,UAAU,CAGnF;AAED,6FAA6F;AAC7F,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,SAAS,EACd,GAAG,GAAE,IAAiB,GACrB,mBAAmB,EAAE,CAKvB"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { computeBackoff } from './backoff.js';
|
|
2
|
+
/**
|
|
3
|
+
* Default execution timeout (issue A3) enforced on every `execution: 'auto'` step that declares no
|
|
4
|
+
* `timeout_seconds` — bounds a hung adapter/handler call so it fails loudly (`STEP_TIMEOUT`)
|
|
5
|
+
* instead of pinning the runner forever. Generous (1 hour, GitHub-Actions-style): it guards against
|
|
6
|
+
* a genuine hang, not normal-operation latency. Also now the basis of the claim-deadline DETECTION
|
|
7
|
+
* horizon in `computeClaimDeadline` below, so detection tracks the real enforcement bound. See
|
|
8
|
+
* plans/execution-timeout-a3-design.md for the full rationale.
|
|
9
|
+
*/
|
|
10
|
+
export const DEFAULT_EXECUTION_TIMEOUT_SECONDS = 3600; // 1 hour
|
|
11
|
+
/**
|
|
12
|
+
* Whether `step`'s dispatch must be bounded by a timeout (issue A3). Pure: `execution === 'auto'`,
|
|
13
|
+
* period. Deliberately NOT conjoined with `hasFinalizers` — that conjunct is correct for
|
|
14
|
+
* *detection*'s claim horizon below (a claim may legitimately be held through a finalizer drain),
|
|
15
|
+
* but would be WRONG for *enforcement*: it would leave every auto step in a finalizer-bearing
|
|
16
|
+
* workflow completely unbounded — the exact hang this feature exists to prevent. Do NOT re-add a
|
|
17
|
+
* `hasFinalizers`/finalizer conjunct here (this split was the Design Reviewer's blocking-fix).
|
|
18
|
+
*/
|
|
19
|
+
export function shouldEnforceTimeout(step) {
|
|
20
|
+
return step.execution === 'auto';
|
|
21
|
+
}
|
|
22
|
+
// --- Deadline constants (Phase 1: the deadline drives the DETECTION DISPLAY only; it gates no
|
|
23
|
+
// action, so a too-large horizon merely delays a `claim_stale` label — bias LARGE).
|
|
24
|
+
/**
|
|
25
|
+
* @deprecated Superseded by `DEFAULT_EXECUTION_TIMEOUT_SECONDS`; retained for API compatibility.
|
|
26
|
+
* Assumed handler wall-clock bound when a step declares no `timeout_seconds`. Biased large.
|
|
27
|
+
*/
|
|
28
|
+
export const DEFAULT_STEP_TIMEOUT_SECONDS = 300; // 5 min
|
|
29
|
+
/** Added to a step's `timeout_seconds` to absorb scheduling / clock skew before a claim is stale. */
|
|
30
|
+
export const RECLAIM_MARGIN_SECONDS = 60; // 1 min
|
|
31
|
+
/**
|
|
32
|
+
* Minimum staleness horizon. A concrete claim is never `claim_stale` sooner than this, even for a
|
|
33
|
+
* fast handler — so a live-but-slow runner is not mislabeled. Biased large: too-large only delays
|
|
34
|
+
* the label (Phase 1 gates no action); too-small risks flagging live work. (Concrete deadlines are
|
|
35
|
+
* set ONLY for finalizer-free auto steps, so the worst-case finalizer-drain span never applies to a
|
|
36
|
+
* deadline-carrying claim — finalizer-bearing steps get `deadline: null` → `claim_unknown_age`.)
|
|
37
|
+
*/
|
|
38
|
+
export const RECLAIM_FLOOR_SECONDS = 900; // 15 min
|
|
39
|
+
/**
|
|
40
|
+
* Computes the claim deadline for `stepName` at claim time. A CONCRETE deadline is returned ONLY
|
|
41
|
+
* for a reliably time-boundable claim: an `execution: 'auto'` (handler-driven) step in a workflow
|
|
42
|
+
* with NO `execution: 'finalizer'` steps (so no finalizer drain can legitimately extend the claim
|
|
43
|
+
* past the seal). Every other claim returns `null` (→ `claim_unknown_age`): agent steps have no
|
|
44
|
+
* reliable wall-clock bound (the dispatcher returns instantly; `timeout_seconds` is advisory), and
|
|
45
|
+
* any step in a finalizer-bearing workflow may hold its claim through the terminal drain.
|
|
46
|
+
*
|
|
47
|
+
* The horizon is the WORST-CASE wall-clock across every retry attempt (issue #101 follow-up —
|
|
48
|
+
* Design Reviewer finding #4 from the A3 debate): a single-attempt bound understates a retrying
|
|
49
|
+
* step's real claim span (`max_attempts × per-attempt-timeout + the declared backoffs between
|
|
50
|
+
* attempts`), so a legitimately-retrying step could be labeled `claim_stale` — and, if
|
|
51
|
+
* `idempotent`, become eligible for a premature `realm run reclaim --all --force` re-drive —
|
|
52
|
+
* while still on an early attempt. For `n = 1` (no `retry:`, or `max_attempts: 1`) this reduces
|
|
53
|
+
* EXACTLY to the prior single-attempt formula `max(RECLAIM_FLOOR, perAttemptSec + MARGIN)`, so
|
|
54
|
+
* non-retry steps' horizons are byte-unchanged. This uses the DECLARED backoff schedule only — a
|
|
55
|
+
* runtime `retry_after` (rate-limit 429 override, applied in execution-loop.ts) is not knowable at
|
|
56
|
+
* claim time; the horizon stays a best-effort, floored, advisory bound (Phase 1 gates no action on
|
|
57
|
+
* this label) and does not attempt to model `retry_after`.
|
|
58
|
+
*/
|
|
59
|
+
export function computeClaimDeadline(definition, stepName, now) {
|
|
60
|
+
const step = definition.steps[stepName];
|
|
61
|
+
if (step === undefined)
|
|
62
|
+
return null;
|
|
63
|
+
const hasFinalizers = Object.values(definition.steps).some((s) => s.execution === 'finalizer');
|
|
64
|
+
if (step.execution !== 'auto' || hasFinalizers)
|
|
65
|
+
return null;
|
|
66
|
+
const n = step.retry?.max_attempts ?? 1;
|
|
67
|
+
const perAttemptSec = step.timeout_seconds ?? DEFAULT_EXECUTION_TIMEOUT_SECONDS;
|
|
68
|
+
// Backoffs occur BETWEEN attempts: n-1 of them, for attemptNum 1..n-1 (matches the retry loop's
|
|
69
|
+
// schedule in execution-loop.ts). computeBackoff returns ms; the horizon is seconds.
|
|
70
|
+
let backoffSec = 0;
|
|
71
|
+
if (step.retry !== undefined) {
|
|
72
|
+
for (let a = 1; a < n; a++)
|
|
73
|
+
backoffSec += computeBackoff(step.retry, a) / 1000;
|
|
74
|
+
}
|
|
75
|
+
const worstCaseSec = n * perAttemptSec + backoffSec;
|
|
76
|
+
const horizonSeconds = Math.max(RECLAIM_FLOOR_SECONDS, worstCaseSec + RECLAIM_MARGIN_SECONDS);
|
|
77
|
+
return new Date(now.getTime() + horizonSeconds * 1000).toISOString();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Returns a NEW claims record with `stepName` removed (a fresh object — never mutates the input,
|
|
81
|
+
* so it is safe to use on a value spread from the prior record). Used at the settle/seal sites to
|
|
82
|
+
* delete the claim clock in the SAME record mutation that removes the step from
|
|
83
|
+
* `in_progress_steps`. Returns `{}` when the last claim is removed (harmless; detection ignores a
|
|
84
|
+
* run with no in-progress steps). A missed delete self-heals: `claimStep` overwrites `claims[S]`.
|
|
85
|
+
*/
|
|
86
|
+
export function omitClaim(claims, stepName) {
|
|
87
|
+
if (claims === undefined)
|
|
88
|
+
return {};
|
|
89
|
+
const { [stepName]: _removed, ...rest } = claims;
|
|
90
|
+
return rest;
|
|
91
|
+
}
|
|
92
|
+
/** Classifies a single claim record against `now`. Definition-free (reads only the stored deadline). */
|
|
93
|
+
export function classifyClaim(claim, now) {
|
|
94
|
+
if (claim === undefined || claim.deadline === null)
|
|
95
|
+
return 'claim_unknown_age';
|
|
96
|
+
return now.getTime() > new Date(claim.deadline).getTime() ? 'claim_stale' : 'healthy';
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Classifies every in-progress claim on a run. Definition-free — works even when the workflow
|
|
100
|
+
* definition is unresolved (detection reads the stored per-claim deadline, not the definition).
|
|
101
|
+
*/
|
|
102
|
+
export function classifyInProgressClaims(run, now = new Date()) {
|
|
103
|
+
return run.in_progress_steps.map((step) => {
|
|
104
|
+
const claim = run.claims?.[step];
|
|
105
|
+
return { step, state: classifyClaim(claim, now), deadline: claim?.deadline ?? null };
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=claim-liveness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claim-liveness.js","sourceRoot":"","sources":["../../src/engine/claim-liveness.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-loop.d.ts","sourceRoot":"","sources":["../../src/engine/execution-loop.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,SAAS,EAIT,eAAe,EAChB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EACV,kBAAkB,
|
|
1
|
+
{"version":3,"file":"execution-loop.d.ts","sourceRoot":"","sources":["../../src/engine/execution-loop.ts"],"names":[],"mappings":"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"}
|