draftwright 0.4.26__tar.gz → 0.4.28__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 (601) hide show
  1. {draftwright-0.4.26 → draftwright-0.4.28}/CHANGELOG.md +15 -0
  2. {draftwright-0.4.26 → draftwright-0.4.28}/PKG-INFO +2 -2
  3. {draftwright-0.4.26 → draftwright-0.4.28}/docs/reference/recogniser-capabilities.md +16 -3
  4. {draftwright-0.4.26 → draftwright-0.4.28}/docs/reference/sheet.md +5 -2
  5. {draftwright-0.4.26 → draftwright-0.4.28}/pyproject.toml +2 -2
  6. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/_core.py +26 -6
  7. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/analysis.py +17 -3
  8. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/annotations/orchestrator.py +1 -2
  9. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/builder.py +46 -69
  10. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/cli.py +13 -2
  11. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/drawing.py +44 -0
  12. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/inspection_contract.py +1 -1
  13. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/__init__.py +6 -0
  14. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/coverage.py +111 -0
  15. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/pmi_coverage.py +91 -0
  16. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/quality.py +16 -0
  17. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/pmi.py +29 -0
  18. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/sheet.py +16 -2
  19. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/sheet_emit.py +24 -4
  20. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/view_plan.py +4 -2
  21. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_add_dimension.py +1 -1
  22. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_compiled_plan_boundary.py +1 -0
  23. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_inspection_contract.py +1 -1
  24. draftwright-0.4.28/tests/test_issue_1126_requesting_less_never_scores_better.py +99 -0
  25. draftwright-0.4.28/tests/test_issue_1132_turned_profile_span_is_reported.py +174 -0
  26. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1144_transactional_hole_table.py +1 -1
  27. draftwright-0.4.28/tests/test_issue_1157_no_implicit_general_tolerance.py +140 -0
  28. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1217_the_facility_is_shared.py +15 -6
  29. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1296_cylindrical_diameter_pmi.py +11 -0
  30. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1298_manufacturing_requirements.py +5 -0
  31. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1308_machined_leader_analytics.py +4 -1
  32. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1357_plural_turned_profiles.py +12 -8
  33. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1514_projection_safeguard.py +1 -1
  34. draftwright-0.4.28/tests/test_issue_1555_turned_recognition_format_invariance.py +84 -0
  35. draftwright-0.4.28/tests/test_issue_1563_sheet_pmi_reconciliation.py +185 -0
  36. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_740_leader_assignment.py +17 -4
  37. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_make_drawing.py +68 -28
  38. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_pmi.py +13 -0
  39. draftwright-0.4.28/tests/test_projection_symbol_default.py +164 -0
  40. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_recogniser_capabilities.py +1 -1
  41. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_sheet_emit.py +18 -5
  42. {draftwright-0.4.26 → draftwright-0.4.28}/.gitignore +0 -0
  43. {draftwright-0.4.26 → draftwright-0.4.28}/LICENSE +0 -0
  44. {draftwright-0.4.26 → draftwright-0.4.28}/README.md +0 -0
  45. {draftwright-0.4.26 → draftwright-0.4.28}/docs/adr/README.md +0 -0
  46. {draftwright-0.4.26 → draftwright-0.4.28}/docs/research/1062-repeating-radial-profile-evidence.md +0 -0
  47. {draftwright-0.4.26 → draftwright-0.4.28}/skills/SKILL.md +0 -0
  48. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/__init__.py +0 -0
  49. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/_build_profile.py +0 -0
  50. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/_geometry.py +0 -0
  51. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/_pmi_part21.py +0 -0
  52. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/_warnings.py +0 -0
  53. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/angular_geometry.py +0 -0
  54. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/annotate.py +0 -0
  55. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/annotations/__init__.py +0 -0
  56. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/annotations/_common.py +0 -0
  57. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/annotations/angular.py +0 -0
  58. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/annotations/balloons.py +0 -0
  59. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/annotations/from_model.py +0 -0
  60. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/annotations/gears.py +0 -0
  61. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/annotations/holes.py +0 -0
  62. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/annotations/leaders.py +0 -0
  63. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/annotations/sections.py +0 -0
  64. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/audit.py +0 -0
  65. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/blend_contract.py +0 -0
  66. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/compose.py +0 -0
  67. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/document.py +0 -0
  68. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/document_evidence.py +0 -0
  69. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/document_input.py +0 -0
  70. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/evaluation/__init__.py +0 -0
  71. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/evaluation/step_analysis.py +0 -0
  72. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/export.py +0 -0
  73. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/feature_identity.py +0 -0
  74. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/fits.py +0 -0
  75. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/fonts/IBMPlexMono-Regular.ttf +0 -0
  76. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/fonts/IBMPlexSansCondensed-Regular.ttf +0 -0
  77. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/fonts/LICENSE-IBMPlexMono-OFL.txt +0 -0
  78. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/fonts/LICENSE-IBMPlexSansCondensed-OFL.txt +0 -0
  79. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/fonts/__init__.py +0 -0
  80. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/inspection.py +0 -0
  81. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/intents.py +0 -0
  82. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/layout.py +0 -0
  83. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/_registry.py +0 -0
  84. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/angled_step_coverage.py +0 -0
  85. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/angular.py +0 -0
  86. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/blend_coverage.py +0 -0
  87. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/chamfer_coverage.py +0 -0
  88. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/channel_coverage.py +0 -0
  89. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/circular_blind_step_coverage.py +0 -0
  90. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/evidence.py +0 -0
  91. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/fillet_coverage.py +0 -0
  92. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/flat_coverage.py +0 -0
  93. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/gear_coverage.py +0 -0
  94. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/groove_coverage.py +0 -0
  95. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/hole_coverage.py +0 -0
  96. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/ink_overlap.py +0 -0
  97. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/issues.py +0 -0
  98. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/oriented_slot_coverage.py +0 -0
  99. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/pad_coverage.py +0 -0
  100. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/paired_ramp_step_coverage.py +0 -0
  101. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/passage_coverage.py +0 -0
  102. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/plate_coverage.py +0 -0
  103. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/pocket_coverage.py +0 -0
  104. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/pocket_pattern_coverage.py +0 -0
  105. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/polygonal_boss_coverage.py +0 -0
  106. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/polygonal_stock_coverage.py +0 -0
  107. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/prismatic_pocket_coverage.py +0 -0
  108. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/profiled_bore_coverage.py +0 -0
  109. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/rectangular_blind_slot_coverage.py +0 -0
  110. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/requirements.py +0 -0
  111. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/round_bottom_blind_slot_coverage.py +0 -0
  112. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/schedule_evidence.py +0 -0
  113. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/section_recess_coverage.py +0 -0
  114. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/slot_coverage.py +0 -0
  115. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/structural.py +0 -0
  116. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/suggest.py +0 -0
  117. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/through_step_coverage.py +0 -0
  118. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/linting/turned_step_coverage.py +0 -0
  119. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/location_contract.py +0 -0
  120. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/make_drawing.py +0 -0
  121. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/measurement_support.py +0 -0
  122. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/model/__init__.py +0 -0
  123. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/model/callout.py +0 -0
  124. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/model/compiled.py +0 -0
  125. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/model/declare.py +0 -0
  126. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/model/detect.py +0 -0
  127. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/model/ir.py +0 -0
  128. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/model/planner.py +0 -0
  129. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/model/pmi_lowering.py +0 -0
  130. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/oriented_slot_contract.py +0 -0
  131. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/plate_correspondence.py +0 -0
  132. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/profile_angles.py +0 -0
  133. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/progress.py +0 -0
  134. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/projection.py +0 -0
  135. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/py.typed +0 -0
  136. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/recogniser_contract.py +0 -0
  137. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/recogniser_policy.py +0 -0
  138. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/recogniser_schema.py +0 -0
  139. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/recognition/__init__.py +0 -0
  140. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/recognition_cache.py +0 -0
  141. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/recognition_frame.py +0 -0
  142. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/recognition_ownership.py +0 -0
  143. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/registry.py +0 -0
  144. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/repair.py +0 -0
  145. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/reporting.py +0 -0
  146. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/score.py +0 -0
  147. {draftwright-0.4.26 → draftwright-0.4.28}/src/draftwright/section_recess_contract.py +0 -0
  148. {draftwright-0.4.26 → draftwright-0.4.28}/tests/_evidence_contract.py +0 -0
  149. {draftwright-0.4.26 → draftwright-0.4.28}/tests/_kernel.py +0 -0
  150. {draftwright-0.4.26 → draftwright-0.4.28}/tests/_layout_sig.py +0 -0
  151. {draftwright-0.4.26 → draftwright-0.4.28}/tests/_mutation_corpus.py +0 -0
  152. {draftwright-0.4.26 → draftwright-0.4.28}/tests/_recogniser_public_contract.py +0 -0
  153. {draftwright-0.4.26 → draftwright-0.4.28}/tests/_section_recess_cases.py +0 -0
  154. {draftwright-0.4.26 → draftwright-0.4.28}/tests/conftest.py +0 -0
  155. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/ap242_single_cylinder_diameter.step +0 -0
  156. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/README.md +0 -0
  157. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/ambiguous-open-semicircle.step +0 -0
  158. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/blind-hole.step +0 -0
  159. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/chamfer-asymmetric.step +0 -0
  160. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/chamfer-compound.step +0 -0
  161. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/chamfer-overlap.step +0 -0
  162. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/chamfer-plain.step +0 -0
  163. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/chamfer-planar-x.step +0 -0
  164. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/chamfer-planar-y.step +0 -0
  165. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/chamfer-planar-z.step +0 -0
  166. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/chamfer-topology-a.step +0 -0
  167. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/chamfer-topology-b.step +0 -0
  168. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/chamfer-turned.step +0 -0
  169. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/corpus-chamfers-v1.json +0 -0
  170. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/corpus-countersinks-v1.json +0 -0
  171. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/corpus-double-d-bores-v1.json +0 -0
  172. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/corpus-fillets-v1.json +0 -0
  173. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/corpus-flats-v1.json +0 -0
  174. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/corpus-grooves-v1.json +0 -0
  175. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/corpus-hole-patterns-v1.json +0 -0
  176. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/corpus-plates-v1.json +0 -0
  177. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/corpus-pocket-patterns-v1.json +0 -0
  178. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/corpus-pockets-v1.json +0 -0
  179. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/corpus-polygonal-bosses-v1.json +0 -0
  180. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/corpus-polygonal-stock-v1.json +0 -0
  181. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/corpus-rectangular-pads-v1.json +0 -0
  182. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/corpus-turned-steps-v1.json +0 -0
  183. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/corpus-v1.json +0 -0
  184. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/countersink-deburr.step +0 -0
  185. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/countersink-external-cone.step +0 -0
  186. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/countersink-mixed-pair.step +0 -0
  187. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/countersink-single.step +0 -0
  188. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/countersink-topology-a.step +0 -0
  189. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/countersink-topology-b.step +0 -0
  190. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/double-d-axis-x.step +0 -0
  191. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/double-d-axis-y.step +0 -0
  192. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/double-d-blind.step +0 -0
  193. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/double-d-coaxial-compound.step +0 -0
  194. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/double-d-opposed-blind.step +0 -0
  195. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/double-d-roll-30.step +0 -0
  196. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/double-d-round-bore.step +0 -0
  197. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/double-d-single-z.step +0 -0
  198. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/double-d-topology-a.step +0 -0
  199. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/double-d-topology-b.step +0 -0
  200. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/fillet-compound.step +0 -0
  201. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/fillet-overlap.step +0 -0
  202. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/fillet-plain.step +0 -0
  203. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/fillet-planar-x.step +0 -0
  204. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/fillet-planar-y.step +0 -0
  205. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/fillet-planar-z.step +0 -0
  206. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/fillet-repeated.step +0 -0
  207. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/fillet-topology-a.step +0 -0
  208. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/fillet-topology-b.step +0 -0
  209. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/fillet-turned.step +0 -0
  210. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/flat-coaxial.step +0 -0
  211. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/flat-double-d.step +0 -0
  212. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/flat-lone-d.step +0 -0
  213. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/flat-nonround.step +0 -0
  214. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/flat-slanted-double-d.step +0 -0
  215. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/flat-topology-a.step +0 -0
  216. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/flat-topology-b.step +0 -0
  217. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/groove-compound.step +0 -0
  218. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/groove-lone-x.step +0 -0
  219. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/groove-lone-y.step +0 -0
  220. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/groove-lone-z.step +0 -0
  221. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/groove-monotonic-negative.step +0 -0
  222. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/groove-narrow.step +0 -0
  223. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/groove-topology-a.step +0 -0
  224. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/groove-topology-b.step +0 -0
  225. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pad-compound-equal.step +0 -0
  226. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pad-detached-body-negative.step +0 -0
  227. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pad-full-span-ledge-negative.step +0 -0
  228. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pad-nested-staircase-negative.step +0 -0
  229. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pad-topology-a.step +0 -0
  230. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pad-topology-b.step +0 -0
  231. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pad-x-negative.step +0 -0
  232. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pad-x-positive.step +0 -0
  233. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pad-y-negative.step +0 -0
  234. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pad-y-positive.step +0 -0
  235. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pad-z-negative.step +0 -0
  236. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pad-z-positive.step +0 -0
  237. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pattern-ambiguous.step +0 -0
  238. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pattern-grid.step +0 -0
  239. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pattern-topology-a.step +0 -0
  240. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pattern-topology-b.step +0 -0
  241. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/plain-block.step +0 -0
  242. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/plate-compound-equal.step +0 -0
  243. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/plate-cross-topology-a.step +0 -0
  244. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/plate-cross-topology-b.step +0 -0
  245. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/plate-detached-negative.step +0 -0
  246. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/plate-rotational-negative.step +0 -0
  247. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/plate-single-negative.step +0 -0
  248. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/plate-t-xz.step +0 -0
  249. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/plate-t-yz.step +0 -0
  250. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/plate-thick-negative.step +0 -0
  251. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/plate-u-additive.step +0 -0
  252. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/plate-u-cut.step +0 -0
  253. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pocket-compound.step +0 -0
  254. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pocket-edge-anchored.step +0 -0
  255. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pocket-lone.step +0 -0
  256. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pocket-opposed.step +0 -0
  257. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pocket-pattern-ambiguous.step +0 -0
  258. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pocket-pattern-grid.step +0 -0
  259. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pocket-pattern-linear.step +0 -0
  260. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pocket-pattern-pair.step +0 -0
  261. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pocket-pattern-topology-a.step +0 -0
  262. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pocket-pattern-topology-b.step +0 -0
  263. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pocket-prismatic-negative.step +0 -0
  264. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pocket-side.step +0 -0
  265. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pocket-through-negative.step +0 -0
  266. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pocket-topology-a.step +0 -0
  267. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pocket-topology-b.step +0 -0
  268. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/pocket-two-equal.step +0 -0
  269. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-boss-compound-equal.step +0 -0
  270. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-boss-detached-negative.step +0 -0
  271. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-boss-in-plane-rotated.step +0 -0
  272. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-boss-other-protrusions-negative.step +0 -0
  273. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-boss-recess-negative.step +0 -0
  274. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-boss-stock-negative.step +0 -0
  275. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-boss-topology-a.step +0 -0
  276. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-boss-topology-b.step +0 -0
  277. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-boss-x.step +0 -0
  278. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-boss-y.step +0 -0
  279. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-boss-z.step +0 -0
  280. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-stock-compound-negative.step +0 -0
  281. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-stock-cylinder-negative.step +0 -0
  282. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-stock-irregular-negative.step +0 -0
  283. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-stock-octagon-negative.step +0 -0
  284. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-stock-recess-negative.step +0 -0
  285. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-stock-roll17.step +0 -0
  286. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-stock-topology-a.step +0 -0
  287. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-stock-topology-b.step +0 -0
  288. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-stock-translated.step +0 -0
  289. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-stock-x.step +0 -0
  290. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/polygonal-stock-y.step +0 -0
  291. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/topology-a.step +0 -0
  292. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/topology-b.step +0 -0
  293. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/turned-step-axis-x.step +0 -0
  294. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/turned-step-axis-y.step +0 -0
  295. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/turned-step-axis-z.step +0 -0
  296. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/turned-step-compound.step +0 -0
  297. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/turned-step-repeated-lengths.step +0 -0
  298. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/turned-step-through-bore.step +0 -0
  299. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/turned-step-topology-a.step +0 -0
  300. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/turned-step-topology-b.step +0 -0
  301. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/evaluation/turned-step-translated-blind-bore.step +0 -0
  302. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/grm03_thumbwheel_drive_screw.step +0 -0
  303. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/grm03_thumbwheel_drive_screw_ap242_pmi.step +0 -0
  304. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/grm04_drive_plate.step +0 -0
  305. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/if_step_flat_across_cylinder.step +0 -0
  306. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/issue_1058_wheel_rh.step +0 -0
  307. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/issue_1247_angled_blind_step.step +0 -0
  308. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/issue_909_basic_part_design_017_body.step +0 -0
  309. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/issue_915_case_study_2.step +0 -0
  310. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/nist_ctc_01_asme1_ap203.stp +0 -0
  311. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/nist_ctc_01_asme1_ap242.stp +0 -0
  312. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/nist_ctc_02_asme1_ap203.stp +0 -0
  313. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/nist_ctc_02_asme1_ap242.stp +0 -0
  314. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/nist_ctc_03_asme1_ap203.stp +0 -0
  315. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/nist_ctc_03_asme1_ap242.stp +0 -0
  316. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/nist_ctc_04_asme1_ap203.stp +0 -0
  317. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/nist_ctc_04_asme1_ap242.stp +0 -0
  318. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/nist_ctc_05_asme1_ap203.stp +0 -0
  319. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/nist_ctc_05_asme1_ap242.stp +0 -0
  320. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/tuner_jig_blind_obround_pockets.step +0 -0
  321. {draftwright-0.4.26 → draftwright-0.4.28}/tests/fixtures/whistle_frame_reference.step +0 -0
  322. {draftwright-0.4.26 → draftwright-0.4.28}/tests/refactor_golden/bracket_section.json +0 -0
  323. {draftwright-0.4.26 → draftwright-0.4.28}/tests/refactor_golden/centered_rebate.json +0 -0
  324. {draftwright-0.4.26 → draftwright-0.4.28}/tests/refactor_golden/chamfered.json +0 -0
  325. {draftwright-0.4.26 → draftwright-0.4.28}/tests/refactor_golden/filleted.json +0 -0
  326. {draftwright-0.4.26 → draftwright-0.4.28}/tests/refactor_golden/flange_dense.json +0 -0
  327. {draftwright-0.4.26 → draftwright-0.4.28}/tests/refactor_golden/grid_plate.json +0 -0
  328. {draftwright-0.4.26 → draftwright-0.4.28}/tests/refactor_golden/grooved_shaft.json +0 -0
  329. {draftwright-0.4.26 → draftwright-0.4.28}/tests/refactor_golden/hex_bar.json +0 -0
  330. {draftwright-0.4.26 → draftwright-0.4.28}/tests/refactor_golden/holed_slot.json +0 -0
  331. {draftwright-0.4.26 → draftwright-0.4.28}/tests/refactor_golden/pocketed.json +0 -0
  332. {draftwright-0.4.26 → draftwright-0.4.28}/tests/refactor_golden/prismatic_ladder.json +0 -0
  333. {draftwright-0.4.26 → draftwright-0.4.28}/tests/refactor_golden/scattered_plate.json +0 -0
  334. {draftwright-0.4.26 → draftwright-0.4.28}/tests/refactor_golden/side_drilled.json +0 -0
  335. {draftwright-0.4.26 → draftwright-0.4.28}/tests/refactor_golden/turned_stepped.json +0 -0
  336. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_adr0018_arrangement_gate.py +0 -0
  337. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_adr0018_view_routing.py +0 -0
  338. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_adr0018_view_selection.py +0 -0
  339. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_adr_corpus.py +0 -0
  340. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_agents_guide.py +0 -0
  341. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_api_docs.py +0 -0
  342. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_architecture_docs.py +0 -0
  343. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_audit_differential.py +0 -0
  344. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_balloon_ring_standoff.py +0 -0
  345. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_build_profile_harness.py +0 -0
  346. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_carve_free_position_callers.py +0 -0
  347. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_clone_budget.py +0 -0
  348. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_counting_calls.py +0 -0
  349. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_declare.py +0 -0
  350. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_declared_recognition_gate.py +0 -0
  351. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_dense_sheet_canary.py +0 -0
  352. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_deprecation_dates.py +0 -0
  353. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_detect_once.py +0 -0
  354. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_detect_registry.py +0 -0
  355. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_dimension_role_vocabulary.py +0 -0
  356. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_drawing_encapsulation.py +0 -0
  357. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_e2e_slice.py +0 -0
  358. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_e2e_standards.py +0 -0
  359. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_export_dxf_curves.py +0 -0
  360. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_export_dxf_zoom.py +0 -0
  361. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_export_reproducible.py +0 -0
  362. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_external_recognition_boundary.py +0 -0
  363. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_fillets_adjacency.py +0 -0
  364. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_fits.py +0 -0
  365. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_flat_completeness.py +0 -0
  366. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_flat_stock_identity.py +0 -0
  367. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_flat_stock_opposition.py +0 -0
  368. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_gdt_placement.py +0 -0
  369. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_geometry_graph_spike.py +0 -0
  370. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_grid_lattice_convention.py +0 -0
  371. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_import_boundaries.py +0 -0
  372. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_iso_nts_caption_placement.py +0 -0
  373. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1000_envelope_reuse.py +0 -0
  374. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1006_measurement_comparison.py +0 -0
  375. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1058_wheel_profile.py +0 -0
  376. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1073_cross_body_patterns.py +0 -0
  377. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1082_polygonal_stock.py +0 -0
  378. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1086_declared_gears.py +0 -0
  379. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1116_ap242_hole_tolerance_lowering.py +0 -0
  380. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1130_view_planning_evidence.py +0 -0
  381. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1142_hole_leader_labels.py +0 -0
  382. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1143_hole_completeness.py +0 -0
  383. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1146_scale_completeness.py +0 -0
  384. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1147_legibility_pair_aggregation.py +0 -0
  385. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1153_contradictory_dimensions.py +0 -0
  386. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1154_one_owner_per_measurement.py +0 -0
  387. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1155_grm04_sheet_use.py +0 -0
  388. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1166_cross_pass_feature_leaders.py +0 -0
  389. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1176_quality_fidelity.py +0 -0
  390. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1177_angular_dimensions.py +0 -0
  391. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1187_unroutable_leaders.py +0 -0
  392. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1188_per_view_assignment.py +0 -0
  393. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1190_section_decision.py +0 -0
  394. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1196_deterministic_view_names.py +0 -0
  395. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1202_observed_drawing_consumer.py +0 -0
  396. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1204_multiscale_view_issues.py +0 -0
  397. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1209_linear_pmi_witnesses.py +0 -0
  398. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1215_envelope_tolerance.py +0 -0
  399. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1215_no_approved_tolerance_is_dropped.py +0 -0
  400. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1216_callout_reservation_measures_ink.py +0 -0
  401. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1216_pairwise_across_scale_groups.py +0 -0
  402. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1217_claimed_representations.py +0 -0
  403. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1219_location_claims_its_own_axis.py +0 -0
  404. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1229_ledger_member_keying.py +0 -0
  405. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1240_iso_above_strip_visibility.py +0 -0
  406. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1245_passage_disposition.py +0 -0
  407. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1246_prismatic_pocket_disposition.py +0 -0
  408. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1247_angled_step_disposition.py +0 -0
  409. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1254_turned_chamfers.py +0 -0
  410. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1260_view_constraints.py +0 -0
  411. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1262_automatic_turned_views.py +0 -0
  412. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1276_turned_leader_targets.py +0 -0
  413. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1281_turned_fillets.py +0 -0
  414. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1299_page_escalation.py +0 -0
  415. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1312_engine_costs.py +0 -0
  416. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1325_nominal_agreement.py +0 -0
  417. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1332_overlap_remedy.py +0 -0
  418. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1332_zone_labels.py +0 -0
  419. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1333_bounded_ink_repair.py +0 -0
  420. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1334_prevent_ink.py +0 -0
  421. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1336_grm03_ap242_pmi_fixture.py +0 -0
  422. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1338_scale_before_page_escalation.py +0 -0
  423. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1349_precision_display.py +0 -0
  424. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1350_detected_takeover.py +0 -0
  425. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1351_structured_note_coverage.py +0 -0
  426. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1352_searchable_pdf_text.py +0 -0
  427. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1353_cnc_authoritative_workflow.py +0 -0
  428. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1357_framed_activation.py +0 -0
  429. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1357_framed_boundary.py +0 -0
  430. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1357_pmi_frame.py +0 -0
  431. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1360_thread_depth.py +0 -0
  432. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1369_hole_completeness_evidence.py +0 -0
  433. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1370_countersink_completeness_evidence.py +0 -0
  434. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1370_double_d_completeness_evidence.py +0 -0
  435. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1370_hole_pattern_completeness_evidence.py +0 -0
  436. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1371_flat_completeness_evidence.py +0 -0
  437. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1371_polygonal_stock_completeness_evidence.py +0 -0
  438. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1372_groove_completeness_evidence.py +0 -0
  439. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1372_pad_completeness_evidence.py +0 -0
  440. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1372_pocket_completeness_evidence.py +0 -0
  441. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1372_pocket_pattern_completeness_evidence.py +0 -0
  442. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1372_polygonal_boss_completeness_evidence.py +0 -0
  443. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1373_plate_completeness_evidence.py +0 -0
  444. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1374_chamfer_completeness_evidence.py +0 -0
  445. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1374_fillet_completeness_evidence.py +0 -0
  446. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1374_turned_step_completeness_evidence.py +0 -0
  447. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1378_diameter_leader_targets.py +0 -0
  448. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1382_046_step_inventory.py +0 -0
  449. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1382_circular_blind_step_semantics.py +0 -0
  450. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1382_framed_step_family_evidence.py +0 -0
  451. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1382_paired_ramp_semantics.py +0 -0
  452. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1382_through_step_semantics.py +0 -0
  453. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1390_sheet_registration.py +0 -0
  454. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1392_recognisers_048.py +0 -0
  455. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1395_degenerate_iso_region.py +0 -0
  456. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1396_layout_advisories.py +0 -0
  457. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1397_unverifiable_requirement_message.py +0 -0
  458. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1421_rectangular_blind_slot_completeness.py +0 -0
  459. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1421_rectangular_blind_slot_semantics.py +0 -0
  460. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1421_round_bottom_blind_slot_completeness.py +0 -0
  461. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1421_round_bottom_blind_slot_semantics.py +0 -0
  462. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1432_adoption.py +0 -0
  463. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1432_boundary_failures.py +0 -0
  464. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1432_oriented_slot_semantics.py +0 -0
  465. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1433_blend_semantics.py +0 -0
  466. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1438_boss_ownership.py +0 -0
  467. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1438_channel_ownership.py +0 -0
  468. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1438_cli_report_sidecar.py +0 -0
  469. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1438_generation_snapshot.py +0 -0
  470. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1438_nested_ownership.py +0 -0
  471. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1438_occurrence_ownership.py +0 -0
  472. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1438_pattern_ownership.py +0 -0
  473. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1438_plate_ownership.py +0 -0
  474. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1438_policy_dispositions.py +0 -0
  475. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1438_report_projection.py +0 -0
  476. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1438_report_writer.py +0 -0
  477. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1438_through_step_ownership.py +0 -0
  478. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1438_turned_step_ownership.py +0 -0
  479. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1450_boss_blend_ownership.py +0 -0
  480. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1460_step_inspection.py +0 -0
  481. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1466_dimension_options.py +0 -0
  482. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1466_semantic_sides.py +0 -0
  483. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1471_boundary_failures.py +0 -0
  484. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1471_evidence_schema.py +0 -0
  485. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1471_groove_profile.py +0 -0
  486. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1471_section_recess_contract.py +0 -0
  487. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1471_section_recess_pockets.py +0 -0
  488. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1479_radius_leader_targets.py +0 -0
  489. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1485_curved_pockets.py +0 -0
  490. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1485_quiddity_024_boundary.py +0 -0
  491. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1485_rounded_pockets.py +0 -0
  492. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1504_angle_patterns.py +0 -0
  493. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1504_angular_references.py +0 -0
  494. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1504_angular_rendering.py +0 -0
  495. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1504_canonical_angles.py +0 -0
  496. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1504_profile_angles.py +0 -0
  497. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1505_diameter_coverage.py +0 -0
  498. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1505_short_axial_chains.py +0 -0
  499. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1511_turned_boss_heights.py +0 -0
  500. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1515_first_angle.py +0 -0
  501. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1516_dimension_text.py +0 -0
  502. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1517_through_indicator.py +0 -0
  503. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1518_explicit_rear.py +0 -0
  504. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1524_tolerance_magnitude.py +0 -0
  505. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1530_section_provenance.py +0 -0
  506. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1531_semantic_hole_counts.py +0 -0
  507. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1532_authored_section_examples.py +0 -0
  508. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1533_review_diagnostics.py +0 -0
  509. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1534_build_progress.py +0 -0
  510. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1536_title_overflow.py +0 -0
  511. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1542_applicability.py +0 -0
  512. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1542_catalog.py +0 -0
  513. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1542_catalog_families.py +0 -0
  514. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1542_claim_authority.py +0 -0
  515. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1542_document.py +0 -0
  516. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1542_document_claims.py +0 -0
  517. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1542_document_coverage.py +0 -0
  518. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1542_document_report.py +0 -0
  519. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1542_report_authority.py +0 -0
  520. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1542_requirement_carriers.py +0 -0
  521. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1543_feature_schedules.py +0 -0
  522. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1543_schedule_requirements.py +0 -0
  523. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_1544_frame_document_canary.py +0 -0
  524. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_367_leader_ink.py +0 -0
  525. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_443_grm03_axial_coverage.py +0 -0
  526. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_563_placement_intent.py +0 -0
  527. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_676_polygonal_boss.py +0 -0
  528. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_676_polygonal_boss_declare.py +0 -0
  529. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_798_floor_cardinality.py +0 -0
  530. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_798_material_field.py +0 -0
  531. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_798_silhouette_lint.py +0 -0
  532. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_827_real_part_canary.py +0 -0
  533. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_883_location_identity.py +0 -0
  534. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_885_prismatic_coverage.py +0 -0
  535. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_909_sloped_profile.py +0 -0
  536. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_915_dense_case.py +0 -0
  537. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_916_pocket_leader.py +0 -0
  538. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_917_open_channel.py +0 -0
  539. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_924_zero_length_shoulders.py +0 -0
  540. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_955_height_contingency.py +0 -0
  541. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_issue_958_cross_solid_recognition.py +0 -0
  542. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_label_provenance.py +0 -0
  543. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_layout.py +0 -0
  544. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_layout_cleanliness.py +0 -0
  545. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_layout_hypothesis.py +0 -0
  546. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_layout_property.py +0 -0
  547. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_leader_footprint.py +0 -0
  548. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_lint_box_cache.py +0 -0
  549. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_lint_ink_overlap.py +0 -0
  550. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_lint_reconciliation.py +0 -0
  551. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_lint_structural.py +0 -0
  552. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_linting.py +0 -0
  553. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_location_vocabulary.py +0 -0
  554. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_note_verb.py +0 -0
  555. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_object_aspects.py +0 -0
  556. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_occupancy_boxes.py +0 -0
  557. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_overall_height_coverage.py +0 -0
  558. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_parameter_id.py +0 -0
  559. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_part_model.py +0 -0
  560. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_pitch_dim_footprint.py +0 -0
  561. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_pmi_datum_lowering.py +0 -0
  562. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_pmi_gtol_lowering.py +0 -0
  563. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_pmi_part21.py +0 -0
  564. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_pocket_pattern.py +0 -0
  565. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_pocket_pattern_recognition.py +0 -0
  566. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_principal_profile_classifier.py +0 -0
  567. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_private_test_attr_reads.py +0 -0
  568. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_private_test_imports.py +0 -0
  569. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_quality_components.py +0 -0
  570. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_recogniser_adoption.py +0 -0
  571. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_recogniser_contract.py +0 -0
  572. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_recognition_result.py +0 -0
  573. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_refactor_golden.py +0 -0
  574. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_registry.py +0 -0
  575. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_render_seam.py +0 -0
  576. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_repack_geometry_seam.py +0 -0
  577. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_score.py +0 -0
  578. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_script_detail_parity.py +0 -0
  579. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_shared_box_memo.py +0 -0
  580. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_sheet_gdt.py +0 -0
  581. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_sheet_identity_invariant.py +0 -0
  582. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_sheet_notes.py +0 -0
  583. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_sheet_of.py +0 -0
  584. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_sheet_section.py +0 -0
  585. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_sheet_tables.py +0 -0
  586. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_slanted_blind_step.py +0 -0
  587. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_slot_completeness.py +0 -0
  588. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_slot_pattern.py +0 -0
  589. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_slot_pattern_recognition.py +0 -0
  590. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_soft_deprecation.py +0 -0
  591. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_solve_trace.py +0 -0
  592. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_step_analysis_evaluation.py +0 -0
  593. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_strip_layout.py +0 -0
  594. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_suppression_ledger.py +0 -0
  595. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_suppression_marks.py +0 -0
  596. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_tolerances.py +0 -0
  597. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_turned_steps.py +0 -0
  598. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_version_bump_ci.py +0 -0
  599. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_view_plan.py +0 -0
  600. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_witness_label_reconciliation.py +0 -0
  601. {draftwright-0.4.26 → draftwright-0.4.28}/tests/test_workflows.py +0 -0
@@ -154,6 +154,21 @@
154
154
 
155
155
  ### Changed
156
156
 
157
+ - Updated the exact Quiddity runtime and declared-inspection contract to **0.2.8**, which stops
158
+ a modelled thread being read as a stack of turned shoulders and coalesces contiguous
159
+ equal-diameter bands into the one span they physically are. Measured on the repo corpus,
160
+ NIST CTC-05 is again the only fixture that moves: its ⌀304.8 region was three adjacent
161
+ rungs and is now one, in both STEP encodings (#1135, quiddity#587).
162
+
163
+ - Updated the exact Quiddity runtime and declared-inspection contract to **0.2.7**. Unlike the
164
+ 0.2.5 adoption below, this one changes drawings: the provider now requires circumferential
165
+ cylinder support to establish a turned-profile axis line, so rounded plate corners and parallel
166
+ offset cylinders no longer form a false stepped shaft. Measured on the repo corpus, NIST CTC-05
167
+ is the only fixture whose recognised turned profile moves — its two STEP encodings previously
168
+ disagreed (3 steps and 9 steps for the same solid) and now agree on 5 — and a plate part that
169
+ previously raised out of `generate_sheet_script` now emits and builds. No family, record schema
170
+ or adapter changed (#1555, quiddity#586).
171
+
157
172
  - Updated the exact Quiddity runtime and declared-inspection contract to 0.2.5 for the
158
173
  provider's recognition performance improvements.
159
174
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: draftwright
3
- Version: 0.4.26
3
+ Version: 0.4.28
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
@@ -692,7 +692,7 @@ Requires-Dist: numpy>=1.24
692
692
  Requires-Dist: ocp-gordon<0.3
693
693
  Requires-Dist: pillow>=10
694
694
  Requires-Dist: pypdfium2>=4
695
- Requires-Dist: quiddity==0.2.6
695
+ Requires-Dist: quiddity==0.2.8
696
696
  Requires-Dist: reportlab>=4.0
697
697
  Requires-Dist: rich>=10.11
698
698
  Requires-Dist: steputils==0.1
@@ -70,11 +70,24 @@ 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 0.2.6 runtime contract
73
+ ### Quiddity 0.2.8 runtime contract
74
74
 
75
- The runtime pins the published `quiddity==0.2.6` package, following the 0.2.4 adoption in
75
+ The runtime pins the published `quiddity==0.2.8` package, following the 0.2.4 adoption in
76
76
  [#1486](https://github.com/pzfreo/draftwright/pull/1486) and the migration in
77
- [#1471](https://github.com/pzfreo/draftwright/issues/1471). Its public `quiddity`, `quiddity.evidence` and
77
+ [#1471](https://github.com/pzfreo/draftwright/issues/1471). 0.2.7 is a patch adoption: it requires
78
+ circumferential cylinder support to establish a turned-profile axis line, so rounded plate corners
79
+ and parallel offset cylinders no longer form a false stepped shaft
80
+ ([quiddity#586](https://github.com/pzfreo/quiddity/issues/586), [#1555](https://github.com/pzfreo/draftwright/issues/1555)).
81
+ No family, record schema or adapter changed.
82
+
83
+ 0.2.7 also partitions bands by physical axis line rather than by axis direction, requiring two
84
+ distinct diameters *per line*. One body can therefore publish **several** coaxial
85
+ `TurnedProfile`s where 0.2.6 published at most one. `Analysis.profiles` already holds every
86
+ body-local profile and is unaffected; `Analysis.prof` remains the compatible zero/one view and
87
+ is `None` for a plural result, which sends `holes.py`'s `a.prof is not None` branches down their
88
+ non-rotational path. **No fixture in this repository reaches plural cardinality on either
89
+ version**, so the green tiers are not evidence that path behaves well — it is newly reachable
90
+ and untested. Its public `quiddity`, `quiddity.evidence` and
78
91
  `quiddity.inspection` surfaces supply recognition, exact occurrence evidence and declared geometry
79
92
  reads. There is one recognition aggregate per build; consumers project that result rather than
80
93
  calling the document builder to obtain another run.
@@ -9,7 +9,10 @@ with an underscore.
9
9
  Use `Sheet(part, projection="first")` or `build_drawing(part, projection="first")`
10
10
  for first-angle layout and its matching projection symbol. The CLI equivalent is
11
11
  `--projection first`. Explicit `"third"` selects third-angle layout and its symbol;
12
- omitting `projection` keeps third-angle layout without a symbol.
12
+ omitting `projection` uses third-angle layout and its symbol. Use
13
+ `projection_symbol=False` (CLI: `--no-projection-symbol`) to omit the symbol for an
14
+ embedded illustration; this does not change the projection convention or view layout.
15
+ The visibility choice also survives generated-script replay.
13
16
 
14
17
  View names retain their physical viewing directions in the working part frame. Changing
15
18
  convention changes sheet relationships, not which side of the part a name shows:
@@ -275,7 +278,7 @@ produces `angular_support_unverifiable`; contradictory supports produce
275
278
  `angular_support_mismatch`.
276
279
 
277
280
  Automatic drawings derive outside-profile angular requirements from ordered face
278
- supports in Quiddity 0.2.6. Angles already defined by a recognised chamfer or
281
+ supports, available since Quiddity 0.2.6. Angles already defined by a recognised chamfer or
279
282
  regular-polygon callout do not add duplicate automatic requirements. This requires
280
283
  the same run's exact face or shared-edge evidence, not matching numerical angles;
281
284
  explicit angle declarations remain available on those corners.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "draftwright"
7
- version = "0.4.26"
7
+ version = "0.4.28"
8
8
  description = "Automated technical-drawing generation for build123d"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -23,7 +23,7 @@ dependencies = [
23
23
  # published wheels, not only uv's development resolver constraints.
24
24
  "cadquery-ocp-novtk!=7.9.3.1.1 ; python_full_version >= '3.13'",
25
25
  "build123d-drafting-helpers>=0.15.1",
26
- "quiddity==0.2.6",
26
+ "quiddity==0.2.8",
27
27
  "numpy>=1.24",
28
28
  # PNG raster export (SVG→PDF→PNG). Both permissively licensed (Pillow HPND; pypdfium2
29
29
  # Apache-2.0 wrapping Google PDFium BSD-3) and ship pre-built wheels with NO native system
@@ -174,6 +174,15 @@ def _zone_divisions(page_w: float, page_h: float) -> tuple[int, int]:
174
174
 
175
175
  _TB_CLEAR = _MARGIN + 1.0 # title-block inset: one extra mm over _MARGIN for clearance
176
176
 
177
+ #: What the general-tolerance cell states when no tolerance was authored or sourced.
178
+ #: A blank cell is indistinguishable from an oversight and invites a shop to assume its
179
+ #: own house standard, so the absent case is named rather than left empty (#1157).
180
+ #: The cell is not tight — 48 mm on A4's 120 mm block, 60 mm above it, against 16.9 mm of
181
+ #: ink here — so this is a wording choice, not a width-forced one. The paired test still
182
+ #: measures it against the block's own `cell_bbox` on A4, the narrowest supported width,
183
+ #: because a longer replacement (a sentence, say) would overflow there and nowhere else.
184
+ _TOLERANCE_UNSPECIFIED = "UNSPECIFIED"
185
+
177
186
  _FONT_SIZE = 3.0 # annotation text height (page-mm); the draft preset is built with this
178
187
 
179
188
 
@@ -1236,7 +1245,12 @@ class Analysis:
1236
1245
  step_file: str | Path | Shape
1237
1246
  title: str
1238
1247
  number: str
1239
- tolerance: str
1248
+ #: The general tolerance for the title block. ``None`` means the caller supplied none
1249
+ #: and none was sourced — a distinct state from an explicitly authored string, because a
1250
+ #: general tolerance is a manufacturing requirement and defaulting one invents intent
1251
+ #: the source model may not carry (#1157). ``""`` is the explicit request for a blank
1252
+ #: cell. `_make_title_block` renders `None` as `_TOLERANCE_UNSPECIFIED`.
1253
+ tolerance: str | None
1240
1254
  drawn_by: str
1241
1255
  out: str
1242
1256
  # Canonical AP242 source census + extraction outcomes for a STEP input, including off mode
@@ -1260,9 +1274,10 @@ class Analysis:
1260
1274
  # Draw a sheet border/frame (#767). When True, `margin` is already the reserved content
1261
1275
  # margin (`_content_margin(True)`), so content clears the frame drawn at `_MARGIN`.
1262
1276
  frame: bool = False
1263
- # Projection-method symbol (#769): "third" / "first" (ISO 5456-2) or None (omit).
1277
+ # Requested convention; None resolves to third-angle. Symbol visibility is independent.
1264
1278
  projection: str | None = None
1265
1279
  projection_convention: str = "third"
1280
+ projection_symbol: bool = True
1266
1281
  text_position: str = "inline"
1267
1282
  text_orientation: str = "aligned"
1268
1283
  # Draw the ISO 5457 zone-grid border ruler (#768). Implies a frame (the ticks sit on it).
@@ -1350,7 +1365,7 @@ def _make_title_block(dwg, a: Analysis):
1350
1365
  so the two never drift."""
1351
1366
  title = _font_safe_text(a.title)
1352
1367
  number = _font_safe_text(a.number)
1353
- tolerance = _font_safe_text(a.tolerance)
1368
+ tolerance = _font_safe_text(_TOLERANCE_UNSPECIFIED if a.tolerance is None else a.tolerance)
1354
1369
  designed_by = _font_safe_text(_attribution_author(a.drawn_by))
1355
1370
  material = _font_safe_text(a.material)
1356
1371
  date = _font_safe_text(a.date)
@@ -1481,11 +1496,15 @@ def _add_projection_symbol(dwg, a: Analysis):
1481
1496
  just above the drawn title block (deterministic empty space — the block reserves _TB_H but
1482
1497
  draws shorter). Registered ``projection_symbol`` with an ``is_projection_symbol`` identity
1483
1498
  rider. Unlike the page-spanning frame it is NOT lint-exempt: it's a small, well-placed glyph,
1484
- so lint covers it and a future mispositioning is caught. Gated on ``a.projection``."""
1499
+ so lint covers it and a future mispositioning is caught. Suppressed only by
1500
+ ``projection_symbol=False``."""
1501
+ if not a.projection_symbol:
1502
+ return
1503
+
1485
1504
  from build123d_drafting import ProjectionSymbol
1486
1505
 
1487
1506
  sym = ProjectionSymbol(
1488
- a.projection,
1507
+ a.projection_convention,
1489
1508
  draft=draft_preset(
1490
1509
  font_size=dwg.draft.font_size,
1491
1510
  decimal_precision=dwg.draft.decimal_precision,
@@ -1496,7 +1515,8 @@ def _add_projection_symbol(dwg, a: Analysis):
1496
1515
  bx, by = (b.min.X + b.max.X) / 2, (b.min.Y + b.max.Y) / 2
1497
1516
  w, h = b.max.X - b.min.X, b.max.Y - b.min.Y
1498
1517
  # Right side of the title-block column, near the top of its reserved band.
1499
- cx = a.PAGE_W - _TB_CLEAR - w / 2 - 3
1518
+ # Sheet frames reserve an inner content margin; keep furniture inside it too.
1519
+ cx = a.PAGE_W - max(_TB_CLEAR + 3, a.margin) - w / 2
1500
1520
  cy = _TB_CLEAR + _TB_H - h / 2 - 2
1501
1521
  sym = sym.locate(Location((cx - bx, cy - by, 0)))
1502
1522
  sym.is_projection_symbol = True
@@ -771,6 +771,7 @@ def _analyse(
771
771
  scale=None,
772
772
  page=None,
773
773
  pmi=None,
774
+ source=None,
774
775
  model=None,
775
776
  decorations=None,
776
777
  authored=None,
@@ -781,6 +782,7 @@ def _analyse(
781
782
  company="",
782
783
  frame: bool = False,
783
784
  projection: str | None = None,
785
+ projection_symbol: bool = True,
784
786
  text_position: str = "inline",
785
787
  text_orientation: str = "aligned",
786
788
  zones: bool = False,
@@ -932,12 +934,23 @@ def _analyse(
932
934
  # Semantic PMI census (AP242 only; separate read-only pass). Framed extraction receives
933
935
  # the provider frame before it classifies correlation topology, preserving tight local
934
936
  # boxes and arbitrary directions (#1401 / ADR 3 (was 0020)). Even off mode inventories a STEP
935
- # source so it can report ignored authored PMI; in-memory Shapes have no AP242 document.
936
- if not isinstance(step_file, Shape):
937
+ # source so it can report ignored authored PMI.
938
+ #
939
+ # An in-memory Shape has no AP242 document of its own, which used to end the matter — and
940
+ # a `Sheet` ALWAYS holds one, so no script-built drawing reconciled its PMI at all, not
941
+ # even to say it had not (#1563). `source` is the caller naming the STEP the solid was
942
+ # read from; a generated script already opens exactly that path in its own `part =
943
+ # import_step(...)` line, so the emitter can state it. It is the caller's claim, not a
944
+ # proof the bytes produced this solid, so `pmi_source` records name and digest and the
945
+ # stage summary reports them rather than leaving the link assumed.
946
+ pmi_source = None if isinstance(step_file, Shape) else step_file
947
+ if pmi_source is None and source is not None:
948
+ pmi_source = source
949
+ if pmi_source is not None:
937
950
  from draftwright.pmi import PmiExtractionReport, extract_pmi_report
938
951
 
939
952
  try:
940
- pmi_report = extract_pmi_report(step_file, frame=recognition_frame)
953
+ pmi_report = extract_pmi_report(pmi_source, frame=recognition_frame)
941
954
  if pmi_mode != "off":
942
955
  pmi_records = list(pmi_report.records)
943
956
  except Exception as exc:
@@ -1442,6 +1455,7 @@ def _analyse(
1442
1455
  company=company,
1443
1456
  frame=frame,
1444
1457
  projection=projection,
1458
+ projection_symbol=projection_symbol,
1445
1459
  text_position=text_position,
1446
1460
  text_orientation=text_orientation,
1447
1461
  projection_convention=convention,
@@ -900,8 +900,7 @@ def _auto_annotate(dwg, a: Analysis, *, detail_view: bool = False):
900
900
 
901
901
  def _s_projection_symbol():
902
902
  # ISO 5456-2 projection-method glyph (#769) in the reserved title-block band.
903
- if a.projection:
904
- _add_projection_symbol(dwg, a)
903
+ _add_projection_symbol(dwg, a)
905
904
 
906
905
  def _s_tabulate():
907
906
  # Escalate to a hole table when the plan view is too dense to dimension
@@ -75,7 +75,6 @@ from draftwright.linting.coverage import lint_axial_coverage
75
75
  from draftwright.model import (
76
76
  Datum,
77
77
  Feature,
78
- GrooveFeature,
79
78
  PartModel,
80
79
  StepFeature,
81
80
  build_pmi_features,
@@ -461,9 +460,7 @@ def _check_dimension_sources(model: PartModel) -> None:
461
460
  def _detect_part_model_analysis(part, *, pmi="off") -> tuple[PartModel, Analysis]:
462
461
  """Return one detected model together with the exact analysis run that produced it."""
463
462
 
464
- a = _analyse(
465
- part, title="", number="", tolerance="ISO 2768-m", drawn_by="", out="model", pmi=pmi
466
- )
463
+ a = _analyse(part, title="", number="", tolerance=None, drawn_by="", out="model", pmi=pmi)
467
464
  # `_analyse` already detected and stored the model, so calling `build_model(a)`
468
465
  # unconditionally re-ran every detector `build_part_model` doesn't take by injection —
469
466
  # the #602 duplicate-detection bug, fixed in `_assemble` but never here. It went unnoticed
@@ -567,62 +564,13 @@ def _assemble(
567
564
  # measurements actually reach the page is settled downstream and reported by lint
568
565
  # (`axial_length_missing`). Guard on the tiling condition rather than a classifier
569
566
  # proxy (is_rotational / prof both have blind spots).
570
- z_steps = [f for f in pm.features if isinstance(f, StepFeature) and f.frame.axis == "z"]
571
- # The global-envelope check is meaningful only in its legacy single-solid domain;
572
- # caller-owned group strings cannot turn one solid into several physical bodies.
573
- # Multiple solids can be parallel, axially disjoint, or accompanied by unrelated
574
- # compound members, so their steps need not tile the compound bbox (#1357).
575
- owns_global_envelope = any(feature.kind == "envelope" for feature in pm.features)
576
- if (
577
- z_steps
578
- and len(a.part.solids()) == 1
579
- and (pm.orientation == "z" or owns_global_envelope)
580
- ):
581
- tol = 1e-3 * max(a.z_size, 1.0) # small absolute float epsilon, floored
582
- # Tiling means the segments run end to end — a single reach to each end isn't
583
- # enough, since an interior gap is a stretch of part no declared step describes.
584
- # Walk the spans low→high, extending coverage.
585
- # A GROOVE counts as one of those segments (#953): it is machined INTO the turned
586
- # profile, so a shaft that has one is still a turned profile, which is the only
587
- # thing this guard is asking. Without it the emitted script for any grooved shaft
588
- # RAISED — the detector produces exactly this model (step, groove, step) and the
589
- # direct build draws it, so the engine rejected its own detector's output the
590
- # moment that output was declared rather than detected. Grooves are the only
591
- # detected feature that splits the chain: a chamfered or filleted shoulder leaves
592
- # the two step spans meeting (checked), and a bore or cross-hole carves no axial
593
- # interval. #631's own repro still raises.
594
- # What this does NOT do is verify the declaration against the solid, and it never
595
- # did: `.step(diameter=20, length=48, at=…)` fabricating one full-extent segment
596
- # already defeats it on its own, groove or no groove (checked). Declared spans are
597
- # the author's statement of intent, which ADR 4 (was 0011) takes at face value rather than
598
- # re-deriving, so this catches the honest mistake #631 reported — declaring the
599
- # boss you can see and getting a worse drawing — not a fabricated coverage claim.
600
- # Hardening it into a real verb-domain check is #956.
601
- # NOT claimed here: that the resulting drawing dimensions the height. On this very
602
- # fixture the step chain drops at placement (crowded shoulders) and the height,
603
- # suppressed at compile time on the premise the chain conveys it, is then conveyed
604
- # by nothing — identically on the detected path. That is a real defect, tracked
605
- # separately (#955); raising here would not fix it, only hide it from one of the
606
- # two front doors.
607
- spans = sorted(
608
- [(min(p0[2], p1[2]), max(p0[2], p1[2])) for f in z_steps for (p0, p1) in [f.span]]
609
- + [
610
- (f.frame.origin[2] - f.width / 2, f.frame.origin[2] + f.width / 2)
611
- for f in pm.features
612
- if isinstance(f, GrooveFeature) and f.frame.axis == "z"
613
- ]
614
- )
615
- covered = a.bb.min.Z
616
- for lo, hi in spans:
617
- if lo <= covered + tol:
618
- covered = max(covered, hi)
619
- if spans[0][0] > a.bb.min.Z + tol or covered < a.bb.max.Z - tol:
620
- raise ValueError(
621
- "step() declares a segment of a turned profile, but the declared steps "
622
- "don't span this part's full height — it is not a turned (rotational) "
623
- "body. For a boss (an external cylinder on a prismatic part) use .boss() "
624
- "— it renders its own ø and height."
625
- )
567
+ # The z-turned span check that used to RAISE here now reports from
568
+ # `linting.coverage.lint_turned_profile_span` instead (#1132). Raising made
569
+ # `generate_sheet_script` return nothing at all for a part whose recognised
570
+ # profile does not tile, and an entry point that produces no script and no
571
+ # drawing is the one failure a consumer cannot route around. The check itself is
572
+ # unchanged in substance; only its severity and its home moved, and the annotate
573
+ # pass's `reset_issues()` is why it cannot be recorded from here.
626
574
  # PMI (STEP AP242) is likewise detection-sourced, so a declared / emitted-script model
627
575
  # carries none. When PMI annotation is on, synthesise the same imported drafting
628
576
  # annotations detection would (render_pmi reads them off the model, gated on a.pmi_mode)
@@ -787,8 +735,7 @@ def _assemble(
787
735
  _add_sheet_frame(dwg, a)
788
736
  if a.zones: # zone-grid ruler (#768), on the frame
789
737
  _add_zone_grid(dwg, a)
790
- if a.projection: # projection-method glyph (#769) — auto path adds it via the orchestrator
791
- _add_projection_symbol(dwg, a)
738
+ _add_projection_symbol(dwg, a)
792
739
 
793
740
  # The NTS caption is post-fit late furniture too, and goes FIRST: it is tied to the
794
741
  # iso block it labels, whereas a table may sit anywhere the sheet has room. Placing
@@ -1176,7 +1123,7 @@ def _build_drawing_once(
1176
1123
  out: str | None = None,
1177
1124
  title: str | None = None,
1178
1125
  number: str = "DWG-001",
1179
- tolerance: str = "ISO 2768-m",
1126
+ tolerance: str | None = None,
1180
1127
  drawn_by: str = "",
1181
1128
  scale: float | None = None,
1182
1129
  page: str | tuple | None = None,
@@ -1196,6 +1143,7 @@ def _build_drawing_once(
1196
1143
  company: str = "",
1197
1144
  frame: bool = False,
1198
1145
  projection: str | None = None,
1146
+ projection_symbol: bool = True,
1199
1147
  zones: bool = False,
1200
1148
  reproducible: bool = False,
1201
1149
  framed_recognition: bool = False,
@@ -1211,6 +1159,12 @@ def _build_drawing_once(
1211
1159
  _required_tables=(),
1212
1160
  _select_automatic_views: bool = False,
1213
1161
  _document_input=None,
1162
+ *,
1163
+ #: The STEP document the geometry came from, when it is not `step_file` itself
1164
+ #: (#1563). Keyword-only: inserting it among the positional parameters would shift
1165
+ #: every later binding, which `test_existing_positional_arguments_keep_their_bindings`
1166
+ #: exists to catch — and did.
1167
+ source: str | Path | None = None,
1214
1168
  ) -> Drawing:
1215
1169
  """Build a customisable 4-view :class:`Drawing` without exporting it.
1216
1170
 
@@ -1326,6 +1280,7 @@ def _build_drawing_once(
1326
1280
  scale=scale,
1327
1281
  page=page,
1328
1282
  pmi=pmi,
1283
+ source=source,
1329
1284
  model=model,
1330
1285
  decorations=decorations,
1331
1286
  authored=authored,
@@ -1336,6 +1291,7 @@ def _build_drawing_once(
1336
1291
  company=company,
1337
1292
  frame=frame,
1338
1293
  projection=projection,
1294
+ projection_symbol=projection_symbol,
1339
1295
  text_position=text_position,
1340
1296
  text_orientation=text_orientation,
1341
1297
  zones=zones,
@@ -1880,7 +1836,7 @@ def build_drawing(
1880
1836
  out: str | None = None,
1881
1837
  title: str | None = None,
1882
1838
  number: str = "DWG-001",
1883
- tolerance: str = "ISO 2768-m",
1839
+ tolerance: str | None = None,
1884
1840
  drawn_by: str = "",
1885
1841
  scale: float | None = None,
1886
1842
  page: str | tuple | None = None,
@@ -1912,6 +1868,13 @@ def build_drawing(
1912
1868
  _include_iso: bool = True,
1913
1869
  _view_constraints=None,
1914
1870
  _document_input=None,
1871
+ *,
1872
+ projection_symbol: bool = True,
1873
+ #: The STEP document the geometry came from, when it is not `step_file` itself
1874
+ #: (#1563). Keyword-only: inserting it among the positional parameters would shift
1875
+ #: every later binding, which `test_existing_positional_arguments_keep_their_bindings`
1876
+ #: exists to catch — and did.
1877
+ source: str | Path | None = None,
1915
1878
  ) -> Drawing:
1916
1879
  """Build a drawing, protecting required annotations under an explicit scale.
1917
1880
 
@@ -1926,14 +1889,14 @@ def build_drawing(
1926
1889
  recognition frame. Raw remains the default. Other arguments and return semantics are
1927
1890
  unchanged from the one-pass builder.
1928
1891
 
1929
- ``projection='third'`` adds the matching projection symbol. The default omits the
1930
- symbol but uses the same third-angle layout. ``projection='first'`` places plan below
1892
+ Third-angle layout and its matching projection symbol are the default.
1893
+ ``projection_symbol=False`` suppresses only the symbol. ``projection='first'`` places plan below
1931
1894
  front and side to its left, keeping the physical viewing directions unchanged.
1932
1895
 
1933
1896
  ``text_position="inline"|"above"`` and ``text_orientation="aligned"|"horizontal"``
1934
1897
  independently select dimension typography. Defaults preserve existing appearance.
1935
1898
  """
1936
- validate_projection(projection)
1899
+ validate_projection(projection, projection_symbol=projection_symbol)
1937
1900
  _dimension_draft(text_position, text_orientation)
1938
1901
  if scale_policy not in {"strict", "fallback", "permissive"}:
1939
1902
  raise ValueError(
@@ -1951,6 +1914,7 @@ def build_drawing(
1951
1914
  auto_dims=auto_dims,
1952
1915
  detail_view=detail_view,
1953
1916
  pmi=pmi,
1917
+ source=source,
1954
1918
  repair=repair,
1955
1919
  assembly=assembly,
1956
1920
  model=model,
@@ -1964,6 +1928,7 @@ def build_drawing(
1964
1928
  company=company,
1965
1929
  frame=frame,
1966
1930
  projection=projection,
1931
+ projection_symbol=projection_symbol,
1967
1932
  text_position=text_position,
1968
1933
  text_orientation=text_orientation,
1969
1934
  zones=zones,
@@ -2835,7 +2800,7 @@ def make_drawing(
2835
2800
  out: str | None = None,
2836
2801
  title: str | None = None,
2837
2802
  number: str = "DWG-001",
2838
- tolerance: str = "ISO 2768-m",
2803
+ tolerance: str | None = None,
2839
2804
  drawn_by: str = "",
2840
2805
  scale: float | None = None,
2841
2806
  page: str | tuple | None = None,
@@ -2855,6 +2820,13 @@ def make_drawing(
2855
2820
  framed_recognition: bool = False,
2856
2821
  text_position: str = "inline",
2857
2822
  text_orientation: str = "aligned",
2823
+ *,
2824
+ projection_symbol: bool = True,
2825
+ #: The STEP document the geometry came from, when it is not `step_file` itself
2826
+ #: (#1563). Keyword-only: inserting it among the positional parameters would shift
2827
+ #: every later binding, which `test_existing_positional_arguments_keep_their_bindings`
2828
+ #: exists to catch — and did.
2829
+ source: str | Path | None = None,
2858
2830
  ) -> tuple[str, str]:
2859
2831
  """Generate a 4-view technical drawing from a STEP file or build123d object.
2860
2832
 
@@ -2865,7 +2837,10 @@ def make_drawing(
2865
2837
  when a build123d object is passed).
2866
2838
  title: Part title for the title block (default: stem uppercased).
2867
2839
  number: Drawing number (e.g. ``"DWG-042"``).
2868
- tolerance: General tolerance string (e.g. ``"ISO 2768-m"``).
2840
+ tolerance: General tolerance string (e.g. ``"ISO 2768-m"``). ``None`` (the
2841
+ default) states none: the title block says the tolerance is unspecified
2842
+ rather than inventing a manufacturing requirement the source never
2843
+ carried (#1157). ``""`` requests a blank cell.
2869
2844
  drawn_by: Designer name for the title block.
2870
2845
  scale: Drawing-scale override (e.g. ``5`` for 5:1, ``0.5`` for 1:2).
2871
2846
  Default: chosen automatically by :func:`choose_scale`.
@@ -2912,6 +2887,7 @@ def make_drawing(
2912
2887
  auto_dims=auto_dims,
2913
2888
  detail_view=detail_view,
2914
2889
  pmi=pmi,
2890
+ source=source,
2915
2891
  assembly=assembly,
2916
2892
  material=material,
2917
2893
  date=date,
@@ -2919,6 +2895,7 @@ def make_drawing(
2919
2895
  company=company,
2920
2896
  frame=frame,
2921
2897
  projection=projection,
2898
+ projection_symbol=projection_symbol,
2922
2899
  text_position=text_position,
2923
2900
  text_orientation=text_orientation,
2924
2901
  zones=zones,
@@ -159,7 +159,10 @@ def main(
159
159
  out: str | None = typer.Option(None, help="Output prefix (default: input stem)"),
160
160
  title: str | None = typer.Option(None, help="Part title for title block"),
161
161
  number: str = typer.Option("DWG-001", help="Drawing number"),
162
- tolerance: str = typer.Option("ISO 2768-m", help="General tolerance"),
162
+ tolerance: str | None = typer.Option(
163
+ None,
164
+ help="General tolerance (e.g. 'ISO 2768-m'); omitted, the title block says UNSPECIFIED",
165
+ ),
163
166
  drawn_by: str = typer.Option("", "--drawn-by", help="Designer name"),
164
167
  material: str = typer.Option("", help="Material for the title block"),
165
168
  date: str = typer.Option("", help="Date for the title block"),
@@ -171,7 +174,12 @@ def main(
171
174
  projection: str = typer.Option(
172
175
  "",
173
176
  "--projection",
174
- help="Projection convention: 'first' or 'third' (default: third-angle, no symbol)",
177
+ help="Projection convention: 'first' or 'third' (default: third-angle)",
178
+ ),
179
+ projection_symbol: bool = typer.Option(
180
+ True,
181
+ "--projection-symbol/--no-projection-symbol",
182
+ help="Show the symbol for the selected projection convention",
175
183
  ),
176
184
  text_position: str = typer.Option("inline", help="Dimension text position: inline or above"),
177
185
  text_orientation: str = typer.Option(
@@ -294,6 +302,7 @@ def main(
294
302
  frame=frame,
295
303
  zones=zones,
296
304
  projection=projection or None,
305
+ projection_symbol=projection_symbol,
297
306
  text_position=text_position,
298
307
  text_orientation=text_orientation,
299
308
  part_expr=source.seam,
@@ -320,6 +329,7 @@ def main(
320
329
  frame=frame,
321
330
  zones=zones,
322
331
  projection=projection or None,
332
+ projection_symbol=projection_symbol,
323
333
  text_position=text_position,
324
334
  text_orientation=text_orientation,
325
335
  pmi=pmi.value if pmi is not None else "off",
@@ -355,6 +365,7 @@ def main(
355
365
  company=company,
356
366
  frame=frame,
357
367
  projection=projection or None,
368
+ projection_symbol=projection_symbol,
358
369
  text_position=text_position,
359
370
  text_orientation=text_orientation,
360
371
  zones=zones,
@@ -125,6 +125,8 @@ from draftwright.linting import (
125
125
  lint_pmi_ignored,
126
126
  lint_pmi_lowering,
127
127
  lint_pmi_rendering,
128
+ lint_pmi_source_unknown,
129
+ lint_pmi_unreconciled,
128
130
  lint_pocket_coverage,
129
131
  lint_pocket_pattern_coverage,
130
132
  lint_polygonal_boss_coverage,
@@ -136,6 +138,7 @@ from draftwright.linting import (
136
138
  lint_round_bottom_blind_slot_coverage,
137
139
  lint_slot_coverage,
138
140
  lint_through_step_coverage,
141
+ lint_turned_profile_span,
139
142
  pmi_stage_summary,
140
143
  )
141
144
  from draftwright.linting.angular import lint_angular_supports, lint_profile_angle_coverage
@@ -210,6 +213,12 @@ _GEOMETRY_AWARE_CODES = frozenset(
210
213
  "unrecognised_defining_geometry",
211
214
  "pmi_not_lowered",
212
215
  "pmi_not_rendered",
216
+ # Registered here for the same reason as the two above: an unverified or
217
+ # fabricated AP242 claim is a statement about the geometry, not about layout
218
+ # (#1563). Leaving them out would let a drawing carrying either report
219
+ # `geometry_issues: 0`, which is the shape of defect this register exists for.
220
+ "pmi_unreconciled",
221
+ "pmi_source_unknown",
213
222
  # These REPLACE `pmi_not_rendered` for a record that produced no annotation (#1177);
214
223
  # the content is equally missing, so the count must not fall just because the
215
224
  # reason improved. `authored_dim_degenerate` suppressed that error without
@@ -219,6 +228,10 @@ _GEOMETRY_AWARE_CODES = frozenset(
219
228
  "authored_dim_degenerate",
220
229
  "authored_dim_source_unresolved",
221
230
  "axial_length_missing",
231
+ # A turned profile that leaves part of the body undescribed (#1132). Registered
232
+ # here for the same reason as `axial_length_missing` beside it: the shortfall is
233
+ # about the part, not about where an annotation landed.
234
+ "turned_profile_not_spanned",
222
235
  "flat_requirement_suppressed",
223
236
  "flat_requirement_missing",
224
237
  "flat_requirement_unverifiable",
@@ -4458,6 +4471,23 @@ class Drawing:
4458
4471
  cyls,
4459
4472
  recognition=recognition,
4460
4473
  )
4474
+ # Declared-vs-geometry in the axial direction (#1132): a z-turned profile that
4475
+ # leaves part of the body undescribed. Gated with the reconciliation check
4476
+ # above because both are only meaningful for a caller-declared model — the
4477
+ # detection path is NOT immune — it is scoped this way for a different reason.
4478
+ #
4479
+ # Measured on CADGenBench 132: a plain `build_drawing(<step file>)` detects
4480
+ # z-steps covering 0..113 of a 140 mm body and reports nothing here, while this
4481
+ # predicate applied to that same detected model returns the warning. Same part,
4482
+ # same shortfall, one door silent. It is scoped to the declared model because
4483
+ # that is where the raise it replaces lived, so this change alters no automatic
4484
+ # drawing. Widening it is a real question and a separate one.
4485
+ issues += lint_turned_profile_span(
4486
+ features,
4487
+ (self._analysis.bb.min.Z, self._analysis.bb.max.Z),
4488
+ orientation=getattr(self._part_model, "orientation", None),
4489
+ single_solid=len(self._analysis.part.solids()) == 1,
4490
+ )
4461
4491
  if physical and self._analysis is not None:
4462
4492
  issues += lint_pmi_ignored(
4463
4493
  self._analysis.pmi_report,
@@ -4477,6 +4507,20 @@ class Drawing:
4477
4507
  self._analysis.pmi_mode,
4478
4508
  decorations=getattr(self._part_model, "decorations", {}),
4479
4509
  )
4510
+ # The two directions the four checks above cannot cover, because each of them
4511
+ # reasons FROM the census: content whose census is missing entirely, and content
4512
+ # claiming an identity the census does not contain (#1563). Both take the report
4513
+ # itself rather than the mode — an absent census is the condition, not a setting.
4514
+ issues += lint_pmi_unreconciled(
4515
+ self._analysis.pmi_report,
4516
+ getattr(self._part_model, "features", ()),
4517
+ decorations=getattr(self._part_model, "decorations", {}),
4518
+ )
4519
+ issues += lint_pmi_source_unknown(
4520
+ self._analysis.pmi_report,
4521
+ getattr(self._part_model, "features", ()),
4522
+ decorations=getattr(self._part_model, "decorations", {}),
4523
+ )
4480
4524
  issues += list(self._registry.issues)
4481
4525
  # Attach a ready-to-paste fix snippet where one is computable (#29).
4482
4526
  # str | None — None when no concrete repair can be inferred.
@@ -17,7 +17,7 @@ from quiddity.inspection import inspection_api_manifest
17
17
  CONSUMER_INSPECTION_FORMAT = "draftwright-inspection-api"
18
18
  CONSUMER_INSPECTION_FORMAT_VERSION = 1
19
19
  SUPPORTED_INSPECTION_API_MAJOR = 1
20
- SUPPORTED_RECOGNISER_VERSION = "0.2.6"
20
+ SUPPORTED_RECOGNISER_VERSION = "0.2.8"
21
21
  _DISTRIBUTION = "quiddity"
22
22
  _PROVIDER_FORMAT = "quiddity-inspection-api"
23
23
  _NAMESPACE = "quiddity.inspection"