@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/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
+ }