draftwright 0.4.17__tar.gz → 0.4.19__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (526) hide show
  1. {draftwright-0.4.17 → draftwright-0.4.19}/CHANGELOG.md +124 -10
  2. {draftwright-0.4.17 → draftwright-0.4.19}/PKG-INFO +8 -7
  3. {draftwright-0.4.17 → draftwright-0.4.19}/README.md +6 -5
  4. draftwright-0.4.19/docs/adr/README.md +48 -0
  5. {draftwright-0.4.17 → draftwright-0.4.19}/docs/reference/recogniser-capabilities.md +94 -18
  6. {draftwright-0.4.17 → draftwright-0.4.19}/docs/reference/sheet.md +32 -10
  7. {draftwright-0.4.17 → draftwright-0.4.19}/docs/research/1062-repeating-radial-profile-evidence.md +5 -5
  8. {draftwright-0.4.17 → draftwright-0.4.19}/pyproject.toml +5 -2
  9. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/__init__.py +17 -0
  10. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/_core.py +28 -16
  11. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/_geometry.py +6 -6
  12. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/_warnings.py +1 -1
  13. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/analysis.py +67 -19
  14. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/annotations/__init__.py +1 -1
  15. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/annotations/_common.py +25 -25
  16. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/annotations/balloons.py +5 -5
  17. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/annotations/from_model.py +247 -78
  18. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/annotations/holes.py +16 -16
  19. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/annotations/leaders.py +1 -1
  20. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/annotations/orchestrator.py +23 -22
  21. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/annotations/sections.py +12 -12
  22. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/audit.py +1 -1
  23. draftwright-0.4.19/src/draftwright/blend_contract.py +147 -0
  24. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/builder.py +140 -47
  25. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/cli.py +38 -4
  26. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/compose.py +42 -19
  27. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/drawing.py +221 -51
  28. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/evaluation/step_analysis.py +5 -5
  29. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/export.py +2 -2
  30. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/fits.py +1 -1
  31. draftwright-0.4.19/src/draftwright/inspection.py +281 -0
  32. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/inspection_contract.py +1 -1
  33. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/intents.py +1 -1
  34. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/layout.py +17 -17
  35. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/__init__.py +1 -1
  36. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/blend_coverage.py +20 -6
  37. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/chamfer_coverage.py +8 -3
  38. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/channel_coverage.py +5 -1
  39. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/circular_blind_step_coverage.py +13 -3
  40. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/coverage.py +58 -7
  41. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/evidence.py +5 -5
  42. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/fillet_coverage.py +8 -3
  43. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/flat_coverage.py +11 -3
  44. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/groove_coverage.py +48 -8
  45. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/hole_coverage.py +32 -14
  46. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/ink_overlap.py +3 -3
  47. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/issues.py +37 -1
  48. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/pad_coverage.py +20 -5
  49. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/paired_ramp_step_coverage.py +13 -3
  50. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/plate_coverage.py +30 -294
  51. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/pmi_coverage.py +1 -1
  52. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/pocket_coverage.py +16 -6
  53. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/pocket_pattern_coverage.py +13 -5
  54. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/polygonal_boss_coverage.py +12 -5
  55. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/polygonal_stock_coverage.py +37 -7
  56. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/quality.py +26 -77
  57. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/rectangular_blind_slot_coverage.py +11 -3
  58. draftwright-0.4.19/src/draftwright/linting/requirements.py +102 -0
  59. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/round_bottom_blind_slot_coverage.py +11 -3
  60. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/slot_coverage.py +16 -9
  61. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/structural.py +5 -5
  62. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/suggest.py +1 -1
  63. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/through_step_coverage.py +21 -3
  64. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/turned_step_coverage.py +38 -8
  65. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/make_drawing.py +1 -1
  66. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/model/__init__.py +2 -2
  67. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/model/callout.py +6 -6
  68. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/model/compiled.py +71 -18
  69. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/model/declare.py +29 -15
  70. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/model/detect.py +984 -108
  71. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/model/ir.py +46 -33
  72. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/model/planner.py +26 -26
  73. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/model/pmi_lowering.py +50 -10
  74. draftwright-0.4.19/src/draftwright/plate_correspondence.py +318 -0
  75. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/projection.py +39 -3
  76. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/recogniser_contract.py +21 -80
  77. draftwright-0.4.19/src/draftwright/recogniser_policy.py +132 -0
  78. draftwright-0.4.19/src/draftwright/recogniser_schema.py +89 -0
  79. draftwright-0.4.19/src/draftwright/recognition_cache.py +78 -0
  80. draftwright-0.4.19/src/draftwright/recognition_ownership.py +959 -0
  81. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/registry.py +6 -6
  82. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/repair.py +2 -2
  83. draftwright-0.4.19/src/draftwright/reporting.py +583 -0
  84. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/sheet.py +60 -45
  85. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/sheet_emit.py +166 -67
  86. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/view_plan.py +18 -18
  87. {draftwright-0.4.17 → draftwright-0.4.19}/tests/_kernel.py +1 -1
  88. {draftwright-0.4.17 → draftwright-0.4.19}/tests/_layout_sig.py +1 -1
  89. {draftwright-0.4.17 → draftwright-0.4.19}/tests/_recogniser_public_contract.py +8 -2
  90. {draftwright-0.4.17 → draftwright-0.4.19}/tests/conftest.py +10 -8
  91. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_add_dimension.py +7 -7
  92. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_adr0018_arrangement_gate.py +4 -4
  93. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_adr0018_view_routing.py +3 -3
  94. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_adr0018_view_selection.py +3 -3
  95. draftwright-0.4.19/tests/test_adr_corpus.py +134 -0
  96. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_architecture_docs.py +7 -4
  97. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_audit_differential.py +8 -6
  98. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_carve_free_position_callers.py +10 -10
  99. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_compiled_plan_boundary.py +83 -28
  100. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_declare.py +11 -11
  101. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_declared_recognition_gate.py +11 -9
  102. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_dense_sheet_canary.py +2 -2
  103. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_deprecation_dates.py +3 -2
  104. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_detect_once.py +20 -6
  105. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_detect_registry.py +30 -3
  106. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_drawing_encapsulation.py +31 -17
  107. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_e2e_slice.py +1 -1
  108. draftwright-0.4.19/tests/test_external_recognition_boundary.py +127 -0
  109. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_fits.py +1 -1
  110. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_flat_stock_identity.py +2 -2
  111. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_gdt_placement.py +4 -4
  112. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_grid_lattice_convention.py +1 -1
  113. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_import_boundaries.py +271 -13
  114. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_inspection_contract.py +1 -1
  115. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1058_wheel_profile.py +2 -1
  116. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1130_view_planning_evidence.py +9 -7
  117. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1142_hole_leader_labels.py +1 -1
  118. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1146_scale_completeness.py +14 -10
  119. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1153_contradictory_dimensions.py +1 -1
  120. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1176_quality_fidelity.py +2 -2
  121. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1177_angular_dimensions.py +1 -1
  122. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1196_deterministic_view_names.py +2 -2
  123. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1202_observed_drawing_consumer.py +3 -3
  124. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1215_envelope_tolerance.py +1 -1
  125. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1215_no_approved_tolerance_is_dropped.py +11 -11
  126. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1216_callout_reservation_measures_ink.py +1 -1
  127. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1217_claimed_representations.py +2 -2
  128. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1217_the_facility_is_shared.py +3 -3
  129. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1260_view_constraints.py +1 -1
  130. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1308_machined_leader_analytics.py +5 -1
  131. draftwright-0.4.19/tests/test_issue_1325_nominal_agreement.py +107 -0
  132. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1332_overlap_remedy.py +1 -1
  133. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1357_framed_activation.py +1 -1
  134. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1357_framed_boundary.py +3 -3
  135. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1369_hole_completeness_evidence.py +2 -2
  136. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1370_countersink_completeness_evidence.py +2 -2
  137. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1370_double_d_completeness_evidence.py +4 -4
  138. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1370_hole_pattern_completeness_evidence.py +4 -4
  139. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1371_flat_completeness_evidence.py +6 -6
  140. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1371_polygonal_stock_completeness_evidence.py +8 -8
  141. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1372_groove_completeness_evidence.py +8 -8
  142. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1372_pad_completeness_evidence.py +8 -8
  143. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1372_pocket_completeness_evidence.py +6 -6
  144. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1372_pocket_pattern_completeness_evidence.py +8 -8
  145. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1372_polygonal_boss_completeness_evidence.py +11 -11
  146. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1373_plate_completeness_evidence.py +12 -12
  147. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1374_chamfer_completeness_evidence.py +6 -6
  148. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1374_fillet_completeness_evidence.py +6 -6
  149. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1374_turned_step_completeness_evidence.py +6 -6
  150. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1382_circular_blind_step_semantics.py +2 -2
  151. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1382_through_step_semantics.py +6 -2
  152. draftwright-0.4.19/tests/test_issue_1390_sheet_registration.py +62 -0
  153. draftwright-0.4.19/tests/test_issue_1395_degenerate_iso_region.py +277 -0
  154. draftwright-0.4.19/tests/test_issue_1396_layout_advisories.py +134 -0
  155. draftwright-0.4.19/tests/test_issue_1397_unverifiable_requirement_message.py +247 -0
  156. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1421_rectangular_blind_slot_semantics.py +6 -0
  157. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1433_blend_semantics.py +438 -28
  158. draftwright-0.4.19/tests/test_issue_1438_boss_ownership.py +481 -0
  159. draftwright-0.4.19/tests/test_issue_1438_channel_ownership.py +376 -0
  160. draftwright-0.4.19/tests/test_issue_1438_cli_report_sidecar.py +132 -0
  161. draftwright-0.4.19/tests/test_issue_1438_generation_snapshot.py +276 -0
  162. draftwright-0.4.19/tests/test_issue_1438_nested_ownership.py +318 -0
  163. draftwright-0.4.19/tests/test_issue_1438_occurrence_ownership.py +329 -0
  164. draftwright-0.4.19/tests/test_issue_1438_pattern_ownership.py +350 -0
  165. draftwright-0.4.19/tests/test_issue_1438_plate_ownership.py +444 -0
  166. draftwright-0.4.19/tests/test_issue_1438_policy_dispositions.py +316 -0
  167. draftwright-0.4.19/tests/test_issue_1438_report_projection.py +882 -0
  168. draftwright-0.4.19/tests/test_issue_1438_report_writer.py +136 -0
  169. draftwright-0.4.19/tests/test_issue_1438_through_step_ownership.py +462 -0
  170. draftwright-0.4.19/tests/test_issue_1438_turned_step_ownership.py +249 -0
  171. draftwright-0.4.19/tests/test_issue_1450_boss_blend_ownership.py +345 -0
  172. draftwright-0.4.19/tests/test_issue_1460_step_inspection.py +790 -0
  173. draftwright-0.4.19/tests/test_issue_1471_section_recess_pockets.py +361 -0
  174. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_798_silhouette_lint.py +2 -2
  175. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_915_dense_case.py +23 -14
  176. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_label_provenance.py +2 -2
  177. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_layout.py +3 -3
  178. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_layout_cleanliness.py +6 -6
  179. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_layout_hypothesis.py +1 -1
  180. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_layout_property.py +1 -1
  181. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_lint_ink_overlap.py +1 -1
  182. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_lint_structural.py +2 -2
  183. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_linting.py +1 -1
  184. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_make_drawing.py +40 -31
  185. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_object_aspects.py +1 -1
  186. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_parameter_id.py +2 -2
  187. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_part_model.py +6 -5
  188. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_pitch_dim_footprint.py +2 -2
  189. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_private_test_attr_reads.py +1 -1
  190. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_private_test_imports.py +1 -1
  191. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_quality_components.py +3 -2
  192. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_recogniser_capabilities.py +34 -11
  193. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_recogniser_contract.py +3 -3
  194. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_recognition_result.py +3 -3
  195. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_refactor_golden.py +9 -9
  196. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_registry.py +1 -1
  197. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_render_seam.py +4 -4
  198. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_repack_geometry_seam.py +1 -1
  199. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_sheet_emit.py +122 -8
  200. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_sheet_gdt.py +1 -1
  201. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_sheet_notes.py +2 -2
  202. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_sheet_of.py +1 -1
  203. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_sheet_section.py +1 -1
  204. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_sheet_tables.py +3 -3
  205. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_slanted_blind_step.py +1 -1
  206. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_soft_deprecation.py +2 -2
  207. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_strip_layout.py +6 -6
  208. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_suppression_ledger.py +3 -3
  209. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_suppression_marks.py +1 -1
  210. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_tolerances.py +8 -8
  211. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_turned_steps.py +1 -1
  212. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_view_plan.py +9 -9
  213. draftwright-0.4.17/docs/adr/README.md +0 -58
  214. draftwright-0.4.17/src/draftwright/blend_contract.py +0 -90
  215. draftwright-0.4.17/src/draftwright/recognition_cache.py +0 -26
  216. draftwright-0.4.17/tests/test_external_recognition_boundary.py +0 -65
  217. {draftwright-0.4.17 → draftwright-0.4.19}/.gitignore +0 -0
  218. {draftwright-0.4.17 → draftwright-0.4.19}/LICENSE +0 -0
  219. {draftwright-0.4.17 → draftwright-0.4.19}/skills/SKILL.md +0 -0
  220. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/_build_profile.py +0 -0
  221. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/_pmi_part21.py +0 -0
  222. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/annotate.py +0 -0
  223. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/annotations/gears.py +0 -0
  224. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/evaluation/__init__.py +0 -0
  225. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/fonts/IBMPlexMono-Regular.ttf +0 -0
  226. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/fonts/IBMPlexSansCondensed-Regular.ttf +0 -0
  227. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/fonts/LICENSE-IBMPlexMono-OFL.txt +0 -0
  228. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/fonts/LICENSE-IBMPlexSansCondensed-OFL.txt +0 -0
  229. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/fonts/__init__.py +0 -0
  230. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/_registry.py +0 -0
  231. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/angled_step_coverage.py +0 -0
  232. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/gear_coverage.py +0 -0
  233. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/passage_coverage.py +0 -0
  234. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/prismatic_pocket_coverage.py +0 -0
  235. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/linting/profiled_bore_coverage.py +0 -0
  236. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/pmi.py +0 -0
  237. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/py.typed +0 -0
  238. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/recognition/__init__.py +0 -0
  239. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/recognition_frame.py +0 -0
  240. {draftwright-0.4.17 → draftwright-0.4.19}/src/draftwright/score.py +0 -0
  241. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/ap242_single_cylinder_diameter.step +0 -0
  242. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/README.md +0 -0
  243. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/ambiguous-open-semicircle.step +0 -0
  244. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/blind-hole.step +0 -0
  245. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-asymmetric.step +0 -0
  246. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-compound.step +0 -0
  247. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-overlap.step +0 -0
  248. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-plain.step +0 -0
  249. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-planar-x.step +0 -0
  250. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-planar-y.step +0 -0
  251. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-planar-z.step +0 -0
  252. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-topology-a.step +0 -0
  253. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-topology-b.step +0 -0
  254. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/chamfer-turned.step +0 -0
  255. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-chamfers-v1.json +0 -0
  256. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-countersinks-v1.json +0 -0
  257. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-double-d-bores-v1.json +0 -0
  258. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-fillets-v1.json +0 -0
  259. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-flats-v1.json +0 -0
  260. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-grooves-v1.json +0 -0
  261. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-hole-patterns-v1.json +0 -0
  262. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-plates-v1.json +0 -0
  263. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-pocket-patterns-v1.json +0 -0
  264. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-pockets-v1.json +0 -0
  265. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-polygonal-bosses-v1.json +0 -0
  266. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-polygonal-stock-v1.json +0 -0
  267. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-rectangular-pads-v1.json +0 -0
  268. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-turned-steps-v1.json +0 -0
  269. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/corpus-v1.json +0 -0
  270. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/countersink-deburr.step +0 -0
  271. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/countersink-external-cone.step +0 -0
  272. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/countersink-mixed-pair.step +0 -0
  273. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/countersink-single.step +0 -0
  274. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/countersink-topology-a.step +0 -0
  275. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/countersink-topology-b.step +0 -0
  276. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-axis-x.step +0 -0
  277. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-axis-y.step +0 -0
  278. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-blind.step +0 -0
  279. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-coaxial-compound.step +0 -0
  280. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-opposed-blind.step +0 -0
  281. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-roll-30.step +0 -0
  282. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-round-bore.step +0 -0
  283. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-single-z.step +0 -0
  284. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-topology-a.step +0 -0
  285. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/double-d-topology-b.step +0 -0
  286. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-compound.step +0 -0
  287. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-overlap.step +0 -0
  288. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-plain.step +0 -0
  289. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-planar-x.step +0 -0
  290. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-planar-y.step +0 -0
  291. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-planar-z.step +0 -0
  292. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-repeated.step +0 -0
  293. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-topology-a.step +0 -0
  294. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-topology-b.step +0 -0
  295. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/fillet-turned.step +0 -0
  296. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/flat-coaxial.step +0 -0
  297. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/flat-double-d.step +0 -0
  298. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/flat-lone-d.step +0 -0
  299. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/flat-nonround.step +0 -0
  300. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/flat-slanted-double-d.step +0 -0
  301. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/flat-topology-a.step +0 -0
  302. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/flat-topology-b.step +0 -0
  303. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/groove-compound.step +0 -0
  304. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/groove-lone-x.step +0 -0
  305. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/groove-lone-y.step +0 -0
  306. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/groove-lone-z.step +0 -0
  307. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/groove-monotonic-negative.step +0 -0
  308. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/groove-narrow.step +0 -0
  309. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/groove-topology-a.step +0 -0
  310. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/groove-topology-b.step +0 -0
  311. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-compound-equal.step +0 -0
  312. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-detached-body-negative.step +0 -0
  313. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-full-span-ledge-negative.step +0 -0
  314. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-nested-staircase-negative.step +0 -0
  315. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-topology-a.step +0 -0
  316. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-topology-b.step +0 -0
  317. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-x-negative.step +0 -0
  318. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-x-positive.step +0 -0
  319. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-y-negative.step +0 -0
  320. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-y-positive.step +0 -0
  321. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-z-negative.step +0 -0
  322. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pad-z-positive.step +0 -0
  323. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pattern-ambiguous.step +0 -0
  324. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pattern-grid.step +0 -0
  325. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pattern-topology-a.step +0 -0
  326. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pattern-topology-b.step +0 -0
  327. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/plain-block.step +0 -0
  328. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-compound-equal.step +0 -0
  329. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-cross-topology-a.step +0 -0
  330. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-cross-topology-b.step +0 -0
  331. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-detached-negative.step +0 -0
  332. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-rotational-negative.step +0 -0
  333. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-single-negative.step +0 -0
  334. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-t-xz.step +0 -0
  335. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-t-yz.step +0 -0
  336. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-thick-negative.step +0 -0
  337. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-u-additive.step +0 -0
  338. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/plate-u-cut.step +0 -0
  339. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-compound.step +0 -0
  340. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-edge-anchored.step +0 -0
  341. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-lone.step +0 -0
  342. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-opposed.step +0 -0
  343. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-pattern-ambiguous.step +0 -0
  344. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-pattern-grid.step +0 -0
  345. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-pattern-linear.step +0 -0
  346. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-pattern-pair.step +0 -0
  347. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-pattern-topology-a.step +0 -0
  348. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-pattern-topology-b.step +0 -0
  349. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-prismatic-negative.step +0 -0
  350. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-side.step +0 -0
  351. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-through-negative.step +0 -0
  352. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-topology-a.step +0 -0
  353. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-topology-b.step +0 -0
  354. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/pocket-two-equal.step +0 -0
  355. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-compound-equal.step +0 -0
  356. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-detached-negative.step +0 -0
  357. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-in-plane-rotated.step +0 -0
  358. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-other-protrusions-negative.step +0 -0
  359. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-recess-negative.step +0 -0
  360. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-stock-negative.step +0 -0
  361. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-topology-a.step +0 -0
  362. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-topology-b.step +0 -0
  363. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-x.step +0 -0
  364. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-y.step +0 -0
  365. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-boss-z.step +0 -0
  366. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-compound-negative.step +0 -0
  367. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-cylinder-negative.step +0 -0
  368. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-irregular-negative.step +0 -0
  369. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-octagon-negative.step +0 -0
  370. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-recess-negative.step +0 -0
  371. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-roll17.step +0 -0
  372. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-topology-a.step +0 -0
  373. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-topology-b.step +0 -0
  374. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-translated.step +0 -0
  375. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-x.step +0 -0
  376. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/polygonal-stock-y.step +0 -0
  377. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/topology-a.step +0 -0
  378. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/topology-b.step +0 -0
  379. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/turned-step-axis-x.step +0 -0
  380. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/turned-step-axis-y.step +0 -0
  381. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/turned-step-axis-z.step +0 -0
  382. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/turned-step-compound.step +0 -0
  383. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/turned-step-repeated-lengths.step +0 -0
  384. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/turned-step-through-bore.step +0 -0
  385. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/turned-step-topology-a.step +0 -0
  386. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/turned-step-topology-b.step +0 -0
  387. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/evaluation/turned-step-translated-blind-bore.step +0 -0
  388. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/grm03_thumbwheel_drive_screw.step +0 -0
  389. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/grm03_thumbwheel_drive_screw_ap242_pmi.step +0 -0
  390. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/grm04_drive_plate.step +0 -0
  391. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/if_step_flat_across_cylinder.step +0 -0
  392. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/issue_1058_wheel_rh.step +0 -0
  393. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/issue_1247_angled_blind_step.step +0 -0
  394. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/issue_909_basic_part_design_017_body.step +0 -0
  395. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/issue_915_case_study_2.step +0 -0
  396. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/nist_ctc_01_asme1_ap203.stp +0 -0
  397. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/nist_ctc_01_asme1_ap242.stp +0 -0
  398. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/nist_ctc_02_asme1_ap203.stp +0 -0
  399. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/nist_ctc_02_asme1_ap242.stp +0 -0
  400. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/nist_ctc_03_asme1_ap203.stp +0 -0
  401. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/nist_ctc_03_asme1_ap242.stp +0 -0
  402. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/nist_ctc_04_asme1_ap203.stp +0 -0
  403. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/nist_ctc_04_asme1_ap242.stp +0 -0
  404. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/nist_ctc_05_asme1_ap203.stp +0 -0
  405. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/nist_ctc_05_asme1_ap242.stp +0 -0
  406. {draftwright-0.4.17 → draftwright-0.4.19}/tests/fixtures/tuner_jig_blind_obround_pockets.step +0 -0
  407. {draftwright-0.4.17 → draftwright-0.4.19}/tests/refactor_golden/bracket_section.json +0 -0
  408. {draftwright-0.4.17 → draftwright-0.4.19}/tests/refactor_golden/centered_rebate.json +0 -0
  409. {draftwright-0.4.17 → draftwright-0.4.19}/tests/refactor_golden/chamfered.json +0 -0
  410. {draftwright-0.4.17 → draftwright-0.4.19}/tests/refactor_golden/filleted.json +0 -0
  411. {draftwright-0.4.17 → draftwright-0.4.19}/tests/refactor_golden/flange_dense.json +0 -0
  412. {draftwright-0.4.17 → draftwright-0.4.19}/tests/refactor_golden/grid_plate.json +0 -0
  413. {draftwright-0.4.17 → draftwright-0.4.19}/tests/refactor_golden/grooved_shaft.json +0 -0
  414. {draftwright-0.4.17 → draftwright-0.4.19}/tests/refactor_golden/hex_bar.json +0 -0
  415. {draftwright-0.4.17 → draftwright-0.4.19}/tests/refactor_golden/holed_slot.json +0 -0
  416. {draftwright-0.4.17 → draftwright-0.4.19}/tests/refactor_golden/pocketed.json +0 -0
  417. {draftwright-0.4.17 → draftwright-0.4.19}/tests/refactor_golden/prismatic_ladder.json +0 -0
  418. {draftwright-0.4.17 → draftwright-0.4.19}/tests/refactor_golden/scattered_plate.json +0 -0
  419. {draftwright-0.4.17 → draftwright-0.4.19}/tests/refactor_golden/side_drilled.json +0 -0
  420. {draftwright-0.4.17 → draftwright-0.4.19}/tests/refactor_golden/turned_stepped.json +0 -0
  421. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_agents_guide.py +0 -0
  422. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_api_docs.py +0 -0
  423. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_balloon_ring_standoff.py +0 -0
  424. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_build_profile_harness.py +0 -0
  425. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_counting_calls.py +0 -0
  426. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_dimension_role_vocabulary.py +0 -0
  427. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_e2e_standards.py +0 -0
  428. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_export_dxf_curves.py +0 -0
  429. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_export_dxf_zoom.py +0 -0
  430. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_export_reproducible.py +0 -0
  431. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_fillets_adjacency.py +0 -0
  432. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_flat_completeness.py +0 -0
  433. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_flat_stock_opposition.py +0 -0
  434. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_geometry_graph_spike.py +0 -0
  435. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_iso_nts_caption_placement.py +0 -0
  436. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1000_envelope_reuse.py +0 -0
  437. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1073_cross_body_patterns.py +0 -0
  438. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1082_polygonal_stock.py +0 -0
  439. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1086_declared_gears.py +0 -0
  440. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1116_ap242_hole_tolerance_lowering.py +0 -0
  441. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1143_hole_completeness.py +0 -0
  442. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1144_transactional_hole_table.py +0 -0
  443. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1147_legibility_pair_aggregation.py +0 -0
  444. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1154_one_owner_per_measurement.py +0 -0
  445. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1155_grm04_sheet_use.py +0 -0
  446. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1166_cross_pass_feature_leaders.py +0 -0
  447. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1187_unroutable_leaders.py +0 -0
  448. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1188_per_view_assignment.py +0 -0
  449. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1190_section_decision.py +0 -0
  450. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1204_multiscale_view_issues.py +0 -0
  451. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1209_linear_pmi_witnesses.py +0 -0
  452. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1216_pairwise_across_scale_groups.py +0 -0
  453. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1219_location_claims_its_own_axis.py +0 -0
  454. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1229_ledger_member_keying.py +0 -0
  455. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1240_iso_above_strip_visibility.py +0 -0
  456. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1245_passage_disposition.py +0 -0
  457. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1246_prismatic_pocket_disposition.py +0 -0
  458. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1247_angled_step_disposition.py +0 -0
  459. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1254_turned_chamfers.py +0 -0
  460. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1262_automatic_turned_views.py +0 -0
  461. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1276_turned_leader_targets.py +0 -0
  462. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1281_turned_fillets.py +0 -0
  463. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1296_cylindrical_diameter_pmi.py +0 -0
  464. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1298_manufacturing_requirements.py +0 -0
  465. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1299_page_escalation.py +0 -0
  466. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1312_engine_costs.py +0 -0
  467. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1332_zone_labels.py +0 -0
  468. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1334_prevent_ink.py +0 -0
  469. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1336_grm03_ap242_pmi_fixture.py +0 -0
  470. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1338_scale_before_page_escalation.py +0 -0
  471. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1349_precision_display.py +0 -0
  472. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1350_detected_takeover.py +0 -0
  473. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1351_structured_note_coverage.py +0 -0
  474. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1352_searchable_pdf_text.py +0 -0
  475. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1353_cnc_authoritative_workflow.py +0 -0
  476. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1357_plural_turned_profiles.py +0 -0
  477. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1357_pmi_frame.py +0 -0
  478. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1360_thread_depth.py +0 -0
  479. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1382_046_step_inventory.py +0 -0
  480. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1382_framed_step_family_evidence.py +0 -0
  481. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1382_paired_ramp_semantics.py +0 -0
  482. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1392_recognisers_048.py +0 -0
  483. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1421_rectangular_blind_slot_completeness.py +0 -0
  484. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1421_round_bottom_blind_slot_completeness.py +0 -0
  485. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_1421_round_bottom_blind_slot_semantics.py +0 -0
  486. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_367_leader_ink.py +0 -0
  487. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_443_grm03_axial_coverage.py +0 -0
  488. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_563_placement_intent.py +0 -0
  489. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_676_polygonal_boss.py +0 -0
  490. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_676_polygonal_boss_declare.py +0 -0
  491. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_740_leader_assignment.py +0 -0
  492. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_798_floor_cardinality.py +0 -0
  493. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_798_material_field.py +0 -0
  494. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_885_prismatic_coverage.py +0 -0
  495. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_909_sloped_profile.py +0 -0
  496. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_916_pocket_leader.py +0 -0
  497. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_917_open_channel.py +0 -0
  498. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_924_zero_length_shoulders.py +0 -0
  499. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_955_height_contingency.py +0 -0
  500. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_issue_958_cross_solid_recognition.py +0 -0
  501. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_leader_footprint.py +0 -0
  502. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_lint_box_cache.py +0 -0
  503. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_lint_reconciliation.py +0 -0
  504. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_location_vocabulary.py +0 -0
  505. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_note_verb.py +0 -0
  506. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_occupancy_boxes.py +0 -0
  507. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_pmi.py +0 -0
  508. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_pmi_datum_lowering.py +0 -0
  509. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_pmi_gtol_lowering.py +0 -0
  510. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_pmi_part21.py +0 -0
  511. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_pocket_pattern.py +0 -0
  512. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_pocket_pattern_recognition.py +0 -0
  513. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_principal_profile_classifier.py +0 -0
  514. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_recogniser_adoption.py +0 -0
  515. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_recognition.py +0 -0
  516. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_score.py +0 -0
  517. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_script_detail_parity.py +0 -0
  518. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_shared_box_memo.py +0 -0
  519. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_sheet_identity_invariant.py +0 -0
  520. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_slot_completeness.py +0 -0
  521. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_slot_pattern.py +0 -0
  522. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_slot_pattern_recognition.py +0 -0
  523. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_solve_trace.py +0 -0
  524. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_step_analysis_evaluation.py +0 -0
  525. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_witness_label_reconciliation.py +0 -0
  526. {draftwright-0.4.17 → draftwright-0.4.19}/tests/test_workflows.py +0 -0
@@ -4,6 +4,116 @@
4
4
 
5
5
  ### Added
6
6
 
7
+ - Report schema v1 now projects one recognition-owned physical requirement ledger shared with
8
+ completeness. Each bounded requirement identifies its accepted source occurrence(s), final IR
9
+ owner(s), semantic parameter where applicable, placement/satisfaction state, annotation names,
10
+ and representation rationale. The roster is evaluated once per report and fails closed when
11
+ exact same-run evidence or provenance is absent; it does not create a second recognition scan,
12
+ persistent topology identity, inferred manufacturing intent, or visual change (#1438, ADR 0017
13
+ Amendment 26).
14
+
15
+ - Direct CLI rendering now writes `<output>.draftwright.json` by default, after successful visual
16
+ export, and prints its path with the requested artefacts. `--no-report` is the explicit opt-out;
17
+ library `Drawing.export()` remains free of report-writing side effects (#1438, ADR 0017
18
+ Amendment 25).
19
+
20
+ - Generated Sheet Python now embeds a deterministic, versioned, JSON-compatible snapshot of
21
+ actionable accepted-occurrence gaps from the exact recognition run that produced its model.
22
+ The compact snapshot carries only unsupported, deferred, evidence-only, and unexpectedly
23
+ missing public records; STEP inputs are read once and recognition uses a private copy of the
24
+ exact bytes named by the embedded basename and SHA-256, with a best-effort final replay-target
25
+ check before writing. The hash is a later reconciliation boundary, not a lock on the mutable
26
+ source path. It is explicitly generation-time evidence, never current completeness authority
27
+ (#1438, ADR 0017 Amendment 24).
28
+
29
+ - Accepted Plate occurrences now retain exact conditional ownership. Genuine multi-axis plates
30
+ keep their direct `PlateFeature`; other slabs are absorbed only when released same-run AAG
31
+ evidence joins them to the exact retained face-level, riser-shoulder, or slot-pattern owner.
32
+ Multi-owner claims are conjunctive, while whole-envelope, polygonal-boss, disconnected,
33
+ ambiguous, or malformed cases remain visibly `unexpectedly_missing` rather than borrowing an
34
+ owner from matching values or traversal order (#1438, ADR 0017 Amendment 23).
35
+
36
+ - `Drawing.write_report(path)` now atomically writes the versioned report as deterministic,
37
+ strict UTF-8 JSON without coupling library export to sidecar generation. Report and filesystem
38
+ failures leave any existing destination untouched, with best-effort temporary cleanup that does
39
+ not mask the primary error (#1438, ADR 0017 Amendment 22).
40
+
41
+ - Raw automatic drawings now expose `Drawing.report()`, a strict version-1 JSON-compatible
42
+ projection of every accepted recognition occurrence, its explicit consumer disposition and
43
+ report-local final IR owner(s), plus the existing lint summary. The published schema never
44
+ serializes provider references, topology IDs, object addresses, or transient member positions;
45
+ it makes requirement coverage an explicit field (subsequently populated by Amendment 26) and
46
+ calls a clean result `bounded-clear`, not manufacturing-ready. Paths without exact occurrence
47
+ ownership and raw paths with an unclassified accepted occurrence fail explicitly rather than
48
+ emit an empty or inferred report. Rendering remains unchanged (#1438, ADR 0017 Amendment 21).
49
+
50
+ - Accepted `FaceLevel` and `RiserEvidence` occurrences now receive explicit `evidence_only`
51
+ outcomes. The released records remain shared substrate for the supported correlated height
52
+ ladder and shoulder projection, not independent inferred features or drawing requirements; no
53
+ IR, Sheet DSL, renderer, or recogniser API change is introduced (#1438, ADR 0017 Amendment 20).
54
+
55
+ - Accepted round-boss occurrences now retain the exact existing consumer outcome: a singleton
56
+ `BossFeature`, one diameter-consolidated representative with transient member lineage, the exact
57
+ turned-step owner, or the exact groove owner reached through that step or the profile-gate
58
+ fallback. Ambiguous or missing correspondence fails closed without another scan, persistent ID,
59
+ generated artefact, or visual change (#1438, ADR 0017 Amendment 19).
60
+
61
+ - Accepted through-step occurrences now retain either their exact `ThroughStepFeature` or every
62
+ exact final `StepLevelFeature`, `PlateFeature`, and `EnvelopeFeature` that jointly carries the
63
+ established compatibility projection. Plate claims are body-local, replacement is atomic, and a
64
+ missing or ambiguous selected owner fails closed rather than granting partial credit. One
65
+ occurrence can name multiple run-local IR owners without a second scan, persistent ID, generated
66
+ artefact, or change to rendering machinery (#1438, ADR 0017 Amendment 18).
67
+
68
+ - Accepted turned-step occurrences now retain the conversion decision that already gives an
69
+ ordinary profile band its exact `StepFeature` or absorbs a groove-floor band into the exact
70
+ same-run `GrooveFeature`. The takeover must be one-to-one in both directions, so an ambiguous
71
+ groove, an adjacent band inside its positional tolerance, or any missing final owner fails closed
72
+ as `unexpectedly_missing`, with no second scan, persistent ID, generated artefact, or visual
73
+ change (#1438, ADR 0017 Amendment 17).
74
+
75
+ - Accepted channel occurrences now receive an exact conditional consumer outcome. A genuine
76
+ multi-axis plate channel is `represented` by its `ChannelFeature`; a monolithic Z-depth rebate is
77
+ `absorbed` only when one retained body-local support carries its floor and both shoulders into the
78
+ final step ladder. Cross-axis, disconnected, or filtered channels fail closed as
79
+ `unexpectedly_missing` instead of inheriting an unrelated ladder, without a second scan,
80
+ persistent ID, generated artefact, or visual change (#1438, ADR 0017 Amendment 16).
81
+
82
+ - Accepted countersink occurrences now receive an exact run-local outcome. A seat carried by a
83
+ `HoleRecord` is `absorbed` by that hole's final feature and transient member lineage; an unattached,
84
+ unowned, or duplicate nested occurrence fails closed without dimension matching, topology IDs, a
85
+ second scan, duplicate IR requirements, or visual changes (#1438, ADR 0017 Amendment 15).
86
+
87
+ - Accepted angled-step, passage, prismatic-pocket, oriented-slot, and repeating-radial-profile
88
+ occurrences now receive exact run-local ownerless outcomes from Draftwright's existing consumer
89
+ capability declaration: `unsupported`, `deferred`, or report-facing `evidence_only`, with closed
90
+ reason codes and existing tracking issues. Equal-valued occurrences stay distinct; policy does
91
+ not invent IR owners, requirements, topology IDs, recognition scans, generated artefacts, or
92
+ visual output (#1438, ADR 0017 Amendment 14).
93
+
94
+ - Accepted physical hole, slot, and pocket occurrences now retain explicit run-local ownership
95
+ when conversion represents a singleton or absorbs members into one same-spec hole group or
96
+ derived pattern feature. Family-specific reason codes and transient member lineage follow
97
+ member-specific AP242 splits to the exact final IR objects; missing lineage fails closed rather
98
+ than retaining a stale owner. Provider-derived patterns do not become invented occurrences, and
99
+ no report ID, extra recognition scan, generated artefact, or visual output is introduced (#1438,
100
+ ADR 0017 Amendment 13).
101
+
102
+ - Raw automatic builds now capture run-local, conversion-time ownership from accepted provider
103
+ occurrences to their exact Draftwright IR features for unconditional one-to-one adapters. Equal
104
+ record values, order, coordinates and topology indices cannot create a binding; an omitted direct
105
+ binding fails closed as unexpectedly missing, while ownership rules not yet implemented remain
106
+ explicitly unclassified. The experimental read-only `Drawing.recognition_ownership()` exposes
107
+ the non-serializable ledger; it stays outside the IR/compiler and changes no generated or visual
108
+ artefact (#1438, ADR 0017 Amendment 12).
109
+
110
+ - Raw automatic recognition now retains the provider's run-scoped `RecognitionEvidence` beside
111
+ its exact `RecognitionResult`, exposed through the experimental read-only
112
+ `Drawing.recognition_evidence()`. Declared drawings acquire the pair lazily on first physical
113
+ critique; bare and framed results remain evidence-less, and Draftwright never rescans merely to
114
+ backfill evidence. This is a non-visual reporting foundation and changes no rendered artefact
115
+ (#1438, ADRs 0015, 0017, 0020).
116
+
7
117
  - Automatic drawings can opt into the provider-owned local recognition frame with
8
118
  `framed_recognition=True`. The returned drawing exposes caller provenance, the exact downstream
9
119
  working solid, frame, and a copied framed/raw/refusal decision. PMI correlation, off-axis pattern
@@ -44,21 +154,25 @@
44
154
 
45
155
  ### Changed
46
156
 
47
- - Accepted schema-v1 convex `Blend` chains now cross a dedicated end-to-end consumer path:
157
+ - Accepted schema-v3 straight or circular `Blend` chains, including concave occurrences, now cross
158
+ a dedicated end-to-end consumer path:
48
159
  `BlendFeature`, explicit `Sheet.blend(...)`, executable generated declarations, one
49
160
  compiler-approved `blend.radius` requirement, and a solver-owned grouped `n× R` leader. The
50
- full canonical `axis_direction` remains in IR instead of being coerced to legacy Fillet
161
+ discriminated path kind, full canonical direction/normal, circular-path major radius,
162
+ rolling-ball radius, and material side remain in IR instead of being coerced to legacy Fillet
51
163
  semantics; the provider aggregate remains the sole exact Fillet/Blend precedence authority.
52
164
  Exact public-record/IR validation and completeness follow every accepted occurrence to placed,
53
165
  structured-note, authored-suppressed, dropped, missing, or unverifiable outcomes. Raw and
54
- provider-framed arbitrary rigid motions retain the same radius meaning (#1433; ADRs 0011,
55
- 0013–0017, 0020).
56
-
57
- - Draftwright now exactly pins the immutable `b123d-recognisers` 0.4.12 release and advances its
58
- fail-closed capability and inspection joins. This adoption first made the additive `Blend`,
59
- `OrientedSlot`, `OrientedSlotArray`, and `OrientedSlotGrid` records visible and deferred under
60
- #1430; Blend is now promoted by #1433 above, while oriented slots/patterns remain deferred and
61
- recognised-but-unscored. All earlier record schemas remain compatible. The provider's newly
166
+ provider-framed arbitrary rigid motions retain straight-path radius meaning; framed recognition
167
+ also retains circular paths, while raw arbitrarily rotated circular recognition remains an
168
+ upstream limitation (b123d-recognisers#491) (#1433; ADRs 0011, 0013–0017, 0020).
169
+
170
+ - Draftwright now exactly pins the immutable `b123d-recognisers` 0.4.14 release and advances its
171
+ fail-closed capability and inspection joins. `Blend` schema v3 replaces the old flat cylindrical
172
+ fields with exact `StraightBlendPath` and `CircularBlendPath` records and admits proved concave
173
+ and toroidal occurrences; Draftwright preserves those semantics through IR, `Sheet.blend(...)`,
174
+ generated replay, reporting, drawing, and completeness. Passage nested records advance to schema
175
+ v2 without changing Draftwright's unsupported passage policy. The provider's previously
62
176
  recognised shallow nonzero `PairedRampStep` keeps its existing
63
177
  two-requirement IR, public `Sheet.paired_ramp_step(...)` declaration, generated-code, compiler
64
178
  callout, solver placement, and completeness meaning (#1430; ADRs 0011, 0013–0017, 0020).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: draftwright
3
- Version: 0.4.17
3
+ Version: 0.4.19
4
4
  Summary: Automated technical-drawing generation for build123d
5
5
  Project-URL: Homepage, https://github.com/pzfreo/draftwright
6
6
  Project-URL: Repository, https://github.com/pzfreo/draftwright
@@ -684,7 +684,7 @@ Classifier: Programming Language :: Python :: 3.14
684
684
  Classifier: Topic :: Scientific/Engineering
685
685
  Requires-Python: <3.15,>=3.10
686
686
  Requires-Dist: antlr4-python3-runtime<4.10
687
- Requires-Dist: b123d-recognisers==0.4.12
687
+ Requires-Dist: b123d-recognisers==0.4.14
688
688
  Requires-Dist: build123d-drafting-helpers>=0.14.2
689
689
  Requires-Dist: build123d<0.11,>=0.9.0; python_full_version < '3.13'
690
690
  Requires-Dist: build123d<0.12,>=0.11; python_full_version >= '3.13'
@@ -740,13 +740,14 @@ Point it at a STEP file — that's the whole workflow:
740
740
 
741
741
  ```
742
742
  draftwright my_part.step --title "Mounting Plate" --number DWG-001
743
- # writes my_part.pdf (the default)
743
+ # writes my_part.pdf and my_part.draftwright.json (the defaults)
744
744
  ```
745
745
 
746
746
  Choose formats, scale, and page; or emit an editable drawing script:
747
747
 
748
748
  ```
749
749
  draftwright my_part.step --format pdf,dxf # also: svg, all
750
+ draftwright my_part.step --no-report # opt out of the JSON sidecar
750
751
  draftwright my_part.step --scale 2 --page A3 # override the auto scale / page
751
752
  draftwright my_part.step --scale 1 --page A4 --scale-policy strict
752
753
  draftwright my_part.step --script # write an editable declarative Sheet script
@@ -794,7 +795,7 @@ and removed in 0.5.0 (see [docs/deprecations.md](docs/deprecations.md)).
794
795
  Instead of relying on detection, **reference the build123d objects you built** and declare
795
796
  only the drawing intent — geometry supplies the sizes (⌀ read off the object), you supply
796
797
  tolerances, fits, datums, GD&T, and surface finish. The fluent `Sheet` skips detection and
797
- dimensions exactly what you declare (ADR 0011):
798
+ dimensions exactly what you declare (ADR 4 (was 0011)):
798
799
 
799
800
  ```python
800
801
  from build123d import Box, Cylinder, Pos
@@ -810,7 +811,7 @@ hole = sheet.hole(bore).finish("1.6").note("M3x0.5 TAP") # ⌀8 bore, Ra 1.6, t
810
811
  sheet.control(hole).position(0.1, to="A", diameter=True) # ⌀0.1 position wrt A
811
812
 
812
813
  sheet.authored_dimensions() # THIS is the complete set
813
- sheet.dimension(env, "width.length") # (ADR 0016: a build says where
814
+ sheet.dimension(env, "width.length") # (ADR 4 (was 0016): a build says where
814
815
  sheet.dimension(env, "height.length") # its dimensions come from, and
815
816
  sheet.dimension(hole, "bore.diameter") # omitting one means suppress it)
816
817
 
@@ -857,7 +858,7 @@ draftwright mymodule:thumbwheel --script
857
858
 
858
859
  The emitted values are *detected* off the geometry — honest, and a good starting point. Since
859
860
  you have the objects, swap each numbered line for a reference so the object stays the single
860
- source of truth (ADR 0011 — the size is read off the object, no numbers restated):
861
+ source of truth (ADR 4 (was 0011) — the size is read off the object, no numbers restated):
861
862
 
862
863
  ```python
863
864
  # generated (detected):
@@ -991,7 +992,7 @@ generation, the lint→repair loop, and collect-then-solve placement).
991
992
 
992
993
  ## Architecture
993
994
 
994
- draftwright is structured as a **part-drawing compiler** (ADR 0015): recognised
995
+ draftwright is structured as a **part-drawing compiler** (ADR 1 (was 0015)): recognised
995
996
  or declared features converge on a `PartModel` IR, then planner-fed and
996
997
  sanctioned model-routed render intents feed shared placement, projection, and
997
998
  export. Coverage lint independently compares recognised geometry with the
@@ -40,13 +40,14 @@ Point it at a STEP file — that's the whole workflow:
40
40
 
41
41
  ```
42
42
  draftwright my_part.step --title "Mounting Plate" --number DWG-001
43
- # writes my_part.pdf (the default)
43
+ # writes my_part.pdf and my_part.draftwright.json (the defaults)
44
44
  ```
45
45
 
46
46
  Choose formats, scale, and page; or emit an editable drawing script:
47
47
 
48
48
  ```
49
49
  draftwright my_part.step --format pdf,dxf # also: svg, all
50
+ draftwright my_part.step --no-report # opt out of the JSON sidecar
50
51
  draftwright my_part.step --scale 2 --page A3 # override the auto scale / page
51
52
  draftwright my_part.step --scale 1 --page A4 --scale-policy strict
52
53
  draftwright my_part.step --script # write an editable declarative Sheet script
@@ -94,7 +95,7 @@ and removed in 0.5.0 (see [docs/deprecations.md](docs/deprecations.md)).
94
95
  Instead of relying on detection, **reference the build123d objects you built** and declare
95
96
  only the drawing intent — geometry supplies the sizes (⌀ read off the object), you supply
96
97
  tolerances, fits, datums, GD&T, and surface finish. The fluent `Sheet` skips detection and
97
- dimensions exactly what you declare (ADR 0011):
98
+ dimensions exactly what you declare (ADR 4 (was 0011)):
98
99
 
99
100
  ```python
100
101
  from build123d import Box, Cylinder, Pos
@@ -110,7 +111,7 @@ hole = sheet.hole(bore).finish("1.6").note("M3x0.5 TAP") # ⌀8 bore, Ra 1.6, t
110
111
  sheet.control(hole).position(0.1, to="A", diameter=True) # ⌀0.1 position wrt A
111
112
 
112
113
  sheet.authored_dimensions() # THIS is the complete set
113
- sheet.dimension(env, "width.length") # (ADR 0016: a build says where
114
+ sheet.dimension(env, "width.length") # (ADR 4 (was 0016): a build says where
114
115
  sheet.dimension(env, "height.length") # its dimensions come from, and
115
116
  sheet.dimension(hole, "bore.diameter") # omitting one means suppress it)
116
117
 
@@ -157,7 +158,7 @@ draftwright mymodule:thumbwheel --script
157
158
 
158
159
  The emitted values are *detected* off the geometry — honest, and a good starting point. Since
159
160
  you have the objects, swap each numbered line for a reference so the object stays the single
160
- source of truth (ADR 0011 — the size is read off the object, no numbers restated):
161
+ source of truth (ADR 4 (was 0011) — the size is read off the object, no numbers restated):
161
162
 
162
163
  ```python
163
164
  # generated (detected):
@@ -291,7 +292,7 @@ generation, the lint→repair loop, and collect-then-solve placement).
291
292
 
292
293
  ## Architecture
293
294
 
294
- draftwright is structured as a **part-drawing compiler** (ADR 0015): recognised
295
+ draftwright is structured as a **part-drawing compiler** (ADR 1 (was 0015)): recognised
295
296
  or declared features converge on a `PartModel` IR, then planner-fed and
296
297
  sanctioned model-routed render intents feed shared placement, projection, and
297
298
  export. Coverage lint independently compares recognised geometry with the
@@ -0,0 +1,48 @@
1
+ # Architecture decision records
2
+
3
+ Five live records, one per core aspect of Draftwright. Read them before changing anything they
4
+ govern. Each states a decision, then a numbered list of invariants an agent must not violate,
5
+ each naming the test that fails if it is — that list is the reason the document exists.
6
+
7
+ | ADR | Owns | Guard tests (representative) |
8
+ | --- | --- | --- |
9
+ | [1 — The compiler pipeline](0001-compiler-pipeline.md) | One engine, the `PartModel` IR waist, the module DAG, single-owner build state, the compiled plan fed to placement | `test_import_boundaries.py`, `test_drawing_encapsulation.py`, `test_detect_once.py`, `test_compiled_plan_boundary.py` |
10
+ | [2 — Sheet layout and view planning](0002-sheet-layout-and-view-planning.md) | Requirement-driven view planning, compose-then-pack, collect-then-solve placement, Policy B, scale-before-sheet | `test_carve_free_position_callers.py`, `test_layout_cleanliness.py`, `test_issue_1146_scale_completeness.py`, `test_issue_1260_view_constraints.py` |
11
+ | [3 — The recognition boundary](0003-recognition-boundary.md) | External geometry-only recognition, one run per build, the fail-closed provider join, occurrence ownership, the framed boundary | `test_recogniser_capabilities.py`, `test_declared_recognition_gate.py`, `test_detect_registry.py`, `test_issue_1357_framed_boundary.py` |
12
+ | [4 — Declared intent](0004-declared-intent.md) | The IR as public input, authored dimension sets, suppression by omission, the compiled-plan boundary, one declarative script | `test_declare.py`, `test_label_provenance.py`, `test_parameter_id.py`, `test_sheet_identity_invariant.py` |
13
+ | [5 — Trust and honest failure](0005-trust-and-honest-failure.md) | Determinism, lint as an independent judge, provenance, reports that refuse rather than shrink, absences reported | `test_export_reproducible.py`, `test_render_seam.py`, `test_issue_1215_no_approved_tolerance_is_dropped.py`, `test_issue_1438_report_projection.py` |
14
+
15
+ `archive/` holds the twenty records these replaced, frozen, with their filenames and numbers
16
+ unchanged. Each is stamped with the live record that now owns its decision. They are the
17
+ why-trail; nothing in them is a work instruction.
18
+
19
+ ## Rules of engagement
20
+
21
+ These exist because the previous corpus reached 21 files, 8,787 lines and one record with 28
22
+ amendments, and its own "at roughly four amendments, write a successor" rule was a convention
23
+ that nothing enforced. Each rule below is enforced by `tests/test_adr_corpus.py` where a test can
24
+ enforce it.
25
+
26
+ 1. **A record changes only when a boundary or invariant changes.** Adopting a provider version,
27
+ adding a feature family, recording ownership for one more record type, adding a report field:
28
+ that is a PR body, not an amendment. If the change does not alter the Invariants section, it
29
+ does not touch the record.
30
+ 2. **No record text is written without the maintainer's sign-off.** An agent or contributor who
31
+ believes a record needs to change says so in the PR in two sentences and waits. A reviewer
32
+ recommending an ADR is a recommendation, not an authorisation.
33
+ 3. **Each live record is at most 200 lines; the five together at most 1,000.** Enforced.
34
+ 4. **No live document cites an archived record as its authority.** Code, tests and docs cite
35
+ ADR 1–5. A pointer into the archive is written `ADR n (was 00NN …)` so the history stays
36
+ findable while the live number is the one a reader acts on. A bare `ADR 00NN` outside
37
+ `archive/` fails the guard.
38
+ 5. **Every invariant names its guard.** One without a test is listed under *Unguarded* with the
39
+ reason, never mixed into the numbered list. The guard checks that every named test module and
40
+ test function exists. That list is expected to shrink.
41
+ 6. **Cite symbols and test names, never source line numbers.**
42
+
43
+ ## Reading order
44
+
45
+ Pipeline first (1), then whichever aspect the change touches. Layout (2) and declared intent (4)
46
+ each assume the pipeline; recognition (3) and trust (5) each assume the other four's boundaries.
47
+
48
+ The consolidation itself is recorded in `docs/plans/adr-consolidation-plan.md`.
@@ -70,6 +70,36 @@ issue. The contract test derives package record outputs, converter registries, l
70
70
  and emitter branches independently, so copying a new name into the declaration alone cannot make CI
71
71
  pass.
72
72
 
73
+ ### Quiddity migration baseline
74
+
75
+ The first [#1471](https://github.com/pzfreo/draftwright/issues/1471) migration slice tests the
76
+ released Quiddity SectionRecess document against the existing authored pocket corpus. Quiddity is
77
+ pinned in the development dependencies for this comparison. Production continues to use the
78
+ existing recogniser dependency and capability declaration.
79
+
80
+ The private pocket adapter in `model/detect.py` reads primitive schema-2 occurrence geometry and
81
+ produces the existing `PocketFeature`. It admits principal-axis closed rectangles and open
82
+ rectangular corner/edge chains, preserves the opening direction, and refuses unsupported shapes,
83
+ sloped ends, invalid frames and malformed measurements. An open chain remains edge-anchored; its
84
+ missing boundary is never reconstructed as a physical edge.
85
+
86
+ `tests/test_issue_1471_section_recess_pockets.py` checks independently authored dimensions,
87
+ opposed and side openings, disconnected bodies, topology variants, the existing drawing path,
88
+ executed generated Sheet scripts and authored omission. The baseline tests for pocket patterns,
89
+ channels and both blind-slot families remain the acceptance floor for their later adapters.
90
+
91
+ This is preparation for adoption, not a new automatic detection mode. The adapter does not yet
92
+ participate in the production registry, bind occurrence ownership or provide Quiddity-based lint.
93
+ Its comparison drawings use the pinned provider for physical critique. The eventual cutover must
94
+ validate result-local references, bind exact same-run occurrences, migrate patterns and explicit
95
+ refusals, and update independent lint, reports and inspection together. A build already holding an
96
+ aggregate must project it rather than invoke the document builder for a second recognition run.
97
+
98
+ The comparison pins Quiddity 0.2.1, which fixes
99
+ [Quiddity #505](https://github.com/pzfreo/quiddity/issues/505): support proofs now handle
100
+ build123d 0.10 `ShapeList` boolean results. The pocket corpus exercises this public recognition
101
+ path across the supported Python/build123d matrix before consumer adaptation.
102
+
73
103
  `bosses` is the fully consumed reference family. `repeating-radial-profiles` is the opposite
74
104
  reference: it remains geometry-only critique evidence for a separately authored gear declaration,
75
105
  with no inferred gear feature added to fill the table.
@@ -188,7 +218,7 @@ directional datum locations. Edge-anchored pockets intentionally require only th
188
218
  because the adjacent stock edges establish position. Pattern members are excluded rather than
189
219
  double-counted. Each fact must survive automatic IR, public `Sheet.pocket`, executed generated
190
220
  Sheet code and placed size/location provenance. The IR now retains provider `open_sign`, and the
191
- shared location renderer records which physical X/Y ordinate landed while preserving ADR 0016's
221
+ shared location renderer records which physical X/Y ordinate landed while preserving ADR 4 (was 0016)'s
192
222
  single public `location` authoring unit.
193
223
 
194
224
  ## Pocket-pattern completeness evidence
@@ -485,11 +515,12 @@ physical corpora.
485
515
  ## Historical: recognisers 0.4.8 raw boundary and RaisedPad v2
486
516
 
487
517
  Draftwright pinned the published `b123d-recognisers==0.4.8` wheel in the preceding release.
488
- The default route deliberately calls `build_raw_recognition_result`; records remain in the
489
- caller/world coordinate system. #1357 now provides a reviewed explicit framed-result activation
490
- added with 0.4.9. The 0.4.8 tests used the public framed API as release evidence for upstream #331, #332,
491
- and #334, comparing each aggregate inventory with the corresponding public family call on the exact
492
- returned local solid. Production added no fallback, second aggregate, or family rescan. Face levels,
518
+ At that time the default route deliberately called `build_raw_recognition_result`; records
519
+ remained in the caller/world coordinate system. #1357 now provides a reviewed explicit
520
+ framed-result activation added with 0.4.9. The 0.4.8 tests used the public framed API as release
521
+ evidence for upstream #331, #332, and #334, comparing each aggregate inventory with the
522
+ corresponding public family call on the exact returned local solid. Production added no fallback,
523
+ second aggregate, or family rescan. Face levels,
493
524
  risers, and turned profiles remained outside framed production pending their subsequently released
494
525
  upstream fixes.
495
526
 
@@ -552,9 +583,30 @@ with exact full-record correspondence and parameter/outcome provenance under the
552
583
  rules as the rectangular family. It now participates independently in `audited_score`; ordinary
553
584
  slots, pockets, channels and rectangular blind slots do not share ownership.
554
585
 
555
- ## Recognisers 0.4.12 adoption and additive-family boundary
556
-
557
- Draftwright exactly pins `b123d-recognisers==0.4.12`, including the immutable 0.4.11 `Blend`
586
+ ## Recognisers 0.4.14 adoption and path-complete Blends
587
+
588
+ Draftwright exactly pins `b123d-recognisers==0.4.14`; the provider family count remains 33 and
589
+ the inspection API remains format 1 / major 1. The fail-closed record join now accepts `Blend`
590
+ schema v3 with nested `StraightBlendPath` and `CircularBlendPath` schema-v1 records. It also
591
+ accepts `PassageEnds`, `PassageSection`, and `SectionPassage` schema v2. Passage remains explicitly
592
+ unsupported under #1245: accepting its released structural schema does not invent an IR feature,
593
+ Sheet declaration, or completeness credit.
594
+
595
+ The supported Blend adapter preserves the complete discriminated path. Straight occurrences keep
596
+ their canonical line direction and anchor; circular occurrences keep their centre, canonical
597
+ normal, and major path radius; both keep rolling-ball radius and proved convex/concave material
598
+ side. `BlendFeature`, `Sheet.blend(...)`, generated replay, report projection, renderer, and
599
+ completeness all carry those facts. The provider aggregate remains the only Fillet/Blend precedence
600
+ authority, and Draftwright does not rescan or reinterpret detached faces. Circular leaders combine
601
+ the two radii with analysis-owned coaxial cylinder candidates, then use exact same-run
602
+ occurrence/IR ownership and the provider-issued defining face to select the physical surface
603
+ tangency instead of the rolling path or its centre. A declaration without that face authority
604
+ refuses competing support radii rather than choosing another body's cylinder; the shared placement
605
+ solve still owns the page position.
606
+
607
+ ## Historical 0.4.12 adoption and additive-family boundary
608
+
609
+ Draftwright initially pinned `b123d-recognisers==0.4.12`, including the immutable 0.4.11 `Blend`
558
610
  addition and the 0.4.12 `OrientedSlot`, `OrientedSlotArray`, and `OrientedSlotGrid` records. The
559
611
  provider capability manifest therefore contains 33 families. Every family and public record has an
560
612
  explicit consumer declaration and registry home; the inspection API remains format 1 / major 1.
@@ -578,9 +630,33 @@ recognition to shallow nonzero ramp pairs. A released shallow specimen now cross
578
630
  supported consumer path without changing meaning: exact record-to-IR lowering, the existing
579
631
  `Sheet.paired_ramp_step(...)` declaration, executed generated code, two compiler-approved angle/run
580
632
  requirements, one solver-owned compound leader, and the established completeness ledger. Existing
581
- raw and provider-framed contract suites continue to guard the ADR 0020 boundary. Draftwright uses no
633
+ raw and provider-framed contract suites continue to guard the ADR 3 (was 0020) boundary. Draftwright uses no
582
634
  provider-private geometry or sibling checkout for any of these claims.
583
635
 
636
+ #1438 first consumed the release's public raw `b123d_recognisers.evidence` acquisition. One
637
+ `RecognitionEvidence` owns the accepted physical occurrence/face references and projects the same
638
+ `RecognitionResult` the existing compiler and lint consumers already read. Draftwright retains
639
+ both in its per-drawing `RecognitionCache`, including across scale/view retries; declared builds
640
+ remain recognition-free until physical critique, and a bare result is never rescanned merely to
641
+ backfill evidence. Recognisers 0.4.14 publishes the framed-evidence contract requested by
642
+ [`b123d-recognisers#463`](https://github.com/pzfreo/b123d-recognisers/issues/463), but Draftwright's
643
+ framed route remains evidence-less until the independent #1438 consumer slice adopts it; it does
644
+ not infer cross-frame occurrence identity in the interim.
645
+
646
+ Round-boss ownership is now explicit at that same run-local boundary. Each accepted `BossRecord`
647
+ retains the exact consumer-selected final owner: its singleton `BossFeature`, the one existing
648
+ same-diameter representative, its body-local turned step, or the groove that absorbs that step or
649
+ the profile-gate fallback. The occurrence's own geometry remains available even when the drawing
650
+ uses a consolidated owner. Ambiguous selection fails closed as `unexpectedly_missing`; it cannot be
651
+ certified by equal values, ordering, rendered labels, or topology identity.
652
+
653
+ `FaceLevel` and `RiserEvidence` occurrences now receive explicit `evidence_only` outcomes. This
654
+ follows the released provider manifest: both are role=`evidence`, deliberately absent from the
655
+ feature census, and consumed as shared substrate for Draftwright's correlated `StepLevelFeature`
656
+ height/shoulder projection. The aggregate face-level and riser families remain supported; the
657
+ outcome says only that each raw evidence record is not itself an independent inferred feature or
658
+ completeness requirement. It adds no Sheet word, IR adapter, drawing ink, or provider API.
659
+
584
660
  ## Recognisers 0.4.9 prepared frame boundary
585
661
 
586
662
  Draftwright's 0.4.9 boundary accepted `RiserEvidence` v2,
@@ -588,7 +664,7 @@ Draftwright's 0.4.9 boundary accepted `RiserEvidence` v2,
588
664
  same-solid levels and physical turned-profile membership in compounds. The fail-closed capability
589
665
  join rejects an older, future, missing, or malformed schema instead of treating it as equivalent.
590
666
 
591
- ADR 0020 adds `prepare_framed_detection`, the one Draftwright-owned intake for the public
667
+ ADR 3 (was 0020) adds `prepare_framed_detection`, the one Draftwright-owned intake for the public
592
668
  `prepare_framed_part` seam. A successful unit retains the caller-space source as provenance while
593
669
  pairing the exact local working solid, provider frame, prepared cylinders, Draftwright's local
594
670
  rotational classification, and aggregate. Classification reuses the prepared cylinder objects;
@@ -649,12 +725,12 @@ profile warning only for that occurrence, so an unrelated unrecognised profile r
649
725
 
650
726
  ## Passage compatibility boundary
651
727
 
652
- The installed `b123d-recognisers==0.4.8` release contains the `passages` family introduced
653
- in 0.2.6. Version 0.4.0 makes `SectionPassage` the authoritative physical output and retains
654
- schema-v1 `Passage` as its compatibility projection. Draftwright declares all six public and nested
655
- record schemas exhaustively but deliberately keeps the family `unsupported`, with the drafting
656
- decision recorded by issue #1245. This is a truthful consumer disposition: both aggregate
657
- inventories remain visible, but only authoritative `section_passages` contributes an explicitly
728
+ The installed `b123d-recognisers==0.4.14` release contains the `passages` family introduced
729
+ in 0.2.6. Version 0.4.0 made `SectionPassage` the authoritative physical output; 0.4.14 publishes
730
+ its nested schema v2 and retains `Passage` as a compatibility projection. Draftwright declares all
731
+ six public and nested record schemas exhaustively but deliberately keeps the family `unsupported`,
732
+ with the drafting decision recorded by issue #1245. This is a truthful consumer disposition: both
733
+ aggregate inventories remain visible, but only authoritative `section_passages` contributes an explicitly
658
734
  `unsupported` completeness requirement. Draftwright does not invent an IR feature, DSL
659
735
  declaration, generated code, or drawing annotation for either inventory.
660
736
 
@@ -667,7 +743,7 @@ The 0.4 contract is explicit:
667
743
  - rich split-junction passages can supersede a Slot claim, moving physical ownership to the
668
744
  unsupported Passage family through `SLOT_SUPERSEDED_BY_PASSAGE`.
669
745
 
670
- The exact 0.4.8 pin, manifest-v2 validator and explicit unsupported inventories make that limitation
746
+ The exact 0.4.14 pin, manifest-v2 validator and explicit unsupported inventories make that limitation
671
747
  fail-visible rather than silently treating rich passages as supported. Draftwright deliberately
672
748
  does not claim that a regular-polygon `HEX … A/F THRU` callout covers the complete line/arc section
673
749
  schema. Each authoritative `RecognitionResult.section_passages` occurrence therefore emits
@@ -40,6 +40,14 @@ refused at declaration and constraints are never silently relaxed. The immutable
40
40
  snapshot is available as `sheet.view_constraints`, while `drawing.view_plan` is the distinct
41
41
  resolved result.
42
42
 
43
+ Layout advisories are also available as structured findings from `Drawing.lint()` and
44
+ `lint(physical=False)`. `legibility_floor_breached` reports an explicit scale below the
45
+ legibility floor when a legible automatic fit exists; `page_fit_uncertain` reports an
46
+ unsuccessful layout fit; `layout_repack_stalled` reports unresolved measured-repack
47
+ triggers; and `scale_fallback_applied` reports a computed scale or a completeness-driven
48
+ scale fallback. These warnings contribute to the legibility component of `lint_summary()`.
49
+ A successful measured fit replaces the earlier estimated fit warning.
50
+
43
51
  ### Taking over a detected baseline
44
52
 
45
53
  `Sheet.from_part(part)` retains the detector's feature set and starts with implicit automatic
@@ -122,27 +130,35 @@ callout. More general ordered operation stacks remain tracked by issue #1360. Un
122
130
  requirement has a structured parameter, use a feature-linked `note(..., satisfies=(...))` only
123
131
  for parameter ids the handle actually exposes; free prose does not satisfy coverage.
124
132
 
125
- ### Convex Blend chains
133
+ ### Straight and circular Blend chains
126
134
 
127
- When recognition accepts a complete schema-v1 convex Blend chain that is not superseded by a
128
- dimension-worthy Fillet, it becomes one radius requirement. Declare the same meaning explicitly
129
- with the dedicated word:
135
+ When recognition accepts a complete schema-v3 straight or circular rolling-ball Blend path that is
136
+ not superseded by a dimension-worthy Fillet, it becomes one radius requirement. Declare the same
137
+ meaning explicitly with the dedicated word:
130
138
 
131
139
  ```python
132
140
  blend = sheet.blend(
133
- axis="z", # dominant component only
141
+ axis="z", # canonical dominant component (x/y/z tie-break)
134
142
  axis_direction=(0.321394, 0.383022, 0.866025),
135
143
  radius=0.2,
136
- at=(12.345, -4.5, 6.789), # physical leader anchor in part coordinates
144
+ at=(12.345, -4.5, 6.789), # straight anchor / circular centre in part coordinates
137
145
  side="convex",
138
146
  )
139
147
  sheet.dimension(blend, "blend.radius")
140
148
  ```
141
149
 
142
- `axis_direction` is authoritative and may be non-principal; it is preserved by generated Sheet
143
- code. `at` identifies feature geometry, not a page position. The annotation placement solve owns
144
- the final leader and label coordinates. The word is explicit-only because a detached cylindrical
145
- face cannot prove a complete chain or the provider aggregate's Fillet precedence.
150
+ For a straight path, `at` is a point on its analytic line and `axis_direction` is the canonical
151
+ line direction. A circular path uses `path_kind="circular"`, treats `at` as its centre and
152
+ `axis_direction` as its normal, and requires `path_radius=` for the centre-line circle's major
153
+ radius. `radius` remains the rolling-ball radius; `side` may be `"convex"` or `"concave"`.
154
+ `axis` must match the same first-maximum `x`/`y`/`z` tie-break used by automatic conversion, so an
155
+ explicit declaration has the same exact occurrence identity and view routing as its released
156
+ record.
157
+ Generated Sheet code preserves every field.
158
+
159
+ These are part-space feature coordinates, never page positions. The annotation placement solve
160
+ owns the final leader and label coordinates. The word is explicit-only because detached surface
161
+ geometry cannot prove a complete chain or the provider aggregate's Fillet precedence.
146
162
 
147
163
  ## View handle
148
164
 
@@ -281,3 +297,9 @@ drop, or missing ink is not hidden by the ownership choice.
281
297
  ::: draftwright.sheet._Control
282
298
  options:
283
299
  filters: public
300
+
301
+ Imported AP242 nominal-diameter ownership requires absolute agreement within `1e-6`
302
+ with the canonical feature diameter, using the same rule as planning. A larger mismatch
303
+ keeps the original source value and identity in a blocked dimension; it does not replace
304
+ the canonical value or crash planning. Generated Sheet scripts retain the blocker, and
305
+ `authored_dim_source_unresolved` reports the withheld source dimension through lint.
@@ -77,17 +77,17 @@ discovery does not invent them.
77
77
 
78
78
  ## ADR Fit
79
79
 
80
- - **ADR 0013:** the proven repeat is lower-tier, geometry-only evidence. `gear` is an
80
+ - **ADR 3 (was 0013):** the proven repeat is lower-tier, geometry-only evidence. `gear` is an
81
81
  application semantic and must not be smuggled into the recognition record.
82
- - **ADR 0015:** any future automatic record must enter through the compiler's existing
82
+ - **ADR 1 (was 0015):** any future automatic record must enter through the compiler's existing
83
83
  recognition waist. A declared gear requirement belongs on the declared path.
84
- - **ADR 0017:** if productionised, one orchestration owns the correspondence evidence and
84
+ - **ADR 3 (was 0017):** if productionised, one orchestration owns the correspondence evidence and
85
85
  consumers project from it. The mutation precedes trust in the guard, and a new identity
86
86
  scheme is not justified by this single case.
87
- - **ADR 0011:** explicit author intent is the appropriate source for requirements that the
87
+ - **ADR 4 (was 0011):** explicit author intent is the appropriate source for requirements that the
88
88
  B-rep cannot establish.
89
89
 
90
- No ADR amendment is required. No placement decision is made, so ADR 0014 is unaffected.
90
+ No ADR amendment is required. No placement decision is made, so ADR 2 (was 0014) is unaffected.
91
91
 
92
92
  ## Follow-up Slices
93
93
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "draftwright"
7
- version = "0.4.17"
7
+ version = "0.4.19"
8
8
  description = "Automated technical-drawing generation for build123d"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -18,7 +18,7 @@ dependencies = [
18
18
  "build123d>=0.9.0,<0.11 ; python_full_version < '3.13'",
19
19
  "build123d>=0.11,<0.12 ; python_full_version >= '3.13'",
20
20
  "build123d-drafting-helpers>=0.14.2",
21
- "b123d-recognisers==0.4.12",
21
+ "b123d-recognisers==0.4.14",
22
22
  "numpy>=1.24",
23
23
  # PNG raster export (SVG→PDF→PNG). Both permissively licensed (Pillow HPND; pypdfium2
24
24
  # Apache-2.0 wrapping Google PDFium BSD-3) and ship pre-built wheels with NO native system
@@ -162,12 +162,15 @@ docs = [
162
162
  dev = [
163
163
  "codespell>=2.3.0",
164
164
  "hypothesis>=6",
165
+ "jsonschema>=4,<5",
165
166
  "mypy>=2.1.0",
166
167
  "pytest>=8",
167
168
  "pytest-cov>=5",
168
169
  "pytest-split>=0.8",
169
170
  "pytest-timeout>=2",
170
171
  "pytest-xdist>=3",
172
+ # Released provider used by the migration parity tests; production remains on 0.4.14.
173
+ "quiddity==0.2.1",
171
174
  "ruff>=0.4",
172
175
  "tomli>=2; python_version < '3.11'",
173
176
  ]