test(voyage): add Group B (structure) + Group C (annotation export schema) tests [skip-docs]

Step 29 of v4.3 plan — Wave 7:
- Group B (9 tests): DS-token classes (badge--scope-voyage, guide-panel,
  fleet-grid), theme-toggle wiring (data-action, wireThemeToggle,
  localStorage), sidebar-tab keyboard pattern (role=tablist,
  aria-selected, J/K/Esc), anchor-ID format mirror.
- Group C (7 tests, +1 vs original): export-bundle JSON parse, required
  keys, per-annotation field validation, empty-export edge case,
  annotation_digest order-independence, SHA-256 16-hex-char validity
  (SC6 / SC-GAP-3), fixture plan anchor format.
- Fixtures: tests/fixtures/playground/v43-export-bundle.json +
  v43-plan-pre-annotate.md (ANN-0001 + ANN-0002, revision: 0).

Test count: 689 → 705 pass / 0 fail / 2 skipped.
This commit is contained in:
Kjell Tore Guttormsen 2026-05-10 18:18:24 +02:00
commit 5820478f71
4 changed files with 263 additions and 0 deletions

View file

@ -0,0 +1,25 @@
{
"schema_version": 1,
"exported_at": "2026-05-10T18:00:00Z",
"target_artifact": "plan",
"target_filename": "annotated-plan.md",
"annotations": [
{
"id": "ANN-0001",
"target_artifact": "plan",
"target_anchor": "step-1-sentinel-touch",
"intent": "question",
"comment": "Should this sentinel use a deterministic timestamp?",
"timestamp": "2026-05-10T18:01:00Z"
},
{
"id": "ANN-0002",
"target_artifact": "plan",
"target_anchor": "step-2-sentinel-touch-paired",
"intent": "fix",
"comment": "Step 2 manifest should reference Step 1 in must_contain.",
"timestamp": "2026-05-10T18:02:00Z"
}
],
"annotation_digest": "PLACEHOLDER_OVERWRITTEN_AT_TEST_TIME"
}

View file

@ -0,0 +1,69 @@
---
plan_version: 1.7
profile: balanced
revision: 0
---
# v4.3 fixture — pre-annotate plan
Minimal plan used by Group C tests to seed an annotated round-trip.
Two anchors target `Step 1` and `Step 2` so the export-bundle has at
least 2 ANN-IDs to canonicalize for `annotation_digest`.
## Context
Fixture only — not executed. Anchors below match the v4.2 anchor format
`<!-- voyage:anchor id="ANN-NNNN" target="<slug>" line="<N>" -->` and
sit on their own line surrounded by blank lines (block-boundary rule).
## Implementation Plan
### Step 1: Sentinel touch
<!-- voyage:anchor id="ANN-0001" target="step-1-sentinel-touch" line="20" -->
- **Files:** `tmp/sentinel-1.txt` (new)
- **Changes:** Create the sentinel file with the literal content "step-1".
- **Reuses:** none.
- **Test first:** none — sentinel-only step.
- **Verify:** `test -f tmp/sentinel-1.txt`
- **On failure:** revert.
- **Checkpoint:** `git commit -m "chore: sentinel step 1"`
- **Manifest:**
```yaml
manifest:
expected_paths:
- tmp/sentinel-1.txt
min_file_count: 1
commit_message_pattern: "^chore: sentinel step 1"
bash_syntax_check: []
forbidden_paths: []
must_contain: []
```
### Step 2: Sentinel touch (paired)
<!-- voyage:anchor id="ANN-0002" target="step-2-sentinel-touch-paired" line="38" -->
- **Files:** `tmp/sentinel-2.txt` (new)
- **Changes:** Create the sentinel file with the literal content "step-2".
- **Reuses:** none.
- **Test first:** none.
- **Verify:** `test -f tmp/sentinel-2.txt`
- **On failure:** revert.
- **Checkpoint:** `git commit -m "chore: sentinel step 2"`
- **Manifest:**
```yaml
manifest:
expected_paths:
- tmp/sentinel-2.txt
min_file_count: 1
commit_message_pattern: "^chore: sentinel step 2"
bash_syntax_check: []
forbidden_paths: []
must_contain: []
```
## Verification
- Both sentinel files exist after execution.