footprintjs - v11.2.0
    Preparing search index...

    Interface FlowChartExecutorOptions<TScope>

    Options object for FlowChartExecutor — preferred over positional params.

    const ex = new FlowChartExecutor(chart, {
    scopeFactory: myFactory,
    defaultValuesForContext: { ... },
    });

    Sync note for maintainers: a field added here must also be added to ExecutorArgs and resolveExecutorArgs below, or it is accepted and never applied. The DIALS are the exception: they come from RunDials and travel whole as dials.

    TScope inference note: When using the options-object form with a custom scope, TypeScript cannot infer TScope through the options object. Pass the type explicitly: new FlowChartExecutor<TOut, MyScope>(chart, { scopeFactory }).

    interface FlowChartExecutorOptions<TScope = any> {
        captureClosure?: boolean;
        captureCoverage?: boolean;
        captureExtent?: boolean;
        commitValues?: CommitValuesMode;
        defaultValuesForContext?: unknown;
        initialContext?: unknown;
        readOnlyContext?: unknown;
        readSources?: boolean | { limits: Partial<ReadSourceLimits> };
        readTracking?: RetentionPolicy;
        scopeFactory?: ScopeFactory<TScope>;
        scopeProtectionMode?: ScopeProtectionMode;
        sink?: RecordSinkOption;
        streamHandlers?: StreamHandlers;
        throttlingErrorChecker?: (error: unknown) => boolean;
        writeProvenance?: WriteProvenanceMode;
        writeTracking?: RetentionPolicy;
    }

    Type Parameters

    • TScope = any

    Hierarchy

    Index
    captureClosure?: boolean

    Preserve a bounded immutable native root prefix, separately from live snapshots. Requires both capture options.

    captureCoverage?: boolean

    Opt in to a versioned, memory-only root-log capture note on snapshots (#111 stage 1).

    captureExtent?: boolean

    Opt in to bounded native invocation bookkeeping. Requires captureCoverage; never attests closed capture.

    commitValues?: CommitValuesMode

    Encoding policy for COMMIT LOG values (#13c-B) — the third dial of the family, and unlike its siblings it is lossless in both modes (it changes the log's encoding, never its information).

    • 'full' (default) — every surviving set path stores the full final value; byte-identical to the historical behavior.
    • 'delta' — array net-changes that are "base plus a tail" commit as an append trace verb storing ONLY the tail (the growing-history commit log becomes linear instead of O(N²) retained); deleteValue() commits as a real delete verb (replay removes the key instead of leaving key: undefined); bundles carry exactly ONE trace entry per surviving path. Replay (the one verb law — live state, materialise(), the redacted mirror, stateAt) reconstructs every step's full state exactly.

    Consumers that read bundle.overwrite[key] as "the full value written" must switch to commitValueAt(commitLog, idx, key) from foottrace — under 'delta' that value is verb-qualified (an append bundle holds only the tail). Path-tier consumers (findLastWriter, causalChain, narrative, lens highlights) are unaffected. The active mode is surfaced as getSnapshot().commitValues.

    Honest cost note: append detection is new wall work — an O(|base array|) structural prefix compare per array-set path per commit. On a hit the commit gets cheaper in both wall and heap; on a miss (prefix diverges) it pays compare + full clone. 'full' pays zero. Equivalent to calling executor.setCommitValues(mode) before run().

    defaultValuesForContext?: unknown

    Default values for the shared context. Merged with initialContext once, when the run's state is created (top-level keys; a key in initialContext wins). Never re-applied: a stage that deletes or overwrites a defaulted key keeps that change.

    initialContext?: unknown

    Initial context values. Merged with defaultValuesForContext once, when the run's state is created; on a top-level key both set, this value wins.

    readOnlyContext?: unknown

    Read-only input accessible via scope.$getArgs() — never tracked or written.

    readSources?: boolean | { limits: Partial<ReadSourceLimits> }

    Native, bounded scalar read-source occurrences (#113). Default false; memory-only in packet 3.

    readTracking?: RetentionPolicy

    Policy for StageSnapshot.stageReads (#14). Default 'full' — a tracked read keeps a structuredClone of the value in the stage's read view (what lens/agentfootprint snapshots show). The clone is taken once for each object a key holds, not at every read (keptReads.ts); a key the stage itself has written is cloned at every read from then on. 'summary' records a cheap type/size/preview marker in its place; 'off' records nothing — no clone cost at all (reads of large values become ~free). Narrative and ScopeRecorder.onRead are identical in every mode. Caveat: under 'off' a stage's snapshot is indistinguishable from one that read nothing — auditing consumers that need "did it read?" without the value cost should prefer 'summary'. Equivalent to calling executor.setReadTracking(mode) before run().

    scopeFactory?: ScopeFactory<TScope>

    Custom scope factory. Defaults to TypedScope or ScopeFacade auto-detection.

    scopeProtectionMode?: ScopeProtectionMode

    Scope protection mode for TypedScope direct-assignment detection.

    Where the run's record goes AS IT LANDS, so a run that never finishes still leaves it: every log of the run (the root and each subflow mount) hands the sink its opened base, each commit, a note per attempt that ended, and its closed outcome. fileSink(path) (footprintjs/sinks, Node) or memorySink() (foottrace/write); read it back with readStoredRecord (foottrace). The redaction policy applies before any entry is written. A failing sink never stops the run (onFailure: 'report', the default) — getSnapshot().sink counts what was lost. See the guide's "A crash-safe record".

    const executor = new FlowChartExecutor(chart, { sink: fileSink('/var/footprint/run.jsonl') });
    
    streamHandlers?: StreamHandlers

    Handlers for streaming stage lifecycle events (see addStreamingFunction).

    throttlingErrorChecker?: (error: unknown) => boolean

    Custom error classifier for throttling detection. Return true if a fork child's error represents a rate-limit or backpressure condition; the executor then fires FlowRecorder.onThrottled for that child (9.39.0 — an EVENT, not a state key: the monitor.isThrottled write it replaced never landed). The child's failure is otherwise handled as before. Defaults to no throttling classification.

    writeProvenance?: WriteProvenanceMode

    Per-write read provenance (#P1) — the fourth dial of the family. Default 'off': zero cost, byte-identical commit logs. 'reads-prefix': every committed TraceEntry carries readKeys — the keys tracked-read BEFORE that write — enabling per-write causal attribution (causalChain's edgeAttribution: 'per-write' and variable slices). Cost: one small array copy per write. Snapshot discriminant: getSnapshot().writeProvenance.

    writeTracking?: RetentionPolicy

    Policy for StageSnapshot.stageWrites (#13c-A) — the sibling of readTracking; the two dials are independent. Default 'full' — every tracked write structuredClones the value into the stage's write view (the historical behavior). 'summary' records a cheap WriteSummaryMarker (type/size/preview) per write; 'off' records nothing — stageWrites is absent from the snapshot.

    Observable consequences — what the policy DOES govern:

    • StageSnapshot.stageWrites (markers under 'summary', absent under 'off').
    • The commit observer payload: ScopeRecorder.onCommit(mutations) receives the retained _stageWrites entries, so it carries the same markers under 'summary' and an empty mutations bag under 'off' — deferred/observer consumers see exactly what retention stored.

    What it does NOT govern:

    • The writes themselves: shared state, the transaction buffer, and the COMMIT LOG are identical in every mode (commitLog values keep their full payloads — the lossless linear-cost fix for those is the commitValues dial, #13c-B).
    • Per-op ScopeRecorder.onWrite events — they fire with live values regardless (delivery tier, RFC-001's concern), so narrative output is identical in every mode.
    • Redaction: a policy/per-call-redacted write stores '[REDACTED]' under 'full' AND 'summary' (redaction takes precedence over the dial; a marker would leak size/preview), and nothing under 'off'.

    Caveat: under 'off' a stage's SNAPSHOT is indistinguishable from one that wrote nothing — but unlike readTracking: 'off', the commit log still records every net change, so "did it write?" stays answerable. Equivalent to calling executor.setWriteTracking(mode) before run().