@quolu/lattice 0.63.9 → 0.64.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 (72) hide show
  1. package/LICENSE +147 -147
  2. package/README.ja.md +378 -378
  3. package/README.md +303 -303
  4. package/bin/lattice-mcp.mjs +0 -0
  5. package/bin/lattice-scripted-adapter.mjs +0 -0
  6. package/bin/lattice-scripted-worker.mjs +0 -0
  7. package/bin/lattice-work-order-adapter.mjs +0 -0
  8. package/bin/lattice.mjs +0 -0
  9. package/docs/bridge-setup.md +248 -248
  10. package/docs/schemas/lattice.executor_packet.v1.schema.json +57 -57
  11. package/docs/schemas/lattice.executor_receipt.v1.schema.json +66 -66
  12. package/docs/schemas/lattice.phase_todo_revision.v3.schema.json +360 -360
  13. package/docs/schemas/lattice.plan_create_input.v1.schema.json +56 -56
  14. package/docs/schemas/lattice.plan_create_input.v2.schema.json +72 -72
  15. package/docs/schemas/lattice.plan_create_input.v3.schema.json +81 -81
  16. package/docs/schemas/lattice.plan_create_input.v4.schema.json +357 -357
  17. package/docs/schemas/lattice.plan_scope_review.v1.schema.json +55 -55
  18. package/docs/schemas/lattice.run_request.v1.schema.json +238 -238
  19. package/docs/schemas/lattice.runtime_adapter_capabilities.v2.schema.json +55 -55
  20. package/docs/schemas/lattice.runtime_adapter_registration_input.v1.schema.json +78 -78
  21. package/docs/schemas/lattice.runtime_adapter_registration_input.v2.schema.json +86 -86
  22. package/docs/schemas/lattice.todo_extraction.v2.schema.json +298 -298
  23. package/docs/schemas/lattice.todo_extraction.v3.schema.json +150 -150
  24. package/docs/schemas/lattice.todo_extraction.v4.schema.json +161 -161
  25. package/docs/schemas/lattice.todo_revision.v2.schema.json +260 -260
  26. package/docs/schemas/lattice.todo_revision_set.v3.schema.json +363 -363
  27. package/docs/schemas/lattice.todo_structure_binding.v1.schema.json +47 -47
  28. package/docs/schemas/lattice.todo_structure_realization.v1.schema.json +55 -55
  29. package/docs/schemas/lattice.todo_structure_set.v1.schema.json +264 -264
  30. package/package.json +109 -109
  31. package/sensor/LICENSE +21 -21
  32. package/sensor/NOTICE +19 -19
  33. package/sensor/dist/bin/lattice-sensor.js +9 -9
  34. package/sensor/dist/db/index.js +24 -24
  35. package/sensor/dist/db/migrations.js +41 -41
  36. package/sensor/dist/db/queries.js +164 -164
  37. package/sensor/dist/db/schema.sql +205 -205
  38. package/sensor/dist/directory.js +5 -5
  39. package/sensor/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
  40. package/sensor/dist/extraction/wasm/tree-sitter-cfml.wasm +0 -0
  41. package/sensor/dist/extraction/wasm/tree-sitter-cfquery.wasm +0 -0
  42. package/sensor/dist/extraction/wasm/tree-sitter-cfscript.wasm +0 -0
  43. package/sensor/dist/extraction/wasm/tree-sitter-cobol.wasm +0 -0
  44. package/sensor/dist/extraction/wasm/tree-sitter-erlang.wasm +0 -0
  45. package/sensor/dist/extraction/wasm/tree-sitter-go.wasm +0 -0
  46. package/sensor/dist/extraction/wasm/tree-sitter-java.wasm +0 -0
  47. package/sensor/dist/extraction/wasm/tree-sitter-javascript.wasm +0 -0
  48. package/sensor/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
  49. package/sensor/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
  50. package/sensor/dist/extraction/wasm/tree-sitter-python.wasm +0 -0
  51. package/sensor/dist/extraction/wasm/tree-sitter-tsx.wasm +0 -0
  52. package/sensor/dist/extraction/wasm/tree-sitter-typescript.wasm +0 -0
  53. package/sensor/dist/extraction/wasm/tree-sitter-vbnet.wasm +0 -0
  54. package/sensor/dist/mcp/liveness-watchdog.js +53 -53
  55. package/sensor/dist/mcp/server-instructions.js +95 -95
  56. package/sensor/package.json +56 -56
  57. package/src/cli-help.mjs +5 -5
  58. package/src/fs-dir-sync.mjs +14 -0
  59. package/src/hooks-cli.mjs +85 -42
  60. package/src/rc2-campaign.mjs +1 -12
  61. package/src/runtime-adapter-registry.mjs +2 -10
  62. package/src/runtime-cli.mjs +2 -6
  63. package/src/runtime-control-store.mjs +1 -8
  64. package/src/runtime-driver-state.mjs +1 -12
  65. package/src/runtime-gate-store.mjs +1 -8
  66. package/src/runtime-lifecycle-lock.mjs +1 -8
  67. package/src/runtime-multi-epoch-store.mjs +1 -12
  68. package/src/runtime-pull-intake.mjs +1 -8
  69. package/src/runtime-scripted-adapter-controller.mjs +2 -10
  70. package/src/runtime-work-order-controller.mjs +2 -10
  71. package/src/todo-note-store.mjs +2 -6
  72. package/src/todo-store.mjs +2 -14
@@ -1,4 +1,5 @@
1
1
  import { createHash, randomUUID } from 'node:crypto';
2
+ import { fsyncDirectory } from './fs-dir-sync.mjs';
2
3
  import { constants as fsConstants } from 'node:fs';
3
4
  import {
4
5
  lstat,
@@ -187,16 +188,7 @@ async function durableReplaceBytes(directory, name, bytes) {
187
188
  await handle.close();
188
189
  handle = null;
189
190
  await rename(temporaryPath, path.join(directory, name));
190
- const directoryHandle = await open(directory, fsConstants.O_RDONLY);
191
- // Windowsはdirectory handleのfsyncを許さず常にEPERM/EINVALを返す(Node仕様)。
192
- // win32のこの2値だけ許容し、他OS・他エラーは従来どおり失敗させる。
193
- try {
194
- await directoryHandle.sync();
195
- } catch (error) {
196
- if (process.platform !== 'win32' || !['EPERM', 'EINVAL'].includes(error?.code)) throw error;
197
- } finally {
198
- await directoryHandle.close();
199
- }
191
+ await fsyncDirectory(directory);
200
192
  } finally {
201
193
  if (handle) await handle.close().catch(() => {});
202
194
  await rm(temporaryPath, { force: true }).catch(() => {});
@@ -1,4 +1,5 @@
1
1
  import { gitSpawn } from './git-process.mjs';
2
+ import { fsyncDirectory } from './fs-dir-sync.mjs';
2
3
  import { createHash, randomUUID } from 'node:crypto';
3
4
  import { constants as fsConstants } from 'node:fs';
4
5
  import {
@@ -794,12 +795,7 @@ async function durableReplaceBytes(directory, name, bytes) {
794
795
  await handle.close();
795
796
  handle = null;
796
797
  await rename(temporaryPath, path.join(directory, name));
797
- const directoryHandle = await open(directory, fsConstants.O_RDONLY);
798
- // Windowsはdirectory handleのfsyncを許さず常にEPERM/EINVALを返す(Node仕様)。
799
- // win32のこの2値だけ許容し、他OS・他エラーは従来どおり失敗させる。
800
- try { await directoryHandle.sync(); } catch (error) {
801
- if (process.platform !== 'win32' || !['EPERM', 'EINVAL'].includes(error?.code)) throw error;
802
- } finally { await directoryHandle.close(); }
798
+ await fsyncDirectory(directory);
803
799
  } finally {
804
800
  if (handle) await handle.close().catch(() => {});
805
801
  await rm(temporaryPath, { force: true }).catch(() => {});
@@ -1,4 +1,5 @@
1
1
  import { randomUUID } from 'node:crypto';
2
+ import { fsyncDirectory } from './fs-dir-sync.mjs';
2
3
  import { constants as fsConstants } from 'node:fs';
3
4
  import { lstat, open, readFile, rename, unlink } from 'node:fs/promises';
4
5
  import path from 'node:path';
@@ -279,14 +280,6 @@ async function readCanonical(pathname, validator, label, { missing = false } = {
279
280
  return { value, bytes };
280
281
  }
281
282
 
282
- async function fsyncDirectory(directory) {
283
- const handle = await open(directory, fsConstants.O_RDONLY);
284
- // Windowsはdirectory handleのfsyncを許さず常にEPERM/EINVALを返す(Node仕様)。
285
- // win32のこの2値だけ許容し、他OS・他エラーは従来どおり失敗させる。
286
- try { await handle.sync(); } catch (error) {
287
- if (process.platform !== 'win32' || !['EPERM', 'EINVAL'].includes(error?.code)) throw error;
288
- } finally { await handle.close(); }
289
- }
290
283
 
291
284
  async function inject(crashInjector, point, context) {
292
285
  if (typeof crashInjector === 'function') await crashInjector(point, structuredClone(context));
@@ -1,4 +1,5 @@
1
1
  import { randomUUID } from 'node:crypto';
2
+ import { fsyncDirectory } from './fs-dir-sync.mjs';
2
3
  import { lstat, mkdir, open, readFile, rename, rm } from 'node:fs/promises';
3
4
  import path from 'node:path';
4
5
 
@@ -75,18 +76,6 @@ function statePath(runDir) {
75
76
  return path.join(runDir, 'supervisor', 'driver-state.json');
76
77
  }
77
78
 
78
- async function fsyncDirectory(directory) {
79
- const handle = await open(directory, 'r');
80
- // Windowsはdirectory handleのfsyncを許さず常にEPERM/EINVALを返す(Node仕様)。
81
- // win32のこの2値だけ許容し、他OS・他エラーは従来どおり失敗させる。
82
- try {
83
- await handle.sync();
84
- } catch (error) {
85
- if (process.platform !== 'win32' || !['EPERM', 'EINVAL'].includes(error?.code)) throw error;
86
- } finally {
87
- await handle.close();
88
- }
89
- }
90
79
 
91
80
  export async function replaceRuntimeDriverState({
92
81
  runDir,
@@ -1,4 +1,5 @@
1
1
  import { randomUUID } from 'node:crypto';
2
+ import { fsyncDirectory } from './fs-dir-sync.mjs';
2
3
  import { constants as fsConstants } from 'node:fs';
3
4
  import { lstat, mkdir, open, readFile, rename, unlink } from 'node:fs/promises';
4
5
  import path from 'node:path';
@@ -197,14 +198,6 @@ async function readCanonical(pathname, validator, label, { missing = false } = {
197
198
  return value;
198
199
  }
199
200
 
200
- async function fsyncDirectory(directory) {
201
- const handle = await open(directory, fsConstants.O_RDONLY);
202
- // Windowsはdirectory handleのfsyncを許さず常にEPERM/EINVALを返す(Node仕様)。
203
- // win32のこの2値だけ許容し、他OS・他エラーは従来どおり失敗させる。
204
- try { await handle.sync(); } catch (error) {
205
- if (process.platform !== 'win32' || !['EPERM', 'EINVAL'].includes(error?.code)) throw error;
206
- } finally { await handle.close(); }
207
- }
208
201
 
209
202
  async function inject(crashInjector, point, context) {
210
203
  if (typeof crashInjector === 'function') await crashInjector(point, structuredClone(context));
@@ -1,4 +1,5 @@
1
1
  import { randomUUID } from 'node:crypto';
2
+ import { fsyncDirectory as syncDirectory } from './fs-dir-sync.mjs';
2
3
  import { constants as fsConstants } from 'node:fs';
3
4
  import { lstat, open, readFile, rename, rm, unlink } from 'node:fs/promises';
4
5
  import path from 'node:path';
@@ -124,14 +125,6 @@ async function ownerIsLive(artifact, observer) {
124
125
  return observed.identity_digest === artifact.owner_process_start_identity.identity_digest;
125
126
  }
126
127
 
127
- async function syncDirectory(directory) {
128
- const handle = await open(directory, fsConstants.O_RDONLY);
129
- // Windowsはdirectory handleのfsyncを許さず常にEPERM/EINVALを返す(Node仕様)。
130
- // win32のこの2値だけ許容し、他OS・他エラーは従来どおり失敗させる。
131
- try { await handle.sync(); } catch (error) {
132
- if (process.platform !== 'win32' || !['EPERM', 'EINVAL'].includes(error?.code)) throw error;
133
- } finally { await handle.close(); }
134
- }
135
128
 
136
129
  async function recoverStaleLock(lockPath, expectedDigest) {
137
130
  const quarantine = path.join(path.dirname(lockPath),
@@ -1,3 +1,4 @@
1
+ import { fsyncDirectory } from './fs-dir-sync.mjs';
1
2
  import {
2
3
  lstat,
3
4
  mkdir,
@@ -217,18 +218,6 @@ async function readRegularJson(filePath, label) {
217
218
  }
218
219
  }
219
220
 
220
- async function fsyncDirectory(directory) {
221
- const handle = await open(directory, 'r');
222
- // Windowsはdirectory handleのfsyncを許さず常にEPERM/EINVALを返す(Node仕様)。
223
- // win32のこの2値だけ許容し、他OS・他エラーは従来どおり失敗させる。
224
- try {
225
- await handle.sync();
226
- } catch (error) {
227
- if (process.platform !== 'win32' || !['EPERM', 'EINVAL'].includes(error?.code)) throw error;
228
- } finally {
229
- await handle.close();
230
- }
231
- }
232
221
 
233
222
  async function writeDurableJson(filePath, value, { exclusive = true } = {}) {
234
223
  const bytes = `${JSON.stringify(value, null, 1)}\n`;
@@ -1,4 +1,5 @@
1
1
  import { spawn } from 'node:child_process';
2
+ import { fsyncDirectory as syncDirectory } from './fs-dir-sync.mjs';
2
3
  import { createHash, randomUUID } from 'node:crypto';
3
4
  import { constants as fsConstants } from 'node:fs';
4
5
  import {
@@ -94,14 +95,6 @@ async function readJson(filePath, label) {
94
95
  return value;
95
96
  }
96
97
 
97
- async function syncDirectory(directory) {
98
- const handle = await open(directory, fsConstants.O_RDONLY);
99
- // Windowsはdirectory handleのfsyncを許さず常にEPERM/EINVALを返す(Node仕様)。
100
- // win32のこの2値だけ許容し、他OS・他エラーは従来どおり失敗させる。
101
- try { await handle.sync(); } catch (error) {
102
- if (process.platform !== 'win32' || !['EPERM', 'EINVAL'].includes(error?.code)) throw error;
103
- } finally { await handle.close(); }
104
- }
105
98
 
106
99
  async function writeCanonicalNew(filePath, value) {
107
100
  await writeFile(filePath, `${canonicalizeArtifact(value)}\n`, { mode: 0o600, flag: 'wx' });
@@ -1,4 +1,5 @@
1
1
  import net from 'node:net';
2
+ import { fsyncDirectory } from './fs-dir-sync.mjs';
2
3
  import { createHash, randomBytes } from 'node:crypto';
3
4
  import { execFile, spawn } from 'node:child_process';
4
5
  import { constants as fsConstants, readFileSync } from 'node:fs';
@@ -172,16 +173,7 @@ async function durableReplaceBytes(filePath, bytes, mode = 0o600) {
172
173
  handle = null;
173
174
  await rename(temporaryPath, filePath);
174
175
  await chmod(filePath, mode);
175
- const directoryHandle = await open(directory, fsConstants.O_RDONLY);
176
- // Windowsはdirectory handleのfsyncを許さず常にEPERM/EINVALを返す(Node仕様)。
177
- // win32のこの2値だけ許容し、他OS・他エラーは従来どおり失敗させる。
178
- try {
179
- await directoryHandle.sync();
180
- } catch (error) {
181
- if (process.platform !== 'win32' || !['EPERM', 'EINVAL'].includes(error?.code)) throw error;
182
- } finally {
183
- await directoryHandle.close();
184
- }
176
+ await fsyncDirectory(directory);
185
177
  } finally {
186
178
  await handle?.close().catch(() => {});
187
179
  await rm(temporaryPath, { force: true }).catch(() => {});
@@ -1,4 +1,5 @@
1
1
  import net from 'node:net';
2
+ import { fsyncDirectory } from './fs-dir-sync.mjs';
2
3
  import { createHash, randomBytes } from 'node:crypto';
3
4
  import { constants as fsConstants, readFileSync } from 'node:fs';
4
5
  import {
@@ -166,16 +167,7 @@ async function durableReplaceBytes(filePath, bytes, mode = 0o600) {
166
167
  handle = null;
167
168
  await rename(temporaryPath, filePath);
168
169
  await chmod(filePath, mode);
169
- const directoryHandle = await open(directory, fsConstants.O_RDONLY);
170
- // Windowsはdirectory handleのfsyncを許さず常にEPERM/EINVALを返す(Node仕様)。
171
- // win32のこの2値だけ許容し、他OS・他エラーは従来どおり失敗させる。
172
- try {
173
- await directoryHandle.sync();
174
- } catch (error) {
175
- if (process.platform !== 'win32' || !['EPERM', 'EINVAL'].includes(error?.code)) throw error;
176
- } finally {
177
- await directoryHandle.close();
178
- }
170
+ await fsyncDirectory(directory);
179
171
  } finally {
180
172
  await handle?.close().catch(() => {});
181
173
  await rm(temporaryPath, { force: true }).catch(() => {});
@@ -1,4 +1,5 @@
1
1
  import { createHash, randomBytes } from 'node:crypto';
2
+ import { fsyncDirectory } from './fs-dir-sync.mjs';
2
3
  import {
3
4
  mkdir, open, readFile, readdir, rename, rm, stat,
4
5
  } from 'node:fs/promises';
@@ -193,12 +194,7 @@ async function atomicWrite(ref, bytes) {
193
194
  await handle.close();
194
195
  handle = null;
195
196
  await rename(temporary, ref);
196
- const directory = await open(path.dirname(ref), 'r');
197
- // Windowsはdirectory handleのfsyncを許さず常にEPERM/EINVALを返す(Node仕様)。
198
- // win32のこの2値だけ許容し、他OS・他エラーは従来どおり失敗させる。
199
- try { await directory.sync(); } catch (error) {
200
- if (process.platform !== 'win32' || !['EPERM', 'EINVAL'].includes(error?.code)) throw error;
201
- } finally { await directory.close(); }
197
+ await fsyncDirectory(path.dirname(ref));
202
198
  } finally {
203
199
  if (handle) await handle.close();
204
200
  await rm(temporary, { force: true });
@@ -1,4 +1,5 @@
1
1
  import { randomBytes } from 'node:crypto';
2
+ import { fsyncDirectory } from './fs-dir-sync.mjs';
2
3
  import {
3
4
  lstat, mkdir, open, readFile, readdir, realpath, rename, rm, rmdir,
4
5
  } from 'node:fs/promises';
@@ -1654,12 +1655,7 @@ async function atomicWrite(absolute, bytes) {
1654
1655
  }
1655
1656
  await handle.close(); handle = null;
1656
1657
  await rename(temporary, absolute);
1657
- const directory = await open(path.dirname(absolute), 'r');
1658
- // Windowsはdirectory handleのfsyncを許さず常にEPERM/EINVALを返す(Node仕様)。
1659
- // win32のこの2値だけ許容し、他OS・他エラーは従来どおり失敗させる。
1660
- try { await directory.sync(); } catch (error) {
1661
- if (process.platform !== 'win32' || !['EPERM', 'EINVAL'].includes(error?.code)) throw error;
1662
- } finally { await directory.close(); }
1658
+ await fsyncDirectory(path.dirname(absolute));
1663
1659
  } finally {
1664
1660
  if (handle) await handle.close();
1665
1661
  await rm(temporary, { force: true });
@@ -1687,14 +1683,6 @@ async function atomicWriteMode(absolute, bytes, mode) {
1687
1683
  }
1688
1684
  }
1689
1685
 
1690
- async function fsyncDirectory(absolute) {
1691
- const directory = await open(absolute, 'r');
1692
- // Windowsはdirectory handleのfsyncを許さず常にEPERM/EINVALを返す(Node仕様)。
1693
- // win32のこの2値だけ許容し、他OS・他エラーは従来どおり失敗させる。
1694
- try { await directory.sync(); } catch (error) {
1695
- if (process.platform !== 'win32' || !['EPERM', 'EINVAL'].includes(error?.code)) throw error;
1696
- } finally { await directory.close(); }
1697
- }
1698
1686
 
1699
1687
  async function createWriteLock(lockRef, { recordOwner = false } = {}) {
1700
1688
  const handle = await open(lockRef, 'wx', 0o600);