sud-cli 0.1.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 (274) hide show
  1. sud_cli-0.1.0/.gitattributes +3 -0
  2. sud_cli-0.1.0/AUTHORS +5 -0
  3. sud_cli-0.1.0/CHANGELOG.md +11 -0
  4. sud_cli-0.1.0/CONTRIBUTING.md +12 -0
  5. sud_cli-0.1.0/LICENSE.md +661 -0
  6. sud_cli-0.1.0/NOTICE +7 -0
  7. sud_cli-0.1.0/PKG-INFO +121 -0
  8. sud_cli-0.1.0/README.en.md +100 -0
  9. sud_cli-0.1.0/README.md +102 -0
  10. sud_cli-0.1.0/SECURITY.md +8 -0
  11. sud_cli-0.1.0/assets/flags/gb.svg +1 -0
  12. sud_cli-0.1.0/assets/flags/ru.svg +1 -0
  13. sud_cli-0.1.0/assets/poster.jpg +0 -0
  14. sud_cli-0.1.0/case_search/__init__.py +46 -0
  15. sud_cli-0.1.0/case_search/__main__.py +3 -0
  16. sud_cli-0.1.0/case_search/_logging.py +45 -0
  17. sud_cli-0.1.0/case_search/_rate_limit.py +78 -0
  18. sud_cli-0.1.0/case_search/alerts.py +70 -0
  19. sud_cli-0.1.0/case_search/alerts_dedup.py +156 -0
  20. sud_cli-0.1.0/case_search/browser_native.py +228 -0
  21. sud_cli-0.1.0/case_search/cli.py +1130 -0
  22. sud_cli-0.1.0/case_search/config.py +131 -0
  23. sud_cli-0.1.0/case_search/diff.py +89 -0
  24. sud_cli-0.1.0/case_search/doctor.py +351 -0
  25. sud_cli-0.1.0/case_search/errors.py +91 -0
  26. sud_cli-0.1.0/case_search/kad/__init__.py +15 -0
  27. sud_cli-0.1.0/case_search/kad/html_import.py +244 -0
  28. sud_cli-0.1.0/case_search/kad/import_json.py +72 -0
  29. sud_cli-0.1.0/case_search/kad/instances.py +107 -0
  30. sud_cli-0.1.0/case_search/kad/parser.py +339 -0
  31. sud_cli-0.1.0/case_search/kad/search.py +584 -0
  32. sud_cli-0.1.0/case_search/license.py +77 -0
  33. sud_cli-0.1.0/case_search/mos/__init__.py +22 -0
  34. sud_cli-0.1.0/case_search/mos/cache.py +225 -0
  35. sud_cli-0.1.0/case_search/mos/dom.py +140 -0
  36. sud_cli-0.1.0/case_search/mos/live.py +517 -0
  37. sud_cli-0.1.0/case_search/mos/live_spike.py +196 -0
  38. sud_cli-0.1.0/case_search/mos/parser.py +700 -0
  39. sud_cli-0.1.0/case_search/normalize.py +142 -0
  40. sud_cli-0.1.0/case_search/normalize_refs.py +58 -0
  41. sud_cli-0.1.0/case_search/ocr.py +220 -0
  42. sud_cli-0.1.0/case_search/pipeline.py +68 -0
  43. sud_cli-0.1.0/case_search/public_api.py +956 -0
  44. sud_cli-0.1.0/case_search/schema.py +158 -0
  45. sud_cli-0.1.0/case_search/snapshots.py +44 -0
  46. sud_cli-0.1.0/case_search/sources/__init__.py +30 -0
  47. sud_cli-0.1.0/case_search/sources/base.py +98 -0
  48. sud_cli-0.1.0/case_search/sources/import_html.py +47 -0
  49. sud_cli-0.1.0/case_search/sources/live.py +34 -0
  50. sud_cli-0.1.0/case_search/sources/mos_dom.py +62 -0
  51. sud_cli-0.1.0/case_search/sources/synthetic.py +86 -0
  52. sud_cli-0.1.0/case_search/storage.py +136 -0
  53. sud_cli-0.1.0/case_search/sudact/__init__.py +10 -0
  54. sud_cli-0.1.0/case_search/sudact/_common.py +21 -0
  55. sud_cli-0.1.0/case_search/sudact/case_history.py +150 -0
  56. sud_cli-0.1.0/case_search/sudact/parser.py +311 -0
  57. sud_cli-0.1.0/case_search/sudact/runtime.py +292 -0
  58. sud_cli-0.1.0/case_search/sudact/search.py +253 -0
  59. sud_cli-0.1.0/case_search/sudrf/__init__.py +0 -0
  60. sud_cli-0.1.0/case_search/sudrf/cache.py +227 -0
  61. sud_cli-0.1.0/case_search/sudrf/live.py +768 -0
  62. sud_cli-0.1.0/case_search/sudrf/parser.py +431 -0
  63. sud_cli-0.1.0/case_search/sudrf/registry.json +28271 -0
  64. sud_cli-0.1.0/case_search/vsrf/__init__.py +9 -0
  65. sud_cli-0.1.0/case_search/vsrf/live.py +272 -0
  66. sud_cli-0.1.0/case_search/vsrf/parser.py +280 -0
  67. sud_cli-0.1.0/case_search_runner.py +12 -0
  68. sud_cli-0.1.0/docs/CASE-SEARCH-PARITY.md +112 -0
  69. sud_cli-0.1.0/fixtures/kad/variations/README.md +28 -0
  70. sud_cli-0.1.0/fixtures/kad/variations/kad-variation-appeal-16AP-1234-2026.html +132 -0
  71. sud_cli-0.1.0/fixtures/kad/variations/kad-variation-cassation-02-3696-2026.html +138 -0
  72. sud_cli-0.1.0/fixtures/kad/variations/kad-variation-supervision-VAS-12345-2026.html +99 -0
  73. sud_cli-0.1.0/fixtures/kad-live-extract-/320/22040-308035-2025.json +25 -0
  74. sud_cli-0.1.0/fixtures/kad-saved-card-/320/22040-308035-2025.html +4370 -0
  75. sud_cli-0.1.0/fixtures/sudact/arbitral-doc-A41-69570-2025.html +203 -0
  76. sud_cli-0.1.0/fixtures/sudact/arbitral-doc-asmo-2026.html +156 -0
  77. sud_cli-0.1.0/fixtures/sudact/live-7-1013-2026.json +11 -0
  78. sud_cli-0.1.0/fixtures/sudact/live-7-2536-2017.json +11 -0
  79. sud_cli-0.1.0/fixtures/sudact/regular-doc-2A-1222-2026.html +162 -0
  80. sud_cli-0.1.0/fixtures/sudact/regular-doc-2A-3400-2025.html +172 -0
  81. sud_cli-0.1.0/fixtures/sudact/search-results-arbitral.html +289 -0
  82. sud_cli-0.1.0/fixtures/sudact/search-results-js-mode.html +286 -0
  83. sud_cli-0.1.0/fixtures/sudrf/gas-print-2a-2939-2025.html +1343 -0
  84. sud_cli-0.1.0/fixtures/synthetic/court_cases.json +37 -0
  85. sud_cli-0.1.0/fixtures/synthetic/court_records.json +28 -0
  86. sud_cli-0.1.0/fixtures/synthetic/empty_response.json +1 -0
  87. sud_cli-0.1.0/fixtures/synthetic/http500_response.json +1 -0
  88. sud_cli-0.1.0/fixtures/synthetic/kad_case.json +31 -0
  89. sud_cli-0.1.0/fixtures/synthetic/kad_extract.json +17 -0
  90. sud_cli-0.1.0/fixtures/synthetic/malformed_case.json +10 -0
  91. sud_cli-0.1.0/fixtures/synthetic/malformed_response.json +1 -0
  92. sud_cli-0.1.0/fixtures/synthetic/mos_gorsud_case.json +36 -0
  93. sud_cli-0.1.0/fixtures/synthetic/npa_documents.json +18 -0
  94. sud_cli-0.1.0/fixtures/synthetic/ratelimit_response.json +1 -0
  95. sud_cli-0.1.0/fixtures/synthetic/waf_response.json +1 -0
  96. sud_cli-0.1.0/fixtures/synthetic/watchlist.json +1 -0
  97. sud_cli-0.1.0/fixtures/vsrf/obzor-mezhdunarodnye-organy-4-2026.pdf +0 -0
  98. sud_cli-0.1.0/fixtures/vsrf/presidium-272-PEK25-A40-217461-2024.pdf +0 -0
  99. sud_cli-0.1.0/mos-spike/README.md +62 -0
  100. sud_cli-0.1.0/mos-spike/fixtures/ambiguous-summary.html +28 -0
  101. sud_cli-0.1.0/mos-spike/fixtures/case-02-0387-2025.redacted.html +3148 -0
  102. sud_cli-0.1.0/mos-spike/fixtures/empty.html +0 -0
  103. sud_cli-0.1.0/mos-spike/fixtures/malformed-timeline.html +26 -0
  104. sud_cli-0.1.0/mos-spike/fixtures/missing-summary.html +1 -0
  105. sud_cli-0.1.0/mos-spike/fixtures/waf.html +1 -0
  106. sud_cli-0.1.0/pyproject.toml +34 -0
  107. sud_cli-0.1.0/sud_cli/__init__.py +3 -0
  108. sud_cli-0.1.0/sud_cli/__main__.py +4 -0
  109. sud_cli-0.1.0/sud_cli/_wm.py +118 -0
  110. sud_cli-0.1.0/sud_cli/agenda.py +90 -0
  111. sud_cli-0.1.0/sud_cli/autofill.py +192 -0
  112. sud_cli-0.1.0/sud_cli/autofill_markers.json +56 -0
  113. sud_cli-0.1.0/sud_cli/backup.py +256 -0
  114. sud_cli-0.1.0/sud_cli/calendar_ics.py +191 -0
  115. sud_cli-0.1.0/sud_cli/case_diff.py +165 -0
  116. sud_cli-0.1.0/sud_cli/case_search_bridge.py +1322 -0
  117. sud_cli-0.1.0/sud_cli/chain.py +226 -0
  118. sud_cli-0.1.0/sud_cli/cli.py +3721 -0
  119. sud_cli-0.1.0/sud_cli/completeness.py +105 -0
  120. sud_cli-0.1.0/sud_cli/config.py +20 -0
  121. sud_cli-0.1.0/sud_cli/conflict.py +210 -0
  122. sud_cli-0.1.0/sud_cli/conflicts.py +207 -0
  123. sud_cli-0.1.0/sud_cli/court_alerts.py +156 -0
  124. sud_cli-0.1.0/sud_cli/court_source.py +108 -0
  125. sud_cli-0.1.0/sud_cli/data/completeness_rules.json +18 -0
  126. sud_cli-0.1.0/sud_cli/data/key_rates.json +59 -0
  127. sud_cli-0.1.0/sud_cli/data/npa_historical_editions.json +19 -0
  128. sud_cli-0.1.0/sud_cli/db.py +2072 -0
  129. sud_cli-0.1.0/sud_cli/deadline_matrix.py +99 -0
  130. sud_cli-0.1.0/sud_cli/deadline_state.py +25 -0
  131. sud_cli-0.1.0/sud_cli/deadlines.py +8 -0
  132. sud_cli-0.1.0/sud_cli/deadlines_state.py +1 -0
  133. sud_cli-0.1.0/sud_cli/deferral.py +5 -0
  134. sud_cli-0.1.0/sud_cli/efrsb_manual.py +85 -0
  135. sud_cli-0.1.0/sud_cli/efrsb_public.py +210 -0
  136. sud_cli-0.1.0/sud_cli/egrul_nalog.py +150 -0
  137. sud_cli-0.1.0/sud_cli/explain.py +190 -0
  138. sud_cli-0.1.0/sud_cli/fees_extra.py +104 -0
  139. sud_cli-0.1.0/sud_cli/forms.py +204 -0
  140. sud_cli-0.1.0/sud_cli/fssp_manual.py +91 -0
  141. sud_cli-0.1.0/sud_cli/fssp_semi.py +285 -0
  142. sud_cli-0.1.0/sud_cli/fssp_stats.py +105 -0
  143. sud_cli-0.1.0/sud_cli/government_transfers.json +8 -0
  144. sud_cli-0.1.0/sud_cli/holidays_rf.json +62 -0
  145. sud_cli-0.1.0/sud_cli/idempotency.py +78 -0
  146. sud_cli-0.1.0/sud_cli/importing.py +575 -0
  147. sud_cli-0.1.0/sud_cli/interest.py +144 -0
  148. sud_cli-0.1.0/sud_cli/jurisdiction.py +177 -0
  149. sud_cli-0.1.0/sud_cli/jurisdiction_rules.json +265 -0
  150. sud_cli-0.1.0/sud_cli/legal_deadlines.py +278 -0
  151. sud_cli-0.1.0/sud_cli/legal_engine.py +558 -0
  152. sud_cli-0.1.0/sud_cli/legal_rules.json +1058 -0
  153. sud_cli-0.1.0/sud_cli/limitation.py +70 -0
  154. sud_cli-0.1.0/sud_cli/mcp_server.py +1594 -0
  155. sud_cli-0.1.0/sud_cli/metrics.py +142 -0
  156. sud_cli-0.1.0/sud_cli/npa_as_of.py +21 -0
  157. sud_cli-0.1.0/sud_cli/output.py +89 -0
  158. sud_cli-0.1.0/sud_cli/payment.py +24 -0
  159. sud_cli-0.1.0/sud_cli/pdn.py +259 -0
  160. sud_cli-0.1.0/sud_cli/plenum_corpus.py +134 -0
  161. sud_cli-0.1.0/sud_cli/plenums_seed.json +45 -0
  162. sud_cli-0.1.0/sud_cli/practice_status.py +136 -0
  163. sud_cli-0.1.0/sud_cli/pravo_publication.py +361 -0
  164. sud_cli-0.1.0/sud_cli/pretrial.py +151 -0
  165. sud_cli-0.1.0/sud_cli/production_calendar.py +233 -0
  166. sud_cli-0.1.0/sud_cli/providers.py +95 -0
  167. sud_cli-0.1.0/sud_cli/readiness.py +234 -0
  168. sud_cli-0.1.0/sud_cli/regional_holidays.py +37 -0
  169. sud_cli-0.1.0/sud_cli/reminders.py +92 -0
  170. sud_cli-0.1.0/sud_cli/reports.py +349 -0
  171. sud_cli-0.1.0/sud_cli/sud_netguard.py +943 -0
  172. sud_cli-0.1.0/sud_cli/timeline_audit.py +80 -0
  173. sud_cli-0.1.0/sud_cli/verify.py +201 -0
  174. sud_cli-0.1.0/tests/__init__.py +0 -0
  175. sud_cli-0.1.0/tests/conftest.py +33 -0
  176. sud_cli-0.1.0/tests/test_alerts_dedup.py +183 -0
  177. sud_cli-0.1.0/tests/test_audit_infra.py +230 -0
  178. sud_cli-0.1.0/tests/test_blocked.py +192 -0
  179. sud_cli-0.1.0/tests/test_bridge_case_numbers.py +224 -0
  180. sud_cli-0.1.0/tests/test_bridge_flag_commands.py +931 -0
  181. sud_cli-0.1.0/tests/test_case_diff.py +160 -0
  182. sud_cli-0.1.0/tests/test_case_search_bridge.py +1084 -0
  183. sud_cli-0.1.0/tests/test_cli.py +275 -0
  184. sud_cli-0.1.0/tests/test_cli_live_commands.py +133 -0
  185. sud_cli-0.1.0/tests/test_court_case.py +674 -0
  186. sud_cli-0.1.0/tests/test_court_search.py +487 -0
  187. sud_cli-0.1.0/tests/test_date_window_consistency.py +53 -0
  188. sud_cli-0.1.0/tests/test_doctor.py +247 -0
  189. sud_cli-0.1.0/tests/test_efrsb_public.py +109 -0
  190. sud_cli-0.1.0/tests/test_import.py +360 -0
  191. sud_cli-0.1.0/tests/test_import_mode.py +93 -0
  192. sud_cli-0.1.0/tests/test_json_stream_contract.py +114 -0
  193. sud_cli-0.1.0/tests/test_kad_chrono.py +54 -0
  194. sud_cli-0.1.0/tests/test_kad_html_auto.py +64 -0
  195. sud_cli-0.1.0/tests/test_kad_import.py +113 -0
  196. sud_cli-0.1.0/tests/test_kad_parser.py +218 -0
  197. sud_cli-0.1.0/tests/test_kad_participant_search.py +158 -0
  198. sud_cli-0.1.0/tests/test_kad_search.py +115 -0
  199. sud_cli-0.1.0/tests/test_kad_variations.py +196 -0
  200. sud_cli-0.1.0/tests/test_legal_engine.py +1161 -0
  201. sud_cli-0.1.0/tests/test_manifest_runtime_state_exclusion.py +26 -0
  202. sud_cli-0.1.0/tests/test_mcp_server.py +193 -0
  203. sud_cli-0.1.0/tests/test_mos_cache.py +166 -0
  204. sud_cli-0.1.0/tests/test_mos_canon.py +132 -0
  205. sud_cli-0.1.0/tests/test_mos_catalog.py +53 -0
  206. sud_cli-0.1.0/tests/test_mos_dom.py +442 -0
  207. sud_cli-0.1.0/tests/test_mos_live.py +107 -0
  208. sud_cli-0.1.0/tests/test_mos_live_spike.py +441 -0
  209. sud_cli-0.1.0/tests/test_mos_snapshot.py +149 -0
  210. sud_cli-0.1.0/tests/test_netguard_sudrf.py +91 -0
  211. sud_cli-0.1.0/tests/test_normalize_refs.py +60 -0
  212. sud_cli-0.1.0/tests/test_npa.py +210 -0
  213. sud_cli-0.1.0/tests/test_ocr.py +123 -0
  214. sud_cli-0.1.0/tests/test_parity_doc.py +176 -0
  215. sud_cli-0.1.0/tests/test_phase2_features.py +89 -0
  216. sud_cli-0.1.0/tests/test_pravo_publication.py +510 -0
  217. sud_cli-0.1.0/tests/test_pravo_transport_modes.py +267 -0
  218. sud_cli-0.1.0/tests/test_public_api.py +141 -0
  219. sud_cli-0.1.0/tests/test_readiness.py +117 -0
  220. sud_cli-0.1.0/tests/test_recalc_manifest.py +692 -0
  221. sud_cli-0.1.0/tests/test_runner_protocol.py +37 -0
  222. sud_cli-0.1.0/tests/test_search.py +167 -0
  223. sud_cli-0.1.0/tests/test_stage3_features.py +61 -0
  224. sud_cli-0.1.0/tests/test_storage.py +37 -0
  225. sud_cli-0.1.0/tests/test_strategic_modules.py +67 -0
  226. sud_cli-0.1.0/tests/test_sudact_case_history.py +143 -0
  227. sud_cli-0.1.0/tests/test_sudact_import.py +170 -0
  228. sud_cli-0.1.0/tests/test_sudact_runtime.py +263 -0
  229. sud_cli-0.1.0/tests/test_sudact_search.py +161 -0
  230. sud_cli-0.1.0/tests/test_sudrf_cache.py +189 -0
  231. sud_cli-0.1.0/tests/test_sudrf_import.py +68 -0
  232. sud_cli-0.1.0/tests/test_sudrf_live.py +114 -0
  233. sud_cli-0.1.0/tests/test_sudrf_snapshot.py +76 -0
  234. sud_cli-0.1.0/tests/test_synthetic_core.py +467 -0
  235. sud_cli-0.1.0/tests/test_v2100_tariff_as_of.py +635 -0
  236. sud_cli-0.1.0/tests/test_v2110_1_parity.py +328 -0
  237. sud_cli-0.1.0/tests/test_v2110_2_explain.py +129 -0
  238. sud_cli-0.1.0/tests/test_v2110_3_ics.py +163 -0
  239. sud_cli-0.1.0/tests/test_v2110_4_alerts.py +130 -0
  240. sud_cli-0.1.0/tests/test_v2110_5_autofill.py +200 -0
  241. sud_cli-0.1.0/tests/test_v2120_1_evidence.py +212 -0
  242. sud_cli-0.1.0/tests/test_v2120_2_dochistory.py +174 -0
  243. sud_cli-0.1.0/tests/test_v2120_3_checklist.py +163 -0
  244. sud_cli-0.1.0/tests/test_v2120_4_forms.py +177 -0
  245. sud_cli-0.1.0/tests/test_v2120_5_final.py +63 -0
  246. sud_cli-0.1.0/tests/test_v2130_1_chain.py +234 -0
  247. sud_cli-0.1.0/tests/test_v2130_2_reps.py +238 -0
  248. sud_cli-0.1.0/tests/test_v2130_3_conflicts.py +288 -0
  249. sud_cli-0.1.0/tests/test_v2130_4_reports.py +298 -0
  250. sud_cli-0.1.0/tests/test_v2130_5_backup_metrics_pdn.py +581 -0
  251. sud_cli-0.1.0/tests/test_v2130_6_final.py +286 -0
  252. sud_cli-0.1.0/tests/test_v2140_egrul.py +103 -0
  253. sud_cli-0.1.0/tests/test_v2150_fssp.py +124 -0
  254. sud_cli-0.1.0/tests/test_v2160_fssp_semi.py +100 -0
  255. sud_cli-0.1.0/tests/test_v2170_build_flags.py +93 -0
  256. sud_cli-0.1.0/tests/test_v2180_w7_directives.py +130 -0
  257. sud_cli-0.1.0/tests/test_v2181_audit_fixes.py +56 -0
  258. sud_cli-0.1.0/tests/test_v231_fees_decimal.py +177 -0
  259. sud_cli-0.1.0/tests/test_v231_mcp_fees_and_aliases.py +337 -0
  260. sud_cli-0.1.0/tests/test_v232_engineering.py +72 -0
  261. sud_cli-0.1.0/tests/test_v233_panel.py +82 -0
  262. sud_cli-0.1.0/tests/test_v240_registry.py +176 -0
  263. sud_cli-0.1.0/tests/test_v241_conflict.py +149 -0
  264. sud_cli-0.1.0/tests/test_v250_anti_laches.py +276 -0
  265. sud_cli-0.1.0/tests/test_v260_local_coverage.py +278 -0
  266. sud_cli-0.1.0/tests/test_v270_matrix.py +126 -0
  267. sud_cli-0.1.0/tests/test_v280a_amounts.py +192 -0
  268. sud_cli-0.1.0/tests/test_v280b_reminders.py +168 -0
  269. sud_cli-0.1.0/tests/test_v280c_w4_pack.py +103 -0
  270. sud_cli-0.1.0/tests/test_v290a_verify_quote.py +296 -0
  271. sud_cli-0.1.0/tests/test_v290b_practice_status.py +163 -0
  272. sud_cli-0.1.0/tests/test_vsrf_import.py +119 -0
  273. sud_cli-0.1.0/tests/test_vsrf_live.py +113 -0
  274. sud_cli-0.1.0/tools/recalc_manifest.py +326 -0
@@ -0,0 +1,3 @@
1
+ # Захваченные страницы-фикстуры и генерируемые HTML-примеры — тестовые данные, не код проекта.
2
+ *.html linguist-vendored
3
+ *.htm linguist-vendored
sud_cli-0.1.0/AUTHORS ADDED
@@ -0,0 +1,5 @@
1
+ # Authors
2
+
3
+ sud-cli is maintained by the project owner.
4
+
5
+ Copyright (C) 2026 lnfnt <lnfnt@proton.me>
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ - Первый публичный релиз: поиск практики и карточек дел по официальным источникам,
6
+ процессуальные сроки с производственным календарём, расчёт госпошлин (ГПК/АПК/КАС),
7
+ досье и реестр доказательств, НПА, корпус разъяснений ВС/ВАС, полу-автомат ФССП
8
+ с человеческой капчей, ручной контур ЕФРСБ, экспорт календаря (RFC 5545),
9
+ бэкап/метрики/purge.
10
+ - MCP-сервер: 65 инструментов, JSON-конверт на команду.
11
+ - §13 AGPL: команда `license` — лицензия, режим сборки, получение исходников.
@@ -0,0 +1,12 @@
1
+ # Contributing
2
+
3
+ AGPL-3.0-only applies to all contributions.
4
+
5
+ By contributing you certify:
6
+
7
+ 1. The Contribution was created in whole or in part by you and you have
8
+ the right to submit it under the license of this project;
9
+ 2. You grant the project owner the right to relicense and redistribute your
10
+ Contribution under any license, without additional consent or attribution
11
+ constraints beyond copyright law;
12
+ 3. Each contribution carries a `Signed-off-by:` line (DCO 1.1).