@descryy/runtime-evidence-store 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/evidence-store.d.ts +204 -0
- package/dist/evidence-store.d.ts.map +1 -0
- package/dist/evidence-store.js +511 -0
- package/dist/evidence-store.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/redaction.d.ts +120 -0
- package/dist/redaction.d.ts.map +1 -0
- package/dist/redaction.js +337 -0
- package/dist/redaction.js.map +1 -0
- package/dist/replay.d.ts +118 -0
- package/dist/replay.d.ts.map +1 -0
- package/dist/replay.js +104 -0
- package/dist/replay.js.map +1 -0
- package/package.json +29 -0
package/dist/replay.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replay (plan §24).
|
|
3
|
+
*
|
|
4
|
+
* ## What this replays, and what it does not
|
|
5
|
+
*
|
|
6
|
+
* **It replays evidence, not the application.** Given an `executionId`, it
|
|
7
|
+
* returns the recorded execution, the environment it was recorded in, and its
|
|
8
|
+
* evidence in recorded order — enough to re-derive correlation, findings and
|
|
9
|
+
* an evidence package without booting anything. It does not spawn a process,
|
|
10
|
+
* drive a browser, or reissue a request, and it never will from here: those
|
|
11
|
+
* are `descry-runtime`'s live path, and a "replay" that quietly re-executed
|
|
12
|
+
* would produce a *new* observation while claiming to reproduce an old one.
|
|
13
|
+
*
|
|
14
|
+
* That distinction is the whole reason this file names its own limits at the
|
|
15
|
+
* top. §24's row was `[ ]` with the note *"having the data is not having the
|
|
16
|
+
* capability"* — the opposite error is equally available, and it is shipping
|
|
17
|
+
* something called replay that reproduces less than the name promises.
|
|
18
|
+
*
|
|
19
|
+
* ## The gap this had to close first
|
|
20
|
+
*
|
|
21
|
+
* Evidence survived a process restart. **The execution that produced it did
|
|
22
|
+
* not.** `Execution` lived in `ExecutionController`'s memory and nowhere on
|
|
23
|
+
* disk, so after a restart the store held a pile of rows keyed by an
|
|
24
|
+
* `executionId` that no longer resolved to an application, a commit, or a
|
|
25
|
+
* configuration. §24 marked "execution configuration — persisted with the
|
|
26
|
+
* execution" as done, and it was true of the object and false of the disk.
|
|
27
|
+
*
|
|
28
|
+
* `recordExecution` is that missing half. It is a **new table**, never a new
|
|
29
|
+
* column on `evidence` — an added table appears under `CREATE TABLE IF NOT
|
|
30
|
+
* EXISTS` on an existing store file, where an added column would need a
|
|
31
|
+
* migration this package has no mechanism for.
|
|
32
|
+
*
|
|
33
|
+
* ## Redaction applies here too, and that is not obvious
|
|
34
|
+
*
|
|
35
|
+
* §20's rows are all about payloads, and every one of them is about evidence.
|
|
36
|
+
* But a service command is `configuration.services[x].command`, and a command
|
|
37
|
+
* line is one of the classic places a credential is passed —
|
|
38
|
+
* `node server.mjs --api-key=…`, `DATABASE_URL=… node app.js`. The execution
|
|
39
|
+
* record goes through the same `redact()` the evidence write path uses, for
|
|
40
|
+
* the same reason and on the same terms. `redactedKeys` (RT-063) reports what
|
|
41
|
+
* it caught.
|
|
42
|
+
*
|
|
43
|
+
* ## The environment fingerprint is deliberately narrow
|
|
44
|
+
*
|
|
45
|
+
* Four fields: node version, platform, arch, and the declared service
|
|
46
|
+
* commands. **`process.env` is not captured, and its absence is the design.**
|
|
47
|
+
* §20 records that the injected process environment is not captured or
|
|
48
|
+
* filtered — *"so there is nothing to leak yet, which is not the same as
|
|
49
|
+
* filtering."* Capturing it here to improve reproducibility would create
|
|
50
|
+
* exactly the leak that row says does not exist, inside the one module whose
|
|
51
|
+
* output is meant to be safe to hand to a model. A narrower fingerprint that
|
|
52
|
+
* can be trusted beats a fuller one that cannot.
|
|
53
|
+
*/
|
|
54
|
+
/**
|
|
55
|
+
* The current machine's fingerprint.
|
|
56
|
+
*
|
|
57
|
+
* `serviceCommands` comes from the caller's configuration rather than being
|
|
58
|
+
* discovered, because there is nothing on a machine to discover it from — an
|
|
59
|
+
* execution's services are a property of the run, not of the host.
|
|
60
|
+
*/
|
|
61
|
+
export function captureEnvironment(serviceCommands = {}, runtime = process) {
|
|
62
|
+
return {
|
|
63
|
+
nodeVersion: runtime.version,
|
|
64
|
+
platform: runtime.platform,
|
|
65
|
+
arch: runtime.arch,
|
|
66
|
+
serviceCommands,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Differences between the environment an execution was recorded in and the
|
|
71
|
+
* one it is being replayed in.
|
|
72
|
+
*
|
|
73
|
+
* **Reported, never enforced.** A replay in a different node version is not
|
|
74
|
+
* wrong; it is a fact a reader needs when a re-derived finding disagrees with
|
|
75
|
+
* the original. Refusing to replay would be this module deciding a question
|
|
76
|
+
* it has no information about.
|
|
77
|
+
*/
|
|
78
|
+
export function environmentDifferences(recorded, current) {
|
|
79
|
+
const differences = [];
|
|
80
|
+
if (recorded.nodeVersion !== current.nodeVersion) {
|
|
81
|
+
differences.push(`node ${recorded.nodeVersion} → ${current.nodeVersion}`);
|
|
82
|
+
}
|
|
83
|
+
if (recorded.platform !== current.platform) {
|
|
84
|
+
differences.push(`platform ${recorded.platform} → ${current.platform}`);
|
|
85
|
+
}
|
|
86
|
+
if (recorded.arch !== current.arch) {
|
|
87
|
+
differences.push(`arch ${recorded.arch} → ${current.arch}`);
|
|
88
|
+
}
|
|
89
|
+
const names = new Set([...Object.keys(recorded.serviceCommands), ...Object.keys(current.serviceCommands)]);
|
|
90
|
+
for (const name of [...names].sort()) {
|
|
91
|
+
const before = recorded.serviceCommands[name];
|
|
92
|
+
const after = current.serviceCommands[name];
|
|
93
|
+
if (before === after)
|
|
94
|
+
continue;
|
|
95
|
+
if (before === undefined)
|
|
96
|
+
differences.push(`service "${name}" is new`);
|
|
97
|
+
else if (after === undefined)
|
|
98
|
+
differences.push(`service "${name}" is gone`);
|
|
99
|
+
else
|
|
100
|
+
differences.push(`service "${name}" command changed: ${before} → ${after}`);
|
|
101
|
+
}
|
|
102
|
+
return differences;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=replay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay.js","sourceRoot":"","sources":["../src/replay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAiDH;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,kBAAoD,EAAE,EACtD,UAA+D,OAAO;IAEtE,OAAO;QACL,WAAW,EAAE,OAAO,CAAC,OAAO;QAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,eAAe;KAChB,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CACpC,QAAgC,EAChC,OAA+B;IAE/B,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,IAAI,QAAQ,CAAC,WAAW,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC;QACjD,WAAW,CAAC,IAAI,CAAC,QAAQ,QAAQ,CAAC,WAAW,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC3C,WAAW,CAAC,IAAI,CAAC,YAAY,QAAQ,CAAC,QAAQ,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC;QACnC,WAAW,CAAC,IAAI,CAAC,QAAQ,QAAQ,CAAC,IAAI,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC3G,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,MAAM,KAAK,KAAK;YAAE,SAAS;QAC/B,IAAI,MAAM,KAAK,SAAS;YAAE,WAAW,CAAC,IAAI,CAAC,YAAY,IAAI,UAAU,CAAC,CAAC;aAClE,IAAI,KAAK,KAAK,SAAS;YAAE,WAAW,CAAC,IAAI,CAAC,YAAY,IAAI,WAAW,CAAC,CAAC;;YACvE,WAAW,CAAC,IAAI,CAAC,YAAY,IAAI,sBAAsB,MAAM,MAAM,KAAK,EAAE,CAAC,CAAC;IACnF,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@descryy/runtime-evidence-store",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Evidence persistence keyed by executionId, with redaction enforced on write -- there is no path to read an unredacted payload.",
|
|
6
|
+
"license": "UNLICENSED",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=22.5"
|
|
9
|
+
},
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"registry": "https://registry.npmjs.org",
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc -b"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@descryy/runtime-contracts": "0.0.0"
|
|
28
|
+
}
|
|
29
|
+
}
|