footprintjs 9.34.0 → 9.35.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.
Files changed (37) hide show
  1. package/dist/advanced.js +41 -38
  2. package/dist/esm/advanced.d.ts +3 -0
  3. package/dist/esm/advanced.js +2 -1
  4. package/dist/esm/index.d.ts +5 -0
  5. package/dist/esm/index.js +1 -1
  6. package/dist/esm/lib/engine/handlers/SubflowExecutor.d.ts +0 -12
  7. package/dist/esm/lib/engine/handlers/SubflowExecutor.js +46 -84
  8. package/dist/esm/lib/engine/types.d.ts +7 -6
  9. package/dist/esm/lib/engine/types.js +1 -1
  10. package/dist/esm/lib/memory/StageContext.d.ts +49 -99
  11. package/dist/esm/lib/memory/StageContext.js +83 -136
  12. package/dist/esm/lib/memory/index.d.ts +2 -0
  13. package/dist/esm/lib/memory/index.js +2 -1
  14. package/dist/esm/lib/memory/runPolicy.d.ts +151 -0
  15. package/dist/esm/lib/memory/runPolicy.js +70 -0
  16. package/dist/esm/lib/runner/ExecutionRuntime.d.ts +45 -59
  17. package/dist/esm/lib/runner/ExecutionRuntime.js +80 -85
  18. package/dist/esm/lib/runner/FlowChartExecutor.d.ts +6 -90
  19. package/dist/esm/lib/runner/FlowChartExecutor.js +22 -65
  20. package/dist/index.js +1 -1
  21. package/dist/lib/engine/handlers/SubflowExecutor.js +47 -85
  22. package/dist/lib/engine/types.js +1 -1
  23. package/dist/lib/memory/StageContext.js +83 -136
  24. package/dist/lib/memory/index.js +5 -2
  25. package/dist/lib/memory/runPolicy.js +77 -0
  26. package/dist/lib/runner/ExecutionRuntime.js +80 -85
  27. package/dist/lib/runner/FlowChartExecutor.js +22 -65
  28. package/dist/types/advanced.d.ts +3 -0
  29. package/dist/types/index.d.ts +5 -0
  30. package/dist/types/lib/engine/handlers/SubflowExecutor.d.ts +0 -12
  31. package/dist/types/lib/engine/types.d.ts +7 -6
  32. package/dist/types/lib/memory/StageContext.d.ts +49 -99
  33. package/dist/types/lib/memory/index.d.ts +2 -0
  34. package/dist/types/lib/memory/runPolicy.d.ts +151 -0
  35. package/dist/types/lib/runner/ExecutionRuntime.d.ts +45 -59
  36. package/dist/types/lib/runner/FlowChartExecutor.d.ts +6 -90
  37. package/package.json +1 -1
@@ -11,6 +11,8 @@ export { StageContext } from './StageContext.js';
11
11
  export { TransactionBuffer } from './TransactionBuffer.js';
12
12
  export type { RedactionVerdict } from './redaction.js';
13
13
  export { RedactionRule, redactPatch } from './redaction.js';
14
+ export type { RunDials, RunPolicy } from './runPolicy.js';
15
+ export { DEFAULT_RUN_POLICY, runPolicy } from './runPolicy.js';
14
16
  export type { HonestyCode } from './honesty.js';
15
17
  export { HONESTY_CODES } from './honesty.js';
16
18
  export { LOG_PLACEHOLDER, SCOPE_PLACEHOLDER } from './placeholders.js';
@@ -12,6 +12,7 @@ export { SharedMemory } from './SharedMemory.js';
12
12
  export { StageContext } from './StageContext.js';
13
13
  export { TransactionBuffer } from './TransactionBuffer.js';
14
14
  export { RedactionRule, redactPatch } from './redaction.js';
15
+ export { DEFAULT_RUN_POLICY, runPolicy } from './runPolicy.js';
15
16
  export { HONESTY_CODES } from './honesty.js';
16
17
  // The two strings a redaction leaves where a value was (F4a; `REDACTED` is now `SCOPE_PLACEHOLDER`)
17
18
  export { LOG_PLACEHOLDER, SCOPE_PLACEHOLDER } from './placeholders.js';
@@ -20,4 +21,4 @@ export { READ_PREVIEW_LENGTH, SUMMARY_PREVIEW_LENGTH } from './types.js';
20
21
  export { UnknownVerbError } from './verbs.js';
21
22
  // Utilities
22
23
  export { applySmartMerge, deepSmartMerge, DELIM, getNestedValue, getRunAndGlobalPaths, normalisePath, pathSegments, setNestedValue, updateNestedValue, updateValue, } from './utils.js';
23
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL21lbW9yeS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwQkFBMEI7QUFDMUI7Ozs7O0dBS0c7QUFFSCxVQUFVO0FBQ1YsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDL0QsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDakQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBSTNELE9BQU8sRUFBRSxhQUFhLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFJNUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUU3QyxvR0FBb0c7QUFDcEcsT0FBTyxFQUFFLGVBQWUsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBbUJ2RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFekUsdUZBQXVGO0FBQ3ZGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUU5QyxZQUFZO0FBQ1osT0FBTyxFQUNMLGVBQWUsRUFDZixjQUFjLEVBQ2QsS0FBSyxFQUNMLGNBQWMsRUFDZCxvQkFBb0IsRUFDcEIsYUFBYSxFQUNiLFlBQVksRUFDWixjQUFjLEVBQ2QsaUJBQWlCLEVBQ2pCLFdBQVcsR0FDWixNQUFNLFlBQVksQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGlzdGFuYnVsIGlnbm9yZSBmaWxlICovXG4vKipcbiAqIG1lbW9yeS8g4oCUIEZvdW5kYXRpb24gbGlicmFyeSAoemVybyBleHRlcm5hbCBkZXBzKVxuICpcbiAqIFRyYW5zYWN0aW9uYWwgc3RhdGUgbWFuYWdlbWVudCB3aXRoIG5hbWVzcGFjZSBpc29sYXRpb24sXG4gKiBhdG9taWMgY29tbWl0cywgYW5kIGV2ZW50LXNvdXJjZWQgdGltZS10cmF2ZWwuXG4gKi9cblxuLy8gQ2xhc3Nlc1xuZXhwb3J0IHsgRGlhZ25vc3RpY0NvbGxlY3RvciB9IGZyb20gJy4vRGlhZ25vc3RpY0NvbGxlY3Rvci5qcyc7XG5leHBvcnQgeyBFdmVudExvZyB9IGZyb20gJy4vRXZlbnRMb2cuanMnO1xuZXhwb3J0IHsgU2hhcmVkTWVtb3J5IH0gZnJvbSAnLi9TaGFyZWRNZW1vcnkuanMnO1xuZXhwb3J0IHsgU3RhZ2VDb250ZXh0IH0gZnJvbSAnLi9TdGFnZUNvbnRleHQuanMnO1xuZXhwb3J0IHsgVHJhbnNhY3Rpb25CdWZmZXIgfSBmcm9tICcuL1RyYW5zYWN0aW9uQnVmZmVyLmpzJztcblxuLy8gUmVkYWN0aW9uIOKAlCB0aGUgT05FIG93bmVyIG9mIHRoZSB2ZXJkaWN0ICg5LjE5LjApXG5leHBvcnQgdHlwZSB7IFJlZGFjdGlvblZlcmRpY3QgfSBmcm9tICcuL3JlZGFjdGlvbi5qcyc7XG5leHBvcnQgeyBSZWRhY3Rpb25SdWxlLCByZWRhY3RQYXRjaCB9IGZyb20gJy4vcmVkYWN0aW9uLmpzJztcblxuLy8gSG9uZXN0eSDigJQgdGhlIE9ORSB2b2NhYnVsYXJ5IGZvciB3aGF0IGEgcmVhZGVyIGNhbm5vdCBzZWUgKEY0YSk6IGNvZGUg4oaSIHRoZSBvbmUgc2VudGVuY2VcbmV4cG9ydCB0eXBlIHsgSG9uZXN0eUNvZGUgfSBmcm9tICcuL2hvbmVzdHkuanMnO1xuZXhwb3J0IHsgSE9ORVNUWV9DT0RFUyB9IGZyb20gJy4vaG9uZXN0eS5qcyc7XG5cbi8vIFRoZSB0d28gc3RyaW5ncyBhIHJlZGFjdGlvbiBsZWF2ZXMgd2hlcmUgYSB2YWx1ZSB3YXMgKEY0YTsgYFJFREFDVEVEYCBpcyBub3cgYFNDT1BFX1BMQUNFSE9MREVSYClcbmV4cG9ydCB7IExPR19QTEFDRUhPTERFUiwgU0NPUEVfUExBQ0VIT0xERVIgfSBmcm9tICcuL3BsYWNlaG9sZGVycy5qcyc7XG5cbi8vIFR5cGVzXG5leHBvcnQgdHlwZSB7XG4gIENvbW1pdEJ1bmRsZSxcbiAgQ29tbWl0VmFsdWVzTW9kZSxcbiAgRmxvd0NvbnRyb2xUeXBlLFxuICBGbG93TWVzc2FnZSxcbiAgTWVtb3J5UGF0Y2gsXG4gIFJlYWRTdW1tYXJ5TWFya2VyLFxuICBSZWFkVHJhY2tpbmdNb2RlLFxuICBSZXRlbnRpb25Qb2xpY3ksXG4gIFNjb3BlRmFjdG9yeSxcbiAgU3RhZ2VTbmFwc2hvdCxcbiAgVHJhY2VFbnRyeSxcbiAgVW50cmFja2VkU291cmNlLFxuICBXcml0ZVN1bW1hcnlNYXJrZXIsXG4gIFdyaXRlVHJhY2tpbmdNb2RlLFxufSBmcm9tICcuL3R5cGVzLmpzJztcbmV4cG9ydCB7IFJFQURfUFJFVklFV19MRU5HVEgsIFNVTU1BUllfUFJFVklFV19MRU5HVEggfSBmcm9tICcuL3R5cGVzLmpzJztcblxuLy8gVGhlIHZlcmIgbGF3J3MgcmVmdXNhbDogYSBjb21taXQgcm93IHdob3NlIHZlcmIgaXMgbm90IHNldCB8IG1lcmdlIHwgYXBwZW5kIHwgZGVsZXRlXG5leHBvcnQgeyBVbmtub3duVmVyYkVycm9yIH0gZnJvbSAnLi92ZXJicy5qcyc7XG5cbi8vIFV0aWxpdGllc1xuZXhwb3J0IHtcbiAgYXBwbHlTbWFydE1lcmdlLFxuICBkZWVwU21hcnRNZXJnZSxcbiAgREVMSU0sXG4gIGdldE5lc3RlZFZhbHVlLFxuICBnZXRSdW5BbmRHbG9iYWxQYXRocyxcbiAgbm9ybWFsaXNlUGF0aCxcbiAgcGF0aFNlZ21lbnRzLFxuICBzZXROZXN0ZWRWYWx1ZSxcbiAgdXBkYXRlTmVzdGVkVmFsdWUsXG4gIHVwZGF0ZVZhbHVlLFxufSBmcm9tICcuL3V0aWxzLmpzJztcbiJdfQ==
24
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL21lbW9yeS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwQkFBMEI7QUFDMUI7Ozs7O0dBS0c7QUFFSCxVQUFVO0FBQ1YsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDL0QsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDakQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBSTNELE9BQU8sRUFBRSxhQUFhLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFJNUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBSS9ELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFN0Msb0dBQW9HO0FBQ3BHLE9BQU8sRUFBRSxlQUFlLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQW1CdkUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLHNCQUFzQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRXpFLHVGQUF1RjtBQUN2RixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFOUMsWUFBWTtBQUNaLE9BQU8sRUFDTCxlQUFlLEVBQ2YsY0FBYyxFQUNkLEtBQUssRUFDTCxjQUFjLEVBQ2Qsb0JBQW9CLEVBQ3BCLGFBQWEsRUFDYixZQUFZLEVBQ1osY0FBYyxFQUNkLGlCQUFpQixFQUNqQixXQUFXLEdBQ1osTUFBTSxZQUFZLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBpc3RhbmJ1bCBpZ25vcmUgZmlsZSAqL1xuLyoqXG4gKiBtZW1vcnkvIOKAlCBGb3VuZGF0aW9uIGxpYnJhcnkgKHplcm8gZXh0ZXJuYWwgZGVwcylcbiAqXG4gKiBUcmFuc2FjdGlvbmFsIHN0YXRlIG1hbmFnZW1lbnQgd2l0aCBuYW1lc3BhY2UgaXNvbGF0aW9uLFxuICogYXRvbWljIGNvbW1pdHMsIGFuZCBldmVudC1zb3VyY2VkIHRpbWUtdHJhdmVsLlxuICovXG5cbi8vIENsYXNzZXNcbmV4cG9ydCB7IERpYWdub3N0aWNDb2xsZWN0b3IgfSBmcm9tICcuL0RpYWdub3N0aWNDb2xsZWN0b3IuanMnO1xuZXhwb3J0IHsgRXZlbnRMb2cgfSBmcm9tICcuL0V2ZW50TG9nLmpzJztcbmV4cG9ydCB7IFNoYXJlZE1lbW9yeSB9IGZyb20gJy4vU2hhcmVkTWVtb3J5LmpzJztcbmV4cG9ydCB7IFN0YWdlQ29udGV4dCB9IGZyb20gJy4vU3RhZ2VDb250ZXh0LmpzJztcbmV4cG9ydCB7IFRyYW5zYWN0aW9uQnVmZmVyIH0gZnJvbSAnLi9UcmFuc2FjdGlvbkJ1ZmZlci5qcyc7XG5cbi8vIFJlZGFjdGlvbiDigJQgdGhlIE9ORSBvd25lciBvZiB0aGUgdmVyZGljdCAoOS4xOS4wKVxuZXhwb3J0IHR5cGUgeyBSZWRhY3Rpb25WZXJkaWN0IH0gZnJvbSAnLi9yZWRhY3Rpb24uanMnO1xuZXhwb3J0IHsgUmVkYWN0aW9uUnVsZSwgcmVkYWN0UGF0Y2ggfSBmcm9tICcuL3JlZGFjdGlvbi5qcyc7XG5cbi8vIFRoZSBydW4ncyBwb2xpY3kg4oCUIHRoZSBmb3VyIGRpYWxzLCB0aGUgcnVsZSwgdGhlIG1pcnJvciBmbGFnIGFzIE9ORSBvYmplY3QgKEY1KVxuZXhwb3J0IHR5cGUgeyBSdW5EaWFscywgUnVuUG9saWN5IH0gZnJvbSAnLi9ydW5Qb2xpY3kuanMnO1xuZXhwb3J0IHsgREVGQVVMVF9SVU5fUE9MSUNZLCBydW5Qb2xpY3kgfSBmcm9tICcuL3J1blBvbGljeS5qcyc7XG5cbi8vIEhvbmVzdHkg4oCUIHRoZSBPTkUgdm9jYWJ1bGFyeSBmb3Igd2hhdCBhIHJlYWRlciBjYW5ub3Qgc2VlIChGNGEpOiBjb2RlIOKGkiB0aGUgb25lIHNlbnRlbmNlXG5leHBvcnQgdHlwZSB7IEhvbmVzdHlDb2RlIH0gZnJvbSAnLi9ob25lc3R5LmpzJztcbmV4cG9ydCB7IEhPTkVTVFlfQ09ERVMgfSBmcm9tICcuL2hvbmVzdHkuanMnO1xuXG4vLyBUaGUgdHdvIHN0cmluZ3MgYSByZWRhY3Rpb24gbGVhdmVzIHdoZXJlIGEgdmFsdWUgd2FzIChGNGE7IGBSRURBQ1RFRGAgaXMgbm93IGBTQ09QRV9QTEFDRUhPTERFUmApXG5leHBvcnQgeyBMT0dfUExBQ0VIT0xERVIsIFNDT1BFX1BMQUNFSE9MREVSIH0gZnJvbSAnLi9wbGFjZWhvbGRlcnMuanMnO1xuXG4vLyBUeXBlc1xuZXhwb3J0IHR5cGUge1xuICBDb21taXRCdW5kbGUsXG4gIENvbW1pdFZhbHVlc01vZGUsXG4gIEZsb3dDb250cm9sVHlwZSxcbiAgRmxvd01lc3NhZ2UsXG4gIE1lbW9yeVBhdGNoLFxuICBSZWFkU3VtbWFyeU1hcmtlcixcbiAgUmVhZFRyYWNraW5nTW9kZSxcbiAgUmV0ZW50aW9uUG9saWN5LFxuICBTY29wZUZhY3RvcnksXG4gIFN0YWdlU25hcHNob3QsXG4gIFRyYWNlRW50cnksXG4gIFVudHJhY2tlZFNvdXJjZSxcbiAgV3JpdGVTdW1tYXJ5TWFya2VyLFxuICBXcml0ZVRyYWNraW5nTW9kZSxcbn0gZnJvbSAnLi90eXBlcy5qcyc7XG5leHBvcnQgeyBSRUFEX1BSRVZJRVdfTEVOR1RILCBTVU1NQVJZX1BSRVZJRVdfTEVOR1RIIH0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbi8vIFRoZSB2ZXJiIGxhdydzIHJlZnVzYWw6IGEgY29tbWl0IHJvdyB3aG9zZSB2ZXJiIGlzIG5vdCBzZXQgfCBtZXJnZSB8IGFwcGVuZCB8IGRlbGV0ZVxuZXhwb3J0IHsgVW5rbm93blZlcmJFcnJvciB9IGZyb20gJy4vdmVyYnMuanMnO1xuXG4vLyBVdGlsaXRpZXNcbmV4cG9ydCB7XG4gIGFwcGx5U21hcnRNZXJnZSxcbiAgZGVlcFNtYXJ0TWVyZ2UsXG4gIERFTElNLFxuICBnZXROZXN0ZWRWYWx1ZSxcbiAgZ2V0UnVuQW5kR2xvYmFsUGF0aHMsXG4gIG5vcm1hbGlzZVBhdGgsXG4gIHBhdGhTZWdtZW50cyxcbiAgc2V0TmVzdGVkVmFsdWUsXG4gIHVwZGF0ZU5lc3RlZFZhbHVlLFxuICB1cGRhdGVWYWx1ZSxcbn0gZnJvbSAnLi91dGlscy5qcyc7XG4iXX0=
@@ -0,0 +1,151 @@
1
+ /**
2
+ * RunPolicy — what a run retains, encodes and scrubs, as ONE immutable object (F5).
3
+ *
4
+ * WHY. A run carries six settings that every stage frame must agree on: the four
5
+ * observability dials (`readTracking`, `writeTracking`, `commitValues`, `writeProvenance`),
6
+ * the redaction rule, and whether a redacted mirror is kept. Until 9.34.0 each one was
7
+ * copied field by field down three separate paths — `ExecutionRuntime.use*` on the root,
8
+ * `StageContext.createNext`/`createChild` (six assignments each), and a duck-typed push per
9
+ * dial in `SubflowExecutor` — so a new dial meant six edits, and a missed one ran a subflow
10
+ * on the default silently. Now the executor builds ONE policy per run (and per resume), the
11
+ * runtime installs it on its root frame, and every frame holds it BY REFERENCE: a child, a
12
+ * continuation and a subflow's root (its seed frame included) all point at the same object.
13
+ * The borrowed idea is Go's `context.Context` / OpenTelemetry's `Context`: an immutable value
14
+ * handed down, never copied apart.
15
+ *
16
+ * ADDING A DIAL is two files: a field + its default here ({@link RunDials},
17
+ * {@link DIAL_DEFAULTS}), and the frame code that reads `policy.<dial>` (`StageContext`). The
18
+ * executor's options inherit {@link RunDials}, picks them with {@link pickDials}, and every
19
+ * propagation path carries the whole object — none of them names a dial.
20
+ *
21
+ * ```ts
22
+ * const policy = runPolicy({ commitValues: 'delta' }, rule, true);
23
+ * policy.readTracking; // 'full' — an absent dial is its default
24
+ * Object.isFrozen(policy); // true — a frame can never edit what its siblings share
25
+ * ```
26
+ *
27
+ * The RULE inside is shared too, and is itself stateful by design (per-call `setValue(k, v,
28
+ * true)` marks a key on it for the rest of the run); the policy freezes which rule, not the
29
+ * rule's marks. The mirror STORE is not policy — each runtime (a subflow has its own) keeps
30
+ * its own store when `mirror` is set.
31
+ */
32
+ import type { RedactionRule } from './redaction.js';
33
+ import type { CommitValuesMode, ReadTrackingMode, WriteProvenanceMode, WriteTrackingMode } from './types.js';
34
+ /**
35
+ * The four observability dials as an executor takes them — every field optional, an absent
36
+ * one is its default. `FlowChartExecutorOptions` extends this interface.
37
+ */
38
+ export interface RunDials {
39
+ /**
40
+ * Policy for `StageSnapshot.stageReads` (#14). Default `'full'` — every
41
+ * tracked read `structuredClone`s the value into the stage's read view
42
+ * (the historical behavior; what lens/agentfootprint snapshots show).
43
+ * `'summary'` records a cheap type/size/preview marker per read; `'off'`
44
+ * records nothing — zero per-read clone cost (reads of large values become
45
+ * ~free). Narrative and `ScopeRecorder.onRead` are identical in every mode.
46
+ * Caveat: under `'off'` a stage's snapshot is indistinguishable from one
47
+ * that read nothing — auditing consumers that need "did it read?" without
48
+ * the value cost should prefer `'summary'`.
49
+ * Equivalent to calling `executor.setReadTracking(mode)` before `run()`.
50
+ */
51
+ readTracking?: ReadTrackingMode;
52
+ /**
53
+ * Policy for `StageSnapshot.stageWrites` (#13c-A) — the sibling of
54
+ * {@link readTracking}; the two dials are independent. Default `'full'` —
55
+ * every tracked write `structuredClone`s the value into the stage's write
56
+ * view (the historical behavior). `'summary'` records a cheap
57
+ * `WriteSummaryMarker` (type/size/preview) per write; `'off'` records
58
+ * nothing — `stageWrites` is absent from the snapshot.
59
+ *
60
+ * Observable consequences — what the policy DOES govern:
61
+ * - `StageSnapshot.stageWrites` (markers under `'summary'`, absent under
62
+ * `'off'`).
63
+ * - The commit observer payload: `ScopeRecorder.onCommit(mutations)`
64
+ * receives the retained `_stageWrites` entries, so it carries the same
65
+ * markers under `'summary'` and an empty mutations bag under `'off'` —
66
+ * deferred/observer consumers see exactly what retention stored.
67
+ *
68
+ * What it does NOT govern:
69
+ * - The writes themselves: shared state, the transaction buffer, and the
70
+ * COMMIT LOG are identical in every mode (commitLog values keep their
71
+ * full payloads — the lossless linear-cost fix for those is the
72
+ * {@link commitValues} dial, #13c-B).
73
+ * - Per-op `ScopeRecorder.onWrite` events — they fire with live values
74
+ * regardless (delivery tier, RFC-001's concern), so narrative output is
75
+ * identical in every mode.
76
+ * - Redaction: a policy/per-call-redacted write stores `'[REDACTED]'`
77
+ * under `'full'` AND `'summary'` (redaction takes precedence over the
78
+ * dial; a marker would leak size/preview), and nothing under `'off'`.
79
+ *
80
+ * Caveat: under `'off'` a stage's SNAPSHOT is indistinguishable from one
81
+ * that wrote nothing — but unlike `readTracking: 'off'`, the commit log
82
+ * still records every net change, so "did it write?" stays answerable.
83
+ * Equivalent to calling `executor.setWriteTracking(mode)` before `run()`.
84
+ */
85
+ writeTracking?: WriteTrackingMode;
86
+ /**
87
+ * Encoding policy for COMMIT LOG values (#13c-B) — the third dial of the
88
+ * family, and unlike its siblings it is **lossless in both modes** (it
89
+ * changes the log's encoding, never its information).
90
+ *
91
+ * - `'full'` (default) — every surviving `set` path stores the full final
92
+ * value; byte-identical to the historical behavior.
93
+ * - `'delta'` — array net-changes that are "base plus a tail" commit as an
94
+ * `append` trace verb storing ONLY the tail (the growing-history commit
95
+ * log becomes linear instead of O(N²) retained); `deleteValue()` commits
96
+ * as a real `delete` verb (replay removes the key instead of leaving
97
+ * `key: undefined`); bundles carry exactly ONE trace entry per surviving
98
+ * path. Replay (the one verb law — live state, `materialise()`, the
99
+ * redacted mirror, `stateAt`) reconstructs every step's full state
100
+ * exactly.
101
+ *
102
+ * Consumers that read `bundle.overwrite[key]` as "the full value written"
103
+ * must switch to `commitValueAt(commitLog, idx, key)` from
104
+ * `footprintjs/trace` — under `'delta'` that value is verb-qualified (an
105
+ * `append` bundle holds only the tail). Path-tier consumers
106
+ * (`findLastWriter`, `causalChain`, narrative, lens highlights) are
107
+ * unaffected. The active mode is surfaced as
108
+ * `getSnapshot().commitValues`.
109
+ *
110
+ * Honest cost note: append detection is new wall work — an O(|base array|)
111
+ * structural prefix compare per array-set path per commit. On a hit the
112
+ * commit gets cheaper in both wall and heap; on a miss (prefix diverges)
113
+ * it pays compare + full clone. `'full'` pays zero.
114
+ * Equivalent to calling `executor.setCommitValues(mode)` before `run()`.
115
+ */
116
+ commitValues?: CommitValuesMode;
117
+ /**
118
+ * Per-write read provenance (#P1) — the fourth dial of the family. Default
119
+ * `'off'`: zero cost, byte-identical commit logs. `'reads-prefix'`: every
120
+ * committed `TraceEntry` carries `readKeys` — the keys tracked-read BEFORE
121
+ * that write — enabling per-write causal attribution (`causalChain`'s
122
+ * `edgeAttribution: 'per-write'` and variable slices). Cost: one small
123
+ * array copy per write. Snapshot discriminant:
124
+ * `getSnapshot().writeProvenance`.
125
+ */
126
+ writeProvenance?: WriteProvenanceMode;
127
+ }
128
+ /** The run's policy: every dial resolved, plus the redaction rule and the mirror flag. Frozen. */
129
+ export interface RunPolicy extends Readonly<Required<RunDials>> {
130
+ /** The run's redaction rule — the ONE owner of the verdict (`redaction.ts`). Absent on bare frames. */
131
+ readonly redaction?: RedactionRule;
132
+ /** Keep a redacted mirror of the heap (a run with a redaction policy). Each runtime owns its own store. */
133
+ readonly mirror: boolean;
134
+ }
135
+ /** Each dial's default — the value a run gets when the option is absent. The dial list IS these keys. */
136
+ export declare const DIAL_DEFAULTS: Readonly<Required<RunDials>>;
137
+ /** Every default, no rule, no mirror — what a bare frame (a unit test's `new StageContext`) runs under. */
138
+ export declare const DEFAULT_RUN_POLICY: RunPolicy;
139
+ /** Build a run's policy: absent dials take their default; the result is frozen. */
140
+ export declare function runPolicy(dials?: RunDials, redaction?: RedactionRule, mirror?: boolean): RunPolicy;
141
+ /** The dials set on `source` (an options object, say) — and nothing else from it. */
142
+ export declare function pickDials(source: RunDials): RunDials;
143
+ /** The same policy under another rule — a NEW frozen object; the old one is never edited. */
144
+ export declare function withRedaction(policy: RunPolicy, redaction: RedactionRule): RunPolicy;
145
+ /**
146
+ * The same policy with some settings changed — a NEW frozen object; the old one is never
147
+ * edited. What the deprecated per-dial setters (`StageContext.useReadTracking`,
148
+ * `ExecutionRuntime.useCommitValues`, …) delegate to: they swap in a derived policy, so no
149
+ * mutable dial field exists anywhere.
150
+ */
151
+ export declare function derivePolicy(policy: RunPolicy, patch: Partial<RunPolicy>): RunPolicy;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * RunPolicy — what a run retains, encodes and scrubs, as ONE immutable object (F5).
3
+ *
4
+ * WHY. A run carries six settings that every stage frame must agree on: the four
5
+ * observability dials (`readTracking`, `writeTracking`, `commitValues`, `writeProvenance`),
6
+ * the redaction rule, and whether a redacted mirror is kept. Until 9.34.0 each one was
7
+ * copied field by field down three separate paths — `ExecutionRuntime.use*` on the root,
8
+ * `StageContext.createNext`/`createChild` (six assignments each), and a duck-typed push per
9
+ * dial in `SubflowExecutor` — so a new dial meant six edits, and a missed one ran a subflow
10
+ * on the default silently. Now the executor builds ONE policy per run (and per resume), the
11
+ * runtime installs it on its root frame, and every frame holds it BY REFERENCE: a child, a
12
+ * continuation and a subflow's root (its seed frame included) all point at the same object.
13
+ * The borrowed idea is Go's `context.Context` / OpenTelemetry's `Context`: an immutable value
14
+ * handed down, never copied apart.
15
+ *
16
+ * ADDING A DIAL is two files: a field + its default here ({@link RunDials},
17
+ * {@link DIAL_DEFAULTS}), and the frame code that reads `policy.<dial>` (`StageContext`). The
18
+ * executor's options inherit {@link RunDials}, picks them with {@link pickDials}, and every
19
+ * propagation path carries the whole object — none of them names a dial.
20
+ *
21
+ * ```ts
22
+ * const policy = runPolicy({ commitValues: 'delta' }, rule, true);
23
+ * policy.readTracking; // 'full' — an absent dial is its default
24
+ * Object.isFrozen(policy); // true — a frame can never edit what its siblings share
25
+ * ```
26
+ *
27
+ * The RULE inside is shared too, and is itself stateful by design (per-call `setValue(k, v,
28
+ * true)` marks a key on it for the rest of the run); the policy freezes which rule, not the
29
+ * rule's marks. The mirror STORE is not policy — each runtime (a subflow has its own) keeps
30
+ * its own store when `mirror` is set.
31
+ */
32
+ /** Each dial's default — the value a run gets when the option is absent. The dial list IS these keys. */
33
+ export const DIAL_DEFAULTS = Object.freeze({
34
+ readTracking: 'full',
35
+ writeTracking: 'full',
36
+ commitValues: 'full',
37
+ writeProvenance: 'off',
38
+ });
39
+ const DIAL_NAMES = Object.keys(DIAL_DEFAULTS);
40
+ /** Every default, no rule, no mirror — what a bare frame (a unit test's `new StageContext`) runs under. */
41
+ export const DEFAULT_RUN_POLICY = Object.freeze({ ...DIAL_DEFAULTS, mirror: false });
42
+ /** Build a run's policy: absent dials take their default; the result is frozen. */
43
+ export function runPolicy(dials = {}, redaction, mirror = false) {
44
+ const resolved = { ...DIAL_DEFAULTS, ...pickDials(dials), mirror };
45
+ if (redaction)
46
+ resolved.redaction = redaction;
47
+ return Object.freeze(resolved);
48
+ }
49
+ /** The dials set on `source` (an options object, say) — and nothing else from it. */
50
+ export function pickDials(source) {
51
+ const dials = {};
52
+ for (const name of DIAL_NAMES)
53
+ if (source[name] !== undefined)
54
+ dials[name] = source[name];
55
+ return dials;
56
+ }
57
+ /** The same policy under another rule — a NEW frozen object; the old one is never edited. */
58
+ export function withRedaction(policy, redaction) {
59
+ return derivePolicy(policy, { redaction });
60
+ }
61
+ /**
62
+ * The same policy with some settings changed — a NEW frozen object; the old one is never
63
+ * edited. What the deprecated per-dial setters (`StageContext.useReadTracking`,
64
+ * `ExecutionRuntime.useCommitValues`, …) delegate to: they swap in a derived policy, so no
65
+ * mutable dial field exists anywhere.
66
+ */
67
+ export function derivePolicy(policy, patch) {
68
+ return Object.freeze({ ...policy, ...patch });
69
+ }
70
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuUG9saWN5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9tZW1vcnkvcnVuUG9saWN5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4Qkc7QUErR0gseUdBQXlHO0FBQ3pHLE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBaUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUN2RSxZQUFZLEVBQUUsTUFBTTtJQUNwQixhQUFhLEVBQUUsTUFBTTtJQUNyQixZQUFZLEVBQUUsTUFBTTtJQUNwQixlQUFlLEVBQUUsS0FBSztDQUN2QixDQUFDLENBQUM7QUFFSCxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBMEIsQ0FBQztBQUV2RSwyR0FBMkc7QUFDM0csTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQWMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsYUFBYSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0FBRWhHLG1GQUFtRjtBQUNuRixNQUFNLFVBQVUsU0FBUyxDQUFDLFFBQWtCLEVBQUUsRUFBRSxTQUF5QixFQUFFLE1BQU0sR0FBRyxLQUFLO0lBQ3ZGLE1BQU0sUUFBUSxHQUE0QixFQUFFLEdBQUcsYUFBYSxFQUFFLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDO0lBQzVGLElBQUksU0FBUztRQUFFLFFBQVEsQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO0lBQzlDLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQXlCLENBQUM7QUFDekQsQ0FBQztBQUVELHFGQUFxRjtBQUNyRixNQUFNLFVBQVUsU0FBUyxDQUFDLE1BQWdCO0lBQ3hDLE1BQU0sS0FBSyxHQUE0QixFQUFFLENBQUM7SUFDMUMsS0FBSyxNQUFNLElBQUksSUFBSSxVQUFVO1FBQUUsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssU0FBUztZQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDMUYsT0FBTyxLQUFpQixDQUFDO0FBQzNCLENBQUM7QUFFRCw2RkFBNkY7QUFDN0YsTUFBTSxVQUFVLGFBQWEsQ0FBQyxNQUFpQixFQUFFLFNBQXdCO0lBQ3ZFLE9BQU8sWUFBWSxDQUFDLE1BQU0sRUFBRSxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7QUFDN0MsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLFlBQVksQ0FBQyxNQUFpQixFQUFFLEtBQXlCO0lBQ3ZFLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsTUFBTSxFQUFFLEdBQUcsS0FBSyxFQUFFLENBQUMsQ0FBQztBQUNoRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBSdW5Qb2xpY3kg4oCUIHdoYXQgYSBydW4gcmV0YWlucywgZW5jb2RlcyBhbmQgc2NydWJzLCBhcyBPTkUgaW1tdXRhYmxlIG9iamVjdCAoRjUpLlxuICpcbiAqIFdIWS4gQSBydW4gY2FycmllcyBzaXggc2V0dGluZ3MgdGhhdCBldmVyeSBzdGFnZSBmcmFtZSBtdXN0IGFncmVlIG9uOiB0aGUgZm91clxuICogb2JzZXJ2YWJpbGl0eSBkaWFscyAoYHJlYWRUcmFja2luZ2AsIGB3cml0ZVRyYWNraW5nYCwgYGNvbW1pdFZhbHVlc2AsIGB3cml0ZVByb3ZlbmFuY2VgKSxcbiAqIHRoZSByZWRhY3Rpb24gcnVsZSwgYW5kIHdoZXRoZXIgYSByZWRhY3RlZCBtaXJyb3IgaXMga2VwdC4gVW50aWwgOS4zNC4wIGVhY2ggb25lIHdhc1xuICogY29waWVkIGZpZWxkIGJ5IGZpZWxkIGRvd24gdGhyZWUgc2VwYXJhdGUgcGF0aHMg4oCUIGBFeGVjdXRpb25SdW50aW1lLnVzZSpgIG9uIHRoZSByb290LFxuICogYFN0YWdlQ29udGV4dC5jcmVhdGVOZXh0YC9gY3JlYXRlQ2hpbGRgIChzaXggYXNzaWdubWVudHMgZWFjaCksIGFuZCBhIGR1Y2stdHlwZWQgcHVzaCBwZXJcbiAqIGRpYWwgaW4gYFN1YmZsb3dFeGVjdXRvcmAg4oCUIHNvIGEgbmV3IGRpYWwgbWVhbnQgc2l4IGVkaXRzLCBhbmQgYSBtaXNzZWQgb25lIHJhbiBhIHN1YmZsb3dcbiAqIG9uIHRoZSBkZWZhdWx0IHNpbGVudGx5LiBOb3cgdGhlIGV4ZWN1dG9yIGJ1aWxkcyBPTkUgcG9saWN5IHBlciBydW4gKGFuZCBwZXIgcmVzdW1lKSwgdGhlXG4gKiBydW50aW1lIGluc3RhbGxzIGl0IG9uIGl0cyByb290IGZyYW1lLCBhbmQgZXZlcnkgZnJhbWUgaG9sZHMgaXQgQlkgUkVGRVJFTkNFOiBhIGNoaWxkLCBhXG4gKiBjb250aW51YXRpb24gYW5kIGEgc3ViZmxvdydzIHJvb3QgKGl0cyBzZWVkIGZyYW1lIGluY2x1ZGVkKSBhbGwgcG9pbnQgYXQgdGhlIHNhbWUgb2JqZWN0LlxuICogVGhlIGJvcnJvd2VkIGlkZWEgaXMgR28ncyBgY29udGV4dC5Db250ZXh0YCAvIE9wZW5UZWxlbWV0cnkncyBgQ29udGV4dGA6IGFuIGltbXV0YWJsZSB2YWx1ZVxuICogaGFuZGVkIGRvd24sIG5ldmVyIGNvcGllZCBhcGFydC5cbiAqXG4gKiBBRERJTkcgQSBESUFMIGlzIHR3byBmaWxlczogYSBmaWVsZCArIGl0cyBkZWZhdWx0IGhlcmUgKHtAbGluayBSdW5EaWFsc30sXG4gKiB7QGxpbmsgRElBTF9ERUZBVUxUU30pLCBhbmQgdGhlIGZyYW1lIGNvZGUgdGhhdCByZWFkcyBgcG9saWN5LjxkaWFsPmAgKGBTdGFnZUNvbnRleHRgKS4gVGhlXG4gKiBleGVjdXRvcidzIG9wdGlvbnMgaW5oZXJpdCB7QGxpbmsgUnVuRGlhbHN9LCBwaWNrcyB0aGVtIHdpdGgge0BsaW5rIHBpY2tEaWFsc30sIGFuZCBldmVyeVxuICogcHJvcGFnYXRpb24gcGF0aCBjYXJyaWVzIHRoZSB3aG9sZSBvYmplY3Qg4oCUIG5vbmUgb2YgdGhlbSBuYW1lcyBhIGRpYWwuXG4gKlxuICogYGBgdHNcbiAqIGNvbnN0IHBvbGljeSA9IHJ1blBvbGljeSh7IGNvbW1pdFZhbHVlczogJ2RlbHRhJyB9LCBydWxlLCB0cnVlKTtcbiAqIHBvbGljeS5yZWFkVHJhY2tpbmc7IC8vICdmdWxsJyDigJQgYW4gYWJzZW50IGRpYWwgaXMgaXRzIGRlZmF1bHRcbiAqIE9iamVjdC5pc0Zyb3plbihwb2xpY3kpOyAvLyB0cnVlIOKAlCBhIGZyYW1lIGNhbiBuZXZlciBlZGl0IHdoYXQgaXRzIHNpYmxpbmdzIHNoYXJlXG4gKiBgYGBcbiAqXG4gKiBUaGUgUlVMRSBpbnNpZGUgaXMgc2hhcmVkIHRvbywgYW5kIGlzIGl0c2VsZiBzdGF0ZWZ1bCBieSBkZXNpZ24gKHBlci1jYWxsIGBzZXRWYWx1ZShrLCB2LFxuICogdHJ1ZSlgIG1hcmtzIGEga2V5IG9uIGl0IGZvciB0aGUgcmVzdCBvZiB0aGUgcnVuKTsgdGhlIHBvbGljeSBmcmVlemVzIHdoaWNoIHJ1bGUsIG5vdCB0aGVcbiAqIHJ1bGUncyBtYXJrcy4gVGhlIG1pcnJvciBTVE9SRSBpcyBub3QgcG9saWN5IOKAlCBlYWNoIHJ1bnRpbWUgKGEgc3ViZmxvdyBoYXMgaXRzIG93bikga2VlcHNcbiAqIGl0cyBvd24gc3RvcmUgd2hlbiBgbWlycm9yYCBpcyBzZXQuXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBSZWRhY3Rpb25SdWxlIH0gZnJvbSAnLi9yZWRhY3Rpb24uanMnO1xuaW1wb3J0IHR5cGUgeyBDb21taXRWYWx1ZXNNb2RlLCBSZWFkVHJhY2tpbmdNb2RlLCBXcml0ZVByb3ZlbmFuY2VNb2RlLCBXcml0ZVRyYWNraW5nTW9kZSB9IGZyb20gJy4vdHlwZXMuanMnO1xuXG4vKipcbiAqIFRoZSBmb3VyIG9ic2VydmFiaWxpdHkgZGlhbHMgYXMgYW4gZXhlY3V0b3IgdGFrZXMgdGhlbSDigJQgZXZlcnkgZmllbGQgb3B0aW9uYWwsIGFuIGFic2VudFxuICogb25lIGlzIGl0cyBkZWZhdWx0LiBgRmxvd0NoYXJ0RXhlY3V0b3JPcHRpb25zYCBleHRlbmRzIHRoaXMgaW50ZXJmYWNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJ1bkRpYWxzIHtcbiAgLyoqXG4gICAqIFBvbGljeSBmb3IgYFN0YWdlU25hcHNob3Quc3RhZ2VSZWFkc2AgKCMxNCkuIERlZmF1bHQgYCdmdWxsJ2Ag4oCUIGV2ZXJ5XG4gICAqIHRyYWNrZWQgcmVhZCBgc3RydWN0dXJlZENsb25lYHMgdGhlIHZhbHVlIGludG8gdGhlIHN0YWdlJ3MgcmVhZCB2aWV3XG4gICAqICh0aGUgaGlzdG9yaWNhbCBiZWhhdmlvcjsgd2hhdCBsZW5zL2FnZW50Zm9vdHByaW50IHNuYXBzaG90cyBzaG93KS5cbiAgICogYCdzdW1tYXJ5J2AgcmVjb3JkcyBhIGNoZWFwIHR5cGUvc2l6ZS9wcmV2aWV3IG1hcmtlciBwZXIgcmVhZDsgYCdvZmYnYFxuICAgKiByZWNvcmRzIG5vdGhpbmcg4oCUIHplcm8gcGVyLXJlYWQgY2xvbmUgY29zdCAocmVhZHMgb2YgbGFyZ2UgdmFsdWVzIGJlY29tZVxuICAgKiB+ZnJlZSkuIE5hcnJhdGl2ZSBhbmQgYFNjb3BlUmVjb3JkZXIub25SZWFkYCBhcmUgaWRlbnRpY2FsIGluIGV2ZXJ5IG1vZGUuXG4gICAqIENhdmVhdDogdW5kZXIgYCdvZmYnYCBhIHN0YWdlJ3Mgc25hcHNob3QgaXMgaW5kaXN0aW5ndWlzaGFibGUgZnJvbSBvbmVcbiAgICogdGhhdCByZWFkIG5vdGhpbmcg4oCUIGF1ZGl0aW5nIGNvbnN1bWVycyB0aGF0IG5lZWQgXCJkaWQgaXQgcmVhZD9cIiB3aXRob3V0XG4gICAqIHRoZSB2YWx1ZSBjb3N0IHNob3VsZCBwcmVmZXIgYCdzdW1tYXJ5J2AuXG4gICAqIEVxdWl2YWxlbnQgdG8gY2FsbGluZyBgZXhlY3V0b3Iuc2V0UmVhZFRyYWNraW5nKG1vZGUpYCBiZWZvcmUgYHJ1bigpYC5cbiAgICovXG4gIHJlYWRUcmFja2luZz86IFJlYWRUcmFja2luZ01vZGU7XG5cbiAgLyoqXG4gICAqIFBvbGljeSBmb3IgYFN0YWdlU25hcHNob3Quc3RhZ2VXcml0ZXNgICgjMTNjLUEpIOKAlCB0aGUgc2libGluZyBvZlxuICAgKiB7QGxpbmsgcmVhZFRyYWNraW5nfTsgdGhlIHR3byBkaWFscyBhcmUgaW5kZXBlbmRlbnQuIERlZmF1bHQgYCdmdWxsJ2Ag4oCUXG4gICAqIGV2ZXJ5IHRyYWNrZWQgd3JpdGUgYHN0cnVjdHVyZWRDbG9uZWBzIHRoZSB2YWx1ZSBpbnRvIHRoZSBzdGFnZSdzIHdyaXRlXG4gICAqIHZpZXcgKHRoZSBoaXN0b3JpY2FsIGJlaGF2aW9yKS4gYCdzdW1tYXJ5J2AgcmVjb3JkcyBhIGNoZWFwXG4gICAqIGBXcml0ZVN1bW1hcnlNYXJrZXJgICh0eXBlL3NpemUvcHJldmlldykgcGVyIHdyaXRlOyBgJ29mZidgIHJlY29yZHNcbiAgICogbm90aGluZyDigJQgYHN0YWdlV3JpdGVzYCBpcyBhYnNlbnQgZnJvbSB0aGUgc25hcHNob3QuXG4gICAqXG4gICAqIE9ic2VydmFibGUgY29uc2VxdWVuY2VzIOKAlCB3aGF0IHRoZSBwb2xpY3kgRE9FUyBnb3Zlcm46XG4gICAqIC0gYFN0YWdlU25hcHNob3Quc3RhZ2VXcml0ZXNgIChtYXJrZXJzIHVuZGVyIGAnc3VtbWFyeSdgLCBhYnNlbnQgdW5kZXJcbiAgICogICBgJ29mZidgKS5cbiAgICogLSBUaGUgY29tbWl0IG9ic2VydmVyIHBheWxvYWQ6IGBTY29wZVJlY29yZGVyLm9uQ29tbWl0KG11dGF0aW9ucylgXG4gICAqICAgcmVjZWl2ZXMgdGhlIHJldGFpbmVkIGBfc3RhZ2VXcml0ZXNgIGVudHJpZXMsIHNvIGl0IGNhcnJpZXMgdGhlIHNhbWVcbiAgICogICBtYXJrZXJzIHVuZGVyIGAnc3VtbWFyeSdgIGFuZCBhbiBlbXB0eSBtdXRhdGlvbnMgYmFnIHVuZGVyIGAnb2ZmJ2Ag4oCUXG4gICAqICAgZGVmZXJyZWQvb2JzZXJ2ZXIgY29uc3VtZXJzIHNlZSBleGFjdGx5IHdoYXQgcmV0ZW50aW9uIHN0b3JlZC5cbiAgICpcbiAgICogV2hhdCBpdCBkb2VzIE5PVCBnb3Zlcm46XG4gICAqIC0gVGhlIHdyaXRlcyB0aGVtc2VsdmVzOiBzaGFyZWQgc3RhdGUsIHRoZSB0cmFuc2FjdGlvbiBidWZmZXIsIGFuZCB0aGVcbiAgICogICBDT01NSVQgTE9HIGFyZSBpZGVudGljYWwgaW4gZXZlcnkgbW9kZSAoY29tbWl0TG9nIHZhbHVlcyBrZWVwIHRoZWlyXG4gICAqICAgZnVsbCBwYXlsb2FkcyDigJQgdGhlIGxvc3NsZXNzIGxpbmVhci1jb3N0IGZpeCBmb3IgdGhvc2UgaXMgdGhlXG4gICAqICAge0BsaW5rIGNvbW1pdFZhbHVlc30gZGlhbCwgIzEzYy1CKS5cbiAgICogLSBQZXItb3AgYFNjb3BlUmVjb3JkZXIub25Xcml0ZWAgZXZlbnRzIOKAlCB0aGV5IGZpcmUgd2l0aCBsaXZlIHZhbHVlc1xuICAgKiAgIHJlZ2FyZGxlc3MgKGRlbGl2ZXJ5IHRpZXIsIFJGQy0wMDEncyBjb25jZXJuKSwgc28gbmFycmF0aXZlIG91dHB1dCBpc1xuICAgKiAgIGlkZW50aWNhbCBpbiBldmVyeSBtb2RlLlxuICAgKiAtIFJlZGFjdGlvbjogYSBwb2xpY3kvcGVyLWNhbGwtcmVkYWN0ZWQgd3JpdGUgc3RvcmVzIGAnW1JFREFDVEVEXSdgXG4gICAqICAgdW5kZXIgYCdmdWxsJ2AgQU5EIGAnc3VtbWFyeSdgIChyZWRhY3Rpb24gdGFrZXMgcHJlY2VkZW5jZSBvdmVyIHRoZVxuICAgKiAgIGRpYWw7IGEgbWFya2VyIHdvdWxkIGxlYWsgc2l6ZS9wcmV2aWV3KSwgYW5kIG5vdGhpbmcgdW5kZXIgYCdvZmYnYC5cbiAgICpcbiAgICogQ2F2ZWF0OiB1bmRlciBgJ29mZidgIGEgc3RhZ2UncyBTTkFQU0hPVCBpcyBpbmRpc3Rpbmd1aXNoYWJsZSBmcm9tIG9uZVxuICAgKiB0aGF0IHdyb3RlIG5vdGhpbmcg4oCUIGJ1dCB1bmxpa2UgYHJlYWRUcmFja2luZzogJ29mZidgLCB0aGUgY29tbWl0IGxvZ1xuICAgKiBzdGlsbCByZWNvcmRzIGV2ZXJ5IG5ldCBjaGFuZ2UsIHNvIFwiZGlkIGl0IHdyaXRlP1wiIHN0YXlzIGFuc3dlcmFibGUuXG4gICAqIEVxdWl2YWxlbnQgdG8gY2FsbGluZyBgZXhlY3V0b3Iuc2V0V3JpdGVUcmFja2luZyhtb2RlKWAgYmVmb3JlIGBydW4oKWAuXG4gICAqL1xuICB3cml0ZVRyYWNraW5nPzogV3JpdGVUcmFja2luZ01vZGU7XG5cbiAgLyoqXG4gICAqIEVuY29kaW5nIHBvbGljeSBmb3IgQ09NTUlUIExPRyB2YWx1ZXMgKCMxM2MtQikg4oCUIHRoZSB0aGlyZCBkaWFsIG9mIHRoZVxuICAgKiBmYW1pbHksIGFuZCB1bmxpa2UgaXRzIHNpYmxpbmdzIGl0IGlzICoqbG9zc2xlc3MgaW4gYm90aCBtb2RlcyoqIChpdFxuICAgKiBjaGFuZ2VzIHRoZSBsb2cncyBlbmNvZGluZywgbmV2ZXIgaXRzIGluZm9ybWF0aW9uKS5cbiAgICpcbiAgICogLSBgJ2Z1bGwnYCAoZGVmYXVsdCkg4oCUIGV2ZXJ5IHN1cnZpdmluZyBgc2V0YCBwYXRoIHN0b3JlcyB0aGUgZnVsbCBmaW5hbFxuICAgKiAgIHZhbHVlOyBieXRlLWlkZW50aWNhbCB0byB0aGUgaGlzdG9yaWNhbCBiZWhhdmlvci5cbiAgICogLSBgJ2RlbHRhJ2Ag4oCUIGFycmF5IG5ldC1jaGFuZ2VzIHRoYXQgYXJlIFwiYmFzZSBwbHVzIGEgdGFpbFwiIGNvbW1pdCBhcyBhblxuICAgKiAgIGBhcHBlbmRgIHRyYWNlIHZlcmIgc3RvcmluZyBPTkxZIHRoZSB0YWlsICh0aGUgZ3Jvd2luZy1oaXN0b3J5IGNvbW1pdFxuICAgKiAgIGxvZyBiZWNvbWVzIGxpbmVhciBpbnN0ZWFkIG9mIE8oTsKyKSByZXRhaW5lZCk7IGBkZWxldGVWYWx1ZSgpYCBjb21taXRzXG4gICAqICAgYXMgYSByZWFsIGBkZWxldGVgIHZlcmIgKHJlcGxheSByZW1vdmVzIHRoZSBrZXkgaW5zdGVhZCBvZiBsZWF2aW5nXG4gICAqICAgYGtleTogdW5kZWZpbmVkYCk7IGJ1bmRsZXMgY2FycnkgZXhhY3RseSBPTkUgdHJhY2UgZW50cnkgcGVyIHN1cnZpdmluZ1xuICAgKiAgIHBhdGguIFJlcGxheSAodGhlIG9uZSB2ZXJiIGxhdyDigJQgbGl2ZSBzdGF0ZSwgYG1hdGVyaWFsaXNlKClgLCB0aGVcbiAgICogICByZWRhY3RlZCBtaXJyb3IsIGBzdGF0ZUF0YCkgcmVjb25zdHJ1Y3RzIGV2ZXJ5IHN0ZXAncyBmdWxsIHN0YXRlXG4gICAqICAgZXhhY3RseS5cbiAgICpcbiAgICogQ29uc3VtZXJzIHRoYXQgcmVhZCBgYnVuZGxlLm92ZXJ3cml0ZVtrZXldYCBhcyBcInRoZSBmdWxsIHZhbHVlIHdyaXR0ZW5cIlxuICAgKiBtdXN0IHN3aXRjaCB0byBgY29tbWl0VmFsdWVBdChjb21taXRMb2csIGlkeCwga2V5KWAgZnJvbVxuICAgKiBgZm9vdHByaW50anMvdHJhY2VgIOKAlCB1bmRlciBgJ2RlbHRhJ2AgdGhhdCB2YWx1ZSBpcyB2ZXJiLXF1YWxpZmllZCAoYW5cbiAgICogYGFwcGVuZGAgYnVuZGxlIGhvbGRzIG9ubHkgdGhlIHRhaWwpLiBQYXRoLXRpZXIgY29uc3VtZXJzXG4gICAqIChgZmluZExhc3RXcml0ZXJgLCBgY2F1c2FsQ2hhaW5gLCBuYXJyYXRpdmUsIGxlbnMgaGlnaGxpZ2h0cykgYXJlXG4gICAqIHVuYWZmZWN0ZWQuIFRoZSBhY3RpdmUgbW9kZSBpcyBzdXJmYWNlZCBhc1xuICAgKiBgZ2V0U25hcHNob3QoKS5jb21taXRWYWx1ZXNgLlxuICAgKlxuICAgKiBIb25lc3QgY29zdCBub3RlOiBhcHBlbmQgZGV0ZWN0aW9uIGlzIG5ldyB3YWxsIHdvcmsg4oCUIGFuIE8ofGJhc2UgYXJyYXl8KVxuICAgKiBzdHJ1Y3R1cmFsIHByZWZpeCBjb21wYXJlIHBlciBhcnJheS1zZXQgcGF0aCBwZXIgY29tbWl0LiBPbiBhIGhpdCB0aGVcbiAgICogY29tbWl0IGdldHMgY2hlYXBlciBpbiBib3RoIHdhbGwgYW5kIGhlYXA7IG9uIGEgbWlzcyAocHJlZml4IGRpdmVyZ2VzKVxuICAgKiBpdCBwYXlzIGNvbXBhcmUgKyBmdWxsIGNsb25lLiBgJ2Z1bGwnYCBwYXlzIHplcm8uXG4gICAqIEVxdWl2YWxlbnQgdG8gY2FsbGluZyBgZXhlY3V0b3Iuc2V0Q29tbWl0VmFsdWVzKG1vZGUpYCBiZWZvcmUgYHJ1bigpYC5cbiAgICovXG4gIGNvbW1pdFZhbHVlcz86IENvbW1pdFZhbHVlc01vZGU7XG5cbiAgLyoqXG4gICAqIFBlci13cml0ZSByZWFkIHByb3ZlbmFuY2UgKCNQMSkg4oCUIHRoZSBmb3VydGggZGlhbCBvZiB0aGUgZmFtaWx5LiBEZWZhdWx0XG4gICAqIGAnb2ZmJ2A6IHplcm8gY29zdCwgYnl0ZS1pZGVudGljYWwgY29tbWl0IGxvZ3MuIGAncmVhZHMtcHJlZml4J2A6IGV2ZXJ5XG4gICAqIGNvbW1pdHRlZCBgVHJhY2VFbnRyeWAgY2FycmllcyBgcmVhZEtleXNgIOKAlCB0aGUga2V5cyB0cmFja2VkLXJlYWQgQkVGT1JFXG4gICAqIHRoYXQgd3JpdGUg4oCUIGVuYWJsaW5nIHBlci13cml0ZSBjYXVzYWwgYXR0cmlidXRpb24gKGBjYXVzYWxDaGFpbmAnc1xuICAgKiBgZWRnZUF0dHJpYnV0aW9uOiAncGVyLXdyaXRlJ2AgYW5kIHZhcmlhYmxlIHNsaWNlcykuIENvc3Q6IG9uZSBzbWFsbFxuICAgKiBhcnJheSBjb3B5IHBlciB3cml0ZS4gU25hcHNob3QgZGlzY3JpbWluYW50OlxuICAgKiBgZ2V0U25hcHNob3QoKS53cml0ZVByb3ZlbmFuY2VgLlxuICAgKi9cbiAgd3JpdGVQcm92ZW5hbmNlPzogV3JpdGVQcm92ZW5hbmNlTW9kZTtcbn1cblxuLyoqIFRoZSBydW4ncyBwb2xpY3k6IGV2ZXJ5IGRpYWwgcmVzb2x2ZWQsIHBsdXMgdGhlIHJlZGFjdGlvbiBydWxlIGFuZCB0aGUgbWlycm9yIGZsYWcuIEZyb3plbi4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUnVuUG9saWN5IGV4dGVuZHMgUmVhZG9ubHk8UmVxdWlyZWQ8UnVuRGlhbHM+PiB7XG4gIC8qKiBUaGUgcnVuJ3MgcmVkYWN0aW9uIHJ1bGUg4oCUIHRoZSBPTkUgb3duZXIgb2YgdGhlIHZlcmRpY3QgKGByZWRhY3Rpb24udHNgKS4gQWJzZW50IG9uIGJhcmUgZnJhbWVzLiAqL1xuICByZWFkb25seSByZWRhY3Rpb24/OiBSZWRhY3Rpb25SdWxlO1xuICAvKiogS2VlcCBhIHJlZGFjdGVkIG1pcnJvciBvZiB0aGUgaGVhcCAoYSBydW4gd2l0aCBhIHJlZGFjdGlvbiBwb2xpY3kpLiBFYWNoIHJ1bnRpbWUgb3ducyBpdHMgb3duIHN0b3JlLiAqL1xuICByZWFkb25seSBtaXJyb3I6IGJvb2xlYW47XG59XG5cbi8qKiBFYWNoIGRpYWwncyBkZWZhdWx0IOKAlCB0aGUgdmFsdWUgYSBydW4gZ2V0cyB3aGVuIHRoZSBvcHRpb24gaXMgYWJzZW50LiBUaGUgZGlhbCBsaXN0IElTIHRoZXNlIGtleXMuICovXG5leHBvcnQgY29uc3QgRElBTF9ERUZBVUxUUzogUmVhZG9ubHk8UmVxdWlyZWQ8UnVuRGlhbHM+PiA9IE9iamVjdC5mcmVlemUoe1xuICByZWFkVHJhY2tpbmc6ICdmdWxsJyxcbiAgd3JpdGVUcmFja2luZzogJ2Z1bGwnLFxuICBjb21taXRWYWx1ZXM6ICdmdWxsJyxcbiAgd3JpdGVQcm92ZW5hbmNlOiAnb2ZmJyxcbn0pO1xuXG5jb25zdCBESUFMX05BTUVTID0gT2JqZWN0LmtleXMoRElBTF9ERUZBVUxUUykgYXMgQXJyYXk8a2V5b2YgUnVuRGlhbHM+O1xuXG4vKiogRXZlcnkgZGVmYXVsdCwgbm8gcnVsZSwgbm8gbWlycm9yIOKAlCB3aGF0IGEgYmFyZSBmcmFtZSAoYSB1bml0IHRlc3QncyBgbmV3IFN0YWdlQ29udGV4dGApIHJ1bnMgdW5kZXIuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9SVU5fUE9MSUNZOiBSdW5Qb2xpY3kgPSBPYmplY3QuZnJlZXplKHsgLi4uRElBTF9ERUZBVUxUUywgbWlycm9yOiBmYWxzZSB9KTtcblxuLyoqIEJ1aWxkIGEgcnVuJ3MgcG9saWN5OiBhYnNlbnQgZGlhbHMgdGFrZSB0aGVpciBkZWZhdWx0OyB0aGUgcmVzdWx0IGlzIGZyb3plbi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBydW5Qb2xpY3koZGlhbHM6IFJ1bkRpYWxzID0ge30sIHJlZGFjdGlvbj86IFJlZGFjdGlvblJ1bGUsIG1pcnJvciA9IGZhbHNlKTogUnVuUG9saWN5IHtcbiAgY29uc3QgcmVzb2x2ZWQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0geyAuLi5ESUFMX0RFRkFVTFRTLCAuLi5waWNrRGlhbHMoZGlhbHMpLCBtaXJyb3IgfTtcbiAgaWYgKHJlZGFjdGlvbikgcmVzb2x2ZWQucmVkYWN0aW9uID0gcmVkYWN0aW9uO1xuICByZXR1cm4gT2JqZWN0LmZyZWV6ZShyZXNvbHZlZCkgYXMgdW5rbm93biBhcyBSdW5Qb2xpY3k7XG59XG5cbi8qKiBUaGUgZGlhbHMgc2V0IG9uIGBzb3VyY2VgIChhbiBvcHRpb25zIG9iamVjdCwgc2F5KSDigJQgYW5kIG5vdGhpbmcgZWxzZSBmcm9tIGl0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBpY2tEaWFscyhzb3VyY2U6IFJ1bkRpYWxzKTogUnVuRGlhbHMge1xuICBjb25zdCBkaWFsczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgZm9yIChjb25zdCBuYW1lIG9mIERJQUxfTkFNRVMpIGlmIChzb3VyY2VbbmFtZV0gIT09IHVuZGVmaW5lZCkgZGlhbHNbbmFtZV0gPSBzb3VyY2VbbmFtZV07XG4gIHJldHVybiBkaWFscyBhcyBSdW5EaWFscztcbn1cblxuLyoqIFRoZSBzYW1lIHBvbGljeSB1bmRlciBhbm90aGVyIHJ1bGUg4oCUIGEgTkVXIGZyb3plbiBvYmplY3Q7IHRoZSBvbGQgb25lIGlzIG5ldmVyIGVkaXRlZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRoUmVkYWN0aW9uKHBvbGljeTogUnVuUG9saWN5LCByZWRhY3Rpb246IFJlZGFjdGlvblJ1bGUpOiBSdW5Qb2xpY3kge1xuICByZXR1cm4gZGVyaXZlUG9saWN5KHBvbGljeSwgeyByZWRhY3Rpb24gfSk7XG59XG5cbi8qKlxuICogVGhlIHNhbWUgcG9saWN5IHdpdGggc29tZSBzZXR0aW5ncyBjaGFuZ2VkIOKAlCBhIE5FVyBmcm96ZW4gb2JqZWN0OyB0aGUgb2xkIG9uZSBpcyBuZXZlclxuICogZWRpdGVkLiBXaGF0IHRoZSBkZXByZWNhdGVkIHBlci1kaWFsIHNldHRlcnMgKGBTdGFnZUNvbnRleHQudXNlUmVhZFRyYWNraW5nYCxcbiAqIGBFeGVjdXRpb25SdW50aW1lLnVzZUNvbW1pdFZhbHVlc2AsIOKApikgZGVsZWdhdGUgdG86IHRoZXkgc3dhcCBpbiBhIGRlcml2ZWQgcG9saWN5LCBzbyBub1xuICogbXV0YWJsZSBkaWFsIGZpZWxkIGV4aXN0cyBhbnl3aGVyZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlcml2ZVBvbGljeShwb2xpY3k6IFJ1blBvbGljeSwgcGF0Y2g6IFBhcnRpYWw8UnVuUG9saWN5Pik6IFJ1blBvbGljeSB7XG4gIHJldHVybiBPYmplY3QuZnJlZXplKHsgLi4ucG9saWN5LCAuLi5wYXRjaCB9KTtcbn1cbiJdfQ==
@@ -11,6 +11,7 @@
11
11
  */
12
12
  import { EventLog } from '../memory/EventLog.js';
13
13
  import type { RedactionRule } from '../memory/redaction.js';
14
+ import type { RunPolicy } from '../memory/runPolicy.js';
14
15
  import { SharedMemory } from '../memory/SharedMemory.js';
15
16
  import { StageContext } from '../memory/StageContext.js';
16
17
  import type { CommitBundle, CommitValuesMode, ReadTrackingMode, StageSnapshot, WriteProvenanceMode, WriteTrackingMode } from '../memory/types.js';
@@ -127,9 +128,9 @@ export declare class ExecutionRuntime {
127
128
  /**
128
129
  * Parallel redacted mirror of `globalStore`. Populated during traversal via
129
130
  * `StageContext.commit()` using the already-computed redacted patches.
130
- * Only exists when `enableRedactedMirror()` has been called — typically by
131
- * `FlowChartExecutor` when a `RedactionPolicy` is configured. Otherwise
132
- * undefined and zero cost.
131
+ * Only exists when the run's policy keeps a mirror (`RunPolicy.mirror` —
132
+ * `FlowChartExecutor` sets it when a `RedactionPolicy` is configured).
133
+ * Otherwise undefined and zero cost.
133
134
  *
134
135
  * Read via `getSnapshot({ redact: true })`.
135
136
  */
@@ -140,75 +141,60 @@ export declare class ExecutionRuntime {
140
141
  private _snapshotRoot?;
141
142
  private _initialState;
142
143
  private _defaultValues;
143
- /** Active commit-values encoding (#13c-B) — surfaced as the snapshot
144
- * discriminant {@link RuntimeSnapshot.commitValues}. */
145
- private commitValues;
146
- /** Mirror of the writeProvenance dial for the snapshot discriminant (#P1). */
147
- private writeProvenance;
144
+ /** The run's policy (`memory/runPolicy.ts`) — installed on the root frame;
145
+ * its `commitValues` and `writeProvenance` are the snapshot discriminants. */
146
+ private policy;
148
147
  /** Memoized frozen fold base — see {@link RuntimeSnapshot.initialState}. */
149
148
  private _foldBase?;
150
- constructor(rootName: string, rootId: string, defaultValues?: unknown, initialState?: unknown);
151
149
  /**
152
- * Opt in to maintaining a parallel redacted mirror of `globalStore`. After
153
- * this call, every `StageContext.commit()` in the run writes the redacted
154
- * patches (the same ones fed to the event log) into `redactedStore` in
155
- * addition to the raw ones written to `globalStore`.
156
- *
157
- * The mirror is created lazily and propagated into all child / next
158
- * contexts, so it correctly reflects subflow-scope writes. When no
159
- * `RedactionPolicy` is configured, callers should skip this — unused
160
- * allocation, no functional difference in the snapshot.
150
+ * @param policy The run's policy (`runPolicy.ts`, F5) — the four dials, the
151
+ * redaction rule, the mirror flag. Installed on the root frame here, so
152
+ * the FIRST commit (a subflow's seed, `history[0]`) already runs under it;
153
+ * every frame after inherits the same reference. Default: every dial at
154
+ * its default, no rule, no mirror.
161
155
  */
162
- enableRedactedMirror(): void;
156
+ constructor(rootName: string, rootId: string, defaultValues?: unknown, initialState?: unknown, policy?: RunPolicy);
163
157
  /**
164
- * Install the run's redaction rule (the ONE owner of the verdict —
165
- * `memory/redaction.ts`) on the root stage context. Descendants inherit
166
- * via `createNext`/`createChild`; subflow roots inherit from their
167
- * parent-mount context via `SubflowExecutor`. Called by
168
- * `FlowChartExecutor.createTraverser()` on every run AND resume — after the
169
- * resume-path root swap, like the dials — so every staged write and tracked
170
- * read of the run, facade or not, is retained under the same policy.
158
+ * A fresh root frame for this runtime — `globalStore`, `executionHistory`,
159
+ * the run's policy and (when kept) the mirror. Also how `SubflowExecutor`
160
+ * replaces a subflow's seed frame with the frame its first stage runs on.
171
161
  */
172
- useRedaction(rule: RedactionRule): void;
162
+ newRoot(name: string, id: string): StageContext;
173
163
  /**
174
- * Set the read-tracking policy (#14) on the root stage context. Descendant
175
- * contexts inherit via `createNext`/`createChild`; subflow root contexts
176
- * inherit from their parent-mount context via `SubflowExecutor`. Called by
177
- * `FlowChartExecutor.createTraverser()` when the executor's policy is not
178
- * the default `'full'` — including the resume path, where it is applied to
179
- * the freshly-created continuation root.
164
+ * Install the run's policy on the CURRENT root frame — a same-executor
165
+ * resume, whose continuation root (`leaf.createNext`) is advanced before
166
+ * the executor builds this leg's policy (a fresh rule per leg). Every
167
+ * descendant takes the reference from there.
180
168
  */
169
+ usePolicy(policy: RunPolicy): void;
170
+ private derive;
171
+ /** @deprecated since 9.35.0 — construct with `runPolicy({ readTracking })`, or `usePolicy`. */
181
172
  useReadTracking(mode: ReadTrackingMode): void;
182
- /**
183
- * Set the write-tracking policy (#13c-A) on the root stage context — the
184
- * sibling of {@link useReadTracking}, with identical plumbing: descendant
185
- * contexts inherit via `createNext`/`createChild`; subflow root contexts
186
- * inherit from their parent-mount context via `SubflowExecutor`. Called by
187
- * `FlowChartExecutor.createTraverser()` when the executor's policy is not
188
- * the default `'full'` — including the resume path, where it is applied to
189
- * the freshly-created continuation root.
190
- */
173
+ /** @deprecated since 9.35.0 — construct with `runPolicy({ writeTracking })`, or `usePolicy`. */
191
174
  useWriteTracking(mode: WriteTrackingMode): void;
192
- /**
193
- * Set the commit-values encoding policy (#13c-B) on the root stage context
194
- * — the third dial of the {@link useReadTracking}/{@link useWriteTracking}
195
- * family, with identical plumbing: descendant contexts inherit via
196
- * `createNext`/`createChild`; subflow root contexts inherit from their
197
- * parent-mount context via `SubflowExecutor`. Called by
198
- * `FlowChartExecutor.createTraverser()` when the executor's policy is not
199
- * the default `'full'` — including the resume path, where it is applied to
200
- * the freshly-created continuation root.
201
- */
175
+ /** @deprecated since 9.35.0 — construct with `runPolicy({ commitValues })`, or `usePolicy`. */
202
176
  useCommitValues(mode: CommitValuesMode): void;
177
+ /** @deprecated since 9.35.0 — construct with `runPolicy({ writeProvenance })`, or `usePolicy`. */
178
+ useWriteProvenance(mode: WriteProvenanceMode): void;
179
+ /** @deprecated since 9.35.0 — construct with `runPolicy(dials, rule)`, or `usePolicy`. */
180
+ useRedaction(rule: RedactionRule): void;
203
181
  /**
204
- * Set the per-write read-provenance policy (#P1) on the root stage context
205
- * — the fourth dial of the family, identical plumbing: descendant contexts
206
- * inherit via `createNext`/`createChild`; subflow root contexts inherit
207
- * from their parent-mount context via `SubflowExecutor`. Called by
208
- * `FlowChartExecutor.createTraverser()` when the executor's policy is not
209
- * the default `'off'` — including the resume path.
182
+ * @deprecated since 9.35.0 — construct with `runPolicy(dials, rule, true)`.
183
+ * Idempotent, as before: a runtime that already keeps a mirror is untouched.
210
184
  */
211
- useWriteProvenance(mode: WriteProvenanceMode): void;
185
+ enableRedactedMirror(): void;
186
+ /**
187
+ * The policy on `root`, and the mirror store when the policy keeps one.
188
+ * The mirror is a SERVED surface, so its seed must already be the policy's
189
+ * view of the starting state: a policy key that arrives by `initialContext`
190
+ * / `defaultValuesForContext` (or, on a cross-executor resume, by the
191
+ * checkpoint's `sharedState`) and is never re-written would otherwise sit
192
+ * in `getSnapshot({ redact: true })` in plaintext — so the seed is scrubbed
193
+ * with the LOG's placeholder, the same string the redacted patches carry.
194
+ * Created once per runtime (a subflow's runtime keeps its own; its seed is
195
+ * empty — the input arrives as a commit).
196
+ */
197
+ private installPolicy;
212
198
  /** Preserve the current rootStageContext for snapshots before changing it for resume. */
213
199
  preserveSnapshotRoot(): void;
214
200
  /**