scip-query 0.19.6 → 0.19.10

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 (377) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/README.md +156 -44
  3. package/dist/augment-vue-worker.js +1 -1
  4. package/dist/chunk-26QA6FAI.js +8 -0
  5. package/dist/{chunk-J7VT2CRB.js → chunk-2HPVVXM5.js} +2 -2
  6. package/dist/chunk-2KAZEZ6M.js +2 -0
  7. package/dist/chunk-32LVLCLN.js +40 -0
  8. package/dist/{chunk-2CVXCGL4.js → chunk-3CLX5EOX.js} +2 -2
  9. package/dist/{chunk-5OC3HWP5.js → chunk-3G66UZBH.js} +2 -2
  10. package/dist/{chunk-S2GP3CU3.js → chunk-3ORVDL3H.js} +2 -2
  11. package/dist/chunk-46XGSFNI.js +2 -0
  12. package/dist/chunk-4MAK2HOY.js +6 -0
  13. package/dist/chunk-4TURLRL5.js +16 -0
  14. package/dist/chunk-4UQVNCQE.js +2 -0
  15. package/dist/chunk-55Q3WLZX.js +2 -0
  16. package/dist/{chunk-OQ2A4G2G.js → chunk-5E4WNAVD.js} +2 -2
  17. package/dist/{chunk-YGQN3XGZ.js → chunk-5I5G2QOX.js} +2 -2
  18. package/dist/chunk-6LDJQXAH.js +2 -0
  19. package/dist/{chunk-WXAAURU7.js → chunk-6O5TICIZ.js} +2 -2
  20. package/dist/{chunk-OBKDTVZ3.js → chunk-6SHPK5ZE.js} +2 -2
  21. package/dist/chunk-7BAVHKMJ.js +49 -0
  22. package/dist/chunk-7O5IKBTZ.js +16 -0
  23. package/dist/chunk-7PIO7NKH.js +60 -0
  24. package/dist/chunk-7S5E7KWT.js +2 -0
  25. package/dist/{chunk-GK3GRUJX.js → chunk-7SQQWSY3.js} +2 -2
  26. package/dist/chunk-7WPLAODU.js +5 -0
  27. package/dist/chunk-A73XVBCR.js +20 -0
  28. package/dist/chunk-AFHORGLH.js +42 -0
  29. package/dist/chunk-AIE7TFJW.js +9 -0
  30. package/dist/chunk-AQOFWNQJ.js +1 -0
  31. package/dist/{chunk-MGBJHRFB.js → chunk-AZJQQKDD.js} +2 -2
  32. package/dist/{chunk-IYAOX36F.js → chunk-B2PX5I6M.js} +2 -2
  33. package/dist/{chunk-EVOC5I5I.js → chunk-B7PBSLZN.js} +2 -2
  34. package/dist/{chunk-ZLJLE6LK.js → chunk-BBW6JFHN.js} +2 -2
  35. package/dist/{chunk-NBRUH7OE.js → chunk-BDCC2NPY.js} +2 -2
  36. package/dist/{chunk-DD5BOU5I.js → chunk-BNXCIFVY.js} +2 -2
  37. package/dist/{chunk-FHCTEANE.js → chunk-BPAPWKP6.js} +2 -2
  38. package/dist/chunk-BS2NMXQZ.js +4 -0
  39. package/dist/chunk-C3KV2II6.js +2 -0
  40. package/dist/chunk-C43RDDP4.js +20 -0
  41. package/dist/{chunk-QBYYWGAT.js → chunk-CJST5ETY.js} +2 -2
  42. package/dist/chunk-DAFAHMNB.js +42 -0
  43. package/dist/chunk-DHEQMPLW.js +2 -0
  44. package/dist/{chunk-336DC5NJ.js → chunk-DQGFVPUV.js} +2 -2
  45. package/dist/chunk-DQLPXMH6.js +8 -0
  46. package/dist/chunk-EKZTZXHZ.js +117 -0
  47. package/dist/{chunk-KLVJABXA.js → chunk-EN3O7VJA.js} +2 -2
  48. package/dist/{chunk-U5CNPPTZ.js → chunk-EW2NTSFA.js} +2 -2
  49. package/dist/chunk-F3Z4OUDS.js +8 -0
  50. package/dist/chunk-FJH2NW7J.js +66 -0
  51. package/dist/{chunk-3OIKRYU5.js → chunk-FKSELJQF.js} +2 -2
  52. package/dist/chunk-FTFP6O3L.js +11 -0
  53. package/dist/chunk-FYLK2DEJ.js +2 -0
  54. package/dist/chunk-GH74ASD6.js +11 -0
  55. package/dist/{chunk-NQLSSVOB.js → chunk-GMXWZP2B.js} +2 -2
  56. package/dist/chunk-GOUBFH5O.js +3 -0
  57. package/dist/{chunk-RJHCPSZ7.js → chunk-HLF2TX6R.js} +2 -2
  58. package/dist/{chunk-PC44K7RF.js → chunk-HX4GQPZP.js} +2 -2
  59. package/dist/chunk-HX7M4BDI.js +30 -0
  60. package/dist/chunk-HZ72SESS.js +128 -0
  61. package/dist/{chunk-YTUD45PU.js → chunk-IB2N4FIY.js} +2 -2
  62. package/dist/chunk-ILMHV3KM.js +2 -0
  63. package/dist/chunk-IZYYAFN5.js +2 -0
  64. package/dist/{chunk-A43URCQ3.js → chunk-JAYYFEQY.js} +2 -2
  65. package/dist/{chunk-RWRLUZ6U.js → chunk-JDOEX4E6.js} +2 -2
  66. package/dist/chunk-JFGGXWQF.js +947 -0
  67. package/dist/chunk-JN4NMBEX.js +8 -0
  68. package/dist/{chunk-JELJLXEE.js → chunk-JVYA47YU.js} +2 -2
  69. package/dist/{chunk-F42A3AKG.js → chunk-JW56N3KI.js} +2 -2
  70. package/dist/{chunk-FQTPPXNA.js → chunk-JZ2OXNWB.js} +2 -2
  71. package/dist/chunk-KFZNKUNT.js +2 -0
  72. package/dist/chunk-KMKTIO2G.js +8 -0
  73. package/dist/chunk-L5GJNV2T.js +8 -0
  74. package/dist/{chunk-RBFFD4V2.js → chunk-L7AW2QB5.js} +2 -2
  75. package/dist/chunk-L7JDSCDF.js +4 -0
  76. package/dist/chunk-LU47HG23.js +14 -0
  77. package/dist/chunk-LVY7NPF7.js +2 -0
  78. package/dist/chunk-LY4WC4AD.js +74 -0
  79. package/dist/{chunk-MLGTCX56.js → chunk-MKCDWWGV.js} +2 -2
  80. package/dist/chunk-MNE7YG56.js +2 -0
  81. package/dist/{chunk-YWB2EBNB.js → chunk-MRXBEXSY.js} +2 -2
  82. package/dist/chunk-MV7OWDUX.js +2 -0
  83. package/dist/{chunk-2GSQR6YA.js → chunk-N5W4YZMK.js} +2 -2
  84. package/dist/chunk-NGEXCJJW.js +11 -0
  85. package/dist/{chunk-CYJM7CYF.js → chunk-NIW6JDC5.js} +2 -2
  86. package/dist/{chunk-YHXBD52M.js → chunk-O64IZ6UX.js} +2 -2
  87. package/dist/chunk-PBUQFCNB.js +16 -0
  88. package/dist/{chunk-UQK5CRUK.js → chunk-POAVPHH7.js} +2 -2
  89. package/dist/{chunk-TYQ76QHQ.js → chunk-PQCI4SQX.js} +2 -2
  90. package/dist/chunk-PXY7F6Y4.js +5 -0
  91. package/dist/chunk-RDO52JGY.js +2 -0
  92. package/dist/chunk-RJT3TUUZ.js +2 -0
  93. package/dist/{chunk-OHWZKLVA.js → chunk-RUJURYSV.js} +2 -2
  94. package/dist/{chunk-CSTYYXKC.js → chunk-RVLDN63O.js} +2 -2
  95. package/dist/chunk-RXOXSKY3.js +2 -0
  96. package/dist/chunk-S7OYBOCK.js +2 -0
  97. package/dist/chunk-SMNXQT5Z.js +3 -0
  98. package/dist/{chunk-QQWOFXNW.js → chunk-SRAFT254.js} +2 -2
  99. package/dist/{chunk-6XHTISLI.js → chunk-SXP2MBJH.js} +2 -2
  100. package/dist/chunk-T7YQSHPQ.js +3 -0
  101. package/dist/{chunk-2EZSOTSY.js → chunk-TFRAYKN6.js} +2 -2
  102. package/dist/{chunk-XVJ3V7LM.js → chunk-UJCOIXDY.js} +2 -2
  103. package/dist/{chunk-7LABSJSR.js → chunk-UJPRPGCO.js} +5 -5
  104. package/dist/chunk-W4ETQAXM.js +2 -0
  105. package/dist/chunk-WCCFZ7V7.js +113 -0
  106. package/dist/chunk-WUPW3UN3.js +3 -0
  107. package/dist/{chunk-VP542C25.js → chunk-WXZLAAWK.js} +2 -2
  108. package/dist/{chunk-LMFVTUW2.js → chunk-X54AGLVX.js} +2 -2
  109. package/dist/chunk-XKWKXZKW.js +20 -0
  110. package/dist/{chunk-OP3MTFJR.js → chunk-XSRF6Q77.js} +2 -2
  111. package/dist/chunk-Y2MVPNKY.js +5 -0
  112. package/dist/{chunk-6XFC7PQ5.js → chunk-YKUU5AIC.js} +2 -2
  113. package/dist/chunk-YLCJLTPL.js +2 -0
  114. package/dist/{chunk-47X75ZKH.js → chunk-YTQVETEO.js} +2 -2
  115. package/dist/chunk-Z4N3MZYA.js +38 -0
  116. package/dist/chunk-ZHXX42OH.js +18 -0
  117. package/dist/chunk-ZJOOT3BG.js +2 -0
  118. package/dist/chunk-ZK26BAQL.js +2 -0
  119. package/dist/{chunk-UUJBLG6J.js → chunk-ZTETIQ35.js} +2 -2
  120. package/dist/cli.js +3 -3
  121. package/dist/command-descriptors-4A4HWV4F.js +642 -0
  122. package/dist/{config-types-BWQ5xPGI.d.ts → config-types-jVM3D7MA.d.ts} +72 -2
  123. package/dist/{db-B0r1o7Vt.d.ts → db-B5PM5yNk.d.ts} +20 -2
  124. package/dist/{diff-gate-types-C9BoYwYD.d.ts → diff-gate-types-B0QYpDv1.d.ts} +2 -1
  125. package/dist/direct-navigation-6YHV6IB5.js +3 -0
  126. package/dist/{health-CFnlCiTz.d.ts → health-Do5TKSJI.d.ts} +1 -1
  127. package/dist/index.d.ts +3 -3
  128. package/dist/index.js +1 -1
  129. package/dist/postinstall.js +1 -1
  130. package/dist/queries/affected.d.ts +2 -2
  131. package/dist/queries/affected.js +1 -1
  132. package/dist/queries/architecture.d.ts +2 -2
  133. package/dist/queries/architecture.js +1 -1
  134. package/dist/queries/bottlenecks.d.ts +2 -2
  135. package/dist/queries/bottlenecks.js +1 -1
  136. package/dist/queries/by-kind.d.ts +2 -2
  137. package/dist/queries/by-kind.js +1 -1
  138. package/dist/queries/call-graph.d.ts +2 -2
  139. package/dist/queries/call-graph.js +1 -1
  140. package/dist/queries/change-surface.d.ts +22 -3
  141. package/dist/queries/change-surface.js +1 -1
  142. package/dist/queries/cleanup-plan.d.ts +2 -2
  143. package/dist/queries/cleanup-plan.js +1 -1
  144. package/dist/queries/co-change.d.ts +2 -2
  145. package/dist/queries/co-change.js +1 -1
  146. package/dist/queries/code.d.ts +2 -2
  147. package/dist/queries/code.js +1 -1
  148. package/dist/queries/complexity-hotspots.d.ts +3 -3
  149. package/dist/queries/complexity-hotspots.js +1 -1
  150. package/dist/queries/complexity.d.ts +3 -3
  151. package/dist/queries/complexity.js +1 -1
  152. package/dist/queries/convergence.d.ts +2 -2
  153. package/dist/queries/convergence.js +1 -1
  154. package/dist/queries/coupling.d.ts +2 -2
  155. package/dist/queries/coupling.js +1 -1
  156. package/dist/queries/cycles.d.ts +2 -2
  157. package/dist/queries/cycles.js +1 -1
  158. package/dist/queries/dataflow.d.ts +2 -2
  159. package/dist/queries/dataflow.js +1 -1
  160. package/dist/queries/dead.d.ts +2 -2
  161. package/dist/queries/dead.js +1 -1
  162. package/dist/queries/decorative-checkers.d.ts +2 -2
  163. package/dist/queries/decorative-checkers.js +1 -1
  164. package/dist/queries/deep-chains.d.ts +2 -2
  165. package/dist/queries/deep-chains.js +1 -1
  166. package/dist/queries/deps.d.ts +2 -2
  167. package/dist/queries/deps.js +1 -1
  168. package/dist/queries/diff-gate.d.ts +40 -7
  169. package/dist/queries/diff-gate.js +1 -1
  170. package/dist/queries/diff-impact.d.ts +84 -6
  171. package/dist/queries/diff-impact.js +1 -1
  172. package/dist/queries/doc-drift.d.ts +3 -3
  173. package/dist/queries/doc-drift.js +1 -1
  174. package/dist/queries/drift.d.ts +2 -2
  175. package/dist/queries/drift.js +1 -1
  176. package/dist/queries/duplicate-bodies.d.ts +3 -3
  177. package/dist/queries/duplicate-bodies.js +1 -1
  178. package/dist/queries/extract-candidates.d.ts +2 -2
  179. package/dist/queries/extract-candidates.js +1 -1
  180. package/dist/queries/fan.d.ts +2 -2
  181. package/dist/queries/fan.js +1 -1
  182. package/dist/queries/files.d.ts +12 -3
  183. package/dist/queries/files.js +1 -1
  184. package/dist/queries/health.d.ts +3 -3
  185. package/dist/queries/health.js +1 -1
  186. package/dist/queries/hierarchy.d.ts +2 -2
  187. package/dist/queries/hierarchy.js +1 -1
  188. package/dist/queries/hotspots.d.ts +2 -2
  189. package/dist/queries/hotspots.js +1 -1
  190. package/dist/queries/imports.d.ts +2 -2
  191. package/dist/queries/imports.js +1 -1
  192. package/dist/queries/incomplete-migration.d.ts +8 -6
  193. package/dist/queries/incomplete-migration.js +1 -1
  194. package/dist/queries/index.d.ts +141 -10
  195. package/dist/queries/index.js +1 -1
  196. package/dist/queries/isolated.d.ts +2 -2
  197. package/dist/queries/isolated.js +1 -1
  198. package/dist/queries/locality-candidates.d.ts +2 -2
  199. package/dist/queries/locality-candidates.js +1 -1
  200. package/dist/queries/members.d.ts +2 -2
  201. package/dist/queries/members.js +1 -1
  202. package/dist/queries/methods.d.ts +34 -3
  203. package/dist/queries/methods.js +1 -1
  204. package/dist/queries/not-implemented.d.ts +2 -2
  205. package/dist/queries/not-implemented.js +1 -1
  206. package/dist/queries/outline.d.ts +2 -2
  207. package/dist/queries/outline.js +1 -1
  208. package/dist/queries/passthrough-candidates.d.ts +3 -3
  209. package/dist/queries/passthrough-candidates.js +1 -1
  210. package/dist/queries/plan-context.d.ts +3 -3
  211. package/dist/queries/plan-context.js +1 -1
  212. package/dist/queries/react-component-duplicates.d.ts +2 -2
  213. package/dist/queries/react-component-duplicates.js +1 -1
  214. package/dist/queries/react-hook-candidates.d.ts +2 -2
  215. package/dist/queries/react-hook-candidates.js +1 -1
  216. package/dist/queries/react-large-component-pressure.d.ts +2 -2
  217. package/dist/queries/react-large-component-pressure.js +1 -1
  218. package/dist/queries/recent-duplicates.d.ts +2 -2
  219. package/dist/queries/recent-duplicates.js +1 -1
  220. package/dist/queries/redundant-reexports.d.ts +2 -2
  221. package/dist/queries/redundant-reexports.js +1 -1
  222. package/dist/queries/refs.d.ts +2 -2
  223. package/dist/queries/refs.js +1 -1
  224. package/dist/queries/self-audit.d.ts +2 -2
  225. package/dist/queries/self-audit.js +1 -1
  226. package/dist/queries/similar-chains.d.ts +2 -2
  227. package/dist/queries/similar-chains.js +1 -1
  228. package/dist/queries/similar-files.d.ts +2 -2
  229. package/dist/queries/similar-files.js +1 -1
  230. package/dist/queries/similar-signatures.d.ts +2 -2
  231. package/dist/queries/similar-signatures.js +1 -1
  232. package/dist/queries/similar.d.ts +2 -2
  233. package/dist/queries/similar.js +1 -1
  234. package/dist/queries/slice.d.ts +2 -2
  235. package/dist/queries/slice.js +1 -1
  236. package/dist/queries/stale-abstractions.d.ts +2 -2
  237. package/dist/queries/stale-abstractions.js +1 -1
  238. package/dist/queries/stats.d.ts +2 -2
  239. package/dist/queries/surface.d.ts +2 -2
  240. package/dist/queries/surface.js +1 -1
  241. package/dist/queries/symbols.d.ts +2 -2
  242. package/dist/queries/symbols.js +1 -1
  243. package/dist/queries/system.d.ts +2 -2
  244. package/dist/queries/system.js +1 -1
  245. package/dist/queries/test-quality.d.ts +2 -2
  246. package/dist/queries/test-quality.js +1 -1
  247. package/dist/queries/trace.d.ts +2 -2
  248. package/dist/queries/trace.js +1 -1
  249. package/dist/queries/twin-ab.d.ts +14 -3
  250. package/dist/queries/twin-ab.js +1 -1
  251. package/dist/queries/twin-drift.d.ts +2 -2
  252. package/dist/queries/twin-drift.js +1 -1
  253. package/dist/queries/unused-imports.d.ts +2 -2
  254. package/dist/queries/unused-imports.js +1 -1
  255. package/dist/queries/unused-params.d.ts +2 -2
  256. package/dist/queries/unused-params.js +1 -1
  257. package/dist/queries/vue-component-duplicates.d.ts +2 -2
  258. package/dist/queries/vue-component-duplicates.js +1 -1
  259. package/dist/queries/vue-composable-candidates.d.ts +2 -2
  260. package/dist/queries/vue-composable-candidates.js +1 -1
  261. package/dist/queries/vue-large-view-pressure.d.ts +2 -2
  262. package/dist/queries/vue-large-view-pressure.js +1 -1
  263. package/dist/queries/wrapper-candidates.d.ts +2 -2
  264. package/dist/queries/wrapper-candidates.js +1 -1
  265. package/dist/reindex-worker.js +26 -25
  266. package/dist/reindex.d.ts +7 -3
  267. package/dist/reindex.js +34 -33
  268. package/dist/runtime.d.ts +5 -10
  269. package/dist/runtime.js +3 -3
  270. package/dist/rust-semantic-session-server.js +1 -1
  271. package/dist/rust-semantic-session-worker.js +1 -1
  272. package/dist/rust-semantic-worker.js +1 -1
  273. package/dist/{scip-cli-DCvnlZCu.d.ts → scip-cli-BnEwZRLJ.d.ts} +2 -2
  274. package/dist/{symbol-types-BgWU6lhL.d.ts → symbol-types-BIQwfoAx.d.ts} +7 -1
  275. package/dist/typescript-mailbox-worker.js +2 -0
  276. package/dist/watch-server.js +2 -42
  277. package/docs/AGENT_GUIDE.md +28 -5
  278. package/docs/CLI_JSON_OUTPUT.md +176 -3
  279. package/docs/COMMAND_REFERENCE.md +89 -87
  280. package/docs/COMMITTED_RECORD_COMPATIBILITY.md +55 -18
  281. package/docs/DURABILITY.md +88 -38
  282. package/docs/INDEX_GENERATIONS.md +65 -19
  283. package/docs/MAILBOX_LIFECYCLE.md +28 -1
  284. package/docs/REINDEX_METADATA_COMPATIBILITY.md +18 -8
  285. package/docs/SECURITY_MODEL.md +146 -0
  286. package/docs/TELEMETRY_RETENTION.md +16 -4
  287. package/docs/WATCH_REFRESH_REQUESTS.md +34 -21
  288. package/docs/WINDOWS_SIDECAR_RELEASE.md +9 -4
  289. package/docs/analyzer-inventory.md +31 -22
  290. package/docs/analyzer-validation-ledger.md +8 -0
  291. package/docs/schemas/cli-output-page.schema.json +104 -0
  292. package/docs/schemas/outcome-event-record.schema.json +57 -1
  293. package/docs/schemas/project-config.schema.json +82 -1
  294. package/docs/schemas/suppression-record.schema.json +84 -3
  295. package/package.json +9 -8
  296. package/skills/_shared/SKILL.md +5 -3
  297. package/skills/_shared/references/agent-contract-catalog.md +1 -1
  298. package/skills/_shared/references/detector-precision-and-diffgate.md +1 -1
  299. package/skills/scip-audit/SKILL.md +9 -8
  300. package/skills/scip-audit/references/claims.md +1 -1
  301. package/skills/scip-audit/references/cleanup.md +19 -20
  302. package/skills/scip-audit/references/directory.md +4 -4
  303. package/skills/scip-audit/references/frontend.md +10 -10
  304. package/skills/scip-audit/references/twin-drift.md +2 -2
  305. package/skills/scip-diagnose/references/debug.md +8 -8
  306. package/skills/scip-diagnose/references/root-cause.md +3 -3
  307. package/skills/scip-diagnose/references/triage.md +10 -10
  308. package/skills/scip-explore/SKILL.md +4 -4
  309. package/skills/scip-improve/SKILL.md +10 -10
  310. package/skills/scip-improve/references/cleanup-batches.md +3 -3
  311. package/skills/scip-improve/references/directory-moves.md +3 -3
  312. package/skills/scip-improve/references/doc-reconcile.md +1 -1
  313. package/skills/scip-improve/references/frontend-extraction.md +2 -2
  314. package/skills/scip-improve/references/twin-drift.md +3 -3
  315. package/skills/scip-plan/SKILL.md +3 -3
  316. package/skills/scip-plan/references/api-impact.md +5 -5
  317. package/skills/scip-plan/references/conductor.md +2 -2
  318. package/skills/scip-plan/references/hyper-optimization.md +1 -1
  319. package/skills/scip-query/SKILL.md +15 -5
  320. package/skills/scip-setup/references/bootstrap-workflow.md +7 -8
  321. package/skills/scip-setup/references/language-verification.md +2 -2
  322. package/skills/scip-setup/references/per-repo-triage.md +1 -1
  323. package/skills/scip-verify/SKILL.md +16 -11
  324. package/skills/scip-verify/references/calibrate-detectors.md +7 -7
  325. package/dist/chunk-24QNP7MN.js +0 -2
  326. package/dist/chunk-26X7KCJR.js +0 -5
  327. package/dist/chunk-273W2U4Y.js +0 -40
  328. package/dist/chunk-2OXVAGGT.js +0 -3
  329. package/dist/chunk-2ZOCHAL2.js +0 -8
  330. package/dist/chunk-35SQLYCQ.js +0 -2
  331. package/dist/chunk-4CGVLUDP.js +0 -18
  332. package/dist/chunk-4RI4BJGT.js +0 -8
  333. package/dist/chunk-52HQTTPB.js +0 -2
  334. package/dist/chunk-64MNV6AB.js +0 -8
  335. package/dist/chunk-7E3TH5ZN.js +0 -33
  336. package/dist/chunk-7Q6VYYCH.js +0 -2
  337. package/dist/chunk-A63U2W3P.js +0 -3
  338. package/dist/chunk-ADFSIJP2.js +0 -16
  339. package/dist/chunk-AOLE4DYM.js +0 -6
  340. package/dist/chunk-APMMR5Y2.js +0 -2
  341. package/dist/chunk-B5MHCHP3.js +0 -107
  342. package/dist/chunk-DGAGY7RJ.js +0 -60
  343. package/dist/chunk-DGMCFMPG.js +0 -11
  344. package/dist/chunk-E2ZXPB7J.js +0 -38
  345. package/dist/chunk-FKGN4A4E.js +0 -61
  346. package/dist/chunk-G4UQL4CP.js +0 -2
  347. package/dist/chunk-GA64UPMI.js +0 -6
  348. package/dist/chunk-HEBAY673.js +0 -2
  349. package/dist/chunk-HELS7KFF.js +0 -2
  350. package/dist/chunk-IPDCSB6N.js +0 -6
  351. package/dist/chunk-JERWGHQT.js +0 -16
  352. package/dist/chunk-JJJCO4QC.js +0 -945
  353. package/dist/chunk-JZNLMHWY.js +0 -56
  354. package/dist/chunk-K42M2KWT.js +0 -2
  355. package/dist/chunk-KP4KBDVF.js +0 -3
  356. package/dist/chunk-LRTP3DKL.js +0 -3
  357. package/dist/chunk-N3SE646F.js +0 -2
  358. package/dist/chunk-NN4ZIRPK.js +0 -8
  359. package/dist/chunk-P6HBYNBE.js +0 -5
  360. package/dist/chunk-QHKUY4FW.js +0 -2
  361. package/dist/chunk-QHRL4LKM.js +0 -2
  362. package/dist/chunk-SHKZ7OVJ.js +0 -35
  363. package/dist/chunk-TFUU5MQQ.js +0 -2
  364. package/dist/chunk-UXP636P5.js +0 -144
  365. package/dist/chunk-VEVBIAOJ.js +0 -16
  366. package/dist/chunk-VKRQDBW5.js +0 -9
  367. package/dist/chunk-VOQFGC2W.js +0 -67
  368. package/dist/chunk-WMXRRBII.js +0 -8
  369. package/dist/chunk-X3NLZHPA.js +0 -20
  370. package/dist/chunk-XF3KLXN3.js +0 -11
  371. package/dist/chunk-YCPASUCX.js +0 -2
  372. package/dist/chunk-YLVE3SXZ.js +0 -20
  373. package/dist/chunk-Z2LHPIOM.js +0 -2
  374. package/dist/chunk-Z5QQPJ3U.js +0 -30
  375. package/dist/chunk-ZTTISZ7J.js +0 -112
  376. package/dist/command-descriptors-SJDZ7QGR.js +0 -617
  377. package/dist/direct-navigation-HTKOZEOM.js +0 -3
@@ -15,10 +15,12 @@ directory entry survive power loss.
15
15
 
16
16
  A **crash-durable replacement** is a visibility-atomic replacement that also
17
17
  flushes the complete staging file before rename and flushes the containing
18
- directory after rename. Those ordered flushes are what make acknowledged file
19
- contents and the name that reaches them recoverable after an operating-system
20
- or machine crash, subject to the host filesystem and device honoring their
21
- flush contract.
18
+ directory after rename. When the writer creates a missing directory path, it
19
+ also creates each component from the nearest existing ancestor outward and
20
+ flushes the directory that names each new component. Those ordered flushes are
21
+ what make acknowledged file contents and the complete path that reaches them
22
+ recoverable after an operating-system or machine crash, subject to the host
23
+ filesystem and device honoring their flush contract.
22
24
 
23
25
  An **authoritative record** is file-backed state whose loss can change which
24
26
  generation, owner, policy, or accepted decision the program treats as current.
@@ -35,16 +37,28 @@ from a filename to its file—after the file itself has been flushed. Flushing
35
37
  only file contents is insufficient because a crash can otherwise lose the
36
38
  rename that made those contents current.
37
39
 
40
+ An **achieved durability result** is the guarantee established by the
41
+ operations that actually completed, not the guarantee the caller requested.
42
+ `visibility` means only old-or-new complete process visibility;
43
+ `file-flushed` means the final file bytes were flushed but at least one
44
+ directory namespace could not be synchronized; and `directory-durable` means
45
+ the file plus every newly created ancestor and final directory entry crossed
46
+ the supported persistence frontier.
47
+
38
48
  ## APIs
39
49
 
40
- | API | Staging identity | File flush | Rename | Parent-directory flush |
41
- | --- | --- | --- | --- | --- |
42
- | `writeJsonAtomic` / `replaceFileAtomic(..., { durability: "visibility" })` | Exclusive random token | No | Yes | No |
43
- | `writeJsonDurable` / `replaceFileAtomic(..., { durability: "durable" })` | Exclusive random token | Yes | Yes | Yes where supported |
50
+ | API | Staging identity | File flush | Rename/link | New-ancestor flush | Final-directory flush |
51
+ | -------------------------------------------------------------------------- | ----------------------------------------------- | --------------------- | --------------------------------- | ------------------- | --------------------- |
52
+ | `writeJsonAtomic` / `replaceFileAtomic(..., { durability: "visibility" })` | Exclusive random token | No | Yes | No | No |
53
+ | `writeJsonDurable` / `replaceFileAtomic(..., { durability: "durable" })` | Exclusive random token | Yes | Yes | Yes where supported | Yes where supported |
54
+ | `createFileAtomicExclusive(..., { durability: "durable" })` | Exclusive random token | Yes | Exclusive hard link | Yes where supported | Yes where supported |
55
+ | `cloneFileDurable` | Final target inside an unpublished staging tree | Yes, after final mode | Caller publishes the staging tree | Yes where supported | Yes where supported |
44
56
 
45
57
  `writeJsonAtomic` retains its original `void` return contract for compatibility.
46
- `writeJsonDurable` and `replaceFileAtomic` return the achieved directory-sync
47
- status. Verified binary installation owns an equivalent platform-local
58
+ `writeJsonDurable`, `replaceFileAtomic`, and `createFileAtomicExclusive`
59
+ return `requestedDurability`, `achievedDurability`, and `directorySync`.
60
+ Callers must use the achieved fields when logging or forwarding a durability
61
+ claim. Verified binary installation owns an equivalent platform-local
48
62
  flush/rename sequence because the enforced architecture forbids dependencies
49
63
  between the sibling `platform` and `storage` boundaries.
50
64
 
@@ -53,18 +67,25 @@ Known Windows "directory handles unsupported" errors produce
53
67
  `directorySync: "unsupported"` after the staged file itself has been flushed
54
68
  and renamed. That result means complete visibility plus flushed file contents,
55
69
  not the full POSIX directory-entry durability guarantee. Other directory-sync
56
- errors remain failures.
70
+ errors remain failures. An API that returns only a path or value makes no
71
+ machine-crash claim; protocol APIs that acknowledge work expose the achieved
72
+ result explicitly.
57
73
 
58
74
  ## Failure Outcomes
59
75
 
60
- | Failure point | Target visible after return/throw | Owned staging file |
61
- | --- | --- | --- |
62
- | Exclusive create | Previous target | No owned file was created |
63
- | Write or short/invalid progress | Previous target | Closed and removed |
64
- | File flush | Previous target | Closed and removed |
65
- | Rename | Previous target | Removed by the writer |
66
- | POSIX directory flush | New complete target; durability unconfirmed and the call throws | Already renamed; no staging path |
67
- | Unsupported Windows directory flush | New complete target; result reports the limitation | Already renamed; no staging path |
76
+ | Failure point | Target visible after return/throw | Owned staging file |
77
+ | ----------------------------------- | --------------------------------------------------------------- | -------------------------------- |
78
+ | Exclusive create | Previous target | No owned file was created |
79
+ | Write or short/invalid progress | Previous target | Closed and removed |
80
+ | File flush | Previous target | Closed and removed |
81
+ | Rename | Previous target | Removed by the writer |
82
+ | POSIX directory flush | New complete target; durability unconfirmed and the call throws | Already renamed; no staging path |
83
+ | Unsupported Windows directory flush | New complete target; result reports the limitation | Already renamed; no staging path |
84
+
85
+ When a parent chain is new, a failure while creating or flushing any ancestor
86
+ also throws before a durable result is returned. The incomplete path can be
87
+ visible to the running process, but recovery may discard every component that
88
+ has not yet been named by a flushed parent.
68
89
 
69
90
  The post-rename failure row is deliberately explicit. Once rename succeeds,
70
91
  rolling back would be another publication with its own crash window. The
@@ -73,25 +94,28 @@ could not confirm the stronger durability guarantee.
73
94
 
74
95
  ## Call-Site Classification
75
96
 
76
- | Record | Contract | Reason |
77
- | --- | --- | --- |
78
- | Reindex `meta.json` | Durable | Names the accepted index status, fingerprint, and generation metadata |
79
- | SQLite generation manifest and `state.json` | Durable | Flushes one complete immutable artifact set, then atomically selects it for new readers |
80
- | Shared-generation manifest | Durable file within staging | Authenticates immutable artifacts; the later generation-directory publication remains a separate generation-store operation |
81
- | Worktree lease and local cache pointer | Durable | Protect generations from collection and bind a worktree to repository cache identity; generation changes, liveness touches, and cleanup serialize through the repository-cache lock |
82
- | Watch service state | Durable | Publishes the process instance and index generation accepted as current |
83
- | Rust semantic session `server.json` | Durable | Publishes the live server process and mailbox identity |
84
- | Project `.scipquery.json` | Durable | Controls indexing, watch, architecture, and detector policy; versioned reads reject unsupported meaning before use, and authorized writes migrate legacy bytes without dropping unknown fields |
85
- | Codex/Claude hook JSON | Durable | Controls whether and when agent hooks execute |
86
- | Structured suppression file | Durable | Records an accepted finding and its reason |
87
- | Health baseline | Durable | Acts as a committed regression policy |
88
- | Verified binary cache promotion | Durable | Makes checksum-accepted executable or tool bytes current |
89
- | TypeScript/Rust request and response mailboxes | Visibility-atomic | A timeout or retry reconstructs the ephemeral message |
90
- | Watch activity | Visibility-atomic | A newer timestamp supersedes an older idle-lifetime observation; it carries no durable intent |
91
- | Watch refresh request, claim, and completion records | Durable immutable admission and acknowledgement | Accepted intent survives activity replacement and owner crashes; exclusive claims may be recovered only by the next lock owner |
92
- | TypeScript fragment/overlay manifests | Visibility-atomic | Content-addressed cache artifacts are validated and rebuildable |
93
- | Repository GC state | Visibility-atomic | Sweep history can be reconstructed conservatively |
94
- | Affected-set shadow latest record | Visibility-atomic | Calibration telemetry does not control publication |
97
+ | Record | Contract | Reason |
98
+ | ---------------------------------------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
99
+ | Reindex `meta.json` | Durable | Names the accepted index status, fingerprint, and generation metadata |
100
+ | SQLite generation manifest and `state.json` | Directory-durable where supported | Durably establishes the generation root, flushes final read-only artifact bytes and metadata, publishes the immutable directory, then selects it for new readers |
101
+ | Shared generation | Directory-durable where supported | Flushes every read-only artifact and manifest, the staging namespace, the final generation rename, and the shared `generations/` namespace |
102
+ | Worktree lease and local cache pointer | Durable | Protect generations from collection and bind a worktree to repository cache identity; generation changes, liveness touches, and cleanup serialize through the repository-cache lock |
103
+ | Watch service state | Durable | Publishes the process instance and index generation accepted as current |
104
+ | Rust semantic session `server.json` | Durable | Publishes the live server process and mailbox identity |
105
+ | Project `.scipquery.json` | Durable | Controls indexing, watch, architecture, and detector policy; versioned reads reject unsupported meaning before use, and authorized writes migrate legacy bytes without dropping unknown fields |
106
+ | Codex/Claude hook JSON | Durable | Controls whether and when agent hooks execute |
107
+ | Structured suppression file | Durable | Records an accepted finding and its reason |
108
+ | Health baseline | Durable | Acts as a committed regression policy |
109
+ | Verified binary cache promotion | Durable | Makes checksum-accepted executable or tool bytes current |
110
+ | TypeScript/Rust request and response mailboxes | Directory-durable where supported | Admission is acknowledged only after the pending name is flushed; a new owner directory is durably named before a request moves from pending to inflight; responses precede claim release |
111
+ | Watch activity | Visibility-atomic | A newer timestamp supersedes an older idle-lifetime observation; it carries no durable intent |
112
+ | Watch refresh request, claim, and completion records | Durable immutable admission and acknowledgement | Accepted intent survives activity replacement and owner crashes; exclusive claims may be recovered only by the next lock owner |
113
+ | Cache ownership credential | Directory-durable where supported | A complete file is flushed privately, hardening is revalidated, the public credential is linked exclusively, and its directory is flushed before detailed publication success |
114
+ | npm release state | Directory-durable where supported; file-flushed on bounded hosts | The registry is freshly reconciled and remains external authority; the local coordinate-pair recovery record reports its exact achieved guarantee |
115
+ | Outcome event | File publication locally; repository-durable only after Git commit | The event becomes shared history through the committed repository record, not merely because a checkout-local file exists |
116
+ | TypeScript fragment/overlay manifests | Visibility-atomic | Content-addressed cache artifacts are validated and rebuildable |
117
+ | Repository GC state | Visibility-atomic | Sweep history can be reconstructed conservatively |
118
+ | Affected-set shadow latest record | Visibility-atomic | Calibration telemetry does not control publication |
95
119
 
96
120
  Process locks use exclusive descriptor creation rather than replacement. Their
97
121
  durable token ownership, malformed-creation grace, guarded recovery, and
@@ -101,3 +125,29 @@ stable compatibility mirrors, and their crash ordering are defined in
101
125
  [Local Index Generations](INDEX_GENERATIONS.md). Durable watch demand,
102
126
  idempotency, claim recovery, and acknowledgement ordering are defined in
103
127
  [Watch Refresh Requests](WATCH_REFRESH_REQUESTS.md).
128
+
129
+ ## Executable crash model
130
+
131
+ `tests/helpers/persistence-frontier.ts` models the two states a normal
132
+ filesystem test otherwise conflates. Writes, links, renames, and removals first
133
+ change process-visible state. File synchronization advances persisted inode
134
+ bytes and mode; directory synchronization advances persisted names. A modeled
135
+ power loss discards everything beyond those frontiers.
136
+
137
+ `tests/storage/atomic-file-crash.test.ts` replays replacement, exclusive
138
+ publication, new ancestor creation, and durable artifact cloning after every
139
+ relevant phase. Boundary-specific tests then hold the higher-level protocol
140
+ order:
141
+
142
+ - local generation stage and same-size corruption tests;
143
+ - shared-generation artifact, manifest, staging, rename, and final-directory
144
+ stage tests;
145
+ - watch admission, claim, completion, and retry tests;
146
+ - mailbox owner-directory, claim-transfer, response, and recovery tests;
147
+ - ownership short-write, unsupported-sync, and failed-sync tests; and
148
+ - release-state synchronized, unsupported, and failed-write tests.
149
+
150
+ The deterministic model proves the filesystem primitive’s persisted-state
151
+ semantics. The boundary tests prove each protocol invokes those primitives in
152
+ the required order. Neither an exception callback alone nor a successful live
153
+ filesystem read is described as a simulated power loss.
@@ -23,6 +23,10 @@ The worktree cache keeps this internal layout:
23
23
  meta.json compatibility mirror
24
24
  .scipquery-generations/
25
25
  state.json atomic current-generation pointer
26
+ gc.json last bounded-collection observation
27
+ gc.lock collection/reader-admission coordinator
28
+ readers/
29
+ <pid>-<token>.json live process-generation leases
26
30
  <generation-sha256>/
27
31
  manifest.json
28
32
  index.db
@@ -30,11 +34,19 @@ The worktree cache keeps this internal layout:
30
34
  meta.json
31
35
  ```
32
36
 
33
- The files inside a named generation directory are immutable. The SHA-256
37
+ The files inside a named generation directory are immutable. Their final
38
+ read-only mode is applied before their final file synchronization, so the
39
+ persisted inode contains both the accepted bytes and the protection metadata.
40
+ The SHA-256
34
41
  identity incorporates the database bytes, SCIP bytes when present, and the
35
42
  generation-bearing metadata fields. `manifest.json` records the exact size and
36
43
  digest of each stored artifact. `state.json` names the accepted directory and
37
44
  is the only publication decision read by internal database consumers.
45
+ Opening a named generation authenticates the database, SCIP, and metadata
46
+ bytes against those digests; matching size alone is never sufficient. A
47
+ bounded process-local validation cache is keyed by manifest identity plus
48
+ stable device, inode, size, modification-time, and change-time evidence, so a
49
+ same-size mutation invalidates the cached proof and is rehashed.
38
50
 
39
51
  The top-level files remain for the SCIP CLI, indexers, older scip-query
40
52
  versions, and external inspection. They are derived mirrors, not the internal
@@ -48,18 +60,26 @@ Publication proceeds in this order:
48
60
 
49
61
  1. Retain the previously published stable artifacts as an immutable
50
62
  generation when upgrading a legacy cache.
51
- 2. Copy-on-write clone or copy every accepted candidate artifact into a
52
- private staging directory.
53
- 3. Flush the artifact files and manifest, rename the complete staging
54
- directory into its content-derived identity, and flush the generation
63
+ 2. Durably establish `.scipquery-generations/` from its nearest existing
64
+ ancestor when this is the cache's first generation.
65
+ 3. Copy-on-write clone or copy every accepted candidate artifact into a
66
+ private staging directory, apply its final read-only mode, and flush the
67
+ resulting inode.
68
+ 4. Flush the manifest and staging namespace, rename the complete staging
69
+ directory into its content-derived identity, and flush the generation-root
55
70
  directory entry.
56
- 4. Durably replace `state.json` so new internal readers select the complete
71
+ 5. Establish the versioned query layout after augmentation: add the
72
+ definition-only covering index, remove known redundant indexes only when
73
+ schema inspection proves a retained equivalent, and run `ANALYZE` so the
74
+ planner sees the final row distribution. Query-plan tests hold those
75
+ proofs.
76
+ 6. Durably replace `state.json` so new internal readers select the complete
57
77
  new directory.
58
- 5. Replace the three compatibility mirrors and durably record their file
78
+ 7. Replace the three compatibility mirrors and durably record their file
59
79
  identities for drift diagnostics.
60
80
 
61
- A crash before step 4 leaves the prior pointer authoritative. A crash after
62
- step 4 leaves the new immutable generation authoritative even if one or more
81
+ A crash before step 6 leaves the prior pointer authoritative. A crash after
82
+ the pointer step leaves the new immutable generation authoritative even if one or more
63
83
  compatibility mirrors are old. `scip-query status` and freshness inspection
64
84
  report that mirror drift and a later refresh repairs it; database-backed
65
85
  queries remain generation-consistent throughout.
@@ -70,6 +90,14 @@ and TypeScript semantic mailbox requests carry the handle identity, so a
70
90
  continuation or numeric symbol identifier from an older generation is rejected
71
91
  when a service has moved to a newer one.
72
92
 
93
+ Current metadata also records `sqliteLayoutVersion`. A current-version
94
+ metadata record that predates this field remains readable and can reuse its
95
+ language SCIP shards, but it cannot take the whole-SQLite unchanged fast path.
96
+ The next refresh applies query-layout maintenance to the stable mirror,
97
+ publishes a new immutable generation and current layout metadata, and does not
98
+ rerun unchanged language indexers. Later unchanged refreshes resume the
99
+ ordinary whole-generation reuse path.
100
+
73
101
  Mailbox protocol version 3 additionally binds that generation identity into a
74
102
  content-derived logical-operation key. The deterministic request ID lets a
75
103
  retry join an already pending, inflight, or retained completed operation,
@@ -86,18 +114,36 @@ generation implementation, which did not name an immutable artifact set, also
86
114
  uses this compatibility path. New publications upgrade either layout without
87
115
  deleting the stable files.
88
116
 
89
- Published local generation directories are retained conservatively. Automatic
90
- collection is intentionally disabled until a cross-process reader lease can
91
- prove that no surviving handle can later need the retained SCIP companion.
92
- This can temporarily consume more cache space, but it preserves the stronger
93
- rule that storage reclamation may never change or remove evidence owned by a
94
- live query.
117
+ Published local generation directories are retained by a bounded,
118
+ reader-aware collector. Opening an immutable `ScipDatabase` first acquires the
119
+ generation GC lock, resolves the current pointer, and visibility-atomically
120
+ publishes a lease containing its random token, generation identity, PID, and
121
+ operating-system process-start identity when available. Closing the database
122
+ removes that exact lease idempotently.
123
+
124
+ Publication and collection use the same token-owned process lock. Collection
125
+ always protects the current generation, the named recovery generation, and
126
+ every live reader generation. It removes only oldest unprotected generations
127
+ until both default limits hold: at most eight retained generations and at most
128
+ 2 GiB of logical artifact bytes. A lease whose recorded process instance is
129
+ provably dead is reclaimed. A malformed lease protects every generation and
130
+ defers deletion; uncertainty cannot authorize reclamation.
131
+
132
+ `gc.json` is a visibility-atomic diagnostic containing retained counts, logical
133
+ bytes, protected/readers counts, removed counts, limits, state, time, and any
134
+ reason. `scip-query status` reports that observation together with the current
135
+ retained set and oldest generation age. Collection failure does not invalidate
136
+ the accepted index; it remains explicit bounded-storage debt for the operator.
95
137
 
96
138
  The repository-wide shared generation store is a separate cache layer. It
97
- warms a worktree by copying a complete generation into the worktree's private
98
- cache; the local publisher then creates the local immutable directory and
99
- pointer described here. Later worktree writes cannot mutate either the shared
100
- source or a retained local reader.
139
+ warms a worktree from a complete content-addressed generation. Publication
140
+ flushes each final read-only artifact, the manifest, the staging namespace, the
141
+ rename into `generations/<identity>`, and `generations/` itself before
142
+ returning `directory-durable` on supported hosts. On a host without directory
143
+ sync, it returns `file-flushed`; readers still rehash every artifact and reject
144
+ an incomplete generation. The local publisher then creates the private
145
+ immutable directory and pointer described here. Later worktree writes cannot
146
+ mutate either the shared source or a retained local reader.
101
147
 
102
148
  ## Shared worktree lease invariant
103
149
 
@@ -122,7 +122,12 @@ boundaries.
122
122
  A claim is a time-bounded service ownership record made real by renaming one
123
123
  pending file into an owner-specific inflight directory. Rename is the
124
124
  ownership compare-and-set: only the process whose rename succeeds owns that
125
- file. The directory's owner record binds the random owner ID to a PID and,
125
+ file. Before a first claim can remove the pending name, the service durably
126
+ establishes the fixed mailbox skeleton, creates the owner directory, and
127
+ flushes `inflight/` so the complete destination path survives. It then writes
128
+ the owner record, renames the request, flushes the source directory, and
129
+ flushes the owner directory in that order. The directory's owner record binds
130
+ the random owner ID to a PID and,
126
131
  when the operating system exposes it, a process-start identity. A process-start
127
132
  identity is the operating-system fact that distinguishes successive
128
133
  executions occupying the same numeric PID slot.
@@ -147,6 +152,14 @@ answer-affecting operations are read-only or rebuildable, the response
147
152
  identity is stable, and exclusive completion remains a final defense against
148
153
  two observable answers.
149
154
 
155
+ Accepted admission and successful claims expose the achieved directory-sync
156
+ result. On POSIX hosts that complete every directory flush this is
157
+ `directory-durable`. When Node reports directory handles unsupported on
158
+ Windows, it is `file-flushed`: complete file bytes and process-crash recovery
159
+ remain, but the protocol does not upgrade that bounded result into a
160
+ machine-crash namespace claim. Any other directory synchronization error
161
+ throws instead of acknowledging the transition.
162
+
150
163
  ## Fairness and maintenance
151
164
 
152
165
  Pending work is ordered by `enqueuedAtMs`, then stable request identity.
@@ -158,6 +171,19 @@ at most 64 removals or reclaims. Those caps are what let the watch and Rust
158
171
  server loops regain control to update heartbeats, observe stop signals, and
159
172
  run unrelated maintenance even when a mailbox was flooded.
160
173
 
174
+ The TypeScript watch service initializes its two mailbox layouts once after
175
+ acquiring service ownership. An empty poll reads the already-established
176
+ directories; it does not recreate or chmod the full layout. Consecutive empty
177
+ polls back off from 50 ms through 100 ms and 200 ms to a 250 ms ceiling. A poll
178
+ that processes work returns to a 10 ms drain interval. The Rust service uses
179
+ the same 10–250 ms adaptive range.
180
+
181
+ Deadline authority is re-evaluated per claimed request. A service reads its
182
+ clock immediately before starting each handler and again after the handler
183
+ returns. Therefore a request that expires while an earlier request runs is
184
+ rejected before execution, and an answer completed after its authoritative
185
+ deadline is not published as success.
186
+
161
187
  Maintenance:
162
188
 
163
189
  - reclaims expired inflight ownership only after the recorded process instance
@@ -190,6 +216,7 @@ window. Clock-domain rules for these records are documented in
190
216
  Focused contract coverage lives in:
191
217
 
192
218
  - `tests/storage/bounded-mailbox.test.ts`;
219
+ - `tests/storage/atomic-file-crash.test.ts`;
193
220
  - `tests/semantic/typescript/typescript-session-mailbox.test.ts`;
194
221
  - `tests/reindex/typescript-index-mailbox.test.ts`;
195
222
  - `tests/semantic/rust/durable-session-protocol.test.ts`;
@@ -7,7 +7,7 @@ record rather than an authority by itself: a consumer still verifies the
7
7
  database, SCIP companion, immutable-generation state, or current source
8
8
  fingerprint required by its operation.
9
9
 
10
- `src/domain/reindex-metadata.ts` is the dependency-free decoding boundary. It
10
+ `src/domain/reindex-metadata.ts` is the domain decoding boundary. It
11
11
  classifies an input as:
12
12
 
13
13
  - `legacy`: a structurally valid version 2 record;
@@ -38,12 +38,20 @@ Future records are never rewritten.
38
38
 
39
39
  Recognized versions validate `status`, optional timestamp,
40
40
  requested/indexed language sets, skipped-language rows, SCIP companion state,
41
- and v3 shard maps. A fingerprint is an opaque JSON identity for evidence and
42
- stable-generation compatibility, preserving the pre-decoder v2/v3 contract;
43
- freshness and publication additionally require it to be an object. Language
44
- lists contain unique names from the same
41
+ the optional positive `sqliteLayoutVersion`, and v3 shard maps. A fingerprint
42
+ is an opaque JSON identity for evidence and stable-generation compatibility,
43
+ preserving the pre-decoder v2/v3 contract; freshness and publication
44
+ additionally require it to be an object. Language lists contain unique names
45
+ from the same
45
46
  `SUPPORTED_LANGUAGES` catalog used by configuration.
46
47
 
48
+ The SQLite layout field is an additive v3 upgrade boundary rather than a wire
49
+ version migration. A v3 record without it remains queryable, evidence-usable,
50
+ and eligible for language-shard reuse. It is not eligible for whole-SQLite
51
+ unchanged reuse. The next refresh can therefore reuse unchanged language SCIP
52
+ shards, establish the current post-conversion indexes and planner statistics,
53
+ and publish a new generation without rerunning those indexers.
54
+
47
55
  ## Capability matrix
48
56
 
49
57
  A capability is a named permission to interpret a decoded record for one
@@ -62,14 +70,16 @@ the same version while intentionally requiring different completeness.
62
70
  Consumer-specific comparisons happen only after this matrix accepts the
63
71
  record:
64
72
 
65
- - freshness and unchanged-index reuse compare a publishable fingerprint and
66
- sorted indexed languages with current inputs;
73
+ - freshness compares a publishable fingerprint and sorted indexed languages
74
+ with current inputs; whole-SQLite unchanged reuse additionally requires the
75
+ current `sqliteLayoutVersion`;
67
76
  - shared-generation publication additionally verifies the immutable artifact
68
77
  set, project root, and database integrity;
69
78
  - evidence and TypeScript semantic cache keys accept complete or partial
70
79
  records and include status, so partial and complete results cannot collide;
71
80
  - SQLite and TypeScript service generation identities use the same canonical
72
- projection and reject records without stable-identity capability;
81
+ projection, including `sqliteLayoutVersion` when present, and reject records
82
+ without stable-identity capability;
73
83
  - per-language and per-project reuse compare the decoded v3 shard
74
84
  fingerprints with current fingerprints and require the corresponding shard
75
85
  file to exist.
@@ -0,0 +1,146 @@
1
+ # Security model
2
+
3
+ `scip-query` treats a checked-out repository and every index or cache artifact
4
+ derived from it as untrusted input. An untrusted checkout is a directory of
5
+ files supplied by a project rather than by the operator, distinguished from
6
+ ordinary input by being able to name source paths, tools, configuration, and
7
+ persisted records that the CLI may otherwise be tempted to trust.
8
+
9
+ The default analysis boundary may read repository files and managed,
10
+ rebuildable cache artifacts. It may not execute a repository-selected program,
11
+ adopt an arbitrary cache directory, escape the canonical project root through
12
+ an indexed path, or install a mutable tool identity merely because the
13
+ checkout requests it.
14
+
15
+ ## Explicit authority
16
+
17
+ An authority grant is an operator action that permits one otherwise-forbidden
18
+ effect, distinguished from project configuration by coming from the current
19
+ CLI invocation:
20
+
21
+ - `--trust-project-tools` permits reviewed repository-local indexer
22
+ executables for that invocation.
23
+ - `--tla-tools <jar>` selects a reviewed TLA jar explicitly. The default
24
+ downloaded TLA artifact remains version- and SHA-256-pinned.
25
+ - `--install-missing` permits installation of the exact immutable tool
26
+ identities listed by the command. Without it, missing tools produce setup
27
+ instructions instead of a mutation.
28
+ - environment overrides such as `SCIP_QUERY_CACHE_DIR` are operator-owned
29
+ storage choices. Tracked `.scipquery.json` cannot grant destructive authority
30
+ over an arbitrary external cache.
31
+
32
+ A managed cache is rebuildable local state rooted under a scip-query-owned
33
+ directory, distinguished from a caller-selected directory by an ownership
34
+ record and canonical containment checks. Destructive cache operations require
35
+ both properties.
36
+
37
+ ## Input budgets
38
+
39
+ An input budget is a maximum amount of untrusted data one operation will
40
+ materialize or ask a parser to compile, distinguished from silent truncation by
41
+ failing explicitly with the input kind, observed amount, and accepted limit.
42
+
43
+ | Input class | Limit | Representative users |
44
+ | ------------------------------------------------------ | -----------------------: | ------------------------------------------------------------------------ |
45
+ | Config, manifest, lock, lease, and other small records | 8 MiB | `.scipquery.json`, package manifests, generation metadata, hook settings |
46
+ | One source or per-document fragment | 64 MiB | indexed source reads, TypeScript/Vue snapshots, mailbox result payloads |
47
+ | One SCIP index artifact | 512 MiB | merge, sanitize, Rust occurrence fallback, shared-generation hydration |
48
+ | Profile or retained JSONL artifact | 256 MiB | profiling audits, legacy event ledgers, rotating diagnostic segments |
49
+ | Generated TLA trace | 16 MiB and 100,000 steps | `tla instrument` recorder |
50
+ | Repository-supplied regular-expression pattern | 4,096 characters | entry-root patterns and TLA statement bindings |
51
+ | Agent hook standard input | 8 MiB | stop-hook request payload |
52
+
53
+ Regular files are opened first, checked through that descriptor, read, and
54
+ checked again so replacement or growth cannot bypass the pre-read limit.
55
+ Streams and pseudo-files are counted while reading. Large file fingerprints
56
+ are computed in fixed-size chunks rather than by retaining the complete file.
57
+
58
+ An oversized artifact is not partially interpreted. Operations that require
59
+ the complete artifact fail and name the limit; query-level detectors that
60
+ intentionally sample or cap logical rows retain their existing machine-readable
61
+ coverage metadata and `--full` remediation.
62
+
63
+ ## Complete command output
64
+
65
+ Output pagination is a resumable transport for one rendered command result,
66
+ distinguished from a result limit by preserving every rendered character.
67
+ Human output above 12,000 characters automatically includes the exact command
68
+ for the next page. Large default JSON remains byte-compatible and writes the
69
+ exact opt-in paging command to stderr before and after the JSON stream.
70
+
71
+ Every command accepts:
72
+
73
+ ```text
74
+ --output-page-size <characters>
75
+ --output-cursor <cursor>
76
+ ```
77
+
78
+ The opaque cursor binds the command, working directory, non-pagination
79
+ arguments, immutable page number and size, private output snapshot, and
80
+ complete output hash. The first invocation records UTF-8 byte ranges and a
81
+ hash for each page while retaining only one page in memory. A continuation
82
+ reads and verifies only its own range instead of re-running the command or
83
+ rescanning the complete output.
84
+
85
+ One snapshot is limited to 32 million rendered characters, 64 MiB, and 32,768
86
+ pages. The current user's snapshot pool is limited to 32 snapshots and 256 MiB
87
+ under a process-identity-aware lock. Abandoned writers are reclaimed without
88
+ removing a live writer; complete snapshots expire after one hour and are
89
+ removed after their final page.
90
+
91
+ Run commands normally without selecting a page size. If human output is
92
+ oversized, the readable multiline page prints one `Continue exactly:` command;
93
+ run it unchanged until the transport-complete marker. That marker proves every
94
+ rendered character was retrieved; command coverage remains a separate claim.
95
+ Explicit paged `--json`
96
+ returns the versioned object envelope and must be followed until
97
+ `page.complete` is `true`. Do not pipe output through `head`, `tail`, or a
98
+ line-range `sed`; those programs discard data without creating a resumable
99
+ position. See [CLI JSON output](CLI_JSON_OUTPUT.md) and the [output-page
100
+ schema](schemas/cli-output-page.schema.json).
101
+
102
+ ## Diff-gate process containment
103
+
104
+ A diff-gate lease is one live process identity permitted to evaluate a
105
+ project's current diff, distinguished from an ordinary lock file by recording
106
+ and validating the owner's PID, process start, and project identity. CLI and
107
+ Stop-hook gates share this lease, so an overlapping request reports the live
108
+ owner instead of multiplying detector work.
109
+
110
+ The public gate owns an isolated child process. Its default deadline is 60
111
+ seconds, or 180 seconds with `--full`. On timeout, failure, or interruption the
112
+ parent terminates and reaps that child before releasing the lease. An operator
113
+ may set `SCIP_QUERY_DIFF_GATE_TIMEOUT_MS` to a positive millisecond value; the
114
+ runtime caps it at 10 minutes.
115
+
116
+ The parent creates a unique, private progress path and one-run token while it
117
+ owns the lease. The child visibility-atomically records the current gate phase
118
+ and detector immediately before and after each detector. A timed-out parent
119
+ accepts only the record carrying its token, reports the active detector or
120
+ phase plus the last completed detector, and removes the record before releasing
121
+ the lease. The progress record is diagnostic evidence, not authority: failure
122
+ to write it cannot turn a passing gate into a failure, and a stale or malformed
123
+ record cannot alter the gate result.
124
+
125
+ Outcome reconciliation rechecks at most one historical comparison base per
126
+ gate. Deferred bases remain open and the result reports their exact base and
127
+ finding counts, so accumulated event history cannot silently multiply one
128
+ foreground gate into an unbounded replay batch.
129
+
130
+ ## Terminal and JSON output
131
+
132
+ Human terminal output is presentation text written to an interactive terminal,
133
+ distinguished from JSON by being able to activate terminal control sequences.
134
+ Repository-controlled human fields therefore have control bytes rendered
135
+ inert. JSON values retain their printable data and are protected by JSON
136
+ encoding rather than human-output rewriting.
137
+
138
+ Registry and release diagnostics redact URL user information and
139
+ credential-bearing query fields before rendering nested errors.
140
+
141
+ ## Reporting a security issue
142
+
143
+ Do not include a live credential, private repository, or destructive
144
+ proof-of-concept target in a public report. Describe the affected command,
145
+ platform, trust flags, and smallest disposable reproduction needed to
146
+ distinguish the boundary failure.
@@ -27,6 +27,11 @@ segments. That bounded-history deletion is different from concurrency loss:
27
27
  which segment is pruned is decided while the append/rotation lock excludes
28
28
  other writers.
29
29
 
30
+ The retained-set reader also has a 256 MiB byte budget across the files it
31
+ opens. It validates each segment as the same regular file before and after the
32
+ read. Exceeding that operational budget is an explicit read failure; it does
33
+ not silently return a prefix and present it as complete telemetry.
34
+
30
35
  ## Serialization and crash recovery
31
36
 
32
37
  The rotation lock is `<history>.rotation.lock`. It is a process-instance lock:
@@ -53,10 +58,17 @@ mailbox-response, and release records use their own durable protocols.
53
58
 
54
59
  Lock timeout and ownership-changed release are typed failures at the shared
55
60
  helper boundary. The reindex-activity and affected-shadow production writers
56
- remain best effort: they catch telemetry failure so an observation cannot
57
- change the authoritative reindex result. Callers that invoke the shared helper
58
- directly can distinguish lock timeout, count repaired tail bytes, and count
59
- partial bytes ignored during reads.
61
+ remain best effort: telemetry failure cannot change the authoritative reindex
62
+ result. A reindex-activity writer returns either `recorded` or `failed` with a
63
+ reason; reindex, foreground watch, and daemon watch surface that failure as a
64
+ warning or watch-state error rather than silently losing the observation.
65
+
66
+ A retained-set summary carries an activity-confidence state. `complete` means
67
+ every selected non-empty record decoded; `partial` means a valid subset was
68
+ used while exact invalid/skipped/read-error or incomplete-tail counts are
69
+ reported; `unavailable` means no reliable summary could be formed. The summary
70
+ also exposes records read and ignored partial-tail bytes, so consumers can
71
+ distinguish zero activity from missing evidence.
60
72
 
61
73
  The regression suite forces:
62
74