draftwright 0.4.18__tar.gz → 0.4.19__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 (522) hide show
  1. {draftwright-0.4.18 → draftwright-0.4.19}/PKG-INFO +1 -1
  2. {draftwright-0.4.18 → draftwright-0.4.19}/docs/reference/recogniser-capabilities.md +30 -0
  3. {draftwright-0.4.18 → draftwright-0.4.19}/docs/reference/sheet.md +14 -0
  4. {draftwright-0.4.18 → draftwright-0.4.19}/pyproject.toml +3 -1
  5. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/_core.py +1 -0
  6. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/analysis.py +13 -2
  7. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/builder.py +57 -0
  8. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/compose.py +20 -0
  9. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/drawing.py +6 -0
  10. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/coverage.py +51 -0
  11. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/quality.py +4 -0
  12. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/model/detect.py +236 -15
  13. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/model/ir.py +4 -0
  14. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/model/planner.py +1 -1
  15. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/model/pmi_lowering.py +19 -4
  16. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/recognition_ownership.py +148 -1
  17. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/sheet.py +19 -6
  18. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1146_scale_completeness.py +1 -0
  19. draftwright-0.4.19/tests/test_issue_1325_nominal_agreement.py +107 -0
  20. draftwright-0.4.19/tests/test_issue_1390_sheet_registration.py +62 -0
  21. draftwright-0.4.19/tests/test_issue_1396_layout_advisories.py +134 -0
  22. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1421_rectangular_blind_slot_semantics.py +6 -0
  23. draftwright-0.4.19/tests/test_issue_1450_boss_blend_ownership.py +345 -0
  24. draftwright-0.4.19/tests/test_issue_1471_section_recess_pockets.py +361 -0
  25. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_make_drawing.py +9 -5
  26. {draftwright-0.4.18 → draftwright-0.4.19}/.gitignore +0 -0
  27. {draftwright-0.4.18 → draftwright-0.4.19}/CHANGELOG.md +0 -0
  28. {draftwright-0.4.18 → draftwright-0.4.19}/LICENSE +0 -0
  29. {draftwright-0.4.18 → draftwright-0.4.19}/README.md +0 -0
  30. {draftwright-0.4.18 → draftwright-0.4.19}/docs/adr/README.md +0 -0
  31. {draftwright-0.4.18 → draftwright-0.4.19}/docs/research/1062-repeating-radial-profile-evidence.md +0 -0
  32. {draftwright-0.4.18 → draftwright-0.4.19}/skills/SKILL.md +0 -0
  33. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/__init__.py +0 -0
  34. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/_build_profile.py +0 -0
  35. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/_geometry.py +0 -0
  36. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/_pmi_part21.py +0 -0
  37. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/_warnings.py +0 -0
  38. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/annotate.py +0 -0
  39. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/annotations/__init__.py +0 -0
  40. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/annotations/_common.py +0 -0
  41. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/annotations/balloons.py +0 -0
  42. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/annotations/from_model.py +0 -0
  43. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/annotations/gears.py +0 -0
  44. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/annotations/holes.py +0 -0
  45. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/annotations/leaders.py +0 -0
  46. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/annotations/orchestrator.py +0 -0
  47. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/annotations/sections.py +0 -0
  48. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/audit.py +0 -0
  49. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/blend_contract.py +0 -0
  50. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/cli.py +0 -0
  51. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/evaluation/__init__.py +0 -0
  52. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/evaluation/step_analysis.py +0 -0
  53. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/export.py +0 -0
  54. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/fits.py +0 -0
  55. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/fonts/IBMPlexMono-Regular.ttf +0 -0
  56. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/fonts/IBMPlexSansCondensed-Regular.ttf +0 -0
  57. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/fonts/LICENSE-IBMPlexMono-OFL.txt +0 -0
  58. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/fonts/LICENSE-IBMPlexSansCondensed-OFL.txt +0 -0
  59. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/fonts/__init__.py +0 -0
  60. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/inspection.py +0 -0
  61. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/inspection_contract.py +0 -0
  62. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/intents.py +0 -0
  63. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/layout.py +0 -0
  64. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/__init__.py +0 -0
  65. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/_registry.py +0 -0
  66. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/angled_step_coverage.py +0 -0
  67. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/blend_coverage.py +0 -0
  68. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/chamfer_coverage.py +0 -0
  69. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/channel_coverage.py +0 -0
  70. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/circular_blind_step_coverage.py +0 -0
  71. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/evidence.py +0 -0
  72. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/fillet_coverage.py +0 -0
  73. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/flat_coverage.py +0 -0
  74. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/gear_coverage.py +0 -0
  75. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/groove_coverage.py +0 -0
  76. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/hole_coverage.py +0 -0
  77. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/ink_overlap.py +0 -0
  78. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/issues.py +0 -0
  79. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/pad_coverage.py +0 -0
  80. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/paired_ramp_step_coverage.py +0 -0
  81. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/passage_coverage.py +0 -0
  82. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/plate_coverage.py +0 -0
  83. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/pmi_coverage.py +0 -0
  84. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/pocket_coverage.py +0 -0
  85. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/pocket_pattern_coverage.py +0 -0
  86. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/polygonal_boss_coverage.py +0 -0
  87. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/polygonal_stock_coverage.py +0 -0
  88. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/prismatic_pocket_coverage.py +0 -0
  89. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/profiled_bore_coverage.py +0 -0
  90. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/rectangular_blind_slot_coverage.py +0 -0
  91. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/requirements.py +0 -0
  92. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/round_bottom_blind_slot_coverage.py +0 -0
  93. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/slot_coverage.py +0 -0
  94. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/structural.py +0 -0
  95. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/suggest.py +0 -0
  96. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/through_step_coverage.py +0 -0
  97. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/linting/turned_step_coverage.py +0 -0
  98. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/make_drawing.py +0 -0
  99. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/model/__init__.py +0 -0
  100. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/model/callout.py +0 -0
  101. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/model/compiled.py +0 -0
  102. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/model/declare.py +0 -0
  103. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/plate_correspondence.py +0 -0
  104. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/pmi.py +0 -0
  105. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/projection.py +0 -0
  106. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/py.typed +0 -0
  107. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/recogniser_contract.py +0 -0
  108. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/recogniser_policy.py +0 -0
  109. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/recogniser_schema.py +0 -0
  110. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/recognition/__init__.py +0 -0
  111. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/recognition_cache.py +0 -0
  112. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/recognition_frame.py +0 -0
  113. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/registry.py +0 -0
  114. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/repair.py +0 -0
  115. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/reporting.py +0 -0
  116. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/score.py +0 -0
  117. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/sheet_emit.py +0 -0
  118. {draftwright-0.4.18 → draftwright-0.4.19}/src/draftwright/view_plan.py +0 -0
  119. {draftwright-0.4.18 → draftwright-0.4.19}/tests/_kernel.py +0 -0
  120. {draftwright-0.4.18 → draftwright-0.4.19}/tests/_layout_sig.py +0 -0
  121. {draftwright-0.4.18 → draftwright-0.4.19}/tests/_recogniser_public_contract.py +0 -0
  122. {draftwright-0.4.18 → draftwright-0.4.19}/tests/conftest.py +0 -0
  123. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/ap242_single_cylinder_diameter.step +0 -0
  124. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/README.md +0 -0
  125. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/ambiguous-open-semicircle.step +0 -0
  126. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/blind-hole.step +0 -0
  127. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-asymmetric.step +0 -0
  128. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-compound.step +0 -0
  129. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-overlap.step +0 -0
  130. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-plain.step +0 -0
  131. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-planar-x.step +0 -0
  132. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-planar-y.step +0 -0
  133. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-planar-z.step +0 -0
  134. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-topology-a.step +0 -0
  135. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-topology-b.step +0 -0
  136. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-turned.step +0 -0
  137. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-chamfers-v1.json +0 -0
  138. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-countersinks-v1.json +0 -0
  139. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-double-d-bores-v1.json +0 -0
  140. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-fillets-v1.json +0 -0
  141. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-flats-v1.json +0 -0
  142. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-grooves-v1.json +0 -0
  143. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-hole-patterns-v1.json +0 -0
  144. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-plates-v1.json +0 -0
  145. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-pocket-patterns-v1.json +0 -0
  146. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-pockets-v1.json +0 -0
  147. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-polygonal-bosses-v1.json +0 -0
  148. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-polygonal-stock-v1.json +0 -0
  149. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-rectangular-pads-v1.json +0 -0
  150. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-turned-steps-v1.json +0 -0
  151. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-v1.json +0 -0
  152. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/countersink-deburr.step +0 -0
  153. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/countersink-external-cone.step +0 -0
  154. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/countersink-mixed-pair.step +0 -0
  155. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/countersink-single.step +0 -0
  156. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/countersink-topology-a.step +0 -0
  157. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/countersink-topology-b.step +0 -0
  158. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-axis-x.step +0 -0
  159. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-axis-y.step +0 -0
  160. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-blind.step +0 -0
  161. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-coaxial-compound.step +0 -0
  162. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-opposed-blind.step +0 -0
  163. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-roll-30.step +0 -0
  164. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-round-bore.step +0 -0
  165. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-single-z.step +0 -0
  166. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-topology-a.step +0 -0
  167. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-topology-b.step +0 -0
  168. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-compound.step +0 -0
  169. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-overlap.step +0 -0
  170. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-plain.step +0 -0
  171. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-planar-x.step +0 -0
  172. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-planar-y.step +0 -0
  173. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-planar-z.step +0 -0
  174. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-repeated.step +0 -0
  175. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-topology-a.step +0 -0
  176. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-topology-b.step +0 -0
  177. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-turned.step +0 -0
  178. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/flat-coaxial.step +0 -0
  179. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/flat-double-d.step +0 -0
  180. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/flat-lone-d.step +0 -0
  181. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/flat-nonround.step +0 -0
  182. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/flat-slanted-double-d.step +0 -0
  183. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/flat-topology-a.step +0 -0
  184. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/flat-topology-b.step +0 -0
  185. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/groove-compound.step +0 -0
  186. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/groove-lone-x.step +0 -0
  187. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/groove-lone-y.step +0 -0
  188. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/groove-lone-z.step +0 -0
  189. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/groove-monotonic-negative.step +0 -0
  190. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/groove-narrow.step +0 -0
  191. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/groove-topology-a.step +0 -0
  192. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/groove-topology-b.step +0 -0
  193. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-compound-equal.step +0 -0
  194. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-detached-body-negative.step +0 -0
  195. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-full-span-ledge-negative.step +0 -0
  196. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-nested-staircase-negative.step +0 -0
  197. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-topology-a.step +0 -0
  198. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-topology-b.step +0 -0
  199. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-x-negative.step +0 -0
  200. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-x-positive.step +0 -0
  201. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-y-negative.step +0 -0
  202. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-y-positive.step +0 -0
  203. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-z-negative.step +0 -0
  204. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-z-positive.step +0 -0
  205. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pattern-ambiguous.step +0 -0
  206. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pattern-grid.step +0 -0
  207. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pattern-topology-a.step +0 -0
  208. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pattern-topology-b.step +0 -0
  209. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/plain-block.step +0 -0
  210. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-compound-equal.step +0 -0
  211. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-cross-topology-a.step +0 -0
  212. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-cross-topology-b.step +0 -0
  213. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-detached-negative.step +0 -0
  214. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-rotational-negative.step +0 -0
  215. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-single-negative.step +0 -0
  216. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-t-xz.step +0 -0
  217. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-t-yz.step +0 -0
  218. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-thick-negative.step +0 -0
  219. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-u-additive.step +0 -0
  220. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-u-cut.step +0 -0
  221. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-compound.step +0 -0
  222. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-edge-anchored.step +0 -0
  223. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-lone.step +0 -0
  224. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-opposed.step +0 -0
  225. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-pattern-ambiguous.step +0 -0
  226. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-pattern-grid.step +0 -0
  227. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-pattern-linear.step +0 -0
  228. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-pattern-pair.step +0 -0
  229. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-pattern-topology-a.step +0 -0
  230. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-pattern-topology-b.step +0 -0
  231. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-prismatic-negative.step +0 -0
  232. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-side.step +0 -0
  233. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-through-negative.step +0 -0
  234. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-topology-a.step +0 -0
  235. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-topology-b.step +0 -0
  236. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-two-equal.step +0 -0
  237. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-compound-equal.step +0 -0
  238. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-detached-negative.step +0 -0
  239. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-in-plane-rotated.step +0 -0
  240. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-other-protrusions-negative.step +0 -0
  241. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-recess-negative.step +0 -0
  242. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-stock-negative.step +0 -0
  243. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-topology-a.step +0 -0
  244. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-topology-b.step +0 -0
  245. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-x.step +0 -0
  246. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-y.step +0 -0
  247. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-z.step +0 -0
  248. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-compound-negative.step +0 -0
  249. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-cylinder-negative.step +0 -0
  250. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-irregular-negative.step +0 -0
  251. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-octagon-negative.step +0 -0
  252. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-recess-negative.step +0 -0
  253. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-roll17.step +0 -0
  254. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-topology-a.step +0 -0
  255. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-topology-b.step +0 -0
  256. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-translated.step +0 -0
  257. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-x.step +0 -0
  258. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-y.step +0 -0
  259. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/topology-a.step +0 -0
  260. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/topology-b.step +0 -0
  261. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/turned-step-axis-x.step +0 -0
  262. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/turned-step-axis-y.step +0 -0
  263. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/turned-step-axis-z.step +0 -0
  264. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/turned-step-compound.step +0 -0
  265. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/turned-step-repeated-lengths.step +0 -0
  266. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/turned-step-through-bore.step +0 -0
  267. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/turned-step-topology-a.step +0 -0
  268. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/turned-step-topology-b.step +0 -0
  269. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/evaluation/turned-step-translated-blind-bore.step +0 -0
  270. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/grm03_thumbwheel_drive_screw.step +0 -0
  271. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/grm03_thumbwheel_drive_screw_ap242_pmi.step +0 -0
  272. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/grm04_drive_plate.step +0 -0
  273. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/if_step_flat_across_cylinder.step +0 -0
  274. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/issue_1058_wheel_rh.step +0 -0
  275. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/issue_1247_angled_blind_step.step +0 -0
  276. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/issue_909_basic_part_design_017_body.step +0 -0
  277. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/issue_915_case_study_2.step +0 -0
  278. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/nist_ctc_01_asme1_ap203.stp +0 -0
  279. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/nist_ctc_01_asme1_ap242.stp +0 -0
  280. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/nist_ctc_02_asme1_ap203.stp +0 -0
  281. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/nist_ctc_02_asme1_ap242.stp +0 -0
  282. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/nist_ctc_03_asme1_ap203.stp +0 -0
  283. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/nist_ctc_03_asme1_ap242.stp +0 -0
  284. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/nist_ctc_04_asme1_ap203.stp +0 -0
  285. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/nist_ctc_04_asme1_ap242.stp +0 -0
  286. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/nist_ctc_05_asme1_ap203.stp +0 -0
  287. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/nist_ctc_05_asme1_ap242.stp +0 -0
  288. {draftwright-0.4.18 → draftwright-0.4.19}/tests/fixtures/tuner_jig_blind_obround_pockets.step +0 -0
  289. {draftwright-0.4.18 → draftwright-0.4.19}/tests/refactor_golden/bracket_section.json +0 -0
  290. {draftwright-0.4.18 → draftwright-0.4.19}/tests/refactor_golden/centered_rebate.json +0 -0
  291. {draftwright-0.4.18 → draftwright-0.4.19}/tests/refactor_golden/chamfered.json +0 -0
  292. {draftwright-0.4.18 → draftwright-0.4.19}/tests/refactor_golden/filleted.json +0 -0
  293. {draftwright-0.4.18 → draftwright-0.4.19}/tests/refactor_golden/flange_dense.json +0 -0
  294. {draftwright-0.4.18 → draftwright-0.4.19}/tests/refactor_golden/grid_plate.json +0 -0
  295. {draftwright-0.4.18 → draftwright-0.4.19}/tests/refactor_golden/grooved_shaft.json +0 -0
  296. {draftwright-0.4.18 → draftwright-0.4.19}/tests/refactor_golden/hex_bar.json +0 -0
  297. {draftwright-0.4.18 → draftwright-0.4.19}/tests/refactor_golden/holed_slot.json +0 -0
  298. {draftwright-0.4.18 → draftwright-0.4.19}/tests/refactor_golden/pocketed.json +0 -0
  299. {draftwright-0.4.18 → draftwright-0.4.19}/tests/refactor_golden/prismatic_ladder.json +0 -0
  300. {draftwright-0.4.18 → draftwright-0.4.19}/tests/refactor_golden/scattered_plate.json +0 -0
  301. {draftwright-0.4.18 → draftwright-0.4.19}/tests/refactor_golden/side_drilled.json +0 -0
  302. {draftwright-0.4.18 → draftwright-0.4.19}/tests/refactor_golden/turned_stepped.json +0 -0
  303. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_add_dimension.py +0 -0
  304. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_adr0018_arrangement_gate.py +0 -0
  305. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_adr0018_view_routing.py +0 -0
  306. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_adr0018_view_selection.py +0 -0
  307. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_adr_corpus.py +0 -0
  308. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_agents_guide.py +0 -0
  309. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_api_docs.py +0 -0
  310. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_architecture_docs.py +0 -0
  311. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_audit_differential.py +0 -0
  312. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_balloon_ring_standoff.py +0 -0
  313. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_build_profile_harness.py +0 -0
  314. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_carve_free_position_callers.py +0 -0
  315. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_compiled_plan_boundary.py +0 -0
  316. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_counting_calls.py +0 -0
  317. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_declare.py +0 -0
  318. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_declared_recognition_gate.py +0 -0
  319. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_dense_sheet_canary.py +0 -0
  320. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_deprecation_dates.py +0 -0
  321. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_detect_once.py +0 -0
  322. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_detect_registry.py +0 -0
  323. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_dimension_role_vocabulary.py +0 -0
  324. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_drawing_encapsulation.py +0 -0
  325. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_e2e_slice.py +0 -0
  326. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_e2e_standards.py +0 -0
  327. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_export_dxf_curves.py +0 -0
  328. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_export_dxf_zoom.py +0 -0
  329. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_export_reproducible.py +0 -0
  330. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_external_recognition_boundary.py +0 -0
  331. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_fillets_adjacency.py +0 -0
  332. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_fits.py +0 -0
  333. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_flat_completeness.py +0 -0
  334. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_flat_stock_identity.py +0 -0
  335. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_flat_stock_opposition.py +0 -0
  336. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_gdt_placement.py +0 -0
  337. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_geometry_graph_spike.py +0 -0
  338. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_grid_lattice_convention.py +0 -0
  339. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_import_boundaries.py +0 -0
  340. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_inspection_contract.py +0 -0
  341. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_iso_nts_caption_placement.py +0 -0
  342. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1000_envelope_reuse.py +0 -0
  343. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1058_wheel_profile.py +0 -0
  344. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1073_cross_body_patterns.py +0 -0
  345. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1082_polygonal_stock.py +0 -0
  346. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1086_declared_gears.py +0 -0
  347. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1116_ap242_hole_tolerance_lowering.py +0 -0
  348. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1130_view_planning_evidence.py +0 -0
  349. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1142_hole_leader_labels.py +0 -0
  350. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1143_hole_completeness.py +0 -0
  351. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1144_transactional_hole_table.py +0 -0
  352. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1147_legibility_pair_aggregation.py +0 -0
  353. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1153_contradictory_dimensions.py +0 -0
  354. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1154_one_owner_per_measurement.py +0 -0
  355. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1155_grm04_sheet_use.py +0 -0
  356. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1166_cross_pass_feature_leaders.py +0 -0
  357. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1176_quality_fidelity.py +0 -0
  358. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1177_angular_dimensions.py +0 -0
  359. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1187_unroutable_leaders.py +0 -0
  360. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1188_per_view_assignment.py +0 -0
  361. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1190_section_decision.py +0 -0
  362. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1196_deterministic_view_names.py +0 -0
  363. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1202_observed_drawing_consumer.py +0 -0
  364. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1204_multiscale_view_issues.py +0 -0
  365. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1209_linear_pmi_witnesses.py +0 -0
  366. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1215_envelope_tolerance.py +0 -0
  367. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1215_no_approved_tolerance_is_dropped.py +0 -0
  368. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1216_callout_reservation_measures_ink.py +0 -0
  369. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1216_pairwise_across_scale_groups.py +0 -0
  370. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1217_claimed_representations.py +0 -0
  371. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1217_the_facility_is_shared.py +0 -0
  372. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1219_location_claims_its_own_axis.py +0 -0
  373. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1229_ledger_member_keying.py +0 -0
  374. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1240_iso_above_strip_visibility.py +0 -0
  375. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1245_passage_disposition.py +0 -0
  376. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1246_prismatic_pocket_disposition.py +0 -0
  377. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1247_angled_step_disposition.py +0 -0
  378. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1254_turned_chamfers.py +0 -0
  379. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1260_view_constraints.py +0 -0
  380. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1262_automatic_turned_views.py +0 -0
  381. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1276_turned_leader_targets.py +0 -0
  382. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1281_turned_fillets.py +0 -0
  383. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1296_cylindrical_diameter_pmi.py +0 -0
  384. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1298_manufacturing_requirements.py +0 -0
  385. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1299_page_escalation.py +0 -0
  386. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1308_machined_leader_analytics.py +0 -0
  387. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1312_engine_costs.py +0 -0
  388. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1332_overlap_remedy.py +0 -0
  389. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1332_zone_labels.py +0 -0
  390. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1334_prevent_ink.py +0 -0
  391. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1336_grm03_ap242_pmi_fixture.py +0 -0
  392. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1338_scale_before_page_escalation.py +0 -0
  393. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1349_precision_display.py +0 -0
  394. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1350_detected_takeover.py +0 -0
  395. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1351_structured_note_coverage.py +0 -0
  396. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1352_searchable_pdf_text.py +0 -0
  397. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1353_cnc_authoritative_workflow.py +0 -0
  398. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1357_framed_activation.py +0 -0
  399. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1357_framed_boundary.py +0 -0
  400. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1357_plural_turned_profiles.py +0 -0
  401. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1357_pmi_frame.py +0 -0
  402. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1360_thread_depth.py +0 -0
  403. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1369_hole_completeness_evidence.py +0 -0
  404. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1370_countersink_completeness_evidence.py +0 -0
  405. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1370_double_d_completeness_evidence.py +0 -0
  406. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1370_hole_pattern_completeness_evidence.py +0 -0
  407. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1371_flat_completeness_evidence.py +0 -0
  408. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1371_polygonal_stock_completeness_evidence.py +0 -0
  409. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1372_groove_completeness_evidence.py +0 -0
  410. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1372_pad_completeness_evidence.py +0 -0
  411. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1372_pocket_completeness_evidence.py +0 -0
  412. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1372_pocket_pattern_completeness_evidence.py +0 -0
  413. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1372_polygonal_boss_completeness_evidence.py +0 -0
  414. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1373_plate_completeness_evidence.py +0 -0
  415. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1374_chamfer_completeness_evidence.py +0 -0
  416. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1374_fillet_completeness_evidence.py +0 -0
  417. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1374_turned_step_completeness_evidence.py +0 -0
  418. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1382_046_step_inventory.py +0 -0
  419. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1382_circular_blind_step_semantics.py +0 -0
  420. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1382_framed_step_family_evidence.py +0 -0
  421. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1382_paired_ramp_semantics.py +0 -0
  422. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1382_through_step_semantics.py +0 -0
  423. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1392_recognisers_048.py +0 -0
  424. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1395_degenerate_iso_region.py +0 -0
  425. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1397_unverifiable_requirement_message.py +0 -0
  426. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1421_rectangular_blind_slot_completeness.py +0 -0
  427. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1421_round_bottom_blind_slot_completeness.py +0 -0
  428. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1421_round_bottom_blind_slot_semantics.py +0 -0
  429. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1433_blend_semantics.py +0 -0
  430. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1438_boss_ownership.py +0 -0
  431. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1438_channel_ownership.py +0 -0
  432. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1438_cli_report_sidecar.py +0 -0
  433. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1438_generation_snapshot.py +0 -0
  434. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1438_nested_ownership.py +0 -0
  435. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1438_occurrence_ownership.py +0 -0
  436. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1438_pattern_ownership.py +0 -0
  437. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1438_plate_ownership.py +0 -0
  438. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1438_policy_dispositions.py +0 -0
  439. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1438_report_projection.py +0 -0
  440. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1438_report_writer.py +0 -0
  441. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1438_through_step_ownership.py +0 -0
  442. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1438_turned_step_ownership.py +0 -0
  443. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_1460_step_inspection.py +0 -0
  444. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_367_leader_ink.py +0 -0
  445. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_443_grm03_axial_coverage.py +0 -0
  446. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_563_placement_intent.py +0 -0
  447. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_676_polygonal_boss.py +0 -0
  448. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_676_polygonal_boss_declare.py +0 -0
  449. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_740_leader_assignment.py +0 -0
  450. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_798_floor_cardinality.py +0 -0
  451. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_798_material_field.py +0 -0
  452. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_798_silhouette_lint.py +0 -0
  453. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_885_prismatic_coverage.py +0 -0
  454. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_909_sloped_profile.py +0 -0
  455. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_915_dense_case.py +0 -0
  456. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_916_pocket_leader.py +0 -0
  457. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_917_open_channel.py +0 -0
  458. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_924_zero_length_shoulders.py +0 -0
  459. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_955_height_contingency.py +0 -0
  460. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_issue_958_cross_solid_recognition.py +0 -0
  461. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_label_provenance.py +0 -0
  462. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_layout.py +0 -0
  463. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_layout_cleanliness.py +0 -0
  464. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_layout_hypothesis.py +0 -0
  465. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_layout_property.py +0 -0
  466. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_leader_footprint.py +0 -0
  467. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_lint_box_cache.py +0 -0
  468. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_lint_ink_overlap.py +0 -0
  469. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_lint_reconciliation.py +0 -0
  470. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_lint_structural.py +0 -0
  471. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_linting.py +0 -0
  472. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_location_vocabulary.py +0 -0
  473. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_note_verb.py +0 -0
  474. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_object_aspects.py +0 -0
  475. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_occupancy_boxes.py +0 -0
  476. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_parameter_id.py +0 -0
  477. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_part_model.py +0 -0
  478. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_pitch_dim_footprint.py +0 -0
  479. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_pmi.py +0 -0
  480. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_pmi_datum_lowering.py +0 -0
  481. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_pmi_gtol_lowering.py +0 -0
  482. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_pmi_part21.py +0 -0
  483. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_pocket_pattern.py +0 -0
  484. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_pocket_pattern_recognition.py +0 -0
  485. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_principal_profile_classifier.py +0 -0
  486. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_private_test_attr_reads.py +0 -0
  487. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_private_test_imports.py +0 -0
  488. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_quality_components.py +0 -0
  489. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_recogniser_adoption.py +0 -0
  490. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_recogniser_capabilities.py +0 -0
  491. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_recogniser_contract.py +0 -0
  492. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_recognition.py +0 -0
  493. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_recognition_result.py +0 -0
  494. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_refactor_golden.py +0 -0
  495. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_registry.py +0 -0
  496. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_render_seam.py +0 -0
  497. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_repack_geometry_seam.py +0 -0
  498. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_score.py +0 -0
  499. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_script_detail_parity.py +0 -0
  500. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_shared_box_memo.py +0 -0
  501. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_sheet_emit.py +0 -0
  502. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_sheet_gdt.py +0 -0
  503. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_sheet_identity_invariant.py +0 -0
  504. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_sheet_notes.py +0 -0
  505. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_sheet_of.py +0 -0
  506. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_sheet_section.py +0 -0
  507. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_sheet_tables.py +0 -0
  508. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_slanted_blind_step.py +0 -0
  509. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_slot_completeness.py +0 -0
  510. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_slot_pattern.py +0 -0
  511. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_slot_pattern_recognition.py +0 -0
  512. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_soft_deprecation.py +0 -0
  513. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_solve_trace.py +0 -0
  514. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_step_analysis_evaluation.py +0 -0
  515. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_strip_layout.py +0 -0
  516. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_suppression_ledger.py +0 -0
  517. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_suppression_marks.py +0 -0
  518. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_tolerances.py +0 -0
  519. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_turned_steps.py +0 -0
  520. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_view_plan.py +0 -0
  521. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_witness_label_reconciliation.py +0 -0
  522. {draftwright-0.4.18 → draftwright-0.4.19}/tests/test_workflows.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: draftwright
3
- Version: 0.4.18
3
+ Version: 0.4.19
4
4
  Summary: Automated technical-drawing generation for build123d
5
5
  Project-URL: Homepage, https://github.com/pzfreo/draftwright
6
6
  Project-URL: Repository, https://github.com/pzfreo/draftwright
@@ -70,6 +70,36 @@ issue. The contract test derives package record outputs, converter registries, l
70
70
  and emitter branches independently, so copying a new name into the declaration alone cannot make CI
71
71
  pass.
72
72
 
73
+ ### Quiddity migration baseline
74
+
75
+ The first [#1471](https://github.com/pzfreo/draftwright/issues/1471) migration slice tests the
76
+ released Quiddity SectionRecess document against the existing authored pocket corpus. Quiddity is
77
+ pinned in the development dependencies for this comparison. Production continues to use the
78
+ existing recogniser dependency and capability declaration.
79
+
80
+ The private pocket adapter in `model/detect.py` reads primitive schema-2 occurrence geometry and
81
+ produces the existing `PocketFeature`. It admits principal-axis closed rectangles and open
82
+ rectangular corner/edge chains, preserves the opening direction, and refuses unsupported shapes,
83
+ sloped ends, invalid frames and malformed measurements. An open chain remains edge-anchored; its
84
+ missing boundary is never reconstructed as a physical edge.
85
+
86
+ `tests/test_issue_1471_section_recess_pockets.py` checks independently authored dimensions,
87
+ opposed and side openings, disconnected bodies, topology variants, the existing drawing path,
88
+ executed generated Sheet scripts and authored omission. The baseline tests for pocket patterns,
89
+ channels and both blind-slot families remain the acceptance floor for their later adapters.
90
+
91
+ This is preparation for adoption, not a new automatic detection mode. The adapter does not yet
92
+ participate in the production registry, bind occurrence ownership or provide Quiddity-based lint.
93
+ Its comparison drawings use the pinned provider for physical critique. The eventual cutover must
94
+ validate result-local references, bind exact same-run occurrences, migrate patterns and explicit
95
+ refusals, and update independent lint, reports and inspection together. A build already holding an
96
+ aggregate must project it rather than invoke the document builder for a second recognition run.
97
+
98
+ The comparison pins Quiddity 0.2.1, which fixes
99
+ [Quiddity #505](https://github.com/pzfreo/quiddity/issues/505): support proofs now handle
100
+ build123d 0.10 `ShapeList` boolean results. The pocket corpus exercises this public recognition
101
+ path across the supported Python/build123d matrix before consumer adaptation.
102
+
73
103
  `bosses` is the fully consumed reference family. `repeating-radial-profiles` is the opposite
74
104
  reference: it remains geometry-only critique evidence for a separately authored gear declaration,
75
105
  with no inferred gear feature added to fill the table.
@@ -40,6 +40,14 @@ refused at declaration and constraints are never silently relaxed. The immutable
40
40
  snapshot is available as `sheet.view_constraints`, while `drawing.view_plan` is the distinct
41
41
  resolved result.
42
42
 
43
+ Layout advisories are also available as structured findings from `Drawing.lint()` and
44
+ `lint(physical=False)`. `legibility_floor_breached` reports an explicit scale below the
45
+ legibility floor when a legible automatic fit exists; `page_fit_uncertain` reports an
46
+ unsuccessful layout fit; `layout_repack_stalled` reports unresolved measured-repack
47
+ triggers; and `scale_fallback_applied` reports a computed scale or a completeness-driven
48
+ scale fallback. These warnings contribute to the legibility component of `lint_summary()`.
49
+ A successful measured fit replaces the earlier estimated fit warning.
50
+
43
51
  ### Taking over a detected baseline
44
52
 
45
53
  `Sheet.from_part(part)` retains the detector's feature set and starts with implicit automatic
@@ -289,3 +297,9 @@ drop, or missing ink is not hidden by the ownership choice.
289
297
  ::: draftwright.sheet._Control
290
298
  options:
291
299
  filters: public
300
+
301
+ Imported AP242 nominal-diameter ownership requires absolute agreement within `1e-6`
302
+ with the canonical feature diameter, using the same rule as planning. A larger mismatch
303
+ keeps the original source value and identity in a blocked dimension; it does not replace
304
+ the canonical value or crash planning. Generated Sheet scripts retain the blocker, and
305
+ `authored_dim_source_unresolved` reports the withheld source dimension through lint.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "draftwright"
7
- version = "0.4.18"
7
+ version = "0.4.19"
8
8
  description = "Automated technical-drawing generation for build123d"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -169,6 +169,8 @@ dev = [
169
169
  "pytest-split>=0.8",
170
170
  "pytest-timeout>=2",
171
171
  "pytest-xdist>=3",
172
+ # Released provider used by the migration parity tests; production remains on 0.4.14.
173
+ "quiddity==0.2.1",
172
174
  "ruff>=0.4",
173
175
  "tomli>=2; python_version < '3.11'",
174
176
  ]
@@ -1202,6 +1202,7 @@ class Analysis:
1202
1202
  # Standing ISO 7200 title-block fields (#766) — defaulted, so they sit after the
1203
1203
  # non-default fields above. Defaults preserve the prior output: revision "A", the rest
1204
1204
  # blank (the TitleBlock helper's own defaults).
1205
+ layout_advisories: tuple[tuple[str, str], ...] = ()
1205
1206
  material: str = ""
1206
1207
  date: str = ""
1207
1208
  revision: str = "A"
@@ -676,6 +676,7 @@ def _validate_explicit_scale(
676
676
  layout_required_tables=(),
677
677
  margin=_MARGIN,
678
678
  warn_advisory: bool = True,
679
+ advisories: list[tuple[str, str]] | None = None,
679
680
  views: tuple[str, ...] | None = None,
680
681
  include_iso: bool = True,
681
682
  iso_scale_factor: float | None = None,
@@ -701,7 +702,7 @@ def _validate_explicit_scale(
701
702
  f"below {_MIN_RENDER_MM:g} mm (OCCT arc construction fails). "
702
703
  f"Use scale ≥ {safe:.3g} or omit the scale for automatic selection."
703
704
  )
704
- if not warn_advisory:
705
+ if not warn_advisory and advisories is None:
705
706
  return
706
707
  auto_scale, _, _, _ = choose_scale(
707
708
  x_size,
@@ -727,12 +728,16 @@ def _validate_explicit_scale(
727
728
  # No stacklevel that reaches user code: this fires deep in _analyse, and the public
728
729
  # entry points (make_drawing, Sheet.export, build_drawing) sit at different depths.
729
730
  # The message is self-contained (names the scale, the projection, and the fix).
730
- warnings.warn(
731
+ message = (
731
732
  f"scale {SCALE!r} projects the smallest part dimension ({min_dim:.0f} mm) to "
732
733
  f"{min_view:.1f} mm, below the {_MIN_VIEW_MM:.0f} mm legibility floor — "
733
734
  f"annotations may crowd or overlap. Honouring the requested scale; use "
734
735
  f"scale ≥ {safe:.3g} or omit the scale for an automatic legible fit."
735
736
  )
737
+ if advisories is not None:
738
+ advisories.append(("legibility_floor_breached", message))
739
+ if warn_advisory:
740
+ warnings.warn(message)
736
741
 
737
742
 
738
743
  def _analyse(
@@ -1126,7 +1131,10 @@ def _analyse(
1126
1131
  bore_callout_width=bore_callout_width,
1127
1132
  )
1128
1133
 
1134
+ layout_advisories: list[tuple[str, str]] = []
1135
+
1129
1136
  def _pick_for_step_count(n_steps_i: int, strips_i: StripDepths) -> _ScalePick:
1137
+ layout_advisories.clear()
1130
1138
  return choose_scale(
1131
1139
  x_size,
1132
1140
  y_size,
@@ -1140,6 +1148,7 @@ def _analyse(
1140
1148
  required_tables=layout_required_tables,
1141
1149
  margin=margin,
1142
1150
  arrangements=_arrangements,
1151
+ advisories=layout_advisories,
1143
1152
  views=_views,
1144
1153
  include_iso=_include_iso,
1145
1154
  iso_scale_factor=planned_iso_scale,
@@ -1171,6 +1180,7 @@ def _analyse(
1171
1180
  layout_required_tables,
1172
1181
  margin=margin,
1173
1182
  warn_advisory=_reuse is None,
1183
+ advisories=layout_advisories,
1174
1184
  views=_views,
1175
1185
  include_iso=_include_iso,
1176
1186
  iso_scale_factor=planned_iso_scale,
@@ -1264,6 +1274,7 @@ def _analyse(
1264
1274
  )
1265
1275
 
1266
1276
  return Analysis(
1277
+ layout_advisories=tuple(layout_advisories),
1267
1278
  arrangement=ARRANGEMENT,
1268
1279
  planned_views=_views,
1269
1280
  planned_iso=_include_iso,
@@ -491,6 +491,17 @@ def detect_part_model(part, *, pmi="off") -> PartModel:
491
491
  return _detect_part_model_analysis(part, pmi=pmi)[0]
492
492
 
493
493
 
494
+ def _layout_advisory(code: str, message: str) -> LintIssue:
495
+ """Validate the closed layout-advisory vocabulary at the lint boundary."""
496
+ if code == "legibility_floor_breached":
497
+ return LintIssue(severity="warning", code="legibility_floor_breached", message=message)
498
+ if code == "page_fit_uncertain":
499
+ return LintIssue(severity="warning", code="page_fit_uncertain", message=message)
500
+ if code == "scale_fallback_applied":
501
+ return LintIssue(severity="warning", code="scale_fallback_applied", message=message)
502
+ raise ValueError(f"unknown layout advisory: {code!r}")
503
+
504
+
494
505
  def _assemble(
495
506
  a,
496
507
  out,
@@ -824,6 +835,8 @@ def _assemble(
824
835
  # produce a confident "nothing was suppressed" (#996).
825
836
  _diagnostics = compile_dimensions(dwg.model()).diagnostics
826
837
  dwg._build.omissions = tuple(_diagnostics or ())
838
+ for code, message in a.layout_advisories:
839
+ dwg.registry.record_issue(_layout_advisory(code, message))
827
840
  return dwg
828
841
 
829
842
 
@@ -882,6 +895,7 @@ def _repack(
882
895
  no view actually moves).
883
896
  """
884
897
  if not _needs_repack(dwg, a):
898
+ dwg.registry.drop_issues({"page_fit_uncertain"})
885
899
  return None
886
900
  blocks = _measure_blocks(dwg, a)
887
901
 
@@ -940,6 +954,7 @@ def _repack(
940
954
  return g.auto_fits if auto_search else g.fits
941
955
 
942
956
  fit = next(((c, gg) for c in candidates if _candidate_fits(gg := _geom(c))), None)
957
+ repack_advisories: list[tuple[str, str]] = []
943
958
  if fit is not None:
944
959
  chosen, g = fit
945
960
  else:
@@ -961,6 +976,12 @@ def _repack(
961
976
  if lo > 0.0:
962
977
  chosen = (lo, pw0, ph0, tb0)
963
978
  g = _geom(chosen)
979
+ repack_advisories.append(
980
+ (
981
+ "scale_fallback_applied",
982
+ f"No standard scale fits the measured layout; using computed {lo:g}",
983
+ )
984
+ )
964
985
  _log.warning(
965
986
  "measure-repack: no standard sheet fits the measured layout; "
966
987
  "using computed %s",
@@ -971,6 +992,9 @@ def _repack(
971
992
  # keep the largest candidate and let lint report the overflow (as before).
972
993
  chosen = candidates[-1]
973
994
  g = _geom(chosen)
995
+ repack_advisories.append(
996
+ ("page_fit_uncertain", f"No sheet/scale fits the measured layout; using {chosen}")
997
+ )
974
998
  _log.warning(
975
999
  "measure-repack: no sheet/scale fits the measured layout; using %s", chosen
976
1000
  )
@@ -983,11 +1007,22 @@ def _repack(
983
1007
  abs(g.SV_X - a.SV_X),
984
1008
  abs(g.SV_Y - a.SV_Y),
985
1009
  )
1010
+ # Seed fit warnings yield to the measured result; retain the explicit legibility
1011
+ # advisory only at the scale for which it was evaluated.
1012
+ advisories = tuple(
1013
+ (code, message)
1014
+ for code, message in a.layout_advisories
1015
+ if code == "legibility_floor_breached" and s == a.SCALE
1016
+ ) + tuple(repack_advisories)
986
1017
  if s == a.SCALE and pw == a.PAGE_W and ph == a.PAGE_H and moved < _REPACK_TOL:
1018
+ dwg.registry.drop_issues({"page_fit_uncertain", "scale_fallback_applied"})
1019
+ for code, message in repack_advisories:
1020
+ dwg.registry.record_issue(_layout_advisory(code, message))
987
1021
  return None
988
1022
  fv_zones, pv_zones, sv_zones = _build_zones(g, a.margin, ph)
989
1023
  a2 = replace(
990
1024
  a,
1025
+ layout_advisories=advisories,
991
1026
  SCALE=s,
992
1027
  PAGE_W=pw,
993
1028
  PAGE_H=ph,
@@ -1080,6 +1115,13 @@ def _repack_to_fixed_point(
1080
1115
  )
1081
1116
  if repacked is None:
1082
1117
  if _needs_repack(cur_dwg, cur_a):
1118
+ cur_dwg.registry.record_issue(
1119
+ LintIssue(
1120
+ severity="warning",
1121
+ code="layout_repack_stalled",
1122
+ message=f"Measured repack stalled after {i} iterations with residual layout triggers",
1123
+ )
1124
+ )
1083
1125
  _log.warning(
1084
1126
  "measure-repack: stalled after %d iteration(s) with residual layout triggers",
1085
1127
  i,
@@ -1088,6 +1130,13 @@ def _repack_to_fixed_point(
1088
1130
  cur_a, cur_dwg = repacked
1089
1131
 
1090
1132
  if _needs_repack(cur_dwg, cur_a):
1133
+ cur_dwg.registry.record_issue(
1134
+ LintIssue(
1135
+ severity="warning",
1136
+ code="layout_repack_stalled",
1137
+ message=f"Measured repack reached its {_REPACK_MAX_ITER} iteration limit with residual layout triggers",
1138
+ )
1139
+ )
1091
1140
  _log.warning(
1092
1141
  "measure-repack: reached iteration limit (%d) with residual layout triggers",
1093
1142
  _REPACK_MAX_ITER,
@@ -2639,6 +2688,14 @@ def build_drawing(
2639
2688
  attempted=attempted,
2640
2689
  attempts=attempts,
2641
2690
  )
2691
+ fallback.registry.record_issue(
2692
+ LintIssue(
2693
+ severity="warning",
2694
+ code="scale_fallback_applied",
2695
+ message=f"Requested scale {requested_scale:g} dropped required annotations; "
2696
+ f"using complete fallback scale {fallback.scale:g}",
2697
+ )
2698
+ )
2642
2699
  warnings.warn(
2643
2700
  f"requested scale {requested_scale:g} dropped required annotation outcomes; "
2644
2701
  f"using complete fallback scale {fallback.scale:g}",
@@ -689,6 +689,7 @@ def choose_scale(
689
689
  views: tuple[str, ...] | None = None,
690
690
  include_iso: bool = True,
691
691
  iso_scale_factor: float | None = None,
692
+ advisories: list[tuple[str, str]] | None = None,
692
693
  ) -> tuple:
693
694
  """Return (SCALE, PAGE_W, PAGE_H, TB_W) for a 4-view layout.
694
695
 
@@ -734,6 +735,13 @@ def choose_scale(
734
735
  include_iso=include_iso,
735
736
  iso_scale_factor=iso_scale_factor,
736
737
  ):
738
+ if advisories is not None:
739
+ advisories.append(
740
+ (
741
+ "page_fit_uncertain",
742
+ f"Requested scale {scale} on {page} may not fit the requested view layout",
743
+ )
744
+ )
737
745
  _log.warning(
738
746
  "Requested scale %s on %s page may not fit the requested view layout",
739
747
  scale,
@@ -867,6 +875,10 @@ def choose_scale(
867
875
  iso_scale_factor=iso_scale_factor,
868
876
  )
869
877
  if s is not None:
878
+ if advisories is not None:
879
+ advisories.append(
880
+ ("scale_fallback_applied", f"No standard scale fits; using computed {s:g}")
881
+ )
870
882
  _log.warning(
871
883
  "No standard scale fits %.0f × %.0f × %.0f mm; using computed %s",
872
884
  x_size,
@@ -875,6 +887,14 @@ def choose_scale(
875
887
  format_drawing_scale(s),
876
888
  )
877
889
  return s, _pw, _ph, _tb
890
+ if advisories is not None:
891
+ advisories.append(
892
+ (
893
+ "page_fit_uncertain",
894
+ f"No layout fits {x_size:g} × {y_size:g} × {z_size:g} mm; "
895
+ f"falling back to {candidates[-1]}",
896
+ )
897
+ )
878
898
  _log.warning(
879
899
  "No layout fits %.0f × %.0f × %.0f mm; falling back to %s",
880
900
  x_size,
@@ -3718,6 +3718,12 @@ class Drawing:
3718
3718
  assembly=self.assembly,
3719
3719
  holes=holes,
3720
3720
  bosses=bosses,
3721
+ blends=recognition.blends,
3722
+ recognition_evidence=self._build.recognition_evidence,
3723
+ # The same profile set `detect` used, so the boss/blend absorption decision
3724
+ # is one decision rather than two that can disagree. `prof_kw` is empty only
3725
+ # where detect also falls back to the aggregate.
3726
+ **({"turned_profiles": prof_kw["profiles"]} if "profiles" in prof_kw else {}),
3721
3727
  registry=self._registry,
3722
3728
  )
3723
3729
  issues += lint_axial_coverage(
@@ -58,6 +58,11 @@ from draftwright.recognition_frame import (
58
58
  groove_owns_turned_step_band,
59
59
  profiles_owning_axial_band,
60
60
  )
61
+ from draftwright.recognition_ownership import (
62
+ BOSS_BLEND_DIAMETER_TOL,
63
+ boss_blend_owner_pairs,
64
+ envelope_is_emittable,
65
+ )
61
66
  from draftwright.view_plan import VIEW_AXES
62
67
 
63
68
  _UNSET = object() # sentinel: distinguishes "not supplied" from a valid prof=None
@@ -269,6 +274,9 @@ def lint_feature_coverage(
269
274
  assembly=None,
270
275
  holes=None,
271
276
  bosses=None,
277
+ blends=None,
278
+ recognition_evidence=None,
279
+ turned_profiles=_UNSET,
272
280
  registry=None,
273
281
  ) -> list:
274
282
  """Coarse completeness check: report part diameters with no callout (#80).
@@ -303,6 +311,11 @@ def lint_feature_coverage(
303
311
  ``cyls`` accepts a precomputed ``analyse_cylinders(part)`` result so
304
312
  repeated lint runs need not re-scan the solid.
305
313
 
314
+ When same-run ``recognition_evidence`` proves that a recognised boss and blend share the
315
+ same defining face and circular value, the boss diameter is excluded from this coarse
316
+ physical inventory. The blend radius is the truthful callout for that face; counting its
317
+ equivalent diameter again would recreate the duplicate this lint is meant to detect.
318
+
306
319
  Counts are checked too (#92): the part's holes (via ``recognise_holes``) give
307
320
  a required count per diameter (each bore, counterbore, and spotface
308
321
  occurrence counts one), and structured callouts declare how many holes
@@ -318,6 +331,44 @@ def lint_feature_coverage(
318
331
  z_cyls, cross_cyls = cyls if cyls is not None else analyse_cylinders(part)
319
332
  if holes is None:
320
333
  holes = recognise_holes(part, cyls=(z_cyls, cross_cyls))
334
+ if bosses is None and recognition_evidence is not None:
335
+ bosses = recognition_evidence.result.bosses
336
+ if blends is None and recognition_evidence is not None:
337
+ blends = recognition_evidence.result.blends
338
+ # `bosses`/`blends` are inventories, so an empty one is not None. Testing `is not None`
339
+ # bought a `part.bounding_box()` on every lint of every part, including the great majority
340
+ # with no boss or blend to reconcile — a second solid measurement on the re-lint path that
341
+ # `test_relint_recomputes_no_annotation_boxes` budgets exactly one of. Truthiness skips it.
342
+ if bosses and blends and recognition_evidence is not None:
343
+ bbox = part.bounding_box()
344
+ # The BUILD's profile set, not the recognition result's. On a declared build they
345
+ # differ — `detect._analyse` uses the caller's `prof`/`profiles` — and detect decides
346
+ # absorption from its own. Re-deriving here let the IR drop a boss diameter that this
347
+ # lint still demanded a callout for. `_UNSET` means the caller had none to state, which
348
+ # is the same condition under which detect falls back to the aggregate.
349
+ profiles = (
350
+ recognition_evidence.result.turned_profiles
351
+ if turned_profiles is _UNSET
352
+ else turned_profiles
353
+ )
354
+ envelope_emittable = envelope_is_emittable(
355
+ bbox=bbox,
356
+ bosses=bosses,
357
+ turned_profiles=profiles,
358
+ polygonal_stock=recognition_evidence.result.polygonal_stock,
359
+ )
360
+ blend_owned_boss_ids = {
361
+ id(boss)
362
+ for boss, _blend in boss_blend_owner_pairs(
363
+ recognition_evidence,
364
+ tuple(bosses),
365
+ tuple(blends),
366
+ bbox=bbox,
367
+ envelope_emittable=envelope_emittable,
368
+ diameter_tolerance=BOSS_BLEND_DIAMETER_TOL,
369
+ )
370
+ }
371
+ bosses = tuple(boss for boss in bosses if id(boss) not in blend_owned_boss_ids)
321
372
  # Coverage inventory: the *recognised* dimensionable diameters (bores,
322
373
  # cbore/spotface steps, bosses) from feature_diameters — built via
323
374
  # recognise_holes/recognise_bosses, so slot ends and interrupted recesses (partial
@@ -53,6 +53,10 @@ _OUTCOME_STATES = (
53
53
  # distinguish validation from layout.
54
54
  _LEGIBILITY_CODES = frozenset(
55
55
  {
56
+ "legibility_floor_breached",
57
+ "page_fit_uncertain",
58
+ "layout_repack_stalled",
59
+ "scale_fallback_applied",
56
60
  "annotation_out_of_bounds",
57
61
  "annotation_overlap",
58
62
  "annotation_ink_overlap",