rall Trust

The trust contract

How we measure your technique, and how confident we are.

Rallo is a technique coach. We claim observations about your stroke — knee load through the trophy pose, kinetic-chain ordering, contact position relative to your body, racket path through impact. Every one of those carries a target band or a qualitative read, a set of capture conditions it depends on, and an honest statement of what we have and have not checked it against. Today that answer is the same for every metric: not yet checked against any independent reference. This page is the engineering contract behind those observations, in plain language. If a metric is missing here, it is not in the app.

What Rallo is not: a line judge. We do not call ball placement or in/out. We do not show a ball-flight map. The trust-contract wedge is the accuracy of what we say about your body, your racket, and your timing — not where the ball landed.

This page is that contract in full. The bands below are the accuracy targets each metric must meet to ship — they are targets, and none of them has been checked against an instrument or an independent human annotation. What we run today is a stability check against our own earlier output on the bundled clips, described exactly in section 02; the tighter instrument cross-checks a lab would use are named there, each with its real status — some planned, one not scheduled at all. When a target or a method changes, we log it at the bottom — no silent revisions.

v1 scope note (2026-05-17)

v1 ships the body-pose + scale-prior path. Metrics tagged COURT_CALIBRATED in the tables below are deferred to v1.1. That includes ball placement, ball speed, on-court player position, foot-fault checks, and court-frame metrics generally. Metric scale comes from your stored height and racket length rather than the court geometry — bands widen accordingly. The technique-coaching value prop ships intact.

01 /What we measure

Three confidence tiers. High-confidence metrics are published as a number with a tight band. Medium-confidence metrics are published with a wider band or as a qualitative bucket. The third tier is the list of numbers we will not show you, and the reasons.

High confidence Number, no band

Rendered as a number, together with a plain-language read of what it means. No error band is shown next to it, because we do not have one. The band in the table below is the accuracy target the metric must meet — it is a design target, not a measured result, and no measurement on this page has yet been checked against an instrument or an independent human annotation (section 02 sets out exactly what we do and do not run). Publishing no interval is a decision, not an oversight. We could model one from tracking confidence and print a plausible ±, and it would look more rigorous than what we show you. It would also be a number about our own certainty dressed up as a number about your body, and you would have no way to tell the difference. We would rather show you a figure with an honest description of what stands behind it than a figure with a margin we invented. The first check that could produce a real interval is independent human annotation, listed in section 02; when one exists it will be published with the reference that produced it. If the capture conditions for a metric fail, the metric is hidden and the app says why.

Metric Units Target band (target, not measured result) Capture required
Knee load at loading degrees ± 8° peak (geometry target, not a measured result). Deep flexion at the trophy is the hardest knee angle to read from a single camera, so this carries the widest band of the knee readings. SIDE_VIEW
Contact reach torso-lengths (scale-free) ± 0.2 torso-lengths (geometry target, not a measured result). Normalised to the player’s own torso, so this one needs no court calibration. PLAYER_IN_FRAME
Leg drive at contact degrees ± 8° peak (geometry target, not a measured result). Read as knee extension, not as a height — a single uncalibrated camera cannot turn vertical travel into centimetres. SIDE_VIEW
Leg drive into contact degrees ± 8° peak (geometry target, not a measured result). Same limitation as leg drive at contact: an angle change, never a distance. SIDE_VIEW
Leg drive travel degrees ± 8° peak (geometry target, not a measured result). The span of knee extension across the drive, not a measured displacement. SIDE_VIEW
Trunk balance at contact degrees ± 5° controlled, ± 8° peak (geometry target, not a measured result). Distinct from balance offset above, which is a centimetre reading. SIDE_VIEW
Trunk extension at contact degrees ± 5° controlled, ± 8° peak (geometry target, not a measured result). SIDE_VIEW
Trophy elbow angle degrees ± 5° SIDE_VIEW
Knee joint angle (general) degrees ± 5° controlled, ± 8° peak SIDE_VIEWPLAYER_IN_FRAME
Elbow joint angle degrees ± 5° controlled, ± 8° peak SIDE_VIEWPLAYER_IN_FRAME
Shoulder elevation angle degrees ± 5° controlled, ± 8° peak SIDE_VIEW
Wrist layback angle degrees ± 5° controlled, ± 8° peak SIDE_VIEW
Body rotation at contact degrees ± 5° AUDIO_FIDELITY
Racket path angle degrees, low to high ± 5° SIDE_VIEWFRAMERATE_120+
Racket drop depth cm below top of head ± 5 cm SIDE_VIEW
Racket drop dwell time ms ± 16 ms (1 frame at 60 fps) FRAMERATE_60+
Contact height above shoulder cm, court-calibrated ± 5 cm COURT_CALIBRATEDSIDE_VIEW
Forward contact distance cm in front of lead hip ± 5 cm COURT_CALIBRATEDSIDE_VIEWAUDIO_FIDELITY
Contact lateral position cm from body midline ± 5 cm AUDIO_FIDELITY
Toss height cm above contact ± 5 cm COURT_CALIBRATED
Toss lateral placement cm from center mark ± 5 cm COURT_CALIBRATEDBEHIND_FENCE
Vertical hip displacement cm ± 2 cm at typical 6–8 m, ± 1 cm at tight 4 m COURT_CALIBRATEDSIDE_VIEW
Forward weight transfer cm of CoM travel ± 5 cm COURT_CALIBRATEDSIDE_VIEW
Balance offset cm ± 5 cm SIDE_VIEW
Player position on court (x, y) m on court surface ± 5 cm COURT_CALIBRATED
Ball placement at bounce court coordinates, in/out ± 10–20 cm COURT_CALIBRATED
Outgoing ball speed km/h ± 5 km/h target (v1.1; radar cross-check planned, not yet run) COURT_CALIBRATEDFRAMERATE_120+
Contact timing (audio anchored) ms same pose-frame window (~33 ms at 30 fps); audio impact onset corroborates contact in that frame, not a sub-frame bound AUDIO_FIDELITY
Stroke phase boundaries frame index per phase ≤ 2 frames at 60 fps (~33 ms) PLAYER_IN_FRAME
Split-step timing ms vs opposing-stroke-end ± 1 frame at 60 fps PLAYER_IN_FRAME
Racket tip 2D trajectory pixels per frame, 1080p ≤ 8 px error, ≥ 95 % detection on unoccluded frames SHUTTER_LOCKED_FAST
Racket tip court-plane trajectory (x, y) m on court ≤ 5 cm RMS during groundstroke phases, ≤ 10 cm at peak swing COURT_CALIBRATEDSHUTTER_LOCKED_FAST
Volley backswing length cm, target < 10 cm ± 3 cm SIDE_VIEW
Volley followthrough length cm, target < 25 cm ± 3 cm SIDE_VIEW
Volley wrist-angle variation degrees through contact ± 3° FRAMERATE_120+
Choke-up grip detection cm of palm above grip butt ± 1 cm SIDE_VIEW
Grip type categorical: continental, eastern, semi-western, western ≥ 90 % correct, contact frame SIDE_VIEWPLAYER_IN_FRAME
Stroke type identification 12-class (serve flat / slice / kick, FH topspin / slice, BH 1H / 2H / slice, volleys, smash) macro F1 ≥ 0.92 target (labelled-set certification planned) PLAYER_IN_FRAME
Backhand handedness (1H vs 2H) categorical ≥ 95 % correct in contact ± 100 ms window PLAYER_IN_FRAME
Court calibration status categorical: ok / degraded / failed v1.1 court-pose target, not yet set or run; v1 is single-line scale calibration, checked against known ITF line geometry — no court-pose accuracy figure claimed INTRINSICS_PRESENT

Medium confidence Number with caveat, or qualitative bucket

Either the band is wider than coaching needs, the signal isn't fully validated yet, or a physics floor (camera frame rate, motion blur) caps the achievable accuracy. Where the band exceeds what a coach would call useful, the app drops the number and shows a qualitative bucket instead.

Metric Units Target band (target, not measured result) Capture required
Kinematic sequence (2D, v1 path) verdict: proper / partial / inverted / insufficient, with adjacent lead-gap (ms) verdict only; pipeline runs end-to-end on the bundled pro forehand and serve canaries; no per-clip cross-check against an independent reference has been run, and none is scheduled SIDE_VIEWPLAYER_IN_FRAME
Hip–shoulder separation (X-factor) degrees, 3D ± 5°, peak timing ± 1 frame at 60 fps SIDE_VIEW
Hip–shoulder separation timing ms ± 1 frame at 240 fps (~4 ms), audio-anchored FRAMERATE_240AUDIO_FIDELITY
Stance class categorical: open / semi-open / neutral / closed ≥ 80 % target (labelled-set certification planned) COURT_CALIBRATEDSIDE_VIEW
Racket-head speed (groundstrokes 60–120 km/h) km/h ± 8–12 km/h (240 fps sampling-rate floor) FRAMERATE_240SHUTTER_LOCKED_FASTAUDIO_FIDELITYCOURT_CALIBRATED
Racket-head speed (serves 120–200 km/h) km/h, or qualitative bucket if band > 15 km/h ± 10–15 km/h (sampling-rate floor) FRAMERATE_240SHUTTER_LOCKED_FASTAUDIO_FIDELITYCOURT_CALIBRATED
Racket face orientation at contact degrees from vertical ± 8°, hidden if motion blur > 8 px or racket edge-on FRAMERATE_240SHUTTER_LOCKED_FASTAUDIO_FIDELITY
Brush distance (topspin) cm of vertical racket-tip travel through contact ± 10 cm FRAMERATE_240AUDIO_FIDELITY
Spin classification categorical: topspin / flat / slice ≥ 90 % target (labelled-set certification planned) AUDIO_FIDELITY
Contact timing (visual fallback, no audio) ms ± 16–33 ms (visual frame quantum at 30–60 fps) PLAYER_IN_FRAME
Foot-fault check categorical with cm-over-line if true ± 15 cm boundary uncertainty (ankle-only) COURT_CALIBRATEDBEHIND_FENCETRIPOD
Forehand late-contact catch position categorical: late / on-time / out-front qualitative bucket; no degree band claimed PLAYER_IN_FRAME
Forehand hip rotation (load → contact) degrees, image-plane ± 10° on side-view; behind-fence reads attenuated PLAYER_IN_FRAME
Forehand shoulder rotation (load → contact) degrees, image-plane ± 10° on side-view PLAYER_IN_FRAME
Backhand late-contact catch position categorical: late / on-time / out-front qualitative bucket PLAYER_IN_FRAME
Backhand shoulder rotation (load → contact) degrees, image-plane ± 10°; 1H BH band 95–130°, 2H BH band 80–110° PLAYER_IN_FRAME
Racket-drop arm fold degrees, not scored Not scored. Shown as a number with its caveat and never graded, because a single 2D camera cannot back a validated window for it. No error band is claimed. The deepest dominant-elbow fold between loading and contact. Distinct from racket drop depth above, which is a centimetre reading. SIDE_VIEW
Shoulder-over-shoulder at contact degrees, not scored Not scored. Shown as a number with its caveat and never graded, because a single 2D camera cannot back a validated window for it. No error band is claimed. The tilt of the shoulder line from horizontal at contact. This is not the shoulder elevation angle listed above. SIDE_VIEW
Elbow at contact degrees, not scored Not scored. Shown as a number with its caveat and never graded, because a single 2D camera cannot back a validated window for it. No error band is claimed. The groundstroke elbow angle at contact. Listed separately from the elbow joint angle above, which is graded against a window. SIDE_VIEW
Knee at contact degrees (2D), not scored Not scored. Shown as a number with its caveat and never graded, because a single 2D camera cannot back a validated window for it. No error band is claimed. A three-point angle from hip, knee and ankle read in the image plane at contact. Listed separately from the knee joint angle above, which is graded against a window. SIDE_VIEW
Shoulder separation at contact degrees (2D), not scored Not scored. Shown as a number with its caveat and never graded, because a single 2D camera cannot back a validated window for it. No error band is claimed. A three-point angle across both shoulders and one hip, read in the image plane. It is not the 3D hip–shoulder X-factor listed above and must not be read as one. SIDE_VIEW

What we don't claim Hidden in v1

A single phone on a tripod cannot recover every measurement a biomechanics lab can. Where the physics or the licensing block a credible number, we hide the metric and tell you why instead of fudging it. These are the lines we will not cross to look more impressive.

What we don't show Why
Spin in RPM Optical RPM measurement of a tennis ball from a single phone is not solved at consumer hardware. Phones can't deliver > 1000 fps consistently; specialised radar or Doppler is required. We show qualitative spin (topspin / flat / slice) instead.
Pose-derived ball speed in mph as a precise number Pose-only estimation lands at roughly ± 8 % accuracy. That's not a number to put next to a radar gun. Outgoing ball speed comes from ball tracking with court calibration (high confidence, see above), not from the player's pose. Anything called "swing speed" without ball tracking gets a qualitative bucket.
Clinical 3D internal joint angles at impact A single monocular camera cannot recover hidden depth at peak velocities. Published floors for monocular methods sit around 4.8° rotational MAE under good conditions; that is not clinical grade. Bert AI and OnCourtAI display these anyway. We don't.
Joint torques and kinetic-chain power Requires force plates or instrumented insoles. Camera-only ML estimation that approaches lab grade is research-licence-only and cannot ship in a commercial app.
Internal shoulder rotation and pronation at impact Occluded and motion-blurred even at 240 fps from a side-view phone. An optional racket-butt IMU sensor add-on is on the v2 path.
3D string-bed normal at impact The racket is edge-on, blurred, or occluded at impact. A 3-frame illustration is not a continuous 3D measurement and will not be shown as one.
Ground reaction force No camera-only path. Needs force plates or instrumented insoles.
Foot-strike pattern (heel vs toe) Requires heel and first-metatarsal keypoints. The pose stack we use has ankle only, no foot keypoints. Documented as a known gap, not silently substituted. v2 path adds a small targeted foot-keypoint detector.
Foot pronation 3D foot orientation requires foot keypoints with depth. Single-phone monocular cannot resolve this reliably. Same v2 path.
Sub-cm foot-fault precision Sub-cm requires foot extent (toe and heel), not just ankle. v1 ships a coarse near-baseline / past-baseline read with a ± 15 cm buffer. We will not say "out by 3 cm" until the foot detector ships.
Injury-risk diagnosis Out of scope. Clinical claims unsupported by single-phone biomechanics, with liability we will not assume.
Match-play analysis v1 is practice only. Match play violates the capture contract: handheld phone, no tripod, no consistent court calibration, no locked exposure. The app refuses to enter metric mode under those conditions instead of silently degrading. Match analysis returns as a v2+ feature once the on-tripod product is shipped and trusted.
"AI tennis coach used by ATP players" or similar global accuracy claims Marketing language without external validation. We will not put it next to a metric until pro-canary results plus independent coach review pass for two release cycles.

02 /How we validate

Today, validation is what we can actually run, and it is narrower than we previously described on this page. The full pipeline executes end-to-end on the bundled pro-clip fixtures every build, and their measured reads are pinned so an unintended change fails the build. That is a regression check against our own earlier output: it proves our numbers are stable, not that they are correct. No human has hand-marked a contact frame or a phase boundary on any clip committed to this repo, so no measurement on this page has been checked against an independent reference. The instrument cross-checks a biomechanics lab would use — mocap, goniometers, a radar gun — are named below with their real status: planned, or in one case not scheduled at all; nothing on this page is anchored to them today. Independent human annotation is the next check we intend to run, ahead of any instrument work, because it is the only one on that list that can show a timing claim is wrong rather than agree with it.

Reference Status and what it covers
Bundled pro-clip fixtures in use The full pipeline runs end-to-end on the bundled clips — Djokovic and Isner serves, Sinner and Nadal forehands, and the SportAI reference serve — in the app and in the test suite. Their measured reads are pinned, so an unintended change surfaces as a failing test and the numbers can't drift clip-to-clip unnoticed. Read this for what it is: a stability check against our own earlier output. It catches regressions. It cannot tell us whether a number was right in the first place, because the value it compares against is one we produced, not one an instrument or a person measured.
Hand-marked frames not in use We previously claimed on this page that we hand-mark contact and phase frames on the bundled clips and check the pipeline lands in the same window. That was wrong, and we have removed it. There are no hand-marked frames on any bundled clip. The one fixture of frame indices we hold covers a single serve on a clip that is not committed here, no reviewer or review date was ever recorded against it, and its indices were derived by the same kinematic rules the segmenter itself uses — contact as the lowest dominant-wrist position, toss release as the non-dominant-wrist apex, knee bend as the minimum knee angle. Two of its eight stages are not observations at all but the midpoint in time between two neighbouring stages. Checking the segmenter against those indices tests that it reproduces its own rule; it cannot detect a rule that is wrong. Genuine human annotation is planned and is listed below.
Independent human annotation planned A reviewer marking contact and stroke-phase boundaries frame-by-frame from the video, blind to what the pipeline produced, on clips that are committed with resolved licensing. This is the first check that could actually falsify a phase or contact claim rather than confirm it. Until it runs, every timing claim on this page rests on rules we wrote, checked against themselves.
Court line geometry in use ITF singles-court dimensions are exact, so court calibration is checked against the known line geometry rather than an instrument. The court-frame metrics it enables are themselves v1.1 (see the scope note).
Motion-capture cross-check not scheduled A marker-based mocap comparison for joint angles at peak motion and kinematic-sequence timing. We previously listed this as planned for v1.5. It is not funded and not scheduled, and saying otherwise was a promise we had no plan to keep. It is also not the right first check: mocap certifies a lab condition with markers, controlled lighting and a fixed rig, and Rallo is used on a phone propped against a fence. It could tell us our geometry is sound under conditions we never ship in. Independent human annotation costs less, matches the condition we actually run in, and is the only one of these that can falsify a timing claim rather than confirm it, so it goes first. Nothing on this page is anchored to mocap today, and nothing is waiting on it.
Goniometer cross-check planned Controlled slow-swing joint-angle comparison to tighten the degree bands (knee, elbow, shoulder, wrist). Planned; not yet run.
Radar cross-check planned v1.1 Outgoing-ball-speed agreement against a radar gun, shipping with the court-calibrated speed path in v1.1. Planned; not yet run. Until then we publish no absolute ball speed.
Larger labelled benchmarks planned The classifier figures above (stroke ID, stance, grip, spin, handedness) are the targets each must meet. The balanced labelled sets to certify them are planned, not yet assembled.
Public-dataset held-out splits planned Reproducible held-out validation on public data (THETIS, AthletePose3D, RacketVision and similar) so an outsider can check the numbers. Planned; not part of the shipping build yet.

The audio-anchored kinematic sequence (the high-confidence version that uses 240 fps + impact-onset audio as t=0) is staged for v1.5. The 2D kinematic sequence at medium confidence ships now, using the bundled pro canaries as its reference. Those canaries are our own clips, not an independent standard, so the sequence verdict is a comparison against reference technique rather than a validated measurement. No mocap cross-check is scheduled; see the row above for why independent human annotation goes first.

03 /Capture conditions

The bands above hold when the capture meets the conditions below. The app evaluates these every session and tells you when a metric is hidden because a condition failed. Practice sessions only. No match play in v1 — the conditions can't be met handheld, courtside, mid-rally.

PLAYER_IN_FRAME

Player visible across the stroke

At least 90 % of player keypoints present in every frame across the stroke arc. If the player walks out of frame mid-swing, that stroke is flagged low confidence.

COURT_CALIBRATED

Court calibration locked

Court-frame metrics are v1.1 (see the scope note). What v1 ships is single-line scale calibration: you mark one court line of known length (an ITF baseline, service box, or net) and that fixes real-world scale for the distance and speed reads, checked against the known line length — not against an instrument, and with no accuracy figure claimed. Full court-pose calibration — solving the camera against the whole court geometry, with an accuracy target for it — is planned for v1.1 and has not been built or validated. There is no continuous drift-detection or auto-pause today: if the phone moves, you re-mark the line. No court-frame metric is shown until that calibration lands.

SIDE_VIEW

Side view (parallel to baseline)

Required for joint angles, racket drop depth, contact height, and most kinetic-chain reads. The app's first-frame view classifier flags the angle and selects the per-angle metric set.

BEHIND_FENCE

Behind fence (perpendicular to baseline)

Required for serve toss lateral placement, foot-fault check, and the behind-fence half of the serve report. We support both views; the report uses whichever angles are present.

FRAMERATE_120+

120 fps or better

Required for outgoing ball speed and any frame-quantised timing claim tighter than 33 ms. Below 120 fps, those metrics are hidden.

FRAMERATE_240

240 fps (slow-mo)

Required for racket-head speed at impact, body rotation timing in milliseconds, and brush distance through contact. iPhone 14 Pro and newer can sustain 240 fps; older devices fall back to 120 fps and the affected metrics are hidden.

SHUTTER_LOCKED_FAST

Shutter locked at 1/500 s or faster

Locked exposure, ISO, and shutter at recording start. Without this, the racket motion-blurs to a streak at impact and the keypoint detector can't read it.

AUDIO_FIDELITY

Audio impact band clean

Phone built-in microphone, RMS in the 3–5 kHz transient band above floor. The audio onset corroborates which pose frame contact lands in — frame resolution (~33 ms), not a sub-frame time. If the wind or distance kills the impact transient, contact timing falls back to a wider visual-only band and the app says so.

TRIPOD

Tripod-class stability

IMU-measured orientation noise under 0.1°. Stable handheld is supported with widened bands; wobbly capture is review-only and the metric layer is silent. Foot-fault detection always requires tripod.

04 /What we changed

The trust contract changes. When it does, we list the change here and date it. No silent revisions.

2026-07-30
Made the absence of an error band an explicit position rather than a gap. We could model a ± from tracking confidence and print something that looks more rigorous than what we show you; it would be a number about our own certainty wearing the costume of a number about your body, and nothing on screen would let you tell those apart. So we publish the figure and an honest account of what stands behind it, and no interval at all. Also removed the planned v1.5 promise from the motion-capture cross-check and marked it not scheduled, because it is neither funded nor scheduled and listing a release for it was a commitment we had no plan to keep. Mocap certifies a lab condition — markers, controlled lighting, a fixed rig — and this product is used on a phone propped against a fence. Independent human annotation is now stated as the next check we intend to run, ahead of any instrument work: it costs less, it matches the condition we actually ship in, and it is the only check on that list that could show a timing claim is wrong rather than agree with it.
2026-07-30
Added Knee at contact as its own not-scored row. The app shows a knee angle on the stroke metrics panel, read as a three-point angle from hip, knee and ankle in the image plane at the contact frame. That is not the same quantity as Knee joint angle (general) listed above, which is graded against a validated window and carries a degree band. Publishing the panel’s reading under the graded row would have claimed a ± 5° / ± 8° band for a number we do not grade — the same mistake we already caught and removed once for the contact elbow, which is why Elbow at contact sits separately below. The knee now gets the identical treatment: shown with its caveat, never graded, no band claimed. A guard now requires every metric on that panel to resolve to a not-scored entry, so an ungraded panel reading can no longer be published under a graded row at all.
2026-07-30
Withdrew this page’s central validation claim, which was false. Section 02 said the pipeline’s outputs “are checked against hand-marked frames on those clips at frame resolution”, carried as an in use badge, and the high-confidence tier said metrics are “rendered as a number with its error band”. Neither was true. The five bundled clips carry zero labelled entries; every labelled entry we hold sits on a single serve in a clip that is not committed to the repo, with no reviewer and no review date ever recorded against it. Those indices were not marked by a person at all — they were derived by the same kinematic rules the segmenter under test uses (contact as the lowest dominant-wrist position, toss release as the non-dominant-wrist apex, knee bend as the minimum knee angle), and two of the eight stages are not observations but the midpoint in time between their neighbours. Checking the segmenter against them confirms it reproduces its own rule; it cannot detect a rule that is wrong. Separately, no error band is rendered anywhere in the product — the code deliberately refuses to show a ± it cannot support, so this page was promising a precision the app correctly withholds. What we actually run is a stability check against our own earlier output, and section 02 now says exactly that. Independent human annotation is listed as planned, because it is the first check that could falsify a timing claim rather than confirm it. A guard now parses this page’s validation table and fails the build if a row is badged in use without evidence behind it, if a self-referential check is published as an independent one, or if any in-use row claims hand-marking — and it reads the claim from this page while reading the evidence from a separate declared inventory, so editing one to agree with the other does not quiet it.
2026-07-29
Closed a completeness gap in this page’s own promise. The contract states if a metric is missing here, it is not in the app, but seven readings shipped with no row: contact reach, the three leg-drive readings, the racket-drop arm fold, trunk balance at contact, and trunk extension at contact. They are documented above now, each marked as a geometry target rather than a measured result. We also corrected knee load at loading, which this page described as read as a quality, not a degree while the app rendered a degree value. It now states degrees with the widest band of the knee readings, because deep flexion at the trophy is the hardest knee angle to read from a single camera. A test now runs the read engines directly and fails the build when any displayed measurement has no row here, or when a row states a different unit than the one shipped, so this promise is checked rather than asserted.
2026-07-28
Removed two fabricated calibration claims that had survived earlier passes. The band table asserted the court calibration status held to RMSE under 2 cm on the singles court, and the capture-conditions card described an on-device court detector or 4-tap court-pose solve that was re-evaluated continuously and would pause the affected metrics until you tap to recalibrate. No code produces that RMSE figure and no continuous drift-detection or auto-pause exists — the 2 cm number had no measurement or derivation behind it, and the runtime behaviour was never built. What v1 actually ships is single-line scale calibration: one court line of known length fixes real-world scale for distance and speed, checked against the known ITF line geometry, with no instrument RMSE. Full court-pose calibration and any accuracy target for it are v1.1, not yet built or validated. The card and the band now state exactly that, consistent with section 02, which already validates court calibration against line geometry rather than an instrument.
2026-07-28
Renamed the band-table column header from "Error band" to "Target band", with a "(target, not measured result)" sub-label, so a reader scanning only the table cannot read the physics-derived accuracy targets as achieved measurements — the framing that was only in the prose before now sits in the column header itself. Made this Trust page reachable at its canonical /trust URL in every mode, including after public launch, rather than only under the prelaunch static path, and added it to the public sitemap. Aligned the Terms page's uncertainty clause to the same contract stated here — every observation carries an error band or a qualitative read, not a universal error band — so a qualitative read such as knee load is not misdescribed as a degree band.
2026-07-27
Rewrote "How we validate" to state only the checks we actually run today — the pipeline executing end-to-end on the bundled pro-clip fixtures, and hand-marked contact and phase frames on those clips at frame resolution. Removed claims of validation we have not run: a Vicon mocap protocol, a goniometer comparison, a 100-stroke radar cross-check, hand-labelled benchmarks with specific stroke counts, held-out public-dataset splits, and a release-blocking canary gate with a km/h floor. Each is now listed as planned, with the release it is due in. Removed the reference to a synced metrics_matrix.yaml authority file: no such file exists, and this page is the contract in full. Corrected the loading-knee row to a qualitative read (good load / shallow), matching the app, which reads load depth as a quality rather than a degree because a single camera can't pin the knee angle at the trophy. Also fixed a capture note that still said audio gives "sub-frame" contact timing — it corroborates the frame, at ~33 ms resolution, not below it.
2026-05-07
Added the 2D kinematic sequence verdict at medium confidence as the v1 path. The high-confidence audio-anchored version (240 fps + impact onset as t=0) waits on v1.5. The 2D version reports a verdict (proper / partial / inverted / insufficient) plus per-adjacent-pair lead-gap in milliseconds; no degrees-per-second number is published.
2026-04-28
Revised racket-head speed bands from "± 5 % vs lab mocap" to per-stroke-class bands: ± 8–12 km/h on groundstrokes, ± 10–15 km/h on serves. The change reflects the sampling-rate floor at 240 fps for fast impacts: a single video frame at 150 km/h moves the racket tip about 17 cm, and finite-difference velocity is bounded by that regardless of model quality. If the band exceeds 15 km/h we drop the number and show a hard / medium / soft bucket instead.
2026-04-28
Narrowed v1 use-case scope to practice sessions only — drills, ball machine, basket feeding, serve practice, cooperative rallies, lessons. Match play moved out of v1 because the capture conditions can't be met handheld, courtside, mid-rally. Match analysis returns as a v2+ feature once the on-tripod product is shipped and validated.
2026-04-28
Vertical hip displacement band split by capture distance: ± 2 cm at the typical 6–8 m setup, ± 1 cm only at tight 4 m framing. The original "≤ 1 cm" claim assumed every clip was tight-framed; pixel-per-cm math at 1080p, 6 m, ~73° HFOV is the binding constraint.