You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit a36b526
Browse filesBrowse the repository at this point in the historyBrowse files
docs(automation): three declaration-truth residues on the run-history row — a one-way discriminator, the row's step log, and the write that names its reader (#17549)
* docs(automation): correct three declaration-truth residues on the run-history row
`variables_json`'s description stated presence and "this run had a pause its
resume consumed" as EQUIVALENT. Only the forward direction is true: the
terminal write is an upsert that always writes the four snapshot columns,
NULL included, so a run that stranded, was restored and then finished has its
row rewritten with NULLs — leaving it indistinguishable, in exactly those
columns, from a run that never paused. The text is what was wrong; the
clearing is the ruled design, and nothing reads the reverse direction.
`deserializeConsumedSuspension` described the rebuilt snapshot's steps as the
step log AS OF THE PAUSE. That is true of the engine's process-local journal
copy only (it slices `run.steps` back to the step count at the pause); the
row's `steps_json` is the terminal row's log of the WHOLE run, and both bounds
on it — history compaction and the byte cap — deliberately keep the failure
and trim the head.
`recordTerminal` now names the verb that reads what it writes, and the three
properties of this write that are that verb's inputs. Its summary line also
said "completed / failed" where the terminal vocabulary has had four members
since #15223.
Pins the two falsifying shapes in `suspended-run-store.test.ts`; the
cross-reference has no executable surface and is not pinned.
Claude-Session: https://claude.ai/code/session_01ToDPcx9AESFubJkDiFMtKW
Co-authored-by: Claude <noreply@anthropic.com>
* chore(changeset): patch for the run-history declaration-truth corrections
The `variables_json` description reaches `dist/index.js` and `dist/index.cjs`,
and `recordTerminal`'s docblock reaches `dist/index.d.ts` — measured on the
built tree against this package's own `files[]`, with a pre-existing
description as the positive control and the module-private docblock (0 hits,
comments stripped) as the negative one. Published bytes move, so this is a
`patch`, not `skip-changeset`.
Claude-Session: https://claude.ai/code/session_01ToDPcx9AESFubJkDiFMtKW
Co-authored-by: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
`sys_automation_run.variables_json` states its presence discriminator in ONE direction, and a row-rebuilt snapshot no longer claims its steps are the pause's
6
+
7
+
Three corrections to text this package ships. No behaviour changes; every shape
8
+
described below is the ruled design, measured as it already is.
9
+
10
+
**`variables_json` said `⇔` where only `⇒` holds.** The field description
11
+
declared "present on a completed/failed row" and "the row's run had a pause its
12
+
resume consumed before a downstream node failed" to be equivalent. The forward
13
+
direction holds — nothing but the consumed-suspension path writes that column on
14
+
a terminal row. The reverse does not, for one shape: a run that stranded, was
15
+
restored and then finished. `recordTerminal` upserts the SAME `run_<id>` row
16
+
with all four snapshot columns explicitly `null` — deliberately, so
17
+
"restorable" cannot outlive the condition it describes — which leaves that row
18
+
equal, across every column the discriminator is read from, to the row of a run
19
+
that never paused at all. Absence means "nothing to restore now", never "this
20
+
run never had one", and the restore verb already refuses in exactly those terms:
21
+
it names the status it observed and declines to say which. The description now
22
+
says so.
23
+
24
+
**A snapshot rebuilt from a row does not carry the step log as of the pause.**
25
+
`deserializeConsumedSuspension`'s docblock said its `steps` are the log "AS OF
26
+
THE PAUSE". That is true of the engine's process-local journal copy only, which
27
+
slices `run.steps` back to the step count at the pause; the trimmed array is
28
+
never persisted. `steps` are the one field the rebuild takes from the row's own
29
+
`steps_json`, which is the terminal row's log of the WHOLE run — and both bounds
30
+
on that column keep the failure on purpose (history compaction retains every
31
+
failure; the byte cap trims the head). A row-rebuilt snapshot therefore carries
32
+
steps the pause did not have. It re-arms the same run regardless: the pause is
33
+
`nodeId` plus `variables` / `context` / `correlation`, none of which the step log
34
+
feeds.
35
+
36
+
**`recordTerminal` now names the verb that reads what it writes** — the
37
+
restore path in `engine.ts` — and the three properties of the write that are
38
+
that verb's inputs rather than local detail. Its summary line also said
39
+
"completed / failed" where the terminal vocabulary has had four members since
40
+
the fold was removed from both ends of this write.
41
+
42
+
Both falsifying shapes are pinned in `suspended-run-store.test.ts`, including the
43
+
indistinguishability itself: the restored-then-finished row and a never-paused
44
+
row compare equal across those five columns, with the same comparison separating
// `RunRecord.consumedSuspensionDropped`), so "present" now has two shapes
270
270
// and only one of them is a restorable snapshot — stated in the
271
271
// description rather than left to the reader of the column.
272
+
//
273
+
// [#15336] The description used to state that presence and "this run had a
274
+
// consumed suspension" imply EACH OTHER. Only the forward direction is
275
+
// true. The falsifying shape is a run that stranded, was restored and then
276
+
// finished: `recordTerminal` upserts the SAME `run_<id>` row and
277
+
// `serializeConsumedSuspension(undefined)` writes explicit NULLs into all
278
+
// four columns — deliberately, so "restorable" cannot outlive the condition
279
+
// it describes (`RunRecord.consumedSuspension` in `engine.ts` states the
280
+
// clearing rule from the producer's side). ⛔ The fix is the TEXT, not the
281
+
// clearing: nothing reads the reverse direction — `restoreConsumedSuspension`
282
+
// refuses a snapshot-less row by naming the status it observed and
283
+
// deliberately declines to say whether the run never paused or lost its
284
+
// snapshot, which is that direction being unavailable, honestly. The
285
+
// clearing itself is pinned in `suspended-run-store.test.ts`.
272
286
variables_json: Field.textarea({
273
287
label: 'Variables',
274
288
required: false,
275
-
description: 'JSON snapshot of the flow variable map at suspend time. On a terminal row its PRESENCE is the discriminator: nothing but the consumed-suspension path writes it there, so variables_json present on a completed/failed row ⇔ the row\'s run had a pause that its resume consumed before a downstream node failed — the store\'s deserializer keys off exactly this. Two shapes on such a row: the snapshot itself (a restorable suspension), or a one-key notice `{"$consumedSuspensionDropped": …}` recording that the snapshot existed and was NOT persisted (over the store\'s row budget) — the notice is not a restorable snapshot; such a run can be restored only by the process that stranded it, while it runs.',
289
+
description: 'JSON snapshot of the flow variable map at suspend time. On a terminal row its PRESENCE is the discriminator: nothing but the consumed-suspension path writes it there, so variables_json present on a completed/failed row ⇒ the row\'s run had a pause that its resume consumed before a downstream node failed — the store\'s deserializer keys off exactly this. ⛔ It does NOT hold in reverse: the terminal write is an upsert that always writes these columns, NULL included, so a stranded run that was restored and then finished has its row rewritten with NULLs. Absence therefore means "nothing to restore NOW", never "this run never had a consumed suspension" — the restore verb says exactly that when it refuses, naming the status it observed instead of claiming which. Two shapes on such a row: the snapshot itself (a restorable suspension), or a one-key notice `{"$consumedSuspensionDropped": …}` recording that the snapshot existed and was NOT persisted (over the store\'s row budget) — the notice is not a restorable snapshot; such a run can be restored only by the process that stranded it, while it runs.',
0 commit comments