Skip to content

Enhance Markdown artifact review in Wizard and SDD canvases - #29

Open
vibeCoder500 wants to merge 17 commits into
github:mainfrom
vibeCoder500:feat/canvas-markdown-review
Open

vibeCoder500 wants to merge 17 commits into
github:mainfrom
vibeCoder500:feat/canvas-markdown-review

Conversation

@vibeCoder500

@vibeCoder500 vibeCoder500 commented Sep 15, 2026 •

Copy link
Copy Markdown

Summary

Enhance Markdown viewing inside the existing Wizard and SDD canvas previews, without introducing another plugin or canvas.

  • Add a shared GFM reader with a heading outline, responsive TOC drawer, related-artifact selection, local-reference navigation, history, and revision-aware refresh.
  • Keep reading and navigation separate from workflow execution. Bind reads and clarification controls to the existing canvas workspace, context, artifact, revision, and owning command.
  • Package the reader and parser independently in both plugins, with dependency notices and source/hash/import-closure verification. Installed plugins do not need reader development dependencies or a sibling checkout.

Existing Offerings Preserved

  • Existing canvas identities, agent actions, stage commands, setup ordering, Run/Rerun, overwrite confirmation, and legacy endpoint response shapes remain.
  • Wizard retains catalogs, composition, pipeline customization, folder browsing, command/template source previews, and non-Markdown previews.
  • SDD retains feature targeting, constitution, progress, optional quality gates, new-feature flow, targeted clarification, and artifact deep links.
  • Regression checks cover conventional template paths, active composition-stack preset overrides, and workflow progress/focus restoration after returning from the reader.

Intentional behavior changes: existing documents are readable while setup or execution is gated; Run/Rerun remains gated. Clarification markers in code examples or HTML comments are inert, and stale reviewed answers require refresh/reconfirmation.

Scope And Review Guide

Reader-only changes for both canvases. No repository browsing/authentication/cloning, preview installers or distribution, generated agent files, historical release records, branding, version bumps, or changes to unrelated plugins/skills/presets.

Verification

Verified locally on Windows with Node 24.19.0 and Edge 153.0.4234.32:

  • 377 canvas regression/security tests passed.
  • 32 reader rendering/security tests passed.
  • 23 independent packaging/read-only security tests passed.
  • 39 actual-shell browser journeys passed, including responsive layout, navigation, freshness, clarification, focus, and bounded-document performance.
  • Typecheck, lint, build, package verification, Markdown links, and CI configuration checks passed. Both dependency audits report zero vulnerabilities. No candidate tests skipped.
  • Untouched upstream-test replay: all 281 Wizard tests passed; 3 of 4 SDD tests passed. The remaining static assertion required hiding feature cards before setup and is intentionally replaced by coverage for readable artifacts with execution still gated.

Native And Hosted Acceptance

Final candidate: 5e3b459a1666ec28a3087f3595ca68e60efc44bc.

Hosted Windows and Linux validation: both jobs passed on this exact candidate. These are fork-hosted checks; upstream PR check runs are not currently attached.

Tested in GitHub Copilot App 1.1.20 on Windows using an owned synthetic repository and real project-local Wizard and SDD providers. Served payloads were hash-verified; normal installed plugins and real projects were not modified.

  • Both original artifact entry points, rendered revisions/GFM, related-document navigation/history, and return focus passed.
  • Native compact SDD pointer close and restored focus passed after fixing the reader stacking context. Wizard compact visibility and accessibility dismissal passed; its pointer hit-testing is covered by actual-shell browser tests, not claimed as a completed native pointer check.
  • SDD native keyboard heading navigation passed. Wizard uses the shared reader's browser keyboard coverage.
  • Real SDD Analyze ran once through the generated skill: all 146 tracked files remained unchanged, with no additions.
  • Real targeted SDD clarification ran once with 30 days.: only the synthetic specification changed; 145 other tracked files remained unchanged, with no additions. Its resolved question disappeared.
  • Wizard draft save/reopen/cancel/back-discard passed without workflow dispatch. All 37 source/configuration files remained unchanged; only expected Wizard control-plane state changed.
  • Explicit native Refresh recovered evicted contexts in both final canvases, retained the selected document, reset history, and did not rebind discarded/resolved answers.

Native testing found and regression-tested two reader defects: compact drawer stacking and explicit refresh of expired contexts. Recovery revalidates selected-document membership and clears old context bindings; automatic updates do not renew the existing 15-minute expiry. A temporary App WebView loading/focus issue was resolved by reacquiring native controls and opening the preview normally; the final SDD recovery check then passed without another code change.

Limits: actual Windows App acceptance, not native macOS/Linux certification or marketplace-release validation. Raw local evidence and diagnostic captures remain local. PR remains draft; no merge or release performed.

Add one shared reader and independently packaged assets inside the existing canvas preview surfaces. Preserve existing workflows and action contracts, and add scoped reads, revision-bound clarification validation, navigation, and regression coverage. Keep preview distribution and repository discovery outside this change.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Local-reference resolution can escape a scoped review context, while SDD polling and deep-link event handling also need correction.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds a shared, independently packaged Markdown artifact reader to the Wizard and SDD canvases while preserving workflow execution behavior.

Changes:

  • Adds responsive GFM rendering, navigation, history, freshness, and clarification controls.
  • Integrates scoped review services into both canvases.
  • Adds packaging verification and broad browser/security regression coverage.
File summaries
File Description
.gitattributes Marks generated reader assets.
.gitignore Ignores reader build output.
.github/workflows/markdown-artifact-review.yml Adds reader CI verification.
docs/markdown-artifact-review.md Documents architecture and maintenance.
scripts/canvas-reader/playwright.config.mjs Configures browser tests.
scripts/canvas-reader/serve-fixture.mjs Serves isolated canvas fixtures.
scripts/canvas-reader/stage-app-fixture.mjs Stages standalone plugin payloads.
scripts/canvas-reader/sync-assets.d.mts Declares synchronization types.
scripts/canvas-reader/sync-assets.mjs Packages and verifies reader assets.
scripts/canvas-reader/sync-domain.mjs Synchronizes shared domain code.
scripts/canvas-reader/fixtures/workspace.mjs Creates owned fixture workspaces.
scripts/canvas-reader/test/clarifications.spec.mjs Tests clarification workflows.
scripts/canvas-reader/test/fixture-tools.test.mjs Tests fixture safeguards.
scripts/canvas-reader/test/freshness.spec.mjs Tests revision refresh behavior.
scripts/canvas-reader/test/package-security.test.mjs Tests package isolation.
scripts/canvas-reader/test/performance.spec.mjs Tests bounded rendering performance.
scripts/canvas-reader/test/reader-accessibility.spec.mjs Tests responsive accessibility.
scripts/canvas-reader/test/sdd-shell.spec.mjs Tests SDD shell integration.
scripts/canvas-reader/test/sync-assets.test.mjs Tests asset verification.
scripts/canvas-reader/test/wizard-shell.spec.mjs Tests Wizard shell integration.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/README.md Documents reader commands.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/server.mjs Registers review endpoints.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/server/artifact-clarifications.mjs Parses clarification markers.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/server/artifact-clarifications.NOTICES.txt Records parser notices.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/server/artifact-discovery.mjs Discovers review artifacts.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/server/artifact-read.mjs Performs bounded artifact reads.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/server/artifact-review.mjs Manages review contexts.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/app.js Integrates reader state.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/artifact-review.js Adapts the shared reader.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/client.js Handles review events.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/handlers-phase.js Opens phase artifacts.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/phase-card.js Adds artifact review actions.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/phase-runtime.js Preserves workflow state.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/setup.js Wires reader setup.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/styles/artifact-review.css Styles review controls.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/styles/overlays.css Updates overlay layout.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/vendor/markdown-reader/markdown-reader.css Packages generated reader styles.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/package.json Defines reader tooling.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/package-lock.json Locks reader dependencies.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/eslint.config.mjs Configures reader linting.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/tsconfig.json Configures reader type checking.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/vite.config.ts Configures browser bundling.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/vite.parser.config.ts Configures parser bundling.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/src/bundle.ts Exposes the reader bundle.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/src/clarificationParser.ts Extracts clarification markers.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/src/mount.tsx Implements mounting lifecycle.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/src/types.ts Defines reader contracts.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/src/MarkdownReader/MarkdownReader.tsx Implements the reader UI.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/src/MarkdownReader/markdownOutline.ts Builds heading outlines.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/src/MarkdownReader/reader.css Styles responsive reading.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/src/MarkdownReader/useActiveMarkdownHeading.ts Tracks active headings.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/src/MarkdownReader/MarkdownTableOfContents/MarkdownTableOfContents.tsx Implements responsive TOC navigation.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/test/clarification-source.test.ts Tests marker parsing.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/test/clarifications.test.tsx Tests clarification controls.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/test/content-security.test.tsx Tests sanitized rendering.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/test/markdown-outline.test.ts Tests outline generation.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/test/markdown-reader.test.tsx Tests reader behavior.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/test/markdown-table-of-contents.test.tsx Tests TOC interaction.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/test/mount.test.tsx Tests mounting and updates.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/test/reader-fixture.ts Provides reader fixtures.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/test/reader-states.test.tsx Tests reader states.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/test/artifact-review-context.test.mjs Tests review context binding.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/test/modals.test.mjs Tests clarification modals.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/test/reader-probe.mjs Probes packaged reader behavior.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/test/fixtures/review-freshness-fixture.mjs Supplies freshness fixtures.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/test/fixtures/review-http-fixture.mjs Supplies review HTTP fixtures.
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/test/fixtures/server-integration-fixture.mjs Integrates server fixtures.
plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/README.md Documents SDD reader behavior.
plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/artifact-review.mjs Adapts SDD review contexts.
plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/extension.mjs Hosts review APIs and events.
plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/index.html Integrates the SDD reader UI.
plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/sdd.mjs Preserves SDD workflow behavior.
plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/ui/artifact-review.js Packages the browser adapter.
plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/vendor/artifact-clarifications.mjs Packages clarification parsing.
plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/vendor/artifact-clarifications.NOTICES.txt Records parser notices.
plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/vendor/artifact-discovery.mjs Packages artifact discovery.
plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/vendor/artifact-read.mjs Packages bounded reading.
plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/vendor/artifact-review.mjs Packages review services.
plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/vendor/markdown-reader/markdown-reader.css Packages reader styles.
plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/vendor/markdown-reader/markdown-reader.js Packages reader runtime.
plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/vendor/markdown-reader/manifest.json Records reader provenance.
plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/vendor/markdown-reader/THIRD_PARTY_NOTICES.txt Records reader dependencies.
plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/tests/artifact-review.test.mjs Tests SDD review services.
plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/tests/reader-probe.mjs Probes packaged SDD reader.
Review details
  • Files reviewed: 77/93 changed files
  • Comments generated: 3
  • Review effort level: Balanced (auto)

Note

Copilot is running an experiment and ran this review at Balanced.


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI review requested due to automatic review settings September 15, 2026 10:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Relative links can escape the selected review scope, while clarification nesting, polling cost, and incomplete parser type-check coverage also remain unresolved.

Review details

Suppressed comments (4)

Previously missed (3) — in code that hasn't changed since the last review.

plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/server/artifact-review.mjs:367

  • Each SDD poll calls signature(), which recursively rediscovers and stats up to 10,000 entries for every retained review context. Contexts remain retained after the reader closes, so the 1.5-second timer can repeatedly perform tens or hundreds of thousands of filesystem operations for up to 15 minutes. Cache/incrementally update the signature or explicitly unregister closed reader contexts instead of rescanning them on every poll.
    plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/src/clarificationParser.ts:24
  • This check excludes only text whose immediate parent is a link. Markdown such as [**[NEEDS CLARIFICATION: Q?]**](research.md) has an emphasis/strong parent, so it becomes a trusted clarification binding and the renderer can place a button inside a navigable anchor. Exclude text with any link ancestor in both the parser and renderer transform.
    plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/tsconfig.json:20
  • npm run typecheck does not include the newly added parser Vite configuration, so type errors in that build path are silently skipped even though CI reports the reader configuration as typechecked.

plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/server/artifact-review.mjs:344

  • Relative links are read before checking that the normalized target belongs to the current feature/composition scope. A client can POST ../../other-feature/private.md (with a valid source revision) and receive any workspace Markdown file, contradicting the scope boundary. Reject targets outside the scope’s explicit candidates and allowed roots before reading them.
            const document = await readArtifact(workspacePath, relativeTarget);
  • Files reviewed: 78/94 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced (auto)

Note

Copilot is running an experiment and ran this review at Balanced.

Copilot AI review requested due to automatic review settings September 15, 2026 11:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Local-reference scope enforcement and bounded SDD polling must be corrected before approval.

Review details

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/server/artifact-review.mjs:369

  • The 1.5-second SDD poll calls discoverCandidates for every still-valid selection, while closing the reader does not remove selections and up to 20 contexts remain valid for 15 minutes. Each discovery can inspect 10,000 entries before this loop increments inspected only for returned Markdown candidates, so repeated opens—or directories containing mostly non-Markdown files—can cause hundreds of thousands of filesystem operations per poll. Deduplicate/cache signatures by scope and retire selections on close/expiry; also account for discovered.inspectedCount rather than only candidate count.

plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/server/artifact-review.mjs:344

  • Relative-link resolution reads and registers any Markdown path that normalizes inside the workspace, without checking that it belongs to the current feature/composition scope. For example, a link from specs/001-feature/spec.md to ../002-other/private.md normalizes to a valid path and bypasses the membership boundary. Check the target against the current scope's candidates/roots before readArtifact, and return an inert result when it is outside that scope.
                relativeTarget = path.posix.normalize(path.posix.join(path.posix.dirname(source.relativePath), relativeTarget));
                validateArtifactPath(relativeTarget);
            } catch { return { kind: "inert", reason: "unsupported_target" }; }
            if (relativeTarget === source.relativePath) return { kind: "fragment", artifactId: sourceArtifactId, fragment };
            const document = await readArtifact(workspacePath, relativeTarget);
  • Files reviewed: 78/94 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced (auto)

Note

Copilot is running an experiment and ran this review at Balanced.

Copilot AI review requested due to automatic review settings September 15, 2026 14:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Relative links can escape the active review scope, and SDD polling introduces potentially excessive recurring filesystem scans.

Review details

Suppressed comments (3)

Previously missed (1) — in code that hasn't changed since the last review.

plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/tsconfig.json:20

  • The new parser Vite configuration is omitted from the TypeScript project, so npm run typecheck does not check it despite the validation workflow's typecheck step. Include vite.parser.config.ts alongside the reader config so both build configurations are covered.

plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/server/artifact-review.mjs:344

  • Relative links are normalized before authorization, so ../002-other/spec.md from specs/001-fixture/spec.md becomes specs/002-other/spec.md, passes path validation, and is read even though it is outside the current feature/composition scope. Revalidate the normalized target against the context's candidates or allowed roots before reading and registering it; the synchronized SDD copy needs the same correction.
                relativeTarget = path.posix.normalize(path.posix.join(path.posix.dirname(source.relativePath), relativeTarget));
                validateArtifactPath(relativeTarget);
            } catch { return { kind: "inert", reason: "unsupported_target" }; }
            if (relativeTarget === source.relativePath) return { kind: "fragment", artifactId: sourceArtifactId, fragment };
            const document = await readArtifact(workspacePath, relativeTarget);

plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/extension.mjs:240

  • While an SSE client is connected, this runs every 1.5 seconds and review.signature() rescans up to 10,000 entries and stats every candidate. Large feature trees will therefore cause continuous high filesystem load even when nothing changes. Cache discovery/signature state or invalidate it from scoped filesystem changes rather than performing a full scan on every poll.
        const signature = await entry.review.signature();
        const sig = stateSignature(state, signature);
  • Files reviewed: 78/94 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced (auto)

Note

Copilot is running an experiment and ran this review at Balanced.

Choose available Markdown siblings in natural filename order, preserve revision-matched positions, and prevent background refresh from leaving the reader unmounted. Add folder-boundary, loading, refresh-race and actual-shell regressions.
Copilot AI review requested due to automatic review settings September 19, 2026 21:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Relative links can escape the active review scope, and additional correctness and polling-cost issues remain unresolved.

Review effort: Balanced
Findings: 1 High severity · 2 Medium severity

Open (3)
Previously missed (4)

In code that hasn't changed since last review

Medium severity Per-context polling causes excessive repeated directory scans

plugins/​spec-kit-copilot-wizard/​extensions/​speckit-wizard-canvas/​server/​artifact-review.mjs:367

This recomputes a full bounded discovery separately for every retained context on every 1.5-second SDD poll. Closing the reader does not remove its context, so repeated opens can leave up to 20 contexts and trigger up to 20 directory scans (each potentially inspecting 10,000 entries) per poll for 15 minutes. Deduplicate scans by current scope and prune/invalidate contexts when a reader closes, or maintain one watcher-derived signature per scope.

Medium severity Invalid extension owner prevents clarification command reruns

plugins/​spec-kit-copilot-wizard/​extensions/​speckit-wizard-canvas/​server/​artifact-review.mjs:398

Extension phase IDs are shaped like commands/speckit.assess.intake, so this fallback produces speckit.commands/speckit.assess.intake. Because the later command loop skips the same artifact path, the selected descriptor keeps this invalid owner; the reader then filters out its clarification bindings and cannot rerun the real extension command. Derive the owner from the matching snapshot command, or strip the commands/ prefix.

Medium severity Refresh control is a no-op after context load failure

plugins/​spec-kit-copilot-wizard/​extensions/​speckit-wizard-canvas/​ui/​artifact-review.js:229

When opening /api/review/context fails, showState("error") still renders a Refresh control, but activeContext remains null and this guard makes that control a permanent no-op. Let an explicit refresh reopen contextSelection when no context exists, so the advertised retry can recover from an initial transient failure.

Medium severity Nested clarification markers inside links or headings are trusted

plugins/​spec-kit-copilot-wizard/​extensions/​speckit-wizard-canvas/​ui/​markdown-reader/​src/​clarificationParser.ts:24

Checking only the immediate parent does not actually exclude markers inside headings or links when formatting is nested. For example, [**[NEEDS CLARIFICATION: Q?]**](research.md) visits the text with a strong parent, so it becomes a trusted clarification binding and the renderer can place a Clarify button inside the link. Track ancestors and reject any text beneath heading, link, or linkReference.

@nicolehaugen

Copy link
Copy Markdown
Contributor

@vibeCoder500 Thanks for the contribution - this will be a nice add to the canvas apps. Before we merge this, can you please go through the copilot review feedback and decide what is applicable to fix? Thanks!

Tushar Singhal added 3 commits October 9, 2026 13:23
Preserve markdown reader/review behavior while integrating the latest SDD parsing and Wizard canvas-designer changes.
Exclude upstream Playwright E2E sources and configuration from independent App payloads, and verify that packaging boundary.
Render aligned tree/hash iconography in wide and compact outlines, cover wrapping and active states, and synchronize the generated reader assets to Wizard and SDD.
Copilot AI balanced review requested due to automatic review settings October 9, 2026 08:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Constrain reference links to active review scopes, enforce aggregate clarification limits, release and deduplicate active review contexts, preserve loading invalidations, and connect SDD deep-link readers to change events.
Copilot AI balanced review requested due to automatic review settings October 9, 2026 11:04
@nicolehaugen

nicolehaugen commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

I manually verified the artifact-review changes in my local environment using both the SDD and Wizard canvases.

After reviewing the four remaining Copilot review comments, I consider them non-blocking. They describe valid edge cases and potential follow-up improvements, but do not need to keep this contribution in another fix-and-automated-review cycle.

Remaining issue What causes it End-user impact and example Why it can be deferred
Slow scanning of extreme whitespace At each space, the scanner searches the remaining whitespace again instead of skipping unnecessary work. Longer runs therefore become disproportionately expensive. A local reproduction with 80,000 consecutive spaces took about 5.3 seconds in the scanner, potentially freezing the reader during rendering. This requires extreme uninterrupted whitespace, not ordinary paragraph spacing or typical Markdown. It is a valid optimization, but not evidence that normal Spec Kit documents are unusably slow.
Missing clarification controls in continued blockquotes Markdown parsing removes the > quote prefixes, but the new clarification scanner does not correctly account for those removed characters on continuation lines. It loses alignment between the original Markdown and parsed text, so it skips the question. The PR also replaces SDD's previous question detector with this parser, which introduces the regression there. These consecutive lines trigger it:
> Players prepare supplies before departure.
> [NEEDS CLARIFICATION: Can players customize supplies?]
The question remains readable, but neither gets a Clarify button nor appears in SDD's detected-question list. Before this PR, SDD detected it.
It affects a particular formatting arrangement. Moving the marker outside the blockquote restores detection, and answering through chat remains possible. Deferral is reasonable for this experiment, but it should be acknowledged as a small compatibility regression, not dismissed as optional new functionality.
Saved answers remain stale after an edit is reverted Changing the document marks the saved answer stale. Restoring the exact original document does not clear that state, while recovery only permits a different revision. A user queues an answer, edits the source, then undoes that edit. The retained answer cannot be reconfirmed or submitted. This requires a specific edit-and-revert sequence while answers are queued. Closing the reader, discarding the draft, and re-entering it provides a workaround. Project documents are not corrupted.
Test-fixture writes follow redirected parent folders Mutation and restoration check the target file but not whether its parent folders have been replaced with symlinks/junctions. If a temporary fixture folder is redirected elsewhere, test mutation or cleanup could overwrite or delete a file at that other location. This concerns developer test tooling, not normal installed-canvas use. Mutations require explicit opt-in, and a local actor or process must first redirect the temporary folder. A defensive check is worthwhile, but does not warrant blocking this contribution.

Comment thread scripts/canvas-reader/serve-fixture.mjs Dismissed
@nicolehaugen

Copy link
Copy Markdown
Contributor

CI failures and suggested fix

Both Canvas Reader Validation jobs (Windows and Ubuntu) fail at npm audit --audit-level=low --ignore-scripts. The original reader lockfile selects three indirect dependencies with published security advisories. The audit failure stops these jobs before their build, package-verification, and test steps run; it is not a failing viewer test.

These packages are used by the reader's build/test tooling and are not included in the shipped viewer bundle:

Dependency Current lockfile Suggested version Used by
brace-expansion 5.0.9 5.0.12 ESLint through minimatch
source-map-js 1.2.1 1.2.2 Vite/PostCSS and jsdom
undici 8.10.1 8.11.2 jsdom

Suggested fix: refresh these dependencies within their existing compatible ranges, then regenerate the reader metadata using the CI-pinned Node 24.19.0 / npm 11.17.0. From plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader:

npm audit fix --package-lock-only --ignore-scripts --no-fund
npm ci --ignore-scripts --no-fund
npm run build
npm run verify:package

The locally verified update changes only these three files:

  • plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/markdown-reader/package-lock.json
  • plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/ui/vendor/markdown-reader/manifest.json
  • plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/vendor/markdown-reader/manifest.json

The two manifests record the updated source fingerprint. The generated viewer JavaScript/CSS remains unchanged, and this introduces no new installation step for end users.

A local Windows trial of this update passed the strict audit (zero vulnerabilities), typecheck, lint, build/package verification, and 560 tests including 41 browser journeys. This update is not yet in the PR; both GitHub matrix jobs will need to rerun after it is applied.

Separate CodeQL finding: the nine reported alerts were reviewed as false positives involving Markdown table serialization, intentional URI character ranges, and a UUID-based test SDK mock. They have been dismissed with individual explanations, and the CodeQL check is now passing. No scanning rules or exclusions were changed, and no additional code change is suggested for those alerts.

Refresh compatible transitive dependencies, upgrade Vite to its first patched 8.1 release, and regenerate both standalone reader payloads with the pinned toolchain. Document the lockfile provenance regeneration requirement.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 21, 2026 15:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Command ownership resolution can dispatch the wrong workflow, and existing extension artifacts can remain incorrectly locked.

2 open issues
4 resolved since last review

Review effort: Balanced

@vibeCoder500

vibeCoder500 commented Oct 21, 2026 •

Copy link
Copy Markdown
Author

@nicolehaugen Thanks for the detailed dependency diagnosis. The upgrades are implemented and pushed in a10a8a1.

Dependency Previous Updated
brace-expansion 5.0.9 5.0.12
source-map-js 1.2.1 1.2.2
undici 8.10.1 8.12.1
vite 8.0.16 8.1.6

I reproduced the two original audit failures. A fresh audit also reported the newly published launch-editor advisories against the pinned Vite version (GHSA-698v-4r3x-3vcv, GHSA-r825-w8mm-5pxw, and GHSA-587h-7wmj-h5pm). Vite 8.1.6 is the first patched release for that affected version line, so that upgrade and its required bundler dependencies are included too; no forced major upgrade was used. The three indirect upgrades remain within their existing compatible ranges.

Both standalone Wizard and SDD payloads and provenance manifests were regenerated with Node 24.19.0 / npm 11.17.0. The Vite update regenerates the reader JavaScript and clarification parser; the bundled runtime dependency inventory, CSS, and license notices are unchanged. There is no new end-user installation step, and no scanning rules or exclusions were changed.

Additional review fixes

The two Copilot threads posted after the dependency update are also fixed in b4b6e05, with replies and resolution on both threads:

Added three regressions, including service-level command validation and DOM-level navigation/execution-gate checks. Both reported failures reproduced before their fixes and pass afterward; the complete validation below was rerun on the latest changes.

Local verification passed:

  • Clean locked install with lifecycle scripts disabled.
  • npm audit --audit-level=low --ignore-scripts: zero vulnerabilities.
  • Typecheck and lint.
  • Full build and package verification, followed by a second CI-style build without synchronizing the committed copies; both independent payloads verified.
  • 563 tests passed, zero failures/skips: 34 reader tests, 465 Wizard/SDD regression tests, 23 independent tooling/package tests, and 41 Edge browser journeys.

GitHub verification is blocked on maintainer approval, not a new test failure. The fork branch and PR head both match the latest b4b6e05. The license compliance check passes. These three new runs are currently action_required, with no jobs executed:

Please approve those runs so the upstream checks can execute. I am not claiming the GitHub Windows/Linux reruns are green yet. I left the separate non-blocking follow-ups and the existing CodeQL dismissals as you recommended.

Prefer exact stage command matches before shared output paths. Admit read-only navigation through resolved extension artifact paths while preserving execution gates. Add service and DOM regressions, synchronize the SDD discovery copy, and document the behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 22, 2026 06:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Security-sensitive read boundaries, cross-canvas lifecycle changes, and unresolved clarification validation require final human review.

No open issues 🎉

1 previously missed issue

In code that hasn't changed since last review

Medium severity Allow multiline clarification answers during validation

plugins/​spec-kit-copilot-wizard/​extensions/​speckit-wizard-canvas/​server/​handlers-phase.mjs:98

Reviewed clarification submissions reject ordinary multiline answers. The shared validateClarifications() calls boundedString(answer.answer, 4000), whose control-character filter rejects LF, CR, and tabs. Both canvases accept textarea input, and Wizard queues an answer such as Keep 30 days.\nThen delete., but validation then fails before workflow dispatch. Use an answer-specific validator that allows those whitespace characters while preserving the length, nonblank, aggregate-byte, and other control-character checks. Keep the stricter validator for identifiers, synchronize the SDD copy, and add multiline submission regressions for both canvases.

2 resolved since last review

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

One or more issues must be addressed before approval.

5 open issues

Review effort: Max

@mnriem

mnriem commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator

Can you please address the Copilot feedback. If not applicable, please explain why

Restore multiline clarification answers with strict identifier and size limits. Enforce fresh setup admission for legacy and reviewed phase submissions, preserve read-only artifact navigation, and reset composition refresh state without replacing the active reader.

Declare Wizard-owned jsdom test dependencies and verify standalone installs. Update undici within its compatible range and regenerate shared payload metadata. Keep the strict audit gate unchanged; the unavailable patched minimatch remains an explicitly reported blocker for PR github#29.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI max review requested due to automatic review settings November 2, 2026 10:25
@vibeCoder500

Copy link
Copy Markdown
Author

@mnriem @nicolehaugen The five open Copilot comments are fixed in c59904e, with individual explanations and resolved threads:

Feedback Fix and regression evidence
Multiline answers (two threads) Separate answer validation permits CR/LF/tabs while preserving strict IDs, source/question/command bindings, 4,000-character limits, and the aggregate UTF-8 budget. Wizard/SDD service, SDD HTTP, and real textarea browser regressions pass; the SDD shared copy is regenerated.
Clean Wizard tests Declare Wizard-owned jsdom@30.0.1, use that package's test dependency instead of the nested reader installation, and update the README. A clean npm ci and the final 422-test Wizard suite were verified with reader node_modules absent; no hidden reader install is needed.
Non-Markdown setup bypass Viewing remains enabled, but legacy Clarify/Apply controls and the flush helper are setup-gated. Both server phase-submission forms recheck current setup before dispatch, including after asynchronous review validation. Regressions cover zero dispatch, retained answers, setup changes, and successful post-setup submissions.
Stuck Composition Refresh Clear the static Refresh button's busy state before returning early for an active reader. The actual-browser regression verifies the same reader stays mounted and Refresh works after return, without workflow dispatch or workspace writes.

Local verification (Node 24.19.0 / npm 11.17.0): typecheck, lint, reproducible reader/parser builds, and both standalone payload verifications pass. 574 tests pass with zero failures/skips: 34 reader, 470 Wizard/SDD, 23 tooling/package, 42 actual-shell reader browser journeys, and 5 existing Wizard E2E tests. The standalone Wizard install/test check above is additional evidence, not double-counted in that total.

Remaining merge blockers

  1. New dependency advisory, not a CodeQL code alert: the fresh strict reader audit found high-severity undici advisories and GHSA-g3hv-75wg-m249 in minimatch. undici is upgraded from 8.12.1 to 8.12.3 within the existing range; its findings are cleared and both payload provenance manifests are regenerated without changing the shipped reader JavaScript/CSS or runtime dependency inventory. The Wizard package audit is clean.

    The reader audit still fails on the minimatch advisory, propagated through 11 moderate lint-toolchain dependency entries (zero high/critical findings remain). GitHub identifies minimatch >=11.0.1 as patched, but both accessible npm mirrors return 404 for that release, and direct npm registry TLS connections fail in this environment. ESLint/typescript-eslint still request minimatch 10.x, so remediation needs an available patched package plus a validated, scoped compatibility override or an upstream-supported upgrade. I have not installed an unverified replacement, force-downgraded ESLint, weakened the audit threshold, or changed scanning rules/exclusions. This blocker must be addressed before calling the PR merge-ready.

  2. Latest fork workflow runs require maintainer approval:

    These latest runs have not executed yet. After approval, the unchanged reader audit is expected to remain red until the minimatch issue above is remediated. License compliance passes for the new head.

For CodeQL specifically, the preceding b4b6e05 analysis completed successfully and its PR check says "No new alerts in code changed by this pull request." Detailed repository code-scanning alerts are not readable by vibeCoder500; I have not dismissed any new alerts or changed security settings. A new approved scan is still needed for c59904e.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved critical findings include private-mirror lockfiles with weak SHA-1 integrity, unpinned workflow actions, dropped formatted clarification markers, and a race that can dispatch answers against changed artifacts.

9 open issues
5 resolved since last review
1 file not reviewed
  • plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/package-lock.json: Generated file

Review effort: Max

Comment thread scripts/canvas-reader/sync-domain.mjs Resolved
Regenerate both dependency lockfiles from public npm with SHA-512 integrity and pin validation actions to immutable v7 commits. Apply the approved patched minimatch override without weakening strict audit gates.

Restore formatted clarification questions with shared phrasing-source spans, preserved GFM positions and markup, and exact callback bindings. Revalidate answers after the awaited setup scan, improve safe synchronization diagnostics, and move the SDD test below imports. Rebuild both independently packaged payloads and add regression coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI max review requested due to automatic review settings November 2, 2026 12:06
@vibeCoder500

vibeCoder500 commented Nov 2, 2026 •

Copy link
Copy Markdown
Author

@mnriem @nicolehaugen Update: the nine comments from the latest Copilot review are fixed in e6618b6, with individual replies and resolution on every thread. The original nine are resolved; the latest bootstrap follow-up and current 31-thread status are recorded below.

# Addressed review feedback Verification
1 Immutable workflow actions All three actions use verified v7 commit SHAs; fork permissions and pinned Node are preserved.
2 Wizard lockfile registry/integrity All 44 entries use public npm HTTPS and SHA-512.
3 Wizard manifest companion feedback Same public-lockfile fix; standalone install/test verified.
4 Revision race after setup scan Real artifact mutation during the awaited scan receives 409 with zero dispatch.
5 Reader lockfile registry/integrity All 311 entries use public npm HTTPS and SHA-512; both payloads rebuilt.
6 Reader manifest companion feedback Public lockfile/provenance contracts and strict audits pass.
7 Formatted clarification markers Inline code, emphasis, URL/email, table, blockquote and bracketed-code questions retain exact source bindings and rendered formatting; excluded examples stay inert. Both actual canvas submission journeys pass.
8 Test placement Existing test moved below imports; SDD compatibility coverage retained and extended.
9 Safe actionable sync diagnostics Distinct stale/invalid/missing metadata errors are reported without echoing paths or private JSON.

Additional bootstrap follow-up

Final verification caught one additional comment posted during the update. It is also fixed and resolved in e5da861, with the verified reply. First-open bootstrap and recovery now use --omit=dev in both quiet/progress and recovery paths. The actual installer was tested in an owned extension fixture with NODE_ENV=development: only argparse and js-yaml were installed, not jsdom/Playwright or the test tree. All 31 targeted checks and the full 424-test Wizard suite pass; developer installs retain their test dependencies.

A new live check on this latest head confirms 31 total review threads, zero unresolved. The original nine fixes remain in e6618b6; the additional runtime-only bootstrap fix is in e5da861. The 583-test full validation below remains the evidence for the original nine; the bootstrap follow-up is separately verified above rather than double-counted.

Validation: Node 24.19.0 / npm 11.17.0; typecheck, lint, reproducible reader/parser builds, and independent package verification pass. 583 tests pass with zero failures/skips: 36 reader, 472 Wizard/SDD, 26 tooling/package, 44 real-shell reader browser journeys and 5 existing Wizard E2E tests. The additional standalone Wizard check passes 423 tests with reader dependencies absent, using the verified public cache; it is not double-counted.

The public lockfiles were generated by an explicitly authorized, SHA-pinned fork Actions workflow because direct public npm TLS is unavailable locally. They were verified before integration rather than manually rewriting URLs/hashes. The temporary helper branch/worktree and uploaded cache artifacts are removed; verified package bytes are retained in the standard npm cache for offline installs. npm refreshed locked versions only within existing compatible manifest ranges, apart from the explicitly approved scoped minimatch security override.

The previous dependency-audit blocker is now fixed: the scoped minimatch@11.0.1 override passes lint compatibility checks, and both strict public-registry audits and local online audits report zero vulnerabilities. There are no audit exemptions, threshold reductions, ESLint downgrades, CodeQL exclusions, or security-setting changes. This supersedes the previous remaining-blocker report.

Remaining verification: the latest fork runs still require maintainer approval:

License compliance passes for this head. These latest workflow runs have not executed yet, so I am not claiming the new upstream CI/CodeQL scan is green or that merge readiness is fully verified. The older Copilot assessment was made against c59904e; the latest resolved-thread state and bootstrap follow-up above reflect e5da861.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep first-open and recovery installs runtime-only while preserving developer npm ci/test behavior. Apply --omit=dev consistently in quiet/progress modes and recovery guidance, add regression coverage, and document the bootstrap boundary.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI max review requested due to automatic review settings November 2, 2026 12:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Human assessment is needed because read-only review scans can unexpectedly rewrite workspace cache state and overwrite concurrent updates.

No open issues 🎉

1 resolved since last review

Review effort: Max

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants