spolvero 0.4.0__tar.gz → 0.6.0__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 (174) hide show
  1. {spolvero-0.4.0 → spolvero-0.6.0}/.github/instructions/spolvero.instructions.md +2 -0
  2. {spolvero-0.4.0 → spolvero-0.6.0}/.github/workflows/ci.yml +25 -8
  3. {spolvero-0.4.0 → spolvero-0.6.0}/.github/workflows/codeql.yml +1 -1
  4. {spolvero-0.4.0 → spolvero-0.6.0}/.github/workflows/dependency-review.yml +2 -2
  5. {spolvero-0.4.0 → spolvero-0.6.0}/.github/workflows/release.yml +25 -1
  6. {spolvero-0.4.0 → spolvero-0.6.0}/.gitignore +1 -0
  7. {spolvero-0.4.0 → spolvero-0.6.0}/HANDOFF.md +22 -12
  8. spolvero-0.6.0/LICENSE +21 -0
  9. {spolvero-0.4.0 → spolvero-0.6.0}/PKG-INFO +72 -15
  10. {spolvero-0.4.0 → spolvero-0.6.0}/README.md +69 -13
  11. spolvero-0.6.0/adapters/claude/.claude/skills/spolvero-roundtrip/SKILL.md +56 -0
  12. {spolvero-0.4.0 → spolvero-0.6.0}/adapters/copilot/.github/instructions/spolvero.instructions.md +2 -0
  13. {spolvero-0.4.0 → spolvero-0.6.0}/docs/agents/recipes.md +13 -0
  14. spolvero-0.6.0/docs/artifact-governance.md +151 -0
  15. spolvero-0.6.0/docs/consumer-ci-recipe.md +213 -0
  16. {spolvero-0.4.0 → spolvero-0.6.0}/docs/current-state.md +26 -6
  17. {spolvero-0.4.0 → spolvero-0.6.0}/docs/declaratus-migration.md +5 -7
  18. spolvero-0.6.0/docs/demos/round-trip/README.md +244 -0
  19. spolvero-0.6.0/docs/demos/round-trip/accepted/diagram-001.layout.yml +36 -0
  20. spolvero-0.6.0/docs/demos/round-trip/accepted/drift.json +10 -0
  21. spolvero-0.6.0/docs/demos/round-trip/accepted/drift.md +11 -0
  22. spolvero-0.6.0/docs/demos/round-trip/rejected/drift.json +27 -0
  23. spolvero-0.6.0/docs/demos/round-trip/rejected/drift.md +23 -0
  24. spolvero-0.6.0/docs/plans/03-connector-endpoint-drift.md +264 -0
  25. spolvero-0.6.0/docs/plans/04-container-stamping-and-multi-diagram-patches.md +205 -0
  26. spolvero-0.6.0/docs/plans/05-manual-annotations.md +131 -0
  27. spolvero-0.6.0/docs/releases/0.6.0.md +48 -0
  28. spolvero-0.6.0/docs/research/artifact-governance.md +272 -0
  29. spolvero-0.6.0/docs/round-trip-workflow.md +161 -0
  30. {spolvero-0.4.0 → spolvero-0.6.0}/docs/specs/01-round-trip-drift-engine.md +1 -1
  31. spolvero-0.6.0/docs/specs/02-visio-diagram-handoff-assistant-skill.md +125 -0
  32. spolvero-0.6.0/docs/specs/03-connector-endpoint-drift.md +194 -0
  33. spolvero-0.6.0/docs/specs/04-container-stamping-and-multi-diagram-patches.md +269 -0
  34. spolvero-0.6.0/docs/specs/05-manual-annotations.md +210 -0
  35. {spolvero-0.4.0 → spolvero-0.6.0}/docs/vsdx-template-contract.md +10 -6
  36. {spolvero-0.4.0 → spolvero-0.6.0}/pyproject.toml +2 -1
  37. {spolvero-0.4.0 → spolvero-0.6.0}/skills/codex/spolvero/SKILL.md +2 -0
  38. spolvero-0.6.0/skills/codex/spolvero-roundtrip/SKILL.md +73 -0
  39. spolvero-0.6.0/skills/codex/spolvero-roundtrip/agents/openai.yaml +4 -0
  40. spolvero-0.6.0/skills/codex/spolvero-roundtrip/references/coverage-and-drift.md +101 -0
  41. spolvero-0.6.0/skills/codex/spolvero-roundtrip/references/pr-preparation.md +56 -0
  42. spolvero-0.6.0/skills/codex/spolvero-roundtrip/references/workflow.md +101 -0
  43. spolvero-0.6.0/skills/codex/spolvero-roundtrip/scripts/roundtrip_review.py +506 -0
  44. spolvero-0.6.0/src/spolvero/__main__.py +6 -0
  45. spolvero-0.6.0/src/spolvero/annotations.py +163 -0
  46. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/builder.py +170 -20
  47. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/cli.py +102 -18
  48. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/constants.py +1 -1
  49. spolvero-0.6.0/src/spolvero/drift_detection.py +470 -0
  50. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/engines/__init__.py +3 -0
  51. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/engines/vsdx_template.py +195 -3
  52. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/hygiene.py +2 -0
  53. spolvero-0.6.0/src/spolvero/layout_extraction.py +172 -0
  54. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/layout_patch.py +57 -3
  55. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/render.py +130 -49
  56. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/schema.py +30 -0
  57. spolvero-0.4.0/src/spolvero/schemas/layout-patch.schema.json → spolvero-0.6.0/src/spolvero/schemas/annotations.schema.json +7 -6
  58. spolvero-0.6.0/src/spolvero/schemas/layout-patch.schema.json +80 -0
  59. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/schemas/manifest.schema.json +4 -0
  60. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/stamping.py +45 -32
  61. spolvero-0.6.0/tests/_review_toolkit.py +216 -0
  62. spolvero-0.6.0/tests/desktop/__init__.py +0 -0
  63. spolvero-0.6.0/tests/desktop/test_visio_desktop.py +224 -0
  64. spolvero-0.6.0/tests/fixtures/connector-attachment.mmd +3 -0
  65. spolvero-0.6.0/tests/fixtures/connector-direction.mmd +6 -0
  66. spolvero-0.6.0/tests/fixtures/reviewed-connectors.vsdx +0 -0
  67. {spolvero-0.4.0 → spolvero-0.6.0}/tests/fixtures/reviewed-simple.vsdx +0 -0
  68. spolvero-0.6.0/tests/fixtures/reviewed-topology.vsdx +0 -0
  69. spolvero-0.6.0/tests/test_annotations.py +183 -0
  70. {spolvero-0.4.0 → spolvero-0.6.0}/tests/test_cli_detect_drift.py +92 -0
  71. spolvero-0.6.0/tests/test_cli_extract_layout.py +134 -0
  72. spolvero-0.6.0/tests/test_drift_detection.py +817 -0
  73. spolvero-0.6.0/tests/test_layout_extraction.py +217 -0
  74. spolvero-0.6.0/tests/test_layout_patch.py +323 -0
  75. spolvero-0.6.0/tests/test_package_build.py +319 -0
  76. spolvero-0.6.0/tests/test_render_with_overrides.py +316 -0
  77. spolvero-0.6.0/tests/test_review_toolkit.py +209 -0
  78. spolvero-0.6.0/tests/test_roundtrip_annotations.py +178 -0
  79. spolvero-0.6.0/tests/test_roundtrip_review.py +368 -0
  80. spolvero-0.6.0/tests/test_roundtrip_review_guard.py +167 -0
  81. spolvero-0.6.0/tests/test_roundtrip_topology.py +168 -0
  82. {spolvero-0.4.0 → spolvero-0.6.0}/tests/test_stamping.py +108 -2
  83. spolvero-0.6.0/tests/test_vsdx_connectors.py +271 -0
  84. {spolvero-0.4.0 → spolvero-0.6.0}/tests/test_vsdx_template.py +88 -0
  85. spolvero-0.6.0/tests/validation/test_roundtrip_script_hardening.py +83 -0
  86. spolvero-0.6.0/tests/validation/test_skill_adapters.py +107 -0
  87. {spolvero-0.4.0 → spolvero-0.6.0}/uv.lock +20 -17
  88. spolvero-0.4.0/docs/round-trip-workflow.md +0 -75
  89. spolvero-0.4.0/src/spolvero/drift_detection.py +0 -227
  90. spolvero-0.4.0/src/spolvero/layout_extraction.py +0 -92
  91. spolvero-0.4.0/tests/_review_toolkit.py +0 -103
  92. spolvero-0.4.0/tests/test_cli_extract_layout.py +0 -38
  93. spolvero-0.4.0/tests/test_drift_detection.py +0 -266
  94. spolvero-0.4.0/tests/test_layout_extraction.py +0 -72
  95. spolvero-0.4.0/tests/test_layout_patch.py +0 -130
  96. spolvero-0.4.0/tests/test_package_build.py +0 -127
  97. spolvero-0.4.0/tests/test_render_with_overrides.py +0 -49
  98. spolvero-0.4.0/tests/test_review_toolkit.py +0 -78
  99. spolvero-0.4.0/tests/validation/test_skill_adapters.py +0 -52
  100. {spolvero-0.4.0 → spolvero-0.6.0}/.gitattributes +0 -0
  101. {spolvero-0.4.0 → spolvero-0.6.0}/.github/CODEOWNERS +0 -0
  102. {spolvero-0.4.0 → spolvero-0.6.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  103. {spolvero-0.4.0 → spolvero-0.6.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  104. {spolvero-0.4.0 → spolvero-0.6.0}/.github/ISSUE_TEMPLATE/feature_engine_work.md +0 -0
  105. {spolvero-0.4.0 → spolvero-0.6.0}/.github/ISSUE_TEMPLATE/qa_hygiene_work.md +0 -0
  106. {spolvero-0.4.0 → spolvero-0.6.0}/.github/ISSUE_TEMPLATE/release_work.md +0 -0
  107. {spolvero-0.4.0 → spolvero-0.6.0}/.github/ISSUE_TEMPLATE/vsdx_template_work.md +0 -0
  108. {spolvero-0.4.0 → spolvero-0.6.0}/.github/copilot-instructions.md +0 -0
  109. {spolvero-0.4.0 → spolvero-0.6.0}/.github/dependabot.yml +0 -0
  110. {spolvero-0.4.0 → spolvero-0.6.0}/.github/pull_request_template.md +0 -0
  111. {spolvero-0.4.0 → spolvero-0.6.0}/AGENTS.md +0 -0
  112. {spolvero-0.4.0 → spolvero-0.6.0}/CLAUDE.md +0 -0
  113. {spolvero-0.4.0 → spolvero-0.6.0}/SECURITY.md +0 -0
  114. {spolvero-0.4.0 → spolvero-0.6.0}/adapters/claude/.claude/skills/spolvero/SKILL.md +0 -0
  115. {spolvero-0.4.0 → spolvero-0.6.0}/adapters/claude/CLAUDE.md +0 -0
  116. {spolvero-0.4.0 → spolvero-0.6.0}/adapters/claude/INSTALL.md +0 -0
  117. {spolvero-0.4.0 → spolvero-0.6.0}/adapters/copilot/.github/copilot-instructions.md +0 -0
  118. {spolvero-0.4.0 → spolvero-0.6.0}/adapters/copilot/INSTALL.md +0 -0
  119. {spolvero-0.4.0 → spolvero-0.6.0}/adapters/generic/AGENTS.md +0 -0
  120. {spolvero-0.4.0 → spolvero-0.6.0}/docs/agent-usage.md +0 -0
  121. {spolvero-0.4.0 → spolvero-0.6.0}/docs/agents/architecture.md +0 -0
  122. {spolvero-0.4.0 → spolvero-0.6.0}/docs/agents/extending.md +0 -0
  123. {spolvero-0.4.0 → spolvero-0.6.0}/docs/agents/glossary.md +0 -0
  124. {spolvero-0.4.0 → spolvero-0.6.0}/docs/feature-expansion/template-testing-lessons.md +0 -0
  125. {spolvero-0.4.0 → spolvero-0.6.0}/docs/plans/01-round-trip-drift-engine.md +0 -0
  126. {spolvero-0.4.0 → spolvero-0.6.0}/docs/qa-corpus-and-sanitization.md +0 -0
  127. {spolvero-0.4.0 → spolvero-0.6.0}/docs/qa-findings-plan.md +0 -0
  128. {spolvero-0.4.0 → spolvero-0.6.0}/docs/security-posture-audit.md +0 -0
  129. {spolvero-0.4.0 → spolvero-0.6.0}/docs/support-matrix.md +0 -0
  130. {spolvero-0.4.0 → spolvero-0.6.0}/docs/topology-ir.md +0 -0
  131. {spolvero-0.4.0 → spolvero-0.6.0}/docs/using-the-package.md +0 -0
  132. {spolvero-0.4.0 → spolvero-0.6.0}/skills/codex/spolvero/agents/openai.yaml +0 -0
  133. {spolvero-0.4.0 → spolvero-0.6.0}/skills/codex/spolvero/references/support-matrix.md +0 -0
  134. {spolvero-0.4.0 → spolvero-0.6.0}/skills/codex/spolvero/scripts/spolvero_packager.py +0 -0
  135. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/__init__.py +0 -0
  136. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/engines/data_visualizer.py +0 -0
  137. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/engines/package_only.py +0 -0
  138. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/engines/visio_com.py +0 -0
  139. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/inspection.py +0 -0
  140. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/ir.py +0 -0
  141. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/models.py +0 -0
  142. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/reports.py +0 -0
  143. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/schemas/__init__.py +0 -0
  144. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/schemas/ir.schema.json +0 -0
  145. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/schemas/topology.schema.json +0 -0
  146. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/source.py +0 -0
  147. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/templates/LICENSE.txt +0 -0
  148. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/templates/minimal_flowchart.vsdx +0 -0
  149. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/topology/__init__.py +0 -0
  150. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/topology/model.py +0 -0
  151. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/utils.py +0 -0
  152. {spolvero-0.4.0 → spolvero-0.6.0}/src/spolvero/workbook.py +0 -0
  153. {spolvero-0.4.0 → spolvero-0.6.0}/tests/__init__.py +0 -0
  154. {spolvero-0.4.0 → spolvero-0.6.0}/tests/_paths.py +0 -0
  155. {spolvero-0.4.0 → spolvero-0.6.0}/tests/fixtures/sample-network.topology.yaml +0 -0
  156. {spolvero-0.4.0 → spolvero-0.6.0}/tests/fixtures/sample-sequence.mmd +0 -0
  157. {spolvero-0.4.0 → spolvero-0.6.0}/tests/fixtures/sample-trd.topology.json +0 -0
  158. {spolvero-0.4.0 → spolvero-0.6.0}/tests/fixtures/sample.dot +0 -0
  159. {spolvero-0.4.0 → spolvero-0.6.0}/tests/fixtures/sample.md +0 -0
  160. {spolvero-0.4.0 → spolvero-0.6.0}/tests/fixtures/sample.png +0 -0
  161. {spolvero-0.4.0 → spolvero-0.6.0}/tests/fixtures/sample.puml +0 -0
  162. {spolvero-0.4.0 → spolvero-0.6.0}/tests/fixtures/sample.svg +0 -0
  163. {spolvero-0.4.0 → spolvero-0.6.0}/tests/fixtures/simple.mmd +0 -0
  164. {spolvero-0.4.0 → spolvero-0.6.0}/tests/fixtures/synthetic-rich.mmd +0 -0
  165. {spolvero-0.4.0 → spolvero-0.6.0}/tests/test_cli.py +0 -0
  166. {spolvero-0.4.0 → spolvero-0.6.0}/tests/test_engine_registry.py +0 -0
  167. {spolvero-0.4.0 → spolvero-0.6.0}/tests/test_extraction.py +0 -0
  168. {spolvero-0.4.0 → spolvero-0.6.0}/tests/test_hygiene.py +0 -0
  169. {spolvero-0.4.0 → spolvero-0.6.0}/tests/test_mermaid_ir.py +0 -0
  170. {spolvero-0.4.0 → spolvero-0.6.0}/tests/test_optional_tools.py +0 -0
  171. {spolvero-0.4.0 → spolvero-0.6.0}/tests/test_topology_ir.py +0 -0
  172. {spolvero-0.4.0 → spolvero-0.6.0}/tests/test_visio_com.py +0 -0
  173. {spolvero-0.4.0 → spolvero-0.6.0}/tests/test_vsdx_inspection.py +0 -0
  174. {spolvero-0.4.0 → spolvero-0.6.0}/tests/test_workbook.py +0 -0
@@ -14,3 +14,5 @@ Expected outputs include `manifest.json`, `README.md`, `source/`, `normalized/`,
14
14
 
15
15
  For unsupported diagrams, still preserve the source and generate preview/reference artifacts with a clear `vector_reference` or `raster_reference` editability declaration.
16
16
 
17
+ Round-trip review runs (`spolvero-roundtrip` skill) commit only the layout patch and drift report. Rebuilt packages stay in `.tmp/`; regenerated previews are committed only over already-tracked docs assets, never as new paths. Reviewed `.vsdx` binaries are never committed (headless test fixtures under `tests/fixtures/` are a separate, sanctioned class). `docs/artifact-governance.md` is the governing policy for all round-trip artifact retention.
18
+
@@ -18,11 +18,11 @@ jobs:
18
18
  python-version: ["3.11", "3.13"]
19
19
 
20
20
  steps:
21
- - uses: actions/checkout@v4
22
- - uses: astral-sh/setup-uv@v6
21
+ - uses: actions/checkout@v7
22
+ - uses: astral-sh/setup-uv@v7
23
23
  with:
24
24
  enable-cache: true
25
- - uses: actions/setup-python@v5
25
+ - uses: actions/setup-python@v6
26
26
  with:
27
27
  python-version: ${{ matrix.python-version }}
28
28
  - name: Compile
@@ -34,16 +34,33 @@ jobs:
34
34
  - name: Assert generated artifacts
35
35
  run: uv run python -c "import json, pathlib, zipfile; root=pathlib.Path('.tmp/ci-smoke'); manifest=json.loads((root/'manifest.json').read_text()); assert manifest['schema_version']=='1.0.0'; assert len(manifest['diagrams'])==3; assert (root/'preview/diagram-001.png').read_bytes().startswith(b'\x89PNG\r\n\x1a\n'); assert zipfile.is_zipfile(root/'visio/diagram-001-data-visualizer.xlsx')"
36
36
 
37
+ test-vsdx:
38
+ # Real-VSDX round-trip tests are skipped in the matrix above (no [vsdx] extra).
39
+ name: Real-VSDX tests (Python 3.13 on ubuntu-latest)
40
+ runs-on: ubuntu-latest
41
+ env:
42
+ SPOLVERO_TEST_VSDX: "1"
43
+ steps:
44
+ - uses: actions/checkout@v7
45
+ - uses: astral-sh/setup-uv@v7
46
+ with:
47
+ enable-cache: true
48
+ - uses: actions/setup-python@v6
49
+ with:
50
+ python-version: "3.13"
51
+ - name: Test with [vsdx] extra
52
+ run: uv run --extra vsdx pytest -rs
53
+
37
54
  ci-summary:
38
55
  name: ci-summary
39
56
  runs-on: ubuntu-latest
40
- needs: [test]
57
+ needs: [test, test-vsdx]
41
58
  if: always()
42
59
  steps:
43
- - name: Check test matrix result
60
+ - name: Check test results
44
61
  run: |
45
- if [ "${{ needs.test.result }}" != "success" ]; then
46
- echo "test result: ${{ needs.test.result }}"
62
+ echo "test result: ${{ needs.test.result }}"
63
+ echo "test-vsdx result: ${{ needs.test-vsdx.result }}"
64
+ if [ "${{ needs.test.result }}" != "success" ] || [ "${{ needs.test-vsdx.result }}" != "success" ]; then
47
65
  exit 1
48
66
  fi
49
- echo "test result: ${{ needs.test.result }}"
@@ -20,7 +20,7 @@ jobs:
20
20
  runs-on: ubuntu-latest
21
21
  timeout-minutes: 15
22
22
  steps:
23
- - uses: actions/checkout@v6
23
+ - uses: actions/checkout@v7
24
24
 
25
25
  - uses: github/codeql-action/init@v4
26
26
  with:
@@ -12,9 +12,9 @@ jobs:
12
12
  runs-on: ubuntu-latest
13
13
  timeout-minutes: 10
14
14
  steps:
15
- - uses: actions/checkout@v6
15
+ - uses: actions/checkout@v7
16
16
 
17
- - uses: actions/dependency-review-action@v4
17
+ - uses: actions/dependency-review-action@v5
18
18
  with:
19
19
  fail-on-severity: high
20
20
  fail-on-scopes: runtime, development, unknown
@@ -12,12 +12,21 @@ jobs:
12
12
  name: Build sdist + wheel
13
13
  runs-on: ubuntu-latest
14
14
  steps:
15
- - uses: actions/checkout@v6
15
+ - uses: actions/checkout@v7
16
16
 
17
17
  - uses: actions/setup-python@v6
18
18
  with:
19
19
  python-version: "3.13"
20
20
 
21
+ - name: Check tag matches package version
22
+ run: |
23
+ version="$(python -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"])')"
24
+ if [ "${GITHUB_REF_NAME}" != "v${version}" ]; then
25
+ echo "::error::Tag ${GITHUB_REF_NAME} does not match pyproject.toml version ${version} (expected v${version})."
26
+ exit 1
27
+ fi
28
+ echo "Tag ${GITHUB_REF_NAME} matches version ${version}."
29
+
21
30
  - name: Install build tooling
22
31
  run: python -m pip install --upgrade build twine
23
32
 
@@ -57,6 +66,20 @@ jobs:
57
66
  permissions:
58
67
  contents: write
59
68
  steps:
69
+ - uses: actions/checkout@v7
70
+ with:
71
+ sparse-checkout: docs/releases
72
+
73
+ - name: Select curated release notes
74
+ id: notes
75
+ run: |
76
+ notes="docs/releases/${GITHUB_REF_NAME#v}.md"
77
+ if [ -f "$notes" ]; then
78
+ echo "body_path=$notes" >> "$GITHUB_OUTPUT"
79
+ else
80
+ echo "::warning::No $notes; the release body will be auto-generated only."
81
+ fi
82
+
60
83
  - uses: actions/download-artifact@v8
61
84
  with:
62
85
  name: dist
@@ -65,5 +88,6 @@ jobs:
65
88
  - uses: softprops/action-gh-release@v3
66
89
  with:
67
90
  files: dist/*
91
+ body_path: ${{ steps.notes.outputs.body_path }}
68
92
  generate_release_notes: true
69
93
  draft: false
@@ -18,3 +18,4 @@ __pycache__/
18
18
  /generated/
19
19
  /packages/
20
20
  .codex/
21
+ layouts/reviewed/
@@ -8,6 +8,7 @@ Latest durable queue for `spolvero`.
8
8
  - The repository now lives at `Declaratus/spolvero`; `main` should remain ready for post-release governance and operations work.
9
9
  - CI exposes a single `ci-summary` aggregate check for org ruleset readiness.
10
10
  - Latest default-branch checks are green, including `ci-summary`, CodeQL, and Dependency Review.
11
+ - v0.5.0 is the previous tagged release. The package version is 0.6.0 (container stamping, multi-diagram patch matching, and manual annotation preservation; PRs #63–#66). Tagging and publication require separate approval; check for a `v0.6.0` tag before assuming it has shipped. See [docs/releases/0.6.0.md](docs/releases/0.6.0.md).
11
12
  - Spolvero is promoted to `tier=internal`; repo-local branch protection is disabled, and default-branch policy is enforced through Declaratus org rulesets.
12
13
  - Spolvero is recorded in `Declaratus/governance` property assignments; issue #18 is closed.
13
14
  - CODEOWNERS covers release and governance-sensitive paths with the current owner handle until a Declaratus maintainer team exists.
@@ -49,8 +50,10 @@ Residual governance notes:
49
50
 
50
51
  ## Round-trip & drift engine (spec 01)
51
52
 
52
- The round-trip/drift engine is merged to `main` and released in v0.4.0
53
- (Tasks 1–14 pure-logic foundation in PR #43, Tasks 15–25 VSDX integration in PR #44).
53
+ The round-trip/drift engine is merged to `main`
54
+ (Tasks 1–14 pure-logic foundation in PR #43, Tasks 15–25 VSDX integration in PR #44)
55
+ and shipped in 0.4.0. Connector-endpoint drift and edge routes (spec 03, PR #61)
56
+ ship in 0.5.0.
54
57
  See `docs/specs/01-round-trip-drift-engine.md` for the spec and
55
58
  `docs/round-trip-workflow.md` for the end-to-end flow.
56
59
 
@@ -59,17 +62,24 @@ New capabilities:
59
62
  1. Source-metadata stamping (per-shape Visio Shape Data plus doc-level
60
63
  `docProps/custom.xml`) on every `vsdx-template` build; see
61
64
  `docs/vsdx-template-contract.md` for the stamp keys.
62
- 2. `spolvero extract-layout` lifts reviewer node positions into a YAML layout
63
- patch keyed by `spolvero.source_id`.
64
- 3. `spolvero detect-drift` runs the D1–D4 detectors against the source IR (and,
65
- with `--source`, the doc-level source hash).
66
- 4. `spolvero build --layout-patch` regenerates while honouring reviewer layout.
65
+ 2. `spolvero extract-layout` lifts reviewer node positions, connector
66
+ endpoints, and topology container bounds into a YAML layout patch
67
+ (`patch_schema_version: 3`) keyed by `spolvero.source_id`; `--diagram`
68
+ defaults to the stamped `spolvero.diagram_id`.
69
+ 3. `spolvero detect-drift` runs the D1–D6 detectors against the source IR
70
+ (D5 connector-endpoint drift landed with spec 03 / DEC-169; D1 containers
71
+ and the D6 pairing guard with spec 04 / DEC-170).
72
+ 4. `spolvero build --layout-patch` regenerates while honouring reviewer
73
+ layout, including connector endpoint routes and container bounds;
74
+ `--layout-patch` is repeatable and matched to diagrams by id.
75
+ 5. `spolvero extract-layout --annotations-out` / `build --annotations`
76
+ capture and re-materialize reviewer-added shapes as `ownership: manual`
77
+ annotations via a committed sidecar (spec 05 / DEC-172).
67
78
 
68
79
  Follow-ups:
69
80
 
70
- 1. The Visio Diagram Handoff Assistant skill (DEC-104) is the next piece.
71
- 2. Connector-endpoint drift detection plus edge-route geometry is the next
72
- engine follow-up.
73
- 3. Container/topology shape stamping and multi-diagram patch-to-diagram matching
74
- remain unimplemented (see the MVP limitations in
81
+ 1. The residual engine scope is tracked in Linear on the Visio Renderer
82
+ initiative: waypoint/polyline route geometry, annotation styling fidelity,
83
+ and reviewer-drawn (1-D) annotations. Container membership drift and
84
+ flowchart-subgraph stamping are out of scope (see the MVP limitations in
75
85
  `docs/round-trip-workflow.md`).
spolvero-0.6.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Declaratus
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,9 +1,10 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: spolvero
3
- Version: 0.4.0
3
+ Version: 0.6.0
4
4
  Summary: Package docs-as-code diagrams into Visio-friendly handoff artifacts.
5
5
  Author: Spolvero maintainers
6
6
  License: MIT
7
+ License-File: LICENSE
7
8
  Keywords: data-visualizer,diagram,handoff,mermaid,visio
8
9
  Requires-Python: >=3.11
9
10
  Provides-Extra: com
@@ -24,12 +25,47 @@ The package treats source diagrams as canonical unless a project deliberately mo
24
25
 
25
26
  See [docs/using-the-package.md](docs/using-the-package.md) for what to do with the handoff folder once it has been generated.
26
27
 
28
+ **Status:** pre-1.0. The manifest and IR schemas are versioned, but the CLI and Python API may still change between minor releases. The `visio-com` engine does not create native COM shapes yet; it delegates to the engines below it.
29
+
30
+ ## Install
31
+
32
+ Requires Python 3.11 or later.
33
+
34
+ ```bash
35
+ pip install spolvero
36
+ ```
37
+
38
+ The core install is stdlib-only. Each extra unlocks one optional engine or input format and is feature-detected at runtime so it never blocks the default path.
39
+
40
+ ```bash
41
+ pip install 'spolvero[vsdx]' # vsdx-template engine (cross-platform)
42
+ pip install 'spolvero[topology]' # YAML topology inputs (PyYAML)
43
+ pip install 'spolvero[com]' # visio-com engine (Windows + Visio Plan 2)
44
+ ```
45
+
46
+ A Mermaid CLI (`mmdc`) on `PATH` is auto-detected for higher-fidelity Mermaid previews. Set `SPOLVERO_DISABLE_MMDC=1` to force the built-in renderer.
47
+
27
48
  ## Quick Start
28
49
 
29
50
  ```bash
30
51
  spolvero build input.md --out ./handoff --target data-visualizer
31
52
  ```
32
53
 
54
+ For an input with one supported Mermaid flowchart, the output folder looks like this (`<id>` is the diagram id, such as `diagram-001`):
55
+
56
+ ```text
57
+ handoff/
58
+ ├── manifest.json # everything that was built, plus warnings
59
+ ├── README.md # auto-generated package overview
60
+ ├── source/ # original input + per-diagram extracted source
61
+ ├── normalized/<id>.ir.json # validated intermediate representation
62
+ ├── preview/<id>.svg, <id>.png # always generated
63
+ ├── visio/<id>-data-visualizer.xlsx
64
+ └── qa/<id>-qa.md, <id>-conversion-log.json
65
+ ```
66
+
67
+ The workbook appears only for supported flowcharts and topology inputs; other diagrams are packaged as previews with reference editability. Open `manifest.json` for the summary and `qa/<id>-qa.md` for per-diagram warnings. The [handoff guide](docs/using-the-package.md) walks through each file.
68
+
33
69
  From a checkout without installation:
34
70
 
35
71
  ```bash
@@ -51,6 +87,7 @@ build_package(Path("input.md"), Path("handoff"), "data-visualizer", title="Revie
51
87
  - `src/spolvero/`: neutral Python library and CLI.
52
88
  - `src/spolvero/schemas/`: versioned manifest and IR schemas.
53
89
  - `skills/codex/spolvero/`: Codex-installable skill bundle generated from canonical docs and wrappers.
90
+ - `skills/codex/spolvero-roundtrip/`: Codex skill bundle for processing a reviewed `.vsdx` (coverage, layout patch, drift report).
54
91
  - `adapters/`: Claude Code, GitHub Copilot, and generic agent install notes/instruction files.
55
92
  - `tests/`: pytest coverage for extraction, Mermaid parsing, schemas, artifacts, adapters, and CLI smoke builds.
56
93
 
@@ -74,19 +111,6 @@ uv run spolvero sanitize-vsdx src/spolvero/templates/minimal_flowchart.vsdx --ou
74
111
 
75
112
  See [docs/declaratus-migration.md](docs/declaratus-migration.md) for post-import operating guidance.
76
113
 
77
- ## Optional Extras
78
-
79
- The core install is stdlib-only. Each extra unlocks one optional engine or input format and is feature-detected at runtime so it never blocks the default path.
80
-
81
- ```bash
82
- pip install spolvero # stdlib-only default
83
- pip install 'spolvero[vsdx]' # vsdx-template engine (cross-platform)
84
- pip install 'spolvero[topology]' # YAML topology inputs (PyYAML)
85
- pip install 'spolvero[com]' # visio-com engine (Windows + Visio Plan 2)
86
- ```
87
-
88
- A Mermaid CLI (`mmdc`) on `PATH` is auto-detected for higher-fidelity Mermaid previews. Set `SPOLVERO_DISABLE_MMDC=1` to force the built-in renderer.
89
-
90
114
  ## Targets and Editability
91
115
 
92
116
  | Target | Engine | Flowchart editability | Notes |
@@ -100,6 +124,33 @@ The manifest always records both `requested_engine` and `actual_engine` so engin
100
124
 
101
125
  The VSDX template stamp contract is documented in [docs/vsdx-template-contract.md](docs/vsdx-template-contract.md). The bundled template is intentionally minimal; richer templates can provide preferred flowchart, topology, and container stamp names while remaining synthetic and organization-agnostic.
102
126
 
127
+ ## Round-trip Review
128
+
129
+ When a `vsdx-template` file comes back from review in Visio, Spolvero keeps the reviewer's layout without editing your source. Every generated shape is stamped with its source id, so the reviewed file can be read back. Requires the `[vsdx]` extra.
130
+
131
+ ```bash
132
+ # Capture reviewer positions, connector routes, and container bounds as a layout patch.
133
+ # --annotations-out also keeps shapes the reviewer added (callouts, notes) as a sidecar.
134
+ spolvero extract-layout reviewed.vsdx --out diagram-001.layout.yml \
135
+ --annotations-out diagram-001.annotations.yml
136
+
137
+ # Check what changed against the source: deleted or relabelled shapes,
138
+ # re-pointed connectors, stale source, or a file paired with the wrong diagram.
139
+ spolvero detect-drift handoff/normalized/diagram-001.ir.json reviewed.vsdx \
140
+ --source input.md --report drift.md
141
+ ```
142
+
143
+ `detect-drift` exits 1 on high-severity drift. Stop there and review `drift.md` before rebuilding; only continue once the drift is understood or accepted.
144
+
145
+ ```bash
146
+ # Rebuild with the reviewer's layout and annotations. Both flags are repeatable
147
+ # and matched to diagrams by id in multi-diagram packages.
148
+ spolvero build input.md --out handoff --target vsdx-template \
149
+ --layout-patch diagram-001.layout.yml --annotations diagram-001.annotations.yml
150
+ ```
151
+
152
+ Routes keep endpoints, not waypoints, and annotations keep geometry and text only. See [docs/round-trip-workflow.md](docs/round-trip-workflow.md) for the full workflow and limits, and the `spolvero-roundtrip` agent skill for a scripted review run.
153
+
103
154
  ## Inputs
104
155
 
105
156
  - Mermaid flowchart (`.mmd`, fenced ` ```mermaid ` in Markdown) — primary input; full IR + workbook.
@@ -109,3 +160,9 @@ The VSDX template stamp contract is documented in [docs/vsdx-template-contract.m
109
160
  ## The name
110
161
 
111
162
  Spolvero (Italian, *spol-VEH-roh*) is the Renaissance pouncing technique: an artist pricks holes along the lines of a finished drawing, then dusts pigment through them to transfer the design onto a wall or panel. The pricked cartoon is a deliberate intermediate — made for transfer, distinct from the original. This tool works the same way: it produces a transfer-ready rendering of a source diagram for the Visio surface, while the source stays canonical.
163
+
164
+ ## Security and License
165
+
166
+ Report vulnerabilities as described in [SECURITY.md](SECURITY.md).
167
+
168
+ Spolvero is released under the [MIT License](LICENSE). The bundled `minimal_flowchart.vsdx` template is redistributed under the BSD 3-Clause License; see [src/spolvero/templates/LICENSE.txt](src/spolvero/templates/LICENSE.txt).
@@ -6,12 +6,47 @@ The package treats source diagrams as canonical unless a project deliberately mo
6
6
 
7
7
  See [docs/using-the-package.md](docs/using-the-package.md) for what to do with the handoff folder once it has been generated.
8
8
 
9
+ **Status:** pre-1.0. The manifest and IR schemas are versioned, but the CLI and Python API may still change between minor releases. The `visio-com` engine does not create native COM shapes yet; it delegates to the engines below it.
10
+
11
+ ## Install
12
+
13
+ Requires Python 3.11 or later.
14
+
15
+ ```bash
16
+ pip install spolvero
17
+ ```
18
+
19
+ The core install is stdlib-only. Each extra unlocks one optional engine or input format and is feature-detected at runtime so it never blocks the default path.
20
+
21
+ ```bash
22
+ pip install 'spolvero[vsdx]' # vsdx-template engine (cross-platform)
23
+ pip install 'spolvero[topology]' # YAML topology inputs (PyYAML)
24
+ pip install 'spolvero[com]' # visio-com engine (Windows + Visio Plan 2)
25
+ ```
26
+
27
+ A Mermaid CLI (`mmdc`) on `PATH` is auto-detected for higher-fidelity Mermaid previews. Set `SPOLVERO_DISABLE_MMDC=1` to force the built-in renderer.
28
+
9
29
  ## Quick Start
10
30
 
11
31
  ```bash
12
32
  spolvero build input.md --out ./handoff --target data-visualizer
13
33
  ```
14
34
 
35
+ For an input with one supported Mermaid flowchart, the output folder looks like this (`<id>` is the diagram id, such as `diagram-001`):
36
+
37
+ ```text
38
+ handoff/
39
+ ├── manifest.json # everything that was built, plus warnings
40
+ ├── README.md # auto-generated package overview
41
+ ├── source/ # original input + per-diagram extracted source
42
+ ├── normalized/<id>.ir.json # validated intermediate representation
43
+ ├── preview/<id>.svg, <id>.png # always generated
44
+ ├── visio/<id>-data-visualizer.xlsx
45
+ └── qa/<id>-qa.md, <id>-conversion-log.json
46
+ ```
47
+
48
+ The workbook appears only for supported flowcharts and topology inputs; other diagrams are packaged as previews with reference editability. Open `manifest.json` for the summary and `qa/<id>-qa.md` for per-diagram warnings. The [handoff guide](docs/using-the-package.md) walks through each file.
49
+
15
50
  From a checkout without installation:
16
51
 
17
52
  ```bash
@@ -33,6 +68,7 @@ build_package(Path("input.md"), Path("handoff"), "data-visualizer", title="Revie
33
68
  - `src/spolvero/`: neutral Python library and CLI.
34
69
  - `src/spolvero/schemas/`: versioned manifest and IR schemas.
35
70
  - `skills/codex/spolvero/`: Codex-installable skill bundle generated from canonical docs and wrappers.
71
+ - `skills/codex/spolvero-roundtrip/`: Codex skill bundle for processing a reviewed `.vsdx` (coverage, layout patch, drift report).
36
72
  - `adapters/`: Claude Code, GitHub Copilot, and generic agent install notes/instruction files.
37
73
  - `tests/`: pytest coverage for extraction, Mermaid parsing, schemas, artifacts, adapters, and CLI smoke builds.
38
74
 
@@ -56,19 +92,6 @@ uv run spolvero sanitize-vsdx src/spolvero/templates/minimal_flowchart.vsdx --ou
56
92
 
57
93
  See [docs/declaratus-migration.md](docs/declaratus-migration.md) for post-import operating guidance.
58
94
 
59
- ## Optional Extras
60
-
61
- The core install is stdlib-only. Each extra unlocks one optional engine or input format and is feature-detected at runtime so it never blocks the default path.
62
-
63
- ```bash
64
- pip install spolvero # stdlib-only default
65
- pip install 'spolvero[vsdx]' # vsdx-template engine (cross-platform)
66
- pip install 'spolvero[topology]' # YAML topology inputs (PyYAML)
67
- pip install 'spolvero[com]' # visio-com engine (Windows + Visio Plan 2)
68
- ```
69
-
70
- A Mermaid CLI (`mmdc`) on `PATH` is auto-detected for higher-fidelity Mermaid previews. Set `SPOLVERO_DISABLE_MMDC=1` to force the built-in renderer.
71
-
72
95
  ## Targets and Editability
73
96
 
74
97
  | Target | Engine | Flowchart editability | Notes |
@@ -82,6 +105,33 @@ The manifest always records both `requested_engine` and `actual_engine` so engin
82
105
 
83
106
  The VSDX template stamp contract is documented in [docs/vsdx-template-contract.md](docs/vsdx-template-contract.md). The bundled template is intentionally minimal; richer templates can provide preferred flowchart, topology, and container stamp names while remaining synthetic and organization-agnostic.
84
107
 
108
+ ## Round-trip Review
109
+
110
+ When a `vsdx-template` file comes back from review in Visio, Spolvero keeps the reviewer's layout without editing your source. Every generated shape is stamped with its source id, so the reviewed file can be read back. Requires the `[vsdx]` extra.
111
+
112
+ ```bash
113
+ # Capture reviewer positions, connector routes, and container bounds as a layout patch.
114
+ # --annotations-out also keeps shapes the reviewer added (callouts, notes) as a sidecar.
115
+ spolvero extract-layout reviewed.vsdx --out diagram-001.layout.yml \
116
+ --annotations-out diagram-001.annotations.yml
117
+
118
+ # Check what changed against the source: deleted or relabelled shapes,
119
+ # re-pointed connectors, stale source, or a file paired with the wrong diagram.
120
+ spolvero detect-drift handoff/normalized/diagram-001.ir.json reviewed.vsdx \
121
+ --source input.md --report drift.md
122
+ ```
123
+
124
+ `detect-drift` exits 1 on high-severity drift. Stop there and review `drift.md` before rebuilding; only continue once the drift is understood or accepted.
125
+
126
+ ```bash
127
+ # Rebuild with the reviewer's layout and annotations. Both flags are repeatable
128
+ # and matched to diagrams by id in multi-diagram packages.
129
+ spolvero build input.md --out handoff --target vsdx-template \
130
+ --layout-patch diagram-001.layout.yml --annotations diagram-001.annotations.yml
131
+ ```
132
+
133
+ Routes keep endpoints, not waypoints, and annotations keep geometry and text only. See [docs/round-trip-workflow.md](docs/round-trip-workflow.md) for the full workflow and limits, and the `spolvero-roundtrip` agent skill for a scripted review run.
134
+
85
135
  ## Inputs
86
136
 
87
137
  - Mermaid flowchart (`.mmd`, fenced ` ```mermaid ` in Markdown) — primary input; full IR + workbook.
@@ -91,3 +141,9 @@ The VSDX template stamp contract is documented in [docs/vsdx-template-contract.m
91
141
  ## The name
92
142
 
93
143
  Spolvero (Italian, *spol-VEH-roh*) is the Renaissance pouncing technique: an artist pricks holes along the lines of a finished drawing, then dusts pigment through them to transfer the design onto a wall or panel. The pricked cartoon is a deliberate intermediate — made for transfer, distinct from the original. This tool works the same way: it produces a transfer-ready rendering of a source diagram for the Visio surface, while the source stays canonical.
144
+
145
+ ## Security and License
146
+
147
+ Report vulnerabilities as described in [SECURITY.md](SECURITY.md).
148
+
149
+ Spolvero is released under the [MIT License](LICENSE). The bundled `minimal_flowchart.vsdx` template is redistributed under the BSD 3-Clause License; see [src/spolvero/templates/LICENSE.txt](src/spolvero/templates/LICENSE.txt).
@@ -0,0 +1,56 @@
1
+ ---
2
+ name: spolvero-roundtrip
3
+ description: Process a reviewed VSDX back into source control — verify source-metadata coverage, extract a layout patch, detect drift against the source IR, and produce a validation report before preparing a layout-patch PR. Use for reviewed VSDX, layout patch, drift, or validation report requests; building new handoff packages is the spolvero skill.
4
+ ---
5
+
6
+ # Spolvero Roundtrip
7
+
8
+ Return leg only: a reviewed `.vsdx` comes back; the outcome is a layout patch
9
+ plus reports, never an automatic edit to canonical source.
10
+
11
+ Run the hardened script from the skill bundle
12
+ (`skills/codex/spolvero-roundtrip/scripts/roundtrip_review.py` in the spolvero
13
+ repo):
14
+
15
+ ```bash
16
+ python scripts/roundtrip_review.py run \
17
+ --vsdx reviewed.vsdx --ir diagram-001.ir.json --source sample.md \
18
+ --out-dir .tmp/review
19
+ ```
20
+
21
+ For source checkouts:
22
+
23
+ ```bash
24
+ uv run --extra vsdx python skills/codex/spolvero-roundtrip/scripts/roundtrip_review.py run \
25
+ --vsdx reviewed.vsdx --ir handoff/normalized/diagram-001.ir.json \
26
+ --source sample.md --out-dir .tmp/review
27
+ ```
28
+
29
+ Core rules:
30
+
31
+ - Engine work goes through the committed script or named `spolvero`
32
+ subcommands only. Never run ad-hoc Python against a `.vsdx`.
33
+ - Exit 0: clean or medium findings — proceed to PR preparation per the
34
+ bundle's `references/pr-preparation.md`.
35
+ - Exit 1: high-severity drift (D1 deleted shape, connector, or container /
36
+ D4 revision mismatch / D5 re-pointed endpoint / D6 wrong diagram) — HALT
37
+ before PR preparation; show `validation-report.md` and let a human decide.
38
+ - Shapes the reviewer added in Visio are medium (D2) findings and are dropped
39
+ on rebuild. Keep them only if the user asks: run
40
+ `spolvero extract-layout reviewed.vsdx --out <diagram>.layout.yml --annotations-out <diagram>.annotations.yml`
41
+ and commit the sidecar next to the patch (see the bundle's
42
+ `references/coverage-and-drift.md`).
43
+ - Exit 2: input/environment error or failed/incomplete rebuild. HALT before
44
+ PR preparation. Rebuild failures retain a HALT validation report; the "not
45
+ a round-trip candidate" stop retains `coverage.json` and `drift.*` as evidence.
46
+ - If the `.vsdx` came from outside the repo, run `spolvero inspect-vsdx`
47
+ (read-only) first and surface sensitive-pattern findings.
48
+ - Never merge, never push to a protected branch, never commit a reviewed
49
+ `.vsdx` binary. No COM automation.
50
+
51
+ The wrapper requires a non-empty IR id; explicit `--diagram` must match it.
52
+ Rebuild patch warnings (`patch_unmatched`, `patch_diagram_mismatch`,
53
+ `patch_stale`) halt PR preparation with exit 2 and a HALT validation report.
54
+ Failed rebuilds also halt; retained previews are not validated.
55
+
56
+ Requires the `[vsdx]` extra: `pip install 'spolvero[vsdx]'`.
@@ -14,3 +14,5 @@ Expected outputs include `manifest.json`, `README.md`, `source/`, `normalized/`,
14
14
 
15
15
  For unsupported diagrams, still preserve the source and generate preview/reference artifacts with a clear `vector_reference` or `raster_reference` editability declaration.
16
16
 
17
+ Round-trip review runs (`spolvero-roundtrip` skill) commit only the layout patch and drift report. Rebuilt packages stay in `.tmp/`; regenerated previews are committed only over already-tracked docs assets, never as new paths. Reviewed `.vsdx` binaries are never committed.
18
+
@@ -19,6 +19,19 @@ set SPOLVERO_TEST_COM=1
19
19
  uv run pytest -q
20
20
  ```
21
21
 
22
+ ## Live Visio acceptance checks
23
+
24
+ `tests/desktop` opens generated files in an invisible Visio instance, moves
25
+ connected nodes, saves, reopens and rebuilds. Hosted CI cannot run it (no
26
+ licensed Visio), so a maintainer runs it on a licensed Windows machine:
27
+
28
+ ```bash
29
+ SPOLVERO_TEST_VSDX=1 SPOLVERO_TEST_VISIO_DESKTOP=1 uv run --extra vsdx --extra com pytest -m visio_desktop -rsx
30
+ ```
31
+
32
+ Report which tests passed, failed, xfailed or were skipped. Never run these on
33
+ a self-hosted runner that executes public pull-request code.
34
+
22
35
  ## Smoke build a sample package
23
36
 
24
37
  ```bash