Add phet_simulations mirror site (port 40015) - #29
Conversation
Adds Flask app, templates, and seed DB for PhET Interactive Simulations (https://phet.colorado.edu/), claiming port slot 40015. Catalog: 98 simulations across 5 subjects (physics, chemistry, math, biology, earth-science), 4 grade levels (elementary, middle, high, university), and 28 languages (incl. 3 RTL scripts). Every primary filter bucket clears the >=20-record threshold. Models: User, Subject, GradeLevel, Language, Simulation, Activity, SavedSimulation. Routes: 17 public + 2 JSON APIs + /_health, all reachable from /. Auth via Flask-Login + bcrypt; saves via CSRF-protected JSON endpoints. Idempotency: every seed_* helper early-returns when its table is populated; verified byte-identical (md5 e094a2ee...) across the control_server reset cycle (rm -rf instance; cp -a instance_seed instance; re-import app). Tested under the exact Dockerfile pin set (Flask 3.1.0, SQLAlchemy 2.0.36, Werkzeug 3.1.3). Per the port-slot convention, also: - websyn_start.sh: append to SITES, bump 15 -> 16 in startup messages - control_server.py: append 'phet_simulations' to SITES list - Dockerfile: EXPOSE 40000-40014 -> 40000-40015 Seed DB (instance_seed/phet_simulations.db, 143KB) packs into a 17KB phet_simulations.tar.gz via scripts/extract_assets.sh and ships separately via the Hugging Face dataset. .assets-revision will need a bump after the HF PR merges. tasks.jsonl: 43 benchmark prompts covering catalog browse, subject filters, simulation detail extraction, search, translations, teacher activities, and the account save flow.
Replace placeholder UI with a high-fidelity mirror of the real
PhET Interactive Simulations site.
Visual:
- Real PhET yellow trademark logo + CU Boulder logo in white header bar
- Right-aligned nav (Simulations / Studio / Teaching / Research / Initiatives)
with hover dropdowns; collapsing search icon + profile icon
- Dismissible pink educator banner
- Photo-backed top hero ("Interactive Simulations for Science and Math")
- 5 pastel subject squares in PhET's canonical order (Physics, Math &
Statistics, Chemistry, Earth & Space, Biology) with their SVG icons
- Photo-backed Teaching Resources callout
- "Interact. Discover. Learn." stats section with real iconography
- Secondary STEM hero photo + centered "Supported in part by" + Donate CTA
- Real footer: social row, 4-column links, language selector, app-store
badges, sponsor logos strip (Moore, Hewlett, NSF, Mastercard, Yidan)
Simulations browse page:
- Underwater illustration banner + Browse / Filter / Customize sub-tabs
- Filter view is the default; left sidebar with collapsible subject tree,
grade level, compatibility, release type, inclusive features, locale,
apply / clear, active-filter chips, sort dropdown, results count
- Browse view groups sims by subject with "View all »" links
Simulation detail page:
- Large screenshot with hover "Play" overlay
- Tabbed sections (About / Teaching Resources / Activities /
Translations / Credits) plus topics, learning goals, related sims
- "Supported by" sidebar, share row, pink Explore More + Donate CTA
Backend wiring:
- Index route adds total_activities for the stats section
- Simulations route exposes view tab and per-subject buckets
- App.py exposes available_thumbnails so cards fall back gracefully
when a slug has no screenshot
Assets ship via the paired HF dataset tarball (not committed):
- 98 sim screenshots (49 from PhET CDN, 49 generated placeholders)
- PhET + CU Boulder logos, subject icons, sponsor logos, hero photos,
app-store badges, underwater simulations banner
Seed DB unchanged, /reset/phet_simulations remains byte-identical
(md5 e094a2ee23369d3b60232f49f4ac691c).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Conflicts resolved: - websyn_start.sh / control_server.py: append berkeley after phet_simulations (PR base predated aiming-lab#29). - Dockerfile EXPOSE 40000-40015 → 40000-40016. Fixes on top of PR: - sites/berkeley/seed_data.py: pin bcrypt hash for benchmark users. set_password() uses bcrypt.generate_password_hash which mixes a random salt on every call, breaking the byte-identical reset invariant. We store a pinned $2b$12$ hash for 'test1234' directly; check_password_hash still accepts it so login works unchanged. - sites/berkeley/app.py: __main__ port 40015 → 40016 (cosmetic — site_runner passes port via -c string, not via __main__).
Conflicts resolved:
- websyn_start.sh: keep PR's dynamic count (${#SITES[@]}) — removes the
hardcoded "16" from aiming-lab#11/aiming-lab#29 base; append drugs_com after berkeley.
- control_server.py: append drugs_com after berkeley.
- Dockerfile EXPOSE 40000-40016 → 40000-40017; keep berkeley build-time
RUN; pick up requests==2.32.3 dep from PR.
- .gitignore: merge both sides (keep main's dashboard ignores + PR's
local artifact ignores).
Note: drugs_com seeds via pre-built HF db (refs/pr/13), so the dynamic
bcrypt salt in app.py's set_password does NOT cycle on reset.
Review —
|
Addresses all points from MufanQiu's review:
1. Homepage now renders simulation grids (BLOCKER). index.html displays
the route's featured / new_sims / most_played context in three
subject-section rows (20 sim cards), so task --41 is solvable from /.
2. 'New' release filter is functional (MAJOR). simulations() now reads
release=new (is_new) and release=updated (released >= 2024-01-01);
the sidebar checkboxes persist state and the active-filter chip,
sort, and pagination links carry the param. Task --21 is solvable
via UI (answer: 7 New sims, all released 2025).
3. No DB mutation on GET (MAJOR). Removed play_count increment in
simulation_detail and download_count increment in activity_detail;
counts are now fixed seed data, so tasks --6/--31/--41 have
deterministic answers.
4. Seed/task disambiguation (MINOR):
- Activities carry explicit pairwise-distinct download counts;
unique most-downloaded = Net Force Investigation (8742), paired
with Forces and Motion: Basics (task --12).
- Sim versions derived deterministically from seed constants
(47 distinct versions; Wave Interference = 1.5.2, task --28).
- Tasks --6, --24, --28, --31 reworded with tighter constraints so
each has exactly one valid answer (verified programmatically).
Seed DB rebuilt; reset cycle remains byte-idempotent
(md5 48ca438b8ac6dab37a6503a4e5574503). 66/66 routes return 200.
New phet_simulations.tar.gz must be re-uploaded to the HF dataset and
.assets-revision repinned to the HF merge SHA (separate commit).
|
Thanks for the thorough review — all five points addressed in b15feb3:
Re-verified locally: 66/66 routes 200, reset cycle byte-idempotent (seed md5 |
|
I'm taking over the review and remediation of this PhET Interactive Simulations contribution. I'll build a separate The review will cover current-main integration (site registry/port slot and the |
|
Review PR is up as a Draft: #114 (branch Two findings drove most of the work, and I want to be direct about the larger one. 43 of the 98 seeded simulations do not exist on phet.colorado.edu. I checked every one of The catalogue is now the real HTML5 library from PhET's official metadata service: 120 Every page overflowed horizontally below about 840px. The desktop nav, search form and user Also fixed from @MufanQiu's earlier list, which I re-verified at The task set is rebuilt from 43 to 18. Nine targeted fabricated simulations, four read the Assets: ChilleD/WebHarbor discussions/79 supersedes #19, since #19's seed is the fabricated Still outstanding on the review PR: the independent review of the frozen runs, and a full |
Addresses all points from MufanQiu's review:
1. Homepage now renders simulation grids (BLOCKER). index.html displays
the route's featured / new_sims / most_played context in three
subject-section rows (20 sim cards), so task --41 is solvable from /.
2. 'New' release filter is functional (MAJOR). simulations() now reads
release=new (is_new) and release=updated (released >= 2024-01-01);
the sidebar checkboxes persist state and the active-filter chip,
sort, and pagination links carry the param. Task --21 is solvable
via UI (answer: 7 New sims, all released 2025).
3. No DB mutation on GET (MAJOR). Removed play_count increment in
simulation_detail and download_count increment in activity_detail;
counts are now fixed seed data, so tasks --6/--31/--41 have
deterministic answers.
4. Seed/task disambiguation (MINOR):
- Activities carry explicit pairwise-distinct download counts;
unique most-downloaded = Net Force Investigation (8742), paired
with Forces and Motion: Basics (task --12).
- Sim versions derived deterministically from seed constants
(47 distinct versions; Wave Interference = 1.5.2, task --28).
- Tasks --6, --24, --28, --31 reworded with tighter constraints so
each has exactly one valid answer (verified programmatically).
Seed DB rebuilt; reset cycle remains byte-idempotent
(md5 48ca438b8ac6dab37a6503a4e5574503). 66/66 routes return 200.
New phet_simulations.tar.gz must be re-uploaded to the HF dataset and
.assets-revision repinned to the HF merge SHA (separate commit).
|
Review complete. #114 is out of Draft and ready for maintainer review. Since my last comment the branch was rebased again: upstream merged fedex, webmd_doctor, Two independent review rounds were run on the frozen executions in sessions with no access to the The first round flagged evidence-quality gaps rather than wrong verdicts, and chasing them turned
A 90-cell adversarial matrix then found three verifiers a wrong answer could satisfy: the two One thing for the maintainers rather than for you: Merge order: HF discussion #79 first, then Thanks for the mirror — the Flask app, auth, CSRF and reset behaviour were solid throughout, and |
Addresses all points from MufanQiu's review:
1. Homepage now renders simulation grids (BLOCKER). index.html displays
the route's featured / new_sims / most_played context in three
subject-section rows (20 sim cards), so task --41 is solvable from /.
2. 'New' release filter is functional (MAJOR). simulations() now reads
release=new (is_new) and release=updated (released >= 2024-01-01);
the sidebar checkboxes persist state and the active-filter chip,
sort, and pagination links carry the param. Task --21 is solvable
via UI (answer: 7 New sims, all released 2025).
3. No DB mutation on GET (MAJOR). Removed play_count increment in
simulation_detail and download_count increment in activity_detail;
counts are now fixed seed data, so tasks --6/--31/--41 have
deterministic answers.
4. Seed/task disambiguation (MINOR):
- Activities carry explicit pairwise-distinct download counts;
unique most-downloaded = Net Force Investigation (8742), paired
with Forces and Motion: Basics (task --12).
- Sim versions derived deterministically from seed constants
(47 distinct versions; Wave Interference = 1.5.2, task --28).
- Tasks --6, --24, --28, --31 reworded with tighter constraints so
each has exactly one valid answer (verified programmatically).
Seed DB rebuilt; reset cycle remains byte-idempotent
(md5 48ca438b8ac6dab37a6503a4e5574503). 66/66 routes return 200.
New phet_simulations.tar.gz must be re-uploaded to the HF dataset and
.assets-revision repinned to the HF merge SHA (separate commit).
Summary
Adds a 16th mirror site to WebHarbor: PhET Interactive Simulations
(https://phet.colorado.edu/). Bound to port 40015.
Real site: University of Colorado Boulder's CC-BY-licensed catalog of
free interactive math and science simulations. Selected for its clean
taxonomy (subjects × grade bands × languages), stable academic content,
and no commercial anti-bot defenses.
Seeded catalog
Visual fidelity
Mirror is reskinned to closely match the real PhET site:
(Simulations / Studio / Teaching / Research / Initiatives)
photo-backed Teaching Resources callout, Interact/Discover/Learn stats,
second STEM hero, sponsor footer (Moore / NSF / Hewlett / Mastercard / Yidan)
/simulationsBrowse / Filter / Customize tabs with underwater banner;Filter view has left-sidebar with collapsible subject tree, grade level,
compatibility, locale, active-filter chips, sort
Credits), large screenshot, supported-by sidebar, Donate CTA
Assets ship via the paired HF dataset PR (see below). 98 sim screenshots
(49 from PhET CDN, 49 styled placeholders for slugs not in HTML5 lib),
plus logos, sponsor logos, hero photos, subject icons, app-store badges,
underwater banner. ~5 MB tarball total.
Paired HF dataset PR
https://huggingface.co/datasets/ChilleD/WebHarbor/discussions/19
This PR is in Draft status until the HF PR merges. Once merged,
.assets-revisionwill be bumped to the merge commit SHA and thedraft will be marked ready for review.
Test plan
python3 -m py_compile sites/phet_simulations/app.py./scripts/build.shsucceeds (3.07 GB image)docker run -d --rm -p 8101:8101 -p 40000-40015:40000-40015 webharbor:devphet_simulationsalive on port 40015/,/simulations,/simulations?view=browse,/simulations?view=filter&subject=physics,/simulation/build-an-atom,/simulation/algebra-tiles,/teachers,/translations,/about,/accessibility)POST /reset/phet_simulationsreturns"ready": trueinstance/phet_simulations.dband
instance_seed/phet_simulations.dbboth equale094a2ee23369d3b60232f49f4ac691cpost-reset and afterdocker restartReset evidence