spolvero 0.4.0__tar.gz → 0.5.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 (151) hide show
  1. {spolvero-0.4.0 → spolvero-0.5.0}/.github/instructions/spolvero.instructions.md +2 -0
  2. {spolvero-0.4.0 → spolvero-0.5.0}/.github/workflows/ci.yml +3 -3
  3. {spolvero-0.4.0 → spolvero-0.5.0}/.github/workflows/codeql.yml +1 -1
  4. {spolvero-0.4.0 → spolvero-0.5.0}/.github/workflows/dependency-review.yml +2 -2
  5. {spolvero-0.4.0 → spolvero-0.5.0}/.github/workflows/release.yml +1 -1
  6. {spolvero-0.4.0 → spolvero-0.5.0}/.gitignore +1 -0
  7. {spolvero-0.4.0 → spolvero-0.5.0}/HANDOFF.md +16 -11
  8. {spolvero-0.4.0 → spolvero-0.5.0}/PKG-INFO +1 -1
  9. spolvero-0.5.0/adapters/claude/.claude/skills/spolvero-roundtrip/SKILL.md +46 -0
  10. {spolvero-0.4.0 → spolvero-0.5.0}/adapters/copilot/.github/instructions/spolvero.instructions.md +2 -0
  11. spolvero-0.5.0/docs/artifact-governance.md +146 -0
  12. spolvero-0.5.0/docs/consumer-ci-recipe.md +209 -0
  13. {spolvero-0.4.0 → spolvero-0.5.0}/docs/current-state.md +21 -6
  14. spolvero-0.5.0/docs/demos/round-trip/README.md +241 -0
  15. spolvero-0.5.0/docs/demos/round-trip/accepted/d1.layout.yml +21 -0
  16. spolvero-0.5.0/docs/demos/round-trip/accepted/drift.json +10 -0
  17. spolvero-0.5.0/docs/demos/round-trip/accepted/drift.md +11 -0
  18. spolvero-0.5.0/docs/demos/round-trip/rejected/drift.json +27 -0
  19. spolvero-0.5.0/docs/demos/round-trip/rejected/drift.md +23 -0
  20. spolvero-0.5.0/docs/plans/03-connector-endpoint-drift.md +264 -0
  21. spolvero-0.5.0/docs/research/artifact-governance.md +272 -0
  22. {spolvero-0.4.0 → spolvero-0.5.0}/docs/round-trip-workflow.md +47 -18
  23. {spolvero-0.4.0 → spolvero-0.5.0}/docs/specs/01-round-trip-drift-engine.md +1 -1
  24. spolvero-0.5.0/docs/specs/02-visio-diagram-handoff-assistant-skill.md +125 -0
  25. spolvero-0.5.0/docs/specs/03-connector-endpoint-drift.md +194 -0
  26. {spolvero-0.4.0 → spolvero-0.5.0}/pyproject.toml +1 -1
  27. {spolvero-0.4.0 → spolvero-0.5.0}/skills/codex/spolvero/SKILL.md +2 -0
  28. spolvero-0.5.0/skills/codex/spolvero-roundtrip/SKILL.md +66 -0
  29. spolvero-0.5.0/skills/codex/spolvero-roundtrip/agents/openai.yaml +4 -0
  30. spolvero-0.5.0/skills/codex/spolvero-roundtrip/references/coverage-and-drift.md +71 -0
  31. spolvero-0.5.0/skills/codex/spolvero-roundtrip/references/pr-preparation.md +53 -0
  32. spolvero-0.5.0/skills/codex/spolvero-roundtrip/references/workflow.md +87 -0
  33. spolvero-0.5.0/skills/codex/spolvero-roundtrip/scripts/roundtrip_review.py +406 -0
  34. spolvero-0.5.0/src/spolvero/__main__.py +6 -0
  35. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/builder.py +14 -1
  36. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/cli.py +28 -8
  37. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/constants.py +1 -1
  38. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/drift_detection.py +175 -11
  39. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/engines/__init__.py +1 -0
  40. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/engines/vsdx_template.py +10 -3
  41. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/hygiene.py +1 -0
  42. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/layout_extraction.py +65 -11
  43. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/layout_patch.py +38 -3
  44. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/render.py +74 -35
  45. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/schema.py +18 -0
  46. spolvero-0.5.0/src/spolvero/schemas/layout-patch.schema.json +58 -0
  47. {spolvero-0.4.0 → spolvero-0.5.0}/tests/_review_toolkit.py +77 -0
  48. spolvero-0.5.0/tests/fixtures/reviewed-connectors.vsdx +0 -0
  49. {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/reviewed-simple.vsdx +0 -0
  50. {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_cli_detect_drift.py +88 -0
  51. spolvero-0.5.0/tests/test_cli_extract_layout.py +66 -0
  52. spolvero-0.5.0/tests/test_drift_detection.py +591 -0
  53. spolvero-0.5.0/tests/test_layout_extraction.py +195 -0
  54. {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_layout_patch.py +106 -0
  55. spolvero-0.5.0/tests/test_render_with_overrides.py +175 -0
  56. spolvero-0.5.0/tests/test_review_toolkit.py +209 -0
  57. spolvero-0.5.0/tests/test_roundtrip_review.py +224 -0
  58. {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_vsdx_template.py +55 -0
  59. spolvero-0.5.0/tests/validation/test_roundtrip_script_hardening.py +83 -0
  60. spolvero-0.5.0/tests/validation/test_skill_adapters.py +107 -0
  61. {spolvero-0.4.0 → spolvero-0.5.0}/uv.lock +20 -17
  62. spolvero-0.4.0/src/spolvero/schemas/layout-patch.schema.json +0 -28
  63. spolvero-0.4.0/tests/test_cli_extract_layout.py +0 -38
  64. spolvero-0.4.0/tests/test_drift_detection.py +0 -266
  65. spolvero-0.4.0/tests/test_layout_extraction.py +0 -72
  66. spolvero-0.4.0/tests/test_render_with_overrides.py +0 -49
  67. spolvero-0.4.0/tests/test_review_toolkit.py +0 -78
  68. spolvero-0.4.0/tests/validation/test_skill_adapters.py +0 -52
  69. {spolvero-0.4.0 → spolvero-0.5.0}/.gitattributes +0 -0
  70. {spolvero-0.4.0 → spolvero-0.5.0}/.github/CODEOWNERS +0 -0
  71. {spolvero-0.4.0 → spolvero-0.5.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  72. {spolvero-0.4.0 → spolvero-0.5.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  73. {spolvero-0.4.0 → spolvero-0.5.0}/.github/ISSUE_TEMPLATE/feature_engine_work.md +0 -0
  74. {spolvero-0.4.0 → spolvero-0.5.0}/.github/ISSUE_TEMPLATE/qa_hygiene_work.md +0 -0
  75. {spolvero-0.4.0 → spolvero-0.5.0}/.github/ISSUE_TEMPLATE/release_work.md +0 -0
  76. {spolvero-0.4.0 → spolvero-0.5.0}/.github/ISSUE_TEMPLATE/vsdx_template_work.md +0 -0
  77. {spolvero-0.4.0 → spolvero-0.5.0}/.github/copilot-instructions.md +0 -0
  78. {spolvero-0.4.0 → spolvero-0.5.0}/.github/dependabot.yml +0 -0
  79. {spolvero-0.4.0 → spolvero-0.5.0}/.github/pull_request_template.md +0 -0
  80. {spolvero-0.4.0 → spolvero-0.5.0}/AGENTS.md +0 -0
  81. {spolvero-0.4.0 → spolvero-0.5.0}/CLAUDE.md +0 -0
  82. {spolvero-0.4.0 → spolvero-0.5.0}/README.md +0 -0
  83. {spolvero-0.4.0 → spolvero-0.5.0}/SECURITY.md +0 -0
  84. {spolvero-0.4.0 → spolvero-0.5.0}/adapters/claude/.claude/skills/spolvero/SKILL.md +0 -0
  85. {spolvero-0.4.0 → spolvero-0.5.0}/adapters/claude/CLAUDE.md +0 -0
  86. {spolvero-0.4.0 → spolvero-0.5.0}/adapters/claude/INSTALL.md +0 -0
  87. {spolvero-0.4.0 → spolvero-0.5.0}/adapters/copilot/.github/copilot-instructions.md +0 -0
  88. {spolvero-0.4.0 → spolvero-0.5.0}/adapters/copilot/INSTALL.md +0 -0
  89. {spolvero-0.4.0 → spolvero-0.5.0}/adapters/generic/AGENTS.md +0 -0
  90. {spolvero-0.4.0 → spolvero-0.5.0}/docs/agent-usage.md +0 -0
  91. {spolvero-0.4.0 → spolvero-0.5.0}/docs/agents/architecture.md +0 -0
  92. {spolvero-0.4.0 → spolvero-0.5.0}/docs/agents/extending.md +0 -0
  93. {spolvero-0.4.0 → spolvero-0.5.0}/docs/agents/glossary.md +0 -0
  94. {spolvero-0.4.0 → spolvero-0.5.0}/docs/agents/recipes.md +0 -0
  95. {spolvero-0.4.0 → spolvero-0.5.0}/docs/declaratus-migration.md +0 -0
  96. {spolvero-0.4.0 → spolvero-0.5.0}/docs/feature-expansion/template-testing-lessons.md +0 -0
  97. {spolvero-0.4.0 → spolvero-0.5.0}/docs/plans/01-round-trip-drift-engine.md +0 -0
  98. {spolvero-0.4.0 → spolvero-0.5.0}/docs/qa-corpus-and-sanitization.md +0 -0
  99. {spolvero-0.4.0 → spolvero-0.5.0}/docs/qa-findings-plan.md +0 -0
  100. {spolvero-0.4.0 → spolvero-0.5.0}/docs/security-posture-audit.md +0 -0
  101. {spolvero-0.4.0 → spolvero-0.5.0}/docs/support-matrix.md +0 -0
  102. {spolvero-0.4.0 → spolvero-0.5.0}/docs/topology-ir.md +0 -0
  103. {spolvero-0.4.0 → spolvero-0.5.0}/docs/using-the-package.md +0 -0
  104. {spolvero-0.4.0 → spolvero-0.5.0}/docs/vsdx-template-contract.md +0 -0
  105. {spolvero-0.4.0 → spolvero-0.5.0}/skills/codex/spolvero/agents/openai.yaml +0 -0
  106. {spolvero-0.4.0 → spolvero-0.5.0}/skills/codex/spolvero/references/support-matrix.md +0 -0
  107. {spolvero-0.4.0 → spolvero-0.5.0}/skills/codex/spolvero/scripts/spolvero_packager.py +0 -0
  108. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/__init__.py +0 -0
  109. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/engines/data_visualizer.py +0 -0
  110. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/engines/package_only.py +0 -0
  111. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/engines/visio_com.py +0 -0
  112. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/inspection.py +0 -0
  113. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/ir.py +0 -0
  114. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/models.py +0 -0
  115. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/reports.py +0 -0
  116. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/schemas/__init__.py +0 -0
  117. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/schemas/ir.schema.json +0 -0
  118. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/schemas/manifest.schema.json +0 -0
  119. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/schemas/topology.schema.json +0 -0
  120. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/source.py +0 -0
  121. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/stamping.py +0 -0
  122. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/templates/LICENSE.txt +0 -0
  123. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/templates/minimal_flowchart.vsdx +0 -0
  124. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/topology/__init__.py +0 -0
  125. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/topology/model.py +0 -0
  126. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/utils.py +0 -0
  127. {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/workbook.py +0 -0
  128. {spolvero-0.4.0 → spolvero-0.5.0}/tests/__init__.py +0 -0
  129. {spolvero-0.4.0 → spolvero-0.5.0}/tests/_paths.py +0 -0
  130. {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/sample-network.topology.yaml +0 -0
  131. {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/sample-sequence.mmd +0 -0
  132. {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/sample-trd.topology.json +0 -0
  133. {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/sample.dot +0 -0
  134. {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/sample.md +0 -0
  135. {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/sample.png +0 -0
  136. {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/sample.puml +0 -0
  137. {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/sample.svg +0 -0
  138. {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/simple.mmd +0 -0
  139. {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/synthetic-rich.mmd +0 -0
  140. {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_cli.py +0 -0
  141. {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_engine_registry.py +0 -0
  142. {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_extraction.py +0 -0
  143. {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_hygiene.py +0 -0
  144. {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_mermaid_ir.py +0 -0
  145. {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_optional_tools.py +0 -0
  146. {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_package_build.py +0 -0
  147. {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_stamping.py +0 -0
  148. {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_topology_ir.py +0 -0
  149. {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_visio_com.py +0 -0
  150. {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_vsdx_inspection.py +0 -0
  151. {spolvero-0.4.0 → spolvero-0.5.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
@@ -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,7 +12,7 @@ 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:
@@ -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.4.0 is tagged and published to PyPI. Connector-endpoint drift and edge routes are merged (PR #61); the 0.5.0 version bump is staged, and the `v0.5.0` tag/publish should follow once the bump is merged.
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,19 @@ 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 and connector
66
+ endpoints into a YAML layout patch (`patch_schema_version: 2`) keyed by
67
+ `spolvero.source_id`.
68
+ 3. `spolvero detect-drift` runs the D1–D5 detectors against the source IR
69
+ (D5 connector-endpoint drift landed with spec 03 / DEC-169).
70
+ 4. `spolvero build --layout-patch` regenerates while honouring reviewer
71
+ layout, including connector endpoint routes.
67
72
 
68
73
  Follow-ups:
69
74
 
70
75
  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
76
+ 2. The residual engine scope is tracked in Linear on the Visio Renderer
77
+ initiative: waypoint/polyline route geometry, container/topology shape
78
+ stamping and multi-diagram patch-to-diagram matching, manual annotations,
79
+ and a consumer CI recipe (see the MVP limitations in
75
80
  `docs/round-trip-workflow.md`).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spolvero
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: Package docs-as-code diagrams into Visio-friendly handoff artifacts.
5
5
  Author: Spolvero maintainers
6
6
  License: MIT
@@ -0,0 +1,46 @@
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 / D4 revision mismatch) —
36
+ HALT before PR preparation; show `validation-report.md` and let a human
37
+ decide.
38
+ - Exit 2: usage/environment error. Usage and environment stops leave nothing
39
+ valid; the "not a round-trip candidate" stop (no `spolvero.*` stamps) leaves
40
+ `coverage.json` and `drift.*` as evidence of the rejection.
41
+ - If the `.vsdx` came from outside the repo, run `spolvero inspect-vsdx`
42
+ (read-only) first and surface sensitive-pattern findings.
43
+ - Never merge, never push to a protected branch, never commit a reviewed
44
+ `.vsdx` binary. No COM automation.
45
+
46
+ 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
+
@@ -0,0 +1,146 @@
1
+ # Artifact governance policy
2
+
3
+ Date: 2026-07-05
4
+ Status: Policy (DEC-67)
5
+ Related: DEC-66 (`docs/research/artifact-governance.md` — the research this
6
+ policy adopts), DEC-104, `docs/specs/01-round-trip-drift-engine.md` §13.
7
+
8
+ ## Scope
9
+
10
+ This is the normative policy for every artifact the round-trip workflow
11
+ touches: what's committed, what's local-only, where it lives, and how long
12
+ it's kept. `docs/research/artifact-governance.md` is background — it
13
+ compares options and explains why. This document states the decision. Where
14
+ the two disagree, this document wins.
15
+
16
+ The organizing principle: **an artifact only gets a durable home if it can't
17
+ be rebuilt from committed source plus a committed patch.** Everything that
18
+ passes that test stays local and ephemeral, no matter how convenient a
19
+ storage mechanism might seem. Everything that fails it gets the lightest
20
+ retention that closes the actual gap, not the most convenient one.
21
+
22
+ ## Reviewed `.vsdx` binaries
23
+
24
+ Never committed. A reviewer's Visio session produces a reviewed `.vsdx`
25
+ locally; it lives at `layouts/reviewed/<diagram>.vsdx` and is gitignored.
26
+
27
+ - Do not stage a reviewed `.vsdx` under any prompt, any workflow, any
28
+ exception.
29
+ - Discard the file once `extract-layout` has produced the patch and
30
+ `detect-drift` has produced the drift report. The patch and drift report
31
+ are the durable record of the review session — not the binary.
32
+ - If a reviewer's edit needs a provenance trail beyond what the patch format
33
+ captures (waypoint/polyline routing, anything below the D1-D5 detectors'
34
+ coverage), retain the file in the org's existing M365 storage
35
+ (SharePoint/OneDrive) and record the link in the PR body. This is a
36
+ human-maintained pointer, not a spolvero-managed artifact, and it's the
37
+ exception, not routine practice.
38
+ - No Git LFS, no GitHub Releases, no dedicated artifacts repo for this
39
+ class. None of them improve reproducibility over the patch + report pair,
40
+ and all of them default to permanent retention where the actual need is a
41
+ single review cycle.
42
+
43
+ ## Layout patches
44
+
45
+ Committed. `layouts/<diagram>.layout.yml`, alongside the source diagram,
46
+ tracked in git as long as the diagram exists.
47
+
48
+ - This is the canonical, durable output of a review session. It's text,
49
+ small, and diffable — treat it the same as any other reviewed source
50
+ change.
51
+ - Keyed by `spolvero.source_id`; carries `source_revision` pinning it to the
52
+ doc-level `spolvero.source_hash` at extraction time. Don't hand-edit a
53
+ patch to work around a stale `source_revision` — re-extract instead.
54
+ - Lives alongside the diagram it patches, not in a separate patches
55
+ directory or branch.
56
+
57
+ ## Drift reports
58
+
59
+ Committed, in the same PR as the patch it describes.
60
+
61
+ - `drift.md` / `drift.json` (or the repo's chosen report location, e.g.
62
+ `docs/reviews/<diagram>-drift.md`) travel with the patch, not separately
63
+ and not later.
64
+ - This is the durable record of what the reviewed `.vsdx` actually
65
+ contained, once that file is gone. It captures findings, not the file
66
+ itself — that asymmetry is accepted, not a gap to close with binary
67
+ retention.
68
+ - The PR body states drift status explicitly (summary line, any medium
69
+ findings verbatim) and coverage counts, per
70
+ `skills/codex/spolvero-roundtrip/references/pr-preparation.md`. The
71
+ report and the PR body are complementary, not redundant — don't drop one
72
+ because the other exists.
73
+ - Reviewer identity is not a spolvero-managed field today. Record it in the
74
+ PR body (author, or an explicit "reviewed by" line if review and
75
+ PR-authoring are different people). This is a documentation habit, not a
76
+ new stamp or schema field.
77
+
78
+ ## Generated handoff packages
79
+
80
+ Never committed. `manifest.json`, `README.md`, `source/`, `normalized/`,
81
+ `preview/`, `visio/`, `qa/` — the full output of `spolvero build` — lives
82
+ under `.tmp/` and nowhere else.
83
+
84
+ - Fully reproducible from committed source plus a committed patch. A
85
+ package holds no information a rebuild can't recreate, so it never earns
86
+ a storage mechanism of its own.
87
+ - Regenerate on demand for inspection; don't keep stale builds around
88
+ in-tree or out-of-tree.
89
+ - The one narrow exception: if a built package needs to reach someone who
90
+ isn't running the build themselves, use CI workflow artifacts with a
91
+ short retention window (7-14 days), not git, LFS, or Releases. Don't
92
+ stand this up preemptively — wire it only when that need actually shows
93
+ up.
94
+
95
+ ## Regenerated previews
96
+
97
+ Committed only as updates to already-tracked docs assets, never as new
98
+ tracked paths.
99
+
100
+ - If `docs/diagrams/<diagram>.svg` (or equivalent) is already tracked,
101
+ copy the refreshed render over it and include it in the review PR.
102
+ - If a diagram has no existing tracked preview, its rebuilt preview stays
103
+ in `.tmp/` with the rest of the package. Don't introduce a new tracked
104
+ preview path as a side effect of a layout review.
105
+ - Note the mmdc-rendered preview does not reflect layout patches (see
106
+ `docs/round-trip-workflow.md` MVP limitations) — don't treat an
107
+ mmdc-rendered SVG as authoritative for reviewer-applied positions.
108
+
109
+ ## The bundled template
110
+
111
+ `src/spolvero/templates/minimal_flowchart.vsdx` is the single sanctioned
112
+ exception to "no committed binaries," and it stays singular by default.
113
+
114
+ - Permanent, tracked, ~20 KB. It exists because the engine needs some stamp
115
+ template to ship runnable, not because binaries are generally welcome in
116
+ this repo.
117
+ - Provenance is mandatory and already set as precedent: derived from the
118
+ BSD 3-Clause-licensed `vsdx` Python library's test fixture, license and
119
+ origin recorded in `src/spolvero/templates/LICENSE.txt`.
120
+ - Any future second tracked `.vsdx` (richer templates, DEC-104 follow-on
121
+ work) requires the same treatment before it's added: documented origin,
122
+ compatible license, and an entry in `LICENSE.txt` (or an equivalent
123
+ provenance file) alongside it. A second template without that paperwork
124
+ is not an incremental addition, it's a policy exception, and needs the
125
+ same scrutiny this one got.
126
+ - This exception does not generalize. It justifies exactly the templates
127
+ that go through this process, not a broader allowance for committing
128
+ `.vsdx` files elsewhere in the repo. Committed test fixtures are the one
129
+ other carve-out, below.
130
+
131
+ ## Test fixtures
132
+
133
+ Checked-in adversarial `.vsdx` fixtures under `tests/fixtures/` are
134
+ sanctioned — `reviewed-simple.vsdx` has been tracked since spec 01, and
135
+ spec 03 adds `reviewed-connectors.vsdx`. They are not reviewer output and
136
+ the "reviewed `.vsdx` binaries are never committed" rule does not apply to
137
+ them: they are generated headlessly from tracked sources by
138
+ `tests/_review_toolkit.py` (spec 01 §11's stand-in for a Visio session) and
139
+ committed so end-to-end tests are reproducible without regenerating on
140
+ every CI run.
141
+
142
+ - Each committed fixture's regeneration recipe is documented in the introducing spec/plan checklist, and should be mirrored in the test file that consumes it.
143
+ - Fixtures stay small (tens of KB) and are only added when a spec's test
144
+ strategy calls for one — not as a convenience for ad-hoc test data.
145
+ - Real reviewer output never becomes a fixture; fixtures are fabricated
146
+ from tracked sources so they carry nothing a reviewer produced.
@@ -0,0 +1,209 @@
1
+ # Consumer CI: drift-gating recipe
2
+
3
+ A recipe for gating pull requests in a *consumer* repo (one that uses
4
+ spolvero to generate Visio handoff packages, not spolvero itself) on the
5
+ round-trip drift engine. See `docs/round-trip-workflow.md` for the CLI
6
+ shapes referenced below, `docs/specs/01-round-trip-drift-engine.md` §7 for
7
+ D1–D4 semantics, and `docs/specs/03-connector-endpoint-drift.md` §7 for D5.
8
+
9
+ ## 1. What the gate is
10
+
11
+ `spolvero detect-drift` exits non-zero when any **high-severity** finding is
12
+ present:
13
+
14
+ - **D1** — source-owned shape or connector deleted from the reviewed VSDX.
15
+ - **D4** — doc-level source-hash no longer matches the `--source` file.
16
+ - **D5** (`endpoint_repointed`) — a connector endpoint re-pointed at a
17
+ different source-owned node.
18
+
19
+ Medium findings (**D2** invalid/missing metadata, **D3** label changed,
20
+ **D5** `endpoint_dangling`) are reported but exit 0 — they're
21
+ recommendations for a human reviewer, not blockers. That non-zero-on-high exit is the CI gate: wire it into a required
22
+ check and a round-trip review PR cannot merge with undetected shape deletions
23
+ or a stale source revision. Exit codes are enumerated in §4; note that runtime
24
+ errors (missing inputs, missing `vsdx` extra) also exit 1, distinguishable
25
+ from a drift failure by the absence of a written report.
26
+
27
+ ## 2. The artifact-availability problem, stated honestly
28
+
29
+ Reviewed `.vsdx` binaries are never committed — that's the repo convention
30
+ (`docs/round-trip-workflow.md`, "Suggested file conventions"). A round-trip
31
+ review PR carries the layout patch (`layouts/<diagram>.layout.yml`) and,
32
+ when a review run produced one, the drift report (`drift.md` / `drift.json`)
33
+ — not the reviewed binary. That means a consumer CI job **cannot always
34
+ re-run `detect-drift` itself**: the input it needs may simply not be in the
35
+ PR.
36
+
37
+ Two patterns cover the two situations:
38
+
39
+ ### Pattern A — gate on the committed drift report (default)
40
+
41
+ Works with the repo convention as-is, no extra plumbing. CI validates the
42
+ committed `drift.json` instead of regenerating it: fail if
43
+ `summary.high > 0`, and fail if a layout patch changed but no drift report
44
+ came with it (a PR that touches `layouts/**` without evidence a drift check
45
+ ran is treated as ungated, not as clean).
46
+
47
+ ```bash
48
+ # fail if the committed report shows any high-severity finding
49
+ python -c "
50
+ import json, sys
51
+ report = json.load(open('drift.json'))
52
+ high = report['summary']['high']
53
+ print(f\"drift: {report['summary']['total']} finding(s), {high} high\")
54
+ sys.exit(1 if high > 0 else 0)
55
+ "
56
+ ```
57
+
58
+ Equivalent with `jq`:
59
+
60
+ ```bash
61
+ high=$(jq '.summary.high' drift.json)
62
+ echo "drift: $high high-severity finding(s)"
63
+ test "$high" -eq 0
64
+ ```
65
+
66
+ ### Pattern B — full re-run when the reviewed file is supplied out of band
67
+
68
+ When the reviewed `.vsdx` *is* available to the runner — fetched as a
69
+ workflow artifact from an upstream job, or pulled from wherever reviewed
70
+ files are parked — CI can rebuild the package from committed source and run
71
+ `detect-drift` directly, the same way a local review run would. This repo
72
+ stays agnostic about *where* that file comes from: an artifact-governance
73
+ policy for reviewed binaries is being drafted separately (DEC-66/67). Until
74
+ that lands, treat Pattern B as opt-in and gated on the file's presence, not
75
+ as the default path.
76
+
77
+ ## 3. Worked GitHub Actions workflow
78
+
79
+ Drop this in a **consumer** repo (not spolvero) as
80
+ `.github/workflows/drift-gate.yml`. Pattern A runs unconditionally as the
81
+ required check; Pattern B runs only when a reviewed `.vsdx` is present,
82
+ e.g. dropped at `layouts/reviewed/<diagram>.vsdx` by an earlier job or a
83
+ manual upload — see `docs/round-trip-workflow.md` for the convention.
84
+
85
+ ```yaml
86
+ name: Drift gate
87
+
88
+ on:
89
+ pull_request:
90
+ paths:
91
+ - "diagrams/**"
92
+ - "layouts/**"
93
+
94
+ permissions:
95
+ contents: read
96
+
97
+ jobs:
98
+ # Pattern A: validate the committed drift report. Required check.
99
+ gate-on-report:
100
+ runs-on: ubuntu-latest
101
+ steps:
102
+ - uses: actions/checkout@v7
103
+ with:
104
+ # full history so the base branch is available for the diff below
105
+ fetch-depth: 0
106
+
107
+ - name: Require a drift report alongside a layout patch change
108
+ run: |
109
+ if git diff --name-only "origin/${{ github.base_ref }}"...HEAD | grep -q '^layouts/.*\.layout\.yml$'; then
110
+ test -f drift.json || { echo "layout patch changed but drift.json is missing"; exit 1; }
111
+ fi
112
+
113
+ - name: Fail on high-severity drift
114
+ run: |
115
+ if [ -f drift.json ]; then
116
+ high=$(python -c "import json; print(json.load(open('drift.json'))['summary']['high'])")
117
+ echo "drift: $high high-severity finding(s)"
118
+ test "$high" -eq 0
119
+ fi
120
+
121
+ # Pattern B: full re-run, only when the reviewed .vsdx is available to the runner.
122
+ gate-on-rerun:
123
+ runs-on: ubuntu-latest
124
+ steps:
125
+ - uses: actions/checkout@v7
126
+
127
+ - uses: actions/setup-python@v6
128
+ with:
129
+ python-version: "3.13"
130
+
131
+ - name: Check for reviewed .vsdx
132
+ id: reviewed
133
+ run: |
134
+ if [ -f "layouts/reviewed/diagram-001.vsdx" ]; then
135
+ echo "present=true" >> "$GITHUB_OUTPUT"
136
+ else
137
+ echo "present=false" >> "$GITHUB_OUTPUT"
138
+ fi
139
+
140
+ - name: Install spolvero
141
+ if: steps.reviewed.outputs.present == 'true'
142
+ run: pip install "spolvero[vsdx]>=0.4,<0.5"
143
+
144
+ - name: Rebuild from source
145
+ if: steps.reviewed.outputs.present == 'true'
146
+ run: >
147
+ spolvero build diagrams/architecture.md --out .tmp/handoff
148
+ --target vsdx-template
149
+
150
+ - name: Detect drift against the reviewed file
151
+ if: steps.reviewed.outputs.present == 'true'
152
+ run: >
153
+ spolvero detect-drift .tmp/handoff/normalized/diagram-001.ir.json
154
+ layouts/reviewed/diagram-001.vsdx
155
+ --report drift.md --json drift.json
156
+ --source diagrams/architecture.md
157
+
158
+ - name: Upload drift reports on failure
159
+ if: failure() && steps.reviewed.outputs.present == 'true'
160
+ uses: actions/upload-artifact@v4
161
+ with:
162
+ name: drift-reports
163
+ path: |
164
+ drift.md
165
+ drift.json
166
+ ```
167
+
168
+ Adjust `diagrams/architecture.md`, `diagram-001`, and the `paths:` filter to
169
+ match the consumer repo's own source layout. The `.tmp/` output directory
170
+ and `--source`/`--diagram` flags follow the exact CLI shape in
171
+ `src/spolvero/cli.py`; nothing here is inferred.
172
+
173
+ ## 4. Exit-code reference
174
+
175
+ | Code | Meaning | CI action |
176
+ |---|---|---|
177
+ | 0 | Clean, or medium (D2/D3/D5-dangling) findings only | Pass. |
178
+ | 1 | High-severity finding present (D1, D4, or D5-repointed), **or** a runtime error: missing IR/`.vsdx`/source input, `vsdx` extra not installed | Fail the check. |
179
+ | 2 | Usage error (unknown flag, missing required argument; argparse's exit) | Fail the check; pipeline problem, not a drift finding. |
180
+
181
+ The two exit-1 causes are distinguishable by the report: a genuine drift
182
+ failure writes `drift.md`/`drift.json` and prints a findings summary to
183
+ stderr before exiting; a runtime error prints the error and writes nothing.
184
+ A job that needs to tell them apart should check for `drift.json` after a
185
+ failure — the upload-artifact step in the worked example above surfaces
186
+ exactly that difference.
187
+
188
+ ## 5. What to do when the gate fires
189
+
190
+ - **D4 (source-revision mismatch).** The reviewed `.vsdx` was built from a
191
+ source revision that no longer matches HEAD. Regenerate the handoff
192
+ package from current source and have the reviewer redo their edits
193
+ against the new file before re-submitting; don't try to patch around a
194
+ stale D4.
195
+ - **D1 (source-owned shape or connector deleted).** A shape or connector the
196
+ source still defines was removed in the reviewed file. Either restore it
197
+ in Visio and re-extract the layout, or, if the deletion was deliberate,
198
+ remove the node or edge from source first so the next build no longer
199
+ emits it, then redo the review round-trip.
200
+ - **D5 (`endpoint_repointed`).** A connector endpoint was re-anchored at a
201
+ different source-owned node in the reviewed file. Update the source edge
202
+ if the new relationship is intended; otherwise re-anchor the connector in
203
+ Visio and re-extract.
204
+ - **D2/D3/D5-dangling (medium).** These don't fail the gate but should still
205
+ be quoted in the review PR's body — a human decides whether an untracked
206
+ shape (D2), a relabeled one (D3), or a connector endpoint left floating
207
+ (D5 `endpoint_dangling`) is intentional. Teams using the spolvero-roundtrip
208
+ agent skill get this quoting automatically as part of its PR preparation
209
+ flow.
@@ -1,24 +1,24 @@
1
1
  # Current State
2
2
 
3
- Snapshot of the `spolvero` package after the v0.3.0 release and Declaratus import.
3
+ Snapshot of the `spolvero` package after the round-trip/drift engine merge and the 0.4.0 version bump.
4
4
 
5
5
  ## Version
6
6
 
7
- - Package: `spolvero` 0.3.0
7
+ - Package: `spolvero` 0.4.0 (version bump merged in PR #49; the `v0.4.0` tag and PyPI publish are pending)
8
8
  - Schema version: `1.0.0` (manifest, IR, topology IR)
9
- - Local validation on this Windows / Python 3.14 host: 61 passed, 5 skipped. Hosted CI runs Linux/Windows on Python 3.11 and 3.13; skip counts vary by optional tools and extras.
9
+ - Local validation on this Windows / Python 3.14 host: 108 passed, 16 skipped. Hosted CI runs Linux/Windows on Python 3.11 and 3.13; skip counts vary by optional tools and extras.
10
10
 
11
11
  ## Governance / Operations
12
12
 
13
13
  - Repository: `Declaratus/spolvero`
14
- - Release baseline: `v0.3.0`
14
+ - Release baseline: `v0.3.0`; the 0.4.0 version bump is merged and awaiting the `v0.4.0` tag and PyPI publish.
15
15
  - Current governance track: post-import operations and follow-up security hardening.
16
16
  - Custom properties: `tier=internal`, `data-classification=internal`, `lifecycle-stage=active`; owner assignment is managed in the governance source of truth.
17
17
  - CI runs the Linux/Windows Python 3.11/3.13 matrix and exposes `ci-summary` as the aggregate check for Declaratus org ruleset readiness.
18
18
  - Repo-local branch protection is disabled. Default-branch policy is enforced through Declaratus org rulesets after `ci-summary` proved green.
19
19
  - Active governance rulesets applying to Spolvero include `tier-internal` (default-branch PR policy and required `ci-summary`), `tag-all-tiers`, and `push-internal-baseline`.
20
20
  - CODEOWNERS routes release workflows, package metadata, schemas, bundled template assets, agent adapters, and core package code to the current owner handle until a Declaratus maintainer team exists.
21
- - Root `SECURITY.md`, issue/PR templates, Dependabot updates, and the security posture audit are in place. Follow-ups #30, #31, and #32 track release environment protection, Python audit tooling, and Code Security/code scanning.
21
+ - Root `SECURITY.md`, issue/PR templates, Dependabot updates, and the security posture audit are in place. Follow-ups #30, #31, and #32 (release environment protection, Python audit tooling, Code Security/code scanning) are closed; the `pypi` environment is restricted to `v*` release tags and CodeQL/dependency-review workflows are active.
22
22
 
23
23
  ## What Works
24
24
 
@@ -31,7 +31,7 @@ Every declared input type produces a valid handoff package without crashing. The
31
31
  - `normalized/<id>.ir.json` — normalized IR (validated before write)
32
32
  - `preview/<id>.{svg,png}` — always generated
33
33
  - `visio/<id>-data-visualizer.xlsx` — Mermaid flowcharts, valid JSON topology/TRD inputs, and valid YAML topology/TRD inputs when PyYAML is installed
34
- - `visio/<id>.vsdx` — supported flowchart/topology IRs when `[vsdx]` is installed and the template satisfies the stamp contract
34
+ - `visio/<id>.vsdx` — supported flowchart/topology IRs when `[vsdx]` is installed and the template satisfies the stamp contract; node and connector shapes carry `spolvero.*` source-metadata stamps and `docProps/custom.xml` records the source hash (see [vsdx-template-contract.md](vsdx-template-contract.md))
35
35
  - `visio/<id>-template-notes.md` — per-diagram template guidance
36
36
  - `qa/<id>-qa.md` and `qa/<id>-conversion-log.json`
37
37
  - `README.md` — package overview
@@ -105,6 +105,14 @@ Slashes from parallelogram `[/.../]` are stripped from the label.
105
105
  - Generated IR and manifests are schema-validated before write; internal schema drift fails fast with a clear error.
106
106
  - `template-notes.md` recommends Cross-Functional Flowchart vs. Basic Flowchart based on whether the IR has containers.
107
107
 
108
+ ### Round-trip layout and drift tooling
109
+
110
+ - Every `vsdx-template` build stamps source metadata: per-shape `spolvero.*` Visio Shape Data keys plus doc-level `docProps/custom.xml` entries including the source hash, per [vsdx-template-contract.md](vsdx-template-contract.md).
111
+ - `spolvero extract-layout` lifts reviewer node positions and connector begin/end endpoints from a reviewed `.vsdx` into a YAML layout patch (`patch_schema_version: 2`) keyed by `spolvero.source_id`. Requires the `[vsdx]` extra.
112
+ - `spolvero detect-drift` runs the D1–D5 detectors against the source IR and compares the doc-level source hash against `--source`; it exits non-zero on high-severity findings (D1 deleted shape or connector, D4 source-hash mismatch, D5 re-pointed connector endpoint). Requires the `[vsdx]` extra.
113
+ - `spolvero build --layout-patch` regenerates a package while honouring reviewer positions; patched node x/y and connector endpoints apply to the VSDX and the built-in preview. v1 (node-only) patches still load and apply.
114
+ - See [round-trip-workflow.md](round-trip-workflow.md) for the end-to-end flow and MVP limitations.
115
+
108
116
  ### Governance and repository hygiene tooling
109
117
 
110
118
  - `spolvero hygiene` scans tracked files for governance-sensitive patterns, generated package artifacts, stray workbooks, and unapproved `.vsdx` templates. Use `--include-untracked` only for intentional local workspace review.
@@ -119,6 +127,7 @@ Slashes from parallelogram `[/.../]` are stripped from the label.
119
127
  | Engines | TODO: higher-fidelity synthetic templates | The engine now documents preferred flowchart/topology/container stamp names and warns on degradation, but the bundled template remains intentionally minimal. |
120
128
  | Engines | TODO: `visio-com` native body | The Windows-only path currently delegates to downstream engines and preserves delegated editability. A fully COM-driven shape/connector pass is a future iteration and should be the only path that emits `native`. |
121
129
  | QA / safety | TODO: external corpus automation | Read-only inspection and opt-in XML sanitization are implemented. External corpus manifests, license approvals, and media/OCR automation remain outside tracked source until explicitly approved. |
130
+ | Round-trip | Residual engine scope | Waypoint/polyline route geometry, container/topology shape stamping, multi-diagram patch-to-diagram matching, and manual annotations are deferred (see the MVP limitations in [round-trip-workflow.md](round-trip-workflow.md)); tracked in Linear on the Visio Renderer initiative. |
122
131
  | Workbook metadata | Mermaid metadata columns | Mermaid carries no `Phase`, `System`, `Owner`, or `Criticality` metadata; topology nodes can populate them via `metadata`. |
123
132
 
124
133
  ## Roadmap
@@ -134,16 +143,22 @@ Major engineering items now landed:
134
143
 
135
144
  7. Declaratus import, post-import operating docs, repository hygiene gate, read-only VSDX inspector, and opt-in sanitization helper.
136
145
 
146
+ 8. ✅ Round-trip layout and drift engine (spec 01): source-metadata stamping, `extract-layout`, `detect-drift`, and `build --layout-patch` (PRs #43/#44).
147
+
148
+ 9. ✅ Connector-endpoint drift and edge-route geometry (spec 03, DEC-169): D5 detector with glue read-through, layout patch v2 with edge routes, and edge overrides on both rebuild surfaces.
149
+
137
150
  Next-up TODO areas:
138
151
 
139
152
  - Hand-rolled `.vsdx` body in the visio-com engine (true native shapes/connectors when Visio is reachable).
140
153
  - Higher-fidelity synthetic templates for flowchart/topology stamps beyond the bundled minimal fixture.
141
154
  - External corpus harnesses and media/OCR review workflows as post-release security/QA work.
155
+ - Residual round-trip scope (waypoint/polyline routes, container/topology stamping, multi-diagram patch matching, manual annotations, consumer CI recipe), tracked in Linear on the Visio Renderer initiative.
142
156
 
143
157
  ## References
144
158
 
145
159
  - [support-matrix.md](support-matrix.md)
146
160
  - [vsdx-template-contract.md](vsdx-template-contract.md)
161
+ - [round-trip-workflow.md](round-trip-workflow.md)
147
162
  - [qa-corpus-and-sanitization.md](qa-corpus-and-sanitization.md)
148
163
  - [qa-findings-plan.md](qa-findings-plan.md)
149
164
  - [agent-usage.md](agent-usage.md)