browserrig 0.1.0__tar.gz → 0.2.0__tar.gz

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 (471) hide show
  1. browserrig-0.2.0/.agents/skills/smelt/references/CHANGELOG.md +646 -0
  2. browserrig-0.2.0/.agents/skills/smelt/references/README.md +186 -0
  3. browserrig-0.2.0/.agents/skills/smelt/references/docs/adoption.md +103 -0
  4. browserrig-0.2.0/.agents/skills/smelt/references/docs/architecture.md +171 -0
  5. browserrig-0.2.0/.agents/skills/smelt/references/docs/cli.md +152 -0
  6. browserrig-0.2.0/.agents/skills/smelt/references/docs/configuration.md +299 -0
  7. browserrig-0.2.0/.agents/skills/smelt/references/docs/integrations.md +103 -0
  8. browserrig-0.2.0/.agents/skills/smelt/references/docs/rule-selection.md +102 -0
  9. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/README.md +71 -0
  10. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT101.md +40 -0
  11. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT102.md +38 -0
  12. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT103.md +39 -0
  13. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT104.md +39 -0
  14. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT105.md +38 -0
  15. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT106.md +39 -0
  16. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT107.md +36 -0
  17. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT108.md +38 -0
  18. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT109.md +41 -0
  19. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT301.md +40 -0
  20. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT302.md +33 -0
  21. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT305.md +39 -0
  22. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT306.md +47 -0
  23. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT307.md +41 -0
  24. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT308.md +38 -0
  25. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT309.md +37 -0
  26. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT310.md +35 -0
  27. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT311.md +37 -0
  28. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT312.md +39 -0
  29. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT313.md +43 -0
  30. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT314.md +39 -0
  31. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT315.md +45 -0
  32. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT316.md +47 -0
  33. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT317.md +45 -0
  34. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT318.md +43 -0
  35. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT319.md +38 -0
  36. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT320.md +47 -0
  37. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT321.md +36 -0
  38. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT322.md +41 -0
  39. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT323.md +42 -0
  40. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT324.md +53 -0
  41. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT325.md +34 -0
  42. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT326.md +42 -0
  43. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT327.md +43 -0
  44. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT328.md +44 -0
  45. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT329.md +42 -0
  46. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT330.md +43 -0
  47. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT331.md +37 -0
  48. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT332.md +37 -0
  49. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT333.md +44 -0
  50. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT334.md +43 -0
  51. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT335.md +47 -0
  52. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT336.md +34 -0
  53. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT401.md +37 -0
  54. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT420.md +38 -0
  55. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT421.md +38 -0
  56. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT422.md +39 -0
  57. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT423.md +38 -0
  58. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT424.md +38 -0
  59. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT425.md +38 -0
  60. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT426.md +38 -0
  61. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT427.md +39 -0
  62. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT428.md +40 -0
  63. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT429.md +48 -0
  64. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT430.md +58 -0
  65. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT431.md +42 -0
  66. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT901.md +33 -0
  67. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT902.md +33 -0
  68. browserrig-0.2.0/.agents/skills/smelt/references/docs/rules/SMT903.md +33 -0
  69. browserrig-0.2.0/.agents/skills/smelt/references/docs/structure.md +624 -0
  70. browserrig-0.2.0/.agents/skills/smelt/references/docs/testing.md +252 -0
  71. browserrig-0.2.0/.agents/skills/smelt/references/docs/upgrading.md +344 -0
  72. {browserrig-0.1.0 → browserrig-0.2.0}/.github/workflows/checks.yml +2 -2
  73. {browserrig-0.1.0 → browserrig-0.2.0}/.pre-commit-config.yml +0 -7
  74. {browserrig-0.1.0 → browserrig-0.2.0}/.smelt/debt.json +18 -18
  75. {browserrig-0.1.0 → browserrig-0.2.0}/.smelt.schema.json +375 -1
  76. browserrig-0.2.0/CHANGELOG.md +237 -0
  77. browserrig-0.2.0/PKG-INFO +270 -0
  78. browserrig-0.1.0/PKG-INFO → browserrig-0.2.0/README.md +95 -62
  79. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/__init__.py +45 -13
  80. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/activity/plugin.py +23 -18
  81. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/agent.py +12 -10
  82. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/__init__.py +6 -0
  83. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/base.py +7 -13
  84. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/chrome.py +42 -27
  85. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/config.py +20 -11
  86. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/downloads.py +48 -24
  87. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/favicon.py +1 -2
  88. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/frame.py +21 -5
  89. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/frames.py +19 -14
  90. browserrig-0.2.0/browserrig/browser/guard.py +203 -0
  91. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/images.py +9 -1
  92. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/input.py +2 -0
  93. browserrig-0.2.0/browserrig/browser/network.py +77 -0
  94. browserrig-0.2.0/browserrig/browser/overlays.py +193 -0
  95. browserrig-0.2.0/browserrig/browser/plugin.py +131 -0
  96. browserrig-0.2.0/browserrig/browser/policy.py +19 -0
  97. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/process.py +1 -1
  98. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/tab.py +39 -9
  99. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/tabs.py +101 -13
  100. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/worlds.py +1 -2
  101. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/choreography/__init__.py +8 -0
  102. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/choreography/events.py +69 -2
  103. browserrig-0.2.0/browserrig/choreography/images.py +21 -0
  104. browserrig-0.2.0/browserrig/choreography/plugin.py +398 -0
  105. browserrig-0.2.0/browserrig/choreography/projection.py +214 -0
  106. browserrig-0.2.0/browserrig/choreography/receipts.py +109 -0
  107. browserrig-0.2.0/browserrig/choreography/renderer.py +101 -0
  108. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/choreography/stage.py +14 -10
  109. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/choreography/tabstrip.py +7 -9
  110. browserrig-0.2.0/browserrig/choreography/view.css +841 -0
  111. browserrig-0.2.0/browserrig/choreography/view.html +68 -0
  112. browserrig-0.2.0/browserrig/choreography/work.py +264 -0
  113. browserrig-0.2.0/browserrig/completion/__init__.py +3 -0
  114. browserrig-0.2.0/browserrig/completion/models.py +43 -0
  115. browserrig-0.2.0/browserrig/completion/output.py +73 -0
  116. browserrig-0.1.0/browserrig/completion.py → browserrig-0.2.0/browserrig/completion/plugin.py +73 -81
  117. browserrig-0.2.0/browserrig/completion/state.py +8 -0
  118. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/composition.py +29 -18
  119. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/core/__init__.py +7 -2
  120. browserrig-0.2.0/browserrig/core/coordination.py +30 -0
  121. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/core/kinds.py +12 -0
  122. browserrig-0.2.0/browserrig/core/tools.py +93 -0
  123. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/events.py +70 -5
  124. browserrig-0.2.0/browserrig/files/__init__.py +43 -0
  125. browserrig-0.2.0/browserrig/files/bridge.py +137 -0
  126. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/config.py +4 -4
  127. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/content.py +2 -2
  128. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/data.py +0 -22
  129. browserrig-0.2.0/browserrig/files/extras.py +10 -0
  130. browserrig-0.2.0/browserrig/files/formats.py +90 -0
  131. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/imaging.py +17 -4
  132. browserrig-0.2.0/browserrig/files/media.py +23 -0
  133. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/models.py +5 -3
  134. browserrig-0.2.0/browserrig/files/plugin.py +50 -0
  135. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/reading.py +55 -5
  136. browserrig-0.2.0/browserrig/files/system.py +206 -0
  137. browserrig-0.2.0/browserrig/files/transfer.py +89 -0
  138. browserrig-0.2.0/browserrig/files/workspace.py +146 -0
  139. browserrig-0.2.0/browserrig/guardrails/__init__.py +3 -0
  140. browserrig-0.2.0/browserrig/guardrails/domains.py +127 -0
  141. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/handoff/models.py +4 -4
  142. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/handoff/plugin.py +81 -50
  143. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/handoff/state.py +3 -0
  144. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/input/controller.py +5 -1
  145. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/input/keyboard.py +54 -101
  146. browserrig-0.2.0/browserrig/input/keys.py +158 -0
  147. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/input/mouse.py +49 -7
  148. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/input/presenter.py +23 -5
  149. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/input/target.py +1 -0
  150. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/kinds.py +2 -0
  151. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/nudges/plugin.py +20 -12
  152. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/__init__.py +8 -2
  153. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/capture.py +138 -38
  154. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/changes.py +4 -0
  155. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/content.py +49 -10
  156. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/delta.py +6 -2
  157. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/dom.py +3 -1
  158. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/extraction/__init__.py +51 -13
  159. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/extraction/accessibility.py +4 -0
  160. browserrig-0.2.0/browserrig/observation/extraction/cookies.py +202 -0
  161. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/extraction/document.py +38 -0
  162. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/extraction/elements.py +123 -19
  163. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/extraction/semantics.py +12 -0
  164. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/find.py +1 -1
  165. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/handle.py +6 -0
  166. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/images.py +28 -9
  167. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/marks.py +3 -0
  168. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/models.py +38 -6
  169. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/plugin.py +97 -32
  170. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/render.py +69 -4
  171. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/renderer.py +14 -4
  172. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/state.py +7 -3
  173. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/pacing/plugin.py +5 -5
  174. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/__init__.py +3 -0
  175. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/downloads.py +2 -2
  176. browserrig-0.2.0/browserrig/readiness/network.py +99 -0
  177. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/plugin.py +24 -14
  178. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/policies.py +2 -0
  179. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/state.py +2 -2
  180. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/wait.py +35 -3
  181. browserrig-0.2.0/browserrig/recording/__init__.py +4 -0
  182. browserrig-0.2.0/browserrig/recording/capture.py +64 -0
  183. browserrig-0.2.0/browserrig/recording/editing.py +120 -0
  184. browserrig-0.2.0/browserrig/recording/models.py +27 -0
  185. browserrig-0.2.0/browserrig/recording/plugin.py +195 -0
  186. browserrig-0.2.0/browserrig/recording/timeline.py +67 -0
  187. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/README.md +9 -0
  188. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/__init__.py +40 -4
  189. browserrig-0.2.0/browserrig/scripts/choreography.js +36 -0
  190. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/content.js +12 -1
  191. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/element.js +13 -0
  192. browserrig-0.2.0/browserrig/scripts/file_input.js +12 -0
  193. browserrig-0.2.0/browserrig/scripts/lib/choreography/caption.js +148 -0
  194. browserrig-0.2.0/browserrig/scripts/lib/choreography/cursor.js +302 -0
  195. browserrig-0.2.0/browserrig/scripts/lib/choreography/keyboard.js +136 -0
  196. browserrig-0.2.0/browserrig/scripts/lib/choreography/panels.js +131 -0
  197. browserrig-0.2.0/browserrig/scripts/lib/choreography/surface.js +90 -0
  198. browserrig-0.2.0/browserrig/scripts/lib/choreography/transfers.js +140 -0
  199. browserrig-0.2.0/browserrig/scripts/lib/choreography/work.js +225 -0
  200. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/models.py +21 -0
  201. browserrig-0.2.0/browserrig/scripts/overlay.js +56 -0
  202. browserrig-0.2.0/browserrig/scripts/overlay_message.js +5 -0
  203. browserrig-0.2.0/browserrig/scripts/overlay_styles.js +14 -0
  204. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/stability.js +26 -2
  205. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/secrets/plugin.py +10 -13
  206. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/terminal.py +5 -2
  207. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/__init__.py +2 -1
  208. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/chains.py +10 -5
  209. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/dialogs.py +7 -6
  210. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/effects.py +2 -0
  211. browserrig-0.2.0/browserrig/tools/execution/__init__.py +3 -0
  212. browserrig-0.2.0/browserrig/tools/execution/completion.py +124 -0
  213. browserrig-0.2.0/browserrig/tools/execution/context.py +56 -0
  214. browserrig-0.2.0/browserrig/tools/execution/invocation.py +66 -0
  215. browserrig-0.2.0/browserrig/tools/execution/plugin.py +179 -0
  216. browserrig-0.2.0/browserrig/tools/execution/policy.py +65 -0
  217. browserrig-0.2.0/browserrig/tools/execution/transaction.py +250 -0
  218. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/files.py +147 -102
  219. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/find.py +20 -22
  220. browserrig-0.2.0/browserrig/tools/forms.py +79 -0
  221. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/intents.py +2 -2
  222. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/javascript.py +8 -11
  223. browserrig-0.2.0/browserrig/tools/keyboard.py +136 -0
  224. browserrig-0.2.0/browserrig/tools/mouse.py +279 -0
  225. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/navigation.py +60 -85
  226. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/scrolling.py +3 -0
  227. browserrig-0.2.0/browserrig/tools/tabs.py +60 -0
  228. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/tools/targeting.py +11 -4
  229. {browserrig-0.1.0 → browserrig-0.2.0}/docs/agent-guide.md +162 -71
  230. browserrig-0.2.0/docs/browser-choreography.md +148 -0
  231. {browserrig-0.1.0 → browserrig-0.2.0}/docs/browser-composition.md +276 -24
  232. {browserrig-0.1.0 → browserrig-0.2.0}/docs/browser-interaction.md +94 -28
  233. {browserrig-0.1.0 → browserrig-0.2.0}/docs/development.md +42 -15
  234. {browserrig-0.1.0 → browserrig-0.2.0}/docs/files-and-events.md +196 -46
  235. {browserrig-0.1.0 → browserrig-0.2.0}/docs/harnessed-telemetry-feedback.md +9 -1
  236. {browserrig-0.1.0 → browserrig-0.2.0}/docs/human-handoff.md +36 -13
  237. browserrig-0.2.0/docs/media/choreography/compact.png +0 -0
  238. browserrig-0.2.0/docs/media/choreography/demo.mp4 +0 -0
  239. browserrig-0.2.0/docs/media/choreography/files.png +0 -0
  240. browserrig-0.2.0/docs/media/choreography/find.png +0 -0
  241. browserrig-0.2.0/docs/media/choreography/keyboard.png +0 -0
  242. browserrig-0.2.0/docs/media/choreography/navigation.png +0 -0
  243. browserrig-0.2.0/docs/media/choreography/observation.png +0 -0
  244. browserrig-0.2.0/docs/media/choreography/overview.png +0 -0
  245. browserrig-0.2.0/docs/media/choreography/pointer.png +0 -0
  246. browserrig-0.2.0/docs/media/choreography/scroll.png +0 -0
  247. browserrig-0.2.0/docs/media/choreography/tabs.png +0 -0
  248. browserrig-0.2.0/docs/media/choreography/thinking.png +0 -0
  249. {browserrig-0.1.0 → browserrig-0.2.0}/docs/telemetry.md +130 -36
  250. browserrig-0.2.0/evals/README.md +71 -0
  251. {browserrig-0.1.0 → browserrig-0.2.0}/examples/connect_browser.py +2 -1
  252. {browserrig-0.1.0 → browserrig-0.2.0}/examples/controls.py +5 -4
  253. {browserrig-0.1.0 → browserrig-0.2.0}/examples/direct_browser.py +2 -1
  254. {browserrig-0.1.0 → browserrig-0.2.0}/examples/openai_agent.py +19 -5
  255. {browserrig-0.1.0 → browserrig-0.2.0}/examples/session_store.py +5 -9
  256. {browserrig-0.1.0 → browserrig-0.2.0}/examples/telemetry.py +12 -2
  257. {browserrig-0.1.0 → browserrig-0.2.0}/examples/tracing_smoke.py +3 -2
  258. browserrig-0.2.0/examples/visualization.html +54 -0
  259. browserrig-0.2.0/examples/visualization.py +89 -0
  260. browserrig-0.2.0/examples/visualization_gallery.py +57 -0
  261. browserrig-0.2.0/examples/visualization_run.py +257 -0
  262. browserrig-0.2.0/examples/visualization_server.py +68 -0
  263. {browserrig-0.1.0 → browserrig-0.2.0}/pyproject.toml +19 -12
  264. {browserrig-0.1.0 → browserrig-0.2.0}/smelt.yml +30 -2
  265. browserrig-0.2.0/tests/activity/__init__.py +0 -0
  266. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/activity}/test_activity.py +10 -6
  267. browserrig-0.2.0/tests/browser/__init__.py +0 -0
  268. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/browser}/test_chrome.py +38 -3
  269. browserrig-0.2.0/tests/browser/test_plugin.py +158 -0
  270. browserrig-0.1.0/tests/test_javascript.py → browserrig-0.2.0/tests/browser/test_tab.py +2 -1
  271. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/browser}/test_tab_state.py +2 -2
  272. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/browser}/test_worlds.py +1 -1
  273. {browserrig-0.1.0 → browserrig-0.2.0}/tests/check_distribution.py +31 -4
  274. {browserrig-0.1.0 → browserrig-0.2.0}/tests/check_file_corpus.py +7 -6
  275. browserrig-0.2.0/tests/choreography/__init__.py +0 -0
  276. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/choreography}/test_choreography.py +46 -34
  277. browserrig-0.2.0/tests/choreography/test_plugin_work.py +86 -0
  278. browserrig-0.2.0/tests/choreography/test_projection.py +41 -0
  279. browserrig-0.2.0/tests/choreography/test_receipts.py +84 -0
  280. browserrig-0.2.0/tests/choreography/test_work.py +104 -0
  281. browserrig-0.2.0/tests/completion/__init__.py +0 -0
  282. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/completion}/test_completion.py +108 -28
  283. {browserrig-0.1.0 → browserrig-0.2.0}/tests/conftest.py +13 -0
  284. browserrig-0.2.0/tests/core/__init__.py +0 -0
  285. browserrig-0.2.0/tests/core/test_coordination.py +47 -0
  286. {browserrig-0.1.0 → browserrig-0.2.0}/tests/fakes.py +61 -21
  287. browserrig-0.2.0/tests/files/__init__.py +0 -0
  288. browserrig-0.1.0/tests/test_file_readers.py → browserrig-0.2.0/tests/files/test_reading.py +85 -53
  289. browserrig-0.1.0/tests/test_archive_input_limit.py → browserrig-0.2.0/tests/files/test_reading_archive_input_limit.py +9 -4
  290. browserrig-0.1.0/tests/test_extraction_budget.py → browserrig-0.2.0/tests/files/test_reading_extraction_budget.py +7 -3
  291. browserrig-0.2.0/tests/guardrails/test_domains.py +83 -0
  292. browserrig-0.2.0/tests/guardrails/test_domains_tools.py +60 -0
  293. browserrig-0.2.0/tests/handoff/__init__.py +0 -0
  294. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/handoff}/test_handoff.py +165 -62
  295. browserrig-0.2.0/tests/input/__init__.py +0 -0
  296. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/input}/test_input.py +103 -31
  297. browserrig-0.2.0/tests/integration/__init__.py +0 -0
  298. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_agent_facade_integration.py +67 -19
  299. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_agent_integration.py +18 -15
  300. browserrig-0.2.0/tests/integration/test_allowed_domains_integration.py +215 -0
  301. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_attached_context_integration.py +2 -1
  302. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_browser_integration.py +24 -5
  303. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_chains_integration.py +65 -11
  304. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_content_integration.py +5 -2
  305. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_controls_integration.py +34 -15
  306. browserrig-0.2.0/tests/integration/test_cookies_integration.py +213 -0
  307. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_download_integration.py +233 -40
  308. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_elements_integration.py +2 -1
  309. browserrig-0.2.0/tests/integration/test_extraction_context_integration.py +244 -0
  310. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_find_integration.py +4 -4
  311. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_frames_integration.py +58 -11
  312. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_gestures_integration.py +15 -12
  313. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_input_integration.py +142 -16
  314. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_javascript_integration.py +6 -6
  315. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_navigation_integration.py +3 -4
  316. browserrig-0.2.0/tests/integration/test_new_tab_integration.py +89 -0
  317. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_observation_integration.py +39 -22
  318. browserrig-0.2.0/tests/integration/test_overlays_integration.py +294 -0
  319. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_readiness_integration.py +15 -17
  320. browserrig-0.2.0/tests/integration/test_recording_integration.py +249 -0
  321. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_references_integration.py +8 -8
  322. browserrig-0.2.0/tests/integration/test_reveal_actions_integration.py +292 -0
  323. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_scripts_integration.py +2 -1
  324. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_secret_javascript_guard_integration.py +7 -1
  325. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_secret_screenshots_integration.py +2 -1
  326. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_secrets_integration.py +13 -11
  327. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_tab_state_integration.py +5 -6
  328. browserrig-0.2.0/tests/integration/test_tracing_integration.py +94 -0
  329. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/integration}/test_viewport_integration.py +41 -17
  330. browserrig-0.2.0/tests/integration/test_visualization_integration.py +390 -0
  331. browserrig-0.2.0/tests/nudges/__init__.py +0 -0
  332. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/nudges}/test_nudges.py +18 -17
  333. browserrig-0.2.0/tests/observation/__init__.py +0 -0
  334. browserrig-0.2.0/tests/observation/test_capture.py +255 -0
  335. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/observation}/test_delta.py +21 -0
  336. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/observation}/test_models.py +50 -4
  337. browserrig-0.2.0/tests/observation/test_plugin.py +64 -0
  338. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/observation}/test_references.py +18 -23
  339. browserrig-0.2.0/tests/project/__init__.py +0 -0
  340. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/project}/test_architecture.py +1 -1
  341. browserrig-0.2.0/tests/project/test_documentation.py +39 -0
  342. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/project}/test_optional_defaults.py +4 -4
  343. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/project}/test_telemetry.py +124 -2
  344. browserrig-0.2.0/tests/readiness/__init__.py +0 -0
  345. browserrig-0.2.0/tests/readiness/test_network.py +199 -0
  346. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/readiness}/test_readiness.py +32 -15
  347. browserrig-0.2.0/tests/recording/__init__.py +0 -0
  348. browserrig-0.2.0/tests/recording/test_recording.py +407 -0
  349. browserrig-0.2.0/tests/scripts/__init__.py +0 -0
  350. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/scripts}/test_scripts.py +10 -2
  351. browserrig-0.2.0/tests/secrets/__init__.py +0 -0
  352. browserrig-0.1.0/tests/test_secret_javascript_guard.py → browserrig-0.2.0/tests/secrets/test_plugin_javascript_guard.py +1 -1
  353. browserrig-0.1.0/tests/test_secret_screenshots.py → browserrig-0.2.0/tests/secrets/test_redaction_screenshots.py +6 -2
  354. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/secrets}/test_secrets.py +19 -11
  355. browserrig-0.1.0/tests/test_session_store.py → browserrig-0.2.0/tests/test_agent_session_store.py +85 -12
  356. {browserrig-0.1.0 → browserrig-0.2.0}/tests/test_composition.py +30 -16
  357. browserrig-0.1.0/tests/test_browser_composition.py → browserrig-0.2.0/tests/test_composition_browser.py +131 -48
  358. browserrig-0.1.0/tests/test_dependencies.py → browserrig-0.2.0/tests/test_composition_dependencies.py +198 -72
  359. browserrig-0.1.0/tests/test_kit.py → browserrig-0.2.0/tests/test_composition_pack.py +69 -53
  360. {browserrig-0.1.0 → browserrig-0.2.0}/tests/test_events.py +28 -1
  361. {browserrig-0.1.0 → browserrig-0.2.0}/tests/test_terminal.py +25 -1
  362. browserrig-0.2.0/tests/tools/__init__.py +0 -0
  363. browserrig-0.2.0/tests/tools/execution/__init__.py +0 -0
  364. browserrig-0.2.0/tests/tools/execution/test_invocation.py +146 -0
  365. browserrig-0.1.0/tests/test_actions.py → browserrig-0.2.0/tests/tools/execution/test_transaction.py +66 -15
  366. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/tools}/test_chains.py +24 -50
  367. browserrig-0.2.0/tests/tools/test_files.py +770 -0
  368. browserrig-0.2.0/tests/tools/test_mouse.py +210 -0
  369. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/tools}/test_navigation.py +17 -14
  370. {browserrig-0.1.0 → browserrig-0.2.0}/uv.lock +310 -95
  371. browserrig-0.1.0/CHANGELOG.md +0 -27
  372. browserrig-0.1.0/README.md +0 -124
  373. browserrig-0.1.0/browserrig/browser/plugin.py +0 -44
  374. browserrig-0.1.0/browserrig/choreography/plugin.py +0 -75
  375. browserrig-0.1.0/browserrig/core/tools.py +0 -32
  376. browserrig-0.1.0/browserrig/files/__init__.py +0 -25
  377. browserrig-0.1.0/browserrig/files/formats.py +0 -84
  378. browserrig-0.1.0/browserrig/files/system.py +0 -204
  379. browserrig-0.1.0/browserrig/tools/execution.py +0 -333
  380. browserrig-0.1.0/browserrig/tools/forms.py +0 -76
  381. browserrig-0.1.0/browserrig/tools/keyboard.py +0 -126
  382. browserrig-0.1.0/browserrig/tools/mouse.py +0 -224
  383. browserrig-0.1.0/browserrig/tools/tabs.py +0 -81
  384. browserrig-0.1.0/tests/test_capture.py +0 -82
  385. browserrig-0.1.0/tests/test_files.py +0 -460
  386. {browserrig-0.1.0 → browserrig-0.2.0}/.env.example +0 -0
  387. {browserrig-0.1.0 → browserrig-0.2.0}/.gitattributes +0 -0
  388. {browserrig-0.1.0 → browserrig-0.2.0}/.github/workflows/release.yml +0 -0
  389. {browserrig-0.1.0 → browserrig-0.2.0}/.gitignore +0 -0
  390. {browserrig-0.1.0 → browserrig-0.2.0}/.prettierignore +0 -0
  391. {browserrig-0.1.0 → browserrig-0.2.0}/.prettierrc.json +0 -0
  392. {browserrig-0.1.0 → browserrig-0.2.0}/LICENSE +0 -0
  393. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/activity/__init__.py +0 -0
  394. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/activity/models.py +0 -0
  395. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/activity/state.py +0 -0
  396. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/models.py +0 -0
  397. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/browser/setup.py +0 -0
  398. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/choreography/scenes.py +0 -0
  399. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/core/errors.py +0 -0
  400. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/core/geometry.py +0 -0
  401. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/core/ids.py +0 -0
  402. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/core/options.py +0 -0
  403. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/containers.py +0 -0
  404. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/documents.py +0 -0
  405. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/kinds.py +0 -0
  406. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/spreadsheets.py +0 -0
  407. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/text.py +0 -0
  408. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/files/xlsx.py +0 -0
  409. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/handoff/__init__.py +0 -0
  410. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/handoff/changes.py +0 -0
  411. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/input/__init__.py +0 -0
  412. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/input/motor.py +0 -0
  413. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/input/pointer.py +0 -0
  414. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/input/wheel.py +0 -0
  415. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/nudges/__init__.py +0 -0
  416. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/nudges/state.py +0 -0
  417. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/config.py +0 -0
  418. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/extraction/styles.py +0 -0
  419. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/extraction/visibility.py +0 -0
  420. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/redirects.py +0 -0
  421. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/observation/references.py +0 -0
  422. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/pacing/__init__.py +0 -0
  423. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/py.typed +0 -0
  424. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/config.py +0 -0
  425. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/dom.py +0 -0
  426. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/hooks.py +0 -0
  427. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/models.py +0 -0
  428. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/readiness/strategy.py +0 -0
  429. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/cursor.js +0 -0
  430. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/find.js +0 -0
  431. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/focused.js +0 -0
  432. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/lib/composed.js +0 -0
  433. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/lib/elements.js +0 -0
  434. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/lib/geometry.js +0 -0
  435. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/lib/hit.js +0 -0
  436. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/lib/markdown.js +0 -0
  437. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/lib/scroll.js +0 -0
  438. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/lib/secret.js +0 -0
  439. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/lib/visibility.js +0 -0
  440. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/owner_hits.js +0 -0
  441. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/owner_scroll.js +0 -0
  442. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/owner_size.js +0 -0
  443. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/page_facts.js +0 -0
  444. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/reset.js +0 -0
  445. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/scroll.js +0 -0
  446. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/secret_field.js +0 -0
  447. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/secret_focus.js +0 -0
  448. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/seed.js +0 -0
  449. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/tab_strip.js +0 -0
  450. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/scripts/viewport.js +0 -0
  451. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/secrets/__init__.py +0 -0
  452. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/secrets/models.py +0 -0
  453. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/secrets/origin.py +0 -0
  454. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/secrets/redaction.py +0 -0
  455. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/secrets/state.py +0 -0
  456. {browserrig-0.1.0 → browserrig-0.2.0}/browserrig/secrets/totp.py +0 -0
  457. {browserrig-0.1.0 → browserrig-0.2.0}/compose.yml +0 -0
  458. {browserrig-0.1.0 → browserrig-0.2.0}/eslint.config.mjs +0 -0
  459. {browserrig-0.1.0 → browserrig-0.2.0}/examples/__init__.py +0 -0
  460. {browserrig-0.1.0 → browserrig-0.2.0}/package.json +0 -0
  461. {browserrig-0.1.0 → browserrig-0.2.0}/pnpm-lock.yaml +0 -0
  462. {browserrig-0.1.0 → browserrig-0.2.0}/tests/__init__.py +0 -0
  463. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/browser}/test_process.py +0 -0
  464. {browserrig-0.1.0 → browserrig-0.2.0}/tests/check_release.py +0 -0
  465. {browserrig-0.1.0 → browserrig-0.2.0}/tests/file_corpus.json +0 -0
  466. {browserrig-0.1.0 → browserrig-0.2.0}/tests/javascript.py +0 -0
  467. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/observation}/test_marks.py +0 -0
  468. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/observation}/test_redirects.py +0 -0
  469. {browserrig-0.1.0 → browserrig-0.2.0}/tests/observations.py +0 -0
  470. {browserrig-0.1.0/tests → browserrig-0.2.0/tests/project}/test_release.py +0 -0
  471. /browserrig-0.1.0/tests/test_secret_unicode.py → /browserrig-0.2.0/tests/secrets/test_redaction_unicode.py +0 -0
@@ -0,0 +1,646 @@
1
+ # Changelog
2
+
3
+ User-visible changes, newest first. Agents should read the latest release's
4
+ migration notes before interpreting fewer findings as an improvement. For the
5
+ current configuration and complete rule contracts, see the [README](README.md),
6
+ [rule catalog](docs/rules/README.md) and [activation guide](docs/rule-selection.md).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.6.0] - 2026-11-08
11
+
12
+ Report schema 2, YAML version 1, grouped debt baseline version 2 and the default
13
+ rule set remain unchanged. The six new rules SMT331–SMT336 are opt-in; canonical
14
+ filename checks activate through explicit file-naming policy. Existing individual
15
+ rule selections remain valid. New `init --maintainability` configurations select
16
+ `information-hiding`, adding SMT320 and SMT335 to the previous starter policy.
17
+ Update installation, hook and CI pins together to `0.6.0` (`v0.6.0`), refresh the
18
+ editor schema and review findings before changing debt. No baseline rewrite is
19
+ required for this upgrade. See the [upgrade checklist](docs/upgrading.md#050-to-060).
20
+
21
+ - Optional [SMT336](docs/rules/SMT336.md) reviews module filenames that repeat an
22
+ ancestor package, such as `cars/application/car_exporter.py`. Enable
23
+ `rules: {redundant-module-name: hint}`. Whole-name prefixes/suffixes and simple
24
+ trailing-s plurals are recognized; occupied shorter names are not suggested.
25
+ Renames and import updates remain manual. Implements
26
+ [#94](https://github.com/mathisarends/smelt/issues/94).
27
+
28
+ - Enable the five public-API reviews together with
29
+ `rules: {information-hiding: warning}` (SMT316/SMT320/SMT335/SMT429/SMT430).
30
+ Tests alone do not justify public visibility. Individual entries override the
31
+ group in the same map regardless of order; closer package settings still win.
32
+ The group works with CLI selection/ignores and scoped ignores, and is exposed
33
+ in `explain`, catalog JSON and the editor schema. Existing names, codes,
34
+ suppressions and debt identities remain valid. `init --maintainability` now
35
+ writes this group, adding the module-symbol and attribute reviews to its
36
+ generated selection. See [scope and migration](docs/rule-selection.md#information-hiding).
37
+
38
+ - Optional [SMT335](docs/rules/SMT335.md) reviews public instance and class data
39
+ attributes with no observed access outside their class. Enable
40
+ `rules: {internal-public-attribute: warning}`. Test access preserves visibility
41
+ without duplicating SMT430; exports and uncertain inheritance/framework
42
+ contracts remain protected. Renames stay manual. Implements
43
+ [#96](https://github.com/mathisarends/smelt/issues/96).
44
+
45
+ - Ship the official `smelt` agent skill with every wheel and source distribution,
46
+ including the complete offline rule, configuration and CLI reference. Install
47
+ with `smelt skill install`; refresh after upgrading with `--force`, which
48
+ replaces local edits and obsolete references. Use `--destination` to choose
49
+ another skill directory. See [agent skill installation](docs/cli.md#agent-skill).
50
+ Generated references are checked for drift in CI and release validation with
51
+ `python scripts/generate.py --check`. The bundle contains consumer guides and
52
+ rule pages; benchmark/evaluation data and maintainer documents stay in the repo.
53
+
54
+ - Optional [SMT334](docs/rules/SMT334.md) reviews private literal constants such
55
+ as `DownloadController._DOWNLOADABLE_EXTENSIONS` for placement at module scope.
56
+ Enable `rules: {private-class-constant: error}` to block them. Inherited and
57
+ decorated classes retain their attribute contracts; moves and reference updates
58
+ remain manual. Implements [#82](https://github.com/mathisarends/smelt/issues/82).
59
+
60
+ - Optional [SMT333](docs/rules/SMT333.md), enabled with
61
+ `rules: {prefer-callable-instance: hint}`, reviews classes with one public
62
+ instance method for `__call__` and an operation-based class name. Findings keep
63
+ constructor and call-time signatures separate. Existing callable APIs,
64
+ inheritance and decorated/protocol classes remain valid; no automatic rename.
65
+
66
+ - Declare canonical YAML extensions and Compose basenames once with
67
+ `structure.file_naming: {yaml_extension: yaml, compose_basename: compose}`.
68
+ [SMT331](docs/rules/SMT331.md) and [SMT332](docs/rules/SMT332.md) flag other
69
+ spellings throughout the project, including hidden configuration directories
70
+ and dotted Compose variants. Policies are optional, respect exclusions and
71
+ support staged checks; renames and reference updates remain manual.
72
+ Staged checks reuse YAML candidates from native Git-index capture, with an
73
+ independent flat-inventory fallback, instead of walking virtual directories.
74
+
75
+ ## [0.5.0] - 2026-11-02
76
+
77
+ Report schema 2, YAML version 1 and the default rule set remain unchanged.
78
+ Debt writes now use grouped baseline version 2, which older Smelt versions cannot
79
+ read. Existing version-1 baselines remain readable; unscoped SMT321 debt needs
80
+ review and explicit re-recording. Update installation, hook and CI pins together
81
+ to `0.5.0` (`v0.5.0`) before rewriting baselines, and refresh the editor schema.
82
+ See the [upgrade checklist](docs/upgrading.md#040-to-050).
83
+
84
+ - Contributor checks now require an issue/ticket reference for TODO comments
85
+ through Ruff TD003. Tracked TODOs remain allowed; Smelt's rule catalog is unchanged.
86
+
87
+ - Document SMT317's activation and developer-facing extraction evidence with
88
+ concrete query-helper regressions. Inherited-class exclusions and the existing
89
+ advisory behavior are preserved; no duplicate static-method rule is added.
90
+
91
+ - Optional SMT329 (`rules: {caller-before-callee: hint}`) reviews step-down reading
92
+ order for direct same-visibility functions and ordinary methods. Recursive,
93
+ shadowed and definition-time-dependent pairs are retained; SMT313's public-first
94
+ categories take precedence. No definitions are moved automatically.
95
+
96
+ - Optional SMT328 (`rules: {redundant-dishka-provider: hint}`) reviews Dishka
97
+ provider methods that only forward dependencies to a constructor. Findings
98
+ include a direct registration candidate with recognized decorator options.
99
+ Resource factories and additional logic remain valid; no automatic rewrite.
100
+
101
+ - Optional SMT327 (`rules: {secret-settings-field: warning}`) reviews secret-named
102
+ Pydantic settings fields accepting plain `str`/`bytes`, including optional and
103
+ annotated types. Correct secret types and nonsecret names remain valid.
104
+ Findings omit default values; no annotations or consumers are rewritten.
105
+
106
+ - Optional SMT326 (`rules: {no-base-class-suffix: error}`) reviews class definitions
107
+ such as `_MessageBase`. SMT323 retains its existing prefix semantics. Imports,
108
+ aliases and test classes remain outside scope; no automatic rename.
109
+
110
+ - Optional SMT330 (`rules: {package-only-dunder-all: error}`) restricts module
111
+ `__all__` declarations to package `__init__.py` files. Package overrides and
112
+ reasoned suppressions retain deliberate compatibility exports; no automatic move.
113
+
114
+ - Optional SMT431 (`rules: {nondeterministic-test-data: warning}`) reviews known
115
+ random/UUID data generators in tests and fixtures. Prefer fixed test inputs or
116
+ seeded local generators; intentional randomness tests can retain reasoned
117
+ suppressions. Production generators are unaffected; no automatic rewrite.
118
+
119
+ - SMT108 now reviews mixed package-facade and implementation imports with
120
+ `bundle_imports_at: 2`, includes missing export proposals and blocks bundling
121
+ advice when proposed caller/facade edges close a known runtime import cycle.
122
+
123
+ - Debt baselines now write grouped JSON version 2: repeated rule/path/message
124
+ metadata appears once, while every accepted fingerprint and duplicate occurrence
125
+ remains available for matching. Version-1 files remain readable; `smelt debt
126
+ --prune` upgrades assessed entries without accepting new debt. Use `smelt debt
127
+ --show [PATHS]` for a compact, read-only baseline summary, or add `--format json`
128
+ for the grouped data. [SMT321](docs/rules/SMT321.md) now distinguishes enclosing
129
+ functions in debt and changed checks, so fixing one function cannot silently
130
+ accept an identical new violation in another. Old unscoped SMT321 debt requires
131
+ review and explicit re-recording. See [adoption](docs/adoption.md).
132
+
133
+ - Package contracts now support `module_docstrings: require`, activating
134
+ [SMT325](docs/rules/SMT325.md) `missing-module-docstring` for every analyzed
135
+ production module, including empty package initializers. Empty/blank docstrings
136
+ do not satisfy the requirement. Choose `forbid` for the existing
137
+ [SMT309](docs/rules/SMT309.md) convention; use a reasoned file suppression or an
138
+ explicit nested `allow` policy for exceptions. Defaults remain unchanged.
139
+
140
+ - Optional [SMT324](docs/rules/SMT324.md), enabled with
141
+ `rules: {prefer-str-enum-discriminator: hint}`, reviews single-string `Literal`
142
+ fields named `type`, `kind` or `tag` for shared `StrEnum` members. Keep narrow
143
+ `Literal[EventType.MEMBER]` annotations and matching enum defaults. This syntax
144
+ review does not prove union membership or rewrite code; Python targets before
145
+ 3.11 and general multi-value Literals remain unchanged.
146
+
147
+ ## [0.4.0] - 2026-11-01
148
+
149
+ Report schema 2, YAML version 1 and the default rule set remain unchanged.
150
+ Custom rules must update `BaseRule` imports to `Rule` and annotations for the
151
+ former `Rule` protocol to `RuleContract`. Update installation, hook and CI pins
152
+ together to `0.4.0` (`v0.4.0`) and refresh the editor schema. See the
153
+ [upgrade checklist](docs/upgrading.md#030-to-040).
154
+
155
+ - Use `.yml` consistently in configuration examples, fixtures and maintainer
156
+ scripts. `smelt init` now creates `smelt.yml`, which takes precedence when both
157
+ supported filenames exist. Existing `smelt.yaml` files still work. The published
158
+ `.pre-commit-hooks.yaml` manifest retains its required filename. Integration
159
+ instructions consistently use prek.
160
+
161
+ - Optional [SMT323](docs/rules/SMT323.md), enabled with
162
+ `rules: {no-base-class-prefix: error}`, rejects class definitions such as
163
+ `BaseRepository` and `_BaseRepository` in favor of responsibility-based names.
164
+ Imports, third-party inheritance, `Baseline` and `Base64` remain valid. Package
165
+ rule overrides can disable the convention; checks never rename symbols.
166
+ Smelt enables the convention for its own sources; the default set is unchanged.
167
+ - Smelt also enables the opt-in `deep-object-navigation` Law of Demeter review
168
+ for its own sources. Facade analysis receives its file inventory directly,
169
+ and filesystem/Python-target analysis receives its source store explicitly.
170
+ SMT322 recognizes statically evidenced module/data namespaces and known value
171
+ APIs, preserving unknown collaborator findings. Changes to imported record
172
+ definitions are considered on every check; no code is executed or rewritten.
173
+ Unproven namespaces remain advisory review candidates, with known receiver
174
+ types and the unresolved step included for agent API-contract review. A finding
175
+ alone does not require an architecture change.
176
+ - Rule implementations now inherit `smelt.rules.base.Rule` instead of `BaseRule`.
177
+ The former structural `Rule` protocol is named `RuleContract`; lazy rule
178
+ implementations retain the same interface. Update custom rule imports and
179
+ type annotations accordingly.
180
+ - Independent workspaces can share a local policy fragment with `extends` and
181
+ explicit child overrides. Mappings merge; lists replace, including `[]`.
182
+ Project paths remain relative to the selected workspace. `config show --sources`
183
+ explains effective inputs and origins; staged checks and cache dependencies
184
+ include all bases. Both published hooks now run on every commit, including
185
+ policy-only edits. See [shared configuration](docs/configuration.md#shared-local-policy).
186
+
187
+ - New opt-in [SMT322](docs/rules/SMT322.md) `deep-object-navigation` reviews
188
+ method calls reached through multiple stored instance attributes, such as
189
+ `self.browser.input.motor().aim()`. Enable with
190
+ `rules: {deep-object-navigation: hint}` or `--select SMT322`; package rule
191
+ overrides and inline suppressions preserve intentional navigation. Direct
192
+ collaborator calls, pure data reads and direct-collaborator fluent chains
193
+ remain quiet. This bounded syntax review has no automatic rewrite.
194
+ - [SMT901](docs/rules/SMT901.md) diagnoses unknown inline suppression identifiers,
195
+ including readable rule names where stable SMT codes are required. Known
196
+ inactive rules retain their narrowed-check behavior.
197
+ - [SMT426](docs/rules/SMT426.md) groups shared-helper operations by one repair in
198
+ text and adds deterministic `shared_helper` JSON groups. Individual findings,
199
+ identities, counts, suppressions and debt remain unchanged. [SMT424](docs/rules/SMT424.md)
200
+ explains known helper inference limits at the affected call sites.
201
+ - [SMT104](docs/rules/SMT104.md) adds the opt-in `cycles: [modules]` scope and
202
+ independent `type_checking_cycles: ignore`. Existing scopes are explicitly
203
+ labeled as aggregated; witnesses include edge phases. Default scopes stay unchanged.
204
+ - [SMT109](docs/rules/SMT109.md) accepts optional, statically verified
205
+ `structure.canonical_exports` ownership and distinguishes same-root/other-root
206
+ importers. Existing exports inform the review; frequency alone never expands API.
207
+ - Literal lazy-export tables with a matching guarded `import_module`/`getattr`
208
+ forwarder now contribute export identity and visibility evidence. Unsupported
209
+ dynamic handlers, escaped/mutated tables and type stubs alone remain unverified.
210
+ - [SMT313](docs/rules/SMT313.md) permits bounded ordering fixes around unrelated
211
+ nested-function dictionaries and `nonlocal` closure writes. Reflection on
212
+ unknown receivers or ordered namespaces retains its manual-review barrier.
213
+
214
+ - New opt-in [SMT321](docs/rules/SMT321.md) `implicit-optional-default`
215
+ reviews `parameter or fallback` for explicitly optional parameters with a
216
+ `None` default. Enable with `rules: {implicit-optional-default: warning}` or
217
+ `--select SMT321`. Use `--fix --unsafe-fixes` to replace it with an explicit
218
+ `is not None` conditional after reviewing intentional falsy defaults. Plain
219
+ `--fix` preserves existing truthiness behavior.
220
+
221
+ ## [0.3.0] - 2026-11-01
222
+
223
+ ### Upgrade first
224
+
225
+ **JSON consumers need an update.** Check and error documents now use schema 2.
226
+ Request `--show-coverage` for full coverage details and resolve
227
+ `expected.usage_scope_index` through the report's `usage_scopes` array. This is
228
+ a report-format change; YAML stays `version: 1`, and default rules, exit codes,
229
+ SMT codes and debt identities stay unchanged. See the
230
+ [upgrade checklist and compatible parser example](docs/upgrading.md).
231
+
232
+ Update tool, dependency, hook and CI pins together to `0.3.0` (Git tag `v0.3.0`),
233
+ then refresh `.smelt.schema.json`. Upgrading from 0.1.x also requires the
234
+ [configuration migration](docs/configuration.md#breaking-change-migration).
235
+
236
+ ### New capabilities
237
+
238
+ | Capability | Enable / use | Details |
239
+ | --- | --- | --- |
240
+ | Review widely imported names missing from a package facade | Set a contract's `export_at` threshold; opt-in, hint severity | [SMT109](docs/rules/SMT109.md) |
241
+ | Review internal public constants and PEP 695 aliases | `rules: {internal-public-module-symbol: warning}`; opt-in | [SMT320](docs/rules/SMT320.md) |
242
+ | Get one-line findings with repair advice | `smelt check --format concise` | [CLI and reports](docs/cli.md) |
243
+ | Migrate existing installations and report consumers | Follow the release-specific checklist | [Upgrading](docs/upgrading.md) |
244
+
245
+ ### Ordering and module visibility
246
+
247
+ - SMT313 now recognizes unions of unshadowed builtin types and `None` in eager
248
+ function annotations for declared Python 3.10+ targets, so a helper annotated
249
+ `str | bytes` no longer silently blocks public-first ordering on Python 3.12/3.13.
250
+ Imported/user-defined operands, shadowed names, explicit namespace mutations and unions in defaults remain
251
+ execution barriers. Inspect barriers with `check --format json --show-coverage`.
252
+ - New opt-in [SMT320](docs/rules/SMT320.md) `internal-public-module-symbol`
253
+ reviews single, unconditional uppercase module assignments and PEP 695 type
254
+ aliases with no observed external use or public-signature evidence. Enable it
255
+ with `rules: {internal-public-module-symbol: warning}` or `--select SMT320`.
256
+ Exports, imports/re-exports, test accesses, escaped modules and public annotation
257
+ dependencies preserve names. Dynamic namespaces and uncertain bindings are
258
+ skipped; external consumers remain unassessed. No automatic renaming.
259
+ - SMT311/SMT313 explanations clarify that Python 3.12/3.13 projects can retain
260
+ an annotations future import for forward references in their chosen public-first
261
+ order. Eager dependencies still take priority when the import is absent. `Self`
262
+ requires a subclass-preserving return contract; no automatic replacement of a
263
+ matching class-name annotation is suggested. See [definition ordering](docs/structure.md#definition-order-with-execution-dependencies).
264
+
265
+ ### Test evidence and package contracts
266
+
267
+ - Opt-in SMT424/SMT425/SMT426 outcome and deadline reviews follow one direct call
268
+ to an unambiguous, undecorated, non-generator helper in the same file, including local async
269
+ helpers executed with `await` or `asyncio.run`. Assertions retain empty-loop
270
+ review, and hidden unbounded operations report their helper and call site.
271
+ Caller async deadlines guard async waits, never synchronous subprocesses.
272
+ Uncalled definitions, unexecuted coroutines, callbacks, imported helper bodies
273
+ and further helper calls remain outside inference; configured assertion helpers
274
+ continue to work. No analyzed code is executed.
275
+ - Overlapping test roots consistently assign a test to the most specific declared
276
+ root, independent of configuration order. Mirror checks retain separate
277
+ workspace-member roots.
278
+ - Package contracts can set `export_at` for SMT109 `facade-export-gap`: one
279
+ advisory finding per widely imported implementation name missing from its
280
+ facade, with definition location, importer lists, other re-exports and a bounded
281
+ cycle check. Tests count only with `count_tests: true`; type-checking-only
282
+ imports and uncertain exports are skipped. No automatic API or import changes.
283
+ See [facade reviews](docs/structure.md#suggestions-to-bundle-implementation-imports).
284
+ - Overlapping SMT108/SMT109 thresholds now choose the most specific pattern per
285
+ concrete package, removing duplicate hints and allowing exact overrides of
286
+ wildcard contracts. Equally specific conflicting settings are config errors.
287
+
288
+ ### Reports, suppressions and fixes
289
+
290
+ - **JSON report schema 2:** `check --format json` emits a small coverage summary
291
+ by default; `--show-coverage` restores full policy details and the per-file
292
+ inventory. Repeated visibility boundaries move to report-level `usage_scopes`,
293
+ referenced by each finding's `expected.usage_scope_index`. Scope, comparison,
294
+ warnings and exit thresholds remain available. See [report compatibility](docs/cli.md).
295
+ - `check --format concise` prints one line per finding with repair advice.
296
+ Text omits empty details, prints visibility limits once, and groups related
297
+ late-import SMT313 findings with their affected lines. JSON keeps individual
298
+ findings plus an `ordering` group; debt fingerprints are retained.
299
+ - Inline suppressions follow logical continuation lines, including interior
300
+ comments in multiline assertions, formatted calls and signatures. Interior
301
+ import-name exceptions stay local and never cover neighboring names, the next
302
+ statement or a function body. Unused-suppression checks remain active. See
303
+ [suppression scope](docs/adoption.md).
304
+ - Visibility rules preserve public members of classes exported through static
305
+ package facades or `__all__`, including aliases and re-export chains; cache
306
+ invalidation tracks export changes. SMT429 distinguishes functions referenced
307
+ only by tests from helpers also used inside their module, without claiming
308
+ unassessed external consumers do not exist.
309
+ - Cache directories ignore their own contents. Init reports the number of tests
310
+ matching a mirror pattern, and ordinary text checks omit the policy coverage
311
+ banner without architecture (strict coverage still applies). Hook documentation
312
+ uses a pinned wheel installation and explains source-build requirements.
313
+ SMT311/SMT318 explanations clarify decorated annotations and Literal-typed
314
+ boundaries; SMT426's subprocess example explicitly sets `check=False`.
315
+ - Release checks enforce matching Python/native/lockfile versions, dated release
316
+ notes and current installation pins. Publication also waits for installation
317
+ smoke tests of the exact Linux x86_64, Windows x86_64 and macOS aarch64 wheels.
318
+
319
+ ## [0.2.0] - 2026-10-31
320
+
321
+ - Visibility reviews (SMT316/SMT317/SMT429/SMT430) explicitly limit their claims to
322
+ analyzed callers and expose `usage_scope`, including exclusions and unassessed
323
+ maintainer scripts, unselected packages and external consumers. They do not
324
+ scan excluded code or infer that unobserved callers cannot exist.
325
+ - SMT313 fix refusals identify the triggering expression and source location in
326
+ `fix_blocker` and the human-readable reason, including inherited/decorated
327
+ classes, namespace inspection and nonliteral type variables. Existing safety
328
+ refusals are retained; skipped-fix output carries the same location.
329
+ - SMT425 recognizes locally assigned nonempty list/set/dict literals, including
330
+ annotations and aliases, and discards that evidence after possible mutations,
331
+ calls or branch merges. SMT424/SMT425 also recognize direct assertions in
332
+ statically known, checked `sys.executable -c` subprocesses. Unchecked exits,
333
+ optimized Python, dynamic scripts, files and potentially swallowed failures
334
+ remain outside recognition; subprocess review hints explain that boundary.
335
+ - Smelt now checks its own sources with public-first ordering, internal-member
336
+ visibility, test-only public API reviews, when-needed future annotations and
337
+ test-quality reviews. CI and release validation fail on warnings too. Internal
338
+ helpers are private, obsolete snapshot helpers are removed, and deliberate
339
+ primitive/cache tests carry local, reasoned exceptions. Consumer defaults stay
340
+ unchanged.
341
+ - SMT420 locates private imports on the imported name, including aliases in
342
+ multiline imports. A reasoned exception on that name now survives Ruff
343
+ formatting and does not suppress neighboring import lines; put multiline
344
+ import exceptions next to the affected name.
345
+ - Optional [SMT319](docs/rules/SMT319.md), enabled with
346
+ `rules: {prefer-package-import: hint}` or `--select SMT319`, suggests existing
347
+ package re-exports so callers can combine imports through a common `__init__.py`.
348
+ All names must have direct, unconditional public re-exports in analyzed code;
349
+ internal package imports and unscanned third-party packages are excluded.
350
+ Findings preserve aliases in their suggestions; checks never rewrite imports.
351
+ - Worker transport now acknowledges requests within 250 ms and bounds accepted
352
+ responses to five seconds, including partial output. Failures fall back to
353
+ foreground checking without repeating accepted requests. A watchdog and four
354
+ OS-owned worker slots bound background sessions; terminated workers release
355
+ capacity. Whole-process memory observations include helpers and Windows
356
+ launchers; the retained-state budget is not a total-process memory quota.
357
+ - Default cached staged checks read HEAD, the index and Git objects through a
358
+ persistent native reader, avoiding Git child-process starts. The reader supports
359
+ SHA-1/SHA-256, packed objects, linked worktrees, split indexes and alternate
360
+ commit indexes. Unsupported repositories, other Git overrides and reader
361
+ failures fall back to Git; `--no-cache` keeps independent reads. Workers also
362
+ retain bounded member dependency state, validating current inputs before reuse
363
+ and discarding borrowed state on failed updates. Worker requests are sent as
364
+ complete TCP frames. See the [paired CLI and complete-hook measurements](https://github.com/mathisarends/smelt/blob/main/docs/agent-workflow.md).
365
+ - Staged checks reuse verified policy blobs before parsing configuration, avoiding
366
+ a redundant Git blob subprocess after source edits. Policy changes still use
367
+ their captured object ID; `--no-cache` keeps independent reads. Paired Windows
368
+ CLI edit medians improve about 11%; complete-hook gains remain inconclusive.
369
+ - The installed CLI now uses a native Rust client and bounded local workers for
370
+ read-only checks. Fresh clients reuse imports, while every check captures current
371
+ Git/config inputs. CI, fixes and other commands stay in the foreground; worker
372
+ startup/transport failures fall back to checking. Workers restart when analyzer
373
+ identity changes and expire after 120 idle seconds. Source installs, including
374
+ pre-commit environments from Git, now require Rust; release wheels include the
375
+ compiled client. `python -m smelt` retains the direct Python entry point.
376
+ - Member-local checks maintain a persistent reverse dependency index and replace
377
+ only changed usage contributions. Unchanged decisions can be reused without
378
+ loading all definition objects. Removed callers, re-exports, missing namespaces,
379
+ inheritance and inventory changes remain part of invalidation.
380
+
381
+ - Checks select built-in rules using a generated lightweight catalog, loading only
382
+ the needed implementations. Staged results can survive edits to unobserved
383
+ content while preserving the current index hash in JSON/SARIF; additions,
384
+ deletions, observed source, config, metadata and debt still invalidate them.
385
+ Normal cached staged retries capture repository/HEAD and index in two Git
386
+ invocations. A separate benchmark measures a retained Python worker including
387
+ fresh client startup and IPC; it preceded the native client above.
388
+ See [the performance measurements](https://github.com/mathisarends/smelt/blob/main/docs/agent-workflow.md).
389
+ - Staged checks read captured Git blobs directly instead of writing temporary
390
+ source trees. An unchanged retry can reuse its exact result before loading the
391
+ analysis engine. Per-file import, member and test facts and selected findings
392
+ are reused across edits, with dependency-aware invalidation for callers,
393
+ re-exports and fixtures. `--no-cache` remains an independent check. See the
394
+ [paired CLI benchmarks and cache limits](https://github.com/mathisarends/smelt/blob/main/docs/agent-workflow.md).
395
+ - `architecture.imports.transitive: true` now checks arbitrary import chains for
396
+ layer, cross-feature, shared, composition-root and third-party policies, e.g.
397
+ `domain → shared.utils → sqlalchemy`. Findings include a deterministic shortest
398
+ chain with each hop's source line; `TYPE_CHECKING` policy applies at every hop.
399
+ The opt-in now follows all reachable module imports, including allowed layers
400
+ and unused facade exports, rather than just selected re-exports. External
401
+ packages remain leaves and the default is still direct imports only. Smelt's
402
+ own repository policy enables these checks. See
403
+ [SMT101](docs/rules/SMT101.md) and [SMT103](docs/rules/SMT103.md).
404
+ - **Breaking configuration API:** fixed source/test checks are enabled directly by
405
+ problem name in `rules`, with one value for activation and severity. Removed
406
+ `review_*`, assertion/private-import boolean flags, binary helper conventions,
407
+ `ordering.enabled` and the experimental preset. Public-first ordering needs an
408
+ explicit rule entry; options alone do not enable it. Package `rules` use the
409
+ same names and closest-package precedence. Stable SMT codes, debt identities
410
+ and architecture-policy activation are retained. See the complete
411
+ [migration table and developer-facing YAML API](docs/configuration.md).
412
+ - `--select` and `--ignore` accept the same canonical names as YAML and `explain`.
413
+ `context` reports effective rule severities for existing and planned modules.
414
+ Scoped-off debt is retained as unassessed when recording/pruning.
415
+ - `smelt init --maintainability` writes explicit individual checks, plus a local
416
+ `.smelt.schema.json` and YAML modeline. Editor completions, validation and hover
417
+ examples come from the real catalog and work offline. Plain `init` keeps its
418
+ conservative check selection. Existing configs can export `smelt config schema`
419
+ and add the modeline; see [editor setup](docs/configuration.md#editor-completion-hover-and-validation).
420
+ - Optional [SMT430](docs/rules/SMT430.md), enabled by
421
+ `rules: {test-only-public-attribute: warning}` or `--select SMT430`,
422
+ reviews public instance/class data attributes read only by tests outside their
423
+ class. Findings include test locations and a collision-free private name.
424
+ Possible production accesses and uncertain class contracts preserve visibility;
425
+ checks never rename code. Public-use rules now share the same member index,
426
+ export/import evidence and private-name suggestions. The new rule is off by
427
+ default and never renames code automatically.
428
+ - Optional [SMT318](docs/rules/SMT318.md), enabled with `rules: {SMT318: hint}`
429
+ or `--select SMT318`, reviews direct `StrEnum.MEMBER.value` reads for using the
430
+ string enum member directly. Known import aliases and analyzed re-exports are
431
+ supported; ordinary enums, uncertain bindings and instance inference are
432
+ excluded. Exact-string boundaries can still need a conversion, so findings
433
+ remain advisory and checks stay read-only. The default rule set is unchanged.
434
+ - `smelt check --staged` reviews the actual Git index against HEAD, using staged
435
+ source, configuration, Python metadata and debt. The new `smelt-staged` hook
436
+ blocks new warnings as well as errors, including findings in unchanged methods
437
+ whose last caller was removed. Partial staging and untracked files cannot hide
438
+ commit findings. JSON/SARIF distinguish staged scope from working-tree changes.
439
+ - Content-addressed JSON caches reuse complete analyses, per-file member facts
440
+ and the historical baseline. `--no-cache` recomputes independently. Member-use
441
+ analysis avoids repeated per-function tree walks; cache invalidation includes
442
+ contents, inventory, policy, Python targets and analyzer implementation. See
443
+ [the commit workflow and benchmark](https://github.com/mathisarends/smelt/blob/main/docs/agent-workflow.md). Changed/staged
444
+ snapshots reject symbolic links; staged fixes require editing and re-staging
445
+ working files explicitly.
446
+ - SMT316 feedback explains how to retain a deliberate public API with a reasoned
447
+ `# smelt: ignore[SMT316] -- ...` comment on its definition. Existing suppression
448
+ reason and unused-suppression checks continue to apply with caching.
449
+
450
+ - Optional [SMT316](docs/rules/SMT316.md), enabled with
451
+ `rules: {internal-public-member: warning}`, reviews public module functions and
452
+ ordinary instance methods with no observed external use, including unused
453
+ definitions. Findings suggest a private name and list internal uses/callbacks
454
+ so agents can review renames. Existing private names are avoided. Explicit
455
+ exports, decorators, inheritance and possible external method accesses preserve
456
+ public APIs; test-only public module functions remain covered by SMT429.
457
+ - Optional [SMT317](docs/rules/SMT317.md), enabled with
458
+ `rules: {internal-static-helper: hint}`, suggests extracting internal static helpers
459
+ to private module functions. Class dependencies, inheritance, extra decorators
460
+ and possible external callers preserve deliberate static APIs. Both new
461
+ rules support closest package `off` overrides and appear in `smelt context`.
462
+ Checks remain read-only and the default rule set is unchanged.
463
+ - Optional [SMT429](docs/rules/SMT429.md), enabled by
464
+ `rules: {test-only-public-function: warning}`, reviews public module functions
465
+ accessed from tests but not from other analyzed production modules. Findings
466
+ suggest a leading underscore and include test locations so agents can review
467
+ the rename and test the public caller. Explicit exports and decorated functions
468
+ stay public; external/dynamic consumers remain a review limitation. The default
469
+ rule set is unchanged.
470
+
471
+ ## [0.1.6] - 2026-10-29
472
+
473
+ ### Compatibility and activation
474
+
475
+ - SMT428 remains opt-in through `tests.review_async_mock_assertions`; the default
476
+ rule set is unchanged. Its findings ask for review of an individual test, not a
477
+ claim that the suite misses the regression.
478
+ - Existing `tests.review_test_deadlines` policies can now report additional known
479
+ asyncio subprocess waits. Review each operation's local deadline, including
480
+ cleanup paths, rather than adding a blanket timeout or await restriction.
481
+
482
+ ### Added and fixed
483
+
484
+ - SMT426 now reviews `wait()` and `communicate()` on known asyncio subprocesses
485
+ created through awaited standard factories or explicit Process annotations.
486
+ Each operation needs its own local guard, including exit waits after bounded
487
+ reads or `kill()`. Unknown process-like objects remain outside scope.
488
+ - Optional SMT428 (`tests.review_async_mock_assertions`) reviews call-only checks
489
+ on known async mocks and async class-spec methods. Await assertions, deliberate
490
+ scheduling checks and synchronous methods remain valid. Known fixture specs and
491
+ simple local history values are traced without executing analyzed code; unknown
492
+ methods and general data flow remain outside scope. Executed missing-await
493
+ counterexamples demonstrate the distinction between call and await assertions.
494
+ - `context` text now shows all adopted test-quality review flags, including when
495
+ only the newer policies are enabled.
496
+ - SMT424 recognizes awaited, typed Event observations inside local timeout
497
+ contexts that raise on expiry, consistently with SMT426 deadline recognition.
498
+ Unused contexts, unawaited waits and `move_on_after` scopes are not outcome
499
+ evidence; configured timeout helpers alone still do not count as assertions.
500
+
501
+ ## [0.1.5] - 2026-10-29
502
+
503
+ ### Compatibility and activation
504
+
505
+ - Existing opted-in test policies can report additional MonkeyPatch operations
506
+ and known instance accesses. New SMT425-SMT427 review policies remain opt-in;
507
+ the small default rule set is unchanged. Review legitimate boundary tests
508
+ rather than exposing internals or imposing a global mock ban.
509
+ - `--fail-on warning` now includes configuration warnings, and unused
510
+ `pytest.raises`/`warns` context objects no longer count as outcome evidence.
511
+ A passing static report is not proof of test effectiveness.
512
+
513
+ ### Added and fixed
514
+
515
+ - `scripts/evaluate.py` supports repeatable agent review loops: compare two import
516
+ roots on identical config bytes, retain
517
+ structured recognition changes and independently bounded logs, then optionally
518
+ execute explicitly selected pytest targets. Invalid analysis, timeouts and
519
+ incomplete collection remain distinct from test failures; normal checks never
520
+ execute analyzed tests. See the [evaluation workflow](docs/testing.md#evaluate-a-test-quality-change).
521
+ - Test outcome review now recognizes known mock interaction assertions, annotated
522
+ fixture receivers and awaited, bounded asyncio Event observations. Unused
523
+ `pytest.raises`/`warns` context objects no longer count as checks. Unknown
524
+ `assert_*` methods and fixture execution alone remain insufficient evidence.
525
+ - [SMT420](docs/rules/SMT420.md) tracks direct known production constructors and
526
+ explicitly typed instance reads, including analyzed facade re-exports and
527
+ consistent known fixture return/yield tuple components. Unknown/conflicting
528
+ outputs, private writes and local fakes are excluded; fixture inference has
529
+ separate provenance and respects class/conftest scope. A private class import
530
+ is not reported again for each public instance operation.
531
+ [SMT421–SMT423](docs/rules/SMT422.md) now include MonkeyPatch attribute
532
+ replacement, aliases and context scopes, with operation/provenance metadata.
533
+ MonkeyPatch environment/mapping setup is excluded from the mock count.
534
+ - Optional [SMT425](docs/rules/SMT425.md), [SMT426](docs/rules/SMT426.md) and
535
+ [SMT427](docs/rules/SMT427.md) review potentially vacuous outcomes, known waits
536
+ without deadlines/scheduler-clock replacements, and small independent-case loop
537
+ candidates. They remain advisory and require explicit test policies; no fixer,
538
+ blanket mock/sleep ban or assertion quota is introduced.
539
+ - Configuration warnings now appear in JSON `configuration_diagnostics`, SARIF
540
+ configuration notifications, GitHub annotations and text summaries. They count
541
+ toward `summary.warnings` and `--fail-on warning`, including scoped/changed
542
+ checks; rule selection, suppressions and debt cannot hide configuration warnings.
543
+
544
+ ## [0.1.4] - 2026-10-29
545
+
546
+ ### Migration: rule activation changed
547
+
548
+ - Only **SMT301, SMT901, SMT902 and SMT903** run by default. Declaring an
549
+ architecture, package or test policy activates the corresponding checks without
550
+ a second enable switch. The catalog now distinguishes 4 default, 24 policy-driven
551
+ and 2 explicitly selected rules; activation and severity are separate.
552
+ - **SMT104 import cycles and SMT305 unclassified-module hints require explicit
553
+ selection.** To retain these checks from earlier versions, add:
554
+
555
+ ```yaml
556
+ rules:
557
+ SMT104: error
558
+ SMT305: warning
559
+ ```
560
+
561
+ - `--select SMT3` and `--select ALL` activate matching opt-in checks and replace
562
+ normal selection. Explicit `off` settings and ignores still win; selection does
563
+ not invent missing policies. Strict coverage remains mandatory when configured
564
+ or requested, even outside the selected rule prefix.
565
+ - `smelt init` still proposes architecture but leaves naming conventions and test
566
+ mirroring disabled for review. A detected mirror pattern remains available as a
567
+ setting, with an activation comment.
568
+ - Debt for inactive or hint-only rules is retained when recording/pruning, rather
569
+ than silently considered resolved. Older cycle and indirect-import debt can
570
+ resurface because corrected fingerprints track the actual dependency. Review
571
+ these findings before recording new debt.
572
+
573
+ ### Added
574
+
575
+ | Capability | Rules / interface | What agents can now check |
576
+ | --- | --- | --- |
577
+ | Strict architecture coverage | [SMT306](docs/rules/SMT306.md), `project.coverage: strict`, `--strict-coverage` | Production files outside package selection, missing architecture roles and exclusions without reasons. These gaps cannot be hidden by changed/path filters, suppressions or debt. |
578
+ | Package structure and public APIs | [SMT107](docs/rules/SMT107.md), [SMT307](docs/rules/SMT307.md) | Required modules and explicit public entry points through `structure.contracts`; outside callers cannot import private implementation modules. |
579
+ | Import fanout | [SMT108](docs/rules/SMT108.md) | Optional hints when one outside caller imports too many distinct modules from the same contracted package. |
580
+ | Source conventions | [SMT308](docs/rules/SMT308.md)–[SMT312](docs/rules/SMT312.md) | Scoped absolute/relative import styles, module-docstring policy, future-annotation policy and private module/package names. Python targets come from declared metadata or configuration. |
581
+ | Definition order | [SMT313](docs/rules/SMT313.md) | Dependency-aware module/class ordering, including execution barriers and bounded, explicitly requested fixes. |
582
+ | Instance field assignments | [SMT314](docs/rules/SMT314.md) | Bundled or chained writes to multiple direct instance attributes when `instance_assignments: separate` is declared. |
583
+ | Type dispatch | [SMT315](docs/rules/SMT315.md) | Review hints for same-subject `isinstance`/`elif` chains under a declared `type_dispatch` policy. |
584
+ | Test quality | [SMT420](docs/rules/SMT420.md)–[SMT424](docs/rules/SMT424.md) | Configured private production access, forbidden mocks, string patch targets, per-test patch limits and missing recognized outcome assertions. |
585
+
586
+ - `smelt context <path> --format json` explains ownership, coverage status,
587
+ applicable contracts, effective conventions and Python targets for existing or
588
+ planned files. Planned placement is distinguished from analyzed source.
589
+ - `check --show-coverage` exposes the per-file policy inventory. JSON reports add
590
+ discovery roots, classification counts, policy references, exclusions and a
591
+ policy hash. Rule metadata exposes activation, analysis requirements and
592
+ configuration paths through `rules`, `explain` and reports.
593
+ - Contributor documentation and catalog checks verify explicit registration,
594
+ unique rule codes/names, complete metadata and generated documentation.
595
+ - Tag-triggered PyPI Trusted Publishing validates the tag/version and main
596
+ ancestry, runs checks, builds and smoke-tests both distributions, then publishes
597
+ the validated artifacts without a stored PyPI API token.
598
+
599
+ ### Fixed
600
+
601
+ - Resolve named re-exports across layer, feature, shared and composition-root
602
+ boundaries. Indirect findings retain the final forbidden target; declared
603
+ feature wiring no longer produces false unknown-layer findings.
604
+ - Track every cyclic architecture edge and semantic identities/multiplicity in
605
+ changed/debt comparisons. New edges, patches or ordering inversions cannot hide
606
+ behind an accepted aggregate finding. Existing violations do not become new
607
+ merely because an import's formatting, comment or alias changed.
608
+ - Merge namespace package portions, reject duplicate module definitions and infer
609
+ usable workspace source roots. Grouped imports check every alias, and source
610
+ discovery avoids symlink cycles.
611
+ - Reject duplicate YAML keys and invalid source encoding. With `--format json`,
612
+ usage/configuration/analysis errors return structured error documents; reports
613
+ identify their origin and comparison scope. SARIF and GitHub paths are rebased
614
+ correctly for nested configurations.
615
+
616
+ ### Agent workflow and limits
617
+
618
+ ```bash
619
+ smelt rules --format json
620
+ smelt context path/to/module.py --format json
621
+ smelt check --changed --base origin/main --format json
622
+ smelt check --strict-coverage --show-coverage --format json
623
+ smelt explain SMT313 --format json
624
+ ```
625
+
626
+ - Normal checks are read-only. After configuring ordering with `fix: safe-only`,
627
+ `smelt check --select SMT313 --fix` can apply bounded definition moves. It
628
+ preserves source trivia, validates the permitted AST moves and refuses unsafe
629
+ or concurrently changed files. Run the project formatter afterwards.
630
+ - SMT314 and SMT315 have no automatic rewrite. Splitting assignments or converting
631
+ type dispatch can change evaluation, guards and fallthrough.
632
+ - Coverage means policy assignment within declared discovery roots, not a proof
633
+ of behavior. Package APIs and test-quality checks are static and do not infer
634
+ dynamic imports, arbitrary runtime access or fixture dependency effects.
635
+ - Import fanout, match suggestions and missing-assertion checks are review aids;
636
+ their default severities differ. Configure policy and severity deliberately.
637
+
638
+ [Unreleased]: https://github.com/mathisarends/smelt/compare/v0.6.0...HEAD
639
+ [0.6.0]: https://github.com/mathisarends/smelt/compare/v0.5.0...v0.6.0
640
+ [0.5.0]: https://github.com/mathisarends/smelt/compare/v0.4.0...v0.5.0
641
+ [0.4.0]: https://github.com/mathisarends/smelt/compare/v0.3.0...v0.4.0
642
+ [0.3.0]: https://github.com/mathisarends/smelt/compare/v0.2.0...v0.3.0
643
+ [0.2.0]: https://github.com/mathisarends/smelt/compare/v0.1.6...v0.2.0
644
+ [0.1.6]: https://github.com/mathisarends/smelt/compare/v0.1.5...v0.1.6
645
+ [0.1.5]: https://github.com/mathisarends/smelt/compare/v0.1.4...v0.1.5
646
+ [0.1.4]: https://github.com/mathisarends/smelt/compare/v0.1.3...v0.1.4