Skip to content

feat(wedge): PR-WV1-4 — canvas response paths 5→3 + handoff retirement#187

Merged
jukka-matti merged 11 commits into
mainfrom
feat/wedge-pr-wv1-4-canvas-persona
May 17, 2026
Merged

feat(wedge): PR-WV1-4 — canvas response paths 5→3 + handoff retirement#187
jukka-matti merged 11 commits into
mainfrom
feat/wedge-pr-wv1-4-canvas-persona

Conversation

@jukka-matti
Copy link
Copy Markdown
Owner

Summary

Retires the canvas drill menu's Handoff response path end-to-end and reduces the canvas drill CTAs from 5 to 3 (Quick action / Focused investigation / Improvement Project). Handoff is folded into Sustainment-closure per wedge spec §10 and ADR-082 (already shipped at the IP-stage level via PR-WV1-2).

Material scope correction vs the master sequencer:

  • Persona-routing deletion was confirmed a no-op — investigation revealed zero references to usePersonaStore, personaRouter, *HomeShell.tsx, or personaRole in packages//apps/. Persona was design-only; code never shipped post-wedge-pivot.
  • Handoff blast was wider than the master plan listed: 16+ files referenced 'control-handoff'. HandoffForm (281 LoC) + HandoffPanel × 2 (297 LoC each) + a whole onRecordHandoff prop chain through 4 component layers + the Sustainment-region "Control handoff" bucket all retired.
  • 'control-handoff-missing' was runtime-computed (not stored), so no .vrs migration was required (partial-integration policy declared upfront in Task 7).

What changed

Core (@variscout/core):

  • ProcessStateResponsePath: drop 'control-handoff' (7 values → 6)
  • ResponsePathAction.open-sustainment: drop surface: 'review' | 'handoff' discriminator (no longer meaningful)
  • deriveResponsePathAction: drop the case + simplify
  • isHandoffReady / selectControlHandoffCandidates / control-handoff push block in buildCurrentProcessState: all deleted
  • SustainmentReviewReason: drop 'control-handoff-missing' (4 values remain)
  • Barrel re-exports cleaned in index.ts + processHub.ts

UI (@variscout/ui):

  • ResponsePathKind: 5 values → 3 (quick-action | focused-investigation | charter)
  • ResponsePathCtaState: drop 'prerequisite-locked' variant (all 3 surviving paths are always-available)
  • computeCtaState: drop signals param; use canonical assertNever from @variscout/core/types
  • CanvasStepOverlay: drop signals + onSustainment + onHandoff props; drop PREREQUISITE_TOOLTIP_KEY; drop useTranslation (no longer needed); render exactly 3 CTAs
  • Canvas + CanvasWorkspace: drop dead signals/onSustainment/onHandoff passthrough chain
  • LocalMechanismView: drop sustainment/handoff buttons + ColumnMiniChart prop cleanup
  • ProcessHubSustainmentRegion: drop handoffCandidates bucket + onRecordHandoff prop chain (cascades to ProcessHubCadenceQueues, ProcessHubReviewPanel, ProcessHubView, Dashboard)
  • ProcessHubCurrentStatePanel: drop 'control-handoff': 'Control handoff' label entry
  • Deleted: Handoff/HandoffForm.tsx (281 LoC) + tests + barrel

Apps:

  • apps/azure/src/components/handoff/HandoffPanel.tsx (297 LoC) — deleted
  • apps/pwa/src/components/HandoffPanel.tsx (297 LoC) — deleted
  • panelsStore.showHandoff → aliased to showSustainment in both apps (keeps Inbox-prompt / context-link routing reachable; documented with inline comment)
  • Editor.tsx, both App.tsx files, Dashboard.tsx, processHubRoutes.ts, usePanelsPersistence.ts: HandoffPanel state + URL surface=handoff + render paths all retired
  • useAppPanels.ts: handoffTargetId selector + return-shape member dropped
  • Both FrameView.tsx files: handleSustainment / handleHandoff callbacks deleted; signals useMemo deleted; WorkflowReadinessSignals import dropped

Preserved invariants

  • ADR-080 Sustainment auto-fire — triggers on project phase → 'sustain' via co-located reducer dispatch (independent of the deleted Canvas-CTA path).
  • Sustainment panel reachability — Inbox prompts emitting surface === 'handoff' and context-link callers still route to the Sustainment panel via the showHandoff alias.
  • 'handoff' as a surface type on ControlHandoff records — that's a legitimate domain field on stored records, unrelated to the deprecated navigation surface.

Plan

Sub-plan: docs/superpowers/plans/2026-05-16-pr-wv1-4-canvas-paths-persona-deletion.md
Master sequencer: docs/superpowers/plans/2026-05-16-wedge-implementation.md

8 implementation tasks + 1 cascading fix (dead signals prop chain caught by pnpm build) + 1 test-fixup (stale surface: 'review'). 11 commits total, net -1626 lines across ~50 files.

Test plan

  • pnpm test (turbo) green — @variscout/core 3447 pass, @variscout/ui build clean, @variscout/pwa 366 pass, @variscout/azure-app 1329 pass
  • pnpm build (turbo) green
  • bash scripts/pr-ready-check.sh green
  • ADR-074 architecture tests pass
  • Browser walk via claude --chrome: canvas drill = 3 CTAs; Sustainment auto-fires; Inbox routes handoff prompts to Sustainment panel

Wedge progress

🤖 Generated with Claude Code

jukka-matti and others added 10 commits May 16, 2026 23:35
…production

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Drop sustainment/handoff handlers, signals prop, prerequisite-locked
branch, and PREREQUISITE_TOOLTIP_KEY from CanvasStepOverlay. Component
now passes (path, hasHandler) to computeCtaState with no signals
dependency. useTranslation removed as no longer referenced.
…iring

Removes the `onSustainment` and `onHandoff` prop chain from the Canvas
component tree (CanvasProps → CanvasWorkspace → CanvasLevelRouter →
LocalMechanismView) and from both FrameView consumer apps. The sustainment
and handoff panels remain reachable via other entry points (response-path
prompts, action-item navigation, URL-driven handoff in Editor).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… to Sustainment

Wedge V1 folds Handoff into Sustainment. Deletes all Handoff UI components
and wires all showHandoff() call sites to route to Sustainment instead.

- Delete HandoffForm.tsx (281 LoC), its test, its barrel index.ts
- Delete HandoffPanel.tsx in both azure (297 LoC) and pwa (297 LoC)
- Remove HandoffForm export from @variscout/ui barrel
- Drop 'control-handoff' from RESPONSE_LABELS in ProcessHubCurrentStatePanel
- Redirect showHandoff() → showSustainment() in both panelStores
- Remove HandoffPanel lazy import + render block from pwa App.tsx
- Remove HandoffPanel import + render block + navigationHandoffTargetId state
  from azure Editor.tsx; remove handoff-specific useEffects + prop
- Remove pendingHandoffTargetId state from azure App.tsx; clean prop chain
- Strip handoffTargetId param from Dashboard.onOpenProject signature +
  handleRecordHandoff; remove PENDING_HANDOFF_TARGET_KEY constant
- Drop surface=handoff URL variant from processHubRoutes.ts
- Remove 'handoff' from usePanelsPersistence STUB_VIEWS
- Update panelsStore tests to assert sustainment redirect
- Update processHubRoutes tests to drop surface=handoff assertions + snapshot

showHandoff() is kept as a named alias on both stores (routes to sustainment)
so Inbox/context-link call sites remain intact without requiring simultaneous
FrameView changes. handoffTargetId state field + 'handoff' in activeView union
are dead values until Task 7 cleanup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…n + retire handoffTargetId dead state

- Remove 'control-handoff-missing' from ProcessHubAttentionReason union (processHub.ts)
- Retire selectControlHandoffCandidates logic — returns [] per ADR-082 handoff-folds-into-sustainment (sustainment.ts)
- Drop selectControlHandoffCandidates describe block from sustainment.test.ts (2 tests)
- Drop 'includes controlled investigations missing a ControlHandoff' test from processHub.test.ts (1 test)
- Remove handoffTargetId field + initial state from both panelsStore files (azure + pwa)
- Remove 'handoff' from activeView union in both panelsStore files + initFromViewState param type (azure)
- Remove handoffTargetId selector read, return-shape entry, and UseAppPanelsReturn type member from useAppPanels.ts
- Persona-routing grep: empty (no usePersonaStore / PersonaRouter / *HomeShell references)
…idates

Deletes the stub selectControlHandoffCandidates (always returned []) and
removes the dead "Control handoff" UI bucket from ProcessHubSustainmentRegion.
Propagates onRecordHandoff prop removal up through CadenceQueues →
ReviewPanel → ProcessHubView → Dashboard; drops handleRecordHandoff callback
and its orphaned usePanelsStore import.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…llowup)

Task 4 removed `signals` from `CanvasStepOverlayProps` but the parent
chain (CanvasWorkspace → Canvas → CanvasStepOverlay) still passed
`signals={signals}` through without consuming it, causing TS2322.

Remove the entire chain:
- Drop `signals: WorkflowReadinessSignals` from CanvasProps + CanvasWorkspaceProps
- Drop `signals` useMemo + JSX prop from both FrameView files
- Remove `hasCompletedInterventionEvidence` helper (only used by signals useMemo)
- Remove unused imports: WorkflowReadinessSignals, ImprovementProject
- Update Canvas/CanvasWorkspace tests: remove SIGNALS const + all usages
- Update FrameView tests: remove WorkflowReadinessSignals import, signals type
  in mock, signals prop assertions; retain contextLinkGroups assertion

WorkflowReadinessSignals + isSustainmentReady remain in @variscout/core
(sustainmentConfirmed still used in IPDetail/stageState.ts, isCharterReady
is a live export). Only the Canvas passthrough chain is dead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…anel test

Task 1 simplified ResponsePathAction's open-sustainment variant to drop the
surface discriminator. The ProcessHubCurrentStatePanel test still constructed
the action with the old surface: 'review' field, breaking tsc.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 17, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
mean-beoynd-lite-pwa Ready Ready Preview, Comment May 17, 2026 3:11am
variscout_website Ready Ready Preview, Comment May 17, 2026 3:11am

Removes full-lifecycle.spec.ts entirely — its only test drove the deleted
HandoffPanel UX (Record control handoff → System name / Reaction plan /
Acknowledge handoff / Mark operational); no Sustainment equivalent exists
so rewriting would produce a fake test, and the seedLifecycleHub helper
had no remaining callers. Logs the surviving survey/handoff.ts rule layer
in docs/investigations.md as a deferred cleanup item per Opus PR #187 review.
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.

1 participant