@ttsc/graph 0.30.3 → 0.31.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 (292) hide show
  1. package/README.md +122 -30
  2. package/lib/CapturedProcessOutput.d.ts +47 -0
  3. package/lib/CapturedProcessOutput.js +3 -0
  4. package/lib/CapturedProcessOutput.js.map +1 -0
  5. package/lib/ILauncherOption.d.ts +22 -0
  6. package/lib/ILauncherOption.js +3 -0
  7. package/lib/ILauncherOption.js.map +1 -0
  8. package/lib/IProjectOptions.d.ts +18 -0
  9. package/lib/IProjectOptions.js +3 -0
  10. package/lib/IProjectOptions.js.map +1 -0
  11. package/lib/ParsedLauncherOptions.d.ts +13 -0
  12. package/lib/ParsedLauncherOptions.js +3 -0
  13. package/lib/ParsedLauncherOptions.js.map +1 -0
  14. package/lib/TtscGraphApplication.d.ts +38 -1
  15. package/lib/TtscGraphApplication.js +26 -1
  16. package/lib/TtscGraphApplication.js.map +1 -1
  17. package/lib/TtscGraphLauncherArguments.d.ts +115 -0
  18. package/lib/TtscGraphLauncherArguments.js +181 -0
  19. package/lib/TtscGraphLauncherArguments.js.map +1 -0
  20. package/lib/TtscGraphViewSnapshot.d.ts +35 -0
  21. package/lib/TtscGraphViewSnapshot.js +48 -0
  22. package/lib/TtscGraphViewSnapshot.js.map +1 -0
  23. package/lib/index.d.ts +9 -24
  24. package/lib/index.js +6 -128
  25. package/lib/index.js.map +1 -1
  26. package/lib/internal/GraphProcessTrace.d.ts +1 -0
  27. package/lib/internal/GraphProcessTrace.js +235 -0
  28. package/lib/internal/GraphProcessTrace.js.map +1 -0
  29. package/lib/launcherArgs.d.ts +75 -16
  30. package/lib/launcherArgs.js +77 -8
  31. package/lib/launcherArgs.js.map +1 -1
  32. package/lib/model/IArtifactDirectory.d.ts +26 -0
  33. package/lib/model/IArtifactDirectory.js +3 -0
  34. package/lib/model/IArtifactDirectory.js.map +1 -0
  35. package/lib/model/IArtifactInputs.d.ts +19 -0
  36. package/lib/model/IArtifactInputs.js +3 -0
  37. package/lib/model/IArtifactInputs.js.map +1 -0
  38. package/lib/model/IPublishedArtifacts.d.ts +76 -0
  39. package/lib/model/IPublishedArtifacts.js +3 -0
  40. package/lib/model/IPublishedArtifacts.js.map +1 -0
  41. package/lib/model/IPublishedArtifactsResident.d.ts +19 -0
  42. package/lib/model/IPublishedArtifactsResident.js +3 -0
  43. package/lib/model/IPublishedArtifactsResident.js.map +1 -0
  44. package/lib/model/ITtscLintDaemonTarget.d.ts +20 -0
  45. package/lib/model/ITtscLintDaemonTarget.js +3 -0
  46. package/lib/model/ITtscLintDaemonTarget.js.map +1 -0
  47. package/lib/model/TtscGraphLinePeer.d.ts +146 -0
  48. package/lib/model/TtscGraphLinePeer.js +213 -0
  49. package/lib/model/TtscGraphLinePeer.js.map +1 -0
  50. package/lib/model/TtscGraphMemory.d.ts +156 -16
  51. package/lib/model/TtscGraphMemory.js +228 -222
  52. package/lib/model/TtscGraphMemory.js.map +1 -1
  53. package/lib/model/TtscGraphNativeArguments.d.ts +40 -0
  54. package/lib/model/TtscGraphNativeArguments.js +64 -0
  55. package/lib/model/TtscGraphNativeArguments.js.map +1 -0
  56. package/lib/model/TtscGraphNodeId.d.ts +55 -3
  57. package/lib/model/TtscGraphNodeId.js +40 -2
  58. package/lib/model/TtscGraphNodeId.js.map +1 -1
  59. package/lib/model/TtscGraphProjection.d.ts +156 -0
  60. package/lib/model/TtscGraphProjection.js +390 -0
  61. package/lib/model/TtscGraphProjection.js.map +1 -0
  62. package/lib/model/TtscGraphProtocol.d.ts +28 -0
  63. package/lib/model/TtscGraphProtocol.js +928 -0
  64. package/lib/model/TtscGraphProtocol.js.map +1 -0
  65. package/lib/model/TtscGraphReadonly.d.ts +15 -0
  66. package/lib/model/TtscGraphReadonly.js +3 -0
  67. package/lib/model/TtscGraphReadonly.js.map +1 -0
  68. package/lib/model/TtscGraphRequestOptions.d.ts +16 -0
  69. package/lib/model/TtscGraphRequestOptions.js +3 -0
  70. package/lib/model/TtscGraphRequestOptions.js.map +1 -0
  71. package/lib/model/TtscGraphSession.d.ts +82 -36
  72. package/lib/model/TtscGraphSession.js +164 -1238
  73. package/lib/model/TtscGraphSession.js.map +1 -1
  74. package/lib/model/TtscGraphSessionOptions.d.ts +20 -0
  75. package/lib/model/TtscGraphSessionOptions.js +3 -0
  76. package/lib/model/TtscGraphSessionOptions.js.map +1 -0
  77. package/lib/model/TtscGraphSessionState.d.ts +187 -0
  78. package/lib/model/TtscGraphSessionState.js +417 -0
  79. package/lib/model/TtscGraphSessionState.js.map +1 -0
  80. package/lib/model/TtscGraphShardStore.d.ts +64 -3
  81. package/lib/model/TtscGraphShardStore.js +85 -15
  82. package/lib/model/TtscGraphShardStore.js.map +1 -1
  83. package/lib/model/TtscGraphSourceReader.d.ts +31 -8
  84. package/lib/model/TtscGraphSourceReader.js +37 -13
  85. package/lib/model/TtscGraphSourceReader.js.map +1 -1
  86. package/lib/model/TtscLintDaemon.d.ts +35 -17
  87. package/lib/model/TtscLintDaemon.js +39 -117
  88. package/lib/model/TtscLintDaemon.js.map +1 -1
  89. package/lib/model/TtscLintDaemonState.d.ts +69 -0
  90. package/lib/model/TtscLintDaemonState.js +166 -0
  91. package/lib/model/TtscLintDaemonState.js.map +1 -0
  92. package/lib/model/copyGraphRecords.d.ts +14 -0
  93. package/lib/model/copyGraphRecords.js +19 -0
  94. package/lib/model/copyGraphRecords.js.map +1 -0
  95. package/lib/model/copyGraphSnapshot.d.ts +17 -0
  96. package/lib/model/copyGraphSnapshot.js +33 -0
  97. package/lib/model/copyGraphSnapshot.js.map +1 -0
  98. package/lib/model/loadGraph.d.ts +19 -10
  99. package/lib/model/loadGraph.js +21 -12
  100. package/lib/model/loadGraph.js.map +1 -1
  101. package/lib/model/publishedArtifacts.d.ts +78 -97
  102. package/lib/model/publishedArtifacts.js +271 -85
  103. package/lib/model/publishedArtifacts.js.map +1 -1
  104. package/lib/nativeExecutable.d.ts +19 -8
  105. package/lib/nativeExecutable.js +75 -15
  106. package/lib/nativeExecutable.js.map +1 -1
  107. package/lib/reduce.d.ts +19 -45
  108. package/lib/reduce.js +19 -3
  109. package/lib/reduce.js.map +1 -1
  110. package/lib/resolveGraphBinary.d.ts +9 -0
  111. package/lib/resolveGraphBinary.js +11 -3
  112. package/lib/resolveGraphBinary.js.map +1 -1
  113. package/lib/runGraph.d.ts +21 -0
  114. package/lib/runGraph.js +83 -0
  115. package/lib/runGraph.js.map +1 -0
  116. package/lib/server/IResolvedGraphHandle.d.ts +22 -0
  117. package/lib/server/IResolvedGraphHandle.js +3 -0
  118. package/lib/server/IResolvedGraphHandle.js.map +1 -0
  119. package/lib/server/createServer.d.ts +14 -10
  120. package/lib/server/createServer.js +42 -39
  121. package/lib/server/createServer.js.map +1 -1
  122. package/lib/server/exportSurface.d.ts +23 -1
  123. package/lib/server/exportSurface.js +23 -1
  124. package/lib/server/exportSurface.js.map +1 -1
  125. package/lib/server/formatGraphFailure.d.ts +20 -0
  126. package/lib/server/formatGraphFailure.js +35 -0
  127. package/lib/server/formatGraphFailure.js.map +1 -0
  128. package/lib/server/pathPolicy.d.ts +70 -5
  129. package/lib/server/pathPolicy.js +66 -4
  130. package/lib/server/pathPolicy.js.map +1 -1
  131. package/lib/server/resolveHandle.d.ts +10 -5
  132. package/lib/server/resolveHandle.js +39 -7
  133. package/lib/server/resolveHandle.js.map +1 -1
  134. package/lib/server/resultAudit.d.ts +17 -14
  135. package/lib/server/resultAudit.js +56 -27
  136. package/lib/server/resultAudit.js.map +1 -1
  137. package/lib/server/resultNext.d.ts +26 -1
  138. package/lib/server/resultNext.js +14 -0
  139. package/lib/server/resultNext.js.map +1 -1
  140. package/lib/server/runDetails.d.ts +72 -15
  141. package/lib/server/runDetails.js +104 -69
  142. package/lib/server/runDetails.js.map +1 -1
  143. package/lib/server/runEntrypoints.d.ts +9 -0
  144. package/lib/server/runEntrypoints.js +9 -0
  145. package/lib/server/runEntrypoints.js.map +1 -1
  146. package/lib/server/runLookup.d.ts +13 -3
  147. package/lib/server/runLookup.js +19 -6
  148. package/lib/server/runLookup.js.map +1 -1
  149. package/lib/server/runOverview.d.ts +13 -4
  150. package/lib/server/runOverview.js +13 -4
  151. package/lib/server/runOverview.js.map +1 -1
  152. package/lib/server/runTour.d.ts +9 -0
  153. package/lib/server/runTour.js +33 -65
  154. package/lib/server/runTour.js.map +1 -1
  155. package/lib/server/runTrace.d.ts +25 -1
  156. package/lib/server/runTrace.js +133 -88
  157. package/lib/server/runTrace.js.map +1 -1
  158. package/lib/server/startServer.d.ts +16 -0
  159. package/lib/server/startServer.js +24 -1
  160. package/lib/server/startServer.js.map +1 -1
  161. package/lib/structures/ITtscGraphApplication.d.ts +95 -41
  162. package/lib/structures/ITtscGraphDecorator.d.ts +18 -0
  163. package/lib/structures/ITtscGraphDetails.d.ts +81 -6
  164. package/lib/structures/ITtscGraphDocTag.d.ts +17 -8
  165. package/lib/structures/ITtscGraphDump.d.ts +106 -8
  166. package/lib/structures/ITtscGraphEdge.d.ts +14 -2
  167. package/lib/structures/ITtscGraphEntrypoints.d.ts +81 -6
  168. package/lib/structures/ITtscGraphEscape.d.ts +24 -2
  169. package/lib/structures/ITtscGraphEvidence.d.ts +9 -0
  170. package/lib/structures/ITtscGraphLookup.d.ts +42 -9
  171. package/lib/structures/ITtscGraphNext.d.ts +12 -1
  172. package/lib/structures/ITtscGraphNode.d.ts +38 -11
  173. package/lib/structures/ITtscGraphOverview.d.ts +81 -6
  174. package/lib/structures/ITtscGraphSnapshot.d.ts +97 -2
  175. package/lib/structures/ITtscGraphSpan.d.ts +9 -0
  176. package/lib/structures/ITtscGraphTour.d.ts +83 -9
  177. package/lib/structures/ITtscGraphTrace.d.ts +99 -14
  178. package/lib/structures/RawDump.d.ts +22 -0
  179. package/lib/structures/RawDump.js +3 -0
  180. package/lib/structures/RawDump.js.map +1 -0
  181. package/lib/structures/RawEdge.d.ts +20 -0
  182. package/lib/structures/RawEdge.js +3 -0
  183. package/lib/structures/RawEdge.js.map +1 -0
  184. package/lib/structures/RawNode.d.ts +26 -0
  185. package/lib/structures/RawNode.js +3 -0
  186. package/lib/structures/RawNode.js.map +1 -0
  187. package/lib/structures/TtscGraphArtifactNodeKind.d.ts +9 -0
  188. package/lib/structures/TtscGraphArtifactNodeKind.js +9 -0
  189. package/lib/structures/TtscGraphArtifactNodeKind.js.map +1 -1
  190. package/lib/structures/TtscGraphDumpEdgeKind.d.ts +15 -1
  191. package/lib/structures/TtscGraphDumpNodeKind.d.ts +9 -0
  192. package/lib/structures/TtscGraphEdgeKind.d.ts +13 -4
  193. package/lib/structures/TtscGraphNodeKind.d.ts +9 -0
  194. package/lib/structures/TtscGraphNodeModifier.d.ts +9 -0
  195. package/lib/structures/ViewerLink.d.ts +20 -0
  196. package/lib/structures/ViewerLink.js +3 -0
  197. package/lib/structures/ViewerLink.js.map +1 -0
  198. package/lib/structures/ViewerNode.d.ts +24 -0
  199. package/lib/structures/ViewerNode.js +3 -0
  200. package/lib/structures/ViewerNode.js.map +1 -0
  201. package/lib/structures/ViewerPayload.d.ts +42 -0
  202. package/lib/structures/ViewerPayload.js +3 -0
  203. package/lib/structures/ViewerPayload.js.map +1 -0
  204. package/lib/view.d.ts +9 -0
  205. package/lib/view.js +203 -91
  206. package/lib/view.js.map +1 -1
  207. package/lib/viewer/viewer.js +1 -1
  208. package/package.json +8 -6
  209. package/src/CapturedProcessOutput.ts +50 -0
  210. package/src/ILauncherOption.ts +24 -0
  211. package/src/IProjectOptions.ts +19 -0
  212. package/src/ParsedLauncherOptions.ts +13 -0
  213. package/src/TtscGraphApplication.ts +38 -1
  214. package/src/TtscGraphLauncherArguments.ts +207 -0
  215. package/src/TtscGraphViewSnapshot.ts +46 -0
  216. package/src/index.ts +9 -160
  217. package/src/internal/GraphProcessTrace.ts +242 -0
  218. package/src/launcherArgs.ts +89 -23
  219. package/src/model/IArtifactDirectory.ts +27 -0
  220. package/src/model/IArtifactInputs.ts +21 -0
  221. package/src/model/IPublishedArtifacts.ts +81 -0
  222. package/src/model/IPublishedArtifactsResident.ts +24 -0
  223. package/src/model/ITtscLintDaemonTarget.ts +22 -0
  224. package/src/model/TtscGraphLinePeer.ts +318 -0
  225. package/src/model/TtscGraphMemory.ts +284 -246
  226. package/src/model/TtscGraphNativeArguments.ts +67 -0
  227. package/src/model/TtscGraphNodeId.ts +57 -3
  228. package/src/model/TtscGraphProjection.ts +473 -0
  229. package/src/model/TtscGraphProtocol.ts +90 -0
  230. package/src/model/TtscGraphReadonly.ts +17 -0
  231. package/src/model/TtscGraphRequestOptions.ts +16 -0
  232. package/src/model/TtscGraphSession.ts +196 -475
  233. package/src/model/TtscGraphSessionOptions.ts +22 -0
  234. package/src/model/TtscGraphSessionState.ts +558 -0
  235. package/src/model/TtscGraphShardStore.ts +99 -23
  236. package/src/model/TtscGraphSourceReader.ts +37 -15
  237. package/src/model/TtscLintDaemon.ts +55 -136
  238. package/src/model/TtscLintDaemonState.ts +174 -0
  239. package/src/model/copyGraphRecords.ts +17 -0
  240. package/src/model/copyGraphSnapshot.ts +30 -0
  241. package/src/model/loadGraph.ts +23 -12
  242. package/src/model/publishedArtifacts.ts +361 -182
  243. package/src/nativeExecutable.ts +93 -26
  244. package/src/reduce.ts +24 -51
  245. package/src/resolveGraphBinary.ts +13 -3
  246. package/src/runGraph.ts +90 -0
  247. package/src/server/IResolvedGraphHandle.ts +24 -0
  248. package/src/server/createServer.ts +16 -22
  249. package/src/server/exportSurface.ts +23 -1
  250. package/src/server/formatGraphFailure.ts +32 -0
  251. package/src/server/pathPolicy.ts +70 -5
  252. package/src/server/resolveHandle.ts +45 -14
  253. package/src/server/resultAudit.ts +58 -27
  254. package/src/server/resultNext.ts +26 -1
  255. package/src/server/runDetails.ts +138 -73
  256. package/src/server/runEntrypoints.ts +13 -1
  257. package/src/server/runLookup.ts +23 -7
  258. package/src/server/runOverview.ts +17 -5
  259. package/src/server/runTour.ts +44 -82
  260. package/src/server/runTrace.ts +175 -102
  261. package/src/server/startServer.ts +29 -1
  262. package/src/structures/ITtscGraphApplication.ts +95 -41
  263. package/src/structures/ITtscGraphDecorator.ts +18 -0
  264. package/src/structures/ITtscGraphDetails.ts +81 -6
  265. package/src/structures/ITtscGraphDocTag.ts +17 -8
  266. package/src/structures/ITtscGraphDump.ts +106 -8
  267. package/src/structures/ITtscGraphEdge.ts +14 -2
  268. package/src/structures/ITtscGraphEntrypoints.ts +81 -6
  269. package/src/structures/ITtscGraphEscape.ts +24 -2
  270. package/src/structures/ITtscGraphEvidence.ts +9 -0
  271. package/src/structures/ITtscGraphLookup.ts +42 -9
  272. package/src/structures/ITtscGraphNext.ts +12 -1
  273. package/src/structures/ITtscGraphNode.ts +38 -11
  274. package/src/structures/ITtscGraphOverview.ts +88 -6
  275. package/src/structures/ITtscGraphSnapshot.ts +117 -2
  276. package/src/structures/ITtscGraphSpan.ts +9 -0
  277. package/src/structures/ITtscGraphTour.ts +83 -9
  278. package/src/structures/ITtscGraphTrace.ts +100 -14
  279. package/src/structures/RawDump.ts +25 -0
  280. package/src/structures/RawEdge.ts +22 -0
  281. package/src/structures/RawNode.ts +31 -0
  282. package/src/structures/TtscGraphArtifactNodeKind.ts +9 -0
  283. package/src/structures/TtscGraphDumpEdgeKind.ts +15 -1
  284. package/src/structures/TtscGraphDumpNodeKind.ts +9 -0
  285. package/src/structures/TtscGraphEdgeKind.ts +13 -4
  286. package/src/structures/TtscGraphNodeKind.ts +9 -0
  287. package/src/structures/TtscGraphNodeModifier.ts +9 -0
  288. package/src/structures/ViewerLink.ts +22 -0
  289. package/src/structures/ViewerNode.ts +28 -0
  290. package/src/structures/ViewerPayload.ts +52 -0
  291. package/src/view.ts +208 -110
  292. package/src/viewer/legend.ts +119 -27
@@ -0,0 +1,242 @@
1
+ import {
2
+ type SpawnOptions,
3
+ type SpawnSyncOptions,
4
+ spawn as nativeSpawn,
5
+ spawnSync as nativeSpawnSync,
6
+ } from "node:child_process";
7
+ import { randomUUID } from "node:crypto";
8
+ import { errorMonitor } from "node:events";
9
+ import fs from "node:fs";
10
+ import path from "node:path";
11
+
12
+ /**
13
+ * Private process observers; package entrypoints do not export this namespace.
14
+ * The aliases retain Node's overloads while their adapters pass arguments
15
+ * intact. Native executable, argv and option types stay with Node. This
16
+ * grouping adds no product flag, protocol field, cache, process holder or
17
+ * algorithm; those responsibilities remain with the adapters and their existing
18
+ * callers.
19
+ *
20
+ * @internal
21
+ */
22
+ export namespace GraphProcessTrace {
23
+ export const spawn = observeSpawn as typeof nativeSpawn;
24
+ export const spawnSync = observeSpawnSync as typeof nativeSpawnSync;
25
+ }
26
+
27
+ /**
28
+ * Correlate one actual call in the coordinator's absolute scratch directory.
29
+ * Failed writes leave bounded integrity evidence where possible; an unwritable
30
+ * sink remains missing measurement data. Neither failure changes product IO.
31
+ *
32
+ * A process-local nonce and increasing ordinal distinguish calls from child PID
33
+ * reuse. The optional closure owns correlation and the append sink only;
34
+ * callers own process behavior. Node's absolute-path and append operations use
35
+ * the coordinator's native path spelling and process.pid identifies the writer.
36
+ * No fixture oracle, foreign mutation or test-helper dependency is involved.
37
+ * Each event carries the writer's actual process.version; that runtime string
38
+ * alone does not authenticate executable bytes or the loaded native image.
39
+ *
40
+ * Each event serializes its observed fields once, so temporary text follows
41
+ * event size. Synchronous IO is measurement overhead, not a claimed speedup.
42
+ * Effectful calls and writes are never deduplicated. Scalar counters and one
43
+ * nonce persist per module instance; each append closes its handle. Events are
44
+ * capped at64MiB and writer output at256MiB, plus one overwritten bounded
45
+ * integrity marker. The coordinator retains these files until writers join.
46
+ */
47
+ function begin() {
48
+ const root = process.env.TTSC_E2E_TRACE;
49
+ if (!root || !path.isAbsolute(root)) return undefined;
50
+ try {
51
+ instance ??= randomUUID();
52
+ } catch {
53
+ return undefined;
54
+ }
55
+ const writerInstance = instance;
56
+ const invocation = `${writerInstance}:${++ordinal}`;
57
+ const file = path.join(root, `${process.pid}-${writerInstance}.jsonl`);
58
+ return (event: string, fields: Record<string, unknown>): void => {
59
+ try {
60
+ const line =
61
+ JSON.stringify({
62
+ ...fields,
63
+ schema: 1,
64
+ event,
65
+ writerPid: process.pid,
66
+ instance: writerInstance,
67
+ sequence: ++sequence,
68
+ at: new Date().toISOString(),
69
+ invocation,
70
+ data: {
71
+ ...(fields.data as Record<string, unknown> | undefined),
72
+ writerRuntime: process.version,
73
+ },
74
+ }) + "\n";
75
+ const bytes = Buffer.byteLength(line);
76
+ if (bytes > EVENT_LIMIT || written + bytes > WRITER_LIMIT)
77
+ throw new Error("trace writer byte budget exceeded");
78
+ fs.appendFileSync(file, line, { encoding: "utf8", mode: 0o600 });
79
+ written += bytes;
80
+ } catch {
81
+ try {
82
+ fs.writeFileSync(
83
+ `${file}.integrity`,
84
+ "trace serialization, append or byte budget failed",
85
+ { mode: 0o600 },
86
+ );
87
+ } catch {
88
+ /* Missing trace remains an integrity failure. */
89
+ }
90
+ }
91
+ };
92
+ }
93
+
94
+ /**
95
+ * Observe the supported spawn, exit and close events on the original child.
96
+ * errorMonitor observes errors without becoming a normal error handler. Call
97
+ * bounds are not exact OS creation times; close does not join descendants.
98
+ *
99
+ * Native spawn executes once with unchanged executable, argv and options and
100
+ * returns the original child or throws the same synchronous error. Events
101
+ * provide actual PID and lifecycle observations under one invocation; cwd
102
+ * records explicit or inherited intent without guessing native resolution.
103
+ * Streams, parsing, shutdown, references and normal errors stay caller-owned.
104
+ *
105
+ * Disabled observation delegates directly; enabled calls serialize argv and a
106
+ * fixed event population. Effectful starts are not reusable results. Once
107
+ * listeners retain correlation until their event or child collection; no timer,
108
+ * reference change, kill or independent wait is added. Existing owners release
109
+ * the child, and no foreign process export is patched.
110
+ */
111
+ function observeSpawn(...args: Parameters<typeof nativeSpawn>) {
112
+ const trace = begin();
113
+ if (!trace) return Reflect.apply(nativeSpawn, undefined, args);
114
+ const options = (Array.isArray(args[1]) ? args[2] : args[1]) as
115
+ | SpawnOptions
116
+ | undefined;
117
+ const selected = {
118
+ argv: [args[0], ...(Array.isArray(args[1]) ? args[1] : [])],
119
+ cwd: options?.cwd === undefined ? null : String(options.cwd),
120
+ data: { primitive: "spawn", cwdInherited: options?.cwd === undefined },
121
+ };
122
+ const startLowerBound = new Date().toISOString();
123
+ trace("process-attempt", { ...selected, pid: null, startLowerBound });
124
+ let child: ReturnType<typeof nativeSpawn>;
125
+ try {
126
+ child = Reflect.apply(nativeSpawn, undefined, args);
127
+ } catch (error) {
128
+ trace("process-result", {
129
+ pid: null,
130
+ started: false,
131
+ exitObserved: false,
132
+ startLowerBound,
133
+ startUpperBound: new Date().toISOString(),
134
+ data: { outcome: "synchronous-spawn-error", error },
135
+ });
136
+ throw error;
137
+ }
138
+ const startUpperBound = new Date().toISOString();
139
+ let started = false;
140
+ let exitObserved = false;
141
+ child.once("spawn", () => {
142
+ started = true;
143
+ trace("process-start", {
144
+ pid: child.pid ?? null,
145
+ started,
146
+ startLowerBound,
147
+ startUpperBound,
148
+ });
149
+ });
150
+ child.once(errorMonitor, (error: Error) =>
151
+ trace("process-error", {
152
+ pid: child.pid ?? null,
153
+ started,
154
+ exitObserved,
155
+ error: error.message,
156
+ data: { code: (error as NodeJS.ErrnoException).code },
157
+ }),
158
+ );
159
+ child.once("exit", (status, signal) => {
160
+ exitObserved = true;
161
+ trace("process-exit", {
162
+ pid: child.pid ?? null,
163
+ started,
164
+ exitObserved,
165
+ status,
166
+ signal,
167
+ });
168
+ });
169
+ child.once("close", (status, signal) =>
170
+ trace("process-close", {
171
+ pid: child.pid ?? null,
172
+ started,
173
+ exitObserved,
174
+ status,
175
+ signal,
176
+ }),
177
+ );
178
+ return child;
179
+ }
180
+
181
+ /**
182
+ * Observe the original synchronous result without replacing file descriptors,
183
+ * encoding, buffers, shell options or errors. A positive returned PID records a
184
+ * started child; call bounds do not invent its exact creation timestamp.
185
+ *
186
+ * Actual returned PID/status/signal/error distinguish a child from a failed
187
+ * pre-start attempt. Executable, argv, native options and the identical result
188
+ * or thrown error pass through unchanged. Explicit cwd and inherited intent are
189
+ * distinct observations, not resolved executable identity. Downstream capture,
190
+ * status mapping, protocol bytes and disposal remain in their existing owners.
191
+ *
192
+ * Observation adds argv serialization and two bounded event writes per actual
193
+ * effectful call; captured output is not copied or reused as expected counts.
194
+ * One correlation remains until native return, append handles close per write
195
+ * and original callers still release their captures.
196
+ */
197
+ function observeSpawnSync(...args: Parameters<typeof nativeSpawnSync>) {
198
+ const trace = begin();
199
+ if (!trace) return Reflect.apply(nativeSpawnSync, undefined, args);
200
+ const options = (Array.isArray(args[1]) ? args[2] : args[1]) as
201
+ | SpawnSyncOptions
202
+ | undefined;
203
+ const selected = {
204
+ argv: [args[0], ...(Array.isArray(args[1]) ? args[1] : [])],
205
+ cwd: options?.cwd === undefined ? null : String(options.cwd),
206
+ data: { primitive: "spawnSync", cwdInherited: options?.cwd === undefined },
207
+ };
208
+ const startLowerBound = new Date().toISOString();
209
+ trace("process-attempt", { ...selected, pid: null, startLowerBound });
210
+ let result: ReturnType<typeof nativeSpawnSync>;
211
+ try {
212
+ result = Reflect.apply(nativeSpawnSync, undefined, args);
213
+ } catch (error) {
214
+ trace("process-result", {
215
+ pid: null,
216
+ started: false,
217
+ exitObserved: false,
218
+ startLowerBound,
219
+ startUpperBound: new Date().toISOString(),
220
+ data: { outcome: "synchronous-spawn-error", error },
221
+ });
222
+ throw error;
223
+ }
224
+ trace("process-result", {
225
+ pid: result.pid || null,
226
+ started: result.pid > 0,
227
+ exitObserved: result.status !== null || result.signal !== null,
228
+ status: result.status,
229
+ signal: result.signal,
230
+ error: result.error?.message,
231
+ startLowerBound,
232
+ startUpperBound: new Date().toISOString(),
233
+ });
234
+ return result;
235
+ }
236
+
237
+ let instance: string | undefined;
238
+ let ordinal = 0;
239
+ let sequence = 0;
240
+ let written = 0;
241
+ const EVENT_LIMIT = 64 * 1024 * 1024;
242
+ const WRITER_LIMIT = 256 * 1024 * 1024;
@@ -1,5 +1,21 @@
1
1
  import path from "node:path";
2
2
 
3
+ import type { ILauncherOption } from "./ILauncherOption";
4
+ import type { IProjectOptions } from "./IProjectOptions";
5
+ import type { ParsedLauncherOptions } from "./ParsedLauncherOptions";
6
+
7
+ /**
8
+ * Invalid launcher syntax or a value outside the option's supported domain.
9
+ *
10
+ * @evidence contracts/common.md#principled-implementation An Error subtype gives callers a distinct argument-failure category while preserving the original diagnostic message.
11
+ * @evidence contracts/common.md#clear-and-simple-design Only the error name differs; native Error owns stack and message behavior.
12
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts No global Error behavior is patched to classify launcher failures.
13
+ * @evidence contracts/common.md#meaningful-documentation The native headline identifies the two supported causes without restating the class name.
14
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Argument failure representation has no filesystem or process boundary.
15
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources an Error subclass retains only its message and stack for the catcher.
16
+ * @evidenceExclude contracts/performance.md#efficient-algorithms an Error subclass that only sets its name, so it runs no algorithm.
17
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work an Error subclass holds no computation that could be shared.
18
+ */
3
19
  export class GraphArgumentError extends Error {
4
20
  public constructor(message: string) {
5
21
  super(message);
@@ -7,27 +23,26 @@ export class GraphArgumentError extends Error {
7
23
  }
8
24
  }
9
25
 
10
- type OptionKind = "value" | "flag" | "boolean";
11
-
12
- export interface ILauncherOption {
13
- key: string;
14
- flags: readonly string[];
15
- kind: OptionKind;
16
- }
17
-
18
- export type ParsedLauncherOptions = ReadonlyMap<string, string | boolean>;
19
-
20
- export interface IProjectOptions {
21
- cwd: string;
22
- tsconfig: string;
23
- }
24
-
25
26
  export const PROJECT_OPTIONS: readonly ILauncherOption[] = [
26
27
  { key: "cwd", flags: ["--cwd"], kind: "value" },
27
28
  { key: "tsconfig", flags: ["--tsconfig"], kind: "value" },
28
29
  ];
29
30
 
30
- /** Parse one complete launcher argument vector and reject every unknown token. */
31
+ /**
32
+ * Parse one complete launcher argument vector and reject every unknown token.
33
+ *
34
+ * Repeated aliases replace the prior canonical value. Missing values, values on
35
+ * bare flags and unsupported boolean spellings throw GraphArgumentError.
36
+ *
37
+ * @evidence contracts/common.md#principled-implementation An alias map and ordered argument scan implement explicit option grammar; typed validators reject unsupported values without coercion.
38
+ * @evidence contracts/common.md#clear-and-simple-design Definitions own grammar while private helpers own equals syntax, nonempty text and boolean spellings.
39
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Every token must match a configured option; unknown input is not silently accepted for a known fixture.
40
+ * @evidence contracts/common.md#meaningful-documentation Native prose explains repeated options and argument failures, with tags separated by a blank comment line.
41
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Token parsing interprets no path and invokes no native process; projectOptions handles path-bearing options later.
42
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources builds a local Map that it returns and keeps no handle.
43
+ * @evidenceExclude contracts/performance.md#efficient-algorithms one pass over argv with a Map of flag aliases, linear in the argument count.
44
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work parses one argv per launch and caches nothing.
45
+ */
31
46
  export function parseLauncherOptions(
32
47
  argv: readonly string[],
33
48
  definitions: readonly ILauncherOption[],
@@ -42,12 +57,18 @@ export function parseLauncherOptions(
42
57
  const arg = argv[i]!;
43
58
  const exact = flags.get(arg);
44
59
  if (exact !== undefined) {
45
- if (exact.kind === "value") {
60
+ if (exact.kind === "value" || exact.kind === "string") {
46
61
  const value = argv[++i];
47
- if (value === undefined || value.startsWith("-")) {
62
+ if (
63
+ value === undefined ||
64
+ (exact.kind === "value" && value.startsWith("-"))
65
+ ) {
48
66
  throw new GraphArgumentError(`${arg} requires a non-empty value`);
49
67
  }
50
- parsed.set(exact.key, requireValue(arg, value));
68
+ parsed.set(
69
+ exact.key,
70
+ exact.kind === "string" ? value : requireValue(arg, value),
71
+ );
51
72
  } else {
52
73
  parsed.set(exact.key, true);
53
74
  }
@@ -65,13 +86,30 @@ export function parseLauncherOptions(
65
86
  if (definition.kind === "boolean") {
66
87
  parsed.set(definition.key, parseBoolean(flag, value));
67
88
  } else {
68
- parsed.set(definition.key, requireValue(flag, value));
89
+ parsed.set(
90
+ definition.key,
91
+ definition.kind === "string" ? value : requireValue(flag, value),
92
+ );
69
93
  }
70
94
  }
71
95
  return parsed;
72
96
  }
73
97
 
74
- /** Resolve the two project-selection values shared by every launcher lane. */
98
+ /**
99
+ * Resolve the two project-selection values shared by every launcher lane.
100
+ *
101
+ * Defaults are the process directory and tsconfig.json; relative cwd values are
102
+ * resolved before package lookup or native process invocation.
103
+ *
104
+ * @evidence contracts/common.md#principled-implementation Native path.resolve makes cwd absolute while the config retains the producer's cwd-relative convention.
105
+ * @evidence contracts/common.md#clear-and-simple-design One adapter owns both shared defaults for all launcher lanes.
106
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Defaults are public launcher conventions rather than named-repository exceptions.
107
+ * @evidence contracts/common.md#meaningful-documentation Native prose documents defaults and resolution timing instead of only listing returned keys.
108
+ * @evidence contracts/portability.md#os-neutral-implementation Node path.resolve applies the host's native path rules without manually concatenating separators.
109
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources returns a fresh value and keeps no handle or state.
110
+ * @evidenceExclude contracts/performance.md#efficient-algorithms resolves two values in constant time.
111
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work two lookups per call, nothing worth sharing.
112
+ */
75
113
  export function projectOptions(values: ParsedLauncherOptions): IProjectOptions {
76
114
  return {
77
115
  cwd: path.resolve(stringValue(values, "cwd") ?? process.cwd()),
@@ -79,7 +117,22 @@ export function projectOptions(values: ParsedLauncherOptions): IProjectOptions {
79
117
  };
80
118
  }
81
119
 
82
- /** Read a bounded non-negative integer option without JavaScript coercion. */
120
+ /**
121
+ * Read a bounded non-negative integer option without JavaScript coercion.
122
+ *
123
+ * The value must be present, decimal digits and a safe integer no greater than
124
+ * maximum. Missing parser state is an internal error; invalid text is an
125
+ * argument error.
126
+ *
127
+ * @evidence contracts/common.md#principled-implementation Decimal syntax plus safe-integer and maximum checks exclude coercible nonintegers and precision loss before returning a number.
128
+ * @evidence contracts/common.md#clear-and-simple-design One validator owns nonnegative parsing and is reused by the positive validator.
129
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Bounds are supplied by the option contract rather than expected fixture values.
130
+ * @evidence contracts/common.md#meaningful-documentation Native prose explains numeric domain and the distinction between missing state and invalid input.
131
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Numeric option validation has no native filesystem or process operation.
132
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources returns a number and retains nothing.
133
+ * @evidenceExclude contracts/performance.md#efficient-algorithms one digit-pattern test and one Number conversion of a single option value.
134
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work validates one option value per call.
135
+ */
83
136
  export function nonNegativeIntegerOption(
84
137
  values: ParsedLauncherOptions,
85
138
  key: string,
@@ -101,7 +154,20 @@ export function nonNegativeIntegerOption(
101
154
  return number;
102
155
  }
103
156
 
104
- /** Read a bounded positive integer option without JavaScript coercion. */
157
+ /**
158
+ * Read a bounded positive integer option without JavaScript coercion.
159
+ *
160
+ * Uses the nonnegative validator and additionally rejects zero.
161
+ *
162
+ * @evidence contracts/common.md#principled-implementation Reusing safe nonnegative validation then excluding zero yields exactly the bounded positive-integer domain.
163
+ * @evidence contracts/common.md#clear-and-simple-design The adapter adds one domain restriction rather than duplicating numeric parsing.
164
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Zero rejection follows the option domain, not a special expected command case.
165
+ * @evidence contracts/common.md#meaningful-documentation Native prose states the additional restriction and identifies the shared validator.
166
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation The positivity restriction is a platform-independent numeric predicate.
167
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources returns a number and retains nothing.
168
+ * @evidenceExclude contracts/performance.md#efficient-algorithms delegates to nonNegativeIntegerOption and compares the result with zero.
169
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work validates one option value per call.
170
+ */
105
171
  export function positiveIntegerOption(
106
172
  values: ParsedLauncherOptions,
107
173
  key: string,
@@ -0,0 +1,27 @@
1
+ /**
2
+ * A directory watched on behalf of the pattern that named it.
3
+ *
4
+ * @evidence contracts/common.md#principled-implementation The absolute root and descent flag identify the conservative tree population needed to notice a declared pattern changing.
5
+ * @evidence contracts/common.md#clear-and-simple-design A directory watch contains only its native root and traversal choice; resolved files remain in the separate file list.
6
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The depth decision follows wildcard path structure rather than an arbitrary maximum documentation depth.
7
+ * @evidence contracts/common.md#meaningful-documentation Native prose explains the recursive distinction and why a bare filename wildcard does not require a repository-wide scan.
8
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources data shape only: it holds no handle, task or retained state.
9
+ * @evidenceExclude contracts/performance.md#efficient-algorithms data shape only: it contains no loop or algorithm.
10
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work data shape only: it computes nothing another request could share.
11
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation data shape only: it touches no file, path or process.
12
+ */
13
+ export interface IArtifactDirectory {
14
+ /** Absolute path of the directory to walk. */
15
+ path: string;
16
+
17
+ /**
18
+ * Whether the walk descends.
19
+ *
20
+ * Taken from wildcard path structure rather than assumed, because assuming it
21
+ * is expensive in exactly the case that looks harmless: a rule declaring
22
+ * `*.md` has the project root for its fixed prefix, and treating that as
23
+ * recursive would state every file in the repository before every graph
24
+ * request.
25
+ */
26
+ recursive: boolean;
27
+ }
@@ -0,0 +1,21 @@
1
+ import { IArtifactDirectory } from "./IArtifactDirectory";
2
+
3
+ /**
4
+ * Paths an answer was derived from, split by how they are watched.
5
+ *
6
+ * @evidence contracts/common.md#principled-implementation Explicit files and watched directories represent edits and membership changes as distinct input populations.
7
+ * @evidence contracts/common.md#clear-and-simple-design Two lists carry sidecar-declared provenance without a second glob interpreter or compiler dependency model.
8
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts An input inventory does not assert complete discovery provenance for a missing publisher.
9
+ * @evidence contracts/common.md#meaningful-documentation Native property prose identifies individual files and directories that notice additions and deletions.
10
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources data shape only: it holds no handle, task or retained state.
11
+ * @evidenceExclude contracts/performance.md#efficient-algorithms data shape only: it contains no loop or algorithm.
12
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work data shape only: it computes nothing another request could share.
13
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation data shape only: it touches no file, path or process.
14
+ */
15
+ export interface IArtifactInputs {
16
+ /** Files stated one by one. */
17
+ files: string[];
18
+
19
+ /** Directories walked, which is what notices an added or deleted file. */
20
+ directories: IArtifactDirectory[];
21
+ }
@@ -0,0 +1,81 @@
1
+ import { type ITtscCapabilityPluginResolution } from "ttsc";
2
+
3
+ import { IArtifactInputs } from "./IArtifactInputs";
4
+
5
+ /**
6
+ * Ask the project's `@ttsc/lint` for the artifacts a citation can name, and
7
+ * write them where `ttscgraph dump --artifacts` reads them.
8
+ *
9
+ * A project that configures no such plugin gets `file: null`, which is the
10
+ * common case and not an error: the graph it produces is the graph it produced
11
+ * before this existed, and the dump says so by not claiming the capability.
12
+ *
13
+ * ## Why this runs here and not in the compiler host
14
+ *
15
+ * The addresses a citation names — a Markdown anchor, `prisma:Sale.price`,
16
+ * `POST:/orders` — are produced by parsers that live in the rule that owns
17
+ * them, and re-deriving any of them in the graph producer would be a second
18
+ * implementation of a published contract. So the units have to arrive from the
19
+ * rule.
20
+ *
21
+ * They cannot arrive in-process. `ttscgraph` is the shipped per-platform
22
+ * binary, never a per-project native host, so it can never have a linked
23
+ * plugin; and `packages/lint` is its own Go module that deliberately carries no
24
+ * requirement on the compiler host. What is left is the channel the host
25
+ * already has: a plugin declares a capability and its sidecar answers a verb,
26
+ * exactly as `lsp-hints` does. `resolveCapabilityPluginResolution` builds and
27
+ * locates those sidecars, and it is the seam `ttscserver` already uses for
28
+ * `capabilities.lsp`, published so a consumer outside the compiler can ask
29
+ * too.
30
+ *
31
+ * Nothing here knows what `@ttsc/evidence` is. It asks a lint install for
32
+ * whatever its configured rules published, and a project that configured none
33
+ * gets an empty answer.
34
+ *
35
+ * @evidence contracts/common.md#principled-implementation Publication carries the sidecar's artifact file and the input identity captured before asking for artifacts, so later input changes can invalidate that answer.
36
+ * @evidence contracts/common.md#clear-and-simple-design The result separates the producer exchange path, input inventory and freshness identity without embedding compiler Program state.
37
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts A null file states an absent publication, not an invented artifact set or a successful compiler capability claim.
38
+ * @evidence contracts/common.md#meaningful-documentation Native member prose explains publication absence, independent document inputs and the fingerprint's ordering role.
39
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources data shape only: it holds no handle, task or retained state.
40
+ * @evidenceExclude contracts/performance.md#efficient-algorithms data shape only: it contains no loop or algorithm.
41
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work data shape only: it computes nothing another request could share.
42
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation data shape only: it touches no file, path or process.
43
+ */
44
+ export interface IPublishedArtifacts {
45
+ /**
46
+ * Path to the JSON the native producer reads, or `null` when no configured
47
+ * plugin publishes one.
48
+ *
49
+ * `null` is a state rather than an absence, which is why it still carries
50
+ * {@link inputs}. A project that adds an evidence plugin while a session is
51
+ * running would otherwise never be reconsidered: nothing would be watched, so
52
+ * nothing could report that the answer had changed from "none" to "some".
53
+ */
54
+ file: string | null;
55
+
56
+ /**
57
+ * Everything the answer was derived from, as paths this process can state for
58
+ * itself.
59
+ *
60
+ * The artifacts describe documents the compiler's Program never read, so a
61
+ * source edit does not move them and a document edit does not move the code
62
+ * graph. Refreshing them is therefore a second invalidation with its own
63
+ * inputs, and these are those inputs.
64
+ */
65
+ inputs: IArtifactInputs;
66
+
67
+ /**
68
+ * The state of {@link inputs} when the answer was produced.
69
+ *
70
+ * Compared against a freshly taken one to decide whether the answer is stale.
71
+ * When it moved, nothing else in the session can tell: the compiler's own
72
+ * invalidation watches the build universe, and none of this is in it.
73
+ */
74
+ fingerprint: string;
75
+
76
+ /**
77
+ * Owning plugin discovery proof, including successful absence. Omitted by
78
+ * legacy callers, whose publication cannot establish discovery freshness.
79
+ */
80
+ discovery?: ITtscCapabilityPluginResolution;
81
+ }
@@ -0,0 +1,24 @@
1
+ import type { CapabilityPluginResolver } from "ttsc";
2
+
3
+ import type { IPublishedArtifacts } from "./IPublishedArtifacts";
4
+
5
+ /**
6
+ * Publication paired with the exact resolver-owned asynchronous proof. The
7
+ * session releases this proof on replacement or resolver shutdown.
8
+ *
9
+ * @evidence contracts/common.md#principled-implementation The publication inputs remain separate from the exact discovery generation's opaque validity query.
10
+ * @evidence contracts/common.md#clear-and-simple-design Only discovery ownership differs from the synchronous publication data shape.
11
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The original SDK authority supplies currentness rather than a consumer-reconstructed watch list.
12
+ * @evidence contracts/common.md#meaningful-documentation Native prose identifies asynchronous proof identity and release ownership.
13
+ * @evidenceExclude contracts/performance.md#efficient-algorithms This data shape selects no computation strategy.
14
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work The producing and freshness operations decide whether consumers may reuse it.
15
+ * @evidence contracts/performance.md#bound-retention-and-release-resources The holder must release discovery after replacement; resolver close also drops all retained proofs.
16
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation This representation performs no filesystem or process operation.
17
+ */
18
+ export interface IPublishedArtifactsResident extends Omit<
19
+ IPublishedArtifacts,
20
+ "discovery"
21
+ > {
22
+ /** Owning asynchronous discovery authority, released by the session. */
23
+ discovery: CapabilityPluginResolver.Resolution;
24
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * One plugin sidecar this daemon can be opened against.
3
+ *
4
+ * @evidence contracts/common.md#principled-implementation Binary, plugin manifest and optional project context identify the sidecar executable and configuration inputs for its verbs.
5
+ * @evidence contracts/common.md#clear-and-simple-design The target groups only launch identity while cwd and tsconfig remain session-owned coordinates.
6
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Plugin configuration is passed through its supported manifest/context flags rather than patched into a running foreign process.
7
+ * @evidence contracts/common.md#meaningful-documentation Native member comments explain binary identity and the two configuration channels.
8
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources data shape only: it holds no handle, task or retained state.
9
+ * @evidenceExclude contracts/performance.md#efficient-algorithms data shape only: it contains no loop or algorithm.
10
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work data shape only: it computes nothing another request could share.
11
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation data shape only: it touches no file, path or process.
12
+ */
13
+ export interface ITtscLintDaemonTarget {
14
+ /** Native plugin sidecar executable path. */
15
+ binary: string;
16
+
17
+ /** Serialized plugin manifest consumed by the sidecar. */
18
+ manifest: string;
19
+
20
+ /** Optional serialized project identity passed to context-aware rules. */
21
+ projectContext?: string;
22
+ }