Two files do all the work. One file you edit often. One file you almost never touch.
✏️
ilab-data.js
Edit this
- All program signup links (LINKS)
- Every event that can appear in results (EVENTS)
- Every office hours session (OHS)
- The 3 recommended steps per persona + sector (STEPS_DATA)
- Persona card copy and colors (PERSONAS)
- Content resolver functions (getSteps, getEvents, getOHs)
🔒
founder_xp_generator.html
Rarely touch
- Quiz questions Q1–Q5 (HTML)
- Quiz navigation logic (pick, fwd, back)
- Persona scoring algorithm (calcPersona)
- Results page renderer (renderResults)
- Visual design and layout (CSS)
Rule of thumb: If the real world changed (new event, new link, new program), edit ilab-data.js.
If the quiz itself needs to behave differently (new question, different routing), edit the HTML.
You should almost never need to touch the HTML.
Q1
Stage
Explore · Test · Propel
Q2
Goal
Feedback · Milestones · Community · Funding
Q3
Time Commitment
Light · Moderate · Heavy
Q4
Sector
LifeSci · Climate · DeepTech · Social Impact · General
Q5
Format
Remote · Hybrid · In-Person
calcPersona() — in founder_xp_generator.html
Answers are scored → Persona is assigned
Q1, Q2, Q3, Q4 all contribute. Q5 (format) does NOT affect persona — it only affects display.
Left column
3 Steps
From STEPS_DATA in ilab-data.js
Filtered by persona + sector
Right column
Events
From EVENTS in ilab-data.js
Filtered by tags, sorted by format
Bottom grid
Office Hours
From OHS in ilab-data.js
Filtered by persona tags
Quiz answers add points to four buckets. The highest scoring bucket wins and becomes the persona.
Two hard overrides skip scoring entirely and route directly.
⚡ Hard Overrides — checked first, skip all scoring
if (sector === 'socialimpact') return 'impact';
if (time === 'light') return 'community';
If either of these conditions is true, the scoring table below is never consulted. The persona is locked immediately.
| Quiz Answer |
Explorer |
Validator |
Builder |
Propeller |
| Stage (Q1) |
| Stage = Explore |
+5 |
– |
– |
– |
| Stage = Test |
– |
+3 |
+2 |
– |
| Stage = Propel |
– |
– |
+1 |
+5 |
| Goal (Q2) |
| Goal = Feedback |
+2 |
+3 |
– |
– |
| Goal = Milestones |
– |
+1 |
+3 |
– |
| Goal = Community |
+2 |
+1 |
– |
– |
| Goal = Funding |
– |
– |
+1 |
+3 |
| Time (Q3) |
| Time = Moderate |
+1 |
+2 |
– |
– |
| Time = Heavy |
– |
– |
+3 |
+1 |
Worked Example
Someone answers: Stage = Explore · Goal = Feedback · Time = Moderate · Sector = Deep Tech
Result: Explorer persona. Deep Tech sector is then used to customize which step 2 they see — but it never changed the persona itself.
The Six Personas
🌱
Explorer
High explore score. Still figuring out the idea.
🧪
Validator
High feedback + moderate time. Testing a real problem.
🏗️
Sprint Builder
High builder score + heavy time commitment.
🚀
Growth Founder
High propeller score. Traction exists, building momentum.
💚
Impact Founder
Hard override: sector = Social Impact
🤝
Community First
Hard override: time = Light
Dimension 1 — Persona
Who you are as a founder
Determined by quiz scoring. Controls the shape and tone of the results page — headline, description, recommended journey stack.
Dimension 2 — Sector
What you're building
Selected directly in Q4. Never changes the persona. Only changes which specific steps, events, and programs appear inside that persona's results.
← PERSONA
|
Life Sci |
Climate |
Deep Tech |
Social Impact |
General |
| 🌱 Explorer |
OOH + Primer |
OOH + Primer |
OOH + Hackathon |
OOH + Primer + SIFF |
OOH + Primer + Hackathon |
| 🧪 Validator |
Sys Dynamics + OOH |
Primer + OOH |
Primer + OOH |
Primer + OOH + SIFF |
Primer + OOH |
| 🏗️ Builder |
Sys Dynamics + Sprint |
Sprint (default) |
Vibe Coding + Sprint |
Sprint + SIFF |
Sprint |
| 🚀 Propeller |
Accel Sessions |
Accel Sessions |
AI Agents + Accel |
Accel Sessions + SIFF |
Accel Sessions |
| 💚 Impact |
Always routes here when sector = Social Impact — sector column becomes irrelevant |
| 🤝 Community |
Always routes here when time = Light — only community events shown, sector irrelevant |
Highlighted cells = sector-specific programming exists. Others fall back to default path.
Steps are a lookup table. Each row says: "For this persona, in this sector, at this step number — show this action."
Three sector keywords control the priority.
sector: 'lifesci'
Sector-specific
Wins for founders in that exact sector. Override the default for this persona.
sector: 'default'
Fallback
Shows when no sector-specific row exists. Every persona should have one per step.
sector: 'all'
Universal
Always shows, regardless of sector. Use for steps that apply to everyone in this persona.
Priority Order — for each step number
Sector-specific row
e.g. sector: 'lifesci'
→
not found?
→
Default row
sector: 'default'
→
not found?
→
Example: Builder persona — who sees what at Step 1
STEPS_DATA → builder array
builder
lifesci
1
Register: System Dynamics for HC + Life Sciences wins for LifeSci
builder
deeptech
1
Register: Vibe Coding Workshop wins for DeepTech
builder
default
1
Commit to the Customer Discovery Sprint wins for Climate, General, others
builder
all
3
Register for MVP Feedback Session shows for everyone
Every change you will ever make falls into one of two categories.
Identifying the type first tells you exactly which file to open.
Type 1 — Catalog Update
Something in the real world changed
A new event was added. A link changed. A session was cancelled. A step description has an old date. These are factual updates to what exists — you're keeping the catalog accurate.
File to open: ilab-data.js — LINKS, EVENTS, OHS, or STEPS_DATA sections
Type 2 — Logic Update
Who sees what needs to change
An event should now surface for a different persona. A step should be different for Climate founders. Too many people are landing on the wrong persona. You're changing the rules of who gets shown what.
File to open: ilab-data.js (tags or STEPS_DATA) or founder_xp_generator.html (calcPersona)
Type 1 — Catalog
Updating a link
1
Find the program row in the Links tab of your Google Sheet
The key column tells you the exact identifier (e.g. SPRINT_SIGNUP)
2
Open ilab-data.js on GitHub → find the LINKS section at the top
Ctrl+F the key name to jump directly to it
ilab-data.js → LINKS
3
Replace the '#' or old URL with the new URL
Commit the change — it goes live immediately
Type 1 — Catalog
Adding a new event
1
Add a row in the Google Sheet → Events tab
Fill in all columns. Set active to yes. Decide which tags it should carry.
2
Add the same event as an object in ilab-data.js → EVENTS array
Copy an existing event object as a template. Change the id, name, date, format, tags, desc.
ilab-data.js → EVENTS
3
If it needs a signup link, add the key to LINKS first
Add the key to LINKS, then reference it in the event object if needed
Type 1 — Catalog
Removing a cancelled event
1
Find the event in ilab-data.js → EVENTS
Never delete the row — future semesters you may want to bring it back
ilab-data.js → EVENTS
2
Change active: true to active: false
The event immediately disappears from all results. The row stays in your data for reference.
Type 2 — Logic
Making an event show for a different persona
1
Find the event in ilab-data.js → EVENTS
ilab-data.js → EVENTS
2
Add or remove the relevant persona or sector tag from the tags array
Example: to show this event for validators, add 'validator' to tags. To stop showing it for builders, remove 'builder' from tags.
Type 2 — Logic
Changing a recommended step for a persona
1
Open ilab-data.js → STEPS_DATA
ilab-data.js → STEPS_DATA
2
Find the right persona block, then the right sector and step number
e.g. builder → sector: 'lifesci' → step: 1
3
Edit the a: (action title) and/or d: (description) fields
To add a new sector-specific path, add a new row with the sector name. The default row still covers everyone else.
Type 2 — Logic
Changing how personas are scored / routed
1
Open founder_xp_generator.html → find calcPersona()
This is the only function in the HTML you should ever need to edit for content reasons
founder_xp_generator.html → calcPersona()
2
Adjust the point values to change relative weighting
Higher number = stronger pull toward that persona. Refer to the scoring table in Section 3 of this page to understand current weights before editing.
3
To add a hard override, add it at the top of the function
Example: if (sector === 'climate') return 'impact'; — this skips all scoring for Climate founders
Run through this at the start of every semester. In order.
-
Duplicate the Google Sheet and rename it for the new semester
Google Sheet
-
Update every URL in the Links tab — confirm no '#' placeholders remain
ilab-data.js → LINKS
-
Set active: false for any events that are not running this semester
ilab-data.js → EVENTS
-
Add new events as objects with correct tags and format
ilab-data.js → EVENTS
-
Update office hours schedules and set active: false for anything not running
ilab-data.js → OHS
-
Review each step in STEPS_DATA — update dates in action titles and descriptions
ilab-data.js → STEPS_DATA
-
Update the header eyebrow text ("Summer 2026") in the HTML if semester changed
founder_xp_generator.html → header
-
Push all changes to GitHub
-
Test at least 6 persona combinations — one per persona — and verify links work
-
Test retake flow — confirm quiz resets cleanly from results page
| I want to change… |
Update type |
File |
Location in file |
| A signup or info link |
Type 1 |
ilab-data.js |
LINKS section at top |
| An event name, date, or description |
Type 1 |
ilab-data.js |
EVENTS array — find by id |
| Hide a cancelled event |
Type 1 |
ilab-data.js |
EVENTS → active: false |
| Add a new event |
Type 1 |
ilab-data.js |
EVENTS → add new object |
| Office hours schedule |
Type 1 |
ilab-data.js |
OHS → sched field |
| Step action title or description |
Type 1 |
ilab-data.js |
STEPS_DATA → a: or d: fields |
| Persona card headline or description |
Type 1 |
ilab-data.js |
PERSONAS → hl: or desc: fields |
| Which persona or sector sees an event |
Type 2 |
ilab-data.js |
EVENTS → tags: [] on that event |
| Which persona sees an office hour |
Type 2 |
ilab-data.js |
OHS → tags: [] on that OH |
| What a persona sees at step 1, 2, or 3 |
Type 2 |
ilab-data.js |
STEPS_DATA → find persona + sector + step |
| Add a sector-specific step path |
Type 2 |
ilab-data.js |
STEPS_DATA → add new row with sector name |
| How personas are scored / weighted |
Type 2 |
founder_xp_generator.html |
calcPersona() function |
| Add a hard override (always route X to Y) |
Type 2 |
founder_xp_generator.html |
calcPersona() — top of function |
| Quiz questions or answer choices |
Type 2 |
founder_xp_generator.html |
Q1–Q5 HTML blocks |
| Design, colors, or layout |
Design |
founder_xp_generator.html |
CSS :root variables + style rules |