services/vitals reads the real pulse and breathing of the volunteer lying on the table, using Presage SmartSpectra on a fixed camera. It’s an iPhone on a stand, connected to the Mac as a Continuity Camera. Processing happens on the Mac, and Scalpal stores no footage.
Why it’s there
The volunteer’s real vitals don’t react to virtual surgery, so we never show them as live surgical vitals. Instead:- Baseline (real). At Time-Out, Presage measures the volunteer. That becomes this patient’s starting pulse and breathing rate.
- Change (simulated). A small physiology model maps the surgery state to vitals changes, using ATLS hemorrhage classes against an estimated blood volume of 70 mL per kg.
- Display. The OR monitor shows the combined value with a label, like
HR 110 · simulated from baseline 85 (measured).
An active bleed pushes toward the next class, stopping it lets values recover over 10 to 30 seconds, and a critical injury adds an acute spike. The model is a pure function, so Unity, Scalpal and the recap can all reproduce the same numbers. It’s authored teaching content, not a validated clinical simulation.
Quota guard
The Presage key has a fixed budget of live minutes, so the service protects it:- Demo by default.
npm startruns labeled demo mode with synthetic vitals and no quota. Live mode needsnpm run live. - Sessions stop themselves after
PRESAGE_LIVE_MINUTES(default 5). - No face, no spend. If no face is in view for
PRESAGE_NO_FACE_SECONDS(default 15), the session ends. - Clean failures. If the camera can’t open, the session ends with the reason and the server keeps running.
- A ledger. Live time is logged to
.presage-usage.json, and live mode is refused oncePRESAGE_BUDGET_MINUTES(default 50) is used up.
Setup
.env (never committed):
The process running the service needs camera permission in System Settings → Privacy & Security → Camera. Without it, the camera won’t open, but the session fails cleanly and logs no time.
Camera setup for someone lying flat
- Mount the phone at the head end, 0.5 to 1 m away, angled down.
- Frame the face and upper chest. Presage reads pulse from facial skin and breathing from chest movement. It doesn’t need the abdomen, so the surgeon’s hands stay out of its view.
- Turn the phone so the volunteer’s chin points to the bottom of the image.
- Use even light on the face, and keep everyone else out of frame.
- The volunteer stays still and doesn’t talk.