chaffjs 0.25.0 → 0.27.0

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 (468) hide show
  1. package/README.md +179 -42
  2. package/dist/adapter-import.d.ts +2 -0
  3. package/dist/adapter-import.d.ts.map +1 -0
  4. package/dist/adapter-import.js +11 -0
  5. package/dist/adapter-import.js.map +1 -0
  6. package/dist/adapter-load.d.ts.map +1 -1
  7. package/dist/adapter-load.js +2 -9
  8. package/dist/adapter-load.js.map +1 -1
  9. package/dist/ai-score/human-shares.d.ts +4 -0
  10. package/dist/ai-score/human-shares.d.ts.map +1 -0
  11. package/dist/ai-score/human-shares.js +205 -0
  12. package/dist/ai-score/human-shares.js.map +1 -0
  13. package/dist/ai-score/lint-line.d.ts +4 -0
  14. package/dist/ai-score/lint-line.d.ts.map +1 -0
  15. package/dist/ai-score/lint-line.js +9 -0
  16. package/dist/ai-score/lint-line.js.map +1 -0
  17. package/dist/ai-score/of-document.d.ts +7 -0
  18. package/dist/ai-score/of-document.d.ts.map +1 -0
  19. package/dist/ai-score/of-document.js +40 -0
  20. package/dist/ai-score/of-document.js.map +1 -0
  21. package/dist/ai-score/render.d.ts +24 -0
  22. package/dist/ai-score/render.d.ts.map +1 -0
  23. package/dist/ai-score/render.js +100 -0
  24. package/dist/ai-score/render.js.map +1 -0
  25. package/dist/ai-score/score.d.ts +77 -0
  26. package/dist/ai-score/score.d.ts.map +1 -0
  27. package/dist/ai-score/score.js +52 -0
  28. package/dist/ai-score/score.js.map +1 -0
  29. package/dist/ai-score/signals.d.ts +19 -0
  30. package/dist/ai-score/signals.d.ts.map +1 -0
  31. package/dist/ai-score/signals.js +30 -0
  32. package/dist/ai-score/signals.js.map +1 -0
  33. package/dist/ai-score/text.d.ts +37 -0
  34. package/dist/ai-score/text.d.ts.map +1 -0
  35. package/dist/ai-score/text.js +59 -0
  36. package/dist/ai-score/text.js.map +1 -0
  37. package/dist/ai-score/view.d.ts +5 -0
  38. package/dist/ai-score/view.d.ts.map +1 -0
  39. package/dist/ai-score/view.js +19 -0
  40. package/dist/ai-score/view.js.map +1 -0
  41. package/dist/backends/anthropic.d.ts +0 -1
  42. package/dist/backends/anthropic.d.ts.map +1 -1
  43. package/dist/backends/anthropic.js +0 -1
  44. package/dist/backends/anthropic.js.map +1 -1
  45. package/dist/backends/default-model.d.ts +3 -0
  46. package/dist/backends/default-model.d.ts.map +1 -0
  47. package/dist/backends/default-model.js +5 -0
  48. package/dist/backends/default-model.js.map +1 -0
  49. package/dist/backends/openai.d.ts +0 -1
  50. package/dist/backends/openai.d.ts.map +1 -1
  51. package/dist/backends/openai.js +0 -1
  52. package/dist/backends/openai.js.map +1 -1
  53. package/dist/browser/adapter-import.d.ts +2 -0
  54. package/dist/browser/adapter-import.d.ts.map +1 -0
  55. package/dist/browser/adapter-import.js +17 -0
  56. package/dist/browser/adapter-import.js.map +1 -0
  57. package/dist/browser/bounded-match.d.ts +3 -0
  58. package/dist/browser/bounded-match.d.ts.map +1 -0
  59. package/dist/browser/bounded-match.js +4 -0
  60. package/dist/browser/bounded-match.js.map +1 -0
  61. package/dist/browser/check-text.d.ts +43 -0
  62. package/dist/browser/check-text.d.ts.map +1 -0
  63. package/dist/browser/check-text.js +50 -0
  64. package/dist/browser/check-text.js.map +1 -0
  65. package/dist/browser/detectors.d.ts +4 -0
  66. package/dist/browser/detectors.d.ts.map +1 -0
  67. package/dist/browser/detectors.js +22 -0
  68. package/dist/browser/detectors.js.map +1 -0
  69. package/dist/browser/package-files.d.ts +5 -0
  70. package/dist/browser/package-files.d.ts.map +1 -0
  71. package/dist/browser/package-files.js +8 -0
  72. package/dist/browser/package-files.js.map +1 -0
  73. package/dist/browser/path.d.ts +9 -0
  74. package/dist/browser/path.d.ts.map +1 -0
  75. package/dist/browser/path.js +70 -0
  76. package/dist/browser/path.js.map +1 -0
  77. package/dist/browser/working-dir.d.ts +2 -0
  78. package/dist/browser/working-dir.d.ts.map +1 -0
  79. package/dist/browser/working-dir.js +3 -0
  80. package/dist/browser/working-dir.js.map +1 -0
  81. package/dist/browser-files.d.ts +21 -0
  82. package/dist/browser-files.d.ts.map +1 -0
  83. package/dist/browser-files.js +65 -0
  84. package/dist/browser-files.js.map +1 -0
  85. package/dist/browser.d.ts +9 -0
  86. package/dist/browser.d.ts.map +1 -0
  87. package/dist/browser.js +13 -0
  88. package/dist/browser.js.map +1 -0
  89. package/dist/capitals-with-small.d.ts +8 -0
  90. package/dist/capitals-with-small.d.ts.map +1 -0
  91. package/dist/capitals-with-small.js +20 -0
  92. package/dist/capitals-with-small.js.map +1 -0
  93. package/dist/cli-text.d.ts.map +1 -1
  94. package/dist/cli-text.js +2 -0
  95. package/dist/cli-text.js.map +1 -1
  96. package/dist/cli.d.ts.map +1 -1
  97. package/dist/cli.js +4 -1
  98. package/dist/cli.js.map +1 -1
  99. package/dist/commands/ai-score.d.ts +8 -0
  100. package/dist/commands/ai-score.d.ts.map +1 -0
  101. package/dist/commands/ai-score.js +59 -0
  102. package/dist/commands/ai-score.js.map +1 -0
  103. package/dist/commands/document-commands.d.ts.map +1 -1
  104. package/dist/commands/document-commands.js +2 -0
  105. package/dist/commands/document-commands.js.map +1 -1
  106. package/dist/config/by-path-problems.d.ts +5 -0
  107. package/dist/config/by-path-problems.d.ts.map +1 -0
  108. package/dist/config/by-path-problems.js +11 -0
  109. package/dist/config/by-path-problems.js.map +1 -0
  110. package/dist/config/load.d.ts +9 -2
  111. package/dist/config/load.d.ts.map +1 -1
  112. package/dist/config/load.js +21 -8
  113. package/dist/config/load.js.map +1 -1
  114. package/dist/config/read.d.ts +2 -0
  115. package/dist/config/read.d.ts.map +1 -1
  116. package/dist/config/read.js +4 -1
  117. package/dist/config/read.js.map +1 -1
  118. package/dist/config/warnings.d.ts +1 -1
  119. package/dist/config/warnings.d.ts.map +1 -1
  120. package/dist/config/warnings.js +3 -1
  121. package/dist/config/warnings.js.map +1 -1
  122. package/dist/config/working-dir.d.ts +2 -0
  123. package/dist/config/working-dir.d.ts.map +1 -0
  124. package/dist/config/working-dir.js +3 -0
  125. package/dist/config/working-dir.js.map +1 -0
  126. package/dist/custom/bounded-match.d.ts +1 -12
  127. package/dist/custom/bounded-match.d.ts.map +1 -1
  128. package/dist/custom/bounded-match.js +1 -11
  129. package/dist/custom/bounded-match.js.map +1 -1
  130. package/dist/custom/pattern-timeout.d.ts +13 -0
  131. package/dist/custom/pattern-timeout.d.ts.map +1 -0
  132. package/dist/custom/pattern-timeout.js +13 -0
  133. package/dist/custom/pattern-timeout.js.map +1 -0
  134. package/dist/derived/relative-weekdays.d.ts +16 -0
  135. package/dist/derived/relative-weekdays.d.ts.map +1 -0
  136. package/dist/derived/relative-weekdays.js +52 -0
  137. package/dist/derived/relative-weekdays.js.map +1 -0
  138. package/dist/detect.d.ts.map +1 -1
  139. package/dist/detect.js +4 -5
  140. package/dist/detect.js.map +1 -1
  141. package/dist/detectors/change-rate.d.ts +3 -0
  142. package/dist/detectors/change-rate.d.ts.map +1 -0
  143. package/dist/detectors/change-rate.js +102 -0
  144. package/dist/detectors/change-rate.js.map +1 -0
  145. package/dist/detectors/date-year.d.ts +10 -2
  146. package/dist/detectors/date-year.d.ts.map +1 -1
  147. package/dist/detectors/date-year.js +44 -8
  148. package/dist/detectors/date-year.js.map +1 -1
  149. package/dist/detectors/defined-term-form.d.ts +5 -0
  150. package/dist/detectors/defined-term-form.d.ts.map +1 -1
  151. package/dist/detectors/defined-term-form.js +22 -5
  152. package/dist/detectors/defined-term-form.js.map +1 -1
  153. package/dist/detectors/derived-numbers.d.ts.map +1 -1
  154. package/dist/detectors/derived-numbers.js +3 -7
  155. package/dist/detectors/derived-numbers.js.map +1 -1
  156. package/dist/detectors/document-date.d.ts +4 -0
  157. package/dist/detectors/document-date.d.ts.map +1 -0
  158. package/dist/detectors/document-date.js +12 -0
  159. package/dist/detectors/document-date.js.map +1 -0
  160. package/dist/detectors/orthographic-variant.d.ts.map +1 -1
  161. package/dist/detectors/orthographic-variant.js +60 -28
  162. package/dist/detectors/orthographic-variant.js.map +1 -1
  163. package/dist/detectors/party-role-name.d.ts +3 -0
  164. package/dist/detectors/party-role-name.d.ts.map +1 -0
  165. package/dist/detectors/party-role-name.js +35 -0
  166. package/dist/detectors/party-role-name.js.map +1 -0
  167. package/dist/detectors/quote-without-source.d.ts +17 -0
  168. package/dist/detectors/quote-without-source.d.ts.map +1 -0
  169. package/dist/detectors/quote-without-source.js +64 -0
  170. package/dist/detectors/quote-without-source.js.map +1 -0
  171. package/dist/detectors/reference-text.js +1 -1
  172. package/dist/detectors/reference-text.js.map +1 -1
  173. package/dist/detectors/registry/change-rate.d.ts +3 -0
  174. package/dist/detectors/registry/change-rate.d.ts.map +1 -0
  175. package/dist/detectors/registry/change-rate.js +3 -0
  176. package/dist/detectors/registry/change-rate.js.map +1 -0
  177. package/dist/detectors/registry/party-role-name.d.ts +3 -0
  178. package/dist/detectors/registry/party-role-name.d.ts.map +1 -0
  179. package/dist/detectors/registry/party-role-name.js +3 -0
  180. package/dist/detectors/registry/party-role-name.js.map +1 -0
  181. package/dist/detectors/registry/quote-without-source.d.ts +3 -0
  182. package/dist/detectors/registry/quote-without-source.d.ts.map +1 -0
  183. package/dist/detectors/registry/quote-without-source.js +3 -0
  184. package/dist/detectors/registry/quote-without-source.js.map +1 -0
  185. package/dist/detectors/registry/vague-deadline.d.ts +3 -0
  186. package/dist/detectors/registry/vague-deadline.d.ts.map +1 -0
  187. package/dist/detectors/registry/vague-deadline.js +3 -0
  188. package/dist/detectors/registry/vague-deadline.js.map +1 -0
  189. package/dist/detectors/registry/version-mismatch.d.ts +3 -0
  190. package/dist/detectors/registry/version-mismatch.d.ts.map +1 -0
  191. package/dist/detectors/registry/version-mismatch.js +3 -0
  192. package/dist/detectors/registry/version-mismatch.js.map +1 -0
  193. package/dist/detectors/relative-dates.d.ts.map +1 -1
  194. package/dist/detectors/relative-dates.js +3 -1
  195. package/dist/detectors/relative-dates.js.map +1 -1
  196. package/dist/detectors/relative-day-words.d.ts +4 -0
  197. package/dist/detectors/relative-day-words.d.ts.map +1 -0
  198. package/dist/detectors/relative-day-words.js +105 -0
  199. package/dist/detectors/relative-day-words.js.map +1 -0
  200. package/dist/detectors/run-in-label.d.ts +7 -0
  201. package/dist/detectors/run-in-label.d.ts.map +1 -0
  202. package/dist/detectors/run-in-label.js +53 -0
  203. package/dist/detectors/run-in-label.js.map +1 -0
  204. package/dist/detectors/sentence-counts.d.ts +3 -1
  205. package/dist/detectors/sentence-counts.d.ts.map +1 -1
  206. package/dist/detectors/sentence-counts.js +11 -4
  207. package/dist/detectors/sentence-counts.js.map +1 -1
  208. package/dist/detectors/sentence-ending.d.ts +1 -1
  209. package/dist/detectors/sentence-ending.d.ts.map +1 -1
  210. package/dist/detectors/sentence-ending.js +2 -1
  211. package/dist/detectors/sentence-ending.js.map +1 -1
  212. package/dist/detectors/structure-tree.d.ts +8 -2
  213. package/dist/detectors/structure-tree.d.ts.map +1 -1
  214. package/dist/detectors/structure-tree.js +86 -5
  215. package/dist/detectors/structure-tree.js.map +1 -1
  216. package/dist/detectors/unbalanced-bracket.d.ts +1 -1
  217. package/dist/detectors/unbalanced-bracket.d.ts.map +1 -1
  218. package/dist/detectors/unbalanced-bracket.js +23 -11
  219. package/dist/detectors/unbalanced-bracket.js.map +1 -1
  220. package/dist/detectors/vague-deadline.d.ts +25 -0
  221. package/dist/detectors/vague-deadline.d.ts.map +1 -0
  222. package/dist/detectors/vague-deadline.js +97 -0
  223. package/dist/detectors/vague-deadline.js.map +1 -0
  224. package/dist/detectors/version-mismatch.d.ts +3 -0
  225. package/dist/detectors/version-mismatch.d.ts.map +1 -0
  226. package/dist/detectors/version-mismatch.js +19 -0
  227. package/dist/detectors/version-mismatch.js.map +1 -0
  228. package/dist/furigana.d.ts +7 -0
  229. package/dist/furigana.d.ts.map +1 -0
  230. package/dist/furigana.js +16 -0
  231. package/dist/furigana.js.map +1 -0
  232. package/dist/genre-load.d.ts.map +1 -1
  233. package/dist/genre-load.js +5 -7
  234. package/dist/genre-load.js.map +1 -1
  235. package/dist/grade/ai-score.d.ts +16 -0
  236. package/dist/grade/ai-score.d.ts.map +1 -0
  237. package/dist/grade/ai-score.js +17 -0
  238. package/dist/grade/ai-score.js.map +1 -0
  239. package/dist/grade/finding.d.ts +6 -0
  240. package/dist/grade/finding.d.ts.map +1 -0
  241. package/dist/grade/finding.js +13 -0
  242. package/dist/grade/finding.js.map +1 -0
  243. package/dist/grade/grade-item.d.ts.map +1 -1
  244. package/dist/grade/grade-item.js +4 -11
  245. package/dist/grade/grade-item.js.map +1 -1
  246. package/dist/grade/render-variants.d.ts.map +1 -1
  247. package/dist/grade/render-variants.js +3 -0
  248. package/dist/grade/render-variants.js.map +1 -1
  249. package/dist/grade/render.d.ts.map +1 -1
  250. package/dist/grade/render.js +1 -0
  251. package/dist/grade/render.js.map +1 -1
  252. package/dist/grade/result.d.ts +3 -0
  253. package/dist/grade/result.d.ts.map +1 -1
  254. package/dist/grade/results-read.d.ts.map +1 -1
  255. package/dist/grade/results-read.js +13 -2
  256. package/dist/grade/results-read.js.map +1 -1
  257. package/dist/grade/summary.d.ts +3 -0
  258. package/dist/grade/summary.d.ts.map +1 -1
  259. package/dist/grade/summary.js +6 -0
  260. package/dist/grade/summary.js.map +1 -1
  261. package/dist/grade/text.d.ts +2 -0
  262. package/dist/grade/text.d.ts.map +1 -1
  263. package/dist/grade/text.js +2 -0
  264. package/dist/grade/text.js.map +1 -1
  265. package/dist/grade/variants-text.d.ts +3 -0
  266. package/dist/grade/variants-text.d.ts.map +1 -1
  267. package/dist/grade/variants-text.js +4 -0
  268. package/dist/grade/variants-text.js.map +1 -1
  269. package/dist/grade/variants.d.ts +3 -0
  270. package/dist/grade/variants.d.ts.map +1 -1
  271. package/dist/grade/variants.js +1 -0
  272. package/dist/grade/variants.js.map +1 -1
  273. package/dist/grade-api.d.ts +1 -0
  274. package/dist/grade-api.d.ts.map +1 -1
  275. package/dist/grade-api.js +2 -1
  276. package/dist/grade-api.js.map +1 -1
  277. package/dist/judge.d.ts +0 -1
  278. package/dist/judge.d.ts.map +1 -1
  279. package/dist/judge.js +0 -1
  280. package/dist/judge.js.map +1 -1
  281. package/dist/known-genres.js +2 -2
  282. package/dist/known-genres.js.map +1 -1
  283. package/dist/package-files.d.ts +6 -0
  284. package/dist/package-files.d.ts.map +1 -0
  285. package/dist/package-files.js +11 -0
  286. package/dist/package-files.js.map +1 -0
  287. package/dist/profile/load.d.ts.map +1 -1
  288. package/dist/profile/load.js +5 -6
  289. package/dist/profile/load.js.map +1 -1
  290. package/dist/rule-load.d.ts.map +1 -1
  291. package/dist/rule-load.js +5 -6
  292. package/dist/rule-load.js.map +1 -1
  293. package/dist/rule-offs.js +3 -3
  294. package/dist/rule-offs.js.map +1 -1
  295. package/dist/run.js +1 -1
  296. package/dist/run.js.map +1 -1
  297. package/dist/structure/change-rate.d.ts +33 -0
  298. package/dist/structure/change-rate.d.ts.map +1 -0
  299. package/dist/structure/change-rate.js +71 -0
  300. package/dist/structure/change-rate.js.map +1 -0
  301. package/dist/structure/date-range.d.ts +4 -0
  302. package/dist/structure/date-range.d.ts.map +1 -1
  303. package/dist/structure/date-range.js +23 -3
  304. package/dist/structure/date-range.js.map +1 -1
  305. package/dist/structure/issues.d.ts +17 -1
  306. package/dist/structure/issues.d.ts.map +1 -1
  307. package/dist/structure/issues.js +54 -5
  308. package/dist/structure/issues.js.map +1 -1
  309. package/dist/structure/list-numbering.d.ts +17 -0
  310. package/dist/structure/list-numbering.d.ts.map +1 -0
  311. package/dist/structure/list-numbering.js +27 -0
  312. package/dist/structure/list-numbering.js.map +1 -0
  313. package/dist/structure/party-role.d.ts +30 -0
  314. package/dist/structure/party-role.d.ts.map +1 -0
  315. package/dist/structure/party-role.js +58 -0
  316. package/dist/structure/party-role.js.map +1 -0
  317. package/dist/structure/percent-sum-prose.d.ts +7 -0
  318. package/dist/structure/percent-sum-prose.d.ts.map +1 -0
  319. package/dist/structure/percent-sum-prose.js +44 -0
  320. package/dist/structure/percent-sum-prose.js.map +1 -0
  321. package/dist/structure/prose-total.d.ts +28 -0
  322. package/dist/structure/prose-total.d.ts.map +1 -0
  323. package/dist/structure/prose-total.js +99 -0
  324. package/dist/structure/prose-total.js.map +1 -0
  325. package/dist/structure/reference-text.d.ts +5 -0
  326. package/dist/structure/reference-text.d.ts.map +1 -1
  327. package/dist/structure/reference-text.js +17 -4
  328. package/dist/structure/reference-text.js.map +1 -1
  329. package/dist/structure/term-prefix.d.ts +18 -0
  330. package/dist/structure/term-prefix.d.ts.map +1 -0
  331. package/dist/structure/term-prefix.js +40 -0
  332. package/dist/structure/term-prefix.js.map +1 -0
  333. package/dist/structure/total.d.ts +2 -0
  334. package/dist/structure/total.d.ts.map +1 -1
  335. package/dist/structure/total.js +2 -0
  336. package/dist/structure/total.js.map +1 -1
  337. package/dist/structure/version-mismatch.d.ts +23 -0
  338. package/dist/structure/version-mismatch.d.ts.map +1 -0
  339. package/dist/structure/version-mismatch.js +74 -0
  340. package/dist/structure/version-mismatch.js.map +1 -0
  341. package/dist/structure/weekday.d.ts +21 -2
  342. package/dist/structure/weekday.d.ts.map +1 -1
  343. package/dist/structure/weekday.js +70 -8
  344. package/dist/structure/weekday.js.map +1 -1
  345. package/dist/structure-shape/baseline-load.d.ts.map +1 -1
  346. package/dist/structure-shape/baseline-load.js +4 -5
  347. package/dist/structure-shape/baseline-load.js.map +1 -1
  348. package/dist/style-load.d.ts.map +1 -1
  349. package/dist/style-load.js +5 -6
  350. package/dist/style-load.js.map +1 -1
  351. package/package.json +24 -3
  352. package/rules/agreement-slip.yaml +2 -2
  353. package/rules/change-rate-mismatch.yaml +44 -0
  354. package/rules/cliche.yaml +28 -8
  355. package/rules/date-weekday-mismatch.yaml +4 -4
  356. package/rules/date-without-year.yaml +28 -3
  357. package/rules/defined-term-form.yaml +9 -6
  358. package/rules/demonstrative-opener-run.yaml +24 -7
  359. package/rules/max-sentence-length.yaml +1 -0
  360. package/rules/no-mixed-desumasu.yaml +2 -2
  361. package/rules/numbering-gap.yaml +4 -4
  362. package/rules/one-sentence-paragraph-run.yaml +1 -0
  363. package/rules/orthographic-variant.yaml +3 -3
  364. package/rules/party-role-name.yaml +94 -0
  365. package/rules/percent-sum-mismatch.yaml +4 -4
  366. package/rules/quote-without-source.yaml +61 -0
  367. package/rules/relative-date-mismatch.yaml +4 -4
  368. package/rules/total-mismatch.yaml +8 -8
  369. package/rules/undefined-acronym.yaml +1 -0
  370. package/rules/vague-deadline.yaml +95 -0
  371. package/rules/version-mismatch.yaml +77 -0
  372. package/rules/weasel-word.yaml +25 -7
  373. package/skills/chaff/SKILL.md +12 -2
  374. package/src/adapter-import.ts +3 -0
  375. package/src/adapter-load.ts +2 -1
  376. package/src/ai-score/human-shares.ts +207 -0
  377. package/src/ai-score/lint-line.ts +10 -0
  378. package/src/ai-score/of-document.ts +46 -0
  379. package/src/ai-score/render.ts +124 -0
  380. package/src/ai-score/score.ts +121 -0
  381. package/src/ai-score/signals.ts +39 -0
  382. package/src/ai-score/text.ts +103 -0
  383. package/src/ai-score/view.ts +21 -0
  384. package/src/backends/anthropic.ts +0 -2
  385. package/src/backends/default-model.ts +9 -0
  386. package/src/backends/openai.ts +0 -2
  387. package/src/browser/adapter-import.ts +19 -0
  388. package/src/browser/bounded-match.ts +9 -0
  389. package/src/browser/check-text.ts +106 -0
  390. package/src/browser/detectors.ts +40 -0
  391. package/src/browser/import-meta-glob.d.ts +5 -0
  392. package/src/browser/package-files.ts +13 -0
  393. package/src/browser/path.ts +73 -0
  394. package/src/browser/working-dir.ts +3 -0
  395. package/src/browser-files.ts +87 -0
  396. package/src/browser.ts +19 -0
  397. package/src/capitals-with-small.ts +23 -0
  398. package/src/cli-text.ts +2 -0
  399. package/src/cli.ts +4 -1
  400. package/src/commands/ai-score.ts +77 -0
  401. package/src/commands/document-commands.ts +2 -0
  402. package/src/config/by-path-problems.ts +17 -0
  403. package/src/config/load.ts +21 -8
  404. package/src/config/read.ts +5 -1
  405. package/src/config/warnings.ts +3 -1
  406. package/src/config/working-dir.ts +3 -0
  407. package/src/custom/bounded-match.ts +1 -16
  408. package/src/custom/pattern-timeout.ts +17 -0
  409. package/src/derived/relative-weekdays.ts +65 -0
  410. package/src/detect.ts +4 -5
  411. package/src/detectors/change-rate.ts +122 -0
  412. package/src/detectors/date-year.ts +51 -12
  413. package/src/detectors/defined-term-form.ts +28 -6
  414. package/src/detectors/derived-numbers.ts +3 -11
  415. package/src/detectors/document-date.ts +18 -0
  416. package/src/detectors/orthographic-variant.ts +67 -22
  417. package/src/detectors/party-role-name.ts +44 -0
  418. package/src/detectors/quote-without-source.ts +90 -0
  419. package/src/detectors/reference-text.ts +1 -1
  420. package/src/detectors/registry/change-rate.ts +4 -0
  421. package/src/detectors/registry/party-role-name.ts +4 -0
  422. package/src/detectors/registry/quote-without-source.ts +4 -0
  423. package/src/detectors/registry/vague-deadline.ts +4 -0
  424. package/src/detectors/registry/version-mismatch.ts +4 -0
  425. package/src/detectors/relative-dates.ts +3 -1
  426. package/src/detectors/relative-day-words.ts +126 -0
  427. package/src/detectors/run-in-label.ts +60 -0
  428. package/src/detectors/sentence-counts.ts +13 -4
  429. package/src/detectors/sentence-ending.ts +3 -2
  430. package/src/detectors/structure-tree.ts +104 -10
  431. package/src/detectors/unbalanced-bracket.ts +25 -10
  432. package/src/detectors/vague-deadline.ts +132 -0
  433. package/src/detectors/version-mismatch.ts +23 -0
  434. package/src/furigana.ts +20 -0
  435. package/src/genre-load.ts +5 -7
  436. package/src/grade/ai-score.ts +32 -0
  437. package/src/grade/finding.ts +16 -0
  438. package/src/grade/grade-item.ts +4 -13
  439. package/src/grade/render-variants.ts +5 -0
  440. package/src/grade/render.ts +1 -0
  441. package/src/grade/result.ts +3 -0
  442. package/src/grade/results-read.ts +17 -2
  443. package/src/grade/summary.ts +9 -0
  444. package/src/grade/text.ts +6 -0
  445. package/src/grade/variants-text.ts +7 -0
  446. package/src/grade/variants.ts +4 -0
  447. package/src/grade-api.ts +3 -1
  448. package/src/judge.ts +0 -2
  449. package/src/known-genres.ts +2 -2
  450. package/src/package-files.ts +15 -0
  451. package/src/profile/load.ts +5 -6
  452. package/src/rule-load.ts +5 -6
  453. package/src/rule-offs.ts +3 -3
  454. package/src/run.ts +1 -1
  455. package/src/structure/change-rate.ts +103 -0
  456. package/src/structure/date-range.ts +28 -3
  457. package/src/structure/issues.ts +61 -6
  458. package/src/structure/list-numbering.ts +34 -0
  459. package/src/structure/party-role.ts +94 -0
  460. package/src/structure/percent-sum-prose.ts +54 -0
  461. package/src/structure/prose-total.ts +135 -0
  462. package/src/structure/reference-text.ts +17 -4
  463. package/src/structure/term-prefix.ts +54 -0
  464. package/src/structure/total.ts +4 -0
  465. package/src/structure/version-mismatch.ts +103 -0
  466. package/src/structure/weekday.ts +83 -6
  467. package/src/structure-shape/baseline-load.ts +4 -5
  468. package/src/style-load.ts +5 -6
@@ -0,0 +1,94 @@
1
+ id: party-role-name
2
+ layer: L3
3
+ status: stable
4
+ how_to_find: party-role-name
5
+ requires: [structure]
6
+ severity: info
7
+
8
+ name:
9
+ ja: 当事者を、定めた呼び名でなく立場の語で書いている
10
+ en: A party named by its role instead of the name the contract gave it
11
+
12
+ why:
13
+ ja: 「株式会社しおさい技研(以下「乙」という。)」と定めた契約で、途中から「受託者」と書くと、読み手は受託者が乙のことか、別の誰か(再委託先など)なのかを確かめることになります。ひな形の条項を貼り合わせたときに、元の契約の呼び方が残ると起きます。文の途中で括弧に入れて当事者の呼び名を定めた文書で、その後ろに書いた立場の語(委託者・受託者・開示者・受領者・売主・買主・運営者、the Vendor、the Recipient など)を指します。語は言語ごとの語彙表にあります。
14
+ en: Once a contract says "Harbour Works Ltd (the "Supplier")", writing "the Vendor" later makes the reader check whether the Supplier is meant or someone else, such as a subcontractor. It happens when clauses from another template are pasted in with that template's names. In a document that gives its parties short names in brackets, chaff points at each later role word (the Vendor, the Recipient, the Company, 受託者, 売主) that the document did not define. The words are in each language's word list.
15
+
16
+ message:
17
+ ja: 「{role}」は、この契約が当事者に定めた呼び名({names})ではありません
18
+ en: '"{role}" is not a name this contract gave a party ({names})'
19
+
20
+ how_to_fix:
21
+ ja: 定めた呼び名(甲・乙など)に書き換えてください。当事者でない人を指すなら、その人を定義してから使います。
22
+ en: Use the name the contract gave the party. If someone else is meant, define them first.
23
+
24
+ levels: { strict: warning, normal: info, relaxed: info }
25
+
26
+ use_for: [legal, docs, academic, literature, speech]
27
+ off_for:
28
+ docs: "Defined terms and short names are a contract's apparatus: the legal genres check them."
29
+ academic: "Defined terms and short names are a contract's apparatus: the legal genres check them."
30
+ literature: "Defined terms and short names are a contract's apparatus: the legal genres check them."
31
+ speech: "Defined terms and short names are a contract's apparatus: the legal genres check them."
32
+ legal/statute: "A statute names people by their role (委託者, the employer) on purpose: it defines no parties."
33
+
34
+ group: consistency
35
+ summary:
36
+ ja: 当事者を「甲」「乙」と定めたあとで、「委託者」「受託者」のような立場の語で書いている所
37
+ en: A party given a short name ("the Supplier") and later called by a role word (the Vendor)
38
+ example:
39
+ ja:
40
+ config: { genre: legal/contract }
41
+ before: |
42
+ # 業務委託契約書
43
+
44
+ 株式会社みなと製作所(以下「甲」という。)と北浜商事株式会社(以下「乙」という。)は、次のとおり契約を結ぶ。
45
+
46
+ 第1条 受託者は、甲の会議室の予約を代わりに行う。
47
+ after: |
48
+ # 業務委託契約書
49
+
50
+ 株式会社みなと製作所(以下「甲」という。)と北浜商事株式会社(以下「乙」という。)は、次のとおり契約を結ぶ。
51
+
52
+ 第1条 乙は、甲の会議室の予約を代わりに行う。
53
+ en:
54
+ config: { genre: legal/contract }
55
+ before: |
56
+ # Services Agreement
57
+
58
+ This agreement is between Harbour Works Ltd (the "Supplier") and North Trading Inc (the "Customer").
59
+
60
+ 1. The Customer pays the Vendor within thirty days of each invoice.
61
+ after: |
62
+ # Services Agreement
63
+
64
+ This agreement is between Harbour Works Ltd (the "Supplier") and North Trading Inc (the "Customer").
65
+
66
+ 1. The Customer pays the Supplier within thirty days of each invoice.
67
+
68
+ not_flagged:
69
+ ja: 当事者の呼び名を定める前(「売主 有限会社たちばな木工(以下「甲」という。)」の売主)、定めた語そのもの(「開示者」と定義した文書の開示者)、定義した語の一部、長い語の一部(再委託先、委託者側)は見ません。当事者の定義は、呼び名が甲・乙・当社のような語か立場の語であるもの、または括弧のすぐ前に会社の形(株式会社、Ltd)があるものだけを読みます。法務のジャンルで見ます。法令・規程は当事者を定めず、立場の語で人を呼ぶので見ません。
70
+ en: 'Uses before the parties are named, a role word the document defines itself ("Recipient" means), a role word inside a defined term (Receiving Party) or a longer word, and a lower-case role word (the vendor, an ordinary noun) are not reported. A party is read from a short name in brackets that is a party word (we) or a role word itself, or that follows a company name (Ltd, Inc.). The legal genres run this rule, except statutes, which name people by their role and define no parties.'
71
+ rewrite:
72
+ depth: light
73
+ ja:
74
+ direction: 立場の語を、定めた呼び名に置き換えてください。どちらの当事者か分からなければ、書き手に確かめます。当事者でない人を指しているなら、その人を定義します。
75
+ pairs:
76
+ - before: 受託者は、甲の会議室の予約を代わりに行う。
77
+ after: 乙は、甲の会議室の予約を代わりに行う。
78
+ - before: 委託者は、毎月末日までに委託料を支払う。
79
+ after: 甲は、毎月末日までに委託料を支払う。
80
+ keep:
81
+ - 条の番号と中身
82
+ avoid:
83
+ - 甲と乙を取り違える
84
+ en:
85
+ direction: Replace the role word with the name the contract gave the party. If it is not clear which party is meant, ask the writer. If someone else is meant, define them.
86
+ pairs:
87
+ - before: The Customer pays the Vendor within thirty days.
88
+ after: The Customer pays the Supplier within thirty days.
89
+ - before: The Recipient shall return all documents on request.
90
+ after: The Customer shall return all documents on request.
91
+ keep:
92
+ - the clause numbers and their content
93
+ avoid:
94
+ - swapping the parties
@@ -10,8 +10,8 @@ name:
10
10
  en: Shares of a whole that do not add up to 100%
11
11
 
12
12
  why:
13
- ja: 構成比や内訳の百分率を足して 100% にならないと、読み手はどの数字が違うのか、項目が抜けたのかを確かめることになります。項目を足したり消したり、数字を一つだけ直したりしたときに起きます。表のその列の見出しか、箇条書きや表のすぐ上の文・見出しに、全体を分けた割合の語(構成比、内訳、シェア)があるときだけ足します。丸めの誤差は、項目ごとに最後の桁の半分まで(少なくとも 1 ポイント)認めます。
14
- en: When the shares of a whole do not add up to 100%, the reader has to work out which figure is wrong or which item is missing. It happens when an item is added or removed, or when one figure is changed. The percentages are added only when the column's header, or the sentence or heading right above the list or the table, names the parts of a whole (breakdown, market share, composition). Rounding is allowed, up to half the last digit per item (at least one point).
13
+ ja: 構成比や内訳の百分率を足して 100% にならないと、読み手はどの数字が違うのか、項目が抜けたのかを確かめることになります。項目を足したり消したり、数字を一つだけ直したりしたときに起きます。表のその列の見出しか、箇条書きや表のすぐ上の文・見出しに、全体を分けた割合の語(構成比、内訳、シェア)があるときだけ足します。一つの文に並べた内訳(「構成比は、Aが50%、Bが30%、Cが25%」)も、その文に割合の語があり百分率が三つ以上あれば足します。丸めの誤差は、項目ごとに最後の桁の半分まで(少なくとも 1 ポイント)認めます。
14
+ en: When the shares of a whole do not add up to 100%, the reader has to work out which figure is wrong or which item is missing. It happens when an item is added or removed, or when one figure is changed. The percentages are added only when the column's header, or the sentence or heading right above the list or the table, names the parts of a whole (breakdown, market share, composition). A breakdown written in one sentence ("software made up 50% of sales, maintenance 30% and training 25%") is added too, when the sentence has such a word and three or more percentages. Rounding is allowed, up to half the last digit per item (at least one point).
15
15
 
16
16
  message:
17
17
  ja: 内訳の割合の和が {sum} で、100% になりません
@@ -56,5 +56,5 @@ example:
56
56
  - Europe: 40%
57
57
 
58
58
  not_flagged:
59
- ja: 割合の語の無い百分率(利用率、伸び率)、複数回答の集計、符号の付いた増減(+3%)、合計の行がある表(合計が内訳の和と合わない の対象)、項目が一つだけのものは足しません。
60
- en: 'Percentages not named as shares (rates, growth), multiple-answer counts, signed changes (+3%), a table with a total row (left to "A total that is not the sum of its items"), and a single item are not added.'
59
+ ja: 割合の語の無い百分率(利用率、伸び率)、複数回答の集計、符号の付いた増減(+3%)、合計の行がある表(合計が内訳の和と合わない の対象)、項目が一つだけのものは足しません。一つの文の内訳は、和が 100% から 10 ポイントより離れていれば言いません(大きい項目だけを挙げた文や、別の全体・前の年の割合を並べた文)。
60
+ en: 'Percentages not named as shares (rates, growth), multiple-answer counts, signed changes (+3%), a table with a total row (left to "A total that is not the sum of its items"), and a single item are not added. A breakdown in one sentence whose sum is more than 10 points from 100% is not reported: it names only the larger parts, or shares of different wholes or of two periods.'
@@ -0,0 +1,61 @@
1
+ id: quote-without-source
2
+ layer: L2
3
+ status: stable
4
+ how_to_find: quote-without-source
5
+ severity: info
6
+
7
+ name:
8
+ ja: 人の言葉として引いた文に出典がない
9
+ en: A quotation given to someone, with no source
10
+
11
+ why:
12
+ ja: 「〜は『…』と述べている」のように人の言葉として引いた文は、読み手がその人の言葉だと信じて読みます。出典が無いと、本当にその人がそう言ったのか、言い回しが正しいのかを誰も確かめられません。人から人へ伝わるうちに言葉が変わったり、言った人が入れ替わったりするのは、引用でいちばんよく起きる誤りです。chaff はその人が本当に言ったかを知りませんが、確かめる手がかりが無いことは言えます。鉤括弧や引用符で引いた文の直後か少し前に、誰かに帰する言い回し(「と述べ」「によれば」。語の一覧は言語ごとの語彙表にあります)があり、同じ段落にリンクも脚注も番号の引用も括弧の中の年も無いときに指します。
13
+ en: 'A quotation given to someone ("X once said …", "according to X") is read as that person''s words. With no source, nobody can check that the person said it, or said it that way; words change and speakers swap as a quotation is passed along, which is the commonest error in quoting. chaff cannot know who said what, but it can say there is nothing to check the quotation against. It points at a quotation in quotation marks given to someone by the words right after it or shortly before it ("said", "according to"; the words are in each language''s word list), in a paragraph with no link, no footnote, no numbered citation and no year in brackets.'
14
+
15
+ message:
16
+ ja: 「{quote}」を人の言葉として引いていますが、出典(リンク、脚注、書誌)がありません
17
+ en: '"{quote}" is given to someone, but no source (a link, a footnote, a reference) is given'
18
+
19
+ how_to_fix:
20
+ ja: 同じ段落に出典を書いてください。Web で読めるならリンクを、本や論文なら「(著者, 書名, 年)」か脚注を付けます。出典が見つからないなら、言い回しを確かめられるまで人の言葉としては引かないでください。出典を書いたら、`chaff cite <出典> <引用.json>` で、その言葉が出典に本当にあるかを照らせます(chaff --format json の quote がそのまま使えます)。
21
+ en: 'Name the source in the same paragraph: a link when it can be read online, or "(Author, Title, year)" or a footnote for a book or a paper. If no source can be found, do not give the words to the person until they can be checked. With the source in hand, `chaff cite <source> <quotes.json>` checks that the words are really there (each finding''s quote in chaff --format json is the text to check).'
22
+
23
+ levels: { strict: warning, normal: info, relaxed: info }
24
+
25
+ use_for: [blog, academic, docs, legal, literature, speech]
26
+ off_for:
27
+ blog/owned-media: "An organisation's article quotes the people it interviewed: the interview is the source."
28
+ docs: "A manual quotes messages, labels and commands, not people's words."
29
+ legal: "A contract or a statute quotes its own terms and other provisions, which are cited by article."
30
+ literature: "A story's quotations are its characters' words."
31
+ speech: "A speech or a transcript gives its own words, and quotes from memory by design."
32
+
33
+ group: facts
34
+ summary:
35
+ ja: 「〜は『…』と述べた」のように人の言葉として引いたのに、同じ段落に出典の無い所
36
+ en: A quotation given to someone ("X said …") in a paragraph that gives no source
37
+ example:
38
+ ja:
39
+ config: { genre: blog/tech }
40
+ before: |
41
+ # 遅れた計画
42
+
43
+ ある研究者は「遅れているプロジェクトに人を足すと、さらに遅れる」と述べている。人を足す前に、仕事を分けられるかを考えたい。
44
+ after: |
45
+ # 遅れた計画
46
+
47
+ ある研究者は「遅れているプロジェクトに人を足すと、さらに遅れる」と述べている([出典](https://example.com/essay))。人を足す前に、仕事を分けられるかを考えたい。
48
+ en:
49
+ config: { genre: blog/tech }
50
+ before: |
51
+ # Late projects
52
+
53
+ As one engineer put it, "adding people to a late project only makes it later." Before adding people, ask whether the work can be split.
54
+ after: |
55
+ # Late projects
56
+
57
+ As one engineer put it, "adding people to a late project only makes it later" ([source](https://example.com/essay)). Before adding people, ask whether the work can be split.
58
+
59
+ not_flagged:
60
+ ja: 短い鉤括弧(「保存」ボタン、「出典」という語)は語や名前を引いたもので、人の言葉ではないので見ません。誰かに帰する言い回しが引用のすぐ後ろ(「…」と述べた)か少し前(によれば「…」)に無い引用は、書き手自身の言葉か、題名や言い換えなので見ません。同じ段落にリンク、URL、脚注([^1])、番号の引用([3])、括弧の中の年((1975)、(1999年))があれば、出典を書いたと見ます。出典が正しいかは見ません。それは `chaff cite` が照らします。記事(ブログ、エッセイ)と論文で見ます。組織の記事は取材した人の言葉を、プレスリリースや報告書は自分たちの言葉や題名で示した文書を引くので、手順書、仕様、契約や法令、小説、話し言葉とあわせて既定で止めています。
61
+ en: 'A short quotation (the "Save" button, the word "source") names a word or a thing, not someone''s words, and is not read. A quotation with no such words right after it or shortly before it is the writer''s own words, a title or a paraphrase. A link, a URL, a footnote ([^1]), a numbered citation ([3]) or a year in brackets ((1975)) in the same paragraph counts as a source. Whether the source is right is not checked here: `chaff cite` checks that. Blog posts, essays and papers are read. An organisation''s articles quote the people they interviewed, and press releases and reports quote their own people or documents named by title, so they are left out by default, with manuals, specifications, contracts and statutes, fiction and speech.'
@@ -10,8 +10,8 @@ name:
10
10
  en: A relative date that does not match its base date
11
11
 
12
12
  why:
13
- ja: 「10月2日に申し込み、3日後の10月6日に通知」のように、相対の期間と日付を一緒に書くと、読み手はどちらが正しいのか分かりません。日程をずらしたときに、日付か期間の片方だけを直すと起きます。「3日後の」「1か月前の」のすぐ後ろの日付を、同じ文で前にある日付(文が「2週間後、」で始まるなら前の文の日付)に期間を足した(前なら引いた)日と比べます。
14
- en: 'When a relative length and a date are written together ("Applications open on May 1, 2026. Two weeks later, on May 16, 2026, …"), the reader cannot tell which is right. It happens when a schedule moves and only the date or only the length is changed. The date right after "N days later" or "N weeks earlier" is compared with the nearest earlier date in the same sentence (or in the previous sentence when the sentence opens with the relative length), plus or minus the length.'
13
+ ja: 「10月2日に申し込み、3日後の10月6日に通知」のように、相対の期間と日付を一緒に書くと、読み手はどちらが正しいのか分かりません。日程をずらしたときに、日付か期間の片方だけを直すと起きます。「3日後の」「1か月前の」のすぐ後ろの日付を、同じ文で前にある日付(文が「2週間後、」で始まるなら前の文の日付)に期間を足した(前なら引いた)日と比べます。メールや議事録の「来週月曜(10月12日)」「明日(10月7日)」も、メールや議事録の頭の日付の欄(「日付:」「日時:」)の日付から数えた日と比べます。週は月曜からとも日曜からとも、「来週月曜」はすぐ次の月曜とも読み、どの読み方にも合わない日付だけを指します。
14
+ en: 'When a relative length and a date are written together ("Applications open on May 1, 2026. Two weeks later, on May 16, 2026, …"), the reader cannot tell which is right. It happens when a schedule moves and only the date or only the length is changed. The date right after "N days later" or "N weeks earlier" is compared with the nearest earlier date in the same sentence (or in the previous sentence when the sentence opens with the relative length), plus or minus the length. A day word in an email or minutes ("next Monday (October 12)", "tomorrow (October 7)") is compared with the day it counts to from the date field at the head of the email or the minutes ("Date:"). A week may start on Monday or on Sunday, and "next Monday" may be the coming Monday; only a date that fits none of these readings is reported.'
15
15
 
16
16
  message:
17
17
  ja: "{base}の{relative}なら{expected}のはずですが、{target}と書かれています"
@@ -42,8 +42,8 @@ example:
42
42
  Applications close on May 1, 2026. Two weeks later, on May 15, 2026, results are sent.
43
43
 
44
44
  not_flagged:
45
- ja: 期間のすぐ後ろ(「の」や読点だけを挟む)に日付があるときだけ見ます。基準の日付が同じ文(文の頭の「2週間後、」なら前の文)に無いもの、「3営業日後」のように単位が日・週・月・年でないものは見ません。
46
- en: Only a date right after the relative length (with "on" or punctuation between) is checked. A relative length with no date before it in the same sentence (or the previous one, when the sentence opens with it), and units other than days, weeks, months and years ("3 business days later"), are left alone.
45
+ ja: 期間のすぐ後ろ(「の」や読点だけを挟む)に日付があるときだけ見ます。基準の日付が同じ文(文の頭の「2週間後、」なら前の文)に無いもの、「3営業日後」のように単位が日・週・月・年でないものは見ません。「来週月曜」「明日」は、頭に日付の欄が無い文書、すぐ後ろに日付の無い語、引用した返信の中の語、日付を名指す見出しの節(「## 10月1日の会」)の語は見ません。
46
+ en: Only a date right after the relative length (with "on" or punctuation between) is checked. A relative length with no date before it in the same sentence (or the previous one, when the sentence opens with it), and units other than days, weeks, months and years ("3 business days later"), are left alone. A day word ("next Monday", "tomorrow") is left alone when the document has no date field at its head, when no date follows the word, in a quoted reply, and in a section whose heading names a date ("## October 1 meeting").
47
47
  rewrite:
48
48
  depth: light
49
49
  ja:
@@ -10,12 +10,12 @@ name:
10
10
  en: A total that is not the sum of its items
11
11
 
12
12
  why:
13
- ja: 見積や請求の「合計」が、上に並べた金額の和と合わないと、読み手はどちらが正しいのかを計算し直すことになります。行を足したり消したりしたあとに、合計だけ直し忘れると起きます。箇条書きか表で、合計の語(合計・小計)で始まる行を、同じ単位で同じ列の金額の和と比べます。小計のあとの総計のように、足し方が何通りかあるときは、どの足し方でも合わないときだけ指します。
14
- en: When the total of a quote or an invoice is not the sum of the amounts listed above it, the reader has to add them up again to find out which is right. It happens when a line is added or removed and the total is not updated. In a list or a table, a line starting with a total word (Total, Subtotal) is compared with the sum of the amounts in the same unit and column above it. When there is more than one way to add them up, such as a grand total after a subtotal and tax, it is pointed out only when none of them matches.
13
+ ja: 見積や請求の「合計」が、上に並べた金額の和と合わないと、読み手はどちらが正しいのかを計算し直すことになります。行を足したり消したりしたあとに、合計だけ直し忘れると起きます。箇条書きか表で、合計の語(合計・小計)で始まる行を、同じ単位で同じ列の金額の和と比べます。契約書のように一つの文に書いた合計(「保守費60,000円、運用費30,000円とし、合計100,000円とする」「月額150,000円(内訳:…)」)も、その文に並べた同じ単位の金額の和と比べます。小計のあとの総計のように、足し方が何通りかあるときは、どの足し方でも合わないときだけ指します。
14
+ en: When the total of a quote or an invoice is not the sum of the amounts listed above it, the reader has to add them up again to find out which is right. It happens when a line is added or removed and the total is not updated. In a list or a table, a line starting with a total word (Total, Subtotal) is compared with the sum of the amounts in the same unit and column above it. A total written in a sentence, as contracts do ("$6,000 for hosting and $3,000 for support, for a total of $9,000", "$8 per month, made up of …"), is compared with the amounts in the same unit listed in that sentence. When there is more than one way to add them up, such as a grand total after a subtotal and tax, it is pointed out only when none of them matches.
15
15
 
16
16
  message:
17
- ja: 合計「{written}」が、上の金額の和({sum})と合いません
18
- en: "The total {written} is not the sum of the amounts above it ({sum})"
17
+ ja: 合計「{written}」が、内訳の金額の和({sum})と合いません
18
+ en: "The total {written} is not the sum of its items ({sum})"
19
19
 
20
20
  how_to_fix:
21
21
  ja: 内訳の金額と合計のどちらが正しいかを確かめて、片方を直してください。
@@ -30,8 +30,8 @@ sources: [de-marneffe-2008]
30
30
 
31
31
  group: facts
32
32
  summary:
33
- ja: 見積もりや請求書で、合計が上に並べた金額の和と合わない所
34
- en: A total in a quote or an invoice that is not the sum of the amounts above it
33
+ ja: 見積もりや請求書、契約書で、合計が内訳に並べた金額の和と合わない所
34
+ en: A total in a quote, an invoice or a contract that is not the sum of the amounts it is made up of
35
35
  example:
36
36
  ja:
37
37
  before: |
@@ -61,5 +61,5 @@ example:
61
61
  | Total | $8,000 |
62
62
 
63
63
  not_flagged:
64
- ja: 単位や列の違う金額は足しません。足し方が何通りもあるとき(小計と税のあとの総計など)は、どれとも合わないときだけ指します。
65
- en: Amounts in another unit or column are not added. Where there is more than one way to add them up, it is reported only when none matches.
64
+ ja: 単位や列の違う金額は足しません。足し方が何通りもあるとき(小計と税のあとの総計など)は、どれとも合わないときだけ指します。文の中では、合計の語(合計・総額)のすぐ後ろの金額か内訳の語(内訳は)のすぐ前の金額だけを合計と読み、内訳の金額が二つ以上あるときだけ比べます。並びの一部(単価や上限など、合計の語から離れた金額を除いた並び)の和か、一つを引いた額(値引き)と合えば指しません。
65
+ en: Amounts in another unit or column are not added. Where there is more than one way to add them up, it is reported only when none matches. In a sentence, only the amount right after a total phrase (a total of) or right before a breakdown phrase (made up of) is read as a total, and only when two or more items in its unit are listed. It is not reported when the items nearest the phrase add up to it, or when it matches with one item taken away (a discount).
@@ -49,6 +49,7 @@ use_for: [business, technical, legal, docs, academic, literature, speech]
49
49
  off_for:
50
50
  literature: "Length, rhythm, repetition and register are the author's choices in literature, and dialogue mixes styles. Only what one work can hold itself to runs: consistent spacing and commas, and numbering without gaps."
51
51
  speech/transcript: "A transcript records what was said: its sentences, repeats and register are the speaker's, not the writer's to fix."
52
+ academic: measured by yarn rules:measure
52
53
  sources: [plain-2011, jis-z8301-2019]
53
54
 
54
55
  group: readability
@@ -0,0 +1,95 @@
1
+ id: vague-deadline
2
+ layer: L2
3
+ status: stable
4
+ how_to_find: vague-deadline
5
+ severity: info
6
+
7
+ name:
8
+ ja: 期限を「速やかに」のような語で残している
9
+ en: A time limit left to the reader (promptly)
10
+
11
+ why:
12
+ ja: 契約の義務に「速やかに」「遅滞なく」とだけ書くと、何日目までなら守ったことになるのかを、当事者がそれぞれ自分に都合よく読みます。争いになったとき、守ったかどうかを決める物差しがありません。期限は「通知を受けた日から7日以内に」のように数で書くと、誰が読んでも同じに決まります。期限をどう書くかは書き手が決めることなので、chaff は、ほかの期限の多くを数で書いた文書の中で、期限を読み手に決めさせる語(語の一覧は言語ごとの語彙表にあります)を少ないほうとして指します。数の期限(日以内、営業日)を書いた文が、その語を書いた文より多いときだけで、その語と同じ文に数の期限があれば指しません。
13
+ en: 'An obligation written with "promptly" or "without undue delay" alone lets each party read the deadline its own way, and a dispute has no measure of whether it was met. A number ("within seven days of receiving notice") reads the same to everyone. How to write limits is the drafter''s choice, so chaff points only at the minority: in a document where more sentences state a limit in numbers (days, business days) than hold a word that leaves the limit to the reader (each language''s word list has them), it points at those words, unless their own sentence states a number too.'
14
+
15
+ message:
16
+ ja: 「{word}」では期限が決まりません。何日以内かを数で書くと、守ったかどうかを決められます
17
+ en: '"{word}" sets no deadline; a number of days makes it one that can be met or missed'
18
+
19
+ how_to_fix:
20
+ ja: 「通知を受けた日から7日以内に」のように、起点と日数で期限を書いてください。急ぐことを伝えたいだけなら、「速やかに、遅くとも7日以内に」のように数の期限を添えます。
21
+ en: 'Write the limit as a start and a number of days ("within seven days of receiving notice"). To stress urgency too, add the number: "promptly, and in any case within seven days".'
22
+
23
+ levels: { strict: warning, normal: info, relaxed: info }
24
+
25
+ use_for: [legal, docs, academic, literature, speech]
26
+ off_for:
27
+ docs: "A deadline is a contract's obligation: the contract genre checks it."
28
+ academic: "A deadline is a contract's obligation: the contract genre checks it."
29
+ literature: "A deadline is a contract's obligation: the contract genre checks it."
30
+ speech: "A deadline is a contract's obligation: the contract genre checks it."
31
+ legal/statute: "A statute uses 速やかに, 遅滞なく and 直ちに as graded terms of art, and promptly as a duty it does not quantify."
32
+ legal/judgment: "A court decision quotes the statutes and contracts it reads (遅滞なく報告しなければならない); their limits are not the decision's own."
33
+ legal/patent: "A patent sets no deadlines: promptly describes a step of a process (promptly cooled)."
34
+
35
+ group: wording
36
+ summary:
37
+ ja: ほかの期限を日数で書いた契約で、一部の期限だけを「速やかに」「遅滞なく」と書いた所
38
+ en: A deadline written as "promptly" or "without undue delay" in a contract that gives its other deadlines in days
39
+ example:
40
+ ja:
41
+ config: { genre: legal/contract }
42
+ before: |
43
+ 第1条 乙は、毎月5日までに、前月の業務を甲に報告する。
44
+
45
+ 第2条 甲は、報告を受けた日から10日以内に、結果を乙に通知する。
46
+
47
+ 第3条 乙は、甲から求めを受けたときは、速やかに資料を提出する。
48
+ after: |
49
+ 第1条 乙は、毎月5日までに、前月の業務を甲に報告する。
50
+
51
+ 第2条 甲は、報告を受けた日から10日以内に、結果を乙に通知する。
52
+
53
+ 第3条 乙は、甲から求めを受けた日から7日以内に、資料を提出する。
54
+ en:
55
+ config: { genre: legal/contract }
56
+ before: |
57
+ 1. The Supplier shall deliver each report by the fifth business day of the month.
58
+
59
+ 2. The Customer shall pay each invoice within thirty days of receiving it.
60
+
61
+ 3. The Supplier shall notify the Customer promptly of any breach.
62
+ after: |
63
+ 1. The Supplier shall deliver each report by the fifth business day of the month.
64
+
65
+ 2. The Customer shall pay each invoice within thirty days of receiving it.
66
+
67
+ 3. The Supplier shall notify the Customer of any breach within five business days of becoming aware of it.
68
+
69
+ not_flagged:
70
+ ja: 数の期限を書いた文が、期限を読み手に決めさせる語を書いた文より多くない文書では、書き手がそう書くと決めたとみなして指しません。同じ文に日数の期限(7日以内、5営業日)があれば指しません(「速やかに、遅くとも7日以内に」)。権利を定める文(「速やかに本契約を解除することができる」)は、誰かが守る期限ではないので見ません。今すぐを言う「直ちに」と、解除の手続きの決まった言い方「相当の期間を定めて催告し」は見ません。法令は「速やかに」「遅滞なく」「直ちに」を段の違う決まった語として使うので見ません。判決は法令や契約を引いて書くので、特許は期限を定めないので見ません。契約書・規約のジャンルで見ます。
71
+ en: 'A document where sentences stating a limit in numbers are not more than those with a vague one is taken to write its limits that way on purpose, and is not reported. A sentence that also states a limit in numbers ("promptly, and in any case within seven days") is not reported, nor one that grants a right ("We may promptly suspend your account"), which sets no deadline anyone must meet. A bare unit ("24 hours a day") does not count as a limit in numbers; "within … days" does. "Immediately", which means at once, is not read. Statutes use "promptly" and "without delay" as terms of art, court decisions quote statutes and contracts, and patents set no deadlines, so none of them is read; the contract genre runs this rule.'
72
+ rewrite:
73
+ depth: light
74
+ ja:
75
+ direction: 「速やかに」「遅滞なく」を、起点と日数の期限に書き換えます。日数は書き手が決めることなので、決まっていなければ書き手に確かめます。
76
+ pairs:
77
+ - before: 乙は、速やかに資料を提出する。
78
+ after: 乙は、甲の求めを受けた日から7日以内に、資料を提出する。
79
+ - before: 甲は、前項の請求を受けたときは、遅滞なく修補する。
80
+ after: 甲は、前項の請求を受けた日から14日以内に修補する。
81
+ keep:
82
+ - 義務を負う当事者と、すること
83
+ avoid:
84
+ - 日数を書き手に確かめずに決める
85
+ en:
86
+ direction: Replace "promptly" or "without undue delay" with a start and a number of days. The number is the writer's decision; if it is not known, ask.
87
+ pairs:
88
+ - before: The Supplier shall notify the Customer promptly.
89
+ after: The Supplier shall notify the Customer within five business days.
90
+ - before: The Customer shall pay each invoice within a reasonable time.
91
+ after: The Customer shall pay each invoice within thirty days of receiving it.
92
+ keep:
93
+ - the party bound and what it must do
94
+ avoid:
95
+ - choosing the number of days without asking the writer
@@ -0,0 +1,77 @@
1
+ id: version-mismatch
2
+ layer: L1
3
+ status: stable
4
+ how_to_find: version-mismatch
5
+ requires: [markdown]
6
+ severity: warning
7
+
8
+ name:
9
+ ja: 説明の版とコードの版が違う
10
+ en: The version in the text is not the one in the code
11
+
12
+ why:
13
+ ja: 「2.3.0 を入れます」のすぐ下のコマンドが「tidyq@2.4.0」だと、読み手はどちらを入れればよいか分かりません。新しい版を出したときに、コード例か説明の片方だけを直すと起きます。コードブロックのすぐ上の段落に書いた版(2.3.0 のように点で三つに区切った番号)を、そのコードブロックにある版と比べます。コードに版がちょうど一つあり、段落の版がそれと違うとき指します。
14
+ en: 'When "Install version 2.3.0" sits right above a command that installs tidyq@2.4.0, the reader cannot tell which to install. It happens when a release updates the example or the text but not both. chaff compares a version written in the paragraph right above a code block (a number in three dotted parts, such as 2.3.0) with the version the block shows. It reports when the block shows exactly one version and the paragraph names another.'
15
+
16
+ message:
17
+ ja: 「{written}」と書いていますが、すぐ下のコードは {code} です
18
+ en: '"{written}" is written, but the code below has {code}'
19
+
20
+ how_to_fix:
21
+ ja: 説明とコードのどちらが今の版かを確かめて、もう一方を直してください。
22
+ en: Check which of the text and the code has the current version, and correct the other.
23
+
24
+ levels: { strict: error, normal: warning, relaxed: info }
25
+
26
+ use_for: [technical, docs, blog, legal, academic, literature, speech]
27
+ off_for:
28
+ legal: "Code blocks, shell prompts, command headings and numbered steps belong to technical writing."
29
+ academic: "Code blocks, shell prompts, command headings and numbered steps belong to technical writing."
30
+ literature: "Code blocks, shell prompts, command headings and numbered steps belong to technical writing."
31
+ speech: "Code blocks, shell prompts, command headings and numbered steps belong to technical writing."
32
+
33
+ group: facts
34
+ summary:
35
+ ja: コードブロックのすぐ上の説明が名指す版と、コードの版が違う所
36
+ en: A version named right above a code block that the block does not use
37
+ example:
38
+ ja:
39
+ config: { genre: technical/readme }
40
+ before: |
41
+ # インストール
42
+
43
+ npm から 2.3.0 を入れます。
44
+
45
+ ```bash
46
+ npm install --global tidyq@2.4.0
47
+ ```
48
+ after: |
49
+ # インストール
50
+
51
+ npm から 2.4.0 を入れます。
52
+
53
+ ```bash
54
+ npm install --global tidyq@2.4.0
55
+ ```
56
+ en:
57
+ config: { genre: technical/readme }
58
+ before: |
59
+ # Installation
60
+
61
+ Install version 2.3.0 from npm:
62
+
63
+ ```bash
64
+ npm install --global tidyq@2.4.0
65
+ ```
66
+ after: |
67
+ # Installation
68
+
69
+ Install version 2.4.0 from npm:
70
+
71
+ ```bash
72
+ npm install --global tidyq@2.4.0
73
+ ```
74
+
75
+ not_flagged:
76
+ ja: 版の無いコードブロック、版が二つ以上あるコードブロック(「2.3.0 から 2.4.0 へ」の更新)、範囲の端や起点として書いた版(「2.3.0 から」「20.0.0 以上」)、別のプログラムの名前のすぐ後ろの版(「Node.js 18.17.0 が必要」)、見出しや箇条書きや表の版、版だけの行、二つに区切った番号(22.04、3.1)と先頭が四桁の番号(2024.01.15)は比べません。
77
+ en: 'A code block with no version or with two or more (an upgrade from one to the other), a version written as a bound or a starting point ("from 2.3.0", "20.0.0 or later"), a version right after the name of another program ("Requires Node.js 18.17.0"), a version in a heading, a list item, a table or a line of its own, and numbers in two parts (22.04, 3.1) or with a four-digit first part (2024.01.15) are not compared.'
@@ -4,7 +4,7 @@ status: stable
4
4
  how_to_find: phrase-match
5
5
  word_list: weasel-word
6
6
  requires: [pos]
7
- languages: [en]
7
+ languages: [ja, en]
8
8
  severity: info
9
9
 
10
10
  name:
@@ -12,8 +12,8 @@ name:
12
12
  en: Weasel words
13
13
 
14
14
  why:
15
- ja: 英語の「many experts say」「it is widely believed」「studies show」は、主張を名前の無い大勢や、どれとも言わない研究に預けます。読み手は誰がそう言ったのかを確かめられず、書き手は主張に責任を持たずに済みます。言い回しは言語ごとの語彙表にあります。
16
- en: '"Many experts say", "it is widely believed" and "studies show" lend a claim to an unnamed crowd or to research no one names. The reader cannot check who said it, and the writer need not stand behind it. The phrases are listed in the lexicon.'
15
+ ja: 「〜と言われています」「多くの専門家が」「ある研究によると」(英語の many experts say, studies show)は、主張を名前の無い大勢や、どれとも言わない研究に預けます。読み手は誰がそう言ったのかを確かめられず、書き手は主張に責任を持たずに済みます。言い回しは言語ごとの語彙表にあります。
16
+ en: '"Many experts say", "it is widely believed" and "studies show" (と言われています, ある研究によると) lend a claim to an unnamed crowd or to research no one names. The reader cannot check who said it, and the writer need not stand behind it. The phrases are listed in the lexicon.'
17
17
 
18
18
  message:
19
19
  ja: 「{matched}」は、誰が言ったのかを言っていません
@@ -33,9 +33,14 @@ off_for:
33
33
 
34
34
  group: wording
35
35
  summary:
36
- ja: 英語で、「many experts say」「studies show」のように、主張を名前の無い誰かに預ける言い回し
37
- en: Phrases such as "many experts say" and "studies show" that credit a claim to no one in particular
36
+ ja: 「〜と言われています」「ある研究によると」(many experts say, studies show)のように、主張を名前の無い誰かに預ける言い回し
37
+ en: Phrases such as "many experts say" and "studies show" (と言われています, ある研究によると) that credit a claim to no one in particular
38
38
  example:
39
+ ja:
40
+ before: |
41
+ 在宅勤務は生産性を上げると言われています。
42
+ after: |
43
+ 2023年のスタンフォード大学の調査(1,600人)では、在宅勤務で生産性が4%上がりました。
39
44
  en:
40
45
  before: |
41
46
  Many experts say remote work raises output.
@@ -43,13 +48,26 @@ example:
43
48
  A 2023 Stanford study of 1,600 staff found remote work raised output by 4%.
44
49
 
45
50
  not_flagged:
46
- ja: 一覧にある言い回しだけを見ます。英語の文書だけで動きます。すぐ後ろに出典が書いてあっても指摘します(文の中で研究の名前を言えるため)。
47
- en: Only the phrases on chaff's list are checked, and only in English documents. A citation right after the phrase does not silence it, since the sentence can name the study itself.
51
+ ja: 一覧にある言い回しだけを見ます。すぐ後ろに出典が書いてあっても指摘します(文の中で研究の名前を言えるため)。日本語では、前に出典が来やすい「研究によると」「専門家によると」は「ある」「最近の」「多くの」が付いた形だけを、「と言われる」は「と言われている」だけを見ます(「よく言われる話」のように言い回しを話題にするものは見ません)。「一般的に」だけでは指しません。
52
+ en: Only the phrases on chaff's list are checked. A citation right after the phrase does not silence it, since the sentence can name the study itself. In Japanese, 研究によると and 専門家によると, which often follow their source, are checked only as ある・最近の・多くの forms, と言われる only as と言われている (not よく言われる, which mostly talks about the saying itself), and 一般的に alone is not checked.
48
53
  level_meaning:
49
54
  ja: 当てはまる言い回しが {limit} 箇所あれば指摘
50
55
  en: reported once there are {limit}
51
56
  rewrite:
52
57
  depth: light
58
+ ja:
59
+ direction: 名前の無い大勢(多くの専門家、ある研究)を、本文や出典が名指す人や研究に置き換えてください。名指していなければ作らずに書き手に聞くか、書き手自身の主張として書きます。
60
+ pairs:
61
+ - before: ある研究によると、短い会議は時間を節約します[3]。
62
+ after: 山田(2021)は、15分の会議で各チームの時間が週2時間減ったと報告しています[3]。
63
+ - before: 旧APIのほうが遅いと言われています。
64
+ after: 5月の負荷試験では、旧APIのほうが30%遅い結果でした。
65
+ keep:
66
+ - 出典の番号やリンク
67
+ - 主張そのもの
68
+ avoid:
69
+ - 本文に無い研究や名前を作る
70
+ - 別の名前の無い大勢(一部の研究者)に替えるだけ
53
71
  en:
54
72
  direction: Replace the unnamed crowd ("many experts", "studies") with the person or study the text or its sources name. If they name none, do not invent one; ask the writer, or state the claim as the writer's own.
55
73
  pairs:
@@ -70,8 +70,18 @@ relaxing a rule.
70
70
  limit itself (`max-sentence-length: 260`).
71
71
  - `prefer:` maps spellings to the team's (`e-mail: email`); `preferred-term: normal` turns the rule on.
72
72
  - Unknown rule names and unreadable values are reported on stderr — read stderr after editing `chaff.yaml`.
73
- - `genre:` sets the kind of document; `by_path` sets one per folder; `--genre` overrides both for one run.
74
- `rules:` wins over the genre's preset.
73
+ - `genre:` sets the kind of document. `by_path` sets it per path, as a list of `files` globs, each with `genre`,
74
+ `language` or `profile`, and an entry in any other shape is reported on stderr and not used:
75
+
76
+ ```yaml
77
+ by_path:
78
+ - files: ["guides/**/*.md"]
79
+ genre: docs/manual
80
+ ```
81
+
82
+ A file's front matter `genre:` (or `type:`) sets that one file, when neither `genre:` nor a matching `by_path`
83
+ entry does. Strongest first: `--genre` for one run, then `by_path`, `genre:`, front matter, the path, the content,
84
+ and `blog/tech`. `rules:` wins over the genre's preset.
75
85
 
76
86
  ## Turn a team's style note into chaff.yaml
77
87
 
@@ -0,0 +1,3 @@
1
+ // How a language package is imported: by name, at run time. A build without a file system puts its own module in this one's place.
2
+
3
+ export const importPackage = (specifier: string): Promise<unknown> => import(specifier);
@@ -1,3 +1,4 @@
1
+ import { importPackage } from "./adapter-import.ts";
1
2
  import type { LanguageAdapter } from "./plugin.ts";
2
3
 
3
4
  const ADAPTER_PACKAGE: Readonly<Record<string, string>> = { ja: "@chaffjs/lang-ja", en: "@chaffjs/lang-en" };
@@ -102,7 +103,7 @@ const importFirst = async (specifiers: readonly string[], language: string, impo
102
103
  * core だけで起動し、文字種で言語を当ててから、その言語のアダプタを読む。
103
104
  * 全言語を静的に import すると、使わない言語のぶんまで npx の初回取得が膨らむ。
104
105
  */
105
- export const loadAdapter = async (language: string, importer: Importer = (specifier) => import(specifier)): Promise<LanguageAdapter> => {
106
+ export const loadAdapter = async (language: string, importer: Importer = importPackage): Promise<LanguageAdapter> => {
106
107
  const { specifier, module } = await importFirst(packagesFor(language), language, importer);
107
108
  if (typeof module !== "object" || module === null) throw new Error(`${specifier} did not export a module`);
108
109
  const candidate = pickExport(module);