@descryy/runtime-evidence-store 0.3.0 → 0.4.1

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.
@@ -1,19 +1,13 @@
1
1
  /**
2
- * Evidence store (plan §13; plan §36 gate 9 "evidence persistence").
3
- * Persistence keyed by executionId, backed by `node:sqlite` — mirrors
4
- * descry-core's choice (CLAUDE.md: "node:sqlite behind a driver
5
- * interface") for the same reason: zero native deps, no node-gyp-per-
6
- * platform distribution problem. A full swappable-driver abstraction
7
- * (descry-core's `SqlDriver`) is skipped here — one table, no real
8
- * swap-target in view — but the row-rehydration pattern is kept:
9
- * `node:sqlite` returns null-prototype row objects, which trips up
10
- * `JSON.stringify` and structural-equality checks in ways that are easy to
11
- * miss, so every row is spread into a plain object before use.
2
+ * Evidence store, keyed by executionId, backed by `node:sqlite` (mirrors
3
+ * descry-core's driver choice: zero native deps, no node-gyp problem). No
4
+ * swappable-driver abstraction here — one table, no swap target — but the
5
+ * row-rehydration pattern is kept: `node:sqlite` returns null-prototype
6
+ * rows, which trips up `JSON.stringify` and equality checks, so every row
7
+ * is spread into a plain object before use.
12
8
  *
13
- * `node:sqlite` is experimental in this Node version and prints an
14
- * `ExperimentalWarning`. descry-core's own policy is to suppress that only
15
- * at a CLI entrypoint, never in library code or tests — this package has
16
- * no entrypoint of its own, so nothing here suppresses it.
9
+ * `node:sqlite` prints an `ExperimentalWarning`; suppressed only at a CLI
10
+ * entrypoint by policy, and this package has none, so nothing suppresses it here.
17
11
  */
18
12
  import { DatabaseSync } from "node:sqlite";
19
13
  import { randomUUID } from "node:crypto";
@@ -49,18 +43,10 @@ export class EvidenceStore {
49
43
  collector_version TEXT NOT NULL
50
44
  );
51
45
  CREATE INDEX IF NOT EXISTS idx_evidence_execution ON evidence(execution_id);
52
- -- §24's missing half. Evidence survived a process restart; the
53
- -- execution that produced it did not -- it lived in
54
- -- ExecutionController's memory and nowhere on disk, so after a
55
- -- restart the store held rows keyed by an executionId that no longer
56
- -- resolved to an application, a commit, or a configuration.
57
- --
58
- -- A NEW TABLE, never a new column on the evidence table. An added
59
- -- table appears under CREATE TABLE IF NOT EXISTS on an existing store
60
- -- file;
61
- -- an added column would need a migration this package has no
62
- -- mechanism for, and inventing one to persist a fingerprint would be
63
- -- a schema-versioning decision taken sideways.
46
+ -- §24's missing half: evidence survived a restart, the execution
47
+ -- that produced it did not. A NEW TABLE, never a new evidence
48
+ -- column — an added column would need a migration this package has
49
+ -- no mechanism for.
64
50
  CREATE TABLE IF NOT EXISTS executions (
65
51
  execution_id TEXT PRIMARY KEY,
66
52
  application TEXT NOT NULL,
@@ -77,34 +63,23 @@ export class EvidenceStore {
77
63
  CREATE INDEX IF NOT EXISTS idx_evidence_service ON evidence(service);
78
64
  CREATE INDEX IF NOT EXISTS idx_evidence_node ON evidence(graph_node_id);
79
65
  CREATE INDEX IF NOT EXISTS idx_evidence_timestamp ON evidence(timestamp);
80
- -- An expression index, because source_location is stored as JSON
81
- -- rather than split into columns. Splitting it would be the faster
82
- -- schema and would also mean migrating every existing store on disk;
83
- -- the JSON stays authoritative and the index makes the file lookup a
84
- -- seek instead of a scan.
66
+ -- Expression index — source_location stays JSON (splitting would mean
67
+ -- migrating every existing store) but this makes lookup a seek, not a scan.
85
68
  CREATE INDEX IF NOT EXISTS idx_evidence_source_file ON evidence(json_extract(source_location, '$.file'));
86
69
  `);
87
70
  }
88
71
  /**
89
- * The only way to persist evidence. Redaction runs here, unconditionally
72
+ * The only way to persist evidence. Redaction runs here unconditionally
90
73
  * — `EvidenceInput` has no `redactionStatus` field a caller could set,
91
- * so there is no way to write a record claiming redaction happened
92
- * without redact() actually having run. This is the structural
93
- * guarantee plan §28 asks for: "raw runtime evidence must not
94
- * automatically become unrestricted AI context."
74
+ * so there's no way to write a record claiming redaction happened
75
+ * without it actually running (§28's structural guarantee).
95
76
  */
96
77
  write(input) {
97
- // **Validated at the boundary, not trusted from the type system (§3).**
98
- // `EvidenceInput` is typed, and inside one compiled program that is
99
- // enough. It stops being enough the moment a value arrives from anywhere
100
- // the compiler did not check — a JSON body, a stored row from another
101
- // version, a hand-written fixture, a collector built against an older
102
- // contract. §3's own rows are "invalid event rejected" and "unknown event
103
- // handled explicitly", and a compile-time union answers neither.
104
- //
105
- // Throws rather than coerces. A caller writing an event type this build
106
- // does not know is a bug, and the cheapest moment to say so is before the
107
- // row exists.
78
+ // Validated at the boundary, not trusted from the type system — a
79
+ // compile-time union says nothing about a value from a JSON body, an
80
+ // old stored row, or a collector on an older contract. Throws rather
81
+ // than coerces: an unknown event type is a bug, cheapest to say so
82
+ // before the row exists.
108
83
  assertInVocabulary("eventType", input.eventType, RUNTIME_EVENT_TYPES);
109
84
  assertInVocabulary("source", input.source, EVIDENCE_SOURCES);
110
85
  const { payload, redactionStatus } = redact(input.payload, this.#redactionPolicy);
@@ -118,7 +93,7 @@ export class EvidenceStore {
118
93
  .run(evidence.evidenceId, evidence.executionId, evidence.timestamp, evidence.source, evidence.service, evidence.process, evidence.eventType, JSON.stringify(evidence.payload), evidence.traceId, evidence.requestId, evidence.correlationId, evidence.graphNodeId, evidence.sourceLocation ? JSON.stringify(evidence.sourceLocation) : null, evidence.stackTrace ? JSON.stringify(evidence.stackTrace) : null, evidence.confidence, evidence.redactionStatus, evidence.collectorVersion);
119
94
  return evidence;
120
95
  }
121
- /** Every item this execution produced, oldest first — retrievable after the execution has ended, as long as the store is reopened against the same file (plan §36 gate 9). */
96
+ /** Every item this execution produced, oldest first — retrievable after the execution ends, as long as the store reopens against the same file. */
122
97
  getByExecution(executionId) {
123
98
  const rows = this.#db
124
99
  .prepare(`SELECT * FROM evidence WHERE execution_id = ? ORDER BY timestamp ASC`)
@@ -130,18 +105,12 @@ export class EvidenceStore {
130
105
  return row ? rowToEvidence(row) : null;
131
106
  }
132
107
  /**
133
- * Every row whose enum fields this build cannot interpret (§3).
134
- *
135
- * The explicit runtime path for an unknown event. Reads the raw columns
136
- * without rehydrating, so it works on precisely the store that `query()`
137
- * refuses — a caller that hits the refusal can call this to learn which
138
- * rows, which fields and which values, instead of having a throw and no
139
- * next step.
140
- *
141
- * Deliberately reports rather than repairs. Rewriting an unknown
142
- * `event_type` to something this build knows would be inventing an
143
- * observation, and deleting the row would destroy evidence that a newer
144
- * build can read perfectly well.
108
+ * Every row whose enum fields this build can't interpret. Reads raw
109
+ * columns without rehydrating, so it works on the store that `query()`
110
+ * refuses — gives a caller a next step instead of just a throw. Reports
111
+ * rather than repairs: rewriting an unknown value would invent an
112
+ * observation, and deleting the row would destroy evidence a newer build
113
+ * can read fine.
145
114
  */
146
115
  integrityCheck() {
147
116
  const rows = this.#db
@@ -163,19 +132,15 @@ export class EvidenceStore {
163
132
  return issues;
164
133
  }
165
134
  /**
166
- * Persist the execution behind an `executionId` (§24).
135
+ * Persist the execution behind an `executionId`.
167
136
  *
168
- * **The configuration is redacted on the way in, and that is not an
169
- * over-application of §20.** Every one of §20's rows is about an evidence
170
- * payload, but `configuration.services[x].command` is a command line, and
171
- * a command line is one of the classic places a credential travels:
172
- * `node server.mjs --api-key=…`. The same `redact()` the evidence write
173
- * path uses runs here, on the same terms, and `redactedKeys` reports what
174
- * it caught rather than leaving a caller to guess.
137
+ * The configuration is redacted on the way in too —
138
+ * `configuration.services[x].command` is a command line, a classic place
139
+ * a credential travels. Same `redact()` as the evidence write path;
140
+ * `redactedKeys` reports what it caught.
175
141
  *
176
- * Re-recording the same `executionId` replaces the row. An execution is
177
- * recorded once by the component that owns it; a second record for the
178
- * same id is a re-run of that recording, not a second execution.
142
+ * Re-recording the same `executionId` replaces the row — a second record
143
+ * is a re-run of that recording, not a second execution.
179
144
  */
180
145
  recordExecution(input) {
181
146
  const { payload: configuration, redactedKeys } = redact(input.configuration, this.#redactionPolicy);
@@ -248,19 +213,15 @@ export class EvidenceStore {
248
213
  };
249
214
  }
250
215
  /**
251
- * Replay an execution's evidence (§24).
252
- *
253
- * **Replays evidence, not the application.** Nothing is spawned, driven or
254
- * reissued; this returns what was recorded, in recorded order, so
255
- * correlation, findings and an evidence package can be re-derived without
256
- * booting anything. A replay that quietly re-executed would produce a *new*
257
- * observation while claiming to reproduce an old one.
216
+ * Replay an execution's evidence. Replays evidence, not the application —
217
+ * nothing is spawned, driven or reissued, just returned in recorded
218
+ * order. A replay that re-executed would produce a *new* observation
219
+ * while claiming to reproduce an old one.
258
220
  *
259
221
  * Throws for an unrecorded execution rather than returning an empty
260
- * replay. Evidence rows can exist for an `executionId` that was never
261
- * recorded — that is precisely the pre-§24 state — and answering with
262
- * "here is your replay, minus the execution" would present the gap as a
263
- * result.
222
+ * replay — evidence rows can exist for an id that was never recorded,
223
+ * and answering with "here is your replay, minus the execution" would
224
+ * present the gap as a result.
264
225
  */
265
226
  replay(executionId, currentEnvironment) {
266
227
  const execution = this.getExecution(executionId);
@@ -287,11 +248,8 @@ export class EvidenceStore {
287
248
  "observed nothing) and is not the same as an unrecorded execution, which throws.",
288
249
  });
289
250
  }
290
- // getByExecution orders by timestamp, so this cannot detect a bad sort —
291
- // it detects a recorded stream whose own timestamps were never
292
- // monotonic, which means "recorded order" and "the order things
293
- // happened" are not the same list and a reader replaying by index is
294
- // reading a sequence that never occurred.
251
+ // Detects a recorded stream whose timestamps were never monotonic —
252
+ // "recorded order" and "the order things happened" diverge.
295
253
  for (let i = 1; i < evidence.length; i += 1) {
296
254
  if (evidence[i - 1].timestamp === evidence[i].timestamp)
297
255
  continue;
@@ -310,28 +268,16 @@ export class EvidenceStore {
310
268
  /**
311
269
  * Record that correlation resolved this evidence to a graph node.
312
270
  *
313
- * **Written because the correlation was never durable, and that made two
314
- * of the evidence package's four selection tiers inert.** Found by
315
- * mutation, not by reading: `assembleEvidencePackage`'s tier 2 queries
316
- * `graphNodeId`, and a mutation that dropped the execution scope from that
317
- * query changed nothing at all — because in the real pipeline no stored row
318
- * has a `graphNodeId` to match. `graphNodeId` was set in memory at
319
- * composition time, on a copy, and thrown away with the array that held it.
320
- * Every downstream question of the form "what else named this node" was
321
- * therefore answerable only for evidence some caller happened to still be
322
- * holding.
271
+ * Written because correlation was never durable — `graphNodeId` was set
272
+ * in memory at composition time, on a copy, and thrown away with it,
273
+ * making two of the evidence package's four selection tiers inert.
274
+ * Found by mutation testing, not by reading.
323
275
  *
324
- * **Refuses to re-attribute to a different node.** One observation
325
- * genuinely can name two graph entities (RT-052's backend exception names
326
- * the endpoint in its text and the function in its stack), and the answer
327
- * to that is `EvidenceAttribution` passed alongside the evidence — an
328
- * output of correlation, not a property of the observation. Letting this
329
- * method overwrite would silently discard the first correlation and leave
330
- * the store asserting the second as if it were the only one. Idempotent
331
- * for the same node, so re-running a correlation pass is safe.
332
- *
333
- * Throws for an unknown `evidenceId`: a caller attributing evidence this
334
- * store does not hold has a bug, and writing nothing would hide it.
276
+ * Refuses to re-attribute to a different node: one observation can
277
+ * genuinely name two graph entities (RT-052), and that's expressed as an
278
+ * `EvidenceAttribution` alongside the evidence, not by overwriting the
279
+ * stored one. Idempotent for the same node. Throws for an unknown
280
+ * `evidenceId` — a caller bug, not something to write around silently.
335
281
  */
336
282
  attribute(evidenceId, graphNodeId) {
337
283
  const existing = this.getById(evidenceId);
@@ -348,30 +294,17 @@ export class EvidenceStore {
348
294
  this.#db.prepare(`UPDATE evidence SET graph_node_id = ? WHERE evidence_id = ?`).run(graphNodeId, evidenceId);
349
295
  }
350
296
  /**
351
- * The general query surface (§19).
352
- *
353
- * Before this, the store answered two questions — by id and by execution —
354
- * and §19 asks for six axes: trace, service, graph node, source location,
355
- * time, and execution. **Five of the six did not exist**, which is
356
- * invisible from "evidence persistence works" and was found by auditing
357
- * the checklist rather than by anything failing.
297
+ * The general query surface. Before this, the store answered two
298
+ * questions (by id, by execution); five of six needed axes didn't exist.
358
299
  *
359
- * **`executionId` is required and may be explicitly `null`, and that is
360
- * the load-bearing design choice here.** Every other field is optional.
361
- * Evidence not leaking between executions is a guarantee this repo
362
- * enforces elsewhere (`composeFinding` excludes foreign executions with a
363
- * named reason), and a query is the obvious way to lose it: ask for a
364
- * trace id and quietly receive a prior run's evidence too. Making the
365
- * field optional-with-a-default would mean the safe behaviour depends on
366
- * remembering to pass something, which is how the default gets forgotten
367
- * exactly once. Passing `null` is a deliberate statement that a
368
- * cross-execution answer is wanted — the same discipline
369
- * `resolveSymbolNode` applies to `repo`, where there is no honest default
370
- * either.
300
+ * `executionId` is required and may be explicitly `null` — the
301
+ * load-bearing choice here. Making it optional-with-a-default risks a
302
+ * caller forgetting it and silently leaking evidence across executions;
303
+ * passing `null` is a deliberate statement that a cross-execution answer
304
+ * is wanted, same discipline `resolveSymbolNode` applies to `repo`.
371
305
  *
372
- * Criteria combine with AND. An empty criteria object plus a null
373
- * execution returns everything, which is a real request (a store dump)
374
- * and is spelled out rather than reachable by accident.
306
+ * Criteria combine with AND. Empty criteria + null execution returns
307
+ * everything — a real request (store dump), spelled out on purpose.
375
308
  */
376
309
  query(criteria) {
377
310
  const clauses = [];
@@ -380,11 +313,8 @@ export class EvidenceStore {
380
313
  clauses.push("execution_id = ?");
381
314
  params.push(criteria.executionId);
382
315
  }
383
- // Each of these is an exact match, never a LIKE. A prefix or substring
384
- // match on a trace id or a service name would return evidence about a
385
- // *different* thing that happens to share a prefix -- RT-031's
386
- // identity-proxy class, and the last place it belongs is the query
387
- // layer that everything above reads through.
316
+ // Exact match, never LIKE — a prefix match would return evidence about
317
+ // a *different* thing sharing a prefix (RT-031's identity-proxy class).
388
318
  for (const [column, value] of [
389
319
  ["trace_id", criteria.traceId],
390
320
  ["request_id", criteria.requestId],
@@ -429,14 +359,10 @@ export class EvidenceStore {
429
359
  return rows.map(rowToEvidence);
430
360
  }
431
361
  /**
432
- * Deletes every row whose own `timestamp` is older than `retentionMs`
433
- * (constructor option) relative to `now` (defaults to the real current
434
- * time; overridable so a test can purge without a real sleep). Never
435
- * called automatically -- no timer, no call from `write()` -- a caller
436
- * decides when retention actually runs. Throws rather than silently
437
- * no-op-ing if `retentionMs` was never configured: a caller explicitly
438
- * asking to purge with no policy in place is a configuration mistake
439
- * worth surfacing, not masking.
362
+ * Deletes rows older than `retentionMs` relative to `now` (overridable
363
+ * for tests). Never called automatically. Throws rather than no-op-ing
364
+ * if `retentionMs` was never configured — purging with no policy is a
365
+ * config mistake worth surfacing.
440
366
  */
441
367
  purgeExpired(now = new Date()) {
442
368
  if (this.#retentionMs === null) {
@@ -450,14 +376,7 @@ export class EvidenceStore {
450
376
  this.#db.close();
451
377
  }
452
378
  }
453
- /**
454
- * Throws when a value is outside the vocabulary this build knows.
455
- *
456
- * The message names the value **and** the vocabulary, because the two useful
457
- * conclusions are opposite: an unknown value is either a typo (fix the caller)
458
- * or a newer contract (this build is the old one), and only seeing both lists
459
- * distinguishes them.
460
- */
379
+ /** Throws when a value is outside this build's vocabulary. Names both the value and the vocabulary — an unknown value is either a typo or a newer contract, and only seeing both distinguishes them. */
461
380
  function assertInVocabulary(field, value, vocabulary) {
462
381
  if (vocabulary.includes(value))
463
382
  return;
@@ -468,21 +387,12 @@ function assertInVocabulary(field, value, vocabulary) {
468
387
  /**
469
388
  * Rehydrate a row, refusing one this build cannot interpret.
470
389
  *
471
- * **The previous version blind-cast every enum field** — `row.event_type as
472
- * Evidence["eventType"]` — which is a `as` that cannot fail and a value that
473
- * can. A store file written by a build with an extra `RuntimeEventType`, a
474
- * restored backup, or a hand-edited row produced a fully-typed `Evidence`
475
- * whose `eventType` no `switch` in this program handles, and nothing anywhere
476
- * said so. §3's "unknown event handled explicitly" row was open for exactly
477
- * this, and the handling could not be added upstream because there was no
478
- * point at which the unknown was ever recognised as unknown.
479
- *
480
- * **It throws rather than skipping.** Skipping would return fewer rows while
481
- * every caller treated the result as complete — the "unsupported silently
482
- * becomes no failure" shape, applied to a query result, which is the worst
483
- * place for it: `composeFinding` would compose over a subset and report
484
- * confidently. `integrityCheck()` exists so a caller facing this can find out
485
- * how bad it is without the throw being a dead end.
390
+ * Previously blind-cast every enum field (`as Evidence["eventType"]`) — an
391
+ * `as` that can't fail on a value that can. A store from a build with an
392
+ * extra event type produced a fully-typed `Evidence` no `switch` handled,
393
+ * silently. Throws rather than skips: skipping would let `composeFinding`
394
+ * compose over a subset and report confidently. `integrityCheck()` gives a
395
+ * caller a next step instead of a dead-end throw.
486
396
  */
487
397
  function rowToEvidence(raw) {
488
398
  const row = { ...raw };
@@ -513,14 +423,10 @@ function rowToEvidence(raw) {
513
423
  }
514
424
  /**
515
425
  * `serviceName -> command` out of an `ExecutionConfiguration`-shaped object.
516
- *
517
- * Written defensively against `unknown` rather than typed against
518
- * `ExecutionConfiguration`, because the configuration reaching this store has
519
- * already been through `redact()` and is no longer that type: a redacted
520
- * command is the string `[REDACTED]`, which is still a string, but a redacted
521
- * *services* object could in principle be a marker too. Reading it
522
- * structurally means a surprising shape yields an empty map rather than a
523
- * throw inside a persistence call.
426
+ * Written defensively against `unknown`, not typed against
427
+ * `ExecutionConfiguration` — the configuration has already been through
428
+ * `redact()` and may no longer match that shape. A surprising shape yields
429
+ * an empty map, not a throw inside a persistence call.
524
430
  */
525
431
  function serviceCommandsOf(configuration) {
526
432
  const services = configuration?.services;
@@ -1 +1 @@
1
- {"version":3,"file":"evidence-store.js","sourceRoot":"","sources":["../src/evidence-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"evidence-store.js","sourceRoot":"","sources":["../src/evidence-store.ts"],"names":[],"mappings":"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"}
@@ -1,45 +1,23 @@
1
1
  /**
2
- * Redaction (plan §28): "Raw runtime evidence must not automatically
3
- * become unrestricted AI context." This runs at write time, unconditionally
4
- * — `EvidenceStore.write` has no code path that skips it — rather than at
5
- * read time, because a read-time pass is one forgotten call site away from
6
- * failing (peer's framing, kept verbatim since it's exactly right).
2
+ * Redaction (plan §28): raw runtime evidence must not automatically become
3
+ * unrestricted AI context. Runs at write time, unconditionally — a
4
+ * read-time pass is one forgotten call site away from failing.
7
5
  *
8
- * Extends the original key-name-only pass with the two capabilities §28
9
- * names that a pure key-name walk structurally cannot reach:
6
+ * Extends the key-name-only pass with two capabilities a pure key walk
7
+ * can't reach: body filtering (bodies are JSON/text-*encoded strings*, not
8
+ * parsed objects, so a secret inside one was invisible to key matching —
9
+ * body-bearing keys are now parsed if JSON and recursed into, or
10
+ * pattern-scanned as text), and PII filtering, kept as a separate
11
+ * independently toggleable pattern from credentials.
10
12
  *
11
- * - **Body filtering.** `NETWORK_REQUEST`/`NETWORK_RESPONSE` evidence
12
- * (`packages/browser`) carries `postData`/`body` as a JSON- or
13
- * text-*encoded string*, not a parsed object -- the original redact()
14
- * walks object structure, so a secret sitting inside that string (a
15
- * `{"password": "hunter2"}` request body, say) was invisible to it
16
- * regardless of how complete `SENSITIVE_KEY_PATTERN` was. Body-bearing
17
- * keys now get parsed (if JSON) and recursed into with the same rules,
18
- * or pattern-scanned as text otherwise.
19
- * - **PII-aware field filtering.** A separate, independently toggleable
20
- * pattern from credentials -- these are different concerns with
21
- * different owners in a real system (security vs. privacy), and
22
- * collapsing them into one pattern would make either impossible to
23
- * reason about or configure on its own.
13
+ * Configurable via `RedactionPolicy` (`EvidenceStoreOptions`). Every filter
14
+ * fails closed: content it can't classify at all is withheld wholesale
15
+ * rather than assumed safe. A marker replaces the value in place — the key
16
+ * survives so a reader can see *that* something was withheld.
24
17
  *
25
- * **Configurable by whom, refused how (the two questions this row asked to
26
- * have decided rather than defaulted):** by whoever constructs the
27
- * `EvidenceStore` (`RedactionPolicy`, plumbed through
28
- * `EvidenceStoreOptions` -- see `evidence-store.ts`), and every filter
29
- * fails closed, disclosed, not silent: a value the body/PII filter cannot
30
- * classify at all (not JSON, not text that looks safe to pattern-scan) is
31
- * withheld wholesale rather than passed through on the assumption that
32
- * "couldn't parse it" means "couldn't be sensitive." A marker replaces the
33
- * value in place -- the key survives, so a reader can see *that* something
34
- * was withheld, never just find it missing (same discipline the original
35
- * key-based pass already established with `[REDACTED]`).
36
- *
37
- * **Not a claim of completeness.** Pattern-based text scanning is
38
- * inherently partial -- a sensitive string shaped unlike every pattern
39
- * here passes through unredacted, honestly, not silently promised as
40
- * covered. What the "fail closed" guarantee actually claims: content this
41
- * module cannot even classify never leaks by default; content it can
42
- * classify gets the patterns below applied, not more.
18
+ * Not a claim of completeness — pattern-based text scanning is inherently
19
+ * partial. Fail-closed only claims: unclassifiable content never leaks by
20
+ * default; classifiable content gets the patterns below, not more.
43
21
  */
44
22
  import type { RedactionStatus } from "@descryy/runtime-contracts";
45
23
  export interface RedactionPolicy {
@@ -52,66 +30,33 @@ export interface RedactionResult {
52
30
  readonly payload: unknown;
53
31
  readonly redactionStatus: RedactionStatus;
54
32
  /**
55
- * The **key paths** this call redacted by name — `"sessionId"`,
56
- * `"headers.authorization"`, `"items[0].email"`. Key names only; no value
57
- * ever appears here, which is what makes it safe to log, assert on, and
58
- * hand to an operator auditing a policy.
59
- *
60
- * **Added because `redactionStatus` alone made a real bug invisible for
61
- * the life of a package (RT-063).** `SENSITIVE_KEY_PATTERN`'s
62
- * `session(id)?` alternative matches the literal key `sessionId`, and all
63
- * three browser collectors carried `sessionId: session.sessionId` — an
64
- * internal `BrowserSession` handle, not a credential. Every
65
- * `NAVIGATION` / `CLICK` / `INPUT` / `NETWORK_*` / `CONSOLE_MESSAGE` that
66
- * package ever produced had it silently replaced with a marker.
67
- *
68
- * The status flag could not reveal it. `redacted` is what a real payload
69
- * is *expected* to report, so the one signal that existed said exactly
70
- * what it would have said if nothing were wrong — the silent-degradation
71
- * shape this repo keeps meeting, in a module whose whole job is to be
72
- * trustworthy about what it touched.
33
+ * The key paths this call redacted by name — `"sessionId"`,
34
+ * `"headers.authorization"`. Key names only, no values, safe to log or
35
+ * assert on.
73
36
  *
74
- * A collector author can now assert `redactedKeys` is empty for a benign
75
- * payload, which is a claim the boolean cannot express.
37
+ * Added because `redactionStatus` alone hid a real bug (RT-063):
38
+ * `session(id)?` matched the literal key `sessionId`, an internal
39
+ * `BrowserSession` handle, not a credential — silently marker-replaced
40
+ * across every browser collector event, with `redacted` reporting
41
+ * exactly what it would say if nothing were wrong. A collector author
42
+ * can now assert `redactedKeys` is empty for a benign payload.
76
43
  *
77
- * **Text-scan hits are not listed here.** A secret found inside a body
78
- * string by pattern has no key path — it was matched in free text — and
79
- * inventing one (`"body[chars 40-64]"`) would put a fragment of the
80
- * surrounding value into a field documented as name-only. Those still
81
- * flip `redactionStatus`; `redactedKeys` answers "which field did the
82
- * policy hit by name", not "was anything redacted at all".
44
+ * Text-scan hits are NOT listed here — a match in free text has no key
45
+ * path, and inventing one would leak a value fragment into a field
46
+ * documented as name-only. Those still flip `redactionStatus`.
83
47
  */
84
48
  readonly redactedKeys: readonly string[];
85
49
  }
86
50
  export declare function redact(payload: unknown, policy?: RedactionPolicy): RedactionResult;
87
- /**
88
- * Which keys the default policy would redact, without redacting anything.
89
- *
90
- * The tool a collector author needs *before* shipping a payload shape: hand
91
- * it the key names, get back the ones that collide and would be wiped. The
92
- * `sessionId` collision (RT-063) was a name nobody thought to check against
93
- * a pattern list nobody thought to read, and the check costs one call.
94
- */
51
+ /** Which keys the default policy would redact, without redacting anything — check a payload shape before shipping it (RT-063's `sessionId` collision cost one call to catch). */
95
52
  export declare function collidingKeys(keys: readonly string[], policy?: RedactionPolicy): readonly string[];
96
53
  /**
97
54
  * Redact credential values out of a command line, keeping the shape.
98
- *
99
- * Two forms, because a command line has two:
100
- *
101
- * - **Attached** -- `--api-key=SEKRET`, `TOKEN:abc`, `DB_PASSWORD=hunter2`.
102
- * The name and the separator survive; only the value is replaced.
103
- * - **Detached** -- `["--api-key", "SEKRET"]` or `--api-key SEKRET`, where the
104
- * secret is the *next* token. This is the form a naive per-token scanner
105
- * misses entirely: `SEKRET` on its own carries nothing that marks it as a
106
- * secret, and the only thing that does is the token before it.
107
- *
108
- * A detached flag at the very end of a command consumes nothing -- there is
109
- * no value to redact, and inventing one would corrupt the command.
110
- *
111
- * The name and separator are kept on purpose. A command redacted to
112
- * `[REDACTED]` wholesale is useless to the reader it was persisted for; a
113
- * command redacted to `node server.mjs --api-key=[REDACTED]` still answers
114
- * "what was run, and with what shape of argument".
55
+ * Two forms: attached (`--api-key=SEKRET`, name/separator survive) and
56
+ * detached (`--api-key SEKRET`, secret is the *next* token — what a naive
57
+ * per-token scanner misses). A detached flag at the end consumes nothing.
58
+ * Name/separator kept so a redacted command still answers "what was run,
59
+ * with what shape of argument", not just `[REDACTED]` wholesale.
115
60
  */
116
61
  export declare function redactCommand(value: string | readonly string[]): {
117
62
  value: string | string[];
@@ -1 +1 @@
1
- {"version":3,"file":"redaction.d.ts","sourceRoot":"","sources":["../src/redaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AA2GlE,MAAM,WAAW,eAAe;IAC9B,4JAA4J;IAC5J,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,+FAA+F;IAC/F,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;CACjC;AAID,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED,wBAAgB,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,GAAE,eAAoB,GAAG,eAAe,CAStF;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,GAAE,eAAoB,GAAG,SAAS,MAAM,EAAE,CAQtG;AA2HD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG;IAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAahH"}
1
+ {"version":3,"file":"redaction.d.ts","sourceRoot":"","sources":["../src/redaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAkElE,MAAM,WAAW,eAAe;IAC9B,4JAA4J;IAC5J,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,+FAA+F;IAC/F,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;CACjC;AAID,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED,wBAAgB,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,GAAE,eAAoB,GAAG,eAAe,CAStF;AAED,iLAAiL;AACjL,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,GAAE,eAAoB,GAAG,SAAS,MAAM,EAAE,CAQtG;AAoHD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG;IAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAUhH"}