scip-query 0.10.6 → 0.10.7

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 (262) hide show
  1. package/README.md +6 -1
  2. package/dist/augment-vue-worker.js +1 -1
  3. package/dist/{chunk-CJJP64OC.js → chunk-27FU2KX7.js} +2 -2
  4. package/dist/chunk-3C4NIBY5.js +2 -0
  5. package/dist/chunk-3LQFMQPY.js +3 -0
  6. package/dist/{chunk-QVCCLDZI.js → chunk-5JXH6VGF.js} +2 -2
  7. package/dist/{chunk-77YBOOYT.js → chunk-5LM7RJMQ.js} +2 -2
  8. package/dist/{chunk-EWC3UK4V.js → chunk-5MHQI4RR.js} +2 -2
  9. package/dist/{chunk-X7ZY6FFF.js → chunk-72QDTW5U.js} +2 -2
  10. package/dist/{chunk-MZ7APUFN.js → chunk-733EF5FD.js} +2 -2
  11. package/dist/chunk-7AOMEMOA.js +4 -0
  12. package/dist/chunk-A536TEU4.js +3 -0
  13. package/dist/chunk-BZ2RRK7Y.js +8 -0
  14. package/dist/chunk-C6ROZBJA.js +32 -0
  15. package/dist/chunk-CMXD5VC4.js +2 -0
  16. package/dist/{chunk-BNKE4TT5.js → chunk-CQEJU32R.js} +2 -2
  17. package/dist/{chunk-5FOPAXWY.js → chunk-DBTL56LR.js} +2 -2
  18. package/dist/chunk-DOZ2X6TS.js +2 -0
  19. package/dist/{chunk-D322LMSA.js → chunk-DS6QEB3G.js} +5 -5
  20. package/dist/chunk-EOUTP32Q.js +4 -0
  21. package/dist/{chunk-QSXQT3NE.js → chunk-EPPCGQUI.js} +2 -2
  22. package/dist/{chunk-CSWZFD46.js → chunk-EW64FEJL.js} +2 -2
  23. package/dist/{chunk-O3OKSF6O.js → chunk-FG4NT6VY.js} +2 -2
  24. package/dist/chunk-FKYPOK7P.js +5 -0
  25. package/dist/chunk-FPYQA7JK.js +21 -0
  26. package/dist/{chunk-FIB4JPEX.js → chunk-FRIASDLG.js} +2 -2
  27. package/dist/chunk-FXI3AAKO.js +2 -0
  28. package/dist/{chunk-QUJBXLBY.js → chunk-FXWV2V7K.js} +2 -2
  29. package/dist/chunk-G2CGUNQU.js +4 -0
  30. package/dist/{chunk-LPLGJ4HO.js → chunk-GIOT3O6P.js} +2 -2
  31. package/dist/{chunk-YUTRW57I.js → chunk-GKRRO3WC.js} +2 -2
  32. package/dist/{chunk-Z4VHYJ5U.js → chunk-GOWLZ4NA.js} +2 -2
  33. package/dist/{chunk-4ZUJJRWT.js → chunk-GRZRMELG.js} +2 -2
  34. package/dist/{chunk-CFL2CNIF.js → chunk-H6RLM7D7.js} +2 -2
  35. package/dist/chunk-HDBQHJNY.js +2 -0
  36. package/dist/{chunk-AW4N6MGC.js → chunk-IA7Q6HVP.js} +2 -2
  37. package/dist/{chunk-E44ZMVNA.js → chunk-IL2EVPYP.js} +2 -2
  38. package/dist/{chunk-E7KERP7E.js → chunk-J43GIAVM.js} +2 -2
  39. package/dist/{chunk-56UN3DMK.js → chunk-JOGZKF5W.js} +2 -2
  40. package/dist/{chunk-CTCAF3YA.js → chunk-KT2ZO3CE.js} +2 -2
  41. package/dist/{chunk-DAI74TJU.js → chunk-KUIIQPDA.js} +2 -2
  42. package/dist/{chunk-VAA5FFIW.js → chunk-LM5SHAN4.js} +2 -2
  43. package/dist/chunk-LONIY5FF.js +2 -0
  44. package/dist/{chunk-FNRPGGVI.js → chunk-LQSLW7K7.js} +2 -2
  45. package/dist/{chunk-WBJZNPUT.js → chunk-M3YEHOCD.js} +2 -2
  46. package/dist/{chunk-GZCQTZLK.js → chunk-MFWAZFYD.js} +2 -2
  47. package/dist/{chunk-EYLXU575.js → chunk-MHATKJ3J.js} +2 -2
  48. package/dist/{chunk-ZQLO2SCU.js → chunk-MJXJ56LG.js} +2 -2
  49. package/dist/{chunk-47UA45TU.js → chunk-NIGHS7UP.js} +2 -2
  50. package/dist/{chunk-NVFERV4U.js → chunk-OFO7BIRK.js} +2 -2
  51. package/dist/{chunk-7OHWPJ5N.js → chunk-OMGE3V2Q.js} +2 -2
  52. package/dist/{chunk-ICXVNWMI.js → chunk-OT6CDRKC.js} +2 -2
  53. package/dist/{chunk-6UFMPECA.js → chunk-OWXN6ZS5.js} +2 -2
  54. package/dist/{chunk-QLNGUWR7.js → chunk-OZUJ3VZS.js} +2 -2
  55. package/dist/chunk-P3K7LX7M.js +4 -0
  56. package/dist/{chunk-ZSLT7NWQ.js → chunk-PQ6QG3EX.js} +2 -2
  57. package/dist/chunk-PTKQNPWX.js +23 -0
  58. package/dist/{chunk-YYD245WG.js → chunk-QMH2D6S5.js} +2 -2
  59. package/dist/{chunk-5M4TYWVI.js → chunk-QPTVFG4O.js} +2 -2
  60. package/dist/{chunk-MUULWXSJ.js → chunk-QR337MAA.js} +2 -2
  61. package/dist/{chunk-SPE4YCOT.js → chunk-QVS4SYAX.js} +2 -2
  62. package/dist/{chunk-AUVBR62P.js → chunk-RISLKTKQ.js} +2 -2
  63. package/dist/{chunk-OLD6PBU6.js → chunk-S7DNZ6IW.js} +2 -2
  64. package/dist/{chunk-EOZIZWW4.js → chunk-SXESPZUX.js} +2 -2
  65. package/dist/{chunk-TM6GVHA6.js → chunk-TDBTVMHY.js} +2 -2
  66. package/dist/{chunk-3UW7VM4H.js → chunk-TJXOD4IK.js} +2 -2
  67. package/dist/chunk-U73YFD3P.js +3 -0
  68. package/dist/{chunk-YUOAAR24.js → chunk-UBDFQBSE.js} +2 -2
  69. package/dist/chunk-UJEVABIR.js +2 -0
  70. package/dist/{chunk-5QJXH6ZL.js → chunk-VA3FJ3AY.js} +2 -2
  71. package/dist/{chunk-3KLLFNT4.js → chunk-VOYOYC5T.js} +2 -2
  72. package/dist/chunk-W2CBNBEL.js +71 -0
  73. package/dist/chunk-W2TIXAGN.js +40 -0
  74. package/dist/{chunk-CAWSSEVM.js → chunk-WMIQMXSK.js} +2 -2
  75. package/dist/{chunk-YQH353VA.js → chunk-WVRTGVHJ.js} +2 -2
  76. package/dist/{chunk-DJMK4DBL.js → chunk-WXMVK53S.js} +2 -2
  77. package/dist/{chunk-YTR4CO5S.js → chunk-XAYARHNF.js} +3 -3
  78. package/dist/{chunk-ESG4HBEF.js → chunk-XBIF45WK.js} +2 -2
  79. package/dist/{chunk-DE7MA6OD.js → chunk-XYI7XRZC.js} +2 -2
  80. package/dist/{chunk-7KCSELEV.js → chunk-YNLK3G63.js} +2 -2
  81. package/dist/{chunk-NNDYO2DX.js → chunk-YOCYR7KJ.js} +2 -2
  82. package/dist/chunk-YZA6PPZL.js +3 -0
  83. package/dist/{chunk-5UDFZC4D.js → chunk-ZUTV7DDX.js} +2 -2
  84. package/dist/cli.js +274 -237
  85. package/dist/{config-types-Bj4sh28g.d.ts → config-types-BDIWAYzr.d.ts} +13 -1
  86. package/dist/{db-CTarohbZ.d.ts → db-BAVwb4Pb.d.ts} +1 -1
  87. package/dist/{health-Bx0x1HAG.d.ts → health-B17sVFYf.d.ts} +6 -2
  88. package/dist/index.d.ts +3 -3
  89. package/dist/index.js +3 -3
  90. package/dist/queries/affected.d.ts +2 -2
  91. package/dist/queries/affected.js +1 -1
  92. package/dist/queries/bottlenecks.d.ts +2 -2
  93. package/dist/queries/bottlenecks.js +1 -1
  94. package/dist/queries/by-kind.d.ts +2 -2
  95. package/dist/queries/by-kind.js +1 -1
  96. package/dist/queries/call-graph.d.ts +2 -2
  97. package/dist/queries/call-graph.js +1 -1
  98. package/dist/queries/change-surface.d.ts +2 -2
  99. package/dist/queries/change-surface.js +1 -1
  100. package/dist/queries/cleanup-plan.d.ts +2 -2
  101. package/dist/queries/cleanup-plan.js +1 -1
  102. package/dist/queries/co-change.d.ts +2 -2
  103. package/dist/queries/co-change.js +1 -1
  104. package/dist/queries/code.d.ts +2 -2
  105. package/dist/queries/code.js +1 -1
  106. package/dist/queries/complexity-hotspots.d.ts +2 -2
  107. package/dist/queries/complexity-hotspots.js +1 -1
  108. package/dist/queries/complexity.d.ts +2 -2
  109. package/dist/queries/complexity.js +1 -1
  110. package/dist/queries/convergence.d.ts +2 -2
  111. package/dist/queries/convergence.js +1 -1
  112. package/dist/queries/coupling.d.ts +2 -2
  113. package/dist/queries/coupling.js +1 -1
  114. package/dist/queries/cycles.d.ts +2 -2
  115. package/dist/queries/cycles.js +1 -1
  116. package/dist/queries/dataflow.d.ts +2 -2
  117. package/dist/queries/dataflow.js +1 -1
  118. package/dist/queries/dead.d.ts +2 -2
  119. package/dist/queries/dead.js +1 -1
  120. package/dist/queries/deep-chains.d.ts +2 -2
  121. package/dist/queries/deep-chains.js +1 -1
  122. package/dist/queries/deps.d.ts +2 -2
  123. package/dist/queries/deps.js +1 -1
  124. package/dist/queries/diff-gate.d.ts +8 -5
  125. package/dist/queries/diff-gate.js +1 -1
  126. package/dist/queries/diff-impact.d.ts +7 -3
  127. package/dist/queries/diff-impact.js +1 -1
  128. package/dist/queries/doc-drift.d.ts +2 -2
  129. package/dist/queries/doc-drift.js +1 -1
  130. package/dist/queries/drift.d.ts +2 -2
  131. package/dist/queries/drift.js +1 -1
  132. package/dist/queries/extract-candidates.d.ts +2 -2
  133. package/dist/queries/extract-candidates.js +1 -1
  134. package/dist/queries/fan.d.ts +2 -2
  135. package/dist/queries/fan.js +1 -1
  136. package/dist/queries/files.d.ts +2 -2
  137. package/dist/queries/health.d.ts +3 -3
  138. package/dist/queries/health.js +1 -1
  139. package/dist/queries/hierarchy.d.ts +2 -2
  140. package/dist/queries/hierarchy.js +1 -1
  141. package/dist/queries/hotspots.d.ts +2 -2
  142. package/dist/queries/hotspots.js +1 -1
  143. package/dist/queries/imports.d.ts +2 -2
  144. package/dist/queries/imports.js +1 -1
  145. package/dist/queries/incomplete-migration.d.ts +5 -3
  146. package/dist/queries/incomplete-migration.js +1 -1
  147. package/dist/queries/index.d.ts +3 -3
  148. package/dist/queries/index.js +1 -1
  149. package/dist/queries/isolated.d.ts +2 -2
  150. package/dist/queries/isolated.js +1 -1
  151. package/dist/queries/locality-candidates.d.ts +2 -2
  152. package/dist/queries/locality-candidates.js +1 -1
  153. package/dist/queries/members.d.ts +2 -2
  154. package/dist/queries/members.js +1 -1
  155. package/dist/queries/methods.d.ts +2 -2
  156. package/dist/queries/methods.js +1 -1
  157. package/dist/queries/outline.d.ts +2 -2
  158. package/dist/queries/outline.js +1 -1
  159. package/dist/queries/passthrough-candidates.d.ts +2 -2
  160. package/dist/queries/passthrough-candidates.js +1 -1
  161. package/dist/queries/plan-context.d.ts +2 -2
  162. package/dist/queries/plan-context.js +1 -1
  163. package/dist/queries/react-component-duplicates.d.ts +2 -2
  164. package/dist/queries/react-component-duplicates.js +1 -1
  165. package/dist/queries/react-hook-candidates.d.ts +2 -2
  166. package/dist/queries/react-hook-candidates.js +1 -1
  167. package/dist/queries/react-large-component-pressure.d.ts +2 -2
  168. package/dist/queries/react-large-component-pressure.js +1 -1
  169. package/dist/queries/recent-duplicates.d.ts +2 -2
  170. package/dist/queries/recent-duplicates.js +1 -1
  171. package/dist/queries/redundant-reexports.d.ts +2 -2
  172. package/dist/queries/redundant-reexports.js +1 -1
  173. package/dist/queries/refs.d.ts +2 -2
  174. package/dist/queries/refs.js +1 -1
  175. package/dist/queries/self-audit.d.ts +2 -2
  176. package/dist/queries/self-audit.js +1 -1
  177. package/dist/queries/similar-chains.d.ts +2 -2
  178. package/dist/queries/similar-chains.js +1 -1
  179. package/dist/queries/similar-files.d.ts +2 -2
  180. package/dist/queries/similar-files.js +1 -1
  181. package/dist/queries/similar-signatures.d.ts +2 -2
  182. package/dist/queries/similar-signatures.js +1 -1
  183. package/dist/queries/similar.d.ts +5 -3
  184. package/dist/queries/similar.js +1 -1
  185. package/dist/queries/slice.d.ts +2 -2
  186. package/dist/queries/slice.js +1 -1
  187. package/dist/queries/stale-abstractions.d.ts +2 -2
  188. package/dist/queries/stale-abstractions.js +1 -1
  189. package/dist/queries/stats.d.ts +2 -2
  190. package/dist/queries/surface.d.ts +2 -2
  191. package/dist/queries/surface.js +1 -1
  192. package/dist/queries/symbols.d.ts +2 -2
  193. package/dist/queries/symbols.js +1 -1
  194. package/dist/queries/system.d.ts +2 -2
  195. package/dist/queries/system.js +1 -1
  196. package/dist/queries/trace.d.ts +2 -2
  197. package/dist/queries/trace.js +1 -1
  198. package/dist/queries/unused-imports.d.ts +2 -2
  199. package/dist/queries/unused-imports.js +1 -1
  200. package/dist/queries/unused-params.d.ts +2 -2
  201. package/dist/queries/unused-params.js +1 -1
  202. package/dist/queries/vue-component-duplicates.d.ts +2 -2
  203. package/dist/queries/vue-component-duplicates.js +1 -1
  204. package/dist/queries/vue-composable-candidates.d.ts +2 -2
  205. package/dist/queries/vue-composable-candidates.js +1 -1
  206. package/dist/queries/vue-large-view-pressure.d.ts +2 -2
  207. package/dist/queries/vue-large-view-pressure.js +1 -1
  208. package/dist/queries/wrapper-candidates.d.ts +2 -2
  209. package/dist/queries/wrapper-candidates.js +1 -1
  210. package/dist/reindex-worker.js +11 -11
  211. package/dist/reindex.d.ts +11 -2
  212. package/dist/reindex.js +22 -22
  213. package/dist/runtime.d.ts +17 -20
  214. package/dist/runtime.js +2 -2
  215. package/dist/scip-cli-CnK9Va4O.d.ts +56 -0
  216. package/docs/AGENT_GUIDE.md +1 -1
  217. package/docs/COMMAND_REFERENCE.md +3 -2
  218. package/docs/analyzer-inventory.md +2 -2
  219. package/docs/analyzer-validation-ledger.md +2 -2
  220. package/package.json +1 -1
  221. package/skills/concrete-plan/SKILL.md +2 -2
  222. package/skills/scip-adoption/SKILL.md +4 -2
  223. package/skills/scip-ai-cleanup/SKILL.md +1 -1
  224. package/skills/scip-api-impact/SKILL.md +6 -2
  225. package/skills/scip-debloat/SKILL.md +1 -1
  226. package/skills/scip-debug/SKILL.md +6 -2
  227. package/skills/scip-diagram/SKILL.md +3 -1
  228. package/skills/scip-directory-architecture/SKILL.md +7 -3
  229. package/skills/scip-doc-reconcile/SKILL.md +3 -1
  230. package/skills/scip-explore/SKILL.md +2 -2
  231. package/skills/scip-health-audit/SKILL.md +6 -2
  232. package/skills/scip-health-improve/SKILL.md +6 -2
  233. package/skills/scip-maintainability/SKILL.md +6 -3
  234. package/skills/scip-query/SKILL.md +10 -6
  235. package/skills/scip-query-setup/SKILL.md +10 -5
  236. package/skills/scip-react-maintainability/SKILL.md +7 -2
  237. package/skills/scip-triage-issue/SKILL.md +4 -2
  238. package/skills/scip-verify/SKILL.md +5 -3
  239. package/skills/scip-vue-maintainability/SKILL.md +7 -2
  240. package/dist/chunk-237YUOPK.js +0 -8
  241. package/dist/chunk-3UVJJ6Z7.js +0 -2
  242. package/dist/chunk-3ZYF3ELZ.js +0 -2
  243. package/dist/chunk-7JOTOWZO.js +0 -4
  244. package/dist/chunk-A3VNUGKJ.js +0 -2
  245. package/dist/chunk-A4L36SZS.js +0 -22
  246. package/dist/chunk-A7RNHUJH.js +0 -20
  247. package/dist/chunk-AYYIZ4BA.js +0 -4
  248. package/dist/chunk-BKDXBJDQ.js +0 -2
  249. package/dist/chunk-C3MZZ2ZN.js +0 -2
  250. package/dist/chunk-CRU42NJU.js +0 -2
  251. package/dist/chunk-ERHOS6AW.js +0 -2
  252. package/dist/chunk-FOQHUKNZ.js +0 -4
  253. package/dist/chunk-FUPDW5AC.js +0 -3
  254. package/dist/chunk-G3WGZU5Q.js +0 -2
  255. package/dist/chunk-HVTYSC26.js +0 -40
  256. package/dist/chunk-KPHKX4LP.js +0 -71
  257. package/dist/chunk-MA7OVFHI.js +0 -2
  258. package/dist/chunk-OBBDKQAG.js +0 -3
  259. package/dist/chunk-RHTJBYZ5.js +0 -2
  260. package/dist/chunk-UQJGTVHV.js +0 -5
  261. package/dist/chunk-ZFMPHDAT.js +0 -4
  262. package/dist/scip-cli-Bh1M_JPu.d.ts +0 -20
@@ -93,7 +93,7 @@ This syntax summary is generated from the CLI command descriptors. Keep workflow
93
93
  | `affected <symbol>` | Transitive closure of symbols that could break if this symbol changes | `--max-depth <n>`<br>`-s, --scope <path>`<br>`--json` |
94
94
  | `change-surface <file>` | Pre-change briefing: exports, consumers, and blast-radius risk | `--full`<br>`--json` |
95
95
  | `co-change [file]` | Files that change together in git history without a dependency edge — hidden coupling candidates | `--min-together <n>`<br>`-n, --limit <n>`<br>`--all`<br>`--full`<br>`--json` |
96
- | `diff-gate` | Gate the current diff: echo candidates, incomplete migrations, missing co-change partners, uncited doc updates, unused params, new dead symbols; exit 1 on findings | `--base <ref>`<br>`--min-together <n>`<br>`--max-echo-checks <n>`<br>`--max-helpers <n>`<br>`--skip <check>`<br>`--hook`<br>`--json` |
96
+ | `diff-gate` | Gate the current diff: echo candidates, incomplete migrations, missing co-change partners, uncited doc updates, unused params, new dead symbols; exit 1 on findings | `--base <ref>`<br>`--min-together <n>`<br>`--max-echo-checks <n>`<br>`--max-helpers <n>`<br>`--baseline`<br>`--full`<br>`--skip <check>`<br>`--hook`<br>`--json` |
97
97
  | `incomplete-migration` | Partially-completed extraction candidates: new helpers in the diff wired into some sites while similar un-migrated sites remain | `--base <ref>`<br>`--min-containment <n>`<br>`--max-helpers <n>`<br>`-n, --limit <n>`<br>`--full`<br>`--json` |
98
98
  | `diff-impact` | Compute changed symbols and downstream consumers from current git diff | `--base <ref>`<br>`--json` |
99
99
 
@@ -115,6 +115,7 @@ This syntax summary is generated from the CLI command descriptors. Keep workflow
115
115
 
116
116
  | Command | Description | Options |
117
117
  |---|---|---|
118
+ | `bench` | Benchmark indexing and command runtimes for this repository | `--json`<br>`--cold-index`<br>`--include-heavy`<br>`--command <cmd>`<br>`--timeout-ms <n>` |
118
119
  | `install-skills` | Install skills (scip-query, scip-query-setup, scip-adoption, scip-health-audit, scip-health-improve, scip-api-impact, concrete-plan, scip-ai-cleanup, scip-debug, scip-explore, scip-triage-issue, scip-diagram, scip-debloat, scip-doc-reconcile, scip-directory-architecture, scip-maintainability, scip-react-maintainability, scip-vue-maintainability, scip-verify, scip-language-playbook) into Claude Code, Codex, and shared agent roots | - |
119
120
  | `setup-hooks` | Install or refresh project-local Codex and Claude Code lifecycle hooks | `--json` |
120
121
  | `check-deps` | Check whether scip-query and the detected language indexers are actually runnable | - |
@@ -127,7 +128,7 @@ This syntax summary is generated from the CLI command descriptors. Keep workflow
127
128
  | `setup` | Bootstrap this project: install agent skills, refresh the index, verify capabilities, and report health | `--git-hook`<br>`--json` |
128
129
  | `setup-agent` | Seed agent guidance for this project: AGENTS.md/CLAUDE.md block pointing agents at the scip-query skills and diff gate, plus an optional git pre-commit backstop | `--git-hook` |
129
130
  | `setup-ci` | Write a GitHub Actions workflow that runs scip-query reindex and diff-gate on pull requests | `--force`<br>`--dry-run` |
130
- | `watch` | Watch for file changes and reindex automatically | `--debounce <ms>`<br>`--cooldown <ms>` |
131
+ | `watch` | Watch for file changes and reindex automatically | `--debounce <ms>`<br>`--cooldown <ms>`<br>`--git-poll <ms>` |
131
132
  | `status` | Show index status for this project | `--json`<br>`--capabilities` |
132
133
 
133
134
  <!-- END GENERATED COMMAND REFERENCE -->
@@ -20,7 +20,7 @@ The action tiers are:
20
20
 
21
21
  ## Current Surfaces
22
22
 
23
- The published query surface and private query-helper manifest live in `src/queries/public-query-entries.ts`. The CLI command order and families live in `src/runtime/commands/query-command-specs.ts`. The composite health score runs the phases listed in `HEALTH_PHASES` in `src/queries/health/health.ts`. The diff gate runs the checks listed in `DIFF_GATE_CHECKS` in `src/queries/impact/diff-gate.ts`, with doc-reference and baseline policy helpers kept private to the query tree.
23
+ The published query surface and private query-helper manifest live in `src/queries/public-query-entries.ts`. The CLI command order and families live in `src/runtime/commands/query-command-specs.ts`. The composite health score runs the phases listed in `HEALTH_PHASES` in `src/queries/health/health.ts`. The diff gate runs the default diff-scoped checks listed in `DIFF_GATE_CHECKS` in `src/queries/impact/diff-gate.ts`; the baseline policy helper remains private to the query tree and runs only for the explicit full health-baseline ratchet.
24
24
 
25
25
  `health --json` on this repository currently reports:
26
26
 
@@ -67,7 +67,7 @@ The declared-coupling config has been refreshed after the inventory surfaced old
67
67
  | `doc-reference` | Living docs citing changed files, excluding import-only source changes, with citation kind and Markdown-local cited-claim context | Split by citation evidence | Behavioral/current doc claims are direct doc-review evidence. Configuration examples and intentional records are support-tier checks unless the cited target changed meaning. |
68
68
  | `unused-params` | Trailing unused params in changed files | Direct repair | Conservative enough to be a high-confidence local fix. |
69
69
  | `new-dead` | Changed production symbols with zero consumers, excluding entry/root/test/framework-discovered cases | Direct repair | Either wire it up, remove it, or mark it as an externally live root before it lands. |
70
- | `baseline` | New health finding identity versus committed baseline | Direct gate | It does not explain the smell itself, but correctly blocks regression until fixed or accepted. |
70
+ | `baseline` | New health finding identity versus committed baseline, when the caller explicitly asks diff-gate to run the full baseline ratchet | Direct gate | It does not explain the smell itself, but correctly blocks regression until fixed or accepted. It is opt-in for diff-gate because the baseline comparison is repo-wide rather than diff-sized. |
71
71
 
72
72
  ## Standalone Cleanup and Similarity Analyzers
73
73
 
@@ -15,7 +15,7 @@ The ledger is anchored to the current tool surface, not memory.
15
15
  | Surface | Source | Why it anchors the ledger |
16
16
  | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------- |
17
17
  | Repo-wide health analysis | `scip-query code health --json` reported `src/queries/health/health.ts:194`, where `health()` runs `runHealthAnalyses()` and `buildHealthReport()`. | Every repo-wide analyzer validation must eventually reconcile with health output and scoring. |
18
- | Change-time gate analysis | `scip-query code diffGate --json` reported `src/queries/impact/diff-gate.ts:94`, where `diffGate()` runs `echo`, `incomplete-migration`, `co-change-partner`, `doc-reference`, `unused-params`, `new-dead`, and `baseline`. | Every diff-only analyzer needs a separate validation path from repo-wide health. |
18
+ | Change-time gate analysis | `scip-query code diffGate --json` reported `src/queries/impact/diff-gate.ts:94`, where `diffGate()` runs the default diff-scoped checks: `echo`, `incomplete-migration`, `co-change-partner`, `doc-reference`, `unused-params`, and `new-dead`. The baseline ratchet is explicit because it is repo-wide. | Every diff-only analyzer needs a separate validation path from repo-wide health. |
19
19
  | Public command registry | `scip-query trace queryCommandOrder --json` reported `src/runtime/commands/query-command-specs.ts:10`, where the public query command order starts. `scip-query code queryCommandDescriptor --json` reported `src/runtime/commands/query-command-specs.ts:94`, where command descriptors are resolved by id. | The ledger must not silently miss a public analyzer command. |
20
20
  | Diff-gate check list | `scip-query trace DIFF_GATE_CHECKS --json` reported `src/queries/impact/diff-gate.ts:27`, where the canonical diff-gate check list is exported. | The ledger must cover every change-time check that can block a diff. |
21
21
 
@@ -267,4 +267,4 @@ The maintainability-register completion slice rechecked the ledger's command-sur
267
267
 
268
268
  ## 2026-06-23 Current Sweep Citation Refresh
269
269
 
270
- The current maintainability sweep rechecked the `diff-gate.ts` citation again after doc-reference and baseline policy helpers moved into private query modules. The ledger remains accurate because `diffGate()` and `DIFF_GATE_CHECKS` still live in `src/queries/impact/diff-gate.ts`; only helper policy bodies moved behind the same entry point.
270
+ The current maintainability sweep rechecked the `diff-gate.ts` citation again after doc-reference and baseline policy helpers moved into private query modules. The ledger remains accurate because `diffGate()` and `DIFF_GATE_CHECKS` still live in `src/queries/impact/diff-gate.ts`; the baseline policy body remains behind the same entry point, but the repo-wide baseline ratchet is explicit rather than part of default diff-gate execution.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scip-query",
3
- "version": "0.10.6",
3
+ "version": "0.10.7",
4
4
  "description": "Evidence and verification for AI coding agents: map code, reuse concepts, finish migrations, and gate diffs.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -11,7 +11,7 @@ You are writing a production implementation plan as a markdown checklist. Every
11
11
 
12
12
  ## Hard Rules
13
13
 
14
- 1. **Every code reference must come from scip-query.** Run `scip-query reindex` before starting. Re-run if significant code has changed during the session. No reference from memory, grep, or file reads.
14
+ 1. **Every code reference must come from scip-query.** Run `scip-query status --capabilities` or `scip-query status --json` before starting. If freshness is `fresh`, keep going; if it is `stale`, `missing`, or `unknown`, run `scip-query reindex` before using graph facts. No reference from memory, grep, or file reads.
15
15
 
16
16
  2. **Every step must cite its source.** Each step in the plan includes a `Source` field naming the scip-query command that produced the file path, line number, and behavioral claim. A step without a Source is unverified and must not appear in the plan.
17
17
 
@@ -289,7 +289,7 @@ Apply the 11 Principles against every step in the design. For each principle, as
289
289
 
290
290
  After stress-testing is complete:
291
291
 
292
- 1. **Reindex**: Run `scip-query reindex`.
292
+ 1. **Freshness**: Run `scip-query status --capabilities`; reindex only if freshness is not `fresh`.
293
293
  2. **Verify references**: Spawn parallel subagents (one per phase) using the **Subagent Briefing Template**. Each agent confirms that every file path exists, every line number is within +-5 lines, and every described behavior matches reality. Reject output that doesn't cite scip-query commands.
294
294
  3. **Fix drift**: Update any stale references.
295
295
  4. **Check execution order**: No phase depends on a later phase. No step within a phase depends on a later step.
@@ -67,7 +67,9 @@ scip-query config-validate
67
67
  ### 5. Prove ongoing local usefulness
68
68
 
69
69
  ```bash
70
- scip-query reindex
70
+ scip-query status --capabilities
71
+ # If freshness is stale, missing, or unknown:
72
+ # scip-query reindex
71
73
  scip-query stats
72
74
  scip-query files <known-source-term>
73
75
  scip-query outline <known-source-file>
@@ -109,7 +111,7 @@ Health:
109
111
  - confirmed cleanup queue or audit handoff
110
112
 
111
113
  Verification:
112
- - `scip-query reindex`
114
+ - `scip-query status --capabilities`, then `scip-query reindex` only if freshness is `stale`, `missing`, or `unknown`
113
115
  - `scip-query diff-gate --json`
114
116
  - targeted smoke commands
115
117
 
@@ -25,7 +25,7 @@ plan and a CI ratchet.
25
25
 
26
26
  ## Hard Rules
27
27
 
28
- 1. **Evidence first.** Run `scip-query status` and `scip-query reindex` before
28
+ 1. **Evidence first.** Run `scip-query status --capabilities`; reindex only when freshness is `stale`, `missing`, or `unknown` before
29
29
  trusting graph facts. All detectors print whether they're heuristic.
30
30
  2. **Verify before deleting.** Findings are candidates; only
31
31
  `cleanup-plan --verify` output stamped COMPILER-VERIFIED is proof.
@@ -21,7 +21,9 @@ Use this skill before changing a public surface. A public surface is a callable,
21
21
 
22
22
  ```bash
23
23
  scip-query status --capabilities
24
- scip-query reindex
24
+ scip-query status --capabilities
25
+ # If freshness is stale, missing, or unknown:
26
+ # scip-query reindex
25
27
  scip-query surface <module-or-package>
26
28
  scip-query outline <file>
27
29
  scip-query trace <symbol-or-command>
@@ -103,7 +105,9 @@ Verification:
103
105
  ### 6. Verify after editing
104
106
 
105
107
  ```bash
106
- scip-query reindex
108
+ scip-query status --capabilities
109
+ # If freshness is stale, missing, or unknown:
110
+ # scip-query reindex
107
111
  scip-query diff-impact --json
108
112
  scip-query diff-gate --json
109
113
  ```
@@ -304,7 +304,7 @@ scip-query hotspots -n 10 # Most-referenced symbols
304
304
  ### Phase 1: Health Check (5 minutes)
305
305
 
306
306
  ```bash
307
- scip-query reindex # Ensure index is fresh
307
+ scip-query status --capabilities # Ensure freshness; reindex only if stale, missing, or unknown
308
308
  scip-query health # Get the full report
309
309
  ```
310
310
 
@@ -32,7 +32,9 @@ If the user provides no reproduction, make the smallest runnable reproduction yo
32
32
 
33
33
  ```bash
34
34
  scip-query status --capabilities
35
- scip-query reindex
35
+ scip-query status --capabilities
36
+ # If freshness is stale, missing, or unknown:
37
+ # scip-query reindex
36
38
  scip-query files <feature-or-error-term>
37
39
  scip-query outline <candidate-file>
38
40
  scip-query trace <candidate-symbol>
@@ -88,7 +90,9 @@ Name the smallest symbol or file that should change. If the blast radius is larg
88
90
  Apply the minimal code change, then run:
89
91
 
90
92
  ```bash
91
- scip-query reindex
93
+ scip-query status --capabilities
94
+ # If freshness is stale, missing, or unknown:
95
+ # scip-query reindex
92
96
  scip-query diff-gate --json
93
97
  ```
94
98
 
@@ -32,7 +32,9 @@ Start with current graph facts:
32
32
 
33
33
  ```bash
34
34
  scip-query status --capabilities
35
- scip-query reindex
35
+ scip-query status --capabilities
36
+ # If freshness is stale, missing, or unknown:
37
+ # scip-query reindex
36
38
  ```
37
39
 
38
40
  Collect only the commands needed for the diagram:
@@ -24,7 +24,7 @@ A migration slice is the smallest set of file moves and import updates that can
24
24
  3. Preserve working conventions. Existing boundaries are not wrong just because they are broad; central folders such as `errors`, `routes`, `workflows`, `schemas`, `contracts`, or `features` may be doing real work.
25
25
  4. Do not reward generic `shared`. A shared folder is justified only when the shared concept has a name, owner, and consumers across real boundaries.
26
26
  5. Treat messy repos honestly. If ownership concepts are not stable, produce a discovery map and decision list instead of pretending the repo has a clean target structure.
27
- 6. Prefer small verified moves. Broad reorganizations need staged migration slices with import updates, tests, `scip-query reindex`, and `scip-query diff-gate --json`.
27
+ 6. Prefer small verified moves. Broad reorganizations need staged migration slices with import updates, tests, a fresh scip-query index, and `scip-query diff-gate --json`.
28
28
 
29
29
  ## Workflow
30
30
 
@@ -46,7 +46,9 @@ Run:
46
46
 
47
47
  ```bash
48
48
  scip-query status
49
- scip-query reindex
49
+ scip-query status --capabilities
50
+ # If freshness is stale, missing, or unknown:
51
+ # scip-query reindex
50
52
  scip-query stats
51
53
  find . -maxdepth 3 -type d | sort
52
54
  ```
@@ -155,7 +157,9 @@ When the user asks to proceed, pick the smallest high-confidence slice. Before e
155
157
  Then move files with normal filesystem tools, update imports with project tooling where available, and run:
156
158
 
157
159
  ```bash
158
- scip-query reindex
160
+ scip-query status --capabilities
161
+ # If freshness is stale, missing, or unknown:
162
+ # scip-query reindex
159
163
  scip-query incomplete-migration
160
164
  scip-query recent-duplicates
161
165
  scip-query co-change <moved-file-or-config>
@@ -30,7 +30,9 @@ descriptive.
30
30
  ### 1. Build the evidence-backed worklist
31
31
 
32
32
  ```bash
33
- scip-query reindex
33
+ scip-query status --capabilities
34
+ # If freshness is stale, missing, or unknown:
35
+ # scip-query reindex
34
36
  scip-query doc-drift # all living docs, ranked by staleness
35
37
  scip-query doc-drift agent-os/standards # scoped to a standards tree
36
38
  ```
@@ -77,10 +77,10 @@ Start by making sure the SCIP facts are current enough to trust:
77
77
 
78
78
  ```bash
79
79
  scip-query status # Check index location, freshness, and project root
80
- scip-query reindex # Run when missing, stale, uncertain, or after code changes
80
+ scip-query status --capabilities # Reindex only when freshness is stale, missing, or unknown
81
81
  ```
82
82
 
83
- If `status` is unavailable or inconclusive, run `scip-query stats` and `scip-query reindex` when the repository has changed. Do not explore from an index you know is stale.
83
+ If `status` is unavailable or inconclusive, run `scip-query stats` and then `scip-query reindex` only when the repository has changed or freshness cannot be proven. Do not explore from an index you know is stale.
84
84
 
85
85
  ### Step 1: Orient — What are we looking at?
86
86
 
@@ -34,7 +34,9 @@ Then collect the current state:
34
34
  ```bash
35
35
  scip-query doctor
36
36
  scip-query status --capabilities
37
- scip-query reindex
37
+ scip-query status --capabilities
38
+ # If freshness is stale, missing, or unknown:
39
+ # scip-query reindex
38
40
  scip-query health --json --full
39
41
  scip-query diff-gate --json
40
42
  scip-query capability-matrix --json
@@ -139,7 +141,9 @@ When the user has asked for cleanup or the current workflow is post-setup cleanu
139
141
  After every batch:
140
142
 
141
143
  ```bash
142
- scip-query reindex
144
+ scip-query status --capabilities
145
+ # If freshness is stale, missing, or unknown:
146
+ # scip-query reindex
143
147
  scip-query diff-gate --json
144
148
  scip-query health --json --full
145
149
  ```
@@ -40,7 +40,9 @@ Collect the baseline before ranking:
40
40
  ```bash
41
41
  scip-query doctor
42
42
  scip-query status --capabilities
43
- scip-query reindex
43
+ scip-query status --capabilities
44
+ # If freshness is stale, missing, or unknown:
45
+ # scip-query reindex
44
46
  scip-query health --json --full
45
47
  scip-query diff-gate --json
46
48
  scip-query capability-matrix --json
@@ -116,7 +118,9 @@ Then repeat:
116
118
  2. Run the project check that proves the touched behavior.
117
119
  3. Run:
118
120
  ```bash
119
- scip-query reindex
121
+ scip-query status --capabilities
122
+ # If freshness is stale, missing, or unknown:
123
+ # scip-query reindex
120
124
  scip-query diff-gate --json
121
125
  scip-query health --json --full
122
126
  ```
@@ -28,7 +28,7 @@ System compression belongs inside this review. A system compression is a maintai
28
28
 
29
29
  ## Hard Rules
30
30
 
31
- 1. **Evidence first.** Use `scip-query` to ground claims in files, symbols, references, call graphs, dependencies, surfaces, and blast radius. If the SCIP index is missing or stale, run `scip-query reindex` before trusting graph facts.
31
+ 1. **Evidence first.** Use `scip-query` to ground claims in files, symbols, references, call graphs, dependencies, surfaces, and blast radius. Check `scip-query status --capabilities`; if freshness is `stale`, `missing`, or `unknown`, run `scip-query reindex` before trusting graph facts.
32
32
 
33
33
  2. **Do not chase health scores.** `scip-query health`, detector counts, and LOC estimates are diagnostic signals. They are not the objective. A change is valuable only when it reduces real maintenance burden while preserving behavior.
34
34
 
@@ -83,7 +83,7 @@ Start from current code intelligence:
83
83
 
84
84
  ```bash
85
85
  scip-query status
86
- scip-query reindex # Run when missing, stale, uncertain, or after code changes
86
+ scip-query status --capabilities # Reindex only when freshness is stale, missing, or unknown
87
87
  scip-query stats
88
88
  scip-query system <scope>
89
89
  scip-query surface <scope>
@@ -264,7 +264,10 @@ Always finish implemented maintainability work with:
264
264
 
265
265
  ```bash
266
266
  scip-query diff-impact --json
267
- scip-query reindex && scip-query diff-gate --json
267
+ scip-query status --capabilities
268
+ # If freshness is stale, missing, or unknown:
269
+ # scip-query reindex
270
+ scip-query diff-gate --json
268
271
  ```
269
272
 
270
273
  Treat `diff-gate` findings as unfinished work. Fix them or state a concrete acceptance reason; do not silently report success.
@@ -10,8 +10,11 @@ Your job here is only to route: identify the phase of work, invoke the right
10
10
  specialist skill, and enforce the non-negotiable checks. Do not improvise a
11
11
  workflow when a specialist skill exists for it.
12
12
 
13
- If the index might be stale (code changed since the last reindex), run
14
- `scip-query reindex` before anything else.
13
+ Before trusting graph facts, check freshness with `scip-query status --capabilities`
14
+ or `scip-query status --json`. If the index is `fresh`, continue without
15
+ reindexing. If it is `stale`, `missing`, or `unknown`, run `scip-query reindex`
16
+ before using code-intelligence results. Project hooks auto-refresh stale indexes
17
+ by default unless `.scipquery.json` sets `watch.autoRefresh: false`.
15
18
 
16
19
  ## The default loop for any implementation request
17
20
 
@@ -22,9 +25,9 @@ When the user asks you to build, change, or fix something non-trivial:
22
25
  2. **Implement** the plan.
23
26
  3. **Verify** — invoke `scip-verify`, then run the post-checks that match what
24
27
  you changed (table below).
25
- 4. **Gate before done** — run `scip-query reindex`, then
26
- `scip-query diff-gate --json`; fix findings or state explicitly why each is
27
- accepted.
28
+ 4. **Gate before done** — check freshness; reindex only when the index is not
29
+ `fresh`, then run `scip-query diff-gate --json`; fix findings or state
30
+ explicitly why each is accepted.
28
31
 
29
32
  ## Route by phase of work
30
33
 
@@ -37,8 +40,9 @@ When the user asks you to build, change, or fix something non-trivial:
37
40
  | Plan a feature, fix, or refactor | `concrete-plan` | `scip-query plan-context <target>` |
38
41
  | Assess a public API, route, CLI, config, schema, or boundary change | `scip-api-impact` | `scip-query surface <module>`, `scip-query affected <symbol>`, `scip-query co-change <file>` |
39
42
  | Pick high-signal commands for an unfamiliar language | `scip-language-playbook` | — |
43
+ | Benchmark indexing, command runtime, or detector performance | `scip-query` | `scip-query bench --json`, `scip-query bench --cold-index --include-heavy` |
40
44
  | Adopt or bootstrap scip-query in a repository | `scip-adoption` | `scip-query setup --json`, `scip-query check-deps`, `scip-query capability-matrix --json` |
41
- | Verify work you just finished (any implementation, refactor, or extraction) | `scip-verify` | `scip-query reindex`, `scip-query diff-gate --json` |
45
+ | Verify work you just finished (any implementation, refactor, or extraction) | `scip-verify` | `scip-query status --capabilities`, `scip-query diff-gate --json` |
42
46
  | Confirm post-setup health signals before cleanup | `scip-health-audit` | `scip-query health --json --full`, `scip-query diff-gate --json` |
43
47
  | Raise the health score as high as reasonably possible with autonomous verified cleanup | `scip-health-improve` | `scip-query health --json --full`, `scip-query cleanup-plan --verify --json`, `scip-query diff-gate --json` |
44
48
  | Audit dead code, duplication, unnecessary abstractions, or structural bloat and produce a prioritized cleanup plan | `scip-debloat` | `scip-query health` |
@@ -44,7 +44,7 @@ The setup command also installs skills and configures project-local hooks, but r
44
44
  scip-query setup --json
45
45
  ```
46
46
 
47
- This pass installs bundled skills, configures project-local hooks, checks indexer readiness, attempts configured indexer remediation, refreshes the index, verifies capabilities, smoke-tests representative command families, writes `docs/scip-query/health-dossier.md` and `docs/scip-query/health-dossier.json`, and seeds agent guidance.
47
+ This pass installs bundled skills, configures project-local hooks, checks indexer readiness, attempts configured indexer remediation, refreshes or reuses the index, verifies capabilities, smoke-tests representative command families, writes `docs/scip-query/health-dossier.md` and `docs/scip-query/health-dossier.json`, and seeds agent guidance.
48
48
 
49
49
  If setup reports `blocked`, run:
50
50
 
@@ -64,11 +64,14 @@ scip-query config-validate
64
64
 
65
65
  Keep `.scipquery.json` minimal. Add settings only when they are justified by observed repo facts, reviewed false positives, declared coupling, or explicit suppressions.
66
66
 
67
- 6. Refresh the index and inspect project status when setup repairs anything.
67
+ For TypeScript monorepos with multiple discovered project shards, prefer persistent `indexer.typescript.projectMode: "workspace"`. Add `indexerConcurrency` only when the repo has enough CPU/memory or measured cold-index timing justifies a project-specific worker cap.
68
+
69
+ 6. Inspect freshness and refresh only when setup repairs anything or the index is not fresh.
68
70
 
69
71
  ```bash
70
- scip-query reindex
71
72
  scip-query status --capabilities
73
+ # If freshness is stale, missing, or unknown:
74
+ # scip-query reindex
72
75
  scip-query capabilities --json
73
76
  scip-query stats
74
77
  ```
@@ -79,7 +82,7 @@ If an upstream indexer skipped source files that should still be searchable or v
79
82
  scip-query augment-sources
80
83
  ```
81
84
 
82
- Use `scip-query watch` only for an active local session where repeated source edits need automatic reindexing. It is not part of the default setup proof.
85
+ Project hooks auto-refresh stale indexes for agent sessions unless `.scipquery.json` sets `watch.autoRefresh: false`. Use `scip-query watch` only when a human explicitly wants a long-running live watcher in a terminal.
83
86
 
84
87
  7. Confirm health signals before cleanup.
85
88
 
@@ -132,7 +135,9 @@ If the repo has no mature boundaries, the correct setup result is a note, not a
132
135
  10. Finish with the standard gate.
133
136
 
134
137
  ```bash
135
- scip-query reindex
138
+ scip-query status --capabilities
139
+ # If freshness is stale, missing, or unknown:
140
+ # scip-query reindex
136
141
  scip-query diff-gate --json
137
142
  ```
138
143
 
@@ -21,7 +21,9 @@ Refresh the code intelligence before trusting graph facts:
21
21
 
22
22
  ```bash
23
23
  scip-query status
24
- scip-query reindex
24
+ scip-query status --capabilities
25
+ # If freshness is stale, missing, or unknown:
26
+ # scip-query reindex
25
27
  ```
26
28
 
27
29
  Run the React review commands uncapped when doing a serious frontend pass. Do not combine `--full` with `--limit`.
@@ -83,7 +85,10 @@ scip-query unused-params
83
85
  scip-query wrapper-candidates --scope <react-source-scope> --full --json
84
86
  scip-query passthrough-candidates --scope <react-source-scope> --full --json
85
87
  scip-query stale-abstractions --scope <react-source-scope> --include-low-confidence --full --json
86
- scip-query reindex && scip-query diff-gate --json
88
+ scip-query status --capabilities
89
+ # If freshness is stale, missing, or unknown:
90
+ # scip-query reindex
91
+ scip-query diff-gate --json
87
92
  ```
88
93
 
89
94
  Use the results this way:
@@ -34,7 +34,9 @@ If key facts are missing but the repo can answer them, investigate. Ask the user
34
34
 
35
35
  ```bash
36
36
  scip-query status --capabilities
37
- scip-query reindex
37
+ scip-query status --capabilities
38
+ # If freshness is stale, missing, or unknown:
39
+ # scip-query reindex
38
40
  scip-query files <issue-term>
39
41
  scip-query outline <candidate-file>
40
42
  scip-query system <module-or-scope>
@@ -101,7 +103,7 @@ Write the packet before filing or fixing:
101
103
  1. Add or update failing test/smoke check.
102
104
  2. Make the smallest code change.
103
105
  3. Run targeted test.
104
- 4. Run `scip-query reindex`.
106
+ 4. Run `scip-query status --capabilities`; if freshness is `stale`, `missing`, or `unknown`, run `scip-query reindex`.
105
107
  5. Run `scip-query diff-gate --json`.
106
108
  6. Invoke `scip-verify`.
107
109
 
@@ -10,7 +10,7 @@ Verify the actual diff, not your intention. A verification pass proves that the
10
10
  ## Hard Rules
11
11
 
12
12
  1. Run environment checks before trusting graph facts.
13
- 2. Reindex before final verification unless a just-finished command already did so and no files changed afterward.
13
+ 2. Check index freshness before final verification. Reindex only when freshness is `stale`, `missing`, or `unknown`, unless a just-finished command already refreshed the index and no files changed afterward.
14
14
  3. Treat `scip-query diff-gate --json` as the primary blocker for diff-specific risk. Manual checks are drill-down evidence, not a replacement.
15
15
  4. Run the postchecks that match the actual change type.
16
16
  5. Prefer fixing findings. Use `scip-query suppress <id> --reason "<specific reason>"` only for intentional design, compatibility shims, framework entry points, or accepted false positives with durable evidence.
@@ -30,7 +30,9 @@ If either command reports missing indexers, stale indexes, invalid config, or un
30
30
  ### 2. Refresh and assess the diff
31
31
 
32
32
  ```bash
33
- scip-query reindex
33
+ scip-query status --capabilities
34
+ # If freshness is stale, missing, or unknown:
35
+ # scip-query reindex
34
36
  scip-query diff-impact --json
35
37
  ```
36
38
 
@@ -155,4 +157,4 @@ Remaining risk:
155
157
  - accepted suppressions, blocked capabilities, or checks not run
156
158
  ```
157
159
 
158
- Do not claim "safe to commit" unless `scip-query reindex` and `scip-query diff-gate --json` passed after the final file edit.
160
+ Do not claim "safe to commit" unless freshness is `fresh` after the final file edit and `scip-query diff-gate --json` passed.
@@ -21,7 +21,9 @@ Refresh the code intelligence before trusting graph facts:
21
21
 
22
22
  ```bash
23
23
  scip-query status
24
- scip-query reindex
24
+ scip-query status --capabilities
25
+ # If freshness is stale, missing, or unknown:
26
+ # scip-query reindex
25
27
  ```
26
28
 
27
29
  If Vue files need rich internals, find the relevant TypeScript project and augment the index:
@@ -89,7 +91,10 @@ scip-query unused-params
89
91
  scip-query wrapper-candidates --scope <vue-source-scope> --full --json
90
92
  scip-query passthrough-candidates --scope <vue-source-scope> --full --json
91
93
  scip-query stale-abstractions --scope <vue-source-scope> --include-low-confidence --full --json
92
- scip-query reindex && scip-query diff-gate --json
94
+ scip-query status --capabilities
95
+ # If freshness is stale, missing, or unknown:
96
+ # scip-query reindex
97
+ scip-query diff-gate --json
93
98
  ```
94
99
 
95
100
  Use the results this way:
@@ -1,8 +0,0 @@
1
- import{d as E,g as D}from"./chunk-UQJGTVHV.js";import{d as _}from"./chunk-3UVJJ6Z7.js";import{b as N,d as P,g as T}from"./chunk-A7RNHUJH.js";import{a as R}from"./chunk-3ZYF3ELZ.js";import{c as S,d as y}from"./chunk-JM72FNGA.js";var A=5;function ne(e,t={}){let{base:i="HEAD",minContainment:r=.7,minCallees:n=3,minSiteCoverage:o=.4,maxHelpers:a=Number.POSITIVE_INFINITY,limit:g=20}=t,c=t.semantic!==!1,p=t.diffPlan??P(e,{base:i}),s={available:p.note!==N,base:i,changedFiles:p.changedFiles,helpersChecked:0,skipped:[],findings:[]};if(!s.available||p.changedFiles.length===0)return s;let v=new R(e),M=new Set(p.changedFiles),q=new Map(p.renamedFiles.map(l=>[l.to,l.from])),f=K(e,v,M,i,q);if(f.length===0)return s;let k=f.slice(0,a);f.length>a&&(s.note=`helper scoring capped at ${a} of ${f.length} new symbols`);let H=E(e,{minCallees:Math.min(3,n),semantic:c}),x=z(H),O=v.calleeMap(k,{semantic:c}),$=k.map(l=>({def:l,callees:D((O.get(l.symbolId)??[]).map(m=>m.symbol))}));for(let{def:l,callees:m}of $){let h=S(l.symbol);if(m.size<n){s.skipped.push({helperShortName:h,helperFile:l.relativePath,reason:`fewer than ${n} meaningful callees \u2014 too small to score`});continue}let w=J(m,x);if(w===0){s.skipped.push({helperShortName:h,helperFile:l.relativePath,reason:"helper callee pattern is all project-wide infrastructure \u2014 too generic to score"});continue}let b=U(e,l.symbolId);if(b.length===0){s.skipped.push({helperShortName:h,helperFile:l.relativePath,reason:"no references yet \u2014 covered by the new-dead check"});continue}s.helpersChecked+=1;let C=j({candidateIndex:x,changed:M,helperCallees:m,helperFile:l.relativePath,helperSymbol:l.symbol,minContainment:r,minSiteCoverage:o,migratedFiles:b});C.length!==0&&(C.sort((u,d)=>L(d.migrationScope)-L(u.migrationScope)||d.containment-u.containment||d.siteCoverage-u.siteCoverage||u.file.localeCompare(d.file)),s.findings.push({helperSymbol:l.symbol,helperShortName:h,helperFile:l.relativePath,helperShape:"specific-callee-cluster",helperCalleeCount:m.size,specificHelperCalleeCount:w,migratedFiles:b.sort(),leftovers:C.slice(0,A)}))}return s.findings.sort((l,m)=>(m.leftovers[0]?.containment??0)-(l.leftovers[0]?.containment??0)||l.helperFile.localeCompare(m.helperFile)),s.findings=s.findings.slice(0,g),s}function z(e){let t=new Map,i=new Map;for(let r of e)for(let n of r.callees){t.set(n,(t.get(n)??0)+1);let o=i.get(n);o||(o=[],i.set(n,o)),o.push(r)}return{candidatesByCallee:i,docFreq:t,ubiquityThreshold:Math.max(8,Math.ceil(Math.sqrt(e.length)))}}function j(e){let t=[],i=B(e.helperSymbol,e.helperFile,e.migratedFiles),r=new Set;for(let n of e.helperCallees)for(let o of e.candidateIndex.candidatesByCallee.get(n)??[])r.add(o);for(let n of r){if(n.symbol===e.helperSymbol||e.changed.has(n.file)||n.callees.has(e.helperSymbol))continue;let o=_(e.helperCallees,n.callees);if(o<e.minContainment)continue;let a=[...e.helperCallees].filter(p=>n.callees.has(p)),g=n.callees.size===0?0:a.length/n.callees.size;if(g<e.minSiteCoverage||!a.some(p=>(e.candidateIndex.docFreq.get(p)??0)<=e.candidateIndex.ubiquityThreshold))continue;let c=V(i,n.symbol,n.file);t.push({symbol:n.symbol,shortName:S(n.symbol),file:n.file,...c,containment:o,siteCoverage:g,uniqueSiteCalleeCount:Math.max(0,n.callees.size-a.length),sharedCallees:a.map(S).sort()})}return t}function L(e){return e==="same-scope"?2:e==="unknown"?1:0}function B(e,t,i){let r=new Set([...I(t),...F(y(e))]);for(let n of i)for(let o of I(n))r.add(o);return r}function V(e,t,i){let r=new Set([...I(i),...F(y(t))]);if(e.size===0||r.size===0)return{migrationScope:"unknown",migrationScopeReasons:["insufficient path/name tokens to infer migration scope"]};let n=[...r].filter(o=>e.has(o)).sort();return n.length>0?{migrationScope:"same-scope",migrationScopeReasons:[`shares migration-scope token(s): ${n.slice(0,5).join(", ")}`]}:{migrationScope:"possible-subtype",migrationScopeReasons:["no path/name tokens shared with the helper or already migrated files"]}}var G=new Set(["app","apps","common","component","components","helper","helpers","index","lib","package","packages","page","pages","route","routes","service","services","shared","spec","src","test","tests","util","utils"]);function I(e){return F(e.replace(/\.[^.]+$/,""))}function F(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").toLowerCase().split(/[^a-z0-9]+/).filter(t=>t.length>1&&!G.has(t))}function J(e,t){let i=0;for(let r of e)(t.docFreq.get(r)??0)<=t.ubiquityThreshold&&(i+=1);return i}function K(e,t,i,r,n){let o=new Map;return t.productionCallableDefinitions({requireFunctionLikeSymbol:!0}).filter(a=>{if(!i.has(a.relativePath))return!1;let g=n.get(a.relativePath)??a.relativePath,c=o.get(g);return c===void 0&&(c=T(e.config.projectRoot,r,g),o.set(g,c)),c===null||!new RegExp(`\\b${W(a.leaf)}\\b`).test(c)})}function U(e,t){return e.all(`SELECT DISTINCT ref_d.relative_path
2
- FROM mentions m
3
- JOIN chunks c ON m.chunk_id = c.id
4
- JOIN documents ref_d ON c.document_id = ref_d.id
5
- WHERE m.symbol_id = ?
6
- AND m.role != 1
7
- ${e.pathExclusionsFor("ref_d")}`,t).map(r=>r.relative_path)}function W(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}export{ne as a};
8
- //# sourceMappingURL=chunk-237YUOPK.js.map
@@ -1,2 +0,0 @@
1
- function S(n,e){let t=new Set;for(let r of n)e.has(r)&&t.add(r);return t}function M(n,e){let t=new Set;for(let r of n)e.has(r)||t.add(r);return t}function w(n,e){if(n.size===0&&e.size===0)return 0;let t=0;for(let o of n)e.has(o)&&(t+=1);let r=n.size+e.size-t;return r===0?0:t/r}function x(n,e){if(n.size===0)return 0;let t=0;for(let r of n)e.has(r)&&(t+=1);return t/n.size}function z(n){let e=n.length;if(e===0)return new Map;let t=new Map;for(let o of n)for(let s of o)t.set(s,(t.get(s)??0)+1);let r=new Map;for(let[o,s]of t)r.set(o,Math.log(e/s));return r}function p(n){let e=[...n.values()].sort((r,o)=>r-o);if(e.length===0)return 0;let t=Math.floor(e.length/2);return e.length%2===0?(e[t-1]+e[t])/2:e[t]}function b(n,e,t){let r=S(n,e);if(r.size===0)return{similarity:0,significantShared:[],trivialShared:[]};let o=0,s=0,T=0,l=new Set([...n,...e]);for(let i of l){let a=t.get(i)??0,f=n.has(i)?a:0,u=e.has(i)?a:0;o+=f*u,s+=f*f,T+=u*u}let h=Math.sqrt(s)*Math.sqrt(T),g=h>0?o/h:0,m=p(t),c=[],d=[];for(let i of r)(t.get(i)??0)>=m?c.push(i):d.push(i);return c.sort((i,a)=>(t.get(a)??0)-(t.get(i)??0)),{similarity:g,significantShared:c,trivialShared:d}}export{S as a,M as b,w as c,x as d,z as e,b as f};
2
- //# sourceMappingURL=chunk-3UVJJ6Z7.js.map
@@ -1,2 +0,0 @@
1
- import{b as y,f as w,g as E}from"./chunk-ZQLO2SCU.js";import{a as g}from"./chunk-BGBBVSH4.js";import{b as V,c as G,d as O}from"./chunk-GZCQTZLK.js";import{c as B}from"./chunk-YTR4CO5S.js";import{a as K,k as F,l as j}from"./chunk-HVTYSC26.js";import{a as T}from"./chunk-AUVBR62P.js";import{f as q,h as S}from"./chunk-3UW7VM4H.js";import{f as k,g as P,i as N,j as A}from"./chunk-JM72FNGA.js";import{a as C,f as p}from"./chunk-QLNGUWR7.js";import{a as b,b as L}from"./chunk-EWC3UK4V.js";import{d}from"./chunk-D322LMSA.js";import{c as M}from"./chunk-OBBDKQAG.js";import{a as v}from"./chunk-64MNV6AB.js";function H(r,e,t){let a=e.identifierResolution==="strict"?F:j;for(let n of e.paths)if(!(!b(n)&&!(e.includeVueSfc&&L(n)))&&!r.isIgnored(n)&&!e.skipPath?.(n))try{let l=(i,c,R,m)=>{if(e.candidateNames&&!e.candidateNames.has(i))return;let h=e.resolveTargets?e.resolveTargets({sourceFile:n,name:i,kind:c,defaultTargets:m}):m();for(let D of h)t({sourceFile:n,name:i,target:D,occurrences:R,kind:c})},f=K(r,n);for(let[i,c]of f)l(i,"identifier",c.length,()=>a(r,n,i));for(let i of p(r,n,{includeCrossLanguageDispatchNames:e.includeCrossLanguageDispatchNames,includeRustAttributeNames:e.includeRustAttributeNames})){let c=i.kind==="cross-language-dispatch"?()=>F(r,n,i.name):()=>a(r,n,i.name);l(i.name,i.kind,i.occurrences,c)}}finally{e.afterPath?.(n)}}function W(r,e={}){let{scope:t,minLoc:a=1,maxLoc:n=Number.POSITIVE_INFINITY,excludeSymbol:o,excludeEntrySurfaces:l=!1,excludeTypesFiles:f=!1,excludeRootedSymbols:i=!1,requireFunctionLikeSymbol:c=!1,requireCallableSymbol:R=!1,excludeRustTraitImplMembers:m=!1,includeSuppressed:h=!1,sortByLocDesc:D=!1}=e,I=[];for(let s of S(r,t)){let u=s.relativePath;if(r.isIgnored(u)||l&&w(r,u)||!_(s,{requireFunctionLikeSymbol:c,requireCallableSymbol:R})||o!==void 0&&s.symbol===o)continue;let x=g(s);x<a||x>n||f&&z(u)||i&&E(r,s.symbol,u)||m&&N(s.symbol)||y(u)!=="test"&&(A(s.symbol)||!h&&d(r,u,s.startLine)||I.push(s))}return D?I.sort((s,u)=>g(u)-g(s)):I}function _(r,e){return e.requireCallableSymbol?k(r.symbol):e.requireFunctionLikeSymbol?P(r.symbol):r.isFunctionLike}function z(r){return(r.split("/").pop()??"").includes("types")}var Y=class{constructor(e){this.db=e}db;scopedDefinitions(e){return S(this.db,e)}definitionsForFile(e){return q(this.db,e)}productionCallableDefinitions(e={}){return W(this.db,e)}calleeMap(e,t={}){return B(this.db,e,t)}crossFileCallerMap(e,t={}){return V(this.db,e,t)}sourceFallbackCallerFiles(e){return G(this.db,e)}callerFileMap(e,t={}){return O(this.db,e,t)}frameworkReferencedSymbolIds(e){let t=new Map;for(let n of e){if(!n.leaf)continue;let o=t.get(n.leaf)??[];o.push(n.symbolId),t.set(n.leaf,o)}let a=new Set;for(let n of v(this.db,{includeIgnored:!1}))if(b(n)==="rust")for(let{name:o}of p(this.db,n,{includeRustAttributeNames:!0}))for(let l of t.get(o)??[])a.add(l);return a}symbolsWithNonSelfCallees(e,t={}){if(e.length===0)return new Set;let a=new Map(e.map(o=>[o.symbolId,o.symbol])),n=this.calleeMap(e,t);return new Set([...n.entries()].filter(([o,l])=>{let f=a.get(o);return l.some(i=>i.symbol!==f)}).map(([o])=>o))}fileDependencyGraph(e){return T(this.db,e)}fileKind(e){return y(e)}hasSuppressionComment(e){return d(this.db,e.relativePath,e.startLine)}sourceFiles(){return M(this.db)}scanSourceReferences(e,t){H(this.db,e,t)}callableSignature(e){let t=C(this.db,e.relativePath)?.callables.find(a=>a.startLine===e.startLine&&a.endLine===e.endLine);return t?{paramCount:t.paramCount}:null}};export{Y as a};
2
- //# sourceMappingURL=chunk-3ZYF3ELZ.js.map
@@ -1,4 +0,0 @@
1
- import{a as te}from"./chunk-NNDYO2DX.js";import{a as ie}from"./chunk-237YUOPK.js";import{a as y}from"./chunk-B32FX5KB.js";import{a as ee}from"./chunk-SPE4YCOT.js";import{a as Q}from"./chunk-ZFMPHDAT.js";import{a as X}from"./chunk-C2QSK7E7.js";import{a as J,b as Z}from"./chunk-UQJGTVHV.js";import{a as W}from"./chunk-G3WGZU5Q.js";import{a as Y}from"./chunk-DE7MA6OD.js";import{a as q}from"./chunk-7KCSELEV.js";import{a as M,c as I,d as P,g as H}from"./chunk-A7RNHUJH.js";import{a as _,b as F,e as z}from"./chunk-AYYIZ4BA.js";import{a as V}from"./chunk-AW4N6MGC.js";import{b as U}from"./chunk-C3MZZ2ZN.js";import{a as A,c as L,d as N,e as B}from"./chunk-EYLXU575.js";import{g as K}from"./chunk-KRGBLZT2.js";import{a as O}from"./chunk-CJJP64OC.js";import{a as E}from"./chunk-3ZYF3ELZ.js";import{f as k,g as T}from"./chunk-ZQLO2SCU.js";import{d as w,e as j}from"./chunk-JM72FNGA.js";import{createHash as Ke}from"crypto";import{existsSync as le}from"fs";function ne(e){let[i,t]=R(e,":"),r=i||"unknown",o=(s={})=>{let n=s.actionTier??fe(r);return{sourceAnalyzer:r,actionTier:n,rootCauseKey:s.rootCauseKey??(t||e),label:s.label??`${r} finding`,relatedFiles:s.relatedFiles??[],why:s.why??[],remediation:s.remediation??de(n,r),file:s.file}};if(!t)return o({rootCauseKey:e,why:["Baseline identity did not include analyzer payload."]});if(["dead","isolated","extract","wrapper","passthrough","stale"].includes(r)){let[s,n]=R(t,":");return o({file:s,relatedFiles:s?[s]:[],rootCauseKey:n?`${s}:${n}`:t,label:`${r} finding`,why:n?[`Baseline subject: ${n}.`]:[]})}if(r==="cycle"){let s=t.split(">").filter(Boolean);return o({relatedFiles:s,rootCauseKey:t,label:"cycle finding",why:s.length>0?[`Cycle path: ${s.join(" > ")}.`]:[]})}if(r==="similar"){let s=t.split("|").filter(Boolean);return o({relatedFiles:[],rootCauseKey:t,label:"similarity finding",why:s.length>0?[`Similar symbols: ${s.join(" | ")}.`]:[]})}if(r==="drift"){let[s,n]=R(t,":"),[c,a]=R(n,":");return o({actionTier:s==="unused-import"?"direct":"signal",file:c,relatedFiles:[...new Set([c,a].filter(Boolean))],rootCauseKey:t,label:`${s||"drift"} finding`,why:[...s?[`Drift kind: ${s}.`]:[],...a?[`Related dependency: ${a}.`]:[]]})}return o({why:["Baseline analyzer prefix is not recognized by this diff-gate version."]})}function fe(e){switch(e){case"dead":case"isolated":case"cycle":case"passthrough":return"direct";case"similar":case"extract":case"wrapper":case"stale":return"signal";default:return"signal"}}function de(e,i){return e==="direct"?`Fix the new ${i} baseline finding, or knowingly accept it via health --write-baseline.`:`Review the new ${i} baseline signal; fix it if it reflects real debt, or knowingly accept it via health --write-baseline.`}function R(e,i){let t=e.indexOf(i);return t<0?[e,""]:[e.slice(0,t),e.slice(t+i.length)]}import{existsSync as ue,readFileSync as re}from"fs";var $={classifyCitation:he,citationContexts:ge,citationKindLabel:pe,citationRemediation:ye,referenceTargets:be};function he(e){let i=e.join(`
2
- `).toLowerCase(),t=[],r=F(i,[".scipquery","declaredcouplings","suppression","suppressions","config","configuration","json"]);if(r.length>0)return t.push(`configuration/example terms near citation: ${r.join(", ")}`),{citationKind:"configuration-example",actionTier:"support",reasons:t};let o=F(i,["accepted","intentional","intentionally","retained","historical"]);if(o.length>0)return t.push(`intentional-record terms near citation: ${o.join(", ")}`),{citationKind:"intentional-record",actionTier:"support",reasons:t};let s=F(i,["command","cli","usage","example","run","workflow"]);return s.length>0?(t.push(`guide/reference terms near citation: ${s.join(", ")}`),{citationKind:"guide-reference",actionTier:"signal",reasons:t}):(t.push(e.length>0?"citation appears in prose without config or guide markers":"citation context unavailable"),{citationKind:"behavioral-claim",actionTier:"direct",reasons:t})}function ge(e,i,t){let r;try{r=re(`${e.config.projectRoot}/${i}`,"utf-8").split(/\r?\n/)}catch{return[]}let o=t.flatMap(me),s=[];for(let n=0;n<r.length;n+=1){let c=r[n]??"";o.some(a=>c.includes(a))&&s.push(_(r,n))}return s}function me(e){let i=e.split("/");return[e,`./${e}`,i.slice(-3).join("/"),i.slice(-2).join("/")].filter((t,r,o)=>t.length>0&&o.indexOf(t)===r)}function pe(e){switch(e){case"behavioral-claim":return"a behavioral doc claim";case"configuration-example":return"a configuration example";case"guide-reference":return"a guide reference";case"intentional-record":return"an intentional record"}}function ye(e,i){switch(e){case"behavioral-claim":return`Re-read ${i} and update the behavioral claim or citation.`;case"configuration-example":return`Verify the configuration example in ${i} still points at the intended file; update only if the example target changed.`;case"guide-reference":return`Verify the guide reference in ${i} still sends readers to the right implementation or command surface.`;case"intentional-record":return`Verify the intentional citation in ${i} is still meant to name this file.`}}function be(e,i,t){let r=M(t),o=new Set;for(let s of i)Ce(e,s,r.get(s)??[])&&o.add(s);return o}function Ce(e,i,t){if(t.length===0)return!1;if(!Se.test(i))return!0;let r=`${e.config.projectRoot}/${i}`;if(!ue(r))return!0;let o=re(r,"utf-8").split(/\r?\n/),s=$e(o);for(let n of t)for(let c=n.startLine;c<=n.endLine;c+=1)if((o[c]??"").trim()!==""&&!s.has(c))return!0;return!1}var Se=/\.(?:[cm]?[jt]sx?)$/i;function $e(e){let i=new Set,t=!1;for(let r=0;r<e.length;r+=1){let o=e[r].trim();!t&&De(o)&&(t=!0),t&&(i.add(r),o.endsWith(";")&&(t=!1))}return i}function De(e){return/^import(?:\s|$)/.test(e)||/^export(?:\s+type)?\s+(?:\*|\{)/.test(e)}import{existsSync as we,readFileSync as ke,writeFileSync as Te}from"fs";import{isAbsolute as Fe,join as Re}from"path";var ve=75e3,xe=5e3,Ae=2500;function Ge(e){let i=X(e);return i.symbols>=ve||i.documents>=xe?Ae:void 0}var je=".scipquery-baseline.json";function v(e,i){return i&&Fe(i)?i:Re(e.config.projectRoot,i??je)}function oe(e,i={}){let{scope:t}=i,r=Ge(e),o=[],s=U(e,{scope:t,...y.dead,scanLimit:r});for(let n of s.symbols)k(e,n.relativePath)||T(e,n.symbol,n.relativePath)||n.kind==="dead-code"&&o.push(`dead:${n.relativePath}:${n.shortName}`);for(let n of W(e,{scope:t,...y.isolated,scanLimit:r}))k(e,n.relativePath)||T(e,n.symbol,n.relativePath)||o.push(`isolated:${n.relativePath}:${n.shortName}`);for(let n of O(e,{scope:t}))n.kind==="real"&&o.push(`cycle:${Ee(n.path)}`);for(let n of Z(e,{scope:t,...y.similar,scanLimit:r}))o.push(`similar:${[n.symbolA,n.symbolB].sort().join("|")}`);for(let n of q(e,{scope:t,...y.extract,scanLimit:r}))o.push(`extract:${n.relativePath}:${n.shortName}`);for(let n of ee(e,{scope:t,...y.wrappers,scanLimit:r}))o.push(`wrapper:${n.file}:${n.shortName}`);for(let n of Y(e,{scope:t,...y.passthroughs,scanLimit:r}))o.push(`passthrough:${n.file}:${n.shortName}`);for(let n of Q(e,{scope:t,...y.stale,scanLimit:r}))o.push(`stale:${n.file}:${n.shortName}`);for(let n of V(e,{scope:t,...y.drift}).results)n.kind!=="pattern-deviation"&&o.push(`drift:${n.kind}:${n.file}:${n.dep}`);return[...new Set(o)].sort()}function Ee(e){if(e.length===0)return"";let i=0;for(let t=1;t<e.length;t++)e[t]<e[i]&&(i=t);return[...e.slice(i),...e.slice(0,i)].join(">")}function xi(e,i={}){let t=oe(e,{scope:i.scope}),r=v(e,i.path);return Te(r,JSON.stringify({version:1,findings:t},null,2)+`
3
- `),{path:r,findingCount:t.length}}function se(e,i={}){let t=v(e,i.path);if(!we(t))throw new Error(`No baseline found at ${t}. Create one with: scip-query health --write-baseline`);let r=JSON.parse(ke(t,"utf-8")),o=new Set(r.findings??[]),s=oe(e,{scope:i.scope}),n=new Set(s);return{baselinePath:t,baselineCount:o.size,current:s,newFindings:s.filter(c=>!o.has(c)),fixedFindings:[...o].filter(c=>!n.has(c))}}var Vi=["echo","incomplete-migration","co-change-partner","doc-reference","unused-params","new-dead","baseline"];function qi(e,i={}){let t=i.base??"HEAD",{minTogether:r=6,minConfidence:o=.6,maxEchoChecks:s=Number.POSITIVE_INFINITY,maxHelpers:n=Number.POSITIVE_INFINITY,minSimilarity:c=.8}=i,a=new Set(i.skip??[]),f=P(e,{base:t}),g=I(e,{base:t,plan:f}),u=g.changedFiles,d=new Set(u),l=new Set(f.changedFileLines),m=oi(e.config.projectRoot,t,f),h={base:t,changedFiles:u,changedSymbols:g.changedSymbols.length,checksRun:[],skipped:[],suppressed:[],findings:[],rootCauseGroups:[],note:g.summary.note};if(u.length===0)return h;let p=(b,S)=>{if(a.has(b)){h.skipped.push({check:b,reason:"skipped via --skip"});return}S()};return p("echo",()=>Pe(e,g.changedSymbols,d,m,s,c,h)),p("incomplete-migration",()=>Ye(e,t,f,n,h)),p("co-change-partner",()=>Je(e,d,r,o,h)),p("doc-reference",()=>ii(e,d,l,f.changedRanges,h)),p("unused-params",()=>ti(e,u,h)),p("new-dead",()=>ni(e,g.changedSymbols,m,h)),p("baseline",()=>ci(e,h)),Me(h,e.config.suppressions??[]),h.rootCauseGroups=Le(h.findings),h}function Le(e){let i=new Map;for(let t of e){let r=t.groupKey??`${t.check}:${t.id}`,o=i.get(r);o||(o={groupKey:r,check:t.check,severity:t.severity,actionTier:t.actionTier,sourceAnalyzer:t.sourceAnalyzer,rootCauseKey:t.rootCauseKey,count:0,findingIds:[],files:new Set,relatedFiles:new Set,message:t.message,remediation:t.remediation},i.set(r,o)),o.count+=1,o.findingIds.push(t.id),o.severity=Ne(o.severity,t.severity),o.actionTier=Be(o.actionTier,t.actionTier),t.file&&o.files.add(t.file);for(let s of t.relatedFiles??[])o.relatedFiles.add(s)}return[...i.values()].map(t=>({...t,files:[...t.files].sort(),relatedFiles:[...t.relatedFiles].sort()})).sort((t,r)=>r.count-t.count||x(r.severity)-x(t.severity)||t.groupKey.localeCompare(r.groupKey))}function Ne(e,i){return x(i)>x(e)?i:e}function x(e){return e==="error"?2:e==="warning"?1:0}function Be(e,i){return e?i&&ae(i)>ae(e)?i:e:i}function ae(e){return e==="direct"?2:e==="signal"?1:0}function Me(e,i){if(i.length===0||e.findings.length===0)return;let t=[];for(let r of e.findings){let o=i.find(s=>Ie(s,r));o?e.suppressed.push({finding:r,suppression:o}):t.push(r)}e.findings=t}function Ie(e,i){return!e.reason||e.reason.trim()===""||e.expiresAt&&Date.parse(e.expiresAt)<=Date.now()||e.id&&e.id!==i.id||e.check&&e.check!==i.check||e.file&&e.file!==i.file?!1:!!(e.id||e.check)}function D(e,i){e.findings.push({...i,suppressionHint:`scip-query: ignore ${i.check} ${i.id} -- <reason>`})}function Pe(e,i,t,r,o,s,n){n.checksRun.push("echo");for(let c of i.slice(0,o)){if(r(c))continue;let a=J(e,c.symbol,{minSimilarity:s,limit:5}),f=[];for(let l of a){let m=l.fileA===c.file?l.fileB:l.fileA,h=l.fileA===c.file?l.shortNameB:l.shortNameA,p=l.fileA===c.file?l.symbolB:l.symbolA;t.has(m)||f.push({otherFile:m,otherShort:h,otherSymbol:p,similarity:l.similarity,similarityBasis:l.similarityBasis??"callees",sharedEvidence:l.sharedCallees})}if(f.length===0)continue;let g=f[0],u=C("echo",c.symbol,c.file,...f.map(l=>`${l.otherSymbol}|${l.otherFile}`).sort()),d=He(c,f);D(n,{id:u,groupKey:u,actionTier:d,check:"echo",severity:"warning",evidence:"heuristic",confidence:g.similarity,file:c.file,symbol:c.symbol,relatedFiles:[...new Set(f.map(l=>l.otherFile))].sort(),message:Ve(c,f),why:qe(c,f),remediation:We(d,c.shortName,g.otherShort)})}i.length>o&&n.skipped.push({check:"echo",reason:`echo check capped at ${o} of ${i.length} changed symbols`})}function He(e,i){return i.some(r=>_e(e.symbol,r))?"direct":"signal"}function _e(e,i){if(i.similarityBasis!=="source-tokens"||i.similarity<.98||i.sharedEvidence.length>8)return!1;let t=w(e),r=w(i.otherSymbol);return!t||!r?!1:t===r?!0:Ue(i.sharedEvidence)?!1:ze(t,r)}function ze(e,i){let t=ce(e),r=ce(i);if(t.length===0||r.length===0)return!1;let o=new Set(r),s=t.filter(n=>o.has(n)).length;return s>=2&&s/Math.min(t.length,r.length)>=.5}function ce(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").split(/[^A-Za-z0-9]+/).map(i=>i.toLowerCase()).filter(i=>i.length>=2)}var Oe=new Set(["bytes","crypto","hex","num","random","secret","to","token"]);function Ue(e){return e.length>=3&&e.every(i=>Oe.has(i.toLowerCase()))}function Ve(e,i){let t=i[0],r=Math.round(t.similarity*100);return i.length===1?`${e.shortName} (${e.file}) is ${r}% similar to established ${t.otherShort} (${t.otherFile})`:`${e.shortName} (${e.file}) resembles ${i.length} established symbol(s); strongest is ${r}% similar to ${t.otherShort} (${t.otherFile})`}function qe(e,i){let t=[`${e.shortName} was changed in this diff.`];for(let r of i.slice(0,3))t.push(`${r.otherShort} is outside this diff and scored ${Math.round(r.similarity*100)}% similar by ${r.similarityBasis} evidence.`),t.push(`Shared evidence: ${r.sharedEvidence.slice(0,5).join(", ")||"(none listed)"}.`);return i.length>3&&t.push(`${i.length-3} additional similar match(es) grouped into this finding.`),t}function We(e,i,t){return e==="direct"?`Extract or reuse the shared behavior with ${t}, or keep the duplicate with a suppression reason.`:`Review whether ${i} is intentionally parallel to the established implementation(s); extract shared behavior only if the product semantics match.`}function Ye(e,i,t,r,o){let s=ie(e,{base:i,maxHelpers:r,diffPlan:t});if(!s.available){o.skipped.push({check:"incomplete-migration",reason:"no git history"});return}o.checksRun.push("incomplete-migration"),s.note&&o.skipped.push({check:"incomplete-migration",reason:s.note});for(let n of s.findings){let c=n.leftovers.map(l=>`${l.shortName} (${l.file}, ${Math.round(l.containment*100)}% helper / ${Math.round(l.siteCoverage*100)}% site, ${l.migrationScope})`).join(", "),a=n.leftovers.map(l=>`${l.shortName}: ${l.migrationScope} (${l.migrationScopeReasons[0]})`).join("; "),f=[...n.migratedFiles,...n.leftovers.map(l=>l.file)],g=n.leftovers.length===0?void 0:Math.max(...n.leftovers.map(l=>Math.min(l.containment,l.siteCoverage))),u=n.leftovers.some(l=>l.migrationScope==="possible-subtype"),d=C("incomplete-migration",n.helperSymbol,n.helperFile,f.join("|"));D(o,{id:d,check:"incomplete-migration",severity:"warning",evidence:"heuristic",confidence:g,file:n.helperFile,symbol:n.helperSymbol,relatedFiles:f,message:`new helper ${n.helperShortName} (${n.helperFile}) is wired into ${n.migratedFiles.length} file(s), but ${n.leftovers.length} similar un-migrated site(s) remain: ${c}`,why:[`${n.helperShortName} is new in this diff and already referenced by ${n.migratedFiles.join(", ")}.`,`Helper shape: ${n.helperShape}; ${n.specificHelperCalleeCount}/${n.helperCalleeCount} helper callees are specific enough to score.`,`Unchanged site(s) still contain the helper's callee pattern: ${c}.`,`Migration scope hints: ${a}.`],remediation:u?`Migrate same-scope sites to ${n.helperShortName}; review possible subtype/variant sites before applying the helper.`:`Migrate the remaining sites to ${n.helperShortName}, or confirm they are intentionally different.`})}}function Je(e,i,t,r,o){let s=K(e,i,{minTogether:t,minConfidence:0,maxFilesPerCommit:20});if(!s){o.skipped.push({check:"co-change-partner",reason:"no git history"});return}o.checksRun.push("co-change-partner");let n=new Set,c;for(let a of s){let f=i.has(a.fileA),g=i.has(a.fileB);if(f===g)continue;let u=f?a.fileA:a.fileB,d=f?a.fileB:a.fileA,l=f?a.changesA:a.changesB,m=l>0?a.together/l:0;if(m<r||A(d)||A(u)||!le(`${e.config.projectRoot}/${d}`))continue;let h=`${u}|${d}`;if(n.has(h))continue;n.add(h);let p=C("co-change-partner",u,d,String(a.together)),b=L(u,d),S=N({fileA:u,fileB:d,together:a.together,confidence:m,commitScope:a.commitScope,recency:a.recency,subjectContext:a.subjectContext},b,(c??=B(e))(u,d)),G=[u,d].sort().join("|");o.findings.push({id:p,check:"co-change-partner",severity:"warning",evidence:"change-graph",actionTier:"signal",groupKey:`co-change-partner:${G}`,confidence:m,file:u,relatedFiles:[d],sourceAnalyzer:"co-change",rootCauseKey:G,partnerClass:b.partnerClass,partnerClassReasons:b.reasons,commitScope:a.commitScope,recency:a.recency,focusedTogether:a.focusedTogether,broadTogether:a.broadTogether,broadCommitRatio:a.broadCommitRatio,lastTogetherAt:a.lastTogetherAt,recentTogether:a.recentTogether,subjectContext:a.subjectContext,...S?{declaredCouplingSuggestion:S}:{},message:`${u} changed, but ${d} did not \u2014 they change together ${a.together}x (${Math.round(m*100)}% of the time)`,why:[`${u} is in this diff and ${d} is not.`,`Git history shows ${a.together} co-change(s), which is ${Math.round(m*100)}% of changes to the edited side.`,`History context: ${Ze(a)}.`,`Subject context: ${Qe(a.subjectContext)}.`,...Xe(a),`Partner class: ${b.partnerClass} (${b.reasons.join("; ")}).`],remediation:S?`Update ${d} alongside this change, declare the coupling "${S.name}", or confirm the coupling no longer holds.`:`Update ${d} alongside this change, or confirm the coupling no longer holds.`})}}function Ze(e){return`${e.commitScope}/${e.recency}; ${e.focusedTogether} focused, ${e.broadTogether} broad-sweep (${Math.round(e.broadCommitRatio*100)}% broad), ${e.recentTogether} recent, last ${ei(e.lastTogetherAt)}`}function Qe(e){let i=e.subjectLabels.length>0?e.subjectLabels.slice(0,5).join(", "):"none inferred",t=e.issueRefs.length>0?e.issueRefs.slice(0,5).join(", "):"none",r=e.sampleSubjects.length>0?e.sampleSubjects.slice(0,3).map(o=>`"${o}"`).join("; "):"none";return`labels ${i}; refs ${t}; samples ${r}; external issue/PR labels ${e.externalIssueLabelStatus}`}function Xe(e){let i=[];return e.commitScope==="broad-sweep"&&i.push("Broad-sweep history is weaker than focused co-edits; confirm this is a real coordination contract."),e.recency==="stale"&&i.push("The pair has no co-change in the recent history window; confirm the coupling still holds."),i}function ei(e){return e<=0?"unknown":new Date(e*1e3).toISOString().slice(0,10)}function ii(e,i,t,r,o){o.checksRun.push("doc-reference");let s=$.referenceTargets(e,i,r);if(s.size!==0)for(let n of z(e,s)){if(t.has(n.doc))continue;let c=n.citedClaims.length>0?n.citedClaims:$.citationContexts(e,n.doc,n.cited),a=$.classifyCitation(c),f=C("doc-reference",n.doc,n.cited.join("|"));D(o,{id:f,check:"doc-reference",severity:"warning",evidence:"change-graph",actionTier:a.actionTier,confidence:1,file:n.doc,relatedFiles:n.cited,citationKind:a.citationKind,citationKindReasons:a.reasons,citedClaims:c,message:`${n.doc} cites ${n.cited.join(", ")} as ${$.citationKindLabel(a.citationKind)} \u2014 changed in this diff, doc untouched`,why:[`${n.cited.join(", ")} changed in this diff.`,`${n.doc} cites the changed file(s) but was not updated in the same diff.`,...a.reasons.map(g=>`Citation kind evidence: ${g}`)],remediation:$.citationRemediation(a.citationKind,n.doc)})}}function ti(e,i,t){t.checksRun.push("unused-params");for(let r of te(e,{files:i,limit:50})){let o=C("unused-params",r.symbol,r.file,r.unusedTrailing.join("|"));D(t,{id:o,check:"unused-params",severity:"warning",evidence:"heuristic",confidence:.85,file:r.file,startLine:r.startLine,endLine:r.endLine,symbol:r.symbol,message:`${r.shortName} (${r.file}) has trailing unused parameter(s): ${r.unusedTrailing.join(", ")}`,why:[`${r.shortName} is in a changed file.`,`The trailing parameter(s) ${r.unusedTrailing.join(", ")} are not referenced in the function body.`],remediation:"Drop the unused trailing parameters and their call-site arguments."})}}function ni(e,i,t,r){r.checksRun.push("new-dead");let o=new E(e);for(let s of i){if(t(s)||s.fanIn>0||o.fileKind(s.file)==="test"||k(e,s.file)||T(e,s.symbol,s.file)||ri(s.symbol))continue;let n=C("new-dead",s.symbol,s.file);D(r,{id:n,check:"new-dead",severity:"warning",evidence:"graph-fact",confidence:.9,file:s.file,symbol:s.symbol,message:`${s.shortName} (${s.file}) was changed but has zero indexed consumers`,why:[`${s.shortName} is a changed production symbol.`,"The index reports zero consumers for this symbol.","The symbol is not in a detected entry surface or configured live root."],remediation:"Wire it up, or remove it before it becomes permanent dead code."})}}function ri(e){if(j(e)!=="type")return!1;let i=w(e);return i.startsWith("_Assert")||i.startsWith("Assert")}function oi(e,i,t){let r=new Map(t.renamedFiles.map(s=>[s.to,s.from])),o=new Map;return s=>{let n=r.get(s.file)??s.file,c=w(s.symbol);if(!c)return!1;let a=o.get(n);return a===void 0&&(a=H(e,i,n),o.set(n,a)),a!==null&&si(a,c)}}function si(e,i){return new RegExp(`\\b${ai(i)}\\b`).test(e)}function ai(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function ci(e,i){if(!le(v(e))){i.skipped.push({check:"baseline",reason:"no .scipquery-baseline.json \u2014 run health --write-baseline to enable"});return}i.checksRun.push("baseline");let t=se(e);for(let r of t.newFindings){let o=ne(r),s=C("baseline",r);D(i,{id:s,groupKey:`baseline:${o.sourceAnalyzer}:${o.rootCauseKey}`,check:"baseline",severity:"error",evidence:"baseline",actionTier:o.actionTier,confidence:1,file:o.file,relatedFiles:o.relatedFiles.length>0?o.relatedFiles:void 0,sourceAnalyzer:o.sourceAnalyzer,rootCauseKey:o.rootCauseKey,message:`new ${o.label} vs committed baseline: ${r}`,why:["A committed health baseline exists.","The current health result contains a finding not present in that baseline.",`Underlying analyzer: ${o.sourceAnalyzer}.`,`Inherited action tier: ${o.actionTier}.`,`Root cause key: ${o.rootCauseKey}.`,...o.why],remediation:o.remediation})}}function C(e,...i){return`SQ${Ke("sha256").update([e,...i].join("\0")).digest("hex").slice(0,12).toUpperCase()}`}export{oe as a,xi as b,se as c,Vi as d,qi as e,oi as f};
4
- //# sourceMappingURL=chunk-7JOTOWZO.js.map
@@ -1,2 +0,0 @@
1
- import{b as r}from"./chunk-CTCAF3YA.js";import{i as e}from"./chunk-3UW7VM4H.js";function l(t,s){let o=r(t,s);return e(t,o).map(({relativePath:n,...a})=>a)}export{l as a};
2
- //# sourceMappingURL=chunk-A3VNUGKJ.js.map