python-hwpx 3.3.0__tar.gz → 3.3.1__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 (340) hide show
  1. {python_hwpx-3.3.0/src/python_hwpx.egg-info → python_hwpx-3.3.1}/PKG-INFO +2 -2
  2. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/README.md +1 -1
  3. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/pyproject.toml +1 -1
  4. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/agent/blueprint/model.py +103 -7
  5. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/package_validator.py +325 -226
  6. {python_hwpx-3.3.0 → python_hwpx-3.3.1/src/python_hwpx.egg-info}/PKG-INFO +2 -2
  7. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/LICENSE +0 -0
  8. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/NOTICE +0 -0
  9. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/setup.cfg +0 -0
  10. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/__init__.py +0 -0
  11. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/agent/__init__.py +0 -0
  12. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/agent/blueprint/__init__.py +0 -0
  13. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/agent/blueprint/bundle.py +0 -0
  14. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/agent/blueprint/catalog.py +0 -0
  15. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/agent/blueprint/dump.py +0 -0
  16. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/agent/blueprint/mapping.py +0 -0
  17. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/agent/blueprint/native.py +0 -0
  18. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/agent/blueprint/replay.py +0 -0
  19. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/agent/catalog.py +0 -0
  20. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/agent/cli.py +0 -0
  21. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/agent/commands.py +0 -0
  22. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/agent/document.py +0 -0
  23. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/agent/form_plan.py +0 -0
  24. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/agent/model.py +0 -0
  25. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/agent/path.py +0 -0
  26. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/agent/query.py +0 -0
  27. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/agent/story.py +0 -0
  28. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/authoring.py +0 -0
  29. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/benchmark/__init__.py +0 -0
  30. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/benchmark/blind_eval.py +0 -0
  31. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/body_patch.py +0 -0
  32. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/builder/__init__.py +0 -0
  33. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/builder/core.py +0 -0
  34. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/builder/report.py +0 -0
  35. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/conformance/__init__.py +0 -0
  36. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/conformance/badges.py +0 -0
  37. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/conformance/corpus/corpus.json +0 -0
  38. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/conformance/corpus/meeting_summary.hwpx +0 -0
  39. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/conformance/corpus/notice.hwpx +0 -0
  40. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/conformance/corpus/report_table.hwpx +0 -0
  41. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/conformance/corpus.py +0 -0
  42. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/conformance/report.py +0 -0
  43. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/conformance/roundtrip_batch.py +0 -0
  44. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/conformance/runner.py +0 -0
  45. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/data/Skeleton.hwpx +0 -0
  46. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/__init__.py +0 -0
  47. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/_support.py +0 -0
  48. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/composer.py +0 -0
  49. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/harvest.py +0 -0
  50. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/plan.py +0 -0
  51. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profile.py +0 -0
  52. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/application_form/fragments/body.xml +0 -0
  53. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/application_form/fragments/heading.xml +0 -0
  54. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/application_form/fragments/info_table.xml +0 -0
  55. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/application_form/fragments/title.xml +0 -0
  56. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/application_form/profile.json +0 -0
  57. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/application_form/template.hwpx +0 -0
  58. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/home_notice/fragments/body.xml +0 -0
  59. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/home_notice/fragments/heading.xml +0 -0
  60. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/home_notice/fragments/title.xml +0 -0
  61. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/home_notice/profile.json +0 -0
  62. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/home_notice/template.hwpx +0 -0
  63. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/official_notice/fragments/body.xml +0 -0
  64. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/official_notice/fragments/heading.xml +0 -0
  65. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/official_notice/fragments/info_table.xml +0 -0
  66. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/official_notice/fragments/title.xml +0 -0
  67. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/official_notice/profile.json +0 -0
  68. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/official_notice/template.hwpx +0 -0
  69. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/report/fragments/body.xml +0 -0
  70. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/report/fragments/heading.xml +0 -0
  71. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/report/fragments/info_table.xml +0 -0
  72. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/report/fragments/title.xml +0 -0
  73. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/report/profile.json +0 -0
  74. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/profiles/report/template.hwpx +0 -0
  75. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/design/validator.py +0 -0
  76. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/document.py +0 -0
  77. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/evalplan_fill.py +0 -0
  78. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/exam/__init__.py +0 -0
  79. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/exam/compose.py +0 -0
  80. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/exam/ir.py +0 -0
  81. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/exam/measure.py +0 -0
  82. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/exam/parser.py +0 -0
  83. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/exam/profile.py +0 -0
  84. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/fill_residue.py +0 -0
  85. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/form_fill.py +0 -0
  86. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/form_fit/__init__.py +0 -0
  87. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/form_fit/apply.py +0 -0
  88. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/form_fit/engine.py +0 -0
  89. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/form_fit/measure.py +0 -0
  90. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/form_fit/policy.py +0 -0
  91. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/form_fit/report.py +0 -0
  92. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/form_fit/seal.py +0 -0
  93. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/form_fit/wordbox.py +0 -0
  94. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/formfill_quality.py +0 -0
  95. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/guidance_scan.py +0 -0
  96. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/ingest/__init__.py +0 -0
  97. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/ingest/base.py +0 -0
  98. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/ingest/hwpx_converter.py +0 -0
  99. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/layout/__init__.py +0 -0
  100. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/layout/lint.py +0 -0
  101. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/layout/report.py +0 -0
  102. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/opc/package.py +0 -0
  103. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/opc/relationships.py +0 -0
  104. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/opc/security.py +0 -0
  105. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/opc/xml_utils.py +0 -0
  106. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/__init__.py +0 -0
  107. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/_document_impl.py +0 -0
  108. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/_document_primitives.py +0 -0
  109. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/body.py +0 -0
  110. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/canonical_defaults.py +0 -0
  111. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/common.py +0 -0
  112. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/document.py +0 -0
  113. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/document_parts.py +0 -0
  114. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/header.py +0 -0
  115. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/header_part.py +0 -0
  116. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/memo.py +0 -0
  117. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/namespaces.py +0 -0
  118. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/numbering.py +0 -0
  119. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/objects.py +0 -0
  120. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/paragraph.py +0 -0
  121. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/parser.py +0 -0
  122. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/run.py +0 -0
  123. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/schema.py +0 -0
  124. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/section.py +0 -0
  125. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/section_format.py +0 -0
  126. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/section_story.py +0 -0
  127. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/simple_parts.py +0 -0
  128. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/table.py +0 -0
  129. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/oxml/utils.py +0 -0
  130. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/package.py +0 -0
  131. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/patch.py +0 -0
  132. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/presets/__init__.py +0 -0
  133. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/presets/proposal.py +0 -0
  134. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/py.typed +0 -0
  135. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/quality/__init__.py +0 -0
  136. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/quality/ledger.py +0 -0
  137. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/quality/policy.py +0 -0
  138. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/quality/report.py +0 -0
  139. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/quality/save_pipeline.py +0 -0
  140. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/table_patch.py +0 -0
  141. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/template_formfit.py +0 -0
  142. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/templates.py +0 -0
  143. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/__init__.py +0 -0
  144. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/_schemas/header.xsd +0 -0
  145. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/_schemas/section.xsd +0 -0
  146. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/advanced_generators.py +0 -0
  147. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/archive_cli.py +0 -0
  148. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/doc_diff.py +0 -0
  149. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/exporter.py +0 -0
  150. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/fuzz/__init__.py +0 -0
  151. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/fuzz/__main__.py +0 -0
  152. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/fuzz/catalog.py +0 -0
  153. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/fuzz/generator.py +0 -0
  154. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/fuzz/minimize.py +0 -0
  155. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/fuzz/runner.py +0 -0
  156. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/generic_inventory.py +0 -0
  157. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/id_integrity.py +0 -0
  158. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/idempotence.py +0 -0
  159. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/ir_equality.py +0 -0
  160. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/layout_preview.py +0 -0
  161. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/mail_merge.py +0 -0
  162. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/markdown_export.py +0 -0
  163. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/object_finder.py +0 -0
  164. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/official_lint.py +0 -0
  165. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/package_reconcile.py +0 -0
  166. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/page_guard.py +0 -0
  167. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/pii.py +0 -0
  168. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/read_fidelity.py +0 -0
  169. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/recover.py +0 -0
  170. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/redline.py +0 -0
  171. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/repair.py +0 -0
  172. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/report_parser.py +0 -0
  173. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/report_utils.py +0 -0
  174. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/roundtrip_diff.py +0 -0
  175. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/style_profile.py +0 -0
  176. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/table_cleanup.py +0 -0
  177. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/table_compute.py +0 -0
  178. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/table_navigation.py +0 -0
  179. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/template_analyzer.py +0 -0
  180. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/text_extract_cli.py +0 -0
  181. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/text_extractor.py +0 -0
  182. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/toc_author.py +0 -0
  183. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/toc_fidelity.py +0 -0
  184. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/tools/validator.py +0 -0
  185. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/visual/__init__.py +0 -0
  186. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/visual/_hancom_open_rate.ps1 +0 -0
  187. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/visual/_refresh_hwpx_mac.applescript +0 -0
  188. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/visual/_render_hwpx.ps1 +0 -0
  189. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/visual/_render_hwpx_mac.applescript +0 -0
  190. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/visual/detectors.py +0 -0
  191. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/visual/diff.py +0 -0
  192. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/visual/fixture_corpus.py +0 -0
  193. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/visual/hancom_worker.py +0 -0
  194. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/visual/masks.py +0 -0
  195. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/visual/oracle.py +0 -0
  196. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/visual/page_qa.py +0 -0
  197. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/visual/qa_contracts.py +0 -0
  198. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/visual/qa_metrics.py +0 -0
  199. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/hwpx/visual/report.py +0 -0
  200. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/python_hwpx.egg-info/SOURCES.txt +0 -0
  201. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/python_hwpx.egg-info/dependency_links.txt +0 -0
  202. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/python_hwpx.egg-info/entry_points.txt +0 -0
  203. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/python_hwpx.egg-info/requires.txt +0 -0
  204. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/src/python_hwpx.egg-info/top_level.txt +0 -0
  205. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_advanced_generators.py +0 -0
  206. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_agent_blueprint_contracts.py +0 -0
  207. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_agent_blueprint_dump.py +0 -0
  208. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_agent_blueprint_replay.py +0 -0
  209. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_agent_catalog.py +0 -0
  210. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_agent_cli.py +0 -0
  211. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_agent_commands.py +0 -0
  212. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_agent_contracts.py +0 -0
  213. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_agent_document.py +0 -0
  214. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_agent_mixed_form.py +0 -0
  215. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_agent_path_query.py +0 -0
  216. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_agent_story_commands.py +0 -0
  217. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_authoring_profile_routing.py +0 -0
  218. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_authoring_profile_routing_oracle.py +0 -0
  219. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_authoring_render_check.py +0 -0
  220. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_blind_eval_fixture.py +0 -0
  221. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_body_patch.py +0 -0
  222. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_builder_core.py +0 -0
  223. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_builder_plan_v2.py +0 -0
  224. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_builder_vertical_slice.py +0 -0
  225. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_cell_line_spacing.py +0 -0
  226. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_comment_node_robustness.py +0 -0
  227. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_conformance.py +0 -0
  228. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_corpus_read_fidelity.py +0 -0
  229. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_coverage_promotion.py +0 -0
  230. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_coverage_targets.py +0 -0
  231. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_design_builder.py +0 -0
  232. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_deviations_registry.py +0 -0
  233. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_doc_diff.py +0 -0
  234. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_document_context_manager.py +0 -0
  235. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_document_formatting.py +0 -0
  236. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_document_plan.py +0 -0
  237. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_document_plan_computed_fields.py +0 -0
  238. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_document_save_api.py +0 -0
  239. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_evalplan_fill.py +0 -0
  240. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_exam_compose.py +0 -0
  241. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_exam_compose_oracle.py +0 -0
  242. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_exam_fixtures.py +0 -0
  243. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_exam_ir.py +0 -0
  244. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_exam_measure.py +0 -0
  245. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_exam_parser.py +0 -0
  246. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_exam_profile.py +0 -0
  247. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_existing_document_format_editing.py +0 -0
  248. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_fill_residue.py +0 -0
  249. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_form_fields.py +0 -0
  250. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_form_fill_split_run.py +0 -0
  251. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_form_fit.py +0 -0
  252. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_form_fit_integration.py +0 -0
  253. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_form_fit_seal.py +0 -0
  254. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_form_fit_seal_placement.py +0 -0
  255. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_form_fit_wordbox.py +0 -0
  256. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_formfill_quality.py +0 -0
  257. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_fuzz_loop.py +0 -0
  258. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_fuzz_regressions.py +0 -0
  259. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_gap_closure_tools.py +0 -0
  260. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_government_report_preset.py +0 -0
  261. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_government_table_profile.py +0 -0
  262. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_guidance_scan.py +0 -0
  263. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_hancom_render_worker.py +0 -0
  264. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_hp_tab_support.py +0 -0
  265. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_hwpxlib_corpus_read.py +0 -0
  266. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_id_generator_range.py +0 -0
  267. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_id_integrity.py +0 -0
  268. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_image_object_workflow.py +0 -0
  269. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_ingest.py +0 -0
  270. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_inline_models.py +0 -0
  271. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_integration_hwpx_compatibility.py +0 -0
  272. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_integration_roundtrip.py +0 -0
  273. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_kordoc_absorption.py +0 -0
  274. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_layout_lint.py +0 -0
  275. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_layout_preview.py +0 -0
  276. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_mail_merge_fit.py +0 -0
  277. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_mail_merge_table_compute.py +0 -0
  278. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_mail_merge_xlsx.py +0 -0
  279. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_markdown_export.py +0 -0
  280. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_memo_and_style_editing.py +0 -0
  281. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_mixed_form_plan.py +0 -0
  282. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_namespace_handling.py +0 -0
  283. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_new_features.py +0 -0
  284. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_official_document_style.py +0 -0
  285. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_official_lint_gongmun_gate.py +0 -0
  286. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_official_lint_tableaware.py +0 -0
  287. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_opc_package.py +0 -0
  288. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_open_safety_corpus.py +0 -0
  289. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_openrate.py +0 -0
  290. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_oxml_modularization.py +0 -0
  291. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_oxml_parsing.py +0 -0
  292. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_packaging_license_metadata.py +0 -0
  293. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_packaging_py_typed.py +0 -0
  294. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_paragraph_keep_together.py +0 -0
  295. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_paragraph_section_management.py +0 -0
  296. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_pii.py +0 -0
  297. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_pii_structural.py +0 -0
  298. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_pii_wiring.py +0 -0
  299. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_proposal_preset.py +0 -0
  300. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_public_runtime_boundary.py +0 -0
  301. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_question_split_detector.py +0 -0
  302. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_read_fidelity.py +0 -0
  303. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_recover_broken_zip.py +0 -0
  304. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_redline_authoring.py +0 -0
  305. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_redline_verify.py +0 -0
  306. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_repair_repack.py +0 -0
  307. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_report_parser.py +0 -0
  308. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_report_utils.py +0 -0
  309. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_repr_snapshots.py +0 -0
  310. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_rhwp_t1_gates.py +0 -0
  311. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_rhwp_t2_verification.py +0 -0
  312. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_roundtrip_fidelity.py +0 -0
  313. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_row_heights.py +0 -0
  314. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_save_pipeline.py +0 -0
  315. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_save_pipeline_no_bypass.py +0 -0
  316. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_section_headers.py +0 -0
  317. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_set_paragraph_format_keep.py +0 -0
  318. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_skeleton_template_ids.py +0 -0
  319. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_split_cell.py +0 -0
  320. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_split_merged_cell.py +0 -0
  321. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_style_profile.py +0 -0
  322. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_table_cleanup.py +0 -0
  323. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_table_navigation.py +0 -0
  324. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_table_patch.py +0 -0
  325. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_table_patch_dryrun.py +0 -0
  326. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_table_patch_m105.py +0 -0
  327. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_tables_default_border.py +0 -0
  328. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_template_analyzer_enrichment.py +0 -0
  329. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_template_formfit.py +0 -0
  330. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_text_extractor_annotations.py +0 -0
  331. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_toc_author.py +0 -0
  332. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_toc_fidelity.py +0 -0
  333. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_validation_severity.py +0 -0
  334. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_validator_comment_nodes.py +0 -0
  335. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_version_metadata.py +0 -0
  336. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_visual_fixture_corpus.py +0 -0
  337. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_visual_oracle.py +0 -0
  338. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_visual_oracle_budget.py +0 -0
  339. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_visual_qa_contracts.py +0 -0
  340. {python_hwpx-3.3.0 → python_hwpx-3.3.1}/tests/test_visual_qa_metrics.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-hwpx
3
- Version: 3.3.0
3
+ Version: 3.3.1
4
4
  Summary: 한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 자동화 라이브러리
5
5
  Author: python-hwpx Maintainers
6
6
  License-Expression: Apache-2.0
@@ -70,7 +70,7 @@ Dynamic: license-file
70
70
  `hwpx-mcp-server`와 `hwpx-plugin`은 같은 프로젝트가 직접 유지보수하는 first-party 연동 구성요소입니다.
71
71
  “first-party”는 프로젝트 유지보수 관계를 뜻하며, 한컴 또는 제3자의 공식 인증을 뜻하지 않습니다.
72
72
 
73
- 현재 PyPI 공개 릴리스는 `python-hwpx 3.3.0`입니다. 일반
73
+ 현재 PyPI 공개 릴리스는 `python-hwpx 3.3.1`입니다. 일반
74
74
  `pip install python-hwpx`로 이 릴리스를 설치할 수 있습니다.
75
75
  현재 패키지 분류는 `Development Status :: 3 - Alpha`입니다. 이 분류는 API와 제품의
76
76
  성숙도를 나타내며, 공개 버전이나 플러그인의 최소 호환 버전을 대신하지 않습니다.
@@ -25,7 +25,7 @@
25
25
  `hwpx-mcp-server`와 `hwpx-plugin`은 같은 프로젝트가 직접 유지보수하는 first-party 연동 구성요소입니다.
26
26
  “first-party”는 프로젝트 유지보수 관계를 뜻하며, 한컴 또는 제3자의 공식 인증을 뜻하지 않습니다.
27
27
 
28
- 현재 PyPI 공개 릴리스는 `python-hwpx 3.3.0`입니다. 일반
28
+ 현재 PyPI 공개 릴리스는 `python-hwpx 3.3.1`입니다. 일반
29
29
  `pip install python-hwpx`로 이 릴리스를 설치할 수 있습니다.
30
30
  현재 패키지 분류는 `Development Status :: 3 - Alpha`입니다. 이 분류는 API와 제품의
31
31
  성숙도를 나타내며, 공개 버전이나 플러그인의 최소 호환 버전을 대신하지 않습니다.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "python-hwpx"
7
- version = "3.3.0"
7
+ version = "3.3.1"
8
8
  description = "한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 자동화 라이브러리"
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  license = "Apache-2.0"
@@ -242,10 +242,7 @@ def _validate_resource(value: object, *, name: str) -> dict[str, Any]:
242
242
  return record
243
243
 
244
244
 
245
- def validate_blueprint_manifest(value: Mapping[str, Any], *, verify_hash: bool = True) -> dict[str, Any]:
246
- """Validate and detach one strict ``hwpx.agent-blueprint/v1`` manifest."""
247
-
248
- manifest = _object(value, "blueprint")
245
+ def _validate_manifest_header(manifest: dict[str, Any]) -> None:
249
246
  _exact_keys(manifest, required=_MANIFEST_KEYS, name="blueprint")
250
247
  if manifest["schemaVersion"] != BLUEPRINT_SCHEMA:
251
248
  raise AgentContractError("invalid_syntax", "unsupported blueprint schema", target="schemaVersion")
@@ -257,12 +254,16 @@ def validate_blueprint_manifest(value: Mapping[str, Any], *, verify_hash: bool =
257
254
  if mode not in BLUEPRINT_MODES:
258
255
  raise AgentContractError("invalid_syntax", "unsupported blueprint mode", target="mode")
259
256
 
257
+
258
+ def _validate_source(manifest: dict[str, Any]) -> None:
260
259
  source = _object(manifest["source"], "source")
261
260
  _exact_keys(source, required={"revision", "label"}, name="source")
262
261
  if not REVISION_PATTERN.fullmatch(str(source["revision"])):
263
262
  raise AgentContractError("invalid_syntax", "source.revision must be sha256", target="source.revision")
264
263
  _validate_public_json(source, name="source")
265
264
 
265
+
266
+ def _validate_root(manifest: dict[str, Any]) -> dict[str, Any]:
266
267
  root = _object(manifest["root"], "root")
267
268
  _exact_keys(
268
269
  root,
@@ -275,7 +276,12 @@ def validate_blueprint_manifest(value: Mapping[str, Any], *, verify_hash: bool =
275
276
  raise AgentContractError("unknown_kind", "root kind is unknown", target="root.kind")
276
277
  if not str(root["sourcePath"]).startswith("/"):
277
278
  raise AgentContractError("invalid_syntax", "root sourcePath must be semantic", target="root.sourcePath")
279
+ return root
280
+
278
281
 
282
+ def _validate_nodes(
283
+ manifest: dict[str, Any],
284
+ ) -> tuple[list[dict[str, Any]], set[str], dict[str, dict[str, Any]]]:
279
285
  nodes = _list(manifest["nodes"], "nodes")
280
286
  if not nodes or len(nodes) > MAX_BLUEPRINT_NODES:
281
287
  raise AgentContractError("resource_limit", "node count is outside limits", target="nodes")
@@ -321,7 +327,15 @@ def validate_blueprint_manifest(value: Mapping[str, Any], *, verify_hash: bool =
321
327
  _validate_public_json(node["sourceHint"], name=f"{name}.sourceHint")
322
328
  detached_nodes.append(node)
323
329
  nodes_by_id[node_id] = node
330
+ return detached_nodes, node_ids, nodes_by_id
331
+
324
332
 
333
+ def _check_node_tree_shape(
334
+ root: dict[str, Any],
335
+ detached_nodes: list[dict[str, Any]],
336
+ node_ids: set[str],
337
+ nodes_by_id: dict[str, dict[str, Any]],
338
+ ) -> str:
325
339
  if str(root["blueprintId"]) not in node_ids:
326
340
  raise AgentContractError("invariant_violation", "root does not reference a node", target="root")
327
341
  for index, node in enumerate(detached_nodes):
@@ -344,6 +358,14 @@ def validate_blueprint_manifest(value: Mapping[str, Any], *, verify_hash: bool =
344
358
  raise AgentContractError(
345
359
  "invariant_violation", "blueprint nodes must form one rooted tree", target="nodes"
346
360
  )
361
+ return root_id
362
+
363
+
364
+ def _check_node_reachability(
365
+ root_id: str,
366
+ node_ids: set[str],
367
+ nodes_by_id: dict[str, dict[str, Any]],
368
+ ) -> None:
347
369
  visited: set[str] = set()
348
370
  visiting: set[str] = set()
349
371
 
@@ -364,6 +386,10 @@ def validate_blueprint_manifest(value: Mapping[str, Any], *, verify_hash: bool =
364
386
  if visited != node_ids:
365
387
  raise AgentContractError("invariant_violation", "blueprint contains orphan nodes", target="nodes")
366
388
 
389
+
390
+ def _validate_dependency_records(
391
+ manifest: dict[str, Any],
392
+ ) -> tuple[list[dict[str, Any]], list[dict[str, Any]], list[dict[str, Any]]]:
367
393
  styles = _list(manifest["styles"], "styles")
368
394
  numbering = _list(manifest["numbering"], "numbering")
369
395
  resources = _list(manifest["resources"], "resources")
@@ -382,6 +408,14 @@ def validate_blueprint_manifest(value: Mapping[str, Any], *, verify_hash: bool =
382
408
  detached_resources = [
383
409
  _validate_resource(item, name=f"resources[{index}]") for index, item in enumerate(resources)
384
410
  ]
411
+ return detached_styles, detached_numbering, detached_resources
412
+
413
+
414
+ def _check_dependency_uniqueness(
415
+ detached_styles: list[dict[str, Any]],
416
+ detached_numbering: list[dict[str, Any]],
417
+ detached_resources: list[dict[str, Any]],
418
+ ) -> list[str]:
385
419
  style_keys = [str(item["key"]) for item in detached_styles]
386
420
  numbering_keys = [str(item["key"]) for item in detached_numbering]
387
421
  resource_keys = [str(item["key"]) for item in detached_resources]
@@ -393,10 +427,18 @@ def validate_blueprint_manifest(value: Mapping[str, Any], *, verify_hash: bool =
393
427
  raise AgentContractError("invariant_violation", "resource asset paths must be unique", target="resources")
394
428
  if sum(int(item["size"]) for item in detached_resources) > MAX_TOTAL_ASSET_BYTES:
395
429
  raise AgentContractError("resource_limit", "total asset bytes exceed limit", target="resources")
430
+ return dependency_keys
431
+
396
432
 
397
- style_key_set = set(style_keys)
398
- numbering_key_set = set(numbering_keys)
399
- resource_key_set = set(resource_keys)
433
+ def _check_node_dependency_refs(
434
+ detached_nodes: list[dict[str, Any]],
435
+ detached_styles: list[dict[str, Any]],
436
+ detached_numbering: list[dict[str, Any]],
437
+ detached_resources: list[dict[str, Any]],
438
+ ) -> None:
439
+ style_key_set = {str(item["key"]) for item in detached_styles}
440
+ numbering_key_set = {str(item["key"]) for item in detached_numbering}
441
+ resource_key_set = {str(item["key"]) for item in detached_resources}
400
442
  for index, node in enumerate(detached_nodes):
401
443
  if not set(node["styleRefs"]) <= style_key_set:
402
444
  raise AgentContractError("invariant_violation", "node has an orphan style reference", target=f"nodes[{index}].styleRefs")
@@ -405,6 +447,12 @@ def validate_blueprint_manifest(value: Mapping[str, Any], *, verify_hash: bool =
405
447
  if not set(node["resourceRefs"]) <= resource_key_set:
406
448
  raise AgentContractError("invariant_violation", "node has an orphan resource reference", target=f"nodes[{index}].resourceRefs")
407
449
 
450
+
451
+ def _validate_reference_records(
452
+ manifest: dict[str, Any],
453
+ node_ids: set[str],
454
+ dependency_keys: list[str],
455
+ ) -> tuple[list[dict[str, Any]], dict[str, list[str]]]:
408
456
  references = _list(manifest["references"], "references")
409
457
  if len(references) > MAX_REFERENCES:
410
458
  raise AgentContractError("resource_limit", "reference count exceeds limit", target="references")
@@ -423,6 +471,13 @@ def validate_blueprint_manifest(value: Mapping[str, Any], *, verify_hash: bool =
423
471
  if target in node_ids:
424
472
  reference_edges[str(record["from"])].append(target)
425
473
  reference_records.append(record)
474
+ return reference_records, reference_edges
475
+
476
+
477
+ def _check_reference_inventory(
478
+ detached_nodes: list[dict[str, Any]],
479
+ reference_records: list[dict[str, Any]],
480
+ ) -> None:
426
481
  for index, node in enumerate(detached_nodes):
427
482
  declared_fields = {
428
483
  str(record["field"])
@@ -431,6 +486,12 @@ def validate_blueprint_manifest(value: Mapping[str, Any], *, verify_hash: bool =
431
486
  }
432
487
  if set(node["references"]) != declared_fields:
433
488
  raise AgentContractError("invariant_violation", "node reference inventory is inconsistent", target=f"nodes[{index}].references")
489
+
490
+
491
+ def _check_reference_acyclicity(
492
+ node_ids: set[str],
493
+ reference_edges: dict[str, list[str]],
494
+ ) -> None:
434
495
  reference_visited: set[str] = set()
435
496
  reference_visiting: set[str] = set()
436
497
 
@@ -448,6 +509,8 @@ def validate_blueprint_manifest(value: Mapping[str, Any], *, verify_hash: bool =
448
509
  for node_id in sorted(node_ids):
449
510
  visit_reference(node_id)
450
511
 
512
+
513
+ def _validate_metadata_sections(manifest: dict[str, Any]) -> list[Any]:
451
514
  unsupported = _list(manifest["unsupported"], "unsupported")
452
515
  for index, item in enumerate(unsupported):
453
516
  record = _object(item, f"unsupported[{index}]")
@@ -471,7 +534,10 @@ def validate_blueprint_manifest(value: Mapping[str, Any], *, verify_hash: bool =
471
534
  if fidelity["ceiling"] not in FIDELITY_LEVELS:
472
535
  raise AgentContractError("invalid_syntax", "fidelity ceiling is invalid", target="fidelity.ceiling")
473
536
  fidelity["reasons"] = [str(item) for item in _list(fidelity["reasons"], "fidelity.reasons")]
537
+ return unsupported
474
538
 
539
+
540
+ def _verify_manifest_integrity(manifest: dict[str, Any], verify_hash: bool) -> None:
475
541
  _validate_public_json(manifest, name="blueprint")
476
542
  declared_hash = manifest["blueprintHash"]
477
543
  if not SHA256_PATTERN.fullmatch(str(declared_hash)):
@@ -479,6 +545,36 @@ def validate_blueprint_manifest(value: Mapping[str, Any], *, verify_hash: bool =
479
545
  if verify_hash and declared_hash != blueprint_hash(manifest):
480
546
  raise AgentContractError("verification_failed", "blueprintHash mismatch", target="blueprintHash")
481
547
  canonical_manifest_bytes(manifest, include_hash=True)
548
+
549
+
550
+ def validate_blueprint_manifest(value: Mapping[str, Any], *, verify_hash: bool = True) -> dict[str, Any]:
551
+ """Validate and detach one strict ``hwpx.agent-blueprint/v1`` manifest."""
552
+
553
+ manifest = _object(value, "blueprint")
554
+ _validate_manifest_header(manifest)
555
+ _validate_source(manifest)
556
+ root = _validate_root(manifest)
557
+
558
+ detached_nodes, node_ids, nodes_by_id = _validate_nodes(manifest)
559
+ root_id = _check_node_tree_shape(root, detached_nodes, node_ids, nodes_by_id)
560
+ _check_node_reachability(root_id, node_ids, nodes_by_id)
561
+
562
+ detached_styles, detached_numbering, detached_resources = _validate_dependency_records(manifest)
563
+ dependency_keys = _check_dependency_uniqueness(
564
+ detached_styles, detached_numbering, detached_resources
565
+ )
566
+ _check_node_dependency_refs(
567
+ detached_nodes, detached_styles, detached_numbering, detached_resources
568
+ )
569
+
570
+ reference_records, reference_edges = _validate_reference_records(
571
+ manifest, node_ids, dependency_keys
572
+ )
573
+ _check_reference_inventory(detached_nodes, reference_records)
574
+ _check_reference_acyclicity(node_ids, reference_edges)
575
+
576
+ unsupported = _validate_metadata_sections(manifest)
577
+ _verify_manifest_integrity(manifest, verify_hash)
482
578
  return {
483
579
  **manifest,
484
580
  "nodes": detached_nodes,