footprintjs 9.46.0 → 9.47.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 +4 -3
- package/CLAUDE.md +8 -8
- package/README.md +1 -1
- package/dist/advanced.js +95 -90
- package/dist/esm/advanced.d.ts +16 -10
- package/dist/esm/advanced.js +14 -9
- package/dist/esm/index.d.ts +4 -2
- package/dist/esm/index.js +5 -3
- package/dist/esm/lib/decide/evaluator.js +2 -2
- package/dist/esm/lib/decide/evidence.js +2 -2
- package/dist/esm/lib/engine/handlers/servedPause.js +2 -2
- package/dist/esm/lib/memory/EventLog.d.ts +1 -1
- package/dist/esm/lib/memory/EventLog.js +2 -2
- package/dist/esm/lib/memory/RecordFrame.d.ts +41 -6
- package/dist/esm/lib/memory/RecordFrame.js +36 -5
- package/dist/esm/lib/memory/SharedMemory.d.ts +1 -1
- package/dist/esm/lib/memory/SharedMemory.js +2 -2
- package/dist/esm/lib/memory/StageContext.d.ts +21 -14
- package/dist/esm/lib/memory/StageContext.js +36 -74
- package/dist/esm/lib/memory/borrowedMutation.d.ts +1 -1
- package/dist/esm/lib/memory/borrowedMutation.js +2 -2
- package/dist/esm/lib/memory/honesty.d.ts +4 -3
- package/dist/esm/lib/memory/honesty.js +5 -4
- package/dist/esm/lib/memory/index.d.ts +4 -2
- package/dist/esm/lib/memory/index.js +6 -4
- package/dist/esm/lib/memory/placeholders.d.ts +23 -28
- package/dist/esm/lib/memory/placeholders.js +24 -29
- package/dist/esm/lib/memory/recordCommit.d.ts +5 -3
- package/dist/esm/lib/memory/recordCommit.js +7 -5
- package/dist/esm/lib/memory/redaction.d.ts +78 -40
- package/dist/esm/lib/memory/redaction.js +130 -64
- package/dist/esm/lib/memory/runAddress.d.ts +20 -0
- package/dist/esm/lib/memory/runAddress.js +25 -0
- package/dist/esm/lib/memory/scrub.d.ts +53 -0
- package/dist/esm/lib/memory/scrub.js +74 -0
- package/dist/esm/lib/memory/utils.d.ts +3 -3
- package/dist/esm/lib/memory/utils.js +4 -4
- package/dist/esm/lib/memory/verbs.d.ts +1 -1
- package/dist/esm/lib/memory/verbs.js +2 -2
- package/dist/esm/trace.d.ts +2 -0
- package/dist/esm/trace.js +3 -2
- package/dist/esm/write.d.ts +47 -0
- package/dist/esm/write.js +46 -0
- package/dist/index.js +5 -3
- package/dist/lib/decide/evaluator.js +3 -3
- package/dist/lib/decide/evidence.js +3 -3
- package/dist/lib/engine/handlers/servedPause.js +3 -3
- package/dist/lib/memory/EventLog.js +2 -2
- package/dist/lib/memory/RecordFrame.js +36 -5
- package/dist/lib/memory/SharedMemory.js +2 -2
- package/dist/lib/memory/StageContext.js +42 -80
- package/dist/lib/memory/borrowedMutation.js +2 -2
- package/dist/lib/memory/honesty.js +5 -4
- package/dist/lib/memory/index.js +6 -4
- package/dist/lib/memory/placeholders.js +25 -30
- package/dist/lib/memory/recordCommit.js +9 -7
- package/dist/lib/memory/redaction.js +144 -75
- package/dist/lib/memory/runAddress.js +29 -0
- package/dist/lib/memory/scrub.js +79 -0
- package/dist/lib/memory/utils.js +4 -4
- package/dist/lib/memory/verbs.js +2 -2
- package/dist/trace.js +6 -4
- package/dist/types/advanced.d.ts +16 -10
- package/dist/types/index.d.ts +4 -2
- package/dist/types/lib/memory/EventLog.d.ts +1 -1
- package/dist/types/lib/memory/RecordFrame.d.ts +41 -6
- package/dist/types/lib/memory/SharedMemory.d.ts +1 -1
- package/dist/types/lib/memory/StageContext.d.ts +21 -14
- package/dist/types/lib/memory/borrowedMutation.d.ts +1 -1
- package/dist/types/lib/memory/honesty.d.ts +4 -3
- package/dist/types/lib/memory/index.d.ts +4 -2
- package/dist/types/lib/memory/placeholders.d.ts +23 -28
- package/dist/types/lib/memory/recordCommit.d.ts +5 -3
- package/dist/types/lib/memory/redaction.d.ts +78 -40
- package/dist/types/lib/memory/runAddress.d.ts +20 -0
- package/dist/types/lib/memory/scrub.d.ts +53 -0
- package/dist/types/lib/memory/utils.d.ts +3 -3
- package/dist/types/lib/memory/verbs.d.ts +1 -1
- package/dist/types/trace.d.ts +2 -0
- package/dist/types/write.d.ts +47 -0
- package/dist/write.js +52 -0
- package/package.json +15 -1
|
@@ -40,16 +40,41 @@
|
|
|
40
40
|
* the facade held the verdict alone, and every path that wrote or read past
|
|
41
41
|
* the facade — five of them — retained plaintext under a policy.
|
|
42
42
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
43
|
+
* ONE VERDICT OWNER, ONE ENCODING OWNER (C4). This file DECIDES — the rule,
|
|
44
|
+
* and for a staged write {@link decideWrite} (the verdict),
|
|
45
|
+
* {@link inheritByIdentity} and {@link markStagedWrite} (the marks) — and is
|
|
46
|
+
* the engine's (L4, beside the run policy that carries the rule). The BYTES of a
|
|
47
|
+
* verdict are the record's: the frame hands its scrub (`whole`, or the
|
|
48
|
+
* `fields` inside the value — {@link scrubOf}) to `RecordFrame · write`, and
|
|
49
|
+
* the record's own scrub (`memory/scrub.ts`, L2) writes the log's placeholder
|
|
50
|
+
* at commit. Before C4 the scrub lived here too, so the record imported the
|
|
51
|
+
* engine's policy module to write a string.
|
|
52
|
+
*
|
|
53
|
+
* TWO PLACEHOLDERS, BOTH HISTORICAL, ONE PER OWNER: the commit log and the
|
|
54
|
+
* mirror carry `'REDACTED'` (`LOG_PLACEHOLDER`, `memory/placeholders.ts` — a
|
|
55
|
+
* record byte, written by `memory/scrub.ts`); every scope-tier view — scope
|
|
56
|
+
* recorder events, `stageReads`/`stageWrites`, narrative — carries
|
|
57
|
+
* `'[REDACTED]'` ({@link SCOPE_PLACEHOLDER}, below — the verdict's own).
|
|
58
|
+
* Neither string changed in 9.19.0 or since; each is spelled once in `src/`.
|
|
49
59
|
*/
|
|
50
60
|
import type { StructuredErrorInfo } from '../errors/errorInfo.js';
|
|
51
61
|
import type { RedactionMarks } from '../pause/types.js';
|
|
52
|
-
import type {
|
|
62
|
+
import type { WriteScrub, WriteVerb } from './RecordFrame.js';
|
|
63
|
+
/**
|
|
64
|
+
* What the SCOPE CHANNEL carries where a value was scrubbed: a scope recorder's read, write and
|
|
65
|
+
* commit events, the `stageReads` / `stageWrites` retention, the narrative, a decision's evidence, an
|
|
66
|
+
* emit payload matched by `emitPatterns`, a pause payload's served form and a subflow's narrated seed
|
|
67
|
+
* (`onSubflowEntry`) — every value this verdict serves, unless its caller passes the log's string.
|
|
68
|
+
*
|
|
69
|
+
* Its twin is the RECORD's `LOG_PLACEHOLDER` (`'REDACTED'`, `memory/placeholders.ts`): the commit log,
|
|
70
|
+
* the redacted mirror and everything served from them. So NOT every recorder event carries this one:
|
|
71
|
+
* `onSubflowExit.outputState` serves the subflow's redacted mirror when a policy keeps one, and so
|
|
72
|
+
* carries the log's string (without a mirror — per-call marks alone — it is the subflow's heap
|
|
73
|
+
* retained under the rule, with this one). Both strings are historical and neither changed when it
|
|
74
|
+
* moved: this one was the constant `REDACTED` in this file until F4a, then `placeholders.ts ·
|
|
75
|
+
* SCOPE_PLACEHOLDER`, and since C4 it lives here again, beside the verdict that writes it.
|
|
76
|
+
*/
|
|
77
|
+
export declare const SCOPE_PLACEHOLDER = "[REDACTED]";
|
|
53
78
|
/**
|
|
54
79
|
* Declarative key/path redaction for recorded state and boundary records.
|
|
55
80
|
*
|
|
@@ -127,6 +152,14 @@ export type RedactionVerdict = {
|
|
|
127
152
|
readonly paths: readonly string[];
|
|
128
153
|
};
|
|
129
154
|
export declare const CLEAR: RedactionVerdict;
|
|
155
|
+
/**
|
|
156
|
+
* The user-level NAME of `key` under `path` — the key itself at the top level, else the segments
|
|
157
|
+
* joined by a dot (`['profile'] + 'auth'` → `'profile.auth'`): what a verdict decides on, a mark
|
|
158
|
+
* holds, and the frame keys a stage's retained reads and writes by (`StageContext`). A name, not an
|
|
159
|
+
* address — a key may contain a dot — so it never goes into a trace path. No allocation for the
|
|
160
|
+
* common top-level key. (The record spells the same name for `readKeys`, `RecordFrame · noteRead`.)
|
|
161
|
+
*/
|
|
162
|
+
export declare function userKeyOf(path: readonly string[], key: string): string;
|
|
130
163
|
export declare class RedactionRule {
|
|
131
164
|
private policy;
|
|
132
165
|
private diagnosticRule;
|
|
@@ -298,7 +331,7 @@ export declare class RedactionRule {
|
|
|
298
331
|
* (declared or themselves inherited). Run-wide, by name, like a mark.
|
|
299
332
|
*/
|
|
300
333
|
inheritFields(target: string, paths: readonly string[]): void;
|
|
301
|
-
/** The verdict of a key a mapper read — `runs` (the run namespaces) is selected when any namespaced key is. */
|
|
334
|
+
/** The verdict of a key a mapper read — `runs` (the run namespaces, `RUN_NAMESPACE`) is selected when any namespaced key is. */
|
|
302
335
|
verdictOfRead(key: string, value: unknown): RedactionVerdict;
|
|
303
336
|
/**
|
|
304
337
|
* The retained / served form of a value at a path: the placeholder, a
|
|
@@ -381,6 +414,43 @@ export declare class RedactionRule {
|
|
|
381
414
|
static scrubFields(value: unknown, paths: readonly string[], placeholder?: string): Record<string, unknown> | undefined;
|
|
382
415
|
report(): RedactionReport;
|
|
383
416
|
}
|
|
417
|
+
/**
|
|
418
|
+
* Step 1 — THE VERDICT for one staged write: an explicit per-call flag (`setValue(key, value, true)`)
|
|
419
|
+
* makes the value secret whole under its user-level key; else the `active` rule decides from the
|
|
420
|
+
* user-level path; with none (no rule, or an inert one — the caller passes `undefined`), clear, with no
|
|
421
|
+
* verdict call and no path allocation (the no-policy fast path). Marks nothing.
|
|
422
|
+
*
|
|
423
|
+
* ```ts
|
|
424
|
+
* decideWrite(new RedactionRule({ fields: { card: ['number'] } }), [], 'card', false); // { kind: 'fields', key: 'card', paths: ['number'] }
|
|
425
|
+
* decideWrite(undefined, ['profile'], 'auth', true); // { kind: 'whole', key: 'profile.auth' }
|
|
426
|
+
* ```
|
|
427
|
+
*/
|
|
428
|
+
export declare function decideWrite(active: RedactionRule | undefined, path: readonly string[], key: string, explicit: boolean | undefined): RedactionVerdict;
|
|
429
|
+
/**
|
|
430
|
+
* Step 2 — IDENTITY: an OBJECT the stage read under a selected name (`selected` — the frame's selected
|
|
431
|
+
* reads, filled by its tracked reads), written under another name (`s.person = s.profile`), keeps that
|
|
432
|
+
* read's rule, matched by identity: a whole read marks the new key, a `fields` read hands it the fields
|
|
433
|
+
* (re-based under the written path), and the verdict is asked again. A new object, a primitive, or a
|
|
434
|
+
* write already whole is selected by its own name only — `verdict` comes back as it is. Decided BEFORE
|
|
435
|
+
* the write, because the verdict needs it: an inheritance stays even if the write then fails to stage.
|
|
436
|
+
*/
|
|
437
|
+
export declare function inheritByIdentity(active: RedactionRule | undefined, verdict: RedactionVerdict, selected: WeakMap<object, RedactionVerdict> | undefined, path: readonly string[], key: string, value: unknown): RedactionVerdict;
|
|
438
|
+
/**
|
|
439
|
+
* Step 3's input — a verdict's BYTES for the record (`RecordFrame · write`): nothing when clear, the
|
|
440
|
+
* whole value, or the fields inside it. No allocation on the default path (clear) or for a whole verdict.
|
|
441
|
+
*/
|
|
442
|
+
export declare function scrubOf(verdict: RedactionVerdict): WriteScrub | undefined;
|
|
443
|
+
/**
|
|
444
|
+
* Step 4 — the MARKS a staged write leaves; call it only once the write staged, so a write that fails to
|
|
445
|
+
* stage marks nothing. A delete clears its key's mark (and any fields a mapper handed it) on `active`,
|
|
446
|
+
* the rule that was active as the write BEGAN — none when it was inert, even if user code marked the key
|
|
447
|
+
* during the write. A whole verdict marks its key — the key that DECIDED it (`verdict.key`: an ancestor
|
|
448
|
+
* for a nested write under a whole-selected key) — for the rest of the run on `rule`, the run's rule as
|
|
449
|
+
* it stands NOW (user code during the write may have installed one; an explicit mark is what makes an
|
|
450
|
+
* inert rule active). A mark is a run-wide NAME: it stays when the stage's commit fails or a retry
|
|
451
|
+
* discards the attempt — the safe side; only a staged delete removes one.
|
|
452
|
+
*/
|
|
453
|
+
export declare function markStagedWrite(active: RedactionRule | undefined, rule: RedactionRule | undefined, verdict: RedactionVerdict, path: readonly string[], key: string, verb: WriteVerb): void;
|
|
384
454
|
/**
|
|
385
455
|
* Path visits one walk may make — reachable only under a PATH-dependent
|
|
386
456
|
* pattern over a value whose paths outnumber its objects (a linked history, a
|
|
@@ -518,35 +588,3 @@ export declare class MapperTaint {
|
|
|
518
588
|
/** Does a value the mapper BUILT embed, by reference, a selected record it read or was handed? */
|
|
519
589
|
private embedsSelected;
|
|
520
590
|
}
|
|
521
|
-
/**
|
|
522
|
-
* The commit log's scrub: `patch` with {@link LOG_PLACEHOLDER} at every path in `redactedPaths` that
|
|
523
|
-
* holds a defined value — the copy `recordCommit` records and feeds the redacted mirror.
|
|
524
|
-
*
|
|
525
|
-
* CLONE-FREE (9.33.0). The patch is the transaction buffer's commit-time payload, already the record's
|
|
526
|
-
* own copy (`TransactionBuffer · commit` clones each surviving path once; the buffer is dropped at
|
|
527
|
-
* commit), so the scrub copies only what it must not edit in place:
|
|
528
|
-
* - no path to scrub (no policy, no per-call mark — the common case) → `patch` ITSELF, no copy at all;
|
|
529
|
-
* - otherwise → a new root and a shallow copy of each container on a scrubbed path (`pathOps ·
|
|
530
|
-
* ownSpine`), every other subtree shared with `patch`. `patch` is never edited.
|
|
531
|
-
* The engine called the public {@link redactPatch} (a whole `structuredClone`) twice per commit before
|
|
532
|
-
* 9.33.0. The bytes are the same: a scrubbed path holds the placeholder, every other path the value the
|
|
533
|
-
* buffer cloned (pinned by the 9.18.1 / 9.19.1 redaction byte tests).
|
|
534
|
-
*
|
|
535
|
-
* Paths are scrubbed in the set's order, against the tree as scrubbed so far: a path under one already
|
|
536
|
-
* scrubbed finds a string, not a container, and is left alone (as before).
|
|
537
|
-
*
|
|
538
|
-
* INTERNAL — the result shares structure with `patch`. A caller outside the commit path wants
|
|
539
|
-
* {@link redactPatch}.
|
|
540
|
-
*
|
|
541
|
-
* @param redactedPaths DELIM-joined paths (`TransactionBuffer`'s `redactedPaths`; a bundle's
|
|
542
|
-
* `redactedPaths` array works too).
|
|
543
|
-
*/
|
|
544
|
-
export declare function scrubPatch(patch: MemoryPatch, redactedPaths: Iterable<string>): MemoryPatch;
|
|
545
|
-
/**
|
|
546
|
-
* Redacts sensitive values in a patch for logging/debugging — the PUBLIC scrub (`footprintjs/advanced`),
|
|
547
|
-
* its contract unchanged since 4.x: a fresh deep copy of `patch` (`structuredClone`) with
|
|
548
|
-
* {@link LOG_PLACEHOLDER} at every listed path that holds a defined value. Shares nothing with `patch`
|
|
549
|
-
* and never edits it. (Moved here from `memory/utils.ts` in 9.33.0; the engine's own commit path uses the
|
|
550
|
-
* clone-free {@link scrubPatch}.)
|
|
551
|
-
*/
|
|
552
|
-
export declare function redactPatch(patch: MemoryPatch, redactedSet: Set<string>): MemoryPatch;
|