@sensigo/realm 0.37.0 → 0.39.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 +31 -0
- package/dist/adapters/adapter-utils.d.ts.map +1 -1
- package/dist/adapters/adapter-utils.js +16 -0
- package/dist/adapters/adapter-utils.js.map +1 -1
- package/dist/adapters/airtable-adapter.d.ts.map +1 -1
- package/dist/adapters/airtable-adapter.js +25 -14
- package/dist/adapters/airtable-adapter.js.map +1 -1
- package/dist/adapters/gorgias-adapter.d.ts.map +1 -1
- package/dist/adapters/gorgias-adapter.js +7 -3
- package/dist/adapters/gorgias-adapter.js.map +1 -1
- package/dist/adapters/notion-adapter.d.ts.map +1 -1
- package/dist/adapters/notion-adapter.js +10 -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 +8 -2
- package/dist/adapters/slack-adapter.js.map +1 -1
- package/dist/engine/abandon-run.d.ts.map +1 -1
- package/dist/engine/abandon-run.js +5 -7
- package/dist/engine/abandon-run.js.map +1 -1
- package/dist/engine/apply-resume.d.ts.map +1 -1
- package/dist/engine/apply-resume.js +13 -1
- package/dist/engine/apply-resume.js.map +1 -1
- package/dist/engine/eligibility.d.ts +109 -2
- package/dist/engine/eligibility.d.ts.map +1 -1
- package/dist/engine/eligibility.js +306 -16
- package/dist/engine/eligibility.js.map +1 -1
- package/dist/engine/execution-loop.d.ts.map +1 -1
- package/dist/engine/execution-loop.js +199 -34
- package/dist/engine/execution-loop.js.map +1 -1
- package/dist/engine/run-health.d.ts.map +1 -1
- package/dist/engine/run-health.js.map +1 -1
- package/dist/engine/settlement.d.ts +61 -6
- package/dist/engine/settlement.d.ts.map +1 -1
- package/dist/engine/settlement.js +190 -25
- package/dist/engine/settlement.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -2
- package/dist/index.js.map +1 -1
- package/dist/store/json-file-store.d.ts +9 -2
- package/dist/store/json-file-store.d.ts.map +1 -1
- package/dist/store/json-file-store.js +76 -0
- package/dist/store/json-file-store.js.map +1 -1
- package/dist/store/seal-integrity.d.ts +9 -0
- package/dist/store/seal-integrity.d.ts.map +1 -0
- package/dist/store/seal-integrity.js +249 -0
- package/dist/store/seal-integrity.js.map +1 -0
- package/dist/store/store-interface.d.ts +47 -2
- package/dist/store/store-interface.d.ts.map +1 -1
- package/dist/types/run-record.d.ts +123 -6
- package/dist/types/run-record.d.ts.map +1 -1
- package/dist/types/run-record.js +25 -1
- package/dist/types/run-record.js.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/diagnostics.d.ts +10 -0
- package/dist/workflow/diagnostics.d.ts.map +1 -1
- package/dist/workflow/diagnostics.js +1 -1
- package/dist/workflow/diagnostics.js.map +1 -1
- package/dist/workflow/yaml-loader.d.ts.map +1 -1
- package/dist/workflow/yaml-loader.js +141 -1
- package/dist/workflow/yaml-loader.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-health.d.ts","sourceRoot":"","sources":["../../src/engine/run-health.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-health.d.ts","sourceRoot":"","sources":["../../src/engine/run-health.ts"],"names":[],"mappings":"AA2FA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAK1E;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,QAAsB,CAAC;AAE7D;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EACA,oBAAoB,GACpB,aAAa,GACb,qBAAqB,GACrB,kBAAkB,GAClB,4BAA4B,GAE5B,0BAA0B,GAC1B,iBAAiB,GACjB,mCAAmC,GAGnC,6BAA6B,GAM7B,6BAA6B,GAQ7B,8BAA8B,CAAC;IACnC;6DACyD;IACzD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;yCAEqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf;;;;4DAIwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;kDAC8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;mEAG+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAoHD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,SAAS,EACd,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,IAAI,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,kBAAkB,CAAA;CAAE,GAC/E,gBAAgB,EAAE,CAwKpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-health.js","sourceRoot":"","sources":["../../src/engine/run-health.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-health.js","sourceRoot":"","sources":["../../src/engine/run-health.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RunRecord } from '../types/run-record.js';
|
|
1
|
+
import type { RunRecord, EvidenceSnapshot } from '../types/run-record.js';
|
|
2
2
|
import type { WorkflowDefinition, FinalizerTrigger } from '../types/workflow-definition.js';
|
|
3
3
|
import type { SettlementDelta, SettlementResult, SettleStepOutcome } from '../types/settlement.js';
|
|
4
4
|
/**
|
|
@@ -27,22 +27,77 @@ export declare function selectFinalizers(definition: WorkflowDefinition, settled
|
|
|
27
27
|
/**
|
|
28
28
|
* Derives the full set of finalizer triggers a terminal `outcome` satisfies for `record` (issue
|
|
29
29
|
* #302, design record §Mechanics-1): `{outcome}` — always — plus `'completed_with_failed_steps'`
|
|
30
|
-
* when `outcome === 'complete' ∧ record.failed_steps.length > 0` (a "mixed complete" seal
|
|
31
|
-
*
|
|
32
|
-
*
|
|
30
|
+
* when `outcome === 'complete' ∧ record.failed_steps.length > 0` (a "mixed complete" seal).
|
|
31
|
+
*
|
|
32
|
+
* TWO SURFACES, ONE SHAPE, TWO MOMENTS. #304's `completed_with_failed_steps` run-health finding
|
|
33
|
+
* tests the same SHAPE (completed ∧ non-empty `failed_steps`), but it tests it at READ time on
|
|
34
|
+
* the final record, whereas this function is evaluated at MINT time, inside
|
|
35
|
+
* `applyTerminalPostconditions`, before any finalizer has run. There is no shared function and no
|
|
36
|
+
* shared evaluation point — only a shared shape.
|
|
37
|
+
*
|
|
38
|
+
* The moment is what separates them, on a real population: a finalizer's OWN failure joins
|
|
39
|
+
* `failed_steps` after the seal minted (see the failed arm below, where `delta.finalizer` is
|
|
40
|
+
* appended), so a run that completes CLEAN and whose finalizer then fails is seen by the
|
|
41
|
+
* read-time finding and was never seen by this trigger — the record it read had an empty
|
|
42
|
+
* `failed_steps`. The divergence runs one way only: `failed_steps` only grows, so everything this
|
|
43
|
+
* trigger fires on the finding also reports, and the finding additionally reports post-mint
|
|
44
|
+
* finalizer self-failures. Tracked at #374 (P5); this comment describes what the code does today
|
|
45
|
+
* and does not prejudge what that issue decides.
|
|
33
46
|
*
|
|
34
47
|
* Uniform across epochs (design record M1, deliberate): a second-epoch complete seal whose ONLY
|
|
35
48
|
* `failed_steps` scar is a PRIOR epoch's finalizer self-failure (unresumable, so it never leaves
|
|
36
49
|
* `failed_steps`) still fires this trigger — no exclusion of finalizer-declared step names. The
|
|
37
50
|
* alternative (excluding finalizer names from the predicate) buys mint-time purity at the cost of
|
|
38
|
-
*
|
|
39
|
-
*
|
|
51
|
+
* making the two surfaces disagree about a shape they can both see, which is a second divergence
|
|
52
|
+
* on top of the one above.
|
|
40
53
|
*
|
|
41
54
|
* Pure; this ONE function is the seam a future authorable tolerance threshold (SFN-style: fire
|
|
42
55
|
* only when `failed_steps.length` exceeds some declared N) would extend — banked, not built
|
|
43
56
|
* (design record R2).
|
|
44
57
|
*/
|
|
45
58
|
export declare function deriveEffectiveTriggers(outcome: SettleStepOutcome, record: Pick<RunRecord, 'failed_steps'>): ReadonlySet<FinalizerTrigger>;
|
|
59
|
+
/**
|
|
60
|
+
* Renders the run-level cause for a run with MORE THAN ONE distinct failed step (issue #373).
|
|
61
|
+
*
|
|
62
|
+
* PRECONDITION — callers gate on `new Set(failedSteps).size > 1`. That gate is about which
|
|
63
|
+
* sentence SHAPE a call site wants, not about grammar safety: the single-failure sentence is each
|
|
64
|
+
* call site's own template (`Step 'a' failed: …`, `Guard step 'g' failed: …`), left where it is so
|
|
65
|
+
* there is exactly one spelling of each. Output below is grammatical at any count.
|
|
66
|
+
*
|
|
67
|
+
* The defect it fixes: `failed_steps` is append-ordered by settlement commit, so naming one step
|
|
68
|
+
* as THE cause named whichever failure settled LAST — and under true concurrency the lock race
|
|
69
|
+
* decided the culprit. The sentence below is order-independent by construction:
|
|
70
|
+
*
|
|
71
|
+
* - **dedup, then sort lexically.** A domain step cannot appear twice today, but the post-seal
|
|
72
|
+
* finalizer append across resume epochs has never been executed for duplication — dedup makes
|
|
73
|
+
* the count honest either way. Sorting is the order rule (Tekton `sort.Strings`, rustc
|
|
74
|
+
* `error_codes.sort()`); array order IS settle order, the instability this fix exists to kill.
|
|
75
|
+
* - **count first, no culprit, terminating verb.** The count is the one fact true regardless of
|
|
76
|
+
* order.
|
|
77
|
+
* - **a missing message yields a bare step name.** Never fabricated — the string `undefined` must
|
|
78
|
+
* not be constructible here.
|
|
79
|
+
*/
|
|
80
|
+
export declare function renderFailCause(failedSteps: readonly string[], messages: ReadonlyMap<string, string>): string;
|
|
81
|
+
/**
|
|
82
|
+
* Last-`error`-snapshot-per-step, in one linear pass — the same last-per-step idiom
|
|
83
|
+
* `buildSettlementNamespace` already ships. `EvidenceSnapshot.error` is stored VERBATIM by
|
|
84
|
+
* `captureEvidence`, so these are the real per-step messages, not a reconstruction.
|
|
85
|
+
*
|
|
86
|
+
* A step can hold several error snapshots (retries, resume epochs); the LAST one is the message
|
|
87
|
+
* that describes the failure the record currently carries.
|
|
88
|
+
*/
|
|
89
|
+
export declare function failureMessagesFromEvidence(evidence: readonly EvidenceSnapshot[]): Map<string, string>;
|
|
90
|
+
/**
|
|
91
|
+
* The evidence walk plus the call site's OWN in-hand message for its own step.
|
|
92
|
+
*
|
|
93
|
+
* At the guard sites the overlay is now DEFENSIVE, not load-bearing (issue #373 correction): the
|
|
94
|
+
* guard's evidence `error` carries the unresolvable path itself, so the path survives the evidence
|
|
95
|
+
* walk and the post-drain re-render alike. It is kept against caller-shaped evidence that might
|
|
96
|
+
* arrive without it.
|
|
97
|
+
*
|
|
98
|
+
* `undefined` never clobbers an evidence message.
|
|
99
|
+
*/
|
|
100
|
+
export declare function failureMessagesWithOverlay(evidence: readonly EvidenceSnapshot[], step: string, inHand: string | undefined): Map<string, string>;
|
|
46
101
|
/**
|
|
47
102
|
* Applies one {@link SettlementDelta} against `fresh` — pure, synchronous, no I/O, no registry
|
|
48
103
|
* (design record §7 CS-purity: `options` carries VALUES only). `definition` is passed per call
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settlement.d.ts","sourceRoot":"","sources":["../../src/engine/settlement.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"settlement.d.ts","sourceRoot":"","sources":["../../src/engine/settlement.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,SAAS,EAAW,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACnF,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAC5F,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAEhB,iBAAiB,EAQlB,MAAM,wBAAwB,CAAC;AA8GhC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,kBAAkB,EAC9B,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAAC,EACrC,OAAO,EAAE,iBAAiB,GAAG,WAAW,CAAC,gBAAgB,CAAC,GACzD,MAAM,EAAE,CAoBV;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,GACtC,WAAW,CAAC,gBAAgB,CAAC,CAM/B;AAoQD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACpC,MAAM,CAmBR;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,GACpC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAMrB;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,EACrC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAIrB;AA21BD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,eAAe,EACtB,UAAU,EAAE,kBAAkB,EAC9B,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,IAAI,CAAA;CAAE,GACvB,gBAAgB,CAoBlB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,yBAAyB,QAIE,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { deriveRunPhase, isWorkflowComplete, findEligibleSteps, findEligibleGuardSteps, propagateSkips, } from './eligibility.js';
|
|
1
|
+
import { assertSealMarkersAgree, assertSealOutcomeCoherent, deriveRunPhase, isWorkflowComplete, findEligibleSteps, findEligibleGuardSteps, propagateSkips, } from './eligibility.js';
|
|
2
2
|
import { deriveDefaultedSteps } from './defaulted-steps.js';
|
|
3
3
|
import { captureEvidence } from '../evidence/snapshot.js';
|
|
4
4
|
import { omitClaim } from './claim-liveness.js';
|
|
@@ -132,16 +132,29 @@ export function selectFinalizers(definition, settledStepNames, outcome) {
|
|
|
132
132
|
/**
|
|
133
133
|
* Derives the full set of finalizer triggers a terminal `outcome` satisfies for `record` (issue
|
|
134
134
|
* #302, design record §Mechanics-1): `{outcome}` — always — plus `'completed_with_failed_steps'`
|
|
135
|
-
* when `outcome === 'complete' ∧ record.failed_steps.length > 0` (a "mixed complete" seal
|
|
136
|
-
*
|
|
137
|
-
*
|
|
135
|
+
* when `outcome === 'complete' ∧ record.failed_steps.length > 0` (a "mixed complete" seal).
|
|
136
|
+
*
|
|
137
|
+
* TWO SURFACES, ONE SHAPE, TWO MOMENTS. #304's `completed_with_failed_steps` run-health finding
|
|
138
|
+
* tests the same SHAPE (completed ∧ non-empty `failed_steps`), but it tests it at READ time on
|
|
139
|
+
* the final record, whereas this function is evaluated at MINT time, inside
|
|
140
|
+
* `applyTerminalPostconditions`, before any finalizer has run. There is no shared function and no
|
|
141
|
+
* shared evaluation point — only a shared shape.
|
|
142
|
+
*
|
|
143
|
+
* The moment is what separates them, on a real population: a finalizer's OWN failure joins
|
|
144
|
+
* `failed_steps` after the seal minted (see the failed arm below, where `delta.finalizer` is
|
|
145
|
+
* appended), so a run that completes CLEAN and whose finalizer then fails is seen by the
|
|
146
|
+
* read-time finding and was never seen by this trigger — the record it read had an empty
|
|
147
|
+
* `failed_steps`. The divergence runs one way only: `failed_steps` only grows, so everything this
|
|
148
|
+
* trigger fires on the finding also reports, and the finding additionally reports post-mint
|
|
149
|
+
* finalizer self-failures. Tracked at #374 (P5); this comment describes what the code does today
|
|
150
|
+
* and does not prejudge what that issue decides.
|
|
138
151
|
*
|
|
139
152
|
* Uniform across epochs (design record M1, deliberate): a second-epoch complete seal whose ONLY
|
|
140
153
|
* `failed_steps` scar is a PRIOR epoch's finalizer self-failure (unresumable, so it never leaves
|
|
141
154
|
* `failed_steps`) still fires this trigger — no exclusion of finalizer-declared step names. The
|
|
142
155
|
* alternative (excluding finalizer names from the predicate) buys mint-time purity at the cost of
|
|
143
|
-
*
|
|
144
|
-
*
|
|
156
|
+
* making the two surfaces disagree about a shape they can both see, which is a second divergence
|
|
157
|
+
* on top of the one above.
|
|
145
158
|
*
|
|
146
159
|
* Pure; this ONE function is the seam a future authorable tolerance threshold (SFN-style: fire
|
|
147
160
|
* only when `failed_steps.length` exceeds some declared N) would extend — banked, not built
|
|
@@ -204,13 +217,28 @@ function mintFresh(record, definition, outcome) {
|
|
|
204
217
|
* simply the post-write value, read back explicitly (not assumed) so a future caller that ever
|
|
205
218
|
* violates that precondition fails loudly via a wrong `transitioned` value rather than silently.
|
|
206
219
|
*/
|
|
207
|
-
function applyTerminalPostconditions(record, definition, mintOutcome, stampDefaulted
|
|
220
|
+
function applyTerminalPostconditions(record, definition, mintOutcome, stampDefaulted,
|
|
221
|
+
/**
|
|
222
|
+
* issue #367: the ARM this settlement branch seals with — per-branch knowledge that exists
|
|
223
|
+
* exactly once, at the seal site, at seal time (re-inferring it later is lossy in principle:
|
|
224
|
+
* `guard_abort` and `handler_abort` differ only by writer-owned prose). Stamped IFF this apply
|
|
225
|
+
* TRANSITIONED; the eight call sites in this file are the whole settlement-transform writer
|
|
226
|
+
* census. A stale prior seal never survives a non-terminal fork — see the strip below.
|
|
227
|
+
*/
|
|
228
|
+
seal) {
|
|
208
229
|
const transitioned = record.terminal_state === true;
|
|
209
|
-
|
|
230
|
+
// issue #367: strip any stale prior seal FIRST, so a non-terminal fork can never carry one out.
|
|
231
|
+
const { sealed_by: _priorSeal, ...base } = record;
|
|
232
|
+
let sealed = transitioned
|
|
233
|
+
? {
|
|
234
|
+
...base,
|
|
235
|
+
sealed_by: { arm: seal.arm, ...(seal.step !== undefined ? { step: seal.step } : {}) },
|
|
236
|
+
}
|
|
237
|
+
: base;
|
|
210
238
|
if (transitioned) {
|
|
211
239
|
// On terminal false→true edge: mintFresh (§4.1), same atomic write.
|
|
212
|
-
const ledger = mintFresh(
|
|
213
|
-
sealed = { ...
|
|
240
|
+
const ledger = mintFresh(sealed, definition, mintOutcome);
|
|
241
|
+
sealed = { ...sealed, ...(ledger !== undefined ? { finalizer_ledger: ledger } : {}) };
|
|
214
242
|
// defaulted_steps stamped IFF a COMPLETE-terminal edge (§4.2; the FM-5/#232 guard) — never on
|
|
215
243
|
// a fail/abort seal, even one that terminalizes.
|
|
216
244
|
if (stampDefaulted) {
|
|
@@ -218,6 +246,11 @@ function applyTerminalPostconditions(record, definition, mintOutcome, stampDefau
|
|
|
218
246
|
if (defaultedSteps.length > 0)
|
|
219
247
|
sealed = { ...sealed, defaulted_steps: defaultedSteps };
|
|
220
248
|
}
|
|
249
|
+
// issue #367: the two transform-scoped congruence assertions, on the record THIS function
|
|
250
|
+
// produces — never universal (a universal marker law reds the published TERMINAL_STATE_ONLY
|
|
251
|
+
// fixture by construction).
|
|
252
|
+
assertSealMarkersAgree(sealed);
|
|
253
|
+
assertSealOutcomeCoherent(sealed);
|
|
221
254
|
}
|
|
222
255
|
const withPhase = { ...sealed, run_phase: deriveRunPhase(sealed) };
|
|
223
256
|
return { run: withPhase, transitioned };
|
|
@@ -323,7 +356,10 @@ function applyAbortEdge(fresh, withMembership, step, abort, definition, now) {
|
|
|
323
356
|
// §4 shared postconditions: abort NEVER stamps defaulted_steps (the FM-5/#232 guard — only the
|
|
324
357
|
// complete edge does); `transitioned` is always true here (isTerminal(fresh) was already
|
|
325
358
|
// refused above, and `aborted.terminal_state` is unconditionally true).
|
|
326
|
-
const { run, transitioned } = applyTerminalPostconditions(aborted, definition, 'abort', false
|
|
359
|
+
const { run, transitioned } = applyTerminalPostconditions(aborted, definition, 'abort', false, {
|
|
360
|
+
arm: 'handler_abort',
|
|
361
|
+
step,
|
|
362
|
+
});
|
|
327
363
|
return {
|
|
328
364
|
applied: true,
|
|
329
365
|
run,
|
|
@@ -331,6 +367,94 @@ function applyAbortEdge(fresh, withMembership, step, abort, definition, now) {
|
|
|
331
367
|
pendingFinalizers: pendingFinalizerNames(run.finalizer_ledger),
|
|
332
368
|
};
|
|
333
369
|
}
|
|
370
|
+
// ---------------------------------------------------------------------------
|
|
371
|
+
// The run's one-line fail cause (issue #373)
|
|
372
|
+
// ---------------------------------------------------------------------------
|
|
373
|
+
/** Per-message cap before the truncation marker — sized from a real-corpus measurement
|
|
374
|
+
* (2026-08-20, n=31 evidence error messages from a live runsDir: p50=21, p95=248, max=254 — 19%
|
|
375
|
+
* of real messages were truncated at the previous unanchored 120; 256 keeps the whole observed
|
|
376
|
+
* distribution verbatim). Re-measure before changing; the 1024 sentence cap remains the global
|
|
377
|
+
* bound. */
|
|
378
|
+
const FAIL_CAUSE_MESSAGE_CAP = 256;
|
|
379
|
+
/** Hard cap on the WHOLE sentence, marker included — the returned string is never longer than
|
|
380
|
+
* this. (Tekton caps its joined validation detail at 1024 + `"..."`, i.e. 1027 out; realm's cap
|
|
381
|
+
* is inclusive, so an overflowing sentence lands at exactly 1024.) */
|
|
382
|
+
const FAIL_CAUSE_SENTENCE_CAP = 1024;
|
|
383
|
+
/** ASCII, not `…` — the marker travels through logs, terminals and a Postgres text column. */
|
|
384
|
+
const FAIL_CAUSE_TRUNCATION = '...';
|
|
385
|
+
/**
|
|
386
|
+
* Renders the run-level cause for a run with MORE THAN ONE distinct failed step (issue #373).
|
|
387
|
+
*
|
|
388
|
+
* PRECONDITION — callers gate on `new Set(failedSteps).size > 1`. That gate is about which
|
|
389
|
+
* sentence SHAPE a call site wants, not about grammar safety: the single-failure sentence is each
|
|
390
|
+
* call site's own template (`Step 'a' failed: …`, `Guard step 'g' failed: …`), left where it is so
|
|
391
|
+
* there is exactly one spelling of each. Output below is grammatical at any count.
|
|
392
|
+
*
|
|
393
|
+
* The defect it fixes: `failed_steps` is append-ordered by settlement commit, so naming one step
|
|
394
|
+
* as THE cause named whichever failure settled LAST — and under true concurrency the lock race
|
|
395
|
+
* decided the culprit. The sentence below is order-independent by construction:
|
|
396
|
+
*
|
|
397
|
+
* - **dedup, then sort lexically.** A domain step cannot appear twice today, but the post-seal
|
|
398
|
+
* finalizer append across resume epochs has never been executed for duplication — dedup makes
|
|
399
|
+
* the count honest either way. Sorting is the order rule (Tekton `sort.Strings`, rustc
|
|
400
|
+
* `error_codes.sort()`); array order IS settle order, the instability this fix exists to kill.
|
|
401
|
+
* - **count first, no culprit, terminating verb.** The count is the one fact true regardless of
|
|
402
|
+
* order.
|
|
403
|
+
* - **a missing message yields a bare step name.** Never fabricated — the string `undefined` must
|
|
404
|
+
* not be constructible here.
|
|
405
|
+
*/
|
|
406
|
+
export function renderFailCause(failedSteps, messages) {
|
|
407
|
+
const distinct = [...new Set(failedSteps)].sort();
|
|
408
|
+
const rendered = distinct.map((step) => {
|
|
409
|
+
const message = messages.get(step);
|
|
410
|
+
if (message === undefined)
|
|
411
|
+
return step;
|
|
412
|
+
const capped = message.length > FAIL_CAUSE_MESSAGE_CAP
|
|
413
|
+
? message.slice(0, FAIL_CAUSE_MESSAGE_CAP) + FAIL_CAUSE_TRUNCATION
|
|
414
|
+
: message;
|
|
415
|
+
return `${step} ("${capped}")`;
|
|
416
|
+
});
|
|
417
|
+
// Grammatical across the WHOLE input domain, not just the domain the call sites use — a public
|
|
418
|
+
// export that can emit "1 steps failed" is wrong output, precondition or no precondition
|
|
419
|
+
// (ninja's own discipline: "subcommand failed" / "subcommands failed").
|
|
420
|
+
const sentence = `${distinct.length} step${distinct.length === 1 ? '' : 's'} failed: ${rendered.join(', ')}.`;
|
|
421
|
+
return sentence.length > FAIL_CAUSE_SENTENCE_CAP
|
|
422
|
+
? sentence.slice(0, FAIL_CAUSE_SENTENCE_CAP - FAIL_CAUSE_TRUNCATION.length) +
|
|
423
|
+
FAIL_CAUSE_TRUNCATION
|
|
424
|
+
: sentence;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Last-`error`-snapshot-per-step, in one linear pass — the same last-per-step idiom
|
|
428
|
+
* `buildSettlementNamespace` already ships. `EvidenceSnapshot.error` is stored VERBATIM by
|
|
429
|
+
* `captureEvidence`, so these are the real per-step messages, not a reconstruction.
|
|
430
|
+
*
|
|
431
|
+
* A step can hold several error snapshots (retries, resume epochs); the LAST one is the message
|
|
432
|
+
* that describes the failure the record currently carries.
|
|
433
|
+
*/
|
|
434
|
+
export function failureMessagesFromEvidence(evidence) {
|
|
435
|
+
const messages = new Map();
|
|
436
|
+
for (const snapshot of evidence) {
|
|
437
|
+
if (snapshot.error !== undefined)
|
|
438
|
+
messages.set(snapshot.step_id, snapshot.error);
|
|
439
|
+
}
|
|
440
|
+
return messages;
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* The evidence walk plus the call site's OWN in-hand message for its own step.
|
|
444
|
+
*
|
|
445
|
+
* At the guard sites the overlay is now DEFENSIVE, not load-bearing (issue #373 correction): the
|
|
446
|
+
* guard's evidence `error` carries the unresolvable path itself, so the path survives the evidence
|
|
447
|
+
* walk and the post-drain re-render alike. It is kept against caller-shaped evidence that might
|
|
448
|
+
* arrive without it.
|
|
449
|
+
*
|
|
450
|
+
* `undefined` never clobbers an evidence message.
|
|
451
|
+
*/
|
|
452
|
+
export function failureMessagesWithOverlay(evidence, step, inHand) {
|
|
453
|
+
const messages = failureMessagesFromEvidence(evidence);
|
|
454
|
+
if (inHand !== undefined)
|
|
455
|
+
messages.set(step, inHand);
|
|
456
|
+
return messages;
|
|
457
|
+
}
|
|
334
458
|
/** complete / fail: the TWO-DISJUNCT `isComplete` predicate (execution-loop.ts :2579-2583 /
|
|
335
459
|
* :2237-2241 — named, not implied). */
|
|
336
460
|
function applyCompleteOrFailEdge(withMembership, step, outcome, failureMessage, definition) {
|
|
@@ -344,20 +468,30 @@ function applyCompleteOrFailEdge(withMembership, step, outcome, failureMessage,
|
|
|
344
468
|
(withSkipped.in_progress_steps.length === 0 &&
|
|
345
469
|
findEligibleSteps(definition, withSkipped).length === 0 &&
|
|
346
470
|
findEligibleGuardSteps(definition, withSkipped).length === 0);
|
|
471
|
+
// issue #373: with MORE THAN ONE distinct failure the run has no single culprit, and naming one
|
|
472
|
+
// named whichever settled last. At exactly one failure the sentence is unchanged — including the
|
|
473
|
+
// `?? 'unknown error'` fallback, which is this site's shape and stays this site's shape.
|
|
474
|
+
const failCause = new Set(withSkipped.failed_steps).size > 1
|
|
475
|
+
? renderFailCause(withSkipped.failed_steps, failureMessagesWithOverlay(withSkipped.evidence, step, failureMessage))
|
|
476
|
+
: `Step '${step}' failed: ${failureMessage ?? 'unknown error'}`;
|
|
347
477
|
const draft = {
|
|
348
478
|
...withSkipped,
|
|
349
479
|
terminal_state: isComplete,
|
|
350
480
|
...(isComplete
|
|
351
481
|
? {
|
|
352
482
|
terminal_reason: outcome === 'complete'
|
|
353
|
-
? 'Workflow completed.' //
|
|
354
|
-
:
|
|
483
|
+
? 'Workflow completed.' // the legacy-classifier leg keys 'completed' on this (#367)
|
|
484
|
+
: failCause,
|
|
355
485
|
}
|
|
356
486
|
: {}),
|
|
357
487
|
};
|
|
358
488
|
// §4 shared postconditions: defaulted_steps stamps IFF this is a COMPLETE-terminal edge — never
|
|
359
489
|
// on a fail seal, even one that terminalizes.
|
|
360
|
-
const { run, transitioned } = applyTerminalPostconditions(draft, definition, outcome, outcome === 'complete' && isComplete
|
|
490
|
+
const { run, transitioned } = applyTerminalPostconditions(draft, definition, outcome, outcome === 'complete' && isComplete,
|
|
491
|
+
// issue #367: validation exhaustion is deliberately NOT a distinct arm — a VALIDATION_EXHAUSTED
|
|
492
|
+
// fail seals 'step_failure' like any other; the distinction lives in defaulted_steps and the
|
|
493
|
+
// step diagnostics. Never re-introduce a failure-code ternary here.
|
|
494
|
+
{ arm: outcome === 'complete' ? 'complete' : 'step_failure', step });
|
|
361
495
|
return {
|
|
362
496
|
applied: true,
|
|
363
497
|
run,
|
|
@@ -533,10 +667,11 @@ now) {
|
|
|
533
667
|
const draft = {
|
|
534
668
|
...withSkipped,
|
|
535
669
|
terminal_state: isComplete,
|
|
536
|
-
//
|
|
670
|
+
// The legacy-classifier leg of deriveRunPhase keys 'completed' on this exact string —
|
|
671
|
+
// for the LEGACY population only; on a stamped record the arm derives (issue #367).
|
|
537
672
|
...(isComplete ? { terminal_reason: 'Workflow completed.' } : {}),
|
|
538
673
|
};
|
|
539
|
-
const { run, transitioned } = applyTerminalPostconditions(draft, definition, 'complete', isComplete);
|
|
674
|
+
const { run, transitioned } = applyTerminalPostconditions(draft, definition, 'complete', isComplete, { arm: 'gate_resolution_complete', step: stepName });
|
|
540
675
|
return {
|
|
541
676
|
applied: true,
|
|
542
677
|
run,
|
|
@@ -640,7 +775,7 @@ function applyExpireGate(fresh, delta, definition, now) {
|
|
|
640
775
|
terminal_state: isComplete,
|
|
641
776
|
...(isComplete ? { terminal_reason: 'Workflow completed.' } : {}),
|
|
642
777
|
};
|
|
643
|
-
const { run, transitioned } = applyTerminalPostconditions(draft, definition, 'complete', isComplete);
|
|
778
|
+
const { run, transitioned } = applyTerminalPostconditions(draft, definition, 'complete', isComplete, { arm: 'gate_expiry_default', step: stepName });
|
|
644
779
|
return {
|
|
645
780
|
applied: true,
|
|
646
781
|
run,
|
|
@@ -698,7 +833,10 @@ function applyExpireGate(fresh, delta, definition, now) {
|
|
|
698
833
|
};
|
|
699
834
|
// §4 shared postconditions: abort NEVER stamps defaulted_steps (the FM-5/#232 guard);
|
|
700
835
|
// `transitioned` is always true (isTerminal(fresh) already refused above).
|
|
701
|
-
const { run, transitioned } = applyTerminalPostconditions(aborted, definition, 'abort', false
|
|
836
|
+
const { run, transitioned } = applyTerminalPostconditions(aborted, definition, 'abort', false, {
|
|
837
|
+
arm: 'gate_expiry_abort',
|
|
838
|
+
step: stepName,
|
|
839
|
+
});
|
|
702
840
|
return {
|
|
703
841
|
applied: true,
|
|
704
842
|
run,
|
|
@@ -782,13 +920,25 @@ function applySettleGuard(fresh, delta, definition) {
|
|
|
782
920
|
skipped_steps: propagated.skipped,
|
|
783
921
|
skip_details: propagated.details,
|
|
784
922
|
};
|
|
923
|
+
// issue #373: this site names the guard alone even when other steps had already failed
|
|
924
|
+
// (executed with failed_steps=["fail_a","g"]). At >1 distinct failure it renders the whole
|
|
925
|
+
// set; at exactly one the sentence below is byte-unchanged.
|
|
926
|
+
const guardPath = `unresolvable path '${resolutionError.unresolvable_path}'`;
|
|
785
927
|
const draft = {
|
|
786
928
|
...withSkipped,
|
|
787
929
|
terminal_state: true,
|
|
788
|
-
// execution-loop.ts:
|
|
789
|
-
terminal_reason:
|
|
930
|
+
// execution-loop.ts:4812 parity.
|
|
931
|
+
terminal_reason: new Set(withSkipped.failed_steps).size > 1
|
|
932
|
+
? renderFailCause(withSkipped.failed_steps,
|
|
933
|
+
// Defensive once evidence carries the path (issue #373 correction); kept against
|
|
934
|
+
// caller-shaped evidence that arrives without it.
|
|
935
|
+
failureMessagesWithOverlay(withSkipped.evidence, step, guardPath))
|
|
936
|
+
: `Guard step '${step}' failed: ${guardPath}`,
|
|
790
937
|
};
|
|
791
|
-
const { run, transitioned } = applyTerminalPostconditions(draft, definition, 'fail', false
|
|
938
|
+
const { run, transitioned } = applyTerminalPostconditions(draft, definition, 'fail', false, {
|
|
939
|
+
arm: 'guard_resolution_error',
|
|
940
|
+
step,
|
|
941
|
+
});
|
|
792
942
|
return {
|
|
793
943
|
applied: true,
|
|
794
944
|
run,
|
|
@@ -820,7 +970,10 @@ function applySettleGuard(fresh, delta, definition) {
|
|
|
820
970
|
...(abort.abort_message !== undefined ? { abort_message: abort.abort_message } : {}),
|
|
821
971
|
},
|
|
822
972
|
};
|
|
823
|
-
const { run, transitioned } = applyTerminalPostconditions(draft, definition, 'abort', false
|
|
973
|
+
const { run, transitioned } = applyTerminalPostconditions(draft, definition, 'abort', false, {
|
|
974
|
+
arm: 'guard_abort',
|
|
975
|
+
step,
|
|
976
|
+
});
|
|
824
977
|
return {
|
|
825
978
|
applied: true,
|
|
826
979
|
run,
|
|
@@ -847,11 +1000,11 @@ function applySettleGuard(fresh, delta, definition) {
|
|
|
847
1000
|
const draft = {
|
|
848
1001
|
...withSkipped,
|
|
849
1002
|
terminal_state: isComplete,
|
|
850
|
-
// execution-loop.ts:3675-3705 parity;
|
|
1003
|
+
// execution-loop.ts:3675-3705 parity; the legacy-classifier leg keys 'completed' on
|
|
851
1004
|
// this exact string.
|
|
852
1005
|
...(isComplete ? { terminal_reason: 'Workflow completed.' } : {}),
|
|
853
1006
|
};
|
|
854
|
-
const { run, transitioned } = applyTerminalPostconditions(draft, definition, 'complete', isComplete);
|
|
1007
|
+
const { run, transitioned } = applyTerminalPostconditions(draft, definition, 'complete', isComplete, { arm: 'guard_pass_complete', step });
|
|
855
1008
|
return {
|
|
856
1009
|
applied: true,
|
|
857
1010
|
run,
|
|
@@ -999,9 +1152,21 @@ function applyMarkFinalizer(fresh, delta) {
|
|
|
999
1152
|
failed_steps: [...fresh.failed_steps, delta.finalizer],
|
|
1000
1153
|
evidence: [...fresh.evidence, delta.evidence],
|
|
1001
1154
|
};
|
|
1155
|
+
const phase = deriveRunPhase(withLedgerAndEvidence);
|
|
1156
|
+
// issue #373: the finalizer's OWN failure joins `failed_steps` here, AFTER the seal minted the
|
|
1157
|
+
// sentence — which is how a sealed cause went stale and undercounted the record. Re-render from
|
|
1158
|
+
// the grown record, but ONLY on the failed arm: on the completed arm nothing grew, and a
|
|
1159
|
+
// re-render there would rebuild without the seal site's in-hand overlay (the guard sites' path
|
|
1160
|
+
// text) and silently drop it.
|
|
1161
|
+
const failedArmCause = delta.result !== 'completed' &&
|
|
1162
|
+
phase === 'failed' &&
|
|
1163
|
+
new Set(withLedgerAndEvidence.failed_steps).size > 1
|
|
1164
|
+
? renderFailCause(withLedgerAndEvidence.failed_steps, failureMessagesFromEvidence(withLedgerAndEvidence.evidence))
|
|
1165
|
+
: undefined;
|
|
1002
1166
|
const run = {
|
|
1003
1167
|
...withLedgerAndEvidence,
|
|
1004
|
-
run_phase:
|
|
1168
|
+
run_phase: phase,
|
|
1169
|
+
...(failedArmCause !== undefined ? { terminal_reason: failedArmCause } : {}),
|
|
1005
1170
|
};
|
|
1006
1171
|
return {
|
|
1007
1172
|
applied: true,
|