Inspiration
I started with a conversation, not a spreadsheet.
I spoke with a man who spent nearly four decades in prison and knows this system from the inside. He explained where program data actually comes from. Nonprofit facilitators come into the facility, run a class of 20 to 50 people, and leave. Inside, there are no computers, no phones, and no recording. The only record is usually a paper sign-in sheet, and the facilitator has to turn it into numbers after walking out. When they're busy, the record is simply lost.
The stakes are high. In California, people who take part in rehabilitative programming return to prison at 21.1%, compared to 45.6% for those who don't. Every person who stays home saves the state an estimated $21,534 per year. Yet rehabilitation receives less than 0.1% of CDCR's $14B budget.
Transformative Programming Works (TPW) leads a coalition of 120+ organizations making that case to legislators. To make it well, they need clean program data from every member. Today it arrives through a shared spreadsheet and a basic form, full of "TBD", blank fields, and placeholder numbers.
That conversation showed us something the spreadsheet hides. TPW doesn't collect data from people; it collects it from organizations. Each organization runs many programs, at many facilities, through several facilitators. The organization answers to TPW, but the facilitator is the one walking out with the numbers. A spreadsheet asks one person to know everything. So we asked: what if each level only had to enter what it actually knows?
What it does
CycleLog is a data gathering tool for TPW's member organizations. It gives each organization one place to set up its programs, assign its facilitators, and send TPW clean, validated records, without anyone retyping the same information twice.
Three levels, one record
Every program cycle is one record, but different people know different parts of it at different times. CycleLog splits the work so each level enters only what it knows.
TPW sits at the top. A TPW admin creates and archives member organizations, owns the field list, sees every submission across the coalition, and exports clean data for reporting.
Organizations set up their work once. An org admin adds their facilitators and builds a program catalog with names and course hours. Then they create program cycles: facility (from the CDCR list), yard, program, and start date. They assign a facilitator to each cycle and choose how often CycleLog checks in with them. Organization name is locked to their account, so it is consistent across every submission.
Facilitators only report what happened: how many people started, how many completed, the end date, and any notes. Everything else is already filled in.
The result is a facilitator form of about four fields instead of eleven, and an organization that sets up a cycle once instead of retyping it every time.
We call them, or they report on their own
Scheduled check-in calls. CycleLog calls the facilitator at the points the organization chose for that program. It always calls after the first session and after the final session. In between, the organization picks the frequency, such as every two weeks or monthly. Facilitators pick a call window that suits them, and get a text before each call. Each call takes under a minute and asks only what's due at that point.
Keypad for numbers. Facilitators enter numbers on the phone keypad, not by voice, because speech recognition confuses "fifteen" and "fifty". Every number is read back before it's saved.
Self-reporting anytime. Facilitators can open CycleLog and enter the same numbers themselves whenever they like. If they've already reported, the scheduled call is skipped.
Missed calls don't mean missing data. If a call goes unanswered, CycleLog tries once more, then texts a link to the same questions. If there's still no answer, the cycle is flagged to the org admin, who can enter it themselves.
One engine underneath
Schema-driven. TPW's field list is editable config. It generates the call questions, the form questions, the validation, and the output columns. When a TPW admin adds a field, they also choose who fills it (organization or facilitator) and when (at setup or at close-out). The field then appears in the right person's call and form, with no developer and no redeploy.
Deterministic branching. If a cycle is In Progress, CycleLog skips End Date and Number Completed. If an exact date is unknown, it applies TPW's first-of-month / last-of-month rule. If a facilitator says on a final call that the program hasn't finished, the call is rescheduled instead of forcing a number.
Bad data is stopped before it's saved. This covers required fields, valid dates, end after start, no "TBD" in number fields, facility chosen from the CDCR list, and completions that can never exceed participants started. Validation runs live during a call: if a facilitator keys in an impossible number, the call says why and asks again.
Fast repeat entry for organizations. Organizations running 20+ cycles a year can duplicate a previous cycle, copy it to another yard or facility, or upload several at once.
Likely duplicates are flagged with the matching entry shown. Parallel cohorts are real, so the user confirms "separate cohort" instead of being blocked.
Clean output. Each cycle lands as a standardized row in [a Google Sheet / CSV] that TPW can use immediately.
Two calculated fields are added automatically:
$$\text{Total Participant Hours} = N_{\text{completed}} \times H_{\text{course}}$$ $$\text{Program Year} = \text{year}(\text{Start Date})$$
For the stretch goal, we propose an optional aggregate Program Credits field (1 credit = 1 day of reduced sentence), so TPW can estimate the impact of each cycle:
$$\text{Time Saved (years)} = \frac{\text{Credits}}{365} \qquad \text{Money Saved} = \frac{\text{Credits}}{365} \times \$21{,}534$$
Privacy by design
Calls and forms ask how many, never who. No participant names, CDCR numbers, or demographics are collected anywhere. Only the numbers from a call are saved; the audio is not kept. Everything is aggregate, at the program-cycle level. Each organization sees only its own data, and each facilitator sees only their own cycles.
How we built it
- Front end: [framework], mobile-first, with large tap targets and plain-language errors.
- Roles and access: three role-based views over one shared data model (TPW admin, org admin, facilitator), so the hierarchy adds no duplicate data.
- Login: [magic link / SMS code] for facilitators, so there are no passwords to forget.
- Field schema: [JSON / Google Sheet tab], where each field carries its type, rules, owner role, and stage. Call scripts, form questions, validation, and output columns are generated from it at runtime.
- Check-in scheduler: creates calls from each cycle's start date, end date, and the check-in frequency the organization chose, and skips any call whose questions are already answered.
- Calls and texts: [telephony service, e.g. Twilio] for outbound calls with keypad (DTMF) input, read-back confirmation, and text-message fallback.
- Validation engine: plain, deterministic code shared by calls and forms, so the same rules apply on every path.
- Output: [Google Sheets API / CSV export].
Challenges we ran into
- The environment is the constraint: no devices or recording inside, so everything happens after facilitators leave.
- Facilitators forget: so CycleLog calls them instead of waiting for them to submit.
- One call at the end is too late: we split reporting into short check-ins, with the first and final calls always on.
- Calls have to fit real life: facilitators choose a call window and get a text first.
- Voice is bad at numbers: every number is entered on the keypad and read back.
- Missed calls: we retry once, send a text link, then flag the cycle to the org admin.
- Prisons lock down: "not finished yet" reschedules the final call.
- One spreadsheet, three kinds of knowledge: one shared record split across TPW, organizations, and facilitators.
- New fields need an owner: every field says who fills it and when.
- History has to survive change: organizations are archived, never deleted, and renamed fields still match old data.
- Duplicates vs. real cohorts: we flag and ask instead of blocking, and one lead facilitator owns each cycle.
Accomplishments that we're proud of
- We designed from the real workflow, not the assumed one. Our direction changed after hearing how data is actually captured and who actually holds it.
- Reporting no longer depends on anyone remembering. CycleLog calls the facilitator on a schedule the organization chooses, and facilitators can still report on their own anytime.
- Each level enters only what it knows. Organizations set up a cycle once, and facilitators answer about four questions.
- A TPW admin can change a field with no developer. [Demo: adding "Program Credits," assigning it to facilitators at close-out, and hearing it asked on the next call.]
- Validation stops the problems TPW described before they reach the sheet, including during a live phone call: "TBD" in number fields, blank required fields, end dates before start dates, and completions higher than participants.
- A fallback chain, from call to retry to text link to org admin, so a missed call doesn't become a missing record.
- A clean, standardized row landing in the sheet, matching TPW's field list exactly, with Total Participant Hours and Program Year calculated automatically.
What we learned
- Adoption is the real data-quality problem. The best data tool is one people don't have to remember to use.
- The organization is the right unit. TPW's relationship is with 120+ organizations, so the tool should make each organization's job easy, and each organization should make its facilitators' job easy.
- Ask each person only what they know, when they know it. Most bad data comes from asking someone to guess.
- Voice is a good way to ask and a poor way to collect numbers. The keypad and a read-back fixed that.
- Privacy is a design choice. The safest way to protect a name is to never ask for it.
- A schema-driven design makes the tool durable. TPW's fields will change, and the tool shouldn't need a developer when they do.
What's next for CycleLog
- A TPW dashboard showing which organizations have reported, built on the call and fallback status we already track
- A submission summary for each organization: total cycles, facilities, participants, and hours delivered
- Calls and texts in Spanish and other languages facilitators prefer
- Scanning paper sign-in sheets to count signed rows, without reading names, as a third way to report
- Aggregate outcome fields such as program credits, with time and money saved calculated for TPW
- A shared definition of "participants started" across the coalition, so completion rates are comparable between organizations
- A pilot with coalition members and feedback from people who have lived these programs
Built so that the programs that bring people home are counted
Log in or sign up for Devpost to join the conversation.