Bumps .claude-plugin/plugin.json 4.2.0 -> 4.3.0 (package.json, package-lock.json,
and the README badge were already at 4.3.0). Updates the v4.3.0 CHANGELOG entry with
the verified test count (711 pass / 0 fail / 2 skipped, 713 total), a "Re-review
remediation (Sesjon 13-18)" note covering the 11-finding cycle Waves 1-3 closed, and
a "Known issues — deferred to v4.3.1" subsection listing the 3 new findings the Sesjon
18 re-review surfaced in the remediation code (87069b35 SECURITY_INJECTION defense-in-
depth, 4cc3bfc9 PLAN_EXECUTE_DRIFT, c6c64a58 MISSING_TEST). Updates root CLAUDE.md
(voyage v4.0.0 -> v4.3.0, seven-command + playground), root README + plugin README
(test count, Known-limitations note, fixes the stale "trekplan@" install snippet ->
"voyage@"), root marketplace.json (voyage description), and plugin CLAUDE.md (Playground
paragraph). A plan-critic-reviewed Wave-4 remediation plan for the 3 deferred findings
is ready (.claude/plans/, gitignored).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Step 30 of v4.3 plan — Wave 7 Group D:
- voyage-playground-a11y.spec.mjs (3 tests): light + dark theme axe-core
scans (compared against baseline JSON, fails only on NEW or GROWN
violations) + pixel-diff smoke for SC1 (light + dark, 1280x900,
maxDiffPixelRatio=0.02).
- voyage-playground-network.spec.mjs (1 test): SC7 authoritative gate via
page.on('request') instrument — verifies zero external (http/https/ws)
requests during page load.
- playwright.config.mjs: snapshotPathTemplate routes to tests/e2e/snapshots/
(matches Step 31 expected_paths).
Baseline policy: HTML is FROZEN in Sesjon 6 (Wave 7 = verification, not
fix). Existing critical/serious WCAG violations (aria-hidden-focus +
color-contrast) recorded in tests/e2e/snapshots/a11y-baseline.json as
delta-baseline. Actual a11y fix deferred to v4.4.
Verify: npm run test:e2e -> 4 passed (3 a11y + 1 network).
Step 27 of v4.3 plan — adds Playwright 1.59.1 + axe-core/playwright 4.10.2
as devDependencies, npm script test:e2e, and playwright.config.mjs with
file:// baseURL pointing at playground/. Chromium browser binary installed
to ~/Library/Caches/ms-playwright/.
Trace: SC2 (WCAG verifikasjon krever browser-driver), research/04
Recommendation security; brief Constraint linje 64 (zero new deps i
playground/) er OK fordi Playwright er devDependency på voyage-plugin-rot,
ikke i playground/.
Step 20 of v4.3 playground plan. Document-level keydown handler:
- J = next annotation (next sorted-by-line draft, wraps)
- K = prev annotation (wraps)
- ] = toggle sidebar visibility
- Escape = clear active anchor + sidebar list selection
Active annotation gets yellow-tint (Step 18 setActiveAnchor) and the
matching gutter-badge receives focus + scrollIntoView. Aria-live region
announces position + target: "Annotering 3 av 7: <target> — <snippet>".
Skips input/textarea/select/contenteditable so playground never steals
keystrokes from form fields. Modifier keys (Ctrl/Alt/Meta) pass through
to browser shortcuts. Wired in init() after dashboard nav.
Trace: SC2 (WCAG AA keyboard), SC6, research/04 Dim 2 + Insight 5 +
Recommendation keyboard-navigation.
Step 19 of v4.3 playground plan. Sidebar now default aria-hidden=true
(translateX collapses panel, leaves 40px FAB rail). FAB toggle has
data-action=toggle-sidebar for keyboard binding (] in Step 20).
New annotation-list section in sidebar panel:
- filter radiogroup: Alle (default), Åpne (unresolved), Resolved
- voyage-jumplist ordered list with numbered badges matching the
gutter-badge ordering (sorted by line ASC)
- aria-live jumplist count: "X av N" (filtered/total)
- click list-item -> setActiveAnchor + scrollIntoView + data-active
renderAnnotationList wires into mountRender so list refreshes on every
render. Filter state (voyageFilterState) persists across renders within
the session.
Trace: SC6, research/04 Dim 1 (hidden-by-default) + Insight 1 +
Recommendation sidebar/navigation.
Step 18 of v4.3 playground plan. Replaces v4.2 Gesture 2 pencil-icon
hover-reveal with numbered circular badges in the left gutter (one per
anchored paragraph; ordering matches sidebar jumplist). 2-3px accent stripe
extends right from the badge into the gutter. Yellow-tint highlight
(rgba 255, 235, 59, 0.25 — Google Docs pattern) applies to the anchored
paragraph when an annotation is active. Body text never reflowed or
recolored. Gesture 1 (text-select adder) and Gesture 3 (page-level note)
remain for new annotation creation.
CSS uses --color-scope-voyage token for badge background and stripe.
JS adds injectAnchorBadges() + setActiveAnchor() and rewires mountRender.
Trace: SC1 + SC6, research/04 Insight 3 + Recommendation marker-design.
Step 17 of v4.3 playground plan. Pure function relocateAnchorsToBlockBoundaries
(text, anchors) detects atomic markdown blocks (fenced code, tables, deeply
nested lists) and relocates anchor-comment insertion to the line BEFORE block
opening rather than inside the block. Pure markdown-text -> markdown-text
transform (no DOM, no markdown-it dependency).
Companion test tests/integration/annotation-block-boundary.test.mjs extracts
the function via balanced-brace scan and exercises it through Function() —
7 unit tests covering empty anchors, outside-block stays, fenced-code
relocation, table relocation, deeply-nested list relocation, mixed
inside/outside, and shape contract.
Trace: SC6, research/04 Dim 3 (Notion block-level fallback), plan-critic
major #6 (DOM-vs-no-DOM contradiction resolved via pure-function design).
Step 15 (v4.3 Sesjon 3 — Wave 3) — wires the dashboard fleet-tiles
to a drill-down view with breadcrumb update + back-to-dashboard
navigation + browser back/forward restoration via popstate.
renderArtifactDetail(artifactKey) renders the chosen artifact into
the #voyage-detail slot using renderPageShell + renderArtifact:
- brief / plan / review → markdown render
- progress → JSON pretty-print in <pre>
- research → list of all research-briefs
- missing entry → "Artifact mangler" placeholder
Click delegation on .fleet-tile[data-artifact] triggers detail render
+ pushDetailURL (?artifact=<key>); data-action=back-to-dashboard
returns to the dashboard view + pushDashboardURL. Topbar breadcrumb
gets a third segment for detail views.
URL-parameter deep-linking: at page-load, ?project=<basePath>
surfaces a guide-panel hint explaining that webkitdirectory requires
a user-gesture; the hint links to the same Last prosjektmappe button
that wireProjectLoader already exposes. popstate handler restores
the view-state on browser back/forward (no-op when no project loaded).
Test additions (4): renderArtifactDetail function, URLSearchParams
presence, data-action=back-to-dashboard attribute, popstate listener.
Step 14 (v4.3 Sesjon 3 — Wave 3) — adds renderDashboard pipeline that
turns a ProjectArtifacts struct (produced by loadProjectDirectory in
Step 13) into a fleet-grid of fleet-tiles, one per artifact-type
(brief / plan / review / research / progress).
Status vocabulary: complete, in-progress, blocked, missing, stale
Severity mapping: missing → critical, blocked → high, in-progress
+ stale → medium, complete → low. Severity drives DS color tokens
via [data-severity] attribute selectors.
When loadProjectDirectory completes, dashboard takes over the main
stage (paste-flow elements hidden); topbar updates with project
breadcrumb. Step 13's pipeline already calls renderDashboard via
graceful-fallback, so wiring is automatic.
Test additions (4): fleet-grid + fleet-tile presence, renderDashboard
function declaration, status vocabulary completeness.
New docs/three-tier-context.md (110 lines) documents Voyage's position as
Tier 1 in a three-tier ecosystem with upstream consumers (app-creator,
app-factory; both currently in private incubation). The brief identifies
upstream-consumed contracts (brief.md format, /trekplan CLI, handover
schemas), prescribes stability principles, and explicitly preserves
Voyage's runtime agnosticism — no imports, no detection, no special cases.
Awareness without coupling.
CLAUDE.md § Architecture: 2-line callout pointing to the brief, following
the existing "opt-in upstream architect plugin" precedent.
No Voyage behavior change. Documentation-only.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
v4.1.0 → v4.2.0. Two-file change per Step 14 manifest (package.json +
.claude-plugin/plugin.json). Description tagline expanded from
"brief, research, plan, execute, review, continue" to include "revise"
and "+ first marketplace playground".
Out-of-scope under Step 14 forbidden_paths (left at 4.1.0 intentionally):
- lib/exporters/otlp-format.mjs (VOYAGE_SCOPE_VERSION constant)
- hooks/scripts/otel-export.mjs (User-Agent header)
These constants are touched on the next bump where the constants directory
is in scope; keeping them stale for one release is acceptable since
otel/otlp telemetry is opt-in and the version field is informational.
Verification:
- node -e "import('./package.json',{with:{type:'json'}}).then(m=>console.log(m.default.version))" → 4.2.0
- jq -r .version .claude-plugin/plugin.json → 4.2.0
- npm test: 610 pass / 0 fail / 2 skipped (Docker)
- SC11 pipeline-self-eat gate: render-artifact.mjs renders own brief.md + plan.md to non-empty HTML