footprintjs 9.48.2 → 10.0.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/AGENTS.md +12 -10
- package/CLAUDE.md +21 -23
- package/README.md +1 -1
- package/dist/advanced.js +71 -128
- package/dist/esm/advanced.d.ts +24 -58
- package/dist/esm/advanced.js +13 -51
- package/dist/esm/index.d.ts +5 -8
- package/dist/esm/index.js +3 -3
- package/dist/esm/lib/builder/FlowChartBuilder.d.ts +1 -1
- package/dist/esm/lib/builder/FlowChartBuilder.js +3 -3
- package/dist/esm/lib/builder/structure/StructureRecorder.d.ts +1 -1
- package/dist/esm/lib/builder/structure/StructureRecorder.js +1 -1
- package/dist/esm/lib/capture/index.d.ts +0 -1
- package/dist/esm/lib/capture/index.js +1 -2
- package/dist/esm/lib/engine/graph/prefixNodeTree.js +2 -2
- package/dist/esm/lib/engine/handlers/ResumeEntry.d.ts +3 -3
- package/dist/esm/lib/engine/handlers/ResumeEntry.js +4 -4
- package/dist/esm/lib/engine/handlers/SubflowExecutor.d.ts +1 -2
- package/dist/esm/lib/engine/handlers/SubflowExecutor.js +4 -8
- package/dist/esm/lib/engine/index.d.ts +1 -1
- package/dist/esm/lib/engine/index.js +1 -1
- package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +4 -4
- package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.js +1 -1
- package/dist/esm/lib/engine/narrative/index.d.ts +1 -1
- package/dist/esm/lib/engine/narrative/index.js +1 -1
- package/dist/esm/lib/engine/narrative/narrativeTypes.d.ts +1 -11
- package/dist/esm/lib/engine/narrative/narrativeTypes.js +1 -1
- package/dist/esm/lib/engine/traversal/FlowchartTraverser.d.ts +2 -10
- package/dist/esm/lib/engine/traversal/FlowchartTraverser.js +4 -6
- package/dist/esm/lib/engine/traversalContext.d.ts +1 -1
- package/dist/esm/lib/engine/traversalContext.js +2 -2
- package/dist/esm/lib/engine/types.d.ts +2 -10
- package/dist/esm/lib/engine/types.js +1 -1
- package/dist/esm/lib/engine/walkSubflowSpec.js +2 -2
- package/dist/esm/lib/ids/reservedIds.js +2 -2
- package/dist/esm/lib/memory/DiagnosticCollector.js +2 -2
- package/dist/esm/lib/memory/StageContext.d.ts +2 -4
- package/dist/esm/lib/memory/StageContext.js +2 -2
- package/dist/esm/lib/memory/borrowedMutation.js +2 -2
- package/dist/esm/lib/memory/index.d.ts +6 -21
- package/dist/esm/lib/memory/index.js +4 -22
- package/dist/esm/lib/memory/redaction.d.ts +1 -1
- package/dist/esm/lib/memory/redaction.js +2 -2
- package/dist/esm/lib/memory/runPolicy.d.ts +3 -2
- package/dist/esm/lib/memory/runPolicy.js +1 -1
- package/dist/esm/lib/reactive/createTypedScope.js +2 -2
- package/dist/esm/lib/reactive/writeTraps.js +2 -2
- package/dist/esm/lib/recorder/ControlDepRecorder.d.ts +3 -2
- package/dist/esm/lib/recorder/ControlDepRecorder.js +3 -2
- package/dist/esm/lib/recorder/EmitRecorder.d.ts +1 -1
- package/dist/esm/lib/recorder/EmitRecorder.js +1 -1
- package/dist/esm/lib/recorder/InOutRecorder.js +2 -2
- package/dist/esm/lib/recorder/qualityTrace.d.ts +1 -1
- package/dist/esm/lib/recorder/qualityTrace.js +2 -2
- package/dist/esm/lib/runner/DeferredObserverTier.js +2 -2
- package/dist/esm/lib/runner/ExecutionRuntime.d.ts +4 -5
- package/dist/esm/lib/runner/ExecutionRuntime.js +2 -5
- package/dist/esm/lib/runner/FlowChartExecutor.d.ts +1 -1
- package/dist/esm/lib/runner/FlowChartExecutor.js +1 -1
- package/dist/esm/lib/runner/getSubtreeSnapshot.d.ts +1 -1
- package/dist/esm/lib/runner/getSubtreeSnapshot.js +4 -4
- package/dist/esm/lib/runner/resume.js +2 -2
- package/dist/esm/lib/runner/snapshot.js +3 -2
- package/dist/esm/lib/scope/ScopeFacade.js +2 -2
- package/dist/esm/lib/scope/state/zod/scopeFactory.js +2 -2
- package/dist/esm/recorders.d.ts +2 -3
- package/dist/esm/recorders.js +1 -1
- package/dist/esm/trace.d.ts +11 -57
- package/dist/esm/trace.js +10 -68
- package/dist/index.js +3 -3
- package/dist/lib/builder/FlowChartBuilder.js +5 -5
- package/dist/lib/builder/structure/StructureRecorder.js +1 -1
- package/dist/lib/capture/index.js +2 -4
- package/dist/lib/engine/graph/prefixNodeTree.js +5 -5
- package/dist/lib/engine/handlers/ResumeEntry.js +4 -4
- package/dist/lib/engine/handlers/SubflowExecutor.js +5 -9
- package/dist/lib/engine/index.js +1 -1
- package/dist/lib/engine/narrative/CombinedNarrativeRecorder.js +1 -1
- package/dist/lib/engine/narrative/index.js +1 -1
- package/dist/lib/engine/narrative/narrativeTypes.js +1 -1
- package/dist/lib/engine/traversal/FlowchartTraverser.js +8 -10
- package/dist/lib/engine/traversalContext.js +4 -4
- package/dist/lib/engine/types.js +1 -1
- package/dist/lib/engine/walkSubflowSpec.js +3 -3
- package/dist/lib/ids/reservedIds.js +5 -5
- package/dist/lib/memory/DiagnosticCollector.js +3 -3
- package/dist/lib/memory/StageContext.js +3 -3
- package/dist/lib/memory/borrowedMutation.js +3 -3
- package/dist/lib/memory/index.js +7 -42
- package/dist/lib/memory/redaction.js +3 -3
- package/dist/lib/memory/runPolicy.js +1 -1
- package/dist/lib/reactive/createTypedScope.js +3 -3
- package/dist/lib/reactive/writeTraps.js +4 -4
- package/dist/lib/recorder/ControlDepRecorder.js +3 -2
- package/dist/lib/recorder/EmitRecorder.js +1 -1
- package/dist/lib/recorder/InOutRecorder.js +3 -3
- package/dist/lib/recorder/qualityTrace.js +4 -4
- package/dist/lib/runner/DeferredObserverTier.js +3 -3
- package/dist/lib/runner/ExecutionRuntime.js +6 -9
- package/dist/lib/runner/FlowChartExecutor.js +1 -1
- package/dist/lib/runner/getSubtreeSnapshot.js +6 -6
- package/dist/lib/runner/resume.js +3 -3
- package/dist/lib/runner/snapshot.js +6 -5
- package/dist/lib/scope/ScopeFacade.js +3 -3
- package/dist/lib/scope/state/zod/scopeFactory.js +4 -4
- package/dist/recorders.js +1 -1
- package/dist/trace.js +18 -120
- package/dist/types/advanced.d.ts +24 -58
- package/dist/types/index.d.ts +5 -8
- package/dist/types/lib/builder/FlowChartBuilder.d.ts +1 -1
- package/dist/types/lib/builder/structure/StructureRecorder.d.ts +1 -1
- package/dist/types/lib/capture/index.d.ts +0 -1
- package/dist/types/lib/engine/handlers/ResumeEntry.d.ts +3 -3
- package/dist/types/lib/engine/handlers/SubflowExecutor.d.ts +1 -2
- package/dist/types/lib/engine/index.d.ts +1 -1
- package/dist/types/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +4 -4
- package/dist/types/lib/engine/narrative/index.d.ts +1 -1
- package/dist/types/lib/engine/narrative/narrativeTypes.d.ts +1 -11
- package/dist/types/lib/engine/traversal/FlowchartTraverser.d.ts +2 -10
- package/dist/types/lib/engine/traversalContext.d.ts +1 -1
- package/dist/types/lib/engine/types.d.ts +2 -10
- package/dist/types/lib/memory/StageContext.d.ts +2 -4
- package/dist/types/lib/memory/index.d.ts +6 -21
- package/dist/types/lib/memory/redaction.d.ts +1 -1
- package/dist/types/lib/memory/runPolicy.d.ts +3 -2
- package/dist/types/lib/recorder/ControlDepRecorder.d.ts +3 -2
- package/dist/types/lib/recorder/EmitRecorder.d.ts +1 -1
- package/dist/types/lib/recorder/qualityTrace.d.ts +1 -1
- package/dist/types/lib/runner/ExecutionRuntime.d.ts +4 -5
- package/dist/types/lib/runner/FlowChartExecutor.d.ts +1 -1
- package/dist/types/lib/runner/getSubtreeSnapshot.d.ts +1 -1
- package/dist/types/recorders.d.ts +2 -3
- package/dist/types/trace.d.ts +11 -57
- package/package.json +6 -15
- package/dist/esm/lib/capture/freeze.d.ts +0 -91
- package/dist/esm/lib/capture/freeze.js +0 -314
- package/dist/esm/lib/capture/ownData.d.ts +0 -7
- package/dist/esm/lib/capture/ownData.js +0 -15
- package/dist/esm/lib/capture/valueKinds.d.ts +0 -57
- package/dist/esm/lib/capture/valueKinds.js +0 -142
- package/dist/esm/lib/ids/runtimeStageId.d.ts +0 -173
- package/dist/esm/lib/ids/runtimeStageId.js +0 -194
- package/dist/esm/lib/memory/EventLog.d.ts +0 -105
- package/dist/esm/lib/memory/EventLog.js +0 -148
- package/dist/esm/lib/memory/RecordFrame.d.ts +0 -232
- package/dist/esm/lib/memory/RecordFrame.js +0 -296
- package/dist/esm/lib/memory/SharedMemory.d.ts +0 -46
- package/dist/esm/lib/memory/SharedMemory.js +0 -88
- package/dist/esm/lib/memory/TransactionBuffer.d.ts +0 -521
- package/dist/esm/lib/memory/TransactionBuffer.js +0 -946
- package/dist/esm/lib/memory/admission.d.ts +0 -81
- package/dist/esm/lib/memory/admission.js +0 -153
- package/dist/esm/lib/memory/backtrack.d.ts +0 -286
- package/dist/esm/lib/memory/backtrack.js +0 -457
- package/dist/esm/lib/memory/commitLogUtils.d.ts +0 -217
- package/dist/esm/lib/memory/commitLogUtils.js +0 -384
- package/dist/esm/lib/memory/deltaEncoding.d.ts +0 -66
- package/dist/esm/lib/memory/deltaEncoding.js +0 -122
- package/dist/esm/lib/memory/equality.d.ts +0 -93
- package/dist/esm/lib/memory/equality.js +0 -262
- package/dist/esm/lib/memory/eventPosition.d.ts +0 -18
- package/dist/esm/lib/memory/eventPosition.js +0 -2
- package/dist/esm/lib/memory/honesty.d.ts +0 -93
- package/dist/esm/lib/memory/honesty.js +0 -92
- package/dist/esm/lib/memory/keyPaths.d.ts +0 -125
- package/dist/esm/lib/memory/keyPaths.js +0 -227
- package/dist/esm/lib/memory/logModel.d.ts +0 -76
- package/dist/esm/lib/memory/logModel.js +0 -364
- package/dist/esm/lib/memory/merge.d.ts +0 -26
- package/dist/esm/lib/memory/merge.js +0 -60
- package/dist/esm/lib/memory/pathOps.d.ts +0 -115
- package/dist/esm/lib/memory/pathOps.js +0 -290
- package/dist/esm/lib/memory/paths.d.ts +0 -52
- package/dist/esm/lib/memory/paths.js +0 -57
- package/dist/esm/lib/memory/placeholders.d.ts +0 -39
- package/dist/esm/lib/memory/placeholders.js +0 -40
- package/dist/esm/lib/memory/recordCommit.d.ts +0 -45
- package/dist/esm/lib/memory/recordCommit.js +0 -61
- package/dist/esm/lib/memory/scrub.d.ts +0 -53
- package/dist/esm/lib/memory/scrub.js +0 -74
- package/dist/esm/lib/memory/types.d.ts +0 -209
- package/dist/esm/lib/memory/types.js +0 -10
- package/dist/esm/lib/memory/utils.d.ts +0 -73
- package/dist/esm/lib/memory/utils.js +0 -159
- package/dist/esm/lib/memory/verbs.d.ts +0 -333
- package/dist/esm/lib/memory/verbs.js +0 -427
- package/dist/esm/lib/recorder/CommitRangeIndex.d.ts +0 -147
- package/dist/esm/lib/recorder/CommitRangeIndex.js +0 -207
- package/dist/esm/lib/scope/detectCircular.d.ts +0 -13
- package/dist/esm/lib/scope/detectCircular.js +0 -14
- package/dist/esm/lib/scope/recorders/summarizeValue.d.ts +0 -5
- package/dist/esm/lib/scope/recorders/summarizeValue.js +0 -6
- package/dist/esm/lib/slice/elementProvenance.d.ts +0 -81
- package/dist/esm/lib/slice/elementProvenance.js +0 -190
- package/dist/esm/lib/slice/forwardSliceForKey.d.ts +0 -88
- package/dist/esm/lib/slice/forwardSliceForKey.js +0 -243
- package/dist/esm/lib/slice/index.d.ts +0 -25
- package/dist/esm/lib/slice/index.js +0 -25
- package/dist/esm/lib/slice/keyIndex.d.ts +0 -137
- package/dist/esm/lib/slice/keyIndex.js +0 -293
- package/dist/esm/lib/slice/keyTimeline.d.ts +0 -49
- package/dist/esm/lib/slice/keyTimeline.js +0 -113
- package/dist/esm/lib/slice/keysReadSources.d.ts +0 -51
- package/dist/esm/lib/slice/keysReadSources.js +0 -95
- package/dist/esm/lib/slice/serialize.d.ts +0 -78
- package/dist/esm/lib/slice/serialize.js +0 -278
- package/dist/esm/lib/slice/sliceForKey.d.ts +0 -47
- package/dist/esm/lib/slice/sliceForKey.js +0 -88
- package/dist/esm/lib/slice/types.d.ts +0 -567
- package/dist/esm/lib/slice/types.js +0 -25
- package/dist/esm/lib/time-travel/axis.d.ts +0 -119
- package/dist/esm/lib/time-travel/axis.js +0 -179
- package/dist/esm/lib/time-travel/bundles.d.ts +0 -77
- package/dist/esm/lib/time-travel/bundles.js +0 -136
- package/dist/esm/lib/time-travel/chain.d.ts +0 -93
- package/dist/esm/lib/time-travel/chain.js +0 -188
- package/dist/esm/lib/time-travel/commitStops.d.ts +0 -55
- package/dist/esm/lib/time-travel/commitStops.js +0 -202
- package/dist/esm/lib/time-travel/index.d.ts +0 -22
- package/dist/esm/lib/time-travel/index.js +0 -21
- package/dist/esm/lib/time-travel/stateAt.d.ts +0 -102
- package/dist/esm/lib/time-travel/stateAt.js +0 -153
- package/dist/esm/lib/time-travel/tagStops.d.ts +0 -72
- package/dist/esm/lib/time-travel/tagStops.js +0 -102
- package/dist/esm/lib/time-travel/timeTravel.d.ts +0 -70
- package/dist/esm/lib/time-travel/timeTravel.js +0 -360
- package/dist/esm/lib/time-travel/types.d.ts +0 -470
- package/dist/esm/lib/time-travel/types.js +0 -23
- package/dist/esm/write.d.ts +0 -47
- package/dist/esm/write.js +0 -46
- package/dist/lib/capture/freeze.js +0 -320
- package/dist/lib/capture/ownData.js +0 -19
- package/dist/lib/capture/valueKinds.js +0 -146
- package/dist/lib/ids/runtimeStageId.js +0 -210
- package/dist/lib/memory/EventLog.js +0 -152
- package/dist/lib/memory/RecordFrame.js +0 -300
- package/dist/lib/memory/SharedMemory.js +0 -92
- package/dist/lib/memory/TransactionBuffer.js +0 -950
- package/dist/lib/memory/admission.js +0 -159
- package/dist/lib/memory/backtrack.js +0 -463
- package/dist/lib/memory/commitLogUtils.js +0 -399
- package/dist/lib/memory/deltaEncoding.js +0 -128
- package/dist/lib/memory/equality.js +0 -266
- package/dist/lib/memory/eventPosition.js +0 -3
- package/dist/lib/memory/honesty.js +0 -95
- package/dist/lib/memory/keyPaths.js +0 -243
- package/dist/lib/memory/logModel.js +0 -372
- package/dist/lib/memory/merge.js +0 -64
- package/dist/lib/memory/pathOps.js +0 -306
- package/dist/lib/memory/paths.js +0 -62
- package/dist/lib/memory/placeholders.js +0 -43
- package/dist/lib/memory/recordCommit.js +0 -65
- package/dist/lib/memory/scrub.js +0 -79
- package/dist/lib/memory/types.js +0 -11
- package/dist/lib/memory/utils.js +0 -178
- package/dist/lib/memory/verbs.js +0 -444
- package/dist/lib/recorder/CommitRangeIndex.js +0 -211
- package/dist/lib/scope/detectCircular.js +0 -21
- package/dist/lib/scope/recorders/summarizeValue.js +0 -10
- package/dist/lib/slice/elementProvenance.js +0 -195
- package/dist/lib/slice/forwardSliceForKey.js +0 -247
- package/dist/lib/slice/index.js +0 -42
- package/dist/lib/slice/keyIndex.js +0 -313
- package/dist/lib/slice/keyTimeline.js +0 -117
- package/dist/lib/slice/keysReadSources.js +0 -101
- package/dist/lib/slice/serialize.js +0 -286
- package/dist/lib/slice/sliceForKey.js +0 -93
- package/dist/lib/slice/types.js +0 -26
- package/dist/lib/time-travel/axis.js +0 -184
- package/dist/lib/time-travel/bundles.js +0 -144
- package/dist/lib/time-travel/chain.js +0 -193
- package/dist/lib/time-travel/commitStops.js +0 -206
- package/dist/lib/time-travel/index.js +0 -32
- package/dist/lib/time-travel/stateAt.js +0 -160
- package/dist/lib/time-travel/tagStops.js +0 -106
- package/dist/lib/time-travel/timeTravel.js +0 -364
- package/dist/lib/time-travel/types.js +0 -24
- package/dist/types/lib/capture/freeze.d.ts +0 -91
- package/dist/types/lib/capture/ownData.d.ts +0 -7
- package/dist/types/lib/capture/valueKinds.d.ts +0 -57
- package/dist/types/lib/ids/runtimeStageId.d.ts +0 -173
- package/dist/types/lib/memory/EventLog.d.ts +0 -105
- package/dist/types/lib/memory/RecordFrame.d.ts +0 -232
- package/dist/types/lib/memory/SharedMemory.d.ts +0 -46
- package/dist/types/lib/memory/TransactionBuffer.d.ts +0 -521
- package/dist/types/lib/memory/admission.d.ts +0 -81
- package/dist/types/lib/memory/backtrack.d.ts +0 -286
- package/dist/types/lib/memory/commitLogUtils.d.ts +0 -217
- package/dist/types/lib/memory/deltaEncoding.d.ts +0 -66
- package/dist/types/lib/memory/equality.d.ts +0 -93
- package/dist/types/lib/memory/eventPosition.d.ts +0 -18
- package/dist/types/lib/memory/honesty.d.ts +0 -93
- package/dist/types/lib/memory/keyPaths.d.ts +0 -125
- package/dist/types/lib/memory/logModel.d.ts +0 -76
- package/dist/types/lib/memory/merge.d.ts +0 -26
- package/dist/types/lib/memory/pathOps.d.ts +0 -115
- package/dist/types/lib/memory/paths.d.ts +0 -52
- package/dist/types/lib/memory/placeholders.d.ts +0 -39
- package/dist/types/lib/memory/recordCommit.d.ts +0 -45
- package/dist/types/lib/memory/scrub.d.ts +0 -53
- package/dist/types/lib/memory/types.d.ts +0 -209
- package/dist/types/lib/memory/utils.d.ts +0 -73
- package/dist/types/lib/memory/verbs.d.ts +0 -333
- package/dist/types/lib/recorder/CommitRangeIndex.d.ts +0 -147
- package/dist/types/lib/scope/detectCircular.d.ts +0 -13
- package/dist/types/lib/scope/recorders/summarizeValue.d.ts +0 -5
- package/dist/types/lib/slice/elementProvenance.d.ts +0 -81
- package/dist/types/lib/slice/forwardSliceForKey.d.ts +0 -88
- package/dist/types/lib/slice/index.d.ts +0 -25
- package/dist/types/lib/slice/keyIndex.d.ts +0 -137
- package/dist/types/lib/slice/keyTimeline.d.ts +0 -49
- package/dist/types/lib/slice/keysReadSources.d.ts +0 -51
- package/dist/types/lib/slice/serialize.d.ts +0 -78
- package/dist/types/lib/slice/sliceForKey.d.ts +0 -47
- package/dist/types/lib/slice/types.d.ts +0 -567
- package/dist/types/lib/time-travel/axis.d.ts +0 -119
- package/dist/types/lib/time-travel/bundles.d.ts +0 -77
- package/dist/types/lib/time-travel/chain.d.ts +0 -93
- package/dist/types/lib/time-travel/commitStops.d.ts +0 -55
- package/dist/types/lib/time-travel/index.d.ts +0 -22
- package/dist/types/lib/time-travel/stateAt.d.ts +0 -102
- package/dist/types/lib/time-travel/tagStops.d.ts +0 -72
- package/dist/types/lib/time-travel/timeTravel.d.ts +0 -70
- package/dist/types/lib/time-travel/types.d.ts +0 -470
- package/dist/types/write.d.ts +0 -47
- package/dist/write.js +0 -52
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* axis.ts — the shape of an axis, and the one safe way to narrow it.
|
|
3
|
-
*
|
|
4
|
-
* WHY THIS FILE EXISTS. `commitStops` returns `Stop[]`, and every strategy
|
|
5
|
-
* that COMPOSES it (keep the stages my domain recognises, drop the rest) rests
|
|
6
|
-
* on a shape the type never stated: `[start, …stages, end]` for a non-empty
|
|
7
|
-
* log, empty for an empty one. Each composer therefore wrote its own runtime
|
|
8
|
-
* guard against its own reading of the contract, plus a mocked-substrate test
|
|
9
|
-
* to prove the guard fires. That is one invariant, discovered three times, and
|
|
10
|
-
* the library that owns the invariant should be the one that states it.
|
|
11
|
-
*
|
|
12
|
-
* {@link splitAxis} states it. {@link filterStops} then does the whole
|
|
13
|
-
* composition — check the shape, keep what the caller keeps, RE-PARTITION the
|
|
14
|
-
* log so the dropped stages' commits are still folded somewhere, and mark the
|
|
15
|
-
* `'start'` bookend as carrying a prologue — because getting the
|
|
16
|
-
* re-partitioning right by hand is the other thing every composer had to
|
|
17
|
-
* rediscover.
|
|
18
|
-
*/
|
|
19
|
-
import type { AxisSplit, Stop } from './types.js';
|
|
20
|
-
/**
|
|
21
|
-
* Split a strategy's stops into `{ start, stages, end }`, or say why it cannot.
|
|
22
|
-
*
|
|
23
|
-
* THE INVARIANT, stated once: for a non-EMPTY log, `commitStops` returns at
|
|
24
|
-
* least the two bookends, `'start'` first and `'end'` last, with one stop per
|
|
25
|
-
* executed stage in execution order between them. For an EMPTY log it returns
|
|
26
|
-
* `[]` — no bookends around nothing, because a cursor with nowhere to stand
|
|
27
|
-
* should say `reason: 'empty'` rather than offer two positions that are the
|
|
28
|
-
* same position.
|
|
29
|
-
*
|
|
30
|
-
* The two refusals are different facts and must not be collapsed: `'empty'`
|
|
31
|
-
* means the run committed nothing, `'not-bookended'` means a strategy broke
|
|
32
|
-
* the contract. A composer that treats them alike reports a broken strategy as
|
|
33
|
-
* an empty run.
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* ```typescript
|
|
37
|
-
* import { commitStops, splitAxis } from 'footprintjs/trace';
|
|
38
|
-
*
|
|
39
|
-
* const axis = splitAxis(commitStops(snapshot.commitLog, snapshot.executionTree));
|
|
40
|
-
* if (axis.ok) {
|
|
41
|
-
* axis.start.commitIdx; // -1 — the fold base
|
|
42
|
-
* axis.stages.map((s) => s.label);
|
|
43
|
-
* axis.end.lastCommitIdx; // the last bundle in the log
|
|
44
|
-
* } else {
|
|
45
|
-
* axis.reason; // 'empty' | 'not-bookended'
|
|
46
|
-
* }
|
|
47
|
-
* ```
|
|
48
|
-
*/
|
|
49
|
-
export declare function splitAxis<TMeta = unknown>(stops: readonly Stop<TMeta>[]): AxisSplit<TMeta>;
|
|
50
|
-
/**
|
|
51
|
-
* What {@link filterStops} does with one stop: drop it, keep it, or keep it
|
|
52
|
-
* carrying the strategy's own label and vocabulary.
|
|
53
|
-
*
|
|
54
|
-
* `false` / `null` / `undefined` drop. `true` keeps it unchanged. An object
|
|
55
|
-
* keeps it and overrides `label` and/or sets `meta` — the strategy's own
|
|
56
|
-
* classification, travelling ON the stop instead of being re-derived from
|
|
57
|
-
* `runtimeStageId` at every read.
|
|
58
|
-
*/
|
|
59
|
-
export type StopFilter<TMeta> = boolean | null | undefined | {
|
|
60
|
-
readonly label?: string;
|
|
61
|
-
readonly meta?: TMeta;
|
|
62
|
-
};
|
|
63
|
-
/**
|
|
64
|
-
* Build a FILTERING strategy's axis out of another strategy's stops.
|
|
65
|
-
*
|
|
66
|
-
* The rule, in one sentence: keep the stages `keep` recognises, and give the
|
|
67
|
-
* survivors the log back.
|
|
68
|
-
*
|
|
69
|
-
* **Meta is the decision's, never inherited.** The input may already be a
|
|
70
|
-
* filtered axis carrying another strategy's `meta`; a `true` (or a meta-less
|
|
71
|
-
* object) keeps the stop and DROPS that meta, so a `Stop<TMeta>` never carries
|
|
72
|
-
* a value of some other type under `TMeta`. The bookends carry none either.
|
|
73
|
-
*
|
|
74
|
-
* **The survivors re-partition the log.** A dropped stage's commits still
|
|
75
|
-
* happened, so they fold into the stop that PRECEDES them: every kept stop's
|
|
76
|
-
* `lastCommitIdx` runs to just before the next kept stop begins. Nothing is
|
|
77
|
-
* orphaned and `stateAt(stop)` stays "the state that existed when the next
|
|
78
|
-
* kept stage started".
|
|
79
|
-
*
|
|
80
|
-
* **What that costs `'start'`, said out loud.** The commits before the first
|
|
81
|
-
* survivor have nowhere else to go, so `'start'` absorbs them: its fold is the
|
|
82
|
-
* run's base PLUS that prologue — the state the first stop READ, not the raw
|
|
83
|
-
* base. The returned start therefore carries `prologue: true` whenever it
|
|
84
|
-
* actually absorbed a stage, and a renderer that means "before anything ran"
|
|
85
|
-
* checks `kind === 'start' && !prologue`. That flag is the whole reason this
|
|
86
|
-
* helper exists rather than a `.filter()` call.
|
|
87
|
-
*
|
|
88
|
-
* **A log with nothing kept** yields the two bookends and nothing between
|
|
89
|
-
* them: `'start'` folds the whole log, `'end'` folds the whole log, and
|
|
90
|
-
* `jumpTo` on any stage id refuses with `reason: 'miss'`. An axis with nowhere
|
|
91
|
-
* meaningful to stand — which is the truthful shape for a run this strategy
|
|
92
|
-
* recognises nothing in, and NOT the `[]` that says the log was empty.
|
|
93
|
-
*
|
|
94
|
-
* @throws when `stops` is non-empty but not bookended — see {@link splitAxis}.
|
|
95
|
-
* Only a strategy can cause that; a run cannot, so it is a contract error
|
|
96
|
-
* and not a condition to fold into the data.
|
|
97
|
-
*
|
|
98
|
-
* @example
|
|
99
|
-
* ```typescript
|
|
100
|
-
* import { commitStops, filterStops } from 'footprintjs/trace';
|
|
101
|
-
* import type { Stop, TimeTravelStrategy } from 'footprintjs/trace';
|
|
102
|
-
*
|
|
103
|
-
* type Milestone = { kind: 'llm-turn' | 'tool-call'; label: string };
|
|
104
|
-
* declare function milestoneFor(runtimeStageId: string): Milestone | null;
|
|
105
|
-
*
|
|
106
|
-
* const milestoneStops: TimeTravelStrategy<Milestone> = {
|
|
107
|
-
* stopsFor: (log, tree) =>
|
|
108
|
-
* filterStops<Milestone>(commitStops(log, tree), (stop) => {
|
|
109
|
-
* const m = milestoneFor(stop.runtimeStageId);
|
|
110
|
-
* return m ? { label: m.label, meta: m } : null;
|
|
111
|
-
* }),
|
|
112
|
-
* };
|
|
113
|
-
*
|
|
114
|
-
* const cursor = timeTravel(snapshot, { strategy: milestoneStops });
|
|
115
|
-
* cursor.at()?.meta?.kind; // 'llm-turn' — no re-derivation
|
|
116
|
-
* cursor.stops[0].prologue; // true when stages ran before the first turn
|
|
117
|
-
* ```
|
|
118
|
-
*/
|
|
119
|
-
export declare function filterStops<TMeta = unknown>(stops: readonly Stop<unknown>[], keep: (stop: Stop<unknown>) => StopFilter<TMeta>): Stop<TMeta>[];
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* bundles.ts — reading a log whose rows are not typed yet.
|
|
3
|
-
*
|
|
4
|
-
* WHY THIS FILE EXISTS. A LIVE snapshot hands time travel real
|
|
5
|
-
* {@link CommitBundle}s. A STORED recording hands it parsed JSON, and a
|
|
6
|
-
* careful consumer will not claim that what came back off disk is a
|
|
7
|
-
* `CommitBundle` — so it either casts (a lie with a comment on it) or cannot
|
|
8
|
-
* call the library at all. Since 9.18.0 the source takes `readonly unknown[]`
|
|
9
|
-
* and the narrowing happens here, per row, at the one place that actually
|
|
10
|
-
* reads one.
|
|
11
|
-
*
|
|
12
|
-
* A row that is not a bundle becomes a GAP rather than an exception: it KEEPS
|
|
13
|
-
* ITS INDEX — so every `commitIdx` in the axis still addresses the same
|
|
14
|
-
* position — contributes no state, gets no stop, and is reported with its
|
|
15
|
-
* index and a reason. One corrupt row in a stored recording loses that row,
|
|
16
|
-
* not the recording.
|
|
17
|
-
*/
|
|
18
|
-
import type { CommitBundle, ExecutionTree } from '../memory/types.js';
|
|
19
|
-
import type { LogGap } from './types.js';
|
|
20
|
-
/** A plain object — not null, not an array, not a primitive. */
|
|
21
|
-
export declare function isPlainish(value: unknown): value is Record<string, unknown>;
|
|
22
|
-
/**
|
|
23
|
-
* Read a source's `executionTree` as an {@link ExecutionTree}, or as absent.
|
|
24
|
-
*
|
|
25
|
-
* The tree is only ever WALKED for mount ids (`subflowId` + `runtimeStageId`
|
|
26
|
-
* on each node), so the honest narrowing a reader can do is "a plain object";
|
|
27
|
-
* anything else — a stored field that came back as a string, a number, an
|
|
28
|
-
* array — is read as no tree at all, which sends `commitStops` down the same
|
|
29
|
-
* shape-heuristic path a log handed over without its tree already takes.
|
|
30
|
-
*/
|
|
31
|
-
export declare function readTree(value: unknown): ExecutionTree | undefined;
|
|
32
|
-
/**
|
|
33
|
-
* Why `row` cannot be read as a commit bundle, or `undefined` when it can.
|
|
34
|
-
*
|
|
35
|
-
* DELIBERATELY LENIENT — but exactly as lenient as the readers are. It checks
|
|
36
|
-
* what the fold, the axis and `changedSince` actually touch:
|
|
37
|
-
*
|
|
38
|
-
* - `runtimeStageId` must be a string — the axis keys on it.
|
|
39
|
-
* - `trace` must be an ARRAY, and it must be PRESENT. It is the one field
|
|
40
|
-
* every reader WALKS (`applySmartMerge` iterates it verb by verb;
|
|
41
|
-
* `changedSince` reads its paths), so a row without one is not a bundle the
|
|
42
|
-
* fold can survive — it is the crash a gap exists to prevent. `CommitBundle`
|
|
43
|
-
* declares it required, so no live log is affected.
|
|
44
|
-
* - `updates` / `overwrite`, when present, must be plain objects. They are
|
|
45
|
-
* read only AT THE PATHS THE TRACE NAMES, so an absent one is harmless and
|
|
46
|
-
* is tolerated, exactly as the fold tolerates an absent `redactedPaths`.
|
|
47
|
-
*
|
|
48
|
-
* Being stricter than that — demanding `stage`, `stageId`, `idx` — would
|
|
49
|
-
* reject hand-built logs that have folded correctly since 9.17.0, which is a
|
|
50
|
-
* compatibility break dressed up as validation.
|
|
51
|
-
*/
|
|
52
|
-
export declare function bundleRefusal(row: unknown): string | undefined;
|
|
53
|
-
/** `true` when `row` can be read as a {@link CommitBundle}. */
|
|
54
|
-
export declare function isCommitBundle(row: unknown): row is CommitBundle;
|
|
55
|
-
/** A log read row by row: the bundles, index-aligned, plus what was refused. */
|
|
56
|
-
export interface ReadLog {
|
|
57
|
-
/** Same length and order as the input; a refused row holds a GAP stand-in. */
|
|
58
|
-
readonly log: readonly CommitBundle[];
|
|
59
|
-
/** The refused rows, in index order. Empty when the log was clean. */
|
|
60
|
-
readonly gaps: readonly LogGap[];
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Read an unvalidated array as a commit log.
|
|
64
|
-
*
|
|
65
|
-
* The clean case (a live snapshot, or a stored recording that round-tripped
|
|
66
|
-
* intact) returns the SAME array reference and no gaps: nothing is copied,
|
|
67
|
-
* nothing is allocated, and the fold behaves byte for byte as it did in
|
|
68
|
-
* 9.17.0. Only a log with a refused row is rebuilt, and only to keep the
|
|
69
|
-
* indices aligned.
|
|
70
|
-
*
|
|
71
|
-
* @example
|
|
72
|
-
* ```typescript
|
|
73
|
-
* const { log, gaps } = readLog(JSON.parse(stored).commitLog);
|
|
74
|
-
* gaps; // [{ index: 3, reason: 'not an object (null)' }]
|
|
75
|
-
* ```
|
|
76
|
-
*/
|
|
77
|
-
export declare function readLog(raw: readonly unknown[] | undefined): ReadLog;
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* chain.ts — reading a pause/resume as ONE axis.
|
|
3
|
-
*
|
|
4
|
-
* WHY THIS FILE EXISTS. A pause and its resume produce TWO snapshots. On a
|
|
5
|
-
* cross-executor resume (the checkpoint was persisted and a fresh executor
|
|
6
|
-
* picked it up) the second run gets a fresh runtime: its `commitLog` starts at
|
|
7
|
-
* index 0 and holds only the post-resume commits, and its `initialState` is
|
|
8
|
-
* the state at the pause. Two logs, two disjoint axes — so a reader scrubbing
|
|
9
|
-
* a resumed run saw only the second half unless the application had kept the
|
|
10
|
-
* paused snapshot and stitched the halves itself. Every application that
|
|
11
|
-
* pauses would write that stitching, and none of them own the arithmetic.
|
|
12
|
-
*
|
|
13
|
-
* THE HONEST BIT, up front: COMMIT INDICES ARE RUN-LOCAL. There is no global
|
|
14
|
-
* index across a chain and this file does not invent one — `commitIdx` and
|
|
15
|
-
* `lastCommitIdx` keep indexing their own source, and every stop carries the
|
|
16
|
-
* {@link Stop.sourceIdx} they belong to. The cursor's STEPS are what run
|
|
17
|
-
* across the whole chain.
|
|
18
|
-
*
|
|
19
|
-
* AND THE REFUSAL: a chain that is not ordered, or whose legs are not from one
|
|
20
|
-
* lineage, is REFUSED rather than guessed at. The record carries TWO signals
|
|
21
|
-
* and this file reads both:
|
|
22
|
-
*
|
|
23
|
-
* - The execution index the engine stamps into every `runtimeStageId` —
|
|
24
|
-
* globally monotonic per run and, deliberately, NOT reset on resume. So a
|
|
25
|
-
* later leg's first execution index must be past the earlier leg's last, and
|
|
26
|
-
* no stage may appear in two legs. This catches a backwards chain, a fresh
|
|
27
|
-
* run (which restarts at 0) and a same-executor resume (whose one snapshot
|
|
28
|
-
* already holds both halves).
|
|
29
|
-
* - The later leg's `initialState`. On a resume the fresh runtime is seeded
|
|
30
|
-
* from the checkpoint, so that base IS the state at the pause — and the
|
|
31
|
-
* state the earlier legs FOLD TO must deep-equal it. This is what catches a
|
|
32
|
-
* leg from some OTHER lineage whose indices merely happen to be higher: the
|
|
33
|
-
* counters line up by accident, the state never does.
|
|
34
|
-
*
|
|
35
|
-
* A chart identity or a lineage id is NOT on the record, so nothing here
|
|
36
|
-
* pretends to check one. And where the state signal is not on the record
|
|
37
|
-
* either — a leg recorded before 9.17 carries no `initialState`; an earlier
|
|
38
|
-
* leg with no base folds `'log-only'`; a leg with unreadable rows folds an
|
|
39
|
-
* incomplete state — that check is SKIPPED, not faked: the chain then rests on
|
|
40
|
-
* the index checks alone, and every fold's `basis` still says what it stood
|
|
41
|
-
* on. That degradation is documented on `refuseChain`, on `timeTravel`'s
|
|
42
|
-
* `@throws`, and in the README.
|
|
43
|
-
*/
|
|
44
|
-
import type { CommitBundle } from '../memory/types.js';
|
|
45
|
-
import { type ReadSource } from './stateAt.js';
|
|
46
|
-
import type { TimeTravelSource } from './types.js';
|
|
47
|
-
/** One leg of a chain: a source, its read log, and where it sits in the run. */
|
|
48
|
-
export interface ChainLeg {
|
|
49
|
-
readonly source: TimeTravelSource;
|
|
50
|
-
readonly log: readonly CommitBundle[];
|
|
51
|
-
/** Lowest execution index stamped in this leg; `undefined` for an id-less log. */
|
|
52
|
-
readonly firstExecutionIndex: number | undefined;
|
|
53
|
-
/** Highest execution index stamped in this leg. */
|
|
54
|
-
readonly lastExecutionIndex: number | undefined;
|
|
55
|
-
}
|
|
56
|
-
/** The execution-index span of one leg, read off its `runtimeStageId`s. */
|
|
57
|
-
export declare function spanOf(log: readonly CommitBundle[]): {
|
|
58
|
-
first: number | undefined;
|
|
59
|
-
last: number | undefined;
|
|
60
|
-
ids: Set<string>;
|
|
61
|
-
};
|
|
62
|
-
/**
|
|
63
|
-
* Check that `legs` really are one run read in order, and say why not.
|
|
64
|
-
*
|
|
65
|
-
* Returns the refusal message, or `undefined` when the chain is sound. Three
|
|
66
|
-
* distinct failures, because they are three different mistakes, checked in
|
|
67
|
-
* this order:
|
|
68
|
-
*
|
|
69
|
-
* - REPEATED STAGE — one `runtimeStageId` appears in two legs. Ids are unique
|
|
70
|
-
* within a run, so a repeat means the same execution was recorded twice: a
|
|
71
|
-
* same-executor resume, whose snapshot ALREADY holds the whole log and needs
|
|
72
|
-
* no chaining, is the usual cause.
|
|
73
|
-
* - OUT OF ORDER — a later leg's first execution index is not past the earlier
|
|
74
|
-
* leg's last. Either the sources were handed over backwards, or the second
|
|
75
|
-
* is not a continuation at all (a fresh run restarts the counter at 0, so an
|
|
76
|
-
* unrelated snapshot fails here rather than silently interleaving).
|
|
77
|
-
* - WRONG LINEAGE — leg k's `initialState` is not the state legs 0..k-1 fold
|
|
78
|
-
* to. On a resume the later leg is seeded from the checkpoint, so its base
|
|
79
|
-
* IS the state at the pause; a leg that begins anywhere else is from some
|
|
80
|
-
* other run, however its indices happen to line up.
|
|
81
|
-
*
|
|
82
|
-
* THE LINEAGE CHECK RUNS ONLY WHERE THE RECORD ALLOWS IT, and is skipped —
|
|
83
|
-
* never faked — otherwise: leg k must carry an `initialState` (a recording
|
|
84
|
-
* made before 9.17 has none), and the fold of the legs before it must stand on
|
|
85
|
-
* a real base (`basis: 'initial+log'`) with no unreadable rows (`skipped`
|
|
86
|
-
* absent) — a log-only or gapped fold is not a state a real base may be held
|
|
87
|
-
* against. On such a chain the two index checks are the whole defence, and
|
|
88
|
-
* `foldLegs`' leg rule then CONTINUES the fold across the seam, which is the
|
|
89
|
-
* right state for a real resume and is what `basis` reports. Paths the log
|
|
90
|
-
* was redacted at are excluded from the comparison: the fold holds
|
|
91
|
-
* `'REDACTED'` there and the checkpoint holds the value.
|
|
92
|
-
*/
|
|
93
|
-
export declare function refuseChain(legs: readonly ReadSource[]): string | undefined;
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* commitStops — the one strategy footprintjs ships.
|
|
3
|
-
*
|
|
4
|
-
* One stop per executed stage, in execution order, plus `'start'` / `'end'`
|
|
5
|
-
* bookends. It is the only stop grammar the substrate itself knows: the engine
|
|
6
|
-
* stamps one `runtimeStageId` per executed stage, and an empty commit is a
|
|
7
|
-
* deliberate cursor stop, not noise. Richer vocabularies (milestones, turns,
|
|
8
|
-
* tool calls) belong to the consumer that owns them — they plug in through
|
|
9
|
-
* `TimeTravelStrategy`, they do not go here.
|
|
10
|
-
*/
|
|
11
|
-
import type { CommitBundle, ExecutionTree } from '../memory/types.js';
|
|
12
|
-
import type { Stop, TimeTravelStrategy } from './types.js';
|
|
13
|
-
/**
|
|
14
|
-
* Derive one stop per executed stage from a recorded commit log.
|
|
15
|
-
*
|
|
16
|
-
* **One stop per `runtimeStageId`.** A stage can commit MORE than one bundle:
|
|
17
|
-
* a subflow mount commits its output-mapping bundle and then its EXIT; a
|
|
18
|
-
* parallel fork child is committed by the stage funnel and again by the
|
|
19
|
-
* fan-out (its REPEAT), and siblings interleave. The writer names each
|
|
20
|
-
* continuation on its bundle (`phase: 'exit' | 'repeat'`, 9.39.0), so the
|
|
21
|
-
* grouping is read, never inferred: the axis shows the stage ONCE, at its
|
|
22
|
-
* first commit ({@link buildCommitIndex}), which keeps `runtimeStageId → stop`
|
|
23
|
-
* one-to-one — the property `jumpTo` and marks depend on. The FIRST bundle per
|
|
24
|
-
* `runtimeStageId` is the stage's own and never carries a `phase`; a stage
|
|
25
|
-
* whose bundles include an `'exit'` is a `'mount'`. A continuation is normally empty
|
|
26
|
-
* (the first commit released the staging buffer); one that carries a write is
|
|
27
|
-
* folded where it sits in the log, which is when it happened.
|
|
28
|
-
*
|
|
29
|
-
* **Stops PARTITION the log.** A stop's range runs from its own first commit
|
|
30
|
-
* up to (and including) the last commit before the NEXT stop begins —
|
|
31
|
-
* `lastCommitIdx`. Every bundle therefore belongs to exactly one stop, nothing
|
|
32
|
-
* is orphaned, and `stateAt(stop)` is precisely the state that existed just
|
|
33
|
-
* before the next stop's stage started. Folding through `commitIdx` instead
|
|
34
|
-
* would silently drop a mount's output mapping.
|
|
35
|
-
*
|
|
36
|
-
* **Bookends.** `'start'` is the position before the first commit — the fold
|
|
37
|
-
* base, which no commit index can otherwise address. `'end'` is "the run is
|
|
38
|
-
* over"; it folds the whole log, the same as the last stage's stop, because
|
|
39
|
-
* "after the last stage" and "the run finished" are the same state asked as
|
|
40
|
-
* two different questions.
|
|
41
|
-
*
|
|
42
|
-
* An EMPTY log yields NO stops at all — not two bookends around nothing. A
|
|
43
|
-
* cursor with nowhere to stand says so (`Move.reason === 'empty'`).
|
|
44
|
-
*
|
|
45
|
-
* **THE SHAPE IS A CONTRACT (9.18.0).** For a non-empty log the result is
|
|
46
|
-
* `[start, …stages, end]` — `'start'` first, `'end'` last, one stop per
|
|
47
|
-
* executed stage between them, in execution order — and for an empty log it
|
|
48
|
-
* is `[]`. A strategy that COMPOSES this one (keep some stages, drop the rest)
|
|
49
|
-
* rests on that shape; it is pinned by `test/lib/time-travel/`, and
|
|
50
|
-
* {@link splitAxis} is the one guard that reads it — a composer calls that, or
|
|
51
|
-
* {@link filterStops} which calls it, instead of writing its own.
|
|
52
|
-
*/
|
|
53
|
-
export declare function commitStops(commitLog: readonly CommitBundle[], executionTree?: ExecutionTree, subflowResults?: unknown): Stop[];
|
|
54
|
-
/** `commitStops` as a {@link TimeTravelStrategy} — the default for `timeTravel`. */
|
|
55
|
-
export declare const commitStopsStrategy: TimeTravelStrategy;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* time-travel/ — the reader's cursor over a finished trace.
|
|
3
|
-
*
|
|
4
|
-
* Time travel here is READ-TIME: a cursor over a Trace that has already
|
|
5
|
-
* happened, with a Fold at each stop. It is not the Walker and never becomes a
|
|
6
|
-
* second live cursor — nothing in this folder can move, re-run or mutate an
|
|
7
|
-
* execution.
|
|
8
|
-
*
|
|
9
|
-
* See README.md for the five laws, the strategy seam, and a worked example of
|
|
10
|
-
* every export.
|
|
11
|
-
*
|
|
12
|
-
* DAG position: memory ← time-travel (plus `ids/runtimeStageId`, the
|
|
13
|
-
* zero-dependency id grammar).
|
|
14
|
-
*/
|
|
15
|
-
export type { StopFilter } from './axis.js';
|
|
16
|
-
export { filterStops, splitAxis } from './axis.js';
|
|
17
|
-
export { isCommitBundle } from './bundles.js';
|
|
18
|
-
export { commitStops, commitStopsStrategy } from './commitStops.js';
|
|
19
|
-
export { stateAt } from './stateAt.js';
|
|
20
|
-
export { tagStops } from './tagStops.js';
|
|
21
|
-
export { timeTravel } from './timeTravel.js';
|
|
22
|
-
export type { AxisRefusal, AxisSplit, BookendedAxis, FoldBasis, FoldedState, FoldSource, LogGap, Mark, Move, MoveRefusal, Stop, StopKind, TimeTravel, TimeTravelOptions, TimeTravelSource, TimeTravelStrategy, } from './types.js';
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* stateAt — the fold at a stop.
|
|
3
|
-
*
|
|
4
|
-
* The commit log stores DIFFS. Replaying them onto the run's fold base
|
|
5
|
-
* reproduces the state as it stood after any commit — byte-for-byte the state
|
|
6
|
-
* the next stage saw, in both `commitValues` encodings, because the replay
|
|
7
|
-
* runs through `applySmartMergeInto`, the one verb law (`memory/verbs.ts`) the
|
|
8
|
-
* live commit itself uses. There is deliberately no second implementation of
|
|
9
|
-
* the verbs here.
|
|
10
|
-
*/
|
|
11
|
-
import type { CommitBundle } from '../memory/types.js';
|
|
12
|
-
import type { FoldedState, FoldSource, LogGap } from './types.js';
|
|
13
|
-
/** One source, read: its log (gaps held in place) and its fold base. */
|
|
14
|
-
export interface ReadSource {
|
|
15
|
-
readonly log: readonly CommitBundle[];
|
|
16
|
-
readonly gaps: readonly LogGap[];
|
|
17
|
-
readonly base: Record<string, unknown> | undefined;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Read whichever shape the caller handed us — `commitLog` (a run snapshot) or
|
|
21
|
-
* `history` (a subflow's own log) — narrowing the rows to commit bundles as it
|
|
22
|
-
* goes (see `bundles.ts`: a row that is not one becomes an index-holding gap).
|
|
23
|
-
*/
|
|
24
|
-
export declare function readSource(source: FoldSource | undefined): ReadSource;
|
|
25
|
-
/**
|
|
26
|
-
* Fold one chain of legs: every leg BEFORE `legIdx` in full, then `legIdx`
|
|
27
|
-
* through `through`.
|
|
28
|
-
*
|
|
29
|
-
* THE LEG RULE. A leg that carries its own `initialState` RESTARTS the
|
|
30
|
-
* accumulation from it — on a pause/resume that base IS the state at the
|
|
31
|
-
* pause, recorded by the engine, and is authoritative over anything the
|
|
32
|
-
* previous leg's log rebuilt. A leg with no base (a pre-9.17 snapshot, a
|
|
33
|
-
* hand-built log) CONTINUES from what the earlier legs folded, which is the
|
|
34
|
-
* best honest answer available and is exactly what `basis` then reports.
|
|
35
|
-
*
|
|
36
|
-
* With a single leg this is the 9.17.0 fold, unchanged.
|
|
37
|
-
*/
|
|
38
|
-
export declare function foldLegs(legs: readonly ReadSource[], legIdx: number, through: number): FoldedState;
|
|
39
|
-
/**
|
|
40
|
-
* What a fold leaves behind for the NEXT one (9.25.0): the private working
|
|
41
|
-
* copy and the facts accumulated so far. A cursor stepping forward on the
|
|
42
|
-
* same leg hands it back and only the bundles after `through` are applied —
|
|
43
|
-
* one bundle per step instead of a replay from the base. Any other ask (an
|
|
44
|
-
* earlier stop, another leg) folds from scratch; the memo is never a claim.
|
|
45
|
-
*/
|
|
46
|
-
export interface FoldMemo {
|
|
47
|
-
readonly legIdx: number;
|
|
48
|
-
readonly through: number;
|
|
49
|
-
readonly out: Record<string, unknown>;
|
|
50
|
-
readonly based: boolean;
|
|
51
|
-
readonly redactedPaths: ReadonlySet<string>;
|
|
52
|
-
readonly skipped: readonly LogGap[] | undefined;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* The fold, resumable. ONE clone per fold: the base is cloned once (or `{}`
|
|
56
|
-
* stands in), every bundle is applied INTO that copy, and the state handed
|
|
57
|
-
* out is one more clone, frozen — so the working copy stays private and a
|
|
58
|
-
* later step can continue from it. Same answer as the 9.17.0 fold, pinned by
|
|
59
|
-
* test/lib/time-travel/fold-memo.test.ts against a fresh fold at every stop.
|
|
60
|
-
*/
|
|
61
|
-
export declare function foldLegsFrom(legs: readonly ReadSource[], legIdx: number, through: number, memo?: FoldMemo): {
|
|
62
|
-
readonly folded: FoldedState;
|
|
63
|
-
readonly memo: FoldMemo;
|
|
64
|
-
};
|
|
65
|
-
/**
|
|
66
|
-
* Fold `source`'s log from its base up to and including `commitIdx`.
|
|
67
|
-
*
|
|
68
|
-
* @param source A run snapshot (`commitLog` + `initialState`) or a subflow
|
|
69
|
-
* subtree (`history` + `initialState`). Both spellings work,
|
|
70
|
-
* and the rows may be unvalidated (`unknown[]`) — a row that
|
|
71
|
-
* is not a commit bundle is skipped and REPORTED, by index,
|
|
72
|
-
* in {@link FoldedState.skipped}, never crashed on.
|
|
73
|
-
* @param commitIdx ARRAY INDEX of the last bundle to fold, inclusive. `-1`
|
|
74
|
-
* (or any negative) folds nothing and returns the base —
|
|
75
|
-
* the state before the run's first commit. Past the end
|
|
76
|
-
* clamps to the end; the result's `throughCommitIdx` reports
|
|
77
|
-
* where the fold actually stopped.
|
|
78
|
-
*
|
|
79
|
-
* @returns A detached, deeply frozen state plus how it was derived: `basis`
|
|
80
|
-
* says whether the real fold base was available, `redacted` /
|
|
81
|
-
* `redactedPaths` say where the log was scrubbed at write time, and
|
|
82
|
-
* `skipped` says which rows could not be read. The engine redacts values as
|
|
83
|
-
* it records them, so a replay of a redacted run yields `'REDACTED'` in
|
|
84
|
-
* those places — correct, and said out loud rather than presented as the
|
|
85
|
-
* real value.
|
|
86
|
-
*
|
|
87
|
-
* @example
|
|
88
|
-
* ```typescript
|
|
89
|
-
* const snapshot = executor.getSnapshot();
|
|
90
|
-
* const { state, basis } = stateAt(snapshot, 3); // after the 4th commit
|
|
91
|
-
* console.log(basis, state); // 'initial+log' { ... }
|
|
92
|
-
*
|
|
93
|
-
* // A subflow's own log folds identically:
|
|
94
|
-
* const inner = getSubtreeSnapshot(snapshot, 'sf-payment')!;
|
|
95
|
-
* stateAt(inner, 0).state; // after the subflow's first commit
|
|
96
|
-
*
|
|
97
|
-
* // A STORED recording needs no cast — its rows are `unknown[]`:
|
|
98
|
-
* const stored = JSON.parse(await fs.readFile(path, 'utf8'));
|
|
99
|
-
* stateAt(stored, 3).skipped; // undefined, or the bad rows
|
|
100
|
-
* ```
|
|
101
|
-
*/
|
|
102
|
-
export declare function stateAt(source: FoldSource | undefined, commitIdx: number): FoldedState;
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* tagStops — the stops a chart DECLARED, read back off its commit log.
|
|
3
|
-
*
|
|
4
|
-
* WHY THIS FILE EXISTS. `commitStops` is the only stop grammar the substrate
|
|
5
|
-
* knows: one stop per executed stage. Every richer axis — milestones, turns,
|
|
6
|
-
* tool calls — was a consumer's classifier over `runtimeStageId`: a switch
|
|
7
|
-
* that parses `#` and `/`, lives outside the recording, and goes stale when
|
|
8
|
-
* a stage is renamed. Since 9.21.0 the author can put NAMES on a stage at
|
|
9
|
-
* build time (`FlowChartBuilder.tag` / `options.tags`) and the engine stamps
|
|
10
|
-
* them on the stage's commit bundle (`CommitBundle.tags`). This strategy
|
|
11
|
-
* reads them back: a stored recording from ANY chart scrubs by its own
|
|
12
|
-
* milestones, with no id conventions in the reader.
|
|
13
|
-
*
|
|
14
|
-
* WHAT IT IS. One expression over `filterStops(commitStops(...))`: keep the
|
|
15
|
-
* stops whose FIRST bundle carries a tag (any of the asked-for ones, or any
|
|
16
|
-
* tag at all when none are asked for), give the survivors the log back, and
|
|
17
|
-
* carry the bundle's whole tag array as `Stop.meta`. Everything a filtering
|
|
18
|
-
* axis owes — the bookend guard, the re-partition so a dropped stage's
|
|
19
|
-
* commits fold into the tagged stop BEFORE them, `prologue` on a start that
|
|
20
|
-
* absorbed stages — comes from `filterStops`, stated once, in `axis.ts`.
|
|
21
|
-
*
|
|
22
|
-
* WHAT IT IS NOT. Not a second vocabulary: the strings are the consumer's,
|
|
23
|
-
* carried verbatim. Not a derivation: a stage with no declared tag gets no
|
|
24
|
-
* stop here, however recognisable its id — a reader that wants ids classified
|
|
25
|
-
* writes that keep rule itself (`filterStops`), or reads the fold
|
|
26
|
-
* (`stateAt`) and keeps by what changed. And not a re-walk: only a tag the
|
|
27
|
-
* engine actually stamped can put a stop on this axis.
|
|
28
|
-
*/
|
|
29
|
-
import type { TimeTravelStrategy } from './types.js';
|
|
30
|
-
/**
|
|
31
|
-
* A {@link TimeTravelStrategy} whose stops are the stages that carry a
|
|
32
|
-
* declared tag.
|
|
33
|
-
*
|
|
34
|
-
* **Keep rule: any-of.** A stop survives when its bundle's `tags` shares at
|
|
35
|
-
* least one name with `tags`; with `tags` omitted (or empty), every tagged
|
|
36
|
-
* stop survives. All-of, or a rule over more than the tags, is a
|
|
37
|
-
* `filterStops` call away — the library owns no vocabulary, so it owns no
|
|
38
|
-
* richer rule either.
|
|
39
|
-
*
|
|
40
|
-
* **Attribution by precedence.** An untagged stage's commits fold into the
|
|
41
|
-
* tagged stop BEFORE it (what `filterStops` does); the commits before the
|
|
42
|
-
* first tagged stage are absorbed by `'start'`, which then says
|
|
43
|
-
* `prologue: true`. A run with no tagged stage yields the two bookends only.
|
|
44
|
-
*
|
|
45
|
-
* **`meta` is the array.** Each kept stop carries its bundle's full `tags`
|
|
46
|
-
* (not just the ones asked for), so a reader that filtered on
|
|
47
|
-
* `'milestone:llm-turn'` can still see the stage was also `'audit'`.
|
|
48
|
-
*
|
|
49
|
-
* **The equivalence law.** `stateAt(stop)` at every kept stop equals
|
|
50
|
-
* `commitStops`'s fold at the same commit index — a filtering axis moves the
|
|
51
|
-
* stops, never the log.
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* ```typescript
|
|
55
|
-
* import { flowChart } from 'footprintjs';
|
|
56
|
-
* import { tagStops, timeTravel } from 'footprintjs/trace';
|
|
57
|
-
*
|
|
58
|
-
* const chart = flowChart<State>('Seed', seedFn, 'seed')
|
|
59
|
-
* .addFunction('Call model', callFn, 'call-llm')
|
|
60
|
-
* .tag('milestone:llm-turn')
|
|
61
|
-
* .addFunction('Route', routeFn, 'route')
|
|
62
|
-
* .tag('milestone:decision')
|
|
63
|
-
* .build();
|
|
64
|
-
*
|
|
65
|
-
* // …run it, keep the snapshot…
|
|
66
|
-
* const cursor = timeTravel(snapshot, { strategy: tagStops(['milestone:llm-turn']) });
|
|
67
|
-
* cursor.stops.map((s) => s.label); // ['Run start', 'Call model', 'Run end']
|
|
68
|
-
* cursor.stops[1].meta; // ['milestone:llm-turn']
|
|
69
|
-
* cursor.stops[0].prologue; // true — 'seed' ran before the first turn
|
|
70
|
-
* ```
|
|
71
|
-
*/
|
|
72
|
-
export declare function tagStops(tags?: readonly string[]): TimeTravelStrategy<readonly string[]>;
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* timeTravel — a reader's cursor over a finished trace.
|
|
3
|
-
*
|
|
4
|
-
* The five laws this file implements (and the folder README states with an
|
|
5
|
-
* example each):
|
|
6
|
-
*
|
|
7
|
-
* 1. ONE cursor. This object holds the only position. `drill()` returns a
|
|
8
|
-
* separate cursor over a separate log, never a second position here.
|
|
9
|
-
* 2. A miss never moves. Every refusal returns the reason and leaves the
|
|
10
|
-
* cursor exactly where it was.
|
|
11
|
-
* 3. A fold result is detached. `stateAt` returns frozen, cloned state that
|
|
12
|
-
* shares nothing with the engine.
|
|
13
|
-
* 4. Marks live beside the log. They are the reader's notes, never written
|
|
14
|
-
* into the run's record.
|
|
15
|
-
* 5. Stops are DERIVED from the recorded log — read-time queries over
|
|
16
|
-
* collected data, never a re-walk that invents what was not recorded.
|
|
17
|
-
*
|
|
18
|
-
* A CHAIN (9.18.0) does not add a sixth law and does not bend these five: it
|
|
19
|
-
* is still one cursor, over sources that are still only read. What it adds is
|
|
20
|
-
* that the STEPS run across a pause/resume — see `chain.ts` for the ordering
|
|
21
|
-
* and lineage checks, and for why commit indices stay run-local.
|
|
22
|
-
*/
|
|
23
|
-
import type { TimeTravel, TimeTravelOptions, TimeTravelSource } from './types.js';
|
|
24
|
-
/**
|
|
25
|
-
* Open a reader's cursor over a finished run.
|
|
26
|
-
*
|
|
27
|
-
* Nothing here executes anything: `snapshot` is a record of a run that already
|
|
28
|
-
* happened, and every question is answered by reading it. A stored JSON
|
|
29
|
-
* snapshot works exactly like a live one — since 9.18.0 its `commitLog` may be
|
|
30
|
-
* an unvalidated `unknown[]`, narrowed per bundle where the fold reads it, so
|
|
31
|
-
* a replayed recording needs no cast.
|
|
32
|
-
*
|
|
33
|
-
* @param snapshot `executor.getSnapshot()`, or any object with the same
|
|
34
|
-
* shape — including one round-tripped through JSON, or a subflow subtree
|
|
35
|
-
* (`getSubtreeSnapshot()`, whose log is spelled `history`). An ARRAY of them
|
|
36
|
-
* is a CHAIN: a pause and its resume read as one axis (see below).
|
|
37
|
-
* @param options `strategy` chooses how stops are derived (default:
|
|
38
|
-
* `commitStops`, one stop per executed stage); `marks` seeds the cursor with
|
|
39
|
-
* bookmarks, e.g. restored from a saved reading session.
|
|
40
|
-
*
|
|
41
|
-
* @throws when a chain is not in run order, or its legs are not from one
|
|
42
|
-
* lineage — three checks, each with its own reason (see `chain.ts`):
|
|
43
|
-
* no `runtimeStageId` may appear in two legs; each leg's first execution
|
|
44
|
-
* index must be past the previous leg's last (the engine never resets the
|
|
45
|
-
* counter across a resume); and each leg's `initialState` must deep-equal
|
|
46
|
-
* the state the legs before it fold to — on a resume that base IS the state
|
|
47
|
-
* at the pause, so a foreign leg whose indices merely happen to be higher
|
|
48
|
-
* is refused too. The third check runs only where the record allows it: the
|
|
49
|
-
* later leg must carry an `initialState` and the earlier legs must fold from
|
|
50
|
-
* a real base with no unreadable rows; otherwise (an older recording with
|
|
51
|
-
* no base) the chain rests on the two index checks alone, and the fold's
|
|
52
|
-
* `basis` says what it stood on.
|
|
53
|
-
*
|
|
54
|
-
* @example
|
|
55
|
-
* ```typescript
|
|
56
|
-
* const tt = timeTravel(executor.getSnapshot());
|
|
57
|
-
* tt.jumpTo('score-risk#4');
|
|
58
|
-
* console.log(tt.changedSince()); // ['riskScore', 'tier']
|
|
59
|
-
* console.log(tt.stateAt().state); // state as that stage left it
|
|
60
|
-
* tt.mark('the bad one');
|
|
61
|
-
* const inner = tt.drill('sf-payment#7'); // a separate cursor, its own log
|
|
62
|
-
*
|
|
63
|
-
* // A pause and its resume, read as ONE axis:
|
|
64
|
-
* const chained = timeTravel([pausedSnapshot, resumedSnapshot]);
|
|
65
|
-
* chained.last(); // the run's real end
|
|
66
|
-
* chained.at()!.sourceIdx; // 1 — which leg the indices are in
|
|
67
|
-
* chained.jumpTo('approve#3'); // finds it in either leg
|
|
68
|
-
* ```
|
|
69
|
-
*/
|
|
70
|
-
export declare function timeTravel<TMeta = unknown>(snapshot: TimeTravelSource | readonly TimeTravelSource[], options?: TimeTravelOptions<TMeta>): TimeTravel<TMeta>;
|