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.
- {spolvero-0.4.0 → spolvero-0.5.0}/.github/instructions/spolvero.instructions.md +2 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/.github/workflows/ci.yml +3 -3
- {spolvero-0.4.0 → spolvero-0.5.0}/.github/workflows/codeql.yml +1 -1
- {spolvero-0.4.0 → spolvero-0.5.0}/.github/workflows/dependency-review.yml +2 -2
- {spolvero-0.4.0 → spolvero-0.5.0}/.github/workflows/release.yml +1 -1
- {spolvero-0.4.0 → spolvero-0.5.0}/.gitignore +1 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/HANDOFF.md +16 -11
- {spolvero-0.4.0 → spolvero-0.5.0}/PKG-INFO +1 -1
- spolvero-0.5.0/adapters/claude/.claude/skills/spolvero-roundtrip/SKILL.md +46 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/adapters/copilot/.github/instructions/spolvero.instructions.md +2 -0
- spolvero-0.5.0/docs/artifact-governance.md +146 -0
- spolvero-0.5.0/docs/consumer-ci-recipe.md +209 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/docs/current-state.md +21 -6
- spolvero-0.5.0/docs/demos/round-trip/README.md +241 -0
- spolvero-0.5.0/docs/demos/round-trip/accepted/d1.layout.yml +21 -0
- spolvero-0.5.0/docs/demos/round-trip/accepted/drift.json +10 -0
- spolvero-0.5.0/docs/demos/round-trip/accepted/drift.md +11 -0
- spolvero-0.5.0/docs/demos/round-trip/rejected/drift.json +27 -0
- spolvero-0.5.0/docs/demos/round-trip/rejected/drift.md +23 -0
- spolvero-0.5.0/docs/plans/03-connector-endpoint-drift.md +264 -0
- spolvero-0.5.0/docs/research/artifact-governance.md +272 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/docs/round-trip-workflow.md +47 -18
- {spolvero-0.4.0 → spolvero-0.5.0}/docs/specs/01-round-trip-drift-engine.md +1 -1
- spolvero-0.5.0/docs/specs/02-visio-diagram-handoff-assistant-skill.md +125 -0
- spolvero-0.5.0/docs/specs/03-connector-endpoint-drift.md +194 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/pyproject.toml +1 -1
- {spolvero-0.4.0 → spolvero-0.5.0}/skills/codex/spolvero/SKILL.md +2 -0
- spolvero-0.5.0/skills/codex/spolvero-roundtrip/SKILL.md +66 -0
- spolvero-0.5.0/skills/codex/spolvero-roundtrip/agents/openai.yaml +4 -0
- spolvero-0.5.0/skills/codex/spolvero-roundtrip/references/coverage-and-drift.md +71 -0
- spolvero-0.5.0/skills/codex/spolvero-roundtrip/references/pr-preparation.md +53 -0
- spolvero-0.5.0/skills/codex/spolvero-roundtrip/references/workflow.md +87 -0
- spolvero-0.5.0/skills/codex/spolvero-roundtrip/scripts/roundtrip_review.py +406 -0
- spolvero-0.5.0/src/spolvero/__main__.py +6 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/builder.py +14 -1
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/cli.py +28 -8
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/constants.py +1 -1
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/drift_detection.py +175 -11
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/engines/__init__.py +1 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/engines/vsdx_template.py +10 -3
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/hygiene.py +1 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/layout_extraction.py +65 -11
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/layout_patch.py +38 -3
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/render.py +74 -35
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/schema.py +18 -0
- spolvero-0.5.0/src/spolvero/schemas/layout-patch.schema.json +58 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/_review_toolkit.py +77 -0
- spolvero-0.5.0/tests/fixtures/reviewed-connectors.vsdx +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/reviewed-simple.vsdx +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_cli_detect_drift.py +88 -0
- spolvero-0.5.0/tests/test_cli_extract_layout.py +66 -0
- spolvero-0.5.0/tests/test_drift_detection.py +591 -0
- spolvero-0.5.0/tests/test_layout_extraction.py +195 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_layout_patch.py +106 -0
- spolvero-0.5.0/tests/test_render_with_overrides.py +175 -0
- spolvero-0.5.0/tests/test_review_toolkit.py +209 -0
- spolvero-0.5.0/tests/test_roundtrip_review.py +224 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_vsdx_template.py +55 -0
- spolvero-0.5.0/tests/validation/test_roundtrip_script_hardening.py +83 -0
- spolvero-0.5.0/tests/validation/test_skill_adapters.py +107 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/uv.lock +20 -17
- spolvero-0.4.0/src/spolvero/schemas/layout-patch.schema.json +0 -28
- spolvero-0.4.0/tests/test_cli_extract_layout.py +0 -38
- spolvero-0.4.0/tests/test_drift_detection.py +0 -266
- spolvero-0.4.0/tests/test_layout_extraction.py +0 -72
- spolvero-0.4.0/tests/test_render_with_overrides.py +0 -49
- spolvero-0.4.0/tests/test_review_toolkit.py +0 -78
- spolvero-0.4.0/tests/validation/test_skill_adapters.py +0 -52
- {spolvero-0.4.0 → spolvero-0.5.0}/.gitattributes +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/.github/CODEOWNERS +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/.github/ISSUE_TEMPLATE/feature_engine_work.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/.github/ISSUE_TEMPLATE/qa_hygiene_work.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/.github/ISSUE_TEMPLATE/release_work.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/.github/ISSUE_TEMPLATE/vsdx_template_work.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/.github/copilot-instructions.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/.github/dependabot.yml +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/.github/pull_request_template.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/AGENTS.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/CLAUDE.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/README.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/SECURITY.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/adapters/claude/.claude/skills/spolvero/SKILL.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/adapters/claude/CLAUDE.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/adapters/claude/INSTALL.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/adapters/copilot/.github/copilot-instructions.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/adapters/copilot/INSTALL.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/adapters/generic/AGENTS.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/docs/agent-usage.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/docs/agents/architecture.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/docs/agents/extending.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/docs/agents/glossary.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/docs/agents/recipes.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/docs/declaratus-migration.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/docs/feature-expansion/template-testing-lessons.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/docs/plans/01-round-trip-drift-engine.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/docs/qa-corpus-and-sanitization.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/docs/qa-findings-plan.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/docs/security-posture-audit.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/docs/support-matrix.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/docs/topology-ir.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/docs/using-the-package.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/docs/vsdx-template-contract.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/skills/codex/spolvero/agents/openai.yaml +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/skills/codex/spolvero/references/support-matrix.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/skills/codex/spolvero/scripts/spolvero_packager.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/__init__.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/engines/data_visualizer.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/engines/package_only.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/engines/visio_com.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/inspection.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/ir.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/models.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/reports.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/schemas/__init__.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/schemas/ir.schema.json +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/schemas/manifest.schema.json +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/schemas/topology.schema.json +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/source.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/stamping.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/templates/LICENSE.txt +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/templates/minimal_flowchart.vsdx +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/topology/__init__.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/topology/model.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/utils.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/src/spolvero/workbook.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/__init__.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/_paths.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/sample-network.topology.yaml +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/sample-sequence.mmd +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/sample-trd.topology.json +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/sample.dot +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/sample.md +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/sample.png +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/sample.puml +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/sample.svg +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/simple.mmd +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/fixtures/synthetic-rich.mmd +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_cli.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_engine_registry.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_extraction.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_hygiene.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_mermaid_ir.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_optional_tools.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_package_build.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_stamping.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_topology_ir.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_visio_com.py +0 -0
- {spolvero-0.4.0 → spolvero-0.5.0}/tests/test_vsdx_inspection.py +0 -0
- {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@
|
|
22
|
-
- uses: astral-sh/setup-uv@
|
|
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@
|
|
25
|
+
- uses: actions/setup-python@v6
|
|
26
26
|
with:
|
|
27
27
|
python-version: ${{ matrix.python-version }}
|
|
28
28
|
- name: Compile
|
|
@@ -12,9 +12,9 @@ jobs:
|
|
|
12
12
|
runs-on: ubuntu-latest
|
|
13
13
|
timeout-minutes: 10
|
|
14
14
|
steps:
|
|
15
|
-
- uses: actions/checkout@
|
|
15
|
+
- uses: actions/checkout@v7
|
|
16
16
|
|
|
17
|
-
- uses: actions/dependency-review-action@
|
|
17
|
+
- uses: actions/dependency-review-action@v5
|
|
18
18
|
with:
|
|
19
19
|
fail-on-severity: high
|
|
20
20
|
fail-on-scopes: runtime, development, unknown
|
|
@@ -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`
|
|
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
|
|
63
|
-
patch keyed by
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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`).
|
|
@@ -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]'`.
|
{spolvero-0.4.0 → spolvero-0.5.0}/adapters/copilot/.github/instructions/spolvero.instructions.md
RENAMED
|
@@ -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
|
|
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.
|
|
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:
|
|
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
|
|
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)
|