A working build of Verbena LMS.
This is a clickable prototype running on two synthetic programs, Alder and Bluestem, each with a cohort at a different stage. It exists so you can see the program layer working rather than read about it: every number on these screens is computed from the database when the page loads, and the actions write back.
Verbena LMS runs the whole program: coursework, hours, milestones, eligibility, payments and leave. Courses can live in it, or it can read from the LMS a program already uses.
What you will be looking at
76
Candidates
two programs, four cohorts
114.2K
Hours logged
weekly records
144
Milestones complete
derived, not stored
$328.3K
Stipends approved
with an audit entry each
What is in the build
Three views, one set of records.
Candidates, coaches and program staff see different screens computed from the same rows. Change something on one side and the others reflect it without a refresh. What each role can see and do is enforced on the server, not hidden in the interface.
Candidate
Where am I, what is next
One screen answers the question candidates ask program staff most often.
- Milestone timeline with current position and window dates
- Open tasks for the current milestone, and what closed
- Hours pace against the requirement, with the ratio shown
- Next milestone payment and why it is or is not eligible
- Editable weekly hours that recalculate pace on save
- Resource library, announcements, reflections, coach chat
Open a candidate view →
Coach
My caseload, not the cohort
A sponsor at an employing site sees the people they support and nothing else.
- Only the candidates assigned to them, across both programs
- Who needs them first, ranked by overdue work then pace
- Their own check-in list, scoped to that caseload
- Pace distribution and hours for that caseload alone
- Milestones, notes and direct messages per candidate
- Eligibility and enrollment stay with program staff
Open a coach view →
Program staff
Cohort visibility and triage
The layer that usually lives in spreadsheets and email threads.
- Cohort dashboard: active, on leave, at risk, hours, dollars
- Roster with sort, filter and search across every cohort
- At-risk list grouped by the reason each candidate is flagged
- Milestone payments tracked and approved, never disbursed here
- Leave handling that shifts remaining dates when leave ends
- Six CSV reports by program and cohort, plus the audit log
Open the program staff view →
If you only have five minutes
A path that shows the mechanism.
These five steps follow one candidate from their own view, through their coach, to an approved payment and the record of it, and touch most of what the platform does.
Open a candidate who is mid-program.
The timeline shows where they are, the callout names any task that closed unfinished, and the pace card colors against the hours requirement. Nothing here is entered by staff; it is derived from hours and milestone records.
Log hours for them, then go back to the dashboard.
Raise a few recent weeks and tab away. The pace ratio moves, the status changes, and the next milestone payment moves between blocked and on track. Lower the hours and it reverses. This is the loop that usually runs on a spreadsheet beside the LMS.
Open the coach who has them, and try to leave the lane.
A coach is a sponsor at the employing site, not Alliance staff. They see their own caseload and nothing else. Try opening a candidate who belongs to a different coach and the platform will not show them: the assignment is checked when the page is built, not just hidden from the menu.
Switch to program staff and open the at-risk list.
Each candidate is grouped by the reason they were flagged, not by a single score. Open one and generate an AI insight: it reads that candidate's record and drafts outreach a staff member edits and sends. The model never contacts anyone directly.
Approve a payment, open the audit log, then pull a report.
Approving a milestone payment writes a row naming who did it, which candidate, which payment and when. Verbena LMS never moves money; it decides eligibility, records the approval and hands finance a clean list. Reports then export the same figures as CSV, scoped to whichever program and cohort you filtered to, which is the part a funder eventually asks for.
Worth saying plainly
What this build deliberately does not do.
No real authentication
The sign-in screen is a stand-in for the SSO handoff. There is nowhere in this build to enter a credential.
No email or SMS delivery
Reminders are composed and logged rather than sent, so nothing leaves the demo.
Mock integrations
LMS, exam prep and intake-form connections are described, not wired. Records here are local.
No funder-level segregation
Programs and cohorts scope every staff screen, but a funder cannot yet be given a login that sees only their own.
Synthetic records only
Seventy-six generated candidates across four cohorts. No real person appears anywhere in this data.
No content authoring
Milestones, tasks and resources are seeded rather than created through the interface.
These are prototype boundaries, not product limits. Each one is scoped explicitly when a deployment is planned.
Where it runs
The prototype and a deployment are different shapes.
This build is hosted for speed of iteration. A deployment is dedicated to one organization and looks like the architecture below.
This prototype runs on
A deployment runs on
A deployment is dedicated: its own application, database and file storage in a single US AWS region, reached only through an HTTPS load balancer, with point-in-time recovery and separate development, staging and production environments. The subprocessor list for a deployment is AWS, Anthropic, Amazon SES, USPS, GitHub, and the customer's own JotForm account.
Click anything. It is all live.
Edits persist, state updates across both sides, and the data regenerates from a seed script, so nothing here can be broken in a way that matters.