@skillsmith/core 0.11.3 → 0.11.5

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 (304) hide show
  1. package/CHANGELOG.md +34 -9
  2. package/README.md +10 -7
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/src/api/client.d.ts.map +1 -1
  5. package/dist/src/api/client.js +15 -5
  6. package/dist/src/api/client.js.map +1 -1
  7. package/dist/src/api/client.private-registry.d.ts +80 -0
  8. package/dist/src/api/client.private-registry.d.ts.map +1 -0
  9. package/dist/src/api/client.private-registry.js +97 -0
  10. package/dist/src/api/client.private-registry.js.map +1 -0
  11. package/dist/src/api/client.private-registry.test.d.ts +9 -0
  12. package/dist/src/api/client.private-registry.test.d.ts.map +1 -0
  13. package/dist/src/api/client.private-registry.test.js +127 -0
  14. package/dist/src/api/client.private-registry.test.js.map +1 -0
  15. package/dist/src/api/client.toSkill.test.d.ts +25 -0
  16. package/dist/src/api/client.toSkill.test.d.ts.map +1 -0
  17. package/dist/src/api/client.toSkill.test.js +97 -0
  18. package/dist/src/api/client.toSkill.test.js.map +1 -0
  19. package/dist/src/api/client.token-refresh.d.ts +8 -0
  20. package/dist/src/api/client.token-refresh.d.ts.map +1 -1
  21. package/dist/src/api/client.token-refresh.js +26 -0
  22. package/dist/src/api/client.token-refresh.js.map +1 -1
  23. package/dist/src/api/client.token-refresh.test.js +82 -0
  24. package/dist/src/api/client.token-refresh.test.js.map +1 -1
  25. package/dist/src/api/index.d.ts +2 -0
  26. package/dist/src/api/index.d.ts.map +1 -1
  27. package/dist/src/api/index.js +9 -0
  28. package/dist/src/api/index.js.map +1 -1
  29. package/dist/src/api/security-summary.d.ts +73 -0
  30. package/dist/src/api/security-summary.d.ts.map +1 -0
  31. package/dist/src/api/security-summary.js +88 -0
  32. package/dist/src/api/security-summary.js.map +1 -0
  33. package/dist/src/api/security-summary.test.d.ts +9 -0
  34. package/dist/src/api/security-summary.test.d.ts.map +1 -0
  35. package/dist/src/api/security-summary.test.js +94 -0
  36. package/dist/src/api/security-summary.test.js.map +1 -0
  37. package/dist/src/config/config-atomic-write.d.ts +30 -10
  38. package/dist/src/config/config-atomic-write.d.ts.map +1 -1
  39. package/dist/src/config/config-atomic-write.js +33 -80
  40. package/dist/src/config/config-atomic-write.js.map +1 -1
  41. package/dist/src/config/config-atomic-write.test.d.ts +8 -0
  42. package/dist/src/config/config-atomic-write.test.d.ts.map +1 -1
  43. package/dist/src/config/config-atomic-write.test.js +64 -12
  44. package/dist/src/config/config-atomic-write.test.js.map +1 -1
  45. package/dist/src/config/owned-lock.acquire.d.ts +53 -0
  46. package/dist/src/config/owned-lock.acquire.d.ts.map +1 -0
  47. package/dist/src/config/owned-lock.acquire.js +140 -0
  48. package/dist/src/config/owned-lock.acquire.js.map +1 -0
  49. package/dist/src/config/owned-lock.claim.d.ts +84 -0
  50. package/dist/src/config/owned-lock.claim.d.ts.map +1 -0
  51. package/dist/src/config/owned-lock.claim.js +310 -0
  52. package/dist/src/config/owned-lock.claim.js.map +1 -0
  53. package/dist/src/config/owned-lock.d.ts +113 -0
  54. package/dist/src/config/owned-lock.d.ts.map +1 -0
  55. package/dist/src/config/owned-lock.js +121 -0
  56. package/dist/src/config/owned-lock.js.map +1 -0
  57. package/dist/src/config/owned-lock.test.d.ts +12 -0
  58. package/dist/src/config/owned-lock.test.d.ts.map +1 -0
  59. package/dist/src/config/owned-lock.test.js +412 -0
  60. package/dist/src/config/owned-lock.test.js.map +1 -0
  61. package/dist/src/config/owned-lock.types.d.ts +78 -0
  62. package/dist/src/config/owned-lock.types.d.ts.map +1 -0
  63. package/dist/src/config/owned-lock.types.js +30 -0
  64. package/dist/src/config/owned-lock.types.js.map +1 -0
  65. package/dist/src/db/createDatabase.d.ts.map +1 -1
  66. package/dist/src/db/createDatabase.js +19 -7
  67. package/dist/src/db/createDatabase.js.map +1 -1
  68. package/dist/src/embeddings/hnsw-store.exports.d.ts +11 -0
  69. package/dist/src/embeddings/hnsw-store.exports.d.ts.map +1 -0
  70. package/dist/src/embeddings/hnsw-store.exports.js +10 -0
  71. package/dist/src/embeddings/hnsw-store.exports.js.map +1 -0
  72. package/dist/src/embeddings/index.d.ts +1 -2
  73. package/dist/src/embeddings/index.d.ts.map +1 -1
  74. package/dist/src/embeddings/index.js +17 -3
  75. package/dist/src/embeddings/index.js.map +1 -1
  76. package/dist/src/embeddings/probe.d.ts.map +1 -1
  77. package/dist/src/embeddings/probe.js +4 -8
  78. package/dist/src/embeddings/probe.js.map +1 -1
  79. package/dist/src/exports/services.d.ts +4 -1
  80. package/dist/src/exports/services.d.ts.map +1 -1
  81. package/dist/src/exports/services.js +22 -0
  82. package/dist/src/exports/services.js.map +1 -1
  83. package/dist/src/index.d.ts +5 -3
  84. package/dist/src/index.d.ts.map +1 -1
  85. package/dist/src/index.js +17 -3
  86. package/dist/src/index.js.map +1 -1
  87. package/dist/src/install/index.d.ts +1 -1
  88. package/dist/src/install/index.d.ts.map +1 -1
  89. package/dist/src/install/index.js +1 -1
  90. package/dist/src/install/index.js.map +1 -1
  91. package/dist/src/install/paths.d.ts +10 -0
  92. package/dist/src/install/paths.d.ts.map +1 -1
  93. package/dist/src/install/paths.js +19 -0
  94. package/dist/src/install/paths.js.map +1 -1
  95. package/dist/src/logging/logger.test.js +57 -0
  96. package/dist/src/logging/logger.test.js.map +1 -1
  97. package/dist/src/logging/rotation.d.ts +27 -2
  98. package/dist/src/logging/rotation.d.ts.map +1 -1
  99. package/dist/src/logging/rotation.js +44 -3
  100. package/dist/src/logging/rotation.js.map +1 -1
  101. package/dist/src/logging/rotation.test.js +69 -0
  102. package/dist/src/logging/rotation.test.js.map +1 -1
  103. package/dist/src/logging/types.d.ts +8 -2
  104. package/dist/src/logging/types.d.ts.map +1 -1
  105. package/dist/src/security/index.d.ts +2 -1
  106. package/dist/src/security/index.d.ts.map +1 -1
  107. package/dist/src/security/index.js +3 -0
  108. package/dist/src/security/index.js.map +1 -1
  109. package/dist/src/security/scanner/SecurityScanner.d.ts +2 -2
  110. package/dist/src/security/scanner/SecurityScanner.d.ts.map +1 -1
  111. package/dist/src/security/scanner/SecurityScanner.evidence.d.ts +76 -0
  112. package/dist/src/security/scanner/SecurityScanner.evidence.d.ts.map +1 -0
  113. package/dist/src/security/scanner/SecurityScanner.evidence.js +176 -0
  114. package/dist/src/security/scanner/SecurityScanner.evidence.js.map +1 -0
  115. package/dist/src/security/scanner/SecurityScanner.exec.d.ts +8 -1
  116. package/dist/src/security/scanner/SecurityScanner.exec.d.ts.map +1 -1
  117. package/dist/src/security/scanner/SecurityScanner.exec.js +58 -2
  118. package/dist/src/security/scanner/SecurityScanner.exec.js.map +1 -1
  119. package/dist/src/security/scanner/SecurityScanner.helpers.d.ts +35 -10
  120. package/dist/src/security/scanner/SecurityScanner.helpers.d.ts.map +1 -1
  121. package/dist/src/security/scanner/SecurityScanner.helpers.js +106 -59
  122. package/dist/src/security/scanner/SecurityScanner.helpers.js.map +1 -1
  123. package/dist/src/security/scanner/SecurityScanner.js +41 -13
  124. package/dist/src/security/scanner/SecurityScanner.js.map +1 -1
  125. package/dist/src/security/scanner/SecurityScanner.pii.d.ts.map +1 -1
  126. package/dist/src/security/scanner/SecurityScanner.pii.js +23 -1
  127. package/dist/src/security/scanner/SecurityScanner.pii.js.map +1 -1
  128. package/dist/src/security/scanner/SecurityScanner.scanners.d.ts.map +1 -1
  129. package/dist/src/security/scanner/SecurityScanner.scanners.js +15 -3
  130. package/dist/src/security/scanner/SecurityScanner.scanners.js.map +1 -1
  131. package/dist/src/security/scanner/SecurityScanner.ssrf.d.ts +11 -1
  132. package/dist/src/security/scanner/SecurityScanner.ssrf.d.ts.map +1 -1
  133. package/dist/src/security/scanner/SecurityScanner.ssrf.js +18 -7
  134. package/dist/src/security/scanner/SecurityScanner.ssrf.js.map +1 -1
  135. package/dist/src/security/scanner/index.d.ts +3 -3
  136. package/dist/src/security/scanner/index.d.ts.map +1 -1
  137. package/dist/src/security/scanner/index.js +5 -2
  138. package/dist/src/security/scanner/index.js.map +1 -1
  139. package/dist/src/security/scanner/multiline-category-closure.test.d.ts +80 -0
  140. package/dist/src/security/scanner/multiline-category-closure.test.d.ts.map +1 -0
  141. package/dist/src/security/scanner/multiline-category-closure.test.js +287 -0
  142. package/dist/src/security/scanner/multiline-category-closure.test.js.map +1 -0
  143. package/dist/src/security/scanner/patterns.d.ts +41 -14
  144. package/dist/src/security/scanner/patterns.d.ts.map +1 -1
  145. package/dist/src/security/scanner/patterns.jailbreak.d.ts +41 -0
  146. package/dist/src/security/scanner/patterns.jailbreak.d.ts.map +1 -0
  147. package/dist/src/security/scanner/patterns.jailbreak.evidence.d.ts +35 -0
  148. package/dist/src/security/scanner/patterns.jailbreak.evidence.d.ts.map +1 -0
  149. package/dist/src/security/scanner/patterns.jailbreak.evidence.js +119 -0
  150. package/dist/src/security/scanner/patterns.jailbreak.evidence.js.map +1 -0
  151. package/dist/src/security/scanner/patterns.jailbreak.js +370 -0
  152. package/dist/src/security/scanner/patterns.jailbreak.js.map +1 -0
  153. package/dist/src/security/scanner/patterns.js +101 -82
  154. package/dist/src/security/scanner/patterns.js.map +1 -1
  155. package/dist/src/security/scanner/patterns.scope.d.ts +62 -0
  156. package/dist/src/security/scanner/patterns.scope.d.ts.map +1 -0
  157. package/dist/src/security/scanner/patterns.scope.js +207 -0
  158. package/dist/src/security/scanner/patterns.scope.js.map +1 -0
  159. package/dist/src/security/scanner/regex-utils.d.ts +20 -0
  160. package/dist/src/security/scanner/regex-utils.d.ts.map +1 -1
  161. package/dist/src/security/scanner/regex-utils.js +20 -0
  162. package/dist/src/security/scanner/regex-utils.js.map +1 -1
  163. package/dist/src/security/scanner/types.d.ts +35 -0
  164. package/dist/src/security/scanner/types.d.ts.map +1 -1
  165. package/dist/src/services/recommend-guard.d.ts +28 -0
  166. package/dist/src/services/recommend-guard.d.ts.map +1 -0
  167. package/dist/src/services/recommend-guard.js +34 -0
  168. package/dist/src/services/recommend-guard.js.map +1 -0
  169. package/dist/src/services/recommend-guard.test.d.ts +2 -0
  170. package/dist/src/services/recommend-guard.test.d.ts.map +1 -0
  171. package/dist/src/services/recommend-guard.test.js +28 -0
  172. package/dist/src/services/recommend-guard.test.js.map +1 -0
  173. package/dist/src/services/skill-installation.content.d.ts +88 -0
  174. package/dist/src/services/skill-installation.content.d.ts.map +1 -0
  175. package/dist/src/services/skill-installation.content.js +319 -0
  176. package/dist/src/services/skill-installation.content.js.map +1 -0
  177. package/dist/src/services/skill-installation.helpers.d.ts +32 -1
  178. package/dist/src/services/skill-installation.helpers.d.ts.map +1 -1
  179. package/dist/src/services/skill-installation.helpers.js +39 -6
  180. package/dist/src/services/skill-installation.helpers.js.map +1 -1
  181. package/dist/src/services/skill-installation.helpers.test.js +34 -2
  182. package/dist/src/services/skill-installation.helpers.test.js.map +1 -1
  183. package/dist/src/services/skill-installation.io.d.ts.map +1 -1
  184. package/dist/src/services/skill-installation.io.js +86 -2
  185. package/dist/src/services/skill-installation.io.js.map +1 -1
  186. package/dist/src/services/skill-installation.service.d.ts +20 -1
  187. package/dist/src/services/skill-installation.service.d.ts.map +1 -1
  188. package/dist/src/services/skill-installation.service.js +26 -4
  189. package/dist/src/services/skill-installation.service.js.map +1 -1
  190. package/dist/src/services/skill-installation.types.d.ts +42 -1
  191. package/dist/src/services/skill-installation.types.d.ts.map +1 -1
  192. package/dist/src/services/skill-installation.types.js.map +1 -1
  193. package/dist/src/services/skill-resolution.d.ts +67 -0
  194. package/dist/src/services/skill-resolution.d.ts.map +1 -0
  195. package/dist/src/services/skill-resolution.js +67 -0
  196. package/dist/src/services/skill-resolution.js.map +1 -0
  197. package/dist/src/services/skill-resolution.test.d.ts +2 -0
  198. package/dist/src/services/skill-resolution.test.d.ts.map +1 -0
  199. package/dist/src/services/skill-resolution.test.js +143 -0
  200. package/dist/src/services/skill-resolution.test.js.map +1 -0
  201. package/dist/src/sync/inventory-collector.d.ts.map +1 -1
  202. package/dist/src/sync/inventory-collector.js +2 -2
  203. package/dist/src/sync/inventory-collector.js.map +1 -1
  204. package/dist/src/utils/index.d.ts +1 -0
  205. package/dist/src/utils/index.d.ts.map +1 -1
  206. package/dist/src/utils/index.js +4 -0
  207. package/dist/src/utils/index.js.map +1 -1
  208. package/dist/src/utils/quiet-mode.d.ts +21 -0
  209. package/dist/src/utils/quiet-mode.d.ts.map +1 -0
  210. package/dist/src/utils/quiet-mode.js +26 -0
  211. package/dist/src/utils/quiet-mode.js.map +1 -0
  212. package/dist/tests/EmbeddingService.test.js +58 -1
  213. package/dist/tests/EmbeddingService.test.js.map +1 -1
  214. package/dist/tests/SecurityScanner.ai-defence.test.js +32 -7
  215. package/dist/tests/SecurityScanner.ai-defence.test.js.map +1 -1
  216. package/dist/tests/SecurityScanner.exec.test.js +79 -0
  217. package/dist/tests/SecurityScanner.exec.test.js.map +1 -1
  218. package/dist/tests/SecurityScanner.performance.test.js +5 -2
  219. package/dist/tests/SecurityScanner.performance.test.js.map +1 -1
  220. package/dist/tests/db/database-abstraction.test.js +45 -1
  221. package/dist/tests/db/database-abstraction.test.js.map +1 -1
  222. package/dist/tests/helpers/deterministic-dead-pid.d.ts +13 -0
  223. package/dist/tests/helpers/deterministic-dead-pid.d.ts.map +1 -0
  224. package/dist/tests/helpers/deterministic-dead-pid.js +31 -0
  225. package/dist/tests/helpers/deterministic-dead-pid.js.map +1 -0
  226. package/dist/tests/integration/owned-lock-lost-update.test.d.ts +12 -0
  227. package/dist/tests/integration/owned-lock-lost-update.test.d.ts.map +1 -0
  228. package/dist/tests/integration/owned-lock-lost-update.test.js +52 -0
  229. package/dist/tests/integration/owned-lock-lost-update.test.js.map +1 -0
  230. package/dist/tests/integration/owned-lock-reclaim-race.test.d.ts +19 -0
  231. package/dist/tests/integration/owned-lock-reclaim-race.test.d.ts.map +1 -0
  232. package/dist/tests/integration/owned-lock-reclaim-race.test.js +177 -0
  233. package/dist/tests/integration/owned-lock-reclaim-race.test.js.map +1 -0
  234. package/dist/tests/security/ContinuousSecurity.performance.test.js +6 -0
  235. package/dist/tests/security/ContinuousSecurity.performance.test.js.map +1 -1
  236. package/dist/tests/security/ContinuousSecurity.test.js +15 -0
  237. package/dist/tests/security/ContinuousSecurity.test.js.map +1 -1
  238. package/dist/tests/security/ad-crlf-injection.test.d.ts +18 -0
  239. package/dist/tests/security/ad-crlf-injection.test.d.ts.map +1 -0
  240. package/dist/tests/security/ad-crlf-injection.test.js +150 -0
  241. package/dist/tests/security/ad-crlf-injection.test.js.map +1 -0
  242. package/dist/tests/security/ai-defence-multiline-promotion.test.d.ts +25 -0
  243. package/dist/tests/security/ai-defence-multiline-promotion.test.d.ts.map +1 -0
  244. package/dist/tests/security/ai-defence-multiline-promotion.test.js +138 -0
  245. package/dist/tests/security/ai-defence-multiline-promotion.test.js.map +1 -0
  246. package/dist/tests/security/nested-instruction-long-attribute.test.d.ts +15 -0
  247. package/dist/tests/security/nested-instruction-long-attribute.test.d.ts.map +1 -0
  248. package/dist/tests/security/nested-instruction-long-attribute.test.js +60 -0
  249. package/dist/tests/security/nested-instruction-long-attribute.test.js.map +1 -0
  250. package/dist/tests/security/pattern-scope.test.d.ts +17 -0
  251. package/dist/tests/security/pattern-scope.test.d.ts.map +1 -0
  252. package/dist/tests/security/pattern-scope.test.js +128 -0
  253. package/dist/tests/security/pattern-scope.test.js.map +1 -0
  254. package/dist/tests/security/pii-detection.test.js +39 -0
  255. package/dist/tests/security/pii-detection.test.js.map +1 -1
  256. package/dist/tests/security/scanner-evidence-tiers.test.d.ts +30 -0
  257. package/dist/tests/security/scanner-evidence-tiers.test.d.ts.map +1 -0
  258. package/dist/tests/security/scanner-evidence-tiers.test.js +258 -0
  259. package/dist/tests/security/scanner-evidence-tiers.test.js.map +1 -0
  260. package/dist/tests/security/scanner-privesc-severity.test.d.ts +23 -0
  261. package/dist/tests/security/scanner-privesc-severity.test.d.ts.map +1 -0
  262. package/dist/tests/security/scanner-privesc-severity.test.js +43 -0
  263. package/dist/tests/security/scanner-privesc-severity.test.js.map +1 -0
  264. package/dist/tests/security/scanner-regression-guard.exec-locality.test.d.ts +20 -0
  265. package/dist/tests/security/scanner-regression-guard.exec-locality.test.d.ts.map +1 -0
  266. package/dist/tests/security/scanner-regression-guard.exec-locality.test.js +71 -0
  267. package/dist/tests/security/scanner-regression-guard.exec-locality.test.js.map +1 -0
  268. package/dist/tests/security/scanner-regression-guard.test.d.ts +24 -0
  269. package/dist/tests/security/scanner-regression-guard.test.d.ts.map +1 -1
  270. package/dist/tests/security/scanner-regression-guard.test.js +59 -3
  271. package/dist/tests/security/scanner-regression-guard.test.js.map +1 -1
  272. package/dist/tests/security/scanner-ssrf-word-boundary.test.d.ts +19 -0
  273. package/dist/tests/security/scanner-ssrf-word-boundary.test.d.ts.map +1 -0
  274. package/dist/tests/security/scanner-ssrf-word-boundary.test.js +65 -0
  275. package/dist/tests/security/scanner-ssrf-word-boundary.test.js.map +1 -0
  276. package/dist/tests/security.test.js +11 -2
  277. package/dist/tests/security.test.js.map +1 -1
  278. package/dist/tests/skill-scanner/allowlist.test.js +15 -7
  279. package/dist/tests/skill-scanner/allowlist.test.js.map +1 -1
  280. package/dist/tests/unit/services/skill-installation.content.test.d.ts +10 -0
  281. package/dist/tests/unit/services/skill-installation.content.test.d.ts.map +1 -0
  282. package/dist/tests/unit/services/skill-installation.content.test.js +290 -0
  283. package/dist/tests/unit/services/skill-installation.content.test.js.map +1 -0
  284. package/dist/tests/unit/services/skill-installation.io.symlink.test.d.ts +8 -0
  285. package/dist/tests/unit/services/skill-installation.io.symlink.test.d.ts.map +1 -0
  286. package/dist/tests/unit/services/skill-installation.io.symlink.test.js +72 -0
  287. package/dist/tests/unit/services/skill-installation.io.symlink.test.js.map +1 -0
  288. package/dist/tests/unit/services/skill-installation.io.test.js +54 -1
  289. package/dist/tests/unit/services/skill-installation.io.test.js.map +1 -1
  290. package/dist/tests/unit/services/skill-installation.service.error-codes.test.d.ts +15 -0
  291. package/dist/tests/unit/services/skill-installation.service.error-codes.test.d.ts.map +1 -0
  292. package/dist/tests/unit/services/skill-installation.service.error-codes.test.js +190 -0
  293. package/dist/tests/unit/services/skill-installation.service.error-codes.test.js.map +1 -0
  294. package/dist/tests/unit/services/skill-installation.service.multi-client.test.d.ts +17 -0
  295. package/dist/tests/unit/services/skill-installation.service.multi-client.test.d.ts.map +1 -0
  296. package/dist/tests/unit/services/skill-installation.service.multi-client.test.js +126 -0
  297. package/dist/tests/unit/services/skill-installation.service.multi-client.test.js.map +1 -0
  298. package/dist/tests/unit/services/skill-installation.service.test.js +7 -112
  299. package/dist/tests/unit/services/skill-installation.service.test.js.map +1 -1
  300. package/dist/tests/utils/quiet-mode.test.d.ts +12 -0
  301. package/dist/tests/utils/quiet-mode.test.d.ts.map +1 -0
  302. package/dist/tests/utils/quiet-mode.test.js +42 -0
  303. package/dist/tests/utils/quiet-mode.test.js.map +1 -0
  304. package/package.json +17 -5
@@ -0,0 +1,412 @@
1
+ /**
2
+ * Unit tests for the two-level owned-lock primitive (SMI-5883 §8a).
3
+ * @module @skillsmith/core/config/owned-lock.test
4
+ *
5
+ * Single-process tests of `acquireOwnedLock` itself. Cross-process tests
6
+ * (the reclaim-race proof, the orphaned-reclaim-lock residual, and the
7
+ * end-to-end lost-update stress test) live in
8
+ * `packages/core/tests/integration/owned-lock-reclaim-race.test.ts` (§8b/8c)
9
+ * and `packages/core/tests/integration/owned-lock-lost-update.test.ts` (§8f).
10
+ */
11
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
12
+ import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs';
13
+ import { hostname } from 'node:os';
14
+ import * as path from 'node:path';
15
+ import * as os from 'node:os';
16
+ import { acquireOwnedLock, StuckLockError } from './owned-lock.js';
17
+ import { createLockExclusive } from './owned-lock.claim.js';
18
+ import { mintDeadPid } from '../../tests/helpers/deterministic-dead-pid.js';
19
+ let dir;
20
+ let target;
21
+ let lockPath;
22
+ let reclaimPath;
23
+ beforeEach(() => {
24
+ dir =
25
+ os.tmpdir() + path.sep + `owned-lock-test-${Date.now()}-${Math.random().toString(36).slice(2)}`;
26
+ mkdirSync(dir, { recursive: true });
27
+ target = path.join(dir, 'store.json');
28
+ lockPath = `${target}.lock`;
29
+ reclaimPath = `${lockPath}.reclaim`;
30
+ });
31
+ afterEach(() => {
32
+ rmSync(dir, { recursive: true, force: true });
33
+ });
34
+ function seed(content, at = lockPath) {
35
+ writeFileSync(at, content);
36
+ }
37
+ function v1(pid, opts = {}) {
38
+ return (JSON.stringify({
39
+ v: 1,
40
+ pid,
41
+ token: opts.token ?? 'a'.repeat(16),
42
+ host: opts.host ?? hostname(),
43
+ acquiredAt: opts.acquiredAt ?? Date.now(),
44
+ }) + '\n');
45
+ }
46
+ describe('acquireOwnedLock', () => {
47
+ it('1. acquire on a free path succeeds; the lock file is 0600, v1, this pid/host, 16-hex token', () => {
48
+ const release = acquireOwnedLock(target, { timeoutMs: 1_000 });
49
+ const raw = readFileSync(lockPath, 'utf-8');
50
+ const parsed = JSON.parse(raw);
51
+ expect(parsed.v).toBe(1);
52
+ expect(parsed.pid).toBe(process.pid);
53
+ expect(parsed.host).toBe(hostname());
54
+ expect(/^[0-9a-f]{16}$/.test(parsed.token)).toBe(true);
55
+ release();
56
+ });
57
+ it('2. a second acquire while held times out with reason held; the lock file is byte-identical afterwards', () => {
58
+ const release = acquireOwnedLock(target, { timeoutMs: 5_000 });
59
+ const before = readFileSync(lockPath);
60
+ try {
61
+ let caught;
62
+ try {
63
+ acquireOwnedLock(target, { timeoutMs: 200 });
64
+ }
65
+ catch (err) {
66
+ caught = err;
67
+ }
68
+ expect(caught).toBeInstanceOf(StuckLockError);
69
+ expect(caught?.reason).toBe('held');
70
+ expect(readFileSync(lockPath).equals(before)).toBe(true);
71
+ }
72
+ finally {
73
+ release();
74
+ }
75
+ });
76
+ it('3. release removes the lock; a subsequent acquire succeeds immediately', () => {
77
+ const release = acquireOwnedLock(target, { timeoutMs: 1_000 });
78
+ release();
79
+ expect(existsSync(lockPath)).toBe(false);
80
+ const release2 = acquireOwnedLock(target, { timeoutMs: 200 });
81
+ release2();
82
+ });
83
+ it('4. release is idempotent — a second call neither throws nor unlinks', () => {
84
+ const release = acquireOwnedLock(target, { timeoutMs: 1_000 });
85
+ release();
86
+ expect(() => release()).not.toThrow();
87
+ });
88
+ it('5. ownership-verified release: a foreign token in the lock file is never unlinked', () => {
89
+ const release = acquireOwnedLock(target, { timeoutMs: 1_000 });
90
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
91
+ // Overwrite the lock file out-of-band with a DIFFERENT v1 token.
92
+ seed(v1(process.pid, { token: 'f'.repeat(16) }));
93
+ release();
94
+ expect(existsSync(lockPath)).toBe(true);
95
+ expect(JSON.parse(readFileSync(lockPath, 'utf-8')).token).toBe('f'.repeat(16));
96
+ expect(warnSpy.mock.calls.some((c) => String(c[0]).includes('lock_release_not_owner'))).toBe(true);
97
+ warnSpy.mockRestore();
98
+ rmSync(lockPath);
99
+ });
100
+ it('6. v1 dead-PID reclaim: acquire succeeds well inside a tight budget; the reclaim lock is gone afterwards', () => {
101
+ const deadPid = mintDeadPid();
102
+ seed(v1(deadPid));
103
+ const start = Date.now();
104
+ const release = acquireOwnedLock(target, { timeoutMs: 5_000, reclaimProbeAfterMs: 0 });
105
+ expect(Date.now() - start).toBeLessThan(2_000);
106
+ expect(existsSync(reclaimPath)).toBe(false);
107
+ release();
108
+ });
109
+ it('7. v1 live-PID refusal: times out, reason held, file byte-identical', () => {
110
+ seed(v1(process.pid));
111
+ const before = readFileSync(lockPath);
112
+ let caught;
113
+ try {
114
+ acquireOwnedLock(target, { timeoutMs: 200, reclaimProbeAfterMs: 0 });
115
+ }
116
+ catch (err) {
117
+ caught = err;
118
+ }
119
+ expect(caught?.reason).toBe('held');
120
+ expect(readFileSync(lockPath).equals(before)).toBe(true);
121
+ });
122
+ it('H-11: a live-PID lock with a 10-minute-old acquiredAt still times out (age is irrelevant, D-2 regression test)', () => {
123
+ seed(v1(process.pid, { acquiredAt: Date.now() - 10 * 60 * 1000 }));
124
+ const before = readFileSync(lockPath);
125
+ let caught;
126
+ try {
127
+ acquireOwnedLock(target, { timeoutMs: 200, reclaimProbeAfterMs: 0 });
128
+ }
129
+ catch (err) {
130
+ caught = err;
131
+ }
132
+ expect(caught).toBeInstanceOf(StuckLockError);
133
+ expect(caught?.message).toContain(String(process.pid));
134
+ expect(caught?.message).toContain(hostname());
135
+ expect(readFileSync(lockPath).equals(before)).toBe(true);
136
+ });
137
+ it('8. EPERM from the liveness probe counts as alive — no reclaim, timeout', () => {
138
+ const deadPid = mintDeadPid(); // would otherwise be reclaimed
139
+ seed(v1(deadPid));
140
+ const killProbe = () => {
141
+ const err = new Error('EPERM');
142
+ err.code = 'EPERM';
143
+ throw err;
144
+ };
145
+ let caught;
146
+ try {
147
+ // The kill-probe override is threaded via the internal claim module in
148
+ // production; here we assert behaviourally via the public surface by
149
+ // making `process.kill` itself throw EPERM for this one PID.
150
+ const spy = vi.spyOn(process, 'kill').mockImplementation((pid) => {
151
+ if (pid === deadPid)
152
+ return killProbe();
153
+ return true;
154
+ });
155
+ try {
156
+ acquireOwnedLock(target, { timeoutMs: 200, reclaimProbeAfterMs: 0 });
157
+ }
158
+ catch (err) {
159
+ caught = err;
160
+ }
161
+ finally {
162
+ spy.mockRestore();
163
+ }
164
+ }
165
+ finally {
166
+ /* no-op */
167
+ }
168
+ expect(caught?.reason).toBe('held');
169
+ });
170
+ it('9. pid <= 0 rejected without probing (kill(0,0) would signal the process group)', () => {
171
+ for (const pid of [0, -1]) {
172
+ rmSync(lockPath, { force: true });
173
+ seed(v1(pid));
174
+ const spy = vi.spyOn(process, 'kill').mockImplementation(() => true);
175
+ let caught;
176
+ try {
177
+ acquireOwnedLock(target, { timeoutMs: 150, reclaimProbeAfterMs: 0 });
178
+ }
179
+ catch (err) {
180
+ caught = err;
181
+ }
182
+ expect(caught?.reason).toBe('held');
183
+ expect(spy).not.toHaveBeenCalled();
184
+ spy.mockRestore();
185
+ }
186
+ });
187
+ it('10. host mismatch: a dead PID on another host is never reclaimed', () => {
188
+ const deadPid = mintDeadPid();
189
+ seed(v1(deadPid, { host: 'some-other-host' }));
190
+ const before = readFileSync(lockPath);
191
+ let caught;
192
+ try {
193
+ acquireOwnedLock(target, { timeoutMs: 200, reclaimProbeAfterMs: 0 });
194
+ }
195
+ catch (err) {
196
+ caught = err;
197
+ }
198
+ expect(caught?.reason).toBe('held');
199
+ expect(readFileSync(lockPath).equals(before)).toBe(true);
200
+ });
201
+ it('11. unparseable claims (empty / truncated / garbage / wrong version) refuse with a byte-identical file (H-13 a-d)', () => {
202
+ const deadPid = mintDeadPid();
203
+ const cases = [
204
+ '', // (c) empty
205
+ '{"v":1,"pid":', // (c) truncated
206
+ 'not json at all {{{', // (b) garbage bytes
207
+ JSON.stringify({
208
+ v: 2,
209
+ pid: deadPid,
210
+ token: 'a'.repeat(16),
211
+ host: hostname(),
212
+ acquiredAt: Date.now(),
213
+ }), // (d) valid JSON, wrong version -- never auto-reclaimed even with a genuinely dead PID
214
+ ];
215
+ for (const content of cases) {
216
+ rmSync(lockPath, { force: true });
217
+ seed(content);
218
+ const before = readFileSync(lockPath);
219
+ let caught;
220
+ try {
221
+ acquireOwnedLock(target, { timeoutMs: 150, reclaimProbeAfterMs: 0 });
222
+ }
223
+ catch (err) {
224
+ caught = err;
225
+ }
226
+ expect(caught?.reason, `content: ${JSON.stringify(content)}`).toBe('unreclaimable_unparseable');
227
+ expect(readFileSync(lockPath).equals(before)).toBe(true);
228
+ }
229
+ });
230
+ it('12. legacy refusal, dead PID (D-5): a bare minted-dead PID is never reclaimed', () => {
231
+ const deadPid = mintDeadPid();
232
+ seed(String(deadPid));
233
+ const before = readFileSync(lockPath);
234
+ let caught;
235
+ try {
236
+ acquireOwnedLock(target, { timeoutMs: 150, reclaimProbeAfterMs: 0 });
237
+ }
238
+ catch (err) {
239
+ caught = err;
240
+ }
241
+ expect(caught?.reason).toBe('unreclaimable_legacy');
242
+ expect(readFileSync(lockPath).equals(before)).toBe(true);
243
+ });
244
+ it('13. SKILLSMITH_LOCK_NO_AUTO_RECLAIM=1: a v1 dead-PID lock is not reclaimed; reason reclaim_disabled', () => {
245
+ const deadPid = mintDeadPid();
246
+ seed(v1(deadPid));
247
+ process.env['SKILLSMITH_LOCK_NO_AUTO_RECLAIM'] = '1';
248
+ let caught;
249
+ try {
250
+ acquireOwnedLock(target, { timeoutMs: 150, reclaimProbeAfterMs: 0 });
251
+ }
252
+ catch (err) {
253
+ caught = err;
254
+ }
255
+ finally {
256
+ delete process.env['SKILLSMITH_LOCK_NO_AUTO_RECLAIM'];
257
+ }
258
+ expect(caught?.reason).toBe('reclaim_disabled');
259
+ });
260
+ it('14. hardlink-unavailable (R2 branch): a linkSync throwing ENOSYS fails CLOSED, no lock file left behind', () => {
261
+ // SMI-5883 code-review round 1 finding 1: the original fallback
262
+ // (openSync('wx') + a separate writeFileSync) was NOT content-complete --
263
+ // a crash or observer between those two steps would see an empty/
264
+ // truncated lock file, which is then PERMANENTLY unreclaimable (an
265
+ // `unparseable` claim is never auto-reclaimed by design). Fixed by
266
+ // failing closed instead: a filesystem without hardlink support cannot
267
+ // provide the atomic-and-content-complete creation this primitive
268
+ // requires, so `createLockExclusive` now throws rather than falling back.
269
+ const enosys = () => {
270
+ const err = new Error('ENOSYS');
271
+ err.code = 'ENOSYS';
272
+ throw err;
273
+ };
274
+ // Exercised directly against createLockExclusive (owned-lock.claim.ts) --
275
+ // the internal primitive this test targets -- rather than through the
276
+ // public acquireOwnedLock(), which no longer accepts a linkSyncOverride.
277
+ expect(() => createLockExclusive(lockPath, '{"v":1}\n', enosys)).toThrow(/does not support hardlinks/);
278
+ expect(existsSync(lockPath)).toBe(false);
279
+ // No stray temp file left behind either.
280
+ expect(readdirSync(dir).some((f) => f.endsWith('.tmp'))).toBe(false);
281
+ });
282
+ it('15. no litter: after acquire/release cycles above, the directory holds no *.tmp and no *.reclaim', () => {
283
+ const release = acquireOwnedLock(target, { timeoutMs: 1_000 });
284
+ release();
285
+ const entries = readdirSync(dir);
286
+ expect(entries.some((f) => f.endsWith('.tmp'))).toBe(false);
287
+ expect(entries.some((f) => f.endsWith('.reclaim'))).toBe(false);
288
+ });
289
+ it('16. public acquireOwnedLock() strips injected unsafe properties before reaching the core loop (SMI-5883 code-review round 2)', async () => {
290
+ // Round 2 finding: TypeScript's excess-property check only fires on an
291
+ // object LITERAL passed directly at the call site -- a caller passing a
292
+ // variable (or a plain-JavaScript caller with no type checking at all)
293
+ // is NOT constrained by AcquireOwnedLockOptions omitting the two unsafe
294
+ // fields, and the core loop reads them by property name at runtime.
295
+ // owned-lock.ts's public acquireOwnedLock() must therefore reconstruct a
296
+ // FRESH, allowlisted object rather than forward `opts` as-is. Verified
297
+ // here by spying on the core loop itself and asserting neither unsafe
298
+ // key ever reaches it, regardless of what the caller injects.
299
+ const acquireModule = await import('./owned-lock.acquire.js');
300
+ const spy = vi.spyOn(acquireModule, 'acquireOwnedLockCore');
301
+ const maliciousOpts = {
302
+ timeoutMs: 1_000,
303
+ unsafeSkipReclaimRevalidation: true,
304
+ linkSyncOverride: () => {
305
+ throw new Error('should never be called -- injected via a non-literal cast');
306
+ },
307
+ };
308
+ const release = acquireOwnedLock(target, maliciousOpts);
309
+ release();
310
+ expect(spy).toHaveBeenCalledTimes(1);
311
+ const forwarded = spy.mock.calls[0]?.[1];
312
+ // Round 3: the reconstructed object sets both unsafe fields to an
313
+ // explicit OWN `undefined` (to shadow a polluted Object.prototype --
314
+ // see item 17), so the property now exists but must never be truthy /
315
+ // never be the injected function.
316
+ expect(forwarded?.unsafeSkipReclaimRevalidation).toBeUndefined();
317
+ expect(forwarded?.linkSyncOverride).toBeUndefined();
318
+ spy.mockRestore();
319
+ });
320
+ it('17. public acquireOwnedLock() is immune to a globally-polluted Object.prototype (SMI-5883 code-review round 3)', async () => {
321
+ // Round 3 finding: a plain `{ ...safeFields }` reconstruction still
322
+ // inherits from Object.prototype -- if that prototype were ever globally
323
+ // polluted (a distinct, severe vulnerability class in its own right,
324
+ // reachable only by an attacker who already has arbitrary code execution
325
+ // in this process), ordinary property access on an object with no OWN
326
+ // `unsafeSkipReclaimRevalidation`/`linkSyncOverride` would still resolve
327
+ // them via the prototype chain. Fixed by explicitly setting both to
328
+ // `undefined` as OWN properties, which shadows any inherited value.
329
+ // Always restored in `finally` -- this is global, shared mutable state.
330
+ // Round 4 (test-hygiene finding): restore the ORIGINAL descriptors
331
+ // (undefined if the key was absent beforehand) rather than unconditionally
332
+ // deleting -- unconditional delete would be wrong if either key somehow
333
+ // already had a legitimate descriptor on Object.prototype before this test.
334
+ const acquireModule = await import('./owned-lock.acquire.js');
335
+ const spy = vi.spyOn(acquireModule, 'acquireOwnedLockCore');
336
+ const pollutedLinkSync = () => {
337
+ throw new Error('should never be called -- reached via Object.prototype pollution');
338
+ };
339
+ const origUnsafeSkip = Object.getOwnPropertyDescriptor(Object.prototype, 'unsafeSkipReclaimRevalidation');
340
+ const origLinkSync = Object.getOwnPropertyDescriptor(Object.prototype, 'linkSyncOverride');
341
+ try {
342
+ ;
343
+ Object.prototype['unsafeSkipReclaimRevalidation'] = true;
344
+ Object.prototype['linkSyncOverride'] = pollutedLinkSync;
345
+ const release = acquireOwnedLock(target, { timeoutMs: 1_000 });
346
+ release();
347
+ expect(spy).toHaveBeenCalledTimes(1);
348
+ const forwarded = spy.mock.calls[0]?.[1];
349
+ expect(forwarded?.unsafeSkipReclaimRevalidation).toBeUndefined();
350
+ expect(forwarded?.linkSyncOverride).toBeUndefined();
351
+ }
352
+ finally {
353
+ if (origUnsafeSkip) {
354
+ Object.defineProperty(Object.prototype, 'unsafeSkipReclaimRevalidation', origUnsafeSkip);
355
+ }
356
+ else {
357
+ delete Object.prototype['unsafeSkipReclaimRevalidation'];
358
+ }
359
+ if (origLinkSync) {
360
+ Object.defineProperty(Object.prototype, 'linkSyncOverride', origLinkSync);
361
+ }
362
+ else {
363
+ delete Object.prototype['linkSyncOverride'];
364
+ }
365
+ spy.mockRestore();
366
+ }
367
+ });
368
+ });
369
+ // ---------------------------------------------------------------------------
370
+ // §8c — orphaned reclaim lock (residual R1). Single-process: the "orphan" is
371
+ // simulated by hand-planting a live-owner reclaim-lock file, not by a real
372
+ // crash — the assertions are about R1's documented BLAST RADIUS (auto-reclaim
373
+ // disabled, locking itself unaffected), not about producing a real orphan.
374
+ // ---------------------------------------------------------------------------
375
+ describe('orphaned reclaim lock (residual R1, §8c)', () => {
376
+ it('1. a pre-existing (live-owner) reclaim lock blocks reclaim of a genuinely dead-PID main lock', () => {
377
+ const deadPid = mintDeadPid();
378
+ seed(v1(deadPid), lockPath);
379
+ seed(v1(process.pid), reclaimPath); // "orphan" stand-in: live-owner reclaim lock
380
+ const beforeLock = readFileSync(lockPath);
381
+ const beforeReclaim = readFileSync(reclaimPath);
382
+ let caught;
383
+ try {
384
+ acquireOwnedLock(target, { timeoutMs: 800, reclaimProbeAfterMs: 0 });
385
+ }
386
+ catch (err) {
387
+ caught = err;
388
+ }
389
+ expect(caught).toBeInstanceOf(StuckLockError);
390
+ expect(caught?.reason).toBe('reclaim_unavailable');
391
+ expect(caught?.message).toContain(lockPath);
392
+ expect(caught?.message).toContain(reclaimPath);
393
+ expect(caught?.message.toLowerCase()).toContain('manual unstick');
394
+ expect(readFileSync(lockPath).equals(beforeLock)).toBe(true);
395
+ expect(readFileSync(reclaimPath).equals(beforeReclaim)).toBe(true);
396
+ });
397
+ it('2. with no main lock present, acquisition succeeds despite an orphaned reclaim lock (locking unaffected)', () => {
398
+ seed(v1(process.pid), reclaimPath); // orphan stand-in; no `.lock` file exists
399
+ const release = acquireOwnedLock(target, { timeoutMs: 1_000 });
400
+ release();
401
+ });
402
+ it('3. removing the orphan restores service — the dead-PID lock reclaims normally afterward', () => {
403
+ const deadPid = mintDeadPid();
404
+ seed(v1(deadPid), lockPath);
405
+ seed(v1(process.pid), reclaimPath);
406
+ rmSync(reclaimPath); // the documented manual unstick
407
+ const release = acquireOwnedLock(target, { timeoutMs: 2_000, reclaimProbeAfterMs: 0 });
408
+ expect(existsSync(reclaimPath)).toBe(false);
409
+ release();
410
+ });
411
+ });
412
+ //# sourceMappingURL=owned-lock.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owned-lock.test.js","sourceRoot":"","sources":["../../../src/config/owned-lock.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Shared types + tuning constants for the two-level owned-lock primitive.
3
+ * @module @skillsmith/core/config/owned-lock.types
4
+ * @see owned-lock.ts for the full soundness argument and public API.
5
+ */
6
+ /** Max time to wait for the MAIN lock before giving up (ms). Unchanged from today's `acquireConfigLock` default. */
7
+ export declare const LOCK_ACQUIRE_TIMEOUT_MS = 5000;
8
+ /** Backoff between lock-acquisition retries (ms). */
9
+ export declare const LOCK_RETRY_DELAY_MS = 20;
10
+ /** Delay before the FIRST reclaim probe -- keeps the reclaim lock off the hot path when the holder is alive. */
11
+ export declare const RECLAIM_PROBE_AFTER_MS = 250;
12
+ /** Backoff between reclaim probe attempts once contention is established. */
13
+ export declare const RECLAIM_PROBE_INTERVAL_MS = 250;
14
+ /** Max time to wait for the RECLAIM lock. Its critical section is 3 syscalls with no caller code -- a longer wait would itself indicate an orphan (R1). */
15
+ export declare const RECLAIM_LOCK_TIMEOUT_MS = 500;
16
+ /** Bounded read cap for a lock claim file -- refuses (never crashes on) an oversized/garbage lock file. */
17
+ export declare const MAX_LOCK_BYTES = 4096;
18
+ export declare const HARDLINK_UNAVAILABLE_CODES: Set<string>;
19
+ /** A live, current-format claim: `{"v":1,"pid":...,"token":"<16 hex>","host":"...","acquiredAt":...}`. */
20
+ export interface V1Claim {
21
+ kind: 'v1';
22
+ pid: number;
23
+ token: string;
24
+ host: string;
25
+ acquiredAt: number;
26
+ }
27
+ /** A bare-decimal-PID claim (today's `acquireConfigLock` format). Carries no `host` -- NEVER auto-reclaimed (D-5). */
28
+ export interface LegacyClaim {
29
+ kind: 'legacy';
30
+ pid: number;
31
+ }
32
+ /** Empty, garbage, truncated, or valid-JSON-but-wrong-shape/version. NEVER auto-reclaimed. */
33
+ export interface UnparseableClaim {
34
+ kind: 'unparseable';
35
+ }
36
+ /** No lock file present at the path read. */
37
+ export interface AbsentClaim {
38
+ kind: 'absent';
39
+ }
40
+ export type Claim = V1Claim | LegacyClaim | UnparseableClaim | AbsentClaim;
41
+ /** Outcome of a single reclaim attempt (`tryReclaimUnderLock`). */
42
+ export type ReclaimOutcome = 'reclaimed' | 'not-stale' | 'gone' | 'unavailable';
43
+ /** Why the pre-filter (outside the reclaim critical section) declined to even attempt a reclaim. */
44
+ export type RefusalCategory = 'held' | 'legacy' | 'unparseable' | 'reclaim-disabled';
45
+ export type StuckLockReason = 'held' | 'unreclaimable_legacy' | 'unreclaimable_unparseable' | 'reclaim_unavailable' | 'reclaim_disabled';
46
+ /**
47
+ * Public, SAFE option set for `acquireOwnedLock` (owned-lock.ts). Does NOT
48
+ * include the two destructive test-only seams (`unsafeSkipReclaimRevalidation`,
49
+ * `linkSyncOverride`) -- those live only on the internal
50
+ * `AcquireOwnedLockCoreOptions` (owned-lock.acquire.ts, no public subpath
51
+ * export), so a package consumer can never pass them through the public
52
+ * `acquireOwnedLock()` entry point. See owned-lock.acquire.ts's module comment
53
+ * for the full rationale.
54
+ */
55
+ export interface AcquireOwnedLockOptions {
56
+ /** Override the acquire timeout. Production callers should omit this and use the default. */
57
+ timeoutMs?: number;
58
+ /** Human label used in the timeout message, e.g. `'config lock'` -> "Timed out waiting for config lock at ...". Defaults to `'lock'`. */
59
+ label?: string;
60
+ /** Delay before the first reclaim probe (ms). Production callers should omit this; test-only override. */
61
+ reclaimProbeAfterMs?: number;
62
+ /**
63
+ * @internal Test seam (owned-lock-reclaim-race.test.ts §8b). Fires AFTER
64
+ * the pre-filter has validated a dead claim and BEFORE any reclaim-lock
65
+ * acquisition or removal is attempted. Never set in production code.
66
+ * (Read-only observability -- unlike the two omitted options above, this
67
+ * cannot affect the locking safety properties, so it's safe to leave on
68
+ * the public type.)
69
+ */
70
+ onReclaimBoundary?: () => void;
71
+ /**
72
+ * @internal Test seam (owned-lock-reclaim-race.test.ts §8b). Fires
73
+ * immediately after `tryReclaimUnderLock` returns, with its outcome.
74
+ * Never set in production code. Read-only, same rationale as above.
75
+ */
76
+ onReclaimOutcome?: (outcome: ReclaimOutcome) => void;
77
+ }
78
+ //# sourceMappingURL=owned-lock.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owned-lock.types.d.ts","sourceRoot":"","sources":["../../../src/config/owned-lock.types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,oHAAoH;AACpH,eAAO,MAAM,uBAAuB,OAAQ,CAAA;AAC5C,qDAAqD;AACrD,eAAO,MAAM,mBAAmB,KAAK,CAAA;AACrC,gHAAgH;AAChH,eAAO,MAAM,sBAAsB,MAAM,CAAA;AACzC,6EAA6E;AAC7E,eAAO,MAAM,yBAAyB,MAAM,CAAA;AAC5C,2JAA2J;AAC3J,eAAO,MAAM,uBAAuB,MAAM,CAAA;AAC1C,2GAA2G;AAC3G,eAAO,MAAM,cAAc,OAAQ,CAAA;AAEnC,eAAO,MAAM,0BAA0B,aAQrC,CAAA;AAMF,0GAA0G;AAC1G,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,IAAI,CAAA;IACV,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;CACnB;AACD,sHAAsH;AACtH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;CACZ;AACD,8FAA8F;AAC9F,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,aAAa,CAAA;CACpB;AACD,6CAA6C;AAC7C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAA;CACf;AACD,MAAM,MAAM,KAAK,GAAG,OAAO,GAAG,WAAW,GAAG,gBAAgB,GAAG,WAAW,CAAA;AAE1E,mEAAmE;AACnE,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,WAAW,GAAG,MAAM,GAAG,aAAa,CAAA;AAE/E,oGAAoG;AACpG,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,aAAa,GAAG,kBAAkB,CAAA;AAMpF,MAAM,MAAM,eAAe,GACvB,MAAM,GACN,sBAAsB,GACtB,2BAA2B,GAC3B,qBAAqB,GACrB,kBAAkB,CAAA;AAEtB;;;;;;;;GAQG;AACH,MAAM,WAAW,uBAAuB;IACtC,6FAA6F;IAC7F,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yIAAyI;IACzI,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,0GAA0G;IAC1G,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAA;IAC9B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAA;CACrD"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Shared types + tuning constants for the two-level owned-lock primitive.
3
+ * @module @skillsmith/core/config/owned-lock.types
4
+ * @see owned-lock.ts for the full soundness argument and public API.
5
+ */
6
+ // ---------------------------------------------------------------------------
7
+ // Tuning constants
8
+ // ---------------------------------------------------------------------------
9
+ /** Max time to wait for the MAIN lock before giving up (ms). Unchanged from today's `acquireConfigLock` default. */
10
+ export const LOCK_ACQUIRE_TIMEOUT_MS = 5_000;
11
+ /** Backoff between lock-acquisition retries (ms). */
12
+ export const LOCK_RETRY_DELAY_MS = 20;
13
+ /** Delay before the FIRST reclaim probe -- keeps the reclaim lock off the hot path when the holder is alive. */
14
+ export const RECLAIM_PROBE_AFTER_MS = 250;
15
+ /** Backoff between reclaim probe attempts once contention is established. */
16
+ export const RECLAIM_PROBE_INTERVAL_MS = 250;
17
+ /** Max time to wait for the RECLAIM lock. Its critical section is 3 syscalls with no caller code -- a longer wait would itself indicate an orphan (R1). */
18
+ export const RECLAIM_LOCK_TIMEOUT_MS = 500;
19
+ /** Bounded read cap for a lock claim file -- refuses (never crashes on) an oversized/garbage lock file. */
20
+ export const MAX_LOCK_BYTES = 4_096;
21
+ export const HARDLINK_UNAVAILABLE_CODES = new Set([
22
+ 'EPERM',
23
+ 'EACCES',
24
+ 'ENOSYS',
25
+ 'EXDEV',
26
+ 'EMLINK',
27
+ 'EOPNOTSUPP',
28
+ 'ENOTSUP',
29
+ ]);
30
+ //# sourceMappingURL=owned-lock.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owned-lock.types.js","sourceRoot":"","sources":["../../../src/config/owned-lock.types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,oHAAoH;AACpH,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,CAAA;AAC5C,qDAAqD;AACrD,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAA;AACrC,gHAAgH;AAChH,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAA;AACzC,6EAA6E;AAC7E,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAA;AAC5C,2JAA2J;AAC3J,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAA;AAC1C,2GAA2G;AAC3G,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAA;AAEnC,MAAM,CAAC,MAAM,0BAA0B,GAAG,IAAI,GAAG,CAAC;IAChD,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,YAAY;IACZ,SAAS;CACV,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"createDatabase.d.ts","sourceRoot":"","sources":["../../../src/db/createDatabase.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAcxE;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,gBAAgB,GAAG,QAAQ,CAAA;AAEpD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,UAAU,CAAA;IAChB,SAAS,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,UAAU,EAAE,CA0BrD;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,UAAU,GAAG,IAAI,CAiBjD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,MAAmB,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,QAAQ,CAgBjG;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,GAAE,MAAmB,EACzB,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,QAAQ,CAAC,CA2CnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,cAAc,2BAAqB,CAAA"}
1
+ {"version":3,"file":"createDatabase.d.ts","sourceRoot":"","sources":["../../../src/db/createDatabase.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAmBxE;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,gBAAgB,GAAG,QAAQ,CAAA;AAEpD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,UAAU,CAAA;IAChB,SAAS,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,UAAU,EAAE,CA0BrD;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,UAAU,GAAG,IAAI,CAiBjD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,MAAmB,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,QAAQ,CAgBjG;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,GAAE,MAAmB,EACzB,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,QAAQ,CAAC,CAkDnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,cAAc,2BAAqB,CAAA"}
@@ -18,6 +18,11 @@
18
18
  */
19
19
  import { createBetterSqlite3Database, isBetterSqlite3Available, getBetterSqlite3FailureReason, } from './drivers/betterSqlite3Driver.js';
20
20
  import { createSqlJsDatabase, isSqlJsAvailable } from './drivers/sqljsDriver.js';
21
+ // SMI-5897 (C-18/C-19, Wave 4 fix): shared SKILLSMITH_QUIET guard — this was
22
+ // the second, unguarded fallback-warning path C-18/C-19 didn't originally
23
+ // cover; the WASM-driver notice below always printed at least once per
24
+ // process regardless of SKILLSMITH_QUIET.
25
+ import { isQuietModeEnabled } from '../utils/quiet-mode.js';
21
26
  /**
22
27
  * SMI-4807: guard so the WASM-fallback notice is emitted at most once per
23
28
  * process, no matter how many database connections are opened.
@@ -135,15 +140,22 @@ export async function createDatabaseAsync(path = ':memory:', options) {
135
140
  if (isSqlJsAvailable()) {
136
141
  if (!wasmFallbackNoticeEmitted) {
137
142
  wasmFallbackNoticeEmitted = true;
138
- let message = '[Skillsmith] Using WASM SQLite driver ' +
139
- '(native better-sqlite3 not loadedexpected on direct macOS/npx installs).';
140
- if (process.env.SKILLSMITH_DEBUG) {
141
- const reason = getBetterSqlite3FailureReason();
142
- if (reason) {
143
- message += ` Reason: ${reason}`;
143
+ // SMI-5897 (Wave 4 fix): honor SKILLSMITH_QUIET, same as the
144
+ // embeddings-layer fallback warningsthe notice still guards
145
+ // print-once-per-process via wasmFallbackNoticeEmitted above (set
146
+ // regardless of quiet mode, so a later non-quiet caller doesn't get a
147
+ // stale re-print of a decision already made this process).
148
+ if (!isQuietModeEnabled()) {
149
+ let message = '[Skillsmith] Using WASM SQLite driver ' +
150
+ '(native better-sqlite3 not loaded — expected on direct macOS/npx installs).';
151
+ if (process.env.SKILLSMITH_DEBUG) {
152
+ const reason = getBetterSqlite3FailureReason();
153
+ if (reason) {
154
+ message += ` Reason: ${reason}`;
155
+ }
144
156
  }
157
+ console.warn(message);
145
158
  }
146
- console.warn(message);
147
159
  }
148
160
  return await createSqlJsDatabase(path, options);
149
161
  }
@@ -1 +1 @@
1
- {"version":3,"file":"createDatabase.js","sourceRoot":"","sources":["../../../src/db/createDatabase.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"createDatabase.js","sourceRoot":"","sources":["../../../src/db/createDatabase.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * SMI-1519: `HNSWEmbeddingStore` re-exports.
3
+ * SMI-5897: split out of `embeddings/index.ts` (a pure re-export forward,
4
+ * unrelated to the `EmbeddingService` class it otherwise defines) to keep
5
+ * that file under the CLAUDE.md 500-line-per-file cap. No behavior change —
6
+ * `index.ts` re-exports everything from here via `export *`, so existing
7
+ * `@skillsmith/core/embeddings` consumers are unaffected.
8
+ */
9
+ export { HNSWEmbeddingStore, createHNSWStore, isHNSWAvailable, loadHNSWLib, DEFAULT_HNSW_CONFIG, HNSW_PRESETS, } from './hnsw-store.js';
10
+ export type { IEmbeddingStore, HNSWConfig, HNSWEmbeddingStoreOptions, HNSWIndexStats, BatchInsertResult, HierarchicalNSW, HierarchicalNSWConstructor, HNSWSearchResult, } from './hnsw-store.js';
11
+ //# sourceMappingURL=hnsw-store.exports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hnsw-store.exports.d.ts","sourceRoot":"","sources":["../../../src/embeddings/hnsw-store.exports.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,YAAY,GACb,MAAM,iBAAiB,CAAA;AAExB,YAAY,EACV,eAAe,EACf,UAAU,EACV,yBAAyB,EACzB,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,iBAAiB,CAAA"}