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,190 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* slice/elementProvenance.ts — APPEND-FOLD PROVENANCE.
|
|
3
|
-
*
|
|
4
|
-
* THE PROBLEM (why this file exists): in agent charts, almost all dataflow
|
|
5
|
-
* funnels through ONE array key (`history`). A key-level slice on it
|
|
6
|
-
* degenerates to "everything depends on history" — true and useless. The
|
|
7
|
-
* question that actually triages an agent run is element-level:
|
|
8
|
-
* "which stage produced history[7]?".
|
|
9
|
-
*
|
|
10
|
-
* THE INSIGHT: the commit log already contains the answer. Under
|
|
11
|
-
* `commitValues: 'delta'` every array growth is recorded as an `append` verb
|
|
12
|
-
* whose `overwrite[key]` holds exactly the new tail — each element has an
|
|
13
|
-
* explicit birth record. Under `'full'` mode, push-style growth appears as
|
|
14
|
-
* consecutive `set`s where the previous array is a strict prefix of the next
|
|
15
|
-
* — the tail is attributable by inference. No new capture is needed; this is
|
|
16
|
-
* a pure post-hoc query.
|
|
17
|
-
*
|
|
18
|
-
* THE ALGORITHM (append-fold): WATCH the per-key verb fold — the SAME fold
|
|
19
|
-
* `commitValueAt` runs (`memory/verbs.ts` · `foldKey`: one step, `applyVerb`,
|
|
20
|
-
* for every verb; this file has no verb switch of its own) — while carrying a
|
|
21
|
-
* births array kept index-aligned with the value. The observer is told, after
|
|
22
|
-
* each row on, inside or around the key, the value at the key before it and
|
|
23
|
-
* after it, and keeps the births — for the commits that WROTE the key under
|
|
24
|
-
* the writer rule (`commitLogUtils · writersOf`; since 9.33.0 a write inside
|
|
25
|
-
* the key or around it counts, as it does for every key query): a row that
|
|
26
|
-
* records only its tail (`append`) earns an exact attribution; every other row
|
|
27
|
-
* is a whole-value transition attributed by inference. One difference from
|
|
28
|
-
* `commitValueAt`: that helper ANCHORS at the latest `set`/`delete` as a skip
|
|
29
|
-
* optimization (earlier commits cannot change the final VALUE). Provenance
|
|
30
|
-
* must fold from the FIRST touch, because full-mode growth is a chain of
|
|
31
|
-
* `set`s and the anchor would erase every birth but the last. The final value
|
|
32
|
-
* is identical either way (the fold is deterministic left-to-right) — a
|
|
33
|
-
* property test pins this equivalence.
|
|
34
|
-
*
|
|
35
|
-
* INVARIANT (maintained on every branch): when the folded value is an array,
|
|
36
|
-
* `births.length === value.length` and `births[i]` describes `value[i]`.
|
|
37
|
-
*
|
|
38
|
-
* HONESTY: every birth is labeled with how it was determined
|
|
39
|
-
* ({@link AttributionBasis}) — `'append-verb'` is engine-recorded truth,
|
|
40
|
-
* `'prefix-inference'` is a heuristic (a wholesale replacement that happens
|
|
41
|
-
* to share the old prefix is indistinguishable from an append), and
|
|
42
|
-
* `'whole-value'` is an explicit reset. Absence is honest too: a missing
|
|
43
|
-
* provenance carries a {@link MissingProvenanceReason}, mirroring
|
|
44
|
-
* `VariableSlice.missing` — one absence pattern module-wide.
|
|
45
|
-
*
|
|
46
|
-
* COMPLEXITY: delta-mode logs need no equality checks — O(total elements).
|
|
47
|
-
* Full-mode logs pay a strict-prefix check (deepEqual per element) per
|
|
48
|
-
* full-value touch: O(touches × length) element comparisons worst case.
|
|
49
|
-
* Post-hoc query, off the hot path — acceptable; measured in the perf tests.
|
|
50
|
-
*/
|
|
51
|
-
import { commitValueAtWithBasis, rowsUnderRoot, writersOf } from '../memory/commitLogUtils.js';
|
|
52
|
-
import { deepEqual, DELIM } from '../memory/utils.js';
|
|
53
|
-
import { foldKey, recordsTail } from '../memory/verbs.js';
|
|
54
|
-
import { normaliseStateKey } from './sliceForKey.js';
|
|
55
|
-
/** `prev` is a strict (leading, element-equal) prefix of `next`. */
|
|
56
|
-
function isStrictPrefix(prev, next) {
|
|
57
|
-
if (prev.length > next.length)
|
|
58
|
-
return false;
|
|
59
|
-
for (let i = 0; i < prev.length; i++) {
|
|
60
|
-
if (!deepEqual(prev[i], next[i], 'copies'))
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
function birthOf(index, touch, basis, value) {
|
|
66
|
-
return {
|
|
67
|
-
index,
|
|
68
|
-
commitIdx: touch.commitIdx,
|
|
69
|
-
runtimeStageId: touch.bundle.runtimeStageId,
|
|
70
|
-
stageId: touch.bundle.stageId,
|
|
71
|
-
stageName: touch.bundle.stage,
|
|
72
|
-
verb: touch.verb,
|
|
73
|
-
basis,
|
|
74
|
-
value,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Element-level provenance for one array-valued key: fold the key's commits
|
|
79
|
-
* and return index-aligned birth records for every element.
|
|
80
|
-
*
|
|
81
|
-
* @param key A {@link StateKey}: the top-level key string, or a path array
|
|
82
|
-
* for nested keys (normalised internally — no engine delimiters needed).
|
|
83
|
-
* @param options.atIdx Inclusive commit array index to fold to (default: the
|
|
84
|
-
* whole log). NOT the executionIndex from a runtimeStageId.
|
|
85
|
-
* @returns Always an {@link ArrayProvenance}; on failure `missing` says why
|
|
86
|
-
* (`'not-an-array'` for scalar/deleted/degraded keys — those are
|
|
87
|
-
* `sliceForKey` territory). Blind spot shared with the whole commit-log
|
|
88
|
-
* family: elements present in the run's INITIAL state (seeded, never
|
|
89
|
-
* re-set in range) are invisible here.
|
|
90
|
-
*/
|
|
91
|
-
export function arrayProvenance(commitLog, key, options) {
|
|
92
|
-
const normalisedKey = normaliseStateKey(key);
|
|
93
|
-
if (commitLog.length === 0)
|
|
94
|
-
return { key: normalisedKey, missing: 'empty-log' };
|
|
95
|
-
const end = Math.min(options?.atIdx ?? commitLog.length - 1, commitLog.length - 1);
|
|
96
|
-
const segs = normalisedKey.split(DELIM);
|
|
97
|
-
// Every row under the key's top-level key up to `end`, in commit order — the
|
|
98
|
-
// rows commitValueAt folds (refusing a verb the law does not know), with the
|
|
99
|
-
// commit position the birth records need.
|
|
100
|
-
const rows = rowsUnderRoot(commitLog, normalisedKey, end);
|
|
101
|
-
// The commits that WROTE the key — the writer rule every key query shares.
|
|
102
|
-
const writers = new Set(writersOf(commitLog, normalisedKey, { end }));
|
|
103
|
-
// F4b: what the value at `end` rests on — the basis twin's codes, less what `missing` already says.
|
|
104
|
-
const { basis } = commitValueAtWithBasis(commitLog, end, normalisedKey);
|
|
105
|
-
const said = (also) => {
|
|
106
|
-
const rest = basis.filter((c) => !also.includes(c));
|
|
107
|
-
return rest.length > 0 ? { basis: rest } : {};
|
|
108
|
-
};
|
|
109
|
-
if (writers.size === 0)
|
|
110
|
-
return { key: normalisedKey, missing: 'never-written', ...said(['never-written', 'from-initial-state']) };
|
|
111
|
-
// The append-fold: the key's one fold, watched. `births` is the added
|
|
112
|
-
// provenance track, index-aligned whenever the value is an array (the
|
|
113
|
-
// module invariant). A row of a commit that did not write the key (a merge
|
|
114
|
-
// around it that never reached it) moves no birth.
|
|
115
|
-
let births = [];
|
|
116
|
-
const value = foldKey(rows, segs, {
|
|
117
|
-
observe: (touch, before, after) => {
|
|
118
|
-
if (writers.has(touch.commitIdx))
|
|
119
|
-
births = nextBirths(births, touch, before, after);
|
|
120
|
-
},
|
|
121
|
-
});
|
|
122
|
-
if (!Array.isArray(value))
|
|
123
|
-
return { key: normalisedKey, missing: 'not-an-array', ...said([]) };
|
|
124
|
-
return { key: normalisedKey, atIdx: end, length: value.length, births, ...said([]) };
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* The births after one row of the fold, from the value before it and after it.
|
|
128
|
-
*
|
|
129
|
-
* A row that records only its TAIL (`append`) knows exactly what it added —
|
|
130
|
-
* `'append-verb'`, no equality checks, O(tail). Every other row — a `set`, a
|
|
131
|
-
* `merge`, a `delete` — is a whole-value transition: attributed by inference
|
|
132
|
-
* ({@link rebaseBirths}), and a non-array result (a `delete` leaves none) ends
|
|
133
|
-
* the track.
|
|
134
|
-
*/
|
|
135
|
-
function nextBirths(births, touch, before, after) {
|
|
136
|
-
// An `append` records the tail of ITS OWN path. On a container around the key (or a path inside it) the
|
|
137
|
-
// key's value changed wholesale — `append a` with a non-array tail replaces `a`, and `a␟b` with it — so
|
|
138
|
-
// only an append ON the key earns exact tail attribution.
|
|
139
|
-
if (!recordsTail(touch.verb) || touch.relation !== 'exact') {
|
|
140
|
-
return rebaseBirths(before, after, births, touch, 'prefix-inference');
|
|
141
|
-
}
|
|
142
|
-
if (Array.isArray(before) && Array.isArray(after)) {
|
|
143
|
-
// The step extended the array: the elements past the old length are the
|
|
144
|
-
// recorded tail — exact attribution.
|
|
145
|
-
for (let j = before.length; j < after.length; j++) {
|
|
146
|
-
births.push(birthOf(j, touch, 'append-verb', after[j]));
|
|
147
|
-
}
|
|
148
|
-
return births;
|
|
149
|
-
}
|
|
150
|
-
// Degenerate append: onto a non-array, or a non-array tail (e.g. a redacted
|
|
151
|
-
// tail replaced by the 'REDACTED' string). The tail BECAME the value —
|
|
152
|
-
// the step's own rule — and attribution stays exact.
|
|
153
|
-
return Array.isArray(after) ? after.map((el, j) => birthOf(j, touch, 'append-verb', el)) : [];
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* Re-derive births after a full-value transition (`set`/`merge`):
|
|
157
|
-
* - non-array result → no births (invariant: births track arrays only)
|
|
158
|
-
* - previous array is a strict prefix → keep old births, attribute the tail
|
|
159
|
-
* to this touch with the given (heuristic) basis
|
|
160
|
-
* - otherwise → wholesale replacement: every element reborn 'whole-value'
|
|
161
|
-
*/
|
|
162
|
-
function rebaseBirths(prev, next, births, touch, tailBasis) {
|
|
163
|
-
if (!Array.isArray(next))
|
|
164
|
-
return [];
|
|
165
|
-
if (Array.isArray(prev) && isStrictPrefix(prev, next)) {
|
|
166
|
-
const kept = births.slice(0, prev.length);
|
|
167
|
-
for (let i = prev.length; i < next.length; i++) {
|
|
168
|
-
kept.push(birthOf(i, touch, tailBasis, next[i]));
|
|
169
|
-
}
|
|
170
|
-
return kept;
|
|
171
|
-
}
|
|
172
|
-
return next.map((el, i) => birthOf(i, touch, 'whole-value', el));
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Convenience over {@link arrayProvenance}: the birth of ONE element.
|
|
176
|
-
* Returns `undefined` when the key has no array provenance (any
|
|
177
|
-
* {@link MissingProvenanceReason}) or `index` is out of range at `atIdx` —
|
|
178
|
-
* Map.get-like semantics; use {@link arrayProvenance} directly when you need
|
|
179
|
-
* the missing reason.
|
|
180
|
-
*
|
|
181
|
-
* @see ElementBirth
|
|
182
|
-
*/
|
|
183
|
-
export function elementProvenance(commitLog, key, index, options) {
|
|
184
|
-
const prov = arrayProvenance(commitLog, key, options);
|
|
185
|
-
if (!prov.births || index < 0 || index >= prov.births.length)
|
|
186
|
-
return undefined;
|
|
187
|
-
const birth = prov.births[index];
|
|
188
|
-
return prov.basis === undefined ? birth : { ...birth, valueBasis: prov.basis };
|
|
189
|
-
}
|
|
190
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxlbWVudFByb3ZlbmFuY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NsaWNlL2VsZW1lbnRQcm92ZW5hbmNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaURHO0FBRUgsT0FBTyxFQUFtQixzQkFBc0IsRUFBRSxhQUFhLEVBQUUsU0FBUyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFaEgsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN0RCxPQUFPLEVBQWMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3RFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBR3JELG9FQUFvRTtBQUNwRSxTQUFTLGNBQWMsQ0FBQyxJQUFlLEVBQUUsSUFBZTtJQUN0RCxJQUFJLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU07UUFBRSxPQUFPLEtBQUssQ0FBQztJQUM1QyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ3JDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLENBQUM7WUFBRSxPQUFPLEtBQUssQ0FBQztJQUMzRCxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQsU0FBUyxPQUFPLENBQUMsS0FBYSxFQUFFLEtBQVksRUFBRSxLQUF1QixFQUFFLEtBQWM7SUFDbkYsT0FBTztRQUNMLEtBQUs7UUFDTCxTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7UUFDMUIsY0FBYyxFQUFFLEtBQUssQ0FBQyxN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LEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDdEQsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksS0FBSyxHQUFHLENBQUMsSUFBSSxLQUFLLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDL0UsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqQyxPQUFPLElBQUksQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxLQUFLLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztBQUNqRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBzbGljZS9lbGVtZW50UHJvdmVuYW5jZS50cyDigJQgQVBQRU5ELUZPTEQgUFJPVkVOQU5DRS5cbiAqXG4gKiBUSEUgUFJPQkxFTSAod2h5IHRoaXMgZmlsZSBleGlzdHMpOiBpbiBhZ2VudCBjaGFydHMsIGFsbW9zdCBhbGwgZGF0YWZsb3dcbiAqIGZ1bm5lbHMgdGhyb3VnaCBPTkUgYXJyYXkga2V5IChgaGlzdG9yeWApLiBBIGtleS1sZXZlbCBzbGljZSBvbiBpdFxuICogZGVnZW5lcmF0ZXMgdG8gXCJldmVyeXRoaW5nIGRlcGVuZHMgb24gaGlzdG9yeVwiIOKAlCB0cnVlIGFuZCB1c2VsZXNzLiBUaGVcbiAqIHF1ZXN0aW9uIHRoYXQgYWN0dWFsbHkgdHJpYWdlcyBhbiBhZ2VudCBydW4gaXMgZWxlbWVudC1sZXZlbDpcbiAqIFwid2hpY2ggc3RhZ2UgcHJvZHVjZWQgaGlzdG9yeVs3XT9cIi5cbiAqXG4gKiBUSEUgSU5TSUdIVDogdGhlIGNvbW1pdCBsb2cgYWxyZWFkeSBjb250YWlucyB0aGUgYW5zd2VyLiBVbmRlclxuICogYGNvbW1pdFZhbHVlczogJ2RlbHRhJ2AgZXZlcnkgYXJyYXkgZ3Jvd3RoIGlzIHJlY29yZGVkIGFzIGFuIGBhcHBlbmRgIHZlcmJcbiAqIHdob3NlIGBvdmVyd3JpdGVba2V5XWAgaG9sZHMgZXhhY3RseSB0aGUgbmV3IHRhaWwg4oCUIGVhY2ggZWxlbWVudCBoYXMgYW5cbiAqIGV4cGxpY2l0IGJpcnRoIHJlY29yZC4gVW5kZXIgYCdmdWxsJ2AgbW9kZSwgcHVzaC1zdHlsZSBncm93dGggYXBwZWFycyBhc1xuICogY29uc2VjdXRpdmUgYHNldGBzIHdoZXJlIHRoZSBwcmV2aW91cyBhcnJheSBpcyBhIHN0cmljdCBwcmVmaXggb2YgdGhlIG5leHRcbiAqIOKAlCB0aGUgdGFpbCBpcyBhdHRyaWJ1dGFibGUgYnkgaW5mZXJlbmNlLiBObyBuZXcgY2FwdHVyZSBpcyBuZWVkZWQ7IHRoaXMgaXNcbiAqIGEgcHVyZSBwb3N0LWhvYyBxdWVyeS5cbiAqXG4gKiBUSEUgQUxHT1JJVEhNIChhcHBlbmQtZm9sZCk6IFdBVENIIHRoZSBwZXIta2V5IHZlcmIgZm9sZCDigJQgdGhlIFNBTUUgZm9sZFxuICogYGNvbW1pdFZhbHVlQXRgIHJ1bnMgKGBtZW1vcnkvdmVyYnMudHNgIMK3IGBmb2xkS2V5YDogb25lIHN0ZXAsIGBhcHBseVZlcmJgLFxuICogZm9yIGV2ZXJ5IHZlcmI7IHRoaXMgZmlsZSBoYXMgbm8gdmVyYiBzd2l0Y2ggb2YgaXRzIG93bikg4oCUIHdoaWxlIGNhcnJ5aW5nIGFcbiAqIGJpcnRocyBhcnJheSBrZXB0IGluZGV4LWFsaWduZWQgd2l0aCB0aGUgdmFsdWUuIFRoZSBvYnNlcnZlciBpcyB0b2xkLCBhZnRlclxuICogZWFjaCByb3cgb24sIGluc2lkZSBvciBhcm91bmQgdGhlIGtleSwgdGhlIHZhbHVlIGF0IHRoZSBrZXkgYmVmb3JlIGl0IGFuZFxuICogYWZ0ZXIgaXQsIGFuZCBrZWVwcyB0aGUgYmlydGhzIOKAlCBmb3IgdGhlIGNvbW1pdHMgdGhhdCBXUk9URSB0aGUga2V5IHVuZGVyXG4gKiB0aGUgd3JpdGVyIHJ1bGUgKGBjb21taXRMb2dVdGlscyDCtyB3cml0ZXJzT2ZgOyBzaW5jZSA5LjMzLjAgYSB3cml0ZSBpbnNpZGVcbiAqIHRoZSBrZXkgb3IgYXJvdW5kIGl0IGNvdW50cywgYXMgaXQgZG9lcyBmb3IgZXZlcnkga2V5IHF1ZXJ5KTogYSByb3cgdGhhdFxuICogcmVjb3JkcyBvbmx5IGl0cyB0YWlsIChgYXBwZW5kYCkgZWFybnMgYW4gZXhhY3QgYXR0cmlidXRpb247IGV2ZXJ5IG90aGVyIHJvd1xuICogaXMgYSB3aG9sZS12YWx1ZSB0cmFuc2l0aW9uIGF0dHJpYnV0ZWQgYnkgaW5mZXJlbmNlLiBPbmUgZGlmZmVyZW5jZSBmcm9tXG4gKiBgY29tbWl0VmFsdWVBdGA6IHRoYXQgaGVscGVyIEFOQ0hPUlMgYXQgdGhlIGxhdGVzdCBgc2V0YC9gZGVsZXRlYCBhcyBhIHNraXBcbiAqIG9wdGltaXphdGlvbiAoZWFybGllciBjb21taXRzIGNhbm5vdCBjaGFuZ2UgdGhlIGZpbmFsIFZBTFVFKS4gUHJvdmVuYW5jZVxuICogbXVzdCBmb2xkIGZyb20gdGhlIEZJUlNUIHRvdWNoLCBiZWNhdXNlIGZ1bGwtbW9kZSBncm93dGggaXMgYSBjaGFpbiBvZlxuICogYHNldGBzIGFuZCB0aGUgYW5jaG9yIHdvdWxkIGVyYXNlIGV2ZXJ5IGJpcnRoIGJ1dCB0aGUgbGFzdC4gVGhlIGZpbmFsIHZhbHVlXG4gKiBpcyBpZGVudGljYWwgZWl0aGVyIHdheSAodGhlIGZvbGQgaXMgZGV0ZXJtaW5pc3RpYyBsZWZ0LXRvLXJpZ2h0KSDigJQgYVxuICogcHJvcGVydHkgdGVzdCBwaW5zIHRoaXMgZXF1aXZhbGVuY2UuXG4gKlxuICogSU5WQVJJQU5UIChtYWludGFpbmVkIG9uIGV2ZXJ5IGJyYW5jaCk6IHdoZW4gdGhlIGZvbGRlZCB2YWx1ZSBpcyBhbiBhcnJheSxcbiAqIGBiaXJ0aHMubGVuZ3RoID09PSB2YWx1ZS5sZW5ndGhgIGFuZCBgYmlydGhzW2ldYCBkZXNjcmliZXMgYHZhbHVlW2ldYC5cbiAqXG4gKiBIT05FU1RZOiBldmVyeSBiaXJ0aCBpcyBsYWJlbGVkIHdpdGggaG93IGl0IHdhcyBkZXRlcm1pbmVkXG4gKiAoe0BsaW5rIEF0dHJpYnV0aW9uQmFzaXN9KSDigJQgYCdhcHBlbmQtdmVyYidgIGlzIGVuZ2luZS1yZWNvcmRlZCB0cnV0aCxcbiAqIGAncHJlZml4LWluZmVyZW5jZSdgIGlzIGEgaGV1cmlzdGljIChhIHdob2xlc2FsZSByZXBsYWNlbWVudCB0aGF0IGhhcHBlbnNcbiAqIHRvIHNoYXJlIHRoZSBvbGQgcHJlZml4IGlzIGluZGlzdGluZ3Vpc2hhYmxlIGZyb20gYW4gYXBwZW5kKSwgYW5kXG4gKiBgJ3dob2xlLXZhbHVlJ2AgaXMgYW4gZXhwbGljaXQgcmVzZXQuIEFic2VuY2UgaXMgaG9uZXN0IHRvbzogYSBtaXNzaW5nXG4gKiBwcm92ZW5hbmNlIGNhcnJpZXMgYSB7QGxpbmsgTWlzc2luZ1Byb3ZlbmFuY2VSZWFzb259LCBtaXJyb3JpbmdcbiAqIGBWYXJpYWJsZVNsaWNlLm1pc3NpbmdgIOKAlCBvbmUgYWJzZW5jZSBwYXR0ZXJuIG1vZHVsZS13aWRlLlxuICpcbiAqIENPTVBMRVhJVFk6IGRlbHRhLW1vZGUgbG9ncyBuZWVkIG5vIGVxdWFsaXR5IGNoZWNrcyDigJQgTyh0b3RhbCBlbGVtZW50cykuXG4gKiBGdWxsLW1vZGUgbG9ncyBwYXkgYSBzdHJpY3QtcHJlZml4IGNoZWNrIChkZWVwRXF1YWwgcGVyIGVsZW1lbnQpIHBlclxuICogZnVsbC12YWx1ZSB0b3VjaDogTyh0b3VjaGVzIMOXIGxlbmd0aCkgZWxlbWVudCBjb21wYXJpc29ucyB3b3JzdCBjYXNlLlxuICogUG9zdC1ob2MgcXVlcnksIG9mZiB0aGUgaG90IHBhdGgg4oCUIGFjY2VwdGFibGU7IG1lYXN1cmVkIGluIHRoZSBwZXJmIHRlc3RzLlxuICovXG5cbmltcG9ydCB7IHR5cGUgVmFsdWVCYXNpcywgY29tbWl0VmFsdWVBdFdpdGhCYXNpcywgcm93c1VuZGVyUm9vdCwgd3JpdGVyc09mIH0gZnJvbSAnLi4vbWVtb3J5L2NvbW1pdExvZ1V0aWxzLmpzJztcbmltcG9ydCB0eXBlIHsgQ29tbWl0QnVuZGxlIH0gZnJvbSAnLi4vbWVtb3J5L3R5cGVzLmpzJztcbmltcG9ydCB7IGRlZXBFcXVhbCwgREVMSU0gfSBmcm9tICcuLi9tZW1vcnkvdXRpbHMuanMnO1xuaW1wb3J0IHsgdHlwZSBUb3VjaCwgZm9sZEtleSwgcmVjb3Jkc1RhaWwgfSBmcm9tICcuLi9tZW1vcnkvdmVyYnMuanMnO1xuaW1wb3J0IHsgbm9ybWFsaXNlU3RhdGVLZXkgfSBmcm9tICcuL3NsaWNlRm9yS2V5LmpzJztcbmltcG9ydCB0eXBlIHsgQXJyYXlQcm92ZW5hbmNlLCBBdHRyaWJ1dGlvbkJhc2lzLCBFbGVtZW50QmlydGgsIFN0YXRlS2V5IH0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbi8qKiBgcHJldmAgaXMgYSBzdHJpY3QgKGxlYWRpbmcsIGVsZW1lbnQtZXF1YWwpIHByZWZpeCBvZiBgbmV4dGAuICovXG5mdW5jdGlvbiBpc1N0cmljdFByZWZpeChwcmV2OiB1bmtub3duW10sIG5leHQ6IHVua25vd25bXSk6IGJvb2xlYW4ge1xuICBpZiAocHJldi5sZW5ndGggPiBuZXh0Lmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHByZXYubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoIWRlZXBFcXVhbChwcmV2W2ldLCBuZXh0W2ldLCAnY29waWVzJykpIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gYmlydGhPZihpbmRleDogbnVtYmVyLCB0b3VjaDogVG91Y2gsIGJhc2lzOiBBdHRyaWJ1dGlvbkJhc2lzLCB2YWx1ZTogdW5rbm93bik6IEVsZW1lbnRCaXJ0aCB7XG4gIHJldHVybiB7XG4gICAgaW5kZXgsXG4gICAgY29tbWl0SWR4OiB0b3VjaC5jb21taXRJZHgsXG4gICAgcnVudGltZVN0YWdlSWQ6IHRvdWNoLmJ1bmRsZS5ydW50aW1lU3RhZ2VJZCxcbiAgICBzdGFnZUlkOiB0b3VjaC5idW5kbGUuc3RhZ2VJZCxcbiAgICBzdGFnZU5hbWU6IHRvdWNoLmJ1bmRsZS5zdGFnZSxcbiAgICB2ZXJiOiB0b3VjaC52ZXJiLFxuICAgIGJhc2lzLFxuICAgIHZhbHVlLFxuICB9O1xufVxuXG4vKipcbiAqIEVsZW1lbnQtbGV2ZWwgcHJvdmVuYW5jZSBmb3Igb25lIGFycmF5LXZhbHVlZCBrZXk6IGZvbGQgdGhlIGtleSdzIGNvbW1pdHNcbiAqIGFuZCByZXR1cm4gaW5kZXgtYWxpZ25lZCBiaXJ0aCByZWNvcmRzIGZvciBldmVyeSBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSBrZXkgQSB7QGxpbmsgU3RhdGVLZXl9OiB0aGUgdG9wLWxldmVsIGtleSBzdHJpbmcsIG9yIGEgcGF0aCBhcnJheVxuICogICBmb3IgbmVzdGVkIGtleXMgKG5vcm1hbGlzZWQgaW50ZXJuYWxseSDigJQgbm8gZW5naW5lIGRlbGltaXRlcnMgbmVlZGVkKS5cbiAqIEBwYXJhbSBvcHRpb25zLmF0SWR4IEluY2x1c2l2ZSBjb21taXQgYXJyYXkgaW5kZXggdG8gZm9sZCB0byAoZGVmYXVsdDogdGhlXG4gKiAgIHdob2xlIGxvZykuIE5PVCB0aGUgZXhlY3V0aW9uSW5kZXggZnJvbSBhIHJ1bnRpbWVTdGFnZUlkLlxuICogQHJldHVybnMgQWx3YXlzIGFuIHtAbGluayBBcnJheVByb3ZlbmFuY2V9OyBvbiBmYWlsdXJlIGBtaXNzaW5nYCBzYXlzIHdoeVxuICogICAoYCdub3QtYW4tYXJyYXknYCBmb3Igc2NhbGFyL2RlbGV0ZWQvZGVncmFkZWQga2V5cyDigJQgdGhvc2UgYXJlXG4gKiAgIGBzbGljZUZvcktleWAgdGVycml0b3J5KS4gQmxpbmQgc3BvdCBzaGFyZWQgd2l0aCB0aGUgd2hvbGUgY29tbWl0LWxvZ1xuICogICBmYW1pbHk6IGVsZW1lbnRzIHByZXNlbnQgaW4gdGhlIHJ1bidzIElOSVRJQUwgc3RhdGUgKHNlZWRlZCwgbmV2ZXJcbiAqICAgcmUtc2V0IGluIHJhbmdlKSBhcmUgaW52aXNpYmxlIGhlcmUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcnJheVByb3ZlbmFuY2UoXG4gIGNvbW1pdExvZzogQ29tbWl0QnVuZGxlW10sXG4gIGtleTogU3RhdGVLZXksXG4gIG9wdGlvbnM/OiB7IGF0SWR4PzogbnVtYmVyIH0sXG4pOiBBcnJheVByb3ZlbmFuY2Uge1xuICBjb25zdCBub3JtYWxpc2VkS2V5ID0gbm9ybWFsaXNlU3RhdGVLZXkoa2V5KTtcbiAgaWYgKGNvbW1pdExvZy5sZW5ndGggPT09IDApIHJldHVybiB7IGtleTogbm9ybWFsaXNlZEtleSwgbWlzc2luZzogJ2VtcHR5LWxvZycgfTtcbiAgY29uc3QgZW5kID0gTWF0aC5taW4ob3B0aW9ucz8uYXRJZHggPz8gY29tbWl0TG9nLmxlbmd0aCAtIDEsIGNvbW1pdExvZy5sZW5ndGggLSAxKTtcbiAgY29uc3Qgc2VncyA9IG5vcm1hbGlzZWRLZXkuc3BsaXQoREVMSU0pO1xuXG4gIC8vIEV2ZXJ5IHJvdyB1bmRlciB0aGUga2V5J3MgdG9wLWxldmVsIGtleSB1cCB0byBgZW5kYCwgaW4gY29tbWl0IG9yZGVyIOKAlCB0aGVcbiAgLy8gcm93cyBjb21taXRWYWx1ZUF0IGZvbGRzIChyZWZ1c2luZyBhIHZlcmIgdGhlIGxhdyBkb2VzIG5vdCBrbm93KSwgd2l0aCB0aGVcbiAgLy8gY29tbWl0IHBvc2l0aW9uIHRoZSBiaXJ0aCByZWNvcmRzIG5lZWQuXG4gIGNvbnN0IHJvd3MgPSByb3dzVW5kZXJSb290KGNvbW1pdExvZywgbm9ybWFsaXNlZEtleSwgZW5kKTtcbiAgLy8gVGhlIGNvbW1pdHMgdGhhdCBXUk9URSB0aGUga2V5IOKAlCB0aGUgd3JpdGVyIHJ1bGUgZXZlcnkga2V5IHF1ZXJ5IHNoYXJlcy5cbiAgY29uc3Qgd3JpdGVycyA9IG5ldyBTZXQod3JpdGVyc09mKGNvbW1pdExvZywgbm9ybWFsaXNlZEtleSwgeyBlbmQgfSkpO1xuICAvLyBGNGI6IHdoYXQgdGhlIHZhbHVlIGF0IGBlbmRgIHJlc3RzIG9uIOKAlCB0aGUgYmFzaXMgdHdpbidzIGNvZGVzLCBsZXNzIHdoYXQgYG1pc3NpbmdgIGFscmVhZHkgc2F5cy5cbiAgY29uc3QgeyBiYXNpcyB9ID0gY29tbWl0VmFsdWVBdFdpdGhCYXNpcyhjb21taXRMb2csIGVuZCwgbm9ybWFsaXNlZEtleSk7XG4gIGNvbnN0IHNhaWQgPSAoYWxzbzogVmFsdWVCYXNpc1tdKSA9PiB7XG4gICAgY29uc3QgcmVzdCA9IGJhc2lzLmZpbHRlcigoYykgPT4gIWFsc28uaW5jbHVkZXMoYykpO1xuICAgIHJldHVybiByZXN0Lmxlbmd0aCA+IDAgPyB7IGJhc2lzOiByZXN0IH0gOiB7fTtcbiAgfTtcbiAgaWYgKHdyaXRlcnMuc2l6ZSA9PT0gMClcbiAgICByZXR1cm4geyBrZXk6IG5vcm1hbGlzZWRLZXksIG1pc3Npbmc6ICduZXZlci13cml0dGVuJywgLi4uc2FpZChbJ25ldmVyLXdyaXR0ZW4nLCAnZnJvbS1pbml0aWFsLXN0YXRlJ10pIH07XG5cbiAgLy8gVGhlIGFwcGVuZC1mb2xkOiB0aGUga2V5J3Mgb25lIGZvbGQsIHdhdGNoZWQuIGBiaXJ0aHNgIGlzIHRoZSBhZGRlZFxuICAvLyBwcm92ZW5hbmNlIHRyYWNrLCBpbmRleC1hbGlnbmVkIHdoZW5ldmVyIHRoZSB2YWx1ZSBpcyBhbiBhcnJheSAodGhlXG4gIC8vIG1vZHVsZSBpbnZhcmlhbnQpLiBBIHJvdyBvZiBhIGNvbW1pdCB0aGF0IGRpZCBub3Qgd3JpdGUgdGhlIGtleSAoYSBtZXJnZVxuICAvLyBhcm91bmQgaXQgdGhhdCBuZXZlciByZWFjaGVkIGl0KSBtb3ZlcyBubyBiaXJ0aC5cbiAgbGV0IGJpcnRoczogRWxlbWVudEJpcnRoW10gPSBbXTtcbiAgY29uc3QgdmFsdWUgPSBmb2xkS2V5KHJvd3MsIHNlZ3MsIHtcbiAgICBvYnNlcnZlOiAodG91Y2gsIGJlZm9yZSwgYWZ0ZXIpID0+IHtcbiAgICAgIGlmICh3cml0ZXJzLmhhcyh0b3VjaC5jb21taXRJZHgpKSBiaXJ0aHMgPSBuZXh0QmlydGhzKGJpcnRocywgdG91Y2gsIGJlZm9yZSwgYWZ0ZXIpO1xuICAgIH0sXG4gIH0pO1xuXG4gIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiB7IGtleTogbm9ybWFsaXNlZEtleSwgbWlzc2luZzogJ25vdC1hbi1hcnJheScsIC4uLnNhaWQoW10pIH07XG4gIHJldHVybiB7IGtleTogbm9ybWFsaXNlZEtleSwgYXRJZHg6IGVuZCwgbGVuZ3RoOiB2YWx1ZS5sZW5ndGgsIGJpcnRocywgLi4uc2FpZChbXSkgfTtcbn1cblxuLyoqXG4gKiBUaGUgYmlydGhzIGFmdGVyIG9uZSByb3cgb2YgdGhlIGZvbGQsIGZyb20gdGhlIHZhbHVlIGJlZm9yZSBpdCBhbmQgYWZ0ZXIgaXQuXG4gKlxuICogQSByb3cgdGhhdCByZWNvcmRzIG9ubHkgaXRzIFRBSUwgKGBhcHBlbmRgKSBrbm93cyBleGFjdGx5IHdoYXQgaXQgYWRkZWQg4oCUXG4gKiBgJ2FwcGVuZC12ZXJiJ2AsIG5vIGVxdWFsaXR5IGNoZWNrcywgTyh0YWlsKS4gRXZlcnkgb3RoZXIgcm93IOKAlCBhIGBzZXRgLCBhXG4gKiBgbWVyZ2VgLCBhIGBkZWxldGVgIOKAlCBpcyBhIHdob2xlLXZhbHVlIHRyYW5zaXRpb246IGF0dHJpYnV0ZWQgYnkgaW5mZXJlbmNlXG4gKiAoe0BsaW5rIHJlYmFzZUJpcnRoc30pLCBhbmQgYSBub24tYXJyYXkgcmVzdWx0IChhIGBkZWxldGVgIGxlYXZlcyBub25lKSBlbmRzXG4gKiB0aGUgdHJhY2suXG4gKi9cbmZ1bmN0aW9uIG5leHRCaXJ0aHMoYmlydGhzOiBFbGVtZW50QmlydGhbXSwgdG91Y2g6IFRvdWNoLCBiZWZvcmU6IHVua25vd24sIGFmdGVyOiB1bmtub3duKTogRWxlbWVudEJpcnRoW10ge1xuICAvLyBBbiBgYXBwZW5kYCByZWNvcmRzIHRoZSB0YWlsIG9mIElUUyBPV04gcGF0aC4gT24gYSBjb250YWluZXIgYXJvdW5kIHRoZSBrZXkgKG9yIGEgcGF0aCBpbnNpZGUgaXQpIHRoZVxuICAvLyBrZXkncyB2YWx1ZSBjaGFuZ2VkIHdob2xlc2FsZSDigJQgYGFwcGVuZCBhYCB3aXRoIGEgbm9uLWFycmF5IHRhaWwgcmVwbGFjZXMgYGFgLCBhbmQgYGHikJ9iYCB3aXRoIGl0IOKAlCBzb1xuICAvLyBvbmx5IGFuIGFwcGVuZCBPTiB0aGUga2V5IGVhcm5zIGV4YWN0IHRhaWwgYXR0cmlidXRpb24uXG4gIGlmICghcmVjb3Jkc1RhaWwodG91Y2gudmVyYikgfHwgdG91Y2gucmVsYXRpb24gIT09ICdleGFjdCcpIHtcbiAgICByZXR1cm4gcmViYXNlQmlydGhzKGJlZm9yZSwgYWZ0ZXIsIGJpcnRocywgdG91Y2gsICdwcmVmaXgtaW5mZXJlbmNlJyk7XG4gIH1cbiAgaWYgKEFycmF5LmlzQXJyYXkoYmVmb3JlKSAmJiBBcnJheS5pc0FycmF5KGFmdGVyKSkge1xuICAgIC8vIFRoZSBzdGVwIGV4dGVuZGVkIHRoZSBhcnJheTogdGhlIGVsZW1lbnRzIHBhc3QgdGhlIG9sZCBsZW5ndGggYXJlIHRoZVxuICAgIC8vIHJlY29yZGVkIHRhaWwg4oCUIGV4YWN0IGF0dHJpYnV0aW9uLlxuICAgIGZvciAobGV0IGogPSBiZWZvcmUubGVuZ3RoOyBqIDwgYWZ0ZXIubGVuZ3RoOyBqKyspIHtcbiAgICAgIGJpcnRocy5wdXNoKGJpcnRoT2YoaiwgdG91Y2gsICdhcHBlbmQtdmVyYicsIGFmdGVyW2pdKSk7XG4gICAgfVxuICAgIHJldHVybiBiaXJ0aHM7XG4gIH1cbiAgLy8gRGVnZW5lcmF0ZSBhcHBlbmQ6IG9udG8gYSBub24tYXJyYXksIG9yIGEgbm9uLWFycmF5IHRhaWwgKGUuZy4gYSByZWRhY3RlZFxuICAvLyB0YWlsIHJlcGxhY2VkIGJ5IHRoZSAnUkVEQUNURUQnIHN0cmluZykuIFRoZSB0YWlsIEJFQ0FNRSB0aGUgdmFsdWUg4oCUXG4gIC8vIHRoZSBzdGVwJ3Mgb3duIHJ1bGUg4oCUIGFuZCBhdHRyaWJ1dGlvbiBzdGF5cyBleGFjdC5cbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoYWZ0ZXIpID8gYWZ0ZXIubWFwKChlbCwgaikgPT4gYmlydGhPZihqLCB0b3VjaCwgJ2FwcGVuZC12ZXJiJywgZWwpKSA6IFtdO1xufVxuXG4vKipcbiAqIFJlLWRlcml2ZSBiaXJ0aHMgYWZ0ZXIgYSBmdWxsLXZhbHVlIHRyYW5zaXRpb24gKGBzZXRgL2BtZXJnZWApOlxuICogLSBub24tYXJyYXkgcmVzdWx0IOKGkiBubyBiaXJ0aHMgKGludmFyaWFudDogYmlydGhzIHRyYWNrIGFycmF5cyBvbmx5KVxuICogLSBwcmV2aW91cyBhcnJheSBpcyBhIHN0cmljdCBwcmVmaXgg4oaSIGtlZXAgb2xkIGJpcnRocywgYXR0cmlidXRlIHRoZSB0YWlsXG4gKiAgIHRvIHRoaXMgdG91Y2ggd2l0aCB0aGUgZ2l2ZW4gKGhldXJpc3RpYykgYmFzaXNcbiAqIC0gb3RoZXJ3aXNlIOKGkiB3aG9sZXNhbGUgcmVwbGFjZW1lbnQ6IGV2ZXJ5IGVsZW1lbnQgcmVib3JuICd3aG9sZS12YWx1ZSdcbiAqL1xuZnVuY3Rpb24gcmViYXNlQmlydGhzKFxuICBwcmV2OiB1bmtub3duLFxuICBuZXh0OiB1bmtub3duLFxuICBiaXJ0aHM6IEVsZW1lbnRCaXJ0aFtdLFxuICB0b3VjaDogVG91Y2gsXG4gIHRhaWxCYXNpczogQXR0cmlidXRpb25CYXNpcyxcbik6IEVsZW1lbnRCaXJ0aFtdIHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KG5leHQpKSByZXR1cm4gW107XG4gIGlmIChBcnJheS5pc0FycmF5KHByZXYpICYmIGlzU3RyaWN0UHJlZml4KHByZXYsIG5leHQpKSB7XG4gICAgY29uc3Qga2VwdCA9IGJpcnRocy5zbGljZSgwLCBwcmV2Lmxlbmd0aCk7XG4gICAgZm9yIChsZXQgaSA9IHByZXYubGVuZ3RoOyBpIDwgbmV4dC5sZW5ndGg7IGkrKykge1xuICAgICAga2VwdC5wdXNoKGJpcnRoT2YoaSwgdG91Y2gsIHRhaWxCYXNpcywgbmV4dFtpXSkpO1xuICAgIH1cbiAgICByZXR1cm4ga2VwdDtcbiAgfVxuICByZXR1cm4gbmV4dC5tYXAoKGVsLCBpKSA9PiBiaXJ0aE9mKGksIHRvdWNoLCAnd2hvbGUtdmFsdWUnLCBlbCkpO1xufVxuXG4vKipcbiAqIENvbnZlbmllbmNlIG92ZXIge0BsaW5rIGFycmF5UHJvdmVuYW5jZX06IHRoZSBiaXJ0aCBvZiBPTkUgZWxlbWVudC5cbiAqIFJldHVybnMgYHVuZGVmaW5lZGAgd2hlbiB0aGUga2V5IGhhcyBubyBhcnJheSBwcm92ZW5hbmNlIChhbnlcbiAqIHtAbGluayBNaXNzaW5nUHJvdmVuYW5jZVJlYXNvbn0pIG9yIGBpbmRleGAgaXMgb3V0IG9mIHJhbmdlIGF0IGBhdElkeGAg4oCUXG4gKiBNYXAuZ2V0LWxpa2Ugc2VtYW50aWNzOyB1c2Uge0BsaW5rIGFycmF5UHJvdmVuYW5jZX0gZGlyZWN0bHkgd2hlbiB5b3UgbmVlZFxuICogdGhlIG1pc3NpbmcgcmVhc29uLlxuICpcbiAqIEBzZWUgRWxlbWVudEJpcnRoXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbGVtZW50UHJvdmVuYW5jZShcbiAgY29tbWl0TG9nOiBDb21taXRCdW5kbGVbXSxcbiAga2V5OiBTdGF0ZUtleSxcbiAgaW5kZXg6IG51bWJlcixcbiAgb3B0aW9ucz86IHsgYXRJZHg/OiBudW1iZXIgfSxcbik6IEVsZW1lbnRCaXJ0aCB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHByb3YgPSBhcnJheVByb3ZlbmFuY2UoY29tbWl0TG9nLCBrZXksIG9wdGlvbnMpO1xuICBpZiAoIXByb3YuYmlydGhzIHx8IGluZGV4IDwgMCB8fCBpbmRleCA+PSBwcm92LmJpcnRocy5sZW5ndGgpIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IGJpcnRoID0gcHJvdi5iaXJ0aHNbaW5kZXhdO1xuICByZXR1cm4gcHJvdi5iYXNpcyA9PT0gdW5kZWZpbmVkID8gYmlydGggOiB7IC4uLmJpcnRoLCB2YWx1ZUJhc2lzOiBwcm92LmJhc2lzIH07XG59XG4iXX0=
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* slice/forwardSliceForKey.ts — the FORWARD half of variable-first slicing.
|
|
3
|
-
*
|
|
4
|
-
* `sliceForKey` answers "why is `key` what it is?" by walking backward from
|
|
5
|
-
* the value to its causes. This file answers the opposite question, which no
|
|
6
|
-
* query answered before: **"who READ this value, and what did it FEED?"**
|
|
7
|
-
* (the production shape: *who read `recipeId`, and what did it feed?* — one
|
|
8
|
-
* query, not a manual scan of a trace viewer).
|
|
9
|
-
*
|
|
10
|
-
* ## The algorithm: LIVE RANGES, not steps
|
|
11
|
-
*
|
|
12
|
-
* A backward slice hops writer→writer. Forward, the unit is a value's LIFE:
|
|
13
|
-
*
|
|
14
|
-
* 1. Anchor at a write of `key` — the SAME anchor idiom as `sliceForKey`
|
|
15
|
-
* (the last writer, or the last writer before `before`).
|
|
16
|
-
* 2. That value lives until the key's NEXT write (`nextWriteIdx`). Every
|
|
17
|
-
* stage that READ `key` inside that window saw THIS value — a `read`.
|
|
18
|
-
* (9.33.0: a write that reached the key only through paths INSIDE it — a
|
|
19
|
-
* subflow seed, an outputMapper merge-back — changed part of the value
|
|
20
|
-
* and does NOT end its life: a reader after it still read the rest. Every
|
|
21
|
-
* life such a write starts or crosses carries a `'nested-rows'` note.)
|
|
22
|
-
* 3. A reading stage that also WROTE something carried the value onward —
|
|
23
|
-
* a `fed` edge to that write, which is itself the start of a new life.
|
|
24
|
-
* 4. Descend into fed lives breadth-first (visited-set guarded, budgeted).
|
|
25
|
-
*
|
|
26
|
-
* ### LAW — the live range is `(writeIdx, nextWriteIdx]`
|
|
27
|
-
*
|
|
28
|
-
* Open at the bottom, CLOSED at the top, and both ends follow from the
|
|
29
|
-
* engine's event order (`onRead` fires PRE-commit — see CLAUDE.md):
|
|
30
|
-
* - a read by the writing stage itself (`readIdx === writeIdx`) saw the
|
|
31
|
-
* PREVIOUS value: read-modify-write reads belong to the previous life;
|
|
32
|
-
* - a read by the OVERWRITING stage (`readIdx === nextWriteIdx`) also fired
|
|
33
|
-
* before its commit, so it still saw THIS value.
|
|
34
|
-
* A read after that commit attributes to the NEW write, never the old one.
|
|
35
|
-
* (Granularity limit, stated because it cannot be seen: a stage that writes
|
|
36
|
-
* `key` and then re-reads it within the SAME stage read its own value; at
|
|
37
|
-
* commit-index resolution that read is indistinguishable from the one that
|
|
38
|
-
* opened the stage.)
|
|
39
|
-
*
|
|
40
|
-
* ### LAW — a `fed` edge is EXACT only under recorded read provenance
|
|
41
|
-
*
|
|
42
|
-
* With `writeProvenance: 'reads-prefix'` on, the child write's
|
|
43
|
-
* `TraceEntry.readKeys` names the keys read before it: this key IN that list
|
|
44
|
-
* is an exact edge (`basis: 'per-write'`), and this key ABSENT from it is an
|
|
45
|
-
* exact *exclusion* — no edge at all. With the dial off there is no such
|
|
46
|
-
* evidence, only "the stage read this and wrote that": the edge is stamped
|
|
47
|
-
* `basis: 'stage'` and the slice carries a `'conservative-fed-edges'` note.
|
|
48
|
-
* A conservative edge is never presented as an exact one.
|
|
49
|
-
*
|
|
50
|
-
* Budgets mirror `causalChain`'s (maxDepth 20, maxNodes 100) and a cut is
|
|
51
|
-
* STATED — `root.truncated` plus a `'truncated'` note.
|
|
52
|
-
*
|
|
53
|
-
* DAG position: memory ← slice. Imports memory/ only (see README.md).
|
|
54
|
-
*/
|
|
55
|
-
import type { KeysReadLookup } from '../memory/backtrack.js';
|
|
56
|
-
import type { CommitBundle } from '../memory/types.js';
|
|
57
|
-
import type { ForwardSlice, KeysReadSource, StateKey } from './types.js';
|
|
58
|
-
/** Options for {@link forwardSliceForKey} — anchoring plus walk budgets. */
|
|
59
|
-
export interface ForwardSliceForKeyOptions {
|
|
60
|
-
/**
|
|
61
|
-
* Exclusive commit-array-index upper bound for the ANCHOR search: follow
|
|
62
|
-
* the value as it stood BEFORE this idx. Same contract as
|
|
63
|
-
* `sliceForKey`'s `before` / `findLastWriter`'s `beforeIdx`.
|
|
64
|
-
*
|
|
65
|
-
* It bounds the anchor ONLY — the walk then runs forward past it, because
|
|
66
|
-
* "what did the value at step 12 go on to feed?" is the whole question.
|
|
67
|
-
*/
|
|
68
|
-
before?: number;
|
|
69
|
-
/** Maximum BFS depth in value-lives (default: 20 — causalChain's). */
|
|
70
|
-
maxDepth?: number;
|
|
71
|
-
/** Maximum total nodes (default: 100 — causalChain's). */
|
|
72
|
-
maxNodes?: number;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Forward slice for one state key: who read this value, and what did it feed?
|
|
76
|
-
*
|
|
77
|
-
* @param commitLog Ordered commit bundles — `getSnapshot().commitLog`.
|
|
78
|
-
* @param key A {@link StateKey}: the plain key string, or a path array
|
|
79
|
-
* (normalised through the SAME `normaliseStateKey` the backward door uses,
|
|
80
|
-
* so both doors accept identical inputs).
|
|
81
|
-
* @param keysRead A {@link KeysReadSource} strategy or a bare lookup — the
|
|
82
|
-
* same reads providers `sliceForKey` takes. Reads are not in the commit
|
|
83
|
-
* log; without a provider a forward walk can see nothing, which the
|
|
84
|
-
* `'reads-not-recorded'` note says out loud.
|
|
85
|
-
* @returns Always a {@link ForwardSlice}. Absence is a RESULT with a reason
|
|
86
|
-
* and, for an unknown key, a bounded list of the keys the log does know.
|
|
87
|
-
*/
|
|
88
|
-
export declare function forwardSliceForKey(commitLog: CommitBundle[], key: StateKey, keysRead: KeysReadSource | KeysReadLookup, options?: ForwardSliceForKeyOptions): ForwardSlice;
|
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* slice/forwardSliceForKey.ts — the FORWARD half of variable-first slicing.
|
|
3
|
-
*
|
|
4
|
-
* `sliceForKey` answers "why is `key` what it is?" by walking backward from
|
|
5
|
-
* the value to its causes. This file answers the opposite question, which no
|
|
6
|
-
* query answered before: **"who READ this value, and what did it FEED?"**
|
|
7
|
-
* (the production shape: *who read `recipeId`, and what did it feed?* — one
|
|
8
|
-
* query, not a manual scan of a trace viewer).
|
|
9
|
-
*
|
|
10
|
-
* ## The algorithm: LIVE RANGES, not steps
|
|
11
|
-
*
|
|
12
|
-
* A backward slice hops writer→writer. Forward, the unit is a value's LIFE:
|
|
13
|
-
*
|
|
14
|
-
* 1. Anchor at a write of `key` — the SAME anchor idiom as `sliceForKey`
|
|
15
|
-
* (the last writer, or the last writer before `before`).
|
|
16
|
-
* 2. That value lives until the key's NEXT write (`nextWriteIdx`). Every
|
|
17
|
-
* stage that READ `key` inside that window saw THIS value — a `read`.
|
|
18
|
-
* (9.33.0: a write that reached the key only through paths INSIDE it — a
|
|
19
|
-
* subflow seed, an outputMapper merge-back — changed part of the value
|
|
20
|
-
* and does NOT end its life: a reader after it still read the rest. Every
|
|
21
|
-
* life such a write starts or crosses carries a `'nested-rows'` note.)
|
|
22
|
-
* 3. A reading stage that also WROTE something carried the value onward —
|
|
23
|
-
* a `fed` edge to that write, which is itself the start of a new life.
|
|
24
|
-
* 4. Descend into fed lives breadth-first (visited-set guarded, budgeted).
|
|
25
|
-
*
|
|
26
|
-
* ### LAW — the live range is `(writeIdx, nextWriteIdx]`
|
|
27
|
-
*
|
|
28
|
-
* Open at the bottom, CLOSED at the top, and both ends follow from the
|
|
29
|
-
* engine's event order (`onRead` fires PRE-commit — see CLAUDE.md):
|
|
30
|
-
* - a read by the writing stage itself (`readIdx === writeIdx`) saw the
|
|
31
|
-
* PREVIOUS value: read-modify-write reads belong to the previous life;
|
|
32
|
-
* - a read by the OVERWRITING stage (`readIdx === nextWriteIdx`) also fired
|
|
33
|
-
* before its commit, so it still saw THIS value.
|
|
34
|
-
* A read after that commit attributes to the NEW write, never the old one.
|
|
35
|
-
* (Granularity limit, stated because it cannot be seen: a stage that writes
|
|
36
|
-
* `key` and then re-reads it within the SAME stage read its own value; at
|
|
37
|
-
* commit-index resolution that read is indistinguishable from the one that
|
|
38
|
-
* opened the stage.)
|
|
39
|
-
*
|
|
40
|
-
* ### LAW — a `fed` edge is EXACT only under recorded read provenance
|
|
41
|
-
*
|
|
42
|
-
* With `writeProvenance: 'reads-prefix'` on, the child write's
|
|
43
|
-
* `TraceEntry.readKeys` names the keys read before it: this key IN that list
|
|
44
|
-
* is an exact edge (`basis: 'per-write'`), and this key ABSENT from it is an
|
|
45
|
-
* exact *exclusion* — no edge at all. With the dial off there is no such
|
|
46
|
-
* evidence, only "the stage read this and wrote that": the edge is stamped
|
|
47
|
-
* `basis: 'stage'` and the slice carries a `'conservative-fed-edges'` note.
|
|
48
|
-
* A conservative edge is never presented as an exact one.
|
|
49
|
-
*
|
|
50
|
-
* Budgets mirror `causalChain`'s (maxDepth 20, maxNodes 100) and a cut is
|
|
51
|
-
* STATED — `root.truncated` plus a `'truncated'` note.
|
|
52
|
-
*
|
|
53
|
-
* DAG position: memory ← slice. Imports memory/ only (see README.md).
|
|
54
|
-
*/
|
|
55
|
-
import { relation } from '../memory/keyPaths.js';
|
|
56
|
-
import { DELIM } from '../memory/utils.js';
|
|
57
|
-
import { buildKeyIndex, conservativeEdgesNote, firstIndexAfter, hasRecordedReads, indicesInRange, lastIndexBefore, lastTraceEntry, nestedOnlyWrites, nestedRowsNote, preRunOriginNote, readsNotRecordedNote, truncatedNote, unknownKeyNote, writeEntry, writtenPaths, } from './keyIndex.js';
|
|
58
|
-
import { resolveKeysReadSource } from './keysReadSources.js';
|
|
59
|
-
import { normaliseStateKey } from './sliceForKey.js';
|
|
60
|
-
/** Identity of one value life: (write position, key). Never parsed. */
|
|
61
|
-
function nodeKey(commitIdx, key) {
|
|
62
|
-
return `${commitIdx ?? 'pre-run'}${DELIM}${key}`;
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Build the node for ONE value life. `writeIdx === undefined` is the pre-run
|
|
66
|
-
* origin: the value was already there before the log's first write of the
|
|
67
|
-
* key, so the writer identity fields stay ABSENT rather than fabricated.
|
|
68
|
-
*/
|
|
69
|
-
function makeNode(commitLog, index, key, writeIdx, depth) {
|
|
70
|
-
// A life ends at the next write that replaces the value — never at one that only wrote a path INSIDE the
|
|
71
|
-
// key (a seed, a merge-back): a reader after that one still read the rest of this value.
|
|
72
|
-
const writes = index.closingWritesOf(key);
|
|
73
|
-
if (writeIdx === undefined) {
|
|
74
|
-
const firstWrite = writes?.[0];
|
|
75
|
-
return {
|
|
76
|
-
key,
|
|
77
|
-
origin: 'pre-run',
|
|
78
|
-
...(firstWrite !== undefined && { nextWriteIdx: firstWrite }),
|
|
79
|
-
depth,
|
|
80
|
-
reads: [],
|
|
81
|
-
fedEdges: [],
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
const bundle = commitLog[writeIdx];
|
|
85
|
-
const entry = writeEntry(bundle, key);
|
|
86
|
-
const next = firstIndexAfter(writes, writeIdx);
|
|
87
|
-
return {
|
|
88
|
-
key,
|
|
89
|
-
origin: 'write',
|
|
90
|
-
runtimeStageId: bundle.runtimeStageId,
|
|
91
|
-
stageId: bundle.stageId,
|
|
92
|
-
stageName: bundle.stage,
|
|
93
|
-
commitIdx: writeIdx,
|
|
94
|
-
...(entry !== undefined && { verb: entry.verb }),
|
|
95
|
-
...(next !== undefined && { nextWriteIdx: next }),
|
|
96
|
-
depth,
|
|
97
|
-
reads: [],
|
|
98
|
-
fedEdges: [],
|
|
99
|
-
// Untracked-read honesty rides through from the bundle exactly as
|
|
100
|
-
// causalChain stamps CausalNode.incompleteSources.
|
|
101
|
-
...(bundle.untrackedSources !== undefined &&
|
|
102
|
-
bundle.untrackedSources.length > 0 && { incompleteSources: bundle.untrackedSources }),
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Forward slice for one state key: who read this value, and what did it feed?
|
|
107
|
-
*
|
|
108
|
-
* @param commitLog Ordered commit bundles — `getSnapshot().commitLog`.
|
|
109
|
-
* @param key A {@link StateKey}: the plain key string, or a path array
|
|
110
|
-
* (normalised through the SAME `normaliseStateKey` the backward door uses,
|
|
111
|
-
* so both doors accept identical inputs).
|
|
112
|
-
* @param keysRead A {@link KeysReadSource} strategy or a bare lookup — the
|
|
113
|
-
* same reads providers `sliceForKey` takes. Reads are not in the commit
|
|
114
|
-
* log; without a provider a forward walk can see nothing, which the
|
|
115
|
-
* `'reads-not-recorded'` note says out loud.
|
|
116
|
-
* @returns Always a {@link ForwardSlice}. Absence is a RESULT with a reason
|
|
117
|
-
* and, for an unknown key, a bounded list of the keys the log does know.
|
|
118
|
-
*/
|
|
119
|
-
export function forwardSliceForKey(commitLog, key, keysRead, options) {
|
|
120
|
-
const source = resolveKeysReadSource(keysRead);
|
|
121
|
-
const normalisedKey = normaliseStateKey(key);
|
|
122
|
-
const base = {
|
|
123
|
-
key: normalisedKey,
|
|
124
|
-
...(options?.before !== undefined && { before: options.before }),
|
|
125
|
-
keysReadKind: source.kind,
|
|
126
|
-
...(source.coverage !== undefined && { readsCoverage: source.coverage }),
|
|
127
|
-
};
|
|
128
|
-
if (commitLog.length === 0)
|
|
129
|
-
return { ...base, missing: 'empty-log', notes: [] };
|
|
130
|
-
const index = buildKeyIndex(commitLog, source.lookup);
|
|
131
|
-
const readsRecorded = hasRecordedReads(index);
|
|
132
|
-
const notes = [];
|
|
133
|
-
// ── The typo guard, split by what the recording affords ────────────────
|
|
134
|
-
// Unknown key + reads ARE recorded → the log can see readers and this key
|
|
135
|
-
// has none: honest absence with a named reason, no fabricated life.
|
|
136
|
-
// Unknown key + NO reads recorded → a typo and a seeded-but-unread key are
|
|
137
|
-
// genuinely indistinguishable; the pre-run life below is the only honest
|
|
138
|
-
// answer, and it must carry BOTH notes so nobody reads it as "unread".
|
|
139
|
-
const known = index.isKnown(normalisedKey);
|
|
140
|
-
if (!known) {
|
|
141
|
-
notes.push(unknownKeyNote(index, normalisedKey));
|
|
142
|
-
if (readsRecorded)
|
|
143
|
-
return { ...base, missing: 'never-written', notes };
|
|
144
|
-
}
|
|
145
|
-
if (!readsRecorded)
|
|
146
|
-
notes.push(readsNotRecordedNote());
|
|
147
|
-
const maxDepth = options?.maxDepth ?? 20;
|
|
148
|
-
const maxNodes = options?.maxNodes ?? 100;
|
|
149
|
-
const nodes = new Map();
|
|
150
|
-
let created = 0;
|
|
151
|
-
let truncatedByDepth = false;
|
|
152
|
-
let truncatedByNodes = false;
|
|
153
|
-
let anyConservative = false;
|
|
154
|
-
const anchorIdx = lastIndexBefore(index.writesOf(normalisedKey), options?.before);
|
|
155
|
-
const root = makeNode(commitLog, index, normalisedKey, anchorIdx, 0);
|
|
156
|
-
nodes.set(nodeKey(anchorIdx, normalisedKey), root);
|
|
157
|
-
created = 1;
|
|
158
|
-
const queue = [root];
|
|
159
|
-
while (queue.length > 0) {
|
|
160
|
-
const node = queue.shift();
|
|
161
|
-
// Live range: open below the write, CLOSED at the next write (see LAW).
|
|
162
|
-
const from = node.commitIdx !== undefined ? node.commitIdx + 1 : 0;
|
|
163
|
-
const readers = indicesInRange(index.readsOf(node.key), from, node.nextWriteIdx);
|
|
164
|
-
if (node.depth >= maxDepth) {
|
|
165
|
-
// Only a life that still HAD readers to expand counts as a cut.
|
|
166
|
-
if (readers.length > 0)
|
|
167
|
-
truncatedByDepth = true;
|
|
168
|
-
continue;
|
|
169
|
-
}
|
|
170
|
-
for (const readerIdx of readers) {
|
|
171
|
-
const bundle = commitLog[readerIdx];
|
|
172
|
-
node.reads.push({
|
|
173
|
-
runtimeStageId: bundle.runtimeStageId,
|
|
174
|
-
stageId: bundle.stageId,
|
|
175
|
-
stageName: bundle.stage,
|
|
176
|
-
commitIdx: readerIdx,
|
|
177
|
-
});
|
|
178
|
-
// The reader IS the writer of everything it committed — each written
|
|
179
|
-
// path is a candidate `fed` edge.
|
|
180
|
-
for (const path of writtenPaths(bundle)) {
|
|
181
|
-
const entry = lastTraceEntry(bundle, path);
|
|
182
|
-
let basis;
|
|
183
|
-
if (entry?.readKeys !== undefined) {
|
|
184
|
-
// EXACT both ways: recorded provenance can include or EXCLUDE. A read
|
|
185
|
-
// on the key, inside it or around it is a read of its value.
|
|
186
|
-
if (!entry.readKeys.some((read) => relation(read, node.key) !== undefined))
|
|
187
|
-
continue;
|
|
188
|
-
basis = 'per-write';
|
|
189
|
-
}
|
|
190
|
-
else {
|
|
191
|
-
basis = 'stage';
|
|
192
|
-
anyConservative = true;
|
|
193
|
-
}
|
|
194
|
-
const id = nodeKey(readerIdx, path);
|
|
195
|
-
let child = nodes.get(id);
|
|
196
|
-
if (!child) {
|
|
197
|
-
if (created >= maxNodes) {
|
|
198
|
-
truncatedByNodes = true;
|
|
199
|
-
continue;
|
|
200
|
-
}
|
|
201
|
-
child = makeNode(commitLog, index, path, readerIdx, node.depth + 1);
|
|
202
|
-
nodes.set(id, child);
|
|
203
|
-
created++;
|
|
204
|
-
queue.push(child);
|
|
205
|
-
}
|
|
206
|
-
// One edge per distinct child life (a stage reads a key once).
|
|
207
|
-
if (!node.fedEdges.some((e) => e.child === child))
|
|
208
|
-
node.fedEdges.push({ child, basis });
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
// ── Honesty envelope, deterministic order ─────────────────────────────
|
|
213
|
-
if (root.origin === 'pre-run')
|
|
214
|
-
notes.push(preRunOriginNote(normalisedKey));
|
|
215
|
-
// Every life a write INSIDE its key starts or crosses — the anchor's, a pre-run life's, a child's — says so.
|
|
216
|
-
const partial = new Map();
|
|
217
|
-
for (const node of nodes.values()) {
|
|
218
|
-
const start = node.commitIdx ?? -1;
|
|
219
|
-
const crossed = index
|
|
220
|
-
.writesOf(node.key)
|
|
221
|
-
.filter((c) => (c === start || c > start) && (node.nextWriteIdx === undefined || c < node.nextWriteIdx));
|
|
222
|
-
for (const c of nestedOnlyWrites(commitLog, node.key, crossed)) {
|
|
223
|
-
const set = partial.get(node.key) ?? new Set();
|
|
224
|
-
set.add(c);
|
|
225
|
-
partial.set(node.key, set);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
for (const [key, commits] of partial)
|
|
229
|
-
notes.push(nestedRowsNote(key, [...commits].sort((a, b) => a - b)));
|
|
230
|
-
if (anyConservative)
|
|
231
|
-
notes.push(conservativeEdgesNote(normalisedKey));
|
|
232
|
-
if (truncatedByDepth || truncatedByNodes) {
|
|
233
|
-
root.truncated = { byDepth: truncatedByDepth, byNodes: truncatedByNodes };
|
|
234
|
-
notes.push(truncatedNote(truncatedByDepth, truncatedByNodes));
|
|
235
|
-
}
|
|
236
|
-
return {
|
|
237
|
-
...base,
|
|
238
|
-
...(anchorIdx !== undefined && { writer: commitLog[anchorIdx] }),
|
|
239
|
-
root,
|
|
240
|
-
notes,
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yd2FyZFNsaWNlRm9yS2V5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9zbGljZS9mb3J3YXJkU2xpY2VGb3JLZXkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcURHO0FBR0gsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRWpELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUMzQyxPQUFPLEVBRUwsYUFBYSxFQUNiLHFCQUFxQixFQUNyQixlQUFlLEVBQ2YsZ0JBQWdCLEVBQ2hCLGNBQWMsRUFDZCxlQUFlLEVBQ2YsY0FBYyxFQUNkLGdCQUFnQixFQUNoQixjQUFjLEVBQ2QsZ0JBQWdCLEVBQ2hCLG9CQUFvQixFQUNwQixhQUFhLEVBQ2IsY0FBYyxFQUNkLFVBQVUsRUFDVixZQUFZLEdBQ2IsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDN0QsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFvQnJELHVFQUF1RTtBQUN2RSxTQUFTLE9BQU8sQ0FBQyxTQUE2QixFQUFFLEdBQVc7SUFDekQsT0FBTyxHQUFHLFNBQVMsSUFBSSxTQUFTLEdBQUcsS0FBSyxHQUFHLEdBQUcsRUFBRSxDQUFDO0FBQ25ELENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBUyxRQUFRLENBQ2YsU0FBeUIsRUFDekIsS0FBZSxFQUNmLEdBQVcsRUFDWCxRQUE0QixFQUM1QixLQUFhO0lBRWIseUdBQXlHO0lBQ3pHLHlGQUF5RjtJQUN6RixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzFDLElBQUksUUFBUSxLQUFLLFNBQVMsRUFBRSxDQUFD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QUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FDbkMsQ0FDRixDQUFDO0lBQ0osSUFBSSxlQUFlO1FBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDO0lBQ3RFLElBQUksZ0JBQWdCLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztRQUN6QyxJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxDQUFDO1FBQzFFLEtBQUssQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLGdCQUFnQixFQUFFLGdCQUFnQixDQUFDLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRUQsT0FBTztRQUNMLEdBQUcsSUFBSTtRQUNQLEdBQUcsQ0FBQyxTQUFTLEtBQUssU0FBUyxJQUFJLEVBQUUsTUFBTSxFQUFFLFNBQVMsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQ2hFLElBQUk7UUFDSixLQUFLO0tBQ04sQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIHNsaWNlL2ZvcndhcmRTbGljZUZvcktleS50cyDigJQgdGhlIEZPUldBUkQgaGFsZiBvZiB2YXJpYWJsZS1maXJzdCBzbGljaW5nLlxuICpcbiAqIGBzbGljZUZvcktleWAgYW5zd2VycyBcIndoeSBpcyBga2V5YCB3aGF0IGl0IGlzP1wiIGJ5IHdhbGtpbmcgYmFja3dhcmQgZnJvbVxuICogdGhlIHZhbHVlIHRvIGl0cyBjYXVzZXMuIFRoaXMgZmlsZSBhbnN3ZXJzIHRoZSBvcHBvc2l0ZSBxdWVzdGlvbiwgd2hpY2ggbm9cbiAqIHF1ZXJ5IGFuc3dlcmVkIGJlZm9yZTogKipcIndobyBSRUFEIHRoaXMgdmFsdWUsIGFuZCB3aGF0IGRpZCBpdCBGRUVEP1wiKipcbiAqICh0aGUgcHJvZHVjdGlvbiBzaGFwZTogKndobyByZWFkIGByZWNpcGVJZGAsIGFuZCB3aGF0IGRpZCBpdCBmZWVkPyog4oCUIG9uZVxuICogcXVlcnksIG5vdCBhIG1hbnVhbCBzY2FuIG9mIGEgdHJhY2Ugdmlld2VyKS5cbiAqXG4gKiAjIyBUaGUgYWxnb3JpdGhtOiBMSVZFIFJBTkdFUywgbm90IHN0ZXBzXG4gKlxuICogQSBiYWNrd2FyZCBzbGljZSBob3BzIHdyaXRlcuKGkndyaXRlci4gRm9yd2FyZCwgdGhlIHVuaXQgaXMgYSB2YWx1ZSdzIExJRkU6XG4gKlxuICogMS4gQW5jaG9yIGF0IGEgd3JpdGUgb2YgYGtleWAg4oCUIHRoZSBTQU1FIGFuY2hvciBpZGlvbSBhcyBgc2xpY2VGb3JLZXlgXG4gKiAgICAodGhlIGxhc3Qgd3JpdGVyLCBvciB0aGUgbGFzdCB3cml0ZXIgYmVmb3JlIGBiZWZvcmVgKS5cbiAqIDIuIFRoYXQgdmFsdWUgbGl2ZXMgdW50aWwgdGhlIGtleSdzIE5FWFQgd3JpdGUgKGBuZXh0V3JpdGVJZHhgKS4gRXZlcnlcbiAqICAgIHN0YWdlIHRoYXQgUkVBRCBga2V5YCBpbnNpZGUgdGhhdCB3aW5kb3cgc2F3IFRISVMgdmFsdWUg4oCUIGEgYHJlYWRgLlxuICogICAgKDkuMzMuMDogYSB3cml0ZSB0aGF0IHJlYWNoZWQgdGhlIGtleSBvbmx5IHRocm91Z2ggcGF0aHMgSU5TSURFIGl0IOKAlCBhXG4gKiAgICBzdWJmbG93IHNlZWQsIGFuIG91dHB1dE1hcHBlciBtZXJnZS1iYWNrIOKAlCBjaGFuZ2VkIHBhcnQgb2YgdGhlIHZhbHVlXG4gKiAgICBhbmQgZG9lcyBOT1QgZW5kIGl0cyBsaWZlOiBhIHJlYWRlciBhZnRlciBpdCBzdGlsbCByZWFkIHRoZSByZXN0LiBFdmVyeVxuICogICAgbGlmZSBzdWNoIGEgd3JpdGUgc3RhcnRzIG9yIGNyb3NzZXMgY2FycmllcyBhIGAnbmVzdGVkLXJvd3MnYCBub3RlLilcbiAqIDMuIEEgcmVhZGluZyBzdGFnZSB0aGF0IGFsc28gV1JPVEUgc29tZXRoaW5nIGNhcnJpZWQgdGhlIHZhbHVlIG9ud2FyZCDigJRcbiAqICAgIGEgYGZlZGAgZWRnZSB0byB0aGF0IHdyaXRlLCB3aGljaCBpcyBpdHNlbGYgdGhlIHN0YXJ0IG9mIGEgbmV3IGxpZmUuXG4gKiA0LiBEZXNjZW5kIGludG8gZmVkIGxpdmVzIGJyZWFkdGgtZmlyc3QgKHZpc2l0ZWQtc2V0IGd1YXJkZWQsIGJ1ZGdldGVkKS5cbiAqXG4gKiAjIyMgTEFXIOKAlCB0aGUgbGl2ZSByYW5nZSBpcyBgKHdyaXRlSWR4LCBuZXh0V3JpdGVJZHhdYFxuICpcbiAqIE9wZW4gYXQgdGhlIGJvdHRvbSwgQ0xPU0VEIGF0IHRoZSB0b3AsIGFuZCBib3RoIGVuZHMgZm9sbG93IGZyb20gdGhlXG4gKiBlbmdpbmUncyBldmVudCBvcmRlciAoYG9uUmVhZGAgZmlyZXMgUFJFLWNvbW1pdCDigJQgc2VlIENMQVVERS5tZCk6XG4gKiAtIGEgcmVhZCBieSB0aGUgd3JpdGluZyBzdGFnZSBpdHNlbGYgKGByZWFkSWR4ID09PSB3cml0ZUlkeGApIHNhdyB0aGVcbiAqICAgUFJFVklPVVMgdmFsdWU6IHJlYWQtbW9kaWZ5LXdyaXRlIHJlYWRzIGJlbG9uZyB0byB0aGUgcHJldmlvdXMgbGlmZTtcbiAqIC0gYSByZWFkIGJ5IHRoZSBPVkVSV1JJVElORyBzdGFnZSAoYHJlYWRJZHggPT09IG5leHRXcml0ZUlkeGApIGFsc28gZmlyZWRcbiAqICAgYmVmb3JlIGl0cyBjb21taXQsIHNvIGl0IHN0aWxsIHNhdyBUSElTIHZhbHVlLlxuICogQSByZWFkIGFmdGVyIHRoYXQgY29tbWl0IGF0dHJpYnV0ZXMgdG8gdGhlIE5FVyB3cml0ZSwgbmV2ZXIgdGhlIG9sZCBvbmUuXG4gKiAoR3JhbnVsYXJpdHkgbGltaXQsIHN0YXRlZCBiZWNhdXNlIGl0IGNhbm5vdCBiZSBzZWVuOiBhIHN0YWdlIHRoYXQgd3JpdGVzXG4gKiBga2V5YCBhbmQgdGhlbiByZS1yZWFkcyBpdCB3aXRoaW4gdGhlIFNBTUUgc3RhZ2UgcmVhZCBpdHMgb3duIHZhbHVlOyBhdFxuICogY29tbWl0LWluZGV4IHJlc29sdXRpb24gdGhhdCByZWFkIGlzIGluZGlzdGluZ3Vpc2hhYmxlIGZyb20gdGhlIG9uZSB0aGF0XG4gKiBvcGVuZWQgdGhlIHN0YWdlLilcbiAqXG4gKiAjIyMgTEFXIOKAlCBhIGBmZWRgIGVkZ2UgaXMgRVhBQ1Qgb25seSB1bmRlciByZWNvcmRlZCByZWFkIHByb3ZlbmFuY2VcbiAqXG4gKiBXaXRoIGB3cml0ZVByb3ZlbmFuY2U6ICdyZWFkcy1wcmVmaXgnYCBvbiwgdGhlIGNoaWxkIHdyaXRlJ3NcbiAqIGBUcmFjZUVudHJ5LnJlYWRLZXlzYCBuYW1lcyB0aGUga2V5cyByZWFkIGJlZm9yZSBpdDogdGhpcyBrZXkgSU4gdGhhdCBsaXN0XG4gKiBpcyBhbiBleGFjdCBlZGdlIChgYmFzaXM6ICdwZXItd3JpdGUnYCksIGFuZCB0aGlzIGtleSBBQlNFTlQgZnJvbSBpdCBpcyBhblxuICogZXhhY3QgKmV4Y2x1c2lvbiog4oCUIG5vIGVkZ2UgYXQgYWxsLiBXaXRoIHRoZSBkaWFsIG9mZiB0aGVyZSBpcyBubyBzdWNoXG4gKiBldmlkZW5jZSwgb25seSBcInRoZSBzdGFnZSByZWFkIHRoaXMgYW5kIHdyb3RlIHRoYXRcIjogdGhlIGVkZ2UgaXMgc3RhbXBlZFxuICogYGJhc2lzOiAnc3RhZ2UnYCBhbmQgdGhlIHNsaWNlIGNhcnJpZXMgYSBgJ2NvbnNlcnZhdGl2ZS1mZWQtZWRnZXMnYCBub3RlLlxuICogQSBjb25zZXJ2YXRpdmUgZWRnZSBpcyBuZXZlciBwcmVzZW50ZWQgYXMgYW4gZXhhY3Qgb25lLlxuICpcbiAqIEJ1ZGdldHMgbWlycm9yIGBjYXVzYWxDaGFpbmAncyAobWF4RGVwdGggMjAsIG1heE5vZGVzIDEwMCkgYW5kIGEgY3V0IGlzXG4gKiBTVEFURUQg4oCUIGByb290LnRydW5jYXRlZGAgcGx1cyBhIGAndHJ1bmNhdGVkJ2Agbm90ZS5cbiAqXG4gKiBEQUcgcG9zaXRpb246IG1lbW9yeSDihpAgc2xpY2UuIEltcG9ydHMgbWVtb3J5LyBvbmx5IChzZWUgUkVBRE1FLm1kKS5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEtleXNSZWFkTG9va3VwIH0gZnJvbSAnLi4vbWVtb3J5L2JhY2t0cmFjay5qcyc7XG5pbXBvcnQgeyByZWxhdGlvbiB9IGZyb20gJy4uL21lbW9yeS9rZXlQYXRocy5qcyc7XG5pbXBvcnQgdHlwZSB7IENvbW1pdEJ1bmRsZSB9IGZyb20gJy4uL21lbW9yeS90eXBlcy5qcyc7XG5pbXBvcnQgeyBERUxJTSB9IGZyb20gJy4uL21lbW9yeS91dGlscy5qcyc7XG5pbXBvcnQge1xuICB0eXBlIEtleUluZGV4LFxuICBidWlsZEtleUluZGV4LFxuICBjb25zZXJ2YXRpdmVFZGdlc05vdGUsXG4gIGZpcnN0SW5kZXhBZnRlcixcbiAgaGFzUmVjb3JkZWRSZWFkcyxcbiAgaW5kaWNlc0luUmFuZ2UsXG4gIGxhc3RJbmRleEJlZm9yZSxcbiAgbGFzdFRyYWNlRW50cnksXG4gIG5lc3RlZE9ubHlXcml0ZXMsXG4gIG5lc3RlZFJvd3NOb3RlLFxuICBwcmVSdW5PcmlnaW5Ob3RlLFxuICByZWFkc05vdFJlY29yZGVkTm90ZSxcbiAgdHJ1bmNhdGVkTm90ZSxcbiAgdW5rbm93bktleU5vdGUsXG4gIHdyaXRlRW50cnksXG4gIHdyaXR0ZW5QYXRocyxcbn0gZnJvbSAnLi9rZXlJbmRleC5qcyc7XG5pbXBvcnQgeyByZXNvbHZlS2V5c1JlYWRTb3VyY2UgfSBmcm9tICcuL2tleXNSZWFkU291cmNlcy5qcyc7XG5pbXBvcnQgeyBub3JtYWxpc2VTdGF0ZUtleSB9IGZyb20gJy4vc2xpY2VGb3JLZXkuanMnO1xuaW1wb3J0IHR5cGUgeyBGZWRCYXNpcywgRm9yd2FyZE5vZGUsIEZvcndhcmRTbGljZSwgSG9uZXN0eU5vdGUsIEtleXNSZWFkU291cmNlLCBTdGF0ZUtleSB9IGZyb20gJy4vdHlwZXMuanMnO1xuXG4vKiogT3B0aW9ucyBmb3Ige0BsaW5rIGZvcndhcmRTbGljZUZvcktleX0g4oCUIGFuY2hvcmluZyBwbHVzIHdhbGsgYnVkZ2V0cy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRm9yd2FyZFNsaWNlRm9yS2V5T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBFeGNsdXNpdmUgY29tbWl0LWFycmF5LWluZGV4IHVwcGVyIGJvdW5kIGZvciB0aGUgQU5DSE9SIHNlYXJjaDogZm9sbG93XG4gICAqIHRoZSB2YWx1ZSBhcyBpdCBzdG9vZCBCRUZPUkUgdGhpcyBpZHguIFNhbWUgY29udHJhY3QgYXNcbiAgICogYHNsaWNlRm9yS2V5YCdzIGBiZWZvcmVgIC8gYGZpbmRMYXN0V3JpdGVyYCdzIGBiZWZvcmVJZHhgLlxuICAgKlxuICAgKiBJdCBib3VuZHMgdGhlIGFuY2hvciBPTkxZIOKAlCB0aGUgd2FsayB0aGVuIHJ1bnMgZm9yd2FyZCBwYXN0IGl0LCBiZWNhdXNlXG4gICAqIFwid2hhdCBkaWQgdGhlIHZhbHVlIGF0IHN0ZXAgMTIgZ28gb24gdG8gZmVlZD9cIiBpcyB0aGUgd2hvbGUgcXVlc3Rpb24uXG4gICAqL1xuICBiZWZvcmU/OiBudW1iZXI7XG4gIC8qKiBNYXhpbXVtIEJGUyBkZXB0aCBpbiB2YWx1ZS1saXZlcyAoZGVmYXVsdDogMjAg4oCUIGNhdXNhbENoYWluJ3MpLiAqL1xuICBtYXhEZXB0aD86IG51bWJlcjtcbiAgLyoqIE1heGltdW0gdG90YWwgbm9kZXMgKGRlZmF1bHQ6IDEwMCDigJQgY2F1c2FsQ2hhaW4ncykuICovXG4gIG1heE5vZGVzPzogbnVtYmVyO1xufVxuXG4vKiogSWRlbnRpdHkgb2Ygb25lIHZhbHVlIGxpZmU6ICh3cml0ZSBwb3NpdGlvbiwga2V5KS4gTmV2ZXIgcGFyc2VkLiAqL1xuZnVuY3Rpb24gbm9kZUtleShjb21taXRJZHg6IG51bWJlciB8IHVuZGVmaW5lZCwga2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYCR7Y29tbWl0SWR4ID8/ICdwcmUtcnVuJ30ke0RFTElNfSR7a2V5fWA7XG59XG5cbi8qKlxuICogQnVpbGQgdGhlIG5vZGUgZm9yIE9ORSB2YWx1ZSBsaWZlLiBgd3JpdGVJZHggPT09IHVuZGVmaW5lZGAgaXMgdGhlIHByZS1ydW5cbiAqIG9yaWdpbjogdGhlIHZhbHVlIHdhcyBhbHJlYWR5IHRoZXJlIGJlZm9yZSB0aGUgbG9nJ3MgZmlyc3Qgd3JpdGUgb2YgdGhlXG4gKiBrZXksIHNvIHRoZSB3cml0ZXIgaWRlbnRpdHkgZmllbGRzIHN0YXkgQUJTRU5UIHJhdGhlciB0aGFuIGZhYnJpY2F0ZWQuXG4gKi9cbmZ1bmN0aW9uIG1ha2VOb2RlKFxuICBjb21taXRMb2c6IENvbW1pdEJ1bmRsZVtdLFxuICBpbmRleDogS2V5SW5kZXgsXG4gIGtleTogc3RyaW5nLFxuICB3cml0ZUlkeDogbnVtYmVyIHwgdW5kZWZpbmVkLFxuICBkZXB0aDogbnVtYmVyLFxuKTogRm9yd2FyZE5vZGUge1xuICAvLyBBIGxpZmUgZW5kcyBhdCB0aGUgbmV4dCB3cml0ZSB0aGF0IHJlcGxhY2VzIHRoZSB2YWx1ZSDigJQgbmV2ZXIgYXQgb25lIHRoYXQgb25seSB3cm90ZSBhIHBhdGggSU5TSURFIHRoZVxuICAvLyBrZXkgKGEgc2VlZCwgYSBtZXJnZS1iYWNrKTogYSByZWFkZXIgYWZ0ZXIgdGhhdCBvbmUgc3RpbGwgcmVhZCB0aGUgcmVzdCBvZiB0aGlzIHZhbHVlLlxuICBjb25zdCB3cml0ZXMgPSBpbmRleC5jbG9zaW5nV3JpdGVzT2Yoa2V5KTtcbiAgaWYgKHdyaXRlSWR4ID09PSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBmaXJzdFdyaXRlID0gd3JpdGVzPy5bMF07XG4gICAgcmV0dXJuIHtcbiAgICAgIGtleSxcbiAgICAgIG9yaWdpbjogJ3ByZS1ydW4nLFxuICAgICAgLi4uKGZpcnN0V3JpdGUgIT09IHVuZGVmaW5lZCAmJiB7IG5leHRXcml0ZUlkeDogZmlyc3RXcml0ZSB9KSxcbiAgICAgIGRlcHRoLFxuICAgICAgcmVhZHM6IFtdLFxuICAgICAgZmVkRWRnZXM6IFtdLFxuICAgIH07XG4gIH1cbiAgY29uc3QgYnVuZGxlID0gY29tbWl0TG9nW3dyaXRlSWR4XTtcbiAgY29uc3QgZW50cnkgPSB3cml0ZUVudHJ5KGJ1bmRsZSwga2V5KTtcbiAgY29uc3QgbmV4dCA9IGZpcnN0SW5kZXhBZnRlcih3cml0ZXMsIHdyaXRlSWR4KTtcbiAgcmV0dXJuIHtcbiAgICBrZXksXG4gICAgb3JpZ2luOiAnd3JpdGUnLFxuICAgIHJ1bnRpbWVTdGFnZUlkOiBidW5kbGUucnVudGltZVN0YWdlSWQsXG4gICAgc3RhZ2VJZDogYnVuZGxlLnN0YWdlSWQsXG4gICAgc3RhZ2VOYW1lOiBidW5kbGUuc3RhZ2UsXG4gICAgY29tbWl0SWR4OiB3cml0ZUlkeCxcbiAgICAuLi4oZW50cnkgIT09IHVuZGVmaW5lZCAmJiB7IHZlcmI6IGVudHJ5LnZlcmIgfSksXG4gICAgLi4uKG5leHQgIT09IHVuZGVmaW5lZCAmJiB7IG5leHRXcml0ZUlkeDogbmV4dCB9KSxcbiAgICBkZXB0aCxcbiAgICByZWFkczogW10sXG4gICAgZmVkRWRnZXM6IFtdLFxuICAgIC8vIFVudHJhY2tlZC1yZWFkIGhvbmVzdHkgcmlkZXMgdGhyb3VnaCBmcm9tIHRoZSBidW5kbGUgZXhhY3RseSBhc1xuICAgIC8vIGNhdXNhbENoYWluIHN0YW1wcyBDYXVzYWxOb2RlLmluY29tcGxldGVTb3VyY2VzLlxuICAgIC4uLihidW5kbGUudW50cmFja2VkU291cmNlcyAhPT0gdW5kZWZpbmVkICYmXG4gICAgICBidW5kbGUudW50cmFja2VkU291cmNlcy5sZW5ndGggPiAwICYmIHsgaW5jb21wbGV0ZVNvdXJjZXM6IGJ1bmRsZS51bnRyYWNrZWRTb3VyY2VzIH0pLFxuICB9O1xufVxuXG4vKipcbiAqIEZvcndhcmQgc2xpY2UgZm9yIG9uZSBzdGF0ZSBrZXk6IHdobyByZWFkIHRoaXMgdmFsdWUsIGFuZCB3aGF0IGRpZCBpdCBmZWVkP1xuICpcbiAqIEBwYXJhbSBjb21taXRMb2cgT3JkZXJlZCBjb21taXQgYnVuZGxlcyDigJQgYGdldFNuYXBzaG90KCkuY29tbWl0TG9nYC5cbiAqIEBwYXJhbSBrZXkgQSB7QGxpbmsgU3RhdGVLZXl9OiB0aGUgcGxhaW4ga2V5IHN0cmluZywgb3IgYSBwYXRoIGFycmF5XG4gKiAgIChub3JtYWxpc2VkIHRocm91Z2ggdGhlIFNBTUUgYG5vcm1hbGlzZVN0YXRlS2V5YCB0aGUgYmFja3dhcmQgZG9vciB1c2VzLFxuICogICBzbyBib3RoIGRvb3JzIGFjY2VwdCBpZGVudGljYWwgaW5wdXRzKS5cbiAqIEBwYXJhbSBrZXlzUmVhZCBBIHtAbGluayBLZXlzUmVhZFNvdXJjZX0gc3RyYXRlZ3kgb3IgYSBiYXJlIGxvb2t1cCDigJQgdGhlXG4gKiAgIHNhbWUgcmVhZHMgcHJvdmlkZXJzIGBzbGljZUZvcktleWAgdGFrZXMuIFJlYWRzIGFyZSBub3QgaW4gdGhlIGNvbW1pdFxuICogICBsb2c7IHdpdGhvdXQgYSBwcm92aWRlciBhIGZvcndhcmQgd2FsayBjYW4gc2VlIG5vdGhpbmcsIHdoaWNoIHRoZVxuICogICBgJ3JlYWRzLW5vdC1yZWNvcmRlZCdgIG5vdGUgc2F5cyBvdXQgbG91ZC5cbiAqIEByZXR1cm5zIEFsd2F5cyBhIHtAbGluayBGb3J3YXJkU2xpY2V9LiBBYnNlbmNlIGlzIGEgUkVTVUxUIHdpdGggYSByZWFzb25cbiAqICAgYW5kLCBmb3IgYW4gdW5rbm93biBrZXksIGEgYm91bmRlZCBsaXN0IG9mIHRoZSBrZXlzIHRoZSBsb2cgZG9lcyBrbm93LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZm9yd2FyZFNsaWNlRm9yS2V5KFxuICBjb21taXRMb2c6IENvbW1pdEJ1bmRsZVtdLFxuICBrZXk6IFN0YXRlS2V5LFxuICBrZXlzUmVhZDogS2V5c1JlYWRTb3VyY2UgfCBLZXlzUmVhZExvb2t1cCxcbiAgb3B0aW9ucz86IEZvcndhcmRTbGljZUZvcktleU9wdGlvbnMsXG4pOiBGb3J3YXJkU2xpY2Uge1xuICBjb25zdCBzb3VyY2UgPSByZXNvbHZlS2V5c1JlYWRTb3VyY2Uoa2V5c1JlYWQpO1xuICBjb25zdCBub3JtYWxpc2VkS2V5ID0gbm9ybWFsaXNlU3RhdGVLZXkoa2V5KTtcbiAgY29uc3QgYmFzZTogUGljazxGb3J3YXJkU2xpY2UsICdrZXknIHwgJ2JlZm9yZScgfCAna2V5c1JlYWRLaW5kJyB8ICdyZWFkc0NvdmVyYWdlJz4gPSB7XG4gICAga2V5OiBub3JtYWxpc2VkS2V5LFxuICAgIC4uLihvcHRpb25zPy5iZWZvcmUgIT09IHVuZGVmaW5lZCAmJiB7IGJlZm9yZTogb3B0aW9ucy5iZWZvcmUgfSksXG4gICAga2V5c1JlYWRLaW5kOiBzb3VyY2Uua2luZCxcbiAgICAuLi4oc291cmNlLmNvdmVyYWdlICE9PSB1bmRlZmluZWQgJiYgeyByZWFkc0NvdmVyYWdlOiBzb3VyY2UuY292ZXJhZ2UgfSksXG4gIH07XG5cbiAgaWYgKGNvbW1pdExvZy5sZW5ndGggPT09IDApIHJldHVybiB7IC4uLmJhc2UsIG1pc3Npbmc6ICdlbXB0eS1sb2cnLCBub3RlczogW10gfTtcblxuICBjb25zdCBpbmRleCA9IGJ1aWxkS2V5SW5kZXgoY29tbWl0TG9nLCBzb3VyY2UubG9va3VwKTtcbiAgY29uc3QgcmVhZHNSZWNvcmRlZCA9IGhhc1JlY29yZGVkUmVhZHMoaW5kZXgpO1xuICBjb25zdCBub3RlczogSG9uZXN0eU5vdGVbXSA9IFtdO1xuXG4gIC8vIOKUgOKUgCBUaGUgdHlwbyBndWFyZCwgc3BsaXQgYnkgd2hhdCB0aGUgcmVjb3JkaW5nIGFmZm9yZHMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIC8vIFVua25vd24ga2V5ICsgcmVhZHMgQVJFIHJlY29yZGVkIOKGkiB0aGUgbG9nIGNhbiBzZWUgcmVhZGVycyBhbmQgdGhpcyBrZXlcbiAgLy8gaGFzIG5vbmU6IGhvbmVzdCBhYnNlbmNlIHdpdGggYSBuYW1lZCByZWFzb24sIG5vIGZhYnJpY2F0ZWQgbGlmZS5cbiAgLy8gVW5rbm93biBrZXkgKyBOTyByZWFkcyByZWNvcmRlZCDihpIgYSB0eXBvIGFuZCBhIHNlZWRlZC1idXQtdW5yZWFkIGtleSBhcmVcbiAgLy8gZ2VudWluZWx5IGluZGlzdGluZ3Vpc2hhYmxlOyB0aGUgcHJlLXJ1biBsaWZlIGJlbG93IGlzIHRoZSBvbmx5IGhvbmVzdFxuICAvLyBhbnN3ZXIsIGFuZCBpdCBtdXN0IGNhcnJ5IEJPVEggbm90ZXMgc28gbm9ib2R5IHJlYWRzIGl0IGFzIFwidW5yZWFkXCIuXG4gIGNvbnN0IGtub3duID0gaW5kZXguaXNLbm93bihub3JtYWxpc2VkS2V5KTtcbiAgaWYgKCFrbm93bikge1xuICAgIG5vdGVzLnB1c2godW5rbm93bktleU5vdGUoaW5kZXgsIG5vcm1hbGlzZWRLZXkpKTtcbiAgICBpZiAocmVhZHNSZWNvcmRlZCkgcmV0dXJuIHsgLi4uYmFzZSwgbWlzc2luZzogJ25ldmVyLXdyaXR0ZW4nLCBub3RlcyB9O1xuICB9XG4gIGlmICghcmVhZHNSZWNvcmRlZCkgbm90ZXMucHVzaChyZWFkc05vdFJlY29yZGVkTm90ZSgpKTtcblxuICBjb25zdCBtYXhEZXB0aCA9IG9wdGlvbnM/Lm1heERlcHRoID8/IDIwO1xuICBjb25zdCBtYXhOb2RlcyA9IG9wdGlvbnM/Lm1heE5vZGVzID8/IDEwMDtcblxuICBjb25zdCBub2RlcyA9IG5ldyBNYXA8c3RyaW5nLCBGb3J3YXJkTm9kZT4oKTtcbiAgbGV0IGNyZWF0ZWQgPSAwO1xuICBsZXQgdHJ1bmNhdGVkQnlEZXB0aCA9IGZhbHNlO1xuICBsZXQgdHJ1bmNhdGVkQnlOb2RlcyA9IGZhbHNlO1xuICBsZXQgYW55Q29uc2VydmF0aXZlID0gZmFsc2U7XG5cbiAgY29uc3QgYW5jaG9ySWR4ID0gbGFzdEluZGV4QmVmb3JlKGluZGV4LndyaXRlc09mKG5vcm1hbGlzZWRLZXkpLCBvcHRpb25zPy5iZWZvcmUpO1xuICBjb25zdCByb290ID0gbWFrZU5vZGUoY29tbWl0TG9nLCBpbmRleCwgbm9ybWFsaXNlZEtleSwgYW5jaG9ySWR4LCAwKTtcbiAgbm9kZXMuc2V0KG5vZGVLZXkoYW5jaG9ySWR4LCBub3JtYWxpc2VkS2V5KSwgcm9vdCk7XG4gIGNyZWF0ZWQgPSAxO1xuXG4gIGNvbnN0IHF1ZXVlOiBGb3J3YXJkTm9kZVtdID0gW3Jvb3RdO1xuICB3aGlsZSAocXVldWUubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IG5vZGUgPSBxdWV1ZS5zaGlmdCgpITtcbiAgICAvLyBMaXZlIHJhbmdlOiBvcGVuIGJlbG93IHRoZSB3cml0ZSwgQ0xPU0VEIGF0IHRoZSBuZXh0IHdyaXRlIChzZWUgTEFXKS5cbiAgICBjb25zdCBmcm9tID0gbm9kZS5jb21taXRJZHggIT09IHVuZGVmaW5lZCA/IG5vZGUuY29tbWl0SWR4ICsgMSA6IDA7XG4gICAgY29uc3QgcmVhZGVycyA9IGluZGljZXNJblJhbmdlKGluZGV4LnJlYWRzT2Yobm9kZS5rZXkpLCBmcm9tLCBub2RlLm5leHRXcml0ZUlkeCk7XG5cbiAgICBpZiAobm9kZS5kZXB0aCA+PSBtYXhEZXB0aCkge1xuICAgICAgLy8gT25seSBhIGxpZmUgdGhhdCBzdGlsbCBIQUQgcmVhZGVycyB0byBleHBhbmQgY291bnRzIGFzIGEgY3V0LlxuICAgICAgaWYgKHJlYWRlcnMubGVuZ3RoID4gMCkgdHJ1bmNhdGVkQnlEZXB0aCA9IHRydWU7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHJlYWRlcklkeCBvZiByZWFkZXJzKSB7XG4gICAgICBjb25zdCBidW5kbGUgPSBjb21taXRMb2dbcmVhZGVySWR4XTtcbiAgICAgIG5vZGUucmVhZHMucHVzaCh7XG4gICAgICAgIHJ1bnRpbWVTdGFnZUlkOiBidW5kbGUucnVudGltZVN0YWdlSWQsXG4gICAgICAgIHN0YWdlSWQ6IGJ1bmRsZS5zdGFnZUlkLFxuICAgICAgICBzdGFnZU5hbWU6IGJ1bmRsZS5zdGFnZSxcbiAgICAgICAgY29tbWl0SWR4OiByZWFkZXJJZHgsXG4gICAgICB9KTtcblxuICAgICAgLy8gVGhlIHJlYWRlciBJUyB0aGUgd3JpdGVyIG9mIGV2ZXJ5dGhpbmcgaXQgY29tbWl0dGVkIOKAlCBlYWNoIHdyaXR0ZW5cbiAgICAgIC8vIHBhdGggaXMgYSBjYW5kaWRhdGUgYGZlZGAgZWRnZS5cbiAgICAgIGZvciAoY29uc3QgcGF0aCBvZiB3cml0dGVuUGF0aHMoYnVuZGxlKSkge1xuICAgICAgICBjb25zdCBlbnRyeSA9IGxhc3RUcmFjZUVudHJ5KGJ1bmRsZSwgcGF0aCk7XG4gICAgICAgIGxldCBiYXNpczogRmVkQmFzaXM7XG4gICAgICAgIGlmIChlbnRyeT8ucmVhZEtleXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIC8vIEVYQUNUIGJvdGggd2F5czogcmVjb3JkZWQgcHJvdmVuYW5jZSBjYW4gaW5jbHVkZSBvciBFWENMVURFLiBBIHJlYWRcbiAgICAgICAgICAvLyBvbiB0aGUga2V5LCBpbnNpZGUgaXQgb3IgYXJvdW5kIGl0IGlzIGEgcmVhZCBvZiBpdHMgdmFsdWUuXG4gICAgICAgICAgaWYgKCFlbnRyeS5yZWFkS2V5cy5zb21lKChyZWFkKSA9PiByZWxhdGlvbihyZWFkLCBub2RlLmtleSkgIT09IHVuZGVmaW5lZCkpIGNvbnRpbnVlO1xuICAgICAgICAgIGJhc2lzID0gJ3Blci13cml0ZSc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYmFzaXMgPSAnc3RhZ2UnO1xuICAgICAgICAgIGFueUNvbnNlcnZhdGl2ZSA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpZCA9IG5vZGVLZXkocmVhZGVySWR4LCBwYXRoKTtcbiAgICAgICAgbGV0IGNoaWxkID0gbm9kZXMuZ2V0KGlkKTtcbiAgICAgICAgaWYgKCFjaGlsZCkge1xuICAgICAgICAgIGlmIChjcmVhdGVkID49IG1heE5vZGVzKSB7XG4gICAgICAgICAgICB0cnVuY2F0ZWRCeU5vZGVzID0gdHJ1ZTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjaGlsZCA9IG1ha2VOb2RlKGNvbW1pdExvZywgaW5kZXgsIHBhdGgsIHJlYWRlcklkeCwgbm9kZS5kZXB0aCArIDEpO1xuICAgICAgICAgIG5vZGVzLnNldChpZCwgY2hpbGQpO1xuICAgICAgICAgIGNyZWF0ZWQrKztcbiAgICAgICAgICBxdWV1ZS5wdXNoKGNoaWxkKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBPbmUgZWRnZSBwZXIgZGlzdGluY3QgY2hpbGQgbGlmZSAoYSBzdGFnZSByZWFkcyBhIGtleSBvbmNlKS5cbiAgICAgICAgaWYgKCFub2RlLmZlZEVkZ2VzLnNvbWUoKGUpID0+IGUuY2hpbGQgPT09IGNoaWxkKSkgbm9kZS5mZWRFZGdlcy5wdXNoKHsgY2hpbGQsIGJhc2lzIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIOKUgOKUgCBIb25lc3R5IGVudmVsb3BlLCBkZXRlcm1pbmlzdGljIG9yZGVyIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICBpZiAocm9vdC5vcmlnaW4gPT09ICdwcmUtcnVuJykgbm90ZXMucHVzaChwcmVSdW5PcmlnaW5Ob3RlKG5vcm1hbGlzZWRLZXkpKTtcbiAgLy8gRXZlcnkgbGlmZSBhIHdyaXRlIElOU0lERSBpdHMga2V5IHN0YXJ0cyBvciBjcm9zc2VzIOKAlCB0aGUgYW5jaG9yJ3MsIGEgcHJlLXJ1biBsaWZlJ3MsIGEgY2hpbGQncyDigJQgc2F5cyBzby5cbiAgY29uc3QgcGFydGlhbCA9IG5ldyBNYXA8c3RyaW5nLCBTZXQ8bnVtYmVyPj4oKTtcbiAgZm9yIChjb25zdCBub2RlIG9mIG5vZGVzLnZhbHVlcygpKSB7XG4gICAgY29uc3Qgc3RhcnQgPSBub2RlLmNvbW1pdElkeCA/PyAtMTtcbiAgICBjb25zdCBjcm9zc2VkID0gaW5kZXhcbiAgICAgIC53cml0ZXNPZihub2RlLmtleSlcbiAgICAgIC5maWx0ZXIoKGMpID0+IChjID09PSBzdGFydCB8fCBjID4gc3RhcnQpICYmIChub2RlLm5leHRXcml0ZUlkeCA9PT0gdW5kZWZpbmVkIHx8IGMgPCBub2RlLm5leHRXcml0ZUlkeCkpO1xuICAgIGZvciAoY29uc3QgYyBvZiBuZXN0ZWRPbmx5V3JpdGVzKGNvbW1pdExvZywgbm9kZS5rZXksIGNyb3NzZWQpKSB7XG4gICAgICBjb25zdCBzZXQgPSBwYXJ0aWFsLmdldChub2RlLmtleSkgPz8gbmV3IFNldDxudW1iZXI+KCk7XG4gICAgICBzZXQuYWRkKGMpO1xuICAgICAgcGFydGlhbC5zZXQobm9kZS5rZXksIHNldCk7XG4gICAgfVxuICB9XG4gIGZvciAoY29uc3QgW2tleSwgY29tbWl0c10gb2YgcGFydGlhbClcbiAgICBub3Rlcy5wdXNoKFxuICAgICAgbmVzdGVkUm93c05vdGUoXG4gICAgICAgIGtleSxcbiAgICAgICAgWy4uLmNvbW1pdHNdLnNvcnQoKGEsIGIpID0+IGEgLSBiKSxcbiAgICAgICksXG4gICAgKTtcbiAgaWYgKGFueUNvbnNlcnZhdGl2ZSkgbm90ZXMucHVzaChjb25zZXJ2YXRpdmVFZGdlc05vdGUobm9ybWFsaXNlZEtleSkpO1xuICBpZiAodHJ1bmNhdGVkQnlEZXB0aCB8fCB0cnVuY2F0ZWRCeU5vZGVzKSB7XG4gICAgcm9vdC50cnVuY2F0ZWQgPSB7IGJ5RGVwdGg6IHRydW5jYXRlZEJ5RGVwdGgsIGJ5Tm9kZXM6IHRydW5jYXRlZEJ5Tm9kZXMgfTtcbiAgICBub3Rlcy5wdXNoKHRydW5jYXRlZE5vdGUodHJ1bmNhdGVkQnlEZXB0aCwgdHJ1bmNhdGVkQnlOb2RlcykpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5iYXNlLFxuICAgIC4uLihhbmNob3JJZHggIT09IHVuZGVmaW5lZCAmJiB7IHdyaXRlcjogY29tbWl0TG9nW2FuY2hvcklkeF0gfSksXG4gICAgcm9vdCxcbiAgICBub3RlcyxcbiAgfTtcbn1cbiJdfQ==
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* slice/ — variable-first slicing, both directions (the triage query layer).
|
|
3
|
-
*
|
|
4
|
-
* One variable, one contract, every surface — asked identically by UI panels
|
|
5
|
-
* (explainable-ui / lens), LLM triage tools (trace toolpacks), and offline
|
|
6
|
-
* autopsy agents:
|
|
7
|
-
*
|
|
8
|
-
* - BACKWARD — "why is this VARIABLE what it is?" (`sliceForKey`,
|
|
9
|
-
* `arrayProvenance` / `elementProvenance`).
|
|
10
|
-
* - FORWARD — "who READ it, and what did it FEED?" (`forwardSliceForKey`),
|
|
11
|
-
* plus the flat chronological view (`keyTimeline`).
|
|
12
|
-
*
|
|
13
|
-
* See README.md for the algorithms (thin-slice composition, append-fold
|
|
14
|
-
* provenance, live-range walking), the honesty model, serialization rules,
|
|
15
|
-
* and the evolution path.
|
|
16
|
-
*
|
|
17
|
-
* DAG position: memory ← slice (leaf-adjacent; imports memory/ only).
|
|
18
|
-
*/
|
|
19
|
-
export { arrayProvenance, elementProvenance } from './elementProvenance.js';
|
|
20
|
-
export { type ForwardSliceForKeyOptions, forwardSliceForKey } from './forwardSliceForKey.js';
|
|
21
|
-
export { keysReadFromExecutionTree, keysReadFromMap, resolveKeysReadSource } from './keysReadSources.js';
|
|
22
|
-
export { type KeyTimelineOptions, keyTimeline } from './keyTimeline.js';
|
|
23
|
-
export { formatForwardSlice, formatSlice, formatTimeline, forwardSliceToJSON, sliceToJSON } from './serialize.js';
|
|
24
|
-
export { type SliceForKeyOptions, normaliseStateKey, sliceForKey } from './sliceForKey.js';
|
|
25
|
-
export type { ArrayProvenance, AttributionBasis, ElementBirth, FedBasis, ForwardEdge, ForwardNode, ForwardRead, ForwardSlice, ForwardSliceJSON, HonestyNote, HonestyNoteCode, KeyMoment, KeysReadSource, KeyTimeline, MissingProvenanceReason, MissingSliceReason, ReadsCoverage, SliceJSON, StateKey, VariableSlice, } from './types.js';
|