// Red Team Report — Full Audit History
✓ FINDING 1 — FIXED: Loop Test Height Calculation Error
Python version test computed h = 2×R×sin(45°)+R = 24.14m instead of correct R + R×sin(45°) = 17.07m. Core calculation logic was correct — only the test setup had the wrong height. HTML version uses correct height formula throughout.
✓ FINDING 2 — DOCUMENTED: PDF Typo in Example 5c
Source PDF states a = 37.018 m/s² for braking deceleration, but correct math is: 81054 N ÷ 3000 kg = 27.018 m/s² = 2.76g. This simulator uses the mathematically correct value.
✓ FINDING 3 — FIXED: Banked Curve Domain Error
Math.acos(1/g_felt) crashes when g_felt < 1.0. Fixed: validates g_felt ≥ 1.001 before executing arccos.
✓ FINDING 4 — FIXED: Spring Division by Zero
spring_constant = (mass × 107.8) / x_max crashes on x_max = 0. Fixed: validates x_max > 0.
⚠ FINDING 5 — KNOWN LIMITATION: Friction Not Modeled
Ideal energy conservation only (no friction losses). Real coasters lose ~5–15% to friction. Module 10 demonstrates this gap explicitly with three documented coasters.
⚠ FINDING 6 — KNOWN LIMITATION: Train Length Effects
Physics calculated at center of mass only. Rear-car g-forces on hills are approximately 1.2–1.4× higher than calculated.
Red team pass 1: March 2026 — 4 bugs fixed ·
Red team pass 2 (citation-backed): March 2026 — 6 issues fixed ·
Module 10 added: March 2026 · Red team pass 3: March 2026 — 5 bugs fixed + 2 features ·
Architect: Sheldon K. Salmon × ALBEDO · Status: 15 total issues resolved.
// PASS 2 — CITATION-BACKED PEER REVIEW
✓ PASS-2 FINDING 1 — FIXED: getGStatus() called 7.99g “SAFE”
Fixed: Three-tier system. SAFE (≤5g) | CAUTION (5–6.5g) | BLACKOUT-RISK (6.5–8g) | BLACKOUT (8g+). Sources: Tony Wayne AP Physics Guide · CoasterForce (NASA Bioastronautics Data Book 1964) · Coasterpedia.
✓ PASS-2 FINDING 2 — FIXED: Track Builder brake distance was hardcoded
Brake zone length is now a required user input field (default 10m). Fabricated precision over a hidden estimate is a reliability failure.
✓ PASS-2 FINDING 3 — FIXED: Negative g intermediate zone missing
Three zones: AIRTIME (0 to -1g) | NEG-G caution (-1g to -2g) | REDOUT-RISK (-2g to -3g) | REDOUT (-3g+). Source: CoasterForce (NASA).
✓ PASS-2 FINDING 4 — FIXED: Formula notation ambiguous (v²/Rg)
All formula displays now use unambiguous dot notation: v²/(R·g). Citation added: University of Gothenburg / Liseberg Physics (2005).
✓ PASS-2 FINDING 5 — FIXED: Safety table labeled 5g as “SAFE”
Row now reads Design ceiling (Tony Wayne): 5.0g → DESIGN LIMIT. Separate row for typical 3–4g operating range.
✓ PASS-2 FINDING 6 — FIXED: Track Builder loop labeled as generic “LOOP”
Segment now labeled “LOOP (CIRC)” with note directing users to Module 4 for irregular loop design.
// PASS 3 — RT-PASS3 CODE AUDIT & FEATURE ADDITIONS (March 2026)
✓ RT-PASS3-FIX1 — FIXED: designLoop() division by zero when gb=1.0
R_bottom = v² / ((gb−1) × g). If gb=1.0, denominator = 0, result = Infinity. Input HTML had min="1" but no runtime guard. User entering exactly 1.0 would produce Infinity radius with no error. Fixed: guard added at top of designLoop() — if(gb ≤ 1.0) exit with explicit error explaining the physics (at 1g, radius is infinite — the track would be flat).
✓ RT-PASS3-FIX2 — FIXED: designHill() canvas crash when v=0
maxX = √(2 × maxH × v² / g). When v=0, maxX=0. Then sX = (W × 0.4) / 0 = Infinity. All canvas coordinates become NaN. Canvas draws nothing, no error shown. Fixed: guard added — if(v ≤ 0) exit with explicit error: “At v=0 the hill has infinite width (train falls straight down).”
✓ RT-PASS3-FIX3 — FIXED: calcWork() division by zero when mass=0
v2 = √(2 × ke2 / m). When m=0, result = NaN. Previously guarded with safeVal(id, 1) as fallback, but user could type 0 explicitly. Fixed: explicit guard — if(m ≤ 0) exit with error message.
✓ RT-PASS3-FIX4 — FIXED: calcBrake() silent fallback to d=0.001 when distance=0
Previous: const d = safeVal('bf-dist', 0.001). If user entered 0, d silently became 0.001. Braking force output appeared precise (81,054 N) but was computed over an invented 0.001m distance. A simulator presenting fabricated precision over a hidden override is a reliability failure. Fixed: explicit guard — if(d ≤ 0) exit with error.
✓ RT-PASS3-FIX5 — FIXED: applyToEnergy() / applyToGForce() fragile tab activation
applyToGForce() used document.querySelectorAll('.tab-btn')[2].classList.add('active'). Correct as of v2 (index 2 = G-Forces), but any tab order change would silently activate the wrong tab. Fixed: new activateTab(id) helper uses document.querySelector('[data-tabid=“id”]') — looks up by data attribute, not position. Order-independent.
★ RT-PASS3-FEATURE1 — ADDED: Unit Toggle (SI Metric / Imperial)
Full bidirectional unit conversion across all 11 tabs. Implementation: global UNITS flag + rH/rV/rM/rF/rD input readers (always return SI internally) + fmH/fmV/fmM/fmF output formatters + toggleUnits() converts all data-utype tagged inputs on switch. Internal physics always runs in SI. Zero precision loss on round-trip conversion. All labels update dynamically via updateAllLabels(). Results always show both primary and alternate unit where useful.
★ RT-PASS3-FEATURE2 — ADDED: Export to PDF (Lab Report Generator)
Zero-dependency implementation. exportPDF() collects all currently displayed result-box elements from the active tab, constructs a clean white-background lab report HTML with: student name / class / date fields, calculated results in a formatted table, AION certification footer, date/time stamp. Opens in new window, auto-triggers window.print() after 400ms. Browser 'Save as PDF' produces a clean lab handout. No external library. Works offline.