Skip to content

feat: ProcessHubCurrentStatePanel actions (Phase 2 V2 PR #4)#98

Merged
jukka-matti merged 10 commits into
mainfrom
phase-2/pr-4-response-path-routing
Apr 27, 2026
Merged

feat: ProcessHubCurrentStatePanel actions (Phase 2 V2 PR #4)#98
jukka-matti merged 10 commits into
mainfrom
phase-2/pr-4-response-path-routing

Conversation

@jukka-matti
Copy link
Copy Markdown
Owner

Summary

PR #4 of Phase 2 V2 closure — makes ProcessHubCurrentStatePanel actionable. State-item cards now route to their responsePath workflow on click; monitor and measurement-system-work paths render as Informational / Planned pills with no click affordance.

Key building blocks:

  • ResponsePathAction discriminated union + deriveResponsePathAction pure function in @variscout/core (with exhaustive switch + assertNever guard).
  • actionToHref URL adapter in apps/azure/src/lib/processHubRoutes.ts (single URL source).
  • safeTrackEvent no-PII telemetry wrapper in apps/azure/src/lib/appInsights.ts.
  • ProcessHubCurrentStatePanel refactored: 3 required props (state, actions, evidence) — no back-compat optionality per feedback_no_backcompat_clean_architecture memory.
  • Existing consumer (ProcessHubReviewPanel) refactored to pass the contracts.
  • Dashboard wires handleResponsePathAction with App Insights telemetry (hubId is the actual hub ID from rollup.hub.id, not an investigation ID — explicit fix per ADR-059 review).

evidence contract is stubbed in this PR (passes empty findingsFor + no-op onChipClick); PR #5 wires the chip count + click.

Spec: docs/superpowers/specs/2026-04-27-actionable-current-process-state-panel-design.md (commit 24e85496)
Plan: docs/superpowers/plans/2026-04-27-actionable-current-process-state-panel-plan.md

Test plan

  • pnpm --filter @variscout/core exec vitest run — 10 new tests in responsePathAction (incl. compile-time exhaustiveness guard); 2826 total
  • pnpm --filter @variscout/ui exec vitest run — 15 panel tests (8 existing rewired + 7 new for action behavior + Space-key activation); UI total green
  • pnpm --filter @variscout/azure-app exec vitest run — 9 new tests in processHubRoutes (incl. snapshot + exhaustiveness guard); 933 total
  • pnpm --filter @variscout/ui build — clean cross-package type check
  • bash scripts/pr-ready-check.sh — all checks green
  • claude --chrome walk: open Azure Dashboard with seeded hub, click each card type, verify supported paths navigate via existing onOpenProject, unsupported paths show pill + tooltip, telemetry events fire with non-PII payload

What's deferred to PR #5 (already specced)

  • linkFindingsToStateItems aggregator in core (pure function)
  • Evidence chip render in panel + chip-click handler
  • ProcessHubReviewPanel evidence wiring (using findingCounts from rollup metadata)

Notable code-review fixes during implementation

  1. routing/ directory was moved to lib/ to honor the FSD hard rule in apps/azure/CLAUDE.md ("Don't introduce new top-level directories").
  2. Telemetry hubId field initially logged an investigation ID (ADR-059 PII violation); fixed by passing real rollup.hub.id through ProcessHubReviewPanel.
  3. Added compile-time exhaustiveness @ts-expect-error test for both deriveResponsePathAction and actionToHref — prevents future variant additions from silently slipping past.

🤖 Generated with Claude Code

jukka-matti and others added 10 commits April 27, 2026 22:14
…sePathAction

Pure mapping from a state item's response-path to a domain action.
Exhaustive on ProcessStateResponsePath. Returns 'unsupported' for paths
with no current Azure surface (monitor → informational, MSA → planned).

Phase 2 V2 PR #4, Task 5.

Co-Authored-By: ruflo <ruv@ruv.net>
…athAction

Adds a @ts-expect-error test that fails to compile if a future
ProcessStateResponsePath variant is added without a matching case
in deriveResponsePathAction.

Phase 2 V2 PR #4, code-review followup.

Co-Authored-By: ruflo <ruv@ruv.net>
Thin Azure-side adapter mapping ResponsePathAction discriminated union
to URL strings. Single URL source — adding a new ResponsePathAction
variant in core triggers a TS build error here via the exhaustive
switch.

Phase 2 V2 PR #4, Task 7.

Co-Authored-By: ruflo <ruv@ruv.net>
Honors apps/azure/CLAUDE.md FSD rule: 'Don't introduce new top-level
directories. Feature-Sliced Design: features/, hooks/, components/,
services/, auth/, db/, lib/.'

Phase 2 V2 PR #4, code-review followup.

Co-Authored-By: ruflo <ruv@ruv.net>
Try/catch'd facade over App Insights trackEvent. Silently swallows
failures so telemetry can never block UX. Caller is responsible for
ADR-059 no-PII compliance in the payload (enum values, opaque IDs,
integers only).

Phase 2 V2 PR #4, Task 8.

Co-Authored-By: ruflo <ruv@ruv.net>
…ntStatePanel

Refactors panel to take 3 required props (state, actions, evidence)
instead of 1 (state). State-item cards become clickable affordances when
the action is supported; 'monitor' and 'measurement-system-work' paths
render as 'Informational' / 'Planned' pills with no click affordance.

evidence contract is unused in this PR (passes through stubbed); PR #5
wires the chip count + click.

Per feedback_no_backcompat_clean_architecture memory: required props
by default. The Azure consumer (ProcessHubReviewPanel) is refactored
in the next subagent task to pass these contracts.

Adds keyboard activation (Enter/Space), aria-label, and tooltip text
on planned/informational cards.

8 existing tests rewired + 6 new action-behavior tests = 14 tests.

Phase 2 V2 PR #4, Tasks 9-10.

Co-Authored-By: ruflo <ruv@ruv.net>
Code-review followups for ProcessHubCurrentStatePanel:
- Add a Space-key keyboard activation test to mirror the Enter-key
  test (ARIA button convention).
- Document the title-attribute tooltip's accessibility limitation
  (touch unreachable, screen-reader unreliable per WCAG 1.3.3 / 4.1.2)
  as an inline TODO. Pill text already conveys the state visually;
  upgrade to a Tooltip primitive when the design system grows one.

Phase 2 V2 PR #4, code-review followup.

Co-Authored-By: ruflo <ruv@ruv.net>
…entStatePanel actions

ProcessHubReviewPanel now passes the required actions + evidence contracts
to the panel. Adds defaultInvestigationId memo (most-recent investigation
heuristic) and actionFor closure that calls deriveResponsePathAction.

Dashboard wires handleResponsePathAction with safeTrackEvent telemetry
(hubId/responsePath/lens/severity — no PII per ADR-059) and routes via
the existing onOpenProject callback.

evidence contract is stubbed in this PR (passes empty findingsFor +
no-op onChipClick); PR #5 wires the chip count + click.

Phase 2 V2 PR #4, Tasks 11-12.

Co-Authored-By: ruflo <ruv@ruv.net>
ADR-059 forbids logging customer-meaningful identifiers. The previous
handler labeled an investigation ID as 'hubId' in the telemetry payload,
which is a real leak. Now ProcessHubReviewPanel passes rollup.hub.id
(an admin-assigned slug) explicitly to the Dashboard handler.

Also:
- Add safeTrackEvent to handleResponsePathAction useCallback deps
- Document the intentional empty-string defaultInvestigationId fallback

Phase 2 V2 PR #4, code-review followup.

Co-Authored-By: ruflo <ruv@ruv.net>
The assertNever function was added to types.ts and exported from
index.ts as part of the ResponsePathAction work, but the types.ts
change was inadvertently left uncommitted while the export and its
consumers landed across several commits. Local tests passed because
the working directory had it; CI would have failed with an unresolved
export.

Phase 2 V2 PR #4, missing-commit recovery.

Co-Authored-By: ruflo <ruv@ruv.net>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 27, 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 Apr 27, 2026 8:29pm
variscout_website Ready Ready Preview, Comment Apr 27, 2026 8:29pm

@jukka-matti jukka-matti merged commit 85f844a into main Apr 27, 2026
3 checks passed
@jukka-matti jukka-matti deleted the phase-2/pr-4-response-path-routing branch April 27, 2026 20:30
jukka-matti added a commit that referenced this pull request Apr 27, 2026
Combines three sequenced PRs into one spec per feedback_full_vision_spec
memory:
- PR #1 (H1): team notes on state items — question / gemba / data-gap /
  decision kinds, persisted in ProcessHubInvestigationMetadata.stateNotes
- PR #2 (V2 follow-up): full EvidenceSheet rendering — refactors
  ProcessHubEvidenceContract to split countFor (sync) + loadFindingsFor
  (async), eliminates the synthetic-Finding cast from PR #99
- PR #3 (H2 launch): General Evidence Source for CSV/Excel — adds
  GENERIC_TABULAR_PROFILE to DATA_PROFILE_REGISTRY, mapping confirmation
  UI in ProcessHubEvidencePanel, cadence metadata

Resolves both prior open questions inline:
- Evidence contract split (countFor + loadFindingsFor + onChipClick +
  onFindingSelect — cleaner than overloading findingsFor sync/async)
- Mapping UX explicit confirmation (matches operating-model § "analyst
  confirms mappings" language)

Updates spec index, marks the parent V2 actionable-panel spec as
Delivered (PRs #98 #99).

Co-Authored-By: ruflo <ruv@ruv.net>
jukka-matti added a commit that referenced this pull request May 4, 2026
…g) (#121)

* docs: mark layered-process-view-v1 plan delivered

V1 component, FrameView swaps (PWA + Azure), and doc updates (ADR-070,
methodology.md, mental-model-hierarchy.md, llms.txt) all shipped via
production-line-glance C2 (merged 2026-04-29). Plan frontmatter was
never promoted; flipping deferred → delivered.

Co-Authored-By: ruflo <ruv@ruv.net>

* docs: consolidate product vision into one canonical spec

Adds docs/superpowers/specs/2026-05-03-variscout-vision-design.md as the
canonical product vision. Supersedes the 2026-04-27 operating-model and
product-method-roadmap specs (moved to docs/archive/specs/ with
status: superseded + forward pointer). methodology.md gets a
forward-pointer banner and survives as longer-form companion. All
inbound + outbound cross-refs updated; specs/index.md rows show
status: Superseded.

Vision thesis: "the map is the product" — Process Hub IS its logic map;
one continuous canvas (DAG with branch + join + two-level nesting +
context propagation) replaces the FRAME river-SIPOC + LayeredProcessView
+ LayeredProcessViewWithCapability stack; cards-with-mini-charts per
step + drill-down panel + mode lenses replace the separate Analysis tab;
"tributary" / "CTS" jargon retired. Engine and data model survive.

10 canvas commitments in spec section 3.3 are load-bearing. 11 open
questions in section 8 carry brainstorm defaults that need explicit
confirmation before implementation plans are written.

Decision-log pinned under Replayed Decisions (2026-05-03).

In-flight plan reconciliation (frontmatter status flips):
- delivered: production-line-glance C1/C2/charts (PRs #105/#106/#107),
  actionable-current-process-state-panel (PR #98),
  phase-3 H1/H2 (PRs #100/#101/#102)
- in-progress (corrected): coscout-intelligence-architecture,
  question-driven-eda-2-handoff, multi-level-scout-v1
- unchanged: phase-6-implementation-plan (deferred), investigation-wall
  (in-progress)

Brainstorm transcript: ~/.claude/plans/i-would-like-to-composed-rose.md.

Co-Authored-By: ruflo <ruv@ruv.net>

* docs: lock vision §8 decisions; canvas replaces Frame+Analysis tabs

Walk-through resolved 11 brainstorm-default markers in the 2026-05-03
vision spec §8, plus a new Q0 ("tab vs canvas scaffold") that emerged
during journey mapping. Headlines:

- Q0: Canvas eats Frame + Analysis tabs. Investigation / Improvement
  / Report keep their own surfaces. Wall is dual-home (destination
  + canvas overlay). JourneyPhase retires as a top-level nav primitive.
- Q1: Drill-down is a modern floating overlay anchored to the clicked
  card with blurred-canvas backdrop (overrides spec's "side-panel
  slides from right" default — that conflicted with the locked C3
  supersession of CoScout's right-rail claim).
- Q5: No CoScout map drafting in V1; manual click/drag/connect canvas
  authoring is the path (overrides spec default).
- Q7: Hard cutover, no migration window — no users yet to preserve.
- Q8: PWA gets local Hub-of-one with IndexedDB persistence; Azure
  adds cloud sync + multi-Hub + cadence + CoScout + team features.
- Q4 + Q11: Wall is dual-home; promoted hypotheses render as node
  markers, drafts as faint arrows.

Vision spec: §3.4, §5.2, §5.3, §5.4, §5.6, §5.7, §6, §7, §8 rewritten
in place; §8 replaced "open questions" with a "resolved decisions"
table; frontmatter status promoted draft → accepted.

ADR-070 (FRAME workspace): added 2026-05-03 supersession amendment
explicitly retiring FRAME as a top-level route; lists what survives
inside the Canvas vs what gets deleted in the same PR that ships it.

Decision-log: appended 2026-05-03 entry summarizing all 12 decisions
+ pointer to the §8 walkthrough plan.

Full rationale + spec/code follow-ups in
~/.claude/plans/lets-do-this-next-rustling-simon.md.

Co-Authored-By: ruflo <ruv@ruv.net>

* docs: §8 follow-ups — glossary, ADR amendments, roadmap re-tag

Smaller doc follow-ups triggered by the 2026-05-03 vision §8 resolution
(see commit f12e8b1 for the headline changes).

- docs/glossary.md (Q10): canonicalized as the single home for VariScout
  terminology. New "Process methodology terms" section (step / sub-step /
  column / input / output / outcome / branch & join / Process Hub) and
  a "Retired terms" table (tributary → factor; CTS → outcome; FRAME
  workspace → Canvas; Analysis tab → Canvas + lenses; Layered Process
  View → Canvas with lenses; etc) with replacements + retirement reasons.
- docs/01-vision/methodology.md (Q10): added forward pointer to
  glossary.md as the canonical terminology home; methodology stays as
  the longer narrative companion but stops re-defining terms.
- ADR-068 (Q3): added 2026-05-03 amendment formalizing modes and levels
  as orthogonal axes. Modes = which lens; levels = which slice (canvas
  pan/zoom). Level inferred from canvas state, not a separate picker.
  Refines (does not replace) the 2026-04-28 level-aware coaching
  amendment.
- ADR-059 (Q8): added 2026-05-03 amendment specifying PWA local
  Hub-of-one with IndexedDB persistence. Browser-tenant-only — Constitution
  P1 (browser-only processing) and P8 (no AI in free tier) preserved.
  Schema scope listed for the FRAME canvas detail spec to inherit.
- product-method-roadmap-design.md (Q6): added explicit "this is
  sequencing, not destination" header. Status was already superseded;
  the new framing tells stakeholders to read the vision spec first and
  consult this doc only for delivery-order intent.

docs:check green. No broken cross-refs, no orphans, frontmatter valid.

Co-Authored-By: ruflo <ruv@ruv.net>

* docs: add framing-layer design spec (Spec 1 of canvas-detail decomposition)

First of five canvas-detail specs decomposed from the 2026-05-03 vision
§8 walkthrough. Covers everything BEFORE canvas authoring proper —
Hub creation, data ingestion, investigation entry, multi-source join,
defect anchoring, Pareto integration, and the three composable canvas
filter states.

Two-layer model:
- Hub-level (durable): process goal narrative + outcome measure(s)
  + specs + primary scope dimensions
- Investigation-level (episodic): Issue → Question → CTP→CTQ
  Hypothesis → Evidence → Finding

Mode B (first-time Hub creation):
- Stage 1: free-text goal + scaffold chips (Purpose / Customer / What
  matters)
- Stage 2: paste/upload (existing UX)
- Stage 3: outcome confirmation with inline distribution + data quality
  + per-candidate inline specs (no σ-based suggestions — specs are
  customer-driven) + primary scope dimensions sub-step
- Stage 5: investigation entry as floating modal with skip-path →
  observation-triggered EDA

Mode A (reopening existing Hub):
- A.1: reopen, no new data → straight to canvas
- A.2-paste: match-summary card with timeline preview + 2-axis
  classifier (source × temporal); blocks on overlap and different-grain
- A.2-evidence-source: background ingestion with "X new snapshots ↑"
  indicator (Azure only — PWA Hub-of-one has no cloud sync per Q8)

Multi-source via shared keys: Hub spine = process line; multiple
sources joined via lot_id / batch_id / part_id; per-source provenance;
per-source independent timelines (V1).

Defect data + Pareto: multi-anchor (per-step rejects + outcome);
canvas-attached Pareto with two pickers (group-by × weighted-by);
Y-axis adapts to active mode lens (count / cost / time / Cpk gap /
%OOS / ...); Pareto-bar selection becomes canvas-wide scope filter
with "Make this the investigation scope" promote-to-investigation.

Three composable canvas filter states (time-window / scope /
Pareto-grouped) compose declaratively without new aggregation
primitives. ADR-073 holds: per-(node × context-tuple × scope) buckets
stay heterogeneity-aware.

Engine reuse: detectColumns() + inferMode() + validateData()
+ suggestNodeMappings + TimelineWindow + ParetoChart + StepErrorPareto
+ statusForCpk + investigation entities all already shipped. Almost
no new infrastructure required.

Spec is 638 lines, 16 sections including verification criteria.
Indexed at docs/superpowers/specs/index.md.

Inherits Q0 + Q1–Q11 anchors from §8 walkthrough at
~/.claude/plans/lets-do-this-next-rustling-simon.md.

Sibling specs (deferred): Spec 2 manual canvas authoring, Spec 3
cards / drill-down / mode lenses, Spec 4 canvas overlays + Wall sync,
Spec 5 IndexedDB persistence schema.

Co-Authored-By: ruflo <ruv@ruv.net>

* docs: revise Q8 — PWA persistence opt-in; .vrs files = shareable training scenarios

Walking back the original Q8 wording ("PWA = local Hub-of-one with
IndexedDB persistence" — auto-on) to Option 4 hybrid: session-only
by default; opt-in via "Save to this browser" → IndexedDB-backed
Hub-of-one; .vrs file export/import always available.

Strategic reframe: PWA serves four personas (LSSGB students, demos,
casual analysts, AND trainers authoring scenarios). Trainers package
datasets + Hub state + sample investigations into a .vrs bundle and
share via LMS / email; students import to start from a prepared
training state. .vrs becomes the scenario-distribution format,
positioning PWA as the methodology-teaching surface.

Persistence is now explicit consent per persona — training students
opt in once and auto-save; demo users skip; privacy-conscious users
export to file; trainers export+share. Constitution P1 (browser-only
processing) and P8 (no AI in free tier) preserved. Companies still
use Azure tier for centralized + secure persistence per ADR-059.

Updates:
- vision spec §7 tier paragraph rewritten + §8 Q8 row updated
- framing-layer spec §15 V1 scope adds opt-in Save-to-browser +
  .vrs export/import + IndexedDB-loaded-post-opt-in; §14 anchors
  table Q8 row revised
- decision-log §1 entry added: "Q8 revised — PWA persistence opt-in"
  with strategic rationale (training scenarios; trainer persona;
  no surprise persistence on shared computers)
- apps/pwa/CLAUDE.md hard rule updated from "no persistence" to
  "session-only by default; opt-in IndexedDB allowed; .vrs
  import/export for trainer-shared scenarios"

docs:check green.

Co-Authored-By: ruflo <ruv@ruv.net>

* plan: Framing Layer V1 Slice 1 — Foundation (16 tasks, TDD bite-sized)

First implementation plan from the framing-layer spec.

Slice 1 scope (smallest end-to-end):
- Mode B Stages 1–3 + canvas first paint (PWA + Azure)
- Mode A.1 reopen (Azure always; PWA only if opted in)
- PWA opt-in IndexedDB persistence (Q8-revised Option 4)
- PWA .vrs file export/import (round-trip; trainer scenarios)
- ProcessHub schema extension (processGoal, outcomes,
  primaryScopeDimensions)
- Goal-context biased outcome detection
- Multi-outcome validateData refactor
- Inline per-candidate spec editor (no σ-based suggestions)
- Characteristic-type-aware spec defaults
- Primary scope dimensions auto-suggest + multi-select
- Graceful degradation banner (no goal-keyword match)

16 tasks, TDD bite-sized (failing test → run + fail → implement
→ run + pass → commit). Task 0 locks 5 load-bearing decisions
in a companion file. Subagent-driven default execution per
feedback_subagent_driven_default; Sonnet workhorse.

Out of scope (later slices):
- Slice 2: Stage 5 modal + Mode A.2-paste + A.2-evidence-source
- Slice 3: Multi-source via shared keys
- Slice 4: Defect anchoring + Pareto on canvas

Plan referenced from:
- docs/decision-log.md §4 Session Backlog (queued row added)
- docs/superpowers/specs/2026-05-03-framing-layer-design.md
  (Implementation plans section added — lists all 4 V1 slices)

docs:check green; 471 docs frontmatter-valid.

Co-Authored-By: ruflo <ruv@ruv.net>

* plan: expand Tasks 6–15 to full TDD step-by-step

Per writing-plans skill 'no placeholders' rule: each task in a
plan must be self-contained because subagent-driven execution
reads tasks out of order in fresh subagents per task. Original
slice-1 plan had Tasks 1–5 fully step-by-step but Tasks 6–15
sketched ('follow the same TDD shape') — violated the rule.

Expanded all 10 sketched tasks to the same TDD pattern as Tasks
1–5: failing test code → run + fail expected output →
implementation code → run + pass expected output → commit
message. Plan grew 1135 → 3272 lines.

Tasks now self-contained:
- 6: OutcomeCandidateRow (6 RTL tests)
- 7: characteristicTypeDefaults (7 tests)
- 8: suggestPrimaryDimensions + selector UI (9 tests)
- 9: OutcomeNoMatchBanner (3 RTL tests)
- 10: GoalBanner + OutcomePin (8 RTL tests)
- 11: .vrs file format + export/import (5 tests)
- 12: PWA Dexie hubRepository (7 tests)
- 13: SaveToBrowserButton + VrsExport/Import (6 tests)
- 14: PWA Mode B E2E + Mode A.1 RTL (3 tests)
- 15: Azure HubCreationFlow + ProcessHubView GoalBanner (2 tests)

Plan ready for superpowers:subagent-driven-development.
docs:check green.

Co-Authored-By: ruflo <ruv@ruv.net>

* plan: lock 5 decisions for framing-layer V1 slice 1

D1: AnalysisBrief unchanged; new OutcomeSpec type
D2: PWA persistence opt-in via 'Save to this browser'
D3: validateData multi-outcome refactor
D4: Goal-context biasing is deterministic keyword extraction
D5: Mode A.1 reopen gated by IndexedDB opt-in flag (no PWA Hub list)

* feat(core): add framing-layer fields to ProcessHub

processGoal: string narrative (Hub-level durable)
outcomes: OutcomeSpec[] (CTQs in plain language)
primaryScopeDimensions: string[] (prominent picker dimensions)

OutcomeSpec includes characteristicType (nominalIsBest /
smallerIsBetter / largerIsBetter) — drives spec-input UI per
framing-layer spec §5.3. Specs are customer-driven; no σ-based
suggestions per Q8 / spec §3.3.

* feat(core): extractHubName utility

Extracts a short Hub name (≤50 chars, word-boundary truncated)
from the first sentence of a goal narrative.

Used by Stage 1 HubGoalForm to auto-populate the Hub name field
on goal-narrative confirm.

* fixup! feat(core): extractHubName utility

Remove unnecessary .trimEnd() — plan's slice + lastIndexOf + final trim
already handles the space-at-boundary case correctly without dropping
an extra word.

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(core): goal-context biasing in detectColumns

Optional DetectColumnsOptions.goalContext threads the user's
goal narrative through to outcome ranking. Tokenizes the
narrative (lowercased, stopwords removed), computes per-column
keyword overlap with the goal, adds a 0.5-weight bonus on top
of existing scoring.

Implements framing-layer spec §3.1: goal narrative biases
deterministic detection at Stage 3. Deterministic — no AI
(per Q5). Backward-compatible (option is optional).

* feat(parser): refactor validateData to accept string[] outcomeColumns

Signature changed from `(data, outcomeColumn: string | null)` to
`(data, outcomeColumns: string[])`. A row is excluded when ANY listed
outcome column is invalid. New `perOutcome: Record<string, PerOutcomeQuality>`
field on DataQualityReport exposes per-column valid/invalid/missing counts.
All six existing call sites updated; existing tests migrated to array API;
no backward-compat overload (D3, feedback_no_backcompat_clean_architecture).

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(ui): HubGoalForm component (framing layer Stage 1)

Free-text textarea with three scaffold chips ('+ Purpose',
'+ Customer', '+ What matters') that insert labeled prompt
chunks into the narrative on click. Optional 'See examples'
link surfaces three anonymized goal narratives. Skip-framing
path supported.

Implements framing-layer spec §5.1 — Option C 'free-text +
scaffold chips' shape locked during brainstorm.

* feat(ui): OutcomeCandidateRow with inline per-candidate specs

Stage 3 horizontal candidate row layout: radio + name +
sparkline + (when selected) inline spec inputs + quality stack
+ match confidence. LSL/USL placeholders say 'from customer
spec' (no σ-based suggestions per Q8/Q2). LSL disabled for
smallerIsBetter; USL disabled for largerIsBetter.

Adds @variscout/core/processHub sub-path export so consumers can
reach the new CharacteristicType / OutcomeSpec types without
colliding with the unrelated CharacteristicType in core/types.ts.

Implements framing-layer spec §5.3.1.

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(core): characteristic-type-aware spec defaults

inferOutcomeCharacteristicType: case-insensitive name-keyword
detection (defect/reject/scrap/fail/error/fault →
smallerIsBetter; yield/uptime/throughput/recovery/efficiency →
largerIsBetter; default nominalIsBest). Renamed from the plan's
inferCharacteristicType to avoid collision with the existing
spec-limit-based inferCharacteristicType in core/types.ts.

defaultSpecsFor: returns target=mean for nominalIsBest;
target=0 for smallerIsBetter; no target for largerIsBetter.
cpkTarget=1.33 (literature default) across the board. No
LSL/USL suggestions — those are customer-driven (per Q8/Q2).

7 tests in packages/core/src/specs/__tests__/characteristicTypeDefaults.test.ts.
Re-exported at root barrel as inferOutcomeCharacteristicType,
defaultSpecsFor, DataStats.

Co-Authored-By: ruflo <ruv@ruv.net>

* feat: PrimaryScopeDimensions auto-suggest + selector UI

suggestPrimaryDimensions filters columns by cardinality (3-50)
+ name keyword (id/lot/batch/product/customer/shift/operator/
machine/supplier/sku/plant/line/station). High-cardinality
columns (>50 levels) flagged as 'join key, not Pareto
candidate'.

PrimaryScopeDimensionsSelector pre-checks suggested columns;
user confirms or overrides; skippable. Implements framing-
layer spec §3.4 and §5.3.2.

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(ui): OutcomeNoMatchBanner graceful degradation

Renders when max(candidate.matchScore) < 0.30 (cryptic columns
or vague goal). Surfaces rename affordance, free-text 'I
expected the outcome to be' note, and skip-outcome path. Hub
records the user's pick for future detection (slice 1 stub;
full learning loop in Spec 5).

Implements framing-layer spec §5.3.3.

* feat(ui): GoalBanner + OutcomePin canvas first-paint components

GoalBanner renders Hub.processGoal at top of canvas;
click-to-edit opens textarea with Save / Cancel; onChange
callback to parent. Hides itself when goal is empty.

OutcomePin shows Cpk badge when specs are set + n>=10; falls
back to 'mean ± σ + n' + '+ Add specs' chip when specs absent;
shows 'Trust pending' when specs set but n<10. Per Q2 fallback
rule (framing-layer spec §5.2) and sample-size honesty
(vision §2.3).

* feat(core): .vrs file format + export/import (round-trip tested)

VRS_VERSION='1.0'. VrsFile shape: version, exportedAt, hub,
optional rawData, optional metadata (exportSource pwa|azure +
appVersion).

vrsExport(hub, rawData?, metadata?) → JSON string (pretty,
indent 2).
vrsImport(json) → VrsFile with version validation + clear
error messages on mismatch. Hub-only export supported (rawData
optional, useful for canvas-without-data sharing).

Round-trip preserves Hub + rawData via JSON serialization.
.vrs files double as shareable training scenarios per
Q8-revised.

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(pwa): Dexie hubRepository for opt-in Hub-of-one persistence

New PwaDatabase (Dexie v1) with two tables: hubs (single-row
Hub-of-one constraint) + meta (opt-in flag).

hubRepository API: getOptInFlag / setOptInFlag (auto-clears
Hub on false) / saveHub (overwrites single row) / loadHub
(returns null if absent) / clearHub.

Per Q8-revised: Dexie loaded only after explicit opt-in via
'Save to this browser' affordance (Task 13). Default behavior
unchanged from today (session-only). dexie + fake-indexeddb
added as dependencies.

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(pwa): Save-to-browser opt-in + .vrs export/import buttons

SaveToBrowserButton: shows 'Save to this browser' when not
opted in; clicking opts in + persists Hub. Once opted in,
auto-saves on Hub change. Button switches to 'Saved · Forget'
— click + confirm clears persistence (calls setOptInFlag(false)
which auto-clears Hub).

VrsExportButton: serializes current Hub + data via vrsExport,
downloads as <hub-name>.vrs (sanitized).

VrsImportButton: file picker; reads file → vrsImport →
emits onImport({ hub, rawData }) for parent to consume.
Per Q8-revised hybrid persistence (Option 4).

* feat(pwa): Mode A.1 reopen wiring + SessionProvider scaffold

SessionProvider holds current Hub + rawData in React Context (in-memory;
persistence via opt-in hubRepository).

App.tsx: on mount, getOptInFlag → if true, loadHub() and seed sessionHub.
GoalBanner renders above main content when sessionHub.processGoal is set,
so a Mode A.1 reopen surfaces the saved Hub goal immediately. RTL test
verifies both branches: opt-in false → HomeScreen; opt-in true + saved
Hub → canvas with goal banner restored from IndexedDB.

Mode B end-to-end (paste → goal → mapping → canvas first paint with
OutcomePin per outcome) requires the ColumnMapping refactor that is
out of scope for slice 1; the Playwright spec is checked in as .skip
to be re-enabled when Stage 1/3 routing lands inside App.tsx.

* feat(pwa): inject HubGoalForm Stage 1 into Mode B paste flow

After paste analyze, before ColumnMapping, render HubGoalForm so
the user states the process goal. On confirm, store narrative in
sessionStore. On skip, sentinel '' marks the Stage 1 step done
without a narrative. ColumnMapping now waits for goalNarrative !==
null.

ColumnMapping internals unchanged — Stage 3 refactor (using
OutcomeCandidateRow / PrimaryScopeDimensionsSelector /
OutcomeNoMatchBanner) ships in slice 2. Hub.processGoal is set
at ColumnMapping confirm if narrative was provided; outcomes[]
and primaryScopeDimensions are left for slice 2 (TODO marker in
handleMappingConfirmWithGoal).

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(azure): mount GoalBanner above Hub tabs + Dexie v7 no-op

ProcessHubView renders <GoalBanner goal={hub.processGoal}>
above the existing tab container — Mode A.1 reopen surfaces
the saved process goal immediately on Hub load (Azure tier
persists Hub-level state via Dexie always; no opt-in needed).

Dexie schema bumped 6 -> 7 as a no-op version; the new
ProcessHub fields (processGoal, outcomes,
primaryScopeDimensions) added in Task 1 are optional
TypeScript additions that Dexie stores without schema
migration. (Plan said v4 -> v5; the actual Azure schema was
already at v6, so the bump lands at v7.)

GoalBanner is mounted read-only for slice 1 because
ProcessHubView does not currently receive a Hub-update
callback in its props; wiring onChange is deferred to slice 2
alongside HubCreationFlow.

HubCreationFlow component (Stage 1 -> Stage 2 -> Stage 3 ->
built Hub) and the Dashboard "+ New Hub" button are deferred
to slice 2 — the plan's Stage3Mapping implementation is
sketch-only and the full ColumnMapping refactor required to
wire OutcomeCandidateRow / PrimaryScopeDimensionsSelector /
OutcomeNoMatchBanner is out of scope for slice 1 (mirrors the
slice-1 PWA Task 14 follow-up).

Co-Authored-By: ruflo <ruv@ruv.net>

* docs: framing-layer spec status draft -> active

Spec is the active working design. Slice 1 implements its
foundation; Stage 3 ColumnMapping refactor + multi-source +
defect anchoring continue across slices 2-4.

Decision-log session-backlog row already reflects in-flight
status (commit d49cbfe).

* docs: update slice-1 row with delivery state + slice-2 deferrals

Slice 1 row → in-flight with the foundation enumeration and
explicit slice-2 deferrals (Stage 3 ColumnMapping refactor,
canvas first-paint OutcomePin, button mounting in PWA UI,
Azure HubCreationFlow, Mode B E2E). Per final-reviewer
finding (Important #2): Save-to-browser + .vrs Export/Import
buttons are tested + scaffolded but currently unmounted —
slice 2 will surface them in the PWA chrome.

---------

Co-authored-by: ruflo <ruv@ruv.net>
jukka-matti added a commit that referenced this pull request May 17, 2026
…e/ + Coherence §3 markers) (#194)

* docs(wedge): archive Group 1 — 8 pre-wedge specs + fix inbound links

Moves 8 specs superseded by the 2026-05-16 wedge pivot to docs/archive/specs/.
Each file receives status:archived in frontmatter + a blockquote ARCHIVED header
with the specific supersession reason + institutional-knowledge preservation note.

Files moved:
- 2026-05-09-response-path-system-v1-design.md (5-path RPS → wedge 3-path reduction)
- 2026-05-08-improvement-project-v1-design.md (superseded by RPS V1 then wedge)
- 2026-05-04-canvas-migration-design.md (migration completed; canvas is live substrate)
- 2026-05-03-variscout-vision-design.md (5-path + multi-Hub → wedge 3-path + single-Hub)
- 2026-04-29-consolidated-method-and-surface-overview-design.md (pre-wedge state-of-union)
- 2026-04-02-knowledge-tab-design.md (tier-gating retires; scope narrows to project-level)
- 2026-03-30-holistic-evaluation-vqi.md (pre-wedge holistic evaluation)
- 2026-03-24-adr049-evaluation-report.md (point-in-time PR review, pre-wedge surface model)

Inbound links fixed in 17 files (ADRs 059/068/070/078/080/081, decision-log,
roadmap, investigations, methodology, variscout-process measurement-system +
scope-line, 4 plan files, 4 active spec files, specs/index.md).
9 additional files (items 6 and 10-17 in the audit list) were already in
docs/archive/specs/ from earlier work — no action needed.

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

* docs(wedge): archive Group 2 — 8 pre-wedge plans to docs/archive/plans/

Moves 8 implementation plans superseded by the 2026-05-16 wedge pivot to
docs/archive/plans/. Each file receives status:archived in frontmatter + an
ARCHIVED blockquote header with specific supersession reason.

Files moved:
- 2026-05-14-projects-tab-foundation.md (4-stage IP detail; amended by wedge)
- 2026-05-09-response-path-system-v1.md (5-path RPS; delivered, wedge reduced to 3)
- 2026-05-08-improvement-project-v1.md (superseded by RPS V1 system-level plan)
- 2026-05-07-canvas-pr8-8a-mode-aware-ctas.md (5-path tier-gating; wedge retired it)
- 2026-05-06-data-flow-foundation-f1-f2.md (delivered; pre-wedge scope assumptions)
- 2026-05-06-data-flow-foundation-f1-f2-audit.md (audit companion to f1-f2 plan)
- 2026-05-06-canvas-pr4c-pr6-followup.md (delivered; pre-wedge retrospective)
- 2026-04-27-actionable-current-process-state-panel-plan.md (delivered PRs #98/#99)

Inbound links fixed in 11 files (adr-077, adr-080, decision-log, roadmap,
f3-5-ingestion plan, f3-6-azure plan, projects-tab-launchpad-cascade plan,
canvas-pr8-master plan × 2 edits, projects-tab-design spec, projects-tab-launchpad).

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

* docs(wedge): archive Group 3 — ADR-033 to docs/archive/adrs/ (superseded by ADR-082)

* docs(wedge): archive Group 4 — pricing-tiers + tier-gating (single-SKU supersedes)

* docs(wedge): add §3 SUPERSEDED marker to Coherence design spec (V1 single-persona)

* docs(wedge): fix 3 broken cross-refs to archived docs (PR 4 followup)

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
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