@codyswann/lisa 4.28.5 → 4.29.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.
Files changed (188) hide show
  1. package/all/copy-overwrite/scripts/lisa-gates.mjs +2 -1
  2. package/all/copy-overwrite/scripts/lisa-hooks/sonar-secrets.sh +3 -2
  3. package/cdk/create-only/vitest.config.local.ts +5 -1
  4. package/cdk/package-lisa/package.lisa.json +14 -7
  5. package/dist/cli/lisa-test-run-bootstrap.d.ts +3 -0
  6. package/dist/cli/lisa-test-run-bootstrap.d.ts.map +1 -0
  7. package/dist/cli/lisa-test-run-bootstrap.js +201 -0
  8. package/dist/cli/lisa-test-run-bootstrap.js.map +1 -0
  9. package/dist/cli/lisa-test-run-ipc.d.ts +42 -0
  10. package/dist/cli/lisa-test-run-ipc.d.ts.map +1 -0
  11. package/dist/cli/lisa-test-run-ipc.js +200 -0
  12. package/dist/cli/lisa-test-run-ipc.js.map +1 -0
  13. package/dist/cli/lisa-test-run-process-group.d.ts +30 -0
  14. package/dist/cli/lisa-test-run-process-group.d.ts.map +1 -0
  15. package/dist/cli/lisa-test-run-process-group.js +123 -0
  16. package/dist/cli/lisa-test-run-process-group.js.map +1 -0
  17. package/dist/cli/lisa-test-run-reaper.d.ts +3 -0
  18. package/dist/cli/lisa-test-run-reaper.d.ts.map +1 -0
  19. package/dist/cli/lisa-test-run-reaper.js +195 -0
  20. package/dist/cli/lisa-test-run-reaper.js.map +1 -0
  21. package/dist/cli/lisa-test-run-runtime.d.ts +46 -0
  22. package/dist/cli/lisa-test-run-runtime.d.ts.map +1 -0
  23. package/dist/cli/lisa-test-run-runtime.js +123 -0
  24. package/dist/cli/lisa-test-run-runtime.js.map +1 -0
  25. package/dist/cli/lisa-test-run-supervisor.d.ts +13 -0
  26. package/dist/cli/lisa-test-run-supervisor.d.ts.map +1 -0
  27. package/dist/cli/lisa-test-run-supervisor.js +268 -0
  28. package/dist/cli/lisa-test-run-supervisor.js.map +1 -0
  29. package/dist/cli/lisa-test-run.d.ts +3 -0
  30. package/dist/cli/lisa-test-run.d.ts.map +1 -0
  31. package/dist/cli/lisa-test-run.js +66 -0
  32. package/dist/cli/lisa-test-run.js.map +1 -0
  33. package/dist/configs/vitest/base.d.ts.map +1 -1
  34. package/dist/configs/vitest/base.js +5 -2
  35. package/dist/configs/vitest/base.js.map +1 -1
  36. package/dist/configs/vitest/cdk.d.ts +4 -0
  37. package/dist/configs/vitest/cdk.d.ts.map +1 -1
  38. package/dist/configs/vitest/cdk.js +5 -0
  39. package/dist/configs/vitest/cdk.js.map +1 -1
  40. package/dist/configs/vitest/harper-fabric.d.ts.map +1 -1
  41. package/dist/configs/vitest/harper-fabric.js +1 -0
  42. package/dist/configs/vitest/harper-fabric.js.map +1 -1
  43. package/dist/configs/vitest/nestjs.d.ts.map +1 -1
  44. package/dist/configs/vitest/nestjs.js +1 -0
  45. package/dist/configs/vitest/nestjs.js.map +1 -1
  46. package/dist/configs/vitest/phaser.d.ts.map +1 -1
  47. package/dist/configs/vitest/phaser.js +1 -0
  48. package/dist/configs/vitest/phaser.js.map +1 -1
  49. package/dist/configs/vitest/scratch-authority.d.ts +25 -0
  50. package/dist/configs/vitest/scratch-authority.d.ts.map +1 -0
  51. package/dist/configs/vitest/scratch-authority.js +107 -0
  52. package/dist/configs/vitest/scratch-authority.js.map +1 -0
  53. package/dist/configs/vitest/scratch-bound-cleanup-programs.d.ts +5 -0
  54. package/dist/configs/vitest/scratch-bound-cleanup-programs.d.ts.map +1 -0
  55. package/dist/configs/vitest/scratch-bound-cleanup-programs.js +219 -0
  56. package/dist/configs/vitest/scratch-bound-cleanup-programs.js.map +1 -0
  57. package/dist/configs/vitest/scratch-bound-cleanup.d.ts +28 -0
  58. package/dist/configs/vitest/scratch-bound-cleanup.d.ts.map +1 -0
  59. package/dist/configs/vitest/scratch-bound-cleanup.js +155 -0
  60. package/dist/configs/vitest/scratch-bound-cleanup.js.map +1 -0
  61. package/dist/configs/vitest/scratch-bound-root-cleanup.d.ts +17 -0
  62. package/dist/configs/vitest/scratch-bound-root-cleanup.d.ts.map +1 -0
  63. package/dist/configs/vitest/scratch-bound-root-cleanup.js +149 -0
  64. package/dist/configs/vitest/scratch-bound-root-cleanup.js.map +1 -0
  65. package/dist/configs/vitest/scratch-global-setup.d.ts +17 -9
  66. package/dist/configs/vitest/scratch-global-setup.d.ts.map +1 -1
  67. package/dist/configs/vitest/scratch-global-setup.js +103 -35
  68. package/dist/configs/vitest/scratch-global-setup.js.map +1 -1
  69. package/dist/configs/vitest/scratch-leak-setup.d.ts +2 -0
  70. package/dist/configs/vitest/scratch-leak-setup.d.ts.map +1 -0
  71. package/dist/configs/vitest/scratch-leak-setup.js +108 -0
  72. package/dist/configs/vitest/scratch-leak-setup.js.map +1 -0
  73. package/dist/configs/vitest/scratch-namespace-authority.d.ts +80 -0
  74. package/dist/configs/vitest/scratch-namespace-authority.d.ts.map +1 -0
  75. package/dist/configs/vitest/scratch-namespace-authority.js +291 -0
  76. package/dist/configs/vitest/scratch-namespace-authority.js.map +1 -0
  77. package/dist/configs/vitest/scratch-owner.d.ts +131 -0
  78. package/dist/configs/vitest/scratch-owner.d.ts.map +1 -0
  79. package/dist/configs/vitest/scratch-owner.js +297 -0
  80. package/dist/configs/vitest/scratch-owner.js.map +1 -0
  81. package/dist/configs/vitest/scratch-route-profile.d.ts +36 -0
  82. package/dist/configs/vitest/scratch-route-profile.d.ts.map +1 -0
  83. package/dist/configs/vitest/scratch-route-profile.js +217 -0
  84. package/dist/configs/vitest/scratch-route-profile.js.map +1 -0
  85. package/dist/configs/vitest/scratch-run-root-compatibility.d.ts +33 -0
  86. package/dist/configs/vitest/scratch-run-root-compatibility.d.ts.map +1 -0
  87. package/dist/configs/vitest/scratch-run-root-compatibility.js +137 -0
  88. package/dist/configs/vitest/scratch-run-root-compatibility.js.map +1 -0
  89. package/dist/configs/vitest/scratch-run-root-intent.d.ts +66 -0
  90. package/dist/configs/vitest/scratch-run-root-intent.d.ts.map +1 -0
  91. package/dist/configs/vitest/scratch-run-root-intent.js +183 -0
  92. package/dist/configs/vitest/scratch-run-root-intent.js.map +1 -0
  93. package/dist/configs/vitest/scratch-setup.d.ts.map +1 -1
  94. package/dist/configs/vitest/scratch-setup.js +45 -15
  95. package/dist/configs/vitest/scratch-setup.js.map +1 -1
  96. package/dist/configs/vitest/scratch-supervision-intent.d.ts +8 -0
  97. package/dist/configs/vitest/scratch-supervision-intent.d.ts.map +1 -0
  98. package/dist/configs/vitest/scratch-supervision-intent.js +125 -0
  99. package/dist/configs/vitest/scratch-supervision-intent.js.map +1 -0
  100. package/dist/configs/vitest/scratch-supervision-protocol.d.ts +12 -0
  101. package/dist/configs/vitest/scratch-supervision-protocol.d.ts.map +1 -0
  102. package/dist/configs/vitest/scratch-supervision-protocol.js +230 -0
  103. package/dist/configs/vitest/scratch-supervision-protocol.js.map +1 -0
  104. package/dist/configs/vitest/scratch-supervision.d.ts +64 -0
  105. package/dist/configs/vitest/scratch-supervision.d.ts.map +1 -0
  106. package/dist/configs/vitest/scratch-supervision.js +209 -0
  107. package/dist/configs/vitest/scratch-supervision.js.map +1 -0
  108. package/dist/configs/vitest/scratch-sweep.d.ts +66 -0
  109. package/dist/configs/vitest/scratch-sweep.d.ts.map +1 -0
  110. package/dist/configs/vitest/scratch-sweep.js +82 -0
  111. package/dist/configs/vitest/scratch-sweep.js.map +1 -0
  112. package/dist/configs/vitest/scratch.d.ts +14 -187
  113. package/dist/configs/vitest/scratch.d.ts.map +1 -1
  114. package/dist/configs/vitest/scratch.js +18 -285
  115. package/dist/configs/vitest/scratch.js.map +1 -1
  116. package/dist/configs/vitest/typescript.d.ts.map +1 -1
  117. package/dist/configs/vitest/typescript.js +1 -0
  118. package/dist/configs/vitest/typescript.js.map +1 -1
  119. package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
  120. package/dist/core/lisa-owned-hash-ledger.js +4 -0
  121. package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
  122. package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
  123. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  124. package/dist/core/upstream-evidence-manifest.js +59 -13
  125. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  126. package/expo/package-lisa/package.lisa.json +14 -14
  127. package/harper-fabric/package-lisa/package.lisa.json +8 -3
  128. package/nestjs/create-only/vitest.config.local.ts +5 -1
  129. package/nestjs/package-lisa/package.lisa.json +14 -8
  130. package/npm-package/package-lisa/package.lisa.json +8 -0
  131. package/package.json +17 -13
  132. package/phaser/package-lisa/package.lisa.json +9 -3
  133. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  134. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  135. package/plugins/lisa/hooks/sonar-secrets.sh +3 -2
  136. package/plugins/lisa-agy/plugin.json +1 -1
  137. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  138. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  139. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  140. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  141. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  142. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  143. package/plugins/lisa-copilot/hooks/sonar-secrets.sh +3 -2
  144. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  145. package/plugins/lisa-cursor/hooks/sonar-secrets.sh +3 -2
  146. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  147. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  148. package/plugins/lisa-expo-agy/plugin.json +1 -1
  149. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  150. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  151. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  152. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  153. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  154. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  155. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  156. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  157. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  158. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  159. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  160. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  161. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  162. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  163. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  164. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  165. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  166. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  167. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  168. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  169. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  170. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  171. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  172. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  173. package/plugins/lisa-rails-agy/plugin.json +1 -1
  174. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  175. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  176. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  177. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  178. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  179. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  180. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  181. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  182. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  183. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  184. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  185. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  186. package/plugins/src/base/hooks/sonar-secrets.sh +3 -2
  187. package/typescript/create-only/vitest.config.local.ts +5 -1
  188. package/typescript/package-lisa/package.lisa.json +14 -8
@@ -0,0 +1,297 @@
1
+ /**
2
+ * Durable owner records for Vitest scratch roots.
3
+ *
4
+ * A pid is not an identity: kernels reuse it. The marker therefore binds the
5
+ * pid to the process birth value reported by the operating system, and every
6
+ * reclaim decision compares both. A live pid whose birth cannot be read is
7
+ * preserved; deletion fails closed rather than guessing.
8
+ * @module configs/vitest/scratch-owner
9
+ */
10
+ import { randomBytes } from "node:crypto";
11
+ import * as fs from "node:fs";
12
+ import * as path from "node:path";
13
+ import { spawnSync } from "node:child_process";
14
+ /** Owner-marker filename stored directly inside every run root. */
15
+ export const SCRATCH_OWNER_FILE = ".lisa-scratch-owner.json";
16
+ /** Prefix identifying a per-process run root inside the namespace. */
17
+ export const SCRATCH_RUN_ROOT_PREFIX = "run-";
18
+ /** Maximum time allowed for the bounded macOS process-birth probe. */
19
+ const PS_TIMEOUT_MS = 1_000;
20
+ /** Maximum pids admitted to one bounded macOS `ps` invocation. */
21
+ const DARWIN_BIRTH_BATCH_SIZE = 256;
22
+ /** Maximum owner-marker bytes accepted at the destructive authority boundary. */
23
+ const MAX_OWNER_MARKER_BYTES = 16 * 1024;
24
+ /** Maximum bytes accepted for one opaque marker string. */
25
+ const MAX_OWNER_TEXT_BYTES = 256;
26
+ /** Maximum bytes accepted for one canonical filesystem path. */
27
+ const MAX_OWNER_PATH_BYTES = 4_096;
28
+ /** Maximum registered prefixes accepted in one marker. */
29
+ const MAX_OWNER_PREFIXES = 64;
30
+ /**
31
+ * Read Linux's immutable process start ticks.
32
+ * @param pid - Process id to inspect
33
+ * @returns A stable fingerprint, or undefined when unavailable
34
+ */
35
+ function linuxBirthFingerprint(pid) {
36
+ try {
37
+ const stat = fs.readFileSync(`/proc/${String(pid)}/stat`, "utf8");
38
+ const commEnd = stat.lastIndexOf(")");
39
+ if (commEnd < 0)
40
+ return undefined;
41
+ const fields = stat
42
+ .slice(commEnd + 2)
43
+ .trim()
44
+ .split(/\s+/u);
45
+ const startTicks = fields[19];
46
+ return startTicks === undefined ? undefined : `linux:${startTicks}`;
47
+ }
48
+ catch {
49
+ return undefined;
50
+ }
51
+ }
52
+ /**
53
+ * Read macOS kernel-reported process start times through one bounded `ps` call.
54
+ * @param pids - Process ids to inspect together
55
+ * @returns Raw pid/start rows, or undefined when unavailable
56
+ */
57
+ function runDarwinBirthBatch(pids) {
58
+ const result = spawnSync("/bin/ps", ["-p", pids.join(","), "-o", "pid=", "-o", "lstart="], {
59
+ encoding: "utf8",
60
+ killSignal: "SIGKILL",
61
+ maxBuffer: Math.max(4_096, pids.length * 128),
62
+ timeout: PS_TIMEOUT_MS,
63
+ });
64
+ if (result.status !== 0 ||
65
+ result.signal !== null ||
66
+ result.error !== undefined) {
67
+ return undefined;
68
+ }
69
+ return result.stdout;
70
+ }
71
+ /**
72
+ * Parse one bulk `pid lstart` row without depending on locale text.
73
+ * @param row - One bounded `ps` output row
74
+ * @returns Parsed pid and fingerprint, or undefined for malformed output
75
+ */
76
+ function parseDarwinBirthRow(row) {
77
+ const normalized = row.trim();
78
+ const separator = normalized.search(/\s/u);
79
+ if (separator < 1)
80
+ return undefined;
81
+ const pid = Number(normalized.slice(0, separator));
82
+ if (!Number.isSafeInteger(pid) || pid <= 0)
83
+ return undefined;
84
+ const start = normalized.slice(separator).trim().replace(/\s+/gu, " ");
85
+ return start === "" ? undefined : [pid, `darwin:${start}`];
86
+ }
87
+ /**
88
+ * Capture process birth once for a bounded pid set.
89
+ *
90
+ * Darwin has no `/proc`, so namespace audits must not launch one `ps` process
91
+ * per live scratch root. This snapshot deduplicates pids and reads them in
92
+ * bounded 256-pid batches; callers reuse the returned map throughout one
93
+ * sweep/inspection transaction.
94
+ * @param pids - Process ids needed by one audit transaction
95
+ * @param options - Platform and deterministic batch seam
96
+ * @returns A complete lookup whose missing observations remain undefined
97
+ */
98
+ export function processBirthFingerprintSnapshot(pids, options = {}) {
99
+ const unique = [...new Set(pids)]
100
+ .filter(pid => Number.isSafeInteger(pid) && pid > 0)
101
+ .sort((left, right) => left - right);
102
+ const platform = options.platform ?? process.platform;
103
+ if (platform === "linux") {
104
+ return new Map(unique.map(pid => [pid, linuxBirthFingerprint(pid)]));
105
+ }
106
+ if (platform !== "darwin") {
107
+ return new Map(unique.map(pid => [pid, undefined]));
108
+ }
109
+ const runBatch = options.runDarwinBatch ?? runDarwinBirthBatch;
110
+ const batchCount = Math.ceil(unique.length / DARWIN_BIRTH_BATCH_SIZE);
111
+ const observations = new Map(Array.from({ length: batchCount }, (_, index) => unique.slice(index * DARWIN_BIRTH_BATCH_SIZE, (index + 1) * DARWIN_BIRTH_BATCH_SIZE)).flatMap(batch => (runBatch(batch) ?? "")
112
+ .split("\n")
113
+ .map(parseDarwinBirthRow)
114
+ .filter((entry) => entry !== undefined)));
115
+ return new Map(unique.map(pid => [pid, observations.get(pid)]));
116
+ }
117
+ /**
118
+ * Read the OS-authoritative birth fingerprint for a process.
119
+ * @param pid - Process id to inspect
120
+ * @returns Fingerprint, or undefined on an unsupported/ambiguous platform
121
+ */
122
+ export function processBirthFingerprint(pid) {
123
+ if (!Number.isSafeInteger(pid) || pid <= 0)
124
+ return undefined;
125
+ return processBirthFingerprintSnapshot([pid]).get(pid);
126
+ }
127
+ /** Stable unsupported-platform fallback captured once at module load. */
128
+ const UNSUPPORTED_CURRENT_BIRTH = `unsupported:${String(process.pid)}:${String(Math.round(Date.now() - process.uptime() * 1_000))}`;
129
+ /**
130
+ * Fingerprint the current process for a newly-created marker.
131
+ *
132
+ * Unsupported platforms still need an opaque value to make the marker
133
+ * complete. Reclaim never treats this fallback as authoritative: a live pid on
134
+ * such a platform yields an ambiguous observation and is preserved.
135
+ * @returns Current process birth fingerprint
136
+ */
137
+ export function currentProcessBirthFingerprint() {
138
+ return processBirthFingerprint(process.pid) ?? UNSUPPORTED_CURRENT_BIRTH;
139
+ }
140
+ /**
141
+ * Build a run-root basename.
142
+ * @param pid - Owning process id
143
+ * @param startedAt - Creation epoch milliseconds
144
+ * @param suffix - Opaque random suffix
145
+ * @returns Direct namespace-child basename
146
+ */
147
+ export function scratchRunRootName(pid, startedAt, suffix) {
148
+ return `${SCRATCH_RUN_ROOT_PREFIX}${String(pid)}-${String(startedAt)}-${suffix}`;
149
+ }
150
+ /**
151
+ * Parse the owner fields encoded in a run-root basename.
152
+ * @param name - Direct namespace-child basename
153
+ * @returns Parsed owner, or undefined for an unrelated name
154
+ */
155
+ export function parseScratchRunRootName(name) {
156
+ const match = new RegExp(`^${SCRATCH_RUN_ROOT_PREFIX}(\\d+)-(\\d+)-[^-]+$`).exec(name);
157
+ if (match === null)
158
+ return undefined;
159
+ const pid = Number(match[1]);
160
+ const startedAt = Number(match[2]);
161
+ return Number.isSafeInteger(pid) && Number.isSafeInteger(startedAt)
162
+ ? { pid, startedAt }
163
+ : undefined;
164
+ }
165
+ /**
166
+ * Decide whether a valid owner may be reclaimed.
167
+ * @param record - Persisted owner marker
168
+ * @param probes - Kernel probes, injectable for deterministic tests
169
+ * @returns Fail-closed reclaim disposition
170
+ */
171
+ export function classifyScratchOwner(record, probes) {
172
+ if (!probes.isProcessAlive(record.pid))
173
+ return "reclaim";
174
+ if (record.processBirthFingerprint.startsWith("unsupported:")) {
175
+ return "preserve";
176
+ }
177
+ const observed = probes.processBirthFingerprint(record.pid);
178
+ if (observed === undefined)
179
+ return "preserve";
180
+ return observed === record.processBirthFingerprint ? "preserve" : "reclaim";
181
+ }
182
+ /**
183
+ * Capture an immutable filesystem identity without following a final symlink.
184
+ * @param candidate - Existing regular file or directory
185
+ * @returns Canonical path plus device/inode identity
186
+ */
187
+ export function scratchPathIdentity(candidate) {
188
+ const stat = fs.lstatSync(candidate);
189
+ if (stat.isSymbolicLink()) {
190
+ throw new Error(`Scratch authority refuses symlink path: ${candidate}`);
191
+ }
192
+ return {
193
+ canonicalPath: fs.realpathSync(candidate),
194
+ dev: stat.dev,
195
+ ino: stat.ino,
196
+ };
197
+ }
198
+ /**
199
+ * Construct a version-one owner marker from live filesystem state.
200
+ * @param options - Owner and path facts
201
+ * @returns Immutable owner record
202
+ */
203
+ export function createScratchOwnerRecord(options) {
204
+ const prefixes = [...new Set(options.registeredPrefixes)].sort((left, right) => left.localeCompare(right));
205
+ return {
206
+ schema: 1,
207
+ pid: options.pid ?? process.pid,
208
+ processBirthFingerprint: options.processBirthFingerprint ?? currentProcessBirthFingerprint(),
209
+ createdAt: (options.now ?? new Date()).toISOString(),
210
+ token: options.token ?? randomBytes(16).toString("hex"),
211
+ suiteLabel: options.suiteLabel,
212
+ registeredPrefixes: prefixes,
213
+ namespace: options.authority.namespace,
214
+ root: scratchPathIdentity(options.root),
215
+ };
216
+ }
217
+ /**
218
+ * Validate an inert parsed object as a version-one owner record.
219
+ * @param candidate - Parsed marker payload
220
+ * @returns Validated owner record
221
+ */
222
+ function validateOwnerRecord(candidate) {
223
+ if (typeof candidate !== "object" || candidate === null) {
224
+ throw new Error("Scratch owner marker must be an object");
225
+ }
226
+ const value = candidate;
227
+ const namespace = value["namespace"];
228
+ const root = value["root"];
229
+ const prefixes = value["registeredPrefixes"];
230
+ const validText = (text) => typeof text === "string" &&
231
+ text !== "" &&
232
+ Buffer.byteLength(text, "utf8") <= MAX_OWNER_TEXT_BYTES;
233
+ const validPath = (text) => typeof text === "string" &&
234
+ text !== "" &&
235
+ Buffer.byteLength(text, "utf8") <= MAX_OWNER_PATH_BYTES;
236
+ const validIdentity = (identity) => identity !== undefined &&
237
+ validPath(identity["canonicalPath"]) &&
238
+ path.isAbsolute(identity["canonicalPath"]) &&
239
+ Number.isSafeInteger(identity["dev"]) &&
240
+ Number.isSafeInteger(identity["ino"]);
241
+ if (value["schema"] !== 1 ||
242
+ typeof value["pid"] !== "number" ||
243
+ !Number.isSafeInteger(value["pid"]) ||
244
+ value["pid"] <= 0 ||
245
+ !validText(value["processBirthFingerprint"]) ||
246
+ !validText(value["createdAt"]) ||
247
+ Number.isNaN(Date.parse(value["createdAt"])) ||
248
+ !validText(value["token"]) ||
249
+ !validText(value["suiteLabel"]) ||
250
+ !Array.isArray(prefixes) ||
251
+ prefixes.length > MAX_OWNER_PREFIXES ||
252
+ !prefixes.every(prefix => validText(prefix) &&
253
+ !prefix.includes("/") &&
254
+ !prefix.includes("\\") &&
255
+ prefix !== "." &&
256
+ prefix !== "..") ||
257
+ !validIdentity(namespace) ||
258
+ !validIdentity(root)) {
259
+ throw new Error("Invalid scratch owner marker schema");
260
+ }
261
+ return candidate;
262
+ }
263
+ /**
264
+ * Write an owner marker without permitting a pre-existing file or symlink.
265
+ * @param root - Owned run root
266
+ * @param record - Marker to persist
267
+ */
268
+ export function writeScratchOwnerRecord(root, record) {
269
+ const marker = path.join(root, SCRATCH_OWNER_FILE);
270
+ const descriptor = fs.openSync(marker, fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_WRONLY, 0o600);
271
+ try {
272
+ fs.writeFileSync(descriptor, `${JSON.stringify(record)}\n`, "utf8");
273
+ fs.fsyncSync(descriptor);
274
+ }
275
+ finally {
276
+ fs.closeSync(descriptor);
277
+ }
278
+ }
279
+ /**
280
+ * Read and validate an owner marker without following a marker symlink.
281
+ * @param root - Run root containing the marker
282
+ * @returns Validated owner marker
283
+ */
284
+ export function readScratchOwnerRecord(root) {
285
+ const marker = path.join(root, SCRATCH_OWNER_FILE);
286
+ const stat = fs.lstatSync(marker);
287
+ if (stat.isSymbolicLink()) {
288
+ throw new Error(`Scratch owner marker is a symlink: ${marker}`);
289
+ }
290
+ if (!stat.isFile())
291
+ throw new Error(`Scratch owner marker is not a file: ${marker}`);
292
+ if (stat.size > MAX_OWNER_MARKER_BYTES) {
293
+ throw new Error(`Scratch owner marker exceeds ${String(MAX_OWNER_MARKER_BYTES)} bytes`);
294
+ }
295
+ return validateOwnerRecord(JSON.parse(fs.readFileSync(marker, "utf8")));
296
+ }
297
+ //# sourceMappingURL=scratch-owner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scratch-owner.js","sourceRoot":"","sources":["../../../src/configs/vitest/scratch-owner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /** JSON-array environment contract for operator-added direct-child prefixes. */
2
+ export declare const SCRATCH_PREFIXES_ENV = "LISA_TEST_SCRATCH_PREFIXES";
3
+ /** Environment assertion for the immutable route suite label. */
4
+ export declare const SCRATCH_SUITE_ENV = "LISA_TEST_SCRATCH_SUITE";
5
+ /** Every generated route profile understood by the public wrapper. */
6
+ export type ScratchRouteProfileName = "lisa" | "typescript" | "npm-package" | "node" | "expo" | "nestjs" | "cdk" | "harper-fabric" | "phaser";
7
+ /** Frozen suite attribution decided before any scratch root exists. */
8
+ export interface ScratchRouteProfile {
9
+ readonly name: ScratchRouteProfileName;
10
+ readonly suiteLabel: string;
11
+ readonly registeredPrefixes: readonly string[];
12
+ }
13
+ /**
14
+ * Read the validated bounded prefix registry inherited by scratch owners.
15
+ * @returns Sorted unique direct-child prefixes
16
+ */
17
+ export declare function registeredScratchPrefixes(): readonly string[];
18
+ /**
19
+ * Read the opaque bounded suite label used for owner attribution.
20
+ * @returns Valid suite label
21
+ */
22
+ export declare function scratchSuiteLabel(): string;
23
+ /**
24
+ * Resolve a generated route plus bounded operator additions before allocation.
25
+ * @param name - Exact managed route name
26
+ * @param environment - Inherited operator configuration
27
+ * @returns Deeply frozen immutable registry
28
+ */
29
+ export declare function resolveScratchRouteProfile(name: string, environment?: NodeJS.ProcessEnv): ScratchRouteProfile;
30
+ /**
31
+ * Assert dynamic Vitest env agrees with the frozen wrapper lease exactly.
32
+ * @param profile - Frozen wrapper-authoritative profile
33
+ * @param environment - Dynamic Vitest environment to compare
34
+ */
35
+ export declare function assertScratchRouteProfile(profile: Pick<ScratchRouteProfile, "suiteLabel" | "registeredPrefixes">, environment?: NodeJS.ProcessEnv): void;
36
+ //# sourceMappingURL=scratch-route-profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scratch-route-profile.d.ts","sourceRoot":"","sources":["../../../src/configs/vitest/scratch-route-profile.ts"],"names":[],"mappings":"AAGA,gFAAgF;AAChF,eAAO,MAAM,oBAAoB,+BAA+B,CAAC;AAEjE,iEAAiE;AACjE,eAAO,MAAM,iBAAiB,4BAA4B,CAAC;AAQ3D,sEAAsE;AACtE,MAAM,MAAM,uBAAuB,GAC/B,MAAM,GACN,YAAY,GACZ,aAAa,GACb,MAAM,GACN,MAAM,GACN,QAAQ,GACR,KAAK,GACL,eAAe,GACf,QAAQ,CAAC;AAEb,uEAAuE;AACvE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAC;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;CAChD;AAgFD;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,SAAS,MAAM,EAAE,CA0B7D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAU1C;AAsDD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,MAAM,EACZ,WAAW,GAAE,MAAM,CAAC,UAAgB,GACnC,mBAAmB,CA8BrB;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,YAAY,GAAG,oBAAoB,CAAC,EACvE,WAAW,GAAE,MAAM,CAAC,UAAgB,GACnC,IAAI,CAsBN"}
@@ -0,0 +1,217 @@
1
+ /** Immutable wrapper-authoritative scratch registries for every managed route. */
2
+ import { env } from "node:process";
3
+ /** JSON-array environment contract for operator-added direct-child prefixes. */
4
+ export const SCRATCH_PREFIXES_ENV = "LISA_TEST_SCRATCH_PREFIXES";
5
+ /** Environment assertion for the immutable route suite label. */
6
+ export const SCRATCH_SUITE_ENV = "LISA_TEST_SCRATCH_SUITE";
7
+ /** Maximum number of registered prefixes accepted from configuration. */
8
+ const MAX_REGISTERED_PREFIXES = 64;
9
+ /** Maximum bytes in one registered prefix or suite label. */
10
+ const MAX_LABEL_BYTES = 128;
11
+ /** Wrapper-owned base registry; operator additions may only widen prefixes. */
12
+ const ROUTE_PROFILES = Object.freeze({
13
+ lisa: Object.freeze({
14
+ suiteLabel: "lisa",
15
+ registeredPrefixes: Object.freeze([
16
+ "changelog-",
17
+ "derived-",
18
+ "e2e-",
19
+ "failure-signatures-",
20
+ "invoked-",
21
+ "lisa-",
22
+ "maestro-",
23
+ "node-",
24
+ "review-",
25
+ "skipreq-",
26
+ "state-",
27
+ "vacuity-",
28
+ "wiki-",
29
+ ]),
30
+ }),
31
+ typescript: Object.freeze({
32
+ suiteLabel: "typescript",
33
+ registeredPrefixes: [],
34
+ }),
35
+ "npm-package": Object.freeze({
36
+ suiteLabel: "npm-package",
37
+ registeredPrefixes: [],
38
+ }),
39
+ node: Object.freeze({
40
+ suiteLabel: "node",
41
+ registeredPrefixes: Object.freeze(["node-"]),
42
+ }),
43
+ expo: Object.freeze({
44
+ suiteLabel: "expo",
45
+ registeredPrefixes: [],
46
+ }),
47
+ nestjs: Object.freeze({ suiteLabel: "nestjs", registeredPrefixes: [] }),
48
+ cdk: Object.freeze({
49
+ suiteLabel: "cdk",
50
+ registeredPrefixes: Object.freeze(["cdk.out"]),
51
+ }),
52
+ "harper-fabric": Object.freeze({
53
+ suiteLabel: "harper-fabric",
54
+ registeredPrefixes: [],
55
+ }),
56
+ phaser: Object.freeze({
57
+ suiteLabel: "phaser",
58
+ registeredPrefixes: [],
59
+ }),
60
+ });
61
+ /**
62
+ * Whether a label contains a control code unsafe for markers/diagnostics.
63
+ * @param label - Candidate label
64
+ * @returns True when a control code is present
65
+ */
66
+ function containsControlCode(label) {
67
+ return [...label].some(character => {
68
+ const codePoint = character.codePointAt(0) ?? 0;
69
+ return codePoint <= 0x1f || codePoint === 0x7f;
70
+ });
71
+ }
72
+ /**
73
+ * Parse one inherited registry while preserving its public diagnostic.
74
+ * @param raw - Serialized prefix registry
75
+ * @returns Decoded unvalidated value
76
+ */
77
+ function parsePrefixRegistry(raw) {
78
+ try {
79
+ return JSON.parse(raw);
80
+ }
81
+ catch {
82
+ throw new Error(`${SCRATCH_PREFIXES_ENV} must be a JSON array of prefixes`);
83
+ }
84
+ }
85
+ /**
86
+ * Read the validated bounded prefix registry inherited by scratch owners.
87
+ * @returns Sorted unique direct-child prefixes
88
+ */
89
+ export function registeredScratchPrefixes() {
90
+ const raw = env[SCRATCH_PREFIXES_ENV];
91
+ if (raw === undefined || raw === "")
92
+ return [];
93
+ const parsed = parsePrefixRegistry(raw);
94
+ if (!Array.isArray(parsed) || parsed.length > MAX_REGISTERED_PREFIXES) {
95
+ throw new Error(`${SCRATCH_PREFIXES_ENV} must contain at most ${String(MAX_REGISTERED_PREFIXES)} prefixes`);
96
+ }
97
+ const prefixes = parsed.map(value => {
98
+ if (typeof value !== "string" ||
99
+ value === "" ||
100
+ Buffer.byteLength(value, "utf8") > MAX_LABEL_BYTES ||
101
+ value.includes("/") ||
102
+ value.includes("\\") ||
103
+ value === "." ||
104
+ value === "..") {
105
+ throw new Error(`${SCRATCH_PREFIXES_ENV} contains an invalid prefix`);
106
+ }
107
+ return value;
108
+ });
109
+ return [...new Set(prefixes)].sort((left, right) => left.localeCompare(right));
110
+ }
111
+ /**
112
+ * Read the opaque bounded suite label used for owner attribution.
113
+ * @returns Valid suite label
114
+ */
115
+ export function scratchSuiteLabel() {
116
+ const label = env[SCRATCH_SUITE_ENV] ?? "vitest";
117
+ if (label === "" ||
118
+ Buffer.byteLength(label, "utf8") > MAX_LABEL_BYTES ||
119
+ containsControlCode(label)) {
120
+ throw new Error(`${SCRATCH_SUITE_ENV} contains an invalid suite label`);
121
+ }
122
+ return label;
123
+ }
124
+ /**
125
+ * Demand one bounded direct basename.
126
+ * @param value - Candidate value
127
+ * @param context - Public diagnostic context
128
+ * @returns Validated direct label
129
+ */
130
+ function validateLabel(value, context) {
131
+ if (typeof value !== "string" ||
132
+ value === "" ||
133
+ Buffer.byteLength(value, "utf8") > MAX_LABEL_BYTES ||
134
+ containsControlCode(value) ||
135
+ value.includes("/") ||
136
+ value.includes("\\") ||
137
+ value === "." ||
138
+ value === "..") {
139
+ throw new Error(`${context} contains an invalid direct label`);
140
+ }
141
+ return value;
142
+ }
143
+ /**
144
+ * Decode one operator prefix registry.
145
+ * @param raw - Serialized registry
146
+ * @returns Unvalidated decoded value
147
+ */
148
+ function parseOperatorPrefixes(raw) {
149
+ try {
150
+ return JSON.parse(raw);
151
+ }
152
+ catch {
153
+ throw new Error(`${SCRATCH_PREFIXES_ENV} must be a JSON array of prefixes`);
154
+ }
155
+ }
156
+ /**
157
+ * Parse and canonicalize operator prefix additions exactly once.
158
+ * @param environment - Inherited operator configuration
159
+ * @returns Validated operator-added prefixes
160
+ */
161
+ function operatorPrefixes(environment) {
162
+ const raw = environment[SCRATCH_PREFIXES_ENV];
163
+ if (raw === undefined || raw === "")
164
+ return [];
165
+ const parsed = parseOperatorPrefixes(raw);
166
+ if (!Array.isArray(parsed) || parsed.length > MAX_REGISTERED_PREFIXES) {
167
+ throw new Error(`${SCRATCH_PREFIXES_ENV} must contain at most ${String(MAX_REGISTERED_PREFIXES)} prefixes`);
168
+ }
169
+ return parsed.map(value => validateLabel(value, SCRATCH_PREFIXES_ENV));
170
+ }
171
+ /**
172
+ * Resolve a generated route plus bounded operator additions before allocation.
173
+ * @param name - Exact managed route name
174
+ * @param environment - Inherited operator configuration
175
+ * @returns Deeply frozen immutable registry
176
+ */
177
+ export function resolveScratchRouteProfile(name, environment = env) {
178
+ if (!Object.hasOwn(ROUTE_PROFILES, name)) {
179
+ throw new Error(`Unknown lisa-test-run scratch profile: ${name || "<missing>"}`);
180
+ }
181
+ const routeName = name;
182
+ const base = ROUTE_PROFILES[routeName];
183
+ const assertedSuite = environment[SCRATCH_SUITE_ENV];
184
+ if (assertedSuite !== undefined &&
185
+ validateLabel(assertedSuite, SCRATCH_SUITE_ENV) !== base.suiteLabel) {
186
+ throw new Error(`${SCRATCH_SUITE_ENV} conflicts with wrapper profile ${routeName}`);
187
+ }
188
+ const prefixes = [
189
+ ...new Set([...base.registeredPrefixes, ...operatorPrefixes(environment)]),
190
+ ].sort((left, right) => (left === right ? 0 : left < right ? -1 : 1));
191
+ if (prefixes.length > MAX_REGISTERED_PREFIXES) {
192
+ throw new Error(`${SCRATCH_PREFIXES_ENV} exceeds the ${String(MAX_REGISTERED_PREFIXES)} prefix limit after composition`);
193
+ }
194
+ return Object.freeze({
195
+ name: routeName,
196
+ suiteLabel: base.suiteLabel,
197
+ registeredPrefixes: Object.freeze(prefixes),
198
+ });
199
+ }
200
+ /**
201
+ * Assert dynamic Vitest env agrees with the frozen wrapper lease exactly.
202
+ * @param profile - Frozen wrapper-authoritative profile
203
+ * @param environment - Dynamic Vitest environment to compare
204
+ */
205
+ export function assertScratchRouteProfile(profile, environment = env) {
206
+ const observedSuite = validateLabel(environment[SCRATCH_SUITE_ENV], SCRATCH_SUITE_ENV);
207
+ const observedPrefixes = operatorPrefixes(environment);
208
+ const canonical = [...new Set(observedPrefixes)].sort((left, right) => left === right ? 0 : left < right ? -1 : 1);
209
+ if (observedSuite !== profile.suiteLabel ||
210
+ canonical.length !== profile.registeredPrefixes.length ||
211
+ canonical.some((prefix, index) => prefix !== profile.registeredPrefixes[index])) {
212
+ throw new Error(`Vitest scratch configuration conflicts with the immutable wrapper profile: ` +
213
+ `expected ${profile.suiteLabel}/${JSON.stringify(profile.registeredPrefixes)}, ` +
214
+ `received ${observedSuite}/${JSON.stringify(canonical)}`);
215
+ }
216
+ }
217
+ //# sourceMappingURL=scratch-route-profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scratch-route-profile.js","sourceRoot":"","sources":["../../../src/configs/vitest/scratch-route-profile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { writeScratchOwnerRecord } from "./scratch-owner.js";
2
+ import type { OwnedScratchRunRoot } from "./scratch-run-root-intent.js";
3
+ /** Optional seams for creating one transactional run root. */
4
+ interface CreateRunRootOptions {
5
+ readonly now?: number;
6
+ readonly writeOwnerRecord?: typeof writeScratchOwnerRecord;
7
+ }
8
+ /**
9
+ * Create a legacy-compatible owned root with transactional marker rollback.
10
+ * @param options - Clock and marker-writer seams
11
+ * @param options.now - Epoch milliseconds recorded in the basename
12
+ * @param options.writeOwnerRecord - Injectable transactional marker writer
13
+ * @returns Absolute run-root path
14
+ */
15
+ export declare const createRunRoot: ({ now, writeOwnerRecord, }?: CreateRunRootOptions) => string;
16
+ /**
17
+ * Reclaim residue, then allocate a durable owned-root handle.
18
+ * @returns Owned current-process root
19
+ */
20
+ export declare function reclaimAndCreateOwnedRunRoot(): OwnedScratchRunRoot;
21
+ /**
22
+ * Upgrade a source/dist-compatible path memo created by an older setup copy.
23
+ * @param root - Existing memoized run-root path
24
+ * @returns Durable handle for the existing root
25
+ */
26
+ export declare function adoptOwnedScratchRunRoot(root: string): OwnedScratchRunRoot;
27
+ /**
28
+ * Reclaim residue, then return one current-process root path.
29
+ * @returns Newly allocated root path
30
+ */
31
+ export declare const reclaimAndCreateRunRoot: () => string;
32
+ export {};
33
+ //# sourceMappingURL=scratch-run-root-compatibility.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scratch-run-root-compatibility.d.ts","sourceRoot":"","sources":["../../../src/configs/vitest/scratch-run-root-compatibility.ts"],"names":[],"mappings":"AAgBA,OAAO,EAIL,uBAAuB,EAExB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAQxE,8DAA8D;AAC9D,UAAU,oBAAoB;IAC5B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,uBAAuB,CAAC;CAC5D;AAyBD;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GAAI,6BAG3B,oBAAyB,KAAG,MAsC9B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,4BAA4B,IAAI,mBAAmB,CAYlE;AA8BD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,CAoB1E;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB,QAAO,MACN,CAAC"}