@agent-teams/engineering-foundation 0.12.0 → 0.13.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.
Files changed (137) hide show
  1. package/dist/cli.js +23 -12
  2. package/dist/cli.js.map +1 -1
  3. package/dist/foundation-state-contract.d.ts +7 -0
  4. package/dist/foundation-state-contract.d.ts.map +1 -0
  5. package/dist/foundation-state-contract.js +7 -0
  6. package/dist/foundation-state-contract.js.map +1 -0
  7. package/dist/index.d.ts +2 -0
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +1 -0
  10. package/dist/index.js.map +1 -1
  11. package/dist/local-mode/attach-transaction.d.ts.map +1 -1
  12. package/dist/local-mode/attach-transaction.js +13 -7
  13. package/dist/local-mode/attach-transaction.js.map +1 -1
  14. package/dist/local-mode/inspection.d.ts +4 -1
  15. package/dist/local-mode/inspection.d.ts.map +1 -1
  16. package/dist/local-mode/inspection.js +20 -0
  17. package/dist/local-mode/inspection.js.map +1 -1
  18. package/dist/local-mode/local-state-store.d.ts.map +1 -1
  19. package/dist/local-mode/local-state-store.js +8 -105
  20. package/dist/local-mode/local-state-store.js.map +1 -1
  21. package/dist/local-mode/service.d.ts.map +1 -1
  22. package/dist/local-mode/service.js +17 -4
  23. package/dist/local-mode/service.js.map +1 -1
  24. package/dist/local-mode/types.d.ts +7 -4
  25. package/dist/local-mode/types.d.ts.map +1 -1
  26. package/dist/local-mode/types.js +1 -4
  27. package/dist/local-mode/types.js.map +1 -1
  28. package/dist/package-version.d.ts +2 -0
  29. package/dist/package-version.d.ts.map +1 -0
  30. package/dist/package-version.js +10 -0
  31. package/dist/package-version.js.map +1 -0
  32. package/dist/process-execution/windows-managed-process.d.ts.map +1 -1
  33. package/dist/process-execution/windows-managed-process.js +1 -0
  34. package/dist/process-execution/windows-managed-process.js.map +1 -1
  35. package/dist/repository-mutation/adapters/node/node-absent-file-publication.d.ts +31 -0
  36. package/dist/repository-mutation/adapters/node/node-absent-file-publication.d.ts.map +1 -0
  37. package/dist/repository-mutation/adapters/node/node-absent-file-publication.js +272 -0
  38. package/dist/repository-mutation/adapters/node/node-absent-file-publication.js.map +1 -0
  39. package/dist/repository-mutation/adapters/node/node-bounded-regular-file.d.ts +20 -0
  40. package/dist/repository-mutation/adapters/node/node-bounded-regular-file.d.ts.map +1 -0
  41. package/dist/repository-mutation/adapters/node/node-bounded-regular-file.js +123 -0
  42. package/dist/repository-mutation/adapters/node/node-bounded-regular-file.js.map +1 -0
  43. package/dist/repository-mutation/adapters/node/node-directory-durability.d.ts +12 -0
  44. package/dist/repository-mutation/adapters/node/node-directory-durability.d.ts.map +1 -0
  45. package/dist/repository-mutation/adapters/node/node-directory-durability.js +32 -0
  46. package/dist/repository-mutation/adapters/node/node-directory-durability.js.map +1 -0
  47. package/dist/repository-mutation/adapters/node/node-existing-repository-ancestors.d.ts +13 -0
  48. package/dist/repository-mutation/adapters/node/node-existing-repository-ancestors.d.ts.map +1 -0
  49. package/dist/repository-mutation/adapters/node/node-existing-repository-ancestors.js +67 -0
  50. package/dist/repository-mutation/adapters/node/node-existing-repository-ancestors.js.map +1 -0
  51. package/dist/repository-mutation/adapters/node/node-repository-path.d.ts +2 -0
  52. package/dist/repository-mutation/adapters/node/node-repository-path.d.ts.map +1 -0
  53. package/dist/repository-mutation/adapters/node/node-repository-path.js +7 -0
  54. package/dist/repository-mutation/adapters/node/node-repository-path.js.map +1 -0
  55. package/dist/repository-mutation/application/model/exact-postimage.d.ts +17 -0
  56. package/dist/repository-mutation/application/model/exact-postimage.d.ts.map +1 -0
  57. package/dist/repository-mutation/application/model/exact-postimage.js +11 -0
  58. package/dist/repository-mutation/application/model/exact-postimage.js.map +1 -0
  59. package/dist/repository-mutation/application/model/path-identity.d.ts +7 -0
  60. package/dist/repository-mutation/application/model/path-identity.d.ts.map +1 -0
  61. package/dist/repository-mutation/application/model/path-identity.js +2 -0
  62. package/dist/repository-mutation/application/model/path-identity.js.map +1 -0
  63. package/dist/repository-mutation/application/model/repository-path.d.ts +8 -0
  64. package/dist/repository-mutation/application/model/repository-path.d.ts.map +1 -0
  65. package/dist/repository-mutation/application/model/repository-path.js +74 -0
  66. package/dist/repository-mutation/application/model/repository-path.js.map +1 -0
  67. package/dist/scaffolding/adapters/node/filesystem-authority-workspace.d.ts.map +1 -1
  68. package/dist/scaffolding/adapters/node/filesystem-authority-workspace.js +52 -8
  69. package/dist/scaffolding/adapters/node/filesystem-authority-workspace.js.map +1 -1
  70. package/dist/scaffolding/adapters/node/filesystem-file-identity.d.ts +3 -19
  71. package/dist/scaffolding/adapters/node/filesystem-file-identity.d.ts.map +1 -1
  72. package/dist/scaffolding/adapters/node/filesystem-file-identity.js +1 -121
  73. package/dist/scaffolding/adapters/node/filesystem-file-identity.js.map +1 -1
  74. package/dist/scaffolding/adapters/node/filesystem-journal.d.ts +1 -1
  75. package/dist/scaffolding/adapters/node/filesystem-journal.d.ts.map +1 -1
  76. package/dist/scaffolding/adapters/node/filesystem-journal.js +4 -20
  77. package/dist/scaffolding/adapters/node/filesystem-journal.js.map +1 -1
  78. package/dist/scaffolding/adapters/node/filesystem-operation-state.d.ts +2 -1
  79. package/dist/scaffolding/adapters/node/filesystem-operation-state.d.ts.map +1 -1
  80. package/dist/scaffolding/adapters/node/filesystem-operation-state.js +73 -122
  81. package/dist/scaffolding/adapters/node/filesystem-operation-state.js.map +1 -1
  82. package/dist/scaffolding/adapters/node/filesystem-path-guard.d.ts.map +1 -1
  83. package/dist/scaffolding/adapters/node/filesystem-path-guard.js +27 -68
  84. package/dist/scaffolding/adapters/node/filesystem-path-guard.js.map +1 -1
  85. package/dist/scaffolding/adapters/node/installed-foundation-version.d.ts +1 -1
  86. package/dist/scaffolding/adapters/node/installed-foundation-version.d.ts.map +1 -1
  87. package/dist/scaffolding/adapters/node/installed-foundation-version.js +1 -9
  88. package/dist/scaffolding/adapters/node/installed-foundation-version.js.map +1 -1
  89. package/dist/scaffolding/application/policies/legacy-scaffolding-repository-path.d.ts +4 -0
  90. package/dist/scaffolding/application/policies/legacy-scaffolding-repository-path.d.ts.map +1 -0
  91. package/dist/scaffolding/application/policies/legacy-scaffolding-repository-path.js +48 -0
  92. package/dist/scaffolding/application/policies/legacy-scaffolding-repository-path.js.map +1 -0
  93. package/dist/scaffolding/kernel/authority-journal-validation.d.ts +4 -0
  94. package/dist/scaffolding/kernel/authority-journal-validation.d.ts.map +1 -0
  95. package/dist/scaffolding/kernel/authority-journal-validation.js +24 -0
  96. package/dist/scaffolding/kernel/authority-journal-validation.js.map +1 -0
  97. package/dist/transaction-coordination/adapters/node/installed-foundation-build-identity.d.ts +11 -0
  98. package/dist/transaction-coordination/adapters/node/installed-foundation-build-identity.d.ts.map +1 -0
  99. package/dist/transaction-coordination/adapters/node/installed-foundation-build-identity.js +130 -0
  100. package/dist/transaction-coordination/adapters/node/installed-foundation-build-identity.js.map +1 -0
  101. package/dist/transaction-coordination/adapters/node/node-foundation-operation-lock.d.ts +7 -0
  102. package/dist/transaction-coordination/adapters/node/node-foundation-operation-lock.d.ts.map +1 -0
  103. package/dist/transaction-coordination/adapters/node/node-foundation-operation-lock.js +336 -0
  104. package/dist/transaction-coordination/adapters/node/node-foundation-operation-lock.js.map +1 -0
  105. package/dist/transaction-coordination/adapters/node/node-foundation-state-directory.d.ts +4 -0
  106. package/dist/transaction-coordination/adapters/node/node-foundation-state-directory.d.ts.map +1 -0
  107. package/dist/transaction-coordination/adapters/node/node-foundation-state-directory.js +76 -0
  108. package/dist/transaction-coordination/adapters/node/node-foundation-state-directory.js.map +1 -0
  109. package/dist/transaction-coordination/adapters/node/node-foundation-transaction-coordinator.d.ts +3 -0
  110. package/dist/transaction-coordination/adapters/node/node-foundation-transaction-coordinator.d.ts.map +1 -0
  111. package/dist/transaction-coordination/adapters/node/node-foundation-transaction-coordinator.js +23 -0
  112. package/dist/transaction-coordination/adapters/node/node-foundation-transaction-coordinator.js.map +1 -0
  113. package/dist/transaction-coordination/adapters/node/node-foundation-transaction-slot.d.ts +12 -0
  114. package/dist/transaction-coordination/adapters/node/node-foundation-transaction-slot.d.ts.map +1 -0
  115. package/dist/transaction-coordination/adapters/node/node-foundation-transaction-slot.js +332 -0
  116. package/dist/transaction-coordination/adapters/node/node-foundation-transaction-slot.js.map +1 -0
  117. package/dist/transaction-coordination/application/foundation-transaction-coordinator.d.ts +22 -0
  118. package/dist/transaction-coordination/application/foundation-transaction-coordinator.d.ts.map +1 -0
  119. package/dist/transaction-coordination/application/foundation-transaction-coordinator.js +78 -0
  120. package/dist/transaction-coordination/application/foundation-transaction-coordinator.js.map +1 -0
  121. package/dist/transaction-coordination/application/foundation-transaction-error.d.ts +16 -0
  122. package/dist/transaction-coordination/application/foundation-transaction-error.d.ts.map +1 -0
  123. package/dist/transaction-coordination/application/foundation-transaction-error.js +19 -0
  124. package/dist/transaction-coordination/application/foundation-transaction-error.js.map +1 -0
  125. package/dist/transaction-coordination/application/model/transaction-status.d.ts +47 -0
  126. package/dist/transaction-coordination/application/model/transaction-status.d.ts.map +1 -0
  127. package/dist/transaction-coordination/application/model/transaction-status.js +2 -0
  128. package/dist/transaction-coordination/application/model/transaction-status.js.map +1 -0
  129. package/dist/transaction-coordination/application/ports/foundation-operation-lock.d.ts +7 -0
  130. package/dist/transaction-coordination/application/ports/foundation-operation-lock.d.ts.map +1 -0
  131. package/dist/transaction-coordination/application/ports/foundation-operation-lock.js +2 -0
  132. package/dist/transaction-coordination/application/ports/foundation-operation-lock.js.map +1 -0
  133. package/dist/transaction-coordination/application/ports/foundation-transaction-slot.d.ts +5 -0
  134. package/dist/transaction-coordination/application/ports/foundation-transaction-slot.d.ts.map +1 -0
  135. package/dist/transaction-coordination/application/ports/foundation-transaction-slot.js +2 -0
  136. package/dist/transaction-coordination/application/ports/foundation-transaction-slot.js.map +1 -0
  137. package/package.json +1 -1
@@ -0,0 +1,336 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { constants } from "node:fs";
3
+ import { open, rename, unlink } from "node:fs/promises";
4
+ import { hostname } from "node:os";
5
+ import { join } from "node:path";
6
+ import { TextDecoder } from "node:util";
7
+ import { FoundationError } from "../../../errors.js";
8
+ import { LOCAL_OPERATION_LOCK } from "../../../foundation-state-contract.js";
9
+ import { parseStrictJson } from "../../../strict-json.js";
10
+ import { readBoundedRegularFile } from "../../../repository-mutation/adapters/node/node-bounded-regular-file.js";
11
+ import { ensureFoundationStateDirectory, pruneFoundationStateDirectory, syncFoundationStateDirectory } from "./node-foundation-state-directory.js";
12
+ const maximumLockBytes = 8 * 1024;
13
+ const strictUtf8 = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
14
+ function isErrorCode(error, code) {
15
+ return (error instanceof Error &&
16
+ "code" in error &&
17
+ error.code === code);
18
+ }
19
+ function evidenceBytes(evidence) {
20
+ return Buffer.from(`${JSON.stringify(evidence)}\n`, "utf8");
21
+ }
22
+ function parseEvidence(value) {
23
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
24
+ throw new Error("Foundation operation lock evidence is invalid.");
25
+ }
26
+ const candidate = value;
27
+ const tokenIsValid = typeof candidate["token"] === "string" &&
28
+ /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u.test(candidate["token"]);
29
+ if (candidate["schemaVersion"] === 1 &&
30
+ candidate["kind"] === "transaction-barrier" &&
31
+ tokenIsValid &&
32
+ Object.keys(candidate).toSorted().join(",") === "kind,schemaVersion,token") {
33
+ return {
34
+ kind: "transaction-barrier",
35
+ schemaVersion: 1,
36
+ token: candidate["token"]
37
+ };
38
+ }
39
+ if (candidate["schemaVersion"] !== 1 ||
40
+ candidate["kind"] !== "active" ||
41
+ !tokenIsValid ||
42
+ typeof candidate["host"] !== "string" ||
43
+ candidate["host"].length === 0 ||
44
+ !Number.isSafeInteger(candidate["pid"]) ||
45
+ candidate["pid"] <= 0 ||
46
+ Object.keys(candidate).toSorted().join(",") !==
47
+ "host,kind,pid,schemaVersion,token") {
48
+ throw new Error("Foundation operation lock evidence is invalid.");
49
+ }
50
+ return {
51
+ host: candidate["host"],
52
+ kind: "active",
53
+ pid: candidate["pid"],
54
+ schemaVersion: 1,
55
+ token: candidate["token"]
56
+ };
57
+ }
58
+ async function readLock(path) {
59
+ const record = await readBoundedRegularFile(path, maximumLockBytes);
60
+ if (record.outcome !== "read") {
61
+ throw new Error("Foundation operation lock must be a stable bounded regular file.");
62
+ }
63
+ return {
64
+ evidence: parseEvidence(parseStrictJson(strictUtf8.decode(record.bytes))),
65
+ identity: record.identity
66
+ };
67
+ }
68
+ function identitiesEqual(left, right) {
69
+ return (left.birthtimeNs === right.birthtimeNs &&
70
+ left.dev === right.dev &&
71
+ left.ino === right.ino);
72
+ }
73
+ function evidenceEqual(left, right) {
74
+ if (left.kind !== right.kind || left.token !== right.token) {
75
+ return false;
76
+ }
77
+ return left.kind === "transaction-barrier" ||
78
+ right.kind === "transaction-barrier"
79
+ ? left.kind === right.kind
80
+ : left.host === right.host && left.pid === right.pid;
81
+ }
82
+ async function readHandleEvidence(handle, expectedIdentity) {
83
+ const before = await handle.stat({ bigint: true });
84
+ if (!before.isFile() ||
85
+ before.size > BigInt(maximumLockBytes) ||
86
+ !identitiesEqual({
87
+ birthtimeNs: before.birthtimeNs,
88
+ dev: before.dev,
89
+ ino: before.ino
90
+ }, expectedIdentity)) {
91
+ throw new Error("Foundation operation lock identity changed before rewrite.");
92
+ }
93
+ const bytes = Buffer.alloc(Number(before.size));
94
+ let offset = 0;
95
+ while (offset < bytes.byteLength) {
96
+ const { bytesRead } = await handle.read(bytes, offset, bytes.byteLength - offset, offset);
97
+ if (bytesRead === 0) {
98
+ throw new Error("Foundation operation lock was truncated before rewrite.");
99
+ }
100
+ offset += bytesRead;
101
+ }
102
+ const after = await handle.stat({ bigint: true });
103
+ if (before.birthtimeNs !== after.birthtimeNs ||
104
+ before.ctimeNs !== after.ctimeNs ||
105
+ before.dev !== after.dev ||
106
+ before.ino !== after.ino ||
107
+ before.mtimeNs !== after.mtimeNs ||
108
+ before.size !== after.size) {
109
+ throw new Error("Foundation operation lock changed during rewrite verification.");
110
+ }
111
+ return parseEvidence(parseStrictJson(strictUtf8.decode(bytes)));
112
+ }
113
+ async function rewriteOwnedLockEvidence(lockPath, expected, replacement) {
114
+ const noFollow = process.platform === "win32" ? 0 : constants.O_NOFOLLOW;
115
+ const handle = await open(lockPath, constants.O_RDWR | noFollow);
116
+ try {
117
+ const current = await readHandleEvidence(handle, expected.identity);
118
+ if (!evidenceEqual(current, expected.evidence)) {
119
+ throw new Error("Foundation operation lock ownership changed before rewrite.");
120
+ }
121
+ const bytes = evidenceBytes(replacement);
122
+ await handle.truncate(0);
123
+ let offset = 0;
124
+ while (offset < bytes.byteLength) {
125
+ const { bytesWritten } = await handle.write(bytes, offset, bytes.byteLength - offset, offset);
126
+ if (bytesWritten === 0) {
127
+ throw new Error("Foundation operation lock rewrite made no progress.");
128
+ }
129
+ offset += bytesWritten;
130
+ }
131
+ await handle.sync();
132
+ }
133
+ finally {
134
+ await handle.close();
135
+ }
136
+ const observed = await readLock(lockPath);
137
+ if (!evidenceEqual(observed.evidence, replacement) ||
138
+ !identitiesEqual(observed.identity, expected.identity)) {
139
+ throw new Error("Foundation operation lock rewrite was not published.");
140
+ }
141
+ return observed.identity;
142
+ }
143
+ function activeOwnerIsAlive(owner) {
144
+ if (owner.host !== hostname()) {
145
+ return undefined;
146
+ }
147
+ try {
148
+ process.kill(owner.pid, 0);
149
+ return true;
150
+ }
151
+ catch (error) {
152
+ return isErrorCode(error, "ESRCH") ? false : undefined;
153
+ }
154
+ }
155
+ async function createOwnedLock(directory, lockPath) {
156
+ const evidence = {
157
+ host: hostname(),
158
+ kind: "active",
159
+ pid: process.pid,
160
+ schemaVersion: 1,
161
+ token: randomUUID()
162
+ };
163
+ const handle = await open(lockPath, "wx", 0o600);
164
+ try {
165
+ await handle.writeFile(evidenceBytes(evidence));
166
+ await handle.sync();
167
+ }
168
+ finally {
169
+ await handle.close();
170
+ }
171
+ await syncFoundationStateDirectory(directory);
172
+ const observed = await readLock(lockPath);
173
+ if (observed.evidence.kind !== "active" ||
174
+ observed.evidence.token !== evidence.token) {
175
+ throw new Error("Foundation operation lock ownership was not published.");
176
+ }
177
+ return { evidence, identity: observed.identity };
178
+ }
179
+ async function takeoverLock(directory, lockPath) {
180
+ const expected = await readLock(lockPath);
181
+ if (expected.evidence.kind === "active" &&
182
+ activeOwnerIsAlive(expected.evidence) !== false) {
183
+ throw new Error("Foundation operation lock owner is live or cannot be proven dead.");
184
+ }
185
+ const evidence = {
186
+ host: hostname(),
187
+ kind: "active",
188
+ pid: process.pid,
189
+ schemaVersion: 1,
190
+ token: randomUUID()
191
+ };
192
+ const claimPath = `${lockPath}.claim.${expected.evidence.token}`;
193
+ let claimHeld = false;
194
+ let ownershipPublished = false;
195
+ try {
196
+ try {
197
+ const claimHandle = await open(claimPath, "wx", 0o600);
198
+ try {
199
+ await claimHandle.writeFile(evidenceBytes(evidence));
200
+ await claimHandle.sync();
201
+ }
202
+ finally {
203
+ await claimHandle.close();
204
+ }
205
+ await syncFoundationStateDirectory(directory);
206
+ claimHeld = true;
207
+ }
208
+ catch (error) {
209
+ if (isErrorCode(error, "EEXIST")) {
210
+ throw new Error("Foundation operation-lock takeover claim requires manual recovery.", { cause: error });
211
+ }
212
+ throw error;
213
+ }
214
+ const observed = await readLock(lockPath);
215
+ if (!evidenceEqual(observed.evidence, expected.evidence) ||
216
+ !identitiesEqual(observed.identity, expected.identity)) {
217
+ throw new Error("Foundation operation lock changed during takeover.");
218
+ }
219
+ const rewrittenIdentity = await rewriteOwnedLockEvidence(lockPath, observed, evidence);
220
+ await syncFoundationStateDirectory(directory);
221
+ const current = await readLock(lockPath);
222
+ if (current.evidence.kind !== "active" ||
223
+ current.evidence.token !== evidence.token ||
224
+ !identitiesEqual(current.identity, rewrittenIdentity)) {
225
+ throw new Error("Foundation operation-lock takeover was not published.");
226
+ }
227
+ ownershipPublished = true;
228
+ return { evidence, identity: current.identity };
229
+ }
230
+ finally {
231
+ if (claimHeld) {
232
+ await unlink(claimPath).catch((error) => {
233
+ if (!ownershipPublished && !isErrorCode(error, "ENOENT")) {
234
+ throw error;
235
+ }
236
+ });
237
+ }
238
+ }
239
+ }
240
+ async function quarantineObservedLock(directory, lockPath, observed, phase) {
241
+ const quarantinePath = `${lockPath}.${phase}.${observed.evidence.token}`;
242
+ await rename(lockPath, quarantinePath);
243
+ const quarantined = await readLock(quarantinePath);
244
+ if (quarantined.evidence.token !== observed.evidence.token ||
245
+ !identitiesEqual(quarantined.identity, observed.identity)) {
246
+ throw new Error("Foundation operation lock ownership changed during cleanup.");
247
+ }
248
+ await syncFoundationStateDirectory(directory);
249
+ return quarantinePath;
250
+ }
251
+ async function retainTransactionBarrier(directory, lockPath, owned) {
252
+ const current = await readLock(lockPath);
253
+ if (current.evidence.kind !== "active" ||
254
+ current.evidence.token !== owned.evidence.token ||
255
+ !identitiesEqual(current.identity, owned.identity)) {
256
+ throw new Error("Foundation operation lock ownership changed before retention.");
257
+ }
258
+ const barrier = {
259
+ kind: "transaction-barrier",
260
+ schemaVersion: 1,
261
+ token: owned.evidence.token
262
+ };
263
+ const beforePublish = await readLock(lockPath);
264
+ if (beforePublish.evidence.kind !== "active" ||
265
+ beforePublish.evidence.token !== owned.evidence.token ||
266
+ !identitiesEqual(beforePublish.identity, owned.identity)) {
267
+ throw new Error("Foundation operation lock ownership changed during retention.");
268
+ }
269
+ await rewriteOwnedLockEvidence(lockPath, beforePublish, barrier);
270
+ await syncFoundationStateDirectory(directory);
271
+ }
272
+ export class NodeFoundationOperationLock {
273
+ #consumerRoot;
274
+ constructor(consumerRoot) {
275
+ this.#consumerRoot = consumerRoot;
276
+ }
277
+ async acquire() {
278
+ const directory = await ensureFoundationStateDirectory(this.#consumerRoot);
279
+ const lockPath = join(directory, LOCAL_OPERATION_LOCK);
280
+ let owned;
281
+ try {
282
+ try {
283
+ owned = await createOwnedLock(directory, lockPath);
284
+ }
285
+ catch (error) {
286
+ if (!isErrorCode(error, "EEXIST")) {
287
+ throw error;
288
+ }
289
+ owned = await takeoverLock(directory, lockPath);
290
+ }
291
+ }
292
+ catch (error) {
293
+ throw new FoundationError("LOCAL_STATE_INVALID", "Another foundation operation is active or its lock is not safely recoverable.", { cause: error });
294
+ }
295
+ let state = "held";
296
+ let releaseInProgress;
297
+ return async (options = {}) => {
298
+ if (state === "released") {
299
+ return;
300
+ }
301
+ releaseInProgress ??= (async () => {
302
+ try {
303
+ if (options.retainTransactionBarrier === true) {
304
+ await retainTransactionBarrier(directory, lockPath, owned);
305
+ state = "released";
306
+ await syncFoundationStateDirectory(directory);
307
+ return;
308
+ }
309
+ const current = await readLock(lockPath);
310
+ if (current.evidence.kind !== "active" ||
311
+ current.evidence.token !== owned.evidence.token ||
312
+ !identitiesEqual(current.identity, owned.identity)) {
313
+ throw new Error("Foundation operation lock ownership was lost before release.");
314
+ }
315
+ const quarantinePath = await quarantineObservedLock(directory, lockPath, current, "released");
316
+ state = "released";
317
+ await unlink(quarantinePath);
318
+ await syncFoundationStateDirectory(directory);
319
+ await pruneFoundationStateDirectory(this.#consumerRoot);
320
+ await syncFoundationStateDirectory(this.#consumerRoot);
321
+ }
322
+ catch (error) {
323
+ throw new FoundationError("LOCAL_STATE_INVALID", "Foundation operation lock could not be released without violating ownership.", { cause: error });
324
+ }
325
+ })();
326
+ try {
327
+ await releaseInProgress;
328
+ }
329
+ catch (error) {
330
+ releaseInProgress = undefined;
331
+ throw error;
332
+ }
333
+ };
334
+ }
335
+ }
336
+ //# sourceMappingURL=node-foundation-operation-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-foundation-operation-lock.js","sourceRoot":"","sources":["../../../../src/transaction-coordination/adapters/node/node-foundation-operation-lock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function ensureFoundationStateDirectory(consumerRoot: string): Promise<string>;
2
+ export declare function syncFoundationStateDirectory(path: string): Promise<void>;
3
+ export declare function pruneFoundationStateDirectory(consumerRoot: string): Promise<void>;
4
+ //# sourceMappingURL=node-foundation-state-directory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-foundation-state-directory.d.ts","sourceRoot":"","sources":["../../../../src/transaction-coordination/adapters/node/node-foundation-state-directory.ts"],"names":[],"mappings":"AAMA,wBAAsB,8BAA8B,CAClD,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CA2CjB;AAED,wBAAsB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4B9E;AAED,wBAAsB,6BAA6B,CACjD,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAef"}
@@ -0,0 +1,76 @@
1
+ import { lstat, mkdir, open, realpath, rmdir } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { FoundationError } from "../../../errors.js";
4
+ import { LOCAL_STATE_DIRECTORY } from "../../../foundation-state-contract.js";
5
+ export async function ensureFoundationStateDirectory(consumerRoot) {
6
+ const directory = join(consumerRoot, LOCAL_STATE_DIRECTORY);
7
+ try {
8
+ const entry = await lstat(directory);
9
+ if (!entry.isDirectory() || entry.isSymbolicLink()) {
10
+ throw new FoundationError("LOCAL_STATE_INVALID", "Local foundation state path must be a real consumer-owned directory.");
11
+ }
12
+ if ((await realpath(directory)) !== directory) {
13
+ throw new FoundationError("LOCAL_STATE_INVALID", "Local foundation state directory resolves outside its expected path.");
14
+ }
15
+ return directory;
16
+ }
17
+ catch (error) {
18
+ if (!(error instanceof Error &&
19
+ "code" in error &&
20
+ error.code === "ENOENT")) {
21
+ throw error;
22
+ }
23
+ }
24
+ try {
25
+ await mkdir(directory);
26
+ }
27
+ catch (error) {
28
+ if (error instanceof Error &&
29
+ "code" in error &&
30
+ error.code === "EEXIST") {
31
+ return ensureFoundationStateDirectory(consumerRoot);
32
+ }
33
+ throw error;
34
+ }
35
+ await syncFoundationStateDirectory(consumerRoot);
36
+ return directory;
37
+ }
38
+ export async function syncFoundationStateDirectory(path) {
39
+ try {
40
+ const handle = await open(path, "r");
41
+ try {
42
+ await handle.sync();
43
+ }
44
+ finally {
45
+ await handle.close();
46
+ }
47
+ }
48
+ catch (error) {
49
+ if (error instanceof Error &&
50
+ "code" in error &&
51
+ error.code === "ENOENT") {
52
+ return;
53
+ }
54
+ if (process.platform === "win32" &&
55
+ error instanceof Error &&
56
+ "code" in error &&
57
+ ["EACCES", "EINVAL", "EISDIR", "EPERM"].includes(error.code ?? "")) {
58
+ return;
59
+ }
60
+ throw error;
61
+ }
62
+ }
63
+ export async function pruneFoundationStateDirectory(consumerRoot) {
64
+ try {
65
+ await rmdir(join(consumerRoot, LOCAL_STATE_DIRECTORY));
66
+ }
67
+ catch (error) {
68
+ if (error instanceof Error &&
69
+ "code" in error &&
70
+ ["ENOENT", "ENOTEMPTY"].includes(error.code ?? "")) {
71
+ return;
72
+ }
73
+ throw error;
74
+ }
75
+ }
76
+ //# sourceMappingURL=node-foundation-state-directory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-foundation-state-directory.js","sourceRoot":"","sources":["../../../../src/transaction-coordination/adapters/node/node-foundation-state-directory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { FoundationTransactionCoordinator } from "../../application/foundation-transaction-coordinator.js";
2
+ export declare function createNodeFoundationTransactionCoordinator(consumerRoot: string): Promise<FoundationTransactionCoordinator>;
3
+ //# sourceMappingURL=node-foundation-transaction-coordinator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-foundation-transaction-coordinator.d.ts","sourceRoot":"","sources":["../../../../src/transaction-coordination/adapters/node/node-foundation-transaction-coordinator.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gCAAgC,EAAE,MAAM,yDAAyD,CAAC;AAK3G,wBAAsB,0CAA0C,CAC9D,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,gCAAgC,CAAC,CAc3C"}
@@ -0,0 +1,23 @@
1
+ import { realpath } from "node:fs/promises";
2
+ import { resolve } from "node:path";
3
+ import { installedFoundationVersion } from "../../../package-version.js";
4
+ import { FoundationTransactionCoordinator } from "../../application/foundation-transaction-coordinator.js";
5
+ import { installedFoundationBuildIdentity } from "./installed-foundation-build-identity.js";
6
+ import { NodeFoundationOperationLock } from "./node-foundation-operation-lock.js";
7
+ import { NodeFoundationTransactionSlot } from "./node-foundation-transaction-slot.js";
8
+ export async function createNodeFoundationTransactionCoordinator(consumerRoot) {
9
+ const canonicalRoot = await realpath(resolve(consumerRoot));
10
+ const [installedVersion, installedBuildIdentity] = await Promise.all([
11
+ installedFoundationVersion(),
12
+ installedFoundationBuildIdentity()
13
+ ]);
14
+ return new FoundationTransactionCoordinator({
15
+ lock: new NodeFoundationOperationLock(canonicalRoot),
16
+ slot: new NodeFoundationTransactionSlot({
17
+ consumerRoot: canonicalRoot,
18
+ installedVersion,
19
+ installedBuildIdentity
20
+ })
21
+ });
22
+ }
23
+ //# sourceMappingURL=node-foundation-transaction-coordinator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-foundation-transaction-coordinator.js","sourceRoot":"","sources":["../../../../src/transaction-coordination/adapters/node/node-foundation-transaction-coordinator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,gCAAgC,EAAE,MAAM,yDAAyD,CAAC;AAC3G,OAAO,EAAE,gCAAgC,EAAE,MAAM,0CAA0C,CAAC;AAC5F,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AAEtF,MAAM,CAAC,KAAK,UAAU,0CAA0C,CAC9D,YAAoB;IAEpB,MAAM,aAAa,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;IAC5D,MAAM,CAAC,gBAAgB,EAAE,sBAAsB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACnE,0BAA0B,EAAE;QAC5B,gCAAgC,EAAE;KACnC,CAAC,CAAC;IACH,OAAO,IAAI,gCAAgC,CAAC;QAC1C,IAAI,EAAE,IAAI,2BAA2B,CAAC,aAAa,CAAC;QACpD,IAAI,EAAE,IAAI,6BAA6B,CAAC;YACtC,YAAY,EAAE,aAAa;YAC3B,gBAAgB;YAChB,sBAAsB;SACvB,CAAC;KACH,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { FoundationTransactionStatus } from "../../application/model/transaction-status.js";
2
+ import type { FoundationTransactionSlot } from "../../application/ports/foundation-transaction-slot.js";
3
+ export declare class NodeFoundationTransactionSlot implements FoundationTransactionSlot {
4
+ #private;
5
+ constructor(options: {
6
+ readonly consumerRoot: string;
7
+ readonly installedBuildIdentity: string;
8
+ readonly installedVersion: string;
9
+ });
10
+ inspect(): Promise<FoundationTransactionStatus>;
11
+ }
12
+ //# sourceMappingURL=node-foundation-transaction-slot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-foundation-transaction-slot.d.ts","sourceRoot":"","sources":["../../../../src/transaction-coordination/adapters/node/node-foundation-transaction-slot.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAIV,2BAA2B,EAC5B,MAAM,+CAA+C,CAAC;AACvD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wDAAwD,CAAC;AAuWxG,qBAAa,6BAA8B,YAAW,yBAAyB;;IAO7E,YAAY,OAAO,EAAE;QACnB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;QAC9B,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;QACxC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;KACnC,EAUA;IA6CK,OAAO,IAAI,OAAO,CAAC,2BAA2B,CAAC,CAYpD;CACF"}