M4 - Real services and data
From @Brittany Wolff : I have this Confluence doc and this miro board that detail the (more or less) current state of the usage dashboards. It is built on a series of materialized views which are not in Snowflake, but could probably be recreated there. Except it looks like we don't have teachings in Snowflake yet which is one of the base tables. You can find the SQL for the materialized views in the repo (db/views). I think the current versions would be:
M3 - Deletion and sunsetting of Toggles in Atlas
M5 - Legacy platform — QA
QA and regression complete on the §4.5 legacy platform changes; no open blocking defects.
M6 - Full-coverage testing
Unit, integration, E2E, accessibility, performance, and regression coverage per §6 complete across rad-helix and rad-platform-layer.
T1 — Step-machine contract tests
The registration dispatcher is the highest-risk code in the app and has no test. Cover the allowlist (unlisted path, wrong method, undeclared query param all rejected before upstream), the CSRF pair (minted per mutation, Set-Cookie relayed to the browser), the provisioning timeout, and pass-through fidelity — a TrialStepResponse must reach the client unmodified, including the statuses that represent refusals.
Exit criteria: every ENDPOINTS row exercised against a mocked trial_manager; a 200-with- refusal-status never surfaces as an error, and a transport fault never surfaces as a step.
T2 — Funnel E2E across visitor states
Playwright walk of the funnel in each state the step machine can put a visitor in: new email, existing account, SSO-required, student-blocked, expired campaign, out-of-region, plus trial-one and trial-everything. Demo mode drives the signed-in/signed-out split.
Exit criteria: each branch reaches a correct terminal screen; no branch dead-ends or shows a raw error.
M7 - Legacy platform — release
Opt-in banner, user setting, and nav changes shipped to production ahead of go-live.
T1 - Route-level integration coverage
(RC-1110, 5 pts, To Do)
There is no test harness in the repo yet. Scaffold Vitest + @nuxt/test-utils and cover the campaign and catalog routes against mocked upstreams: session forwarding per environment, write-flag gating (405), no-session behavior (401), and upstream-error mapping. These gates are the newest logic in the app and the easiest to regress silently.
Exit criteria: suite runs in CI with no live upstream; every write route asserts its 405 and 401 paths.
T2 - E2E pass over the admin surfaces
(part of RC-1125)
Playwright walk-through of the sidebar shell, campaign create/edit/archive/publish, catalog create and edit across all three record kinds, contact creation, and Trends/Outreach against a mocked analytics payload — including the write-disabled variants of each screen.
Exit criteria: every primary flow green in both write-enabled and write-disabled configurations.
R1 - Verified dev deployment
(part of RC-1125)
The routing exists but has not carried a real deployment. Merge to develop, confirm the dev stack builds and deploys, and confirm the app authenticates against the dev Trial Manager and the content.dev session cookie — the one path where mixing DE_ENVIRONMENT and trialManagerEnv would drop the session.
Exit criteria: dev URL loads authenticated, campaigns and catalog read live dev data.
M8 - Full capability parity / go-live readiness
All P1 must-haves at Built; go/no-go checkpoint for Aug 30 launch.
M9 - Phase 1 launch — teacher opt-in live
LIMITED - teacher opt-in testing available; capability to activate for a small subset of users the same day.
R1 — Ship the migrated funnel to dev, then stage
The funnel now depends on trial_manager for every branch, so the deploy matters more than usual: verify against the dev stack that the anonymous CSRF pair survives the real cookie domain, that provisioning completes inside its timeout, and that the fallback paths don't mask a healthy backend.
Exit criteria: a real trial provisioned end to end in dev with no local heuristics involved.
R2 - Operator docs and handoff
(part of RC-1125)
Document the environment flags (TRIAL_MANAGER_ALLOW_WRITES, CONTENT_API_ALLOW_WRITES, DE_ENVIRONMENT, trialManagerEnv), the per-environment session-cookie model, and the data-gap workflow, then decide the write-flag posture per environment before prod.
Exit criteria: a developer new to the repo can run it locally, explain the flags, and add a data gap unaided.
M2 - Validate the prototype
Close the five open district confirmations and put the Grade 4 Q1 guide in front of the teachers who would run it.
Confirm CKLA unit order by quarter, Ready Math pacing, and whether Mystery Science unit order is actually flexible.
Confirm arts specialist involvement and whether collaborative planning time exists.
Name the pilot grade and teacher team for the coming year.
Write the definition of done for an arc — the rubric that later becomes the automated validator set.
Exit criteria
A teacher team walks the Q1 arc unaided and says they could run it, plus a written arc rubric.
M10 - Phase 1 iteration window
Refinements and fixes shipped based on telemetry, Pulse feedback, and further QA from the initial opt-in cohort.
M11 - Phase 2 expansion
Opt-in expanded to the Phase 2 cap
M12 - Phase 2 iteration window
Refinements and fixes shipped based on Phase 2 cohort feedback and QA.
M13 - Phase 3 expansion
Opt-in expanded to the Phase 3 cap; scale/performance validation per §6 confirmed ahead of the 20x jump.
M14 - Phase 3 iteration window
Refinements and fixes shipped based on Phase 3 cohort feedback and QA.
M15 - Phase 4 expansion
Opt-in expanded to the Phase 4 cap — final expansion within this plan's window.
M5 - Adoption and communication
Tentatively use in Q4 to complement PI Planning (led by @Nikkita Willis). Dates TBD.
M3 - Turn the framework into a schema
The single highest-leverage step. Convert the prose design principles into a machine-readable model so that generating an arc becomes filling a structure, not writing a document.
Define the arc data model — district, program, pacing week, standard, concept, subject thread, touchpoint, alignment record, culminating product.
Build the two output templates as renders of that model: leadership overview and teacher implementation guide.
Encode the rubric from Phase 0 as executable validators.
Exit criteria The Q2 prototype is re-expressed as structured data and re-rendered from it with no loss of quality.
M4 - Scale inside one district
Build all of K–5 for Jefferson County — roughly 24 arcs — with human experts on the schema and light tooling. Instrument the work from arc #1 so the automation targets are measured, not guessed.
Track hours per arc, edits per arc, and which steps consume the time (standards reading, overlap hunting, asset search, or writing).
Harvest reusable pieces: standards overlap maps, per-program pacing normalizations, the culminating product menu.
Ship arcs continuously to the pilot so instructional feedback arrives during the build, not after.
Exit criteria
Median build time per arc down 60%+ from arc #1 to arc #24, with a time breakdown that names the bottleneck.
M5 - Automate the alignment
Build the engine that does the mechanical work: reading pacing guides and standards, detecting genuine overlap, and attaching the right DE assets to the right week. Detailed in the next section.
Exit criteria
≥85% of proposed alignments accepted with no edit; expert review under two hours per arc.
M6 - Make it district- and program-agnostic
Everything district-specific becomes configuration data. Nothing about Alabama or Mystery Science is hard-coded anywhere.
Curriculum program library: each publisher’s scope and sequence normalized once, versioned, and reused by every district that licenses it. Onboarding district #2 with the same programs costs nothing.
Standards crosswalk: every state’s standard set resolved to the same canonical concept layer, so overlap detection works in any state without pairwise mapping.
Proof: a second state with a different publisher stack, built with no code changes.
Exit criteriaA new district is live in ≤2 weeks with zero engineering involvement.
M7 - Productize
Turn the internal pipeline into a surface other people can drive.
Authoring workbench opened to district curriculum staff, not just DE experts.
Teacher delivery experience inside DE — the arc as a live, dated plan rather than a PDF.
A library of published arcs, filterable by state, publisher stack, and grade.
Usage telemetry and teacher edits feeding back into alignment scoring.
Exit criteria
A district authors a usable arc without DE in the room.
Validate
Concept prototype, tested with a few trusted partners. Confirm problem, solution, and willingness to pay.
Scope & build
Working MVP with 1–2 district-approved AI platforms. All DE content indexed and searchable via MCP (DEX, Mystery Science, Techbook, CEP).
Pilot & refine
Test the trust value prop with a small set of pilot districts already on DE.
ContentBot - generated AI metadata
Full AI-forward content architecture for generating standards alignment, grades, subjects, lexile scores and more via extracted text and supporting models, architecture, services, and more. Round one of indexing completed.
Connect to Internal Tools (ScholarBot)
Build to spec in rad layers
@Derek Stutts is building in separate project repository
Testable app (for internal feedback)
Overall functionality accounted for, though may shift with feedback from team and cross-team.
Decision on API Framework
Now (foundation)
8-week workout plan, weekly plan view, AI coach with pre/post-activity and opening-day flows, activity generation, progress tracking and badges, DE asset + standards search, assignments (including public student links). Auth via DE SSO (toggle) behind a passcode gate.
Next
Deepen admin/coach analytics; richer personalization of the coaching path based on teacher profile and prior responses; broaden content/standards integration.
M1 - Initial POC Scaffolding & Data Exploration
Create scaffolding for initial POC and look into fetching data from snowflake. Result is here:
https://rad-mystery-customer-admin.discoveryeducation.com/
M2 - Initiatives Inclusion
Include initiatives and capx budget codes heirarchy per @Nikkita Willis and @Travis Barrs
Later
Full DE SSO rollout (remove passcode gate), expanded grade-band theming, scale beyond pilot cohorts.
M2 - POC Prototype
Based on designs and documentation here:
https://discoveryed.atlassian.net/wiki/spaces/MS1/pages/4739268626/Admin+Dashboard+Prototyping+and+Testing
Will overwrite previous POC and be located here: https://rad-mystery-customer-admin.discoveryeducation.com/
USER MUST BE ON VPN TO ACCESS (for internal testing ... we'll remove this once customers are accessing for testing : )
M3 - Feedback Redesign
Complete design overhaul to stay attuned to evolving project reqs.
M4 - Shift to production timeline
Leverage this work to shift to a production timeline and go-to-market strategy
M4 - Jira Integration
Integration of JIRA epics at the project level. First pass. More to come.
M1 - Roadmap Initial Release
Created v1 in 2 days for internal feedback and communications.
M1 - Kickoff and Scope Lock
M3 - Team Review Mystery Customer Admin with Team
Review Mystery Customer Admin with Team, make any adjustments needed iteratively.
M2 - Legacy platform — dev
Opt-in banner/workflow, user opt-in setting, and global nav changes (§4.5) built on the legacy platform.
M4 - Audit resolution
Every Audit-flagged item (Classrooms/Assignments, Assign, Profile → Recent Activity/History, Release Notes) has a real-vs-faked determination and a decision recorded against §11.
M1 - Signup migrated to the registration step machine
The old approach guessed locally at what the visitor should see next. trial_manager's /v1/trial-registration/* surface is a step machine: every call — including the ones that represent a refusal — answers 200 with a TrialStepResponse carrying status, step, and page_data. Whether an email already has an account, whether SSO is required, whether the visitor is a student, whether the campaign expired, whether the product is licensable in their region: all of it is now the server's call, passed through untranslated.
M2 - Internal management tooling removed; the app is a funnel again
Management surfaces that used to live here — the trials dashboard, per-school detail, contact add/edit, and the health-banner route — are gone. Trials is now the public funnel plus admin.vue for staff provisioning; internal trial and catalog management belongs to Catalyst (rad-trials). Marketing copy across the funnel was refreshed in the same pass.
This split is the point, not a side effect: two apps, one public and one internal, with opposite crawler postures and opposite audiences.
M3 - Demo-mode audience switch for staff
A "Demo as" control lets staff preview the funnel as a signed-in or signed-out visitor without juggling sessions — the thing that makes the funnel's branches walkable at all. Gated behind requireDeStaff, which validates the DE session against /v1/users/me and requires a campaign-manager role (401 unauthenticated, 403 without the role).
M4 - Accessibility and fallback-flow pass
Skip-to-main-content link, aria-live on the loading overlay, role="alert" on every form error across the account / trial / admin flows, prefers-reduced-motion handling, and labelled aria-expanded disclosure controls in the trial layout. Alongside it: the fallback paths were exercised — hardcoded campaign URLs still stand in when a campaign can't be resolved, and the SSR product list still renders when the live catalog fetch fails.
M5 - SEO and AIO surface
All three discovery routes generate from shared/products, so they can't drift as the catalog changes. llms.txt (llmstxt.org format) gives assistants a structured guide with the qualifying facts they need to answer correctly — free, no credit card, up to 60 days, US K–12. FAQPage schema is backed by the same three questions rendered visibly on the page, so an educator and an answer engine get the identical answer. Organization / WebSite / ItemList on the homepage; Product + Offer + BreadcrumbList per product. useSiteUrl pins one canonical origin so preview hosts don't fragment canonicals.
M3 - Catalog management on the EDDE Content API
RC-1109, RC-1122 · contentApiClient.ts, server/api/catalog/*, CatalogManager.vue
New server-side Content API client with environment-aware session cookies, X-Token minting for writes, and upstream errors mapped to real status codes with the API's own message. On top of it, one CatalogManager component drives products, SKUs, and media groups with search, pagination, detail modals, relationship navigation, and debounced reference pickers.
M1 - Live data replaced seeded data on the insight surfaces
One endpoint (/api/trials/analytics) now returns a normalized row per school plus the product catalog, assembled from three trial_manager reads: the paged trials feed, per-school trial detail (cached, time-budgeted fan-out), and the product list. Trends split into Overview / School Trials / Grassroots; Outreach became the call-list surface. Both filter and recompute client-side from that single payload.
The careful parts: opportunity totals dedupe on opportunity_id so a two-product opportunity does not double-count pipeline; days_left comes from upstream so this page and the dashboard cannot disagree; a book past the 20-page ceiling sets a truncated flag rather than silently understating every KPI.
M2 - Campaign Manager, end to end
RC-1108 · server/api/trials/campaigns/*, campaigns.vue
Marketing campaigns — which decide what trial offers registration shows — are now readable and editable in the app: list, create, edit, archive, and a Publish action that triggers the GDS sync so registration sees changes immediately. Writes gate on TRIAL_MANAGER_ALLOW_WRITES and the UI says so instead of failing at the API.

