Skip to content

[analytics] Onboarding v2: welcome hero, anchored coach emphasis, demo recipe v4, chaptered tour (epic tripl-odrj)#52

Merged
vladenisov merged 7 commits into
mainfrom
epic/tripl-odrj-onboarding-v2
Jul 19, 2026
Merged

[analytics] Onboarding v2: welcome hero, anchored coach emphasis, demo recipe v4, chaptered tour (epic tripl-odrj)#52
vladenisov merged 7 commits into
mainfrom
epic/tripl-odrj-onboarding-v2

Conversation

@vladenisov

Copy link
Copy Markdown
Owner

What

Second onboarding wave from the owner's live walkthrough (epic tripl-odrj, issues .1-.4):

Workspace welcome hero (tripl-odrj.1). The empty post-registration page now explains the product instead of showing an all-zero dashboard: README-sourced hero pitch, primary Generate-demo CTA with an expectation-setting caption, secondary New-project CTA, Plan/Observe/Govern pillar cards, docs link. Viewers get an ask-an-owner note. The zero stat band and duplicate header CTAs are hidden until the first project exists.

Anchored coach emphasis (tripl-odrj.2). Coach marks now visibly point at the control to click: pulsing ring beacon overlay (a11y-invisible, layout-neutral, reduced-motion static), data-coach-target attributes, one-shot scroll-into-view, popover arrow, step-declared placement defaults, and a presence registry so the strip flags a missing target with recovery copy. Hide hints silences everything through the one existing gate.

Demo recipe v4 (tripl-odrj.3). The seeded branch carries a deep-copied plan plus exactly one pending change (Buy Button Click description), so diff/merge preview finally show content; one open VariableValueDrift on product_id (observed prod_weekly outside documented values). Deep-copy logic extracted into a non-committing helper; create_branch behavior unchanged. Includes a review-found fix: weekly plan digest now scopes event counts to the main branch (it would otherwise double on any project with a working branch — demos by default after this recipe).

Chaptered tour v2 (tripl-odrj.4). The 4-step scenario becomes a 7-chapter coached tour under the same localStorage key (v1 state migrates): live-loop, edit-event, variables, branches (stops at review/merge preview), reconcile, alerting, explore. Completion via mutation-driven notifies (inert outside the active chapter) or route visits; strip shows chapter progress + next-chapter CTA; ProductTour and DemoWelcomePanel share the ChapterPicker; ~15 new coach anchors.

How it was built and verified

Multi-agent workflow: 3 parallel implementers + chapters agent, then 3 review lenses (React/backend/product-contract) with adversarial verification — 9 confirmed findings, all fixed (completed-status preserved on dismiss, outgoing chapter paused on switch, beacon body-observer, digest branch scoping, docstring accuracy, non-vacuous poll test, consumed-artifact fallback copy, editor deep-link artifact).

Local gates (serial, per machine constraints): backend pytest test_demo_project.py 20 passed, ruff check+format clean; frontend tsc -b clean, eslint zero-warning on all touched files, vitest green per file (scenarioModel 55, Provider 21, Strip 20, CoachMark 16, entryPoints 7, EventForm 8, workspace-welcome 5, ProjectsPage 17, ScansTab 13, ScanDetail 9, ScanConfigDetailView 3, MetricsCatalog 5, MonitoringDetailPage 35).

Test plan

  • CI backend + frontend suites green
  • Fresh-stand click-through: register -> hero -> generate demo -> chapters (live-loop, edit-event, branches diff, reconcile accept, alerting rule)
  • Verify demo reset restores consumed chapter artifacts (accepted shadow event, drift)

Notes for reviewers

  • Watch CI on test_demo_runtime / test_demo_performance / test_demo_scenario — statically reviewed as unaffected by the branch deep-copy, but they only run in CI.
  • Chapter progress stays per-browser (localStorage) by design; server-side resume is a possible follow-up.

…e variable-value drift (tripl-odrj.3)

The seeded feature/checkout-funnel branch now carries a deep-copied plan via
the extracted non-committing deep_copy_plan_to_branch helper (create_branch
behavior unchanged) plus exactly one branch-side edit — a CTA-copy description
change on Buy Button Click — so diff and merge preview finally show real
content. variables.py seeds one open VariableValueDrift on product_id
(observed prod_weekly outside the documented [prod_monthly, prod_annual]),
surfacing in the variables drift UI. DEMO_RECIPE_VERSION bumped to 4.

Review follow-up: _build_plan_digest_message now scopes all four event counts
to the project's main branch — the deep-copied demo branch would otherwise
have doubled every digest number (pre-existing bug for any project with an
open working branch, now triggered by default on demos).

Gates: pytest test_demo_project.py 20 passed; ruff check + format clean.
…(tripl-odrj.1)

A brand-new user now lands on a product intro instead of an all-zero
dashboard: hero with the README pitch (what tripl is, no new SDK, read-only
warehouse), a primary Generate-demo CTA with expectation-setting caption and
a secondary New-project CTA, a Plan/Observe/Govern pillar grid (canonical
copy in workspace-welcome-pillars.ts), and a muted closing strip linking the
docs. Viewers get an ask-an-owner note instead of create buttons. The
all-zero stat band and the duplicate header CTA pair are hidden until the
first project exists.

Gates: vitest workspace-welcome (5) + ProjectsPage (17) green; eslint
zero-warning; tsc clean.
…l-odrj.2, tripl-odrj.4)

Coach marks now point at the exact control: a pulsing coach-ring beacon
overlay (fixed-position, pointer-events-none, aria-hidden; ResizeObserver on
anchor + body, resize + capture scroll refresh; static ring under reduced
motion), data-coach-target stamped on anchors, one-shot scroll-into-view for
off-viewport targets, a popover arrow on the card, step-declared side/align
defaults, and a presence registry that lets the strip flag a missing target
with recovery copy. Hide hints silences ring, card, scroll and presence
through the single existing gate.

The scenario becomes a chaptered tour (state v2 under the same localStorage
key; v1 blobs migrate onto live-loop): live-loop (unchanged), edit-event,
variables, branches (stops at review/merge preview — no merge), reconcile,
alerting, explore. Chapters complete via mutation-driven notifies (inert
outside the active chapter) or route visits; the strip shows chapter progress
and a next-chapter CTA; ProductTour and DemoWelcomePanel share the new
ChapterPicker. ~15 new coach anchors across events, variables, branches,
reconciliation and alerting surfaces; edit-event deep-links back into the
visited editor via a recorded editorPath artifact.

Review fixes folded in: dismiss preserves completed status, chapter switch
pauses the outgoing chapter, digest-safe copy tweaks, non-vacuous poll test.

Gates: tsc clean; eslint zero-warning; vitest green per-file — scenarioModel
55, Provider 21, Strip 20, CoachMark 16, entryPoints 7, EventForm 8,
ScansTab 13, ScanDetail 9, ScanConfigDetailView 3, MetricsCatalog 5,
MonitoringDetailPage 35.
Copilot AI review requested due to automatic review settings July 18, 2026 22:26

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.

Pull request overview

This PR delivers “Onboarding v2” improvements across the demo onboarding experience, adding an empty-workspace welcome hero, stronger in-app coaching emphasis, and a chaptered (multi-area) guided tour that ties real user actions to scenario progress. It also updates the demo seeder (recipe v4) so the branches/variables chapters have real, non-empty content to teach against, and fixes weekly plan digest event counting to avoid double-counting when working branches exist.

Changes:

  • Frontend: replace the empty workspace dashboard with a product-intro hero; upgrade ScenarioCoachMark with beacon emphasis, scroll-into-view, missing-target fallback, and chapter-aware scenario strip/picker.
  • Frontend: expand the demo scenario from a single 4-step chain into multiple chapters (live-loop, edit-event, variables, branches, reconcile, alerting, explore) with many new anchors and updated tests.
  • Backend: bump demo recipe to v4, seed a real working-branch pending change + one open VariableValueDrift, extract reusable deep-copy helper, and scope weekly digest event counts to the main branch.

Reviewed changes

Copilot reviewed 50 out of 50 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
frontend/src/pages/settings/VariablesTab.tsx Adds demo scenario step notifications and coach mark anchors for variable drift/inspection.
frontend/src/pages/settings/ScansTab.tsx Renames scenario step ids to chapter-scoped ids for live-loop.
frontend/src/pages/settings/ScansTab.test.tsx Updates tests to v2 chaptered scenario state helpers and artifacts.
frontend/src/pages/settings/scans/ScanConfigRow.tsx Updates coach mark step id to chapter-scoped live-loop ids.
frontend/src/pages/settings/ScanDetail.tsx Updates watch-scan coach mark to live-loop chapter step id and defaults.
frontend/src/pages/settings/ScanDetail.test.tsx Migrates tests to v2 chapter state + artifacts for watched scan rows.
frontend/src/pages/settings/ScanConfigDetailView.tsx Updates run-scan coach mark step id to live-loop chapter.
frontend/src/pages/settings/ScanConfigDetailView.test.tsx Updates scenario tests to chapter steps and chapter artifact storage.
frontend/src/pages/settings/BranchesTab.tsx Adds branch chapter anchors + step completion notifications for diff/comment/approve flows.
frontend/src/pages/ReconciliationPage.tsx Adds reconcile chapter step completion and a coach mark on seeded shadow accept.
frontend/src/pages/ProjectsPage.tsx Shows WorkspaceWelcome hero for an empty workspace; hides header CTAs/stat band until first project exists.
frontend/src/pages/ProjectsPage.test.tsx Adds regression coverage for the new empty-workspace hero and CTA behavior.
frontend/src/pages/MonitoringDetailPage.tsx Gates collect-metric coaching to the user’s own scenario metric artifact (chaptered).
frontend/src/pages/MonitoringDetailPage.test.tsx Updates demo scenario tests to v2 chapter artifacts and step ids.
frontend/src/pages/metrics/MetricsCatalog.tsx Updates collect/see-chart coach step ids to live-loop chapter equivalents.
frontend/src/pages/metrics/MetricsCatalog.test.tsx Updates scenario tests to v2 chapter state + artifact storage.
frontend/src/pages/events/EventRow.tsx Adds edit-event chapter coaching for edit affordance and reconcile drift badge anchor.
frontend/src/pages/events/EventForm.tsx Adds edit-event chapter step notifications and coach anchors for templated field + save.
frontend/src/pages/events/EventForm.test.tsx Adds a chaptered scenario test ensuring save mutation completes the edit-event chapter.
frontend/src/pages/events/EventDriftBadge.tsx Notifies reconcile chapter step completion when accepting schema drift.
frontend/src/pages/alerting/RuleReplayDialog.tsx Notifies alerting chapter completion on successful replay/simulate flow.
frontend/src/pages/alerting/DestinationCard.tsx Adds alerting chapter anchors/notifications for create-rule and simulate on seeded rule.
frontend/src/index.css Adds coach beacon ring animation + reduced-motion behavior.
frontend/src/demo/scenarioTestState.ts Introduces test-only constructors for v2 scenario/chapter states.
frontend/src/demo/scenarioModel.test.ts Expands reducer tests for chapter model, migration from v1, and step/path contracts.
frontend/src/demo/scenarioEntryPoints.test.tsx Updates entry-point tests to chapter picker UI and chapter lifecycle behaviors.
frontend/src/demo/ScenarioCoachMark.tsx Implements anchor capture, beacon overlay, scroll-into-view, placement defaults, and presence reporting.
frontend/src/demo/ScenarioCoachMark.test.tsx Adds coverage for beacon ring, target stamping, scroll-into-view, and hide-hints gating.
frontend/src/demo/ProductTour.tsx Replaces “Try it hands-on” single chain with chapter picker handoff.
frontend/src/demo/DemoWelcomePanel.tsx Replaces “Run the scenario” entry with a chapter picker for hands-on chapters.
frontend/src/demo/DemoScenarioStrip.tsx Makes the strip chapter-aware, adds missing-target fallback messaging, and next-chapter CTA.
frontend/src/demo/DemoScenarioStrip.test.tsx Updates strip tests for chapter model, next-chapter CTA, and missing-target fallback timing.
frontend/src/demo/DemoScenarioProvider.tsx Updates provider to v2 chapters, adds presence registry, and supports notify- and visit-driven steps.
frontend/src/demo/DemoScenarioProvider.test.tsx Updates provider tests for v2 chapters, migration, and “don’t poll while other chapter active” behavior.
frontend/src/demo/demoScenarioContext.ts Extends contexts for chapters + coach presence registry + artifact helpers.
frontend/src/demo/CoachBeacon.tsx Adds the ring overlay component rendered via portal and updated on layout changes.
frontend/src/demo/ChapterPicker.tsx Adds reusable chapter picker UI shared by welcome panel and tour.
frontend/src/components/workspace-welcome.tsx Introduces the empty-workspace welcome hero component with CTAs and pillar cards.
frontend/src/components/workspace-welcome.test.tsx Adds unit tests for workspace welcome hero copy, CTA behavior, and viewer mode.
frontend/src/components/workspace-welcome-pillars.ts Extracts welcome pillar content into a shared typed constant.
frontend/src/components/ui/popover.tsx Exports PopoverArrow to support coach mark arrow rendering.
frontend/src/components/command-palette.tsx Notifies explore chapter completion when the command palette is opened.
backend/src/tripl/worker/tasks/alerts_messages.py Scopes plan digest event counts to the main branch to prevent branch duplication.
backend/src/tripl/tests/test_demo_project.py Adds recipe v4 tests: pinned version, real branch diff, seeded value drift, determinism, reset purge.
backend/src/tripl/services/plan_branch_service.py Extracts deep-copy helper for reuse by demo seeder without committing.
backend/src/tripl/services/demo/scenario.py Bumps DEMO_RECIPE_VERSION to 4 and updates scenario build commentary.
backend/src/tripl/services/demo/builders/variables.py Seeds one open VariableValueDrift derived from ctx.now for determinism (recipe v4).
backend/src/tripl/services/demo/builders/branches.py Deep-copies plan to the seeded working branch and applies exactly one branch-side edit (recipe v4).
.beads/issues.jsonl Updates beads issue tracker entries for onboarding epic tasks.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +46 to +60
refresh()
const observer = new ResizeObserver(refresh)
observer.observe(anchor)
// The body too: layout shifts that MOVE the anchor without resizing it
// (a diff row collapsing above it, form hints appearing) change the body's
// height, so this catches them without any polling loop.
observer.observe(document.body)
window.addEventListener('resize', refresh)
// Capture: the anchor may live inside any scroll container, not just the page.
window.addEventListener('scroll', refresh, { capture: true, passive: true })
return () => {
observer.disconnect()
window.removeEventListener('resize', refresh)
window.removeEventListener('scroll', refresh, { capture: true })
}

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in db6a873 — CoachBeacon now guards typeof ResizeObserver === 'undefined' and degrades to the existing resize + capture-scroll listeners.

Comment on lines +104 to +108
{available && (
<div className="mt-4 max-w-xl">
<p className="mb-1.5 text-[10px] font-semibold uppercase tracking-[0.07em]" style={{ color: 'var(--fg-faint)' }}>
Coached chapters
</p>

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in db6a873 — quick-start.md, use/user-guide.md and use/demo-workspace.md now describe the Coached chapters picker (seven chapters, live-loop steps kept as the first chapter) instead of the retired single 'Run the scenario' flow.

…ssertion, docs synced to coached chapters

CI: App.test expected the retired 'No projects yet' page copy — the empty
workspace now opens on the welcome hero, so the test asserts the hero heading
(the sidebar keeps its own copy for its own states).

Copilot: CoachBeacon degrades to resize/scroll listeners when ResizeObserver
is unavailable instead of throwing; quick-start, user-guide and demo-workspace
docs now describe the chapter picker (Coached chapters / seven chapters)
instead of the retired single 'Run the scenario' flow.
…tsFound)

The recipe-4 demo branch deep-copies event types under the same names, so
the three unscoped by-name lookups in the worker began matching two rows:
grouped scans crashed with MultipleResultsFound (test_demo_scans on CI), and
the same latent crash sat in metrics find-or-create and catalog sync. New
worker/plan_scope.main_branch_id resolves the project's main branch (same
idiom as the digest fix); all three lookups now filter branch_id. Pre-recipe-4
projects with an open working branch were exposed to the same crash.

Gates: pytest test_demo_scans (7) + test_demo_runtime (12) green; ruff clean.
…5) (#53)

* feat(search): keyless semantic search for the demo project via precomputed embedding fixture (tripl-odrj.5)

The demo now showcases hybrid semantic search with NO embedding provider
configured. A compressed fixture (search_embeddings_v4.npz, 209 KB: float16
vectors + JSON manifest; 66 doc vectors across both demo branches + 8 curated
query vectors) ships in the repo, keyed by sha256 of the exact worker embed
text — extracted into a shared embed_text_for helper so worker and fixture
can never drift, with deterministic ordering of field/meta/tag/variable parts
so keys are dialect-stable. reindex_project_branch stamps fixture vectors on
demo projects (Postgres-only, recipe/dims/model-guarded, idempotent, corrupt-
archive-safe no-op), covering provisioning, the lazily indexed feature branch
and manual reindex; fixture-stamped ready rows survive incremental reindexes.
At query time a demo project with no live embeddings resolves the normalized
query against the canned vectors and runs the real pgvector semantic leg,
marking semantic_used. Non-demo behavior is unchanged and a live provider
under a different model wins over the fixture.

Generation: scripts/generate_demo_search_embeddings.py (injectable embedder,
run once by a maintainer with an OpenAI key; the committed fixture was
generated after the ordering fix). CI freshness gate rebuilds demo docs and
asserts full fixture coverage incl. the advertised queries; it skips only
when the fixture is absent.

Frontend: explore/use-search step and a new tour step teach 'purchase funnel'
/ 'money back'; the command palette marks semantic matches with a 'semantic'
chip. Docs: searching-events, ai-and-search and demo-workspace document the
demo exception to the semantic-requires-provider contract.

Gates: mypy strict + ruff clean; pytest — demo_search_embeddings 17, search
suites 24, demo_project 20; tsc + eslint zero-warning; vitest — tourSteps 5,
scenarioModel 56, command-palette 7. numpy added as a direct dependency.

* fix(tests): derive ProductTour step count from buildTourSteps (CI, PR #53)

The new Smart search tour step made the tour 11 steps; four ProductTour tests
hardcoded 'of 10' and the 9-advance finish walk. The count is now derived
from buildTourSteps so adding a step never breaks these tests again.
@vladenisov
vladenisov merged commit 3108ab3 into main Jul 19, 2026
3 checks passed
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.

2 participants